From c7607b024e601649e781318deae17d6ab0686b59 Mon Sep 17 00:00:00 2001 From: Gary Guo Date: Wed, 27 Dec 2023 04:08:04 +0000 Subject: [PATCH 001/892] Implement asm goto for LLVM and GCC backend --- src/asm.rs | 31 ++++++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/src/asm.rs b/src/asm.rs index 78e8e32b97299..07edd26e27a42 100644 --- a/src/asm.rs +++ b/src/asm.rs @@ -107,7 +107,7 @@ enum ConstraintOrRegister { impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> { - fn codegen_inline_asm(&mut self, template: &[InlineAsmTemplatePiece], rust_operands: &[InlineAsmOperandRef<'tcx, Self>], options: InlineAsmOptions, span: &[Span], instance: Instance<'_>, _dest_catch_funclet: Option<(Self::BasicBlock, Self::BasicBlock, Option<&Self::Funclet>)>) { + fn codegen_inline_asm(&mut self, template: &[InlineAsmTemplatePiece], rust_operands: &[InlineAsmOperandRef<'tcx, Self>], options: InlineAsmOptions, span: &[Span], instance: Instance<'_>, dest: Option, _catch_funclet: Option<(Self::BasicBlock, Option<&Self::Funclet>)>) { if options.contains(InlineAsmOptions::MAY_UNWIND) { self.sess().dcx() .create_err(UnwindingInlineAsm { span: span[0] }) @@ -126,6 +126,10 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> { // added to `outputs.len()` let mut inputs = vec![]; + // GCC index of a label equals its position in the array added to + // `outputs.len() + inputs.len()`. + let mut labels = vec![]; + // Clobbers collected from `out("explicit register") _` and `inout("expl_reg") var => _` let mut clobbers = vec![]; @@ -269,6 +273,10 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> { // some targets to add a leading underscore (Mach-O). constants_len += self.tcx.symbol_name(Instance::mono(self.tcx, def_id)).name.len(); } + + InlineAsmOperandRef::Label { label } => { + labels.push(label); + } } } @@ -368,6 +376,10 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> { InlineAsmOperandRef::Const { .. } => { // processed in the previous pass } + + InlineAsmOperandRef::Label { .. } => { + // processed in the previous pass + } } } @@ -454,6 +466,14 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> { InlineAsmOperandRef::Const { ref string } => { template_str.push_str(string); } + + InlineAsmOperandRef::Label { label } => { + let label_gcc_index = labels.iter() + .position(|&l| l == label) + .expect("wrong rust index"); + let gcc_index = label_gcc_index + outputs.len() + inputs.len(); + push_to_template(Some('l'), gcc_index); + } } } } @@ -466,7 +486,12 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> { // 4. Generate Extended Asm block let block = self.llbb(); - let extended_asm = block.add_extended_asm(None, &template_str); + let extended_asm = if let Some(dest) = dest { + assert!(!labels.is_empty()); + block.end_with_extended_asm_goto(None, &template_str, &labels, Some(dest)) + } else { + block.add_extended_asm(None, &template_str) + }; for op in &outputs { extended_asm.add_output_operand(None, &op.to_constraint(), op.tmp_var); @@ -494,7 +519,7 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> { if !options.contains(InlineAsmOptions::NOSTACK) { // TODO(@Commeownist): figure out how to align stack } - if options.contains(InlineAsmOptions::NORETURN) { + if dest.is_none() && options.contains(InlineAsmOptions::NORETURN) { let builtin_unreachable = self.context.get_builtin_function("__builtin_unreachable"); let builtin_unreachable: RValue<'gcc> = unsafe { std::mem::transmute(builtin_unreachable) }; self.call(self.type_void(), None, None, builtin_unreachable, &[], None); From 3ca0c5913e6f956014c4f2281b7d67f775ef4b3c Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Fri, 23 Feb 2024 12:11:11 +0000 Subject: [PATCH 002/892] Forbid implementing `Freeze` even if the trait is stabilized --- example/mini_core.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/example/mini_core.rs b/example/mini_core.rs index 230009741dc41..1f364f78ece76 100644 --- a/example/mini_core.rs +++ b/example/mini_core.rs @@ -1,6 +1,6 @@ #![feature( no_core, lang_items, intrinsics, unboxed_closures, type_ascription, extern_types, - decl_macro, rustc_attrs, transparent_unions, auto_traits, + decl_macro, rustc_attrs, transparent_unions, auto_traits, freeze_impls, thread_local )] #![no_core] From 0975461837bc9c4d065ac13ee56f7fbd0a737f38 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 5 Mar 2024 11:32:03 +0100 Subject: [PATCH 003/892] only set noalias on Box with the global allocator --- example/mini_core.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/example/mini_core.rs b/example/mini_core.rs index 230009741dc41..cc3d647c8c82f 100644 --- a/example/mini_core.rs +++ b/example/mini_core.rs @@ -472,6 +472,7 @@ pub trait Allocator { impl Allocator for () {} +#[lang = "global_alloc_ty"] pub struct Global; impl Allocator for Global {} From faebf73983661ae2bd7abe2027b5491f4762cc6e Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 5 Mar 2024 19:58:36 +0100 Subject: [PATCH 004/892] Merge commit 'b385428e3ddf330805241e7758e773f933357c4b' into subtree-update_cg_gcc_2024-03-05 --- .github/workflows/ci.yml | 89 +- .github/workflows/failures.yml | 70 +- .github/workflows/gcc12.yml | 55 +- .github/workflows/m68k.yml | 71 +- .github/workflows/release.yml | 69 +- .github/workflows/stdarch.yml | 86 +- .gitignore | 8 +- .ignore | 1 + .rustfmt.toml | 2 +- Cargo.lock | 19 +- Cargo.toml | 7 +- Readme.md | 259 +-- build.rs | 6 + build_sysroot/build_sysroot.sh | 34 - build_system/Cargo.lock | 9 + build_system/Cargo.toml | 3 + build_system/src/build.rs | 196 +-- build_system/src/cargo.rs | 114 ++ build_system/src/clean.rs | 82 + build_system/src/clone_gcc.rs | 79 + build_system/src/config.rs | 647 ++++++-- build_system/src/info.rs | 19 + build_system/src/main.rs | 32 +- build_system/src/prepare.rs | 75 +- build_system/src/test.rs | 1225 +++++++++++++- build_system/src/utils.rs | 323 +++- cargo.sh | 23 - clean_all.sh | 6 - config.example.toml | 2 + config.sh | 85 - .../0002-rand-Disable-failing-test.patch | 32 - deps/libLLVM-18-rust-1.78.0-nightly.so | 1 + doc/debugging-gcc-lto.md | 3 + doc/debugging-libgccjit.md | 74 + doc/errors.md | 27 + doc/subtree.md | 52 + doc/tips.md | 72 + libgccjit.version | 1 + messages.ftl | 2 - ...022-core-Disable-not-compiling-tests.patch | 4 +- .../crates/0001-Remove-deny-warnings.patch | 24 + ...001-Disable-libstd-and-libtest-dylib.patch | 16 - rust-toolchain | 2 +- rustup.sh | 29 - src/abi.rs | 107 +- src/allocator.rs | 62 +- src/asm.rs | 223 +-- src/attributes.rs | 77 +- src/back/lto.rs | 94 +- src/back/write.rs | 54 +- src/base.rs | 59 +- src/builder.rs | 1431 +++++++++++------ src/callee.rs | 259 ++- src/common.rs | 168 +- src/consts.rs | 143 +- src/context.rs | 252 +-- src/debuginfo.rs | 243 ++- src/declare.rs | 225 ++- src/errors.rs | 23 +- src/gcc_util.rs | 67 +- src/int.rs | 942 ++++++----- src/intrinsic/archs.rs | 27 +- src/intrinsic/llvm.rs | 524 ++++-- src/intrinsic/mod.rs | 1101 +++++++------ src/intrinsic/simd.rs | 230 ++- src/lib.rs | 240 ++- src/mono_item.rs | 39 +- src/type_.rs | 71 +- src/type_of.rs | 163 +- test.sh | 479 ------ .../failing-lto-tests.txt | 11 +- .../failing-non-lto-tests.txt | 2 +- .../failing-ui-tests.txt | 8 +- .../failing-ui-tests12.txt | 8 +- tests/lang_tests_common.rs | 88 +- y.sh | 6 +- 76 files changed, 7183 insertions(+), 4278 deletions(-) create mode 100644 build.rs delete mode 100755 build_sysroot/build_sysroot.sh create mode 100644 build_system/src/cargo.rs create mode 100644 build_system/src/clean.rs create mode 100644 build_system/src/clone_gcc.rs create mode 100644 build_system/src/info.rs delete mode 100755 cargo.sh delete mode 100755 clean_all.sh create mode 100644 config.example.toml delete mode 100644 config.sh delete mode 100644 crate_patches/0002-rand-Disable-failing-test.patch create mode 100644 deps/libLLVM-18-rust-1.78.0-nightly.so create mode 100644 doc/debugging-gcc-lto.md create mode 100644 doc/debugging-libgccjit.md create mode 100644 doc/errors.md create mode 100644 doc/subtree.md create mode 100644 doc/tips.md create mode 100644 libgccjit.version create mode 100644 patches/crates/0001-Remove-deny-warnings.patch rename {cross_patches => patches/cross_patches}/0001-Disable-libstd-and-libtest-dylib.patch (64%) delete mode 100755 rustup.sh delete mode 100755 test.sh rename failing-lto-tests.txt => tests/failing-lto-tests.txt (66%) rename failing-non-lto-tests.txt => tests/failing-non-lto-tests.txt (85%) rename failing-ui-tests.txt => tests/failing-ui-tests.txt (93%) rename failing-ui-tests12.txt => tests/failing-ui-tests12.txt (88%) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 308bc55ead71e..839f3ba4de362 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -19,8 +19,8 @@ jobs: fail-fast: false matrix: libgccjit_version: - - { gcc: "libgccjit.so", artifacts_branch: "master" } - - { gcc: "libgccjit_without_int128.so", artifacts_branch: "master-without-128bit-integers" } + - { gcc: "gcc-13.deb" } + - { gcc: "gcc-13-without-int128.deb" } commands: [ "--mini-tests", "--std-tests", @@ -32,60 +32,39 @@ jobs: "--extended-regex-tests", "--test-successful-rustc --nb-parts 2 --current-part 0", "--test-successful-rustc --nb-parts 2 --current-part 1", + "--projects", ] steps: - uses: actions/checkout@v3 + # `rustup show` installs from rust-toolchain.toml + - name: Setup rust toolchain + run: rustup show + + - name: Setup rust cache + uses: Swatinem/rust-cache@v2 + - name: Install packages # `llvm-14-tools` is needed to install the `FileCheck` binary which is used for asm tests. run: sudo apt-get install ninja-build ripgrep llvm-14-tools + - name: Install rustfmt + run: rustup component add rustfmt + - name: Download artifact - uses: dawidd6/action-download-artifact@v2 - with: - workflow: main.yml - name: gcc-13 - path: gcc-13 - repo: antoyo/gcc - branch: ${{ matrix.libgccjit_version.artifacts_branch }} - event: push - search_artifacts: true # Because, instead, the action only check the last job ran and that won't work since we want multiple artifacts. + run: curl -LO https://github.com/antoyo/gcc/releases/latest/download/${{ matrix.libgccjit_version.gcc }} - name: Setup path to libgccjit run: | - sudo dpkg --force-overwrite -i gcc-13/gcc-13.deb - echo /usr/lib/ > gcc_path + sudo dpkg --force-overwrite -i ${{ matrix.libgccjit_version.gcc }} + echo 'gcc-path = "/usr/lib/"' > config.toml - name: Set env run: | - echo "LIBRARY_PATH=$(cat gcc_path)" >> $GITHUB_ENV - echo "LD_LIBRARY_PATH=$(cat gcc_path)" >> $GITHUB_ENV echo "workspace="$GITHUB_WORKSPACE >> $GITHUB_ENV - - - name: Cache cargo installed crates - uses: actions/cache@v3 - with: - path: ~/.cargo/bin - key: cargo-installed-crates2-ubuntu-latest - - - name: Cache cargo registry - uses: actions/cache@v3 - with: - path: ~/.cargo/registry - key: ${{ runner.os }}-cargo-registry2-${{ hashFiles('**/Cargo.lock') }} - - - name: Cache cargo index - uses: actions/cache@v3 - with: - path: ~/.cargo/git - key: ${{ runner.os }}-cargo-index-${{ hashFiles('**/Cargo.lock') }} - - - name: Cache cargo target dir - uses: actions/cache@v3 - with: - path: target - key: ${{ runner.os }}-cargo-build-target-${{ hashFiles('rust-toolchain') }} + echo "LIBRARY_PATH=/usr/lib" >> $GITHUB_ENV + echo "LD_LIBRARY_PATH=/usr/lib" >> $GITHUB_ENV #- name: Cache rust repository ## We only clone the rust repository for rustc tests @@ -99,11 +78,9 @@ jobs: - name: Build run: | ./y.sh prepare --only-libcore - # TODO: remove --features master when it is back to the default. - ./y.sh build --features master - # TODO: remove --features master when it is back to the default. - cargo test --features master - ./clean_all.sh + ./y.sh build + cargo test + ./y.sh clean all - name: Prepare dependencies run: | @@ -111,23 +88,27 @@ jobs: git config --global user.name "User" ./y.sh prepare - # Compile is a separate step, as the actions-rs/cargo action supports error annotations - - name: Compile - uses: actions-rs/cargo@v1.0.3 - with: - command: build - args: --release - - name: Add more failing tests because the sysroot is not compiled with LTO - run: cat failing-non-lto-tests.txt >> failing-ui-tests.txt + run: cat tests/failing-non-lto-tests.txt >> tests/failing-ui-tests.txt - name: Run tests run: | - # TODO: remove --features master when it is back to the default. - ./test.sh --features master --release --clean --build-sysroot ${{ matrix.commands }} + ./y.sh test --release --clean --build-sysroot ${{ matrix.commands }} + + - name: Check formatting + run: cargo fmt -- --check duplicates: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - run: python tools/check_intrinsics_duplicates.py + + build_system: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: Test build system + run: | + cd build_system + cargo test diff --git a/.github/workflows/failures.yml b/.github/workflows/failures.yml index ae8de79b773db..2bca694e83284 100644 --- a/.github/workflows/failures.yml +++ b/.github/workflows/failures.yml @@ -21,14 +21,11 @@ jobs: libgccjit_version: - gcc: "libgccjit.so" artifacts_branch: "master" - # TODO: switch back to --no-default-features in the case of libgccjit 12 when the default is to enable - # master again. - extra: "--features master" - gcc: "libgccjit_without_int128.so" artifacts_branch: "master-without-128bit-integers" - extra: "--features master" - gcc: "libgccjit12.so" artifacts_branch: "gcc12" + extra: "--no-default-features" # FIXME(antoyo): we need to set GCC_EXEC_PREFIX so that the linker can find the linker plugin. # Not sure why it's not found otherwise. env_extra: "TEST_FLAGS='-Cpanic=abort -Zpanic-abort-tests' GCC_EXEC_PREFIX=/usr/lib/gcc/" @@ -36,6 +33,13 @@ jobs: steps: - uses: actions/checkout@v3 + # `rustup show` installs from rust-toolchain.toml + - name: Setup rust toolchain + run: rustup show + + - name: Setup rust cache + uses: Swatinem/rust-cache@v2 + - name: Install packages run: sudo apt-get install ninja-build ripgrep @@ -45,56 +49,27 @@ jobs: - name: Setup path to libgccjit if: matrix.libgccjit_version.gcc == 'libgccjit12.so' - run: echo /usr/lib/gcc/x86_64-linux-gnu/12 > gcc_path + run: | + echo 'gcc-path = "/usr/lib/gcc/x86_64-linux-gnu/12"' > config.toml + echo "LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/12" >> $GITHUB_ENV + echo "LD_LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/12" >> $GITHUB_ENV - name: Download artifact if: matrix.libgccjit_version.gcc != 'libgccjit12.so' - uses: dawidd6/action-download-artifact@v2 - with: - workflow: main.yml - name: gcc-13 - path: gcc-13 - repo: antoyo/gcc - branch: ${{ matrix.libgccjit_version.artifacts_branch }} - event: push - search_artifacts: true # Because, instead, the action only check the last job ran and that won't work since we want multiple artifacts. + run: curl -LO https://github.com/antoyo/gcc/releases/latest/download/gcc-13.deb - name: Setup path to libgccjit if: matrix.libgccjit_version.gcc != 'libgccjit12.so' run: | - sudo dpkg --force-overwrite -i gcc-13/gcc-13.deb - echo /usr/lib/ > gcc_path + sudo dpkg --force-overwrite -i gcc-13.deb + echo 'gcc-path = "/usr/lib"' > config.toml + echo "LIBRARY_PATH=/usr/lib" >> $GITHUB_ENV + echo "LD_LIBRARY_PATH=/usr/lib" >> $GITHUB_ENV - name: Set env run: | - echo "LIBRARY_PATH=$(cat gcc_path)" >> $GITHUB_ENV - echo "LD_LIBRARY_PATH=$(cat gcc_path)" >> $GITHUB_ENV echo "workspace="$GITHUB_WORKSPACE >> $GITHUB_ENV - - name: Cache cargo installed crates - uses: actions/cache@v3 - with: - path: ~/.cargo/bin - key: cargo-installed-crates2-ubuntu-latest - - - name: Cache cargo registry - uses: actions/cache@v3 - with: - path: ~/.cargo/registry - key: ${{ runner.os }}-cargo-registry2-${{ hashFiles('**/Cargo.lock') }} - - - name: Cache cargo index - uses: actions/cache@v3 - with: - path: ~/.cargo/git - key: ${{ runner.os }}-cargo-index-${{ hashFiles('**/Cargo.lock') }} - - - name: Cache cargo target dir - uses: actions/cache@v3 - with: - path: target - key: ${{ runner.os }}-cargo-build-target-${{ hashFiles('rust-toolchain') }} - #- name: Cache rust repository #uses: actions/cache@v3 #id: cache-rust-repository @@ -115,18 +90,11 @@ jobs: if: matrix.libgccjit_version.gcc != 'libgccjit12.so' run: ./y.sh prepare - # Compile is a separate step, as the actions-rs/cargo action supports error annotations - - name: Compile - uses: actions-rs/cargo@v1.0.3 - with: - command: build - args: --release - - name: Add more failing tests because the sysroot is not compiled with LTO - run: cat failing-non-lto-tests.txt >> failing-ui-tests.txt + run: cat tests/failing-non-lto-tests.txt >> tests/failing-ui-tests.txt - name: Run tests id: tests run: | - ${{ matrix.libgccjit_version.env_extra }} ./test.sh --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 }} | tee output_log rg --text "test result" output_log >> $GITHUB_STEP_SUMMARY diff --git a/.github/workflows/gcc12.yml b/.github/workflows/gcc12.yml index a0d363cf1fbda..f7bb156049233 100644 --- a/.github/workflows/gcc12.yml +++ b/.github/workflows/gcc12.yml @@ -28,9 +28,6 @@ jobs: # FIXME: re-enable asm tests when GCC can emit in the right syntax. # "--asm-tests", "--test-libcore", - "--extended-rand-tests", - "--extended-regex-example-tests", - "--extended-regex-tests", "--test-successful-rustc --nb-parts 2 --current-part 0", "--test-successful-rustc --nb-parts 2 --current-part 1", ] @@ -38,42 +35,25 @@ jobs: steps: - uses: actions/checkout@v3 + # `rustup show` installs from rust-toolchain.toml + - name: Setup rust toolchain + run: rustup show + + - name: Setup rust cache + uses: Swatinem/rust-cache@v2 + - name: Install packages # `llvm-14-tools` is needed to install the `FileCheck` binary which is used for asm tests. run: sudo apt-get install ninja-build ripgrep llvm-14-tools libgccjit-12-dev - name: Setup path to libgccjit - run: echo /usr/lib/gcc/x86_64-linux-gnu/12 > gcc_path + run: echo 'gcc-path = "/usr/lib/gcc/x86_64-linux-gnu/12"' > config.toml - name: Set env run: | - echo "LIBRARY_PATH=$(cat gcc_path)" >> $GITHUB_ENV - echo "LD_LIBRARY_PATH=$(cat gcc_path)" >> $GITHUB_ENV echo "workspace="$GITHUB_WORKSPACE >> $GITHUB_ENV - - - name: Cache cargo installed crates - uses: actions/cache@v3 - with: - path: ~/.cargo/bin - key: cargo-installed-crates2-ubuntu-latest - - - name: Cache cargo registry - uses: actions/cache@v3 - with: - path: ~/.cargo/registry - key: ${{ runner.os }}-cargo-registry2-${{ hashFiles('**/Cargo.lock') }} - - - name: Cache cargo index - uses: actions/cache@v3 - with: - path: ~/.cargo/git - key: ${{ runner.os }}-cargo-index-${{ hashFiles('**/Cargo.lock') }} - - - name: Cache cargo target dir - uses: actions/cache@v3 - with: - path: target - key: ${{ runner.os }}-cargo-build-target-${{ hashFiles('rust-toolchain') }} + echo "LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/12" >> $GITHUB_ENV + echo "LD_LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/12" >> $GITHUB_ENV #- name: Cache rust repository ## We only clone the rust repository for rustc tests @@ -89,7 +69,7 @@ jobs: ./y.sh prepare --only-libcore --libgccjit12-patches ./y.sh build --no-default-features --sysroot-panic-abort cargo test --no-default-features - ./clean_all.sh + ./y.sh clean all - name: Prepare dependencies run: | @@ -97,19 +77,12 @@ jobs: git config --global user.name "User" ./y.sh prepare --libgccjit12-patches - # Compile is a separate step, as the actions-rs/cargo action supports error annotations - - name: Compile - uses: actions-rs/cargo@v1.0.3 - with: - command: build - args: --release - - name: Add more failing tests for GCC 12 - run: cat failing-ui-tests12.txt >> failing-ui-tests.txt + 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 failing-non-lto-tests.txt >> failing-ui-tests.txt + run: cat tests/failing-non-lto-tests.txt >> tests/failing-ui-tests.txt - name: Run tests run: | - ./test.sh --release --clean --build-sysroot ${{ matrix.commands }} --no-default-features + ./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 4d9d7e23dc2b5..a8c6b614ce815 100644 --- a/.github/workflows/m68k.yml +++ b/.github/workflows/m68k.yml @@ -36,21 +36,22 @@ jobs: ] steps: + - uses: actions/checkout@v3 + + # `rustup show` installs from rust-toolchain.toml + - name: Setup rust toolchain + run: rustup show + + - name: Setup rust cache + uses: Swatinem/rust-cache@v2 + - name: Install packages run: | sudo apt-get update sudo apt-get install qemu qemu-user-static - - uses: actions/checkout@v3 - - - name: Download GCC artifact - uses: dawidd6/action-download-artifact@v2 - with: - workflow: m68k.yml - name: gcc-m68k-13 - repo: cross-cg-gcc-tools/cross-gcc - branch: master - event: push + - name: Download artifact + run: curl -LO https://github.com/cross-cg-gcc-tools/cross-gcc/releases/latest/download/gcc-m68k-13.deb - name: Download VM artifact uses: dawidd6/action-download-artifact@v2 @@ -64,37 +65,13 @@ jobs: - name: Setup path to libgccjit run: | sudo dpkg -i gcc-m68k-13.deb - echo /usr/lib/ > gcc_path + echo 'gcc-path = "/usr/lib/"' > config.toml - name: Set env run: | - echo "LIBRARY_PATH=$(cat gcc_path)" >> $GITHUB_ENV - echo "LD_LIBRARY_PATH=$(cat gcc_path)" >> $GITHUB_ENV echo "workspace="$GITHUB_WORKSPACE >> $GITHUB_ENV - - - name: Cache cargo installed crates - uses: actions/cache@v3 - with: - path: ~/.cargo/bin - key: cargo-installed-crates2-ubuntu-latest - - #- name: Cache cargo registry - #uses: actions/cache@v3 - #with: - #path: ~/.cargo/registry - #key: ${{ runner.os }}-cargo-registry2-${{ hashFiles('**/Cargo.lock') }} - - #- name: Cache cargo index - #uses: actions/cache@v3 - #with: - #path: ~/.cargo/git - #key: ${{ runner.os }}-cargo-index-${{ hashFiles('**/Cargo.lock') }} - - - name: Cache cargo target dir - uses: actions/cache@v3 - with: - path: target - key: ${{ runner.os }}-cargo-build-target-${{ hashFiles('rust-toolchain') }} + echo "LIBRARY_PATH=/usr/lib" >> $GITHUB_ENV + echo "LD_LIBRARY_PATH=/usr/lib" >> $GITHUB_ENV #- name: Cache rust repository ## We only clone the rust repository for rustc tests @@ -114,11 +91,9 @@ jobs: - name: Build run: | ./y.sh prepare --only-libcore --cross - # TODO: remove --features master when it is back to the default. - ./y.sh build --target-triple m68k-unknown-linux-gnu --features master - # TODO: remove --features master when it is back to the default. - CG_GCC_TEST_TARGET=m68k-unknown-linux-gnu cargo test --features master - ./clean_all.sh + ./y.sh build --target-triple m68k-unknown-linux-gnu + CG_GCC_TEST_TARGET=m68k-unknown-linux-gnu cargo test + ./y.sh clean all - name: Prepare dependencies run: | @@ -126,17 +101,9 @@ jobs: git config --global user.name "User" ./y.sh prepare --cross - # Compile is a separate step, as the actions-rs/cargo action supports error annotations - - name: Compile - uses: actions-rs/cargo@v1.0.3 - with: - command: build - args: --release - - name: Add more failing tests because the sysroot is not compiled with LTO - run: cat failing-non-lto-tests.txt >> failing-ui-tests.txt + run: cat tests/failing-non-lto-tests.txt >> tests/failing-ui-tests.txt - name: Run tests run: | - # TODO: remove --features master when it is back to the default. - ./test.sh --release --features master --clean --build-sysroot ${{ matrix.commands }} + ./y.sh test --release --clean --build-sysroot ${{ matrix.commands }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 43b90fcec9337..28336998ffcd7 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -26,63 +26,36 @@ jobs: steps: - uses: actions/checkout@v3 + # `rustup show` installs from rust-toolchain.toml + - name: Setup rust toolchain + run: rustup show + + - name: Setup rust cache + uses: Swatinem/rust-cache@v2 + - name: Install packages run: sudo apt-get install ninja-build ripgrep - name: Download artifact - uses: dawidd6/action-download-artifact@v2 - with: - workflow: main.yml - name: gcc-13 - path: gcc-13 - repo: antoyo/gcc - branch: "master" - event: push - search_artifacts: true # Because, instead, the action only check the last job ran and that won't work since we want multiple artifacts. + run: curl -LO https://github.com/antoyo/gcc/releases/latest/download/gcc-13.deb - name: Setup path to libgccjit run: | - sudo dpkg --force-overwrite -i gcc-13/gcc-13.deb - echo /usr/lib/ > gcc_path + sudo dpkg --force-overwrite -i gcc-13.deb + echo 'gcc-path = "/usr/lib/"' > config.toml - name: Set env run: | - echo "LIBRARY_PATH=$(cat gcc_path)" >> $GITHUB_ENV - echo "LD_LIBRARY_PATH=$(cat gcc_path)" >> $GITHUB_ENV echo "workspace="$GITHUB_WORKSPACE >> $GITHUB_ENV - - - name: Cache cargo installed crates - uses: actions/cache@v3 - with: - path: ~/.cargo/bin - key: cargo-installed-crates2-ubuntu-latest - - - name: Cache cargo registry - uses: actions/cache@v3 - with: - path: ~/.cargo/registry - key: ${{ runner.os }}-cargo-registry2-${{ hashFiles('**/Cargo.lock') }} - - - name: Cache cargo index - uses: actions/cache@v3 - with: - path: ~/.cargo/git - key: ${{ runner.os }}-cargo-index-${{ hashFiles('**/Cargo.lock') }} - - - name: Cache cargo target dir - uses: actions/cache@v3 - with: - path: target - key: ${{ runner.os }}-cargo-build-target-${{ hashFiles('rust-toolchain') }} + echo "LIBRARY_PATH=/usr/lib" >> $GITHUB_ENV + echo "LD_LIBRARY_PATH=/usr/lib" >> $GITHUB_ENV - name: Build run: | ./y.sh prepare --only-libcore - # TODO: remove --features master when it is back to the default. - EMBED_LTO_BITCODE=1 ./y.sh build --release --release-sysroot --features master - # TODO: remove --features master when it is back to the default. - cargo test --features master - ./clean_all.sh + EMBED_LTO_BITCODE=1 ./y.sh build --release --release-sysroot + cargo test + ./y.sh clean all - name: Prepare dependencies run: | @@ -92,17 +65,9 @@ jobs: # FIXME(antoyo): we cannot enable LTO for stdarch tests currently because of some failing LTO tests using proc-macros. echo -n 'lto = "fat"' >> build_sysroot/Cargo.toml - # Compile is a separate step, as the actions-rs/cargo action supports error annotations - - name: Compile - uses: actions-rs/cargo@v1.0.3 - with: - command: build - args: --release - - name: Add more failing tests because of undefined symbol errors (FIXME) - run: cat failing-lto-tests.txt >> failing-ui-tests.txt + run: cat tests/failing-lto-tests.txt >> tests/failing-ui-tests.txt - name: Run tests run: | - # TODO: remove --features master when it is back to the default. - EMBED_LTO_BITCODE=1 ./test.sh --release --clean --release-sysroot --build-sysroot ${{ matrix.commands }} --features master + EMBED_LTO_BITCODE=1 ./y.sh test --release --clean --release-sysroot --build-sysroot ${{ matrix.commands }} diff --git a/.github/workflows/stdarch.yml b/.github/workflows/stdarch.yml index 42109ba3e0245..41a9318007f15 100644 --- a/.github/workflows/stdarch.yml +++ b/.github/workflows/stdarch.yml @@ -26,6 +26,13 @@ jobs: steps: - uses: actions/checkout@v3 + # `rustup show` installs from rust-toolchain.toml + - name: Setup rust toolchain + run: rustup show + + - name: Setup rust cache + uses: Swatinem/rust-cache@v2 + - name: Install packages run: sudo apt-get install ninja-build ripgrep @@ -34,73 +41,39 @@ jobs: run: | mkdir intel-sde cd intel-sde - dir=sde-external-9.14.0-2022-10-25-lin + dir=sde-external-9.33.0-2024-01-07-lin file=$dir.tar.xz - wget https://downloadmirror.intel.com/751535/$file + wget https://downloadmirror.intel.com/813591/$file tar xvf $file sudo mkdir /usr/share/intel-sde sudo cp -r $dir/* /usr/share/intel-sde sudo ln -s /usr/share/intel-sde/sde /usr/bin/sde sudo ln -s /usr/share/intel-sde/sde64 /usr/bin/sde64 - - name: Download artifact - uses: dawidd6/action-download-artifact@v2 - with: - workflow: main.yml - name: gcc-13 - path: gcc-13 - repo: antoyo/gcc - branch: "master" - event: push - search_artifacts: true # Because, instead, the action only check the last job ran and that won't work since we want multiple artifacts. - - - name: Setup path to libgccjit - run: | - sudo dpkg --force-overwrite -i gcc-13/gcc-13.deb - echo /usr/lib/ > gcc_path - - name: Set env run: | - echo "LIBRARY_PATH=$(cat gcc_path)" >> $GITHUB_ENV - echo "LD_LIBRARY_PATH=$(cat gcc_path)" >> $GITHUB_ENV echo "workspace="$GITHUB_WORKSPACE >> $GITHUB_ENV - - - name: Cache cargo installed crates - uses: actions/cache@v3 - with: - path: ~/.cargo/bin - key: cargo-installed-crates2-ubuntu-latest - - - name: Cache cargo registry - uses: actions/cache@v3 - with: - path: ~/.cargo/registry - key: ${{ runner.os }}-cargo-registry2-${{ hashFiles('**/Cargo.lock') }} - - - name: Cache cargo index - uses: actions/cache@v3 - with: - path: ~/.cargo/git - key: ${{ runner.os }}-cargo-index-${{ hashFiles('**/Cargo.lock') }} - - - name: Cache cargo target dir - uses: actions/cache@v3 - with: - path: target - key: ${{ runner.os }}-cargo-build-target-${{ hashFiles('rust-toolchain') }} + echo 'download-gccjit = true' > config.toml - name: Build run: | ./y.sh prepare --only-libcore - # TODO: remove `--features master` when it is back to the default. - ./y.sh build --release --release-sysroot --features master - # TODO: remove --features master when it is back to the default. - cargo test --features master + ./y.sh build --release --release-sysroot + + - name: Set env (part 2) + run: | + # Set the `LD_LIBRARY_PATH` and `LIBRARY_PATH` env variables... + 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: | - ./clean_all.sh + ./y.sh clean all - name: Prepare dependencies run: | @@ -108,29 +81,20 @@ jobs: git config --global user.name "User" ./y.sh prepare - # Compile is a separate step, as the actions-rs/cargo action supports error annotations - - name: Compile - uses: actions-rs/cargo@v1.0.3 - with: - command: build - # TODO: remove `--features master` when it is back to the default. - args: --release --features master - - name: Run tests if: ${{ !matrix.cargo_runner }} run: | - # TODO: remove `--features master` when it is back to the default. - ./test.sh --release --clean --release-sysroot --build-sysroot --mini-tests --std-tests --test-libcore --features master + ./y.sh test --release --clean --release-sysroot --build-sysroot --mini-tests --std-tests --test-libcore - name: Run stdarch tests if: ${{ !matrix.cargo_runner }} run: | cd build_sysroot/sysroot_src/library/stdarch/ - CHANNEL=release TARGET=x86_64-unknown-linux-gnu CG_RUSTFLAGS="-Ainternal_features" ../../../../cargo.sh test + CHANNEL=release TARGET=x86_64-unknown-linux-gnu CG_RUSTFLAGS="-Ainternal_features" ../../../../y.sh cargo test - name: Run stdarch tests if: ${{ matrix.cargo_runner }} run: | cd build_sysroot/sysroot_src/library/stdarch/ # FIXME: these tests fail when the sysroot is compiled with LTO because of a missing symbol in proc-macro. - STDARCH_TEST_EVERYTHING=1 CHANNEL=release CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_RUNNER="${{ matrix.cargo_runner }}" TARGET=x86_64-unknown-linux-gnu CG_RUSTFLAGS="-Ainternal_features" ../../../../cargo.sh test -- --skip rtm --skip tbm --skip sse4a + STDARCH_TEST_EVERYTHING=1 CHANNEL=release CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_RUNNER="${{ matrix.cargo_runner }}" TARGET=x86_64-unknown-linux-gnu CG_RUSTFLAGS="-Ainternal_features" ../../../../y.sh cargo test -- --skip rtm --skip tbm --skip sse4a diff --git a/.gitignore b/.gitignore index b44d1aa78c2e6..bf975f92014da 100644 --- a/.gitignore +++ b/.gitignore @@ -10,15 +10,11 @@ perf.data.old /build_sysroot/sysroot_src /build_sysroot/Cargo.lock /build_sysroot/test_target/Cargo.lock -/rust -/simple-raytracer -/regex -/rand gimple* *asm res test-backend -gcc_path +projects benchmarks tools/llvm-project tools/llvmint @@ -26,3 +22,5 @@ tools/llvmint-2 # The `llvm` folder is generated by the `tools/generate_intrinsics.py` script to update intrinsics. llvm build_system/target +config.toml +build \ No newline at end of file diff --git a/.ignore b/.ignore index d8d189e5c7c64..702dd9e2a23f3 100644 --- a/.ignore +++ b/.ignore @@ -8,3 +8,4 @@ !*gimple* !*asm* !.github +!config.toml diff --git a/.rustfmt.toml b/.rustfmt.toml index c7ad93bafe36c..2a35f0230c690 100644 --- a/.rustfmt.toml +++ b/.rustfmt.toml @@ -1 +1 @@ -disable_all_formatting = true +use_small_heuristics = "Max" diff --git a/Cargo.lock b/Cargo.lock index ddfce5d59bde8..ab2c7ca8a47c8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -23,6 +23,12 @@ version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635" +[[package]] +name = "boml" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85fdb93f04c73bff54305fa437ffea5449c41edcaadfe882f35836206b166ac5" + [[package]] name = "cc" version = "1.0.79" @@ -64,9 +70,9 @@ checksum = "6999dc1837253364c2ebb0704ba97994bd874e8f195d665c50b7548f6ea92764" [[package]] name = "fm" -version = "0.1.4" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68fda3cff2cce84c19e5dfa5179a4b35d2c0f18b893f108002b8a6a54984acca" +checksum = "21bcf4db620a804cf7e9d84fbcb5d4ac83a8c43396203b2507d62ea31814dfd4" dependencies = [ "regex", ] @@ -74,7 +80,7 @@ dependencies = [ [[package]] name = "gccjit" version = "1.0.0" -source = "git+https://github.com/antoyo/gccjit.rs#6e290f25b1d1edab5ae9ace486fd2dc8c08d6421" +source = "git+https://github.com/antoyo/gccjit.rs#9f8f67edc006d543b17529a001803ffece48349e" dependencies = [ "gccjit_sys", ] @@ -82,7 +88,7 @@ dependencies = [ [[package]] name = "gccjit_sys" version = "0.0.1" -source = "git+https://github.com/antoyo/gccjit.rs#6e290f25b1d1edab5ae9ace486fd2dc8c08d6421" +source = "git+https://github.com/antoyo/gccjit.rs#9f8f67edc006d543b17529a001803ffece48349e" dependencies = [ "libc", ] @@ -104,9 +110,9 @@ checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286" [[package]] name = "lang_tester" -version = "0.3.13" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96bd995a092cac79868250589869b5a5d656b02a02bd74c8ebdc566dc7203090" +checksum = "9af8149dbb3ed7d8e529fcb141fe033b1c26ed54cbffc6762d3a86483c485d23" dependencies = [ "fm", "getopts", @@ -185,6 +191,7 @@ checksum = "436b050e76ed2903236f032a59761c1eb99e1b0aead2c257922771dab1fc8c78" name = "rustc_codegen_gcc" version = "0.1.0" dependencies = [ + "boml", "gccjit", "lang_tester", "object", diff --git a/Cargo.toml b/Cargo.toml index b0b3aeecdbdfd..100c10ef1d7af 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,6 +19,7 @@ harness = false [features] master = ["gccjit/master"] +default = ["master"] [dependencies] gccjit = { git = "https://github.com/antoyo/gccjit.rs" } @@ -35,8 +36,9 @@ smallvec = { version = "1.6.1", features = ["union", "may_dangle"] } tempfile = "3.7.1" [dev-dependencies] -lang_tester = "0.3.9" +lang_tester = "0.8.0" tempfile = "3.1.0" +boml = "0.3.1" [profile.dev] # By compiling dependencies with optimizations, performing tests gets much faster. @@ -55,3 +57,6 @@ debug = false [profile.release.build-override] opt-level = 0 debug = false + +[package.metadata.rust-analyzer] +rustc_private = true diff --git a/Readme.md b/Readme.md index 95fc6374c09ae..da6e91587fdaf 100644 --- a/Readme.md +++ b/Readme.md @@ -17,6 +17,18 @@ A secondary goal is to check if using the gcc backend will provide any run-time **This requires a patched libgccjit in order to work. You need to use my [fork of gcc](https://github.com/antoyo/gcc) which already includes these patches.** +```bash +$ cp config.example.toml config.toml +``` + +If don't need to test GCC patches you wrote in our GCC fork, then the default configuration should +be all you need. You can update the `rustc_codegen_gcc` without worrying about GCC. + +### Building with your own GCC version + +If you wrote a patch for GCC and want to test it without this backend, you will need +to do a few more things. + To build it (most of these instructions come from [here](https://gcc.gnu.org/onlinedocs/jit/internals/index.html), so don't hesitate to take a look there if you encounter an issue): ```bash @@ -49,23 +61,32 @@ $ make check-jit $ make check-jit RUNTESTFLAGS="-v -v -v jit.exp=jit.dg/test-asm.cc" ``` -**Put the path to your custom build of libgccjit in the file `gcc_path`.** +**Put the path to your custom build of libgccjit in the file `config.toml`.** + +You now need to set the `gcc-path` value in `config.toml` with the result of this command: ```bash -$ dirname $(readlink -f `find . -name libgccjit.so`) > gcc_path +$ dirname $(readlink -f `find . -name libgccjit.so`) +``` + +and to comment the `download-gccjit` setting: + +```toml +gcc-path = "[MY PATH]" +# download-gccjit = true ``` Then you can run commands like this: ```bash $ ./y.sh prepare # download and patch sysroot src and install hyperfine for benchmarking -$ LIBRARY_PATH=$(cat gcc_path) LD_LIBRARY_PATH=$(cat gcc_path) ./y.sh build --release +$ ./y.sh build --release ``` To run the tests: ```bash -$ ./test.sh --release +$ ./y.sh test --release ``` ## Usage @@ -79,10 +100,10 @@ export CG_GCCJIT_DIR=[the full path to rustc_codegen_gcc] ### Cargo ```bash -$ CHANNEL="release" $CG_GCCJIT_DIR/cargo.sh run +$ CHANNEL="release" $CG_GCCJIT_DIR/y.sh cargo run ``` -If you compiled cg_gccjit in debug mode (aka you didn't pass `--release` to `./test.sh`) you should use `CHANNEL="debug"` instead or omit `CHANNEL="release"` completely. +If you compiled cg_gccjit in debug mode (aka you didn't pass `--release` to `./y.sh test`) you should use `CHANNEL="debug"` instead or omit `CHANNEL="release"` completely. ### LTO @@ -100,7 +121,7 @@ error: failed to copy bitcode to object file: No such file or directory (os erro > You should prefer using the Cargo method. ```bash -$ LIBRARY_PATH=$(cat gcc_path) LD_LIBRARY_PATH=$(cat gcc_path) rustc +$(cat $CG_GCCJIT_DIR/rust-toolchain | grep 'channel' | cut -d '=' -f 2 | sed 's/"//g' | sed 's/ //g') -Cpanic=abort -Zcodegen-backend=$CG_GCCJIT_DIR/target/release/librustc_codegen_gcc.so --sysroot $CG_GCCJIT_DIR/build_sysroot/sysroot my_crate.rs +$ LIBRARY_PATH="[gcc-path value]" LD_LIBRARY_PATH="[gcc-path value]" rustc +$(cat $CG_GCCJIT_DIR/rust-toolchain | grep 'channel' | cut -d '=' -f 2 | sed 's/"//g' | sed 's/ //g') -Cpanic=abort -Zcodegen-backend=$CG_GCCJIT_DIR/target/release/librustc_codegen_gcc.so --sysroot $CG_GCCJIT_DIR/build_sysroot/sysroot my_crate.rs ``` ## Env vars @@ -118,221 +139,19 @@ $ LIBRARY_PATH=$(cat gcc_path) LD_LIBRARY_PATH=$(cat gcc_path) rustc +$(cat $CG_
Dump a C-like representation to /tmp/gccjit_dumps and enable debug info in order to debug this C-like representation.
-## Licensing - -While this crate is licensed under a dual Apache/MIT license, it links to `libgccjit` which is under the GPLv3+ and thus, the resulting toolchain (rustc + GCC codegen) will need to be released under the GPL license. - -However, programs compiled with `rustc_codegen_gcc` do not need to be released under a GPL license. - -## Debugging - -Sometimes, libgccjit will crash and output an error like this: - -``` -during RTL pass: expand -libgccjit.so: error: in expmed_mode_index, at expmed.h:249 -0x7f0da2e61a35 expmed_mode_index - ../../../gcc/gcc/expmed.h:249 -0x7f0da2e61aa4 expmed_op_cost_ptr - ../../../gcc/gcc/expmed.h:271 -0x7f0da2e620dc sdiv_cost_ptr - ../../../gcc/gcc/expmed.h:540 -0x7f0da2e62129 sdiv_cost - ../../../gcc/gcc/expmed.h:558 -0x7f0da2e73c12 expand_divmod(int, tree_code, machine_mode, rtx_def*, rtx_def*, rtx_def*, int) - ../../../gcc/gcc/expmed.c:4335 -0x7f0da2ea1423 expand_expr_real_2(separate_ops*, rtx_def*, machine_mode, expand_modifier) - ../../../gcc/gcc/expr.c:9240 -0x7f0da2cd1a1e expand_gimple_stmt_1 - ../../../gcc/gcc/cfgexpand.c:3796 -0x7f0da2cd1c30 expand_gimple_stmt - ../../../gcc/gcc/cfgexpand.c:3857 -0x7f0da2cd90a9 expand_gimple_basic_block - ../../../gcc/gcc/cfgexpand.c:5898 -0x7f0da2cdade8 execute - ../../../gcc/gcc/cfgexpand.c:6582 -``` - -To see the code which causes this error, call the following function: - -```c -gcc_jit_context_dump_to_file(ctxt, "/tmp/output.c", 1 /* update_locations */) -``` - -This will create a C-like file and add the locations into the IR pointing to this C file. -Then, rerun the program and it will output the location in the second line: - -``` -libgccjit.so: /tmp/something.c:61322:0: error: in expmed_mode_index, at expmed.h:249 -``` - -Or add a breakpoint to `add_error` in gdb and print the line number using: - -``` -p loc->m_line -p loc->m_filename->m_buffer -``` - -To print a debug representation of a tree: - -```c -debug_tree(expr); -``` - -(defined in print-tree.h) - -To print a debug reprensentation of a gimple struct: - -```c -debug_gimple_stmt(gimple_struct) -``` +## Extra documentation -To get the `rustc` command to run in `gdb`, add the `--verbose` flag to `cargo build`. +More specific documentation is available in the [`doc`](./doc) folder: -To have the correct file paths in `gdb` instead of `/usr/src/debug/gcc/libstdc++-v3/libsupc++/eh_personality.cc`: - -Maybe by calling the following at the beginning of gdb: - -``` -set substitute-path /usr/src/debug/gcc /path/to/gcc-repo/gcc -``` - -TODO(antoyo): but that's not what I remember I was doing. - -### `failed to build archive` error - -When you get this error: - -``` -error: failed to build archive: failed to open object file: No such file or directory (os error 2) -``` - -That can be caused by the fact that you try to compile with `lto = "fat"`, but you didn't compile the sysroot with LTO. -(Not sure if that's the reason since I cannot reproduce anymore. Maybe it happened when forgetting setting `FAT_LTO`.) - -### ld: cannot find crtbegin.o - -When compiling an executable with libgccijt, if setting the `*LIBRARY_PATH` variables to the install directory, you will get the following errors: - -``` -ld: cannot find crtbegin.o: No such file or directory -ld: cannot find -lgcc: No such file or directory -ld: cannot find -lgcc: No such file or directory -libgccjit.so: error: error invoking gcc driver -``` + * [Common errors](./doc/errors.md) + * [Debugging GCC LTO](./doc/debugging-gcc-lto.md) + * [Debugging libgccjit](./doc/debugging-libgccjit.md) + * [Git subtree sync](./doc/subtree.md) + * [List of useful commands](./doc/tips.md) + * [Send a patch to GCC](./doc/sending-gcc-patch.md) -To fix this, set the variables to `gcc-build/build/gcc`. - -### How to debug GCC LTO - -Run do the command with `-v -save-temps` and then extract the `lto1` line from the output and run that under the debugger. - -### How to send arguments to the GCC linker - -``` -CG_RUSTFLAGS="-Clink-args=-save-temps -v" ../cargo.sh build -``` - -### How to see the personality functions in the asm dump - -``` -CG_RUSTFLAGS="-Clink-arg=-save-temps -v -Clink-arg=-dA" ../cargo.sh build -``` - -### How to see the LLVM IR for a sysroot crate - -``` -cargo build -v --target x86_64-unknown-linux-gnu -Zbuild-std -# Take the command from the output and add --emit=llvm-ir -``` - -### To prevent the linker from unmangling symbols - -Run with: - -``` -COLLECT_NO_DEMANGLE=1 -``` - -### How to use a custom-build rustc - - * Build the stage2 compiler (`rustup toolchain link debug-current build/x86_64-unknown-linux-gnu/stage2`). - * Clean and rebuild the codegen with `debug-current` in the file `rust-toolchain`. - -### How to install a forked git-subtree - -Using git-subtree with `rustc` requires a patched git to make it work. -The PR that is needed is [here](https://github.com/gitgitgadget/git/pull/493). -Use the following instructions to install it: - -```bash -git clone git@github.com:tqc/git.git -cd git -git checkout tqc/subtree -make -make install -cd contrib/subtree -make -cp git-subtree ~/bin -``` - -Then, do a sync with this command: - -```bash -PATH="$HOME/bin:$PATH" ~/bin/git-subtree push -P compiler/rustc_codegen_gcc/ ../rustc_codegen_gcc/ sync_branch_name -cd ../rustc_codegen_gcc -git checkout master -git pull -git checkout sync_branch_name -git merge master -``` - -To send the changes to the rust repo: - -```bash -cd ../rust -git pull origin master -git checkout -b subtree-update_cg_gcc_YYYY-MM-DD -PATH="$HOME/bin:$PATH" ~/bin/git-subtree pull --prefix=compiler/rustc_codegen_gcc/ https://github.com/rust-lang/rustc_codegen_gcc.git master -git push -``` - -TODO: write a script that does the above. - -https://rust-lang.zulipchat.com/#narrow/stream/301329-t-devtools/topic/subtree.20madness/near/258877725 - -### How to use [mem-trace](https://github.com/antoyo/mem-trace) - -`rustc` needs to be built without `jemalloc` so that `mem-trace` can overload `malloc` since `jemalloc` is linked statically, so a `LD_PRELOAD`-ed library won't a chance to intercept the calls to `malloc`. - -### How to generate GIMPLE - -If you need to check what gccjit is generating (GIMPLE), then take a look at how to -generate it in [gimple.md](./doc/gimple.md). - -### How to build a cross-compiling libgccjit - -#### Building libgccjit - - * Follow the instructions on [this repo](https://github.com/cross-cg-gcc-tools/cross-gcc). - -#### Configuring rustc_codegen_gcc - - * Run `./y.sh prepare --cross` so that the sysroot is patched for the cross-compiling case. - * Set the path to the cross-compiling libgccjit in `gcc_path`. - * Make sure you have the linker for your target (for instance `m68k-unknown-linux-gnu-gcc`) in your `$PATH`. Currently, the linker name is hardcoded as being `$TARGET-gcc`. Specify the target when building the sysroot: `./y.sh build --target-triple m68k-unknown-linux-gnu`. - * Build your project by specifying the target: `OVERWRITE_TARGET_TRIPLE=m68k-unknown-linux-gnu ../cargo.sh build --target m68k-unknown-linux-gnu`. - -If the target is not yet supported by the Rust compiler, create a [target specification file](https://docs.rust-embedded.org/embedonomicon/custom-target.html) (note that the `arch` specified in this file must be supported by the rust compiler). -Then, you can use it the following way: - - * Add the target specification file using `--target` as an **absolute** path to build the sysroot: `./y.sh build --target-triple m68k-unknown-linux-gnu --target $(pwd)/m68k-unknown-linux-gnu.json` - * Build your project by specifying the target specification file: `OVERWRITE_TARGET_TRIPLE=m68k-unknown-linux-gnu ../cargo.sh build --target path/to/m68k-unknown-linux-gnu.json`. - -If you get the following error: +## Licensing -``` -/usr/bin/ld: unrecognised emulation mode: m68kelf -``` +While this crate is licensed under a dual Apache/MIT license, it links to `libgccjit` which is under the GPLv3+ and thus, the resulting toolchain (rustc + GCC codegen) will need to be released under the GPL license. -Make sure you set `gcc_path` to the install directory. +However, programs compiled with `rustc_codegen_gcc` do not need to be released under a GPL license. diff --git a/build.rs b/build.rs new file mode 100644 index 0000000000000..b93c17793bf37 --- /dev/null +++ b/build.rs @@ -0,0 +1,6 @@ +// TODO: remove this file and deps/libLLVM-18-rust-1.78.0-nightly.so when +// https://github.com/rust-lang/rust/pull/121967 is merged. +fn main() { + println!("cargo:rerun-if-changed=deps/libLLVM-18-rust-1.78.0-nightly.so"); + println!("cargo:rustc-link-search=deps"); +} diff --git a/build_sysroot/build_sysroot.sh b/build_sysroot/build_sysroot.sh deleted file mode 100755 index ebc7dc375b125..0000000000000 --- a/build_sysroot/build_sysroot.sh +++ /dev/null @@ -1,34 +0,0 @@ -#!/usr/bin/env bash - -# Requires the CHANNEL env var to be set to `debug` or `release.` - -set -e -cd $(dirname "$0") - -pushd ../ -source ./config.sh -popd - -# Cleanup for previous run -# v Clean target dir except for build scripts and incremental cache -rm -r target/*/{debug,release}/{build,deps,examples,libsysroot*,native} 2>/dev/null || true -rm Cargo.lock test_target/Cargo.lock 2>/dev/null || true -rm -r sysroot/ 2>/dev/null || true - -# Build libs -export RUSTFLAGS="$RUSTFLAGS -Z force-unstable-if-unmarked" -if [[ "$1" == "--release" ]]; then - sysroot_channel='release' - RUSTFLAGS="$RUSTFLAGS -Zmir-opt-level=3" cargo build --target $TARGET_TRIPLE --release -else - sysroot_channel='debug' - cargo build --target $TARGET_TRIPLE -fi - -# Copy files to sysroot -mkdir -p sysroot/lib/rustlib/$TARGET_TRIPLE/lib/ -cp -r target/$TARGET_TRIPLE/$sysroot_channel/deps/* sysroot/lib/rustlib/$TARGET_TRIPLE/lib/ -# Copy the source files to the sysroot (Rust for Linux needs this). -source_dir=sysroot/lib/rustlib/src/rust -mkdir -p $source_dir -cp -r sysroot_src/library/ $source_dir diff --git a/build_system/Cargo.lock b/build_system/Cargo.lock index 86268e1916030..e727561a2bfba 100644 --- a/build_system/Cargo.lock +++ b/build_system/Cargo.lock @@ -2,6 +2,15 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "boml" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85fdb93f04c73bff54305fa437ffea5449c41edcaadfe882f35836206b166ac5" + [[package]] name = "y" version = "0.1.0" +dependencies = [ + "boml", +] diff --git a/build_system/Cargo.toml b/build_system/Cargo.toml index f36709ea03605..d2600ed5a0314 100644 --- a/build_system/Cargo.toml +++ b/build_system/Cargo.toml @@ -3,6 +3,9 @@ name = "y" version = "0.1.0" edition = "2021" +[dependencies] +boml = "0.3.1" + [[bin]] name = "y" path = "src/main.rs" diff --git a/build_system/src/build.rs b/build_system/src/build.rs index f1c3701a946ec..0eabd1d897292 100644 --- a/build_system/src/build.rs +++ b/build_system/src/build.rs @@ -1,7 +1,5 @@ -use crate::config::{set_config, ConfigInfo}; -use crate::utils::{ - get_gcc_path, run_command, run_command_with_output_and_env, walk_dir, -}; +use crate::config::{Channel, ConfigInfo}; +use crate::utils::{run_command, run_command_with_output_and_env, walk_dir}; use std::collections::HashMap; use std::ffi::OsStr; use std::fs; @@ -9,33 +7,18 @@ use std::path::Path; #[derive(Default)] struct BuildArg { - codegen_release_channel: bool, - sysroot_release_channel: bool, - sysroot_panic_abort: bool, flags: Vec, - gcc_path: String, + config_info: ConfigInfo, } impl BuildArg { fn new() -> Result, String> { - let gcc_path = get_gcc_path()?; - let mut build_arg = Self { - gcc_path, - ..Default::default() - }; + let mut build_arg = Self::default(); // We skip binary name and the `build` command. let mut args = std::env::args().skip(2); while let Some(arg) = args.next() { match arg.as_str() { - "--release" => build_arg.codegen_release_channel = true, - "--release-sysroot" => build_arg.sysroot_release_channel = true, - "--no-default-features" => { - build_arg.flags.push("--no-default-features".to_string()); - } - "--sysroot-panic-abort" => { - build_arg.sysroot_panic_abort = true; - }, "--features" => { if let Some(arg) = args.next() { build_arg.flags.push("--features".to_string()); @@ -50,25 +33,11 @@ impl BuildArg { Self::usage(); return Ok(None); } - "--target-triple" => { - if args.next().is_some() { - // Handled in config.rs. - } else { - return Err( - "Expected a value after `--target-triple`, found nothing".to_string() - ); - } - } - "--target" => { - if args.next().is_some() { - // Handled in config.rs. - } else { - return Err( - "Expected a value after `--target`, found nothing".to_string() - ); + arg => { + if !build_arg.config_info.parse_argument(arg, &mut args)? { + return Err(format!("Unknown argument `{}`", arg)); } } - arg => return Err(format!("Unknown argument `{}`", arg)), } } Ok(Some(build_arg)) @@ -79,29 +48,19 @@ impl BuildArg { r#" `build` command help: - --release : Build codegen in release mode - --release-sysroot : Build sysroot in release mode - --sysroot-panic-abort : Build the sysroot without unwinding support. - --no-default-features : Add `--no-default-features` flag - --features [arg] : Add a new feature [arg] - --target-triple [arg] : Set the target triple to [arg] - --help : Show this help -"# - ) + --features [arg] : Add a new feature [arg]"# + ); + ConfigInfo::show_usage(); + println!(" --help : Show this help"); } } -fn build_sysroot( - env: &mut HashMap, - args: &BuildArg, - config: &ConfigInfo, -) -> Result<(), String> { - std::env::set_current_dir("build_sysroot") - .map_err(|error| format!("Failed to go to `build_sysroot` directory: {:?}", error))?; +pub fn build_sysroot(env: &HashMap, config: &ConfigInfo) -> Result<(), String> { + let start_dir = Path::new("build_sysroot"); // Cleanup for previous run // Clean target dir except for build scripts and incremental cache let _ = walk_dir( - "target", + start_dir.join("target"), |dir: &Path| { for top in &["debug", "release"] { let _ = fs::remove_dir_all(dir.join(top).join("build")); @@ -138,92 +97,114 @@ fn build_sysroot( |_| Ok(()), ); - let _ = fs::remove_file("Cargo.lock"); - let _ = fs::remove_file("test_target/Cargo.lock"); - let _ = fs::remove_dir_all("sysroot"); + let _ = fs::remove_file(start_dir.join("Cargo.lock")); + let _ = fs::remove_file(start_dir.join("test_target/Cargo.lock")); + let _ = fs::remove_dir_all(start_dir.join("sysroot")); // Builds libs - let mut rustflags = env - .get("RUSTFLAGS") - .cloned() - .unwrap_or_default(); - if args.sysroot_panic_abort { + let mut rustflags = env.get("RUSTFLAGS").cloned().unwrap_or_default(); + if config.sysroot_panic_abort { rustflags.push_str(" -Cpanic=abort -Zpanic-abort-tests"); } - env.insert( - "RUSTFLAGS".to_string(), - format!("{} -Zmir-opt-level=3", rustflags), - ); - let channel = if args.sysroot_release_channel { - run_command_with_output_and_env( - &[ - &"cargo", - &"build", - &"--target", - &config.target, - &"--release", - ], - None, - Some(&env), - )?; + rustflags.push_str(" -Z force-unstable-if-unmarked"); + let mut env = env.clone(); + + let mut args: Vec<&dyn AsRef> = vec![&"cargo", &"build", &"--target", &config.target]; + + if config.no_default_features { + rustflags.push_str(" -Csymbol-mangling-version=v0"); + args.push(&"--no-default-features"); + } + + let channel = if config.sysroot_release_channel { + rustflags.push_str(" -Zmir-opt-level=3"); + args.push(&"--release"); "release" } else { - run_command_with_output_and_env( - &[ - &"cargo", - &"build", - &"--target", - &config.target, - ], - None, - Some(env), - )?; "debug" }; + env.insert("RUSTFLAGS".to_string(), rustflags); + run_command_with_output_and_env(&args, Some(start_dir), Some(&env))?; + // Copy files to sysroot - let sysroot_path = format!("sysroot/lib/rustlib/{}/lib/", config.target_triple); - fs::create_dir_all(&sysroot_path) - .map_err(|error| format!("Failed to create directory `{}`: {:?}", sysroot_path, error))?; + let sysroot_path = start_dir.join(format!("sysroot/lib/rustlib/{}/lib/", config.target_triple)); + fs::create_dir_all(&sysroot_path).map_err(|error| { + format!( + "Failed to create directory `{}`: {:?}", + sysroot_path.display(), + error + ) + })?; let copier = |dir_to_copy: &Path| { + // FIXME: should not use shell command! run_command(&[&"cp", &"-r", &dir_to_copy, &sysroot_path], None).map(|_| ()) }; walk_dir( - &format!("target/{}/{}/deps", config.target_triple, channel), + start_dir.join(&format!("target/{}/{}/deps", config.target_triple, channel)), copier, copier, )?; // Copy the source files to the sysroot (Rust for Linux needs this). - let sysroot_src_path = "sysroot/lib/rustlib/src/rust"; - fs::create_dir_all(&sysroot_src_path) - .map_err(|error| format!("Failed to create directory `{}`: {:?}", sysroot_src_path, error))?; - run_command(&[&"cp", &"-r", &"sysroot_src/library/", &sysroot_src_path], None)?; + let sysroot_src_path = start_dir.join("sysroot/lib/rustlib/src/rust"); + fs::create_dir_all(&sysroot_src_path).map_err(|error| { + format!( + "Failed to create directory `{}`: {:?}", + sysroot_src_path.display(), + error + ) + })?; + run_command( + &[ + &"cp", + &"-r", + &start_dir.join("sysroot_src/library/"), + &sysroot_src_path, + ], + None, + )?; Ok(()) } -fn build_codegen(args: &BuildArg) -> Result<(), String> { +fn build_codegen(args: &mut BuildArg) -> Result<(), String> { let mut env = HashMap::new(); - env.insert("LD_LIBRARY_PATH".to_string(), args.gcc_path.clone()); - env.insert("LIBRARY_PATH".to_string(), args.gcc_path.clone()); + 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(), + ); + + if args.config_info.no_default_features { + env.insert( + "RUSTFLAGS".to_string(), + "-Csymbol-mangling-version=v0".to_string(), + ); + } let mut command: Vec<&dyn AsRef> = vec![&"cargo", &"rustc"]; - if args.codegen_release_channel { + if args.config_info.channel == Channel::Release { command.push(&"--release"); env.insert("CHANNEL".to_string(), "release".to_string()); env.insert("CARGO_INCREMENTAL".to_string(), "1".to_string()); } else { env.insert("CHANNEL".to_string(), "debug".to_string()); } + if args.config_info.no_default_features { + command.push(&"--no-default-features"); + } let flags = args.flags.iter().map(|s| s.as_str()).collect::>(); for flag in &flags { command.push(flag); } run_command_with_output_and_env(&command, None, Some(&env))?; - let config = set_config(&mut env, &[], Some(&args.gcc_path))?; + args.config_info.setup(&mut env, false)?; // We voluntarily ignore the error. let _ = fs::remove_dir_all("target/out"); @@ -236,19 +217,16 @@ fn build_codegen(args: &BuildArg) -> Result<(), String> { })?; println!("[BUILD] sysroot"); - build_sysroot( - &mut env, - args, - &config, - )?; + build_sysroot(&env, &args.config_info)?; Ok(()) } pub fn run() -> Result<(), String> { - let args = match BuildArg::new()? { + let mut args = match BuildArg::new()? { Some(args) => args, None => return Ok(()), }; - build_codegen(&args)?; + args.config_info.setup_gcc_path()?; + build_codegen(&mut args)?; Ok(()) } diff --git a/build_system/src/cargo.rs b/build_system/src/cargo.rs new file mode 100644 index 0000000000000..1cfcdba6b1cd1 --- /dev/null +++ b/build_system/src/cargo.rs @@ -0,0 +1,114 @@ +use crate::config::ConfigInfo; +use crate::utils::{ + get_toolchain, run_command_with_output_and_env_no_err, rustc_toolchain_version_info, + rustc_version_info, +}; + +use std::collections::HashMap; +use std::ffi::OsStr; +use std::path::PathBuf; + +fn args() -> Result>, String> { + // We skip the binary and the "cargo" option. + if let Some("--help") = std::env::args().skip(2).next().as_deref() { + usage(); + return Ok(None); + } + let args = std::env::args().skip(2).collect::>(); + if args.is_empty() { + return Err( + "Expected at least one argument for `cargo` subcommand, found none".to_string(), + ); + } + Ok(Some(args)) +} + +fn usage() { + println!( + r#" +`cargo` command help: + + [args] : Arguments to be passed to the cargo command + --help : Show this help +"# + ) +} + +pub fn run() -> Result<(), String> { + let args = match args()? { + Some(a) => a, + None => return Ok(()), + }; + + // We first need to go to the original location to ensure that the config setup will go as + // expected. + let current_dir = std::env::current_dir() + .and_then(|path| path.canonicalize()) + .map_err(|error| format!("Failed to get current directory path: {:?}", error))?; + let current_exe = std::env::current_exe() + .and_then(|path| path.canonicalize()) + .map_err(|error| format!("Failed to get current exe path: {:?}", error))?; + let mut parent_dir = current_exe + .components() + .map(|comp| comp.as_os_str()) + .collect::>(); + // We run this script from "build_system/target/release/y", so we need to remove these elements. + for to_remove in &["y", "release", "target", "build_system"] { + if parent_dir + .last() + .map(|part| part == to_remove) + .unwrap_or(false) + { + parent_dir.pop(); + } else { + return Err(format!( + "Build script not executed from `build_system/target/release/y` (in path {})", + current_exe.display(), + )); + } + } + let parent_dir = PathBuf::from(parent_dir.join(&OsStr::new("/"))); + std::env::set_current_dir(&parent_dir).map_err(|error| { + format!( + "Failed to go to `{}` folder: {:?}", + parent_dir.display(), + error + ) + })?; + + let mut env: HashMap = std::env::vars().collect(); + ConfigInfo::default().setup(&mut env, false)?; + let toolchain = get_toolchain()?; + + let toolchain_version = rustc_toolchain_version_info(&toolchain)?; + let default_version = rustc_version_info(None)?; + if toolchain_version != default_version { + println!( + "rustc_codegen_gcc is built for {} but the default rustc version is {}.", + toolchain_version.short, default_version.short, + ); + println!("Using {}.", toolchain_version.short); + } + + // We go back to the original folder since we now have set up everything we needed. + std::env::set_current_dir(¤t_dir).map_err(|error| { + format!( + "Failed to go back to `{}` folder: {:?}", + current_dir.display(), + error + ) + })?; + + let rustflags = env.get("RUSTFLAGS").cloned().unwrap_or_default(); + env.insert("RUSTDOCFLAGS".to_string(), rustflags); + let toolchain = format!("+{}", toolchain); + let mut command: Vec<&dyn AsRef> = vec![&"cargo", &toolchain]; + for arg in &args { + command.push(arg); + } + if run_command_with_output_and_env_no_err(&command, None, Some(&env)).is_err() { + std::process::exit(1); + } + + Ok(()) +} diff --git a/build_system/src/clean.rs b/build_system/src/clean.rs new file mode 100644 index 0000000000000..cd8e691a0ed9f --- /dev/null +++ b/build_system/src/clean.rs @@ -0,0 +1,82 @@ +use crate::utils::{remove_file, run_command}; + +use std::fs::remove_dir_all; +use std::path::Path; + +#[derive(Default)] +enum CleanArg { + /// `clean all` + All, + /// `clean ui-tests` + UiTests, + /// `clean --help` + #[default] + Help, +} + +impl CleanArg { + fn new() -> Result { + // We skip the binary and the "clean" option. + for arg in std::env::args().skip(2) { + return match arg.as_str() { + "all" => Ok(Self::All), + "ui-tests" => Ok(Self::UiTests), + "--help" => Ok(Self::Help), + a => Err(format!("Unknown argument `{}`", a)), + }; + } + Ok(Self::default()) + } +} + +fn usage() { + println!( + r#" +`clean` command help: + + all : Clean all data + ui-tests : Clean ui tests + --help : Show this help +"# + ) +} + +fn clean_all() -> Result<(), String> { + let dirs_to_remove = [ + "target", + "build_sysroot/sysroot", + "build_sysroot/sysroot_src", + "build_sysroot/target", + ]; + for dir in dirs_to_remove { + let _ = remove_dir_all(dir); + } + let dirs_to_remove = ["regex", "rand", "simple-raytracer"]; + for dir in dirs_to_remove { + let _ = remove_dir_all(Path::new(crate::BUILD_DIR).join(dir)); + } + + let files_to_remove = ["build_sysroot/Cargo.lock", "perf.data", "perf.data.old"]; + + for file in files_to_remove { + let _ = remove_file(file); + } + + println!("Successfully ran `clean all`"); + Ok(()) +} + +fn clean_ui_tests() -> Result<(), String> { + let path = Path::new(crate::BUILD_DIR).join("rust/build/x86_64-unknown-linux-gnu/test/ui/"); + run_command(&[&"find", &path, &"-name", &"stamp", &"-delete"], None)?; + Ok(()) +} + +pub fn run() -> Result<(), String> { + match CleanArg::new()? { + CleanArg::All => clean_all()?, + CleanArg::UiTests => clean_ui_tests()?, + CleanArg::Help => usage(), + } + Ok(()) +} diff --git a/build_system/src/clone_gcc.rs b/build_system/src/clone_gcc.rs new file mode 100644 index 0000000000000..aee46afaeb040 --- /dev/null +++ b/build_system/src/clone_gcc.rs @@ -0,0 +1,79 @@ +use crate::config::ConfigInfo; +use crate::utils::{git_clone, run_command_with_output}; + +use std::path::{Path, PathBuf}; + +fn show_usage() { + println!( + r#" +`clone-gcc` command help: + + --out-path : Location where the GCC repository will be cloned (default: `./gcc`)"# + ); + ConfigInfo::show_usage(); + println!(" --help : Show this help"); +} + +#[derive(Default)] +struct Args { + out_path: PathBuf, + config_info: ConfigInfo, +} + +impl Args { + fn new() -> Result, String> { + let mut command_args = Self::default(); + + let mut out_path = None; + + // We skip binary name and the `clone-gcc` command. + let mut args = std::env::args().skip(2); + + while let Some(arg) = args.next() { + match arg.as_str() { + "--out-path" => match args.next() { + Some(path) if !path.is_empty() => out_path = Some(path), + _ => { + return Err("Expected an argument after `--out-path`, found nothing".into()) + } + }, + "--help" => { + show_usage(); + return Ok(None); + } + arg => { + if !command_args.config_info.parse_argument(arg, &mut args)? { + return Err(format!("Unknown option {}", arg)); + } + } + } + } + command_args.out_path = match out_path { + Some(p) => p.into(), + None => PathBuf::from("./gcc"), + }; + return Ok(Some(command_args)); + } +} + +pub fn run() -> Result<(), String> { + let Some(args) = Args::new()? else { + return Ok(()); + }; + + let result = git_clone("https://github.com/antoyo/gcc", Some(&args.out_path), false)?; + if result.ran_clone { + let gcc_commit = args.config_info.get_gcc_commit()?; + println!("Checking out GCC commit `{}`...", gcc_commit); + run_command_with_output( + &[&"git", &"checkout", &gcc_commit], + Some(Path::new(&result.repo_dir)), + )?; + } else { + println!( + "There is already a GCC folder in `{}`, leaving things as is...", + args.out_path.display() + ); + } + Ok(()) +} diff --git a/build_system/src/config.rs b/build_system/src/config.rs index 64d9bd73e01a3..c633ee57d4a34 100644 --- a/build_system/src/config.rs +++ b/build_system/src/config.rs @@ -1,149 +1,560 @@ -use crate::utils::{get_gcc_path, get_os_name, get_rustc_host_triple}; +use crate::utils::{ + create_symlink, get_os_name, run_command_with_output, rustc_version_info, split_args, +}; use std::collections::HashMap; use std::env as std_env; +use std::ffi::OsStr; +use std::fs; +use std::path::{Path, PathBuf}; +use boml::{types::TomlValue, Toml}; + +#[derive(Default, PartialEq, Eq, Clone, Copy, Debug)] +pub enum Channel { + #[default] + Debug, + Release, +} + +impl Channel { + pub fn as_str(self) -> &'static str { + match self { + Self::Debug => "debug", + Self::Release => "release", + } + } +} + +fn failed_config_parsing(config_file: &Path, err: &str) -> Result { + Err(format!( + "Failed to parse `{}`: {}", + config_file.display(), + err + )) +} + +#[derive(Default)] +pub struct ConfigFile { + gcc_path: Option, + download_gccjit: Option, +} + +impl ConfigFile { + pub fn new(config_file: &Path) -> Result { + let content = fs::read_to_string(config_file).map_err(|_| { + format!( + "Failed to read `{}`. Take a look at `Readme.md` to see how to set up the project", + config_file.display(), + ) + })?; + let toml = Toml::parse(&content).map_err(|err| { + format!( + "Error occurred around `{}`: {:?}", + &content[err.start..=err.end], + err.kind + ) + })?; + let mut config = Self::default(); + for (key, value) in toml.iter() { + match (key, value) { + ("gcc-path", TomlValue::String(value)) => { + config.gcc_path = Some(value.as_str().to_string()) + } + ("gcc-path", _) => { + return failed_config_parsing(config_file, "Expected a string for `gcc-path`") + } + ("download-gccjit", TomlValue::Boolean(value)) => { + config.download_gccjit = Some(*value) + } + ("download-gccjit", _) => { + return failed_config_parsing( + config_file, + "Expected a boolean for `download-gccjit`", + ) + } + _ => return failed_config_parsing(config_file, &format!("Unknown key `{}`", key)), + } + } + match (config.gcc_path.as_mut(), config.download_gccjit) { + (None, None | Some(false)) => { + return failed_config_parsing( + config_file, + "At least one of `gcc-path` or `download-gccjit` value must be set", + ) + } + (Some(_), Some(true)) => { + println!( + "WARNING: both `gcc-path` and `download-gccjit` arguments are used, \ + ignoring `gcc-path`" + ); + } + (Some(gcc_path), _) => { + let path = Path::new(gcc_path); + *gcc_path = path + .canonicalize() + .map_err(|err| { + format!("Failed to get absolute path of `{}`: {:?}", gcc_path, err) + })? + .display() + .to_string(); + } + _ => {} + } + Ok(config) + } +} + +#[derive(Default, Debug)] pub struct ConfigInfo { pub target: String, pub target_triple: String, + pub host_triple: String, pub rustc_command: Vec, + pub run_in_vm: bool, + pub cargo_target_dir: String, + pub dylib_ext: String, + pub sysroot_release_channel: bool, + pub channel: Channel, + pub sysroot_panic_abort: bool, + pub cg_backend_path: String, + pub sysroot_path: String, + pub gcc_path: String, + 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 + // like `libgccjit.version` or `config.toml`. + cg_gcc_path: Option, + // Needed for the `info` command which doesn't want to actually download the lib if needed, + // just to set the `gcc_path` field to display it. + pub no_download: bool, + pub no_default_features: bool, } -// Returns the beginning for the command line of rustc. -pub fn set_config( - env: &mut HashMap, - test_flags: &[String], - gcc_path: Option<&str>, -) -> Result { - env.insert("CARGO_INCREMENTAL".to_string(), "0".to_string()); - - let gcc_path = match gcc_path { - Some(path) => path.to_string(), - None => get_gcc_path()?, - }; - env.insert("GCC_PATH".to_string(), gcc_path.clone()); - - let os_name = get_os_name()?; - let dylib_ext = match os_name.as_str() { - "Linux" => "so", - "Darwin" => "dylib", - os => return Err(format!("unsupported OS `{}`", os)), - }; - let host_triple = get_rustc_host_triple()?; - let mut linker = None; - let mut target_triple = host_triple.clone(); - let mut target = target_triple.clone(); - - // We skip binary name and the command. - let mut args = std::env::args().skip(2); - - let mut set_target_triple = false; - let mut set_target = false; - while let Some(arg) = args.next() { - match arg.as_str() { - "--target-triple" => { +impl ConfigInfo { + /// Returns `true` if the argument was taken into account. + pub fn parse_argument( + &mut self, + arg: &str, + args: &mut impl Iterator, + ) -> Result { + match arg { + "--target" => { if let Some(arg) = args.next() { - target_triple = arg; - set_target_triple = true; + self.target = arg; } else { + return Err("Expected a value after `--target`, found nothing".to_string()); + } + } + "--target-triple" => match args.next() { + Some(arg) if !arg.is_empty() => self.target_triple = arg.to_string(), + _ => { return Err( "Expected a value after `--target-triple`, found nothing".to_string() - ); + ) } }, - "--target" => { - if let Some(arg) = args.next() { - target = arg; - set_target = true; - } else { - return Err( - "Expected a value after `--target`, found nothing".to_string() - ); + "--out-dir" => match args.next() { + Some(arg) if !arg.is_empty() => { + self.cargo_target_dir = arg.to_string(); + } + _ => return Err("Expected a value after `--out-dir`, found nothing".to_string()), + }, + "--config-file" => match args.next() { + Some(arg) if !arg.is_empty() => { + self.config_file = Some(arg.to_string()); + } + _ => { + return Err("Expected a value after `--config-file`, found nothing".to_string()) } }, - _ => (), + "--release-sysroot" => self.sysroot_release_channel = true, + "--release" => self.channel = Channel::Release, + "--sysroot-panic-abort" => self.sysroot_panic_abort = true, + "--cg_gcc-path" => match args.next() { + Some(arg) if !arg.is_empty() => { + self.cg_gcc_path = Some(arg.into()); + } + _ => { + return Err("Expected a value after `--cg_gcc-path`, found nothing".to_string()) + } + }, + "--no-default-features" => self.no_default_features = true, + _ => return Ok(false), } + Ok(true) } - if set_target_triple && !set_target { - target = target_triple.clone(); + pub fn rustc_command_vec(&self) -> Vec<&dyn AsRef> { + let mut command: Vec<&dyn AsRef> = Vec::with_capacity(self.rustc_command.len()); + for arg in self.rustc_command.iter() { + command.push(arg); + } + command } - if host_triple != target_triple { - linker = Some(format!("-Clinker={}-gcc", target_triple)); + pub fn get_gcc_commit(&self) -> Result { + let commit_hash_file = self.compute_path("libgccjit.version"); + let content = fs::read_to_string(&commit_hash_file).map_err(|_| { + format!( + "Failed to read `{}`. Take a look at `Readme.md` to see how to set up the project", + commit_hash_file.display(), + ) + })?; + let commit = content.trim(); + // This is a very simple check to ensure this is not a path. For the rest, it'll just fail + // when trying to download the file so we should be fine. + if commit.contains('/') || commit.contains('\\') { + return Err(format!( + "{}: invalid commit hash `{}`", + commit_hash_file.display(), + commit, + )); + } + Ok(commit.to_string()) } - let current_dir = - std_env::current_dir().map_err(|error| format!("`current_dir` failed: {:?}", error))?; - let channel = if let Some(channel) = env.get("CHANNEL") { - channel.as_str() - } else { - "debug" - }; - let cg_backend_path = current_dir - .join("target") - .join(channel) - .join(&format!("librustc_codegen_gcc.{}", dylib_ext)); - let sysroot_path = current_dir.join("build_sysroot/sysroot"); - let mut rustflags = Vec::new(); - if let Some(cg_rustflags) = env.get("CG_RUSTFLAGS") { - rustflags.push(cg_rustflags.clone()); + + fn download_gccjit_if_needed(&mut self) -> Result<(), String> { + let output_dir = Path::new(crate::BUILD_DIR).join("libgccjit"); + let commit = self.get_gcc_commit()?; + + let output_dir = output_dir.join(&commit); + if !output_dir.is_dir() { + std::fs::create_dir_all(&output_dir).map_err(|err| { + format!( + "failed to create folder `{}`: {:?}", + output_dir.display(), + err, + ) + })?; + } + let output_dir = output_dir.canonicalize().map_err(|err| { + format!( + "Failed to get absolute path of `{}`: {:?}", + output_dir.display(), + err + ) + })?; + + let libgccjit_so_name = "libgccjit.so"; + let libgccjit_so = output_dir.join(libgccjit_so_name); + if !libgccjit_so.is_file() && !self.no_download { + // Download time! + let tempfile_name = format!("{}.download", libgccjit_so_name); + let tempfile = output_dir.join(&tempfile_name); + let is_in_ci = std::env::var("GITHUB_ACTIONS").is_ok(); + + let url = format!( + "https://github.com/antoyo/gcc/releases/download/master-{}/libgccjit.so", + commit, + ); + + println!("Downloading `{}`...", url); + download_gccjit(url, &output_dir, tempfile_name, !is_in_ci)?; + + let libgccjit_so = output_dir.join(libgccjit_so_name); + // If we reach this point, it means the file was correctly downloaded, so let's + // rename it! + std::fs::rename(&tempfile, &libgccjit_so).map_err(|err| { + format!( + "Failed to rename `{}` into `{}`: {:?}", + tempfile.display(), + libgccjit_so.display(), + err, + ) + })?; + + println!("Downloaded libgccjit.so version {} successfully!", commit); + // We need to create a link named `libgccjit.so.0` because that's what the linker is + // looking for. + 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); + Ok(()) } - if let Some(linker) = linker { - rustflags.push(linker.to_string()); + + pub fn compute_path>(&self, other: P) -> PathBuf { + match self.cg_gcc_path { + Some(ref path) => path.join(other), + None => PathBuf::new().join(other), + } } - rustflags.extend_from_slice(&[ - "-Csymbol-mangling-version=v0".to_string(), - "-Cdebuginfo=2".to_string(), - format!("-Zcodegen-backend={}", cg_backend_path.display()), - "--sysroot".to_string(), - sysroot_path.display().to_string(), - ]); - - // Since we don't support ThinLTO, disable LTO completely when not trying to do LTO. - // TODO(antoyo): remove when we can handle ThinLTO. - if !env.contains_key(&"FAT_LTO".to_string()) { - rustflags.push("-Clto=off".to_string()); + + pub fn setup_gcc_path(&mut self) -> Result<(), String> { + let config_file = match self.config_file.as_deref() { + Some(config_file) => config_file.into(), + None => self.compute_path("config.toml"), + }; + let ConfigFile { + gcc_path, + download_gccjit, + } = ConfigFile::new(&config_file)?; + + if let Some(true) = download_gccjit { + 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(), + )) + } + }; + Ok(()) } - rustflags.extend_from_slice(test_flags); - // FIXME(antoyo): remove once the atomic shim is gone - if os_name == "Darwin" { + + pub fn setup( + &mut self, + env: &mut HashMap, + use_system_gcc: bool, + ) -> Result<(), String> { + env.insert("CARGO_INCREMENTAL".to_string(), "0".to_string()); + + if self.gcc_path.is_empty() && !use_system_gcc { + self.setup_gcc_path()?; + } + env.insert("GCC_PATH".to_string(), self.gcc_path.clone()); + + if self.cargo_target_dir.is_empty() { + match env.get("CARGO_TARGET_DIR").filter(|dir| !dir.is_empty()) { + Some(cargo_target_dir) => self.cargo_target_dir = cargo_target_dir.clone(), + None => self.cargo_target_dir = "target/out".to_string(), + } + } + + let os_name = get_os_name()?; + self.dylib_ext = match os_name.as_str() { + "Linux" => "so", + "Darwin" => "dylib", + os => return Err(format!("unsupported OS `{}`", os)), + } + .to_string(); + let rustc = match env.get("RUSTC") { + Some(r) if !r.is_empty() => r.to_string(), + _ => "rustc".to_string(), + }; + self.host_triple = match rustc_version_info(Some(&rustc))?.host { + Some(host) => host, + None => return Err("no host found".to_string()), + }; + + if self.target_triple.is_empty() { + if let Some(overwrite) = env.get("OVERWRITE_TARGET_TRIPLE") { + self.target_triple = overwrite.clone(); + } + } + if self.target_triple.is_empty() { + self.target_triple = self.host_triple.clone(); + } + if self.target.is_empty() && !self.target_triple.is_empty() { + self.target = self.target_triple.clone(); + } + + let mut linker = None; + + if self.host_triple != self.target_triple { + if self.target_triple.is_empty() { + return Err("Unknown non-native platform".to_string()); + } + linker = Some(format!("-Clinker={}-gcc", self.target_triple)); + self.run_in_vm = true; + } + + let current_dir = + std_env::current_dir().map_err(|error| format!("`current_dir` failed: {:?}", error))?; + let channel = if self.channel == Channel::Release { + "release" + } else if let Some(channel) = env.get("CHANNEL") { + channel.as_str() + } else { + "debug" + }; + + let has_builtin_backend = env + .get("BUILTIN_BACKEND") + .map(|backend| !backend.is_empty()) + .unwrap_or(false); + + let mut rustflags = Vec::new(); + if has_builtin_backend { + // It means we're building inside the rustc testsuite, so some options need to be handled + // a bit differently. + self.cg_backend_path = "gcc".to_string(); + + match env.get("RUSTC_SYSROOT") { + Some(rustc_sysroot) if !rustc_sysroot.is_empty() => { + rustflags.extend_from_slice(&["--sysroot".to_string(), rustc_sysroot.clone()]); + } + _ => {} + } + // This should not be needed, but is necessary for the CI in the rust repository. + // FIXME: Remove when the rust CI switches to the master version of libgccjit. + rustflags.push("-Cpanic=abort".to_string()); + } else { + self.cg_backend_path = current_dir + .join("target") + .join(channel) + .join(&format!("librustc_codegen_gcc.{}", self.dylib_ext)) + .display() + .to_string(); + self.sysroot_path = current_dir + .join("build_sysroot/sysroot") + .display() + .to_string(); + rustflags.extend_from_slice(&["--sysroot".to_string(), self.sysroot_path.clone()]); + }; + + // This environment variable is useful in case we want to change options of rustc commands. + if let Some(cg_rustflags) = env.get("CG_RUSTFLAGS") { + rustflags.extend_from_slice(&split_args(&cg_rustflags)?); + } + if let Some(test_flags) = env.get("TEST_FLAGS") { + rustflags.extend_from_slice(&split_args(&test_flags)?); + } + + if let Some(linker) = linker { + rustflags.push(linker.to_string()); + } + + if self.no_default_features { + rustflags.push("-Csymbol-mangling-version=v0".to_string()); + } + rustflags.extend_from_slice(&[ - "-Clink-arg=-undefined".to_string(), - "-Clink-arg=dynamic_lookup".to_string(), + "-Cdebuginfo=2".to_string(), + format!("-Zcodegen-backend={}", self.cg_backend_path), + ]); + + // Since we don't support ThinLTO, disable LTO completely when not trying to do LTO. + // TODO(antoyo): remove when we can handle ThinLTO. + if !env.contains_key(&"FAT_LTO".to_string()) { + rustflags.push("-Clto=off".to_string()); + } + // FIXME(antoyo): remove once the atomic shim is gone + if os_name == "Darwin" { + rustflags.extend_from_slice(&[ + "-Clink-arg=-undefined".to_string(), + "-Clink-arg=dynamic_lookup".to_string(), + ]); + } + env.insert("RUSTFLAGS".to_string(), rustflags.join(" ")); + // display metadata load errors + env.insert("RUSTC_LOG".to_string(), "warn".to_string()); + + let sysroot = current_dir.join(&format!( + "build_sysroot/sysroot/lib/rustlib/{}/lib", + self.target_triple, + )); + let ld_library_path = format!( + "{target}:{sysroot}:{gcc_path}", + // FIXME: It's possible to pick another out directory. Would be nice to have a command + // line option to change it. + target = current_dir.join("target/out").display(), + sysroot = sysroot.display(), + gcc_path = self.gcc_path, + ); + env.insert("LIBRARY_PATH".to_string(), ld_library_path.clone()); + env.insert("LD_LIBRARY_PATH".to_string(), ld_library_path.clone()); + env.insert("DYLD_LIBRARY_PATH".to_string(), ld_library_path); + + // NOTE: To avoid the -fno-inline errors, use /opt/gcc/bin/gcc instead of cc. + // To do so, add a symlink for cc to /opt/gcc/bin/gcc in our PATH. + // Another option would be to add the following Rust flag: -Clinker=/opt/gcc/bin/gcc + let path = std::env::var("PATH").unwrap_or_default(); + env.insert( + "PATH".to_string(), + format!( + "/opt/gcc/bin:/opt/m68k-unknown-linux-gnu/bin{}{}", + if path.is_empty() { "" } else { ":" }, + path + ), + ); + + self.rustc_command = vec![rustc]; + self.rustc_command.extend_from_slice(&rustflags); + self.rustc_command.extend_from_slice(&[ + "-L".to_string(), + "crate=target/out".to_string(), + "--out-dir".to_string(), + self.cargo_target_dir.clone(), ]); + + if !env.contains_key("RUSTC_LOG") { + env.insert("RUSTC_LOG".to_string(), "warn".to_string()); + } + Ok(()) } - env.insert("RUSTFLAGS".to_string(), rustflags.join(" ")); - // display metadata load errors - env.insert("RUSTC_LOG".to_string(), "warn".to_string()); - - let sysroot = current_dir.join(&format!( - "build_sysroot/sysroot/lib/rustlib/{}/lib", - target_triple - )); - let ld_library_path = format!( - "{target}:{sysroot}:{gcc_path}", - target = current_dir.join("target/out").display(), - sysroot = sysroot.display(), + + pub fn show_usage() { + println!( + "\ + --target-triple [arg] : Set the target triple to [arg] + --target [arg] : Set the target to [arg] + --out-dir : Location where the files will be generated + --release : Build in release mode + --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 + --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" + ); + } +} + +fn download_gccjit( + url: String, + output_dir: &Path, + tempfile_name: String, + with_progress_bar: bool, +) -> Result<(), String> { + // Try curl. If that fails and we are on windows, fallback to PowerShell. + let mut ret = run_command_with_output( + &[ + &"curl", + &"--speed-time", + &"30", + &"--speed-limit", + &"10", // timeout if speed is < 10 bytes/sec for > 30 seconds + &"--connect-timeout", + &"30", // timeout if cannot connect within 30 seconds + &"-o", + &tempfile_name, + &"--retry", + &"3", + &"-SRfL", + if with_progress_bar { + &"--progress-bar" + } else { + &"-s" + }, + &url.as_str(), + ], + Some(&output_dir), ); - env.insert("LD_LIBRARY_PATH".to_string(), ld_library_path.clone()); - env.insert("DYLD_LIBRARY_PATH".to_string(), ld_library_path); - - // NOTE: To avoid the -fno-inline errors, use /opt/gcc/bin/gcc instead of cc. - // To do so, add a symlink for cc to /opt/gcc/bin/gcc in our PATH. - // Another option would be to add the following Rust flag: -Clinker=/opt/gcc/bin/gcc - let path = std::env::var("PATH").unwrap_or_default(); - env.insert("PATH".to_string(), format!("/opt/gcc/bin:{}", path)); - - let mut rustc_command = vec!["rustc".to_string()]; - rustc_command.extend_from_slice(&rustflags); - rustc_command.extend_from_slice(&[ - "-L".to_string(), - "crate=target/out".to_string(), - "--out-dir".to_string(), - "target/out".to_string(), - ]); - Ok(ConfigInfo { - target, - target_triple, - rustc_command, - }) + if ret.is_err() && cfg!(windows) { + eprintln!("Fallback to PowerShell"); + ret = run_command_with_output( + &[ + &"PowerShell.exe", + &"/nologo", + &"-Command", + &"[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12;", + &format!( + "(New-Object System.Net.WebClient).DownloadFile('{}', '{}')", + url, tempfile_name, + ) + .as_str(), + ], + Some(&output_dir), + ); + } + ret } diff --git a/build_system/src/info.rs b/build_system/src/info.rs new file mode 100644 index 0000000000000..ea38791d38c9a --- /dev/null +++ b/build_system/src/info.rs @@ -0,0 +1,19 @@ +use crate::config::ConfigInfo; + +pub fn run() -> Result<(), String> { + let mut config = ConfigInfo::default(); + + // We skip binary name and the `info` command. + let mut args = std::env::args().skip(2); + while let Some(arg) = args.next() { + if arg == "--help" { + println!("Display the path where the libgccjit will be located"); + return Ok(()); + } + config.parse_argument(&arg, &mut args)?; + } + config.no_download = true; + config.setup_gcc_path()?; + println!("{}", config.gcc_path); + Ok(()) +} diff --git a/build_system/src/main.rs b/build_system/src/main.rs index bff82b6e3e57d..48ffbc7a9075a 100644 --- a/build_system/src/main.rs +++ b/build_system/src/main.rs @@ -2,12 +2,18 @@ use std::env; use std::process; mod build; +mod cargo; +mod clean; +mod clone_gcc; mod config; +mod info; mod prepare; mod rustc_info; mod test; mod utils; +const BUILD_DIR: &str = "build"; + macro_rules! arg_error { ($($err:tt)*) => {{ eprintln!($($err)*); @@ -22,17 +28,25 @@ fn usage() { "\ Available commands for build_system: - prepare : Run prepare command - build : Run build command - test : Run test command - --help : Show this message" + cargo : Run cargo command + clean : Run clean command + prepare : Run prepare command + build : Run build command + test : Run test command + info : Run info command + clone-gcc : Run clone-gcc command + --help : Show this message" ); } pub enum Command { + Cargo, + Clean, + CloneGcc, Prepare, Build, Test, + Info, } fn main() { @@ -41,9 +55,13 @@ fn main() { } let command = match env::args().nth(1).as_deref() { + Some("cargo") => Command::Cargo, + Some("clean") => Command::Clean, Some("prepare") => Command::Prepare, Some("build") => Command::Build, Some("test") => Command::Test, + Some("info") => Command::Info, + Some("clone-gcc") => Command::CloneGcc, Some("--help") => { usage(); process::exit(0); @@ -57,11 +75,15 @@ fn main() { }; if let Err(e) = match command { + Command::Cargo => cargo::run(), + Command::Clean => clean::run(), Command::Prepare => prepare::run(), Command::Build => build::run(), Command::Test => test::run(), + Command::Info => info::run(), + Command::CloneGcc => clone_gcc::run(), } { - eprintln!("Command failed to run: {e:?}"); + eprintln!("Command failed to run: {e}"); process::exit(1); } } diff --git a/build_system/src/prepare.rs b/build_system/src/prepare.rs index 6c7c858683456..821c793c7e554 100644 --- a/build_system/src/prepare.rs +++ b/build_system/src/prepare.rs @@ -1,10 +1,16 @@ use crate::rustc_info::get_rustc_path; -use crate::utils::{cargo_install, git_clone, run_command, run_command_with_output, walk_dir}; +use crate::utils::{ + cargo_install, git_clone_root_dir, remove_file, run_command, run_command_with_output, walk_dir, +}; use std::fs; use std::path::Path; -fn prepare_libcore(sysroot_path: &Path, libgccjit12_patches: bool, cross_compile: bool) -> Result<(), String> { +fn prepare_libcore( + sysroot_path: &Path, + libgccjit12_patches: bool, + cross_compile: bool, +) -> Result<(), String> { let rustc_path = match get_rustc_path() { Some(path) => path, None => return Err("`rustc` path not found".to_string()), @@ -88,10 +94,14 @@ fn prepare_libcore(sysroot_path: &Path, libgccjit12_patches: bool, cross_compile }, )?; if cross_compile { - walk_dir("cross_patches", |_| Ok(()), |file_path: &Path| { - patches.push(file_path.to_path_buf()); - Ok(()) - })?; + walk_dir( + "patches/cross_patches", + |_| Ok(()), + |file_path: &Path| { + patches.push(file_path.to_path_buf()); + Ok(()) + }, + )?; } if libgccjit12_patches { walk_dir( @@ -121,6 +131,30 @@ fn prepare_libcore(sysroot_path: &Path, libgccjit12_patches: bool, cross_compile )?; } println!("Successfully prepared libcore for building"); + + Ok(()) +} + +// TODO: remove when we can ignore warnings in rustdoc tests. +fn prepare_rand() -> Result<(), String> { + // Apply patch for the rand crate. + let file_path = "patches/crates/0001-Remove-deny-warnings.patch"; + let rand_dir = Path::new("build/rand"); + println!("[GIT] apply `{}`", file_path); + let path = Path::new("../..").join(file_path); + run_command_with_output(&[&"git", &"apply", &path], Some(rand_dir))?; + run_command_with_output(&[&"git", &"add", &"-A"], Some(rand_dir))?; + run_command_with_output( + &[ + &"git", + &"commit", + &"--no-gpg-sign", + &"-m", + &format!("Patch {}", path.display()), + ], + Some(rand_dir), + )?; + Ok(()) } @@ -129,8 +163,7 @@ fn build_raytracer(repo_dir: &Path) -> Result<(), String> { run_command(&[&"cargo", &"build"], Some(repo_dir))?; let mv_target = repo_dir.join("raytracer_cg_llvm"); if mv_target.is_file() { - std::fs::remove_file(&mv_target) - .map_err(|e| format!("Failed to remove file `{}`: {e:?}", mv_target.display()))?; + remove_file(&mv_target)?; } run_command( &[&"mv", &"target/debug/main", &"raytracer_cg_llvm"], @@ -143,28 +176,13 @@ fn clone_and_setup(repo_url: &str, checkout_commit: &str, extra: Option) - where F: Fn(&Path) -> Result<(), String>, { - let clone_result = git_clone(repo_url, None)?; + let clone_result = git_clone_root_dir(repo_url, &Path::new(crate::BUILD_DIR), false)?; if !clone_result.ran_clone { println!("`{}` has already been cloned", clone_result.repo_name); } - let repo_path = Path::new(&clone_result.repo_name); + let repo_path = Path::new(crate::BUILD_DIR).join(&clone_result.repo_name); run_command(&[&"git", &"checkout", &"--", &"."], Some(&repo_path))?; run_command(&[&"git", &"checkout", &checkout_commit], Some(&repo_path))?; - let filter = format!("-{}-", clone_result.repo_name); - walk_dir( - "crate_patches", - |_| Ok(()), - |file_path| { - let patch = file_path.as_os_str().to_str().unwrap(); - if patch.contains(&filter) && patch.ends_with(".patch") { - run_command_with_output( - &[&"git", &"am", &file_path.canonicalize().unwrap()], - Some(&repo_path), - )?; - } - Ok(()) - }, - )?; if let Some(extra) = extra { extra(&repo_path)?; } @@ -210,8 +228,7 @@ impl PrepareArg { --only-libcore : Only setup libcore and don't clone other repositories --cross : Apply the patches needed to do cross-compilation --libgccjit12-patches : Apply patches needed for libgccjit12 - --help : Show this help -"# + --help : Show this help"# ) } } @@ -230,7 +247,7 @@ pub fn run() -> Result<(), String> { let to_clone = &[ ( "https://github.com/rust-random/rand.git", - "0f933f9c7176e53b2a3c7952ded484e1783f0bf1", + "1f4507a8e1cf8050e4ceef95eeda8f64645b6719", None, ), ( @@ -248,6 +265,8 @@ pub fn run() -> Result<(), String> { for (repo_url, checkout_commit, cb) in to_clone { clone_and_setup(repo_url, checkout_commit, *cb)?; } + + prepare_rand()?; } println!("Successfully ran `prepare`"); diff --git a/build_system/src/test.rs b/build_system/src/test.rs index 4c8c63e59ab7c..a4db2fdebef1e 100644 --- a/build_system/src/test.rs +++ b/build_system/src/test.rs @@ -1,15 +1,1222 @@ -use crate::utils::run_command_with_output; +use crate::build; +use crate::config::{Channel, ConfigInfo}; +use crate::utils::{ + get_toolchain, git_clone, git_clone_root_dir, remove_file, run_command, run_command_with_env, + run_command_with_output_and_env, rustc_version_info, split_args, walk_dir, +}; -fn get_args<'a>(args: &mut Vec<&'a dyn AsRef>, extra_args: &'a Vec) { - for extra_arg in extra_args { - args.push(extra_arg); +use std::collections::{BTreeSet, HashMap}; +use std::ffi::OsStr; +use std::fs::{create_dir_all, remove_dir_all, File}; +use std::io::{BufRead, BufReader}; +use std::path::{Path, PathBuf}; +use std::str::FromStr; + +type Env = HashMap; +type Runner = fn(&Env, &TestArg) -> Result<(), String>; +type Runners = HashMap<&'static str, (&'static str, Runner)>; + +fn get_runners() -> Runners { + let mut runners = HashMap::new(); + + runners.insert( + "--test-rustc", + ("Run all rustc tests", test_rustc as Runner), + ); + runners.insert( + "--test-successful-rustc", + ("Run successful rustc tests", test_successful_rustc), + ); + runners.insert( + "--test-failing-rustc", + ("Run failing rustc tests", test_failing_rustc), + ); + runners.insert( + "--projects", + ("Run the tests of popular crates", test_projects), + ); + runners.insert("--test-libcore", ("Run libcore tests", test_libcore)); + runners.insert("--clean", ("Empty cargo target directory", clean)); + runners.insert("--build-sysroot", ("Build sysroot", build_sysroot)); + runners.insert("--std-tests", ("Run std tests", std_tests)); + runners.insert("--asm-tests", ("Run asm tests", asm_tests)); + runners.insert( + "--extended-tests", + ("Run extended sysroot tests", extended_sysroot_tests), + ); + runners.insert( + "--extended-rand-tests", + ("Run extended rand tests", extended_rand_tests), + ); + runners.insert( + "--extended-regex-example-tests", + ( + "Run extended regex example tests", + extended_regex_example_tests, + ), + ); + runners.insert( + "--extended-regex-tests", + ("Run extended regex tests", extended_regex_tests), + ); + runners.insert("--mini-tests", ("Run mini tests", mini_tests)); + + runners +} + +fn get_number_after_arg( + args: &mut impl Iterator, + option: &str, +) -> Result { + match args.next() { + Some(nb) if !nb.is_empty() => match usize::from_str(&nb) { + Ok(nb) => Ok(nb), + Err(_) => Err(format!( + "Expected a number after `{}`, found `{}`", + option, nb + )), + }, + _ => Err(format!( + "Expected a number after `{}`, found nothing", + option + )), + } +} + +fn show_usage() { + println!( + r#" +`test` command help: + + --release : Build codegen in release mode + --sysroot-panic-abort : Build the sysroot without unwinding support. + --features [arg] : Add a new feature [arg] + --use-system-gcc : Use system installed libgccjit + --build-only : Only build rustc_codegen_gcc then exits + --use-backend : Useful only for rustc testsuite + --nb-parts : Used to split rustc_tests (for CI needs) + --current-part : Used with `--nb-parts`, allows you to specify which parts to test"# + ); + ConfigInfo::show_usage(); + for (option, (doc, _)) in get_runners() { + // FIXME: Instead of using the hard-coded `23` value, better to compute it instead. + let needed_spaces = 23_usize.saturating_sub(option.len()); + let spaces: String = std::iter::repeat(' ').take(needed_spaces).collect(); + println!(" {}{}: {}", option, spaces, doc); + } + println!(" --help : Show this help"); +} + +#[derive(Default, Debug)] +struct TestArg { + build_only: bool, + use_system_gcc: bool, + runners: BTreeSet, + flags: Vec, + backend: Option, + nb_parts: Option, + current_part: Option, + sysroot_panic_abort: bool, + config_info: ConfigInfo, +} + +impl TestArg { + fn new() -> Result, String> { + let mut test_arg = Self::default(); + + // We skip binary name and the `test` command. + let mut args = std::env::args().skip(2); + let runners = get_runners(); + + while let Some(arg) = args.next() { + match arg.as_str() { + "--features" => match args.next() { + Some(feature) if !feature.is_empty() => { + test_arg + .flags + .extend_from_slice(&["--features".into(), feature]); + } + _ => { + return Err("Expected an argument after `--features`, found nothing".into()) + } + }, + "--use-system-gcc" => { + println!("Using system GCC"); + test_arg.use_system_gcc = true; + } + "--build-only" => test_arg.build_only = true, + "--use-backend" => match args.next() { + Some(backend) if !backend.is_empty() => test_arg.backend = Some(backend), + _ => { + return Err( + "Expected an argument after `--use-backend`, found nothing".into() + ) + } + }, + "--nb-parts" => { + test_arg.nb_parts = Some(get_number_after_arg(&mut args, "--nb-parts")?); + } + "--current-part" => { + test_arg.current_part = + Some(get_number_after_arg(&mut args, "--current-part")?); + } + "--sysroot-panic-abort" => { + test_arg.sysroot_panic_abort = true; + } + "--help" => { + show_usage(); + return Ok(None); + } + x if runners.contains_key(x) => { + test_arg.runners.insert(x.into()); + } + arg => { + if !test_arg.config_info.parse_argument(arg, &mut args)? { + return Err(format!("Unknown option {}", arg)); + } + } + } + } + match (test_arg.current_part, test_arg.nb_parts) { + (Some(_), Some(_)) | (None, None) => {} + _ => { + return Err( + "If either `--current-part` or `--nb-parts` is specified, the other one \ + needs to be specified as well!" + .to_string(), + ); + } + } + if test_arg.config_info.no_default_features { + test_arg.flags.push("--no-default-features".into()); + } + Ok(Some(test_arg)) + } + + pub fn is_using_gcc_master_branch(&self) -> bool { + !self.config_info.no_default_features + } +} + +fn build_if_no_backend(env: &Env, args: &TestArg) -> Result<(), String> { + if args.backend.is_some() { + return Ok(()); + } + let mut command: Vec<&dyn AsRef> = vec![&"cargo", &"rustc"]; + let mut tmp_env; + let env = if args.config_info.channel == Channel::Release { + tmp_env = env.clone(); + tmp_env.insert("CARGO_INCREMENTAL".to_string(), "1".to_string()); + command.push(&"--release"); + &tmp_env + } else { + &env + }; + for flag in args.flags.iter() { + command.push(flag); + } + run_command_with_output_and_env(&command, None, Some(env)) +} + +fn clean(_env: &Env, args: &TestArg) -> Result<(), String> { + let _ = std::fs::remove_dir_all(&args.config_info.cargo_target_dir); + let path = Path::new(&args.config_info.cargo_target_dir).join("gccjit"); + std::fs::create_dir_all(&path) + .map_err(|error| format!("failed to create folder `{}`: {:?}", path.display(), error)) +} + +fn mini_tests(env: &Env, args: &TestArg) -> Result<(), String> { + // FIXME: create a function "display_if_not_quiet" or something along the line. + println!("[BUILD] mini_core"); + let crate_types = if args.config_info.host_triple != args.config_info.target_triple { + "lib" + } else { + "lib,dylib" + } + .to_string(); + let mut command = args.config_info.rustc_command_vec(); + command.extend_from_slice(&[ + &"example/mini_core.rs", + &"--crate-name", + &"mini_core", + &"--crate-type", + &crate_types, + &"--target", + &args.config_info.target_triple, + ]); + run_command_with_output_and_env(&command, None, Some(&env))?; + + // FIXME: create a function "display_if_not_quiet" or something along the line. + println!("[BUILD] example"); + let mut command = args.config_info.rustc_command_vec(); + command.extend_from_slice(&[ + &"example/example.rs", + &"--crate-type", + &"lib", + &"--target", + &args.config_info.target_triple, + ]); + run_command_with_output_and_env(&command, None, Some(&env))?; + + // FIXME: create a function "display_if_not_quiet" or something along the line. + println!("[AOT] mini_core_hello_world"); + let mut command = args.config_info.rustc_command_vec(); + command.extend_from_slice(&[ + &"example/mini_core_hello_world.rs", + &"--crate-name", + &"mini_core_hello_world", + &"--crate-type", + &"bin", + &"-g", + &"--target", + &args.config_info.target_triple, + ]); + run_command_with_output_and_env(&command, None, Some(&env))?; + + let command: &[&dyn AsRef] = &[ + &Path::new(&args.config_info.cargo_target_dir).join("mini_core_hello_world"), + &"abc", + &"bcd", + ]; + maybe_run_command_in_vm(&command, env, args)?; + Ok(()) +} + +fn build_sysroot(env: &Env, args: &TestArg) -> Result<(), String> { + // FIXME: create a function "display_if_not_quiet" or something along the line. + println!("[BUILD] sysroot"); + build::build_sysroot(env, &args.config_info)?; + Ok(()) +} + +// TODO(GuillaumeGomez): when rewriting in Rust, refactor with the code in tests/lang_tests_common.rs if possible. +fn maybe_run_command_in_vm( + command: &[&dyn AsRef], + env: &Env, + args: &TestArg, +) -> Result<(), String> { + if !args.config_info.run_in_vm { + run_command_with_output_and_env(command, None, Some(env))?; + return Ok(()); + } + let vm_parent_dir = match env.get("CG_GCC_VM_DIR") { + Some(dir) if !dir.is_empty() => PathBuf::from(dir.clone()), + _ => std::env::current_dir().unwrap(), + }; + let vm_dir = "vm"; + let exe_to_run = command.first().unwrap(); + let exe = Path::new(&exe_to_run); + let exe_filename = exe.file_name().unwrap(); + let vm_home_dir = vm_parent_dir.join(vm_dir).join("home"); + let vm_exe_path = vm_home_dir.join(exe_filename); + let inside_vm_exe_path = Path::new("/home").join(exe_filename); + + let sudo_command: &[&dyn AsRef] = &[&"sudo", &"cp", &exe, &vm_exe_path]; + run_command_with_env(sudo_command, None, Some(env))?; + + let mut vm_command: Vec<&dyn AsRef> = vec![ + &"sudo", + &"chroot", + &vm_dir, + &"qemu-m68k-static", + &inside_vm_exe_path, + ]; + vm_command.extend_from_slice(command); + run_command_with_output_and_env(&vm_command, Some(&vm_parent_dir), Some(env))?; + Ok(()) +} + +fn std_tests(env: &Env, args: &TestArg) -> Result<(), String> { + let cargo_target_dir = Path::new(&args.config_info.cargo_target_dir); + // FIXME: create a function "display_if_not_quiet" or something along the line. + println!("[AOT] arbitrary_self_types_pointers_and_wrappers"); + let mut command = args.config_info.rustc_command_vec(); + command.extend_from_slice(&[ + &"example/arbitrary_self_types_pointers_and_wrappers.rs", + &"--crate-name", + &"arbitrary_self_types_pointers_and_wrappers", + &"--crate-type", + &"bin", + &"--target", + &args.config_info.target_triple, + ]); + run_command_with_env(&command, None, Some(env))?; + maybe_run_command_in_vm( + &[&cargo_target_dir.join("arbitrary_self_types_pointers_and_wrappers")], + env, + args, + )?; + + // FIXME: create a function "display_if_not_quiet" or something along the line. + println!("[AOT] alloc_system"); + let mut command = args.config_info.rustc_command_vec(); + command.extend_from_slice(&[ + &"example/alloc_system.rs", + &"--crate-type", + &"lib", + &"--target", + &args.config_info.target_triple, + ]); + if args.is_using_gcc_master_branch() { + command.extend_from_slice(&[&"--cfg", &"feature=\"master\""]); + } + run_command_with_env(&command, None, Some(env))?; + + // FIXME: doesn't work on m68k. + if args.config_info.host_triple == args.config_info.target_triple { + // FIXME: create a function "display_if_not_quiet" or something along the line. + println!("[AOT] alloc_example"); + let mut command = args.config_info.rustc_command_vec(); + command.extend_from_slice(&[ + &"example/alloc_example.rs", + &"--crate-type", + &"bin", + &"--target", + &args.config_info.target_triple, + ]); + run_command_with_env(&command, None, Some(env))?; + maybe_run_command_in_vm(&[&cargo_target_dir.join("alloc_example")], env, args)?; + } + + // FIXME: create a function "display_if_not_quiet" or something along the line. + println!("[AOT] dst_field_align"); + // FIXME(antoyo): Re-add -Zmir-opt-level=2 once rust-lang/rust#67529 is fixed. + let mut command = args.config_info.rustc_command_vec(); + command.extend_from_slice(&[ + &"example/dst-field-align.rs", + &"--crate-name", + &"dst_field_align", + &"--crate-type", + &"bin", + &"--target", + &args.config_info.target_triple, + ]); + run_command_with_env(&command, None, Some(env))?; + maybe_run_command_in_vm(&[&cargo_target_dir.join("dst_field_align")], env, args)?; + + // FIXME: create a function "display_if_not_quiet" or something along the line. + println!("[AOT] std_example"); + let mut command = args.config_info.rustc_command_vec(); + command.extend_from_slice(&[ + &"example/std_example.rs", + &"--crate-type", + &"bin", + &"--target", + &args.config_info.target_triple, + ]); + if args.is_using_gcc_master_branch() { + command.extend_from_slice(&[&"--cfg", &"feature=\"master\""]); + } + run_command_with_env(&command, None, Some(env))?; + maybe_run_command_in_vm( + &[ + &cargo_target_dir.join("std_example"), + &"--target", + &args.config_info.target_triple, + ], + env, + args, + )?; + + let test_flags = if let Some(test_flags) = env.get("TEST_FLAGS") { + split_args(test_flags)? + } else { + Vec::new() + }; + // FIXME: create a function "display_if_not_quiet" or something along the line. + println!("[AOT] subslice-patterns-const-eval"); + let mut command = args.config_info.rustc_command_vec(); + command.extend_from_slice(&[ + &"example/subslice-patterns-const-eval.rs", + &"--crate-type", + &"bin", + &"--target", + &args.config_info.target_triple, + ]); + for test_flag in &test_flags { + command.push(test_flag); + } + run_command_with_env(&command, None, Some(env))?; + maybe_run_command_in_vm( + &[&cargo_target_dir.join("subslice-patterns-const-eval")], + env, + args, + )?; + + // FIXME: create a function "display_if_not_quiet" or something along the line. + println!("[AOT] track-caller-attribute"); + let mut command = args.config_info.rustc_command_vec(); + command.extend_from_slice(&[ + &"example/track-caller-attribute.rs", + &"--crate-type", + &"bin", + &"--target", + &args.config_info.target_triple, + ]); + for test_flag in &test_flags { + command.push(test_flag); + } + run_command_with_env(&command, None, Some(env))?; + maybe_run_command_in_vm( + &[&cargo_target_dir.join("track-caller-attribute")], + env, + args, + )?; + + // FIXME: create a function "display_if_not_quiet" or something along the line. + println!("[AOT] mod_bench"); + let mut command = args.config_info.rustc_command_vec(); + command.extend_from_slice(&[ + &"example/mod_bench.rs", + &"--crate-type", + &"bin", + &"--target", + &args.config_info.target_triple, + ]); + run_command_with_env(&command, None, Some(env))?; + // FIXME: the compiled binary is not run. + + Ok(()) +} + +fn setup_rustc(env: &mut Env, args: &TestArg) -> Result { + let toolchain = format!( + "+{channel}-{host}", + channel = get_toolchain()?, // May also include date + host = args.config_info.host_triple + ); + let rust_dir_path = Path::new(crate::BUILD_DIR).join("rust"); + // If the repository was already cloned, command will fail, so doesn't matter. + let _ = git_clone( + "https://github.com/rust-lang/rust.git", + Some(&rust_dir_path), + false, + ); + let rust_dir: Option<&Path> = Some(&rust_dir_path); + run_command(&[&"git", &"checkout", &"--", &"tests/"], rust_dir)?; + run_command_with_output_and_env(&[&"git", &"fetch"], rust_dir, Some(env))?; + let rustc_commit = match rustc_version_info(env.get("RUSTC").map(|s| s.as_str()))?.commit_hash { + Some(commit_hash) => commit_hash, + None => return Err("Couldn't retrieve rustc commit hash".to_string()), + }; + if rustc_commit != "unknown" { + run_command_with_output_and_env( + &[&"git", &"checkout", &rustc_commit], + rust_dir, + Some(env), + )?; + } else { + run_command_with_output_and_env(&[&"git", &"checkout"], rust_dir, Some(env))?; + } + let cargo = String::from_utf8( + run_command_with_env(&[&"rustup", &"which", &"cargo"], rust_dir, Some(env))?.stdout, + ) + .map_err(|error| format!("Failed to retrieve cargo path: {:?}", error)) + .and_then(|cargo| { + let cargo = cargo.trim().to_owned(); + if cargo.is_empty() { + Err(format!("`cargo` path is empty")) + } else { + Ok(cargo) + } + })?; + let rustc = String::from_utf8( + run_command_with_env( + &[&"rustup", &toolchain, &"which", &"rustc"], + rust_dir, + Some(env), + )? + .stdout, + ) + .map_err(|error| format!("Failed to retrieve rustc path: {:?}", error)) + .and_then(|rustc| { + let rustc = rustc.trim().to_owned(); + if rustc.is_empty() { + Err(format!("`rustc` path is empty")) + } else { + Ok(rustc) + } + })?; + let llvm_filecheck = match run_command_with_env( + &[ + &"bash", + &"-c", + &"which FileCheck-10 || \ + which FileCheck-11 || \ + which FileCheck-12 || \ + which FileCheck-13 || \ + which FileCheck-14", + ], + rust_dir, + Some(env), + ) { + Ok(cmd) => String::from_utf8_lossy(&cmd.stdout).to_string(), + Err(_) => { + eprintln!("Failed to retrieve LLVM FileCheck, ignoring..."); + String::new() + } + }; + let file_path = rust_dir_path.join("config.toml"); + std::fs::write( + &file_path, + &format!( + r#"change-id = 115898 + +[rust] +codegen-backends = [] +deny-warnings = false +verbose-tests = true + +[build] +cargo = "{cargo}" +local-rebuild = true +rustc = "{rustc}" + +[target.x86_64-unknown-linux-gnu] +llvm-filecheck = "{llvm_filecheck}" + +[llvm] +download-ci-llvm = false +"#, + cargo = cargo, + rustc = rustc, + llvm_filecheck = llvm_filecheck.trim(), + ), + ) + .map_err(|error| { + format!( + "Failed to write into `{}`: {:?}", + file_path.display(), + error + ) + })?; + Ok(rust_dir_path) +} + +fn asm_tests(env: &Env, args: &TestArg) -> Result<(), String> { + let mut env = env.clone(); + let rust_dir = setup_rustc(&mut env, args)?; + // FIXME: create a function "display_if_not_quiet" or something along the line. + println!("[TEST] rustc asm test suite"); + + env.insert("COMPILETEST_FORCE_STAGE0".to_string(), "1".to_string()); + + let extra = if args.is_using_gcc_master_branch() { + "" + } else { + " -Csymbol-mangling-version=v0" + }; + + let rustc_args = &format!( + r#"-Zpanic-abort-tests \ + -Zcodegen-backend="{pwd}/target/{channel}/librustc_codegen_gcc.{dylib_ext}" \ + --sysroot "{pwd}/build_sysroot/sysroot" -Cpanic=abort{extra}"#, + pwd = std::env::current_dir() + .map_err(|error| format!("`current_dir` failed: {:?}", error))? + .display(), + channel = args.config_info.channel.as_str(), + dylib_ext = args.config_info.dylib_ext, + extra = extra, + ); + + run_command_with_env( + &[ + &"./x.py", + &"test", + &"--run", + &"always", + &"--stage", + &"0", + &"tests/assembly/asm", + &"--rustc-args", + &rustc_args, + ], + Some(&rust_dir), + Some(&env), + )?; + Ok(()) +} + +fn run_cargo_command( + command: &[&dyn AsRef], + cwd: Option<&Path>, + env: &Env, + args: &TestArg, +) -> Result<(), String> { + run_cargo_command_with_callback(command, cwd, env, args, |cargo_command, cwd, env| { + run_command_with_output_and_env(cargo_command, cwd, Some(env))?; + Ok(()) + }) +} + +fn run_cargo_command_with_callback( + command: &[&dyn AsRef], + cwd: Option<&Path>, + env: &Env, + args: &TestArg, + callback: F, +) -> Result<(), String> +where + F: Fn(&[&dyn AsRef], Option<&Path>, &Env) -> Result<(), String>, +{ + let toolchain = get_toolchain()?; + let toolchain_arg = format!("+{}", toolchain); + let rustc_version = String::from_utf8( + run_command_with_env(&[&args.config_info.rustc_command[0], &"-V"], cwd, Some(env))?.stdout, + ) + .map_err(|error| format!("Failed to retrieve rustc version: {:?}", error))?; + let rustc_toolchain_version = String::from_utf8( + run_command_with_env( + &[&args.config_info.rustc_command[0], &toolchain_arg, &"-V"], + cwd, + Some(env), + )? + .stdout, + ) + .map_err(|error| format!("Failed to retrieve rustc +toolchain version: {:?}", error))?; + + if rustc_version != rustc_toolchain_version { + eprintln!( + "rustc_codegen_gcc is built for `{}` but the default rustc version is `{}`.", + rustc_toolchain_version, rustc_version, + ); + eprintln!("Using `{}`.", rustc_toolchain_version); + } + let mut env = env.clone(); + let rustflags = env.get("RUSTFLAGS").cloned().unwrap_or_default(); + env.insert("RUSTDOCFLAGS".to_string(), rustflags); + let mut cargo_command: Vec<&dyn AsRef> = vec![&"cargo", &toolchain_arg]; + cargo_command.extend_from_slice(&command); + callback(&cargo_command, cwd, &env) +} + +// FIXME(antoyo): linker gives multiple definitions error on Linux +// echo "[BUILD] sysroot in release mode" +// ./build_sysroot/build_sysroot.sh --release + +fn test_projects(env: &Env, args: &TestArg) -> Result<(), String> { + let projects = [ + //"https://gitlab.gnome.org/GNOME/librsvg", // FIXME: doesn't compile in the CI since the + // version of cairo and other libraries is too old. + "https://github.com/rust-random/getrandom", + "https://github.com/BurntSushi/memchr", + "https://github.com/dtolnay/itoa", + "https://github.com/rust-lang/cfg-if", + "https://github.com/rust-lang-nursery/lazy-static.rs", + //"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/rust-lang/log", + "https://github.com/bitflags/bitflags", + //"https://github.com/serde-rs/serde", // FIXME: one test fails. + //"https://github.com/rayon-rs/rayon", // TODO: very slow, only run on master? + //"https://github.com/rust-lang/cargo", // TODO: very slow, only run on master? + ]; + + let run_tests = |projects_path, iter: &mut dyn Iterator| -> Result<(), String> { + for project in iter { + let clone_result = git_clone_root_dir(project, projects_path, true)?; + let repo_path = Path::new(&clone_result.repo_dir); + run_cargo_command(&[&"build", &"--release"], Some(repo_path), env, args)?; + run_cargo_command(&[&"test"], Some(repo_path), env, args)?; + } + + Ok(()) + }; + + let projects_path = Path::new("projects"); + create_dir_all(projects_path) + .map_err(|err| format!("Failed to create directory `projects`: {}", err))?; + + let nb_parts = args.nb_parts.unwrap_or(0); + if nb_parts > 0 { + // We increment the number of tests by one because if this is an odd number, we would skip + // one test. + let count = projects.len() / nb_parts + 1; + let current_part = args.current_part.unwrap(); + let start = current_part * count; + // We remove the projects we don't want to test. + run_tests(projects_path, &mut projects.iter().skip(start).take(count))?; + } else { + run_tests(projects_path, &mut projects.iter())?; } + + Ok(()) +} + +fn test_libcore(env: &Env, args: &TestArg) -> Result<(), String> { + // FIXME: create a function "display_if_not_quiet" or something along the line. + println!("[TEST] libcore"); + let path = Path::new("build_sysroot/sysroot_src/library/core/tests"); + let _ = remove_dir_all(path.join("target")); + run_cargo_command(&[&"test"], Some(path), env, args)?; + Ok(()) +} + +// echo "[BENCH COMPILE] mod_bench" +// +// COMPILE_MOD_BENCH_INLINE="$RUSTC example/mod_bench.rs --crate-type bin -Zmir-opt-level=3 -O --crate-name mod_bench_inline" +// COMPILE_MOD_BENCH_LLVM_0="rustc example/mod_bench.rs --crate-type bin -Copt-level=0 -o $cargo_target_dir/mod_bench_llvm_0 -Cpanic=abort" +// COMPILE_MOD_BENCH_LLVM_1="rustc example/mod_bench.rs --crate-type bin -Copt-level=1 -o $cargo_target_dir/mod_bench_llvm_1 -Cpanic=abort" +// COMPILE_MOD_BENCH_LLVM_2="rustc example/mod_bench.rs --crate-type bin -Copt-level=2 -o $cargo_target_dir/mod_bench_llvm_2 -Cpanic=abort" +// COMPILE_MOD_BENCH_LLVM_3="rustc example/mod_bench.rs --crate-type bin -Copt-level=3 -o $cargo_target_dir/mod_bench_llvm_3 -Cpanic=abort" +// +// Use 100 runs, because a single compilations doesn't take more than ~150ms, so it isn't very slow +// hyperfine --runs ${COMPILE_RUNS:-100} "$COMPILE_MOD_BENCH_INLINE" "$COMPILE_MOD_BENCH_LLVM_0" "$COMPILE_MOD_BENCH_LLVM_1" "$COMPILE_MOD_BENCH_LLVM_2" "$COMPILE_MOD_BENCH_LLVM_3" +// echo "[BENCH RUN] mod_bench" +// hyperfine --runs ${RUN_RUNS:-10} $cargo_target_dir/mod_bench{,_inline} $cargo_target_dir/mod_bench_llvm_* + +fn extended_rand_tests(env: &Env, args: &TestArg) -> Result<(), String> { + if !args.is_using_gcc_master_branch() { + println!("Not using GCC master branch. Skipping `extended_rand_tests`."); + return Ok(()); + } + let mut env = env.clone(); + // newer aho_corasick versions throw a deprecation warning + let rustflags = format!( + "{} --cap-lints warn", + env.get("RUSTFLAGS").cloned().unwrap_or_default() + ); + env.insert("RUSTFLAGS".to_string(), rustflags); + + let path = Path::new(crate::BUILD_DIR).join("rand"); + run_cargo_command(&[&"clean"], Some(&path), &env, args)?; + // FIXME: create a function "display_if_not_quiet" or something along the line. + println!("[TEST] rust-random/rand"); + run_cargo_command(&[&"test", &"--workspace"], Some(&path), &env, args)?; + Ok(()) +} + +fn extended_regex_example_tests(env: &Env, args: &TestArg) -> Result<(), String> { + if !args.is_using_gcc_master_branch() { + println!("Not using GCC master branch. Skipping `extended_regex_example_tests`."); + return Ok(()); + } + let path = Path::new(crate::BUILD_DIR).join("regex"); + run_cargo_command(&[&"clean"], Some(&path), env, args)?; + // FIXME: create a function "display_if_not_quiet" or something along the line. + println!("[TEST] rust-lang/regex example shootout-regex-dna"); + let mut env = env.clone(); + // newer aho_corasick versions throw a deprecation warning + let rustflags = format!( + "{} --cap-lints warn", + env.get("RUSTFLAGS").cloned().unwrap_or_default() + ); + env.insert("RUSTFLAGS".to_string(), rustflags); + // Make sure `[codegen mono items] start` doesn't poison the diff + run_cargo_command( + &[&"build", &"--example", &"shootout-regex-dna"], + Some(&path), + &env, + args, + )?; + + run_cargo_command_with_callback( + &[&"run", &"--example", &"shootout-regex-dna"], + Some(&path), + &env, + args, + |cargo_command, cwd, env| { + // FIXME: rewrite this with `child.stdin.write_all()` because + // `examples/regexdna-input.txt` is very small. + let mut command: Vec<&dyn AsRef> = vec![&"bash", &"-c"]; + let cargo_args = cargo_command + .iter() + .map(|s| s.as_ref().to_str().unwrap()) + .collect::>(); + let bash_command = format!( + "cat examples/regexdna-input.txt | {} | grep -v 'Spawned thread' > res.txt", + cargo_args.join(" "), + ); + command.push(&bash_command); + run_command_with_output_and_env(&command, cwd, Some(env))?; + run_command_with_output_and_env( + &[&"diff", &"-u", &"res.txt", &"examples/regexdna-output.txt"], + cwd, + Some(env), + )?; + Ok(()) + }, + )?; + + Ok(()) +} + +fn extended_regex_tests(env: &Env, args: &TestArg) -> Result<(), String> { + if !args.is_using_gcc_master_branch() { + println!("Not using GCC master branch. Skipping `extended_regex_tests`."); + return Ok(()); + } + // FIXME: create a function "display_if_not_quiet" or something along the line. + println!("[TEST] rust-lang/regex tests"); + let mut env = env.clone(); + // newer aho_corasick versions throw a deprecation warning + let rustflags = format!( + "{} --cap-lints warn", + env.get("RUSTFLAGS").cloned().unwrap_or_default() + ); + env.insert("RUSTFLAGS".to_string(), rustflags); + let path = Path::new(crate::BUILD_DIR).join("regex"); + run_cargo_command( + &[ + &"test", + &"--tests", + &"--", + // FIXME: try removing `--exclude-should-panic` argument + &"--exclude-should-panic", + &"--test-threads", + &"1", + &"-Zunstable-options", + &"-q", + ], + Some(&path), + &env, + args, + )?; + Ok(()) +} + +fn extended_sysroot_tests(env: &Env, args: &TestArg) -> Result<(), String> { + // pushd simple-raytracer + // echo "[BENCH COMPILE] ebobby/simple-raytracer" + // hyperfine --runs "${RUN_RUNS:-10}" --warmup 1 --prepare "cargo clean" \ + // "RUSTC=rustc RUSTFLAGS='' cargo build" \ + // "../y.sh cargo build" + + // echo "[BENCH RUN] ebobby/simple-raytracer" + // cp ./target/debug/main ./raytracer_cg_gcc + // hyperfine --runs "${RUN_RUNS:-10}" ./raytracer_cg_llvm ./raytracer_cg_gcc + // popd + extended_rand_tests(env, args)?; + extended_regex_example_tests(env, args)?; + extended_regex_tests(env, args)?; + + Ok(()) +} + +fn should_not_remove_test(file: &str) -> bool { + // contains //~ERROR, but shouldn't be removed + [ + "issues/auxiliary/issue-3136-a.rs", + "type-alias-impl-trait/auxiliary/cross_crate_ice.rs", + "type-alias-impl-trait/auxiliary/cross_crate_ice2.rs", + "macros/rfc-2011-nicer-assert-messages/auxiliary/common.rs", + "imports/ambiguous-1.rs", + "imports/ambiguous-4-extern.rs", + "entry-point/auxiliary/bad_main_functions.rs", + ] + .iter() + .any(|to_ignore| file.ends_with(to_ignore)) +} + +fn should_remove_test(file_path: &Path) -> Result { + // Tests generating errors. + let file = File::open(file_path) + .map_err(|error| format!("Failed to read `{}`: {:?}", file_path.display(), error))?; + for line in BufReader::new(file).lines().filter_map(|line| line.ok()) { + let line = line.trim(); + if line.is_empty() { + continue; + } + if [ + "//@ error-pattern:", + "//@ build-fail", + "//@ run-fail", + "-Cllvm-args", + "//~", + "thread", + ] + .iter() + .any(|check| line.contains(check)) + { + return Ok(true); + } + if line.contains("//[") && line.contains("]~") { + return Ok(true); + } + } + if file_path + .display() + .to_string() + .contains("ambiguous-4-extern.rs") + { + eprintln!("nothing found for {file_path:?}"); + } + Ok(false) +} + +fn test_rustc_inner(env: &Env, args: &TestArg, prepare_files_callback: F) -> Result<(), String> +where + F: Fn(&Path) -> Result, +{ + // FIXME: create a function "display_if_not_quiet" or something along the line. + println!("[TEST] rust-lang/rust"); + let mut env = env.clone(); + let rust_path = setup_rustc(&mut env, args)?; + + walk_dir( + rust_path.join("tests/ui"), + |dir| { + let dir_name = dir.file_name().and_then(|name| name.to_str()).unwrap_or(""); + if [ + "abi", + "extern", + "unsized-locals", + "proc-macro", + "threads-sendsync", + "borrowck", + "test-attrs", + ] + .iter() + .any(|name| *name == dir_name) + { + std::fs::remove_dir_all(dir).map_err(|error| { + format!("Failed to remove folder `{}`: {:?}", dir.display(), error) + })?; + } + Ok(()) + }, + |_| Ok(()), + )?; + + // 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(()); + } + walk_dir(dir, dir_handling, file_handling) + } + fn file_handling(file_path: &Path) -> Result<(), String> { + if !file_path + .extension() + .map(|extension| extension == "rs") + .unwrap_or(false) + { + return Ok(()); + } + let path_str = file_path.display().to_string().replace("\\", "/"); + if should_not_remove_test(&path_str) { + return Ok(()); + } else if should_remove_test(file_path)? { + return remove_file(&file_path); + } + Ok(()) + } + + remove_file(&rust_path.join("tests/ui/consts/const_cmp_type_id.rs"))?; + remove_file(&rust_path.join("tests/ui/consts/issue-73976-monomorphic.rs"))?; + // this test is oom-killed in the CI. + remove_file(&rust_path.join("tests/ui/consts/issue-miri-1910.rs"))?; + // Tests generating errors. + remove_file(&rust_path.join("tests/ui/consts/issue-94675.rs"))?; + remove_file(&rust_path.join("tests/ui/mir/mir_heavy_promoted.rs"))?; + remove_file(&rust_path.join("tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail.rs"))?; + remove_file(&rust_path.join("tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop.rs"))?; + + walk_dir(rust_path.join("tests/ui"), dir_handling, file_handling)?; + + if !prepare_files_callback(&rust_path)? { + // FIXME: create a function "display_if_not_quiet" or something along the line. + println!("Keeping all UI tests"); + } + + let nb_parts = args.nb_parts.unwrap_or(0); + if nb_parts > 0 { + let current_part = args.current_part.unwrap(); + // FIXME: create a function "display_if_not_quiet" or something along the line. + println!( + "Splitting ui_test into {} parts (and running part {})", + nb_parts, current_part + ); + let out = String::from_utf8( + run_command( + &[ + &"find", + &"tests/ui", + &"-type", + &"f", + &"-name", + &"*.rs", + &"-not", + &"-path", + &"*/auxiliary/*", + ], + Some(&rust_path), + )? + .stdout, + ) + .map_err(|error| format!("Failed to retrieve output of find command: {:?}", error))?; + let mut files = out + .split('\n') + .map(|line| line.trim()) + .filter(|line| !line.is_empty()) + .collect::>(); + // To ensure it'll be always the same sub files, we sort the content. + files.sort(); + // We increment the number of tests by one because if this is an odd number, we would skip + // one test. + let count = files.len() / nb_parts + 1; + let start = current_part * count; + // We remove the files we don't want to test. + for path in files.iter().skip(start).take(count) { + remove_file(&rust_path.join(path))?; + } + } + + // FIXME: create a function "display_if_not_quiet" or something along the line. + println!("[TEST] rustc test suite"); + env.insert("COMPILETEST_FORCE_STAGE0".to_string(), "1".to_string()); + + let extra = if args.is_using_gcc_master_branch() { + "" + } else { + " -Csymbol-mangling-version=v0" + }; + + let rustc_args = format!( + "{} -Zcodegen-backend={} --sysroot {}{}", + env.get("TEST_FLAGS").unwrap_or(&String::new()), + args.config_info.cg_backend_path, + args.config_info.sysroot_path, + extra, + ); + + env.get_mut("RUSTFLAGS").unwrap().clear(); + run_command_with_output_and_env( + &[ + &"./x.py", + &"test", + &"--run", + &"always", + &"--stage", + &"0", + &"tests/ui", + &"--rustc-args", + &rustc_args, + ], + Some(&rust_path), + Some(&env), + )?; + Ok(()) +} + +fn test_rustc(env: &Env, args: &TestArg) -> Result<(), String> { + test_rustc_inner(env, args, |_| Ok(false)) +} + +fn test_failing_rustc(env: &Env, args: &TestArg) -> Result<(), String> { + test_rustc_inner(env, args, |rust_path| { + // Removing all tests. + run_command( + &[ + &"find", + &"tests/ui", + &"-type", + &"f", + &"-name", + &"*.rs", + &"-not", + &"-path", + &"*/auxiliary/*", + &"-delete", + ], + Some(rust_path), + )?; + // Putting back only the failing ones. + let path = "tests/failing-ui-tests.txt"; + if let Ok(files) = std::fs::read_to_string(path) { + for file in files + .split('\n') + .map(|line| line.trim()) + .filter(|line| !line.is_empty()) + { + run_command(&[&"git", &"checkout", &"--", &file], Some(&rust_path))?; + } + } else { + println!( + "Failed to read `{}`, not putting back failing ui tests", + path + ); + } + Ok(true) + }) +} + +fn test_successful_rustc(env: &Env, args: &TestArg) -> Result<(), String> { + test_rustc_inner(env, args, |rust_path| { + // Removing the failing tests. + let path = "tests/failing-ui-tests.txt"; + if let Ok(files) = std::fs::read_to_string(path) { + for file in files + .split('\n') + .map(|line| line.trim()) + .filter(|line| !line.is_empty()) + { + let path = rust_path.join(file); + remove_file(&path)?; + } + } else { + println!( + "Failed to read `{}`, not putting back failing ui tests", + path + ); + } + Ok(true) + }) +} + +fn run_all(env: &Env, args: &TestArg) -> Result<(), String> { + clean(env, args)?; + mini_tests(env, args)?; + build_sysroot(env, args)?; + std_tests(env, args)?; + // asm_tests(env, args)?; + test_libcore(env, args)?; + extended_sysroot_tests(env, args)?; + test_rustc(env, args)?; + Ok(()) } pub fn run() -> Result<(), String> { - let mut args: Vec<&dyn AsRef> = vec![&"bash", &"test.sh"]; - let extra_args = std::env::args().skip(2).collect::>(); - get_args(&mut args, &extra_args); - let current_dir = std::env::current_dir().map_err(|error| format!("`current_dir` failed: {:?}", error))?; - run_command_with_output(args.as_slice(), Some(¤t_dir)) + let mut args = match TestArg::new()? { + Some(args) => args, + None => return Ok(()), + }; + let mut env: HashMap = std::env::vars().collect(); + + 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(), + ); + } + + build_if_no_backend(&env, &args)?; + if args.build_only { + println!("Since it's build only, exiting..."); + return Ok(()); + } + + args.config_info.setup(&mut env, args.use_system_gcc)?; + + if args.runners.is_empty() { + run_all(&env, &args)?; + } else { + let runners = get_runners(); + for runner in args.runners.iter() { + runners.get(runner.as_str()).unwrap().1(&env, &args)?; + } + } + + Ok(()) } diff --git a/build_system/src/utils.rs b/build_system/src/utils.rs index 536f33a80293c..d9c13fd143d15 100644 --- a/build_system/src/utils.rs +++ b/build_system/src/utils.rs @@ -2,7 +2,7 @@ use std::collections::HashMap; use std::ffi::OsStr; use std::fmt::Debug; use std::fs; -use std::path::Path; +use std::path::{Path, PathBuf}; use std::process::{Command, ExitStatus, Output}; fn get_command_inner( @@ -29,22 +29,40 @@ fn check_exit_status( input: &[&dyn AsRef], cwd: Option<&Path>, exit_status: ExitStatus, + output: Option<&Output>, + show_err: bool, ) -> Result<(), String> { if exit_status.success() { - Ok(()) - } else { - Err(format!( - "Command `{}`{} exited with status {:?}", - input - .iter() - .map(|s| s.as_ref().to_str().unwrap()) - .collect::>() - .join(" "), - cwd.map(|cwd| format!(" (running in folder `{}`)", cwd.display())) - .unwrap_or_default(), - exit_status.code(), - )) + return Ok(()); } + let mut error = format!( + "Command `{}`{} exited with status {:?}", + input + .iter() + .map(|s| s.as_ref().to_str().unwrap()) + .collect::>() + .join(" "), + cwd.map(|cwd| format!(" (running in folder `{}`)", cwd.display())) + .unwrap_or_default(), + exit_status.code() + ); + let input = input.iter().map(|i| i.as_ref()).collect::>(); + if show_err { + eprintln!("Command `{:?}` failed", input); + } + if let Some(output) = output { + let stdout = String::from_utf8_lossy(&output.stdout); + if !stdout.is_empty() { + error.push_str("\n==== STDOUT ====\n"); + error.push_str(&*stdout); + } + let stderr = String::from_utf8_lossy(&output.stderr); + if !stderr.is_empty() { + error.push_str("\n==== STDERR ====\n"); + error.push_str(&*stderr); + } + } + Err(error) } fn command_error(input: &[&dyn AsRef], cwd: &Option<&Path>, error: D) -> String { @@ -73,7 +91,7 @@ pub fn run_command_with_env( let output = get_command_inner(input, cwd, env) .output() .map_err(|e| command_error(input, &cwd, e))?; - check_exit_status(input, cwd, output.status)?; + check_exit_status(input, cwd, output.status, Some(&output), true)?; Ok(output) } @@ -86,7 +104,7 @@ pub fn run_command_with_output( .map_err(|e| command_error(input, &cwd, e))? .wait() .map_err(|e| command_error(input, &cwd, e))?; - check_exit_status(input, cwd, exit_status)?; + check_exit_status(input, cwd, exit_status, None, true)?; Ok(()) } @@ -100,7 +118,21 @@ pub fn run_command_with_output_and_env( .map_err(|e| command_error(input, &cwd, e))? .wait() .map_err(|e| command_error(input, &cwd, e))?; - check_exit_status(input, cwd, exit_status)?; + check_exit_status(input, cwd, exit_status, None, true)?; + Ok(()) +} + +pub fn run_command_with_output_and_env_no_err( + input: &[&dyn AsRef], + cwd: Option<&Path>, + env: Option<&HashMap>, +) -> Result<(), String> { + let exit_status = get_command_inner(input, cwd, env) + .spawn() + .map_err(|e| command_error(input, &cwd, e))? + .wait() + .map_err(|e| command_error(input, &cwd, e))?; + check_exit_status(input, cwd, exit_status, None, false)?; Ok(()) } @@ -143,80 +175,157 @@ pub fn get_os_name() -> Result { } } -pub fn get_rustc_host_triple() -> Result { - let output = run_command(&[&"rustc", &"-vV"], None)?; +#[derive(Default, PartialEq)] +pub struct RustcVersionInfo { + pub short: String, + pub version: String, + pub host: Option, + pub commit_hash: Option, + pub commit_date: Option, +} + +pub fn rustc_toolchain_version_info(toolchain: &str) -> Result { + rustc_version_info_inner(None, Some(toolchain)) +} + +pub fn rustc_version_info(rustc: Option<&str>) -> Result { + rustc_version_info_inner(rustc, None) +} + +fn rustc_version_info_inner( + rustc: Option<&str>, + toolchain: Option<&str>, +) -> Result { + let output = if let Some(toolchain) = toolchain { + run_command(&[&rustc.unwrap_or("rustc"), &toolchain, &"-vV"], None) + } else { + run_command(&[&rustc.unwrap_or("rustc"), &"-vV"], None) + }?; let content = std::str::from_utf8(&output.stdout).unwrap_or(""); - for line in content.split('\n').map(|line| line.trim()) { - if !line.starts_with("host:") { - continue; + let mut info = RustcVersionInfo::default(); + let mut lines = content.split('\n'); + info.short = match lines.next() { + Some(s) => s.to_string(), + None => return Err("failed to retrieve rustc version".to_string()), + }; + + for line in lines.map(|line| line.trim()) { + match line.split_once(':') { + Some(("host", data)) => info.host = Some(data.trim().to_string()), + Some(("release", data)) => info.version = data.trim().to_string(), + Some(("commit-hash", data)) => info.commit_hash = Some(data.trim().to_string()), + Some(("commit-date", data)) => info.commit_date = Some(data.trim().to_string()), + _ => {} } - return Ok(line.split(':').nth(1).unwrap().trim().to_string()); } - Err("Cannot find host triple".to_string()) + if info.version.is_empty() { + Err("failed to retrieve rustc version".to_string()) + } else { + Ok(info) + } } -pub fn get_gcc_path() -> Result { - let content = match fs::read_to_string("gcc_path") { +pub fn get_toolchain() -> Result { + let content = match fs::read_to_string("rust-toolchain") { Ok(content) => content, - Err(_) => { - return Err( - "Please put the path to your custom build of libgccjit in the file \ - `gcc_path`, see Readme.md for details" - .into(), - ) - } + Err(_) => return Err("No `rust-toolchain` file found".to_string()), }; match content .split('\n') .map(|line| line.trim()) .filter(|line| !line.is_empty()) + .filter_map(|line| { + if !line.starts_with("channel") { + return None; + } + line.split('"').skip(1).next() + }) .next() { - Some(gcc_path) => { - let path = Path::new(gcc_path); - if !path.exists() { - Err(format!( - "Path `{}` contained in the `gcc_path` file doesn't exist", - gcc_path, - )) - } else { - Ok(gcc_path.into()) - } - } - None => Err("No path found in `gcc_path` file".into()), + Some(toolchain) => Ok(toolchain.to_string()), + None => Err("Couldn't find `channel` in `rust-toolchain` file".to_string()), } } pub struct CloneResult { pub ran_clone: bool, pub repo_name: String, + pub repo_dir: String, } -pub fn git_clone(to_clone: &str, dest: Option<&Path>) -> Result { - let repo_name = to_clone.split('/').last().unwrap(); - let repo_name = match repo_name.strip_suffix(".git") { - Some(n) => n.to_string(), - None => repo_name.to_string(), - }; - - let dest = dest - .map(|dest| dest.join(&repo_name)) - .unwrap_or_else(|| Path::new(&repo_name).into()); +fn git_clone_inner( + to_clone: &str, + dest: &Path, + shallow_clone: bool, + repo_name: String, +) -> Result { if dest.is_dir() { return Ok(CloneResult { ran_clone: false, repo_name, + repo_dir: dest.display().to_string(), }); } - run_command_with_output(&[&"git", &"clone", &to_clone, &dest], None)?; + let mut command: Vec<&dyn AsRef> = vec![&"git", &"clone", &to_clone, &dest]; + if shallow_clone { + command.push(&"--depth"); + command.push(&"1"); + } + run_command_with_output(&command, None)?; Ok(CloneResult { ran_clone: true, repo_name, + repo_dir: dest.display().to_string(), }) } +fn get_repo_name(url: &str) -> String { + let repo_name = url.split('/').last().unwrap(); + match repo_name.strip_suffix(".git") { + Some(n) => n.to_string(), + None => repo_name.to_string(), + } +} + +pub fn git_clone( + to_clone: &str, + dest: Option<&Path>, + shallow_clone: bool, +) -> Result { + let repo_name = get_repo_name(to_clone); + let tmp: PathBuf; + + let dest = match dest { + Some(dest) => dest, + None => { + tmp = repo_name.clone().into(); + &tmp + } + }; + git_clone_inner(to_clone, dest, shallow_clone, repo_name) +} + +/// This function differs from `git_clone` in how it handles *where* the repository will be cloned. +/// In `git_clone`, it is cloned in the provided path. In this function, the path you provide is +/// the parent folder. So if you pass "a" as folder and try to clone "b.git", it will be cloned into +/// `a/b`. +pub fn git_clone_root_dir( + to_clone: &str, + dest_parent_dir: &Path, + shallow_clone: bool, +) -> Result { + let repo_name = get_repo_name(to_clone); + + git_clone_inner( + to_clone, + &dest_parent_dir.join(&repo_name), + shallow_clone, + repo_name, + ) +} + pub fn walk_dir(dir: P, mut dir_cb: D, mut file_cb: F) -> Result<(), String> where P: AsRef, @@ -238,3 +347,105 @@ where } Ok(()) } + +pub fn split_args(args: &str) -> Result, String> { + let mut out = Vec::new(); + let mut start = 0; + let args = args.trim(); + let mut iter = args.char_indices().peekable(); + + while let Some((pos, c)) = iter.next() { + if c == ' ' { + out.push(args[start..pos].to_string()); + let mut found_start = false; + while let Some((pos, c)) = iter.peek() { + if *c != ' ' { + start = *pos; + found_start = true; + break; + } else { + iter.next(); + } + } + if !found_start { + return Ok(out); + } + } else if c == '"' || c == '\'' { + let end = c; + let mut found_end = false; + while let Some((_, c)) = iter.next() { + if c == end { + found_end = true; + break; + } else if c == '\\' { + // We skip the escaped character. + iter.next(); + } + } + if !found_end { + return Err(format!( + "Didn't find `{}` at the end of `{}`", + end, + &args[start..] + )); + } + } else if c == '\\' { + // We skip the escaped character. + iter.next(); + } + } + let s = args[start..].trim(); + if !s.is_empty() { + out.push(s.to_string()); + } + Ok(out) +} + +pub fn remove_file + ?Sized>(file_path: &P) -> Result<(), String> { + std::fs::remove_file(file_path).map_err(|error| { + format!( + "Failed to remove `{}`: {:?}", + file_path.as_ref().display(), + error + ) + }) +} + +pub fn create_symlink, Q: AsRef>(original: P, link: Q) -> Result<(), String> { + #[cfg(windows)] + let symlink = std::os::windows::fs::symlink_file; + #[cfg(not(windows))] + let symlink = std::os::unix::fs::symlink; + + symlink(&original, &link).map_err(|err| { + format!( + "failed to create a symlink `{}` to `{}`: {:?}", + original.as_ref().display(), + link.as_ref().display(), + err, + ) + }) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_split_args() { + // Missing `"` at the end. + assert!(split_args("\"tada").is_err()); + // Missing `'` at the end. + assert!(split_args("\'tada").is_err()); + + assert_eq!( + split_args("a \"b\" c"), + Ok(vec!["a".to_string(), "\"b\"".to_string(), "c".to_string()]) + ); + // Trailing whitespace characters. + assert_eq!( + split_args(" a \"b\" c "), + Ok(vec!["a".to_string(), "\"b\"".to_string(), "c".to_string()]) + ); + } +} diff --git a/cargo.sh b/cargo.sh deleted file mode 100755 index b68a08ee88f80..0000000000000 --- a/cargo.sh +++ /dev/null @@ -1,23 +0,0 @@ -#!/usr/bin/env bash - -if [ -z $CHANNEL ]; then -export CHANNEL='debug' -fi - -pushd $(dirname "$0") >/dev/null -source config.sh - -# read nightly compiler from rust-toolchain file -TOOLCHAIN=$(cat rust-toolchain | grep channel | sed 's/channel = "\(.*\)"/\1/') - -popd >/dev/null - -if [[ $(${RUSTC} -V) != $(${RUSTC} +${TOOLCHAIN} -V) ]]; then - echo "rustc_codegen_gcc is build for $(rustc +${TOOLCHAIN} -V) but the default rustc version is $(rustc -V)." - echo "Using $(rustc +${TOOLCHAIN} -V)." -fi - -cmd=$1 -shift - -RUSTDOCFLAGS="$RUSTFLAGS" cargo +${TOOLCHAIN} $cmd $@ diff --git a/clean_all.sh b/clean_all.sh deleted file mode 100755 index 782bd3e5058c4..0000000000000 --- a/clean_all.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/usr/bin/env bash -set -e -set -v - -rm -rf target/ build_sysroot/{sysroot/,sysroot_src/,target/,Cargo.lock} perf.data{,.old} -rm -rf regex/ simple-raytracer/ diff --git a/config.example.toml b/config.example.toml new file mode 100644 index 0000000000000..dcc414b731001 --- /dev/null +++ b/config.example.toml @@ -0,0 +1,2 @@ +gcc-path = "gcc-build/gcc" +# download-gccjit = true diff --git a/config.sh b/config.sh deleted file mode 100644 index 7ae2175d41de7..0000000000000 --- a/config.sh +++ /dev/null @@ -1,85 +0,0 @@ -set -e - -export CARGO_INCREMENTAL=0 - -if [ -f ./gcc_path ]; then - export GCC_PATH=$(cat gcc_path) -elif (( $use_system_gcc == 1 )); then - echo 'Using system GCC' -else - echo 'Please put the path to your custom build of libgccjit in the file `gcc_path`, see Readme.md for details' - exit 1 -fi - -if [[ -z "$RUSTC" ]]; then - export RUSTC="rustc" -fi - -unamestr=`uname` -if [[ "$unamestr" == 'Linux' ]]; then - dylib_ext='so' -elif [[ "$unamestr" == 'Darwin' ]]; then - dylib_ext='dylib' -else - echo "Unsupported os" - exit 1 -fi - -HOST_TRIPLE=$($RUSTC -vV | grep host | cut -d: -f2 | tr -d " ") -# TODO: remove $OVERWRITE_TARGET_TRIPLE when config.sh is removed. -TARGET_TRIPLE="${OVERWRITE_TARGET_TRIPLE:-$HOST_TRIPLE}" - -linker='' -RUN_WRAPPER='' -if [[ "$HOST_TRIPLE" != "$TARGET_TRIPLE" ]]; then - RUN_WRAPPER=run_in_vm - if [[ "$TARGET_TRIPLE" == "m68k-unknown-linux-gnu" ]]; then - linker='-Clinker=m68k-unknown-linux-gnu-gcc' - elif [[ "$TARGET_TRIPLE" == "aarch64-unknown-linux-gnu" ]]; then - # We are cross-compiling for aarch64. Use the correct linker and run tests in qemu. - linker='-Clinker=aarch64-linux-gnu-gcc' - else - echo "Unknown non-native platform" - fi -fi - -# Since we don't support ThinLTO, disable LTO completely when not trying to do LTO. -# TODO(antoyo): remove when we can handle ThinLTO. -disable_lto_flags='' -if [[ ! -v FAT_LTO ]]; then - disable_lto_flags='-Clto=off' -fi - -if [[ -z "$BUILTIN_BACKEND" ]]; then - export RUSTFLAGS="$CG_RUSTFLAGS $linker -Csymbol-mangling-version=v0 -Cdebuginfo=2 $disable_lto_flags -Zcodegen-backend=$(pwd)/target/${CHANNEL:-debug}/librustc_codegen_gcc.$dylib_ext --sysroot $(pwd)/build_sysroot/sysroot $TEST_FLAGS" -else - export RUSTFLAGS="$CG_RUSTFLAGS $linker -Csymbol-mangling-version=v0 -Cdebuginfo=2 $disable_lto_flags -Zcodegen-backend=gcc $TEST_FLAGS -Cpanic=abort" - - if [[ ! -z "$RUSTC_SYSROOT" ]]; then - export RUSTFLAGS="$RUSTFLAGS --sysroot $RUSTC_SYSROOT" - fi -fi - -# FIXME(antoyo): remove once the atomic shim is gone -if [[ unamestr == 'Darwin' ]]; then - export RUSTFLAGS="$RUSTFLAGS -Clink-arg=-undefined -Clink-arg=dynamic_lookup" -fi - -if [[ -z "$cargo_target_dir" ]]; then - RUST_CMD="$RUSTC $RUSTFLAGS -L crate=target/out --out-dir target/out" - cargo_target_dir="target/out" -else - RUST_CMD="$RUSTC $RUSTFLAGS -L crate=$cargo_target_dir --out-dir $cargo_target_dir" -fi -export RUSTC_LOG=warn # display metadata load errors - -export LD_LIBRARY_PATH="$(pwd)/target/out:$(pwd)/build_sysroot/sysroot/lib/rustlib/$TARGET_TRIPLE/lib" -if [[ ! -z "$:$GCC_PATH" ]]; then - export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:$GCC_PATH" -fi - -export DYLD_LIBRARY_PATH=$LD_LIBRARY_PATH -# NOTE: To avoid the -fno-inline errors, use /opt/gcc/bin/gcc instead of cc. -# To do so, add a symlink for cc to /opt/gcc/bin/gcc in our PATH. -# Another option would be to add the following Rust flag: -Clinker=/opt/gcc/bin/gcc -export PATH="/opt/gcc/bin:/opt/m68k-unknown-linux-gnu/bin:$PATH" diff --git a/crate_patches/0002-rand-Disable-failing-test.patch b/crate_patches/0002-rand-Disable-failing-test.patch deleted file mode 100644 index 449ca5f6e29cd..0000000000000 --- a/crate_patches/0002-rand-Disable-failing-test.patch +++ /dev/null @@ -1,32 +0,0 @@ -From a8fb97120d71252538b6b026695df40d02696bdb Mon Sep 17 00:00:00 2001 -From: bjorn3 -Date: Sat, 15 Aug 2020 20:04:38 +0200 -Subject: [PATCH] [rand] Disable failing test - ---- - src/distributions/uniform.rs | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/src/distributions/uniform.rs b/src/distributions/uniform.rs -index 480b859..c80bb6f 100644 ---- a/src/distributions/uniform.rs -+++ b/src/distributions/uniform.rs -@@ -1085,7 +1085,7 @@ mod tests { - _ => panic!("`UniformDurationMode` was not serialized/deserialized correctly") - } - } -- -+ - #[test] - #[cfg(feature = "serde1")] - fn test_uniform_serialization() { -@@ -1314,6 +1314,7 @@ mod tests { - not(target_arch = "wasm32"), - not(target_arch = "asmjs") - ))] -+ #[ignore] // FIXME - fn test_float_assertions() { - use super::SampleUniform; - use std::panic::catch_unwind; --- -2.20.1 diff --git a/deps/libLLVM-18-rust-1.78.0-nightly.so b/deps/libLLVM-18-rust-1.78.0-nightly.so new file mode 100644 index 0000000000000..c44ca790b4f8c --- /dev/null +++ b/deps/libLLVM-18-rust-1.78.0-nightly.so @@ -0,0 +1 @@ +INPUT(libLLVM.so.18.1-rust-1.78.0-nightly) diff --git a/doc/debugging-gcc-lto.md b/doc/debugging-gcc-lto.md new file mode 100644 index 0000000000000..93b150d768650 --- /dev/null +++ b/doc/debugging-gcc-lto.md @@ -0,0 +1,3 @@ +# How to debug GCC LTO + +Run do the command with `-v -save-temps` and then extract the `lto1` line from the output and run that under the debugger. diff --git a/doc/debugging-libgccjit.md b/doc/debugging-libgccjit.md new file mode 100644 index 0000000000000..be0ec83f7cdc6 --- /dev/null +++ b/doc/debugging-libgccjit.md @@ -0,0 +1,74 @@ +# Debugging libgccjit + +Sometimes, libgccjit will crash and output an error like this: + +``` +during RTL pass: expand +libgccjit.so: error: in expmed_mode_index, at expmed.h:249 +0x7f0da2e61a35 expmed_mode_index + ../../../gcc/gcc/expmed.h:249 +0x7f0da2e61aa4 expmed_op_cost_ptr + ../../../gcc/gcc/expmed.h:271 +0x7f0da2e620dc sdiv_cost_ptr + ../../../gcc/gcc/expmed.h:540 +0x7f0da2e62129 sdiv_cost + ../../../gcc/gcc/expmed.h:558 +0x7f0da2e73c12 expand_divmod(int, tree_code, machine_mode, rtx_def*, rtx_def*, rtx_def*, int) + ../../../gcc/gcc/expmed.c:4335 +0x7f0da2ea1423 expand_expr_real_2(separate_ops*, rtx_def*, machine_mode, expand_modifier) + ../../../gcc/gcc/expr.c:9240 +0x7f0da2cd1a1e expand_gimple_stmt_1 + ../../../gcc/gcc/cfgexpand.c:3796 +0x7f0da2cd1c30 expand_gimple_stmt + ../../../gcc/gcc/cfgexpand.c:3857 +0x7f0da2cd90a9 expand_gimple_basic_block + ../../../gcc/gcc/cfgexpand.c:5898 +0x7f0da2cdade8 execute + ../../../gcc/gcc/cfgexpand.c:6582 +``` + +To see the code which causes this error, call the following function: + +```c +gcc_jit_context_dump_to_file(ctxt, "/tmp/output.c", 1 /* update_locations */) +``` + +This will create a C-like file and add the locations into the IR pointing to this C file. +Then, rerun the program and it will output the location in the second line: + +``` +libgccjit.so: /tmp/something.c:61322:0: error: in expmed_mode_index, at expmed.h:249 +``` + +Or add a breakpoint to `add_error` in gdb and print the line number using: + +``` +p loc->m_line +p loc->m_filename->m_buffer +``` + +To print a debug representation of a tree: + +```c +debug_tree(expr); +``` + +(defined in print-tree.h) + +To print a debug representation of a gimple struct: + +```c +debug_gimple_stmt(gimple_struct) +``` + +To get the `rustc` command to run in `gdb`, add the `--verbose` flag to `cargo build`. + +To have the correct file paths in `gdb` instead of `/usr/src/debug/gcc/libstdc++-v3/libsupc++/eh_personality.cc`: + +Maybe by calling the following at the beginning of gdb: + +``` +set substitute-path /usr/src/debug/gcc /path/to/gcc-repo/gcc +``` + +TODO(antoyo): but that's not what I remember I was doing. diff --git a/doc/errors.md b/doc/errors.md new file mode 100644 index 0000000000000..5727b0ff7c867 --- /dev/null +++ b/doc/errors.md @@ -0,0 +1,27 @@ +# Common errors + +This file lists errors that were encountered and how to fix them. + +### `failed to build archive` error + +When you get this error: + +``` +error: failed to build archive: failed to open object file: No such file or directory (os error 2) +``` + +That can be caused by the fact that you try to compile with `lto = "fat"`, but you didn't compile the sysroot with LTO. +(Not sure if that's the reason since I cannot reproduce anymore. Maybe it happened when forgetting setting `FAT_LTO`.) + +### ld: cannot find crtbegin.o + +When compiling an executable with libgccijt, if setting the `*LIBRARY_PATH` variables to the install directory, you will get the following errors: + +``` +ld: cannot find crtbegin.o: No such file or directory +ld: cannot find -lgcc: No such file or directory +ld: cannot find -lgcc: No such file or directory +libgccjit.so: error: error invoking gcc driver +``` + +To fix this, set the variables to `gcc-build/build/gcc`. diff --git a/doc/subtree.md b/doc/subtree.md new file mode 100644 index 0000000000000..5d7af2a066bd3 --- /dev/null +++ b/doc/subtree.md @@ -0,0 +1,52 @@ +# git subtree sync + +`rustc_codegen_gcc` is a subtree of the rust compiler. As such, it needs to be +sync from time to time to ensure changes that happened on their side are also +included on our side. + +### How to install a forked git-subtree + +Using git-subtree with `rustc` requires a patched git to make it work. +The PR that is needed is [here](https://github.com/gitgitgadget/git/pull/493). +Use the following instructions to install it: + +```bash +git clone git@github.com:tqc/git.git +cd git +git checkout tqc/subtree +make +make install +cd contrib/subtree +make +cp git-subtree ~/bin +``` + +### Syncing with rust compiler + +Do a sync with this command: + +```bash +PATH="$HOME/bin:$PATH" ~/bin/git-subtree push -P compiler/rustc_codegen_gcc/ ../rustc_codegen_gcc/ sync_branch_name +cd ../rustc_codegen_gcc +git checkout master +git pull +git checkout sync_branch_name +git merge master +``` + +To send the changes to the rust repo: + +```bash +cd ../rust +git pull origin master +git checkout -b subtree-update_cg_gcc_YYYY-MM-DD +PATH="$HOME/bin:$PATH" ~/bin/git-subtree pull --prefix=compiler/rustc_codegen_gcc/ https://github.com/rust-lang/rustc_codegen_gcc.git master +git push + +# Immediately merge the merge commit into cg_gcc to prevent merge conflicts when syncing from rust-lang/rust later. +PATH="$HOME/bin:$PATH" ~/bin/git-subtree push -P compiler/rustc_codegen_gcc/ ../rustc_codegen_gcc/ sync_branch_name +``` + +TODO: write a script that does the above. + +https://rust-lang.zulipchat.com/#narrow/stream/301329-t-devtools/topic/subtree.20madness/near/258877725 diff --git a/doc/tips.md b/doc/tips.md new file mode 100644 index 0000000000000..1379f5130be02 --- /dev/null +++ b/doc/tips.md @@ -0,0 +1,72 @@ +# Tips + +The following shows how to do different random small things we encountered and thought could +be useful. + +### How to send arguments to the GCC linker + +``` +CG_RUSTFLAGS="-Clink-args=-save-temps -v" ../y.sh cargo build +``` + +### How to see the personality functions in the asm dump + +``` +CG_RUSTFLAGS="-Clink-arg=-save-temps -v -Clink-arg=-dA" ../y.sh cargo build +``` + +### How to see the LLVM IR for a sysroot crate + +``` +cargo build -v --target x86_64-unknown-linux-gnu -Zbuild-std +# Take the command from the output and add --emit=llvm-ir +``` + +### To prevent the linker from unmangling symbols + +Run with: + +``` +COLLECT_NO_DEMANGLE=1 +``` + +### How to use a custom-build rustc + + * Build the stage2 compiler (`rustup toolchain link debug-current build/x86_64-unknown-linux-gnu/stage2`). + * Clean and rebuild the codegen with `debug-current` in the file `rust-toolchain`. + +### How to use [mem-trace](https://github.com/antoyo/mem-trace) + +`rustc` needs to be built without `jemalloc` so that `mem-trace` can overload `malloc` since `jemalloc` is linked statically, so a `LD_PRELOAD`-ed library won't a chance to intercept the calls to `malloc`. + +### How to generate GIMPLE + +If you need to check what gccjit is generating (GIMPLE), then take a look at how to +generate it in [gimple.md](./doc/gimple.md). + +### How to build a cross-compiling libgccjit + +#### Building libgccjit + + * Follow the instructions on [this repo](https://github.com/cross-cg-gcc-tools/cross-gcc). + +#### Configuring rustc_codegen_gcc + + * Run `./y.sh prepare --cross` so that the sysroot is patched for the cross-compiling case. + * Set the path to the cross-compiling libgccjit in `gcc-path` (in `config.toml`). + * Make sure you have the linker for your target (for instance `m68k-unknown-linux-gnu-gcc`) in your `$PATH`. Currently, the linker name is hardcoded as being `$TARGET-gcc`. Specify the target when building the sysroot: `./y.sh build --target-triple m68k-unknown-linux-gnu`. + * Build your project by specifying the target: `OVERWRITE_TARGET_TRIPLE=m68k-unknown-linux-gnu ../y.sh cargo build --target m68k-unknown-linux-gnu`. + +If the target is not yet supported by the Rust compiler, create a [target specification file](https://docs.rust-embedded.org/embedonomicon/custom-target.html) (note that the `arch` specified in this file must be supported by the rust compiler). +Then, you can use it the following way: + + * Add the target specification file using `--target` as an **absolute** path to build the sysroot: `./y.sh build --target-triple m68k-unknown-linux-gnu --target $(pwd)/m68k-unknown-linux-gnu.json` + * Build your project by specifying the target specification file: `OVERWRITE_TARGET_TRIPLE=m68k-unknown-linux-gnu ../y.sh cargo build --target path/to/m68k-unknown-linux-gnu.json`. + +If you get the following error: + +``` +/usr/bin/ld: unrecognised emulation mode: m68kelf +``` + +Make sure you set `gcc-path` (in `config.toml`) to the install directory. diff --git a/libgccjit.version b/libgccjit.version new file mode 100644 index 0000000000000..41bec6df5d95c --- /dev/null +++ b/libgccjit.version @@ -0,0 +1 @@ +b6f163f52 diff --git a/messages.ftl b/messages.ftl index 5ca0a2e1b6db4..0235384445e71 100644 --- a/messages.ftl +++ b/messages.ftl @@ -20,8 +20,6 @@ codegen_gcc_dynamic_linking_with_lto = cannot prefer dynamic linking when performing LTO .note = only 'staticlib', 'bin', and 'cdylib' outputs are supported with LTO -codegen_gcc_load_bitcode = failed to load bitcode of module "{$name}" - codegen_gcc_lto_disallowed = lto can only be run for executables, cdylibs and static library outputs codegen_gcc_lto_dylib = lto cannot be used for `dylib` crate type without `-Zdylib-lto` diff --git a/patches/0022-core-Disable-not-compiling-tests.patch b/patches/0022-core-Disable-not-compiling-tests.patch index 4db56fa3bd2c7..a7d523f940826 100644 --- a/patches/0022-core-Disable-not-compiling-tests.patch +++ b/patches/0022-core-Disable-not-compiling-tests.patch @@ -39,6 +39,4 @@ index 42a26ae..5ac1042 100644 +#![cfg(test)] #![feature(alloc_layout_extra)] #![feature(array_chunks)] - #![feature(array_methods)] --- -2.21.0 (Apple Git-122) + #![feature(array_windows)] diff --git a/patches/crates/0001-Remove-deny-warnings.patch b/patches/crates/0001-Remove-deny-warnings.patch new file mode 100644 index 0000000000000..66ea1df4e1376 --- /dev/null +++ b/patches/crates/0001-Remove-deny-warnings.patch @@ -0,0 +1,24 @@ +From f4a31d2c57cdbd578b778ab70eb2a0cfb248652c Mon Sep 17 00:00:00 2001 +From: Antoni Boucher +Date: Tue, 5 Mar 2024 12:39:44 -0500 +Subject: [PATCH] Remove #[deny(warnings)] + +--- + src/lib.rs | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/src/lib.rs b/src/lib.rs +index 8ade2881d5..e26c595e38 100644 +--- a/src/lib.rs ++++ b/src/lib.rs +@@ -47,7 +47,6 @@ + )] + #![deny(missing_docs)] + #![deny(missing_debug_implementations)] +-#![doc(test(attr(allow(unused_variables), deny(warnings))))] + #![no_std] + #![cfg_attr(feature = "simd_support", feature(stdsimd, portable_simd))] + #![cfg_attr(doc_cfg, feature(doc_cfg))] +-- +2.44.0 + diff --git a/cross_patches/0001-Disable-libstd-and-libtest-dylib.patch b/patches/cross_patches/0001-Disable-libstd-and-libtest-dylib.patch similarity index 64% rename from cross_patches/0001-Disable-libstd-and-libtest-dylib.patch rename to patches/cross_patches/0001-Disable-libstd-and-libtest-dylib.patch index 74d9c208a05ac..c220f53040f05 100644 --- a/cross_patches/0001-Disable-libstd-and-libtest-dylib.patch +++ b/patches/cross_patches/0001-Disable-libstd-and-libtest-dylib.patch @@ -21,19 +21,3 @@ index 5b21355..cb0c49b 100644 [dependencies] alloc = { path = "../alloc", public = true } -diff --git a/library/test/Cargo.toml b/library/test/Cargo.toml -index 91a1abd..a58c160 100644 ---- a/library/test/Cargo.toml -+++ b/library/test/Cargo.toml -@@ -4,7 +4,7 @@ version = "0.0.0" - edition = "2021" - - [lib] --crate-type = ["dylib", "rlib"] -+crate-type = ["rlib"] - - [dependencies] - getopts = { version = "0.2.21", features = ['rustc-dep-of-std'] } --- -2.42.0 - diff --git a/rust-toolchain b/rust-toolchain index 1962c217258a4..a0ac82866609e 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2023-11-17" +channel = "nightly-2024-03-05" components = ["rust-src", "rustc-dev", "llvm-tools-preview"] diff --git a/rustup.sh b/rustup.sh deleted file mode 100755 index a4f938e4b5b76..0000000000000 --- a/rustup.sh +++ /dev/null @@ -1,29 +0,0 @@ -#!/usr/bin/env bash - -set -e - -case $1 in - "prepare") - TOOLCHAIN=$(date +%Y-%m-%d) - - echo "=> Installing new nightly" - rustup toolchain install --profile minimal nightly-${TOOLCHAIN} # Sanity check to see if the nightly exists - echo nightly-${TOOLCHAIN} > rust-toolchain - - echo "=> Uninstalling all old nightlies" - for nightly in $(rustup toolchain list | grep nightly | grep -v $TOOLCHAIN | grep -v nightly-x86_64); do - rustup toolchain uninstall $nightly - done - - ./clean_all.sh - ./y.sh prepare - ;; - "commit") - git add rust-toolchain - git commit -m "Rustup to $(rustc -V)" - ;; - *) - echo "Unknown command '$1'" - echo "Usage: ./rustup.sh prepare|commit" - ;; -esac diff --git a/src/abi.rs b/src/abi.rs index f601cd95f2a68..b098594dbcc35 100644 --- a/src/abi.rs +++ b/src/abi.rs @@ -18,17 +18,16 @@ impl<'a, 'gcc, 'tcx> AbiBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> { fn get_param(&mut self, index: usize) -> Self::Value { let func = self.current_func(); let param = func.get_param(index as i32); - let on_stack = - if let Some(on_stack_param_indices) = self.on_stack_function_params.borrow().get(&func) { - on_stack_param_indices.contains(&index) - } - else { - false - }; + let on_stack = if let Some(on_stack_param_indices) = + self.on_stack_function_params.borrow().get(&func) + { + on_stack_param_indices.contains(&index) + } else { + false + }; if on_stack { param.to_lvalue().get_address(None) - } - else { + } else { param.to_rvalue() } } @@ -37,13 +36,14 @@ impl<'a, 'gcc, 'tcx> AbiBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> { impl GccType for CastTarget { fn gcc_type<'gcc>(&self, cx: &CodegenCx<'gcc, '_>) -> Type<'gcc> { let rest_gcc_unit = self.rest.unit.gcc_type(cx); - let (rest_count, rem_bytes) = - if self.rest.unit.size.bytes() == 0 { - (0, 0) - } - else { - (self.rest.total.bytes() / self.rest.unit.size.bytes(), self.rest.total.bytes() % self.rest.unit.size.bytes()) - }; + let (rest_count, rem_bytes) = if self.rest.unit.size.bytes() == 0 { + (0, 0) + } else { + ( + self.rest.total.bytes() / self.rest.unit.size.bytes(), + self.rest.total.bytes() % self.rest.unit.size.bytes(), + ) + }; if self.prefix.iter().all(|x| x.is_none()) { // Simplify to a single unit when there is no prefix and size <= unit size @@ -61,9 +61,7 @@ impl GccType for CastTarget { let mut args: Vec<_> = self .prefix .iter() - .flat_map(|option_reg| { - option_reg.map(|reg| reg.gcc_type(cx)) - }) + .flat_map(|option_reg| option_reg.map(|reg| reg.gcc_type(cx))) .chain((0..rest_count).map(|_| rest_gcc_unit)) .collect(); @@ -86,12 +84,10 @@ impl GccType for Reg { fn gcc_type<'gcc>(&self, cx: &CodegenCx<'gcc, '_>) -> Type<'gcc> { match self.kind { RegKind::Integer => cx.type_ix(self.size.bits()), - RegKind::Float => { - match self.size.bits() { - 32 => cx.type_f32(), - 64 => cx.type_f64(), - _ => bug!("unsupported float: {:?}", self), - } + RegKind::Float => match self.size.bits() { + 32 => cx.type_f32(), + 64 => cx.type_f64(), + _ => bug!("unsupported float: {:?}", self), }, RegKind::Vector => unimplemented!(), //cx.type_vector(cx.type_i8(), self.size.bytes()), } @@ -119,19 +115,18 @@ impl<'gcc, 'tcx> FnAbiGccExt<'gcc, 'tcx> for FnAbi<'tcx, Ty<'tcx>> { // This capacity calculation is approximate. let mut argument_tys = Vec::with_capacity( - self.args.len() + if let PassMode::Indirect { .. } = self.ret.mode { 1 } else { 0 } + self.args.len() + if let PassMode::Indirect { .. } = self.ret.mode { 1 } else { 0 }, ); - let return_type = - match self.ret.mode { - PassMode::Ignore => cx.type_void(), - PassMode::Direct(_) | PassMode::Pair(..) => self.ret.layout.immediate_gcc_type(cx), - PassMode::Cast { ref cast, .. } => cast.gcc_type(cx), - PassMode::Indirect { .. } => { - argument_tys.push(cx.type_ptr_to(self.ret.memory_ty(cx))); - cx.type_void() - } - }; + let return_type = match self.ret.mode { + PassMode::Ignore => cx.type_void(), + PassMode::Direct(_) | PassMode::Pair(..) => self.ret.layout.immediate_gcc_type(cx), + PassMode::Cast { ref cast, .. } => cast.gcc_type(cx), + PassMode::Indirect { .. } => { + argument_tys.push(cx.type_ptr_to(self.ret.memory_ty(cx))); + cx.type_void() + } + }; #[cfg(feature = "master")] let mut non_null_args = Vec::new(); @@ -149,17 +144,23 @@ impl<'gcc, 'tcx> FnAbiGccExt<'gcc, 'tcx> for FnAbi<'tcx, Ty<'tcx>> { ty }; #[cfg(not(feature = "master"))] - let apply_attrs = |ty: Type<'gcc>, _attrs: &ArgAttributes, _arg_index: usize| { - ty - }; + let apply_attrs = |ty: Type<'gcc>, _attrs: &ArgAttributes, _arg_index: usize| ty; for arg in self.args.iter() { let arg_ty = match arg.mode { PassMode::Ignore => continue, PassMode::Pair(a, b) => { let arg_pos = argument_tys.len(); - argument_tys.push(apply_attrs(arg.layout.scalar_pair_element_gcc_type(cx, 0), &a, arg_pos)); - argument_tys.push(apply_attrs(arg.layout.scalar_pair_element_gcc_type(cx, 1), &b, arg_pos + 1)); + argument_tys.push(apply_attrs( + arg.layout.scalar_pair_element_gcc_type(cx, 0), + &a, + arg_pos, + )); + argument_tys.push(apply_attrs( + arg.layout.scalar_pair_element_gcc_type(cx, 1), + &b, + arg_pos + 1, + )); continue; } PassMode::Cast { ref cast, pad_i32 } => { @@ -174,14 +175,17 @@ impl<'gcc, 'tcx> FnAbiGccExt<'gcc, 'tcx> for FnAbi<'tcx, Ty<'tcx>> { // This is a "byval" argument, so we don't apply the `restrict` attribute on it. on_stack_param_indices.insert(argument_tys.len()); arg.memory_ty(cx) - }, - PassMode::Direct(attrs) => apply_attrs(arg.layout.immediate_gcc_type(cx), &attrs, argument_tys.len()), + } + PassMode::Direct(attrs) => { + apply_attrs(arg.layout.immediate_gcc_type(cx), &attrs, argument_tys.len()) + } PassMode::Indirect { attrs, meta_attrs: None, on_stack: false } => { apply_attrs(cx.type_ptr_to(arg.memory_ty(cx)), &attrs, argument_tys.len()) } PassMode::Indirect { attrs, meta_attrs: Some(meta_attrs), on_stack } => { assert!(!on_stack); - let ty = apply_attrs(cx.type_ptr_to(arg.memory_ty(cx)), &attrs, argument_tys.len()); + let ty = + apply_attrs(cx.type_ptr_to(arg.memory_ty(cx)), &attrs, argument_tys.len()); apply_attrs(ty, &meta_attrs, argument_tys.len()) } }; @@ -207,15 +211,14 @@ impl<'gcc, 'tcx> FnAbiGccExt<'gcc, 'tcx> for FnAbi<'tcx, Ty<'tcx>> { fn ptr_to_gcc_type(&self, cx: &CodegenCx<'gcc, 'tcx>) -> Type<'gcc> { // FIXME(antoyo): Should we do something with `FnAbiGcc::fn_attributes`? - let FnAbiGcc { - return_type, - arguments_type, - is_c_variadic, + let FnAbiGcc { return_type, arguments_type, is_c_variadic, on_stack_param_indices, .. } = + self.gcc_type(cx); + let pointer_type = + cx.context.new_function_pointer_type(None, return_type, &arguments_type, is_c_variadic); + cx.on_stack_params.borrow_mut().insert( + pointer_type.dyncast_function_ptr_type().expect("function ptr type"), on_stack_param_indices, - .. - } = self.gcc_type(cx); - let pointer_type = cx.context.new_function_pointer_type(None, return_type, &arguments_type, is_c_variadic); - cx.on_stack_params.borrow_mut().insert(pointer_type.dyncast_function_ptr_type().expect("function ptr type"), on_stack_param_indices); + ); pointer_type } } diff --git a/src/allocator.rs b/src/allocator.rs index 7c7044830f3d4..deeb55e9d128e 100644 --- a/src/allocator.rs +++ b/src/allocator.rs @@ -1,4 +1,4 @@ -#[cfg(feature="master")] +#[cfg(feature = "master")] use gccjit::FnAttribute; use gccjit::{Context, FunctionType, GlobalKind, ToRValue, Type}; use rustc_ast::expand::allocator::{ @@ -11,15 +11,20 @@ use rustc_session::config::OomStrategy; use crate::GccContext; -pub(crate) unsafe fn codegen(tcx: TyCtxt<'_>, mods: &mut GccContext, _module_name: &str, kind: AllocatorKind, alloc_error_handler_kind: AllocatorKind) { +pub(crate) unsafe fn codegen( + tcx: TyCtxt<'_>, + mods: &mut GccContext, + _module_name: &str, + kind: AllocatorKind, + alloc_error_handler_kind: AllocatorKind, +) { let context = &mods.context; - let usize = - match tcx.sess.target.pointer_width { - 16 => context.new_type::(), - 32 => context.new_type::(), - 64 => context.new_type::(), - tws => bug!("Unsupported target word size for int: {}", tws), - }; + let usize = match tcx.sess.target.pointer_width { + 16 => context.new_type::(), + 32 => context.new_type::(), + 64 => context.new_type::(), + tws => bug!("Unsupported target word size for int: {}", tws), + }; let i8 = context.new_type::(); let i8p = i8.make_pointer(); @@ -58,7 +63,7 @@ pub(crate) unsafe fn codegen(tcx: TyCtxt<'_>, mods: &mut GccContext, _module_nam tcx, context, "__rust_alloc_error_handler", - &alloc_error_handler_name(alloc_error_handler_kind), + alloc_error_handler_name(alloc_error_handler_kind), &[usize, usize], None, ); @@ -85,24 +90,42 @@ fn create_wrapper_function( ) { let void = context.new_type::<()>(); - let args: Vec<_> = types.iter().enumerate() - .map(|(index, typ)| context.new_parameter(None, *typ, &format!("param{}", index))) + let args: Vec<_> = types + .iter() + .enumerate() + .map(|(index, typ)| context.new_parameter(None, *typ, format!("param{}", index))) .collect(); - let func = context.new_function(None, FunctionType::Exported, output.unwrap_or(void), &args, from_name, false); + let func = context.new_function( + None, + FunctionType::Exported, + output.unwrap_or(void), + &args, + from_name, + false, + ); if tcx.sess.default_hidden_visibility() { - #[cfg(feature="master")] + #[cfg(feature = "master")] func.add_attribute(FnAttribute::Visibility(gccjit::Visibility::Hidden)); } if tcx.sess.must_emit_unwind_tables() { // TODO(antoyo): emit unwind tables. } - let args: Vec<_> = types.iter().enumerate() - .map(|(index, typ)| context.new_parameter(None, *typ, &format!("param{}", index))) + let args: Vec<_> = types + .iter() + .enumerate() + .map(|(index, typ)| context.new_parameter(None, *typ, format!("param{}", index))) .collect(); - let callee = context.new_function(None, FunctionType::Extern, output.unwrap_or(void), &args, to_name, false); - #[cfg(feature="master")] + let callee = context.new_function( + None, + FunctionType::Extern, + output.unwrap_or(void), + &args, + to_name, + false, + ); + #[cfg(feature = "master")] callee.add_attribute(FnAttribute::Visibility(gccjit::Visibility::Hidden)); let block = func.new_block("entry"); @@ -116,8 +139,7 @@ fn create_wrapper_function( //llvm::LLVMSetTailCall(ret, True); if output.is_some() { block.end_with_return(None, ret); - } - else { + } else { block.end_with_void_return(None); } diff --git a/src/asm.rs b/src/asm.rs index 78e8e32b97299..a237f3e6490cb 100644 --- a/src/asm.rs +++ b/src/asm.rs @@ -2,7 +2,10 @@ use gccjit::{LValue, RValue, ToRValue, Type}; use rustc_ast::ast::{InlineAsmOptions, InlineAsmTemplatePiece}; use rustc_codegen_ssa::mir::operand::OperandValue; use rustc_codegen_ssa::mir::place::PlaceRef; -use rustc_codegen_ssa::traits::{AsmBuilderMethods, AsmMethods, BaseTypeMethods, BuilderMethods, GlobalAsmOperandRef, InlineAsmOperandRef}; +use rustc_codegen_ssa::traits::{ + AsmBuilderMethods, AsmMethods, BaseTypeMethods, BuilderMethods, GlobalAsmOperandRef, + InlineAsmOperandRef, +}; use rustc_middle::{bug, ty::Instance}; use rustc_span::Span; @@ -11,11 +14,10 @@ use rustc_target::asm::*; use std::borrow::Cow; use crate::builder::Builder; +use crate::callee::get_fn; use crate::context::CodegenCx; use crate::errors::UnwindingInlineAsm; use crate::type_of::LayoutGccExt; -use crate::callee::get_fn; - // Rust asm! and GCC Extended Asm semantics differ substantially. // @@ -68,7 +70,6 @@ use crate::callee::get_fn; const ATT_SYNTAX_INS: &str = ".att_syntax noprefix\n\t"; const INTEL_SYNTAX_INS: &str = "\n\t.intel_syntax noprefix"; - struct AsmOutOperand<'a, 'tcx, 'gcc> { rust_idx: usize, constraint: &'a str, @@ -76,13 +77,13 @@ struct AsmOutOperand<'a, 'tcx, 'gcc> { readwrite: bool, tmp_var: LValue<'gcc>, - out_place: Option>> + out_place: Option>>, } struct AsmInOperand<'a, 'tcx> { rust_idx: usize, constraint: Cow<'a, str>, - val: RValue<'tcx> + val: RValue<'tcx>, } impl AsmOutOperand<'_, '_, '_> { @@ -95,23 +96,28 @@ impl AsmOutOperand<'_, '_, '_> { res.push('&'); } - res.push_str(&self.constraint); + res.push_str(self.constraint); res } } enum ConstraintOrRegister { Constraint(&'static str), - Register(&'static str) + Register(&'static str), } - impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> { - fn codegen_inline_asm(&mut self, template: &[InlineAsmTemplatePiece], rust_operands: &[InlineAsmOperandRef<'tcx, Self>], options: InlineAsmOptions, span: &[Span], instance: Instance<'_>, _dest_catch_funclet: Option<(Self::BasicBlock, Self::BasicBlock, Option<&Self::Funclet>)>) { + fn codegen_inline_asm( + &mut self, + template: &[InlineAsmTemplatePiece], + rust_operands: &[InlineAsmOperandRef<'tcx, Self>], + options: InlineAsmOptions, + span: &[Span], + instance: Instance<'_>, + _dest_catch_funclet: Option<(Self::BasicBlock, Self::BasicBlock, Option<&Self::Funclet>)>, + ) { if options.contains(InlineAsmOptions::MAY_UNWIND) { - self.sess().dcx() - .create_err(UnwindingInlineAsm { span: span[0] }) - .emit(); + self.sess().dcx().create_err(UnwindingInlineAsm { span: span[0] }).emit(); return; } @@ -157,32 +163,40 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> { use ConstraintOrRegister::*; let (constraint, ty) = match (reg_to_gcc(reg), place) { - (Constraint(constraint), Some(place)) => (constraint, place.layout.gcc_type(self.cx)), + (Constraint(constraint), Some(place)) => { + (constraint, place.layout.gcc_type(self.cx)) + } // When `reg` is a class and not an explicit register but the out place is not specified, // we need to create an unused output variable to assign the output to. This var // needs to be of a type that's "compatible" with the register class, but specific type // doesn't matter. - (Constraint(constraint), None) => (constraint, dummy_output_type(self.cx, reg.reg_class())), + (Constraint(constraint), None) => { + (constraint, dummy_output_type(self.cx, reg.reg_class())) + } (Register(_), Some(_)) => { // left for the next pass - continue - }, + continue; + } (Register(reg_name), None) => { // `clobber_abi` can add lots of clobbers that are not supported by the target, // such as AVX-512 registers, so we just ignore unsupported registers - let is_target_supported = reg.reg_class().supported_types(asm_arch).iter() - .any(|&(_, feature)| { - if let Some(feature) = feature { - self.tcx.asm_target_features(instance.def_id()).contains(&feature) - } else { - true // Register class is unconditionally supported - } - }); + let is_target_supported = + reg.reg_class().supported_types(asm_arch).iter().any( + |&(_, feature)| { + if let Some(feature) = feature { + self.tcx + .asm_target_features(instance.def_id()) + .contains(&feature) + } else { + true // Register class is unconditionally supported + } + }, + ); if is_target_supported && !clobbers.contains(®_name) { clobbers.push(reg_name); } - continue + continue; } }; @@ -193,7 +207,7 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> { late, readwrite: false, tmp_var, - out_place: place + out_place: place, }); } @@ -202,23 +216,22 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> { inputs.push(AsmInOperand { constraint: Cow::Borrowed(constraint), rust_idx, - val: value.immediate() + val: value.immediate(), }); - } - else { + } else { // left for the next pass - continue + continue; } } InlineAsmOperandRef::InOut { reg, late, in_value, out_place } => { - let constraint = if let ConstraintOrRegister::Constraint(constraint) = reg_to_gcc(reg) { - constraint - } - else { - // left for the next pass - continue - }; + let constraint = + if let ConstraintOrRegister::Constraint(constraint) = reg_to_gcc(reg) { + constraint + } else { + // left for the next pass + continue; + }; // Rustc frontend guarantees that input and output types are "compatible", // so we can just use input var's type for the output variable. @@ -249,7 +262,7 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> { inputs.push(AsmInOperand { constraint, rust_idx, - val: in_value.immediate() + val: in_value.immediate(), }); } } @@ -267,7 +280,8 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> { InlineAsmOperandRef::SymStatic { def_id } => { // TODO(@Amanieu): Additional mangling is needed on // some targets to add a leading underscore (Mach-O). - constants_len += self.tcx.symbol_name(Instance::mono(self.tcx, def_id)).name.len(); + constants_len += + self.tcx.symbol_name(Instance::mono(self.tcx, def_id)).name.len(); } } } @@ -280,10 +294,9 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> { if let ConstraintOrRegister::Register(reg_name) = reg_to_gcc(reg) { let out_place = if let Some(place) = place { place - } - else { + } else { // processed in the previous pass - continue + continue; }; let ty = out_place.layout.gcc_type(self.cx); @@ -291,12 +304,12 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> { tmp_var.set_register_name(reg_name); outputs.push(AsmOutOperand { - constraint: "r".into(), + constraint: "r", rust_idx, late, readwrite: false, tmp_var, - out_place: Some(out_place) + out_place: Some(out_place), }); } @@ -314,7 +327,7 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> { inputs.push(AsmInOperand { constraint: "r".into(), rust_idx, - val: reg_var.to_rvalue() + val: reg_var.to_rvalue(), }); } @@ -330,7 +343,7 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> { tmp_var.set_register_name(reg_name); outputs.push(AsmOutOperand { - constraint: "r".into(), + constraint: "r", rust_idx, late, readwrite: false, @@ -342,7 +355,7 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> { inputs.push(AsmInOperand { constraint, rust_idx, - val: in_value.immediate() + val: in_value.immediate(), }); } @@ -373,7 +386,8 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> { // 3. Build the template string - let mut template_str = String::with_capacity(estimate_template_length(template, constants_len, att_dialect)); + let mut template_str = + String::with_capacity(estimate_template_length(template, constants_len, att_dialect)); if att_dialect { template_str.push_str(ATT_SYNTAX_INS); } @@ -383,16 +397,15 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> { InlineAsmTemplatePiece::String(ref string) => { for char in string.chars() { // TODO(antoyo): might also need to escape | if rustc doesn't do it. - let escaped_char = - match char { - '%' => "%%", - '{' => "%{", - '}' => "%}", - _ => { - template_str.push(char); - continue; - }, - }; + let escaped_char = match char { + '%' => "%%", + '{' => "%{", + '}' => "%}", + _ => { + template_str.push(char); + continue; + } + }; template_str.push_str(escaped_char); } } @@ -408,9 +421,10 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> { }; match rust_operands[operand_idx] { - InlineAsmOperandRef::Out { reg, .. } => { + InlineAsmOperandRef::Out { reg, .. } => { let modifier = modifier_to_gcc(asm_arch, reg.reg_class(), modifier); - let gcc_index = outputs.iter() + let gcc_index = outputs + .iter() .position(|op| operand_idx == op.rust_idx) .expect("wrong rust index"); push_to_template(modifier, gcc_index); @@ -418,7 +432,8 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> { InlineAsmOperandRef::In { reg, .. } => { let modifier = modifier_to_gcc(asm_arch, reg.reg_class(), modifier); - let in_gcc_index = inputs.iter() + let in_gcc_index = inputs + .iter() .position(|op| operand_idx == op.rust_idx) .expect("wrong rust index"); let gcc_index = in_gcc_index + outputs.len(); @@ -429,7 +444,8 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> { let modifier = modifier_to_gcc(asm_arch, reg.reg_class(), modifier); // The input register is tied to the output, so we can just use the index of the output register - let gcc_index = outputs.iter() + let gcc_index = outputs + .iter() .position(|op| operand_idx == op.rust_idx) .expect("wrong rust index"); push_to_template(modifier, gcc_index); @@ -496,7 +512,8 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> { } if options.contains(InlineAsmOptions::NORETURN) { let builtin_unreachable = self.context.get_builtin_function("__builtin_unreachable"); - let builtin_unreachable: RValue<'gcc> = unsafe { std::mem::transmute(builtin_unreachable) }; + let builtin_unreachable: RValue<'gcc> = + unsafe { std::mem::transmute(builtin_unreachable) }; self.call(self.type_void(), None, None, builtin_unreachable, &[], None); } @@ -517,19 +534,23 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> { } } -fn estimate_template_length(template: &[InlineAsmTemplatePiece], constants_len: usize, att_dialect: bool) -> usize { - let len: usize = template.iter().map(|piece| { - match *piece { - InlineAsmTemplatePiece::String(ref string) => { - string.len() - } - InlineAsmTemplatePiece::Placeholder { .. } => { - // '%' + 1 char modifier + 1 char index - 3 +fn estimate_template_length( + template: &[InlineAsmTemplatePiece], + constants_len: usize, + att_dialect: bool, +) -> usize { + let len: usize = template + .iter() + .map(|piece| { + match *piece { + InlineAsmTemplatePiece::String(ref string) => string.len(), + InlineAsmTemplatePiece::Placeholder { .. } => { + // '%' + 1 char modifier + 1 char index + 3 + } } - } - }) - .sum(); + }) + .sum(); // increase it by 5% to account for possible '%' signs that'll be duplicated // I pulled the number out of blue, but should be fair enough @@ -562,7 +583,7 @@ fn reg_to_gcc(reg: InlineAsmRegOrRegClass) -> ConstraintOrRegister { _ => unimplemented!(), } - }, + } // They can be retrieved from https://gcc.gnu.org/onlinedocs/gcc/Machine-Constraints.html InlineAsmRegOrRegClass::RegClass(reg) => match reg { InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::reg) => "r", @@ -610,7 +631,7 @@ fn reg_to_gcc(reg: InlineAsmRegOrRegClass) -> ConstraintOrRegister { InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::cr) | InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::xer) => { unreachable!("clobber-only") - }, + } InlineAsmRegClass::RiscV(RiscVInlineAsmRegClass::reg) => "r", InlineAsmRegClass::RiscV(RiscVInlineAsmRegClass::freg) => "f", InlineAsmRegClass::RiscV(RiscVInlineAsmRegClass::vreg) => { @@ -637,7 +658,7 @@ fn reg_to_gcc(reg: InlineAsmRegOrRegClass) -> ConstraintOrRegister { InlineAsmRegClass::S390x(S390xInlineAsmRegClass::reg_addr) => "a", InlineAsmRegClass::S390x(S390xInlineAsmRegClass::freg) => "f", InlineAsmRegClass::Err => unreachable!(), - } + }, }; ConstraintOrRegister::Constraint(constraint) @@ -653,7 +674,7 @@ fn dummy_output_type<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, reg: InlineAsmRegCl | InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::vreg_low16) => { unimplemented!() } - InlineAsmRegClass::Arm(ArmInlineAsmRegClass::reg)=> cx.type_i32(), + InlineAsmRegClass::Arm(ArmInlineAsmRegClass::reg) => cx.type_i32(), InlineAsmRegClass::Arm(ArmInlineAsmRegClass::sreg) | InlineAsmRegClass::Arm(ArmInlineAsmRegClass::sreg_low16) => cx.type_f32(), InlineAsmRegClass::Arm(ArmInlineAsmRegClass::dreg) @@ -686,7 +707,7 @@ fn dummy_output_type<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, reg: InlineAsmRegCl InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::cr) | InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::xer) => { unreachable!("clobber-only") - }, + } InlineAsmRegClass::RiscV(RiscVInlineAsmRegClass::reg) => cx.type_i32(), InlineAsmRegClass::RiscV(RiscVInlineAsmRegClass::freg) => cx.type_f32(), InlineAsmRegClass::RiscV(RiscVInlineAsmRegClass::vreg) => cx.type_f32(), @@ -704,9 +725,9 @@ fn dummy_output_type<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, reg: InlineAsmRegCl InlineAsmRegClass::Wasm(WasmInlineAsmRegClass::local) => cx.type_i32(), InlineAsmRegClass::SpirV(SpirVInlineAsmRegClass::reg) => { bug!("LLVM backend does not support SPIR-V") - }, + } InlineAsmRegClass::S390x( - S390xInlineAsmRegClass::reg | S390xInlineAsmRegClass::reg_addr + S390xInlineAsmRegClass::reg | S390xInlineAsmRegClass::reg_addr, ) => cx.type_i32(), InlineAsmRegClass::S390x(S390xInlineAsmRegClass::freg) => cx.type_f64(), InlineAsmRegClass::Err => unreachable!(), @@ -714,7 +735,13 @@ fn dummy_output_type<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, reg: InlineAsmRegCl } impl<'gcc, 'tcx> AsmMethods<'tcx> for CodegenCx<'gcc, 'tcx> { - fn codegen_global_asm(&self, template: &[InlineAsmTemplatePiece], operands: &[GlobalAsmOperandRef<'tcx>], options: InlineAsmOptions, _line_spans: &[Span]) { + fn codegen_global_asm( + &self, + template: &[InlineAsmTemplatePiece], + operands: &[GlobalAsmOperandRef<'tcx>], + options: InlineAsmOptions, + _line_spans: &[Span], + ) { let asm_arch = self.tcx.sess.asm_arch.unwrap(); // Default to Intel syntax on x86 @@ -732,15 +759,17 @@ impl<'gcc, 'tcx> AsmMethods<'tcx> for CodegenCx<'gcc, 'tcx> { let mut index = 0; while index < string.len() { // NOTE: gcc does not allow inline comment, so remove them. - let comment_index = string[index..].find("//") + let comment_index = string[index..] + .find("//") .map(|comment_index| comment_index + index) .unwrap_or(string.len()); template_str.push_str(&string[index..comment_index]); - index = string[comment_index..].find('\n') + index = string[comment_index..] + .find('\n') .map(|index| index + comment_index) .unwrap_or(string.len()); } - }, + } InlineAsmTemplatePiece::Placeholder { operand_idx, modifier: _, span: _ } => { match operands[operand_idx] { GlobalAsmOperandRef::Const { ref string } => { @@ -782,14 +811,22 @@ impl<'gcc, 'tcx> AsmMethods<'tcx> for CodegenCx<'gcc, 'tcx> { } } -fn modifier_to_gcc(arch: InlineAsmArch, reg: InlineAsmRegClass, modifier: Option) -> Option { +fn modifier_to_gcc( + arch: InlineAsmArch, + reg: InlineAsmRegClass, + modifier: Option, +) -> Option { // The modifiers can be retrieved from // https://gcc.gnu.org/onlinedocs/gcc/Modifiers.html#Modifiers match reg { InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::reg) => modifier, InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::vreg) | InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::vreg_low16) => { - if modifier == Some('v') { None } else { modifier } + if modifier == Some('v') { + None + } else { + modifier + } } InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::preg) => { unreachable!("clobber-only") @@ -821,7 +858,13 @@ fn modifier_to_gcc(arch: InlineAsmArch, reg: InlineAsmRegClass, modifier: Option } InlineAsmRegClass::X86(X86InlineAsmRegClass::reg) | InlineAsmRegClass::X86(X86InlineAsmRegClass::reg_abcd) => match modifier { - None => if arch == InlineAsmArch::X86_64 { Some('q') } else { Some('k') }, + None => { + if arch == InlineAsmArch::X86_64 { + Some('q') + } else { + Some('k') + } + } Some('l') => Some('b'), Some('h') => Some('h'), Some('x') => Some('w'), diff --git a/src/attributes.rs b/src/attributes.rs index 142f86b003ddb..8602566ab8fa2 100644 --- a/src/attributes.rs +++ b/src/attributes.rs @@ -1,21 +1,24 @@ -#[cfg(feature="master")] +#[cfg(feature = "master")] use gccjit::FnAttribute; use gccjit::Function; -use rustc_attr::InstructionSetAttr; -#[cfg(feature="master")] +#[cfg(feature = "master")] use rustc_attr::InlineAttr; -use rustc_middle::ty; -#[cfg(feature="master")] +use rustc_attr::InstructionSetAttr; +#[cfg(feature = "master")] use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; +use rustc_middle::ty; use rustc_span::symbol::sym; -use crate::{context::CodegenCx, errors::TiedTargetFeatures}; use crate::gcc_util::{check_tied_features, to_gcc_features}; +use crate::{context::CodegenCx, errors::TiedTargetFeatures}; /// Get GCC attribute for the provided inline heuristic. -#[cfg(feature="master")] +#[cfg(feature = "master")] #[inline] -fn inline_attr<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, inline: InlineAttr) -> Option> { +fn inline_attr<'gcc, 'tcx>( + cx: &CodegenCx<'gcc, 'tcx>, + inline: InlineAttr, +) -> Option> { match inline { InlineAttr::Hint => Some(FnAttribute::Inline), InlineAttr::Always => Some(FnAttribute::AlwaysInline), @@ -34,24 +37,22 @@ fn inline_attr<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, inline: InlineAttr) -> Op /// attributes. pub fn from_fn_attrs<'gcc, 'tcx>( cx: &CodegenCx<'gcc, 'tcx>, - #[cfg_attr(not(feature="master"), allow(unused_variables))] - func: Function<'gcc>, + #[cfg_attr(not(feature = "master"), allow(unused_variables))] func: Function<'gcc>, instance: ty::Instance<'tcx>, ) { let codegen_fn_attrs = cx.tcx.codegen_fn_attrs(instance.def_id()); - #[cfg(feature="master")] + #[cfg(feature = "master")] { - let inline = - if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::NAKED) { - InlineAttr::Never - } - else if codegen_fn_attrs.inline == InlineAttr::None && instance.def.requires_inline(cx.tcx) { - InlineAttr::Hint - } - else { - codegen_fn_attrs.inline - }; + let inline = if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::NAKED) { + InlineAttr::Never + } else if codegen_fn_attrs.inline == InlineAttr::None + && instance.def.requires_inline(cx.tcx) + { + InlineAttr::Hint + } else { + codegen_fn_attrs.inline + }; if let Some(attr) = inline_attr(cx, inline) { if let FnAttribute::AlwaysInline = attr { func.add_attribute(FnAttribute::Inline); @@ -70,18 +71,21 @@ pub fn from_fn_attrs<'gcc, 'tcx>( } } - let function_features = - codegen_fn_attrs.target_features.iter().map(|features| features.as_str()).collect::>(); + let function_features = codegen_fn_attrs + .target_features + .iter() + .map(|features| features.as_str()) + .collect::>(); - if let Some(features) = check_tied_features(cx.tcx.sess, &function_features.iter().map(|features| (*features, true)).collect()) { - let span = cx.tcx + if let Some(features) = check_tied_features( + cx.tcx.sess, + &function_features.iter().map(|features| (*features, true)).collect(), + ) { + let span = cx + .tcx .get_attr(instance.def_id(), sym::target_feature) .map_or_else(|| cx.tcx.def_span(instance.def_id()), |a| a.span); - cx.tcx.dcx().create_err(TiedTargetFeatures { - features: features.join(", "), - span, - }) - .emit(); + cx.tcx.dcx().create_err(TiedTargetFeatures { features: features.join(", "), span }).emit(); return; } @@ -105,24 +109,25 @@ pub fn from_fn_attrs<'gcc, 'tcx>( // compiling Rust for Linux: // SSE register return with SSE disabled // TODO(antoyo): support soft-float and retpoline-external-thunk. - if feature.contains("soft-float") || feature.contains("retpoline-external-thunk") || *feature == "-sse" { + if feature.contains("soft-float") + || feature.contains("retpoline-external-thunk") + || *feature == "-sse" + { return None; } if feature.starts_with('-') { Some(format!("no{}", feature)) - } - else if feature.starts_with('+') { + } else if feature.starts_with('+') { Some(feature[1..].to_string()) - } - else { + } else { Some(feature.to_string()) } }) .collect::>() .join(","); if !target_features.is_empty() { - #[cfg(feature="master")] + #[cfg(feature = "master")] func.add_attribute(FnAttribute::Target(&target_features)); } } diff --git a/src/back/lto.rs b/src/back/lto.rs index c21b768682399..61e0f203ee0b2 100644 --- a/src/back/lto.rs +++ b/src/back/lto.rs @@ -1,7 +1,6 @@ /// GCC requires to use the same toolchain for the whole compilation when doing LTO. /// So, we need the same version/commit of the linker (gcc) and lto front-end binaries (lto1, /// lto-wrapper, liblto_plugin.so). - // FIXME(antoyo): the executables compiled with LTO are bigger than those compiled without LTO. // Since it is the opposite for cg_llvm, check if this is normal. // @@ -17,7 +16,6 @@ // /usr/bin/ld: warning: type of symbol `_RNvNvNvNtCs5JWOrf9uCus_5rayon11thread_pool19WORKER_THREAD_STATE7___getit5___KEY' changed from 1 to 6 in /tmp/ccKeUSiR.ltrans0.ltrans.o // /usr/bin/ld: warning: type of symbol `_RNvNvNvNvNtNtNtCsAj5i4SGTR7_3std4sync4mpmc5waker17current_thread_id5DUMMY7___getit5___KEY' changed from 1 to 6 in /tmp/ccKeUSiR.ltrans0.ltrans.o // /usr/bin/ld: warning: incremental linking of LTO and non-LTO objects; using -flinker-output=nolto-rel which will bypass whole program optimization - use std::ffi::CString; use std::fs::{self, File}; use std::path::{Path, PathBuf}; @@ -30,18 +28,16 @@ use rustc_codegen_ssa::back::write::{CodegenContext, FatLtoInput}; use rustc_codegen_ssa::traits::*; use rustc_codegen_ssa::{looks_like_rust_object_file, ModuleCodegen, ModuleKind}; use rustc_data_structures::memmap::Mmap; -use rustc_errors::{FatalError, DiagCtxt}; +use rustc_errors::{DiagCtxt, FatalError}; use rustc_hir::def_id::LOCAL_CRATE; use rustc_middle::dep_graph::WorkProduct; use rustc_middle::middle::exported_symbols::{SymbolExportInfo, SymbolExportLevel}; use rustc_session::config::{CrateType, Lto}; -use tempfile::{TempDir, tempdir}; +use tempfile::{tempdir, TempDir}; use crate::back::write::save_temp_bitcode; -use crate::errors::{ - DynamicLinkingWithLTO, LtoBitcodeFromRlib, LtoDisallowed, LtoDylib, -}; -use crate::{GccCodegenBackend, GccContext, to_gcc_opt_level}; +use crate::errors::{DynamicLinkingWithLTO, LtoBitcodeFromRlib, LtoDisallowed, LtoDylib}; +use crate::{to_gcc_opt_level, GccCodegenBackend, GccContext}; /// We keep track of the computed LTO cache keys from the previous /// session to determine which CGUs we can reuse. @@ -61,7 +57,10 @@ struct LtoData { tmp_path: TempDir, } -fn prepare_lto(cgcx: &CodegenContext, dcx: &DiagCtxt) -> Result { +fn prepare_lto( + cgcx: &CodegenContext, + dcx: &DiagCtxt, +) -> Result { let export_threshold = match cgcx.lto { // We're just doing LTO for our one crate Lto::ThinLocal => SymbolExportLevel::Rust, @@ -72,14 +71,13 @@ fn prepare_lto(cgcx: &CodegenContext, dcx: &DiagCtxt) -> Resu Lto::No => panic!("didn't request LTO but we're doing LTO"), }; - let tmp_path = - match tempdir() { - Ok(tmp_path) => tmp_path, - Err(error) => { - eprintln!("Cannot create temporary directory: {}", error); - return Err(FatalError); - }, - }; + let tmp_path = match tempdir() { + Ok(tmp_path) => tmp_path, + Err(error) => { + eprintln!("Cannot create temporary directory: {}", error); + return Err(FatalError); + } + }; let symbol_filter = &|&(ref name, info): &(String, SymbolExportInfo)| { if info.level.is_below_threshold(export_threshold) || info.used { @@ -108,11 +106,10 @@ fn prepare_lto(cgcx: &CodegenContext, dcx: &DiagCtxt) -> Resu if !crate_type_allows_lto(*crate_type) { dcx.emit_err(LtoDisallowed); return Err(FatalError); - } else if *crate_type == CrateType::Dylib { - if !cgcx.opts.unstable_opts.dylib_lto { - dcx.emit_err(LtoDylib); - return Err(FatalError); - } + } + if *crate_type == CrateType::Dylib && !cgcx.opts.unstable_opts.dylib_lto { + dcx.emit_err(LtoDylib); + return Err(FatalError); } } @@ -125,8 +122,7 @@ fn prepare_lto(cgcx: &CodegenContext, dcx: &DiagCtxt) -> Resu let exported_symbols = cgcx.exported_symbols.as_ref().expect("needs exported symbols for LTO"); { - let _timer = - cgcx.prof.generic_activity("GCC_lto_generate_symbols_below_threshold"); + let _timer = cgcx.prof.generic_activity("GCC_lto_generate_symbols_below_threshold"); symbols_below_threshold .extend(exported_symbols[&cnum].iter().filter_map(symbol_filter)); } @@ -170,10 +166,9 @@ fn prepare_lto(cgcx: &CodegenContext, dcx: &DiagCtxt) -> Resu } fn save_as_file(obj: &[u8], path: &Path) -> Result<(), LtoBitcodeFromRlib> { - fs::write(path, obj) - .map_err(|error| LtoBitcodeFromRlib { - gcc_err: format!("write object file to temp dir: {}", error) - }) + fs::write(path, obj).map_err(|error| LtoBitcodeFromRlib { + gcc_err: format!("write object file to temp dir: {}", error), + }) } /// Performs fat LTO by merging all modules into a single one and returning it @@ -186,13 +181,25 @@ pub(crate) fn run_fat( let dcx = cgcx.create_dcx(); let lto_data = prepare_lto(cgcx, &dcx)?; /*let symbols_below_threshold = - lto_data.symbols_below_threshold.iter().map(|c| c.as_ptr()).collect::>();*/ - fat_lto(cgcx, &dcx, modules, cached_modules, lto_data.upstream_modules, lto_data.tmp_path, + lto_data.symbols_below_threshold.iter().map(|c| c.as_ptr()).collect::>();*/ + fat_lto( + cgcx, + &dcx, + modules, + cached_modules, + lto_data.upstream_modules, + lto_data.tmp_path, //&symbols_below_threshold, ) } -fn fat_lto(cgcx: &CodegenContext, _dcx: &DiagCtxt, modules: Vec>, cached_modules: Vec<(SerializedModule, WorkProduct)>, mut serialized_modules: Vec<(SerializedModule, CString)>, tmp_path: TempDir, +fn fat_lto( + cgcx: &CodegenContext, + _dcx: &DiagCtxt, + modules: Vec>, + cached_modules: Vec<(SerializedModule, WorkProduct)>, + mut serialized_modules: Vec<(SerializedModule, CString)>, + tmp_path: TempDir, //symbols_below_threshold: &[*const libc::c_char], ) -> Result, FatalError> { let _timer = cgcx.prof.generic_activity("GCC_fat_lto_build_monolithic_module"); @@ -298,10 +305,15 @@ fn fat_lto(cgcx: &CodegenContext, _dcx: &DiagCtxt, modules: V match bc_decoded { SerializedModule::Local(ref module_buffer) => { module.module_llvm.should_combine_object_files = true; - module.module_llvm.context.add_driver_option(module_buffer.0.to_str().expect("path")); - }, + module + .module_llvm + .context + .add_driver_option(module_buffer.0.to_str().expect("path")); + } SerializedModule::FromRlib(_) => unimplemented!("from rlib"), - SerializedModule::FromUncompressedFile(_) => unimplemented!("from uncompressed file"), + SerializedModule::FromUncompressedFile(_) => { + unimplemented!("from uncompressed file") + } } serialized_bitcode.push(bc_decoded); } @@ -309,13 +321,13 @@ fn fat_lto(cgcx: &CodegenContext, _dcx: &DiagCtxt, modules: V // Internalize everything below threshold to help strip out more modules and such. /*unsafe { - let ptr = symbols_below_threshold.as_ptr(); - llvm::LLVMRustRunRestrictionPass( - llmod, - ptr as *const *const libc::c_char, - symbols_below_threshold.len() as libc::size_t, - );*/ - save_temp_bitcode(cgcx, &module, "lto.after-restriction"); + let ptr = symbols_below_threshold.as_ptr(); + llvm::LLVMRustRunRestrictionPass( + llmod, + ptr as *const *const libc::c_char, + symbols_below_threshold.len() as libc::size_t, + );*/ + save_temp_bitcode(cgcx, &module, "lto.after-restriction"); //} } diff --git a/src/back/write.rs b/src/back/write.rs index 2f8a54f529cc5..76a619a1af782 100644 --- a/src/back/write.rs +++ b/src/back/write.rs @@ -1,19 +1,24 @@ use std::{env, fs}; use gccjit::OutputKind; -use rustc_codegen_ssa::{CompiledModule, ModuleCodegen}; use rustc_codegen_ssa::back::link::ensure_removed; use rustc_codegen_ssa::back::write::{BitcodeSection, CodegenContext, EmitObj, ModuleConfig}; +use rustc_codegen_ssa::{CompiledModule, ModuleCodegen}; use rustc_errors::DiagCtxt; use rustc_fs_util::link_or_copy; use rustc_session::config::OutputType; use rustc_span::fatal_error::FatalError; use rustc_target::spec::SplitDebuginfo; -use crate::{GccCodegenBackend, GccContext}; use crate::errors::CopyBitcode; +use crate::{GccCodegenBackend, GccContext}; -pub(crate) unsafe fn codegen(cgcx: &CodegenContext, dcx: &DiagCtxt, module: ModuleCodegen, config: &ModuleConfig) -> Result { +pub(crate) unsafe fn codegen( + cgcx: &CodegenContext, + dcx: &DiagCtxt, + module: ModuleCodegen, + config: &ModuleConfig, +) -> Result { let _timer = cgcx.prof.generic_activity_with_arg("GCC_module_codegen", &*module.name); { let context = &module.module_llvm.context; @@ -51,7 +56,8 @@ pub(crate) unsafe fn codegen(cgcx: &CodegenContext, dcx: &Dia .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"); - context.compile_to_file(OutputKind::ObjectFile, bc_out.to_str().expect("path to str")); + context + .compile_to_file(OutputKind::ObjectFile, bc_out.to_str().expect("path to str")); } if config.emit_obj == EmitObj::ObjectCode(BitcodeSection::Full) { @@ -65,18 +71,19 @@ pub(crate) unsafe fn codegen(cgcx: &CodegenContext, dcx: &Dia 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")); + context + .compile_to_file(OutputKind::ObjectFile, bc_out.to_str().expect("path to str")); } } if config.emit_ir { - unimplemented!(); + let out = cgcx.output_filenames.temp_path(OutputType::LlvmAssembly, module_name); + std::fs::write(out, "").expect("write file"); } if config.emit_asm { - let _timer = cgcx - .prof - .generic_activity_with_arg("GCC_module_codegen_emit_asm", &*module.name); + let _timer = + cgcx.prof.generic_activity_with_arg("GCC_module_codegen_emit_asm", &*module.name); let path = cgcx.output_filenames.temp_path(OutputType::Assembly, module_name); context.compile_to_file(OutputKind::Assembler, path.to_str().expect("path to str")); } @@ -89,7 +96,9 @@ pub(crate) unsafe fn codegen(cgcx: &CodegenContext, dcx: &Dia if env::var("CG_GCCJIT_DUMP_MODULE_NAMES").as_deref() == Ok("1") { println!("Module {}", module.name); } - if env::var("CG_GCCJIT_DUMP_ALL_MODULES").as_deref() == Ok("1") || env::var("CG_GCCJIT_DUMP_MODULE").as_deref() == Ok(&module.name) { + if env::var("CG_GCCJIT_DUMP_ALL_MODULES").as_deref() == Ok("1") + || env::var("CG_GCCJIT_DUMP_MODULE").as_deref() == Ok(&module.name) + { println!("Dumping reproducer {}", module.name); let _ = fs::create_dir("/tmp/reproducers"); // FIXME(antoyo): segfault in dump_reproducer_to_file() might be caused by @@ -117,10 +126,15 @@ pub(crate) unsafe fn codegen(cgcx: &CodegenContext, dcx: &Dia context.add_driver_option("-fuse-linker-plugin"); // 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")); - } - else { - context.compile_to_file(OutputKind::ObjectFile, obj_out.to_str().expect("path to str")); + context.compile_to_file( + OutputKind::Executable, + obj_out.to_str().expect("path to str"), + ); + } else { + context.compile_to_file( + OutputKind::ObjectFile, + obj_out.to_str().expect("path to str"), + ); } } @@ -148,11 +162,19 @@ pub(crate) unsafe fn codegen(cgcx: &CodegenContext, dcx: &Dia )) } -pub(crate) fn link(_cgcx: &CodegenContext, _dcx: &DiagCtxt, mut _modules: Vec>) -> Result, FatalError> { +pub(crate) fn link( + _cgcx: &CodegenContext, + _dcx: &DiagCtxt, + mut _modules: Vec>, +) -> Result, FatalError> { unimplemented!(); } -pub(crate) fn save_temp_bitcode(cgcx: &CodegenContext, _module: &ModuleCodegen, _name: &str) { +pub(crate) fn save_temp_bitcode( + cgcx: &CodegenContext, + _module: &ModuleCodegen, + _name: &str, +) { if !cgcx.save_temps { return; } diff --git a/src/base.rs b/src/base.rs index b0788718da4d1..2a2d5741d1318 100644 --- a/src/base.rs +++ b/src/base.rs @@ -2,29 +2,26 @@ use std::collections::HashSet; use std::env; use std::time::Instant; -use gccjit::{ - FunctionType, - GlobalKind, -}; -use rustc_middle::dep_graph; -use rustc_middle::ty::TyCtxt; -#[cfg(feature="master")] -use rustc_middle::mir::mono::Visibility; -use rustc_middle::mir::mono::Linkage; -use rustc_codegen_ssa::{ModuleCodegen, ModuleKind}; +use gccjit::{FunctionType, GlobalKind}; use rustc_codegen_ssa::base::maybe_create_entry_wrapper; use rustc_codegen_ssa::mono_item::MonoItemExt; use rustc_codegen_ssa::traits::DebugInfoMethods; +use rustc_codegen_ssa::{ModuleCodegen, ModuleKind}; +use rustc_middle::dep_graph; +use rustc_middle::mir::mono::Linkage; +#[cfg(feature = "master")] +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; -use crate::{LockedTargetInfo, gcc_util, new_context}; -use crate::GccContext; use crate::builder::Builder; use crate::context::CodegenCx; +use crate::GccContext; +use crate::{gcc_util, new_context, LockedTargetInfo}; -#[cfg(feature="master")] +#[cfg(feature = "master")] pub fn visibility_to_gcc(linkage: Visibility) -> gccjit::Visibility { match linkage { Visibility::Default => gccjit::Visibility::Default, @@ -66,7 +63,11 @@ pub fn linkage_to_gcc(linkage: Linkage) -> FunctionType { } } -pub fn compile_codegen_unit(tcx: TyCtxt<'_>, cgu_name: Symbol, target_info: LockedTargetInfo) -> (ModuleCodegen, u64) { +pub fn compile_codegen_unit( + tcx: TyCtxt<'_>, + cgu_name: Symbol, + target_info: LockedTargetInfo, +) -> (ModuleCodegen, u64) { let prof_timer = tcx.prof.generic_activity("codegen_module"); let start_time = Instant::now(); @@ -85,7 +86,10 @@ pub fn compile_codegen_unit(tcx: TyCtxt<'_>, cgu_name: Symbol, target_info: Lock // the time we needed for codegenning it. let cost = time_to_codegen.as_secs() * 1_000_000_000 + time_to_codegen.subsec_nanos() as u64; - fn module_codegen(tcx: TyCtxt<'_>, (cgu_name, target_info): (Symbol, LockedTargetInfo)) -> ModuleCodegen { + fn module_codegen( + tcx: TyCtxt<'_>, + (cgu_name, target_info): (Symbol, LockedTargetInfo), + ) -> ModuleCodegen { let cgu = tcx.codegen_unit(cgu_name); // Instantiate monomorphizations without filling out definitions yet... let context = new_context(tcx); @@ -95,7 +99,12 @@ pub fn compile_codegen_unit(tcx: TyCtxt<'_>, cgu_name: Symbol, target_info: Lock context.add_driver_option("-fexceptions"); } - let disabled_features: HashSet<_> = tcx.sess.opts.cg.target_feature.split(',') + let disabled_features: HashSet<_> = tcx + .sess + .opts + .cg + .target_feature + .split(',') .filter(|feature| feature.starts_with('-')) .map(|string| &string[1..]) .collect(); @@ -129,7 +138,13 @@ pub fn compile_codegen_unit(tcx: TyCtxt<'_>, cgu_name: Symbol, target_info: Lock context.add_command_line_option(&format!("-march={}", target_cpu)); } - if tcx.sess.opts.unstable_opts.function_sections.unwrap_or(tcx.sess.target.function_sections) { + if tcx + .sess + .opts + .unstable_opts + .function_sections + .unwrap_or(tcx.sess.target.function_sections) + { context.add_command_line_option("-ffunction-sections"); context.add_command_line_option("-fdata-sections"); } @@ -152,19 +167,17 @@ pub fn compile_codegen_unit(tcx: TyCtxt<'_>, cgu_name: Symbol, target_info: Lock if env::var("CG_GCCJIT_DUMP_GIMPLE").as_deref() == Ok("1") { context.set_dump_initial_gimple(true); } - context.set_debug_info(true); if env::var("CG_GCCJIT_DUMP_EVERYTHING").as_deref() == Ok("1") { context.set_dump_everything(true); } if env::var("CG_GCCJIT_KEEP_INTERMEDIATES").as_deref() == Ok("1") { context.set_keep_intermediates(true); } - if env::var("CG_GCCJIT_VERBOSE").as_deref() == Ok("1") { context.add_driver_option("-v"); } - // NOTE: The codegen generates unrechable blocks. + // NOTE: The codegen generates unreachable blocks. context.set_allow_unreachable_blocks(true); { @@ -192,11 +205,7 @@ pub fn compile_codegen_unit(tcx: TyCtxt<'_>, cgu_name: Symbol, target_info: Lock ModuleCodegen { name: cgu_name.to_string(), - module_llvm: GccContext { - context, - should_combine_object_files: false, - temp_dir: None, - }, + module_llvm: GccContext { context, should_combine_object_files: false, temp_dir: None }, kind: ModuleKind::Regular, } } diff --git a/src/builder.rs b/src/builder.rs index 71a0a4c2e96f2..f5cda81f6ab86 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -4,53 +4,36 @@ use std::convert::TryFrom; use std::ops::Deref; use gccjit::{ - BinaryOp, - Block, - ComparisonOp, - Context, - Function, - LValue, - RValue, - ToRValue, - Type, + BinaryOp, Block, ComparisonOp, Context, Function, LValue, Location, RValue, ToRValue, Type, UnaryOp, }; use rustc_apfloat::{ieee, Float, Round, Status}; -use rustc_codegen_ssa::MemFlags; use rustc_codegen_ssa::common::{ AtomicOrdering, AtomicRmwBinOp, IntPredicate, RealPredicate, SynchronizationScope, TypeKind, }; use rustc_codegen_ssa::mir::operand::{OperandRef, OperandValue}; use rustc_codegen_ssa::mir::place::PlaceRef; use rustc_codegen_ssa::traits::{ - BackendTypes, - BaseTypeMethods, - BuilderMethods, - ConstMethods, - LayoutTypeMethods, - HasCodegen, - OverflowOp, - StaticBuilderMethods, + BackendTypes, BaseTypeMethods, BuilderMethods, ConstMethods, HasCodegen, LayoutTypeMethods, + OverflowOp, StaticBuilderMethods, }; +use rustc_codegen_ssa::MemFlags; use rustc_data_structures::fx::FxHashSet; use rustc_middle::bug; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs; +use rustc_middle::ty::layout::{ + FnAbiError, FnAbiOfHelpers, FnAbiRequest, HasParamEnv, HasTyCtxt, LayoutError, LayoutOfHelpers, + TyAndLayout, +}; use rustc_middle::ty::{ParamEnv, Ty, TyCtxt}; -use rustc_middle::ty::layout::{FnAbiError, FnAbiOfHelpers, FnAbiRequest, HasParamEnv, HasTyCtxt, LayoutError, LayoutOfHelpers, TyAndLayout}; -use rustc_span::Span; use rustc_span::def_id::DefId; +use rustc_span::Span; use rustc_target::abi::{ - self, - call::FnAbi, - Align, - HasDataLayout, - Size, - TargetDataLayout, - WrappingRange, + self, call::FnAbi, Align, HasDataLayout, Size, TargetDataLayout, WrappingRange, }; use rustc_target::spec::{HasTargetSpec, Target}; -use crate::common::{SignType, TypeReflection, type_is_pointer}; +use crate::common::{type_is_pointer, SignType, TypeReflection}; use crate::context::CodegenCx; use crate::intrinsic::llvm; use crate::type_of::LayoutGccExt; @@ -70,54 +53,74 @@ pub struct Builder<'a: 'gcc, 'gcc, 'tcx> { pub cx: &'a CodegenCx<'gcc, 'tcx>, pub block: Block<'gcc>, stack_var_count: Cell, + pub location: Option>, } impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { fn with_cx(cx: &'a CodegenCx<'gcc, 'tcx>, block: Block<'gcc>) -> Self { - Builder { - cx, - block, - stack_var_count: Cell::new(0), - } + Builder { cx, block, stack_var_count: Cell::new(0), location: None } } - fn atomic_extremum(&mut self, operation: ExtremumOperation, dst: RValue<'gcc>, src: RValue<'gcc>, order: AtomicOrdering) -> RValue<'gcc> { + fn atomic_extremum( + &mut self, + operation: ExtremumOperation, + dst: RValue<'gcc>, + src: RValue<'gcc>, + order: AtomicOrdering, + ) -> RValue<'gcc> { let size = src.get_type().get_size(); let func = self.current_func(); - let load_ordering = - match order { - // TODO(antoyo): does this make sense? - AtomicOrdering::AcquireRelease | AtomicOrdering::Release => AtomicOrdering::Acquire, - _ => order, - }; - let previous_value = self.atomic_load(dst.get_type(), dst, load_ordering, Size::from_bytes(size)); - let previous_var = func.new_local(None, previous_value.get_type(), "previous_value"); - let return_value = func.new_local(None, previous_value.get_type(), "return_value"); - self.llbb().add_assignment(None, previous_var, previous_value); - self.llbb().add_assignment(None, return_value, previous_var.to_rvalue()); + let load_ordering = match order { + // TODO(antoyo): does this make sense? + AtomicOrdering::AcquireRelease | AtomicOrdering::Release => AtomicOrdering::Acquire, + _ => order, + }; + let previous_value = + self.atomic_load(dst.get_type(), dst, load_ordering, Size::from_bytes(size)); + let previous_var = + func.new_local(self.location, previous_value.get_type(), "previous_value"); + let return_value = func.new_local(self.location, previous_value.get_type(), "return_value"); + self.llbb().add_assignment(self.location, previous_var, previous_value); + self.llbb().add_assignment(self.location, return_value, previous_var.to_rvalue()); let while_block = func.new_block("while"); let after_block = func.new_block("after_while"); - self.llbb().end_with_jump(None, while_block); + self.llbb().end_with_jump(self.location, while_block); // NOTE: since jumps were added and compare_exchange doesn't expect this, the current block in the // state need to be updated. self.switch_to_block(while_block); - let comparison_operator = - match operation { - ExtremumOperation::Max => ComparisonOp::LessThan, - ExtremumOperation::Min => ComparisonOp::GreaterThan, - }; - - let cond1 = self.context.new_comparison(None, comparison_operator, previous_var.to_rvalue(), self.context.new_cast(None, src, previous_value.get_type())); - let compare_exchange = self.compare_exchange(dst, previous_var, src, order, load_ordering, false); - let cond2 = self.cx.context.new_unary_op(None, UnaryOp::LogicalNegate, compare_exchange.get_type(), compare_exchange); - let cond = self.cx.context.new_binary_op(None, BinaryOp::LogicalAnd, self.cx.bool_type, cond1, cond2); + let comparison_operator = match operation { + ExtremumOperation::Max => ComparisonOp::LessThan, + ExtremumOperation::Min => ComparisonOp::GreaterThan, + }; - while_block.end_with_conditional(None, cond, while_block, after_block); + let cond1 = self.context.new_comparison( + self.location, + comparison_operator, + previous_var.to_rvalue(), + self.context.new_cast(self.location, src, previous_value.get_type()), + ); + let compare_exchange = + self.compare_exchange(dst, previous_var, src, order, load_ordering, false); + let cond2 = self.cx.context.new_unary_op( + self.location, + UnaryOp::LogicalNegate, + compare_exchange.get_type(), + compare_exchange, + ); + let cond = self.cx.context.new_binary_op( + self.location, + BinaryOp::LogicalAnd, + self.cx.bool_type, + cond1, + cond2, + ); + + while_block.end_with_conditional(self.location, cond, while_block, after_block); // NOTE: since jumps were added in a place rustc does not expect, the current block in the // state need to be updated. @@ -126,29 +129,48 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { return_value.to_rvalue() } - fn compare_exchange(&self, dst: RValue<'gcc>, cmp: LValue<'gcc>, src: RValue<'gcc>, order: AtomicOrdering, failure_order: AtomicOrdering, weak: bool) -> RValue<'gcc> { + fn compare_exchange( + &self, + dst: RValue<'gcc>, + cmp: LValue<'gcc>, + src: RValue<'gcc>, + order: AtomicOrdering, + failure_order: AtomicOrdering, + weak: bool, + ) -> RValue<'gcc> { let size = src.get_type().get_size(); - let compare_exchange = self.context.get_builtin_function(&format!("__atomic_compare_exchange_{}", size)); + let compare_exchange = + self.context.get_builtin_function(&format!("__atomic_compare_exchange_{}", size)); let order = self.context.new_rvalue_from_int(self.i32_type, order.to_gcc()); let failure_order = self.context.new_rvalue_from_int(self.i32_type, failure_order.to_gcc()); let weak = self.context.new_rvalue_from_int(self.bool_type, weak as i32); let void_ptr_type = self.context.new_type::<*mut ()>(); let volatile_void_ptr_type = void_ptr_type.make_volatile(); - let dst = self.context.new_cast(None, dst, volatile_void_ptr_type); - let expected = self.context.new_cast(None, cmp.get_address(None), void_ptr_type); + let dst = self.context.new_cast(self.location, dst, volatile_void_ptr_type); + let expected = + self.context.new_cast(self.location, cmp.get_address(self.location), void_ptr_type); // NOTE: not sure why, but we have the wrong type here. let int_type = compare_exchange.get_param(2).to_rvalue().get_type(); - let src = self.context.new_cast(None, src, int_type); - self.context.new_call(None, compare_exchange, &[dst, expected, src, weak, order, failure_order]) + let src = self.context.new_cast(self.location, src, int_type); + self.context.new_call( + self.location, + compare_exchange, + &[dst, expected, src, weak, order, failure_order], + ) } pub fn assign(&self, lvalue: LValue<'gcc>, value: RValue<'gcc>) { - self.llbb().add_assignment(None, lvalue, value); + self.llbb().add_assignment(self.location, lvalue, value); } - fn check_call<'b>(&mut self, _typ: &str, func: Function<'gcc>, args: &'b [RValue<'gcc>]) -> Cow<'b, [RValue<'gcc>]> { + fn check_call<'b>( + &mut self, + _typ: &str, + func: Function<'gcc>, + args: &'b [RValue<'gcc>], + ) -> Cow<'b, [RValue<'gcc>]> { let mut all_args_match = true; let mut param_types = vec![]; let param_count = func.get_param_count(); @@ -173,8 +195,7 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { let actual_ty = actual_val.get_type(); if expected_ty != actual_ty { self.bitcast(actual_val, expected_ty) - } - else { + } else { actual_val } }) @@ -185,7 +206,12 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { Cow::Owned(casted_args) } - fn check_ptr_call<'b>(&mut self, _typ: &str, func_ptr: RValue<'gcc>, args: &'b [RValue<'gcc>]) -> Cow<'b, [RValue<'gcc>]> { + fn check_ptr_call<'b>( + &mut self, + _typ: &str, + func_ptr: RValue<'gcc>, + args: &'b [RValue<'gcc>], + ) -> Cow<'b, [RValue<'gcc>]> { let mut all_args_match = true; let mut param_types = vec![]; let gcc_func = func_ptr.get_type().dyncast_function_ptr_type().expect("function ptr"); @@ -219,20 +245,32 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { let actual_ty = actual_val.get_type(); if expected_ty != actual_ty { - if !actual_ty.is_vector() && !expected_ty.is_vector() && (actual_ty.is_integral() && expected_ty.is_integral()) || (actual_ty.get_pointee().is_some() && expected_ty.get_pointee().is_some()) { - self.context.new_cast(None, actual_val, expected_ty) - } - else if on_stack_param_indices.contains(&index) { - actual_val.dereference(None).to_rvalue() - } - else { - assert!(!((actual_ty.is_vector() && !expected_ty.is_vector()) || (!actual_ty.is_vector() && expected_ty.is_vector())), "{:?} ({}) -> {:?} ({}), index: {:?}[{}]", actual_ty, actual_ty.is_vector(), expected_ty, expected_ty.is_vector(), func_ptr, index); + if !actual_ty.is_vector() + && !expected_ty.is_vector() + && (actual_ty.is_integral() && expected_ty.is_integral()) + || (actual_ty.get_pointee().is_some() + && expected_ty.get_pointee().is_some()) + { + self.context.new_cast(self.location, actual_val, expected_ty) + } else if on_stack_param_indices.contains(&index) { + actual_val.dereference(self.location).to_rvalue() + } else { + assert!( + !((actual_ty.is_vector() && !expected_ty.is_vector()) + || (!actual_ty.is_vector() && expected_ty.is_vector())), + "{:?} ({}) -> {:?} ({}), index: {:?}[{}]", + actual_ty, + actual_ty.is_vector(), + expected_ty, + expected_ty.is_vector(), + func_ptr, + index + ); // TODO(antoyo): perhaps use __builtin_convertvector for vector casting. // TODO: remove bitcast now that vector types can be compared? self.bitcast(actual_val, expected_ty) } - } - else { + } else { actual_val } }) @@ -256,7 +294,12 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { self.block.get_function() } - fn function_call(&mut self, func: RValue<'gcc>, args: &[RValue<'gcc>], _funclet: Option<&Funclet>) -> RValue<'gcc> { + fn function_call( + &mut self, + func: RValue<'gcc>, + args: &[RValue<'gcc>], + _funclet: Option<&Funclet>, + ) -> RValue<'gcc> { // TODO(antoyo): remove when the API supports a different type for functions. let func: Function<'gcc> = self.cx.rvalue_as_function(func); let args = self.check_call("call", func, args); @@ -268,35 +311,54 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { let current_func = self.block.get_function(); if return_type != void_type { unsafe { RETURN_VALUE_COUNT += 1 }; - let result = current_func.new_local(None, return_type, &format!("returnValue{}", unsafe { RETURN_VALUE_COUNT })); - self.block.add_assignment(None, result, self.cx.context.new_call(None, func, &args)); + let result = current_func.new_local( + self.location, + return_type, + &format!("returnValue{}", unsafe { RETURN_VALUE_COUNT }), + ); + self.block.add_assignment( + self.location, + result, + self.cx.context.new_call(self.location, func, &args), + ); result.to_rvalue() - } - else { - self.block.add_eval(None, self.cx.context.new_call(None, func, &args)); + } else { + self.block + .add_eval(self.location, self.cx.context.new_call(self.location, func, &args)); // Return dummy value when not having return value. self.context.new_rvalue_from_long(self.isize_type, 0) } } - fn function_ptr_call(&mut self, typ: Type<'gcc>, mut func_ptr: RValue<'gcc>, args: &[RValue<'gcc>], _funclet: Option<&Funclet>) -> RValue<'gcc> { - let gcc_func = - match func_ptr.get_type().dyncast_function_ptr_type() { - Some(func) => func, - None => { - // NOTE: due to opaque pointers now being used, we need to cast here. - let new_func_type = typ.dyncast_function_ptr_type().expect("function ptr"); - func_ptr = self.context.new_cast(None, func_ptr, typ); - new_func_type - }, - }; + fn function_ptr_call( + &mut self, + typ: Type<'gcc>, + mut func_ptr: RValue<'gcc>, + args: &[RValue<'gcc>], + _funclet: Option<&Funclet>, + ) -> RValue<'gcc> { + let gcc_func = match func_ptr.get_type().dyncast_function_ptr_type() { + Some(func) => func, + None => { + // NOTE: due to opaque pointers now being used, we need to cast here. + let new_func_type = typ.dyncast_function_ptr_type().expect("function ptr"); + func_ptr = self.context.new_cast(self.location, func_ptr, typ); + new_func_type + } + }; let func_name = format!("{:?}", func_ptr); let previous_arg_count = args.len(); let orig_args = args; let args = { let function_address_names = self.function_address_names.borrow(); let original_function_name = function_address_names.get(&func_ptr); - llvm::adjust_intrinsic_arguments(&self, gcc_func, args.into(), &func_name, original_function_name) + llvm::adjust_intrinsic_arguments( + &self, + gcc_func, + args.into(), + &func_name, + original_function_name, + ) }; let args_adjusted = args.len() != previous_arg_count; let args = self.check_ptr_call("call", func_ptr, &*args); @@ -309,39 +371,78 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { if return_type != void_type { unsafe { RETURN_VALUE_COUNT += 1 }; - let return_value = self.cx.context.new_call_through_ptr(None, func_ptr, &args); - let return_value = llvm::adjust_intrinsic_return_value(&self, return_value, &func_name, &args, args_adjusted, orig_args); - let result = current_func.new_local(None, return_value.get_type(), &format!("ptrReturnValue{}", unsafe { RETURN_VALUE_COUNT })); - self.block.add_assignment(None, result, return_value); + let return_value = self.cx.context.new_call_through_ptr(self.location, func_ptr, &args); + let return_value = llvm::adjust_intrinsic_return_value( + &self, + return_value, + &func_name, + &args, + args_adjusted, + orig_args, + ); + let result = current_func.new_local( + self.location, + return_value.get_type(), + &format!("ptrReturnValue{}", unsafe { RETURN_VALUE_COUNT }), + ); + self.block.add_assignment(self.location, result, return_value); result.to_rvalue() - } - else { - #[cfg(not(feature="master"))] + } else { + #[cfg(not(feature = "master"))] if gcc_func.get_param_count() == 0 { // FIXME(antoyo): As a temporary workaround for unsupported LLVM intrinsics. - self.block.add_eval(None, self.cx.context.new_call_through_ptr(None, func_ptr, &[])); - } - else { - self.block.add_eval(None, self.cx.context.new_call_through_ptr(None, func_ptr, &args)); + self.block.add_eval( + self.location, + self.cx.context.new_call_through_ptr(self.location, func_ptr, &[]), + ); + } else { + self.block.add_eval( + self.location, + self.cx.context.new_call_through_ptr(self.location, func_ptr, &args), + ); } - #[cfg(feature="master")] - self.block.add_eval(None, self.cx.context.new_call_through_ptr(None, func_ptr, &args)); + #[cfg(feature = "master")] + self.block.add_eval( + self.location, + self.cx.context.new_call_through_ptr(self.location, func_ptr, &args), + ); // Return dummy value when not having return value. - let result = current_func.new_local(None, self.isize_type, "dummyValueThatShouldNeverBeUsed"); - self.block.add_assignment(None, result, self.context.new_rvalue_from_long(self.isize_type, 0)); + let result = current_func.new_local( + self.location, + self.isize_type, + "dummyValueThatShouldNeverBeUsed", + ); + self.block.add_assignment( + self.location, + result, + self.context.new_rvalue_from_long(self.isize_type, 0), + ); result.to_rvalue() } } - pub fn overflow_call(&self, func: Function<'gcc>, args: &[RValue<'gcc>], _funclet: Option<&Funclet>) -> RValue<'gcc> { + pub fn overflow_call( + &self, + func: Function<'gcc>, + args: &[RValue<'gcc>], + _funclet: Option<&Funclet>, + ) -> RValue<'gcc> { // gccjit requires to use the result of functions, even when it's not used. // That's why we assign the result to a local. let return_type = self.context.new_type::(); let current_func = self.block.get_function(); // TODO(antoyo): return the new_call() directly? Since the overflow function has no side-effects. unsafe { RETURN_VALUE_COUNT += 1 }; - let result = current_func.new_local(None, return_type, &format!("overflowReturnValue{}", unsafe { RETURN_VALUE_COUNT })); - self.block.add_assignment(None, result, self.cx.context.new_call(None, func, &args)); + let result = current_func.new_local( + self.location, + return_type, + &format!("overflowReturnValue{}", unsafe { RETURN_VALUE_COUNT }), + ); + self.block.add_assignment( + self.location, + result, + self.cx.context.new_call(self.location, func, &args), + ); result.to_rvalue() } } @@ -405,6 +506,17 @@ impl<'gcc, 'tcx> BackendTypes for Builder<'_, 'gcc, 'tcx> { type DIVariable = as BackendTypes>::DIVariable; } +fn set_rvalue_location<'a, 'gcc, 'tcx>( + bx: &mut Builder<'a, 'gcc, 'tcx>, + rvalue: RValue<'gcc>, +) -> RValue<'gcc> { + if bx.location.is_some() { + #[cfg(feature = "master")] + rvalue.set_location(bx.location.unwrap()); + } + rvalue +} + impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { fn build(cx: &'a CodegenCx<'gcc, 'tcx>, block: Block<'gcc>) -> Builder<'a, 'gcc, 'tcx> { Builder::with_cx(cx, block) @@ -429,43 +541,58 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { } fn ret_void(&mut self) { - self.llbb().end_with_void_return(None) + self.llbb().end_with_void_return(self.location) } fn ret(&mut self, mut value: RValue<'gcc>) { if self.structs_as_pointer.borrow().contains(&value) { // NOTE: hack to workaround a limitation of the rustc API: see comment on // CodegenCx.structs_as_pointer - value = value.dereference(None).to_rvalue(); + value = value.dereference(self.location).to_rvalue(); } let expected_return_type = self.current_func().get_return_type(); if !expected_return_type.is_compatible_with(value.get_type()) { // NOTE: due to opaque pointers now being used, we need to cast here. - value = self.context.new_cast(None, value, expected_return_type); + value = self.context.new_cast(self.location, value, expected_return_type); } - self.llbb().end_with_return(None, value); + self.llbb().end_with_return(self.location, value); } fn br(&mut self, dest: Block<'gcc>) { - self.llbb().end_with_jump(None, dest) + self.llbb().end_with_jump(self.location, dest) } fn cond_br(&mut self, cond: RValue<'gcc>, then_block: Block<'gcc>, else_block: Block<'gcc>) { - self.llbb().end_with_conditional(None, cond, then_block, else_block) + self.llbb().end_with_conditional(self.location, cond, then_block, else_block) } - fn switch(&mut self, value: RValue<'gcc>, default_block: Block<'gcc>, cases: impl ExactSizeIterator)>) { + fn switch( + &mut self, + value: RValue<'gcc>, + default_block: Block<'gcc>, + cases: impl ExactSizeIterator)>, + ) { let mut gcc_cases = vec![]; let typ = self.val_ty(value); for (on_val, dest) in cases { let on_val = self.const_uint_big(typ, on_val); gcc_cases.push(self.context.new_case(on_val, on_val, dest)); } - self.block.end_with_switch(None, value, default_block, &gcc_cases); + self.block.end_with_switch(self.location, value, default_block, &gcc_cases); } - #[cfg(feature="master")] - fn invoke(&mut self, typ: Type<'gcc>, fn_attrs: Option<&CodegenFnAttrs>, _fn_abi: Option<&FnAbi<'tcx, Ty<'tcx>>>, func: RValue<'gcc>, args: &[RValue<'gcc>], then: Block<'gcc>, catch: Block<'gcc>, _funclet: Option<&Funclet>) -> RValue<'gcc> { + #[cfg(feature = "master")] + fn invoke( + &mut self, + typ: Type<'gcc>, + fn_attrs: Option<&CodegenFnAttrs>, + _fn_abi: Option<&FnAbi<'tcx, Ty<'tcx>>>, + func: RValue<'gcc>, + args: &[RValue<'gcc>], + then: Block<'gcc>, + catch: Block<'gcc>, + _funclet: Option<&Funclet>, + ) -> RValue<'gcc> { let try_block = self.current_func().new_block("try"); let current_block = self.block.clone(); @@ -473,30 +600,39 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { let call = self.call(typ, fn_attrs, None, func, args, None); // TODO(antoyo): use funclet here? self.block = current_block; - let return_value = self.current_func() - .new_local(None, call.get_type(), "invokeResult"); + let return_value = + self.current_func().new_local(self.location, call.get_type(), "invokeResult"); - try_block.add_assignment(None, return_value, call); + try_block.add_assignment(self.location, return_value, call); - try_block.end_with_jump(None, then); + try_block.end_with_jump(self.location, then); if self.cleanup_blocks.borrow().contains(&catch) { - self.block.add_try_finally(None, try_block, catch); - } - else { - self.block.add_try_catch(None, try_block, catch); + self.block.add_try_finally(self.location, try_block, catch); + } else { + self.block.add_try_catch(self.location, try_block, catch); } - self.block.end_with_jump(None, then); + self.block.end_with_jump(self.location, then); return_value.to_rvalue() } - #[cfg(not(feature="master"))] - fn invoke(&mut self, typ: Type<'gcc>, fn_attrs: Option<&CodegenFnAttrs>, fn_abi: Option<&FnAbi<'tcx, Ty<'tcx>>>, func: RValue<'gcc>, args: &[RValue<'gcc>], then: Block<'gcc>, catch: Block<'gcc>, _funclet: Option<&Funclet>) -> RValue<'gcc> { + #[cfg(not(feature = "master"))] + fn invoke( + &mut self, + typ: Type<'gcc>, + fn_attrs: Option<&CodegenFnAttrs>, + fn_abi: Option<&FnAbi<'tcx, Ty<'tcx>>>, + func: RValue<'gcc>, + args: &[RValue<'gcc>], + then: Block<'gcc>, + catch: Block<'gcc>, + _funclet: Option<&Funclet>, + ) -> RValue<'gcc> { let call_site = self.call(typ, fn_attrs, None, func, args, None); let condition = self.context.new_rvalue_from_int(self.bool_type, 1); - self.llbb().end_with_conditional(None, condition, then, catch); + self.llbb().end_with_conditional(self.location, condition, then, catch); if let Some(_fn_abi) = fn_abi { // TODO(bjorn3): Apply function attributes } @@ -505,16 +641,15 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { fn unreachable(&mut self) { let func = self.context.get_builtin_function("__builtin_unreachable"); - self.block.add_eval(None, self.context.new_call(None, func, &[])); + self.block.add_eval(self.location, self.context.new_call(self.location, func, &[])); let return_type = self.block.get_function().get_return_type(); let void_type = self.context.new_type::<()>(); if return_type == void_type { - self.block.end_with_void_return(None) - } - else { - let return_value = self.current_func() - .new_local(None, return_type, "unreachableReturn"); - self.block.end_with_return(None, return_value) + self.block.end_with_void_return(self.location) + } else { + let return_value = + self.current_func().new_local(self.location, return_type, "unreachableReturn"); + self.block.end_with_return(self.location, return_value) } } @@ -539,7 +674,7 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { } fn fmul(&mut self, a: RValue<'gcc>, b: RValue<'gcc>) -> RValue<'gcc> { - a * b + self.cx.context.new_binary_op(self.location, BinaryOp::Mult, a.get_type(), a, b) } fn udiv(&mut self, a: RValue<'gcc>, b: RValue<'gcc>) -> RValue<'gcc> { @@ -564,7 +699,7 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { // FIXME(antoyo): rustc_codegen_ssa::mir::intrinsic uses different types for a and b but they // should be the same. let typ = a.get_type().to_signed(self); - let b = self.context.new_cast(None, b, typ); + let b = self.context.new_cast(self.location, b, typ); a / b } @@ -606,15 +741,32 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { // ../../../gcc/gcc/cfgexpand.cc:6069 // 0x7f0101bf9194 execute // ../../../gcc/gcc/cfgexpand.cc:6795 - if a.get_type().is_compatible_with(self.cx.float_type) { + let a_type = a.get_type(); + let a_type_unqualified = a_type.unqualified(); + if a_type.is_compatible_with(self.cx.float_type) { let fmodf = self.context.get_builtin_function("fmodf"); // FIXME(antoyo): this seems to produce the wrong result. - return self.context.new_call(None, fmodf, &[a, b]); + return self.context.new_call(self.location, fmodf, &[a, b]); + } + if let Some(vector_type) = a_type_unqualified.dyncast_vector() { + assert_eq!(a_type_unqualified, b.get_type().unqualified()); + + let num_units = vector_type.get_num_units(); + let new_elements: Vec<_> = (0..num_units) + .map(|i| { + let index = self.context.new_rvalue_from_long(self.cx.type_u32(), i as _); + let x = self.extract_element(a, index).to_rvalue(); + let y = self.extract_element(b, index).to_rvalue(); + self.frem(x, y) + }) + .collect(); + + return self.context.new_rvalue_from_vector(self.location, a_type, &new_elements); } - assert_eq!(a.get_type().unqualified(), self.cx.double_type); + assert_eq!(a_type_unqualified, self.cx.double_type); let fmod = self.context.get_builtin_function("fmod"); - return self.context.new_call(None, fmod, &[a, b]); + self.context.new_call(self.location, fmod, &[a, b]) } fn shl(&mut self, a: RValue<'gcc>, b: RValue<'gcc>) -> RValue<'gcc> { @@ -636,73 +788,78 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { } fn or(&mut self, a: RValue<'gcc>, b: RValue<'gcc>) -> RValue<'gcc> { - self.cx.gcc_or(a, b) + self.cx.gcc_or(a, b, self.location) } fn xor(&mut self, a: RValue<'gcc>, b: RValue<'gcc>) -> RValue<'gcc> { - self.gcc_xor(a, b) + set_rvalue_location(self, self.gcc_xor(a, b)) } fn neg(&mut self, a: RValue<'gcc>) -> RValue<'gcc> { - self.gcc_neg(a) + set_rvalue_location(self, self.gcc_neg(a)) } fn fneg(&mut self, a: RValue<'gcc>) -> RValue<'gcc> { - self.cx.context.new_unary_op(None, UnaryOp::Minus, a.get_type(), a) + set_rvalue_location( + self, + self.cx.context.new_unary_op(self.location, UnaryOp::Minus, a.get_type(), a), + ) } fn not(&mut self, a: RValue<'gcc>) -> RValue<'gcc> { - self.gcc_not(a) + set_rvalue_location(self, self.gcc_not(a)) } fn unchecked_sadd(&mut self, a: RValue<'gcc>, b: RValue<'gcc>) -> RValue<'gcc> { - self.gcc_add(a, b) + set_rvalue_location(self, self.gcc_add(a, b)) } fn unchecked_uadd(&mut self, a: RValue<'gcc>, b: RValue<'gcc>) -> RValue<'gcc> { - self.gcc_add(a, b) + set_rvalue_location(self, self.gcc_add(a, b)) } fn unchecked_ssub(&mut self, a: RValue<'gcc>, b: RValue<'gcc>) -> RValue<'gcc> { - self.gcc_sub(a, b) + set_rvalue_location(self, self.gcc_sub(a, b)) } fn unchecked_usub(&mut self, a: RValue<'gcc>, b: RValue<'gcc>) -> RValue<'gcc> { // TODO(antoyo): should generate poison value? - self.gcc_sub(a, b) + set_rvalue_location(self, self.gcc_sub(a, b)) } fn unchecked_smul(&mut self, a: RValue<'gcc>, b: RValue<'gcc>) -> RValue<'gcc> { - self.gcc_mul(a, b) + set_rvalue_location(self, self.gcc_mul(a, b)) } fn unchecked_umul(&mut self, a: RValue<'gcc>, b: RValue<'gcc>) -> RValue<'gcc> { - self.gcc_mul(a, b) + set_rvalue_location(self, self.gcc_mul(a, b)) } fn fadd_fast(&mut self, lhs: RValue<'gcc>, rhs: RValue<'gcc>) -> RValue<'gcc> { // NOTE: it seems like we cannot enable fast-mode for a single operation in GCC. - lhs + rhs + set_rvalue_location(self, lhs + rhs) } fn fsub_fast(&mut self, lhs: RValue<'gcc>, rhs: RValue<'gcc>) -> RValue<'gcc> { // NOTE: it seems like we cannot enable fast-mode for a single operation in GCC. - lhs - rhs + set_rvalue_location(self, lhs - rhs) } fn fmul_fast(&mut self, lhs: RValue<'gcc>, rhs: RValue<'gcc>) -> RValue<'gcc> { // NOTE: it seems like we cannot enable fast-mode for a single operation in GCC. - lhs * rhs + set_rvalue_location(self, lhs * rhs) } fn fdiv_fast(&mut self, lhs: RValue<'gcc>, rhs: RValue<'gcc>) -> RValue<'gcc> { // NOTE: it seems like we cannot enable fast-mode for a single operation in GCC. - lhs / rhs + set_rvalue_location(self, lhs / rhs) } fn frem_fast(&mut self, lhs: RValue<'gcc>, rhs: RValue<'gcc>) -> RValue<'gcc> { // NOTE: it seems like we cannot enable fast-mode for a single operation in GCC. - self.frem(lhs, rhs) + let result = self.frem(lhs, rhs); + set_rvalue_location(self, result); + result } fn fadd_algebraic(&mut self, lhs: RValue<'gcc>, rhs: RValue<'gcc>) -> RValue<'gcc> { @@ -730,23 +887,33 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { self.frem(lhs, rhs) } - fn checked_binop(&mut self, oop: OverflowOp, typ: Ty<'_>, lhs: Self::Value, rhs: Self::Value) -> (Self::Value, Self::Value) { + fn checked_binop( + &mut self, + oop: OverflowOp, + typ: Ty<'_>, + lhs: Self::Value, + rhs: Self::Value, + ) -> (Self::Value, Self::Value) { self.gcc_checked_binop(oop, typ, lhs, rhs) } fn alloca(&mut self, ty: Type<'gcc>, align: Align) -> RValue<'gcc> { // FIXME(antoyo): this check that we don't call get_aligned() a second time on a type. // Ideally, we shouldn't need to do this check. - let aligned_type = - if ty == self.cx.u128_type || ty == self.cx.i128_type { - ty - } - else { - ty.get_aligned(align.bytes()) - }; + let aligned_type = if ty == self.cx.u128_type || ty == self.cx.i128_type { + ty + } else { + ty.get_aligned(align.bytes()) + }; // TODO(antoyo): It might be better to return a LValue, but fixing the rustc API is non-trivial. self.stack_var_count.set(self.stack_var_count.get() + 1); - self.current_func().new_local(None, aligned_type, &format!("stack_var_{}", self.stack_var_count.get())).get_address(None) + self.current_func() + .new_local( + self.location, + aligned_type, + &format!("stack_var_{}", self.stack_var_count.get()), + ) + .get_address(self.location) } fn byte_array_alloca(&mut self, _len: RValue<'gcc>, _align: Align) -> RValue<'gcc> { @@ -761,48 +928,62 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { // dereference after a drop, for instance. // FIXME(antoyo): this check that we don't call get_aligned() a second time on a type. // Ideally, we shouldn't need to do this check. - let aligned_type = - if pointee_ty == self.cx.u128_type || pointee_ty == self.cx.i128_type { - pointee_ty - } - else { - pointee_ty.get_aligned(align.bytes()) - }; - let ptr = self.context.new_cast(None, ptr, aligned_type.make_pointer()); - let deref = ptr.dereference(None).to_rvalue(); + let aligned_type = if pointee_ty == self.cx.u128_type || pointee_ty == self.cx.i128_type { + pointee_ty + } else { + pointee_ty.get_aligned(align.bytes()) + }; + let ptr = self.context.new_cast(self.location, ptr, aligned_type.make_pointer()); + let deref = ptr.dereference(self.location).to_rvalue(); unsafe { RETURN_VALUE_COUNT += 1 }; - let loaded_value = function.new_local(None, aligned_type, &format!("loadedValue{}", unsafe { RETURN_VALUE_COUNT })); - block.add_assignment(None, loaded_value, deref); + let loaded_value = function.new_local( + self.location, + aligned_type, + &format!("loadedValue{}", unsafe { RETURN_VALUE_COUNT }), + ); + block.add_assignment(self.location, loaded_value, deref); loaded_value.to_rvalue() } fn volatile_load(&mut self, ty: Type<'gcc>, ptr: RValue<'gcc>) -> RValue<'gcc> { - let ptr = self.context.new_cast(None, ptr, ty.make_volatile().make_pointer()); - ptr.dereference(None).to_rvalue() + let ptr = self.context.new_cast(self.location, ptr, ty.make_volatile().make_pointer()); + ptr.dereference(self.location).to_rvalue() } - fn atomic_load(&mut self, _ty: Type<'gcc>, ptr: RValue<'gcc>, order: AtomicOrdering, size: Size) -> RValue<'gcc> { + fn atomic_load( + &mut self, + _ty: Type<'gcc>, + ptr: RValue<'gcc>, + order: AtomicOrdering, + size: Size, + ) -> RValue<'gcc> { // TODO(antoyo): use ty. // TODO(antoyo): handle alignment. - let atomic_load = self.context.get_builtin_function(&format!("__atomic_load_{}", size.bytes())); + let atomic_load = + self.context.get_builtin_function(&format!("__atomic_load_{}", size.bytes())); let ordering = self.context.new_rvalue_from_int(self.i32_type, order.to_gcc()); - let volatile_const_void_ptr_type = self.context.new_type::<()>() - .make_const() - .make_volatile() - .make_pointer(); - let ptr = self.context.new_cast(None, ptr, volatile_const_void_ptr_type); - self.context.new_call(None, atomic_load, &[ptr, ordering]) + let volatile_const_void_ptr_type = + self.context.new_type::<()>().make_const().make_volatile().make_pointer(); + let ptr = self.context.new_cast(self.location, ptr, volatile_const_void_ptr_type); + self.context.new_call(self.location, atomic_load, &[ptr, ordering]) } - fn load_operand(&mut self, place: PlaceRef<'tcx, RValue<'gcc>>) -> OperandRef<'tcx, RValue<'gcc>> { + fn load_operand( + &mut self, + place: PlaceRef<'tcx, RValue<'gcc>>, + ) -> OperandRef<'tcx, RValue<'gcc>> { assert_eq!(place.llextra.is_some(), place.layout.is_unsized()); if place.layout.is_zst() { return OperandRef::zero_sized(place.layout); } - fn scalar_load_metadata<'a, 'gcc, 'tcx>(bx: &mut Builder<'a, 'gcc, 'tcx>, load: RValue<'gcc>, scalar: &abi::Scalar) { + fn scalar_load_metadata<'a, 'gcc, 'tcx>( + bx: &mut Builder<'a, 'gcc, 'tcx>, + load: RValue<'gcc>, + scalar: &abi::Scalar, + ) { let vr = scalar.valid_range(bx); match scalar.primitive() { abi::Int(..) => { @@ -817,49 +998,50 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { } } - let val = - if let Some(llextra) = place.llextra { - OperandValue::Ref(place.llval, Some(llextra), place.align) - } - else if place.layout.is_gcc_immediate() { - let load = self.load( - place.layout.gcc_type(self), - place.llval, - place.align, - ); - if let abi::Abi::Scalar(ref scalar) = place.layout.abi { - scalar_load_metadata(self, load, scalar); - } - OperandValue::Immediate(self.to_immediate(load, place.layout)) + let val = if let Some(llextra) = place.llextra { + OperandValue::Ref(place.llval, Some(llextra), place.align) + } else if place.layout.is_gcc_immediate() { + let load = self.load(place.layout.gcc_type(self), place.llval, place.align); + if let abi::Abi::Scalar(ref scalar) = place.layout.abi { + scalar_load_metadata(self, load, scalar); } - else if let abi::Abi::ScalarPair(ref a, ref b) = place.layout.abi { - let b_offset = a.size(self).align_to(b.align(self).abi); - - let mut load = |i, scalar: &abi::Scalar, align| { - let llptr = if i == 0 { - place.llval - } else { - self.inbounds_ptradd(place.llval, self.const_usize(b_offset.bytes())) - }; - let llty = place.layout.scalar_pair_element_gcc_type(self, i); - let load = self.load(llty, llptr, align); - scalar_load_metadata(self, load, scalar); - if scalar.is_bool() { self.trunc(load, self.type_i1()) } else { load } + OperandValue::Immediate(self.to_immediate(load, place.layout)) + } else if let abi::Abi::ScalarPair(ref a, ref b) = place.layout.abi { + let b_offset = a.size(self).align_to(b.align(self).abi); + + let mut load = |i, scalar: &abi::Scalar, align| { + let llptr = if i == 0 { + place.llval + } else { + self.inbounds_ptradd(place.llval, self.const_usize(b_offset.bytes())) }; - - OperandValue::Pair( - load(0, a, place.align), - load(1, b, place.align.restrict_for_offset(b_offset)), - ) - } - else { - OperandValue::Ref(place.llval, None, place.align) + let llty = place.layout.scalar_pair_element_gcc_type(self, i); + let load = self.load(llty, llptr, align); + scalar_load_metadata(self, load, scalar); + if scalar.is_bool() { + self.trunc(load, self.type_i1()) + } else { + load + } }; + OperandValue::Pair( + load(0, a, place.align), + load(1, b, place.align.restrict_for_offset(b_offset)), + ) + } else { + OperandValue::Ref(place.llval, None, place.align) + }; + OperandRef { val, layout: place.layout } } - fn write_operand_repeatedly(&mut self, cg_elem: OperandRef<'tcx, RValue<'gcc>>, count: u64, dest: PlaceRef<'tcx, RValue<'gcc>>) { + fn write_operand_repeatedly( + &mut self, + cg_elem: OperandRef<'tcx, RValue<'gcc>>, + count: u64, + dest: PlaceRef<'tcx, RValue<'gcc>>, + ) { let zero = self.const_usize(0); let count = self.const_usize(count); let start = dest.project_index(self, zero).llval; @@ -870,7 +1052,7 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { let next_bb = self.append_sibling_block("repeat_loop_next"); let ptr_type = start.get_type(); - let current = self.llbb().get_function().new_local(None, ptr_type, "loop_var"); + let current = self.llbb().get_function().new_local(self.location, ptr_type, "loop_var"); let current_val = current.to_rvalue(); self.assign(current, start); @@ -884,8 +1066,12 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { let align = dest.align.restrict_for_offset(dest.layout.field(self.cx(), 0).size); cg_elem.val.store(self, PlaceRef::new_sized_aligned(current_val, cg_elem.layout, align)); - let next = self.inbounds_gep(self.backend_type(cg_elem.layout), current.to_rvalue(), &[self.const_usize(1)]); - self.llbb().add_assignment(None, current, next); + let next = self.inbounds_gep( + self.backend_type(cg_elem.layout), + current.to_rvalue(), + &[self.const_usize(1)], + ); + self.llbb().add_assignment(self.location, current, next); self.br(header_bb); self.switch_to_block(next_bb); @@ -903,75 +1089,100 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { self.store_with_flags(val, ptr, align, MemFlags::empty()) } - fn store_with_flags(&mut self, val: RValue<'gcc>, ptr: RValue<'gcc>, align: Align, _flags: MemFlags) -> RValue<'gcc> { + fn store_with_flags( + &mut self, + val: RValue<'gcc>, + ptr: RValue<'gcc>, + align: Align, + _flags: MemFlags, + ) -> RValue<'gcc> { let ptr = self.check_store(val, ptr); - let destination = ptr.dereference(None); + 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(None, ptr, aligned_type); - let aligned_destination = aligned_destination.dereference(None); - self.llbb().add_assignment(None, aligned_destination, val); + 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. // NOTE: dummy value here since it's never used. FIXME(antoyo): API should not return a value here? self.cx.context.new_rvalue_zero(self.type_i32()) } - fn atomic_store(&mut self, value: RValue<'gcc>, ptr: RValue<'gcc>, order: AtomicOrdering, size: Size) { + fn atomic_store( + &mut self, + value: RValue<'gcc>, + ptr: RValue<'gcc>, + order: AtomicOrdering, + size: Size, + ) { // TODO(antoyo): handle alignment. - let atomic_store = self.context.get_builtin_function(&format!("__atomic_store_{}", size.bytes())); + let atomic_store = + self.context.get_builtin_function(&format!("__atomic_store_{}", size.bytes())); let ordering = self.context.new_rvalue_from_int(self.i32_type, order.to_gcc()); - let volatile_const_void_ptr_type = self.context.new_type::<()>() - .make_volatile() - .make_pointer(); - let ptr = self.context.new_cast(None, ptr, volatile_const_void_ptr_type); + let volatile_const_void_ptr_type = + self.context.new_type::<()>().make_volatile().make_pointer(); + let ptr = self.context.new_cast(self.location, ptr, volatile_const_void_ptr_type); // FIXME(antoyo): fix libgccjit to allow comparing an integer type with an aligned integer type because // the following cast is required to avoid this error: // gcc_jit_context_new_call: mismatching types for argument 2 of function "__atomic_store_4": assignment to param arg1 (type: int) from loadedValue3577 (type: unsigned int __attribute__((aligned(4)))) let int_type = atomic_store.get_param(1).to_rvalue().get_type(); - let value = self.context.new_cast(None, value, int_type); - self.llbb() - .add_eval(None, self.context.new_call(None, atomic_store, &[ptr, value, ordering])); + let value = self.context.new_cast(self.location, value, int_type); + self.llbb().add_eval( + self.location, + self.context.new_call(self.location, atomic_store, &[ptr, value, ordering]), + ); } - fn gep(&mut self, typ: Type<'gcc>, ptr: RValue<'gcc>, indices: &[RValue<'gcc>]) -> RValue<'gcc> { + fn gep( + &mut self, + typ: Type<'gcc>, + ptr: RValue<'gcc>, + indices: &[RValue<'gcc>], + ) -> RValue<'gcc> { // NOTE: due to opaque pointers now being used, we need to cast here. - let ptr = self.context.new_cast(None, ptr, typ.make_pointer()); + let ptr = self.context.new_cast(self.location, ptr, typ.make_pointer()); let ptr_type = ptr.get_type(); let mut pointee_type = ptr.get_type(); // NOTE: we cannot use array indexing here like in inbounds_gep because array indexing is // always considered in bounds in GCC (TODO(antoyo): to be verified). // So, we have to cast to a number. - let mut result = self.context.new_bitcast(None, ptr, self.sizet_type); + let mut result = self.context.new_bitcast(self.location, ptr, self.sizet_type); // FIXME(antoyo): if there were more than 1 index, this code is probably wrong and would // require dereferencing the pointer. for index in indices { pointee_type = pointee_type.get_pointee().expect("pointee type"); - #[cfg(feature="master")] + #[cfg(feature = "master")] let pointee_size = { let size = self.cx.context.new_sizeof(pointee_type); - self.context.new_cast(None, size, index.get_type()) + self.context.new_cast(self.location, size, index.get_type()) }; - #[cfg(not(feature="master"))] - let pointee_size = self.context.new_rvalue_from_int(index.get_type(), pointee_type.get_size() as i32); + #[cfg(not(feature = "master"))] + let pointee_size = + self.context.new_rvalue_from_int(index.get_type(), pointee_type.get_size() as i32); result = result + self.gcc_int_cast(*index * pointee_size, self.sizet_type); } - self.context.new_bitcast(None, result, ptr_type) + self.context.new_bitcast(self.location, result, ptr_type) } - fn inbounds_gep(&mut self, typ: Type<'gcc>, ptr: RValue<'gcc>, indices: &[RValue<'gcc>]) -> RValue<'gcc> { + fn inbounds_gep( + &mut self, + typ: Type<'gcc>, + ptr: RValue<'gcc>, + indices: &[RValue<'gcc>], + ) -> RValue<'gcc> { // NOTE: due to opaque pointers now being used, we need to cast here. - let ptr = self.context.new_cast(None, ptr, typ.make_pointer()); + let ptr = self.context.new_cast(self.location, ptr, typ.make_pointer()); // NOTE: array indexing is always considered in bounds in GCC (TODO(antoyo): to be verified). let mut indices = indices.into_iter(); let index = indices.next().expect("first index in inbounds_gep"); - let mut result = self.context.new_array_access(None, ptr, *index); + let mut result = self.context.new_array_access(self.location, ptr, *index); for index in indices { - result = self.context.new_array_access(None, result, *index); + result = self.context.new_array_access(self.location, result, *index); } - result.get_address(None) + result.get_address(self.location) } /* Casts */ @@ -986,32 +1197,32 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { // TODO(antoyo): nothing to do as it is only for LLVM? return value; } - self.context.new_cast(None, value, dest_ty) + self.context.new_cast(self.location, value, dest_ty) } fn fptoui(&mut self, value: RValue<'gcc>, dest_ty: Type<'gcc>) -> RValue<'gcc> { - self.gcc_float_to_uint_cast(value, dest_ty) + set_rvalue_location(self, self.gcc_float_to_uint_cast(value, dest_ty)) } fn fptosi(&mut self, value: RValue<'gcc>, dest_ty: Type<'gcc>) -> RValue<'gcc> { - self.gcc_float_to_int_cast(value, dest_ty) + set_rvalue_location(self, self.gcc_float_to_int_cast(value, dest_ty)) } fn uitofp(&mut self, value: RValue<'gcc>, dest_ty: Type<'gcc>) -> RValue<'gcc> { - self.gcc_uint_to_float_cast(value, dest_ty) + set_rvalue_location(self, self.gcc_uint_to_float_cast(value, dest_ty)) } fn sitofp(&mut self, value: RValue<'gcc>, dest_ty: Type<'gcc>) -> RValue<'gcc> { - self.gcc_int_to_float_cast(value, dest_ty) + set_rvalue_location(self, self.gcc_int_to_float_cast(value, dest_ty)) } fn fptrunc(&mut self, value: RValue<'gcc>, dest_ty: Type<'gcc>) -> RValue<'gcc> { // TODO(antoyo): make sure it truncates. - self.context.new_cast(None, value, dest_ty) + set_rvalue_location(self, self.context.new_cast(self.location, value, dest_ty)) } fn fpext(&mut self, value: RValue<'gcc>, dest_ty: Type<'gcc>) -> RValue<'gcc> { - self.context.new_cast(None, value, dest_ty) + set_rvalue_location(self, self.context.new_cast(self.location, value, dest_ty)) } fn ptrtoint(&mut self, value: RValue<'gcc>, dest_ty: Type<'gcc>) -> RValue<'gcc> { @@ -1028,7 +1239,12 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { self.cx.const_bitcast(value, dest_ty) } - fn intcast(&mut self, value: RValue<'gcc>, dest_typ: Type<'gcc>, _is_signed: bool) -> RValue<'gcc> { + fn intcast( + &mut self, + value: RValue<'gcc>, + dest_typ: Type<'gcc>, + _is_signed: bool, + ) -> RValue<'gcc> { // NOTE: is_signed is for value, not dest_typ. self.gcc_int_cast(value, dest_typ) } @@ -1039,13 +1255,17 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { (false, true) => { // NOTE: Projecting a field of a pointer type will attempt a cast from a signed char to // a pointer, which is not supported by gccjit. - return self.cx.context.new_cast(None, self.inttoptr(value, val_type.make_pointer()), dest_ty); - }, + self.cx.context.new_cast( + self.location, + self.inttoptr(value, val_type.make_pointer()), + dest_ty, + ) + } (false, false) => { // When they are not pointers, we want a transmute (or reinterpret_cast). self.bitcast(value, dest_ty) - }, - (true, true) => self.cx.context.new_cast(None, value, dest_ty), + } + (true, true) => self.cx.context.new_cast(self.location, value, dest_ty), (true, false) => unimplemented!(), } } @@ -1056,11 +1276,19 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { } fn fcmp(&mut self, op: RealPredicate, lhs: RValue<'gcc>, rhs: RValue<'gcc>) -> RValue<'gcc> { - self.context.new_comparison(None, op.to_gcc_comparison(), lhs, rhs) + self.context.new_comparison(self.location, op.to_gcc_comparison(), lhs, rhs) } /* Miscellaneous instructions */ - fn memcpy(&mut self, dst: RValue<'gcc>, _dst_align: Align, src: RValue<'gcc>, _src_align: Align, size: RValue<'gcc>, flags: MemFlags) { + fn memcpy( + &mut self, + dst: RValue<'gcc>, + _dst_align: Align, + src: RValue<'gcc>, + _src_align: Align, + size: RValue<'gcc>, + flags: MemFlags, + ) { assert!(!flags.contains(MemFlags::NONTEMPORAL), "non-temporal memcpy not supported"); let size = self.intcast(size, self.type_size_t(), false); let _is_volatile = flags.contains(MemFlags::VOLATILE); @@ -1068,10 +1296,21 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { let src = self.pointercast(src, self.type_ptr_to(self.type_void())); let memcpy = self.context.get_builtin_function("memcpy"); // TODO(antoyo): handle aligns and is_volatile. - self.block.add_eval(None, self.context.new_call(None, memcpy, &[dst, src, size])); + self.block.add_eval( + self.location, + self.context.new_call(self.location, memcpy, &[dst, src, size]), + ); } - fn memmove(&mut self, dst: RValue<'gcc>, dst_align: Align, src: RValue<'gcc>, src_align: Align, size: RValue<'gcc>, flags: MemFlags) { + fn memmove( + &mut self, + dst: RValue<'gcc>, + dst_align: Align, + src: RValue<'gcc>, + src_align: Align, + size: RValue<'gcc>, + flags: MemFlags, + ) { if flags.contains(MemFlags::NONTEMPORAL) { // HACK(nox): This is inefficient but there is no nontemporal memmove. let val = self.load(src.get_type().get_pointee().expect("get_pointee"), src, src_align); @@ -1086,35 +1325,53 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { let memmove = self.context.get_builtin_function("memmove"); // TODO(antoyo): handle is_volatile. - self.block.add_eval(None, self.context.new_call(None, memmove, &[dst, src, size])); + self.block.add_eval( + self.location, + self.context.new_call(self.location, memmove, &[dst, src, size]), + ); } - fn memset(&mut self, ptr: RValue<'gcc>, fill_byte: RValue<'gcc>, size: RValue<'gcc>, _align: Align, flags: MemFlags) { + fn memset( + &mut self, + ptr: RValue<'gcc>, + fill_byte: RValue<'gcc>, + size: RValue<'gcc>, + _align: Align, + flags: MemFlags, + ) { let _is_volatile = flags.contains(MemFlags::VOLATILE); let ptr = self.pointercast(ptr, self.type_i8p()); let memset = self.context.get_builtin_function("memset"); // TODO(antoyo): handle align and is_volatile. - let fill_byte = self.context.new_cast(None, fill_byte, self.i32_type); + let fill_byte = self.context.new_cast(self.location, fill_byte, self.i32_type); let size = self.intcast(size, self.type_size_t(), false); - self.block.add_eval(None, self.context.new_call(None, memset, &[ptr, fill_byte, size])); + self.block.add_eval( + self.location, + self.context.new_call(self.location, memset, &[ptr, fill_byte, size]), + ); } - fn select(&mut self, cond: RValue<'gcc>, then_val: RValue<'gcc>, mut else_val: RValue<'gcc>) -> RValue<'gcc> { + fn select( + &mut self, + cond: RValue<'gcc>, + then_val: RValue<'gcc>, + mut else_val: RValue<'gcc>, + ) -> RValue<'gcc> { let func = self.current_func(); - let variable = func.new_local(None, then_val.get_type(), "selectVar"); + let variable = func.new_local(self.location, then_val.get_type(), "selectVar"); let then_block = func.new_block("then"); let else_block = func.new_block("else"); let after_block = func.new_block("after"); - self.llbb().end_with_conditional(None, cond, then_block, else_block); + self.llbb().end_with_conditional(self.location, cond, then_block, else_block); - then_block.add_assignment(None, variable, then_val); - then_block.end_with_jump(None, after_block); + then_block.add_assignment(self.location, variable, then_val); + then_block.end_with_jump(self.location, after_block); if !then_val.get_type().is_compatible_with(else_val.get_type()) { - else_val = self.context.new_cast(None, else_val, then_val.get_type()); + else_val = self.context.new_cast(self.location, else_val, then_val.get_type()); } - else_block.add_assignment(None, variable, else_val); - else_block.end_with_jump(None, after_block); + else_block.add_assignment(self.location, variable, else_val); + else_block.end_with_jump(self.location, after_block); // NOTE: since jumps were added in a place rustc does not expect, the current block in the // state need to be updated. @@ -1128,19 +1385,24 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { unimplemented!(); } - #[cfg(feature="master")] + #[cfg(feature = "master")] fn extract_element(&mut self, vec: RValue<'gcc>, idx: RValue<'gcc>) -> RValue<'gcc> { - self.context.new_vector_access(None, vec, idx).to_rvalue() + self.context.new_vector_access(self.location, vec, idx).to_rvalue() } - #[cfg(not(feature="master"))] + #[cfg(not(feature = "master"))] fn extract_element(&mut self, vec: RValue<'gcc>, idx: RValue<'gcc>) -> RValue<'gcc> { - let vector_type = vec.get_type().unqualified().dyncast_vector().expect("Called extract_element on a non-vector type"); + let vector_type = vec + .get_type() + .unqualified() + .dyncast_vector() + .expect("Called extract_element on a non-vector type"); let element_type = vector_type.get_element_type(); let vec_num_units = vector_type.get_num_units(); - let array_type = self.context.new_array_type(None, element_type, vec_num_units as u64); - let array = self.context.new_bitcast(None, vec, array_type).to_rvalue(); - self.context.new_array_access(None, array, idx).to_rvalue() + let array_type = + self.context.new_array_type(self.location, element_type, vec_num_units as u64); + let array = self.context.new_bitcast(self.location, vec, array_type).to_rvalue(); + self.context.new_array_access(self.location, array, idx).to_rvalue() } fn vector_splat(&mut self, _num_elts: usize, _elt: RValue<'gcc>) -> RValue<'gcc> { @@ -1153,82 +1415,85 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { let value_type = aggregate_value.get_type(); if value_type.dyncast_array().is_some() { - let index = self.context.new_rvalue_from_long(self.u64_type, i64::try_from(idx).expect("i64::try_from")); - let element = self.context.new_array_access(None, aggregate_value, index); - element.get_address(None) - } - else if value_type.dyncast_vector().is_some() { + let index = self + .context + .new_rvalue_from_long(self.u64_type, i64::try_from(idx).expect("i64::try_from")); + let element = self.context.new_array_access(self.location, aggregate_value, index); + element.get_address(self.location) + } else if value_type.dyncast_vector().is_some() { panic!(); - } - else if let Some(pointer_type) = value_type.get_pointee() { + } else if let Some(pointer_type) = value_type.get_pointee() { if let Some(struct_type) = pointer_type.is_struct() { // NOTE: hack to workaround a limitation of the rustc API: see comment on // CodegenCx.structs_as_pointer - aggregate_value.dereference_field(None, struct_type.get_field(idx as i32)).to_rvalue() - } - else { + aggregate_value + .dereference_field(self.location, struct_type.get_field(idx as i32)) + .to_rvalue() + } else { panic!("Unexpected type {:?}", value_type); } - } - else if let Some(struct_type) = value_type.is_struct() { - aggregate_value.access_field(None, struct_type.get_field(idx as i32)).to_rvalue() - } - else { + } else if let Some(struct_type) = value_type.is_struct() { + aggregate_value + .access_field(self.location, struct_type.get_field(idx as i32)) + .to_rvalue() + } else { panic!("Unexpected type {:?}", value_type); } } - fn insert_value(&mut self, aggregate_value: RValue<'gcc>, value: RValue<'gcc>, idx: u64) -> RValue<'gcc> { + fn insert_value( + &mut self, + aggregate_value: RValue<'gcc>, + value: RValue<'gcc>, + idx: u64, + ) -> RValue<'gcc> { // FIXME(antoyo): it would be better if the API only called this on struct, not on arrays. assert_eq!(idx as usize as u64, idx); let value_type = aggregate_value.get_type(); - let lvalue = - if value_type.dyncast_array().is_some() { - let index = self.context.new_rvalue_from_long(self.u64_type, i64::try_from(idx).expect("i64::try_from")); - self.context.new_array_access(None, aggregate_value, index) - } - else if value_type.dyncast_vector().is_some() { - panic!(); - } - else if let Some(pointer_type) = value_type.get_pointee() { - if let Some(struct_type) = pointer_type.is_struct() { - // NOTE: hack to workaround a limitation of the rustc API: see comment on - // CodegenCx.structs_as_pointer - aggregate_value.dereference_field(None, struct_type.get_field(idx as i32)) - } - else { - panic!("Unexpected type {:?}", value_type); - } - } - else { + let lvalue = if value_type.dyncast_array().is_some() { + let index = self + .context + .new_rvalue_from_long(self.u64_type, i64::try_from(idx).expect("i64::try_from")); + self.context.new_array_access(self.location, aggregate_value, index) + } else if value_type.dyncast_vector().is_some() { + panic!(); + } else if let Some(pointer_type) = value_type.get_pointee() { + if let Some(struct_type) = pointer_type.is_struct() { + // NOTE: hack to workaround a limitation of the rustc API: see comment on + // CodegenCx.structs_as_pointer + aggregate_value.dereference_field(self.location, struct_type.get_field(idx as i32)) + } else { panic!("Unexpected type {:?}", value_type); - }; + } + } else { + panic!("Unexpected type {:?}", value_type); + }; let lvalue_type = lvalue.to_rvalue().get_type(); let value = // NOTE: sometimes, rustc will create a value with the wrong type. if lvalue_type != value.get_type() { - self.context.new_cast(None, value, lvalue_type) + self.context.new_cast(self.location, value, lvalue_type) } else { value }; - self.llbb().add_assignment(None, lvalue, value); + self.llbb().add_assignment(self.location, lvalue, value); aggregate_value } fn set_personality_fn(&mut self, _personality: RValue<'gcc>) { - #[cfg(feature="master")] + #[cfg(feature = "master")] { let personality = self.rvalue_as_function(_personality); self.current_func().set_personality_function(personality); } } - #[cfg(feature="master")] + #[cfg(feature = "master")] fn cleanup_landing_pad(&mut self, pers_fn: RValue<'gcc>) -> (RValue<'gcc>, RValue<'gcc>) { self.set_personality_fn(pers_fn); @@ -1236,23 +1501,27 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { // generate a try/finally instead of a try/catch for this block. self.cleanup_blocks.borrow_mut().insert(self.block); - let eh_pointer_builtin = self.cx.context.get_target_builtin_function("__builtin_eh_pointer"); + let eh_pointer_builtin = + self.cx.context.get_target_builtin_function("__builtin_eh_pointer"); let zero = self.cx.context.new_rvalue_zero(self.int_type); - let ptr = self.cx.context.new_call(None, eh_pointer_builtin, &[zero]); + let ptr = self.cx.context.new_call(self.location, eh_pointer_builtin, &[zero]); let value1_type = self.u8_type.make_pointer(); - let ptr = self.cx.context.new_cast(None, ptr, value1_type); + let ptr = self.cx.context.new_cast(self.location, ptr, value1_type); let value1 = ptr; let value2 = zero; // TODO(antoyo): set the proper value here (the type of exception?). (value1, value2) } - #[cfg(not(feature="master"))] + #[cfg(not(feature = "master"))] fn cleanup_landing_pad(&mut self, _pers_fn: RValue<'gcc>) -> (RValue<'gcc>, RValue<'gcc>) { - let value1 = self.current_func().new_local(None, self.u8_type.make_pointer(), "landing_pad0") - .to_rvalue(); - let value2 = self.current_func().new_local(None, self.i32_type, "landing_pad1").to_rvalue(); + let value1 = self + .current_func() + .new_local(self.location, self.u8_type.make_pointer(), "landing_pad0") + .to_rvalue(); + let value2 = + self.current_func().new_local(self.location, self.i32_type, "landing_pad1").to_rvalue(); (value1, value2) } @@ -1261,16 +1530,17 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { self.cleanup_landing_pad(pers_fn) } - #[cfg(feature="master")] + #[cfg(feature = "master")] fn resume(&mut self, exn0: RValue<'gcc>, _exn1: RValue<'gcc>) { let exn_type = exn0.get_type(); - let exn = self.context.new_cast(None, exn0, exn_type); + let exn = self.context.new_cast(self.location, exn0, exn_type); let unwind_resume = self.context.get_target_builtin_function("__builtin_unwind_resume"); - self.llbb().add_eval(None, self.context.new_call(None, unwind_resume, &[exn])); + self.llbb() + .add_eval(self.location, self.context.new_call(self.location, unwind_resume, &[exn])); self.unreachable(); } - #[cfg(not(feature="master"))] + #[cfg(not(feature = "master"))] fn resume(&mut self, _exn0: RValue<'gcc>, _exn1: RValue<'gcc>) { self.unreachable(); } @@ -1297,68 +1567,82 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { } // Atomic Operations - fn atomic_cmpxchg(&mut self, dst: RValue<'gcc>, cmp: RValue<'gcc>, src: RValue<'gcc>, order: AtomicOrdering, failure_order: AtomicOrdering, weak: bool) -> (RValue<'gcc>, RValue<'gcc>) { + fn atomic_cmpxchg( + &mut self, + dst: RValue<'gcc>, + cmp: RValue<'gcc>, + src: RValue<'gcc>, + order: AtomicOrdering, + failure_order: AtomicOrdering, + weak: bool, + ) -> (RValue<'gcc>, RValue<'gcc>) { let expected = self.current_func().new_local(None, cmp.get_type(), "expected"); self.llbb().add_assignment(None, expected, cmp); // NOTE: gcc doesn't support a failure memory model that is stronger than the success // memory model. - let order = - if failure_order as i32 > order as i32 { - failure_order - } - else { - order - }; + let order = if failure_order as i32 > order as i32 { failure_order } else { order }; let success = self.compare_exchange(dst, expected, src, order, failure_order, weak); // NOTE: since success contains the call to the intrinsic, it must be added to the basic block before // expected so that we store expected after the call. - let success_var = self.current_func().new_local(None, self.bool_type, "success"); - self.llbb().add_assignment(None, success_var, success); + let success_var = self.current_func().new_local(self.location, self.bool_type, "success"); + self.llbb().add_assignment(self.location, success_var, success); (expected.to_rvalue(), success_var.to_rvalue()) } - fn atomic_rmw(&mut self, op: AtomicRmwBinOp, dst: RValue<'gcc>, src: RValue<'gcc>, order: AtomicOrdering) -> RValue<'gcc> { + fn atomic_rmw( + &mut self, + op: AtomicRmwBinOp, + dst: RValue<'gcc>, + src: RValue<'gcc>, + order: AtomicOrdering, + ) -> RValue<'gcc> { let size = src.get_type().get_size(); - let name = - match op { - AtomicRmwBinOp::AtomicXchg => format!("__atomic_exchange_{}", size), - AtomicRmwBinOp::AtomicAdd => format!("__atomic_fetch_add_{}", size), - AtomicRmwBinOp::AtomicSub => format!("__atomic_fetch_sub_{}", size), - AtomicRmwBinOp::AtomicAnd => format!("__atomic_fetch_and_{}", size), - AtomicRmwBinOp::AtomicNand => format!("__atomic_fetch_nand_{}", size), - AtomicRmwBinOp::AtomicOr => format!("__atomic_fetch_or_{}", size), - AtomicRmwBinOp::AtomicXor => format!("__atomic_fetch_xor_{}", size), - AtomicRmwBinOp::AtomicMax => return self.atomic_extremum(ExtremumOperation::Max, dst, src, order), - AtomicRmwBinOp::AtomicMin => return self.atomic_extremum(ExtremumOperation::Min, dst, src, order), - AtomicRmwBinOp::AtomicUMax => return self.atomic_extremum(ExtremumOperation::Max, dst, src, order), - AtomicRmwBinOp::AtomicUMin => return self.atomic_extremum(ExtremumOperation::Min, dst, src, order), - }; - + let name = match op { + AtomicRmwBinOp::AtomicXchg => format!("__atomic_exchange_{}", size), + AtomicRmwBinOp::AtomicAdd => format!("__atomic_fetch_add_{}", size), + AtomicRmwBinOp::AtomicSub => format!("__atomic_fetch_sub_{}", size), + AtomicRmwBinOp::AtomicAnd => format!("__atomic_fetch_and_{}", size), + AtomicRmwBinOp::AtomicNand => format!("__atomic_fetch_nand_{}", size), + AtomicRmwBinOp::AtomicOr => format!("__atomic_fetch_or_{}", size), + AtomicRmwBinOp::AtomicXor => format!("__atomic_fetch_xor_{}", size), + AtomicRmwBinOp::AtomicMax => { + return self.atomic_extremum(ExtremumOperation::Max, dst, src, order); + } + AtomicRmwBinOp::AtomicMin => { + return self.atomic_extremum(ExtremumOperation::Min, dst, src, order); + } + AtomicRmwBinOp::AtomicUMax => { + return self.atomic_extremum(ExtremumOperation::Max, dst, src, order); + } + AtomicRmwBinOp::AtomicUMin => { + return self.atomic_extremum(ExtremumOperation::Min, dst, src, order); + } + }; let atomic_function = self.context.get_builtin_function(name); let order = self.context.new_rvalue_from_int(self.i32_type, order.to_gcc()); let void_ptr_type = self.context.new_type::<*mut ()>(); let volatile_void_ptr_type = void_ptr_type.make_volatile(); - let dst = self.context.new_cast(None, dst, volatile_void_ptr_type); + let dst = self.context.new_cast(self.location, dst, volatile_void_ptr_type); // FIXME(antoyo): not sure why, but we have the wrong type here. let new_src_type = atomic_function.get_param(1).to_rvalue().get_type(); - let src = self.context.new_cast(None, src, new_src_type); - let res = self.context.new_call(None, atomic_function, &[dst, src, order]); - self.context.new_cast(None, res, src.get_type()) + let src = self.context.new_cast(self.location, src, new_src_type); + let res = self.context.new_call(self.location, atomic_function, &[dst, src, order]); + self.context.new_cast(self.location, res, src.get_type()) } fn atomic_fence(&mut self, order: AtomicOrdering, scope: SynchronizationScope) { - let name = - match scope { - SynchronizationScope::SingleThread => "__atomic_signal_fence", - SynchronizationScope::CrossThread => "__atomic_thread_fence", - }; + let name = match scope { + SynchronizationScope::SingleThread => "__atomic_signal_fence", + SynchronizationScope::CrossThread => "__atomic_thread_fence", + }; let thread_fence = self.context.get_builtin_function(name); let order = self.context.new_rvalue_from_int(self.i32_type, order.to_gcc()); - self.llbb().add_eval(None, self.context.new_call(None, thread_fence, &[order])); + self.llbb() + .add_eval(self.location, self.context.new_call(self.location, thread_fence, &[order])); } fn set_invariant_load(&mut self, load: RValue<'gcc>) { @@ -1388,8 +1672,7 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { let gcc_func = unsafe { std::mem::transmute(func) }; let call = if self.functions.borrow().values().any(|value| *value == gcc_func) { self.function_call(func, args, funclet) - } - else { + } else { // If it's a not function that was defined, it's a function pointer. self.function_ptr_call(typ, func, args, funclet) }; @@ -1422,8 +1705,7 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { fn from_immediate(&mut self, val: Self::Value) -> Self::Value { if self.cx().val_ty(val) == self.cx().type_i1() { self.zext(val, self.cx().type_i8()) - } - else { + } else { val } } @@ -1443,13 +1725,24 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { self.fptoint_sat(true, val, dest_ty) } - fn instrprof_increment(&mut self, _fn_name: RValue<'gcc>, _hash: RValue<'gcc>, _num_counters: RValue<'gcc>, _index: RValue<'gcc>) { + fn instrprof_increment( + &mut self, + _fn_name: RValue<'gcc>, + _hash: RValue<'gcc>, + _num_counters: RValue<'gcc>, + _index: RValue<'gcc>, + ) { unimplemented!(); } } impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { - fn fptoint_sat(&mut self, signed: bool, val: RValue<'gcc>, dest_ty: Type<'gcc>) -> RValue<'gcc> { + fn fptoint_sat( + &mut self, + signed: bool, + val: RValue<'gcc>, + dest_ty: Type<'gcc>, + ) -> RValue<'gcc> { let src_ty = self.cx.val_ty(val); let (float_ty, int_ty) = if self.cx.type_kind(src_ty) == TypeKind::Vector { assert_eq!(self.cx.vector_length(src_ty), self.cx.vector_length(dest_ty)); @@ -1486,10 +1779,18 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { // This already happens today with u128::MAX = 2^128 - 1 > f32::MAX. let int_max = |signed: bool, int_width: u64| -> u128 { let shift_amount = 128 - int_width; - if signed { i128::MAX as u128 >> shift_amount } else { u128::MAX >> shift_amount } + if signed { + i128::MAX as u128 >> shift_amount + } else { + u128::MAX >> shift_amount + } }; let int_min = |signed: bool, int_width: u64| -> i128 { - if signed { i128::MIN >> (128 - int_width) } else { 0 } + if signed { + i128::MIN >> (128 - int_width) + } else { + 0 + } }; let compute_clamp_bounds_single = |signed: bool, int_width: u64| -> (u128, u128) { @@ -1573,7 +1874,8 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { let zero = maybe_splat(self, zero); // Step 1 ... - let fptosui_result = if signed { self.fptosi(val, dest_ty) } else { self.fptoui(val, dest_ty) }; + let fptosui_result = + if signed { self.fptosi(val, dest_ty) } else { self.fptoui(val, dest_ty) }; let less_or_nan = self.fcmp(RealPredicate::RealULT, val, f_min); let greater = self.fcmp(RealPredicate::RealOGT, val, f_max); @@ -1609,8 +1911,13 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { } } - #[cfg(feature="master")] - pub fn shuffle_vector(&mut self, v1: RValue<'gcc>, v2: RValue<'gcc>, mask: RValue<'gcc>) -> RValue<'gcc> { + #[cfg(feature = "master")] + pub fn shuffle_vector( + &mut self, + v1: RValue<'gcc>, + v2: RValue<'gcc>, + mask: RValue<'gcc>, + ) -> RValue<'gcc> { let struct_type = mask.get_type().is_struct().expect("mask should be of struct type"); // TODO(antoyo): use a recursive unqualified() here. @@ -1620,21 +1927,23 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { let mask_num_units = struct_type.get_field_count(); let mut vector_elements = vec![]; - let mask_element_type = - if element_type.is_integral() { - element_type + let mask_element_type = if element_type.is_integral() { + element_type + } else { + #[cfg(feature = "master")] + { + self.cx.type_ix(element_type.get_size() as u64 * 8) } - else { - #[cfg(feature="master")] - { - self.cx.type_ix(element_type.get_size() as u64 * 8) - } - #[cfg(not(feature="master"))] - self.int_type - }; + #[cfg(not(feature = "master"))] + self.int_type + }; for i in 0..mask_num_units { let field = struct_type.get_field(i as i32); - vector_elements.push(self.context.new_cast(None, mask.access_field(None, field).to_rvalue(), mask_element_type)); + vector_elements.push(self.context.new_cast( + self.location, + mask.access_field(self.location, field).to_rvalue(), + mask_element_type, + )); } // NOTE: the mask needs to be the same length as the input vectors, so add the missing @@ -1644,53 +1953,84 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { } let result_type = self.context.new_vector_type(element_type, mask_num_units as u64); - let (v1, v2) = - if vec_num_units < mask_num_units { - // NOTE: the mask needs to be the same length as the input vectors, so join the 2 - // vectors and create a dummy second vector. - let mut elements = vec![]; - for i in 0..vec_num_units { - elements.push(self.context.new_vector_access(None, v1, self.context.new_rvalue_from_int(self.int_type, i as i32)).to_rvalue()); - } - for i in 0..(mask_num_units - vec_num_units) { - elements.push(self.context.new_vector_access(None, v2, self.context.new_rvalue_from_int(self.int_type, i as i32)).to_rvalue()); - } - let v1 = self.context.new_rvalue_from_vector(None, result_type, &elements); - let zero = self.context.new_rvalue_zero(element_type); - let v2 = self.context.new_rvalue_from_vector(None, result_type, &vec![zero; mask_num_units]); - (v1, v2) + let (v1, v2) = if vec_num_units < mask_num_units { + // NOTE: the mask needs to be the same length as the input vectors, so join the 2 + // vectors and create a dummy second vector. + let mut elements = vec![]; + for i in 0..vec_num_units { + elements.push( + self.context + .new_vector_access( + self.location, + v1, + self.context.new_rvalue_from_int(self.int_type, i as i32), + ) + .to_rvalue(), + ); } - else { - (v1, v2) - }; + for i in 0..(mask_num_units - vec_num_units) { + elements.push( + self.context + .new_vector_access( + self.location, + v2, + self.context.new_rvalue_from_int(self.int_type, i as i32), + ) + .to_rvalue(), + ); + } + let v1 = self.context.new_rvalue_from_vector(self.location, result_type, &elements); + let zero = self.context.new_rvalue_zero(element_type); + let v2 = self.context.new_rvalue_from_vector( + self.location, + result_type, + &vec![zero; mask_num_units], + ); + (v1, v2) + } else { + (v1, v2) + }; let new_mask_num_units = std::cmp::max(mask_num_units, vec_num_units); let mask_type = self.context.new_vector_type(mask_element_type, new_mask_num_units as u64); - let mask = self.context.new_rvalue_from_vector(None, mask_type, &vector_elements); - let result = self.context.new_rvalue_vector_perm(None, v1, v2, mask); + let mask = self.context.new_rvalue_from_vector(self.location, mask_type, &vector_elements); + let result = self.context.new_rvalue_vector_perm(self.location, v1, v2, mask); if vec_num_units != mask_num_units { // NOTE: if padding was added, only select the number of elements of the masks to // remove that padding in the result. let mut elements = vec![]; for i in 0..mask_num_units { - elements.push(self.context.new_vector_access(None, result, self.context.new_rvalue_from_int(self.int_type, i as i32)).to_rvalue()); + elements.push( + self.context + .new_vector_access( + self.location, + result, + self.context.new_rvalue_from_int(self.int_type, i as i32), + ) + .to_rvalue(), + ); } - self.context.new_rvalue_from_vector(None, result_type, &elements) - } - else { + self.context.new_rvalue_from_vector(self.location, result_type, &elements) + } else { result } } - #[cfg(not(feature="master"))] - pub fn shuffle_vector(&mut self, _v1: RValue<'gcc>, _v2: RValue<'gcc>, _mask: RValue<'gcc>) -> RValue<'gcc> { + #[cfg(not(feature = "master"))] + pub fn shuffle_vector( + &mut self, + _v1: RValue<'gcc>, + _v2: RValue<'gcc>, + _mask: RValue<'gcc>, + ) -> RValue<'gcc> { unimplemented!(); } - #[cfg(feature="master")] + #[cfg(feature = "master")] pub fn vector_reduce(&mut self, src: RValue<'gcc>, op: F) -> RValue<'gcc> - where F: Fn(RValue<'gcc>, RValue<'gcc>, &'gcc Context<'gcc>) -> RValue<'gcc> + where + F: Fn(RValue<'gcc>, RValue<'gcc>, &'gcc Context<'gcc>) -> RValue<'gcc>, { let vector_type = src.get_type().unqualified().dyncast_vector().expect("vector type"); let element_type = vector_type.get_element_type(); @@ -1704,130 +2044,178 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { let mut shift = 1; let mut res = src; while shift < element_count { - let vector_elements: Vec<_> = - vector_elements.iter() - .map(|i| self.context.new_rvalue_from_int(mask_element_type, ((i + shift) % element_count) as i32)) - .collect(); - let mask = self.context.new_rvalue_from_vector(None, mask_type, &vector_elements); - let shifted = self.context.new_rvalue_vector_perm(None, res, res, mask); + let vector_elements: Vec<_> = vector_elements + .iter() + .map(|i| { + self.context.new_rvalue_from_int( + mask_element_type, + ((i + shift) % element_count) as i32, + ) + }) + .collect(); + let mask = + self.context.new_rvalue_from_vector(self.location, mask_type, &vector_elements); + let shifted = self.context.new_rvalue_vector_perm(self.location, res, res, mask); shift *= 2; res = op(res, shifted, &self.context); } - self.context.new_vector_access(None, res, self.context.new_rvalue_zero(self.int_type)) + self.context + .new_vector_access(self.location, res, self.context.new_rvalue_zero(self.int_type)) .to_rvalue() } - #[cfg(not(feature="master"))] + #[cfg(not(feature = "master"))] pub fn vector_reduce(&mut self, _src: RValue<'gcc>, _op: F) -> RValue<'gcc> - where F: Fn(RValue<'gcc>, RValue<'gcc>, &'gcc Context<'gcc>) -> RValue<'gcc> + where + F: Fn(RValue<'gcc>, RValue<'gcc>, &'gcc Context<'gcc>) -> RValue<'gcc>, { unimplemented!(); } pub fn vector_reduce_op(&mut self, src: RValue<'gcc>, op: BinaryOp) -> RValue<'gcc> { - self.vector_reduce(src, |a, b, context| context.new_binary_op(None, op, a.get_type(), a, b)) + let loc = self.location.clone(); + self.vector_reduce(src, |a, b, context| context.new_binary_op(loc, op, a.get_type(), a, b)) } - pub fn vector_reduce_fadd_reassoc(&mut self, _acc: RValue<'gcc>, _src: RValue<'gcc>) -> RValue<'gcc> { + pub fn vector_reduce_fadd_reassoc( + &mut self, + _acc: RValue<'gcc>, + _src: RValue<'gcc>, + ) -> RValue<'gcc> { unimplemented!(); } - #[cfg(feature="master")] + #[cfg(feature = "master")] pub fn vector_reduce_fadd(&mut self, acc: RValue<'gcc>, src: RValue<'gcc>) -> RValue<'gcc> { let vector_type = src.get_type().unqualified().dyncast_vector().expect("vector type"); let element_count = vector_type.get_num_units(); - (0..element_count).into_iter() - .map(|i| self.context - .new_vector_access(None, src, self.context.new_rvalue_from_int(self.int_type, i as _)) - .to_rvalue()) + (0..element_count) + .into_iter() + .map(|i| { + self.context + .new_vector_access( + self.location, + src, + self.context.new_rvalue_from_int(self.int_type, i as _), + ) + .to_rvalue() + }) .fold(acc, |x, i| x + i) } - #[cfg(not(feature="master"))] + #[cfg(not(feature = "master"))] pub fn vector_reduce_fadd(&mut self, _acc: RValue<'gcc>, _src: RValue<'gcc>) -> RValue<'gcc> { unimplemented!(); } - pub fn vector_reduce_fmul_reassoc(&mut self, _acc: RValue<'gcc>, _src: RValue<'gcc>) -> RValue<'gcc> { + pub fn vector_reduce_fmul_reassoc( + &mut self, + _acc: RValue<'gcc>, + _src: RValue<'gcc>, + ) -> RValue<'gcc> { unimplemented!(); } - #[cfg(feature="master")] + #[cfg(feature = "master")] pub fn vector_reduce_fmul(&mut self, acc: RValue<'gcc>, src: RValue<'gcc>) -> RValue<'gcc> { let vector_type = src.get_type().unqualified().dyncast_vector().expect("vector type"); let element_count = vector_type.get_num_units(); - (0..element_count).into_iter() - .map(|i| self.context - .new_vector_access(None, src, self.context.new_rvalue_from_int(self.int_type, i as _)) - .to_rvalue()) + (0..element_count) + .into_iter() + .map(|i| { + self.context + .new_vector_access( + self.location, + src, + self.context.new_rvalue_from_int(self.int_type, i as _), + ) + .to_rvalue() + }) .fold(acc, |x, i| x * i) } - #[cfg(not(feature="master"))] + #[cfg(not(feature = "master"))] pub fn vector_reduce_fmul(&mut self, _acc: RValue<'gcc>, _src: RValue<'gcc>) -> RValue<'gcc> { unimplemented!() } // Inspired by Hacker's Delight min implementation. pub fn vector_reduce_min(&mut self, src: RValue<'gcc>) -> RValue<'gcc> { + let loc = self.location.clone(); self.vector_reduce(src, |a, b, context| { - let differences_or_zeros = difference_or_zero(a, b, context); - context.new_binary_op(None, BinaryOp::Plus, b.get_type(), b, differences_or_zeros) + let differences_or_zeros = difference_or_zero(loc, a, b, context); + context.new_binary_op(loc, BinaryOp::Plus, b.get_type(), b, differences_or_zeros) }) } // Inspired by Hacker's Delight max implementation. pub fn vector_reduce_max(&mut self, src: RValue<'gcc>) -> RValue<'gcc> { + let loc = self.location.clone(); self.vector_reduce(src, |a, b, context| { - let differences_or_zeros = difference_or_zero(a, b, context); - context.new_binary_op(None, BinaryOp::Minus, a.get_type(), a, differences_or_zeros) + let differences_or_zeros = difference_or_zero(loc, a, b, context); + context.new_binary_op(loc, BinaryOp::Minus, a.get_type(), a, differences_or_zeros) }) } - fn vector_extremum(&mut self, a: RValue<'gcc>, b: RValue<'gcc>, direction: ExtremumOperation) -> RValue<'gcc> { + fn vector_extremum( + &mut self, + a: RValue<'gcc>, + b: RValue<'gcc>, + direction: ExtremumOperation, + ) -> RValue<'gcc> { let vector_type = a.get_type(); // mask out the NaNs in b and replace them with the corresponding lane in a, so when a and // b get compared & spliced together, we get the numeric values instead of NaNs. - let b_nan_mask = self.context.new_comparison(None, ComparisonOp::NotEquals, b, b); + let b_nan_mask = self.context.new_comparison(self.location, ComparisonOp::NotEquals, b, b); let mask_type = b_nan_mask.get_type(); - let b_nan_mask_inverted = self.context.new_unary_op(None, UnaryOp::BitwiseNegate, mask_type, b_nan_mask); - let a_cast = self.context.new_bitcast(None, a, mask_type); - let b_cast = self.context.new_bitcast(None, b, mask_type); + let b_nan_mask_inverted = + self.context.new_unary_op(self.location, UnaryOp::BitwiseNegate, mask_type, b_nan_mask); + let a_cast = self.context.new_bitcast(self.location, a, mask_type); + let b_cast = self.context.new_bitcast(self.location, b, mask_type); let res = (b_nan_mask & a_cast) | (b_nan_mask_inverted & b_cast); - let b = self.context.new_bitcast(None, res, vector_type); + let b = self.context.new_bitcast(self.location, res, vector_type); // now do the actual comparison let comparison_op = match direction { ExtremumOperation::Min => ComparisonOp::LessThan, ExtremumOperation::Max => ComparisonOp::GreaterThan, }; - let cmp = self.context.new_comparison(None, comparison_op, a, b); - let cmp_inverted = self.context.new_unary_op(None, UnaryOp::BitwiseNegate, cmp.get_type(), cmp); + let cmp = self.context.new_comparison(self.location, comparison_op, a, b); + let cmp_inverted = + self.context.new_unary_op(self.location, UnaryOp::BitwiseNegate, cmp.get_type(), cmp); let res = (cmp & a_cast) | (cmp_inverted & res); - self.context.new_bitcast(None, res, vector_type) + self.context.new_bitcast(self.location, res, vector_type) } pub fn vector_fmin(&mut self, a: RValue<'gcc>, b: RValue<'gcc>) -> RValue<'gcc> { self.vector_extremum(a, b, ExtremumOperation::Min) } - #[cfg(feature="master")] + #[cfg(feature = "master")] pub fn vector_reduce_fmin(&mut self, src: RValue<'gcc>) -> RValue<'gcc> { let vector_type = src.get_type().unqualified().dyncast_vector().expect("vector type"); let element_count = vector_type.get_num_units(); - let mut acc = self.context.new_vector_access(None, src, self.context.new_rvalue_zero(self.int_type)).to_rvalue(); + let mut acc = self + .context + .new_vector_access(self.location, src, self.context.new_rvalue_zero(self.int_type)) + .to_rvalue(); for i in 1..element_count { - let elem = self.context - .new_vector_access(None, src, self.context.new_rvalue_from_int(self.int_type, i as _)) + let elem = self + .context + .new_vector_access( + self.location, + src, + self.context.new_rvalue_from_int(self.int_type, i as _), + ) .to_rvalue(); - let cmp = self.context.new_comparison(None, ComparisonOp::LessThan, acc, elem); + let cmp = self.context.new_comparison(self.location, ComparisonOp::LessThan, acc, elem); acc = self.select(cmp, acc, elem); } acc } - #[cfg(not(feature="master"))] + #[cfg(not(feature = "master"))] pub fn vector_reduce_fmin(&mut self, _src: RValue<'gcc>) -> RValue<'gcc> { unimplemented!(); } @@ -1836,36 +2224,51 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { self.vector_extremum(a, b, ExtremumOperation::Max) } - #[cfg(feature="master")] + #[cfg(feature = "master")] pub fn vector_reduce_fmax(&mut self, src: RValue<'gcc>) -> RValue<'gcc> { let vector_type = src.get_type().unqualified().dyncast_vector().expect("vector type"); let element_count = vector_type.get_num_units(); - let mut acc = self.context.new_vector_access(None, src, self.context.new_rvalue_zero(self.int_type)).to_rvalue(); + let mut acc = self + .context + .new_vector_access(self.location, src, self.context.new_rvalue_zero(self.int_type)) + .to_rvalue(); for i in 1..element_count { - let elem = self.context - .new_vector_access(None, src, self.context.new_rvalue_from_int(self.int_type, i as _)) + let elem = self + .context + .new_vector_access( + self.location, + src, + self.context.new_rvalue_from_int(self.int_type, i as _), + ) .to_rvalue(); - let cmp = self.context.new_comparison(None, ComparisonOp::GreaterThan, acc, elem); + let cmp = + self.context.new_comparison(self.location, ComparisonOp::GreaterThan, acc, elem); acc = self.select(cmp, acc, elem); } acc } - #[cfg(not(feature="master"))] + #[cfg(not(feature = "master"))] pub fn vector_reduce_fmax(&mut self, _src: RValue<'gcc>) -> RValue<'gcc> { unimplemented!(); } - pub fn vector_select(&mut self, cond: RValue<'gcc>, then_val: RValue<'gcc>, else_val: RValue<'gcc>) -> RValue<'gcc> { + pub fn vector_select( + &mut self, + cond: RValue<'gcc>, + then_val: RValue<'gcc>, + else_val: RValue<'gcc>, + ) -> RValue<'gcc> { // cond is a vector of integers, not of bools. let vector_type = cond.get_type().unqualified().dyncast_vector().expect("vector type"); let num_units = vector_type.get_num_units(); let element_type = vector_type.get_element_type(); - #[cfg(feature="master")] + #[cfg(feature = "master")] let (cond, element_type) = { // TODO(antoyo): dyncast_vector should not require a call to unqualified. - let then_val_vector_type = then_val.get_type().unqualified().dyncast_vector().expect("vector type"); + let then_val_vector_type = + then_val.get_type().unqualified().dyncast_vector().expect("vector type"); let then_val_element_type = then_val_vector_type.get_element_type(); let then_val_element_size = then_val_element_type.get_size(); @@ -1873,11 +2276,11 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { // operation to work. if then_val_element_size != element_type.get_size() { let new_element_type = self.type_ix(then_val_element_size as u64 * 8); - let new_vector_type = self.context.new_vector_type(new_element_type, num_units as u64); - let cond = self.context.convert_vector(None, cond, new_vector_type); + let new_vector_type = + self.context.new_vector_type(new_element_type, num_units as u64); + let cond = self.context.convert_vector(self.location, cond, new_vector_type); (cond, new_element_type) - } - else { + } else { (cond, element_type) } }; @@ -1885,24 +2288,25 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { let cond_type = cond.get_type(); let zeros = vec![self.context.new_rvalue_zero(element_type); num_units]; - let zeros = self.context.new_rvalue_from_vector(None, cond_type, &zeros); + let zeros = self.context.new_rvalue_from_vector(self.location, cond_type, &zeros); let result_type = then_val.get_type(); - let masks = self.context.new_comparison(None, ComparisonOp::NotEquals, cond, zeros); + let masks = + self.context.new_comparison(self.location, ComparisonOp::NotEquals, cond, zeros); // NOTE: masks is a vector of integers, but the values can be vectors of floats, so use bitcast to make // the & operation work. let then_val = self.bitcast_if_needed(then_val, masks.get_type()); let then_vals = masks & then_val; let minus_ones = vec![self.context.new_rvalue_from_int(element_type, -1); num_units]; - let minus_ones = self.context.new_rvalue_from_vector(None, cond_type, &minus_ones); + let minus_ones = self.context.new_rvalue_from_vector(self.location, cond_type, &minus_ones); let inverted_masks = masks ^ minus_ones; // NOTE: sometimes, the type of else_val can be different than the type of then_val in // libgccjit (vector of int vs vector of int32_t), but they should be the same for the AND // operation to work. // TODO: remove bitcast now that vector types can be compared? - let else_val = self.context.new_bitcast(None, else_val, then_val.get_type()); + let else_val = self.context.new_bitcast(self.location, else_val, then_val.get_type()); let else_vals = inverted_masks & else_val; let res = then_vals | else_vals; @@ -1910,26 +2314,26 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { } } -fn difference_or_zero<'gcc>(a: RValue<'gcc>, b: RValue<'gcc>, context: &'gcc Context<'gcc>) -> RValue<'gcc> { +fn difference_or_zero<'gcc>( + loc: Option>, + a: RValue<'gcc>, + b: RValue<'gcc>, + context: &'gcc Context<'gcc>, +) -> RValue<'gcc> { let difference = a - b; - let masks = context.new_comparison(None, ComparisonOp::GreaterThanEquals, b, a); + let masks = context.new_comparison(loc, ComparisonOp::GreaterThanEquals, b, a); // NOTE: masks is a vector of integers, but the values can be vectors of floats, so use bitcast to make // the & operation work. let a_type = a.get_type(); let masks = - if masks.get_type() != a_type { - context.new_bitcast(None, masks, a_type) - } - else { - masks - }; + if masks.get_type() != a_type { context.new_bitcast(loc, masks, a_type) } else { masks }; difference & masks } impl<'a, 'gcc, 'tcx> StaticBuilderMethods for Builder<'a, 'gcc, 'tcx> { fn get_static(&mut self, def_id: DefId) -> RValue<'gcc> { // Forward to the `get_static` method of `CodegenCx` - self.cx().get_static(def_id).get_address(None) + self.cx().get_static(def_id).get_address(self.location) } } @@ -2009,15 +2413,14 @@ impl ToGccOrdering for AtomicOrdering { fn to_gcc(self) -> i32 { use MemOrdering::*; - let ordering = - match self { - AtomicOrdering::Unordered => __ATOMIC_RELAXED, - AtomicOrdering::Relaxed => __ATOMIC_RELAXED, // TODO(antoyo): check if that's the same. - AtomicOrdering::Acquire => __ATOMIC_ACQUIRE, - AtomicOrdering::Release => __ATOMIC_RELEASE, - AtomicOrdering::AcquireRelease => __ATOMIC_ACQ_REL, - AtomicOrdering::SequentiallyConsistent => __ATOMIC_SEQ_CST, - }; + let ordering = match self { + AtomicOrdering::Unordered => __ATOMIC_RELAXED, + AtomicOrdering::Relaxed => __ATOMIC_RELAXED, // TODO(antoyo): check if that's the same. + AtomicOrdering::Acquire => __ATOMIC_ACQUIRE, + AtomicOrdering::Release => __ATOMIC_RELEASE, + AtomicOrdering::AcquireRelease => __ATOMIC_ACQ_REL, + AtomicOrdering::SequentiallyConsistent => __ATOMIC_SEQ_CST, + }; ordering as i32 } } diff --git a/src/callee.rs b/src/callee.rs index 9fc77627b1bc5..84f49b6856d4d 100644 --- a/src/callee.rs +++ b/src/callee.rs @@ -1,8 +1,8 @@ -#[cfg(feature="master")] +#[cfg(feature = "master")] use gccjit::{FnAttribute, Visibility}; -use gccjit::{FunctionType, Function}; -use rustc_middle::ty::{self, Instance, TypeVisitableExt}; +use gccjit::{Function, FunctionType}; use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt}; +use rustc_middle::ty::{self, Instance, TypeVisitableExt}; use crate::attributes; use crate::context::CodegenCx; @@ -28,145 +28,144 @@ pub fn get_fn<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, instance: Instance<'tcx>) let fn_abi = cx.fn_abi_of_instance(instance, ty::List::empty()); - let func = - if let Some(_func) = cx.get_declared_value(&sym) { - // FIXME(antoyo): we never reach this because get_declared_value only returns global variables - // and here we try to get a function. - unreachable!(); - /* - // Create a fn pointer with the new signature. - let ptrty = fn_abi.ptr_to_gcc_type(cx); - - // This is subtle and surprising, but sometimes we have to bitcast - // the resulting fn pointer. The reason has to do with external - // functions. If you have two crates that both bind the same C - // library, they may not use precisely the same types: for - // example, they will probably each declare their own structs, - // which are distinct types from LLVM's point of view (nominal - // types). - // - // Now, if those two crates are linked into an application, and - // they contain inlined code, you can wind up with a situation - // where both of those functions wind up being loaded into this - // application simultaneously. In that case, the same function - // (from LLVM's point of view) requires two types. But of course - // LLVM won't allow one function to have two types. - // - // What we currently do, therefore, is declare the function with - // one of the two types (whichever happens to come first) and then - // bitcast as needed when the function is referenced to make sure - // it has the type we expect. - // - // This can occur on either a crate-local or crate-external - // reference. It also occurs when testing libcore and in some - // other weird situations. Annoying. - if cx.val_ty(func) != ptrty { - // TODO(antoyo): cast the pointer. - func - } - else { - func - }*/ + let func = if let Some(_func) = cx.get_declared_value(&sym) { + // FIXME(antoyo): we never reach this because get_declared_value only returns global variables + // and here we try to get a function. + unreachable!(); + /* + // Create a fn pointer with the new signature. + let ptrty = fn_abi.ptr_to_gcc_type(cx); + + // This is subtle and surprising, but sometimes we have to bitcast + // the resulting fn pointer. The reason has to do with external + // functions. If you have two crates that both bind the same C + // library, they may not use precisely the same types: for + // example, they will probably each declare their own structs, + // which are distinct types from LLVM's point of view (nominal + // types). + // + // Now, if those two crates are linked into an application, and + // they contain inlined code, you can wind up with a situation + // where both of those functions wind up being loaded into this + // application simultaneously. In that case, the same function + // (from LLVM's point of view) requires two types. But of course + // LLVM won't allow one function to have two types. + // + // What we currently do, therefore, is declare the function with + // one of the two types (whichever happens to come first) and then + // bitcast as needed when the function is referenced to make sure + // it has the type we expect. + // + // This can occur on either a crate-local or crate-external + // reference. It also occurs when testing libcore and in some + // other weird situations. Annoying. + if cx.val_ty(func) != ptrty { + // TODO(antoyo): cast the pointer. + func } else { - cx.linkage.set(FunctionType::Extern); - let func = cx.declare_fn(&sym, &fn_abi); - - attributes::from_fn_attrs(cx, func, instance); - - let instance_def_id = instance.def_id(); - - // 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(tcx, instance.def_id()).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) - || !cx.tcx.local_crate_exports_generics() - { - #[cfg(feature="master")] - func.add_attribute(FnAttribute::Visibility(Visibility::Hidden)); - } + func + }*/ + } else { + cx.linkage.set(FunctionType::Extern); + let func = cx.declare_fn(&sym, &fn_abi); + + attributes::from_fn_attrs(cx, func, instance); + + let instance_def_id = instance.def_id(); + + // 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(tcx, instance.def_id()).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) + || !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 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)); - } + // 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)); } } - } else { - // When not sharing generics, all instances are in the same - // crate and have hidden visibility - #[cfg(feature="master")] - 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")] + // When not sharing generics, all instances are in the same + // crate and have hidden visibility + #[cfg(feature = "master")] + 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 - }; + func + }; cx.function_instances.borrow_mut().insert(instance, func); diff --git a/src/common.rs b/src/common.rs index c6edd52d1e416..d243d7088ada9 100644 --- a/src/common.rs +++ b/src/common.rs @@ -1,14 +1,9 @@ use gccjit::LValue; -use gccjit::{RValue, Type, ToRValue}; -use rustc_codegen_ssa::traits::{ - BaseTypeMethods, - ConstMethods, - MiscMethods, - StaticMethods, -}; -use rustc_middle::mir::Mutability; -use rustc_middle::ty::layout::{LayoutOf}; +use gccjit::{RValue, ToRValue, Type}; +use rustc_codegen_ssa::traits::{BaseTypeMethods, ConstMethods, MiscMethods, StaticMethods}; use rustc_middle::mir::interpret::{ConstAllocation, GlobalAlloc, Scalar}; +use rustc_middle::mir::Mutability; +use rustc_middle::ty::layout::LayoutOf; use rustc_target::abi::{self, HasDataLayout, Pointer}; use crate::consts::const_alloc_to_gcc; @@ -40,9 +35,7 @@ pub fn bytes_in_context<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, bytes: &[u8]) -> let byte_type = context.new_type::(); let typ = context.new_array_type(None, byte_type, bytes.len() as u64); let elements: Vec<_> = - bytes.iter() - .map(|&byte| context.new_rvalue_from_int(byte_type, byte as i32)) - .collect(); + bytes.iter().map(|&byte| context.new_rvalue_from_int(byte_type, byte as i32)).collect(); context.new_array_constructor(None, typ, &elements) } @@ -54,23 +47,20 @@ impl<'gcc, 'tcx> ConstMethods<'tcx> for CodegenCx<'gcc, 'tcx> { fn const_null(&self, typ: Type<'gcc>) -> RValue<'gcc> { if type_is_pointer(typ) { self.context.new_null(typ) - } - else { + } else { self.const_int(typ, 0) } } fn const_undef(&self, typ: Type<'gcc>) -> RValue<'gcc> { - let local = self.current_func.borrow().expect("func") - .new_local(None, typ, "undefined"); + let local = self.current_func.borrow().expect("func").new_local(None, typ, "undefined"); if typ.is_struct().is_some() { // NOTE: hack to workaround a limitation of the rustc API: see comment on // CodegenCx.structs_as_pointer let pointer = local.get_address(None); self.structs_as_pointer.borrow_mut().insert(pointer); pointer - } - else { + } else { local.to_rvalue() } } @@ -143,16 +133,15 @@ impl<'gcc, 'tcx> ConstMethods<'tcx> for CodegenCx<'gcc, 'tcx> { .or_insert_with(|| (s.to_owned(), self.global_string(s))) .1; let len = s.len(); - let cs = self.const_ptrcast(str_global.get_address(None), + let cs = self.const_ptrcast( + str_global.get_address(None), self.type_ptr_to(self.layout_of(self.tcx.types.str_).gcc_type(self)), ); (cs, self.const_usize(len as u64)) } fn const_struct(&self, values: &[RValue<'gcc>], packed: bool) -> RValue<'gcc> { - let fields: Vec<_> = values.iter() - .map(|value| value.get_type()) - .collect(); + let fields: Vec<_> = values.iter().map(|value| value.get_type()).collect(); // TODO(antoyo): cache the type? It's anonymous, so probably not. let typ = self.type_struct(&fields, packed); let struct_type = typ.is_struct().expect("struct type"); @@ -178,9 +167,10 @@ impl<'gcc, 'tcx> ConstMethods<'tcx> for CodegenCx<'gcc, 'tcx> { // FIXME(antoyo): there's some issues with using the u128 code that follows, so hard-code // the paths for floating-point values. if ty == self.float_type { - return self.context.new_rvalue_from_double(ty, f32::from_bits(data as u32) as f64); - } - else if ty == self.double_type { + return self + .context + .new_rvalue_from_double(ty, f32::from_bits(data as u32) as f64); + } else if ty == self.double_type { return self.context.new_rvalue_from_double(ty, f64::from_bits(data as u64)); } @@ -192,8 +182,7 @@ impl<'gcc, 'tcx> ConstMethods<'tcx> for CodegenCx<'gcc, 'tcx> { // FIXME(antoyo): fix bitcast to work in constant contexts. // TODO(antoyo): perhaps only use bitcast for pointers? self.context.new_cast(None, value, ty) - } - else { + } else { // TODO(bjorn3): assert size is correct self.const_bitcast(value, ty) } @@ -201,42 +190,41 @@ impl<'gcc, 'tcx> ConstMethods<'tcx> for CodegenCx<'gcc, 'tcx> { Scalar::Ptr(ptr, _size) => { let (prov, offset) = ptr.into_parts(); // we know the `offset` is relative let alloc_id = prov.alloc_id(); - let base_addr = - match self.tcx.global_alloc(alloc_id) { - GlobalAlloc::Memory(alloc) => { - let init = const_alloc_to_gcc(self, alloc); - let alloc = alloc.inner(); - let value = - match alloc.mutability { - Mutability::Mut => self.static_addr_of_mut(init, alloc.align, None), - _ => self.static_addr_of(init, alloc.align, None), - }; - if !self.sess().fewer_names() { - // TODO(antoyo): set value name. - } - value - }, - GlobalAlloc::Function(fn_instance) => { - self.get_fn_addr(fn_instance) - }, - GlobalAlloc::VTable(ty, trait_ref) => { - let alloc = self.tcx.global_alloc(self.tcx.vtable_allocation((ty, trait_ref))).unwrap_memory(); - let init = const_alloc_to_gcc(self, alloc); - self.static_addr_of(init, alloc.inner().align, None) + let base_addr = match self.tcx.global_alloc(alloc_id) { + GlobalAlloc::Memory(alloc) => { + let init = const_alloc_to_gcc(self, alloc); + let alloc = alloc.inner(); + let value = match alloc.mutability { + Mutability::Mut => self.static_addr_of_mut(init, alloc.align, None), + _ => self.static_addr_of(init, alloc.align, None), + }; + if !self.sess().fewer_names() { + // TODO(antoyo): set value name. } - GlobalAlloc::Static(def_id) => { - assert!(self.tcx.is_static(def_id)); - self.get_static(def_id).get_address(None) - }, - }; + value + } + GlobalAlloc::Function(fn_instance) => self.get_fn_addr(fn_instance), + GlobalAlloc::VTable(ty, trait_ref) => { + let alloc = self + .tcx + .global_alloc(self.tcx.vtable_allocation((ty, trait_ref))) + .unwrap_memory(); + let init = const_alloc_to_gcc(self, alloc); + self.static_addr_of(init, alloc.inner().align, None) + } + GlobalAlloc::Static(def_id) => { + assert!(self.tcx.is_static(def_id)); + self.get_static(def_id).get_address(None) + } + }; let ptr_type = base_addr.get_type(); let base_addr = self.const_bitcast(base_addr, self.usize_type); - let offset = self.context.new_rvalue_from_long(self.usize_type, offset.bytes() as i64); + 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); if !matches!(layout.primitive(), Pointer(_)) { self.const_bitcast(ptr.dereference(None).to_rvalue(), ty) - } - else { + } else { self.const_bitcast(ptr, ty) } } @@ -261,7 +249,9 @@ impl<'gcc, 'tcx> ConstMethods<'tcx> for CodegenCx<'gcc, 'tcx> { } fn const_ptr_byte_offset(&self, base_addr: Self::Value, offset: abi::Size) -> Self::Value { - self.context.new_array_access(None, base_addr, self.const_usize(offset.bytes())).get_address(None) + self.context + .new_array_access(None, base_addr, self.const_usize(offset.bytes())) + .get_address(None) } } @@ -284,35 +274,25 @@ impl<'gcc, 'tcx> SignType<'gcc, 'tcx> for Type<'gcc> { fn to_signed(&self, cx: &CodegenCx<'gcc, 'tcx>) -> Type<'gcc> { if self.is_u8(cx) { cx.i8_type - } - else if self.is_u16(cx) { + } else if self.is_u16(cx) { cx.i16_type - } - else if self.is_u32(cx) { + } else if self.is_u32(cx) { cx.i32_type - } - else if self.is_u64(cx) { + } else if self.is_u64(cx) { cx.i64_type - } - else if self.is_u128(cx) { + } else if self.is_u128(cx) { cx.i128_type - } - else if self.is_uchar(cx) { + } else if self.is_uchar(cx) { cx.char_type - } - else if self.is_ushort(cx) { + } else if self.is_ushort(cx) { cx.short_type - } - else if self.is_uint(cx) { + } else if self.is_uint(cx) { cx.int_type - } - else if self.is_ulong(cx) { + } else if self.is_ulong(cx) { cx.long_type - } - else if self.is_ulonglong(cx) { + } else if self.is_ulonglong(cx) { cx.longlong_type - } - else { + } else { self.clone() } } @@ -320,41 +300,31 @@ impl<'gcc, 'tcx> SignType<'gcc, 'tcx> for Type<'gcc> { fn to_unsigned(&self, cx: &CodegenCx<'gcc, 'tcx>) -> Type<'gcc> { if self.is_i8(cx) { cx.u8_type - } - else if self.is_i16(cx) { + } else if self.is_i16(cx) { cx.u16_type - } - else if self.is_i32(cx) { + } else if self.is_i32(cx) { cx.u32_type - } - else if self.is_i64(cx) { + } else if self.is_i64(cx) { cx.u64_type - } - else if self.is_i128(cx) { + } else if self.is_i128(cx) { cx.u128_type - } - else if self.is_char(cx) { + } else if self.is_char(cx) { cx.uchar_type - } - else if self.is_short(cx) { + } else if self.is_short(cx) { cx.ushort_type - } - else if self.is_int(cx) { + } else if self.is_int(cx) { cx.uint_type - } - else if self.is_long(cx) { + } else if self.is_long(cx) { cx.ulong_type - } - else if self.is_longlong(cx) { + } else if self.is_longlong(cx) { cx.ulonglong_type - } - else { + } else { self.clone() } } } -pub trait TypeReflection<'gcc, 'tcx> { +pub trait TypeReflection<'gcc, 'tcx> { fn is_uchar(&self, cx: &CodegenCx<'gcc, 'tcx>) -> bool; fn is_ushort(&self, cx: &CodegenCx<'gcc, 'tcx>) -> bool; fn is_uint(&self, cx: &CodegenCx<'gcc, 'tcx>) -> bool; diff --git a/src/consts.rs b/src/consts.rs index 70d8db02247ce..327c9bdada924 100644 --- a/src/consts.rs +++ b/src/consts.rs @@ -2,12 +2,14 @@ use gccjit::{FnAttribute, VarAttribute, Visibility}; use gccjit::{Function, GlobalKind, LValue, RValue, ToRValue}; use rustc_codegen_ssa::traits::{BaseTypeMethods, ConstMethods, DerivedTypeMethods, StaticMethods}; -use rustc_middle::span_bug; use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs}; +use rustc_middle::mir::interpret::{ + self, read_target_uint, ConstAllocation, ErrorHandled, Scalar as InterpScalar, +}; use rustc_middle::mir::mono::MonoItem; -use rustc_middle::ty::{self, Instance, Ty}; +use rustc_middle::span_bug; use rustc_middle::ty::layout::LayoutOf; -use rustc_middle::mir::interpret::{self, ConstAllocation, ErrorHandled, Scalar as InterpScalar, read_target_uint}; +use rustc_middle::ty::{self, Instance, Ty}; use rustc_span::def_id::DefId; use rustc_target::abi::{self, Align, HasDataLayout, Primitive, Size, WrappingRange}; @@ -16,7 +18,11 @@ use crate::context::CodegenCx; use crate::errors::InvalidMinimumAlignment; use crate::type_of::LayoutGccExt; -fn set_global_alignment<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, gv: LValue<'gcc>, mut align: Align) { +fn set_global_alignment<'gcc, 'tcx>( + cx: &CodegenCx<'gcc, 'tcx>, + gv: LValue<'gcc>, + mut align: Align, +) { // The target may require greater alignment for globals than the type does. // Note: GCC and Clang also allow `__attribute__((aligned))` on variables, // which can force it to be smaller. Rust doesn't support this yet. @@ -48,7 +54,9 @@ impl<'gcc, 'tcx> StaticMethods for CodegenCx<'gcc, 'tcx> { } let global_value = self.static_addr_of_mut(cv, align, kind); #[cfg(feature = "master")] - self.global_lvalues.borrow().get(&global_value) + self.global_lvalues + .borrow() + .get(&global_value) .expect("`static_addr_of_mut` did not add the global to `self.global_lvalues`") .global_set_readonly(); self.const_globals.borrow_mut().insert(cv, global_value); @@ -58,25 +66,20 @@ impl<'gcc, 'tcx> StaticMethods for CodegenCx<'gcc, 'tcx> { fn codegen_static(&self, def_id: DefId, is_mutable: bool) { let attrs = self.tcx.codegen_fn_attrs(def_id); - let value = - match codegen_static_initializer(&self, def_id) { - Ok((value, _)) => value, - // Error has already been reported - Err(_) => return, - }; + let value = match codegen_static_initializer(&self, def_id) { + Ok((value, _)) => value, + // Error has already been reported + Err(_) => return, + }; let global = self.get_static(def_id); // boolean SSA values are i1, but they have to be stored in i8 slots, // otherwise some LLVM optimization passes don't work as expected let val_llty = self.val_ty(value); - let value = - if val_llty == self.type_i1() { - unimplemented!(); - } - else { - value - }; + if val_llty == self.type_i1() { + unimplemented!(); + }; let instance = Instance::mono(self.tcx, def_id); let ty = instance.ty(self.tcx, ty::ParamEnv::reveal_all()); @@ -89,11 +92,9 @@ impl<'gcc, 'tcx> StaticMethods for CodegenCx<'gcc, 'tcx> { // As an optimization, all shared statics which do not have interior // mutability are placed into read-only memory. - if !is_mutable { - if self.type_is_freeze(ty) { - #[cfg(feature = "master")] - global.global_set_readonly(); - } + if !is_mutable && self.type_is_freeze(ty) { + #[cfg(feature = "master")] + global.global_set_readonly(); } if attrs.flags.contains(CodegenFnAttrFlags::THREAD_LOCAL) { @@ -149,7 +150,9 @@ impl<'gcc, 'tcx> StaticMethods for CodegenCx<'gcc, 'tcx> { // TODO(antoyo): set link section. } - if attrs.flags.contains(CodegenFnAttrFlags::USED) || attrs.flags.contains(CodegenFnAttrFlags::USED_LINKER) { + if attrs.flags.contains(CodegenFnAttrFlags::USED) + || attrs.flags.contains(CodegenFnAttrFlags::USED_LINKER) + { self.add_used_global(global.to_rvalue()); } } @@ -166,29 +169,33 @@ impl<'gcc, 'tcx> StaticMethods for CodegenCx<'gcc, 'tcx> { } impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { - #[cfg_attr(not(feature="master"), allow(unused_variables))] + #[cfg_attr(not(feature = "master"), allow(unused_variables))] pub fn add_used_function(&self, function: Function<'gcc>) { #[cfg(feature = "master")] function.add_attribute(FnAttribute::Used); } - pub fn static_addr_of_mut(&self, cv: RValue<'gcc>, align: Align, kind: Option<&str>) -> RValue<'gcc> { - let global = - match kind { - Some(kind) if !self.tcx.sess.fewer_names() => { - let name = self.generate_local_symbol_name(kind); - // TODO(antoyo): check if it's okay that no link_section is set. - - let typ = self.val_ty(cv).get_aligned(align.bytes()); - let global = self.declare_private_global(&name[..], typ); - global - } - _ => { - let typ = self.val_ty(cv).get_aligned(align.bytes()); - let global = self.declare_unnamed_global(typ); - global - }, - }; + pub fn static_addr_of_mut( + &self, + cv: RValue<'gcc>, + align: Align, + kind: Option<&str>, + ) -> RValue<'gcc> { + let global = match kind { + Some(kind) if !self.tcx.sess.fewer_names() => { + let name = self.generate_local_symbol_name(kind); + // TODO(antoyo): check if it's okay that no link_section is set. + + let typ = self.val_ty(cv).get_aligned(align.bytes()); + let global = self.declare_private_global(&name[..], typ); + global + } + _ => { + let typ = self.val_ty(cv).get_aligned(align.bytes()); + let global = self.declare_unnamed_global(typ); + global + } + }; global.global_set_initializer_rvalue(cv); // TODO(antoyo): set unnamed address. let rvalue = global.get_address(None); @@ -215,8 +222,7 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { let ty = instance.ty(self.tcx, ty::ParamEnv::reveal_all()); let sym = self.tcx.symbol_name(instance).name; - let global = - if def_id.is_local() && !self.tcx.is_foreign_item(def_id) { + let global = if def_id.is_local() && !self.tcx.is_foreign_item(def_id) { let llty = self.layout_of(ty).gcc_type(self); if let Some(global) = self.get_declared_value(sym) { if self.val_ty(global) != self.type_ptr_to(llty) { @@ -235,7 +241,7 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { if !self.tcx.is_reachable_non_generic(def_id) { #[cfg(feature = "master")] - global.add_attribute(VarAttribute::Visibility(Visibility::Hidden)); + global.add_string_attribute(VarAttribute::Visibility(Visibility::Hidden)); } global @@ -278,7 +284,10 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { } } -pub fn const_alloc_to_gcc<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, alloc: ConstAllocation<'tcx>) -> RValue<'gcc> { +pub fn const_alloc_to_gcc<'gcc, 'tcx>( + cx: &CodegenCx<'gcc, 'tcx>, + alloc: ConstAllocation<'tcx>, +) -> RValue<'gcc> { let alloc = alloc.inner(); let mut llvals = Vec::with_capacity(alloc.provenance().ptrs().len() + 1); let dl = cx.data_layout(); @@ -300,14 +309,14 @@ pub fn const_alloc_to_gcc<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, alloc: ConstAl let bytes = alloc.inspect_with_uninit_and_ptr_outside_interpreter(next_offset..offset); llvals.push(cx.const_bytes(bytes)); } - let ptr_offset = - read_target_uint( dl.endian, - // This `inspect` is okay since it is within the bounds of the allocation, it doesn't - // affect interpreter execution (we inspect the result after interpreter execution), - // and we properly interpret the provenance as a relocation pointer offset. - alloc.inspect_with_uninit_and_ptr_outside_interpreter(offset..(offset + pointer_size)), - ) - .expect("const_alloc_to_llvm: could not read relocation pointer") + let ptr_offset = read_target_uint( + dl.endian, + // This `inspect` is okay since it is within the bounds of the allocation, it doesn't + // affect interpreter execution (we inspect the result after interpreter execution), + // and we properly interpret the provenance as a relocation pointer offset. + alloc.inspect_with_uninit_and_ptr_outside_interpreter(offset..(offset + pointer_size)), + ) + .expect("const_alloc_to_llvm: could not read relocation pointer") as u64; let address_space = cx.tcx.global_alloc(alloc_id).address_space(cx); @@ -317,7 +326,10 @@ pub fn const_alloc_to_gcc<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, alloc: ConstAl interpret::Pointer::new(prov, Size::from_bytes(ptr_offset)), &cx.tcx, ), - abi::Scalar::Initialized { value: Primitive::Pointer(address_space), valid_range: WrappingRange::full(dl.pointer_size) }, + abi::Scalar::Initialized { + value: Primitive::Pointer(address_space), + valid_range: WrappingRange::full(dl.pointer_size), + }, cx.type_i8p_ext(address_space), )); next_offset = offset + pointer_size; @@ -337,17 +349,29 @@ pub fn const_alloc_to_gcc<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, alloc: ConstAl cx.const_struct(&llvals, true) } -pub fn codegen_static_initializer<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, def_id: DefId) -> Result<(RValue<'gcc>, ConstAllocation<'tcx>), ErrorHandled> { +pub fn codegen_static_initializer<'gcc, 'tcx>( + cx: &CodegenCx<'gcc, 'tcx>, + def_id: DefId, +) -> Result<(RValue<'gcc>, ConstAllocation<'tcx>), ErrorHandled> { let alloc = cx.tcx.eval_static_initializer(def_id)?; Ok((const_alloc_to_gcc(cx, alloc), alloc)) } -fn check_and_apply_linkage<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, attrs: &CodegenFnAttrs, ty: Ty<'tcx>, sym: &str) -> LValue<'gcc> { +fn check_and_apply_linkage<'gcc, 'tcx>( + cx: &CodegenCx<'gcc, 'tcx>, + attrs: &CodegenFnAttrs, + ty: Ty<'tcx>, + sym: &str, +) -> LValue<'gcc> { let is_tls = attrs.flags.contains(CodegenFnAttrFlags::THREAD_LOCAL); let gcc_type = cx.layout_of(ty).gcc_type(cx); if let Some(linkage) = attrs.import_linkage { // Declare a symbol `foo` with the desired linkage. - let global1 = cx.declare_global_with_linkage(&sym, cx.type_i8(), base::global_linkage_to_gcc(linkage)); + let global1 = cx.declare_global_with_linkage( + &sym, + cx.type_i8(), + base::global_linkage_to_gcc(linkage), + ); // Declare an internal global `extern_with_linkage_foo` which // is initialized with the address of `foo`. If `foo` is @@ -363,8 +387,7 @@ fn check_and_apply_linkage<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, attrs: &Codeg global2.global_set_initializer_rvalue(value); // TODO(antoyo): use global_set_initializer() when it will work. global2 - } - else { + } else { // Generate an external declaration. // FIXME(nagisa): investigate whether it can be changed into define_global diff --git a/src/context.rs b/src/context.rs index 5760d96165ddf..bc3d62f2679d9 100644 --- a/src/context.rs +++ b/src/context.rs @@ -1,22 +1,25 @@ use std::cell::{Cell, RefCell}; -use gccjit::{Block, CType, Context, Function, FunctionPtrType, FunctionType, LValue, RValue, Type}; -use rustc_codegen_ssa::base::wants_msvc_seh; -use rustc_codegen_ssa::traits::{ - BackendTypes, - BaseTypeMethods, - MiscMethods, +use gccjit::{ + Block, CType, Context, Function, FunctionPtrType, FunctionType, LValue, Location, RValue, Type, }; +use rustc_codegen_ssa::base::wants_msvc_seh; use rustc_codegen_ssa::errors as ssa_errors; +use rustc_codegen_ssa::traits::{BackendTypes, BaseTypeMethods, MiscMethods}; use rustc_data_structures::base_n; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; -use rustc_middle::span_bug; use rustc_middle::mir::mono::CodegenUnit; +use rustc_middle::span_bug; +use rustc_middle::ty::layout::{ + FnAbiError, FnAbiOf, FnAbiOfHelpers, FnAbiRequest, HasParamEnv, HasTyCtxt, LayoutError, + LayoutOfHelpers, TyAndLayout, +}; use rustc_middle::ty::{self, Instance, ParamEnv, PolyExistentialTraitRef, Ty, TyCtxt}; -use rustc_middle::ty::layout::{FnAbiError, FnAbiOf, FnAbiOfHelpers, FnAbiRequest, HasParamEnv, HasTyCtxt, LayoutError, TyAndLayout, LayoutOfHelpers}; use rustc_session::Session; -use rustc_span::{Span, source_map::respan}; -use rustc_target::abi::{call::FnAbi, HasDataLayout, PointeeInfo, Size, TargetDataLayout, VariantIdx}; +use rustc_span::{source_map::respan, Span}; +use rustc_target::abi::{ + call::FnAbi, HasDataLayout, PointeeInfo, Size, TargetDataLayout, VariantIdx, +}; use rustc_target::spec::{HasTargetSpec, Target, TlsModel}; use crate::callee::get_fn; @@ -81,7 +84,8 @@ pub struct CodegenCx<'gcc, 'tcx> { /// Cache function instances of monomorphic and polymorphic items pub function_instances: RefCell, Function<'gcc>>>, /// Cache generated vtables - pub vtables: RefCell, Option>), RValue<'gcc>>>, + pub vtables: + RefCell, Option>), RValue<'gcc>>>, // TODO(antoyo): improve the SSA API to not require those. /// Mapping from function pointer type to indexes of on stack parameters. @@ -121,24 +125,28 @@ pub struct CodegenCx<'gcc, 'tcx> { } impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { - pub fn new(context: &'gcc Context<'gcc>, codegen_unit: &'tcx CodegenUnit<'tcx>, tcx: TyCtxt<'tcx>, supports_128bit_integers: bool) -> Self { + pub fn new( + context: &'gcc Context<'gcc>, + codegen_unit: &'tcx CodegenUnit<'tcx>, + tcx: TyCtxt<'tcx>, + supports_128bit_integers: bool, + ) -> Self { let check_overflow = tcx.sess.overflow_checks(); let create_type = |ctype, rust_type| { let layout = tcx.layout_of(ParamEnv::reveal_all().and(rust_type)).unwrap(); let align = layout.align.abi.bytes(); - #[cfg(feature="master")] + #[cfg(feature = "master")] { context.new_c_type(ctype).get_aligned(align) } - #[cfg(not(feature="master"))] + #[cfg(not(feature = "master"))] { // Since libgccjit 12 doesn't contain the fix to compare aligned integer types, // only align u128 and i128. if layout.ty.int_size_and_signed(tcx).0.bytes() == 16 { context.new_c_type(ctype).get_aligned(align) - } - else { + } else { context.new_c_type(ctype) } } @@ -153,24 +161,22 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { let u32_type = create_type(CType::UInt32t, tcx.types.u32); let u64_type = create_type(CType::UInt64t, tcx.types.u64); - let (i128_type, u128_type) = - if supports_128bit_integers { - let i128_type = create_type(CType::Int128t, tcx.types.i128); - let u128_type = create_type(CType::UInt128t, tcx.types.u128); - (i128_type, u128_type) - } - else { - /*let layout = tcx.layout_of(ParamEnv::reveal_all().and(tcx.types.i128)).unwrap(); - let i128_align = layout.align.abi.bytes(); - let layout = tcx.layout_of(ParamEnv::reveal_all().and(tcx.types.u128)).unwrap(); - let u128_align = layout.align.abi.bytes();*/ - - // TODO(antoyo): re-enable the alignment when libgccjit fixed the issue in - // gcc_jit_context_new_array_constructor (it should not use reinterpret_cast). - let i128_type = context.new_array_type(None, i64_type, 2)/*.get_aligned(i128_align)*/; - let u128_type = context.new_array_type(None, u64_type, 2)/*.get_aligned(u128_align)*/; - (i128_type, u128_type) - }; + let (i128_type, u128_type) = if supports_128bit_integers { + let i128_type = create_type(CType::Int128t, tcx.types.i128); + let u128_type = create_type(CType::UInt128t, tcx.types.u128); + (i128_type, u128_type) + } else { + /*let layout = tcx.layout_of(ParamEnv::reveal_all().and(tcx.types.i128)).unwrap(); + let i128_align = layout.align.abi.bytes(); + let layout = tcx.layout_of(ParamEnv::reveal_all().and(tcx.types.u128)).unwrap(); + let u128_align = layout.align.abi.bytes();*/ + + // TODO(antoyo): re-enable the alignment when libgccjit fixed the issue in + // gcc_jit_context_new_array_constructor (it should not use reinterpret_cast). + let i128_type = context.new_array_type(None, i64_type, 2)/*.get_aligned(i128_align)*/; + let u128_type = context.new_array_type(None, u64_type, 2)/*.get_aligned(u128_align)*/; + (i128_type, u128_type) + }; let tls_model = to_gcc_tls_mode(tcx.sess.tls_model()); @@ -196,16 +202,65 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { let mut functions = FxHashMap::default(); let builtins = [ - "__builtin_unreachable", "abort", "__builtin_expect", /*"__builtin_expect_with_probability",*/ - "__builtin_constant_p", "__builtin_add_overflow", "__builtin_mul_overflow", "__builtin_saddll_overflow", - /*"__builtin_sadd_overflow",*/ "__builtin_smulll_overflow", /*"__builtin_smul_overflow",*/ - "__builtin_ssubll_overflow", /*"__builtin_ssub_overflow",*/ "__builtin_sub_overflow", "__builtin_uaddll_overflow", - "__builtin_uadd_overflow", "__builtin_umulll_overflow", "__builtin_umul_overflow", "__builtin_usubll_overflow", - "__builtin_usub_overflow", "sqrtf", "sqrt", "__builtin_powif", "__builtin_powi", "sinf", "sin", "cosf", "cos", - "powf", "pow", "expf", "exp", "exp2f", "exp2", "logf", "log", "log10f", "log10", "log2f", "log2", "fmaf", - "fma", "fabsf", "fabs", "fminf", "fmin", "fmaxf", "fmax", "copysignf", "copysign", "floorf", "floor", "ceilf", - "ceil", "truncf", "trunc", "rintf", "rint", "nearbyintf", "nearbyint", "roundf", "round", - + "__builtin_unreachable", + "abort", + "__builtin_expect", /*"__builtin_expect_with_probability",*/ + "__builtin_constant_p", + "__builtin_add_overflow", + "__builtin_mul_overflow", + "__builtin_saddll_overflow", + /*"__builtin_sadd_overflow",*/ + "__builtin_smulll_overflow", /*"__builtin_smul_overflow",*/ + "__builtin_ssubll_overflow", + /*"__builtin_ssub_overflow",*/ "__builtin_sub_overflow", + "__builtin_uaddll_overflow", + "__builtin_uadd_overflow", + "__builtin_umulll_overflow", + "__builtin_umul_overflow", + "__builtin_usubll_overflow", + "__builtin_usub_overflow", + "sqrtf", + "sqrt", + "__builtin_powif", + "__builtin_powi", + "sinf", + "sin", + "cosf", + "cos", + "powf", + "pow", + "expf", + "exp", + "exp2f", + "exp2", + "logf", + "log", + "log10f", + "log10", + "log2f", + "log2", + "fmaf", + "fma", + "fabsf", + "fabs", + "fminf", + "fmin", + "fmaxf", + "fmax", + "copysignf", + "copysign", + "floorf", + "floor", + "ceilf", + "ceil", + "truncf", + "trunc", + "rintf", + "rint", + "nearbyintf", + "nearbyint", + "roundf", + "round", ]; for builtin in builtins.iter() { @@ -282,8 +337,12 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { pub fn rvalue_as_function(&self, value: RValue<'gcc>) -> Function<'gcc> { let function: Function<'gcc> = unsafe { std::mem::transmute(value) }; - debug_assert!(self.functions.borrow().values().any(|value| *value == function), - "{:?} ({:?}) is not a function", value, value.get_type()); + debug_assert!( + self.functions.borrow().values().any(|value| *value == function), + "{:?} ({:?}) is not a function", + value, + value.get_type() + ); function } @@ -305,13 +364,13 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { } } - self.supports_128bit_integers && - (self.u128_type.is_compatible_with(typ) || self.i128_type.is_compatible_with(typ)) + self.supports_128bit_integers + && (self.u128_type.is_compatible_with(typ) || self.i128_type.is_compatible_with(typ)) } pub fn is_non_native_int_type(&self, typ: Type<'gcc>) -> bool { - !self.supports_128bit_integers && - (self.u128_type.is_compatible_with(typ) || self.i128_type.is_compatible_with(typ)) + !self.supports_128bit_integers + && (self.u128_type.is_compatible_with(typ) || self.i128_type.is_compatible_with(typ)) } pub fn is_native_int_type_or_bool(&self, typ: Type<'gcc>) -> bool { @@ -319,18 +378,23 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { } pub fn is_int_type_or_bool(&self, typ: Type<'gcc>) -> bool { - self.is_native_int_type(typ) || self.is_non_native_int_type(typ) || typ.is_compatible_with(self.bool_type) + self.is_native_int_type(typ) + || self.is_non_native_int_type(typ) + || typ.is_compatible_with(self.bool_type) } pub fn sess(&self) -> &'tcx Session { &self.tcx.sess } - pub fn bitcast_if_needed(&self, value: RValue<'gcc>, expected_type: Type<'gcc>) -> RValue<'gcc> { + pub fn bitcast_if_needed( + &self, + value: RValue<'gcc>, + expected_type: Type<'gcc>, + ) -> RValue<'gcc> { if value.get_type() != expected_type { self.context.new_bitcast(None, value, expected_type) - } - else { + } else { value } } @@ -345,12 +409,14 @@ impl<'gcc, 'tcx> BackendTypes for CodegenCx<'gcc, 'tcx> { type Funclet = (); // TODO(antoyo) type DIScope = (); // TODO(antoyo) - type DILocation = (); // TODO(antoyo) + type DILocation = Location<'gcc>; type DIVariable = (); // TODO(antoyo) } impl<'gcc, 'tcx> MiscMethods<'tcx> for CodegenCx<'gcc, 'tcx> { - fn vtables(&self) -> &RefCell, Option>), RValue<'gcc>>> { + fn vtables( + &self, + ) -> &RefCell, Option>), RValue<'gcc>>> { &self.vtables } @@ -364,13 +430,11 @@ impl<'gcc, 'tcx> MiscMethods<'tcx> for CodegenCx<'gcc, 'tcx> { fn get_fn_addr(&self, instance: Instance<'tcx>) -> RValue<'gcc> { let func_name = self.tcx.symbol_name(instance).name; - let func = - if self.intrinsics.borrow().contains_key(func_name) { - self.intrinsics.borrow()[func_name].clone() - } - else { - get_fn(self, instance) - }; + let func = if self.intrinsics.borrow().contains_key(func_name) { + self.intrinsics.borrow()[func_name].clone() + } else { + get_fn(self, instance) + }; let ptr = func.get_address(None); // TODO(antoyo): don't do this twice: i.e. in declare_fn and here. @@ -407,37 +471,34 @@ impl<'gcc, 'tcx> MiscMethods<'tcx> for CodegenCx<'gcc, 'tcx> { return llpersonality; } let tcx = self.tcx; - let func = - match tcx.lang_items().eh_personality() { - Some(def_id) if !wants_msvc_seh(self.sess()) => { - let instance = - ty::Instance::resolve( - tcx, - ty::ParamEnv::reveal_all(), - def_id, - ty::List::empty(), - ) - .unwrap().unwrap(); - - let symbol_name = tcx.symbol_name(instance).name; - let fn_abi = self.fn_abi_of_instance(instance, ty::List::empty()); - self.linkage.set(FunctionType::Extern); - let func = self.declare_fn(symbol_name, &fn_abi); - let func: RValue<'gcc> = unsafe { std::mem::transmute(func) }; - func - }, - _ => { - let name = - if wants_msvc_seh(self.sess()) { - "__CxxFrameHandler3" - } - else { - "rust_eh_personality" - }; - let func = self.declare_func(name, self.type_i32(), &[], true); - unsafe { std::mem::transmute(func) } - } - }; + let func = match tcx.lang_items().eh_personality() { + Some(def_id) if !wants_msvc_seh(self.sess()) => { + let instance = ty::Instance::resolve( + tcx, + ty::ParamEnv::reveal_all(), + def_id, + ty::List::empty(), + ) + .unwrap() + .unwrap(); + + let symbol_name = tcx.symbol_name(instance).name; + let fn_abi = self.fn_abi_of_instance(instance, ty::List::empty()); + self.linkage.set(FunctionType::Extern); + let func = self.declare_fn(symbol_name, &fn_abi); + let func: RValue<'gcc> = unsafe { std::mem::transmute(func) }; + func + } + _ => { + let name = if wants_msvc_seh(self.sess()) { + "__CxxFrameHandler3" + } else { + "rust_eh_personality" + }; + let func = self.declare_func(name, self.type_i32(), &[], true); + unsafe { std::mem::transmute(func) } + } + }; // TODO(antoyo): apply target cpu attributes. self.eh_personality.set(Some(func)); func @@ -467,8 +528,7 @@ impl<'gcc, 'tcx> MiscMethods<'tcx> for CodegenCx<'gcc, 'tcx> { let entry_name = self.sess().target.entry_name.as_ref(); if self.get_declared_value(entry_name).is_none() { Some(self.declare_entry_fn(entry_name, fn_type, ())) - } - else { + } else { // If the symbol already exists, it is an error: for example, the user wrote // #[no_mangle] extern "C" fn main(..) {..} // instead of #[start] diff --git a/src/debuginfo.rs b/src/debuginfo.rs index d1bfd833cd87f..aed15769025f1 100644 --- a/src/debuginfo.rs +++ b/src/debuginfo.rs @@ -1,9 +1,14 @@ -use gccjit::RValue; -use rustc_codegen_ssa::mir::debuginfo::{FunctionDebugContext, VariableKind}; +use crate::rustc_index::Idx; +use gccjit::{Location, RValue}; +use rustc_codegen_ssa::mir::debuginfo::{DebugScope, FunctionDebugContext, VariableKind}; use rustc_codegen_ssa::traits::{DebugInfoBuilderMethods, DebugInfoMethods}; -use rustc_middle::mir; +use rustc_data_structures::sync::Lrc; +use rustc_index::bit_set::BitSet; +use rustc_index::IndexVec; +use rustc_middle::mir::{self, Body, SourceScope}; use rustc_middle::ty::{Instance, PolyExistentialTraitRef, Ty}; -use rustc_span::{SourceFile, Span, Symbol}; +use rustc_session::config::DebugInfo; +use rustc_span::{BytePos, Pos, SourceFile, SourceFileAndLine, Span, Symbol}; use rustc_target::abi::call::FnAbi; use rustc_target::abi::Size; use std::ops::Range; @@ -11,31 +16,183 @@ use std::ops::Range; use crate::builder::Builder; use crate::context::CodegenCx; +pub(super) const UNKNOWN_LINE_NUMBER: u32 = 0; +pub(super) const UNKNOWN_COLUMN_NUMBER: u32 = 0; + impl<'a, 'gcc, 'tcx> DebugInfoBuilderMethods for Builder<'a, 'gcc, 'tcx> { // FIXME(eddyb) find a common convention for all of the debuginfo-related // names (choose between `dbg`, `debug`, `debuginfo`, `debug_info` etc.). fn dbg_var_addr( &mut self, _dbg_var: Self::DIVariable, - _scope_metadata: Self::DIScope, + _dbg_loc: Self::DILocation, _variable_alloca: Self::Value, _direct_offset: Size, _indirect_offsets: &[Size], _fragment: Option>, ) { - unimplemented!(); + // FIXME(tempdragon): Not sure if this is correct, probably wrong but still keep it here. + #[cfg(feature = "master")] + _variable_alloca.set_location(_dbg_loc); } fn insert_reference_to_gdb_debug_scripts_section_global(&mut self) { // TODO(antoyo): insert reference to gdb debug scripts section global. } - fn set_var_name(&mut self, _value: RValue<'gcc>, _name: &str) { - unimplemented!(); + /// FIXME(tempdragon): Currently, this function is not yet implemented. It seems that the + /// debug name and the mangled name should both be included in the LValues. + /// Besides, a function to get the rvalue type(m_is_lvalue) should also be included. + fn set_var_name(&mut self, _value: RValue<'gcc>, _name: &str) {} + + fn set_dbg_loc(&mut self, dbg_loc: Self::DILocation) { + self.location = Some(dbg_loc); + } +} + +/// Generate the `debug_context` in an MIR Body. +/// # Souce of Origin +/// Copied from `create_scope_map.rs` of rustc_codegen_llvm +fn compute_mir_scopes<'gcc, 'tcx>( + cx: &CodegenCx<'gcc, 'tcx>, + instance: Instance<'tcx>, + mir: &Body<'tcx>, + debug_context: &mut FunctionDebugContext<'tcx, (), Location<'gcc>>, +) { + // Find all scopes with variables defined in them. + let variables = if cx.sess().opts.debuginfo == DebugInfo::Full { + let mut vars = BitSet::new_empty(mir.source_scopes.len()); + // FIXME(eddyb) take into account that arguments always have debuginfo, + // irrespective of their name (assuming full debuginfo is enabled). + // NOTE(eddyb) actually, on second thought, those are always in the + // function scope, which always exists. + for var_debug_info in &mir.var_debug_info { + vars.insert(var_debug_info.source_info.scope); + } + Some(vars) + } else { + // Nothing to emit, of course. + None + }; + let mut instantiated = BitSet::new_empty(mir.source_scopes.len()); + // Instantiate all scopes. + for idx in 0..mir.source_scopes.len() { + let scope = SourceScope::new(idx); + make_mir_scope(cx, instance, mir, &variables, debug_context, &mut instantiated, scope); + } + assert!(instantiated.count() == mir.source_scopes.len()); +} + +/// Update the `debug_context`, adding new scope to it, +/// if it's not added as is denoted in `instantiated`. +/// +/// # Souce of Origin +/// Copied from `create_scope_map.rs` of rustc_codegen_llvm +/// FIXME(tempdragon/?): Add Scope Support Here. +fn make_mir_scope<'gcc, 'tcx>( + cx: &CodegenCx<'gcc, 'tcx>, + instance: Instance<'tcx>, + mir: &Body<'tcx>, + variables: &Option>, + debug_context: &mut FunctionDebugContext<'tcx, (), Location<'gcc>>, + instantiated: &mut BitSet, + scope: SourceScope, +) { + if instantiated.contains(scope) { + return; + } + + let scope_data = &mir.source_scopes[scope]; + let parent_scope = if let Some(parent) = scope_data.parent_scope { + make_mir_scope(cx, instance, mir, variables, debug_context, instantiated, parent); + debug_context.scopes[parent] + } else { + // The root is the function itself. + let file = cx.sess().source_map().lookup_source_file(mir.span.lo()); + debug_context.scopes[scope] = DebugScope { + file_start_pos: file.start_pos, + file_end_pos: file.end_position(), + ..debug_context.scopes[scope] + }; + instantiated.insert(scope); + return; + }; + + if let Some(vars) = variables { + if !vars.contains(scope) && scope_data.inlined.is_none() { + // Do not create a DIScope if there are no variables defined in this + // MIR `SourceScope`, and it's not `inlined`, to avoid debuginfo bloat. + debug_context.scopes[scope] = parent_scope; + instantiated.insert(scope); + return; + } } - fn set_dbg_loc(&mut self, _dbg_loc: Self::DILocation) { - unimplemented!(); + let loc = cx.lookup_debug_loc(scope_data.span.lo()); + + // FIXME(tempdragon): Add the scope related code here if the scope is supported. + let dbg_scope = (); + + let inlined_at = scope_data.inlined.map(|(_, callsite_span)| { + // FIXME(eddyb) this doesn't account for the macro-related + // `Span` fixups that `rustc_codegen_ssa::mir::debuginfo` does. + let callsite_scope = parent_scope.adjust_dbg_scope_for_span(cx, callsite_span); + cx.dbg_loc(callsite_scope, parent_scope.inlined_at, callsite_span) + }); + let p_inlined_at = parent_scope.inlined_at; + // TODO(tempdragon): dbg_scope: Add support for scope extension here. + inlined_at.or(p_inlined_at); + + debug_context.scopes[scope] = DebugScope { + dbg_scope, + inlined_at, + file_start_pos: loc.file.start_pos, + file_end_pos: loc.file.end_position(), + }; + instantiated.insert(scope); +} + +/// A source code location used to generate debug information. +// FIXME(eddyb) rename this to better indicate it's a duplicate of +// `rustc_span::Loc` rather than `DILocation`, perhaps by making +// `lookup_char_pos` return the right information instead. +pub struct DebugLoc { + /// Information about the original source file. + pub file: Lrc, + /// The (1-based) line number. + pub line: u32, + /// The (1-based) column number. + pub col: u32, +} + +impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { + /// Looks up debug source information about a `BytePos`. + // FIXME(eddyb) rename this to better indicate it's a duplicate of + // `lookup_char_pos` rather than `dbg_loc`, perhaps by making + // `lookup_char_pos` return the right information instead. + // Source of Origin: cg_llvm + pub fn lookup_debug_loc(&self, pos: BytePos) -> DebugLoc { + let (file, line, col) = match self.sess().source_map().lookup_line(pos) { + Ok(SourceFileAndLine { sf: file, line }) => { + let line_pos = file.lines()[line]; + + // Use 1-based indexing. + let line = (line + 1) as u32; + let col = (file.relative_position(pos) - line_pos).to_u32() + 1; + + (file, line, col) + } + Err(file) => (file, UNKNOWN_LINE_NUMBER, UNKNOWN_COLUMN_NUMBER), + }; + + // For MSVC, omit the column number. + // Otherwise, emit it. This mimics clang behaviour. + // See discussion in https://github.com/rust-lang/rust/issues/42921 + if self.sess().target.is_like_msvc { + DebugLoc { file, line, col: UNKNOWN_COLUMN_NUMBER } + } else { + DebugLoc { file, line, col } + } } } @@ -51,13 +208,31 @@ impl<'gcc, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'gcc, 'tcx> { fn create_function_debug_context( &self, - _instance: Instance<'tcx>, - _fn_abi: &FnAbi<'tcx, Ty<'tcx>>, - _llfn: RValue<'gcc>, - _mir: &mir::Body<'tcx>, + instance: Instance<'tcx>, + fn_abi: &FnAbi<'tcx, Ty<'tcx>>, + llfn: RValue<'gcc>, + mir: &mir::Body<'tcx>, ) -> Option> { - // TODO(antoyo) - None + if self.sess().opts.debuginfo == DebugInfo::None { + return None; + } + + // Initialize fn debug context (including scopes). + let empty_scope = DebugScope { + dbg_scope: self.dbg_scope_fn(instance, fn_abi, Some(llfn)), + inlined_at: None, + file_start_pos: BytePos(0), + file_end_pos: BytePos(0), + }; + let mut fn_debug_context = FunctionDebugContext { + scopes: IndexVec::from_elem(empty_scope, &mir.source_scopes.as_slice()), + inlined_function_scopes: Default::default(), + }; + + // Fill in all the scopes, with the information from the MIR body. + compute_mir_scopes(self, instance, mir, &mut fn_debug_context); + + Some(fn_debug_context) } fn extend_scope_to_file( @@ -65,11 +240,11 @@ impl<'gcc, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'gcc, 'tcx> { _scope_metadata: Self::DIScope, _file: &SourceFile, ) -> Self::DIScope { - unimplemented!(); + // TODO(antoyo): implement. } fn debuginfo_finalize(&self) { - // TODO(antoyo) + self.context.set_debug_info(true) } fn create_dbg_var( @@ -80,7 +255,6 @@ impl<'gcc, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'gcc, 'tcx> { _variable_kind: VariableKind, _span: Span, ) -> Self::DIVariable { - unimplemented!(); } fn dbg_scope_fn( @@ -89,15 +263,40 @@ impl<'gcc, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'gcc, 'tcx> { _fn_abi: &FnAbi<'tcx, Ty<'tcx>>, _maybe_definition_llfn: Option>, ) -> Self::DIScope { - unimplemented!(); + // TODO(antoyo): implement. } fn dbg_loc( &self, _scope: Self::DIScope, _inlined_at: Option, - _span: Span, + span: Span, ) -> Self::DILocation { - unimplemented!(); + let pos = span.lo(); + let DebugLoc { file, line, col } = self.lookup_debug_loc(pos); + let loc = match &file.name { + rustc_span::FileName::Real(name) => match name { + rustc_span::RealFileName::LocalPath(name) => { + if let Some(name) = name.to_str() { + self.context.new_location(name, line as i32, col as i32) + } else { + Location::null() + } + } + rustc_span::RealFileName::Remapped { local_path, virtual_name: _ } => { + if let Some(name) = local_path.as_ref() { + if let Some(name) = name.to_str() { + self.context.new_location(name, line as i32, col as i32) + } else { + Location::null() + } + } else { + Location::null() + } + } + }, + _ => Location::null(), + }; + loc } } diff --git a/src/declare.rs b/src/declare.rs index 247454fa58e14..db6edbab12d4d 100644 --- a/src/declare.rs +++ b/src/declare.rs @@ -1,6 +1,6 @@ -use gccjit::{Function, FunctionType, GlobalKind, LValue, RValue, Type}; -#[cfg(feature="master")] +#[cfg(feature = "master")] use gccjit::{FnAttribute, ToRValue}; +use gccjit::{Function, FunctionType, GlobalKind, LValue, RValue, Type}; use rustc_codegen_ssa::traits::BaseTypeMethods; use rustc_middle::ty::Ty; use rustc_span::Symbol; @@ -11,7 +11,13 @@ use crate::context::CodegenCx; use crate::intrinsic::llvm; impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { - pub fn get_or_insert_global(&self, name: &str, ty: Type<'gcc>, is_tls: bool, link_section: Option) -> LValue<'gcc> { + pub fn get_or_insert_global( + &self, + name: &str, + ty: Type<'gcc>, + is_tls: bool, + link_section: Option, + ) -> LValue<'gcc> { if self.globals.borrow().contains_key(name) { let typ = self.globals.borrow()[name].get_type(); let global = self.context.new_global(None, GlobalKind::Imported, typ, name); @@ -22,8 +28,7 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { global.set_link_section(link_section.as_str()); } global - } - else { + } else { self.declare_global(name, ty, GlobalKind::Exported, is_tls, link_section) } } @@ -33,19 +38,37 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { self.context.new_global(None, GlobalKind::Internal, ty, &name) } - pub fn declare_global_with_linkage(&self, name: &str, ty: Type<'gcc>, linkage: GlobalKind) -> LValue<'gcc> { + pub fn declare_global_with_linkage( + &self, + name: &str, + ty: Type<'gcc>, + linkage: GlobalKind, + ) -> LValue<'gcc> { let global = self.context.new_global(None, linkage, ty, name); let global_address = global.get_address(None); self.globals.borrow_mut().insert(name.to_string(), global_address); global } - pub fn declare_func(&self, name: &str, return_type: Type<'gcc>, params: &[Type<'gcc>], variadic: bool) -> Function<'gcc> { + pub fn declare_func( + &self, + name: &str, + return_type: Type<'gcc>, + params: &[Type<'gcc>], + variadic: bool, + ) -> Function<'gcc> { self.linkage.set(FunctionType::Extern); declare_raw_fn(self, name, () /*llvm::CCallConv*/, return_type, params, variadic) } - pub fn declare_global(&self, name: &str, ty: Type<'gcc>, global_kind: GlobalKind, is_tls: bool, link_section: Option) -> LValue<'gcc> { + pub fn declare_global( + &self, + name: &str, + ty: Type<'gcc>, + global_kind: GlobalKind, + is_tls: bool, + link_section: Option, + ) -> LValue<'gcc> { let global = self.context.new_global(None, global_kind, ty, name); if is_tls { global.set_tls_model(self.tls_model); @@ -65,13 +88,25 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { global } - pub fn declare_entry_fn(&self, name: &str, _fn_type: Type<'gcc>, callconv: () /*llvm::CCallConv*/) -> RValue<'gcc> { + pub fn declare_entry_fn( + &self, + name: &str, + _fn_type: Type<'gcc>, + callconv: (), /*llvm::CCallConv*/ + ) -> RValue<'gcc> { // TODO(antoyo): use the fn_type parameter. let const_string = self.context.new_type::().make_pointer().make_pointer(); let return_type = self.type_i32(); let variadic = false; self.linkage.set(FunctionType::Exported); - let func = declare_raw_fn(self, name, callconv, return_type, &[self.type_i32(), const_string], variadic); + let func = declare_raw_fn( + self, + name, + callconv, + return_type, + &[self.type_i32(), const_string], + variadic, + ); // NOTE: it is needed to set the current_func here as well, because get_fn() is not called // for the main function. *self.current_func.borrow_mut() = Some(func); @@ -85,19 +120,32 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { arguments_type, is_c_variadic, on_stack_param_indices, - #[cfg(feature="master")] + #[cfg(feature = "master")] fn_attributes, } = fn_abi.gcc_type(self); - let func = declare_raw_fn(self, name, () /*fn_abi.llvm_cconv()*/, return_type, &arguments_type, is_c_variadic); + let func = declare_raw_fn( + self, + name, + (), /*fn_abi.llvm_cconv()*/ + return_type, + &arguments_type, + is_c_variadic, + ); self.on_stack_function_params.borrow_mut().insert(func, on_stack_param_indices); - #[cfg(feature="master")] + #[cfg(feature = "master")] for fn_attr in fn_attributes { func.add_attribute(fn_attr); } func } - pub fn define_global(&self, name: &str, ty: Type<'gcc>, is_tls: bool, link_section: Option) -> LValue<'gcc> { + pub fn define_global( + &self, + name: &str, + ty: Type<'gcc>, + is_tls: bool, + link_section: Option, + ) -> LValue<'gcc> { self.get_or_insert_global(name, ty, is_tls, link_section) } @@ -111,62 +159,84 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { /// /// If there’s a value with the same name already declared, the function will /// update the declaration and return existing Value instead. -fn declare_raw_fn<'gcc>(cx: &CodegenCx<'gcc, '_>, name: &str, _callconv: () /*llvm::CallConv*/, return_type: Type<'gcc>, param_types: &[Type<'gcc>], variadic: bool) -> Function<'gcc> { +fn declare_raw_fn<'gcc>( + cx: &CodegenCx<'gcc, '_>, + name: &str, + _callconv: (), /*llvm::CallConv*/ + return_type: Type<'gcc>, + param_types: &[Type<'gcc>], + variadic: bool, +) -> Function<'gcc> { if name.starts_with("llvm.") { let intrinsic = llvm::intrinsic(name, cx); cx.intrinsics.borrow_mut().insert(name.to_string(), intrinsic); return intrinsic; } - let func = - if cx.functions.borrow().contains_key(name) { - cx.functions.borrow()[name] - } - else { - let params: Vec<_> = param_types.into_iter().enumerate() - .map(|(index, param)| cx.context.new_parameter(None, *param, &format!("param{}", index))) // TODO(antoyo): set name. + let func = if cx.functions.borrow().contains_key(name) { + cx.functions.borrow()[name] + } else { + let params: Vec<_> = param_types + .into_iter() + .enumerate() + .map(|(index, param)| { + cx.context.new_parameter(None, *param, &format!("param{}", index)) + }) // TODO(antoyo): set name. + .collect(); + #[cfg(not(feature = "master"))] + let name = mangle_name(name); + let func = + cx.context.new_function(None, cx.linkage.get(), return_type, ¶ms, &name, variadic); + cx.functions.borrow_mut().insert(name.to_string(), func); + + #[cfg(feature = "master")] + if name == "rust_eh_personality" { + // NOTE: GCC will sometimes change the personality function set on a function from + // rust_eh_personality to __gcc_personality_v0 as an optimization. + // As such, we need to create a weak alias from __gcc_personality_v0 to + // rust_eh_personality in order to avoid a linker error. + // This needs to be weak in order to still allow using the standard + // __gcc_personality_v0 when the linking to it. + // Since aliases don't work (maybe because of a bug in LTO partitioning?), we + // create a wrapper function that calls rust_eh_personality. + + let params: Vec<_> = param_types + .into_iter() + .enumerate() + .map(|(index, param)| { + cx.context.new_parameter(None, *param, &format!("param{}", index)) + }) // TODO(antoyo): set name. .collect(); - let func = cx.context.new_function(None, cx.linkage.get(), return_type, ¶ms, mangle_name(name), variadic); - cx.functions.borrow_mut().insert(name.to_string(), func); - - #[cfg(feature="master")] - if name == "rust_eh_personality" { - // NOTE: GCC will sometimes change the personality function set on a function from - // rust_eh_personality to __gcc_personality_v0 as an optimization. - // As such, we need to create a weak alias from __gcc_personality_v0 to - // rust_eh_personality in order to avoid a linker error. - // This needs to be weak in order to still allow using the standard - // __gcc_personality_v0 when the linking to it. - // Since aliases don't work (maybe because of a bug in LTO partitioning?), we - // create a wrapper function that calls rust_eh_personality. - - let params: Vec<_> = param_types.into_iter().enumerate() - .map(|(index, param)| cx.context.new_parameter(None, *param, &format!("param{}", index))) // TODO(antoyo): set name. - .collect(); - let gcc_func = cx.context.new_function(None, FunctionType::Exported, return_type, ¶ms, "__gcc_personality_v0", variadic); - - // We need a normal extern function for the crates that access rust_eh_personality - // without defining it, otherwise we'll get a compiler error. - // - // For the crate defining it, that needs to be a weak alias instead. - gcc_func.add_attribute(FnAttribute::Weak); - - let block = gcc_func.new_block("start"); - let mut args = vec![]; - for param in ¶ms { - args.push(param.to_rvalue()); - } - let call = cx.context.new_call(None, func, &args); - if return_type == cx.type_void() { - block.add_eval(None, call); - block.end_with_void_return(None); - } - else { - block.end_with_return(None, call); - } + let gcc_func = cx.context.new_function( + None, + FunctionType::Exported, + return_type, + ¶ms, + "__gcc_personality_v0", + variadic, + ); + + // We need a normal extern function for the crates that access rust_eh_personality + // without defining it, otherwise we'll get a compiler error. + // + // For the crate defining it, that needs to be a weak alias instead. + gcc_func.add_attribute(FnAttribute::Weak); + + let block = gcc_func.new_block("start"); + let mut args = vec![]; + for param in ¶ms { + args.push(param.to_rvalue()); } + let call = cx.context.new_call(None, func, &args); + if return_type == cx.type_void() { + block.add_eval(None, call); + block.end_with_void_return(None); + } else { + block.end_with_return(None, call); + } + } - func - }; + func + }; // TODO(antoyo): set function calling convention. // TODO(antoyo): set unnamed address. @@ -179,15 +249,24 @@ fn declare_raw_fn<'gcc>(cx: &CodegenCx<'gcc, '_>, name: &str, _callconv: () /*ll } // FIXME(antoyo): this is a hack because libgccjit currently only supports alpha, num and _. -// Unsupported characters: `$` and `.`. -pub fn mangle_name(name: &str) -> String { - name.replace(|char: char| { - if !char.is_alphanumeric() && char != '_' { - debug_assert!("$.*".contains(char), "Unsupported char in function name {}: {}", name, char); - true - } - else { - false - } - }, "_") +// Unsupported characters: `$`, `.` and `*`. +// FIXME(antoyo): `*` might not be expected: https://github.com/rust-lang/rust/issues/116979#issuecomment-1840926865 +#[cfg(not(feature = "master"))] +fn mangle_name(name: &str) -> String { + name.replace( + |char: char| { + if !char.is_alphanumeric() && char != '_' { + debug_assert!( + "$.*".contains(char), + "Unsupported char in function name {}: {}", + name, + char + ); + true + } else { + false + } + }, + "_", + ) } diff --git a/src/errors.rs b/src/errors.rs index 988a7e1033e28..f963a153fbaba 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -1,9 +1,6 @@ -use rustc_errors::{ - DiagCtxt, DiagArgValue, Diag, EmissionGuarantee, IntoDiagnostic, IntoDiagnosticArg, Level, -}; +use rustc_errors::{Diag, DiagCtxt, EmissionGuarantee, IntoDiagnostic, Level}; use rustc_macros::{Diagnostic, Subdiagnostic}; use rustc_span::Span; -use std::borrow::Cow; use crate::fluent_generated as fluent; @@ -31,18 +28,6 @@ pub(crate) enum PossibleFeature<'a> { None, } -struct ExitCode(Option); - -impl IntoDiagnosticArg for ExitCode { - fn into_diagnostic_arg(self) -> DiagArgValue { - let ExitCode(exit_code) = self; - match exit_code { - Some(t) => t.into_diagnostic_arg(), - None => DiagArgValue::Str(Cow::Borrowed("")), - } - } -} - #[derive(Diagnostic)] #[diag(codegen_gcc_lto_not_supported)] pub(crate) struct LTONotSupported; @@ -80,12 +65,6 @@ pub(crate) struct CopyBitcode { #[note] pub(crate) struct DynamicLinkingWithLTO; -#[derive(Diagnostic)] -#[diag(codegen_gcc_load_bitcode)] -pub(crate) struct LoadBitcode { - name: String, -} - #[derive(Diagnostic)] #[diag(codegen_gcc_lto_disallowed)] pub(crate) struct LtoDisallowed; diff --git a/src/gcc_util.rs b/src/gcc_util.rs index 4babe5bfb813f..53877e8ff7fad 100644 --- a/src/gcc_util.rs +++ b/src/gcc_util.rs @@ -1,4 +1,4 @@ -#[cfg(feature="master")] +#[cfg(feature = "master")] use gccjit::Context; use smallvec::{smallvec, SmallVec}; @@ -7,7 +7,10 @@ use rustc_middle::bug; use rustc_session::Session; use rustc_target::target_features::RUSTC_SPECIFIC_FEATURES; -use crate::errors::{PossibleFeature, TargetFeatureDisableOrEnable, UnknownCTargetFeature, UnknownCTargetFeaturePrefix}; +use crate::errors::{ + PossibleFeature, TargetFeatureDisableOrEnable, UnknownCTargetFeature, + UnknownCTargetFeaturePrefix, +}; /// The list of GCC features computed from CLI flags (`-Ctarget-cpu`, `-Ctarget-feature`, /// `--target` and similar). @@ -44,7 +47,10 @@ pub(crate) fn global_gcc_features(sess: &Session, diagnostics: bool) -> Vec Vec Vec>(), + Some( + 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::>(), ) }) .flatten(); @@ -184,7 +188,10 @@ pub fn to_gcc_features<'a>(sess: &Session, s: &'a str) -> SmallVec<[&'a str; 2]> // Given a map from target_features to whether they are enabled or disabled, // ensure only valid combinations are allowed. -pub fn check_tied_features(sess: &Session, features: &FxHashMap<&str, bool>) -> Option<&'static [&'static str]> { +pub fn check_tied_features( + sess: &Session, + features: &FxHashMap<&str, bool>, +) -> Option<&'static [&'static str]> { for tied in sess.target.tied_target_features() { // Tied features must be set to the same value, or not set at all let mut tied_iter = tied.iter(); @@ -199,7 +206,7 @@ pub fn check_tied_features(sess: &Session, features: &FxHashMap<&str, bool>) -> fn arch_to_gcc(name: &str) -> &str { match name { "M68020" => "68020", - _ => name, + _ => name, } } @@ -208,15 +215,13 @@ fn handle_native(name: &str) -> &str { return arch_to_gcc(name); } - #[cfg(feature="master")] + #[cfg(feature = "master")] { // Get the native arch. let context = Context::default(); - context.get_target_info().arch().unwrap() - .to_str() - .unwrap() + context.get_target_info().arch().unwrap().to_str().unwrap() } - #[cfg(not(feature="master"))] + #[cfg(not(feature = "master"))] unimplemented!(); } diff --git a/src/int.rs b/src/int.rs index 9b9b3ea4f8704..841bcf592e489 100644 --- a/src/int.rs +++ b/src/int.rs @@ -4,15 +4,22 @@ use std::convert::TryFrom; -use gccjit::{ComparisonOp, FunctionType, RValue, ToRValue, Type, UnaryOp, BinaryOp}; +use gccjit::{BinaryOp, ComparisonOp, FunctionType, Location, RValue, ToRValue, Type, UnaryOp}; use rustc_codegen_ssa::common::{IntPredicate, TypeKind}; use rustc_codegen_ssa::traits::{BackendTypes, BaseTypeMethods, BuilderMethods, OverflowOp}; use rustc_middle::ty::{ParamEnv, Ty}; -use rustc_target::abi::{Endian, call::{ArgAbi, ArgAttributes, Conv, FnAbi, PassMode}}; +use rustc_target::abi::{ + call::{ArgAbi, ArgAttributes, Conv, FnAbi, PassMode}, + Endian, +}; use rustc_target::spec; use crate::builder::ToGccComp; -use crate::{builder::Builder, common::{SignType, TypeReflection}, context::CodegenCx}; +use crate::{ + builder::Builder, + common::{SignType, TypeReflection}, + context::CodegenCx, +}; impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { pub fn gcc_urem(&self, a: RValue<'gcc>, b: RValue<'gcc>) -> RValue<'gcc> { @@ -29,35 +36,39 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { let typ = a.get_type(); if self.is_native_int_type_or_bool(typ) { let operation = - if typ.is_bool() { - UnaryOp::LogicalNegate - } - else { - UnaryOp::BitwiseNegate - }; - self.cx.context.new_unary_op(None, operation, typ, a) - } - else { + if typ.is_bool() { UnaryOp::LogicalNegate } else { UnaryOp::BitwiseNegate }; + self.cx.context.new_unary_op(self.location, operation, typ, a) + } else { let element_type = typ.dyncast_array().expect("element type"); - self.from_low_high_rvalues(typ, - self.cx.context.new_unary_op(None, UnaryOp::BitwiseNegate, element_type, self.low(a)), - self.cx.context.new_unary_op(None, UnaryOp::BitwiseNegate, element_type, self.high(a)), + self.from_low_high_rvalues( + typ, + self.cx.context.new_unary_op( + self.location, + UnaryOp::BitwiseNegate, + element_type, + self.low(a), + ), + self.cx.context.new_unary_op( + self.location, + UnaryOp::BitwiseNegate, + element_type, + self.high(a), + ), ) } } pub fn gcc_neg(&self, a: RValue<'gcc>) -> RValue<'gcc> { let a_type = a.get_type(); - if self.is_native_int_type(a_type) { - self.cx.context.new_unary_op(None, UnaryOp::Minus, a.get_type(), a) - } - else { + if self.is_native_int_type(a_type) || a_type.is_vector() { + self.cx.context.new_unary_op(self.location, UnaryOp::Minus, a.get_type(), a) + } else { self.gcc_add(self.gcc_not(a), self.gcc_int(a_type, 1)) } } pub fn gcc_and(&self, a: RValue<'gcc>, b: RValue<'gcc>) -> RValue<'gcc> { - self.cx.bitwise_operation(BinaryOp::BitwiseAnd, a, b) + self.cx.bitwise_operation(BinaryOp::BitwiseAnd, a, b, self.location) } pub fn gcc_lshr(&mut self, a: RValue<'gcc>, b: RValue<'gcc>) -> RValue<'gcc> { @@ -69,20 +80,16 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { // FIXME(antoyo): remove the casts when libgccjit can shift an unsigned number by a signed number. // TODO(antoyo): cast to unsigned to do a logical shift if that does not work. if a_type.is_signed(self) != b_type.is_signed(self) { - let b = self.context.new_cast(None, b, a_type); + let b = self.context.new_cast(self.location, b, a_type); a >> b - } - else { + } else { a >> b } - } - else if a_type.is_vector() && a_type.is_vector() { + } else if a_type.is_vector() && a_type.is_vector() { a >> b - } - else if a_native && !b_native { + } else if a_native && !b_native { self.gcc_lshr(a, self.gcc_int_cast(b, a_type)) - } - else { + } else { // NOTE: we cannot use the lshr builtin because it's calling hi() (to get the most // significant half of the number) which uses lshr. @@ -95,46 +102,38 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { let b0_block = func.new_block("b0"); let actual_else_block = func.new_block("actual_else"); - let result = func.new_local(None, a_type, "shiftResult"); + let result = func.new_local(self.location, a_type, "shiftResult"); let sixty_four = self.gcc_int(native_int_type, 64); let sixty_three = self.gcc_int(native_int_type, 63); let zero = self.gcc_zero(native_int_type); let b = self.gcc_int_cast(b, native_int_type); let condition = self.gcc_icmp(IntPredicate::IntNE, self.gcc_and(b, sixty_four), zero); - self.llbb().end_with_conditional(None, condition, then_block, else_block); + self.llbb().end_with_conditional(self.location, condition, then_block, else_block); let shift_value = self.gcc_sub(b, sixty_four); let high = self.high(a); - let sign = - if a_type.is_signed(self) { - high >> sixty_three - } - else { - zero - }; + let sign = if a_type.is_signed(self) { high >> sixty_three } else { zero }; let array_value = self.from_low_high_rvalues(a_type, high >> shift_value, sign); - then_block.add_assignment(None, result, array_value); - then_block.end_with_jump(None, after_block); + then_block.add_assignment(self.location, result, array_value); + then_block.end_with_jump(self.location, after_block); let condition = self.gcc_icmp(IntPredicate::IntEQ, b, zero); - else_block.end_with_conditional(None, condition, b0_block, actual_else_block); + else_block.end_with_conditional(self.location, condition, b0_block, actual_else_block); - b0_block.add_assignment(None, result, a); - b0_block.end_with_jump(None, after_block); + b0_block.add_assignment(self.location, result, a); + b0_block.end_with_jump(self.location, after_block); let shift_value = self.gcc_sub(sixty_four, b); // NOTE: cast low to its unsigned type in order to perform a logical right shift. let unsigned_type = native_int_type.to_unsigned(&self.cx); - let casted_low = self.context.new_cast(None, self.low(a), unsigned_type); - let shifted_low = casted_low >> self.context.new_cast(None, b, unsigned_type); - let shifted_low = self.context.new_cast(None, shifted_low, native_int_type); - let array_value = self.from_low_high_rvalues(a_type, - (high << shift_value) | shifted_low, - high >> b, - ); - actual_else_block.add_assignment(None, result, array_value); - actual_else_block.end_with_jump(None, after_block); + let casted_low = self.context.new_cast(self.location, self.low(a), unsigned_type); + let shifted_low = casted_low >> self.context.new_cast(self.location, b, unsigned_type); + let shifted_low = self.context.new_cast(self.location, shifted_low, native_int_type); + let array_value = + self.from_low_high_rvalues(a_type, (high << shift_value) | shifted_low, high >> b); + actual_else_block.add_assignment(self.location, result, array_value); + actual_else_block.end_with_jump(self.location, after_block); // NOTE: since jumps were added in a place rustc does not expect, the current block in the // state need to be updated. @@ -144,38 +143,49 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { } } - fn additive_operation(&self, operation: BinaryOp, a: RValue<'gcc>, mut b: RValue<'gcc>) -> RValue<'gcc> { + fn additive_operation( + &self, + operation: BinaryOp, + a: RValue<'gcc>, + mut b: RValue<'gcc>, + ) -> RValue<'gcc> { let a_type = a.get_type(); let b_type = b.get_type(); - if (self.is_native_int_type_or_bool(a_type) && self.is_native_int_type_or_bool(b_type)) || (a_type.is_vector() && b_type.is_vector()) { + if (self.is_native_int_type_or_bool(a_type) && self.is_native_int_type_or_bool(b_type)) + || (a_type.is_vector() && b_type.is_vector()) + { if a_type != b_type { if a_type.is_vector() { // Vector types need to be bitcast. // TODO(antoyo): perhaps use __builtin_convertvector for vector casting. - b = self.context.new_bitcast(None, b, a.get_type()); - } - else { - b = self.context.new_cast(None, b, a.get_type()); + b = self.context.new_bitcast(self.location, b, a.get_type()); + } else { + b = self.context.new_cast(self.location, b, a.get_type()); } } - self.context.new_binary_op(None, operation, a_type, a, b) - } - else { + self.context.new_binary_op(self.location, operation, a_type, a, b) + } else { debug_assert!(a_type.dyncast_array().is_some()); debug_assert!(b_type.dyncast_array().is_some()); let signed = a_type.is_compatible_with(self.i128_type); - let func_name = - match (operation, signed) { - (BinaryOp::Plus, true) => "__rust_i128_add", - (BinaryOp::Plus, false) => "__rust_u128_add", - (BinaryOp::Minus, true) => "__rust_i128_sub", - (BinaryOp::Minus, false) => "__rust_u128_sub", - _ => unreachable!("unexpected additive operation {:?}", operation), - }; - let param_a = self.context.new_parameter(None, a_type, "a"); - let param_b = self.context.new_parameter(None, b_type, "b"); - let func = self.context.new_function(None, FunctionType::Extern, a_type, &[param_a, param_b], func_name, false); - self.context.new_call(None, func, &[a, b]) + let func_name = match (operation, signed) { + (BinaryOp::Plus, true) => "__rust_i128_add", + (BinaryOp::Plus, false) => "__rust_u128_add", + (BinaryOp::Minus, true) => "__rust_i128_sub", + (BinaryOp::Minus, false) => "__rust_u128_sub", + _ => unreachable!("unexpected additive operation {:?}", operation), + }; + let param_a = self.context.new_parameter(self.location, a_type, "a"); + let param_b = self.context.new_parameter(self.location, b_type, "b"); + let func = self.context.new_function( + self.location, + FunctionType::Extern, + a_type, + &[param_a, param_b], + func_name, + false, + ); + self.context.new_call(self.location, func, &[a, b]) } } @@ -191,27 +201,36 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { self.additive_operation(BinaryOp::Minus, a, b) } - fn multiplicative_operation(&self, operation: BinaryOp, operation_name: &str, signed: bool, a: RValue<'gcc>, b: RValue<'gcc>) -> RValue<'gcc> { + fn multiplicative_operation( + &self, + operation: BinaryOp, + operation_name: &str, + signed: bool, + a: RValue<'gcc>, + b: RValue<'gcc>, + ) -> RValue<'gcc> { let a_type = a.get_type(); let b_type = b.get_type(); - if (self.is_native_int_type_or_bool(a_type) && self.is_native_int_type_or_bool(b_type)) || (a_type.is_vector() && b_type.is_vector()) { - self.context.new_binary_op(None, operation, a_type, a, b) - } - else { + if (self.is_native_int_type_or_bool(a_type) && self.is_native_int_type_or_bool(b_type)) + || (a_type.is_vector() && b_type.is_vector()) + { + self.context.new_binary_op(self.location, operation, a_type, a, b) + } else { debug_assert!(a_type.dyncast_array().is_some()); debug_assert!(b_type.dyncast_array().is_some()); - let sign = - if signed { - "" - } - else { - "u" - }; + let sign = if signed { "" } else { "u" }; let func_name = format!("__{}{}ti3", sign, operation_name); - let param_a = self.context.new_parameter(None, a_type, "a"); - let param_b = self.context.new_parameter(None, b_type, "b"); - let func = self.context.new_function(None, FunctionType::Extern, a_type, &[param_a, param_b], func_name, false); - self.context.new_call(None, func, &[a, b]) + let param_a = self.context.new_parameter(self.location, a_type, "a"); + let param_b = self.context.new_parameter(self.location, b_type, "b"); + let func = self.context.new_function( + self.location, + FunctionType::Extern, + a_type, + &[param_a, param_b], + func_name, + false, + ); + self.context.new_call(self.location, func, &[a, b]) } } @@ -227,137 +246,133 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { self.multiplicative_operation(BinaryOp::Divide, "div", false, a, b) } - pub fn gcc_checked_binop(&self, oop: OverflowOp, typ: Ty<'_>, lhs: ::Value, rhs: ::Value) -> (::Value, ::Value) { + pub fn gcc_checked_binop( + &self, + oop: OverflowOp, + typ: Ty<'_>, + lhs: ::Value, + rhs: ::Value, + ) -> (::Value, ::Value) { use rustc_middle::ty::{Int, IntTy::*, Uint, UintTy::*}; - let new_kind = - match typ.kind() { - Int(t @ Isize) => Int(t.normalize(self.tcx.sess.target.pointer_width)), - Uint(t @ Usize) => Uint(t.normalize(self.tcx.sess.target.pointer_width)), - t @ (Uint(_) | Int(_)) => t.clone(), - _ => panic!("tried to get overflow intrinsic for op applied to non-int type"), - }; + let new_kind = match typ.kind() { + Int(t @ Isize) => Int(t.normalize(self.tcx.sess.target.pointer_width)), + Uint(t @ Usize) => Uint(t.normalize(self.tcx.sess.target.pointer_width)), + t @ (Uint(_) | Int(_)) => t.clone(), + _ => panic!("tried to get overflow intrinsic for op applied to non-int type"), + }; // TODO(antoyo): remove duplication with intrinsic? - let name = - if self.is_native_int_type(lhs.get_type()) { - match oop { - OverflowOp::Add => - match new_kind { - Int(I8) => "__builtin_add_overflow", - Int(I16) => "__builtin_add_overflow", - Int(I32) => "__builtin_sadd_overflow", - Int(I64) => "__builtin_saddll_overflow", - Int(I128) => "__builtin_add_overflow", - - Uint(U8) => "__builtin_add_overflow", - Uint(U16) => "__builtin_add_overflow", - Uint(U32) => "__builtin_uadd_overflow", - Uint(U64) => "__builtin_uaddll_overflow", - Uint(U128) => "__builtin_add_overflow", - + let name = if self.is_native_int_type(lhs.get_type()) { + match oop { + OverflowOp::Add => match new_kind { + Int(I8) => "__builtin_add_overflow", + Int(I16) => "__builtin_add_overflow", + Int(I32) => "__builtin_sadd_overflow", + Int(I64) => "__builtin_saddll_overflow", + Int(I128) => "__builtin_add_overflow", + + Uint(U8) => "__builtin_add_overflow", + Uint(U16) => "__builtin_add_overflow", + Uint(U32) => "__builtin_uadd_overflow", + Uint(U64) => "__builtin_uaddll_overflow", + Uint(U128) => "__builtin_add_overflow", + + _ => unreachable!(), + }, + OverflowOp::Sub => match new_kind { + Int(I8) => "__builtin_sub_overflow", + Int(I16) => "__builtin_sub_overflow", + Int(I32) => "__builtin_ssub_overflow", + Int(I64) => "__builtin_ssubll_overflow", + Int(I128) => "__builtin_sub_overflow", + + Uint(U8) => "__builtin_sub_overflow", + Uint(U16) => "__builtin_sub_overflow", + Uint(U32) => "__builtin_usub_overflow", + Uint(U64) => "__builtin_usubll_overflow", + Uint(U128) => "__builtin_sub_overflow", + + _ => unreachable!(), + }, + OverflowOp::Mul => match new_kind { + Int(I8) => "__builtin_mul_overflow", + Int(I16) => "__builtin_mul_overflow", + Int(I32) => "__builtin_smul_overflow", + Int(I64) => "__builtin_smulll_overflow", + Int(I128) => "__builtin_mul_overflow", + + Uint(U8) => "__builtin_mul_overflow", + Uint(U16) => "__builtin_mul_overflow", + Uint(U32) => "__builtin_umul_overflow", + Uint(U64) => "__builtin_umulll_overflow", + Uint(U128) => "__builtin_mul_overflow", + + _ => unreachable!(), + }, + } + } else { + match new_kind { + Int(I128) | Uint(U128) => { + let func_name = match oop { + OverflowOp::Add => match new_kind { + Int(I128) => "__rust_i128_addo", + Uint(U128) => "__rust_u128_addo", _ => unreachable!(), }, - OverflowOp::Sub => - match new_kind { - Int(I8) => "__builtin_sub_overflow", - Int(I16) => "__builtin_sub_overflow", - Int(I32) => "__builtin_ssub_overflow", - Int(I64) => "__builtin_ssubll_overflow", - Int(I128) => "__builtin_sub_overflow", - - Uint(U8) => "__builtin_sub_overflow", - Uint(U16) => "__builtin_sub_overflow", - Uint(U32) => "__builtin_usub_overflow", - Uint(U64) => "__builtin_usubll_overflow", - Uint(U128) => "__builtin_sub_overflow", - + OverflowOp::Sub => match new_kind { + Int(I128) => "__rust_i128_subo", + Uint(U128) => "__rust_u128_subo", _ => unreachable!(), }, - OverflowOp::Mul => - match new_kind { - Int(I8) => "__builtin_mul_overflow", - Int(I16) => "__builtin_mul_overflow", - Int(I32) => "__builtin_smul_overflow", - Int(I64) => "__builtin_smulll_overflow", - Int(I128) => "__builtin_mul_overflow", - - Uint(U8) => "__builtin_mul_overflow", - Uint(U16) => "__builtin_mul_overflow", - Uint(U32) => "__builtin_umul_overflow", - Uint(U64) => "__builtin_umulll_overflow", - Uint(U128) => "__builtin_mul_overflow", - + OverflowOp::Mul => match new_kind { + Int(I128) => "__rust_i128_mulo", // TODO(antoyo): use __muloti4d instead? + Uint(U128) => "__rust_u128_mulo", _ => unreachable!(), }, + }; + return self.operation_with_overflow(func_name, lhs, rhs); } - } - else { - match new_kind { - Int(I128) | Uint(U128) => { - let func_name = - match oop { - OverflowOp::Add => - match new_kind { - Int(I128) => "__rust_i128_addo", - Uint(U128) => "__rust_u128_addo", - _ => unreachable!(), - }, - OverflowOp::Sub => - match new_kind { - Int(I128) => "__rust_i128_subo", - Uint(U128) => "__rust_u128_subo", - _ => unreachable!(), - }, - OverflowOp::Mul => - match new_kind { - Int(I128) => "__rust_i128_mulo", // TODO(antoyo): use __muloti4d instead? - Uint(U128) => "__rust_u128_mulo", - _ => unreachable!(), - }, - }; - return self.operation_with_overflow(func_name, lhs, rhs); + _ => match oop { + OverflowOp::Mul => match new_kind { + Int(I32) => "__mulosi4", + Int(I64) => "__mulodi4", + _ => unreachable!(), }, - _ => { - match oop { - OverflowOp::Mul => - match new_kind { - Int(I32) => "__mulosi4", - Int(I64) => "__mulodi4", - _ => unreachable!(), - }, - _ => unimplemented!("overflow operation for {:?}", new_kind), - } - } - } - }; + _ => unimplemented!("overflow operation for {:?}", new_kind), + }, + } + }; let intrinsic = self.context.get_builtin_function(&name); - let res = self.current_func() + let res = self + .current_func() // TODO(antoyo): is it correct to use rhs type instead of the parameter typ? - .new_local(None, rhs.get_type(), "binopResult") - .get_address(None); + .new_local(self.location, rhs.get_type(), "binopResult") + .get_address(self.location); let overflow = self.overflow_call(intrinsic, &[lhs, rhs, res], None); - (res.dereference(None).to_rvalue(), overflow) + (res.dereference(self.location).to_rvalue(), overflow) } - pub fn operation_with_overflow(&self, func_name: &str, lhs: RValue<'gcc>, rhs: RValue<'gcc>) -> (RValue<'gcc>, RValue<'gcc>) { + pub fn operation_with_overflow( + &self, + func_name: &str, + lhs: RValue<'gcc>, + rhs: RValue<'gcc>, + ) -> (RValue<'gcc>, RValue<'gcc>) { let a_type = lhs.get_type(); let b_type = rhs.get_type(); debug_assert!(a_type.dyncast_array().is_some()); debug_assert!(b_type.dyncast_array().is_some()); - let param_a = self.context.new_parameter(None, a_type, "a"); - let param_b = self.context.new_parameter(None, b_type, "b"); - let result_field = self.context.new_field(None, a_type, "result"); - let overflow_field = self.context.new_field(None, self.bool_type, "overflow"); + let param_a = self.context.new_parameter(self.location, a_type, "a"); + let param_b = self.context.new_parameter(self.location, b_type, "b"); + let result_field = self.context.new_field(self.location, a_type, "result"); + let overflow_field = self.context.new_field(self.location, self.bool_type, "overflow"); let ret_ty = Ty::new_tup(self.tcx, &[self.tcx.types.i128, self.tcx.types.bool]); let layout = self.tcx.layout_of(ParamEnv::reveal_all().and(ret_ty)).unwrap(); - let arg_abi = ArgAbi { - layout, - mode: PassMode::Direct(ArgAttributes::new()), - }; + let arg_abi = ArgAbi { layout, mode: PassMode::Direct(ArgAttributes::new()) }; let mut fn_abi = FnAbi { args: vec![arg_abi.clone(), arg_abi.clone()].into_boxed_slice(), ret: arg_abi, @@ -366,38 +381,66 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { conv: Conv::C, can_unwind: false, }; - fn_abi.adjust_for_foreign_abi(self.cx, spec::abi::Abi::C { - unwind: false, - }).unwrap(); + fn_abi.adjust_for_foreign_abi(self.cx, spec::abi::Abi::C { unwind: false }).unwrap(); let indirect = matches!(fn_abi.ret.mode, PassMode::Indirect { .. }); - let return_type = self.context.new_struct_type(None, "result_overflow", &[result_field, overflow_field]); - let result = - if indirect { - let return_value = self.current_func().new_local(None, return_type.as_type(), "return_value"); - let return_param_type = return_type.as_type().make_pointer(); - let return_param = self.context.new_parameter(None, return_param_type, "return_value"); - let func = self.context.new_function(None, FunctionType::Extern, self.type_void(), &[return_param, param_a, param_b], func_name, false); - self.llbb().add_eval(None, self.context.new_call(None, func, &[return_value.get_address(None), lhs, rhs])); - return_value.to_rvalue() - } - else { - let func = self.context.new_function(None, FunctionType::Extern, return_type.as_type(), &[param_a, param_b], func_name, false); - self.context.new_call(None, func, &[lhs, rhs]) - }; - let overflow = result.access_field(None, overflow_field); - let int_result = result.access_field(None, result_field); - return (int_result, overflow); + let return_type = self.context.new_struct_type( + self.location, + "result_overflow", + &[result_field, overflow_field], + ); + let result = if indirect { + let return_value = + self.current_func().new_local(self.location, return_type.as_type(), "return_value"); + let return_param_type = return_type.as_type().make_pointer(); + let return_param = + self.context.new_parameter(self.location, return_param_type, "return_value"); + let func = self.context.new_function( + self.location, + FunctionType::Extern, + self.type_void(), + &[return_param, param_a, param_b], + func_name, + false, + ); + self.llbb().add_eval( + self.location, + self.context.new_call( + self.location, + func, + &[return_value.get_address(self.location), lhs, rhs], + ), + ); + return_value.to_rvalue() + } else { + let func = self.context.new_function( + self.location, + FunctionType::Extern, + return_type.as_type(), + &[param_a, param_b], + func_name, + false, + ); + self.context.new_call(self.location, func, &[lhs, rhs]) + }; + let overflow = result.access_field(self.location, overflow_field); + let int_result = result.access_field(self.location, result_field); + (int_result, overflow) } - pub fn gcc_icmp(&mut self, op: IntPredicate, mut lhs: RValue<'gcc>, mut rhs: RValue<'gcc>) -> RValue<'gcc> { + pub fn gcc_icmp( + &mut self, + op: IntPredicate, + mut lhs: RValue<'gcc>, + mut rhs: RValue<'gcc>, + ) -> RValue<'gcc> { let a_type = lhs.get_type(); let b_type = rhs.get_type(); if self.is_non_native_int_type(a_type) || self.is_non_native_int_type(b_type) { // This algorithm is based on compiler-rt's __cmpti2: // https://github.com/llvm-mirror/compiler-rt/blob/f0745e8476f069296a7c71accedd061dce4cdf79/lib/builtins/cmpti2.c#L21 - let result = self.current_func().new_local(None, self.int_type, "icmp_result"); + let result = self.current_func().new_local(self.location, self.int_type, "icmp_result"); let block1 = self.current_func().new_block("block1"); let block2 = self.current_func().new_block("block2"); let block3 = self.current_func().new_block("block3"); @@ -413,92 +456,149 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { // the sign is only on high). let unsigned_type = native_int_type.to_unsigned(&self.cx); - let lhs_low = self.context.new_cast(None, self.low(lhs), unsigned_type); - let rhs_low = self.context.new_cast(None, self.low(rhs), unsigned_type); + let lhs_low = self.context.new_cast(self.location, self.low(lhs), unsigned_type); + let rhs_low = self.context.new_cast(self.location, self.low(rhs), unsigned_type); - let condition = self.context.new_comparison(None, ComparisonOp::LessThan, self.high(lhs), self.high(rhs)); - self.llbb().end_with_conditional(None, condition, block1, block2); + let condition = self.context.new_comparison( + self.location, + ComparisonOp::LessThan, + self.high(lhs), + self.high(rhs), + ); + self.llbb().end_with_conditional(self.location, condition, block1, block2); - block1.add_assignment(None, result, self.context.new_rvalue_zero(self.int_type)); - block1.end_with_jump(None, after); + block1.add_assignment( + self.location, + result, + self.context.new_rvalue_zero(self.int_type), + ); + block1.end_with_jump(self.location, after); - let condition = self.context.new_comparison(None, ComparisonOp::GreaterThan, self.high(lhs), self.high(rhs)); - block2.end_with_conditional(None, condition, block3, block4); + let condition = self.context.new_comparison( + self.location, + ComparisonOp::GreaterThan, + self.high(lhs), + self.high(rhs), + ); + block2.end_with_conditional(self.location, condition, block3, block4); - block3.add_assignment(None, result, self.context.new_rvalue_from_int(self.int_type, 2)); - block3.end_with_jump(None, after); + block3.add_assignment( + self.location, + result, + self.context.new_rvalue_from_int(self.int_type, 2), + ); + block3.end_with_jump(self.location, after); - let condition = self.context.new_comparison(None, ComparisonOp::LessThan, lhs_low, rhs_low); - block4.end_with_conditional(None, condition, block5, block6); + let condition = self.context.new_comparison( + self.location, + ComparisonOp::LessThan, + lhs_low, + rhs_low, + ); + block4.end_with_conditional(self.location, condition, block5, block6); - block5.add_assignment(None, result, self.context.new_rvalue_zero(self.int_type)); - block5.end_with_jump(None, after); + block5.add_assignment( + self.location, + result, + self.context.new_rvalue_zero(self.int_type), + ); + block5.end_with_jump(self.location, after); - let condition = self.context.new_comparison(None, ComparisonOp::GreaterThan, lhs_low, rhs_low); - block6.end_with_conditional(None, condition, block7, block8); + let condition = self.context.new_comparison( + self.location, + ComparisonOp::GreaterThan, + lhs_low, + rhs_low, + ); + block6.end_with_conditional(self.location, condition, block7, block8); - block7.add_assignment(None, result, self.context.new_rvalue_from_int(self.int_type, 2)); - block7.end_with_jump(None, after); + block7.add_assignment( + self.location, + result, + self.context.new_rvalue_from_int(self.int_type, 2), + ); + block7.end_with_jump(self.location, after); - block8.add_assignment(None, result, self.context.new_rvalue_one(self.int_type)); - block8.end_with_jump(None, after); + block8.add_assignment( + self.location, + result, + self.context.new_rvalue_one(self.int_type), + ); + block8.end_with_jump(self.location, after); // NOTE: since jumps were added in a place rustc does not expect, the current block in the // state need to be updated. self.switch_to_block(after); let cmp = result.to_rvalue(); - let (op, limit) = - match op { - IntPredicate::IntEQ => { - return self.context.new_comparison(None, ComparisonOp::Equals, cmp, self.context.new_rvalue_one(self.int_type)); - }, - IntPredicate::IntNE => { - return self.context.new_comparison(None, ComparisonOp::NotEquals, cmp, self.context.new_rvalue_one(self.int_type)); - }, - // TODO(antoyo): cast to u128 for unsigned comparison. See below. - IntPredicate::IntUGT => (ComparisonOp::Equals, 2), - IntPredicate::IntUGE => (ComparisonOp::GreaterThanEquals, 1), - IntPredicate::IntULT => (ComparisonOp::Equals, 0), - IntPredicate::IntULE => (ComparisonOp::LessThanEquals, 1), - IntPredicate::IntSGT => (ComparisonOp::Equals, 2), - IntPredicate::IntSGE => (ComparisonOp::GreaterThanEquals, 1), - IntPredicate::IntSLT => (ComparisonOp::Equals, 0), - IntPredicate::IntSLE => (ComparisonOp::LessThanEquals, 1), - }; - self.context.new_comparison(None, op, cmp, self.context.new_rvalue_from_int(self.int_type, limit)) - } - else if a_type.get_pointee().is_some() && b_type.get_pointee().is_some() { + let (op, limit) = match op { + IntPredicate::IntEQ => { + return self.context.new_comparison( + self.location, + ComparisonOp::Equals, + cmp, + self.context.new_rvalue_one(self.int_type), + ); + } + IntPredicate::IntNE => { + return self.context.new_comparison( + self.location, + ComparisonOp::NotEquals, + cmp, + self.context.new_rvalue_one(self.int_type), + ); + } + // TODO(antoyo): cast to u128 for unsigned comparison. See below. + IntPredicate::IntUGT => (ComparisonOp::Equals, 2), + IntPredicate::IntUGE => (ComparisonOp::GreaterThanEquals, 1), + IntPredicate::IntULT => (ComparisonOp::Equals, 0), + IntPredicate::IntULE => (ComparisonOp::LessThanEquals, 1), + IntPredicate::IntSGT => (ComparisonOp::Equals, 2), + IntPredicate::IntSGE => (ComparisonOp::GreaterThanEquals, 1), + IntPredicate::IntSLT => (ComparisonOp::Equals, 0), + IntPredicate::IntSLE => (ComparisonOp::LessThanEquals, 1), + }; + self.context.new_comparison( + self.location, + op, + cmp, + self.context.new_rvalue_from_int(self.int_type, limit), + ) + } else if a_type.get_pointee().is_some() && b_type.get_pointee().is_some() { // NOTE: gcc cannot compare pointers to different objects, but rustc does that, so cast them to usize. - lhs = self.context.new_bitcast(None, lhs, self.usize_type); - rhs = self.context.new_bitcast(None, rhs, self.usize_type); - self.context.new_comparison(None, op.to_gcc_comparison(), lhs, rhs) - } - else { + lhs = self.context.new_bitcast(self.location, lhs, self.usize_type); + rhs = self.context.new_bitcast(self.location, rhs, self.usize_type); + self.context.new_comparison(self.location, op.to_gcc_comparison(), lhs, rhs) + } else { if a_type != b_type { // NOTE: because libgccjit cannot compare function pointers. - if a_type.dyncast_function_ptr_type().is_some() && b_type.dyncast_function_ptr_type().is_some() { - lhs = self.context.new_cast(None, lhs, self.usize_type.make_pointer()); - rhs = self.context.new_cast(None, rhs, self.usize_type.make_pointer()); + if a_type.dyncast_function_ptr_type().is_some() + && b_type.dyncast_function_ptr_type().is_some() + { + lhs = self.context.new_cast(self.location, lhs, self.usize_type.make_pointer()); + rhs = self.context.new_cast(self.location, rhs, self.usize_type.make_pointer()); } // NOTE: hack because we try to cast a vector type to the same vector type. else if format!("{:?}", a_type) != format!("{:?}", b_type) { - rhs = self.context.new_cast(None, rhs, a_type); + rhs = self.context.new_cast(self.location, rhs, a_type); } } match op { - IntPredicate::IntUGT | IntPredicate::IntUGE | IntPredicate::IntULT | IntPredicate::IntULE => { + IntPredicate::IntUGT + | IntPredicate::IntUGE + | IntPredicate::IntULT + | IntPredicate::IntULE => { if !a_type.is_vector() { let unsigned_type = a_type.to_unsigned(&self.cx); - lhs = self.context.new_cast(None, lhs, unsigned_type); - rhs = self.context.new_cast(None, rhs, unsigned_type); + lhs = self.context.new_cast(self.location, lhs, unsigned_type); + rhs = self.context.new_cast(self.location, rhs, unsigned_type); } - }, + } // TODO(antoyo): we probably need to handle signed comparison for unsigned // integers. _ => (), } - self.context.new_comparison(None, op.to_gcc_comparison(), lhs, rhs) + self.context.new_comparison(self.location, op.to_gcc_comparison(), lhs, rhs) } } @@ -508,12 +608,12 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { if a_type.is_vector() && b_type.is_vector() { let b = self.bitcast_if_needed(b, a_type); a ^ b - } - else if self.is_native_int_type_or_bool(a_type) && self.is_native_int_type_or_bool(b_type) { + } else if self.is_native_int_type_or_bool(a_type) && self.is_native_int_type_or_bool(b_type) + { a ^ b - } - else { - self.from_low_high_rvalues(a_type, + } else { + self.from_low_high_rvalues( + a_type, self.low(a) ^ self.low(b), self.high(a) ^ self.high(b), ) @@ -528,25 +628,20 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { if a_native && b_native { // FIXME(antoyo): remove the casts when libgccjit can shift an unsigned number by an unsigned number. if a_type.is_unsigned(self) && b_type.is_signed(self) { - let a = self.context.new_cast(None, a, b_type); + let a = self.context.new_cast(self.location, a, b_type); let result = a << b; - self.context.new_cast(None, result, a_type) - } - else if a_type.is_signed(self) && b_type.is_unsigned(self) { - let b = self.context.new_cast(None, b, a_type); + self.context.new_cast(self.location, result, a_type) + } else if a_type.is_signed(self) && b_type.is_unsigned(self) { + let b = self.context.new_cast(self.location, b, a_type); a << b - } - else { + } else { a << b } - } - else if a_type.is_vector() && a_type.is_vector() { + } else if a_type.is_vector() && a_type.is_vector() { a << b - } - else if a_native && !b_native { + } else if a_native && !b_native { self.gcc_shl(a, self.gcc_int_cast(b, a_type)) - } - else { + } else { // NOTE: we cannot use the ashl builtin because it's calling widen_hi() which uses ashl. let native_int_type = a_type.dyncast_array().expect("get element type"); @@ -557,40 +652,40 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { let b0_block = func.new_block("b0"); let actual_else_block = func.new_block("actual_else"); - let result = func.new_local(None, a_type, "shiftResult"); + let result = func.new_local(self.location, a_type, "shiftResult"); let b = self.gcc_int_cast(b, native_int_type); let sixty_four = self.gcc_int(native_int_type, 64); let zero = self.gcc_zero(native_int_type); let condition = self.gcc_icmp(IntPredicate::IntNE, self.gcc_and(b, sixty_four), zero); - self.llbb().end_with_conditional(None, condition, then_block, else_block); + self.llbb().end_with_conditional(self.location, condition, then_block, else_block); - let array_value = self.from_low_high_rvalues(a_type, - zero, - self.low(a) << (b - sixty_four), - ); - then_block.add_assignment(None, result, array_value); - then_block.end_with_jump(None, after_block); + let array_value = + self.from_low_high_rvalues(a_type, zero, self.low(a) << (b - sixty_four)); + then_block.add_assignment(self.location, result, array_value); + then_block.end_with_jump(self.location, after_block); let condition = self.gcc_icmp(IntPredicate::IntEQ, b, zero); - else_block.end_with_conditional(None, condition, b0_block, actual_else_block); + else_block.end_with_conditional(self.location, condition, b0_block, actual_else_block); - b0_block.add_assignment(None, result, a); - b0_block.end_with_jump(None, after_block); + b0_block.add_assignment(self.location, result, a); + b0_block.end_with_jump(self.location, after_block); // NOTE: cast low to its unsigned type in order to perform a logical right shift. // TODO(antoyo): adjust this ^ comment. let unsigned_type = native_int_type.to_unsigned(&self.cx); - let casted_low = self.context.new_cast(None, self.low(a), unsigned_type); - let shift_value = self.context.new_cast(None, sixty_four - b, unsigned_type); - let high_low = self.context.new_cast(None, casted_low >> shift_value, native_int_type); + let casted_low = self.context.new_cast(self.location, self.low(a), unsigned_type); + let shift_value = self.context.new_cast(self.location, sixty_four - b, unsigned_type); + let high_low = + self.context.new_cast(self.location, casted_low >> shift_value, native_int_type); - let array_value = self.from_low_high_rvalues(a_type, + let array_value = self.from_low_high_rvalues( + a_type, self.low(a) << b, (self.high(a) << b) | high_low, ); - actual_else_block.add_assignment(None, result, array_value); - actual_else_block.end_with_jump(None, after_block); + actual_else_block.add_assignment(self.location, result, array_value); + actual_else_block.end_with_jump(self.location, after_block); // NOTE: since jumps were added in a place rustc does not expect, the current block in the // state need to be updated. @@ -606,10 +701,10 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { let native_int_type = arg_type.dyncast_array().expect("get element type"); let lsb = self.low(arg); let swapped_lsb = self.gcc_bswap(lsb, width / 2); - let swapped_lsb = self.context.new_cast(None, swapped_lsb, native_int_type); + let swapped_lsb = self.context.new_cast(self.location, swapped_lsb, native_int_type); let msb = self.high(arg); let swapped_msb = self.gcc_bswap(msb, width / 2); - let swapped_msb = self.context.new_cast(None, swapped_msb, native_int_type); + let swapped_msb = self.context.new_cast(self.location, swapped_msb, native_int_type); // NOTE: we also need to swap the two elements here, in addition to swapping inside // the elements themselves like done above. @@ -625,7 +720,7 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { if param_type != arg_type { arg = self.bitcast(arg, param_type); } - self.cx.context.new_call(None, bswap, &[arg]) + self.cx.context.new_call(self.location, bswap, &[arg]) } } @@ -633,8 +728,7 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { pub fn gcc_int(&self, typ: Type<'gcc>, int: i64) -> RValue<'gcc> { if self.is_native_int_type_or_bool(typ) { self.context.new_rvalue_from_long(typ, i64::try_from(int).expect("i64::try_from")) - } - else { + } else { // NOTE: set the sign in high. self.from_low_high(typ, int, -(int.is_negative() as i64)) } @@ -645,11 +739,10 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { // FIXME(antoyo): libgccjit cannot create 128-bit values yet. let num = self.context.new_rvalue_from_long(self.u64_type, int as i64); self.gcc_int_cast(num, typ) - } - else if self.is_native_int_type_or_bool(typ) { - self.context.new_rvalue_from_long(typ, u64::try_from(int).expect("u64::try_from") as i64) - } - else { + } else if self.is_native_int_type_or_bool(typ) { + self.context + .new_rvalue_from_long(typ, u64::try_from(int).expect("u64::try_from") as i64) + } else { self.from_low_high(typ, int as i64, 0) } } @@ -666,17 +759,14 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { let sixty_four = self.context.new_rvalue_from_long(typ, 64); let shift = high << sixty_four; shift | self.context.new_cast(None, low, typ) - } - else { + } else { self.from_low_high(typ, low as i64, high as i64) } - } - else if typ.is_i128(self) { + } else if typ.is_i128(self) { // FIXME(antoyo): libgccjit cannot create 128-bit values yet. let num = self.context.new_rvalue_from_long(self.u64_type, num as u64 as i64); self.gcc_int_cast(num, typ) - } - else { + } else { self.gcc_uint(typ, num as u64) } } @@ -684,8 +774,7 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { pub fn gcc_zero(&self, typ: Type<'gcc>) -> RValue<'gcc> { if self.is_native_int_type_or_bool(typ) { self.context.new_rvalue_zero(typ) - } - else { + } else { self.from_low_high(typ, 0, 0) } } @@ -693,64 +782,88 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { pub fn gcc_int_width(&self, typ: Type<'gcc>) -> u64 { if self.is_native_int_type_or_bool(typ) { typ.get_size() as u64 * 8 - } - else { + } else { // NOTE: the only unsupported types are u128 and i128. 128 } } - fn bitwise_operation(&self, operation: BinaryOp, a: RValue<'gcc>, mut b: RValue<'gcc>) -> RValue<'gcc> { + fn bitwise_operation( + &self, + operation: BinaryOp, + a: RValue<'gcc>, + mut b: RValue<'gcc>, + loc: Option>, + ) -> RValue<'gcc> { let a_type = a.get_type(); let b_type = b.get_type(); let a_native = self.is_native_int_type_or_bool(a_type); let b_native = self.is_native_int_type_or_bool(b_type); if a_type.is_vector() && b_type.is_vector() { let b = self.bitcast_if_needed(b, a_type); - self.context.new_binary_op(None, operation, a_type, a, b) - } - else if a_native && b_native { + self.context.new_binary_op(loc, operation, a_type, a, b) + } else if a_native && b_native { if a_type != b_type { - b = self.context.new_cast(None, b, a_type); + b = self.context.new_cast(loc, b, a_type); } - self.context.new_binary_op(None, operation, a_type, a, b) - } - else { - assert!(!a_native && !b_native, "both types should either be native or non-native for or operation"); + self.context.new_binary_op(loc, operation, a_type, a, b) + } else { + assert!( + !a_native && !b_native, + "both types should either be native or non-native for or operation" + ); let native_int_type = a_type.dyncast_array().expect("get element type"); - self.from_low_high_rvalues(a_type, - self.context.new_binary_op(None, operation, native_int_type, self.low(a), self.low(b)), - self.context.new_binary_op(None, operation, native_int_type, self.high(a), self.high(b)), + self.from_low_high_rvalues( + a_type, + self.context.new_binary_op( + loc, + operation, + native_int_type, + self.low(a), + self.low(b), + ), + self.context.new_binary_op( + loc, + operation, + native_int_type, + self.high(a), + self.high(b), + ), ) } } - pub fn gcc_or(&self, a: RValue<'gcc>, b: RValue<'gcc>) -> RValue<'gcc> { - self.bitwise_operation(BinaryOp::BitwiseOr, a, b) + pub fn gcc_or( + &self, + a: RValue<'gcc>, + b: RValue<'gcc>, + loc: Option>, + ) -> RValue<'gcc> { + self.bitwise_operation(BinaryOp::BitwiseOr, a, b, loc) } // TODO(antoyo): can we use https://github.com/rust-lang/compiler-builtins/blob/master/src/int/mod.rs#L379 instead? pub fn gcc_int_cast(&self, value: RValue<'gcc>, dest_typ: Type<'gcc>) -> RValue<'gcc> { let value_type = value.get_type(); - if self.is_native_int_type_or_bool(dest_typ) && self.is_native_int_type_or_bool(value_type) { + if self.is_native_int_type_or_bool(dest_typ) && self.is_native_int_type_or_bool(value_type) + { self.context.new_cast(None, value, dest_typ) - } - else if self.is_native_int_type_or_bool(dest_typ) { + } else if self.is_native_int_type_or_bool(dest_typ) { self.context.new_cast(None, self.low(value), dest_typ) - } - else if self.is_native_int_type_or_bool(value_type) { + } else if self.is_native_int_type_or_bool(value_type) { let dest_element_type = dest_typ.dyncast_array().expect("get element type"); // NOTE: set the sign of the value. let zero = self.context.new_rvalue_zero(value_type); - let is_negative = self.context.new_comparison(None, ComparisonOp::LessThan, value, zero); + let is_negative = + self.context.new_comparison(None, ComparisonOp::LessThan, value, zero); let is_negative = self.gcc_int_cast(is_negative, dest_element_type); - self.from_low_high_rvalues(dest_typ, + self.from_low_high_rvalues( + dest_typ, self.context.new_cast(None, value, dest_element_type), self.context.new_unary_op(None, UnaryOp::Minus, dest_element_type, is_negative), ) - } - else { + } else { // Since u128 and i128 are the only types that can be unsupported, we know the type of // value and the destination type have the same size, so a bitcast is fine. @@ -759,29 +872,34 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { } } - fn int_to_float_cast(&self, signed: bool, value: RValue<'gcc>, dest_typ: Type<'gcc>) -> RValue<'gcc> { + fn int_to_float_cast( + &self, + signed: bool, + value: RValue<'gcc>, + dest_typ: Type<'gcc>, + ) -> RValue<'gcc> { let value_type = value.get_type(); if self.is_native_int_type_or_bool(value_type) { return self.context.new_cast(None, value, dest_typ); } debug_assert!(value_type.dyncast_array().is_some()); - let name_suffix = - match self.type_kind(dest_typ) { - TypeKind::Float => "tisf", - TypeKind::Double => "tidf", - kind => panic!("cannot cast a non-native integer to type {:?}", kind), - }; - let sign = - if signed { - "" - } - else { - "un" - }; + let name_suffix = match self.type_kind(dest_typ) { + TypeKind::Float => "tisf", + TypeKind::Double => "tidf", + kind => panic!("cannot cast a non-native integer to type {:?}", kind), + }; + let sign = if signed { "" } else { "un" }; let func_name = format!("__float{}{}", sign, name_suffix); let param = self.context.new_parameter(None, value_type, "n"); - let func = self.context.new_function(None, FunctionType::Extern, dest_typ, &[param], func_name, false); + let func = self.context.new_function( + None, + FunctionType::Extern, + dest_typ, + &[param], + func_name, + false, + ); self.context.new_call(None, func, &[value]) } @@ -789,33 +907,42 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { self.int_to_float_cast(true, value, dest_typ) } - pub fn gcc_uint_to_float_cast(&self, value: RValue<'gcc>, dest_typ: Type<'gcc>) -> RValue<'gcc> { + pub fn gcc_uint_to_float_cast( + &self, + value: RValue<'gcc>, + dest_typ: Type<'gcc>, + ) -> RValue<'gcc> { self.int_to_float_cast(false, value, dest_typ) } - fn float_to_int_cast(&self, signed: bool, value: RValue<'gcc>, dest_typ: Type<'gcc>) -> RValue<'gcc> { + fn float_to_int_cast( + &self, + signed: bool, + value: RValue<'gcc>, + dest_typ: Type<'gcc>, + ) -> RValue<'gcc> { let value_type = value.get_type(); if self.is_native_int_type_or_bool(dest_typ) { return self.context.new_cast(None, value, dest_typ); } debug_assert!(value_type.dyncast_array().is_some()); - let name_suffix = - match self.type_kind(value_type) { - TypeKind::Float => "sfti", - TypeKind::Double => "dfti", - kind => panic!("cannot cast a {:?} to non-native integer", kind), - }; - let sign = - if signed { - "" - } - else { - "uns" - }; + let name_suffix = match self.type_kind(value_type) { + TypeKind::Float => "sfti", + TypeKind::Double => "dfti", + kind => panic!("cannot cast a {:?} to non-native integer", kind), + }; + let sign = if signed { "" } else { "uns" }; let func_name = format!("__fix{}{}", sign, name_suffix); let param = self.context.new_parameter(None, value_type, "n"); - let func = self.context.new_function(None, FunctionType::Extern, dest_typ, &[param], func_name, false); + let func = self.context.new_function( + None, + FunctionType::Extern, + dest_typ, + &[param], + func_name, + false, + ); self.context.new_call(None, func, &[value]) } @@ -823,47 +950,54 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { self.float_to_int_cast(true, value, dest_typ) } - pub fn gcc_float_to_uint_cast(&self, value: RValue<'gcc>, dest_typ: Type<'gcc>) -> RValue<'gcc> { + pub fn gcc_float_to_uint_cast( + &self, + value: RValue<'gcc>, + dest_typ: Type<'gcc>, + ) -> RValue<'gcc> { self.float_to_int_cast(false, value, dest_typ) } fn high(&self, value: RValue<'gcc>) -> RValue<'gcc> { - let index = - match self.sess().target.options.endian { - Endian::Little => 1, - Endian::Big => 0, - }; - self.context.new_array_access(None, value, self.context.new_rvalue_from_int(self.int_type, index)) + let index = match self.sess().target.options.endian { + Endian::Little => 1, + Endian::Big => 0, + }; + self.context + .new_array_access(None, value, self.context.new_rvalue_from_int(self.int_type, index)) .to_rvalue() } fn low(&self, value: RValue<'gcc>) -> RValue<'gcc> { - let index = - match self.sess().target.options.endian { - Endian::Little => 0, - Endian::Big => 1, - }; - self.context.new_array_access(None, value, self.context.new_rvalue_from_int(self.int_type, index)) + let index = match self.sess().target.options.endian { + Endian::Little => 0, + Endian::Big => 1, + }; + self.context + .new_array_access(None, value, self.context.new_rvalue_from_int(self.int_type, index)) .to_rvalue() } - fn from_low_high_rvalues(&self, typ: Type<'gcc>, low: RValue<'gcc>, high: RValue<'gcc>) -> RValue<'gcc> { - let (first, last) = - match self.sess().target.options.endian { - Endian::Little => (low, high), - Endian::Big => (high, low), - }; + fn from_low_high_rvalues( + &self, + typ: Type<'gcc>, + low: RValue<'gcc>, + high: RValue<'gcc>, + ) -> RValue<'gcc> { + let (first, last) = match self.sess().target.options.endian { + Endian::Little => (low, high), + Endian::Big => (high, low), + }; let values = [first, last]; self.context.new_array_constructor(None, typ, &values) } fn from_low_high(&self, typ: Type<'gcc>, low: i64, high: i64) -> RValue<'gcc> { - let (first, last) = - match self.sess().target.options.endian { - Endian::Little => (low, high), - Endian::Big => (high, low), - }; + let (first, last) = match self.sess().target.options.endian { + Endian::Little => (low, high), + Endian::Big => (high, low), + }; let native_int_type = typ.dyncast_array().expect("get element type"); let values = [ diff --git a/src/intrinsic/archs.rs b/src/intrinsic/archs.rs index 15d67385c3e98..c4ae1751fa05a 100644 --- a/src/intrinsic/archs.rs +++ b/src/intrinsic/archs.rs @@ -151,8 +151,10 @@ match name { "llvm.amdgcn.msad.u8" => "__builtin_amdgcn_msad_u8", "llvm.amdgcn.perm" => "__builtin_amdgcn_perm", "llvm.amdgcn.permlane16" => "__builtin_amdgcn_permlane16", + "llvm.amdgcn.permlane16.var" => "__builtin_amdgcn_permlane16_var", "llvm.amdgcn.permlane64" => "__builtin_amdgcn_permlane64", "llvm.amdgcn.permlanex16" => "__builtin_amdgcn_permlanex16", + "llvm.amdgcn.permlanex16.var" => "__builtin_amdgcn_permlanex16_var", "llvm.amdgcn.qsad.pk.u16.u8" => "__builtin_amdgcn_qsad_pk_u16_u8", "llvm.amdgcn.queue.ptr" => "__builtin_amdgcn_queue_ptr", "llvm.amdgcn.rcp.legacy" => "__builtin_amdgcn_rcp_legacy", @@ -160,11 +162,20 @@ match name { "llvm.amdgcn.readlane" => "__builtin_amdgcn_readlane", "llvm.amdgcn.rsq.legacy" => "__builtin_amdgcn_rsq_legacy", "llvm.amdgcn.s.barrier" => "__builtin_amdgcn_s_barrier", + "llvm.amdgcn.s.barrier.init" => "__builtin_amdgcn_s_barrier_init", + "llvm.amdgcn.s.barrier.join" => "__builtin_amdgcn_s_barrier_join", + "llvm.amdgcn.s.barrier.leave" => "__builtin_amdgcn_s_barrier_leave", + "llvm.amdgcn.s.barrier.signal" => "__builtin_amdgcn_s_barrier_signal", + "llvm.amdgcn.s.barrier.signal.isfirst" => "__builtin_amdgcn_s_barrier_signal_isfirst", + "llvm.amdgcn.s.barrier.signal.isfirst.var" => "__builtin_amdgcn_s_barrier_signal_isfirst_var", + "llvm.amdgcn.s.barrier.signal.var" => "__builtin_amdgcn_s_barrier_signal_var", + "llvm.amdgcn.s.barrier.wait" => "__builtin_amdgcn_s_barrier_wait", "llvm.amdgcn.s.dcache.inv" => "__builtin_amdgcn_s_dcache_inv", "llvm.amdgcn.s.dcache.inv.vol" => "__builtin_amdgcn_s_dcache_inv_vol", "llvm.amdgcn.s.dcache.wb" => "__builtin_amdgcn_s_dcache_wb", "llvm.amdgcn.s.dcache.wb.vol" => "__builtin_amdgcn_s_dcache_wb_vol", "llvm.amdgcn.s.decperflevel" => "__builtin_amdgcn_s_decperflevel", + "llvm.amdgcn.s.get.barrier.state" => "__builtin_amdgcn_s_get_barrier_state", "llvm.amdgcn.s.get.waveid.in.workgroup" => "__builtin_amdgcn_s_get_waveid_in_workgroup", "llvm.amdgcn.s.getpc" => "__builtin_amdgcn_s_getpc", "llvm.amdgcn.s.getreg" => "__builtin_amdgcn_s_getreg", @@ -176,8 +187,10 @@ match name { "llvm.amdgcn.s.setprio" => "__builtin_amdgcn_s_setprio", "llvm.amdgcn.s.setreg" => "__builtin_amdgcn_s_setreg", "llvm.amdgcn.s.sleep" => "__builtin_amdgcn_s_sleep", + "llvm.amdgcn.s.sleep.var" => "__builtin_amdgcn_s_sleep_var", "llvm.amdgcn.s.wait.event.export.ready" => "__builtin_amdgcn_s_wait_event_export_ready", "llvm.amdgcn.s.waitcnt" => "__builtin_amdgcn_s_waitcnt", + "llvm.amdgcn.s.wakeup.barrier" => "__builtin_amdgcn_s_wakeup_barrier", "llvm.amdgcn.sad.hi.u8" => "__builtin_amdgcn_sad_hi_u8", "llvm.amdgcn.sad.u16" => "__builtin_amdgcn_sad_u16", "llvm.amdgcn.sad.u8" => "__builtin_amdgcn_sad_u8", @@ -314,6 +327,8 @@ match name { // bpf "llvm.bpf.btf.type.id" => "__builtin_bpf_btf_type_id", "llvm.bpf.compare" => "__builtin_bpf_compare", + "llvm.bpf.getelementptr.and.load" => "__builtin_bpf_getelementptr_and_load", + "llvm.bpf.getelementptr.and.store" => "__builtin_bpf_getelementptr_and_store", "llvm.bpf.load.byte" => "__builtin_bpf_load_byte", "llvm.bpf.load.half" => "__builtin_bpf_load_half", "llvm.bpf.load.word" => "__builtin_bpf_load_word", @@ -5776,14 +5791,6 @@ match name { "llvm.s390.verimf" => "__builtin_s390_verimf", "llvm.s390.verimg" => "__builtin_s390_verimg", "llvm.s390.verimh" => "__builtin_s390_verimh", - "llvm.s390.verllb" => "__builtin_s390_verllb", - "llvm.s390.verllf" => "__builtin_s390_verllf", - "llvm.s390.verllg" => "__builtin_s390_verllg", - "llvm.s390.verllh" => "__builtin_s390_verllh", - "llvm.s390.verllvb" => "__builtin_s390_verllvb", - "llvm.s390.verllvf" => "__builtin_s390_verllvf", - "llvm.s390.verllvg" => "__builtin_s390_verllvg", - "llvm.s390.verllvh" => "__builtin_s390_verllvh", "llvm.s390.vfaeb" => "__builtin_s390_vfaeb", "llvm.s390.vfaef" => "__builtin_s390_vfaef", "llvm.s390.vfaeh" => "__builtin_s390_vfaeh", @@ -5815,7 +5822,7 @@ match name { "llvm.s390.vistrh" => "__builtin_s390_vistrh", "llvm.s390.vlbb" => "__builtin_s390_vlbb", "llvm.s390.vll" => "__builtin_s390_vll", - "llvm.s390.vlrl" => "__builtin_s390_vlrl", + "llvm.s390.vlrl" => "__builtin_s390_vlrlr", "llvm.s390.vmaeb" => "__builtin_s390_vmaeb", "llvm.s390.vmaef" => "__builtin_s390_vmaef", "llvm.s390.vmaeh" => "__builtin_s390_vmaeh", @@ -5885,7 +5892,7 @@ match name { "llvm.s390.vstrczb" => "__builtin_s390_vstrczb", "llvm.s390.vstrczf" => "__builtin_s390_vstrczf", "llvm.s390.vstrczh" => "__builtin_s390_vstrczh", - "llvm.s390.vstrl" => "__builtin_s390_vstrl", + "llvm.s390.vstrl" => "__builtin_s390_vstrlr", "llvm.s390.vsumb" => "__builtin_s390_vsumb", "llvm.s390.vsumgf" => "__builtin_s390_vsumgf", "llvm.s390.vsumgh" => "__builtin_s390_vsumgh", diff --git a/src/intrinsic/llvm.rs b/src/intrinsic/llvm.rs index 35eb4a11005b9..ce8dee69a9886 100644 --- a/src/intrinsic/llvm.rs +++ b/src/intrinsic/llvm.rs @@ -3,94 +3,185 @@ use std::borrow::Cow; use gccjit::{Function, FunctionPtrType, RValue, ToRValue, UnaryOp}; use rustc_codegen_ssa::traits::BuilderMethods; -use crate::{context::CodegenCx, builder::Builder}; +use crate::{builder::Builder, context::CodegenCx}; -pub fn adjust_intrinsic_arguments<'a, 'b, 'gcc, 'tcx>(builder: &Builder<'a, 'gcc, 'tcx>, gcc_func: FunctionPtrType<'gcc>, mut args: Cow<'b, [RValue<'gcc>]>, func_name: &str, original_function_name: Option<&String>) -> Cow<'b, [RValue<'gcc>]> { +pub fn adjust_intrinsic_arguments<'a, 'b, 'gcc, 'tcx>( + builder: &Builder<'a, 'gcc, 'tcx>, + gcc_func: FunctionPtrType<'gcc>, + mut args: Cow<'b, [RValue<'gcc>]>, + func_name: &str, + original_function_name: Option<&String>, +) -> Cow<'b, [RValue<'gcc>]> { // Some LLVM intrinsics do not map 1-to-1 to GCC intrinsics, so we add the missing // arguments here. if gcc_func.get_param_count() != args.len() { match &*func_name { // NOTE: the following intrinsics have a different number of parameters in LLVM and GCC. - "__builtin_ia32_prold512_mask" | "__builtin_ia32_pmuldq512_mask" | "__builtin_ia32_pmuludq512_mask" - | "__builtin_ia32_pmaxsd512_mask" | "__builtin_ia32_pmaxsq512_mask" | "__builtin_ia32_pmaxsq256_mask" - | "__builtin_ia32_pmaxsq128_mask" | "__builtin_ia32_pmaxud512_mask" | "__builtin_ia32_pmaxuq512_mask" - | "__builtin_ia32_pminsd512_mask" | "__builtin_ia32_pminsq512_mask" | "__builtin_ia32_pminsq256_mask" - | "__builtin_ia32_pminsq128_mask" | "__builtin_ia32_pminud512_mask" | "__builtin_ia32_pminuq512_mask" - | "__builtin_ia32_prolq512_mask" | "__builtin_ia32_prorq512_mask" | "__builtin_ia32_pslldi512_mask" - | "__builtin_ia32_psrldi512_mask" | "__builtin_ia32_psllqi512_mask" | "__builtin_ia32_psrlqi512_mask" - | "__builtin_ia32_pslld512_mask" | "__builtin_ia32_psrld512_mask" | "__builtin_ia32_psllq512_mask" - | "__builtin_ia32_psrlq512_mask" | "__builtin_ia32_psrad512_mask" | "__builtin_ia32_psraq512_mask" - | "__builtin_ia32_psradi512_mask" | "__builtin_ia32_psraqi512_mask" | "__builtin_ia32_psrav16si_mask" - | "__builtin_ia32_psrav8di_mask" | "__builtin_ia32_prolvd512_mask" | "__builtin_ia32_prorvd512_mask" - | "__builtin_ia32_prolvq512_mask" | "__builtin_ia32_prorvq512_mask" | "__builtin_ia32_psllv16si_mask" - | "__builtin_ia32_psrlv16si_mask" | "__builtin_ia32_psllv8di_mask" | "__builtin_ia32_psrlv8di_mask" - | "__builtin_ia32_permvarsi512_mask" | "__builtin_ia32_vpermilvarps512_mask" - | "__builtin_ia32_vpermilvarpd512_mask" | "__builtin_ia32_permvardi512_mask" - | "__builtin_ia32_permvarsf512_mask" | "__builtin_ia32_permvarqi512_mask" - | "__builtin_ia32_permvarqi256_mask" | "__builtin_ia32_permvarqi128_mask" - | "__builtin_ia32_vpmultishiftqb512_mask" | "__builtin_ia32_vpmultishiftqb256_mask" - | "__builtin_ia32_vpmultishiftqb128_mask" - => { + "__builtin_ia32_prold512_mask" + | "__builtin_ia32_pmuldq512_mask" + | "__builtin_ia32_pmuludq512_mask" + | "__builtin_ia32_pmaxsd512_mask" + | "__builtin_ia32_pmaxsq512_mask" + | "__builtin_ia32_pmaxsq256_mask" + | "__builtin_ia32_pmaxsq128_mask" + | "__builtin_ia32_pmaxud512_mask" + | "__builtin_ia32_pmaxuq512_mask" + | "__builtin_ia32_pminsd512_mask" + | "__builtin_ia32_pminsq512_mask" + | "__builtin_ia32_pminsq256_mask" + | "__builtin_ia32_pminsq128_mask" + | "__builtin_ia32_pminud512_mask" + | "__builtin_ia32_pminuq512_mask" + | "__builtin_ia32_prolq512_mask" + | "__builtin_ia32_prorq512_mask" + | "__builtin_ia32_pslldi512_mask" + | "__builtin_ia32_psrldi512_mask" + | "__builtin_ia32_psllqi512_mask" + | "__builtin_ia32_psrlqi512_mask" + | "__builtin_ia32_pslld512_mask" + | "__builtin_ia32_psrld512_mask" + | "__builtin_ia32_psllq512_mask" + | "__builtin_ia32_psrlq512_mask" + | "__builtin_ia32_psrad512_mask" + | "__builtin_ia32_psraq512_mask" + | "__builtin_ia32_psradi512_mask" + | "__builtin_ia32_psraqi512_mask" + | "__builtin_ia32_psrav16si_mask" + | "__builtin_ia32_psrav8di_mask" + | "__builtin_ia32_prolvd512_mask" + | "__builtin_ia32_prorvd512_mask" + | "__builtin_ia32_prolvq512_mask" + | "__builtin_ia32_prorvq512_mask" + | "__builtin_ia32_psllv16si_mask" + | "__builtin_ia32_psrlv16si_mask" + | "__builtin_ia32_psllv8di_mask" + | "__builtin_ia32_psrlv8di_mask" + | "__builtin_ia32_permvarsi512_mask" + | "__builtin_ia32_vpermilvarps512_mask" + | "__builtin_ia32_vpermilvarpd512_mask" + | "__builtin_ia32_permvardi512_mask" + | "__builtin_ia32_permvarsf512_mask" + | "__builtin_ia32_permvarqi512_mask" + | "__builtin_ia32_permvarqi256_mask" + | "__builtin_ia32_permvarqi128_mask" + | "__builtin_ia32_vpmultishiftqb512_mask" + | "__builtin_ia32_vpmultishiftqb256_mask" + | "__builtin_ia32_vpmultishiftqb128_mask" => { let mut new_args = args.to_vec(); let arg3_type = gcc_func.get_param_type(2); - let first_arg = builder.current_func().new_local(None, arg3_type, "undefined_for_intrinsic").to_rvalue(); + let first_arg = builder + .current_func() + .new_local(None, arg3_type, "undefined_for_intrinsic") + .to_rvalue(); new_args.push(first_arg); let arg4_type = gcc_func.get_param_type(3); let minus_one = builder.context.new_rvalue_from_int(arg4_type, -1); new_args.push(minus_one); args = new_args.into(); - }, - "__builtin_ia32_pmaxuq256_mask" | "__builtin_ia32_pmaxuq128_mask" | "__builtin_ia32_pminuq256_mask" - | "__builtin_ia32_pminuq128_mask" | "__builtin_ia32_prold256_mask" | "__builtin_ia32_prold128_mask" - | "__builtin_ia32_prord512_mask" | "__builtin_ia32_prord256_mask" | "__builtin_ia32_prord128_mask" - | "__builtin_ia32_prolq256_mask" | "__builtin_ia32_prolq128_mask" | "__builtin_ia32_prorq256_mask" - | "__builtin_ia32_prorq128_mask" | "__builtin_ia32_psraq256_mask" | "__builtin_ia32_psraq128_mask" - | "__builtin_ia32_psraqi256_mask" | "__builtin_ia32_psraqi128_mask" | "__builtin_ia32_psravq256_mask" - | "__builtin_ia32_psravq128_mask" | "__builtin_ia32_prolvd256_mask" | "__builtin_ia32_prolvd128_mask" - | "__builtin_ia32_prorvd256_mask" | "__builtin_ia32_prorvd128_mask" | "__builtin_ia32_prolvq256_mask" - | "__builtin_ia32_prolvq128_mask" | "__builtin_ia32_prorvq256_mask" | "__builtin_ia32_prorvq128_mask" - | "__builtin_ia32_permvardi256_mask" | "__builtin_ia32_permvardf512_mask" | "__builtin_ia32_permvardf256_mask" - | "__builtin_ia32_pmulhuw512_mask" | "__builtin_ia32_pmulhw512_mask" | "__builtin_ia32_pmulhrsw512_mask" - | "__builtin_ia32_pmaxuw512_mask" | "__builtin_ia32_pmaxub512_mask" | "__builtin_ia32_pmaxsw512_mask" - | "__builtin_ia32_pmaxsb512_mask" | "__builtin_ia32_pminuw512_mask" | "__builtin_ia32_pminub512_mask" - | "__builtin_ia32_pminsw512_mask" | "__builtin_ia32_pminsb512_mask" - | "__builtin_ia32_pmaddwd512_mask" | "__builtin_ia32_pmaddubsw512_mask" | "__builtin_ia32_packssdw512_mask" - | "__builtin_ia32_packsswb512_mask" | "__builtin_ia32_packusdw512_mask" | "__builtin_ia32_packuswb512_mask" - | "__builtin_ia32_pavgw512_mask" | "__builtin_ia32_pavgb512_mask" | "__builtin_ia32_psllw512_mask" - | "__builtin_ia32_psllwi512_mask" | "__builtin_ia32_psllv32hi_mask" | "__builtin_ia32_psrlw512_mask" - | "__builtin_ia32_psrlwi512_mask" | "__builtin_ia32_psllv16hi_mask" | "__builtin_ia32_psllv8hi_mask" - | "__builtin_ia32_psrlv32hi_mask" | "__builtin_ia32_psraw512_mask" | "__builtin_ia32_psrawi512_mask" - | "__builtin_ia32_psrlv16hi_mask" | "__builtin_ia32_psrlv8hi_mask" | "__builtin_ia32_psrav32hi_mask" - | "__builtin_ia32_permvarhi512_mask" | "__builtin_ia32_pshufb512_mask" | "__builtin_ia32_psrav16hi_mask" - | "__builtin_ia32_psrav8hi_mask" | "__builtin_ia32_permvarhi256_mask" | "__builtin_ia32_permvarhi128_mask" - => { + } + "__builtin_ia32_pmaxuq256_mask" + | "__builtin_ia32_pmaxuq128_mask" + | "__builtin_ia32_pminuq256_mask" + | "__builtin_ia32_pminuq128_mask" + | "__builtin_ia32_prold256_mask" + | "__builtin_ia32_prold128_mask" + | "__builtin_ia32_prord512_mask" + | "__builtin_ia32_prord256_mask" + | "__builtin_ia32_prord128_mask" + | "__builtin_ia32_prolq256_mask" + | "__builtin_ia32_prolq128_mask" + | "__builtin_ia32_prorq256_mask" + | "__builtin_ia32_prorq128_mask" + | "__builtin_ia32_psraq256_mask" + | "__builtin_ia32_psraq128_mask" + | "__builtin_ia32_psraqi256_mask" + | "__builtin_ia32_psraqi128_mask" + | "__builtin_ia32_psravq256_mask" + | "__builtin_ia32_psravq128_mask" + | "__builtin_ia32_prolvd256_mask" + | "__builtin_ia32_prolvd128_mask" + | "__builtin_ia32_prorvd256_mask" + | "__builtin_ia32_prorvd128_mask" + | "__builtin_ia32_prolvq256_mask" + | "__builtin_ia32_prolvq128_mask" + | "__builtin_ia32_prorvq256_mask" + | "__builtin_ia32_prorvq128_mask" + | "__builtin_ia32_permvardi256_mask" + | "__builtin_ia32_permvardf512_mask" + | "__builtin_ia32_permvardf256_mask" + | "__builtin_ia32_pmulhuw512_mask" + | "__builtin_ia32_pmulhw512_mask" + | "__builtin_ia32_pmulhrsw512_mask" + | "__builtin_ia32_pmaxuw512_mask" + | "__builtin_ia32_pmaxub512_mask" + | "__builtin_ia32_pmaxsw512_mask" + | "__builtin_ia32_pmaxsb512_mask" + | "__builtin_ia32_pminuw512_mask" + | "__builtin_ia32_pminub512_mask" + | "__builtin_ia32_pminsw512_mask" + | "__builtin_ia32_pminsb512_mask" + | "__builtin_ia32_pmaddwd512_mask" + | "__builtin_ia32_pmaddubsw512_mask" + | "__builtin_ia32_packssdw512_mask" + | "__builtin_ia32_packsswb512_mask" + | "__builtin_ia32_packusdw512_mask" + | "__builtin_ia32_packuswb512_mask" + | "__builtin_ia32_pavgw512_mask" + | "__builtin_ia32_pavgb512_mask" + | "__builtin_ia32_psllw512_mask" + | "__builtin_ia32_psllwi512_mask" + | "__builtin_ia32_psllv32hi_mask" + | "__builtin_ia32_psrlw512_mask" + | "__builtin_ia32_psrlwi512_mask" + | "__builtin_ia32_psllv16hi_mask" + | "__builtin_ia32_psllv8hi_mask" + | "__builtin_ia32_psrlv32hi_mask" + | "__builtin_ia32_psraw512_mask" + | "__builtin_ia32_psrawi512_mask" + | "__builtin_ia32_psrlv16hi_mask" + | "__builtin_ia32_psrlv8hi_mask" + | "__builtin_ia32_psrav32hi_mask" + | "__builtin_ia32_permvarhi512_mask" + | "__builtin_ia32_pshufb512_mask" + | "__builtin_ia32_psrav16hi_mask" + | "__builtin_ia32_psrav8hi_mask" + | "__builtin_ia32_permvarhi256_mask" + | "__builtin_ia32_permvarhi128_mask" => { let mut new_args = args.to_vec(); let arg3_type = gcc_func.get_param_type(2); let vector_type = arg3_type.dyncast_vector().expect("vector type"); let zero = builder.context.new_rvalue_zero(vector_type.get_element_type()); let num_units = vector_type.get_num_units(); - let first_arg = builder.context.new_rvalue_from_vector(None, arg3_type, &vec![zero; num_units]); + let first_arg = + builder.context.new_rvalue_from_vector(None, arg3_type, &vec![zero; num_units]); new_args.push(first_arg); let arg4_type = gcc_func.get_param_type(3); let minus_one = builder.context.new_rvalue_from_int(arg4_type, -1); new_args.push(minus_one); args = new_args.into(); - }, - "__builtin_ia32_dbpsadbw512_mask" | "__builtin_ia32_dbpsadbw256_mask" | "__builtin_ia32_dbpsadbw128_mask" => { + } + "__builtin_ia32_dbpsadbw512_mask" + | "__builtin_ia32_dbpsadbw256_mask" + | "__builtin_ia32_dbpsadbw128_mask" => { let mut new_args = args.to_vec(); let arg4_type = gcc_func.get_param_type(3); let vector_type = arg4_type.dyncast_vector().expect("vector type"); let zero = builder.context.new_rvalue_zero(vector_type.get_element_type()); let num_units = vector_type.get_num_units(); - let first_arg = builder.context.new_rvalue_from_vector(None, arg4_type, &vec![zero; num_units]); + let first_arg = + builder.context.new_rvalue_from_vector(None, arg4_type, &vec![zero; num_units]); new_args.push(first_arg); let arg5_type = gcc_func.get_param_type(4); let minus_one = builder.context.new_rvalue_from_int(arg5_type, -1); new_args.push(minus_one); args = new_args.into(); - }, - "__builtin_ia32_vplzcntd_512_mask" | "__builtin_ia32_vplzcntd_256_mask" | "__builtin_ia32_vplzcntd_128_mask" - | "__builtin_ia32_vplzcntq_512_mask" | "__builtin_ia32_vplzcntq_256_mask" | "__builtin_ia32_vplzcntq_128_mask" => { + } + "__builtin_ia32_vplzcntd_512_mask" + | "__builtin_ia32_vplzcntd_256_mask" + | "__builtin_ia32_vplzcntd_128_mask" + | "__builtin_ia32_vplzcntq_512_mask" + | "__builtin_ia32_vplzcntq_256_mask" + | "__builtin_ia32_vplzcntq_128_mask" => { let mut new_args = args.to_vec(); // Remove last arg as it doesn't seem to be used in GCC and is always false. new_args.pop(); @@ -98,37 +189,45 @@ pub fn adjust_intrinsic_arguments<'a, 'b, 'gcc, 'tcx>(builder: &Builder<'a, 'gcc let vector_type = arg2_type.dyncast_vector().expect("vector type"); let zero = builder.context.new_rvalue_zero(vector_type.get_element_type()); let num_units = vector_type.get_num_units(); - let first_arg = builder.context.new_rvalue_from_vector(None, arg2_type, &vec![zero; num_units]); + let first_arg = + builder.context.new_rvalue_from_vector(None, arg2_type, &vec![zero; num_units]); new_args.push(first_arg); let arg3_type = gcc_func.get_param_type(2); let minus_one = builder.context.new_rvalue_from_int(arg3_type, -1); new_args.push(minus_one); args = new_args.into(); - }, - "__builtin_ia32_vpconflictsi_512_mask" | "__builtin_ia32_vpconflictsi_256_mask" - | "__builtin_ia32_vpconflictsi_128_mask" | "__builtin_ia32_vpconflictdi_512_mask" - | "__builtin_ia32_vpconflictdi_256_mask" | "__builtin_ia32_vpconflictdi_128_mask" => { + } + "__builtin_ia32_vpconflictsi_512_mask" + | "__builtin_ia32_vpconflictsi_256_mask" + | "__builtin_ia32_vpconflictsi_128_mask" + | "__builtin_ia32_vpconflictdi_512_mask" + | "__builtin_ia32_vpconflictdi_256_mask" + | "__builtin_ia32_vpconflictdi_128_mask" => { let mut new_args = args.to_vec(); let arg2_type = gcc_func.get_param_type(1); let vector_type = arg2_type.dyncast_vector().expect("vector type"); let zero = builder.context.new_rvalue_zero(vector_type.get_element_type()); let num_units = vector_type.get_num_units(); - let first_arg = builder.context.new_rvalue_from_vector(None, arg2_type, &vec![zero; num_units]); + let first_arg = + builder.context.new_rvalue_from_vector(None, arg2_type, &vec![zero; num_units]); new_args.push(first_arg); let arg3_type = gcc_func.get_param_type(2); let minus_one = builder.context.new_rvalue_from_int(arg3_type, -1); new_args.push(minus_one); args = new_args.into(); - }, - "__builtin_ia32_pternlogd512_mask" | "__builtin_ia32_pternlogd256_mask" - | "__builtin_ia32_pternlogd128_mask" | "__builtin_ia32_pternlogq512_mask" - | "__builtin_ia32_pternlogq256_mask" | "__builtin_ia32_pternlogq128_mask" => { + } + "__builtin_ia32_pternlogd512_mask" + | "__builtin_ia32_pternlogd256_mask" + | "__builtin_ia32_pternlogd128_mask" + | "__builtin_ia32_pternlogq512_mask" + | "__builtin_ia32_pternlogq256_mask" + | "__builtin_ia32_pternlogq128_mask" => { let mut new_args = args.to_vec(); let arg5_type = gcc_func.get_param_type(4); let minus_one = builder.context.new_rvalue_from_int(arg5_type, -1); new_args.push(minus_one); args = new_args.into(); - }, + } "__builtin_ia32_vfmaddps512_mask" | "__builtin_ia32_vfmaddpd512_mask" => { let mut new_args = args.to_vec(); @@ -154,24 +253,33 @@ pub fn adjust_intrinsic_arguments<'a, 'b, 'gcc, 'tcx>(builder: &Builder<'a, 'gcc } args = new_args.into(); - }, - "__builtin_ia32_addps512_mask" | "__builtin_ia32_addpd512_mask" - | "__builtin_ia32_subps512_mask" | "__builtin_ia32_subpd512_mask" - | "__builtin_ia32_mulps512_mask" | "__builtin_ia32_mulpd512_mask" - | "__builtin_ia32_divps512_mask" | "__builtin_ia32_divpd512_mask" - | "__builtin_ia32_maxps512_mask" | "__builtin_ia32_maxpd512_mask" - | "__builtin_ia32_minps512_mask" | "__builtin_ia32_minpd512_mask" => { + } + "__builtin_ia32_addps512_mask" + | "__builtin_ia32_addpd512_mask" + | "__builtin_ia32_subps512_mask" + | "__builtin_ia32_subpd512_mask" + | "__builtin_ia32_mulps512_mask" + | "__builtin_ia32_mulpd512_mask" + | "__builtin_ia32_divps512_mask" + | "__builtin_ia32_divpd512_mask" + | "__builtin_ia32_maxps512_mask" + | "__builtin_ia32_maxpd512_mask" + | "__builtin_ia32_minps512_mask" + | "__builtin_ia32_minpd512_mask" => { let mut new_args = args.to_vec(); let last_arg = new_args.pop().expect("last arg"); let arg3_type = gcc_func.get_param_type(2); - let undefined = builder.current_func().new_local(None, arg3_type, "undefined_for_intrinsic").to_rvalue(); + let undefined = builder + .current_func() + .new_local(None, arg3_type, "undefined_for_intrinsic") + .to_rvalue(); new_args.push(undefined); let arg4_type = gcc_func.get_param_type(3); let minus_one = builder.context.new_rvalue_from_int(arg4_type, -1); new_args.push(minus_one); new_args.push(last_arg); args = new_args.into(); - }, + } "__builtin_ia32_vfmaddsubps512_mask" | "__builtin_ia32_vfmaddsubpd512_mask" => { let mut new_args = args.to_vec(); let last_arg = new_args.pop().expect("last arg"); @@ -180,54 +288,72 @@ pub fn adjust_intrinsic_arguments<'a, 'b, 'gcc, 'tcx>(builder: &Builder<'a, 'gcc new_args.push(minus_one); new_args.push(last_arg); args = new_args.into(); - }, - "__builtin_ia32_vpermi2vard512_mask" | "__builtin_ia32_vpermi2vard256_mask" - | "__builtin_ia32_vpermi2vard128_mask" | "__builtin_ia32_vpermi2varq512_mask" - | "__builtin_ia32_vpermi2varq256_mask" | "__builtin_ia32_vpermi2varq128_mask" - | "__builtin_ia32_vpermi2varps512_mask" | "__builtin_ia32_vpermi2varps256_mask" - | "__builtin_ia32_vpermi2varps128_mask" | "__builtin_ia32_vpermi2varpd512_mask" - | "__builtin_ia32_vpermi2varpd256_mask" | "__builtin_ia32_vpermi2varpd128_mask" | "__builtin_ia32_vpmadd52huq512_mask" - | "__builtin_ia32_vpmadd52luq512_mask" | "__builtin_ia32_vpmadd52huq256_mask" | "__builtin_ia32_vpmadd52luq256_mask" - | "__builtin_ia32_vpmadd52huq128_mask" - => { + } + "__builtin_ia32_vpermi2vard512_mask" + | "__builtin_ia32_vpermi2vard256_mask" + | "__builtin_ia32_vpermi2vard128_mask" + | "__builtin_ia32_vpermi2varq512_mask" + | "__builtin_ia32_vpermi2varq256_mask" + | "__builtin_ia32_vpermi2varq128_mask" + | "__builtin_ia32_vpermi2varps512_mask" + | "__builtin_ia32_vpermi2varps256_mask" + | "__builtin_ia32_vpermi2varps128_mask" + | "__builtin_ia32_vpermi2varpd512_mask" + | "__builtin_ia32_vpermi2varpd256_mask" + | "__builtin_ia32_vpermi2varpd128_mask" + | "__builtin_ia32_vpmadd52huq512_mask" + | "__builtin_ia32_vpmadd52luq512_mask" + | "__builtin_ia32_vpmadd52huq256_mask" + | "__builtin_ia32_vpmadd52luq256_mask" + | "__builtin_ia32_vpmadd52huq128_mask" => { let mut new_args = args.to_vec(); let arg4_type = gcc_func.get_param_type(3); let minus_one = builder.context.new_rvalue_from_int(arg4_type, -1); new_args.push(minus_one); args = new_args.into(); - }, - "__builtin_ia32_cvtdq2ps512_mask" | "__builtin_ia32_cvtudq2ps512_mask" - | "__builtin_ia32_sqrtps512_mask" | "__builtin_ia32_sqrtpd512_mask" => { + } + "__builtin_ia32_cvtdq2ps512_mask" + | "__builtin_ia32_cvtudq2ps512_mask" + | "__builtin_ia32_sqrtps512_mask" + | "__builtin_ia32_sqrtpd512_mask" => { let mut new_args = args.to_vec(); let last_arg = new_args.pop().expect("last arg"); let arg2_type = gcc_func.get_param_type(1); - let undefined = builder.current_func().new_local(None, arg2_type, "undefined_for_intrinsic").to_rvalue(); + let undefined = builder + .current_func() + .new_local(None, arg2_type, "undefined_for_intrinsic") + .to_rvalue(); new_args.push(undefined); let arg3_type = gcc_func.get_param_type(2); let minus_one = builder.context.new_rvalue_from_int(arg3_type, -1); new_args.push(minus_one); new_args.push(last_arg); args = new_args.into(); - }, + } "__builtin_ia32_stmxcsr" => { args = vec![].into(); - }, - "__builtin_ia32_addcarryx_u64" | "__builtin_ia32_sbb_u64" | "__builtin_ia32_addcarryx_u32" | "__builtin_ia32_sbb_u32" => { + } + "__builtin_ia32_addcarryx_u64" + | "__builtin_ia32_sbb_u64" + | "__builtin_ia32_addcarryx_u32" + | "__builtin_ia32_sbb_u32" => { let mut new_args = args.to_vec(); let arg2_type = gcc_func.get_param_type(1); let variable = builder.current_func().new_local(None, arg2_type, "addcarryResult"); new_args.push(variable.get_address(None)); args = new_args.into(); - }, - "__builtin_ia32_vpermt2varqi512_mask" | "__builtin_ia32_vpermt2varqi256_mask" - | "__builtin_ia32_vpermt2varqi128_mask" | "__builtin_ia32_vpermt2varhi512_mask" - | "__builtin_ia32_vpermt2varhi256_mask" | "__builtin_ia32_vpermt2varhi128_mask" - => { + } + "__builtin_ia32_vpermt2varqi512_mask" + | "__builtin_ia32_vpermt2varqi256_mask" + | "__builtin_ia32_vpermt2varqi128_mask" + | "__builtin_ia32_vpermt2varhi512_mask" + | "__builtin_ia32_vpermt2varhi256_mask" + | "__builtin_ia32_vpermt2varhi128_mask" => { let new_args = args.to_vec(); let arg4_type = gcc_func.get_param_type(3); let minus_one = builder.context.new_rvalue_from_int(arg4_type, -1); args = vec![new_args[1], new_args[0], new_args[2], minus_one].into(); - }, + } "__builtin_ia32_xrstor" | "__builtin_ia32_xsavec" => { let new_args = args.to_vec(); let thirty_two = builder.context.new_rvalue_from_int(new_args[1].get_type(), 32); @@ -235,22 +361,25 @@ pub fn adjust_intrinsic_arguments<'a, 'b, 'gcc, 'tcx>(builder: &Builder<'a, 'gcc 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(); - }, + } // These builtins are sent one more argument than needed. "__builtin_prefetch" => { let mut new_args = args.to_vec(); new_args.pop(); args = new_args.into(); - }, + } // The GCC version returns one value of the tuple through a pointer. "__builtin_ia32_rdrand64_step" => { - let arg = builder.current_func().new_local(None, builder.ulonglong_type, "return_rdrand_arg"); + let arg = builder.current_func().new_local( + None, + builder.ulonglong_type, + "return_rdrand_arg", + ); args = vec![arg.get_address(None)].into(); - }, + } _ => (), } - } - else { + } else { match &*func_name { "__builtin_ia32_rndscaless_mask_round" | "__builtin_ia32_rndscalesd_mask_round" => { let new_args = args.to_vec(); @@ -259,10 +388,10 @@ pub fn adjust_intrinsic_arguments<'a, 'b, 'gcc, 'tcx>(builder: &Builder<'a, 'gcc let arg4_type = gcc_func.get_param_type(3); let arg4 = builder.context.new_bitcast(None, new_args[2], arg4_type); args = vec![new_args[0], new_args[1], arg3, arg4, new_args[3], new_args[5]].into(); - }, + } // NOTE: the LLVM intrinsic receives 3 floats, but the GCC builtin requires 3 vectors. // FIXME: the intrinsics like _mm_mask_fmadd_sd should probably directly call the GCC - // instrinsic to avoid this. + // intrinsic to avoid this. "__builtin_ia32_vfmaddss3_round" => { let new_args = args.to_vec(); let arg1_type = gcc_func.get_param_type(0); @@ -272,7 +401,7 @@ pub fn adjust_intrinsic_arguments<'a, 'b, 'gcc, 'tcx>(builder: &Builder<'a, 'gcc let b = builder.context.new_rvalue_from_vector(None, arg2_type, &[new_args[1]; 4]); let c = builder.context.new_rvalue_from_vector(None, arg3_type, &[new_args[2]; 4]); args = vec![a, b, c, new_args[3]].into(); - }, + } "__builtin_ia32_vfmaddsd3_round" => { let new_args = args.to_vec(); let arg1_type = gcc_func.get_param_type(0); @@ -282,25 +411,34 @@ pub fn adjust_intrinsic_arguments<'a, 'b, 'gcc, 'tcx>(builder: &Builder<'a, 'gcc let b = builder.context.new_rvalue_from_vector(None, arg2_type, &[new_args[1]; 2]); let c = builder.context.new_rvalue_from_vector(None, arg3_type, &[new_args[2]; 2]); args = vec![a, b, c, new_args[3]].into(); - }, - "__builtin_ia32_vfmaddsubpd256" | "__builtin_ia32_vfmaddsubps" | "__builtin_ia32_vfmaddsubps256" - | "__builtin_ia32_vfmaddsubpd" => { + } + "__builtin_ia32_vfmaddsubpd256" + | "__builtin_ia32_vfmaddsubps" + | "__builtin_ia32_vfmaddsubps256" + | "__builtin_ia32_vfmaddsubpd" => { if let Some(original_function_name) = original_function_name { match &**original_function_name { - "llvm.x86.fma.vfmsubadd.pd.256" | "llvm.x86.fma.vfmsubadd.ps" | "llvm.x86.fma.vfmsubadd.ps.256" - | "llvm.x86.fma.vfmsubadd.pd" => { + "llvm.x86.fma.vfmsubadd.pd.256" + | "llvm.x86.fma.vfmsubadd.ps" + | "llvm.x86.fma.vfmsubadd.ps.256" + | "llvm.x86.fma.vfmsubadd.pd" => { // NOTE: since both llvm.x86.fma.vfmsubadd.ps and llvm.x86.fma.vfmaddsub.ps maps to // __builtin_ia32_vfmaddsubps, only add minus if this comes from a // subadd LLVM intrinsic, e.g. _mm256_fmsubadd_pd. let mut new_args = args.to_vec(); let arg3 = &mut new_args[2]; - *arg3 = builder.context.new_unary_op(None, UnaryOp::Minus, arg3.get_type(), *arg3); + *arg3 = builder.context.new_unary_op( + None, + UnaryOp::Minus, + arg3.get_type(), + *arg3, + ); args = new_args.into(); - }, + } _ => (), } } - }, + } "__builtin_ia32_ldmxcsr" => { // The builtin __builtin_ia32_ldmxcsr takes an integer value while llvm.x86.sse.ldmxcsr takes a pointer, // so dereference the pointer. @@ -309,23 +447,31 @@ pub fn adjust_intrinsic_arguments<'a, 'b, 'gcc, 'tcx>(builder: &Builder<'a, 'gcc let arg1 = builder.context.new_cast(None, args[0], uint_ptr_type); new_args[0] = arg1.dereference(None).to_rvalue(); args = new_args.into(); - }, - "__builtin_ia32_rcp14sd_mask" | "__builtin_ia32_rcp14ss_mask" | "__builtin_ia32_rsqrt14sd_mask" - | "__builtin_ia32_rsqrt14ss_mask" => { + } + "__builtin_ia32_rcp14sd_mask" + | "__builtin_ia32_rcp14ss_mask" + | "__builtin_ia32_rsqrt14sd_mask" + | "__builtin_ia32_rsqrt14ss_mask" => { let new_args = args.to_vec(); args = vec![new_args[1], new_args[0], new_args[2], new_args[3]].into(); - }, + } "__builtin_ia32_sqrtsd_mask_round" | "__builtin_ia32_sqrtss_mask_round" => { let new_args = args.to_vec(); args = vec![new_args[1], new_args[0], new_args[2], new_args[3], new_args[4]].into(); - }, - "__builtin_ia32_vpshrdv_v8di" | "__builtin_ia32_vpshrdv_v4di" | "__builtin_ia32_vpshrdv_v2di" | - "__builtin_ia32_vpshrdv_v16si" | "__builtin_ia32_vpshrdv_v8si" | "__builtin_ia32_vpshrdv_v4si" | - "__builtin_ia32_vpshrdv_v32hi" | "__builtin_ia32_vpshrdv_v16hi" | "__builtin_ia32_vpshrdv_v8hi" => { + } + "__builtin_ia32_vpshrdv_v8di" + | "__builtin_ia32_vpshrdv_v4di" + | "__builtin_ia32_vpshrdv_v2di" + | "__builtin_ia32_vpshrdv_v16si" + | "__builtin_ia32_vpshrdv_v8si" + | "__builtin_ia32_vpshrdv_v4si" + | "__builtin_ia32_vpshrdv_v32hi" + | "__builtin_ia32_vpshrdv_v16hi" + | "__builtin_ia32_vpshrdv_v8hi" => { // The first two arguments are reversed, compared to LLVM. let new_args = args.to_vec(); args = vec![new_args[1], new_args[0], new_args[2]].into(); - }, + } _ => (), } } @@ -333,16 +479,27 @@ pub fn adjust_intrinsic_arguments<'a, 'b, 'gcc, 'tcx>(builder: &Builder<'a, 'gcc args } -pub fn adjust_intrinsic_return_value<'a, 'gcc, 'tcx>(builder: &Builder<'a, 'gcc, 'tcx>, mut return_value: RValue<'gcc>, func_name: &str, args: &[RValue<'gcc>], args_adjusted: bool, orig_args: &[RValue<'gcc>]) -> RValue<'gcc> { +pub fn adjust_intrinsic_return_value<'a, 'gcc, 'tcx>( + builder: &Builder<'a, 'gcc, 'tcx>, + mut return_value: RValue<'gcc>, + func_name: &str, + args: &[RValue<'gcc>], + args_adjusted: bool, + orig_args: &[RValue<'gcc>], +) -> RValue<'gcc> { match func_name { "__builtin_ia32_vfmaddss3_round" | "__builtin_ia32_vfmaddsd3_round" => { - #[cfg(feature="master")] + #[cfg(feature = "master")] { let zero = builder.context.new_rvalue_zero(builder.int_type); - return_value = builder.context.new_vector_access(None, return_value, zero).to_rvalue(); + return_value = + builder.context.new_vector_access(None, return_value, zero).to_rvalue(); } - }, - "__builtin_ia32_addcarryx_u64" | "__builtin_ia32_sbb_u64" | "__builtin_ia32_addcarryx_u32" | "__builtin_ia32_sbb_u32" => { + } + "__builtin_ia32_addcarryx_u64" + | "__builtin_ia32_sbb_u64" + | "__builtin_ia32_addcarryx_u32" + | "__builtin_ia32_sbb_u32" => { // Both llvm.x86.addcarry.32 and llvm.x86.addcarryx.u32 points to the same GCC builtin, // but only the former requires adjusting the return value. // Those 2 LLVM intrinsics differ by their argument count, that's why we check if the @@ -351,10 +508,16 @@ pub fn adjust_intrinsic_return_value<'a, 'gcc, 'tcx>(builder: &Builder<'a, 'gcc, let last_arg = args.last().expect("last arg"); let field1 = builder.context.new_field(None, builder.u8_type, "carryFlag"); let field2 = builder.context.new_field(None, args[1].get_type(), "carryResult"); - let struct_type = builder.context.new_struct_type(None, "addcarryResult", &[field1, field2]); - return_value = builder.context.new_struct_constructor(None, struct_type.as_type(), None, &[return_value, last_arg.dereference(None).to_rvalue()]); + let struct_type = + builder.context.new_struct_type(None, "addcarryResult", &[field1, field2]); + return_value = builder.context.new_struct_constructor( + None, + struct_type.as_type(), + None, + &[return_value, last_arg.dereference(None).to_rvalue()], + ); } - }, + } "__builtin_ia32_stmxcsr" => { // The builtin __builtin_ia32_stmxcsr returns a value while llvm.x86.sse.stmxcsr writes // the result in its pointer argument. @@ -366,20 +529,24 @@ pub fn adjust_intrinsic_return_value<'a, 'gcc, 'tcx>(builder: &Builder<'a, 'gcc, // The return value was assigned to the result pointer above. In order to not call the // builtin twice, we overwrite the return value with a dummy value. return_value = builder.context.new_rvalue_zero(builder.int_type); - }, + } "__builtin_ia32_rdrand64_step" => { let random_number = args[0].dereference(None).to_rvalue(); - let success_variable = builder.current_func().new_local(None, return_value.get_type(), "success"); + let success_variable = + builder.current_func().new_local(None, return_value.get_type(), "success"); builder.llbb().add_assignment(None, success_variable, return_value); let field1 = builder.context.new_field(None, random_number.get_type(), "random_number"); let field2 = builder.context.new_field(None, return_value.get_type(), "success"); - let struct_type = builder.context.new_struct_type(None, "rdrand_result", &[field1, field2]); - return_value = builder.context.new_struct_constructor(None, struct_type.as_type(), None, &[ - random_number, - success_variable.to_rvalue(), - ]); - }, + let struct_type = + builder.context.new_struct_type(None, "rdrand_result", &[field1, field2]); + return_value = builder.context.new_struct_constructor( + None, + struct_type.as_type(), + None, + &[random_number, success_variable.to_rvalue()], + ); + } _ => (), } @@ -391,23 +558,33 @@ pub fn ignore_arg_cast(func_name: &str, index: usize, args_len: usize) -> bool { match func_name { // NOTE: these intrinsics have missing parameters before the last one, so ignore the // last argument type check. - "__builtin_ia32_maxps512_mask" | "__builtin_ia32_maxpd512_mask" - | "__builtin_ia32_minps512_mask" | "__builtin_ia32_minpd512_mask" | "__builtin_ia32_sqrtps512_mask" - | "__builtin_ia32_sqrtpd512_mask" | "__builtin_ia32_addps512_mask" | "__builtin_ia32_addpd512_mask" - | "__builtin_ia32_subps512_mask" | "__builtin_ia32_subpd512_mask" - | "__builtin_ia32_mulps512_mask" | "__builtin_ia32_mulpd512_mask" - | "__builtin_ia32_divps512_mask" | "__builtin_ia32_divpd512_mask" - | "__builtin_ia32_vfmaddsubps512_mask" | "__builtin_ia32_vfmaddsubpd512_mask" - | "__builtin_ia32_cvtdq2ps512_mask" | "__builtin_ia32_cvtudq2ps512_mask" => { - if index == args_len - 1 { - return true; - } - }, + "__builtin_ia32_maxps512_mask" + | "__builtin_ia32_maxpd512_mask" + | "__builtin_ia32_minps512_mask" + | "__builtin_ia32_minpd512_mask" + | "__builtin_ia32_sqrtps512_mask" + | "__builtin_ia32_sqrtpd512_mask" + | "__builtin_ia32_addps512_mask" + | "__builtin_ia32_addpd512_mask" + | "__builtin_ia32_subps512_mask" + | "__builtin_ia32_subpd512_mask" + | "__builtin_ia32_mulps512_mask" + | "__builtin_ia32_mulpd512_mask" + | "__builtin_ia32_divps512_mask" + | "__builtin_ia32_divpd512_mask" + | "__builtin_ia32_vfmaddsubps512_mask" + | "__builtin_ia32_vfmaddsubpd512_mask" + | "__builtin_ia32_cvtdq2ps512_mask" + | "__builtin_ia32_cvtudq2ps512_mask" => { + if index == args_len - 1 { + return true; + } + } "__builtin_ia32_rndscaless_mask_round" | "__builtin_ia32_rndscalesd_mask_round" => { if index == 2 || index == 3 { return true; } - }, + } "__builtin_ia32_vfmaddps512_mask" | "__builtin_ia32_vfmaddpd512_mask" => { // Since there are two LLVM intrinsics that map to each of these GCC builtins and only // one of them has a missing parameter before the last one, we check the number of @@ -415,49 +592,50 @@ pub fn ignore_arg_cast(func_name: &str, index: usize, args_len: usize) -> bool { if args_len == 4 && index == args_len - 1 { return true; } - }, + } // NOTE: the LLVM intrinsic receives 3 floats, but the GCC builtin requires 3 vectors. "__builtin_ia32_vfmaddss3_round" | "__builtin_ia32_vfmaddsd3_round" => return true, - "__builtin_ia32_vplzcntd_512_mask" | "__builtin_ia32_vplzcntd_256_mask" | "__builtin_ia32_vplzcntd_128_mask" - | "__builtin_ia32_vplzcntq_512_mask" | "__builtin_ia32_vplzcntq_256_mask" | "__builtin_ia32_vplzcntq_128_mask" => { + "__builtin_ia32_vplzcntd_512_mask" + | "__builtin_ia32_vplzcntd_256_mask" + | "__builtin_ia32_vplzcntd_128_mask" + | "__builtin_ia32_vplzcntq_512_mask" + | "__builtin_ia32_vplzcntq_256_mask" + | "__builtin_ia32_vplzcntq_128_mask" => { if index == args_len - 1 { return true; } - }, + } _ => (), } false } -#[cfg(not(feature="master"))] +#[cfg(not(feature = "master"))] pub fn intrinsic<'gcc, 'tcx>(name: &str, cx: &CodegenCx<'gcc, 'tcx>) -> Function<'gcc> { - let gcc_name = - match name { - "llvm.x86.sse2.pause" => { - // NOTE: pause is only a hint, so we use a dummy built-in because target built-ins - // are not supported in libgccjit 12. - "__builtin_inff" - }, - "llvm.x86.xgetbv" => { - "__builtin_trap" - }, - _ => unimplemented!("unsupported LLVM intrinsic {}", name), - }; + let gcc_name = match name { + "llvm.x86.sse2.pause" => { + // NOTE: pause is only a hint, so we use a dummy built-in because target built-ins + // are not supported in libgccjit 12. + "__builtin_inff" + } + "llvm.x86.xgetbv" => "__builtin_trap", + _ => unimplemented!("unsupported LLVM intrinsic {}", name), + }; let func = cx.context.get_builtin_function(gcc_name); cx.functions.borrow_mut().insert(gcc_name.to_string(), func); return func; } -#[cfg(feature="master")] +#[cfg(feature = "master")] pub fn intrinsic<'gcc, 'tcx>(name: &str, cx: &CodegenCx<'gcc, 'tcx>) -> Function<'gcc> { match name { "llvm.prefetch" => { let gcc_name = "__builtin_prefetch"; let func = cx.context.get_builtin_function(gcc_name); cx.functions.borrow_mut().insert(gcc_name.to_string(), func); - return func - }, + return func; + } _ => (), } diff --git a/src/intrinsic/mod.rs b/src/intrinsic/mod.rs index d43f5d74757ae..a6c8b72e851b2 100644 --- a/src/intrinsic/mod.rs +++ b/src/intrinsic/mod.rs @@ -1,43 +1,48 @@ pub mod llvm; mod simd; -#[cfg(feature="master")] +#[cfg(feature = "master")] use std::iter; -#[cfg(feature="master")] +#[cfg(feature = "master")] use gccjit::FunctionType; use gccjit::{ComparisonOp, Function, RValue, ToRValue, Type, UnaryOp}; -use rustc_codegen_ssa::MemFlags; use rustc_codegen_ssa::base::wants_msvc_seh; 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; -use rustc_codegen_ssa::traits::{ArgAbiMethods, BuilderMethods, ConstMethods, IntrinsicCallMethods}; -#[cfg(feature="master")] +use rustc_codegen_ssa::traits::{ + ArgAbiMethods, BuilderMethods, ConstMethods, IntrinsicCallMethods, +}; +#[cfg(feature = "master")] use rustc_codegen_ssa::traits::{BaseTypeMethods, MiscMethods}; -use rustc_codegen_ssa::errors::InvalidMonomorphization; +use rustc_codegen_ssa::MemFlags; use rustc_middle::bug; -use rustc_middle::ty::{self, Instance, Ty}; use rustc_middle::ty::layout::LayoutOf; -#[cfg(feature="master")] +#[cfg(feature = "master")] use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt}; -use rustc_span::{Span, Symbol, sym}; -use rustc_target::abi::HasDataLayout; +use rustc_middle::ty::{self, Instance, Ty}; +use rustc_span::{sym, Span, Symbol}; use rustc_target::abi::call::{ArgAbi, FnAbi, PassMode}; -use rustc_target::spec::PanicStrategy; -#[cfg(feature="master")] +use rustc_target::abi::HasDataLayout; +#[cfg(feature = "master")] use rustc_target::spec::abi::Abi; +use rustc_target::spec::PanicStrategy; -use crate::abi::GccType; -#[cfg(feature="master")] +#[cfg(feature = "master")] use crate::abi::FnAbiGccExt; +use crate::abi::GccType; use crate::builder::Builder; use crate::common::{SignType, TypeReflection}; use crate::context::CodegenCx; -use crate::type_of::LayoutGccExt; use crate::intrinsic::simd::generic_simd_intrinsic; +use crate::type_of::LayoutGccExt; -fn get_simple_intrinsic<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, name: Symbol) -> Option> { +fn get_simple_intrinsic<'gcc, 'tcx>( + cx: &CodegenCx<'gcc, 'tcx>, + name: Symbol, +) -> Option> { let gcc_name = match name { sym::sqrtf32 => "sqrtf", sym::sqrtf64 => "sqrt", @@ -90,7 +95,14 @@ fn get_simple_intrinsic<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, name: Symbol) -> } impl<'a, 'gcc, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'a, 'gcc, 'tcx> { - fn codegen_intrinsic_call(&mut self, instance: Instance<'tcx>, fn_abi: &FnAbi<'tcx, Ty<'tcx>>, args: &[OperandRef<'tcx, RValue<'gcc>>], llresult: RValue<'gcc>, span: Span) -> Result<(), Instance<'tcx>> { + fn codegen_intrinsic_call( + &mut self, + instance: Instance<'tcx>, + fn_abi: &FnAbi<'tcx, Ty<'tcx>>, + args: &[OperandRef<'tcx, RValue<'gcc>>], + llresult: RValue<'gcc>, + span: Span, + ) -> Result<(), Instance<'tcx>> { let tcx = self.tcx; let callee_ty = instance.ty(tcx, ty::ParamEnv::reveal_all()); @@ -110,268 +122,274 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'a, 'gcc, 'tcx> { let result = PlaceRef::new_sized(llresult, fn_abi.ret.layout); let simple = get_simple_intrinsic(self, name); - let llval = - match name { - _ if simple.is_some() => { - // FIXME(antoyo): remove this cast when the API supports function. - let func = unsafe { std::mem::transmute(simple.expect("simple")) }; - self.call(self.type_void(), None, None, func, &args.iter().map(|arg| arg.immediate()).collect::>(), None) - }, - sym::likely => { - self.expect(args[0].immediate(), true) - } - sym::unlikely => { - self.expect(args[0].immediate(), false) - } - sym::is_val_statically_known => { - let a = args[0].immediate(); - let builtin = self.context.get_builtin_function("__builtin_constant_p"); - let res = self.context.new_call(None, builtin, &[a]); - self.icmp(IntPredicate::IntEQ, res, self.const_i32(0)) - } - sym::catch_unwind => { - try_intrinsic( - self, - args[0].immediate(), - args[1].immediate(), - args[2].immediate(), - llresult, - ); - return Ok(()); - } - sym::breakpoint => { - unimplemented!(); - } - sym::va_copy => { - unimplemented!(); - } - sym::va_arg => { - unimplemented!(); - } + let llval = match name { + _ if simple.is_some() => { + // FIXME(antoyo): remove this cast when the API supports function. + let func = unsafe { std::mem::transmute(simple.expect("simple")) }; + self.call( + self.type_void(), + None, + None, + func, + &args.iter().map(|arg| arg.immediate()).collect::>(), + None, + ) + } + sym::likely => self.expect(args[0].immediate(), true), + sym::unlikely => self.expect(args[0].immediate(), false), + sym::is_val_statically_known => { + let a = args[0].immediate(); + let builtin = self.context.get_builtin_function("__builtin_constant_p"); + let res = self.context.new_call(None, builtin, &[a]); + self.icmp(IntPredicate::IntEQ, res, self.const_i32(0)) + } + sym::catch_unwind => { + try_intrinsic( + self, + args[0].immediate(), + args[1].immediate(), + args[2].immediate(), + llresult, + ); + return Ok(()); + } + sym::breakpoint => { + unimplemented!(); + } + sym::va_copy => { + unimplemented!(); + } + sym::va_arg => { + unimplemented!(); + } - sym::volatile_load | sym::unaligned_volatile_load => { - let tp_ty = fn_args.type_at(0); - let ptr = args[0].immediate(); - let load = - if let PassMode::Cast { cast: ty, pad_i32: _ } = &fn_abi.ret.mode { - let gcc_ty = ty.gcc_type(self); - self.volatile_load(gcc_ty, ptr) + sym::volatile_load | sym::unaligned_volatile_load => { + let tp_ty = fn_args.type_at(0); + let ptr = args[0].immediate(); + let load = if let PassMode::Cast { cast: ty, pad_i32: _ } = &fn_abi.ret.mode { + let gcc_ty = ty.gcc_type(self); + self.volatile_load(gcc_ty, ptr) + } else { + self.volatile_load(self.layout_of(tp_ty).gcc_type(self), ptr) + }; + // TODO(antoyo): set alignment. + self.to_immediate(load, self.layout_of(tp_ty)) + } + sym::volatile_store => { + let dst = args[0].deref(self.cx()); + args[1].val.volatile_store(self, dst); + return Ok(()); + } + sym::unaligned_volatile_store => { + let dst = args[0].deref(self.cx()); + args[1].val.unaligned_volatile_store(self, dst); + return Ok(()); + } + sym::prefetch_read_data + | sym::prefetch_write_data + | sym::prefetch_read_instruction + | sym::prefetch_write_instruction => { + unimplemented!(); + } + sym::ctlz + | sym::ctlz_nonzero + | sym::cttz + | sym::cttz_nonzero + | sym::ctpop + | sym::bswap + | sym::bitreverse + | sym::rotate_left + | sym::rotate_right + | sym::saturating_add + | sym::saturating_sub => { + let ty = arg_tys[0]; + match int_type_width_signed(ty, self) { + Some((width, signed)) => match name { + sym::ctlz | sym::cttz => { + let func = self.current_func.borrow().expect("func"); + let then_block = func.new_block("then"); + let else_block = func.new_block("else"); + let after_block = func.new_block("after"); + + let arg = args[0].immediate(); + let result = func.new_local(None, arg.get_type(), "zeros"); + let zero = self.cx.gcc_zero(arg.get_type()); + let cond = self.gcc_icmp(IntPredicate::IntEQ, arg, zero); + self.llbb().end_with_conditional(None, cond, then_block, else_block); + + let zero_result = self.cx.gcc_uint(arg.get_type(), width); + then_block.add_assignment(None, result, zero_result); + then_block.end_with_jump(None, after_block); + + // NOTE: since jumps were added in a place + // count_leading_zeroes() does not expect, the current block + // in the state need to be updated. + self.switch_to_block(else_block); + + let zeros = match name { + sym::ctlz => self.count_leading_zeroes(width, arg), + sym::cttz => self.count_trailing_zeroes(width, arg), + _ => unreachable!(), + }; + self.llbb().add_assignment(None, result, zeros); + self.llbb().end_with_jump(None, after_block); + + // NOTE: since jumps were added in a place rustc does not + // expect, the current block in the state need to be updated. + self.switch_to_block(after_block); + + result.to_rvalue() } - else { - self.volatile_load(self.layout_of(tp_ty).gcc_type(self), ptr) - }; - // TODO(antoyo): set alignment. - self.to_immediate(load, self.layout_of(tp_ty)) - } - sym::volatile_store => { - let dst = args[0].deref(self.cx()); - args[1].val.volatile_store(self, dst); - return Ok(()); - } - sym::unaligned_volatile_store => { - let dst = args[0].deref(self.cx()); - args[1].val.unaligned_volatile_store(self, dst); - return Ok(()); - } - sym::prefetch_read_data - | sym::prefetch_write_data - | sym::prefetch_read_instruction - | sym::prefetch_write_instruction => { - unimplemented!(); - } - sym::ctlz - | sym::ctlz_nonzero - | sym::cttz - | sym::cttz_nonzero - | sym::ctpop - | sym::bswap - | sym::bitreverse - | sym::rotate_left - | sym::rotate_right - | sym::saturating_add - | sym::saturating_sub => { - let ty = arg_tys[0]; - match int_type_width_signed(ty, self) { - Some((width, signed)) => match name { - sym::ctlz | sym::cttz => { - let func = self.current_func.borrow().expect("func"); - let then_block = func.new_block("then"); - let else_block = func.new_block("else"); - let after_block = func.new_block("after"); - - let arg = args[0].immediate(); - let result = func.new_local(None, arg.get_type(), "zeros"); - let zero = self.cx.gcc_zero(arg.get_type()); - let cond = self.gcc_icmp(IntPredicate::IntEQ, arg, zero); - self.llbb().end_with_conditional(None, cond, then_block, else_block); - - let zero_result = self.cx.gcc_uint(arg.get_type(), width); - then_block.add_assignment(None, result, zero_result); - then_block.end_with_jump(None, after_block); - - // NOTE: since jumps were added in a place - // count_leading_zeroes() does not expect, the current block - // in the state need to be updated. - self.switch_to_block(else_block); - - let zeros = - match name { - sym::ctlz => self.count_leading_zeroes(width, arg), - sym::cttz => self.count_trailing_zeroes(width, arg), - _ => unreachable!(), - }; - self.llbb().add_assignment(None, result, zeros); - self.llbb().end_with_jump(None, after_block); - - // NOTE: since jumps were added in a place rustc does not - // expect, the current block in the state need to be updated. - self.switch_to_block(after_block); - - result.to_rvalue() - } - sym::ctlz_nonzero => { - self.count_leading_zeroes(width, args[0].immediate()) - }, - sym::cttz_nonzero => { - self.count_trailing_zeroes(width, args[0].immediate()) - } - sym::ctpop => self.pop_count(args[0].immediate()), - sym::bswap => { - if width == 8 { - args[0].immediate() // byte swap a u8/i8 is just a no-op - } - else { - self.gcc_bswap(args[0].immediate(), width) - } - }, - sym::bitreverse => self.bit_reverse(width, args[0].immediate()), - sym::rotate_left | sym::rotate_right => { - // TODO(antoyo): implement using algorithm from: - // https://blog.regehr.org/archives/1063 - // for other platforms. - let is_left = name == sym::rotate_left; - let val = args[0].immediate(); - let raw_shift = args[1].immediate(); - if is_left { - self.rotate_left(val, raw_shift, width) - } - else { - self.rotate_right(val, raw_shift, width) - } - }, - sym::saturating_add => { - self.saturating_add(args[0].immediate(), args[1].immediate(), signed, width) - }, - sym::saturating_sub => { - self.saturating_sub(args[0].immediate(), args[1].immediate(), signed, width) - }, - _ => bug!(), - }, - None => { - tcx.dcx().emit_err(InvalidMonomorphization::BasicIntegerType { span, name, ty }); - return Ok(()); + sym::ctlz_nonzero => self.count_leading_zeroes(width, args[0].immediate()), + sym::cttz_nonzero => self.count_trailing_zeroes(width, args[0].immediate()), + sym::ctpop => self.pop_count(args[0].immediate()), + sym::bswap => { + if width == 8 { + args[0].immediate() // byte swap a u8/i8 is just a no-op + } else { + self.gcc_bswap(args[0].immediate(), width) } } - } - - sym::raw_eq => { - use rustc_target::abi::Abi::*; - let tp_ty = fn_args.type_at(0); - let layout = self.layout_of(tp_ty).layout; - let _use_integer_compare = match layout.abi() { - Scalar(_) | ScalarPair(_, _) => true, - Uninhabited | Vector { .. } => false, - Aggregate { .. } => { - // For rusty ABIs, small aggregates are actually passed - // as `RegKind::Integer` (see `FnAbi::adjust_for_abi`), - // so we re-use that same threshold here. - layout.size() <= self.data_layout().pointer_size * 2 + sym::bitreverse => self.bit_reverse(width, args[0].immediate()), + sym::rotate_left | sym::rotate_right => { + // TODO(antoyo): implement using algorithm from: + // https://blog.regehr.org/archives/1063 + // for other platforms. + let is_left = name == sym::rotate_left; + let val = args[0].immediate(); + let raw_shift = args[1].immediate(); + if is_left { + self.rotate_left(val, raw_shift, width) + } else { + self.rotate_right(val, raw_shift, width) + } } - }; - - let a = args[0].immediate(); - let b = args[1].immediate(); - if layout.size().bytes() == 0 { - self.const_bool(true) - } - /*else if use_integer_compare { - let integer_ty = self.type_ix(layout.size.bits()); // FIXME(antoyo): LLVM creates an integer of 96 bits for [i32; 3], but gcc doesn't support this, so it creates an integer of 128 bits. - let ptr_ty = self.type_ptr_to(integer_ty); - let a_ptr = self.bitcast(a, ptr_ty); - let a_val = self.load(integer_ty, a_ptr, layout.align.abi); - let b_ptr = self.bitcast(b, ptr_ty); - let b_val = self.load(integer_ty, b_ptr, layout.align.abi); - self.icmp(IntPredicate::IntEQ, a_val, b_val) - }*/ - else { - let void_ptr_type = self.context.new_type::<*const ()>(); - let a_ptr = self.bitcast(a, void_ptr_type); - let b_ptr = self.bitcast(b, void_ptr_type); - let n = self.context.new_cast(None, self.const_usize(layout.size().bytes()), self.sizet_type); - let builtin = self.context.get_builtin_function("memcmp"); - let cmp = self.context.new_call(None, builtin, &[a_ptr, b_ptr, n]); - self.icmp(IntPredicate::IntEQ, cmp, self.const_i32(0)) + sym::saturating_add => self.saturating_add( + args[0].immediate(), + args[1].immediate(), + signed, + width, + ), + sym::saturating_sub => self.saturating_sub( + args[0].immediate(), + args[1].immediate(), + signed, + width, + ), + _ => bug!(), + }, + None => { + tcx.dcx().emit_err(InvalidMonomorphization::BasicIntegerType { + span, + name, + ty, + }); + return Ok(()); } } + } - sym::compare_bytes => { - let a = args[0].immediate(); - let b = args[1].immediate(); - let n = args[2].immediate(); + sym::raw_eq => { + use rustc_target::abi::Abi::*; + let tp_ty = fn_args.type_at(0); + let layout = self.layout_of(tp_ty).layout; + let _use_integer_compare = match layout.abi() { + Scalar(_) | ScalarPair(_, _) => true, + Uninhabited | Vector { .. } => false, + Aggregate { .. } => { + // For rusty ABIs, small aggregates are actually passed + // as `RegKind::Integer` (see `FnAbi::adjust_for_abi`), + // so we re-use that same threshold here. + layout.size() <= self.data_layout().pointer_size * 2 + } + }; + let a = args[0].immediate(); + let b = args[1].immediate(); + if layout.size().bytes() == 0 { + self.const_bool(true) + } + /*else if use_integer_compare { + let integer_ty = self.type_ix(layout.size.bits()); // FIXME(antoyo): LLVM creates an integer of 96 bits for [i32; 3], but gcc doesn't support this, so it creates an integer of 128 bits. + let ptr_ty = self.type_ptr_to(integer_ty); + let a_ptr = self.bitcast(a, ptr_ty); + let a_val = self.load(integer_ty, a_ptr, layout.align.abi); + let b_ptr = self.bitcast(b, ptr_ty); + let b_val = self.load(integer_ty, b_ptr, layout.align.abi); + self.icmp(IntPredicate::IntEQ, a_val, b_val) + }*/ + else { let void_ptr_type = self.context.new_type::<*const ()>(); let a_ptr = self.bitcast(a, void_ptr_type); let b_ptr = self.bitcast(b, void_ptr_type); - - // Here we assume that the `memcmp` provided by the target is a NOP for size 0. + let n = self.context.new_cast( + None, + self.const_usize(layout.size().bytes()), + self.sizet_type, + ); let builtin = self.context.get_builtin_function("memcmp"); let cmp = self.context.new_call(None, builtin, &[a_ptr, b_ptr, n]); - self.sext(cmp, self.type_ix(32)) + self.icmp(IntPredicate::IntEQ, cmp, self.const_i32(0)) } + } - sym::black_box => { - args[0].val.store(self, result); + sym::compare_bytes => { + let a = args[0].immediate(); + let b = args[1].immediate(); + let n = args[2].immediate(); - let block = self.llbb(); - let extended_asm = block.add_extended_asm(None, ""); - extended_asm.add_input_operand(None, "r", result.llval); - extended_asm.add_clobber("memory"); - extended_asm.set_volatile_flag(true); + let void_ptr_type = self.context.new_type::<*const ()>(); + let a_ptr = self.bitcast(a, void_ptr_type); + let b_ptr = self.bitcast(b, void_ptr_type); - // We have copied the value to `result` already. - return Ok(()); - } + // Here we assume that the `memcmp` provided by the target is a NOP for size 0. + let builtin = self.context.get_builtin_function("memcmp"); + let cmp = self.context.new_call(None, builtin, &[a_ptr, b_ptr, n]); + self.sext(cmp, self.type_ix(32)) + } - sym::ptr_mask => { - let usize_type = self.context.new_type::(); - let void_ptr_type = self.context.new_type::<*const ()>(); + sym::black_box => { + args[0].val.store(self, result); - let ptr = args[0].immediate(); - let mask = args[1].immediate(); + let block = self.llbb(); + let extended_asm = block.add_extended_asm(None, ""); + extended_asm.add_input_operand(None, "r", result.llval); + extended_asm.add_clobber("memory"); + extended_asm.set_volatile_flag(true); - let addr = self.bitcast(ptr, usize_type); - let masked = self.and(addr, mask); - self.bitcast(masked, void_ptr_type) - }, + // We have copied the value to `result` already. + return Ok(()); + } - _ if name_str.starts_with("simd_") => { - match generic_simd_intrinsic(self, name, callee_ty, args, ret_ty, llret_ty, span) { - Ok(llval) => llval, - Err(()) => return Ok(()), - } + sym::ptr_mask => { + let usize_type = self.context.new_type::(); + let void_ptr_type = self.context.new_type::<*const ()>(); + + let ptr = args[0].immediate(); + let mask = args[1].immediate(); + + let addr = self.bitcast(ptr, usize_type); + let masked = self.and(addr, mask); + self.bitcast(masked, void_ptr_type) + } + + _ if name_str.starts_with("simd_") => { + match generic_simd_intrinsic(self, name, callee_ty, args, ret_ty, llret_ty, span) { + Ok(llval) => llval, + Err(()) => return Ok(()), } + } - // Fall back to default body - _ => return Err(Instance::new(instance.def_id(), instance.args)), - }; + // Fall back to default body + _ => return Err(Instance::new(instance.def_id(), instance.args)), + }; if !fn_abi.ret.is_ignore() { if let PassMode::Cast { cast: ty, .. } = &fn_abi.ret.mode { let ptr_llty = self.type_ptr_to(ty.gcc_type(self)); let ptr = self.pointercast(result.llval, ptr_llty); self.store(llval, ptr, result.align); - } - else { + } else { OperandRef::from_immediate_or_packed_pair(self, llval, result.layout) .val .store(self, result); @@ -423,11 +441,21 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'a, 'gcc, 'tcx> { } impl<'a, 'gcc, 'tcx> ArgAbiMethods<'tcx> for Builder<'a, 'gcc, 'tcx> { - fn store_fn_arg(&mut self, arg_abi: &ArgAbi<'tcx, Ty<'tcx>>, idx: &mut usize, dst: PlaceRef<'tcx, Self::Value>) { + fn store_fn_arg( + &mut self, + arg_abi: &ArgAbi<'tcx, Ty<'tcx>>, + idx: &mut usize, + dst: PlaceRef<'tcx, Self::Value>, + ) { arg_abi.store_fn_arg(self, idx, dst) } - fn store_arg(&mut self, arg_abi: &ArgAbi<'tcx, Ty<'tcx>>, val: RValue<'gcc>, dst: PlaceRef<'tcx, RValue<'gcc>>) { + fn store_arg( + &mut self, + arg_abi: &ArgAbi<'tcx, Ty<'tcx>>, + val: RValue<'gcc>, + dst: PlaceRef<'tcx, RValue<'gcc>>, + ) { arg_abi.store(self, val, dst) } @@ -438,8 +466,18 @@ impl<'a, 'gcc, 'tcx> ArgAbiMethods<'tcx> for Builder<'a, 'gcc, 'tcx> { pub trait ArgAbiExt<'gcc, 'tcx> { fn memory_ty(&self, cx: &CodegenCx<'gcc, 'tcx>) -> Type<'gcc>; - fn store(&self, bx: &mut Builder<'_, 'gcc, 'tcx>, val: RValue<'gcc>, dst: PlaceRef<'tcx, RValue<'gcc>>); - fn store_fn_arg(&self, bx: &mut Builder<'_, 'gcc, 'tcx>, idx: &mut usize, dst: PlaceRef<'tcx, RValue<'gcc>>); + fn store( + &self, + bx: &mut Builder<'_, 'gcc, 'tcx>, + val: RValue<'gcc>, + dst: PlaceRef<'tcx, RValue<'gcc>>, + ); + fn store_fn_arg( + &self, + bx: &mut Builder<'_, 'gcc, 'tcx>, + idx: &mut usize, + dst: PlaceRef<'tcx, RValue<'gcc>>, + ); } impl<'gcc, 'tcx> ArgAbiExt<'gcc, 'tcx> for ArgAbi<'tcx, Ty<'tcx>> { @@ -453,17 +491,20 @@ impl<'gcc, 'tcx> ArgAbiExt<'gcc, 'tcx> for ArgAbi<'tcx, Ty<'tcx>> { /// place for the original Rust type of this argument/return. /// Can be used for both storing formal arguments into Rust variables /// or results of call/invoke instructions into their destinations. - fn store(&self, bx: &mut Builder<'_, 'gcc, 'tcx>, val: RValue<'gcc>, dst: PlaceRef<'tcx, RValue<'gcc>>) { + fn store( + &self, + bx: &mut Builder<'_, 'gcc, 'tcx>, + val: RValue<'gcc>, + dst: PlaceRef<'tcx, RValue<'gcc>>, + ) { if self.is_ignore() { return; } if self.is_sized_indirect() { OperandValue::Ref(val, None, self.layout.align.abi).store(bx, dst) - } - else if self.is_unsized_indirect() { + } else if self.is_unsized_indirect() { bug!("unsized `ArgAbi` must be handled through `store_fn_arg`"); - } - else if let PassMode::Cast { ref cast, .. } = self.mode { + } else if let PassMode::Cast { ref cast, .. } = self.mode { // FIXME(eddyb): Figure out when the simpler Store is safe, clang // uses it for i16 -> {i8, i8}, but not for i24 -> {i8, i8, i8}. let can_store_through_cast_ptr = false; @@ -471,8 +512,7 @@ impl<'gcc, 'tcx> ArgAbiExt<'gcc, 'tcx> for ArgAbi<'tcx, Ty<'tcx>> { let cast_ptr_llty = bx.type_ptr_to(cast.gcc_type(bx)); let cast_dst = bx.pointercast(dst.llval, cast_ptr_llty); bx.store(val, cast_dst, self.layout.align.abi); - } - else { + } else { // The actual return type is a struct, but the ABI // adaptation code has cast it into some scalar type. The // code that follows is the only reliable way I have @@ -508,35 +548,44 @@ impl<'gcc, 'tcx> ArgAbiExt<'gcc, 'tcx> for ArgAbi<'tcx, Ty<'tcx>> { bx.lifetime_end(llscratch, scratch_size); } - } - else { + } else { OperandValue::Immediate(val).store(bx, dst); } } - fn store_fn_arg<'a>(&self, bx: &mut Builder<'a, 'gcc, 'tcx>, idx: &mut usize, dst: PlaceRef<'tcx, RValue<'gcc>>) { + fn store_fn_arg<'a>( + &self, + bx: &mut Builder<'a, 'gcc, 'tcx>, + idx: &mut usize, + dst: PlaceRef<'tcx, RValue<'gcc>>, + ) { let mut next = || { let val = bx.current_func().get_param(*idx as i32); *idx += 1; val.to_rvalue() }; match self.mode { - PassMode::Ignore => {}, + PassMode::Ignore => {} PassMode::Pair(..) => { OperandValue::Pair(next(), next()).store(bx, dst); - }, + } PassMode::Indirect { meta_attrs: Some(_), .. } => { OperandValue::Ref(next(), Some(next()), self.layout.align.abi).store(bx, dst); - }, - PassMode::Direct(_) | PassMode::Indirect { meta_attrs: None, .. } | PassMode::Cast { .. } => { + } + PassMode::Direct(_) + | PassMode::Indirect { meta_attrs: None, .. } + | PassMode::Cast { .. } => { let next_arg = next(); self.store(bx, next_arg, dst); - }, + } } } } -fn int_type_width_signed<'gcc, 'tcx>(ty: Ty<'tcx>, cx: &CodegenCx<'gcc, 'tcx>) -> Option<(u64, bool)> { +fn int_type_width_signed<'gcc, 'tcx>( + ty: Ty<'tcx>, + cx: &CodegenCx<'gcc, 'tcx>, +) -> Option<(u64, bool)> { match ty.kind() { ty::Int(t) => Some(( match t { @@ -570,82 +619,76 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { let typ = result_type.to_unsigned(self.cx); let value = - if result_type.is_signed(self.cx) { - self.gcc_int_cast(value, typ) - } - else { - value - }; + if result_type.is_signed(self.cx) { self.gcc_int_cast(value, typ) } else { value }; let context = &self.cx.context; - let result = - match width { - 8 | 16 | 32 | 64 => { - let mask = ((1u128 << width) - 1) as u64; - let (m0, m1, m2) = if width > 16 { - ( - context.new_rvalue_from_long(typ, (0x5555555555555555u64 & mask) as i64), - context.new_rvalue_from_long(typ, (0x3333333333333333u64 & mask) as i64), - context.new_rvalue_from_long(typ, (0x0f0f0f0f0f0f0f0fu64 & mask) as i64), - ) - } else { - ( - context.new_rvalue_from_int(typ, (0x5555u64 & mask) as i32), - context.new_rvalue_from_int(typ, (0x3333u64 & mask) as i32), - context.new_rvalue_from_int(typ, (0x0f0fu64 & mask) as i32), - ) - }; - let one = context.new_rvalue_from_int(typ, 1); - let two = context.new_rvalue_from_int(typ, 2); - let four = context.new_rvalue_from_int(typ, 4); - - // First step. - let left = self.lshr(value, one); - let left = self.and(left, m0); - let right = self.and(value, m0); - let right = self.shl(right, one); - let step1 = self.or(left, right); - - // Second step. - let left = self.lshr(step1, two); - let left = self.and(left, m1); - let right = self.and(step1, m1); - let right = self.shl(right, two); - let step2 = self.or(left, right); - - // Third step. - let left = self.lshr(step2, four); - let left = self.and(left, m2); - let right = self.and(step2, m2); - let right = self.shl(right, four); - let step3 = self.or(left, right); - - // Fourth step. - if width == 8 { - step3 - } else { - self.gcc_bswap(step3, width) - } - }, - 128 => { - // TODO(antoyo): find a more efficient implementation? - let sixty_four = self.gcc_int(typ, 64); - let right_shift = self.gcc_lshr(value, sixty_four); - let high = self.gcc_int_cast(right_shift, self.u64_type); - let low = self.gcc_int_cast(value, self.u64_type); - - let reversed_high = self.bit_reverse(64, high); - let reversed_low = self.bit_reverse(64, low); - - let new_low = self.gcc_int_cast(reversed_high, typ); - let new_high = self.shl(self.gcc_int_cast(reversed_low, typ), sixty_four); - - self.gcc_or(new_low, new_high) - }, - _ => { - panic!("cannot bit reverse with width = {}", width); - }, - }; + let result = match width { + 8 | 16 | 32 | 64 => { + let mask = ((1u128 << width) - 1) as u64; + let (m0, m1, m2) = if width > 16 { + ( + context.new_rvalue_from_long(typ, (0x5555555555555555u64 & mask) as i64), + context.new_rvalue_from_long(typ, (0x3333333333333333u64 & mask) as i64), + context.new_rvalue_from_long(typ, (0x0f0f0f0f0f0f0f0fu64 & mask) as i64), + ) + } else { + ( + context.new_rvalue_from_int(typ, (0x5555u64 & mask) as i32), + context.new_rvalue_from_int(typ, (0x3333u64 & mask) as i32), + context.new_rvalue_from_int(typ, (0x0f0fu64 & mask) as i32), + ) + }; + let one = context.new_rvalue_from_int(typ, 1); + let two = context.new_rvalue_from_int(typ, 2); + let four = context.new_rvalue_from_int(typ, 4); + + // First step. + let left = self.lshr(value, one); + let left = self.and(left, m0); + let right = self.and(value, m0); + let right = self.shl(right, one); + let step1 = self.or(left, right); + + // Second step. + let left = self.lshr(step1, two); + let left = self.and(left, m1); + let right = self.and(step1, m1); + let right = self.shl(right, two); + let step2 = self.or(left, right); + + // Third step. + let left = self.lshr(step2, four); + let left = self.and(left, m2); + let right = self.and(step2, m2); + let right = self.shl(right, four); + let step3 = self.or(left, right); + + // Fourth step. + if width == 8 { + step3 + } else { + self.gcc_bswap(step3, width) + } + } + 128 => { + // TODO(antoyo): find a more efficient implementation? + let sixty_four = self.gcc_int(typ, 64); + let right_shift = self.gcc_lshr(value, sixty_four); + let high = self.gcc_int_cast(right_shift, self.u64_type); + let low = self.gcc_int_cast(value, self.u64_type); + + let reversed_high = self.bit_reverse(64, high); + let reversed_low = self.bit_reverse(64, low); + + let new_low = self.gcc_int_cast(reversed_high, typ); + let new_high = self.shl(self.gcc_int_cast(reversed_low, typ), sixty_four); + + self.gcc_or(new_low, new_high, self.location) + } + _ => { + panic!("cannot bit reverse with width = {}", width); + } + }; self.gcc_int_cast(result, result_type) } @@ -685,56 +728,54 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { let first_elem = self.context.new_array_access(None, result, zero); let first_value = self.gcc_int_cast(self.context.new_call(None, clzll, &[high]), arg_type); self.llbb() - .add_assignment(None, first_elem, first_value); + .add_assignment(self.location, first_elem, first_value); - let second_elem = self.context.new_array_access(None, result, one); - let cast = self.gcc_int_cast(self.context.new_call(None, clzll, &[low]), arg_type); + let second_elem = self.context.new_array_access(self.location, result, one); + let cast = self.gcc_int_cast(self.context.new_call(self.location, clzll, &[low]), arg_type); let second_value = self.add(cast, sixty_four); self.llbb() - .add_assignment(None, second_elem, second_value); + .add_assignment(self.location, second_elem, second_value); - let third_elem = self.context.new_array_access(None, result, two); + let third_elem = self.context.new_array_access(self.location, result, two); let third_value = self.const_uint(arg_type, 128); self.llbb() - .add_assignment(None, third_elem, third_value); + .add_assignment(self.location, third_elem, third_value); - let not_high = self.context.new_unary_op(None, UnaryOp::LogicalNegate, self.u64_type, high); - let not_low = self.context.new_unary_op(None, UnaryOp::LogicalNegate, self.u64_type, low); + let not_high = self.context.new_unary_op(self.location, UnaryOp::LogicalNegate, self.u64_type, high); + let not_low = self.context.new_unary_op(self.location, UnaryOp::LogicalNegate, self.u64_type, low); let not_low_and_not_high = not_low & not_high; let index = not_high + not_low_and_not_high; // NOTE: the following cast is necessary to avoid a GIMPLE verification failure in // gcc. // TODO(antoyo): do the correct verification in libgccjit to avoid an error at the // compilation stage. - let index = self.context.new_cast(None, index, self.i32_type); + let index = self.context.new_cast(self.location, index, self.i32_type); - let res = self.context.new_array_access(None, result, index); + let res = self.context.new_array_access(self.location, result, index); return self.gcc_int_cast(res.to_rvalue(), arg_type); } else { let count_leading_zeroes = self.context.get_builtin_function("__builtin_clzll"); - let arg = self.context.new_cast(None, arg, self.ulonglong_type); + let arg = self.context.new_cast(self.location, arg, self.ulonglong_type); let diff = self.ulonglong_type.get_size() as i64 - arg_type.get_size() as i64; let diff = self.context.new_rvalue_from_long(self.int_type, diff * 8); - let res = self.context.new_call(None, count_leading_zeroes, &[arg]) - diff; - return self.context.new_cast(None, res, arg_type); + let res = self.context.new_call(self.location, count_leading_zeroes, &[arg]) - diff; + return self.context.new_cast(self.location, res, arg_type); }; let count_leading_zeroes = self.context.get_builtin_function(count_leading_zeroes); - let res = self.context.new_call(None, count_leading_zeroes, &[arg]); - self.context.new_cast(None, res, arg_type) + let res = self.context.new_call(self.location, count_leading_zeroes, &[arg]); + self.context.new_cast(self.location, res, arg_type) } fn count_trailing_zeroes(&mut self, _width: u64, arg: RValue<'gcc>) -> RValue<'gcc> { let result_type = arg.get_type(); - let arg = - if result_type.is_signed(self.cx) { - let new_type = result_type.to_unsigned(self.cx); - self.gcc_int_cast(arg, new_type) - } - else { - arg - }; + let arg = if result_type.is_signed(self.cx) { + let new_type = result_type.to_unsigned(self.cx); + self.gcc_int_cast(arg, new_type) + } else { + arg + }; let arg_type = arg.get_type(); let (count_trailing_zeroes, expected_type) = // TODO(antoyo): write a new function Type::is_compatible_with(&Type) and use it here @@ -766,58 +807,56 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { let ctzll = self.context.get_builtin_function("__builtin_ctzll"); - let first_elem = self.context.new_array_access(None, result, zero); - let first_value = self.gcc_int_cast(self.context.new_call(None, ctzll, &[low]), arg_type); + let first_elem = self.context.new_array_access(self.location, result, zero); + let first_value = self.gcc_int_cast(self.context.new_call(self.location, ctzll, &[low]), arg_type); self.llbb() - .add_assignment(None, first_elem, first_value); + .add_assignment(self.location, first_elem, first_value); - let second_elem = self.context.new_array_access(None, result, one); - let second_value = self.gcc_add(self.gcc_int_cast(self.context.new_call(None, ctzll, &[high]), arg_type), sixty_four); + let second_elem = self.context.new_array_access(self.location, result, one); + let second_value = self.gcc_add(self.gcc_int_cast(self.context.new_call(self.location, ctzll, &[high]), arg_type), sixty_four); self.llbb() - .add_assignment(None, second_elem, second_value); + .add_assignment(self.location, second_elem, second_value); - let third_elem = self.context.new_array_access(None, result, two); + let third_elem = self.context.new_array_access(self.location, result, two); let third_value = self.gcc_int(arg_type, 128); self.llbb() - .add_assignment(None, third_elem, third_value); + .add_assignment(self.location, third_elem, third_value); - let not_low = self.context.new_unary_op(None, UnaryOp::LogicalNegate, self.u64_type, low); - let not_high = self.context.new_unary_op(None, UnaryOp::LogicalNegate, self.u64_type, high); + let not_low = self.context.new_unary_op(self.location, UnaryOp::LogicalNegate, self.u64_type, low); + let not_high = self.context.new_unary_op(self.location, UnaryOp::LogicalNegate, self.u64_type, high); let not_low_and_not_high = not_low & not_high; let index = not_low + not_low_and_not_high; // NOTE: the following cast is necessary to avoid a GIMPLE verification failure in // gcc. // TODO(antoyo): do the correct verification in libgccjit to avoid an error at the // compilation stage. - let index = self.context.new_cast(None, index, self.i32_type); + let index = self.context.new_cast(self.location, index, self.i32_type); - let res = self.context.new_array_access(None, result, index); + let res = self.context.new_array_access(self.location, result, index); return self.gcc_int_cast(res.to_rvalue(), result_type); } else { let count_trailing_zeroes = self.context.get_builtin_function("__builtin_ctzll"); let arg_size = arg_type.get_size(); - let casted_arg = self.context.new_cast(None, arg, self.ulonglong_type); + let casted_arg = self.context.new_cast(self.location, arg, self.ulonglong_type); let byte_diff = self.ulonglong_type.get_size() as i64 - arg_size as i64; let diff = self.context.new_rvalue_from_long(self.int_type, byte_diff * 8); let mask = self.context.new_rvalue_from_long(arg_type, -1); // To get the value with all bits set. - let masked = mask & self.context.new_unary_op(None, UnaryOp::BitwiseNegate, arg_type, arg); - let cond = self.context.new_comparison(None, ComparisonOp::Equals, masked, mask); - let diff = diff * self.context.new_cast(None, cond, self.int_type); - let res = self.context.new_call(None, count_trailing_zeroes, &[casted_arg]) - diff; - return self.context.new_cast(None, res, result_type); + let masked = mask & self.context.new_unary_op(self.location, UnaryOp::BitwiseNegate, arg_type, arg); + let cond = self.context.new_comparison(self.location, ComparisonOp::Equals, masked, mask); + let diff = diff * self.context.new_cast(self.location, cond, self.int_type); + let res = self.context.new_call(self.location, count_trailing_zeroes, &[casted_arg]) - diff; + return self.context.new_cast(self.location, res, result_type); }; let count_trailing_zeroes = self.context.get_builtin_function(count_trailing_zeroes); - let arg = - if arg_type != expected_type { - self.context.new_cast(None, arg, expected_type) - } - else { - arg - }; - let res = self.context.new_call(None, count_trailing_zeroes, &[arg]); - self.context.new_cast(None, res, result_type) + let arg = if arg_type != expected_type { + self.context.new_cast(self.location, arg, expected_type) + } else { + arg + }; + let res = self.context.new_call(self.location, count_trailing_zeroes, &[arg]); + self.context.new_cast(self.location, res, result_type) } fn pop_count(&mut self, value: RValue<'gcc>) -> RValue<'gcc> { @@ -825,13 +864,11 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { let result_type = value.get_type(); let value_type = result_type.to_unsigned(self.cx); - let value = - if result_type.is_signed(self.cx) { - self.gcc_int_cast(value, value_type) - } - else { - value - }; + let value = if result_type.is_signed(self.cx) { + self.gcc_int_cast(value, value_type) + } else { + value + }; // only break apart 128-bit ints if they're not natively supported // TODO(antoyo): remove this if/when native 128-bit integers land in libgccjit @@ -859,8 +896,8 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { let counter = self.current_func().new_local(None, counter_type, "popcount_counter"); let val = self.current_func().new_local(None, value_type, "popcount_value"); let zero = self.gcc_zero(counter_type); - self.llbb().add_assignment(None, counter, zero); - self.llbb().add_assignment(None, val, value); + self.llbb().add_assignment(self.location, counter, zero); + self.llbb().add_assignment(self.location, val, value); self.br(loop_head); // check if value isn't zero @@ -874,12 +911,12 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { let one = self.gcc_int(value_type, 1); let sub = self.gcc_sub(val.to_rvalue(), one); let op = self.gcc_and(val.to_rvalue(), sub); - loop_body.add_assignment(None, val, op); + loop_body.add_assignment(self.location, val, op); // counter += 1 let one = self.gcc_int(counter_type, 1); let op = self.gcc_add(counter.to_rvalue(), one); - loop_body.add_assignment(None, counter, op); + loop_body.add_assignment(self.location, counter, op); self.br(loop_head); // end of loop @@ -888,66 +925,70 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { } // Algorithm from: https://blog.regehr.org/archives/1063 - fn rotate_left(&mut self, value: RValue<'gcc>, shift: RValue<'gcc>, width: u64) -> RValue<'gcc> { + fn rotate_left( + &mut self, + value: RValue<'gcc>, + shift: RValue<'gcc>, + width: u64, + ) -> RValue<'gcc> { let max = self.const_uint(shift.get_type(), width); let shift = self.urem(shift, max); let lhs = self.shl(value, shift); let result_neg = self.neg(shift); - let result_and = - self.and( - result_neg, - self.const_uint(shift.get_type(), width - 1), - ); + let result_and = self.and(result_neg, self.const_uint(shift.get_type(), width - 1)); let rhs = self.lshr(value, result_and); self.or(lhs, rhs) } // Algorithm from: https://blog.regehr.org/archives/1063 - fn rotate_right(&mut self, value: RValue<'gcc>, shift: RValue<'gcc>, width: u64) -> RValue<'gcc> { + fn rotate_right( + &mut self, + value: RValue<'gcc>, + shift: RValue<'gcc>, + width: u64, + ) -> RValue<'gcc> { let max = self.const_uint(shift.get_type(), width); let shift = self.urem(shift, max); let lhs = self.lshr(value, shift); let result_neg = self.neg(shift); - let result_and = - self.and( - result_neg, - self.const_uint(shift.get_type(), width - 1), - ); + let result_and = self.and(result_neg, self.const_uint(shift.get_type(), width - 1)); let rhs = self.shl(value, result_and); self.or(lhs, rhs) } - fn saturating_add(&mut self, lhs: RValue<'gcc>, rhs: RValue<'gcc>, signed: bool, width: u64) -> RValue<'gcc> { + fn saturating_add( + &mut self, + lhs: RValue<'gcc>, + rhs: RValue<'gcc>, + signed: bool, + width: u64, + ) -> RValue<'gcc> { let result_type = lhs.get_type(); if signed { // Based on algorithm from: https://stackoverflow.com/a/56531252/389119 let func = self.current_func.borrow().expect("func"); - let res = func.new_local(None, result_type, "saturating_sum"); + let res = func.new_local(self.location, result_type, "saturating_sum"); let supports_native_type = self.is_native_int_type(result_type); - let overflow = - if supports_native_type { - let func_name = - match width { - 8 => "__builtin_add_overflow", - 16 => "__builtin_add_overflow", - 32 => "__builtin_sadd_overflow", - 64 => "__builtin_saddll_overflow", - 128 => "__builtin_add_overflow", - _ => unreachable!(), - }; - let overflow_func = self.context.get_builtin_function(func_name); - self.overflow_call(overflow_func, &[lhs, rhs, res.get_address(None)], None) - } - else { - let func_name = - match width { - 128 => "__rust_i128_addo", - _ => unreachable!(), - }; - let (int_result, overflow) = self.operation_with_overflow(func_name, lhs, rhs); - self.llbb().add_assignment(None, res, int_result); - overflow + let overflow = if supports_native_type { + let func_name = match width { + 8 => "__builtin_add_overflow", + 16 => "__builtin_add_overflow", + 32 => "__builtin_sadd_overflow", + 64 => "__builtin_saddll_overflow", + 128 => "__builtin_add_overflow", + _ => unreachable!(), + }; + let overflow_func = self.context.get_builtin_function(func_name); + self.overflow_call(overflow_func, &[lhs, rhs, res.get_address(self.location)], None) + } else { + let func_name = match width { + 128 => "__rust_i128_addo", + _ => unreachable!(), }; + let (int_result, overflow) = self.operation_with_overflow(func_name, lhs, rhs); + self.llbb().add_assignment(self.location, res, int_result); + overflow + }; let then_block = func.new_block("then"); let after_block = func.new_block("after"); @@ -955,83 +996,97 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { // Return `result_type`'s maximum or minimum value on overflow // NOTE: convert the type to unsigned to have an unsigned shift. let unsigned_type = result_type.to_unsigned(&self.cx); - let shifted = self.gcc_lshr(self.gcc_int_cast(lhs, unsigned_type), self.gcc_int(unsigned_type, width as i64 - 1)); + let shifted = self.gcc_lshr( + self.gcc_int_cast(lhs, unsigned_type), + self.gcc_int(unsigned_type, width as i64 - 1), + ); let uint_max = self.gcc_not(self.gcc_int(unsigned_type, 0)); let int_max = self.gcc_lshr(uint_max, self.gcc_int(unsigned_type, 1)); - then_block.add_assignment(None, res, self.gcc_int_cast(self.gcc_add(shifted, int_max), result_type)); - then_block.end_with_jump(None, after_block); + then_block.add_assignment( + self.location, + res, + self.gcc_int_cast(self.gcc_add(shifted, int_max), result_type), + ); + then_block.end_with_jump(self.location, after_block); - self.llbb().end_with_conditional(None, overflow, then_block, after_block); + self.llbb().end_with_conditional(self.location, overflow, then_block, after_block); // NOTE: since jumps were added in a place rustc does not // expect, the current block in the state need to be updated. self.switch_to_block(after_block); res.to_rvalue() - } - else { + } else { // Algorithm from: http://locklessinc.com/articles/sat_arithmetic/ let res = self.gcc_add(lhs, rhs); let cond = self.gcc_icmp(IntPredicate::IntULT, res, lhs); let value = self.gcc_neg(self.gcc_int_cast(cond, result_type)); - self.gcc_or(res, value) + self.gcc_or(res, value, self.location) } } // Algorithm from: https://locklessinc.com/articles/sat_arithmetic/ - fn saturating_sub(&mut self, lhs: RValue<'gcc>, rhs: RValue<'gcc>, signed: bool, width: u64) -> RValue<'gcc> { + fn saturating_sub( + &mut self, + lhs: RValue<'gcc>, + rhs: RValue<'gcc>, + signed: bool, + width: u64, + ) -> RValue<'gcc> { let result_type = lhs.get_type(); if signed { // Based on algorithm from: https://stackoverflow.com/a/56531252/389119 let func = self.current_func.borrow().expect("func"); - let res = func.new_local(None, result_type, "saturating_diff"); + let res = func.new_local(self.location, result_type, "saturating_diff"); let supports_native_type = self.is_native_int_type(result_type); - let overflow = - if supports_native_type { - let func_name = - match width { - 8 => "__builtin_sub_overflow", - 16 => "__builtin_sub_overflow", - 32 => "__builtin_ssub_overflow", - 64 => "__builtin_ssubll_overflow", - 128 => "__builtin_sub_overflow", - _ => unreachable!(), - }; - let overflow_func = self.context.get_builtin_function(func_name); - self.overflow_call(overflow_func, &[lhs, rhs, res.get_address(None)], None) - } - else { - let func_name = - match width { - 128 => "__rust_i128_subo", - _ => unreachable!(), - }; - let (int_result, overflow) = self.operation_with_overflow(func_name, lhs, rhs); - self.llbb().add_assignment(None, res, int_result); - overflow + let overflow = if supports_native_type { + let func_name = match width { + 8 => "__builtin_sub_overflow", + 16 => "__builtin_sub_overflow", + 32 => "__builtin_ssub_overflow", + 64 => "__builtin_ssubll_overflow", + 128 => "__builtin_sub_overflow", + _ => unreachable!(), }; + let overflow_func = self.context.get_builtin_function(func_name); + self.overflow_call(overflow_func, &[lhs, rhs, res.get_address(self.location)], None) + } else { + let func_name = match width { + 128 => "__rust_i128_subo", + _ => unreachable!(), + }; + let (int_result, overflow) = self.operation_with_overflow(func_name, lhs, rhs); + self.llbb().add_assignment(self.location, res, int_result); + overflow + }; let then_block = func.new_block("then"); let after_block = func.new_block("after"); // Return `result_type`'s maximum or minimum value on overflow // NOTE: convert the type to unsigned to have an unsigned shift. - let unsigned_type = result_type.to_unsigned(&self.cx); - let shifted = self.gcc_lshr(self.gcc_int_cast(lhs, unsigned_type), self.gcc_int(unsigned_type, width as i64 - 1)); + let unsigned_type = result_type.to_unsigned(self.cx); + let shifted = self.gcc_lshr( + self.gcc_int_cast(lhs, unsigned_type), + self.gcc_int(unsigned_type, width as i64 - 1), + ); let uint_max = self.gcc_not(self.gcc_int(unsigned_type, 0)); let int_max = self.gcc_lshr(uint_max, self.gcc_int(unsigned_type, 1)); - then_block.add_assignment(None, res, self.gcc_int_cast(self.gcc_add(shifted, int_max), result_type)); - then_block.end_with_jump(None, after_block); + then_block.add_assignment( + self.location, + res, + self.gcc_int_cast(self.gcc_add(shifted, int_max), result_type), + ); + then_block.end_with_jump(self.location, after_block); - self.llbb().end_with_conditional(None, overflow, then_block, after_block); + self.llbb().end_with_conditional(self.location, overflow, then_block, after_block); // NOTE: since jumps were added in a place rustc does not // expect, the current block in the state need to be updated. self.switch_to_block(after_block); res.to_rvalue() - } - else { + } else { let res = self.gcc_sub(lhs, rhs); let comparison = self.gcc_icmp(IntPredicate::IntULE, res, lhs); let value = self.gcc_neg(self.gcc_int_cast(comparison, result_type)); @@ -1040,21 +1095,26 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { } } -fn try_intrinsic<'a, 'b, 'gcc, 'tcx>(bx: &'b mut Builder<'a, 'gcc, 'tcx>, try_func: RValue<'gcc>, data: RValue<'gcc>, _catch_func: RValue<'gcc>, dest: RValue<'gcc>) { +fn try_intrinsic<'a, 'b, 'gcc, 'tcx>( + bx: &'b mut Builder<'a, 'gcc, 'tcx>, + try_func: RValue<'gcc>, + data: RValue<'gcc>, + _catch_func: RValue<'gcc>, + dest: RValue<'gcc>, +) { if bx.sess().panic_strategy() == PanicStrategy::Abort { bx.call(bx.type_void(), None, None, try_func, &[data], None); // Return 0 unconditionally from the intrinsic call; // we can never unwind. let ret_align = bx.tcx.data_layout.i32_align.abi; bx.store(bx.const_i32(0), dest, ret_align); - } - else if wants_msvc_seh(bx.sess()) { - unimplemented!(); - } - else { - #[cfg(feature="master")] + } else { + if wants_msvc_seh(bx.sess()) { + unimplemented!(); + } + #[cfg(feature = "master")] codegen_gnu_try(bx, try_func, data, _catch_func, dest); - #[cfg(not(feature="master"))] + #[cfg(not(feature = "master"))] unimplemented!(); } } @@ -1070,8 +1130,14 @@ fn try_intrinsic<'a, 'b, 'gcc, 'tcx>(bx: &'b mut Builder<'a, 'gcc, 'tcx>, try_fu // function calling it, and that function may already have other personality // functions in play. By calling a shim we're guaranteed that our shim will have // the right personality function. -#[cfg(feature="master")] -fn codegen_gnu_try<'gcc>(bx: &mut Builder<'_, 'gcc, '_>, try_func: RValue<'gcc>, data: RValue<'gcc>, catch_func: RValue<'gcc>, dest: RValue<'gcc>) { +#[cfg(feature = "master")] +fn codegen_gnu_try<'gcc>( + bx: &mut Builder<'_, 'gcc, '_>, + try_func: RValue<'gcc>, + data: RValue<'gcc>, + catch_func: RValue<'gcc>, + dest: RValue<'gcc>, +) { let cx: &CodegenCx<'gcc, '_> = bx.cx; let (llty, func) = get_rust_try_fn(cx, &mut |mut bx| { // Codegens the shims described above: @@ -1095,7 +1161,7 @@ fn codegen_gnu_try<'gcc>(bx: &mut Builder<'_, 'gcc, '_>, try_func: RValue<'gcc>, let catch_func = func.get_param(2).to_rvalue(); let try_func_ty = bx.type_func(&[bx.type_i8p()], bx.type_void()); - let current_block = bx.block.clone(); + let current_block = bx.block; bx.switch_to_block(then); bx.ret(bx.const_i32(0)); @@ -1130,36 +1196,44 @@ fn codegen_gnu_try<'gcc>(bx: &mut Builder<'_, 'gcc, '_>, try_func: RValue<'gcc>, bx.store(ret, dest, i32_align); } - // Helper function used to get a handle to the `__rust_try` function used to // catch exceptions. // // This function is only generated once and is then cached. -#[cfg(feature="master")] -fn get_rust_try_fn<'a, 'gcc, 'tcx>(cx: &'a CodegenCx<'gcc, 'tcx>, codegen: &mut dyn FnMut(Builder<'a, 'gcc, 'tcx>)) -> (Type<'gcc>, Function<'gcc>) { +#[cfg(feature = "master")] +fn get_rust_try_fn<'a, 'gcc, 'tcx>( + cx: &'a CodegenCx<'gcc, 'tcx>, + codegen: &mut dyn FnMut(Builder<'a, 'gcc, 'tcx>), +) -> (Type<'gcc>, Function<'gcc>) { if let Some(llfn) = cx.rust_try_fn.get() { return llfn; } // Define the type up front for the signature of the rust_try function. let tcx = cx.tcx; - let i8p = Ty::new_mut_ptr(tcx,tcx.types.i8); + let i8p = Ty::new_mut_ptr(tcx, tcx.types.i8); // `unsafe fn(*mut i8) -> ()` - let try_fn_ty = Ty::new_fn_ptr(tcx,ty::Binder::dummy(tcx.mk_fn_sig( - iter::once(i8p), - Ty::new_unit(tcx,), - false, - rustc_hir::Unsafety::Unsafe, - Abi::Rust, - ))); + let try_fn_ty = Ty::new_fn_ptr( + tcx, + ty::Binder::dummy(tcx.mk_fn_sig( + iter::once(i8p), + Ty::new_unit(tcx), + false, + rustc_hir::Unsafety::Unsafe, + Abi::Rust, + )), + ); // `unsafe fn(*mut i8, *mut i8) -> ()` - let catch_fn_ty = Ty::new_fn_ptr(tcx,ty::Binder::dummy(tcx.mk_fn_sig( - [i8p, i8p].iter().cloned(), - Ty::new_unit(tcx,), - false, - rustc_hir::Unsafety::Unsafe, - Abi::Rust, - ))); + let catch_fn_ty = Ty::new_fn_ptr( + tcx, + ty::Binder::dummy(tcx.mk_fn_sig( + [i8p, i8p].iter().cloned(), + Ty::new_unit(tcx), + false, + rustc_hir::Unsafety::Unsafe, + Abi::Rust, + )), + ); // `unsafe fn(unsafe fn(*mut i8) -> (), *mut i8, unsafe fn(*mut i8, *mut i8) -> ()) -> i32` let rust_fn_sig = ty::Binder::dummy(cx.tcx.mk_fn_sig( [try_fn_ty, i8p, catch_fn_ty], @@ -1175,8 +1249,13 @@ fn get_rust_try_fn<'a, 'gcc, 'tcx>(cx: &'a CodegenCx<'gcc, 'tcx>, codegen: &mut // Helper function to give a Block to a closure to codegen a shim function. // This is currently primarily used for the `try` intrinsic functions above. -#[cfg(feature="master")] -fn gen_fn<'a, 'gcc, 'tcx>(cx: &'a CodegenCx<'gcc, 'tcx>, name: &str, rust_fn_sig: ty::PolyFnSig<'tcx>, codegen: &mut dyn FnMut(Builder<'a, 'gcc, 'tcx>)) -> (Type<'gcc>, Function<'gcc>) { +#[cfg(feature = "master")] +fn gen_fn<'a, 'gcc, 'tcx>( + cx: &'a CodegenCx<'gcc, 'tcx>, + name: &str, + rust_fn_sig: ty::PolyFnSig<'tcx>, + codegen: &mut dyn FnMut(Builder<'a, 'gcc, 'tcx>), +) -> (Type<'gcc>, Function<'gcc>) { let fn_abi = cx.fn_abi_of_fn_ptr(rust_fn_sig, ty::List::empty()); let return_type = fn_abi.gcc_type(cx).return_type; // FIXME(eddyb) find a nicer way to do this. diff --git a/src/intrinsic/simd.rs b/src/intrinsic/simd.rs index d8091724d8647..e9af34059a0ec 100644 --- a/src/intrinsic/simd.rs +++ b/src/intrinsic/simd.rs @@ -1,3 +1,5 @@ +use std::iter::FromIterator; + use gccjit::ToRValue; use gccjit::{BinaryOp, RValue, Type}; #[cfg(feature = "master")] @@ -19,6 +21,8 @@ use rustc_span::{sym, Span, Symbol}; use rustc_target::abi::Align; use crate::builder::Builder; +#[cfg(not(feature = "master"))] +use crate::common::SignType; #[cfg(feature = "master")] use crate::context::CodegenCx; @@ -156,6 +160,197 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( return Ok(compare_simd_types(bx, arg1, arg2, in_elem, llret_ty, cmp_op)); } + let simd_bswap = |bx: &mut Builder<'a, 'gcc, 'tcx>, vector: RValue<'gcc>| -> RValue<'gcc> { + let v_type = vector.get_type(); + let vector_type = v_type.unqualified().dyncast_vector().expect("vector type"); + let elem_type = vector_type.get_element_type(); + let elem_size_bytes = elem_type.get_size(); + if elem_size_bytes == 1 { + return vector; + } + + let type_size_bytes = elem_size_bytes as u64 * in_len; + let shuffle_indices = Vec::from_iter(0..type_size_bytes); + let byte_vector_type = bx.context.new_vector_type(bx.type_u8(), type_size_bytes); + let byte_vector = bx.context.new_bitcast(None, args[0].immediate(), byte_vector_type); + + #[cfg(not(feature = "master"))] + let shuffled = { + let new_elements: Vec<_> = shuffle_indices + .chunks_exact(elem_size_bytes as _) + .flat_map(|x| x.iter().rev()) + .map(|&i| { + let index = bx.context.new_rvalue_from_long(bx.u64_type, i as _); + bx.extract_element(byte_vector, index) + }) + .collect(); + + bx.context.new_rvalue_from_vector(None, byte_vector_type, &new_elements) + }; + #[cfg(feature = "master")] + let shuffled = { + let indices: Vec<_> = shuffle_indices + .chunks_exact(elem_size_bytes as _) + .flat_map(|x| x.iter().rev()) + .map(|&i| bx.context.new_rvalue_from_int(bx.u8_type, i as _)) + .collect(); + + let mask = bx.context.new_rvalue_from_vector(None, byte_vector_type, &indices); + bx.context.new_rvalue_vector_perm(None, byte_vector, byte_vector, mask) + }; + bx.context.new_bitcast(None, shuffled, v_type) + }; + + if name == sym::simd_bswap || name == sym::simd_bitreverse { + require!( + bx.type_kind(bx.element_type(llret_ty)) == TypeKind::Integer, + InvalidMonomorphization::UnsupportedOperation { span, name, in_ty, in_elem } + ); + } + + if name == sym::simd_bswap { + return Ok(simd_bswap(bx, args[0].immediate())); + } + + // We use a different algorithm from non-vector bitreverse to take advantage of most + // processors' vector shuffle units. It works like this: + // 1. Generate pre-reversed low and high nibbles as a vector. + // 2. Byte-swap the input. + // 3. Mask off the low and high nibbles of each byte in the byte-swapped input. + // 4. Shuffle the pre-reversed low and high-nibbles using the masked nibbles as a shuffle mask. + // 5. Combine the results of the shuffle back together and cast back to the original type. + #[cfg(feature = "master")] + if name == sym::simd_bitreverse { + let vector = args[0].immediate(); + let v_type = vector.get_type(); + let vector_type = v_type.unqualified().dyncast_vector().expect("vector type"); + let elem_type = vector_type.get_element_type(); + let elem_size_bytes = elem_type.get_size(); + + let type_size_bytes = elem_size_bytes as u64 * in_len; + // We need to ensure at least 16 entries in our vector type, since the pre-reversed vectors + // we generate below have 16 entries in them. `new_rvalue_vector_perm` requires the mask + // vector to be of the same length as the source vectors. + let byte_vector_type_size = type_size_bytes.max(16); + + let byte_vector_type = bx.context.new_vector_type(bx.u8_type, type_size_bytes); + let long_byte_vector_type = bx.context.new_vector_type(bx.u8_type, byte_vector_type_size); + + // Step 1: Generate pre-reversed low and high nibbles as a vector. + let zero_byte = bx.context.new_rvalue_zero(bx.u8_type); + let hi_nibble_elements: Vec<_> = (0u8..16) + .map(|x| bx.context.new_rvalue_from_int(bx.u8_type, x.reverse_bits() as _)) + .chain((16..byte_vector_type_size).map(|_| zero_byte)) + .collect(); + let hi_nibble = + bx.context.new_rvalue_from_vector(None, long_byte_vector_type, &hi_nibble_elements); + + let lo_nibble_elements: Vec<_> = (0u8..16) + .map(|x| bx.context.new_rvalue_from_int(bx.u8_type, (x.reverse_bits() >> 4) as _)) + .chain((16..byte_vector_type_size).map(|_| zero_byte)) + .collect(); + let lo_nibble = + bx.context.new_rvalue_from_vector(None, long_byte_vector_type, &lo_nibble_elements); + + let mask = bx.context.new_rvalue_from_vector( + None, + long_byte_vector_type, + &vec![bx.context.new_rvalue_from_int(bx.u8_type, 0x0f); byte_vector_type_size as _], + ); + + let four_vec = bx.context.new_rvalue_from_vector( + None, + long_byte_vector_type, + &vec![bx.context.new_rvalue_from_int(bx.u8_type, 4); byte_vector_type_size as _], + ); + + // Step 2: Byte-swap the input. + let swapped = simd_bswap(bx, args[0].immediate()); + let byte_vector = bx.context.new_bitcast(None, swapped, byte_vector_type); + + // We're going to need to extend the vector with zeros to make sure that the types are the + // same, since that's what new_rvalue_vector_perm expects. + let byte_vector = if byte_vector_type_size > type_size_bytes { + let mut byte_vector_elements = Vec::with_capacity(byte_vector_type_size as _); + for i in 0..type_size_bytes { + let idx = bx.context.new_rvalue_from_int(bx.u32_type, i as _); + let val = bx.extract_element(byte_vector, idx); + byte_vector_elements.push(val); + } + for _ in type_size_bytes..byte_vector_type_size { + byte_vector_elements.push(zero_byte); + } + bx.context.new_rvalue_from_vector(None, long_byte_vector_type, &byte_vector_elements) + } else { + bx.context.new_bitcast(None, byte_vector, long_byte_vector_type) + }; + + // Step 3: Mask off the low and high nibbles of each byte in the byte-swapped input. + let masked_hi = (byte_vector >> four_vec) & mask; + let masked_lo = byte_vector & mask; + + // Step 4: Shuffle the pre-reversed low and high-nibbles using the masked nibbles as a shuffle mask. + let hi = bx.context.new_rvalue_vector_perm(None, hi_nibble, hi_nibble, masked_lo); + let lo = bx.context.new_rvalue_vector_perm(None, lo_nibble, lo_nibble, masked_hi); + + // Step 5: Combine the results of the shuffle back together and cast back to the original type. + let result = hi | lo; + let cast_ty = + bx.context.new_vector_type(elem_type, byte_vector_type_size / (elem_size_bytes as u64)); + + // we might need to truncate if sizeof(v_type) < sizeof(cast_type) + if type_size_bytes < byte_vector_type_size { + let cast_result = bx.context.new_bitcast(None, result, cast_ty); + let elems: Vec<_> = (0..in_len) + .map(|i| { + let idx = bx.context.new_rvalue_from_int(bx.u32_type, i as _); + bx.extract_element(cast_result, idx) + }) + .collect(); + return Ok(bx.context.new_rvalue_from_vector(None, v_type, &elems)); + } else { + // avoid the unnecessary truncation as an optimization. + return Ok(bx.context.new_bitcast(None, result, v_type)); + } + } + // since gcc doesn't have vector shuffle methods available in non-patched builds, fallback to + // component-wise bitreverses if they're not available. + #[cfg(not(feature = "master"))] + if name == sym::simd_bitreverse { + let vector = args[0].immediate(); + let vector_ty = vector.get_type(); + let vector_type = vector_ty.unqualified().dyncast_vector().expect("vector type"); + let num_elements = vector_type.get_num_units(); + + let elem_type = vector_type.get_element_type(); + let elem_size_bytes = elem_type.get_size(); + let num_type = elem_type.to_unsigned(bx.cx); + let new_elements: Vec<_> = (0..num_elements) + .map(|idx| { + let index = bx.context.new_rvalue_from_long(num_type, idx as _); + let extracted_value = bx.extract_element(vector, index).to_rvalue(); + bx.bit_reverse(elem_size_bytes as u64 * 8, extracted_value) + }) + .collect(); + return Ok(bx.context.new_rvalue_from_vector(None, vector_ty, &new_elements)); + } + + if name == sym::simd_ctlz || name == sym::simd_cttz { + let vector = args[0].immediate(); + let elements: Vec<_> = (0..in_len) + .map(|i| { + let index = bx.context.new_rvalue_from_long(bx.i32_type, i as i64); + let value = bx.extract_element(vector, index).to_rvalue(); + if name == sym::simd_ctlz { + bx.count_leading_zeroes(value.get_type().get_size() as u64 * 8, value) + } else { + bx.count_trailing_zeroes(value.get_type().get_size() as u64 * 8, value) + } + }) + .collect(); + return Ok(bx.context.new_rvalue_from_vector(None, vector.get_type(), &elements)); + } + if name == sym::simd_shuffle { // Make sure this is actually an array, since typeck only checks the length-suffixed // version of this intrinsic. @@ -504,20 +699,15 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( default: RValue<'gcc>, pointers: RValue<'gcc>, mask: RValue<'gcc>, - pointer_count: usize, bx: &mut Builder<'a, 'gcc, 'tcx>, in_len: u64, - underlying_ty: Ty<'tcx>, invert: bool, ) -> RValue<'gcc> { - let vector_type = if pointer_count > 1 { - bx.context.new_vector_type(bx.usize_type, in_len) - } else { - vector_ty(bx, underlying_ty, in_len) - }; - let elem_type = vector_type.dyncast_vector().expect("vector type").get_element_type(); + let vector_type = default.get_type(); + let elem_type = + vector_type.unqualified().dyncast_vector().expect("vector type").get_element_type(); - let mut values = vec![]; + let mut values = Vec::with_capacity(in_len as usize); for i in 0..in_len { let index = bx.context.new_rvalue_from_long(bx.i32_type, i as i64); let int = bx.context.new_vector_access(None, pointers, index).to_rvalue(); @@ -530,13 +720,15 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( let vector = bx.context.new_rvalue_from_vector(None, vector_type, &values); - let mut mask_types = vec![]; - let mut mask_values = vec![]; + let mut mask_types = Vec::with_capacity(in_len as usize); + let mut mask_values = Vec::with_capacity(in_len as usize); for i in 0..in_len { let index = bx.context.new_rvalue_from_long(bx.i32_type, i as i64); mask_types.push(bx.context.new_field(None, bx.i32_type, "m")); let mask_value = bx.context.new_vector_access(None, mask, index).to_rvalue(); - let masked = bx.context.new_rvalue_from_int(bx.i32_type, in_len as i32) & mask_value; + let mask_value_cast = bx.context.new_cast(None, mask_value, bx.i32_type); + let masked = + bx.context.new_rvalue_from_int(bx.i32_type, in_len as i32) & mask_value_cast; let value = index + masked; mask_values.push(value); } @@ -665,10 +857,8 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( args[0].immediate(), args[1].immediate(), args[2].immediate(), - pointer_count, bx, in_len, - underlying_ty, false, )); } @@ -779,16 +969,8 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( } } - let result = gather( - args[0].immediate(), - args[1].immediate(), - args[2].immediate(), - pointer_count, - bx, - in_len, - underlying_ty, - true, - ); + let result = + gather(args[0].immediate(), args[1].immediate(), args[2].immediate(), bx, in_len, true); let pointers = args[1].immediate(); diff --git a/src/lib.rs b/src/lib.rs index 09ce059476ec7..a4ee3015b8d3a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -4,6 +4,7 @@ * TODO(antoyo): support LTO (gcc's equivalent to Full LTO is -flto -flto-partition=one — https://documentation.suse.com/sbp/all/html/SBP-GCC-10/index.html). * For Thin LTO, this might be helpful: * In gcc 4.6 -fwhopr was removed and became default with -flto. The non-whopr path can still be executed via -flto-partition=none. + * Or the new incremental LTO? * * Maybe some missing optizations enabled by rustc's LTO is in there: https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html * Like -fipa-icf (should be already enabled) and maybe -fdevirtualize-at-ltrans. @@ -24,9 +25,10 @@ hash_raw_entry )] #![allow(broken_intra_doc_links)] -#![recursion_limit="256"] +#![recursion_limit = "256"] #![warn(rust_2018_idioms)] #![warn(unused_lifetimes)] +#![deny(clippy::pattern_type_mismatch)] extern crate rustc_apfloat; extern crate rustc_ast; @@ -37,7 +39,8 @@ extern crate rustc_errors; extern crate rustc_fluent_macro; extern crate rustc_fs_util; extern crate rustc_hir; -#[cfg(feature="master")] +extern crate rustc_index; +#[cfg(feature = "master")] extern crate rustc_interface; extern crate rustc_macros; extern crate rustc_metadata; @@ -77,36 +80,40 @@ mod type_of; use std::any::Any; use std::fmt::Debug; -use std::sync::Arc; -use std::sync::Mutex; -#[cfg(not(feature="master"))] +#[cfg(not(feature = "master"))] use std::sync::atomic::AtomicBool; -#[cfg(not(feature="master"))] +#[cfg(not(feature = "master"))] use std::sync::atomic::Ordering; +use std::sync::Arc; +use std::sync::Mutex; +use errors::LTONotSupported; +#[cfg(not(feature = "master"))] +use gccjit::CType; use gccjit::{Context, OptimizationLevel}; -#[cfg(feature="master")] +#[cfg(feature = "master")] use gccjit::{TargetInfo, Version}; -#[cfg(not(feature="master"))] -use gccjit::CType; -use errors::LTONotSupported; use rustc_ast::expand::allocator::AllocatorKind; -use rustc_codegen_ssa::{CodegenResults, CompiledModule, ModuleCodegen}; -use rustc_codegen_ssa::base::codegen_crate; -use rustc_codegen_ssa::back::write::{CodegenContext, FatLtoInput, ModuleConfig, TargetMachineFactoryFn}; use rustc_codegen_ssa::back::lto::{LtoModuleCodegen, SerializedModule, ThinModule}; +use rustc_codegen_ssa::back::write::{ + CodegenContext, FatLtoInput, ModuleConfig, TargetMachineFactoryFn, +}; +use rustc_codegen_ssa::base::codegen_crate; +use rustc_codegen_ssa::traits::{ + CodegenBackend, ExtraBackendMethods, ThinBufferMethods, WriteBackendMethods, +}; +use rustc_codegen_ssa::{CodegenResults, CompiledModule, ModuleCodegen}; use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::sync::IntoDynSyncSend; -use rustc_codegen_ssa::traits::{CodegenBackend, ExtraBackendMethods, ThinBufferMethods, WriteBackendMethods}; -use rustc_errors::{ErrorGuaranteed, DiagCtxt}; +use rustc_errors::{DiagCtxt, ErrorGuaranteed}; use rustc_metadata::EncodedMetadata; use rustc_middle::dep_graph::{WorkProduct, WorkProductId}; -use rustc_middle::util::Providers; use rustc_middle::ty::TyCtxt; +use rustc_middle::util::Providers; use rustc_session::config::{Lto, OptLevel, OutputFilenames}; use rustc_session::Session; -use rustc_span::Symbol; use rustc_span::fatal_error::FatalError; +use rustc_span::Symbol; use tempfile::TempDir; use crate::back::lto::ModuleBuffer; @@ -124,13 +131,13 @@ impl String> Drop for PrintOnPanic { } } -#[cfg(not(feature="master"))] +#[cfg(not(feature = "master"))] #[derive(Debug)] pub struct TargetInfo { supports_128bit_integers: AtomicBool, } -#[cfg(not(feature="master"))] +#[cfg(not(feature = "master"))] impl TargetInfo { fn cpu_supports(&self, _feature: &str) -> bool { false @@ -173,26 +180,26 @@ impl CodegenBackend for GccCodegenBackend { } fn init(&self, sess: &Session) { - #[cfg(feature="master")] + #[cfg(feature = "master")] { let target_cpu = target_cpu(sess); // Get the second TargetInfo with the correct CPU features by setting the arch. let context = Context::default(); if target_cpu != "generic" { - context.add_command_line_option(&format!("-march={}", target_cpu)); + context.add_command_line_option(format!("-march={}", target_cpu)); } **self.target_info.info.lock().expect("lock") = context.get_target_info(); } - #[cfg(feature="master")] + #[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"))] + #[cfg(not(feature = "master"))] { let temp_dir = TempDir::new().expect("cannot create temporary directory"); let temp_file = temp_dir.into_path().join("result.asm"); @@ -200,39 +207,62 @@ impl CodegenBackend for GccCodegenBackend { check_context.set_print_errors_to_stderr(false); let _int128_ty = check_context.new_c_type(CType::UInt128t); // NOTE: we cannot just call compile() as this would require other files than libgccjit.so. - check_context.compile_to_file(gccjit::OutputKind::Assembler, temp_file.to_str().expect("path to str")); - self.target_info.info.lock().expect("lock").supports_128bit_integers.store(check_context.get_last_error() == Ok(None), Ordering::SeqCst); + check_context.compile_to_file( + gccjit::OutputKind::Assembler, + temp_file.to_str().expect("path to str"), + ); + self.target_info + .info + .lock() + .expect("lock") + .supports_128bit_integers + .store(check_context.get_last_error() == Ok(None), Ordering::SeqCst); } } fn provide(&self, providers: &mut Providers) { - providers.global_backend_features = - |tcx, ()| gcc_util::global_gcc_features(tcx.sess, true) + providers.global_backend_features = |tcx, ()| gcc_util::global_gcc_features(tcx.sess, true) } - fn codegen_crate<'tcx>(&self, tcx: TyCtxt<'tcx>, metadata: EncodedMetadata, need_metadata_module: bool) -> Box { + fn codegen_crate( + &self, + tcx: TyCtxt<'_>, + metadata: EncodedMetadata, + need_metadata_module: bool, + ) -> Box { let target_cpu = target_cpu(tcx.sess); - let res = codegen_crate(self.clone(), tcx, target_cpu.to_string(), metadata, need_metadata_module); + let res = codegen_crate( + self.clone(), + tcx, + target_cpu.to_string(), + metadata, + need_metadata_module, + ); Box::new(res) } - fn join_codegen(&self, ongoing_codegen: Box, sess: &Session, _outputs: &OutputFilenames) -> (CodegenResults, FxIndexMap) { + fn join_codegen( + &self, + ongoing_codegen: Box, + sess: &Session, + _outputs: &OutputFilenames, + ) -> (CodegenResults, FxIndexMap) { ongoing_codegen .downcast::>() .expect("Expected GccCodegenBackend's OngoingCodegen, found Box") .join(sess) } - fn link(&self, sess: &Session, codegen_results: CodegenResults, outputs: &OutputFilenames) -> Result<(), ErrorGuaranteed> { + fn link( + &self, + sess: &Session, + codegen_results: CodegenResults, + outputs: &OutputFilenames, + ) -> Result<(), ErrorGuaranteed> { use rustc_codegen_ssa::back::link::link_binary; - link_binary( - sess, - &crate::archive::ArArchiveBuilderBuilder, - &codegen_results, - outputs, - ) + link_binary(sess, &crate::archive::ArArchiveBuilderBuilder, &codegen_results, outputs) } fn target_features(&self, sess: &Session, allow_unstable: bool) -> Vec { @@ -245,13 +275,15 @@ fn new_context<'gcc, 'tcx>(tcx: TyCtxt<'tcx>) -> Context<'gcc> { if tcx.sess.target.arch == "x86" || tcx.sess.target.arch == "x86_64" { context.add_command_line_option("-masm=intel"); } - #[cfg(feature="master")] + #[cfg(feature = "master")] { + context.set_special_chars_allowed_in_func_names("$.*"); let version = Version::get(); let version = format!("{}.{}.{}", version.major, version.minor, version.patch); - context.set_output_ident(&format!("rustc version {} with libgccjit {}", - rustc_interface::util::rustc_version_str().unwrap_or("unknown version"), - version, + context.set_output_ident(&format!( + "rustc version {} with libgccjit {}", + rustc_interface::util::rustc_version_str().unwrap_or("unknown version"), + version, )); } // TODO(antoyo): check if this should only be added when using -Cforce-unwind-tables=n. @@ -260,26 +292,41 @@ fn new_context<'gcc, 'tcx>(tcx: TyCtxt<'tcx>) -> Context<'gcc> { } impl ExtraBackendMethods for GccCodegenBackend { - fn codegen_allocator<'tcx>(&self, tcx: TyCtxt<'tcx>, module_name: &str, kind: AllocatorKind, alloc_error_handler_kind: AllocatorKind) -> Self::Module { + fn codegen_allocator( + &self, + tcx: TyCtxt<'_>, + module_name: &str, + kind: AllocatorKind, + alloc_error_handler_kind: AllocatorKind, + ) -> Self::Module { let mut mods = GccContext { context: new_context(tcx), should_combine_object_files: false, temp_dir: None, }; - unsafe { allocator::codegen(tcx, &mut mods, module_name, kind, alloc_error_handler_kind); } + unsafe { + allocator::codegen(tcx, &mut mods, module_name, kind, alloc_error_handler_kind); + } mods } - fn compile_codegen_unit(&self, tcx: TyCtxt<'_>, cgu_name: Symbol) -> (ModuleCodegen, u64) { + fn compile_codegen_unit( + &self, + tcx: TyCtxt<'_>, + cgu_name: Symbol, + ) -> (ModuleCodegen, u64) { base::compile_codegen_unit(tcx, cgu_name, self.target_info.clone()) } - fn target_machine_factory(&self, _sess: &Session, _opt_level: OptLevel, _features: &[String]) -> TargetMachineFactoryFn { + fn target_machine_factory( + &self, + _sess: &Session, + _opt_level: OptLevel, + _features: &[String], + ) -> TargetMachineFactoryFn { // TODO(antoyo): set opt level. - Arc::new(|_| { - Ok(()) - }) + Arc::new(|_| Ok(())) } } @@ -310,11 +357,19 @@ impl WriteBackendMethods for GccCodegenBackend { type ThinData = (); type ThinBuffer = ThinBuffer; - fn run_fat_lto(cgcx: &CodegenContext, modules: Vec>, cached_modules: Vec<(SerializedModule, WorkProduct)>) -> Result, FatalError> { + fn run_fat_lto( + cgcx: &CodegenContext, + modules: Vec>, + cached_modules: Vec<(SerializedModule, WorkProduct)>, + ) -> Result, FatalError> { back::lto::run_fat(cgcx, modules, cached_modules) } - fn run_thin_lto(_cgcx: &CodegenContext, _modules: Vec<(String, Self::ThinBuffer)>, _cached_modules: Vec<(SerializedModule, WorkProduct)>) -> Result<(Vec>, Vec), FatalError> { + fn run_thin_lto( + _cgcx: &CodegenContext, + _modules: Vec<(String, Self::ThinBuffer)>, + _cached_modules: Vec<(SerializedModule, WorkProduct)>, + ) -> Result<(Vec>, Vec), FatalError> { unimplemented!(); } @@ -326,21 +381,37 @@ impl WriteBackendMethods for GccCodegenBackend { unimplemented!() } - unsafe fn optimize(_cgcx: &CodegenContext, _dcx: &DiagCtxt, module: &ModuleCodegen, config: &ModuleConfig) -> Result<(), FatalError> { + unsafe fn optimize( + _cgcx: &CodegenContext, + _dcx: &DiagCtxt, + module: &ModuleCodegen, + config: &ModuleConfig, + ) -> Result<(), FatalError> { module.module_llvm.context.set_optimization_level(to_gcc_opt_level(config.opt_level)); Ok(()) } - fn optimize_fat(_cgcx: &CodegenContext, _module: &mut ModuleCodegen) -> Result<(), FatalError> { + fn optimize_fat( + _cgcx: &CodegenContext, + _module: &mut ModuleCodegen, + ) -> Result<(), FatalError> { // TODO(antoyo) Ok(()) } - unsafe fn optimize_thin(_cgcx: &CodegenContext, _thin: ThinModule) -> Result, FatalError> { + unsafe fn optimize_thin( + _cgcx: &CodegenContext, + _thin: ThinModule, + ) -> Result, FatalError> { unimplemented!(); } - unsafe fn codegen(cgcx: &CodegenContext, dcx: &DiagCtxt, module: ModuleCodegen, config: &ModuleConfig) -> Result { + unsafe fn codegen( + cgcx: &CodegenContext, + dcx: &DiagCtxt, + module: ModuleCodegen, + config: &ModuleConfig, + ) -> Result { back::write::codegen(cgcx, dcx, module, config) } @@ -352,7 +423,11 @@ impl WriteBackendMethods for GccCodegenBackend { unimplemented!(); } - fn run_link(cgcx: &CodegenContext, dcx: &DiagCtxt, modules: Vec>) -> Result, FatalError> { + fn run_link( + cgcx: &CodegenContext, + dcx: &DiagCtxt, + modules: Vec>, + ) -> Result, FatalError> { back::write::link(cgcx, dcx, modules) } } @@ -360,56 +435,57 @@ impl WriteBackendMethods for GccCodegenBackend { /// This is the entrypoint for a hot plugged rustc_codegen_gccjit #[no_mangle] pub fn __rustc_codegen_backend() -> Box { - #[cfg(feature="master")] + #[cfg(feature = "master")] let info = { // Check whether the target supports 128-bit integers. let context = Context::default(); Arc::new(Mutex::new(IntoDynSyncSend(context.get_target_info()))) }; - #[cfg(not(feature="master"))] + #[cfg(not(feature = "master"))] let info = Arc::new(Mutex::new(IntoDynSyncSend(TargetInfo { supports_128bit_integers: AtomicBool::new(false), }))); - Box::new(GccCodegenBackend { - target_info: LockedTargetInfo { info }, - }) + Box::new(GccCodegenBackend { target_info: LockedTargetInfo { info } }) } fn to_gcc_opt_level(optlevel: Option) -> OptimizationLevel { match optlevel { None => OptimizationLevel::None, - Some(level) => { - match level { - OptLevel::No => OptimizationLevel::None, - OptLevel::Less => OptimizationLevel::Limited, - OptLevel::Default => OptimizationLevel::Standard, - OptLevel::Aggressive => OptimizationLevel::Aggressive, - OptLevel::Size | OptLevel::SizeMin => OptimizationLevel::Limited, - } + Some(level) => match level { + OptLevel::No => OptimizationLevel::None, + OptLevel::Less => OptimizationLevel::Limited, + OptLevel::Default => OptimizationLevel::Standard, + OptLevel::Aggressive => OptimizationLevel::Aggressive, + OptLevel::Size | OptLevel::SizeMin => OptimizationLevel::Limited, }, } } -pub fn target_features(sess: &Session, allow_unstable: bool, target_info: &LockedTargetInfo) -> Vec { - sess - .target +pub fn target_features( + sess: &Session, + allow_unstable: bool, + target_info: &LockedTargetInfo, +) -> Vec { + sess.target .supported_target_features() .iter() - .filter_map( - |&(feature, gate)| { - if sess.is_nightly_build() || allow_unstable || gate.is_stable() { Some(feature) } else { None } - }, - ) + .filter_map(|&(feature, gate)| { + if sess.is_nightly_build() || allow_unstable || gate.is_stable() { + Some(feature) + } else { + None + } + }) .filter(|_feature| { target_info.cpu_supports(_feature) /* - adx, aes, avx, avx2, avx512bf16, avx512bitalg, avx512bw, avx512cd, avx512dq, avx512er, avx512f, avx512fp16, avx512ifma, - avx512pf, avx512vbmi, avx512vbmi2, avx512vl, avx512vnni, avx512vp2intersect, avx512vpopcntdq, - bmi1, bmi2, cmpxchg16b, ermsb, f16c, fma, fxsr, gfni, lzcnt, movbe, pclmulqdq, popcnt, rdrand, rdseed, rtm, - sha, sse, sse2, sse3, sse4.1, sse4.2, sse4a, ssse3, tbm, vaes, vpclmulqdq, xsave, xsavec, xsaveopt, xsaves - */ + adx, aes, avx, avx2, avx512bf16, avx512bitalg, avx512bw, avx512cd, avx512dq, avx512er, avx512f, avx512fp16, avx512ifma, + avx512pf, avx512vbmi, avx512vbmi2, avx512vl, avx512vnni, avx512vp2intersect, avx512vpopcntdq, + bmi1, bmi2, cmpxchg16b, ermsb, f16c, fma, fxsr, gfni, lzcnt, movbe, pclmulqdq, popcnt, rdrand, rdseed, rtm, + sha, sse, sse2, sse3, sse4.1, sse4.2, sse4a, ssse3, tbm, vaes, vpclmulqdq, xsave, xsavec, xsaveopt, xsaves + */ }) - .map(|feature| Symbol::intern(feature)) + .map(Symbol::intern) .collect() } diff --git a/src/mono_item.rs b/src/mono_item.rs index 3322d56513bbe..e56c49686c012 100644 --- a/src/mono_item.rs +++ b/src/mono_item.rs @@ -1,11 +1,11 @@ -#[cfg(feature="master")] -use gccjit::{VarAttribute, FnAttribute}; +#[cfg(feature = "master")] +use gccjit::{FnAttribute, VarAttribute}; use rustc_codegen_ssa::traits::PreDefineMethods; use rustc_hir::def_id::{DefId, LOCAL_CRATE}; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; use rustc_middle::mir::mono::{Linkage, Visibility}; -use rustc_middle::ty::{self, Instance, TypeVisitableExt}; use rustc_middle::ty::layout::{FnAbiOf, LayoutOf}; +use rustc_middle::ty::{self, Instance, TypeVisitableExt}; use crate::attributes; use crate::base; @@ -13,8 +13,14 @@ use crate::context::CodegenCx; use crate::type_of::LayoutGccExt; impl<'gcc, 'tcx> PreDefineMethods<'tcx> for CodegenCx<'gcc, 'tcx> { - #[cfg_attr(not(feature="master"), allow(unused_variables))] - fn predefine_static(&self, def_id: DefId, _linkage: Linkage, visibility: Visibility, symbol_name: &str) { + #[cfg_attr(not(feature = "master"), allow(unused_variables))] + fn predefine_static( + &self, + def_id: DefId, + _linkage: Linkage, + visibility: Visibility, + symbol_name: &str, + ) { let attrs = self.tcx.codegen_fn_attrs(def_id); let instance = Instance::mono(self.tcx, def_id); let ty = instance.ty(self.tcx, ty::ParamEnv::reveal_all()); @@ -22,20 +28,26 @@ impl<'gcc, 'tcx> PreDefineMethods<'tcx> for CodegenCx<'gcc, 'tcx> { let is_tls = attrs.flags.contains(CodegenFnAttrFlags::THREAD_LOCAL); let global = self.define_global(symbol_name, gcc_type, is_tls, attrs.link_section); - #[cfg(feature="master")] - global.add_attribute(VarAttribute::Visibility(base::visibility_to_gcc(visibility))); + #[cfg(feature = "master")] + global.add_string_attribute(VarAttribute::Visibility(base::visibility_to_gcc(visibility))); // TODO(antoyo): set linkage. self.instances.borrow_mut().insert(instance, global); } - #[cfg_attr(not(feature="master"), allow(unused_variables))] - fn predefine_fn(&self, instance: Instance<'tcx>, linkage: Linkage, visibility: Visibility, symbol_name: &str) { + #[cfg_attr(not(feature = "master"), allow(unused_variables))] + fn predefine_fn( + &self, + instance: Instance<'tcx>, + linkage: Linkage, + visibility: Visibility, + symbol_name: &str, + ) { assert!(!instance.args.has_infer()); let fn_abi = self.fn_abi_of_instance(instance, ty::List::empty()); self.linkage.set(base::linkage_to_gcc(linkage)); - let decl = self.declare_fn(symbol_name, &fn_abi); + let decl = self.declare_fn(symbol_name, fn_abi); //let attrs = self.tcx.codegen_fn_attrs(instance.def_id()); attributes::from_fn_attrs(self, decl, instance); @@ -48,11 +60,10 @@ impl<'gcc, 'tcx> PreDefineMethods<'tcx> for CodegenCx<'gcc, 'tcx> { && linkage != Linkage::Private && self.tcx.is_compiler_builtins(LOCAL_CRATE) { - #[cfg(feature="master")] + #[cfg(feature = "master")] decl.add_attribute(FnAttribute::Visibility(gccjit::Visibility::Hidden)); - } - else { - #[cfg(feature="master")] + } else { + #[cfg(feature = "master")] decl.add_attribute(FnAttribute::Visibility(base::visibility_to_gcc(visibility))); } diff --git a/src/type_.rs b/src/type_.rs index 7e5aa1c1766df..c8e6ae69bd959 100644 --- a/src/type_.rs +++ b/src/type_.rs @@ -1,8 +1,8 @@ use gccjit::{RValue, Struct, Type}; -use rustc_codegen_ssa::traits::{BaseTypeMethods, DerivedTypeMethods, TypeMembershipMethods}; use rustc_codegen_ssa::common::TypeKind; -use rustc_middle::{bug, ty}; +use rustc_codegen_ssa::traits::{BaseTypeMethods, DerivedTypeMethods, TypeMembershipMethods}; use rustc_middle::ty::layout::TyAndLayout; +use rustc_middle::{bug, ty}; use rustc_target::abi::{AddressSpace, Align, Integer, Size}; use crate::common::TypeReflection; @@ -123,7 +123,7 @@ impl<'gcc, 'tcx> BaseTypeMethods<'tcx> for CodegenCx<'gcc, 'tcx> { fn type_f16(&self) -> Type<'gcc> { unimplemented!("f16_f128") } - + fn type_f32(&self) -> Type<'gcc> { self.float_type } @@ -136,6 +136,10 @@ impl<'gcc, 'tcx> BaseTypeMethods<'tcx> for CodegenCx<'gcc, 'tcx> { unimplemented!("f16_f128") } + fn type_f128(&self) -> Type<'gcc> { + unimplemented!("f16_f128") + } + fn type_func(&self, params: &[Type<'gcc>], return_type: Type<'gcc>) -> Type<'gcc> { self.context.new_function_pointer_type(None, return_type, params, false) } @@ -143,14 +147,18 @@ impl<'gcc, 'tcx> BaseTypeMethods<'tcx> for CodegenCx<'gcc, 'tcx> { fn type_struct(&self, fields: &[Type<'gcc>], packed: bool) -> Type<'gcc> { let types = fields.to_vec(); if let Some(typ) = self.struct_types.borrow().get(fields) { - return typ.clone(); + return *typ; } - let fields: Vec<_> = fields.iter().enumerate() - .map(|(index, field)| self.context.new_field(None, *field, &format!("field{}_TODO", index))) + let fields: Vec<_> = fields + .iter() + .enumerate() + .map(|(index, field)| { + self.context.new_field(None, *field, format!("field{}_TODO", index)) + }) .collect(); let typ = self.context.new_struct_type(None, "struct", &fields).as_type(); if packed { - #[cfg(feature="master")] + #[cfg(feature = "master")] typ.set_packed(); } self.struct_types.borrow_mut().insert(types, typ); @@ -160,17 +168,13 @@ impl<'gcc, 'tcx> BaseTypeMethods<'tcx> for CodegenCx<'gcc, 'tcx> { fn type_kind(&self, typ: Type<'gcc>) -> TypeKind { if self.is_int_type_or_bool(typ) { TypeKind::Integer - } - else if typ.is_compatible_with(self.float_type) { + } else if typ.is_compatible_with(self.float_type) { TypeKind::Float - } - else if typ.is_compatible_with(self.double_type) { + } else if typ.is_compatible_with(self.double_type) { TypeKind::Double - } - else if typ.is_vector() { + } else if typ.is_vector() { TypeKind::Vector - } - else { + } else { // TODO(antoyo): support other types. TypeKind::Void } @@ -187,14 +191,11 @@ impl<'gcc, 'tcx> BaseTypeMethods<'tcx> for CodegenCx<'gcc, 'tcx> { fn element_type(&self, ty: Type<'gcc>) -> Type<'gcc> { if let Some(typ) = ty.dyncast_array() { typ - } - else if let Some(vector_type) = ty.dyncast_vector() { + } else if let Some(vector_type) = ty.dyncast_vector() { vector_type.get_element_type() - } - else if let Some(typ) = ty.get_pointee() { + } else if let Some(typ) = ty.get_pointee() { typ - } - else { + } else { unreachable!() } } @@ -208,11 +209,9 @@ impl<'gcc, 'tcx> BaseTypeMethods<'tcx> for CodegenCx<'gcc, 'tcx> { let f64 = self.context.new_type::(); if typ.is_compatible_with(f32) { 32 - } - else if typ.is_compatible_with(f64) { + } else if typ.is_compatible_with(f64) { 64 - } - else { + } else { panic!("Cannot get width of float type {:?}", typ); } // TODO(antoyo): support other sizes. @@ -226,9 +225,9 @@ impl<'gcc, 'tcx> BaseTypeMethods<'tcx> for CodegenCx<'gcc, 'tcx> { value.get_type() } - #[cfg_attr(feature="master", allow(unused_mut))] + #[cfg_attr(feature = "master", allow(unused_mut))] fn type_array(&self, ty: Type<'gcc>, mut len: u64) -> Type<'gcc> { - #[cfg(not(feature="master"))] + #[cfg(not(feature = "master"))] if let Some(struct_type) = ty.is_struct() { if struct_type.get_field_count() == 0 { // NOTE: since gccjit only supports i32 for the array size and libcore's tests uses a @@ -252,12 +251,14 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { } pub fn set_struct_body(&self, typ: Struct<'gcc>, fields: &[Type<'gcc>], packed: bool) { - let fields: Vec<_> = fields.iter().enumerate() - .map(|(index, field)| self.context.new_field(None, *field, &format!("field_{}", index))) + let fields: Vec<_> = fields + .iter() + .enumerate() + .map(|(index, field)| self.context.new_field(None, *field, format!("field_{}", index))) .collect(); typ.set_fields(None, &fields); if packed { - #[cfg(feature="master")] + #[cfg(feature = "master")] typ.as_type().set_packed(); } } @@ -267,7 +268,10 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { } } -pub fn struct_fields<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, layout: TyAndLayout<'tcx>) -> (Vec>, bool) { +pub fn struct_fields<'gcc, 'tcx>( + cx: &CodegenCx<'gcc, 'tcx>, + layout: TyAndLayout<'tcx>, +) -> (Vec>, bool) { let field_count = layout.fields.count(); let mut packed = false; @@ -275,7 +279,7 @@ pub fn struct_fields<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, layout: TyAndLayout let mut prev_effective_align = layout.align.abi; let mut result: Vec<_> = Vec::with_capacity(1 + field_count * 2); for i in layout.fields.index_by_increasing_offset() { - let target_offset = layout.fields.offset(i as usize); + let target_offset = layout.fields.offset(i); let field = layout.field(cx, i); let effective_field_align = layout.align.abi.min(field.align.abi).restrict_for_offset(target_offset); @@ -305,5 +309,4 @@ pub fn struct_fields<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, layout: TyAndLayout (result, packed) } -impl<'gcc, 'tcx> TypeMembershipMethods<'tcx> for CodegenCx<'gcc, 'tcx> { -} +impl<'gcc, 'tcx> TypeMembershipMethods<'tcx> for CodegenCx<'gcc, 'tcx> {} diff --git a/src/type_of.rs b/src/type_of.rs index 5a9212762b7d0..8f9bfbbd18fb0 100644 --- a/src/type_of.rs +++ b/src/type_of.rs @@ -1,13 +1,16 @@ use std::fmt::Write; -use gccjit::{Struct, Type}; use crate::rustc_codegen_ssa::traits::{BaseTypeMethods, DerivedTypeMethods, LayoutTypeMethods}; +use gccjit::{Struct, Type}; use rustc_middle::bug; -use rustc_middle::ty::{self, Ty, TypeVisitableExt}; use rustc_middle::ty::layout::{LayoutOf, TyAndLayout}; use rustc_middle::ty::print::with_no_trimmed_paths; -use rustc_target::abi::{self, Abi, Align, F16, F128, F32, F64, FieldsShape, Int, Integer, Pointer, PointeeInfo, Size, TyAbiInterface, Variants}; +use rustc_middle::ty::{self, Ty, TypeVisitableExt}; use rustc_target::abi::call::{CastTarget, FnAbi, Reg}; +use rustc_target::abi::{ + self, Abi, Align, FieldsShape, Int, Integer, PointeeInfo, Pointer, Size, TyAbiInterface, + Variants, F128, F16, F32, F64, +}; use crate::abi::{FnAbiGcc, FnAbiGccExt, GccType}; use crate::context::CodegenCx; @@ -25,7 +28,7 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { } } - #[cfg(feature="master")] + #[cfg(feature = "master")] pub fn type_int_from_ty(&self, t: ty::IntTy) -> Type<'gcc> { match t { ty::IntTy::Isize => self.type_isize(), @@ -37,7 +40,7 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { } } - #[cfg(feature="master")] + #[cfg(feature = "master")] pub fn type_uint_from_ty(&self, t: ty::UintTy) -> Type<'gcc> { match t { ty::UintTy::Usize => self.type_isize(), @@ -56,7 +59,11 @@ impl<'a, 'tcx> CodegenCx<'a, 'tcx> { } } -fn uncached_gcc_type<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, layout: TyAndLayout<'tcx>, defer: &mut Option<(Struct<'gcc>, TyAndLayout<'tcx>)>) -> Type<'gcc> { +fn uncached_gcc_type<'gcc, 'tcx>( + cx: &CodegenCx<'gcc, 'tcx>, + layout: TyAndLayout<'tcx>, + defer: &mut Option<(Struct<'gcc>, TyAndLayout<'tcx>)>, +) -> Type<'gcc> { match layout.abi { Abi::Scalar(_) => bug!("handled elsewhere"), Abi::Vector { ref element, count } => { @@ -70,7 +77,7 @@ fn uncached_gcc_type<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, layout: TyAndLayout element }; return cx.context.new_vector_type(element, count); - }, + } Abi::ScalarPair(..) => { return cx.type_struct( &[ @@ -87,7 +94,12 @@ fn uncached_gcc_type<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, layout: TyAndLayout // FIXME(eddyb) producing readable type names for trait objects can result // in problematically distinct types due to HRTB and subtyping (see #47638). // ty::Dynamic(..) | - ty::Adt(..) | ty::Closure(..) | ty::CoroutineClosure(..) | ty::Foreign(..) | ty::Coroutine(..) | ty::Str + ty::Adt(..) + | ty::Closure(..) + | ty::CoroutineClosure(..) + | ty::Foreign(..) + | ty::Coroutine(..) + | ty::Str if !cx.sess().fewer_names() => { let mut name = with_no_trimmed_paths!(layout.ty.to_string()); @@ -125,22 +137,21 @@ fn uncached_gcc_type<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, layout: TyAndLayout let gcc_type = cx.type_named_struct(name); cx.set_struct_body(gcc_type, &[fill], packed); gcc_type.as_type() - }, + } } } FieldsShape::Array { count, .. } => cx.type_array(layout.field(cx, 0).gcc_type(cx), count), - FieldsShape::Arbitrary { .. } => - match name { - None => { - let (gcc_fields, packed) = struct_fields(cx, layout); - cx.type_struct(&gcc_fields, packed) - }, - Some(ref name) => { - let gcc_type = cx.type_named_struct(name); - *defer = Some((gcc_type, layout)); - gcc_type.as_type() - }, - }, + FieldsShape::Arbitrary { .. } => match name { + None => { + let (gcc_fields, packed) = struct_fields(cx, layout); + cx.type_struct(&gcc_fields, packed) + } + Some(ref name) => { + let gcc_type = cx.type_named_struct(name); + *defer = Some((gcc_type, layout)); + gcc_type.as_type() + } + }, } } @@ -149,9 +160,22 @@ pub trait LayoutGccExt<'tcx> { fn is_gcc_scalar_pair(&self) -> bool; fn gcc_type<'gcc>(&self, cx: &CodegenCx<'gcc, 'tcx>) -> Type<'gcc>; fn immediate_gcc_type<'gcc>(&self, cx: &CodegenCx<'gcc, 'tcx>) -> Type<'gcc>; - fn scalar_gcc_type_at<'gcc>(&self, cx: &CodegenCx<'gcc, 'tcx>, scalar: &abi::Scalar, offset: Size) -> Type<'gcc>; - fn scalar_pair_element_gcc_type<'gcc>(&self, cx: &CodegenCx<'gcc, 'tcx>, index: usize) -> Type<'gcc>; - fn pointee_info_at<'gcc>(&self, cx: &CodegenCx<'gcc, 'tcx>, offset: Size) -> Option; + fn scalar_gcc_type_at<'gcc>( + &self, + cx: &CodegenCx<'gcc, 'tcx>, + scalar: &abi::Scalar, + offset: Size, + ) -> Type<'gcc>; + fn scalar_pair_element_gcc_type<'gcc>( + &self, + cx: &CodegenCx<'gcc, 'tcx>, + index: usize, + ) -> Type<'gcc>; + fn pointee_info_at<'gcc>( + &self, + cx: &CodegenCx<'gcc, 'tcx>, + offset: Size, + ) -> Option; } impl<'tcx> LayoutGccExt<'tcx> for TyAndLayout<'tcx> { @@ -191,24 +215,24 @@ impl<'tcx> LayoutGccExt<'tcx> for TyAndLayout<'tcx> { if let Some(&ty) = cx.scalar_types.borrow().get(&self.ty) { return ty; } - let ty = - match *self.ty.kind() { - // NOTE: we cannot remove this match like in the LLVM codegen because the call - // to fn_ptr_backend_type handle the on-stack attribute. - // TODO(antoyo): find a less hackish way to hande the on-stack attribute. - ty::FnPtr(sig) => cx.fn_ptr_backend_type(&cx.fn_abi_of_fn_ptr(sig, ty::List::empty())), - _ => self.scalar_gcc_type_at(cx, scalar, Size::ZERO), - }; + let ty = match *self.ty.kind() { + // NOTE: we cannot remove this match like in the LLVM codegen because the call + // to fn_ptr_backend_type handle the on-stack attribute. + // TODO(antoyo): find a less hackish way to hande the on-stack attribute. + ty::FnPtr(sig) => { + cx.fn_ptr_backend_type(&cx.fn_abi_of_fn_ptr(sig, ty::List::empty())) + } + _ => self.scalar_gcc_type_at(cx, scalar, Size::ZERO), + }; cx.scalar_types.borrow_mut().insert(self.ty, ty); return ty; } // Check the cache. - let variant_index = - match self.variants { - Variants::Single { index } => Some(index), - _ => None, - }; + let variant_index = match self.variants { + Variants::Single { index } => Some(index), + _ => None, + }; let cached_type = cx.types.borrow().get(&(self.ty, variant_index)).cloned(); if let Some(ty) = cached_type { return ty; @@ -221,17 +245,15 @@ impl<'tcx> LayoutGccExt<'tcx> for TyAndLayout<'tcx> { let normal_ty = cx.tcx.erase_regions(self.ty); let mut defer = None; - let ty = - if self.ty != normal_ty { - let mut layout = cx.layout_of(normal_ty); - if let Some(v) = variant_index { - layout = layout.for_variant(cx, v); - } - layout.gcc_type(cx) + let ty = if self.ty != normal_ty { + let mut layout = cx.layout_of(normal_ty); + if let Some(v) = variant_index { + layout = layout.for_variant(cx, v); } - else { - uncached_gcc_type(cx, *self, &mut defer) - }; + layout.gcc_type(cx) + } else { + uncached_gcc_type(cx, *self, &mut defer) + }; cx.types.borrow_mut().insert((self.ty, variant_index), ty); @@ -252,7 +274,12 @@ impl<'tcx> LayoutGccExt<'tcx> for TyAndLayout<'tcx> { self.gcc_type(cx) } - fn scalar_gcc_type_at<'gcc>(&self, cx: &CodegenCx<'gcc, 'tcx>, scalar: &abi::Scalar, offset: Size) -> Type<'gcc> { + fn scalar_gcc_type_at<'gcc>( + &self, + cx: &CodegenCx<'gcc, 'tcx>, + scalar: &abi::Scalar, + offset: Size, + ) -> Type<'gcc> { match scalar.primitive() { Int(i, true) => cx.type_from_integer(i), Int(i, false) => cx.type_from_unsigned_integer(i), @@ -262,19 +289,21 @@ impl<'tcx> LayoutGccExt<'tcx> for TyAndLayout<'tcx> { F128 => cx.type_f128(), Pointer(address_space) => { // If we know the alignment, pick something better than i8. - let pointee = - if let Some(pointee) = self.pointee_info_at(cx, offset) { - cx.type_pointee_for_align(pointee.align) - } - else { - cx.type_i8() - }; + let pointee = if let Some(pointee) = self.pointee_info_at(cx, offset) { + cx.type_pointee_for_align(pointee.align) + } else { + cx.type_i8() + }; cx.type_ptr_to_ext(pointee, address_space) } } } - fn scalar_pair_element_gcc_type<'gcc>(&self, cx: &CodegenCx<'gcc, 'tcx>, index: usize) -> Type<'gcc> { + fn scalar_pair_element_gcc_type<'gcc>( + &self, + cx: &CodegenCx<'gcc, 'tcx>, + index: usize, + ) -> Type<'gcc> { // This must produce the same result for `repr(transparent)` wrappers as for the inner type! // In other words, this should generally not look at the type at all, but only at the // layout. @@ -295,13 +324,7 @@ impl<'tcx> LayoutGccExt<'tcx> for TyAndLayout<'tcx> { return cx.type_i1(); } - let offset = - if index == 0 { - Size::ZERO - } - else { - a.size(cx).align_to(b.align(cx).abi) - }; + let offset = if index == 0 { Size::ZERO } else { a.size(cx).align_to(b.align(cx).abi) }; self.scalar_gcc_type_at(cx, scalar, offset) } @@ -334,7 +357,12 @@ impl<'gcc, 'tcx> LayoutTypeMethods<'tcx> for CodegenCx<'gcc, 'tcx> { layout.is_gcc_scalar_pair() } - fn scalar_pair_element_backend_type(&self, layout: TyAndLayout<'tcx>, index: usize, _immediate: bool) -> Type<'gcc> { + fn scalar_pair_element_backend_type( + &self, + layout: TyAndLayout<'tcx>, + index: usize, + _immediate: bool, + ) -> Type<'gcc> { layout.scalar_pair_element_gcc_type(self, index) } @@ -352,12 +380,7 @@ impl<'gcc, 'tcx> LayoutTypeMethods<'tcx> for CodegenCx<'gcc, 'tcx> { fn fn_decl_backend_type(&self, fn_abi: &FnAbi<'tcx, Ty<'tcx>>) -> Type<'gcc> { // FIXME(antoyo): Should we do something with `FnAbiGcc::fn_attributes`? - let FnAbiGcc { - return_type, - arguments_type, - is_c_variadic, - .. - } = fn_abi.gcc_type(self); + let FnAbiGcc { return_type, arguments_type, is_c_variadic, .. } = fn_abi.gcc_type(self); self.context.new_function_pointer_type(None, return_type, &arguments_type, is_c_variadic) } } diff --git a/test.sh b/test.sh deleted file mode 100755 index e896237a1ea4a..0000000000000 --- a/test.sh +++ /dev/null @@ -1,479 +0,0 @@ -#!/usr/bin/env bash - -# TODO(antoyo): rewrite to cargo-make (or just) or something like that to only rebuild the sysroot when needed? - -set -e -#set -x - -flags= -gcc_master_branch=1 -channel="debug" -funcs=() -build_only=0 -nb_parts=0 -current_part=0 -use_system_gcc=0 -use_backend=0 -cargo_target_dir="" - -export CHANNEL='debug' - -while [[ $# -gt 0 ]]; do - case $1 in - --release) - codegen_channel=release - channel="release" - export CHANNEL='release' - shift - ;; - --release-sysroot) - sysroot_channel="--release" - shift - ;; - --no-default-features) - gcc_master_branch=0 - flags="$flags --no-default-features" - shift - ;; - --features) - shift - flags="$flags --features $1" - shift - ;; - "--test-rustc") - funcs+=(test_rustc) - shift - ;; - "--test-successful-rustc") - funcs+=(test_successful_rustc) - shift - ;; - "--test-failing-rustc") - funcs+=(test_failing_rustc) - shift - ;; - - "--test-libcore") - funcs+=(test_libcore) - shift - ;; - - "--clean-ui-tests") - funcs+=(clean_ui_tests) - shift - ;; - "--clean") - funcs+=(clean) - shift - ;; - - "--std-tests") - funcs+=(std_tests) - shift - ;; - - "--asm-tests") - funcs+=(asm_tests) - shift - ;; - - "--extended-tests") - funcs+=(extended_sysroot_tests) - shift - ;; - "--extended-rand-tests") - funcs+=(extended_rand_tests) - shift - ;; - "--extended-regex-example-tests") - funcs+=(extended_regex_example_tests) - shift - ;; - "--extended-regex-tests") - funcs+=(extended_regex_tests) - shift - ;; - - "--mini-tests") - funcs+=(mini_tests) - shift - ;; - - "--build-sysroot") - funcs+=(build_sysroot) - shift - ;; - "--build") - build_only=1 - shift - ;; - "--use-system-gcc") - use_system_gcc=1 - shift - ;; - "--use-backend") - use_backend=1 - shift - export BUILTIN_BACKEND=$1 - shift - ;; - "--out-dir") - shift - export CARGO_TARGET_DIR=$1 - cargo_target_dir=$1 - shift - ;; - "--nb-parts") - shift - nb_parts=$1 - shift - ;; - "--current-part") - shift - current_part=$1 - shift - ;; - *) - echo "Unknown option $1" - exit 1 - ;; - esac -done - -if [ -f ./gcc_path ]; then - export GCC_PATH=$(cat gcc_path) -elif (( $use_system_gcc == 1 )); then - echo 'Using system GCC' -else - echo 'Please put the path to your custom build of libgccjit in the file `gcc_path`, see Readme.md for details' - exit 1 -fi - -export LD_LIBRARY_PATH="$GCC_PATH" -export LIBRARY_PATH="$GCC_PATH" - -if [[ $use_backend == 0 ]]; then - if [[ $channel == "release" ]]; then - CARGO_INCREMENTAL=1 cargo rustc --release $flags - else - echo $LD_LIBRARY_PATH - cargo rustc $flags - fi -fi - -if (( $build_only == 1 )); then - echo "Since it's 'build-only', exiting..." - exit -fi - -source config.sh - -function clean() { - rm -r $cargo_target_dir || true - mkdir -p $cargo_target_dir/gccjit -} - -function mini_tests() { - echo "[BUILD] mini_core" - crate_types="lib,dylib" - - if [[ "$HOST_TRIPLE" != "$TARGET_TRIPLE" ]]; then - crate_types="lib" - fi - - $RUST_CMD example/mini_core.rs --crate-name mini_core --crate-type $crate_types --target $TARGET_TRIPLE - - echo "[BUILD] example" - $RUST_CMD example/example.rs --crate-type lib --target $TARGET_TRIPLE - - echo "[AOT] mini_core_hello_world" - $RUST_CMD example/mini_core_hello_world.rs --crate-name mini_core_hello_world --crate-type bin -g --target $TARGET_TRIPLE - $RUN_WRAPPER $cargo_target_dir/mini_core_hello_world abc bcd -} - -function build_sysroot() { - echo "[BUILD] sysroot" - time ./build_sysroot/build_sysroot.sh $sysroot_channel -} - -# TODO(GuillaumeGomez): when rewriting in Rust, refactor with the code in tests/lang_tests_common.rs if possible. -function run_in_vm() { - vm_parent_dir=${CG_GCC_VM_DIR:-$(pwd)} - vm_dir=vm - exe=$1 - exe_filename=$(basename $exe) - vm_home_dir=$vm_parent_dir/$vm_dir/home - vm_exe_path=$vm_home_dir/$exe_filename - inside_vm_exe_path=/home/$exe_filename - sudo cp $exe $vm_exe_path - - shift - pushd $vm_parent_dir - sudo chroot $vm_dir qemu-m68k-static $inside_vm_exe_path $@ - popd -} - -function std_tests() { - echo "[AOT] arbitrary_self_types_pointers_and_wrappers" - $RUST_CMD example/arbitrary_self_types_pointers_and_wrappers.rs --crate-name arbitrary_self_types_pointers_and_wrappers --crate-type bin --target $TARGET_TRIPLE - $RUN_WRAPPER $cargo_target_dir/arbitrary_self_types_pointers_and_wrappers - - echo "[AOT] alloc_system" - $RUST_CMD example/alloc_system.rs --crate-type lib --target "$TARGET_TRIPLE" - - # FIXME: doesn't work on m68k. - if [[ "$HOST_TRIPLE" == "$TARGET_TRIPLE" ]]; then - echo "[AOT] alloc_example" - $RUST_CMD example/alloc_example.rs --crate-type bin --target $TARGET_TRIPLE - $RUN_WRAPPER $cargo_target_dir/alloc_example - fi - - echo "[AOT] dst_field_align" - # FIXME(antoyo): Re-add -Zmir-opt-level=2 once rust-lang/rust#67529 is fixed. - $RUST_CMD example/dst-field-align.rs --crate-name dst_field_align --crate-type bin --target $TARGET_TRIPLE - $RUN_WRAPPER $cargo_target_dir/dst_field_align || (echo $?; false) - - echo "[AOT] std_example" - std_flags="--cfg feature=\"master\"" - if (( $gcc_master_branch == 0 )); then - std_flags="" - fi - $RUST_CMD example/std_example.rs --crate-type bin --target $TARGET_TRIPLE $std_flags - $RUN_WRAPPER $cargo_target_dir/std_example --target $TARGET_TRIPLE - - echo "[AOT] subslice-patterns-const-eval" - $RUST_CMD example/subslice-patterns-const-eval.rs --crate-type bin $TEST_FLAGS --target $TARGET_TRIPLE - $RUN_WRAPPER $cargo_target_dir/subslice-patterns-const-eval - - echo "[AOT] track-caller-attribute" - $RUST_CMD example/track-caller-attribute.rs --crate-type bin $TEST_FLAGS --target $TARGET_TRIPLE - $RUN_WRAPPER $cargo_target_dir/track-caller-attribute - - echo "[BUILD] mod_bench" - $RUST_CMD example/mod_bench.rs --crate-type bin --target $TARGET_TRIPLE -} - -function setup_rustc() { - rust_toolchain=$(cat rust-toolchain | grep channel | sed 's/channel = "\(.*\)"/\1/') - - git clone https://github.com/rust-lang/rust.git || true - cd rust - git fetch - git checkout $($RUSTC -V | cut -d' ' -f3 | tr -d '(') - export RUSTFLAGS= - - rm config.toml || true - - cat > config.toml < res.txt - diff -u res.txt examples/regexdna-output.txt - popd -} - -function extended_regex_tests() { - if (( $gcc_master_branch == 0 )); then - return - fi - - pushd regex - echo "[TEST] rust-lang/regex tests" - export CG_RUSTFLAGS="--cap-lints warn" # newer aho_corasick versions throw a deprecation warning - ../cargo.sh test --tests -- --exclude-should-panic --test-threads 1 -Zunstable-options -q - popd -} - -function extended_sysroot_tests() { - #pushd simple-raytracer - #echo "[BENCH COMPILE] ebobby/simple-raytracer" - #hyperfine --runs "${RUN_RUNS:-10}" --warmup 1 --prepare "cargo clean" \ - #"RUSTC=rustc RUSTFLAGS='' cargo build" \ - #"../cargo.sh build" - - #echo "[BENCH RUN] ebobby/simple-raytracer" - #cp ./target/debug/main ./raytracer_cg_gcc - #hyperfine --runs "${RUN_RUNS:-10}" ./raytracer_cg_llvm ./raytracer_cg_gcc - #popd - - extended_rand_tests - extended_regex_example_tests - extended_regex_tests -} - -function test_rustc() { - echo - echo "[TEST] rust-lang/rust" - - setup_rustc - - for test in $(rg -i --files-with-matches "//(\[\w+\])?~|// error-pattern:|// build-fail|// run-fail|-Cllvm-args" tests/ui); do - rm $test - done - rm tests/ui/consts/const_cmp_type_id.rs - rm tests/ui/consts/issue-73976-monomorphic.rs - - git checkout -- tests/ui/issues/auxiliary/issue-3136-a.rs # contains //~ERROR, but shouldn't be removed - - rm -r tests/ui/{abi*,extern/,unsized-locals/,proc-macro/,threads-sendsync/,borrowck/,test*,consts/issue-miri-1910.rs} || true - rm tests/ui/mir/mir_heavy_promoted.rs # this test is oom-killed in the CI. - # Tests generating errors. - rm tests/ui/consts/issue-94675.rs - for test in $(rg --files-with-matches "thread" tests/ui); do - rm $test - done - git checkout tests/ui/type-alias-impl-trait/auxiliary/cross_crate_ice.rs - git checkout tests/ui/type-alias-impl-trait/auxiliary/cross_crate_ice2.rs - git checkout tests/ui/macros/rfc-2011-nicer-assert-messages/auxiliary/common.rs - git checkout tests/ui/imports/ambiguous-1.rs - git checkout tests/ui/imports/ambiguous-4-extern.rs - git checkout tests/ui/entry-point/auxiliary/bad_main_functions.rs - - RUSTC_ARGS="$TEST_FLAGS -Csymbol-mangling-version=v0 -Zcodegen-backend="$(pwd)"/../target/"$CHANNEL"/librustc_codegen_gcc."$dylib_ext" --sysroot "$(pwd)"/../build_sysroot/sysroot" - - if [ $# -eq 0 ]; then - # No argument supplied to the function. Doing nothing. - echo "No argument provided. Keeping all UI tests" - elif [ $1 = "0" ]; then - # Removing the failing tests. - xargs -a ../failing-ui-tests.txt -d'\n' rm - else - # Removing all tests. - find tests/ui -type f -name '*.rs' -not -path '*/auxiliary/*' -delete - # Putting back only the failing ones. - xargs -a ../failing-ui-tests.txt -d'\n' git checkout -- - fi - - if [ $nb_parts -gt 0 ]; then - echo "Splitting ui_test into $nb_parts parts (and running part $current_part)" - find tests/ui -type f -name '*.rs' -not -path "*/auxiliary/*" > ui_tests - # To ensure it'll be always the same sub files, we sort the content. - sort ui_tests -o ui_tests - count=$((`wc -l < ui_tests` / $nb_parts)) - # We increment the number of tests by one because if this is an odd number, we would skip - # one test. - count=$((count + 1)) - split -d -l $count -a 1 ui_tests ui_tests.split - # Removing all tests. - find tests/ui -type f -name '*.rs' -not -path "*/auxiliary/*" -delete - # Putting back only the ones we want to test. - xargs -a "ui_tests.split$current_part" -d'\n' git checkout -- - fi - - echo "[TEST] rustc test suite" - COMPILETEST_FORCE_STAGE0=1 ./x.py test --run always --stage 0 tests/ui/ --rustc-args "$RUSTC_ARGS" # --target $TARGET_TRIPLE -} - -function test_failing_rustc() { - test_rustc "1" -} - -function test_successful_rustc() { - test_rustc "0" -} - -function clean_ui_tests() { - find rust/build/x86_64-unknown-linux-gnu/test/ui/ -name stamp -delete -} - -function all() { - clean - mini_tests - build_sysroot - std_tests - #asm_tests - test_libcore - extended_sysroot_tests - test_rustc -} - -if [ ${#funcs[@]} -eq 0 ]; then - echo "No command passed, running '--all'..." - all -else - for t in ${funcs[@]}; do - $t - done -fi diff --git a/failing-lto-tests.txt b/tests/failing-lto-tests.txt similarity index 66% rename from failing-lto-tests.txt rename to tests/failing-lto-tests.txt index 2e0b6134070b9..6e1ed99c6f7a9 100644 --- a/failing-lto-tests.txt +++ b/tests/failing-lto-tests.txt @@ -1,6 +1,6 @@ tests/ui/lint/unsafe_code/forge_unsafe_block.rs tests/ui/lint/unused-qualification-in-derive-expansion.rs -tests/ui/macro-quote-test.rs +tests/ui/macros/macro-quote-test.rs tests/ui/macros/proc_macro.rs tests/ui/panic-runtime/lto-unwind.rs tests/ui/resolve/derive-macro-1.rs @@ -21,3 +21,12 @@ tests/ui/fmt/format-args-capture-issue-106408.rs tests/ui/fmt/indoc-issue-106408.rs tests/ui/hygiene/issue-77523-def-site-async-await.rs tests/ui/inherent-impls-overlap-check/no-overlap.rs +tests/ui/enum-discriminant/issue-46519.rs +tests/ui/issues/issue-45731.rs +tests/ui/lint/test-allow-dead-extern-static-no-warning.rs +tests/ui/macros/macro-comma-behavior-rpass.rs +tests/ui/macros/rfc-2011-nicer-assert-messages/assert-with-custom-errors-does-not-create-unnecessary-code.rs +tests/ui/macros/rfc-2011-nicer-assert-messages/feature-gate-generic_assert.rs +tests/ui/macros/stringify.rs +tests/ui/reexport-test-harness-main.rs +tests/ui/rfcs/rfc-1937-termination-trait/termination-trait-in-test.rs diff --git a/failing-non-lto-tests.txt b/tests/failing-non-lto-tests.txt similarity index 85% rename from failing-non-lto-tests.txt rename to tests/failing-non-lto-tests.txt index 4fd60f2b8e4f0..384dfdc26fb51 100644 --- a/failing-non-lto-tests.txt +++ b/tests/failing-non-lto-tests.txt @@ -5,7 +5,7 @@ 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/sanitize/issue-111184-coroutine-witness.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/failing-ui-tests.txt b/tests/failing-ui-tests.txt similarity index 93% rename from failing-ui-tests.txt rename to tests/failing-ui-tests.txt index 22044eabe9697..d13562f8bb01b 100644 --- a/failing-ui-tests.txt +++ b/tests/failing-ui-tests.txt @@ -13,7 +13,6 @@ tests/ui/sepcomp/sepcomp-extern.rs tests/ui/sepcomp/sepcomp-fns-backwards.rs tests/ui/sepcomp/sepcomp-fns.rs tests/ui/sepcomp/sepcomp-statics.rs -tests/ui/simd/intrinsic/generic-arithmetic-pass.rs tests/ui/asm/x86_64/may_unwind.rs tests/ui/backtrace.rs tests/ui/catch-unwind-bang.rs @@ -49,7 +48,6 @@ tests/ui/rfcs/rfc-1857-stabilize-drop-order/drop-order.rs tests/ui/rfcs/rfc-2091-track-caller/std-panic-locations.rs tests/ui/simd/issue-17170.rs tests/ui/simd/issue-39720.rs -tests/ui/simd/issue-89193.rs tests/ui/statics/issue-91050-1.rs tests/ui/statics/issue-91050-2.rs tests/ui/alloc-error/default-alloc-error-hook.rs @@ -57,7 +55,6 @@ tests/ui/coroutine/panic-safe.rs tests/ui/issues/issue-14875.rs tests/ui/issues/issue-29948.rs tests/ui/panics/nested_panic_caught.rs -tests/ui/simd/intrinsic/generic-bswap-byte.rs tests/ui/const_prop/ice-issue-111353.rs tests/ui/process/println-with-broken-pipe.rs tests/ui/panic-runtime/lto-abort.rs @@ -72,3 +69,8 @@ tests/ui/async-await/deep-futures-are-freeze.rs tests/ui/closures/capture-unsized-by-ref.rs tests/ui/coroutine/resume-after-return.rs tests/ui/macros/rfc-2011-nicer-assert-messages/all-expr-kinds.rs +tests/ui/simd/masked-load-store.rs +tests/ui/simd/repr_packed.rs +tests/ui/async-await/in-trait/dont-project-to-specializable-projection.rs +tests/ui/consts/try-operator.rs +tests/ui/coroutine/unwind-abort-mix.rs diff --git a/failing-ui-tests12.txt b/tests/failing-ui-tests12.txt similarity index 88% rename from failing-ui-tests12.txt rename to tests/failing-ui-tests12.txt index 4af93939b0642..1d9bdaa552c6b 100644 --- a/failing-ui-tests12.txt +++ b/tests/failing-ui-tests12.txt @@ -9,6 +9,7 @@ tests/ui/packed/packed-struct-vec.rs tests/ui/packed/packed-tuple-struct-layout.rs 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 @@ -32,11 +33,16 @@ tests/ui/coroutine/size-moved-locals.rs tests/ui/macros/rfc-2011-nicer-assert-messages/all-not-available-cases.rs tests/ui/simd/intrinsic/generic-gather-pass.rs tests/ui/simd/issue-85915-simd-ptrs.rs +tests/ui/simd/issue-89193.rs tests/ui/issues/issue-68010-large-zst-consts.rs tests/ui/rust-2018/proc-macro-crate-in-paths.rs tests/ui/target-feature/missing-plusminus.rs tests/ui/sse2.rs tests/ui/codegen/issue-79865-llvm-miscompile.rs -tests/ui/intrinsics/intrinsics-integer.rs tests/ui/std-backtrace.rs tests/ui/mir/alignment/packed.rs +tests/ui/intrinsics/intrinsics-integer.rs +tests/ui/asm/x86_64/evex512-implicit-feature.rs +tests/ui/packed/dyn-trait.rs +tests/ui/packed/issue-118537-field-offset-ice.rs +tests/ui/stable-mir-print/basic_function.rs diff --git a/tests/lang_tests_common.rs b/tests/lang_tests_common.rs index af0133aad461d..d321ffc8ff544 100644 --- a/tests/lang_tests_common.rs +++ b/tests/lang_tests_common.rs @@ -5,6 +5,7 @@ use std::{ process::Command, }; +use boml::Toml; use lang_tester::LangTester; use tempfile::TempDir; @@ -20,20 +21,32 @@ 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 gcc_path = include_str!("../gcc_path"); - let gcc_path = gcc_path.trim(); + 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 gcc_path = Path::new(&gcc_path) + .canonicalize() + .expect("failed to get absolute path of `gcc-path`") + .display() + .to_string(); env::set_var("LD_LIBRARY_PATH", gcc_path); - fn rust_filter(filename: &Path) -> bool { - filename.extension().expect("extension").to_str().expect("to_str") == "rs" + fn rust_filter(path: &Path) -> bool { + path.is_file() && path.extension().expect("extension").to_str().expect("to_str") == "rs" } - #[cfg(feature="master")] + #[cfg(feature = "master")] fn filter(filename: &Path) -> bool { rust_filter(filename) } - #[cfg(not(feature="master"))] + #[cfg(not(feature = "master"))] fn filter(filename: &Path) -> bool { if let Some(filename) = filename.to_str() { if filename.ends_with("gep.rs") { @@ -45,16 +58,17 @@ pub fn main_inner(profile: Profile) { LangTester::new() .test_dir("tests/run") - .test_file_filter(filter) - .test_extract(|source| { - let lines = - source.lines() - .skip_while(|l| !l.starts_with("//")) - .take_while(|l| l.starts_with("//")) - .map(|l| &l[2..]) - .collect::>() - .join("\n"); - Some(lines) + .test_path_filter(filter) + .test_extract(|path| { + let lines = std::fs::read_to_string(path) + .expect("read file") + .lines() + .skip_while(|l| !l.starts_with("//")) + .take_while(|l| l.starts_with("//")) + .map(|l| &l[2..]) + .collect::>() + .join("\n"); + lines }) .test_cmds(move |path| { // Test command 1: Compile `x.rs` into `tempdir/x`. @@ -62,19 +76,22 @@ pub fn main_inner(profile: Profile) { exe.push(&tempdir); exe.push(path.file_stem().expect("file_stem")); let mut compiler = Command::new("rustc"); - compiler.args(&[ + compiler.args([ &format!("-Zcodegen-backend={}/target/debug/librustc_codegen_gcc.so", current_dir), - "--sysroot", &format!("{}/build_sysroot/sysroot/", current_dir), + "--sysroot", + &format!("{}/build_sysroot/sysroot/", current_dir), "-Zno-parallel-llvm", - "-C", "link-arg=-lc", - "-o", exe.to_str().expect("to_str"), + "-C", + "link-arg=-lc", + "-o", + exe.to_str().expect("to_str"), path.to_str().expect("to_str"), ]); // TODO(antoyo): find a way to send this via a cli argument. let test_target = std::env::var("CG_GCC_TEST_TARGET"); if let Ok(ref target) = test_target { - compiler.args(&["--target", &target]); + compiler.args(["--target", target]); let linker = format!("{}-gcc", target); compiler.args(&[format!("-Clinker={}", linker)]); let mut env_path = std::env::var("PATH").unwrap_or_default(); @@ -85,49 +102,38 @@ pub fn main_inner(profile: Profile) { if let Some(flags) = option_env!("TEST_FLAGS") { for flag in flags.split_whitespace() { - compiler.arg(&flag); + compiler.arg(flag); } } match profile { Profile::Debug => {} Profile::Release => { - compiler.args(&[ - "-C", "opt-level=3", - "-C", "lto=no", - ]); + compiler.args(["-C", "opt-level=3", "-C", "lto=no"]); } } // Test command 2: run `tempdir/x`. if test_target.is_ok() { let vm_parent_dir = std::env::var("CG_GCC_VM_DIR") - .map(|dir| PathBuf::from(dir)) + .map(PathBuf::from) .unwrap_or_else(|_| std::env::current_dir().unwrap()); let vm_dir = "vm"; let exe_filename = exe.file_name().unwrap(); let vm_home_dir = vm_parent_dir.join(vm_dir).join("home"); let vm_exe_path = vm_home_dir.join(exe_filename); // FIXME(antoyo): panicking here makes the test pass. - let inside_vm_exe_path = PathBuf::from("/home").join(&exe_filename); + let inside_vm_exe_path = PathBuf::from("/home").join(exe_filename); let mut copy = Command::new("sudo"); copy.arg("cp"); - copy.args(&[&exe, &vm_exe_path]); + copy.args([&exe, &vm_exe_path]); let mut runtime = Command::new("sudo"); - runtime.args(&["chroot", vm_dir, "qemu-m68k-static"]); + runtime.args(["chroot", vm_dir, "qemu-m68k-static"]); runtime.arg(inside_vm_exe_path); runtime.current_dir(vm_parent_dir); - vec![ - ("Compiler", compiler), - ("Copy", copy), - ("Run-time", runtime), - ] - } - else { + vec![("Compiler", compiler), ("Copy", copy), ("Run-time", runtime)] + } else { let runtime = Command::new(exe); - vec![ - ("Compiler", compiler), - ("Run-time", runtime), - ] + vec![("Compiler", compiler), ("Run-time", runtime)] } }) .run(); diff --git a/y.sh b/y.sh index 188109743e3db..69d7917dd7779 100755 --- a/y.sh +++ b/y.sh @@ -2,7 +2,7 @@ set -e echo "[BUILD] build system" 1>&2 -cd build_system +pushd $(dirname "$0")/build_system > /dev/null cargo build --release -cd .. -./build_system/target/release/y $@ +popd > /dev/null +$(dirname "$0")/build_system/target/release/y $@ From 06d07f816a9e95de360c95cabca907bd6e666905 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sun, 3 Mar 2024 23:00:46 +0100 Subject: [PATCH 005/892] Remove unneeded special case for rust CI --- build_system/src/config.rs | 65 +++++++++++++++++--------------------- build_system/src/test.rs | 12 +------ 2 files changed, 30 insertions(+), 47 deletions(-) diff --git a/build_system/src/config.rs b/build_system/src/config.rs index c633ee57d4a34..46621ef3b2141 100644 --- a/build_system/src/config.rs +++ b/build_system/src/config.rs @@ -128,6 +128,7 @@ pub struct ConfigInfo { // just to set the `gcc_path` field to display it. pub no_download: bool, pub no_default_features: bool, + pub backend: Option, } impl ConfigInfo { @@ -178,6 +179,14 @@ impl ConfigInfo { return Err("Expected a value after `--cg_gcc-path`, found nothing".to_string()) } }, + "--use-backend" => match args.next() { + Some(backend) if !backend.is_empty() => self.backend = Some(backend), + _ => { + return Err( + "Expected an argument after `--use-backend`, found nothing".into() + ) + } + }, "--no-default-features" => self.no_default_features = true, _ => return Ok(false), } @@ -377,39 +386,25 @@ impl ConfigInfo { "debug" }; - let has_builtin_backend = env - .get("BUILTIN_BACKEND") - .map(|backend| !backend.is_empty()) - .unwrap_or(false); - let mut rustflags = Vec::new(); - if has_builtin_backend { - // It means we're building inside the rustc testsuite, so some options need to be handled - // a bit differently. - self.cg_backend_path = "gcc".to_string(); - - match env.get("RUSTC_SYSROOT") { - Some(rustc_sysroot) if !rustc_sysroot.is_empty() => { - rustflags.extend_from_slice(&["--sysroot".to_string(), rustc_sysroot.clone()]); - } - _ => {} - } - // This should not be needed, but is necessary for the CI in the rust repository. - // FIXME: Remove when the rust CI switches to the master version of libgccjit. - rustflags.push("-Cpanic=abort".to_string()); + self.cg_backend_path = current_dir + .join("target") + .join(channel) + .join(&format!("librustc_codegen_gcc.{}", self.dylib_ext)) + .display() + .to_string(); + self.sysroot_path = current_dir + .join("build_sysroot/sysroot") + .display() + .to_string(); + if let Some(backend) = &self.backend { + rustflags.push(format!("-Zcodegen-backend={}", backend)); } else { - self.cg_backend_path = current_dir - .join("target") - .join(channel) - .join(&format!("librustc_codegen_gcc.{}", self.dylib_ext)) - .display() - .to_string(); - self.sysroot_path = current_dir - .join("build_sysroot/sysroot") - .display() - .to_string(); - rustflags.extend_from_slice(&["--sysroot".to_string(), self.sysroot_path.clone()]); - }; + rustflags.extend_from_slice(&[ + "--sysroot".to_string(), self.sysroot_path.clone(), + format!("-Zcodegen-backend={}", self.cg_backend_path), + ]); + } // This environment variable is useful in case we want to change options of rustc commands. if let Some(cg_rustflags) = env.get("CG_RUSTFLAGS") { @@ -427,10 +422,7 @@ impl ConfigInfo { rustflags.push("-Csymbol-mangling-version=v0".to_string()); } - rustflags.extend_from_slice(&[ - "-Cdebuginfo=2".to_string(), - format!("-Zcodegen-backend={}", self.cg_backend_path), - ]); + rustflags.push("-Cdebuginfo=2".to_string()); // Since we don't support ThinLTO, disable LTO completely when not trying to do LTO. // TODO(antoyo): remove when we can handle ThinLTO. @@ -504,7 +496,8 @@ impl ConfigInfo { --config-file : Location of the config file to be used --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" + --no-default-features : Add `--no-default-features` flag to cargo commands + --use-backend : Useful only for rustc testsuite" ); } } diff --git a/build_system/src/test.rs b/build_system/src/test.rs index a4db2fdebef1e..0895dc6bff700 100644 --- a/build_system/src/test.rs +++ b/build_system/src/test.rs @@ -93,7 +93,6 @@ fn show_usage() { --features [arg] : Add a new feature [arg] --use-system-gcc : Use system installed libgccjit --build-only : Only build rustc_codegen_gcc then exits - --use-backend : Useful only for rustc testsuite --nb-parts : Used to split rustc_tests (for CI needs) --current-part : Used with `--nb-parts`, allows you to specify which parts to test"# ); @@ -113,7 +112,6 @@ struct TestArg { use_system_gcc: bool, runners: BTreeSet, flags: Vec, - backend: Option, nb_parts: Option, current_part: Option, sysroot_panic_abort: bool, @@ -145,14 +143,6 @@ impl TestArg { test_arg.use_system_gcc = true; } "--build-only" => test_arg.build_only = true, - "--use-backend" => match args.next() { - Some(backend) if !backend.is_empty() => test_arg.backend = Some(backend), - _ => { - return Err( - "Expected an argument after `--use-backend`, found nothing".into() - ) - } - }, "--nb-parts" => { test_arg.nb_parts = Some(get_number_after_arg(&mut args, "--nb-parts")?); } @@ -199,7 +189,7 @@ impl TestArg { } fn build_if_no_backend(env: &Env, args: &TestArg) -> Result<(), String> { - if args.backend.is_some() { + if args.config_info.backend.is_some() { return Ok(()); } let mut command: Vec<&dyn AsRef> = vec![&"cargo", &"rustc"]; From 17aa31bfe26ae7acc340c12ce3aa7a0a9269f621 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 5 Mar 2024 20:17:22 +0100 Subject: [PATCH 006/892] Fix cg_gcc build --- src/type_.rs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/type_.rs b/src/type_.rs index c8e6ae69bd959..68471b028beb8 100644 --- a/src/type_.rs +++ b/src/type_.rs @@ -136,10 +136,6 @@ impl<'gcc, 'tcx> BaseTypeMethods<'tcx> for CodegenCx<'gcc, 'tcx> { unimplemented!("f16_f128") } - fn type_f128(&self) -> Type<'gcc> { - unimplemented!("f16_f128") - } - fn type_func(&self, params: &[Type<'gcc>], return_type: Type<'gcc>) -> Type<'gcc> { self.context.new_function_pointer_type(None, return_type, params, false) } From 9aa01ca9e95a1c68f1a06a0fb55501af99e1c894 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 21 Feb 2024 13:30:04 +0100 Subject: [PATCH 007/892] Correctly handle "master" feature --- build_system/src/build.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/build_system/src/build.rs b/build_system/src/build.rs index 0eabd1d897292..c81b02e2183d8 100644 --- a/build_system/src/build.rs +++ b/build_system/src/build.rs @@ -107,6 +107,9 @@ pub fn build_sysroot(env: &HashMap, config: &ConfigInfo) -> Resu rustflags.push_str(" -Cpanic=abort -Zpanic-abort-tests"); } rustflags.push_str(" -Z force-unstable-if-unmarked"); + if config.no_default_features { + rustflags.push_str(" -Csymbol-mangling-version=v0"); + } let mut env = env.clone(); let mut args: Vec<&dyn AsRef> = vec![&"cargo", &"build", &"--target", &config.target]; From c860ac459e3f92aea06c62bf42b01634a940610d Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 6 Mar 2024 16:23:50 +0100 Subject: [PATCH 008/892] Correctly handle `cargo_target_dir` --- build_system/src/config.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/build_system/src/config.rs b/build_system/src/config.rs index 46621ef3b2141..34c92a3485ed6 100644 --- a/build_system/src/config.rs +++ b/build_system/src/config.rs @@ -446,9 +446,7 @@ impl ConfigInfo { )); let ld_library_path = format!( "{target}:{sysroot}:{gcc_path}", - // FIXME: It's possible to pick another out directory. Would be nice to have a command - // line option to change it. - target = current_dir.join("target/out").display(), + target = self.cargo_target_dir, sysroot = sysroot.display(), gcc_path = self.gcc_path, ); @@ -473,7 +471,7 @@ impl ConfigInfo { self.rustc_command.extend_from_slice(&rustflags); self.rustc_command.extend_from_slice(&[ "-L".to_string(), - "crate=target/out".to_string(), + format!("crate={}", self.cargo_target_dir), "--out-dir".to_string(), self.cargo_target_dir.clone(), ]); From 929e12d199ace1d94486a3858f6c9241787178a1 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 5 Mar 2024 18:23:01 +0000 Subject: [PATCH 009/892] Stabilize associated type bounds --- src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index 09ce059476ec7..0f986d554e558 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -18,11 +18,11 @@ #![feature( rustc_private, decl_macro, - associated_type_bounds, never_type, trusted_len, hash_raw_entry )] +#![cfg_attr(bootstrap, feature(associated_type_bounds))] #![allow(broken_intra_doc_links)] #![recursion_limit="256"] #![warn(rust_2018_idioms)] From ed5c3bc397c476f3969a736534fcf89e2523f489 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 9 Mar 2024 18:21:13 +0100 Subject: [PATCH 010/892] Fix cg_gcc merge --- src/asm.rs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/asm.rs b/src/asm.rs index f8afc5c3eb43a..9b679019e96ce 100644 --- a/src/asm.rs +++ b/src/asm.rs @@ -114,7 +114,8 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> { options: InlineAsmOptions, span: &[Span], instance: Instance<'_>, - _catch_funclet: Option<(Self::BasicBlock, Self::BasicBlock, Option<&Self::Funclet>)>, + dest: Option, + _catch_funclet: Option<(Self::BasicBlock, Option<&Self::Funclet>)>, ) { if options.contains(InlineAsmOptions::MAY_UNWIND) { self.sess().dcx().create_err(UnwindingInlineAsm { span: span[0] }).emit(); @@ -537,8 +538,9 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> { } if dest.is_none() && options.contains(InlineAsmOptions::NORETURN) { let builtin_unreachable = self.context.get_builtin_function("__builtin_unreachable"); - let builtin_unreachable: RValue<'gcc> = - unsafe { std::mem::transmute(builtin_unreachable) }; + let builtin_unreachable: RValue<'gcc> = unsafe { + std::mem::transmute(builtin_unreachable) + }; self.call(self.type_void(), None, None, builtin_unreachable, &[], None); } From d0dc94334bfaf38bbc7c8fb5f7a496093345c344 Mon Sep 17 00:00:00 2001 From: daxpedda Date: Tue, 27 Feb 2024 23:06:44 +0100 Subject: [PATCH 011/892] Introduce perma-unstable `wasm-c-abi` flag --- src/builder.rs | 8 +++++++- src/context.rs | 8 +++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/builder.rs b/src/builder.rs index f5cda81f6ab86..3cfc308c54638 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -31,7 +31,7 @@ use rustc_span::Span; use rustc_target::abi::{ self, call::FnAbi, Align, HasDataLayout, Size, TargetDataLayout, WrappingRange, }; -use rustc_target::spec::{HasTargetSpec, Target}; +use rustc_target::spec::{HasTargetSpec, HasWasmCAbiOpt, Target, WasmCAbi}; use crate::common::{type_is_pointer, SignType, TypeReflection}; use crate::context::CodegenCx; @@ -2349,6 +2349,12 @@ impl<'tcx> HasTargetSpec for Builder<'_, '_, 'tcx> { } } +impl<'tcx> HasWasmCAbiOpt for Builder<'_, '_, 'tcx> { + fn wasm_c_abi_opt(&self) -> WasmCAbi { + self.cx.wasm_c_abi_opt() + } +} + pub trait ToGccComp { fn to_gcc_comparison(&self) -> ComparisonOp; } diff --git a/src/context.rs b/src/context.rs index bc3d62f2679d9..99c079f40e03b 100644 --- a/src/context.rs +++ b/src/context.rs @@ -20,7 +20,7 @@ use rustc_span::{source_map::respan, Span}; use rustc_target::abi::{ call::FnAbi, HasDataLayout, PointeeInfo, Size, TargetDataLayout, VariantIdx, }; -use rustc_target::spec::{HasTargetSpec, Target, TlsModel}; +use rustc_target::spec::{HasTargetSpec, HasWasmCAbiOpt, Target, TlsModel, WasmCAbi}; use crate::callee::get_fn; use crate::common::SignType; @@ -555,6 +555,12 @@ impl<'gcc, 'tcx> HasTargetSpec for CodegenCx<'gcc, 'tcx> { } } +impl<'gcc, 'tcx> HasWasmCAbiOpt for CodegenCx<'gcc, 'tcx> { + fn wasm_c_abi_opt(&self) -> WasmCAbi { + self.tcx.sess.opts.unstable_opts.wasm_c_abi + } +} + impl<'gcc, 'tcx> LayoutOfHelpers<'tcx> for CodegenCx<'gcc, 'tcx> { type LayoutOfResult = TyAndLayout<'tcx>; From dd9407dcbedc281a9fe9f11e63ab91410f49b44c Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 10 Mar 2024 11:49:27 +0100 Subject: [PATCH 012/892] use Instance::expect_resolve() instead of unwraping Instance::resolve() --- src/context.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/context.rs b/src/context.rs index bc3d62f2679d9..8f643c7db720f 100644 --- a/src/context.rs +++ b/src/context.rs @@ -473,14 +473,12 @@ impl<'gcc, 'tcx> MiscMethods<'tcx> for CodegenCx<'gcc, 'tcx> { let tcx = self.tcx; let func = match tcx.lang_items().eh_personality() { Some(def_id) if !wants_msvc_seh(self.sess()) => { - let instance = ty::Instance::resolve( + let instance = ty::Instance::expect_resolve( tcx, ty::ParamEnv::reveal_all(), def_id, ty::List::empty(), - ) - .unwrap() - .unwrap(); + ); let symbol_name = tcx.symbol_name(instance).name; let fn_abi = self.fn_abi_of_instance(instance, ty::List::empty()); From 45aa965bd516620a9a92e583c0cfe34ec1b923ba Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sun, 10 Mar 2024 17:19:48 +0100 Subject: [PATCH 013/892] Update rustc version to 2024-03-10 --- rust-toolchain | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-toolchain b/rust-toolchain index a0ac82866609e..42c26df058a60 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2024-03-05" +channel = "nightly-2024-03-10" components = ["rust-src", "rustc-dev", "llvm-tools-preview"] From f7622d11a738cfc9d0dbf1c54d6b035a10c83fc3 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sun, 10 Mar 2024 17:31:34 +0100 Subject: [PATCH 014/892] fmt --- src/asm.rs | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/asm.rs b/src/asm.rs index 6dc21e02de01f..72d572465f404 100644 --- a/src/asm.rs +++ b/src/asm.rs @@ -485,9 +485,8 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> { } InlineAsmOperandRef::Label { label } => { - let label_gcc_index = labels.iter() - .position(|&l| l == label) - .expect("wrong rust index"); + let label_gcc_index = + labels.iter().position(|&l| l == label).expect("wrong rust index"); let gcc_index = label_gcc_index + outputs.len() + inputs.len(); push_to_template(Some('l'), gcc_index); } @@ -538,9 +537,8 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> { } if dest.is_none() && options.contains(InlineAsmOptions::NORETURN) { let builtin_unreachable = self.context.get_builtin_function("__builtin_unreachable"); - let builtin_unreachable: RValue<'gcc> = unsafe { - std::mem::transmute(builtin_unreachable) - }; + let builtin_unreachable: RValue<'gcc> = + unsafe { std::mem::transmute(builtin_unreachable) }; self.call(self.type_void(), None, None, builtin_unreachable, &[], None); } From fc2d1edad794a985ed7fac95b61c3774e5550ca6 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sun, 10 Mar 2024 17:45:20 +0100 Subject: [PATCH 015/892] Add new failing tests --- tests/failing-ui-tests.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/failing-ui-tests.txt b/tests/failing-ui-tests.txt index d13562f8bb01b..de838231a1f96 100644 --- a/tests/failing-ui-tests.txt +++ b/tests/failing-ui-tests.txt @@ -74,3 +74,5 @@ tests/ui/simd/repr_packed.rs tests/ui/async-await/in-trait/dont-project-to-specializable-projection.rs tests/ui/consts/try-operator.rs tests/ui/coroutine/unwind-abort-mix.rs +tests/ui/type-alias-impl-trait/rpit_tait_equality_in_canonical_query.rs +tests/ui/impl-trait/equality-in-canonical-query.rs From ba5231751811386387746bafb1bb791be5057132 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sun, 10 Mar 2024 22:10:05 +0100 Subject: [PATCH 016/892] Add code comment about the `--backend` option usage --- build_system/src/config.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/build_system/src/config.rs b/build_system/src/config.rs index 34c92a3485ed6..0a7258958e7e9 100644 --- a/build_system/src/config.rs +++ b/build_system/src/config.rs @@ -398,6 +398,8 @@ impl ConfigInfo { .display() .to_string(); if let Some(backend) = &self.backend { + // This option is only used in the rust compiler testsuite. The sysroot is handled + // by its build system directly so no need to set it ourselves. rustflags.push(format!("-Zcodegen-backend={}", backend)); } else { rustflags.extend_from_slice(&[ From 915646fe792bdde0d36ae98067e5605bfbcdd540 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 6 Mar 2024 11:02:56 +1100 Subject: [PATCH 017/892] Rename `IntoDiagnostic` as `Diagnostic`. To match `derive(Diagnostic)`. Also rename `into_diagnostic` as `into_diag`. --- src/errors.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/errors.rs b/src/errors.rs index f963a153fbaba..aee2b077dba1f 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -1,4 +1,4 @@ -use rustc_errors::{Diag, DiagCtxt, EmissionGuarantee, IntoDiagnostic, Level}; +use rustc_errors::{Diag, DiagCtxt, Diagnostic, EmissionGuarantee, Level}; use rustc_macros::{Diagnostic, Subdiagnostic}; use rustc_span::Span; @@ -89,8 +89,8 @@ pub(crate) struct TargetFeatureDisableOrEnable<'a> { #[help(codegen_gcc_missing_features)] pub(crate) struct MissingFeatures; -impl IntoDiagnostic<'_, G> for TargetFeatureDisableOrEnable<'_> { - fn into_diagnostic(self, dcx: &'_ DiagCtxt, level: Level) -> Diag<'_, G> { +impl Diagnostic<'_, G> for TargetFeatureDisableOrEnable<'_> { + fn into_diag(self, dcx: &'_ DiagCtxt, level: Level) -> Diag<'_, G> { let mut diag = Diag::new(dcx, level, fluent::codegen_gcc_target_feature_disable_or_enable); if let Some(span) = self.span { diag.span(span); From ca883bdbe48f683a5ed06f40fd156e4d97354ee5 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sun, 10 Mar 2024 23:34:00 +0100 Subject: [PATCH 018/892] Remove unused files --- build.rs | 6 ------ deps/libLLVM-18-rust-1.78.0-nightly.so | 1 - 2 files changed, 7 deletions(-) delete mode 100644 build.rs delete mode 100644 deps/libLLVM-18-rust-1.78.0-nightly.so diff --git a/build.rs b/build.rs deleted file mode 100644 index b93c17793bf37..0000000000000 --- a/build.rs +++ /dev/null @@ -1,6 +0,0 @@ -// TODO: remove this file and deps/libLLVM-18-rust-1.78.0-nightly.so when -// https://github.com/rust-lang/rust/pull/121967 is merged. -fn main() { - println!("cargo:rerun-if-changed=deps/libLLVM-18-rust-1.78.0-nightly.so"); - println!("cargo:rustc-link-search=deps"); -} diff --git a/deps/libLLVM-18-rust-1.78.0-nightly.so b/deps/libLLVM-18-rust-1.78.0-nightly.so deleted file mode 100644 index c44ca790b4f8c..0000000000000 --- a/deps/libLLVM-18-rust-1.78.0-nightly.so +++ /dev/null @@ -1 +0,0 @@ -INPUT(libLLVM.so.18.1-rust-1.78.0-nightly) From 6f76488b2f8ca6019f01e15ffc896ca21f747254 Mon Sep 17 00:00:00 2001 From: tempdragon <645703113@qq.com> Date: Fri, 8 Mar 2024 18:47:20 +0800 Subject: [PATCH 019/892] fix(fmt/style): Remove unncessary clones, into's and deref's --- src/attributes.rs | 6 +++--- src/back/lto.rs | 3 +-- src/back/write.rs | 2 +- src/base.rs | 2 +- src/builder.rs | 30 ++++++++++++++---------------- src/callee.rs | 4 ++-- src/common.rs | 11 ++++++----- src/consts.rs | 24 ++++++++---------------- src/context.rs | 10 +++++----- src/debuginfo.rs | 2 +- src/declare.rs | 14 ++++++-------- src/int.rs | 19 ++++++++----------- src/intrinsic/llvm.rs | 17 +++++++---------- src/intrinsic/mod.rs | 20 ++++++++++---------- src/intrinsic/simd.rs | 5 ++--- src/type_of.rs | 2 +- 16 files changed, 76 insertions(+), 95 deletions(-) diff --git a/src/attributes.rs b/src/attributes.rs index 8602566ab8fa2..2ce0c83008f16 100644 --- a/src/attributes.rs +++ b/src/attributes.rs @@ -92,7 +92,7 @@ pub fn from_fn_attrs<'gcc, 'tcx>( let mut function_features = function_features .iter() .flat_map(|feat| to_gcc_features(cx.tcx.sess, feat).into_iter()) - .chain(codegen_fn_attrs.instruction_set.iter().map(|x| match x { + .chain(codegen_fn_attrs.instruction_set.iter().map(|x| match *x { InstructionSetAttr::ArmA32 => "-thumb-mode", // TODO(antoyo): support removing feature. InstructionSetAttr::ArmT32 => "thumb-mode", })) @@ -118,8 +118,8 @@ pub fn from_fn_attrs<'gcc, 'tcx>( if feature.starts_with('-') { Some(format!("no{}", feature)) - } else if feature.starts_with('+') { - Some(feature[1..].to_string()) + } else if let Some(stripped) = feature.strip_prefix('+') { + Some(stripped.to_string()) } else { Some(feature.to_string()) } diff --git a/src/back/lto.rs b/src/back/lto.rs index 61e0f203ee0b2..96e0b84450f8c 100644 --- a/src/back/lto.rs +++ b/src/back/lto.rs @@ -128,8 +128,7 @@ fn prepare_lto( } let archive_data = unsafe { - Mmap::map(File::open(&path).expect("couldn't open rlib")) - .expect("couldn't map rlib") + Mmap::map(File::open(path).expect("couldn't open rlib")).expect("couldn't map rlib") }; let archive = ArchiveFile::parse(&*archive_data).expect("wanted an rlib"); let obj_files = archive diff --git a/src/back/write.rs b/src/back/write.rs index 76a619a1af782..a38fc8c14fbb7 100644 --- a/src/back/write.rs +++ b/src/back/write.rs @@ -104,7 +104,7 @@ pub(crate) unsafe fn codegen( // FIXME(antoyo): segfault in dump_reproducer_to_file() might be caused by // transmuting an rvalue to an lvalue. // Segfault is actually in gcc::jit::reproducer::get_identifier_as_lvalue - context.dump_reproducer_to_file(&format!("/tmp/reproducers/{}.c", module.name)); + context.dump_reproducer_to_file(format!("/tmp/reproducers/{}.c", module.name)); println!("Dumped reproducer {}", module.name); } if env::var("CG_GCCJIT_DUMP_TO_FILE").as_deref() == Ok("1") { diff --git a/src/base.rs b/src/base.rs index 2a2d5741d1318..79a29a1135a1b 100644 --- a/src/base.rs +++ b/src/base.rs @@ -135,7 +135,7 @@ pub fn compile_codegen_unit( let target_cpu = gcc_util::target_cpu(tcx.sess); if target_cpu != "generic" { - context.add_command_line_option(&format!("-march={}", target_cpu)); + context.add_command_line_option(format!("-march={}", target_cpu)); } if tcx diff --git a/src/builder.rs b/src/builder.rs index f5cda81f6ab86..2241e0ea36437 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -277,8 +277,8 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { .collect(); // NOTE: to take into account variadic functions. - for i in casted_args.len()..args.len() { - casted_args.push(args[i]); + for arg in args.iter().skip(casted_args.len()) { + casted_args.push(*arg); } Cow::Owned(casted_args) @@ -353,7 +353,7 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { let function_address_names = self.function_address_names.borrow(); let original_function_name = function_address_names.get(&func_ptr); llvm::adjust_intrinsic_arguments( - &self, + self, gcc_func, args.into(), &func_name, @@ -361,7 +361,7 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { ) }; let args_adjusted = args.len() != previous_arg_count; - let args = self.check_ptr_call("call", func_ptr, &*args); + let args = self.check_ptr_call("call", func_ptr, &args); // gccjit requires to use the result of functions, even when it's not used. // That's why we assign the result to a local or call add_eval(). @@ -373,7 +373,7 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { unsafe { RETURN_VALUE_COUNT += 1 }; let return_value = self.cx.context.new_call_through_ptr(self.location, func_ptr, &args); let return_value = llvm::adjust_intrinsic_return_value( - &self, + self, return_value, &func_name, &args, @@ -441,7 +441,7 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { self.block.add_assignment( self.location, result, - self.cx.context.new_call(self.location, func, &args), + self.cx.context.new_call(self.location, func, args), ); result.to_rvalue() } @@ -595,7 +595,7 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { ) -> RValue<'gcc> { let try_block = self.current_func().new_block("try"); - let current_block = self.block.clone(); + let current_block = self.block; self.block = try_block; let call = self.call(typ, fn_attrs, None, func, args, None); // TODO(antoyo): use funclet here? self.block = current_block; @@ -1176,7 +1176,7 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { // NOTE: due to opaque pointers now being used, we need to cast here. let ptr = self.context.new_cast(self.location, ptr, typ.make_pointer()); // NOTE: array indexing is always considered in bounds in GCC (TODO(antoyo): to be verified). - let mut indices = indices.into_iter(); + let mut indices = indices.iter(); let index = indices.next().expect("first index in inbounds_gep"); let mut result = self.context.new_array_access(self.location, ptr, *index); for index in indices { @@ -1684,7 +1684,7 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { fn zext(&mut self, value: RValue<'gcc>, dest_typ: Type<'gcc>) -> RValue<'gcc> { // FIXME(antoyo): this does not zero-extend. - if value.get_type().is_bool() && dest_typ.is_i8(&self.cx) { + if value.get_type().is_bool() && dest_typ.is_i8(self.cx) { // FIXME(antoyo): hack because base::from_immediate converts i1 to i8. // Fix the code in codegen_ssa::base::from_immediate. return value; @@ -2057,7 +2057,7 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { self.context.new_rvalue_from_vector(self.location, mask_type, &vector_elements); let shifted = self.context.new_rvalue_vector_perm(self.location, res, res, mask); shift *= 2; - res = op(res, shifted, &self.context); + res = op(res, shifted, self.context); } self.context .new_vector_access(self.location, res, self.context.new_rvalue_zero(self.int_type)) @@ -2073,7 +2073,7 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { } pub fn vector_reduce_op(&mut self, src: RValue<'gcc>, op: BinaryOp) -> RValue<'gcc> { - let loc = self.location.clone(); + let loc = self.location; self.vector_reduce(src, |a, b, context| context.new_binary_op(loc, op, a.get_type(), a, b)) } @@ -2090,7 +2090,6 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { let vector_type = src.get_type().unqualified().dyncast_vector().expect("vector type"); let element_count = vector_type.get_num_units(); (0..element_count) - .into_iter() .map(|i| { self.context .new_vector_access( @@ -2121,7 +2120,6 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { let vector_type = src.get_type().unqualified().dyncast_vector().expect("vector type"); let element_count = vector_type.get_num_units(); (0..element_count) - .into_iter() .map(|i| { self.context .new_vector_access( @@ -2141,7 +2139,7 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { // Inspired by Hacker's Delight min implementation. pub fn vector_reduce_min(&mut self, src: RValue<'gcc>) -> RValue<'gcc> { - let loc = self.location.clone(); + let loc = self.location; self.vector_reduce(src, |a, b, context| { let differences_or_zeros = difference_or_zero(loc, a, b, context); context.new_binary_op(loc, BinaryOp::Plus, b.get_type(), b, differences_or_zeros) @@ -2150,7 +2148,7 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { // Inspired by Hacker's Delight max implementation. pub fn vector_reduce_max(&mut self, src: RValue<'gcc>) -> RValue<'gcc> { - let loc = self.location.clone(); + let loc = self.location; self.vector_reduce(src, |a, b, context| { let differences_or_zeros = difference_or_zero(loc, a, b, context); context.new_binary_op(loc, BinaryOp::Minus, a.get_type(), a, differences_or_zeros) @@ -2345,7 +2343,7 @@ impl<'tcx> HasParamEnv<'tcx> for Builder<'_, '_, 'tcx> { impl<'tcx> HasTargetSpec for Builder<'_, '_, 'tcx> { fn target_spec(&self) -> &Target { - &self.cx.target_spec() + self.cx.target_spec() } } diff --git a/src/callee.rs b/src/callee.rs index 84f49b6856d4d..9ad2e90122f58 100644 --- a/src/callee.rs +++ b/src/callee.rs @@ -28,7 +28,7 @@ pub fn get_fn<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, instance: Instance<'tcx>) let fn_abi = cx.fn_abi_of_instance(instance, ty::List::empty()); - let func = if let Some(_func) = cx.get_declared_value(&sym) { + let func = if let Some(_func) = cx.get_declared_value(sym) { // FIXME(antoyo): we never reach this because get_declared_value only returns global variables // and here we try to get a function. unreachable!(); @@ -68,7 +68,7 @@ pub fn get_fn<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, instance: Instance<'tcx>) }*/ } else { cx.linkage.set(FunctionType::Extern); - let func = cx.declare_fn(&sym, &fn_abi); + let func = cx.declare_fn(sym, fn_abi); attributes::from_fn_attrs(cx, func, instance); diff --git a/src/common.rs b/src/common.rs index d243d7088ada9..6a3b5442adf27 100644 --- a/src/common.rs +++ b/src/common.rs @@ -21,7 +21,7 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { fn global_string(&self, string: &str) -> LValue<'gcc> { // TODO(antoyo): handle non-null-terminated strings. - let string = self.context.new_string_literal(&*string); + let string = self.context.new_string_literal(string); let sym = self.generate_local_symbol_name("str"); let global = self.declare_private_global(&sym, self.val_ty(string)); global.global_set_initializer_rvalue(string); @@ -170,7 +170,8 @@ impl<'gcc, 'tcx> ConstMethods<'tcx> for CodegenCx<'gcc, 'tcx> { return self .context .new_rvalue_from_double(ty, f32::from_bits(data as u32) as f64); - } else if ty == self.double_type { + } + if ty == self.double_type { return self.context.new_rvalue_from_double(ty, f64::from_bits(data as u64)); } @@ -293,7 +294,7 @@ impl<'gcc, 'tcx> SignType<'gcc, 'tcx> for Type<'gcc> { } else if self.is_ulonglong(cx) { cx.longlong_type } else { - self.clone() + *self } } @@ -319,7 +320,7 @@ impl<'gcc, 'tcx> SignType<'gcc, 'tcx> for Type<'gcc> { } else if self.is_longlong(cx) { cx.ulonglong_type } else { - self.clone() + *self } } } @@ -432,7 +433,7 @@ impl<'gcc, 'tcx> TypeReflection<'gcc, 'tcx> for Type<'gcc> { } fn is_vector(&self) -> bool { - let mut typ = self.clone(); + let mut typ = *self; loop { if typ.dyncast_vector().is_some() { return true; diff --git a/src/consts.rs b/src/consts.rs index 327c9bdada924..f47fd56553323 100644 --- a/src/consts.rs +++ b/src/consts.rs @@ -66,7 +66,7 @@ impl<'gcc, 'tcx> StaticMethods for CodegenCx<'gcc, 'tcx> { fn codegen_static(&self, def_id: DefId, is_mutable: bool) { let attrs = self.tcx.codegen_fn_attrs(def_id); - let value = match codegen_static_initializer(&self, def_id) { + let value = match codegen_static_initializer(self, def_id) { Ok((value, _)) => value, // Error has already been reported Err(_) => return, @@ -231,13 +231,8 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { } let is_tls = fn_attrs.flags.contains(CodegenFnAttrFlags::THREAD_LOCAL); - let global = self.declare_global( - &sym, - llty, - GlobalKind::Exported, - is_tls, - fn_attrs.link_section, - ); + let global = + self.declare_global(sym, llty, GlobalKind::Exported, is_tls, fn_attrs.link_section); if !self.tcx.is_reachable_non_generic(def_id) { #[cfg(feature = "master")] @@ -246,7 +241,7 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { global } else { - check_and_apply_linkage(&self, &fn_attrs, ty, sym) + check_and_apply_linkage(self, fn_attrs, ty, sym) }; if !def_id.is_local() { @@ -367,11 +362,8 @@ fn check_and_apply_linkage<'gcc, 'tcx>( let gcc_type = cx.layout_of(ty).gcc_type(cx); if let Some(linkage) = attrs.import_linkage { // Declare a symbol `foo` with the desired linkage. - let global1 = cx.declare_global_with_linkage( - &sym, - cx.type_i8(), - base::global_linkage_to_gcc(linkage), - ); + let global1 = + cx.declare_global_with_linkage(sym, cx.type_i8(), base::global_linkage_to_gcc(linkage)); // Declare an internal global `extern_with_linkage_foo` which // is initialized with the address of `foo`. If `foo` is @@ -380,7 +372,7 @@ fn check_and_apply_linkage<'gcc, 'tcx>( // `extern_with_linkage_foo` will instead be initialized to // zero. let mut real_name = "_rust_extern_with_linkage_".to_string(); - real_name.push_str(&sym); + real_name.push_str(sym); let global2 = cx.define_global(&real_name, gcc_type, is_tls, attrs.link_section); // TODO(antoyo): set linkage. let value = cx.const_ptrcast(global1.get_address(None), gcc_type); @@ -397,6 +389,6 @@ fn check_and_apply_linkage<'gcc, 'tcx>( // don't do this then linker errors can be generated where the linker // complains that one object files has a thread local version of the // symbol and another one doesn't. - cx.declare_global(&sym, gcc_type, GlobalKind::Imported, is_tls, attrs.link_section) + cx.declare_global(sym, gcc_type, GlobalKind::Imported, is_tls, attrs.link_section) } } diff --git a/src/context.rs b/src/context.rs index bc3d62f2679d9..1b9cfd3652c81 100644 --- a/src/context.rs +++ b/src/context.rs @@ -384,7 +384,7 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { } pub fn sess(&self) -> &'tcx Session { - &self.tcx.sess + self.tcx.sess } pub fn bitcast_if_needed( @@ -431,7 +431,7 @@ impl<'gcc, 'tcx> MiscMethods<'tcx> for CodegenCx<'gcc, 'tcx> { let func_name = self.tcx.symbol_name(instance).name; let func = if self.intrinsics.borrow().contains_key(func_name) { - self.intrinsics.borrow()[func_name].clone() + self.intrinsics.borrow()[func_name] } else { get_fn(self, instance) }; @@ -485,7 +485,7 @@ impl<'gcc, 'tcx> MiscMethods<'tcx> for CodegenCx<'gcc, 'tcx> { let symbol_name = tcx.symbol_name(instance).name; let fn_abi = self.fn_abi_of_instance(instance, ty::List::empty()); self.linkage.set(FunctionType::Extern); - let func = self.declare_fn(symbol_name, &fn_abi); + let func = self.declare_fn(symbol_name, fn_abi); let func: RValue<'gcc> = unsafe { std::mem::transmute(func) }; func } @@ -505,7 +505,7 @@ impl<'gcc, 'tcx> MiscMethods<'tcx> for CodegenCx<'gcc, 'tcx> { } fn sess(&self) -> &Session { - &self.tcx.sess + self.tcx.sess } fn check_overflow(&self) -> bool { @@ -612,7 +612,7 @@ impl<'b, 'tcx> CodegenCx<'b, 'tcx> { // user defined names let mut name = String::with_capacity(prefix.len() + 6); name.push_str(prefix); - name.push_str("."); + name.push('.'); base_n::push_str(idx as u128, base_n::ALPHANUMERIC_ONLY, &mut name); name } diff --git a/src/debuginfo.rs b/src/debuginfo.rs index aed15769025f1..7749308380569 100644 --- a/src/debuginfo.rs +++ b/src/debuginfo.rs @@ -225,7 +225,7 @@ impl<'gcc, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'gcc, 'tcx> { file_end_pos: BytePos(0), }; let mut fn_debug_context = FunctionDebugContext { - scopes: IndexVec::from_elem(empty_scope, &mir.source_scopes.as_slice()), + scopes: IndexVec::from_elem(empty_scope, mir.source_scopes.as_slice()), inlined_function_scopes: Default::default(), }; diff --git a/src/declare.rs b/src/declare.rs index db6edbab12d4d..f4e726a34216b 100644 --- a/src/declare.rs +++ b/src/declare.rs @@ -35,7 +35,7 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { pub fn declare_unnamed_global(&self, ty: Type<'gcc>) -> LValue<'gcc> { let name = self.generate_local_symbol_name("global"); - self.context.new_global(None, GlobalKind::Internal, ty, &name) + self.context.new_global(None, GlobalKind::Internal, ty, name) } pub fn declare_global_with_linkage( @@ -176,16 +176,14 @@ fn declare_raw_fn<'gcc>( cx.functions.borrow()[name] } else { let params: Vec<_> = param_types - .into_iter() + .iter() .enumerate() - .map(|(index, param)| { - cx.context.new_parameter(None, *param, &format!("param{}", index)) - }) // TODO(antoyo): set name. + .map(|(index, param)| cx.context.new_parameter(None, *param, format!("param{}", index))) // TODO(antoyo): set name. .collect(); #[cfg(not(feature = "master"))] let name = mangle_name(name); let func = - cx.context.new_function(None, cx.linkage.get(), return_type, ¶ms, &name, variadic); + cx.context.new_function(None, cx.linkage.get(), return_type, ¶ms, name, variadic); cx.functions.borrow_mut().insert(name.to_string(), func); #[cfg(feature = "master")] @@ -200,10 +198,10 @@ fn declare_raw_fn<'gcc>( // create a wrapper function that calls rust_eh_personality. let params: Vec<_> = param_types - .into_iter() + .iter() .enumerate() .map(|(index, param)| { - cx.context.new_parameter(None, *param, &format!("param{}", index)) + cx.context.new_parameter(None, *param, format!("param{}", index)) }) // TODO(antoyo): set name. .collect(); let gcc_func = cx.context.new_function( diff --git a/src/int.rs b/src/int.rs index 841bcf592e489..fe8625d0642fc 100644 --- a/src/int.rs +++ b/src/int.rs @@ -2,8 +2,6 @@ //! This module exists because some integer types are not supported on some gcc platforms, e.g. //! 128-bit integers on 32-bit platforms and thus require to be handled manually. -use std::convert::TryFrom; - use gccjit::{BinaryOp, ComparisonOp, FunctionType, Location, RValue, ToRValue, Type, UnaryOp}; use rustc_codegen_ssa::common::{IntPredicate, TypeKind}; use rustc_codegen_ssa::traits::{BackendTypes, BaseTypeMethods, BuilderMethods, OverflowOp}; @@ -126,7 +124,7 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { let shift_value = self.gcc_sub(sixty_four, b); // NOTE: cast low to its unsigned type in order to perform a logical right shift. - let unsigned_type = native_int_type.to_unsigned(&self.cx); + let unsigned_type = native_int_type.to_unsigned(self.cx); let casted_low = self.context.new_cast(self.location, self.low(a), unsigned_type); let shifted_low = casted_low >> self.context.new_cast(self.location, b, unsigned_type); let shifted_low = self.context.new_cast(self.location, shifted_low, native_int_type); @@ -258,7 +256,7 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { let new_kind = match typ.kind() { Int(t @ Isize) => Int(t.normalize(self.tcx.sess.target.pointer_width)), Uint(t @ Usize) => Uint(t.normalize(self.tcx.sess.target.pointer_width)), - t @ (Uint(_) | Int(_)) => t.clone(), + t @ (Uint(_) | Int(_)) => *t, _ => panic!("tried to get overflow intrinsic for op applied to non-int type"), }; @@ -344,7 +342,7 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { } }; - let intrinsic = self.context.get_builtin_function(&name); + let intrinsic = self.context.get_builtin_function(name); let res = self .current_func() // TODO(antoyo): is it correct to use rhs type instead of the parameter typ? @@ -454,7 +452,7 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { let native_int_type = a_type.dyncast_array().expect("get element type"); // NOTE: cast low to its unsigned type in order to perform a comparison correctly (e.g. // the sign is only on high). - let unsigned_type = native_int_type.to_unsigned(&self.cx); + let unsigned_type = native_int_type.to_unsigned(self.cx); let lhs_low = self.context.new_cast(self.location, self.low(lhs), unsigned_type); let rhs_low = self.context.new_cast(self.location, self.low(rhs), unsigned_type); @@ -589,7 +587,7 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { | IntPredicate::IntULT | IntPredicate::IntULE => { if !a_type.is_vector() { - let unsigned_type = a_type.to_unsigned(&self.cx); + let unsigned_type = a_type.to_unsigned(self.cx); lhs = self.context.new_cast(self.location, lhs, unsigned_type); rhs = self.context.new_cast(self.location, rhs, unsigned_type); } @@ -673,7 +671,7 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { // NOTE: cast low to its unsigned type in order to perform a logical right shift. // TODO(antoyo): adjust this ^ comment. - let unsigned_type = native_int_type.to_unsigned(&self.cx); + let unsigned_type = native_int_type.to_unsigned(self.cx); let casted_low = self.context.new_cast(self.location, self.low(a), unsigned_type); let shift_value = self.context.new_cast(self.location, sixty_four - b, unsigned_type); let high_low = @@ -727,7 +725,7 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { pub fn gcc_int(&self, typ: Type<'gcc>, int: i64) -> RValue<'gcc> { if self.is_native_int_type_or_bool(typ) { - self.context.new_rvalue_from_long(typ, i64::try_from(int).expect("i64::try_from")) + self.context.new_rvalue_from_long(typ, int) } else { // NOTE: set the sign in high. self.from_low_high(typ, int, -(int.is_negative() as i64)) @@ -740,8 +738,7 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { let num = self.context.new_rvalue_from_long(self.u64_type, int as i64); self.gcc_int_cast(num, typ) } else if self.is_native_int_type_or_bool(typ) { - self.context - .new_rvalue_from_long(typ, u64::try_from(int).expect("u64::try_from") as i64) + self.context.new_rvalue_from_long(typ, int as i64) } else { self.from_low_high(typ, int as i64, 0) } diff --git a/src/intrinsic/llvm.rs b/src/intrinsic/llvm.rs index ce8dee69a9886..c845ee5fe5fd6 100644 --- a/src/intrinsic/llvm.rs +++ b/src/intrinsic/llvm.rs @@ -15,7 +15,7 @@ pub fn adjust_intrinsic_arguments<'a, 'b, 'gcc, 'tcx>( // Some LLVM intrinsics do not map 1-to-1 to GCC intrinsics, so we add the missing // arguments here. if gcc_func.get_param_count() != args.len() { - match &*func_name { + match func_name { // NOTE: the following intrinsics have a different number of parameters in LLVM and GCC. "__builtin_ia32_prold512_mask" | "__builtin_ia32_pmuldq512_mask" @@ -380,7 +380,7 @@ pub fn adjust_intrinsic_arguments<'a, 'b, 'gcc, 'tcx>( _ => (), } } else { - match &*func_name { + match func_name { "__builtin_ia32_rndscaless_mask_round" | "__builtin_ia32_rndscalesd_mask_round" => { let new_args = args.to_vec(); let arg3_type = gcc_func.get_param_type(2); @@ -629,14 +629,11 @@ pub fn intrinsic<'gcc, 'tcx>(name: &str, cx: &CodegenCx<'gcc, 'tcx>) -> Function #[cfg(feature = "master")] pub fn intrinsic<'gcc, 'tcx>(name: &str, cx: &CodegenCx<'gcc, 'tcx>) -> Function<'gcc> { - match name { - "llvm.prefetch" => { - let gcc_name = "__builtin_prefetch"; - let func = cx.context.get_builtin_function(gcc_name); - cx.functions.borrow_mut().insert(gcc_name.to_string(), func); - return func; - } - _ => (), + if name == "llvm.prefetch" { + let gcc_name = "__builtin_prefetch"; + let func = cx.context.get_builtin_function(gcc_name); + cx.functions.borrow_mut().insert(gcc_name.to_string(), func); + return func; } let gcc_name = match name { diff --git a/src/intrinsic/mod.rs b/src/intrinsic/mod.rs index a6c8b72e851b2..0cd75ae14250f 100644 --- a/src/intrinsic/mod.rs +++ b/src/intrinsic/mod.rs @@ -91,7 +91,7 @@ fn get_simple_intrinsic<'gcc, 'tcx>( sym::abort => "abort", _ => return None, }; - Some(cx.context.get_builtin_function(&gcc_name)) + Some(cx.context.get_builtin_function(gcc_name)) } impl<'a, 'gcc, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'a, 'gcc, 'tcx> { @@ -699,13 +699,13 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { let count_leading_zeroes = // TODO(antoyo): write a new function Type::is_compatible_with(&Type) and use it here // instead of using is_uint(). - if arg_type.is_uint(&self.cx) { + if arg_type.is_uint(self.cx) { "__builtin_clz" } - else if arg_type.is_ulong(&self.cx) { + else if arg_type.is_ulong(self.cx) { "__builtin_clzl" } - else if arg_type.is_ulonglong(&self.cx) { + else if arg_type.is_ulonglong(self.cx) { "__builtin_clzll" } else if width == 128 { @@ -780,17 +780,17 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { let (count_trailing_zeroes, expected_type) = // TODO(antoyo): write a new function Type::is_compatible_with(&Type) and use it here // instead of using is_uint(). - if arg_type.is_uchar(&self.cx) || arg_type.is_ushort(&self.cx) || arg_type.is_uint(&self.cx) { + if arg_type.is_uchar(self.cx) || arg_type.is_ushort(self.cx) || arg_type.is_uint(self.cx) { // NOTE: we don't need to & 0xFF for uchar because the result is undefined on zero. ("__builtin_ctz", self.cx.uint_type) } - else if arg_type.is_ulong(&self.cx) { + else if arg_type.is_ulong(self.cx) { ("__builtin_ctzl", self.cx.ulong_type) } - else if arg_type.is_ulonglong(&self.cx) { + else if arg_type.is_ulonglong(self.cx) { ("__builtin_ctzll", self.cx.ulonglong_type) } - else if arg_type.is_u128(&self.cx) { + else if arg_type.is_u128(self.cx) { // Adapted from the algorithm to count leading zeroes from: https://stackoverflow.com/a/28433850/389119 let array_type = self.context.new_array_type(None, arg_type, 3); let result = self.current_func() @@ -872,7 +872,7 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { // only break apart 128-bit ints if they're not natively supported // TODO(antoyo): remove this if/when native 128-bit integers land in libgccjit - if value_type.is_u128(&self.cx) && !self.cx.supports_128bit_integers { + if value_type.is_u128(self.cx) && !self.cx.supports_128bit_integers { let sixty_four = self.gcc_int(value_type, 64); let right_shift = self.gcc_lshr(value, sixty_four); let high = self.gcc_int_cast(right_shift, self.cx.ulonglong_type); @@ -995,7 +995,7 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { // Return `result_type`'s maximum or minimum value on overflow // NOTE: convert the type to unsigned to have an unsigned shift. - let unsigned_type = result_type.to_unsigned(&self.cx); + let unsigned_type = result_type.to_unsigned(self.cx); let shifted = self.gcc_lshr( self.gcc_int_cast(lhs, unsigned_type), self.gcc_int(unsigned_type, width as i64 - 1), diff --git a/src/intrinsic/simd.rs b/src/intrinsic/simd.rs index e9af34059a0ec..91caa822d0a74 100644 --- a/src/intrinsic/simd.rs +++ b/src/intrinsic/simd.rs @@ -308,10 +308,9 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( }) .collect(); return Ok(bx.context.new_rvalue_from_vector(None, v_type, &elems)); - } else { - // avoid the unnecessary truncation as an optimization. - return Ok(bx.context.new_bitcast(None, result, v_type)); } + // avoid the unnecessary truncation as an optimization. + return Ok(bx.context.new_bitcast(None, result, v_type)); } // since gcc doesn't have vector shuffle methods available in non-patched builds, fallback to // component-wise bitreverses if they're not available. diff --git a/src/type_of.rs b/src/type_of.rs index 8f9bfbbd18fb0..6779d95359c2e 100644 --- a/src/type_of.rs +++ b/src/type_of.rs @@ -220,7 +220,7 @@ impl<'tcx> LayoutGccExt<'tcx> for TyAndLayout<'tcx> { // to fn_ptr_backend_type handle the on-stack attribute. // TODO(antoyo): find a less hackish way to hande the on-stack attribute. ty::FnPtr(sig) => { - cx.fn_ptr_backend_type(&cx.fn_abi_of_fn_ptr(sig, ty::List::empty())) + cx.fn_ptr_backend_type(cx.fn_abi_of_fn_ptr(sig, ty::List::empty())) } _ => self.scalar_gcc_type_at(cx, scalar, Size::ZERO), }; From 9ea3c1905573add3fbd2d768f5a9eb0ef2628ddc Mon Sep 17 00:00:00 2001 From: tempdragon <645703113@qq.com> Date: Sat, 9 Mar 2024 13:54:30 +0800 Subject: [PATCH 020/892] fix(fmt/style): Further apply Clippy suggestions manually 1. Fix Pattern Type Mismatch by Adding deref's 2. Move commented `else if` to previous block in `intrinsic.rs` --- src/debuginfo.rs | 21 +++++++++++-------- src/int.rs | 4 ++-- src/intrinsic/mod.rs | 32 ++++++++++++++++------------- src/intrinsic/simd.rs | 48 +++++++++++++++++++++---------------------- src/type_of.rs | 2 +- 5 files changed, 58 insertions(+), 49 deletions(-) diff --git a/src/debuginfo.rs b/src/debuginfo.rs index 7749308380569..a485225a25604 100644 --- a/src/debuginfo.rs +++ b/src/debuginfo.rs @@ -91,7 +91,7 @@ fn compute_mir_scopes<'gcc, 'tcx>( /// FIXME(tempdragon/?): Add Scope Support Here. fn make_mir_scope<'gcc, 'tcx>( cx: &CodegenCx<'gcc, 'tcx>, - instance: Instance<'tcx>, + _instance: Instance<'tcx>, mir: &Body<'tcx>, variables: &Option>, debug_context: &mut FunctionDebugContext<'tcx, (), Location<'gcc>>, @@ -104,7 +104,7 @@ fn make_mir_scope<'gcc, 'tcx>( let scope_data = &mir.source_scopes[scope]; let parent_scope = if let Some(parent) = scope_data.parent_scope { - make_mir_scope(cx, instance, mir, variables, debug_context, instantiated, parent); + make_mir_scope(cx, _instance, mir, variables, debug_context, instantiated, parent); debug_context.scopes[parent] } else { // The root is the function itself. @@ -118,7 +118,7 @@ fn make_mir_scope<'gcc, 'tcx>( return; }; - if let Some(vars) = variables { + if let Some(ref vars) = *variables { if !vars.contains(scope) && scope_data.inlined.is_none() { // Do not create a DIScope if there are no variables defined in this // MIR `SourceScope`, and it's not `inlined`, to avoid debuginfo bloat. @@ -136,8 +136,13 @@ fn make_mir_scope<'gcc, 'tcx>( let inlined_at = scope_data.inlined.map(|(_, callsite_span)| { // FIXME(eddyb) this doesn't account for the macro-related // `Span` fixups that `rustc_codegen_ssa::mir::debuginfo` does. - let callsite_scope = parent_scope.adjust_dbg_scope_for_span(cx, callsite_span); - cx.dbg_loc(callsite_scope, parent_scope.inlined_at, callsite_span) + + // NOTE: These variables passed () here. + // Changed to comply to clippy. + + /* let callsite_scope = */ + parent_scope.adjust_dbg_scope_for_span(cx, callsite_span); + cx.dbg_loc(/* callsite_scope */ (), parent_scope.inlined_at, callsite_span) }); let p_inlined_at = parent_scope.inlined_at; // TODO(tempdragon): dbg_scope: Add support for scope extension here. @@ -275,15 +280,15 @@ impl<'gcc, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'gcc, 'tcx> { let pos = span.lo(); let DebugLoc { file, line, col } = self.lookup_debug_loc(pos); let loc = match &file.name { - rustc_span::FileName::Real(name) => match name { - rustc_span::RealFileName::LocalPath(name) => { + rustc_span::FileName::Real(ref name) => match &name { + rustc_span::RealFileName::LocalPath(ref name) => { if let Some(name) = name.to_str() { self.context.new_location(name, line as i32, col as i32) } else { Location::null() } } - rustc_span::RealFileName::Remapped { local_path, virtual_name: _ } => { + rustc_span::RealFileName::Remapped { ref local_path, virtual_name: _unused } => { if let Some(name) = local_path.as_ref() { if let Some(name) = name.to_str() { self.context.new_location(name, line as i32, col as i32) diff --git a/src/int.rs b/src/int.rs index fe8625d0642fc..6d73baa8a9d6c 100644 --- a/src/int.rs +++ b/src/int.rs @@ -253,10 +253,10 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { ) -> (::Value, ::Value) { use rustc_middle::ty::{Int, IntTy::*, Uint, UintTy::*}; - let new_kind = match typ.kind() { + let new_kind = match *typ.kind() { Int(t @ Isize) => Int(t.normalize(self.tcx.sess.target.pointer_width)), Uint(t @ Usize) => Uint(t.normalize(self.tcx.sess.target.pointer_width)), - t @ (Uint(_) | Int(_)) => *t, + t @ (Uint(_) | Int(_)) => t, _ => panic!("tried to get overflow intrinsic for op applied to non-int type"), }; diff --git a/src/intrinsic/mod.rs b/src/intrinsic/mod.rs index 0cd75ae14250f..b170f4303019c 100644 --- a/src/intrinsic/mod.rs +++ b/src/intrinsic/mod.rs @@ -166,7 +166,9 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'a, 'gcc, 'tcx> { sym::volatile_load | sym::unaligned_volatile_load => { let tp_ty = fn_args.type_at(0); let ptr = args[0].immediate(); - let load = if let PassMode::Cast { cast: ty, pad_i32: _ } = &fn_abi.ret.mode { + // The reference was changed to clone to comply to clippy. + let load = if let PassMode::Cast { cast: ty, pad_i32: _ } = fn_abi.ret.mode.clone() + { let gcc_ty = ty.gcc_type(self); self.volatile_load(gcc_ty, ptr) } else { @@ -308,17 +310,18 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'a, 'gcc, 'tcx> { let b = args[1].immediate(); if layout.size().bytes() == 0 { self.const_bool(true) - } - /*else if use_integer_compare { - let integer_ty = self.type_ix(layout.size.bits()); // FIXME(antoyo): LLVM creates an integer of 96 bits for [i32; 3], but gcc doesn't support this, so it creates an integer of 128 bits. - let ptr_ty = self.type_ptr_to(integer_ty); - let a_ptr = self.bitcast(a, ptr_ty); - let a_val = self.load(integer_ty, a_ptr, layout.align.abi); - let b_ptr = self.bitcast(b, ptr_ty); - let b_val = self.load(integer_ty, b_ptr, layout.align.abi); - self.icmp(IntPredicate::IntEQ, a_val, b_val) - }*/ - else { + // The else if an immediate neighbor of this block. + // It is moved here to comply to Clippy. + /*else if use_integer_compare { + let integer_ty = self.type_ix(layout.size.bits()); // FIXME(antoyo): LLVM creates an integer of 96 bits for [i32; 3], but gcc doesn't support this, so it creates an integer of 128 bits. + let ptr_ty = self.type_ptr_to(integer_ty); + let a_ptr = self.bitcast(a, ptr_ty); + let a_val = self.load(integer_ty, a_ptr, layout.align.abi); + let b_ptr = self.bitcast(b, ptr_ty); + let b_val = self.load(integer_ty, b_ptr, layout.align.abi); + self.icmp(IntPredicate::IntEQ, a_val, b_val) + }*/ + } else { let void_ptr_type = self.context.new_type::<*const ()>(); let a_ptr = self.bitcast(a, void_ptr_type); let b_ptr = self.bitcast(b, void_ptr_type); @@ -385,7 +388,8 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'a, 'gcc, 'tcx> { }; if !fn_abi.ret.is_ignore() { - if let PassMode::Cast { cast: ty, .. } = &fn_abi.ret.mode { + // The reference was changed to clone to comply to clippy. + if let PassMode::Cast { cast: ty, .. } = fn_abi.ret.mode.clone() { let ptr_llty = self.type_ptr_to(ty.gcc_type(self)); let ptr = self.pointercast(result.llval, ptr_llty); self.store(llval, ptr, result.align); @@ -586,7 +590,7 @@ fn int_type_width_signed<'gcc, 'tcx>( ty: Ty<'tcx>, cx: &CodegenCx<'gcc, 'tcx>, ) -> Option<(u64, bool)> { - match ty.kind() { + match *ty.kind() { ty::Int(t) => Some(( match t { rustc_middle::ty::IntTy::Isize => u64::from(cx.tcx.sess.target.pointer_width), diff --git a/src/intrinsic/simd.rs b/src/intrinsic/simd.rs index 91caa822d0a74..d5a2c6125104f 100644 --- a/src/intrinsic/simd.rs +++ b/src/intrinsic/simd.rs @@ -71,11 +71,11 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( let expected_bytes = len / 8 + ((len % 8 > 0) as u64); let mask_ty = arg_tys[0]; - let mut mask = match mask_ty.kind() { + let mut mask = match *mask_ty.kind() { ty::Int(i) if i.bit_width() == Some(expected_int_bits) => args[0].immediate(), ty::Uint(i) if i.bit_width() == Some(expected_int_bits) => args[0].immediate(), ty::Array(elem, len) - if matches!(elem.kind(), ty::Uint(ty::UintTy::U8)) + if matches!(*elem.kind(), ty::Uint(ty::UintTy::U8)) && len.try_eval_target_usize(bx.tcx, ty::ParamEnv::reveal_all()) == Some(expected_bytes) => { @@ -353,8 +353,8 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( if name == sym::simd_shuffle { // Make sure this is actually an array, since typeck only checks the length-suffixed // version of this intrinsic. - let n: u64 = match args[2].layout.ty.kind() { - ty::Array(ty, len) if matches!(ty.kind(), ty::Uint(ty::UintTy::U32)) => { + let n: u64 = match *args[2].layout.ty.kind() { + ty::Array(ty, len) if matches!(*ty.kind(), ty::Uint(ty::UintTy::U32)) => { len.try_eval_target_usize(bx.cx.tcx, ty::ParamEnv::reveal_all()).unwrap_or_else( || span_bug!(span, "could not evaluate shuffle index array length"), ) @@ -427,7 +427,7 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( m_len == v_len, InvalidMonomorphization::MismatchedLengths { span, name, m_len, v_len } ); - match m_elem_ty.kind() { + match *m_elem_ty.kind() { ty::Int(_) => {} _ => return_error!(InvalidMonomorphization::MaskType { span, name, ty: m_elem_ty }), } @@ -460,13 +460,13 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( Unsupported, } - let in_style = match in_elem.kind() { + let in_style = match *in_elem.kind() { ty::Int(_) | ty::Uint(_) => Style::Int, ty::Float(_) => Style::Float, _ => Style::Unsupported, }; - let out_style = match out_elem.kind() { + let out_style = match *out_elem.kind() { ty::Int(_) | ty::Uint(_) => Style::Int, ty::Float(_) => Style::Float, _ => Style::Unsupported, @@ -493,7 +493,7 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( macro_rules! arith_binary { ($($name: ident: $($($p: ident),* => $call: ident),*;)*) => { $(if name == sym::$name { - match in_elem.kind() { + match *in_elem.kind() { $($(ty::$p(_))|* => { return Ok(bx.$call(args[0].immediate(), args[1].immediate())) })* @@ -543,13 +543,13 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( shift += 1; } - match ret_ty.kind() { + match *ret_ty.kind() { ty::Uint(i) if i.bit_width() == Some(expected_int_bits) => { // Zero-extend iN to the bitmask type: return Ok(result); } ty::Array(elem, len) - if matches!(elem.kind(), ty::Uint(ty::UintTy::U8)) + if matches!(*elem.kind(), ty::Uint(ty::UintTy::U8)) && len.try_eval_target_usize(bx.tcx, ty::ParamEnv::reveal_all()) == Some(expected_bytes) => { @@ -588,7 +588,7 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( return Err(()); }}; } - let (elem_ty_str, elem_ty) = if let ty::Float(f) = in_elem.kind() { + let (elem_ty_str, elem_ty) = if let ty::Float(ref f) = *in_elem.kind() { let elem_ty = bx.cx.type_float_from_ty(*f); match f.bit_width() { 32 => ("f", elem_ty), @@ -795,7 +795,7 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( // This counts how many pointers fn ptr_count(t: Ty<'_>) -> usize { - match t.kind() { + match *t.kind() { ty::RawPtr(p) => 1 + ptr_count(p.ty), _ => 0, } @@ -803,7 +803,7 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( // Non-ptr type fn non_ptr(t: Ty<'_>) -> Ty<'_> { - match t.kind() { + match *t.kind() { ty::RawPtr(p) => non_ptr(p.ty), _ => t, } @@ -813,7 +813,7 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( // to the element type of the first argument let (_, element_ty0) = arg_tys[0].simd_size_and_type(bx.tcx()); let (_, element_ty1) = arg_tys[1].simd_size_and_type(bx.tcx()); - let (pointer_count, underlying_ty) = match element_ty1.kind() { + let (pointer_count, underlying_ty) = match *element_ty1.kind() { ty::RawPtr(p) if p.ty == in_elem => (ptr_count(element_ty1), non_ptr(element_ty1)), _ => { require!( @@ -837,7 +837,7 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( // The element type of the third argument must be a signed integer type of any width: let (_, element_ty2) = arg_tys[2].simd_size_and_type(bx.tcx()); - match element_ty2.kind() { + match *element_ty2.kind() { ty::Int(_) => (), _ => { require!( @@ -909,7 +909,7 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( // This counts how many pointers fn ptr_count(t: Ty<'_>) -> usize { - match t.kind() { + match *t.kind() { ty::RawPtr(p) => 1 + ptr_count(p.ty), _ => 0, } @@ -917,7 +917,7 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( // Non-ptr type fn non_ptr(t: Ty<'_>) -> Ty<'_> { - match t.kind() { + match *t.kind() { ty::RawPtr(p) => non_ptr(p.ty), _ => t, } @@ -928,7 +928,7 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( let (_, element_ty0) = arg_tys[0].simd_size_and_type(bx.tcx()); let (_, element_ty1) = arg_tys[1].simd_size_and_type(bx.tcx()); let (_, element_ty2) = arg_tys[2].simd_size_and_type(bx.tcx()); - let (pointer_count, underlying_ty) = match element_ty1.kind() { + let (pointer_count, underlying_ty) = match *element_ty1.kind() { ty::RawPtr(p) if p.ty == in_elem && p.mutbl == hir::Mutability::Mut => { (ptr_count(element_ty1), non_ptr(element_ty1)) } @@ -953,7 +953,7 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( assert_eq!(underlying_ty, non_ptr(element_ty0)); // The element type of the third argument must be a signed integer type of any width: - match element_ty2.kind() { + match *element_ty2.kind() { ty::Int(_) => (), _ => { require!( @@ -1011,7 +1011,7 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( macro_rules! arith_unary { ($($name: ident: $($($p: ident),* => $call: ident),*;)*) => { $(if name == sym::$name { - match in_elem.kind() { + match *in_elem.kind() { $($(ty::$p(_))|* => { return Ok(bx.$call(args[0].immediate())) })* @@ -1135,7 +1135,7 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( ret_ty == in_elem, InvalidMonomorphization::ReturnType { span, name, in_elem, in_ty, ret_ty } ); - return match in_elem.kind() { + return match *in_elem.kind() { ty::Int(_) | ty::Uint(_) => { let r = bx.vector_reduce_op(args[0].immediate(), $vec_op); if $ordered { @@ -1204,7 +1204,7 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( ret_ty == in_elem, InvalidMonomorphization::ReturnType { span, name, in_elem, in_ty, ret_ty } ); - return match in_elem.kind() { + return match *in_elem.kind() { ty::Int(_) | ty::Uint(_) => Ok(bx.$int_red(args[0].immediate())), ty::Float(_) => Ok(bx.$float_red(args[0].immediate())), _ => return_error!(InvalidMonomorphization::UnsupportedSymbol { @@ -1233,7 +1233,7 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( ); args[0].immediate() } else { - match in_elem.kind() { + match *in_elem.kind() { ty::Int(_) | ty::Uint(_) => {} _ => return_error!(InvalidMonomorphization::UnsupportedSymbol { span, @@ -1247,7 +1247,7 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( args[0].immediate() }; - return match in_elem.kind() { + return match *in_elem.kind() { ty::Int(_) | ty::Uint(_) => { let r = bx.vector_reduce_op(input, $op); Ok(if !$boolean { diff --git a/src/type_of.rs b/src/type_of.rs index 6779d95359c2e..1c9a41649aae1 100644 --- a/src/type_of.rs +++ b/src/type_of.rs @@ -90,7 +90,7 @@ fn uncached_gcc_type<'gcc, 'tcx>( Abi::Uninhabited | Abi::Aggregate { .. } => {} } - let name = match layout.ty.kind() { + let name = match *layout.ty.kind() { // FIXME(eddyb) producing readable type names for trait objects can result // in problematically distinct types due to HRTB and subtyping (see #47638). // ty::Dynamic(..) | From c6b75581d06a573eb8f419d83f4ecbed18c0e805 Mon Sep 17 00:00:00 2001 From: tempdragon <645703113@qq.com> Date: Sat, 9 Mar 2024 14:26:46 +0800 Subject: [PATCH 021/892] fix(declare.rs): Clone `name` when buiding without the master feat. --- src/declare.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/declare.rs b/src/declare.rs index f4e726a34216b..555f95fb1556a 100644 --- a/src/declare.rs +++ b/src/declare.rs @@ -182,6 +182,18 @@ fn declare_raw_fn<'gcc>( .collect(); #[cfg(not(feature = "master"))] let name = mangle_name(name); + + #[cfg(not(feature = "master"))] + let func = cx.context.new_function( + None, + cx.linkage.get(), + return_type, + ¶ms, + name.clone(), + variadic, + ); + + #[cfg(feature = "master")] let func = cx.context.new_function(None, cx.linkage.get(), return_type, ¶ms, name, variadic); cx.functions.borrow_mut().insert(name.to_string(), func); From 8d4d87859b6ec9d5aae2b0297514b27d413c19d2 Mon Sep 17 00:00:00 2001 From: tempdragon <645703113@qq.com> Date: Mon, 11 Mar 2024 12:13:30 +0800 Subject: [PATCH 022/892] fix(clippy): Clone-related clippy workarounds 1. Use `clone_from` in place of `clone()` in `builder.rs` 2. Change `&name` to `name.clone()` in `debuginfo.rs`(Is this really efficient? But I can't find other workarounds.) --- src/builder.rs | 2 +- src/debuginfo.rs | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/builder.rs b/src/builder.rs index 2241e0ea36437..ebd6595b4382f 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -225,7 +225,7 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { let mut on_stack_param_indices = FxHashSet::default(); if let Some(indices) = self.on_stack_params.borrow().get(&gcc_func) { - on_stack_param_indices = indices.clone(); + on_stack_param_indices.clone_from(indices); } if all_args_match { diff --git a/src/debuginfo.rs b/src/debuginfo.rs index a485225a25604..7ca4743f4b8ef 100644 --- a/src/debuginfo.rs +++ b/src/debuginfo.rs @@ -279,9 +279,9 @@ impl<'gcc, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'gcc, 'tcx> { ) -> Self::DILocation { let pos = span.lo(); let DebugLoc { file, line, col } = self.lookup_debug_loc(pos); - let loc = match &file.name { - rustc_span::FileName::Real(ref name) => match &name { - rustc_span::RealFileName::LocalPath(ref name) => { + let loc = match file.name { + rustc_span::FileName::Real(ref name) => match name.clone() { + rustc_span::RealFileName::LocalPath(name) => { if let Some(name) = name.to_str() { self.context.new_location(name, line as i32, col as i32) } else { From ad97b8c061e6f39a52daaf036c9721e17510c30c Mon Sep 17 00:00:00 2001 From: tempdragon <645703113@qq.com> Date: Mon, 11 Mar 2024 12:20:36 +0800 Subject: [PATCH 023/892] fix(liftime): Gen. by cargo clippy cmd: `cargo clippy --fix --lib -p rustc_codegen_gcc --allow-dirtyxs` --- src/asm.rs | 2 +- src/attributes.rs | 4 ++-- src/builder.rs | 8 ++++---- src/common.rs | 2 +- src/consts.rs | 4 ++-- src/intrinsic/llvm.rs | 10 +++++----- src/intrinsic/mod.rs | 12 ++++++------ src/intrinsic/simd.rs | 4 ++-- src/lib.rs | 2 +- 9 files changed, 24 insertions(+), 24 deletions(-) diff --git a/src/asm.rs b/src/asm.rs index 72d572465f404..68de3fd7b079b 100644 --- a/src/asm.rs +++ b/src/asm.rs @@ -691,7 +691,7 @@ fn reg_to_gcc(reg: InlineAsmRegOrRegClass) -> ConstraintOrRegister { /// Type to use for outputs that are discarded. It doesn't really matter what /// the type is, as long as it is valid for the constraint code. -fn dummy_output_type<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, reg: InlineAsmRegClass) -> Type<'gcc> { +fn dummy_output_type<'gcc>(cx: &CodegenCx<'gcc, '_>, reg: InlineAsmRegClass) -> Type<'gcc> { match reg { InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::reg) => cx.type_i32(), InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::preg) => unimplemented!(), diff --git a/src/attributes.rs b/src/attributes.rs index 2ce0c83008f16..6c518f2c45ebb 100644 --- a/src/attributes.rs +++ b/src/attributes.rs @@ -15,8 +15,8 @@ use crate::{context::CodegenCx, errors::TiedTargetFeatures}; /// Get GCC attribute for the provided inline heuristic. #[cfg(feature = "master")] #[inline] -fn inline_attr<'gcc, 'tcx>( - cx: &CodegenCx<'gcc, 'tcx>, +fn inline_attr<'gcc>( + cx: &CodegenCx<'gcc, '_>, inline: InlineAttr, ) -> Option> { match inline { diff --git a/src/builder.rs b/src/builder.rs index ebd6595b4382f..dbecd297f3844 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -506,8 +506,8 @@ impl<'gcc, 'tcx> BackendTypes for Builder<'_, 'gcc, 'tcx> { type DIVariable = as BackendTypes>::DIVariable; } -fn set_rvalue_location<'a, 'gcc, 'tcx>( - bx: &mut Builder<'a, 'gcc, 'tcx>, +fn set_rvalue_location<'gcc>( + bx: &mut Builder<'_, 'gcc, '_>, rvalue: RValue<'gcc>, ) -> RValue<'gcc> { if bx.location.is_some() { @@ -979,8 +979,8 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { return OperandRef::zero_sized(place.layout); } - fn scalar_load_metadata<'a, 'gcc, 'tcx>( - bx: &mut Builder<'a, 'gcc, 'tcx>, + fn scalar_load_metadata<'gcc>( + bx: &mut Builder<'_, 'gcc, '_>, load: RValue<'gcc>, scalar: &abi::Scalar, ) { diff --git a/src/common.rs b/src/common.rs index 6a3b5442adf27..ff05132653894 100644 --- a/src/common.rs +++ b/src/common.rs @@ -30,7 +30,7 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { } } -pub fn bytes_in_context<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, bytes: &[u8]) -> RValue<'gcc> { +pub fn bytes_in_context<'gcc>(cx: &CodegenCx<'gcc, '_>, bytes: &[u8]) -> RValue<'gcc> { let context = &cx.context; let byte_type = context.new_type::(); let typ = context.new_array_type(None, byte_type, bytes.len() as u64); diff --git a/src/consts.rs b/src/consts.rs index f47fd56553323..0d7ecb56b34be 100644 --- a/src/consts.rs +++ b/src/consts.rs @@ -18,8 +18,8 @@ use crate::context::CodegenCx; use crate::errors::InvalidMinimumAlignment; use crate::type_of::LayoutGccExt; -fn set_global_alignment<'gcc, 'tcx>( - cx: &CodegenCx<'gcc, 'tcx>, +fn set_global_alignment<'gcc>( + cx: &CodegenCx<'gcc, '_>, gv: LValue<'gcc>, mut align: Align, ) { diff --git a/src/intrinsic/llvm.rs b/src/intrinsic/llvm.rs index c845ee5fe5fd6..94c9869bd1f13 100644 --- a/src/intrinsic/llvm.rs +++ b/src/intrinsic/llvm.rs @@ -5,8 +5,8 @@ use rustc_codegen_ssa::traits::BuilderMethods; use crate::{builder::Builder, context::CodegenCx}; -pub fn adjust_intrinsic_arguments<'a, 'b, 'gcc, 'tcx>( - builder: &Builder<'a, 'gcc, 'tcx>, +pub fn adjust_intrinsic_arguments<'b, 'gcc>( + builder: &Builder<'_, 'gcc, '_>, gcc_func: FunctionPtrType<'gcc>, mut args: Cow<'b, [RValue<'gcc>]>, func_name: &str, @@ -479,8 +479,8 @@ pub fn adjust_intrinsic_arguments<'a, 'b, 'gcc, 'tcx>( args } -pub fn adjust_intrinsic_return_value<'a, 'gcc, 'tcx>( - builder: &Builder<'a, 'gcc, 'tcx>, +pub fn adjust_intrinsic_return_value<'gcc>( + builder: &Builder<'_, 'gcc, '_>, mut return_value: RValue<'gcc>, func_name: &str, args: &[RValue<'gcc>], @@ -628,7 +628,7 @@ pub fn intrinsic<'gcc, 'tcx>(name: &str, cx: &CodegenCx<'gcc, 'tcx>) -> Function } #[cfg(feature = "master")] -pub fn intrinsic<'gcc, 'tcx>(name: &str, cx: &CodegenCx<'gcc, 'tcx>) -> Function<'gcc> { +pub fn intrinsic<'gcc>(name: &str, cx: &CodegenCx<'gcc, '_>) -> Function<'gcc> { if name == "llvm.prefetch" { let gcc_name = "__builtin_prefetch"; let func = cx.context.get_builtin_function(gcc_name); diff --git a/src/intrinsic/mod.rs b/src/intrinsic/mod.rs index b170f4303019c..b5835d5649cce 100644 --- a/src/intrinsic/mod.rs +++ b/src/intrinsic/mod.rs @@ -39,8 +39,8 @@ use crate::context::CodegenCx; use crate::intrinsic::simd::generic_simd_intrinsic; use crate::type_of::LayoutGccExt; -fn get_simple_intrinsic<'gcc, 'tcx>( - cx: &CodegenCx<'gcc, 'tcx>, +fn get_simple_intrinsic<'gcc>( + cx: &CodegenCx<'gcc, '_>, name: Symbol, ) -> Option> { let gcc_name = match name { @@ -586,9 +586,9 @@ impl<'gcc, 'tcx> ArgAbiExt<'gcc, 'tcx> for ArgAbi<'tcx, Ty<'tcx>> { } } -fn int_type_width_signed<'gcc, 'tcx>( +fn int_type_width_signed<'tcx>( ty: Ty<'tcx>, - cx: &CodegenCx<'gcc, 'tcx>, + cx: &CodegenCx<'_, 'tcx>, ) -> Option<(u64, bool)> { match *ty.kind() { ty::Int(t) => Some(( @@ -1099,8 +1099,8 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { } } -fn try_intrinsic<'a, 'b, 'gcc, 'tcx>( - bx: &'b mut Builder<'a, 'gcc, 'tcx>, +fn try_intrinsic<'gcc>( + bx: &mut Builder<'_, 'gcc, '_>, try_func: RValue<'gcc>, data: RValue<'gcc>, _catch_func: RValue<'gcc>, diff --git a/src/intrinsic/simd.rs b/src/intrinsic/simd.rs index d5a2c6125104f..3972673afafc0 100644 --- a/src/intrinsic/simd.rs +++ b/src/intrinsic/simd.rs @@ -694,11 +694,11 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( } #[cfg(feature = "master")] - fn gather<'a, 'gcc, 'tcx>( + fn gather<'gcc>( default: RValue<'gcc>, pointers: RValue<'gcc>, mask: RValue<'gcc>, - bx: &mut Builder<'a, 'gcc, 'tcx>, + bx: &mut Builder<'_, 'gcc, '_>, in_len: u64, invert: bool, ) -> RValue<'gcc> { diff --git a/src/lib.rs b/src/lib.rs index a4ee3015b8d3a..f2f3b6fd78780 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -270,7 +270,7 @@ impl CodegenBackend for GccCodegenBackend { } } -fn new_context<'gcc, 'tcx>(tcx: TyCtxt<'tcx>) -> Context<'gcc> { +fn new_context<'gcc>(tcx: TyCtxt<'_>) -> Context<'gcc> { let context = Context::default(); if tcx.sess.target.arch == "x86" || tcx.sess.target.arch == "x86_64" { context.add_command_line_option("-masm=intel"); From 091de55db84aa53ea7845b6ca58fc3bafc40510a Mon Sep 17 00:00:00 2001 From: tempdragon <645703113@qq.com> Date: Mon, 11 Mar 2024 12:31:16 +0800 Subject: [PATCH 024/892] fix(fmt): Try to comply to the format requirement --- src/attributes.rs | 5 +---- src/builder.rs | 5 +---- src/consts.rs | 6 +----- src/intrinsic/mod.rs | 10 ++-------- 4 files changed, 5 insertions(+), 21 deletions(-) diff --git a/src/attributes.rs b/src/attributes.rs index 6c518f2c45ebb..6238daaed1ddf 100644 --- a/src/attributes.rs +++ b/src/attributes.rs @@ -15,10 +15,7 @@ use crate::{context::CodegenCx, errors::TiedTargetFeatures}; /// Get GCC attribute for the provided inline heuristic. #[cfg(feature = "master")] #[inline] -fn inline_attr<'gcc>( - cx: &CodegenCx<'gcc, '_>, - inline: InlineAttr, -) -> Option> { +fn inline_attr<'gcc>(cx: &CodegenCx<'gcc, '_>, inline: InlineAttr) -> Option> { match inline { InlineAttr::Hint => Some(FnAttribute::Inline), InlineAttr::Always => Some(FnAttribute::AlwaysInline), diff --git a/src/builder.rs b/src/builder.rs index dbecd297f3844..7f5156f93be4f 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -506,10 +506,7 @@ impl<'gcc, 'tcx> BackendTypes for Builder<'_, 'gcc, 'tcx> { type DIVariable = as BackendTypes>::DIVariable; } -fn set_rvalue_location<'gcc>( - bx: &mut Builder<'_, 'gcc, '_>, - rvalue: RValue<'gcc>, -) -> RValue<'gcc> { +fn set_rvalue_location<'gcc>(bx: &mut Builder<'_, 'gcc, '_>, rvalue: RValue<'gcc>) -> RValue<'gcc> { if bx.location.is_some() { #[cfg(feature = "master")] rvalue.set_location(bx.location.unwrap()); diff --git a/src/consts.rs b/src/consts.rs index 0d7ecb56b34be..bbc1de1dfae9f 100644 --- a/src/consts.rs +++ b/src/consts.rs @@ -18,11 +18,7 @@ use crate::context::CodegenCx; use crate::errors::InvalidMinimumAlignment; use crate::type_of::LayoutGccExt; -fn set_global_alignment<'gcc>( - cx: &CodegenCx<'gcc, '_>, - gv: LValue<'gcc>, - mut align: Align, -) { +fn set_global_alignment<'gcc>(cx: &CodegenCx<'gcc, '_>, gv: LValue<'gcc>, mut align: Align) { // The target may require greater alignment for globals than the type does. // Note: GCC and Clang also allow `__attribute__((aligned))` on variables, // which can force it to be smaller. Rust doesn't support this yet. diff --git a/src/intrinsic/mod.rs b/src/intrinsic/mod.rs index b5835d5649cce..d4afbcbcc449d 100644 --- a/src/intrinsic/mod.rs +++ b/src/intrinsic/mod.rs @@ -39,10 +39,7 @@ use crate::context::CodegenCx; use crate::intrinsic::simd::generic_simd_intrinsic; use crate::type_of::LayoutGccExt; -fn get_simple_intrinsic<'gcc>( - cx: &CodegenCx<'gcc, '_>, - name: Symbol, -) -> Option> { +fn get_simple_intrinsic<'gcc>(cx: &CodegenCx<'gcc, '_>, name: Symbol) -> Option> { let gcc_name = match name { sym::sqrtf32 => "sqrtf", sym::sqrtf64 => "sqrt", @@ -586,10 +583,7 @@ impl<'gcc, 'tcx> ArgAbiExt<'gcc, 'tcx> for ArgAbi<'tcx, Ty<'tcx>> { } } -fn int_type_width_signed<'tcx>( - ty: Ty<'tcx>, - cx: &CodegenCx<'_, 'tcx>, -) -> Option<(u64, bool)> { +fn int_type_width_signed<'tcx>(ty: Ty<'tcx>, cx: &CodegenCx<'_, 'tcx>) -> Option<(u64, bool)> { match *ty.kind() { ty::Int(t) => Some(( match t { From d2cda90e4ecb32cbf7be08d166daa78b5dbed819 Mon Sep 17 00:00:00 2001 From: tempdragon <645703113@qq.com> Date: Mon, 11 Mar 2024 12:36:39 +0800 Subject: [PATCH 025/892] fix(clippy): redundant variables in `simd.rs` --- src/intrinsic/simd.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/intrinsic/simd.rs b/src/intrinsic/simd.rs index 3972673afafc0..8fca81091dc52 100644 --- a/src/intrinsic/simd.rs +++ b/src/intrinsic/simd.rs @@ -531,7 +531,6 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( let sign_shift = bx.context.new_rvalue_from_int(elem_type, elem_size as i32 - 1); let one = bx.context.new_rvalue_one(elem_type); - let mut shift = 0; for i in 0..in_len { let elem = bx.extract_element(vector, bx.context.new_rvalue_from_int(bx.int_type, i as i32)); @@ -539,8 +538,7 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( let masked = shifted & one; result = result | (bx.context.new_cast(None, masked, result_type) - << bx.context.new_rvalue_from_int(result_type, shift)); - shift += 1; + << bx.context.new_rvalue_from_int(result_type, i as i32)); } match *ret_ty.kind() { From 3fd9db31bf485bd177481f12344e1e501a8a0234 Mon Sep 17 00:00:00 2001 From: tempdragon <645703113@qq.com> Date: Mon, 11 Mar 2024 12:39:57 +0800 Subject: [PATCH 026/892] fix(fmt): Rewrite a condition according to clippy This looks like an (inverted) exclusive-or but I still leave it as it is in clippy. --- src/builder.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/builder.rs b/src/builder.rs index 7f5156f93be4f..79ba110e1c56d 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -256,8 +256,8 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { actual_val.dereference(self.location).to_rvalue() } else { assert!( - !((actual_ty.is_vector() && !expected_ty.is_vector()) - || (!actual_ty.is_vector() && expected_ty.is_vector())), + (!expected_ty.is_vector() || actual_ty.is_vector()) + && (expected_ty.is_vector() || !actual_ty.is_vector()), "{:?} ({}) -> {:?} ({}), index: {:?}[{}]", actual_ty, actual_ty.is_vector(), From a7d39b852a5ad19b11781c18b59d38dc6ef92932 Mon Sep 17 00:00:00 2001 From: tempdragon <645703113@qq.com> Date: Mon, 11 Mar 2024 12:55:28 +0800 Subject: [PATCH 027/892] fix(from_low_high): Renamed according to clippy requirements Changed for clippy naming convention requirement: ``` warning: methods called `from_*` usually take no `self` --> src/int.rs:996:22 | 996 | fn from_low_high(&self, typ: Type<'gcc>, low: i64, high: i64) -> RValue<'gcc> { | ^^^^^ | = help: consider choosing a less ambiguous name = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#wrong_self_convention = note: `#[warn(clippy::wrong_self_convention)]` on by default ``` --- src/int.rs | 35 +++++++++++++++++++---------------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/src/int.rs b/src/int.rs index 6d73baa8a9d6c..1b812b4d137f2 100644 --- a/src/int.rs +++ b/src/int.rs @@ -38,7 +38,7 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { self.cx.context.new_unary_op(self.location, operation, typ, a) } else { let element_type = typ.dyncast_array().expect("element type"); - self.from_low_high_rvalues( + self.concat_low_high_rvalues( typ, self.cx.context.new_unary_op( self.location, @@ -112,7 +112,7 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { let shift_value = self.gcc_sub(b, sixty_four); let high = self.high(a); let sign = if a_type.is_signed(self) { high >> sixty_three } else { zero }; - let array_value = self.from_low_high_rvalues(a_type, high >> shift_value, sign); + let array_value = self.concat_low_high_rvalues(a_type, high >> shift_value, sign); then_block.add_assignment(self.location, result, array_value); then_block.end_with_jump(self.location, after_block); @@ -128,8 +128,11 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { let casted_low = self.context.new_cast(self.location, self.low(a), unsigned_type); let shifted_low = casted_low >> self.context.new_cast(self.location, b, unsigned_type); let shifted_low = self.context.new_cast(self.location, shifted_low, native_int_type); - let array_value = - self.from_low_high_rvalues(a_type, (high << shift_value) | shifted_low, high >> b); + let array_value = self.concat_low_high_rvalues( + a_type, + (high << shift_value) | shifted_low, + high >> b, + ); actual_else_block.add_assignment(self.location, result, array_value); actual_else_block.end_with_jump(self.location, after_block); @@ -610,7 +613,7 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { { a ^ b } else { - self.from_low_high_rvalues( + self.concat_low_high_rvalues( a_type, self.low(a) ^ self.low(b), self.high(a) ^ self.high(b), @@ -659,7 +662,7 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { self.llbb().end_with_conditional(self.location, condition, then_block, else_block); let array_value = - self.from_low_high_rvalues(a_type, zero, self.low(a) << (b - sixty_four)); + self.concat_low_high_rvalues(a_type, zero, self.low(a) << (b - sixty_four)); then_block.add_assignment(self.location, result, array_value); then_block.end_with_jump(self.location, after_block); @@ -677,7 +680,7 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { let high_low = self.context.new_cast(self.location, casted_low >> shift_value, native_int_type); - let array_value = self.from_low_high_rvalues( + let array_value = self.concat_low_high_rvalues( a_type, self.low(a) << b, (self.high(a) << b) | high_low, @@ -706,7 +709,7 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { // NOTE: we also need to swap the two elements here, in addition to swapping inside // the elements themselves like done above. - return self.from_low_high_rvalues(arg_type, swapped_msb, swapped_lsb); + return self.concat_low_high_rvalues(arg_type, swapped_msb, swapped_lsb); } // TODO(antoyo): check if it's faster to use string literals and a @@ -728,7 +731,7 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { self.context.new_rvalue_from_long(typ, int) } else { // NOTE: set the sign in high. - self.from_low_high(typ, int, -(int.is_negative() as i64)) + self.concat_low_high(typ, int, -(int.is_negative() as i64)) } } @@ -740,7 +743,7 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { } else if self.is_native_int_type_or_bool(typ) { self.context.new_rvalue_from_long(typ, int as i64) } else { - self.from_low_high(typ, int as i64, 0) + self.concat_low_high(typ, int as i64, 0) } } @@ -757,7 +760,7 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { let shift = high << sixty_four; shift | self.context.new_cast(None, low, typ) } else { - self.from_low_high(typ, low as i64, high as i64) + self.concat_low_high(typ, low as i64, high as i64) } } else if typ.is_i128(self) { // FIXME(antoyo): libgccjit cannot create 128-bit values yet. @@ -772,7 +775,7 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { if self.is_native_int_type_or_bool(typ) { self.context.new_rvalue_zero(typ) } else { - self.from_low_high(typ, 0, 0) + self.concat_low_high(typ, 0, 0) } } @@ -810,7 +813,7 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { "both types should either be native or non-native for or operation" ); let native_int_type = a_type.dyncast_array().expect("get element type"); - self.from_low_high_rvalues( + self.concat_low_high_rvalues( a_type, self.context.new_binary_op( loc, @@ -855,7 +858,7 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { let is_negative = self.context.new_comparison(None, ComparisonOp::LessThan, value, zero); let is_negative = self.gcc_int_cast(is_negative, dest_element_type); - self.from_low_high_rvalues( + self.concat_low_high_rvalues( dest_typ, self.context.new_cast(None, value, dest_element_type), self.context.new_unary_op(None, UnaryOp::Minus, dest_element_type, is_negative), @@ -975,7 +978,7 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { .to_rvalue() } - fn from_low_high_rvalues( + fn concat_low_high_rvalues( &self, typ: Type<'gcc>, low: RValue<'gcc>, @@ -990,7 +993,7 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { self.context.new_array_constructor(None, typ, &values) } - fn from_low_high(&self, typ: Type<'gcc>, low: i64, high: i64) -> RValue<'gcc> { + fn concat_low_high(&self, typ: Type<'gcc>, low: i64, high: i64) -> RValue<'gcc> { let (first, last) = match self.sess().target.options.endian { Endian::Little => (low, high), Endian::Big => (high, low), From be24d391bc52107334b71c684909f2054e0164cf Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 11 Mar 2024 16:27:44 +0100 Subject: [PATCH 028/892] Use published gccjit dependency instead of git repository --- Cargo.lock | 10 ++++++---- Cargo.toml | 2 +- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ab2c7ca8a47c8..3ecb0ef6b4d29 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -79,16 +79,18 @@ dependencies = [ [[package]] name = "gccjit" -version = "1.0.0" -source = "git+https://github.com/antoyo/gccjit.rs#9f8f67edc006d543b17529a001803ffece48349e" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecaa4c3da2d74c1a991b4faff75d49ab1d0522d9a99d8e2614b3b04d226417ce" dependencies = [ "gccjit_sys", ] [[package]] name = "gccjit_sys" -version = "0.0.1" -source = "git+https://github.com/antoyo/gccjit.rs#9f8f67edc006d543b17529a001803ffece48349e" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "406a66fba005f1a02661f2f9443e5693dd3a667b7c58e70aa4ccc4c8b50b4758" dependencies = [ "libc", ] diff --git a/Cargo.toml b/Cargo.toml index 100c10ef1d7af..c5aa2eed1e004 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,7 +22,7 @@ master = ["gccjit/master"] default = ["master"] [dependencies] -gccjit = { git = "https://github.com/antoyo/gccjit.rs" } +gccjit = "2.0" # Local copy. #gccjit = { path = "../gccjit.rs" } From e3a9b1dbec93d904432351cb78786566cef1cd19 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Fri, 6 Oct 2023 15:00:44 +0000 Subject: [PATCH 029/892] Check whether a static is mutable instead of passing it down --- src/consts.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/consts.rs b/src/consts.rs index 327c9bdada924..740956f6fdfdd 100644 --- a/src/consts.rs +++ b/src/consts.rs @@ -63,7 +63,7 @@ impl<'gcc, 'tcx> StaticMethods for CodegenCx<'gcc, 'tcx> { global_value } - fn codegen_static(&self, def_id: DefId, is_mutable: bool) { + fn codegen_static(&self, def_id: DefId) { let attrs = self.tcx.codegen_fn_attrs(def_id); let value = match codegen_static_initializer(&self, def_id) { @@ -92,7 +92,7 @@ impl<'gcc, 'tcx> StaticMethods for CodegenCx<'gcc, 'tcx> { // As an optimization, all shared statics which do not have interior // mutability are placed into read-only memory. - if !is_mutable && self.type_is_freeze(ty) { + if !self.tcx.static_mutability(def_id).unwrap().is_mut() && self.type_is_freeze(ty) { #[cfg(feature = "master")] global.global_set_readonly(); } From 8fdfbf54ff95987f2f9a8c96e7f28386b3bdd7be Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Mon, 26 Feb 2024 17:43:18 +0000 Subject: [PATCH 030/892] Make some functions private that are only ever used in the same module --- src/consts.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/consts.rs b/src/consts.rs index 740956f6fdfdd..3d73a60b25504 100644 --- a/src/consts.rs +++ b/src/consts.rs @@ -349,7 +349,7 @@ pub fn const_alloc_to_gcc<'gcc, 'tcx>( cx.const_struct(&llvals, true) } -pub fn codegen_static_initializer<'gcc, 'tcx>( +fn codegen_static_initializer<'gcc, 'tcx>( cx: &CodegenCx<'gcc, 'tcx>, def_id: DefId, ) -> Result<(RValue<'gcc>, ConstAllocation<'tcx>), ErrorHandled> { From 6d573e9e3182627efc4ab099196a9234e4abc933 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Mon, 26 Feb 2024 18:03:06 +0000 Subject: [PATCH 031/892] Ensure nested allocations in statics do not get deduplicated --- src/mono_item.rs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/mono_item.rs b/src/mono_item.rs index e56c49686c012..ceaf87d164816 100644 --- a/src/mono_item.rs +++ b/src/mono_item.rs @@ -1,7 +1,9 @@ #[cfg(feature = "master")] use gccjit::{FnAttribute, VarAttribute}; use rustc_codegen_ssa::traits::PreDefineMethods; +use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, LOCAL_CRATE}; +use rustc_middle::bug; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; use rustc_middle::mir::mono::{Linkage, Visibility}; use rustc_middle::ty::layout::{FnAbiOf, LayoutOf}; @@ -23,7 +25,14 @@ impl<'gcc, 'tcx> PreDefineMethods<'tcx> for CodegenCx<'gcc, 'tcx> { ) { let attrs = self.tcx.codegen_fn_attrs(def_id); let instance = Instance::mono(self.tcx, def_id); - let ty = instance.ty(self.tcx, ty::ParamEnv::reveal_all()); + let DefKind::Static { nested, .. } = self.tcx.def_kind(def_id) else { bug!() }; + // Nested statics do not have a type, so pick a random type and let `define_static` figure out + // the gcc type from the actual evaluated initializer. + let ty = if nested { + self.tcx.types.unit + } else { + instance.ty(self.tcx, ty::ParamEnv::reveal_all()) + }; let gcc_type = self.layout_of(ty).gcc_type(self); let is_tls = attrs.flags.contains(CodegenFnAttrFlags::THREAD_LOCAL); From e7795ed0fef657aa7c991772ee1c1eca6f11750c Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Mon, 11 Mar 2024 18:39:23 +0000 Subject: [PATCH 032/892] Some comment nits --- src/mono_item.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mono_item.rs b/src/mono_item.rs index ceaf87d164816..359d3c70b4cae 100644 --- a/src/mono_item.rs +++ b/src/mono_item.rs @@ -26,7 +26,7 @@ impl<'gcc, 'tcx> PreDefineMethods<'tcx> for CodegenCx<'gcc, 'tcx> { let attrs = self.tcx.codegen_fn_attrs(def_id); let instance = Instance::mono(self.tcx, def_id); let DefKind::Static { nested, .. } = self.tcx.def_kind(def_id) else { bug!() }; - // Nested statics do not have a type, so pick a random type and let `define_static` figure out + // Nested statics do not have a type, so pick a dummy type and let `codegen_static` figure out // the gcc type from the actual evaluated initializer. let ty = if nested { self.tcx.types.unit From a64942a3e95033902904bf060ebf768953a22359 Mon Sep 17 00:00:00 2001 From: Arthur Carcano Date: Thu, 4 Jan 2024 17:45:36 +0100 Subject: [PATCH 033/892] Mark codegen_gcc fields used only on feature master as such The dead_code lint was previously eroneously missing those. Since this lint bug has been fixed, the unused fields need to be feature gated. --- src/context.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/context.rs b/src/context.rs index 8f643c7db720f..9e6cf3e34dfe9 100644 --- a/src/context.rs +++ b/src/context.rs @@ -110,6 +110,7 @@ pub struct CodegenCx<'gcc, 'tcx> { local_gen_sym_counter: Cell, eh_personality: Cell>>, + #[cfg(feature="master")] pub rust_try_fn: Cell, Function<'gcc>)>>, pub pointee_infos: RefCell, Size), Option>>, @@ -121,6 +122,7 @@ pub struct CodegenCx<'gcc, 'tcx> { /// FIXME(antoyo): fix the rustc API to avoid having this hack. pub structs_as_pointer: RefCell>>, + #[cfg(feature="master")] pub cleanup_blocks: RefCell>>, } @@ -325,9 +327,11 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { struct_types: Default::default(), local_gen_sym_counter: Cell::new(0), eh_personality: Cell::new(None), + #[cfg(feature="master")] rust_try_fn: Cell::new(None), pointee_infos: Default::default(), structs_as_pointer: Default::default(), + #[cfg(feature="master")] cleanup_blocks: Default::default(), }; // TODO(antoyo): instead of doing this, add SsizeT to libgccjit. From 6c9156717e226a64639b79428febd519a1cbb5d6 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 13 Mar 2024 16:44:54 +0100 Subject: [PATCH 034/892] Regen intrinsics conversions --- src/intrinsic/archs.rs | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/src/intrinsic/archs.rs b/src/intrinsic/archs.rs index c4ae1751fa05a..f750093378989 100644 --- a/src/intrinsic/archs.rs +++ b/src/intrinsic/archs.rs @@ -74,6 +74,10 @@ match name { "llvm.amdgcn.cvt.sr.bf8.f32" => "__builtin_amdgcn_cvt_sr_bf8_f32", "llvm.amdgcn.cvt.sr.fp8.f32" => "__builtin_amdgcn_cvt_sr_fp8_f32", "llvm.amdgcn.dispatch.id" => "__builtin_amdgcn_dispatch_id", + "llvm.amdgcn.dot4.f32.bf8.bf8" => "__builtin_amdgcn_dot4_f32_bf8_bf8", + "llvm.amdgcn.dot4.f32.bf8.fp8" => "__builtin_amdgcn_dot4_f32_bf8_fp8", + "llvm.amdgcn.dot4.f32.fp8.bf8" => "__builtin_amdgcn_dot4_f32_fp8_bf8", + "llvm.amdgcn.dot4.f32.fp8.fp8" => "__builtin_amdgcn_dot4_f32_fp8_fp8", "llvm.amdgcn.ds.add.gs.reg.rtn" => "__builtin_amdgcn_ds_add_gs_reg_rtn", "llvm.amdgcn.ds.bpermute" => "__builtin_amdgcn_ds_bpermute", "llvm.amdgcn.ds.fadd.v2bf16" => "__builtin_amdgcn_ds_atomic_fadd_v2bf16", @@ -2291,6 +2295,10 @@ match name { "llvm.loongarch.csrxchg.d" => "__builtin_loongarch_csrxchg_d", "llvm.loongarch.csrxchg.w" => "__builtin_loongarch_csrxchg_w", "llvm.loongarch.dbar" => "__builtin_loongarch_dbar", + "llvm.loongarch.frecipe.d" => "__builtin_loongarch_frecipe_d", + "llvm.loongarch.frecipe.s" => "__builtin_loongarch_frecipe_s", + "llvm.loongarch.frsqrte.d" => "__builtin_loongarch_frsqrte_d", + "llvm.loongarch.frsqrte.s" => "__builtin_loongarch_frsqrte_s", "llvm.loongarch.ibar" => "__builtin_loongarch_ibar", "llvm.loongarch.iocsrrd.b" => "__builtin_loongarch_iocsrrd_b", "llvm.loongarch.iocsrrd.d" => "__builtin_loongarch_iocsrrd_d", @@ -2529,6 +2537,8 @@ match name { "llvm.loongarch.lasx.xvfnmsub.s" => "__builtin_lasx_xvfnmsub_s", "llvm.loongarch.lasx.xvfrecip.d" => "__builtin_lasx_xvfrecip_d", "llvm.loongarch.lasx.xvfrecip.s" => "__builtin_lasx_xvfrecip_s", + "llvm.loongarch.lasx.xvfrecipe.d" => "__builtin_lasx_xvfrecipe_d", + "llvm.loongarch.lasx.xvfrecipe.s" => "__builtin_lasx_xvfrecipe_s", "llvm.loongarch.lasx.xvfrint.d" => "__builtin_lasx_xvfrint_d", "llvm.loongarch.lasx.xvfrint.s" => "__builtin_lasx_xvfrint_s", "llvm.loongarch.lasx.xvfrintrm.d" => "__builtin_lasx_xvfrintrm_d", @@ -2541,6 +2551,8 @@ match name { "llvm.loongarch.lasx.xvfrintrz.s" => "__builtin_lasx_xvfrintrz_s", "llvm.loongarch.lasx.xvfrsqrt.d" => "__builtin_lasx_xvfrsqrt_d", "llvm.loongarch.lasx.xvfrsqrt.s" => "__builtin_lasx_xvfrsqrt_s", + "llvm.loongarch.lasx.xvfrsqrte.d" => "__builtin_lasx_xvfrsqrte_d", + "llvm.loongarch.lasx.xvfrsqrte.s" => "__builtin_lasx_xvfrsqrte_s", "llvm.loongarch.lasx.xvfrstp.b" => "__builtin_lasx_xvfrstp_b", "llvm.loongarch.lasx.xvfrstp.h" => "__builtin_lasx_xvfrstp_h", "llvm.loongarch.lasx.xvfrstpi.b" => "__builtin_lasx_xvfrstpi_b", @@ -3255,6 +3267,8 @@ match name { "llvm.loongarch.lsx.vfnmsub.s" => "__builtin_lsx_vfnmsub_s", "llvm.loongarch.lsx.vfrecip.d" => "__builtin_lsx_vfrecip_d", "llvm.loongarch.lsx.vfrecip.s" => "__builtin_lsx_vfrecip_s", + "llvm.loongarch.lsx.vfrecipe.d" => "__builtin_lsx_vfrecipe_d", + "llvm.loongarch.lsx.vfrecipe.s" => "__builtin_lsx_vfrecipe_s", "llvm.loongarch.lsx.vfrint.d" => "__builtin_lsx_vfrint_d", "llvm.loongarch.lsx.vfrint.s" => "__builtin_lsx_vfrint_s", "llvm.loongarch.lsx.vfrintrm.d" => "__builtin_lsx_vfrintrm_d", @@ -3267,6 +3281,8 @@ match name { "llvm.loongarch.lsx.vfrintrz.s" => "__builtin_lsx_vfrintrz_s", "llvm.loongarch.lsx.vfrsqrt.d" => "__builtin_lsx_vfrsqrt_d", "llvm.loongarch.lsx.vfrsqrt.s" => "__builtin_lsx_vfrsqrt_s", + "llvm.loongarch.lsx.vfrsqrte.d" => "__builtin_lsx_vfrsqrte_d", + "llvm.loongarch.lsx.vfrsqrte.s" => "__builtin_lsx_vfrsqrte_s", "llvm.loongarch.lsx.vfrstp.b" => "__builtin_lsx_vfrstp_b", "llvm.loongarch.lsx.vfrstp.h" => "__builtin_lsx_vfrstp_h", "llvm.loongarch.lsx.vfrstpi.b" => "__builtin_lsx_vfrstpi_b", @@ -4434,6 +4450,7 @@ match name { "llvm.nvvm.abs.bf16x2" => "__nvvm_abs_bf16x2", "llvm.nvvm.abs.i" => "__nvvm_abs_i", "llvm.nvvm.abs.ll" => "__nvvm_abs_ll", + "llvm.nvvm.activemask" => "__nvvm_activemask", "llvm.nvvm.add.rm.d" => "__nvvm_add_rm_d", "llvm.nvvm.add.rm.f" => "__nvvm_add_rm_f", "llvm.nvvm.add.rm.ftz.f" => "__nvvm_add_rm_ftz_f", @@ -4522,6 +4539,7 @@ match name { "llvm.nvvm.ex2.approx.d" => "__nvvm_ex2_approx_d", "llvm.nvvm.ex2.approx.f" => "__nvvm_ex2_approx_f", "llvm.nvvm.ex2.approx.ftz.f" => "__nvvm_ex2_approx_ftz_f", + "llvm.nvvm.exit" => "__nvvm_exit", "llvm.nvvm.f2bf16.rn" => "__nvvm_f2bf16_rn", "llvm.nvvm.f2bf16.rn.relu" => "__nvvm_f2bf16_rn_relu", "llvm.nvvm.f2bf16.rz" => "__nvvm_f2bf16_rz", @@ -4722,8 +4740,11 @@ match name { "llvm.nvvm.mul24.ui" => "__nvvm_mul24_ui", "llvm.nvvm.mulhi.i" => "__nvvm_mulhi_i", "llvm.nvvm.mulhi.ll" => "__nvvm_mulhi_ll", + "llvm.nvvm.mulhi.s" => "__nvvm_mulhi_s", "llvm.nvvm.mulhi.ui" => "__nvvm_mulhi_ui", "llvm.nvvm.mulhi.ull" => "__nvvm_mulhi_ull", + "llvm.nvvm.mulhi.us" => "__nvvm_mulhi_us", + "llvm.nvvm.nanosleep" => "__nvvm_nanosleep", "llvm.nvvm.neg.bf16" => "__nvvm_neg_bf16", "llvm.nvvm.neg.bf16x2" => "__nvvm_neg_bf16x2", "llvm.nvvm.popc.i" => "__nvvm_popc_i", @@ -4783,6 +4804,7 @@ match name { "llvm.nvvm.read.ptx.sreg.envreg7" => "__nvvm_read_ptx_sreg_envreg7", "llvm.nvvm.read.ptx.sreg.envreg8" => "__nvvm_read_ptx_sreg_envreg8", "llvm.nvvm.read.ptx.sreg.envreg9" => "__nvvm_read_ptx_sreg_envreg9", + "llvm.nvvm.read.ptx.sreg.globaltimer" => "__nvvm_read_ptx_sreg_globaltimer", "llvm.nvvm.read.ptx.sreg.gridid" => "__nvvm_read_ptx_sreg_gridid", // [DUPLICATE]: "llvm.nvvm.read.ptx.sreg.gridid" => "__nvvm_read_ptx_sreg_", "llvm.nvvm.read.ptx.sreg.laneid" => "__nvvm_read_ptx_sreg_laneid", @@ -4835,6 +4857,7 @@ match name { "llvm.nvvm.redux.sync.umax" => "__nvvm_redux_sync_umax", "llvm.nvvm.redux.sync.umin" => "__nvvm_redux_sync_umin", "llvm.nvvm.redux.sync.xor" => "__nvvm_redux_sync_xor", + "llvm.nvvm.reflect" => "__nvvm_reflect", "llvm.nvvm.rotate.b32" => "__nvvm_rotate_b32", "llvm.nvvm.rotate.b64" => "__nvvm_rotate_b64", "llvm.nvvm.rotate.right.b64" => "__nvvm_rotate_right_b64", @@ -4845,7 +4868,11 @@ match name { "llvm.nvvm.rsqrt.approx.f" => "__nvvm_rsqrt_approx_f", "llvm.nvvm.rsqrt.approx.ftz.f" => "__nvvm_rsqrt_approx_ftz_f", "llvm.nvvm.sad.i" => "__nvvm_sad_i", + "llvm.nvvm.sad.ll" => "__nvvm_sad_ll", + "llvm.nvvm.sad.s" => "__nvvm_sad_s", "llvm.nvvm.sad.ui" => "__nvvm_sad_ui", + "llvm.nvvm.sad.ull" => "__nvvm_sad_ull", + "llvm.nvvm.sad.us" => "__nvvm_sad_us", "llvm.nvvm.saturate.d" => "__nvvm_saturate_d", "llvm.nvvm.saturate.f" => "__nvvm_saturate_f", "llvm.nvvm.saturate.ftz.f" => "__nvvm_saturate_ftz_f", @@ -5471,6 +5498,7 @@ match name { "llvm.ppc.fctiwz" => "__builtin_ppc_fctiwz", "llvm.ppc.fctudz" => "__builtin_ppc_fctudz", "llvm.ppc.fctuwz" => "__builtin_ppc_fctuwz", + "llvm.ppc.fence" => "__builtin_ppc_fence", "llvm.ppc.fmaf128.round.to.odd" => "__builtin_fmaf128_round_to_odd", "llvm.ppc.fmsub" => "__builtin_ppc_fmsub", "llvm.ppc.fmsubs" => "__builtin_ppc_fmsubs", @@ -5599,6 +5627,9 @@ match name { "llvm.ppc.qpx.qvstfs" => "__builtin_qpx_qvstfs", "llvm.ppc.qpx.qvstfsa" => "__builtin_qpx_qvstfsa", "llvm.ppc.readflm" => "__builtin_readflm", + "llvm.ppc.rldimi" => "__builtin_ppc_rldimi", + "llvm.ppc.rlwimi" => "__builtin_ppc_rlwimi", + "llvm.ppc.rlwnm" => "__builtin_ppc_rlwnm", "llvm.ppc.scalar.extract.expq" => "__builtin_vsx_scalar_extract_expq", "llvm.ppc.scalar.insert.exp.qp" => "__builtin_vsx_scalar_insert_exp_qp", "llvm.ppc.set.texasr" => "__builtin_set_texasr", @@ -5912,6 +5943,8 @@ match name { "llvm.s390.vupllb" => "__builtin_s390_vupllb", "llvm.s390.vupllf" => "__builtin_s390_vupllf", "llvm.s390.vupllh" => "__builtin_s390_vupllh", + // spv + "llvm.spv.create.handle" => "__builtin_hlsl_create_handle", // ve "llvm.ve.vl.andm.MMM" => "__builtin_ve_vl_andm_MMM", "llvm.ve.vl.andm.mmm" => "__builtin_ve_vl_andm_mmm", From 9476fe7c3bd56bc6847538c4e3a53fee1d64e543 Mon Sep 17 00:00:00 2001 From: Erik Desjardins Date: Fri, 15 Mar 2024 15:53:49 -0400 Subject: [PATCH 035/892] avoid naming LLVM basic blocks when fewer_names is true --- src/builder.rs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/builder.rs b/src/builder.rs index f5cda81f6ab86..c12fa1a58fff8 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -1,6 +1,7 @@ use std::borrow::Cow; use std::cell::Cell; use std::convert::TryFrom; +use std::fmt::Display; use std::ops::Deref; use gccjit::{ @@ -526,14 +527,14 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { self.block } - fn append_block(cx: &'a CodegenCx<'gcc, 'tcx>, func: RValue<'gcc>, name: &str) -> Block<'gcc> { + fn append_block(cx: &'a CodegenCx<'gcc, 'tcx>, func: RValue<'gcc>, name: impl Display) -> Block<'gcc> { let func = cx.rvalue_as_function(func); - func.new_block(name) + func.new_block(name.to_string()) } - fn append_sibling_block(&mut self, name: &str) -> Block<'gcc> { + fn append_sibling_block(&mut self, name: impl Display) -> Block<'gcc> { let func = self.current_func(); - func.new_block(name) + func.new_block(name.to_string()) } fn switch_to_block(&mut self, block: Self::BasicBlock) { From 817d2f298eb07c34806f41ecfe1d1c0b509566b7 Mon Sep 17 00:00:00 2001 From: tempdragon <645703113@qq.com> Date: Sat, 16 Mar 2024 09:43:16 +0800 Subject: [PATCH 036/892] fix(pattern_type_mismatch)): Fix mismatch with ref/deref --- src/debuginfo.rs | 9 ++++++--- src/declare.rs | 14 +------------- src/intrinsic/mod.rs | 5 ++--- 3 files changed, 9 insertions(+), 19 deletions(-) diff --git a/src/debuginfo.rs b/src/debuginfo.rs index 7ca4743f4b8ef..57e7e4e54ca3f 100644 --- a/src/debuginfo.rs +++ b/src/debuginfo.rs @@ -280,15 +280,18 @@ impl<'gcc, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'gcc, 'tcx> { let pos = span.lo(); let DebugLoc { file, line, col } = self.lookup_debug_loc(pos); let loc = match file.name { - rustc_span::FileName::Real(ref name) => match name.clone() { - rustc_span::RealFileName::LocalPath(name) => { + rustc_span::FileName::Real(ref name) => match *name { + rustc_span::RealFileName::LocalPath(ref name) => { if let Some(name) = name.to_str() { self.context.new_location(name, line as i32, col as i32) } else { Location::null() } } - rustc_span::RealFileName::Remapped { ref local_path, virtual_name: _unused } => { + rustc_span::RealFileName::Remapped { + ref local_path, + virtual_name: ref _unused, + } => { if let Some(name) = local_path.as_ref() { if let Some(name) = name.to_str() { self.context.new_location(name, line as i32, col as i32) diff --git a/src/declare.rs b/src/declare.rs index 555f95fb1556a..a2b158ee0a7e8 100644 --- a/src/declare.rs +++ b/src/declare.rs @@ -181,19 +181,7 @@ fn declare_raw_fn<'gcc>( .map(|(index, param)| cx.context.new_parameter(None, *param, format!("param{}", index))) // TODO(antoyo): set name. .collect(); #[cfg(not(feature = "master"))] - let name = mangle_name(name); - - #[cfg(not(feature = "master"))] - let func = cx.context.new_function( - None, - cx.linkage.get(), - return_type, - ¶ms, - name.clone(), - variadic, - ); - - #[cfg(feature = "master")] + let name = &mangle_name(name); let func = cx.context.new_function(None, cx.linkage.get(), return_type, ¶ms, name, variadic); cx.functions.borrow_mut().insert(name.to_string(), func); diff --git a/src/intrinsic/mod.rs b/src/intrinsic/mod.rs index d4afbcbcc449d..b4236a31c5d9f 100644 --- a/src/intrinsic/mod.rs +++ b/src/intrinsic/mod.rs @@ -164,8 +164,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'a, 'gcc, 'tcx> { let tp_ty = fn_args.type_at(0); let ptr = args[0].immediate(); // The reference was changed to clone to comply to clippy. - let load = if let PassMode::Cast { cast: ty, pad_i32: _ } = fn_abi.ret.mode.clone() - { + let load = if let PassMode::Cast { cast: ref ty, pad_i32: _ } = fn_abi.ret.mode { let gcc_ty = ty.gcc_type(self); self.volatile_load(gcc_ty, ptr) } else { @@ -386,7 +385,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'a, 'gcc, 'tcx> { if !fn_abi.ret.is_ignore() { // The reference was changed to clone to comply to clippy. - if let PassMode::Cast { cast: ty, .. } = fn_abi.ret.mode.clone() { + if let PassMode::Cast { cast: ref ty, .. } = fn_abi.ret.mode { let ptr_llty = self.type_ptr_to(ty.gcc_type(self)); let ptr = self.pointercast(result.llval, ptr_llty); self.store(llval, ptr, result.align); From 878f572d0eb9a69f8c69085af1713a30b1a338b4 Mon Sep 17 00:00:00 2001 From: tempdragon <645703113@qq.com> Date: Sat, 16 Mar 2024 10:07:52 +0800 Subject: [PATCH 037/892] fix(comments): Add some info and revert `else if` 1. Put the `else if` comment in intrinsic/mod.rs away 2. Add TODO to debuginfo.rs in `make_mir_scope()` --- src/debuginfo.rs | 1 + src/intrinsic/mod.rs | 21 +++++++++++---------- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/debuginfo.rs b/src/debuginfo.rs index 57e7e4e54ca3f..04c517e7d2952 100644 --- a/src/debuginfo.rs +++ b/src/debuginfo.rs @@ -137,6 +137,7 @@ fn make_mir_scope<'gcc, 'tcx>( // FIXME(eddyb) this doesn't account for the macro-related // `Span` fixups that `rustc_codegen_ssa::mir::debuginfo` does. + // TODO(tempdragon): Add scope support and then revert to cg_llvm version of this closure // NOTE: These variables passed () here. // Changed to comply to clippy. diff --git a/src/intrinsic/mod.rs b/src/intrinsic/mod.rs index b4236a31c5d9f..7cb3eb915917c 100644 --- a/src/intrinsic/mod.rs +++ b/src/intrinsic/mod.rs @@ -308,16 +308,17 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'a, 'gcc, 'tcx> { self.const_bool(true) // The else if an immediate neighbor of this block. // It is moved here to comply to Clippy. - /*else if use_integer_compare { - let integer_ty = self.type_ix(layout.size.bits()); // FIXME(antoyo): LLVM creates an integer of 96 bits for [i32; 3], but gcc doesn't support this, so it creates an integer of 128 bits. - let ptr_ty = self.type_ptr_to(integer_ty); - let a_ptr = self.bitcast(a, ptr_ty); - let a_val = self.load(integer_ty, a_ptr, layout.align.abi); - let b_ptr = self.bitcast(b, ptr_ty); - let b_val = self.load(integer_ty, b_ptr, layout.align.abi); - self.icmp(IntPredicate::IntEQ, a_val, b_val) - }*/ - } else { + } + /*else if use_integer_compare { + let integer_ty = self.type_ix(layout.size.bits()); // FIXME(antoyo): LLVM creates an integer of 96 bits for [i32; 3], but gcc doesn't support this, so it creates an integer of 128 bits. + let ptr_ty = self.type_ptr_to(integer_ty); + let a_ptr = self.bitcast(a, ptr_ty); + let a_val = self.load(integer_ty, a_ptr, layout.align.abi); + let b_ptr = self.bitcast(b, ptr_ty); + let b_val = self.load(integer_ty, b_ptr, layout.align.abi); + self.icmp(IntPredicate::IntEQ, a_val, b_val) + }*/ + else { let void_ptr_type = self.context.new_type::<*const ()>(); let a_ptr = self.bitcast(a, void_ptr_type); let b_ptr = self.bitcast(b, void_ptr_type); From 390f9064e18701f9b863f1790a4bc22bc8e51d0d Mon Sep 17 00:00:00 2001 From: tempdragon <645703113@qq.com> Date: Sat, 16 Mar 2024 10:17:35 +0800 Subject: [PATCH 038/892] revert(lifetime): Add "needless" lifetime(s) and allow it in clippy This reverts commit ad97b8c061e6f39a52daaf036c9721e17510c30c. --- src/asm.rs | 2 +- src/builder.rs | 4 ++-- src/common.rs | 2 +- src/intrinsic/llvm.rs | 10 +++++----- src/intrinsic/mod.rs | 4 ++-- src/intrinsic/simd.rs | 4 ++-- src/lib.rs | 3 ++- 7 files changed, 15 insertions(+), 14 deletions(-) diff --git a/src/asm.rs b/src/asm.rs index 68de3fd7b079b..72d572465f404 100644 --- a/src/asm.rs +++ b/src/asm.rs @@ -691,7 +691,7 @@ fn reg_to_gcc(reg: InlineAsmRegOrRegClass) -> ConstraintOrRegister { /// Type to use for outputs that are discarded. It doesn't really matter what /// the type is, as long as it is valid for the constraint code. -fn dummy_output_type<'gcc>(cx: &CodegenCx<'gcc, '_>, reg: InlineAsmRegClass) -> Type<'gcc> { +fn dummy_output_type<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, reg: InlineAsmRegClass) -> Type<'gcc> { match reg { InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::reg) => cx.type_i32(), InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::preg) => unimplemented!(), diff --git a/src/builder.rs b/src/builder.rs index 79ba110e1c56d..55ab20a03ae1d 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -976,8 +976,8 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { return OperandRef::zero_sized(place.layout); } - fn scalar_load_metadata<'gcc>( - bx: &mut Builder<'_, 'gcc, '_>, + fn scalar_load_metadata<'a, 'gcc, 'tcx>( + bx: &mut Builder<'a, 'gcc, 'tcx>, load: RValue<'gcc>, scalar: &abi::Scalar, ) { diff --git a/src/common.rs b/src/common.rs index ff05132653894..6a3b5442adf27 100644 --- a/src/common.rs +++ b/src/common.rs @@ -30,7 +30,7 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { } } -pub fn bytes_in_context<'gcc>(cx: &CodegenCx<'gcc, '_>, bytes: &[u8]) -> RValue<'gcc> { +pub fn bytes_in_context<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, bytes: &[u8]) -> RValue<'gcc> { let context = &cx.context; let byte_type = context.new_type::(); let typ = context.new_array_type(None, byte_type, bytes.len() as u64); diff --git a/src/intrinsic/llvm.rs b/src/intrinsic/llvm.rs index 94c9869bd1f13..c845ee5fe5fd6 100644 --- a/src/intrinsic/llvm.rs +++ b/src/intrinsic/llvm.rs @@ -5,8 +5,8 @@ use rustc_codegen_ssa::traits::BuilderMethods; use crate::{builder::Builder, context::CodegenCx}; -pub fn adjust_intrinsic_arguments<'b, 'gcc>( - builder: &Builder<'_, 'gcc, '_>, +pub fn adjust_intrinsic_arguments<'a, 'b, 'gcc, 'tcx>( + builder: &Builder<'a, 'gcc, 'tcx>, gcc_func: FunctionPtrType<'gcc>, mut args: Cow<'b, [RValue<'gcc>]>, func_name: &str, @@ -479,8 +479,8 @@ pub fn adjust_intrinsic_arguments<'b, 'gcc>( args } -pub fn adjust_intrinsic_return_value<'gcc>( - builder: &Builder<'_, 'gcc, '_>, +pub fn adjust_intrinsic_return_value<'a, 'gcc, 'tcx>( + builder: &Builder<'a, 'gcc, 'tcx>, mut return_value: RValue<'gcc>, func_name: &str, args: &[RValue<'gcc>], @@ -628,7 +628,7 @@ pub fn intrinsic<'gcc, 'tcx>(name: &str, cx: &CodegenCx<'gcc, 'tcx>) -> Function } #[cfg(feature = "master")] -pub fn intrinsic<'gcc>(name: &str, cx: &CodegenCx<'gcc, '_>) -> Function<'gcc> { +pub fn intrinsic<'gcc, 'tcx>(name: &str, cx: &CodegenCx<'gcc, 'tcx>) -> Function<'gcc> { if name == "llvm.prefetch" { let gcc_name = "__builtin_prefetch"; let func = cx.context.get_builtin_function(gcc_name); diff --git a/src/intrinsic/mod.rs b/src/intrinsic/mod.rs index 7cb3eb915917c..0961c4d1bf9a8 100644 --- a/src/intrinsic/mod.rs +++ b/src/intrinsic/mod.rs @@ -1093,8 +1093,8 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { } } -fn try_intrinsic<'gcc>( - bx: &mut Builder<'_, 'gcc, '_>, +fn try_intrinsic<'a, 'b, 'gcc, 'tcx>( + bx: &'b mut Builder<'a, 'gcc, 'tcx>, try_func: RValue<'gcc>, data: RValue<'gcc>, _catch_func: RValue<'gcc>, diff --git a/src/intrinsic/simd.rs b/src/intrinsic/simd.rs index 8fca81091dc52..6d8ed519b4cc9 100644 --- a/src/intrinsic/simd.rs +++ b/src/intrinsic/simd.rs @@ -692,11 +692,11 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( } #[cfg(feature = "master")] - fn gather<'gcc>( + fn gather<'a, 'gcc, 'tcx>( default: RValue<'gcc>, pointers: RValue<'gcc>, mask: RValue<'gcc>, - bx: &mut Builder<'_, 'gcc, '_>, + bx: &mut Builder<'a, 'gcc, 'tcx>, in_len: u64, invert: bool, ) -> RValue<'gcc> { diff --git a/src/lib.rs b/src/lib.rs index f2f3b6fd78780..616b1944798cc 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -29,6 +29,7 @@ #![warn(rust_2018_idioms)] #![warn(unused_lifetimes)] #![deny(clippy::pattern_type_mismatch)] +#![allow(clippy::needless_lifetimes)] extern crate rustc_apfloat; extern crate rustc_ast; @@ -270,7 +271,7 @@ impl CodegenBackend for GccCodegenBackend { } } -fn new_context<'gcc>(tcx: TyCtxt<'_>) -> Context<'gcc> { +fn new_context<'gcc, 'tcx>(tcx: TyCtxt<'tcx>) -> Context<'gcc> { let context = Context::default(); if tcx.sess.target.arch == "x86" || tcx.sess.target.arch == "x86_64" { context.add_command_line_option("-masm=intel"); From f6cab2cd1eb985737db2d0059c4655588c9ed4e1 Mon Sep 17 00:00:00 2001 From: tempdragon <645703113@qq.com> Date: Sat, 16 Mar 2024 12:05:56 +0800 Subject: [PATCH 039/892] feat(CI): Add clippy check to workflow. --- .github/workflows/ci.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 839f3ba4de362..6079725b3e6c5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -52,6 +52,9 @@ jobs: - name: Install rustfmt run: rustup component add rustfmt + - name: Install clippy + run: rustup component add clippy + - name: Download artifact run: curl -LO https://github.com/antoyo/gcc/releases/latest/download/${{ matrix.libgccjit_version.gcc }} @@ -98,6 +101,11 @@ jobs: - name: Check formatting run: cargo fmt -- --check + - name: clippy + run: | + cargo clippy --all-targets -- -D warnings + cargo clippy --all-targets --features master -- -D warnings + duplicates: runs-on: ubuntu-latest steps: From 653118e797902d7854035a197c319c53d1b8eeef Mon Sep 17 00:00:00 2001 From: tempdragon <645703113@qq.com> Date: Sat, 16 Mar 2024 12:08:39 +0800 Subject: [PATCH 040/892] feat(clippy): Suppress lint `suspicious_else_formatting` temporarily --- src/intrinsic/mod.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/intrinsic/mod.rs b/src/intrinsic/mod.rs index 0961c4d1bf9a8..6cc6e0378f1ff 100644 --- a/src/intrinsic/mod.rs +++ b/src/intrinsic/mod.rs @@ -119,6 +119,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'a, 'gcc, 'tcx> { let result = PlaceRef::new_sized(llresult, fn_abi.ret.layout); let simple = get_simple_intrinsic(self, name); + #[allow(clippy::suspicious_else_formatting)] let llval = match name { _ if simple.is_some() => { // FIXME(antoyo): remove this cast when the API supports function. From 225a32f7d0d668f3044c12e31bf2cf3da48454fb Mon Sep 17 00:00:00 2001 From: tempdragon <645703113@qq.com> Date: Sat, 16 Mar 2024 12:14:01 +0800 Subject: [PATCH 041/892] Revert "feat(CI): Add clippy check to workflow." This reverts commit f6cab2cd1eb985737db2d0059c4655588c9ed4e1. --- .github/workflows/ci.yml | 8 -------- 1 file changed, 8 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6079725b3e6c5..839f3ba4de362 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -52,9 +52,6 @@ jobs: - name: Install rustfmt run: rustup component add rustfmt - - name: Install clippy - run: rustup component add clippy - - name: Download artifact run: curl -LO https://github.com/antoyo/gcc/releases/latest/download/${{ matrix.libgccjit_version.gcc }} @@ -101,11 +98,6 @@ jobs: - name: Check formatting run: cargo fmt -- --check - - name: clippy - run: | - cargo clippy --all-targets -- -D warnings - cargo clippy --all-targets --features master -- -D warnings - duplicates: runs-on: ubuntu-latest steps: From 89acb108b48d206798e7ec2c8522c7650101036f Mon Sep 17 00:00:00 2001 From: tempdragon <645703113@qq.com> Date: Sat, 16 Mar 2024 12:24:05 +0800 Subject: [PATCH 042/892] feat(ci): Install clippy in ci.yml(But no testing) Done incrementally to avoid potential failure. --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 839f3ba4de362..f563583648dd5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -49,8 +49,8 @@ jobs: # `llvm-14-tools` is needed to install the `FileCheck` binary which is used for asm tests. run: sudo apt-get install ninja-build ripgrep llvm-14-tools - - name: Install rustfmt - run: rustup component add rustfmt + - name: Install rustfmt & clippy + run: rustup component add rustfmt clippy - name: Download artifact run: curl -LO https://github.com/antoyo/gcc/releases/latest/download/${{ matrix.libgccjit_version.gcc }} From 4e4efb9b9e45d40f14a8911ed394fc00fa0dc518 Mon Sep 17 00:00:00 2001 From: tempdragon <645703113@qq.com> Date: Sat, 16 Mar 2024 12:30:52 +0800 Subject: [PATCH 043/892] feat(ci): Add clippy check for both master and non-master --- .github/workflows/ci.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f563583648dd5..44730bab4ed15 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -98,6 +98,11 @@ jobs: - name: Check formatting run: cargo fmt -- --check + - name: clippy + run: | + cargo clippy --all-targets -- -D warnings + cargo clippy --all-targets --features master -- -D warnings + duplicates: runs-on: ubuntu-latest steps: From 3b01fba0f5ecfd7e929fcf1948945ae75479c38d Mon Sep 17 00:00:00 2001 From: tempdragon <645703113@qq.com> Date: Sat, 16 Mar 2024 21:16:41 +0800 Subject: [PATCH 044/892] fix(intrinsic/mod.rs): Update comments --- src/intrinsic/mod.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/intrinsic/mod.rs b/src/intrinsic/mod.rs index 6cc6e0378f1ff..b1d8ced66199e 100644 --- a/src/intrinsic/mod.rs +++ b/src/intrinsic/mod.rs @@ -119,6 +119,10 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'a, 'gcc, 'tcx> { let result = PlaceRef::new_sized(llresult, fn_abi.ret.layout); let simple = get_simple_intrinsic(self, name); + + // FIXME(tempdragon): Re-enable `clippy::suspicious_else_formatting` if the following issue is solved: + // https://github.com/rust-lang/rust-clippy/issues/12497 + // and leave `else if use_integer_compare` to be placed "as is". #[allow(clippy::suspicious_else_formatting)] let llval = match name { _ if simple.is_some() => { @@ -164,7 +168,6 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'a, 'gcc, 'tcx> { sym::volatile_load | sym::unaligned_volatile_load => { let tp_ty = fn_args.type_at(0); let ptr = args[0].immediate(); - // The reference was changed to clone to comply to clippy. let load = if let PassMode::Cast { cast: ref ty, pad_i32: _ } = fn_abi.ret.mode { let gcc_ty = ty.gcc_type(self); self.volatile_load(gcc_ty, ptr) @@ -307,8 +310,6 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'a, 'gcc, 'tcx> { let b = args[1].immediate(); if layout.size().bytes() == 0 { self.const_bool(true) - // The else if an immediate neighbor of this block. - // It is moved here to comply to Clippy. } /*else if use_integer_compare { let integer_ty = self.type_ix(layout.size.bits()); // FIXME(antoyo): LLVM creates an integer of 96 bits for [i32; 3], but gcc doesn't support this, so it creates an integer of 128 bits. @@ -386,7 +387,6 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'a, 'gcc, 'tcx> { }; if !fn_abi.ret.is_ignore() { - // The reference was changed to clone to comply to clippy. if let PassMode::Cast { cast: ref ty, .. } = fn_abi.ret.mode { let ptr_llty = self.type_ptr_to(ty.gcc_type(self)); let ptr = self.pointercast(result.llval, ptr_llty); From 0a493514d7596649cc9ca9e70f00fc9b53ba434e Mon Sep 17 00:00:00 2001 From: tempdragon <645703113@qq.com> Date: Sat, 16 Mar 2024 21:26:16 +0800 Subject: [PATCH 045/892] fix(lifetime): Add lifetimes back. --- src/attributes.rs | 5 ++++- src/builder.rs | 5 ++++- src/consts.rs | 6 +++++- src/intrinsic/mod.rs | 10 ++++++++-- 4 files changed, 21 insertions(+), 5 deletions(-) diff --git a/src/attributes.rs b/src/attributes.rs index 6238daaed1ddf..2ce0c83008f16 100644 --- a/src/attributes.rs +++ b/src/attributes.rs @@ -15,7 +15,10 @@ use crate::{context::CodegenCx, errors::TiedTargetFeatures}; /// Get GCC attribute for the provided inline heuristic. #[cfg(feature = "master")] #[inline] -fn inline_attr<'gcc>(cx: &CodegenCx<'gcc, '_>, inline: InlineAttr) -> Option> { +fn inline_attr<'gcc, 'tcx>( + cx: &CodegenCx<'gcc, 'tcx>, + inline: InlineAttr, +) -> Option> { match inline { InlineAttr::Hint => Some(FnAttribute::Inline), InlineAttr::Always => Some(FnAttribute::AlwaysInline), diff --git a/src/builder.rs b/src/builder.rs index 55ab20a03ae1d..385ca7a44a7d2 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -506,7 +506,10 @@ impl<'gcc, 'tcx> BackendTypes for Builder<'_, 'gcc, 'tcx> { type DIVariable = as BackendTypes>::DIVariable; } -fn set_rvalue_location<'gcc>(bx: &mut Builder<'_, 'gcc, '_>, rvalue: RValue<'gcc>) -> RValue<'gcc> { +fn set_rvalue_location<'a, 'gcc, 'tcx>( + bx: &mut Builder<'a, 'gcc, 'tcx>, + rvalue: RValue<'gcc>, +) -> RValue<'gcc> { if bx.location.is_some() { #[cfg(feature = "master")] rvalue.set_location(bx.location.unwrap()); diff --git a/src/consts.rs b/src/consts.rs index bbc1de1dfae9f..f47fd56553323 100644 --- a/src/consts.rs +++ b/src/consts.rs @@ -18,7 +18,11 @@ use crate::context::CodegenCx; use crate::errors::InvalidMinimumAlignment; use crate::type_of::LayoutGccExt; -fn set_global_alignment<'gcc>(cx: &CodegenCx<'gcc, '_>, gv: LValue<'gcc>, mut align: Align) { +fn set_global_alignment<'gcc, 'tcx>( + cx: &CodegenCx<'gcc, 'tcx>, + gv: LValue<'gcc>, + mut align: Align, +) { // The target may require greater alignment for globals than the type does. // Note: GCC and Clang also allow `__attribute__((aligned))` on variables, // which can force it to be smaller. Rust doesn't support this yet. diff --git a/src/intrinsic/mod.rs b/src/intrinsic/mod.rs index b1d8ced66199e..eca4a72c756a0 100644 --- a/src/intrinsic/mod.rs +++ b/src/intrinsic/mod.rs @@ -39,7 +39,10 @@ use crate::context::CodegenCx; use crate::intrinsic::simd::generic_simd_intrinsic; use crate::type_of::LayoutGccExt; -fn get_simple_intrinsic<'gcc>(cx: &CodegenCx<'gcc, '_>, name: Symbol) -> Option> { +fn get_simple_intrinsic<'gcc, 'tcx>( + cx: &CodegenCx<'gcc, 'tcx>, + name: Symbol, +) -> Option> { let gcc_name = match name { sym::sqrtf32 => "sqrtf", sym::sqrtf64 => "sqrt", @@ -584,7 +587,10 @@ impl<'gcc, 'tcx> ArgAbiExt<'gcc, 'tcx> for ArgAbi<'tcx, Ty<'tcx>> { } } -fn int_type_width_signed<'tcx>(ty: Ty<'tcx>, cx: &CodegenCx<'_, 'tcx>) -> Option<(u64, bool)> { +fn int_type_width_signed<'gcc, 'tcx>( + ty: Ty<'tcx>, + cx: &CodegenCx<'gcc, 'tcx>, +) -> Option<(u64, bool)> { match *ty.kind() { ty::Int(t) => Some(( match t { From ff2b405a3c5605f9146ea28d9019833de46d69d1 Mon Sep 17 00:00:00 2001 From: Erik Desjardins Date: Sat, 16 Mar 2024 11:11:53 -0400 Subject: [PATCH 046/892] revert changes and just delete the fixme Avoiding the naming didn't have any meaningful perf impact. --- src/builder.rs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/builder.rs b/src/builder.rs index c12fa1a58fff8..f5cda81f6ab86 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -1,7 +1,6 @@ use std::borrow::Cow; use std::cell::Cell; use std::convert::TryFrom; -use std::fmt::Display; use std::ops::Deref; use gccjit::{ @@ -527,14 +526,14 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { self.block } - fn append_block(cx: &'a CodegenCx<'gcc, 'tcx>, func: RValue<'gcc>, name: impl Display) -> Block<'gcc> { + fn append_block(cx: &'a CodegenCx<'gcc, 'tcx>, func: RValue<'gcc>, name: &str) -> Block<'gcc> { let func = cx.rvalue_as_function(func); - func.new_block(name.to_string()) + func.new_block(name) } - fn append_sibling_block(&mut self, name: impl Display) -> Block<'gcc> { + fn append_sibling_block(&mut self, name: &str) -> Block<'gcc> { let func = self.current_func(); - func.new_block(name.to_string()) + func.new_block(name) } fn switch_to_block(&mut self, block: Self::BasicBlock) { From 4ef3bac2a63405d87d0157d9a0c11f225a5fc28f Mon Sep 17 00:00:00 2001 From: mubarak23 Date: Tue, 19 Mar 2024 08:54:11 +0100 Subject: [PATCH 047/892] remove debug info from emitting --- build_system/src/config.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build_system/src/config.rs b/build_system/src/config.rs index 0a7258958e7e9..4cda356301ada 100644 --- a/build_system/src/config.rs +++ b/build_system/src/config.rs @@ -424,7 +424,7 @@ impl ConfigInfo { rustflags.push("-Csymbol-mangling-version=v0".to_string()); } - rustflags.push("-Cdebuginfo=2".to_string()); + // Since we don't support ThinLTO, disable LTO completely when not trying to do LTO. // TODO(antoyo): remove when we can handle ThinLTO. From 09dbab8fab1eaf4a101330c24febc4ab3fac9939 Mon Sep 17 00:00:00 2001 From: mubarak23 Date: Tue, 19 Mar 2024 13:49:07 +0100 Subject: [PATCH 048/892] change the debug option from true to limited --- build_sysroot/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build_sysroot/Cargo.toml b/build_sysroot/Cargo.toml index e5658273c978a..f46c9c8ce157e 100644 --- a/build_sysroot/Cargo.toml +++ b/build_sysroot/Cargo.toml @@ -18,5 +18,5 @@ rustc-std-workspace-alloc = { path = "./sysroot_src/library/rustc-std-workspace- rustc-std-workspace-std = { path = "./sysroot_src/library/rustc-std-workspace-std" } [profile.release] -debug = true +debug = "limited" #lto = "fat" # TODO(antoyo): re-enable when the failing LTO tests regarding proc-macros are fixed. From 51d27a63b8039765790c469ebb169802da4a307e Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 20 Mar 2024 13:52:36 +0100 Subject: [PATCH 049/892] Move cleanup of sysroot build into its own function --- build_system/src/build.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/build_system/src/build.rs b/build_system/src/build.rs index c81b02e2183d8..2d66fd89fb9f9 100644 --- a/build_system/src/build.rs +++ b/build_system/src/build.rs @@ -55,8 +55,7 @@ impl BuildArg { } } -pub fn build_sysroot(env: &HashMap, config: &ConfigInfo) -> Result<(), String> { - let start_dir = Path::new("build_sysroot"); +fn cleanup_sysroot_previous_build(start_dir: &Path) { // Cleanup for previous run // Clean target dir except for build scripts and incremental cache let _ = walk_dir( @@ -100,6 +99,11 @@ pub fn build_sysroot(env: &HashMap, config: &ConfigInfo) -> Resu let _ = fs::remove_file(start_dir.join("Cargo.lock")); let _ = fs::remove_file(start_dir.join("test_target/Cargo.lock")); let _ = fs::remove_dir_all(start_dir.join("sysroot")); +} + +pub fn build_sysroot(env: &HashMap, config: &ConfigInfo) -> Result<(), String> { + let start_dir = Path::new("build_sysroot"); + cleanup_sysroot_previous_build(&start_dir); // Builds libs let mut rustflags = env.get("RUSTFLAGS").cloned().unwrap_or_default(); From 9b17b3d184a77c6022f51b68aefbad60d0a47d81 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 20 Mar 2024 14:18:25 +0100 Subject: [PATCH 050/892] Simplify directory creation --- build_system/src/build.rs | 26 +++++--------------------- build_system/src/config.rs | 10 ++-------- build_system/src/prepare.rs | 10 ++-------- build_system/src/test.rs | 10 ++++------ build_system/src/utils.rs | 6 ++++++ 5 files changed, 19 insertions(+), 43 deletions(-) diff --git a/build_system/src/build.rs b/build_system/src/build.rs index 2d66fd89fb9f9..a4ea5107a0505 100644 --- a/build_system/src/build.rs +++ b/build_system/src/build.rs @@ -1,5 +1,5 @@ use crate::config::{Channel, ConfigInfo}; -use crate::utils::{run_command, run_command_with_output_and_env, walk_dir}; +use crate::utils::{create_dir, run_command, run_command_with_output_and_env, walk_dir}; use std::collections::HashMap; use std::ffi::OsStr; use std::fs; @@ -103,6 +103,7 @@ fn cleanup_sysroot_previous_build(start_dir: &Path) { pub fn build_sysroot(env: &HashMap, config: &ConfigInfo) -> Result<(), String> { let start_dir = Path::new("build_sysroot"); + cleanup_sysroot_previous_build(&start_dir); // Builds libs @@ -136,13 +137,7 @@ pub fn build_sysroot(env: &HashMap, config: &ConfigInfo) -> Resu // Copy files to sysroot let sysroot_path = start_dir.join(format!("sysroot/lib/rustlib/{}/lib/", config.target_triple)); - fs::create_dir_all(&sysroot_path).map_err(|error| { - format!( - "Failed to create directory `{}`: {:?}", - sysroot_path.display(), - error - ) - })?; + create_dir(&sysroot_path)?; let copier = |dir_to_copy: &Path| { // FIXME: should not use shell command! run_command(&[&"cp", &"-r", &dir_to_copy, &sysroot_path], None).map(|_| ()) @@ -155,13 +150,7 @@ pub fn build_sysroot(env: &HashMap, config: &ConfigInfo) -> Resu // Copy the source files to the sysroot (Rust for Linux needs this). let sysroot_src_path = start_dir.join("sysroot/lib/rustlib/src/rust"); - fs::create_dir_all(&sysroot_src_path).map_err(|error| { - format!( - "Failed to create directory `{}`: {:?}", - sysroot_src_path.display(), - error - ) - })?; + create_dir(&sysroot_src_path)?; run_command( &[ &"cp", @@ -216,12 +205,7 @@ fn build_codegen(args: &mut BuildArg) -> Result<(), String> { // We voluntarily ignore the error. let _ = fs::remove_dir_all("target/out"); let gccjit_target = "target/out/gccjit"; - fs::create_dir_all(gccjit_target).map_err(|error| { - format!( - "Failed to create directory `{}`: {:?}", - gccjit_target, error - ) - })?; + create_dir(gccjit_target)?; println!("[BUILD] sysroot"); build_sysroot(&env, &args.config_info)?; diff --git a/build_system/src/config.rs b/build_system/src/config.rs index 4cda356301ada..2e6d1b038c108 100644 --- a/build_system/src/config.rs +++ b/build_system/src/config.rs @@ -1,5 +1,5 @@ use crate::utils::{ - create_symlink, get_os_name, run_command_with_output, rustc_version_info, split_args, + create_dir, create_symlink, get_os_name, run_command_with_output, rustc_version_info, split_args, }; use std::collections::HashMap; use std::env as std_env; @@ -228,13 +228,7 @@ impl ConfigInfo { let output_dir = output_dir.join(&commit); if !output_dir.is_dir() { - std::fs::create_dir_all(&output_dir).map_err(|err| { - format!( - "failed to create folder `{}`: {:?}", - output_dir.display(), - err, - ) - })?; + create_dir(&output_dir)?; } let output_dir = output_dir.canonicalize().map_err(|err| { format!( diff --git a/build_system/src/prepare.rs b/build_system/src/prepare.rs index 821c793c7e554..fd577fa94341f 100644 --- a/build_system/src/prepare.rs +++ b/build_system/src/prepare.rs @@ -1,6 +1,6 @@ use crate::rustc_info::get_rustc_path; use crate::utils::{ - cargo_install, git_clone_root_dir, remove_file, run_command, run_command_with_output, walk_dir, + cargo_install, create_dir, git_clone_root_dir, remove_file, run_command, run_command_with_output, walk_dir, }; use std::fs; @@ -41,13 +41,7 @@ fn prepare_libcore( } let sysroot_library_dir = sysroot_dir.join("library"); - fs::create_dir_all(&sysroot_library_dir).map_err(|error| { - format!( - "Failed to create folder `{}`: {:?}", - sysroot_library_dir.display(), - error, - ) - })?; + create_dir(&sysroot_library_dir)?; run_command( &[&"cp", &"-r", &rustlib_dir.join("library"), &sysroot_dir], diff --git a/build_system/src/test.rs b/build_system/src/test.rs index 0895dc6bff700..c0cb6c8f2397b 100644 --- a/build_system/src/test.rs +++ b/build_system/src/test.rs @@ -1,13 +1,13 @@ use crate::build; use crate::config::{Channel, ConfigInfo}; use crate::utils::{ - get_toolchain, git_clone, git_clone_root_dir, remove_file, run_command, run_command_with_env, + create_dir, get_toolchain, git_clone, git_clone_root_dir, remove_file, run_command, run_command_with_env, run_command_with_output_and_env, rustc_version_info, split_args, walk_dir, }; use std::collections::{BTreeSet, HashMap}; use std::ffi::OsStr; -use std::fs::{create_dir_all, remove_dir_all, File}; +use std::fs::{remove_dir_all, File}; use std::io::{BufRead, BufReader}; use std::path::{Path, PathBuf}; use std::str::FromStr; @@ -211,8 +211,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 path = Path::new(&args.config_info.cargo_target_dir).join("gccjit"); - std::fs::create_dir_all(&path) - .map_err(|error| format!("failed to create folder `{}`: {:?}", path.display(), error)) + create_dir(&path) } fn mini_tests(env: &Env, args: &TestArg) -> Result<(), String> { @@ -715,8 +714,7 @@ fn test_projects(env: &Env, args: &TestArg) -> Result<(), String> { }; let projects_path = Path::new("projects"); - create_dir_all(projects_path) - .map_err(|err| format!("Failed to create directory `projects`: {}", err))?; + create_dir(projects_path)?; let nb_parts = args.nb_parts.unwrap_or(0); if nb_parts > 0 { diff --git a/build_system/src/utils.rs b/build_system/src/utils.rs index d9c13fd143d15..cd7c035e690c6 100644 --- a/build_system/src/utils.rs +++ b/build_system/src/utils.rs @@ -307,6 +307,12 @@ pub fn git_clone( git_clone_inner(to_clone, dest, shallow_clone, repo_name) } +pub fn create_dir>(path: P) -> Result<(), String> { + fs::create_dir_all(&path).map_err(|error| { + format!("Failed to create directory `{}`: {:?}", path.as_ref().display(), error) + }) +} + /// This function differs from `git_clone` in how it handles *where* the repository will be cloned. /// In `git_clone`, it is cloned in the provided path. In this function, the path you provide is /// the parent folder. So if you pass "a" as folder and try to clone "b.git", it will be cloned into From 6a2f725a45131a1bab709ebd99f498414d7fc409 Mon Sep 17 00:00:00 2001 From: mubarak23 Date: Thu, 21 Mar 2024 16:00:30 +0100 Subject: [PATCH 051/892] remove pass test --- tests/failing-ui-tests.txt | 4 ---- 1 file changed, 4 deletions(-) diff --git a/tests/failing-ui-tests.txt b/tests/failing-ui-tests.txt index de838231a1f96..9d7f9b3e8a6a7 100644 --- a/tests/failing-ui-tests.txt +++ b/tests/failing-ui-tests.txt @@ -16,10 +16,8 @@ tests/ui/sepcomp/sepcomp-statics.rs tests/ui/asm/x86_64/may_unwind.rs tests/ui/backtrace.rs tests/ui/catch-unwind-bang.rs -tests/ui/cfg/cfg-panic-abort.rs tests/ui/drop/dynamic-drop-async.rs tests/ui/drop/repeat-drop.rs -tests/ui/fmt/format-args-capture.rs tests/ui/coroutine/panic-drops-resume.rs tests/ui/coroutine/panic-drops.rs tests/ui/intrinsics/panic-uninitialized-zeroed.rs @@ -29,9 +27,7 @@ tests/ui/mir/mir_calls_to_shims.rs tests/ui/mir/mir_drop_order.rs tests/ui/mir/mir_let_chains_drop_order.rs tests/ui/oom_unwind.rs -tests/ui/panic-runtime/abort-link-to-unwinding-crates.rs tests/ui/panic-runtime/abort.rs -tests/ui/panic-runtime/link-to-abort.rs tests/ui/unwind-no-uwtable.rs tests/ui/parser/unclosed-delimiter-in-dep.rs tests/ui/runtime/rt-explody-panic-payloads.rs From 3cb807b6d36ddf4d12af9f83d08e79dd27f9e901 Mon Sep 17 00:00:00 2001 From: mubarak23 Date: Thu, 21 Mar 2024 16:19:49 +0100 Subject: [PATCH 052/892] remove more pass test from the lists --- tests/failing-ui-tests.txt | 5 ----- 1 file changed, 5 deletions(-) diff --git a/tests/failing-ui-tests.txt b/tests/failing-ui-tests.txt index 9d7f9b3e8a6a7..7c2dbbb33eea1 100644 --- a/tests/failing-ui-tests.txt +++ b/tests/failing-ui-tests.txt @@ -2,7 +2,6 @@ tests/ui/allocator/no_std-alloc-error-handler-custom.rs tests/ui/allocator/no_std-alloc-error-handler-default.rs tests/ui/asm/may_unwind.rs tests/ui/asm/x86_64/multiple-clobber-abi.rs -tests/ui/debuginfo/debuginfo-emit-llvm-ir-and-split-debuginfo.rs tests/ui/functions-closures/parallel-codegen-closures.rs tests/ui/linkage-attr/linkage1.rs tests/ui/lto/dylib-works.rs @@ -27,7 +26,6 @@ tests/ui/mir/mir_calls_to_shims.rs tests/ui/mir/mir_drop_order.rs tests/ui/mir/mir_let_chains_drop_order.rs tests/ui/oom_unwind.rs -tests/ui/panic-runtime/abort.rs tests/ui/unwind-no-uwtable.rs tests/ui/parser/unclosed-delimiter-in-dep.rs tests/ui/runtime/rt-explody-panic-payloads.rs @@ -44,8 +42,6 @@ tests/ui/rfcs/rfc-1857-stabilize-drop-order/drop-order.rs tests/ui/rfcs/rfc-2091-track-caller/std-panic-locations.rs tests/ui/simd/issue-17170.rs tests/ui/simd/issue-39720.rs -tests/ui/statics/issue-91050-1.rs -tests/ui/statics/issue-91050-2.rs tests/ui/alloc-error/default-alloc-error-hook.rs tests/ui/coroutine/panic-safe.rs tests/ui/issues/issue-14875.rs @@ -53,7 +49,6 @@ tests/ui/issues/issue-29948.rs tests/ui/panics/nested_panic_caught.rs tests/ui/const_prop/ice-issue-111353.rs tests/ui/process/println-with-broken-pipe.rs -tests/ui/panic-runtime/lto-abort.rs tests/ui/lto/thin-lto-inlines2.rs tests/ui/lto/weak-works.rs tests/ui/lto/thin-lto-inlines.rs From 193d165e22a090fd2e9307020124551b1f43815e Mon Sep 17 00:00:00 2001 From: mubarak23 Date: Thu, 21 Mar 2024 16:47:20 +0100 Subject: [PATCH 053/892] add back lto-abort.rs to the list --- tests/failing-ui-tests.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/failing-ui-tests.txt b/tests/failing-ui-tests.txt index 7c2dbbb33eea1..713878711b492 100644 --- a/tests/failing-ui-tests.txt +++ b/tests/failing-ui-tests.txt @@ -57,6 +57,7 @@ tests/ui/lto/msvc-imp-present.rs tests/ui/lto/lto-thin-rustc-loads-linker-plugin.rs tests/ui/lto/all-crates.rs tests/ui/async-await/deep-futures-are-freeze.rs +tests/ui/panic-runtime/lto-abort.rs tests/ui/closures/capture-unsized-by-ref.rs tests/ui/coroutine/resume-after-return.rs tests/ui/macros/rfc-2011-nicer-assert-messages/all-expr-kinds.rs From 486f6b7300f4666cb5b84e47374024eca7aab205 Mon Sep 17 00:00:00 2001 From: mubarak23 Date: Thu, 21 Mar 2024 17:04:03 +0100 Subject: [PATCH 054/892] remove lto-abort.rs since it has passed --- tests/failing-ui-tests.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/failing-ui-tests.txt b/tests/failing-ui-tests.txt index 713878711b492..7c2dbbb33eea1 100644 --- a/tests/failing-ui-tests.txt +++ b/tests/failing-ui-tests.txt @@ -57,7 +57,6 @@ tests/ui/lto/msvc-imp-present.rs tests/ui/lto/lto-thin-rustc-loads-linker-plugin.rs tests/ui/lto/all-crates.rs tests/ui/async-await/deep-futures-are-freeze.rs -tests/ui/panic-runtime/lto-abort.rs tests/ui/closures/capture-unsized-by-ref.rs tests/ui/coroutine/resume-after-return.rs tests/ui/macros/rfc-2011-nicer-assert-messages/all-expr-kinds.rs From 67c6c7e00d5f030f12fac14a7372b5f809e264e6 Mon Sep 17 00:00:00 2001 From: mubarak23 Date: Fri, 22 Mar 2024 12:29:56 +0100 Subject: [PATCH 055/892] add two fail test back to the list --- tests/failing-ui-tests.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/failing-ui-tests.txt b/tests/failing-ui-tests.txt index 7c2dbbb33eea1..e1f4cb52d7076 100644 --- a/tests/failing-ui-tests.txt +++ b/tests/failing-ui-tests.txt @@ -16,8 +16,10 @@ tests/ui/asm/x86_64/may_unwind.rs tests/ui/backtrace.rs tests/ui/catch-unwind-bang.rs tests/ui/drop/dynamic-drop-async.rs +tests/ui/cfg/cfg-panic-abort.rs tests/ui/drop/repeat-drop.rs tests/ui/coroutine/panic-drops-resume.rs +format-args-capture.rs tests/ui/coroutine/panic-drops.rs tests/ui/intrinsics/panic-uninitialized-zeroed.rs tests/ui/iterators/iter-sum-overflow-debug.rs From c8cb091e1eae71416c3fd1514de3332a7e173f81 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Sun, 17 Mar 2024 22:26:39 -0400 Subject: [PATCH 056/892] Codegen const panic messages as function calls This skips emitting extra arguments at every callsite (of which there can be many). For a librustc_driver build with overflow checks enabled, this cuts 0.7MB from the resulting binary. --- example/mini_core.rs | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/example/mini_core.rs b/example/mini_core.rs index a868471ed1d4d..4665009e191e6 100644 --- a/example/mini_core.rs +++ b/example/mini_core.rs @@ -418,6 +418,36 @@ pub fn panic(_msg: &'static str) -> ! { } } +macro_rules! panic_const { + ($($lang:ident = $message:expr,)+) => { + #[cfg(not(bootstrap))] + pub mod panic_const { + use super::*; + + $( + #[track_caller] + #[lang = stringify!($lang)] + pub fn $lang() -> ! { + panic($message); + } + )+ + } + } +} + +panic_const! { + panic_const_add_overflow = "attempt to add with overflow", + panic_const_sub_overflow = "attempt to subtract with overflow", + panic_const_mul_overflow = "attempt to multiply with overflow", + panic_const_div_overflow = "attempt to divide with overflow", + panic_const_rem_overflow = "attempt to calculate the remainder with overflow", + panic_const_neg_overflow = "attempt to negate with overflow", + panic_const_shr_overflow = "attempt to shift right with overflow", + panic_const_shl_overflow = "attempt to shift left with overflow", + panic_const_div_by_zero = "attempt to divide by zero", + panic_const_rem_by_zero = "attempt to calculate the remainder with a divisor of zero", +} + #[lang = "panic_cannot_unwind"] fn panic_cannot_unwind() -> ! { unsafe { From 906a2ab5b35a279e8b4ee49b598d98979f40c1f1 Mon Sep 17 00:00:00 2001 From: Mubarak Muhammad Aminu Date: Fri, 22 Mar 2024 15:51:48 +0100 Subject: [PATCH 057/892] Update tests/failing-ui-tests.txt Co-authored-by: antoyo --- tests/failing-ui-tests.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/failing-ui-tests.txt b/tests/failing-ui-tests.txt index e1f4cb52d7076..2ee64f4d9fb43 100644 --- a/tests/failing-ui-tests.txt +++ b/tests/failing-ui-tests.txt @@ -19,7 +19,7 @@ tests/ui/drop/dynamic-drop-async.rs tests/ui/cfg/cfg-panic-abort.rs tests/ui/drop/repeat-drop.rs tests/ui/coroutine/panic-drops-resume.rs -format-args-capture.rs +tests/ui/fmt/format-args-capture.rs tests/ui/coroutine/panic-drops.rs tests/ui/intrinsics/panic-uninitialized-zeroed.rs tests/ui/iterators/iter-sum-overflow-debug.rs From 83eaede0008aff9a281bf322ea74818fef65bd89 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 21 Mar 2024 17:33:10 -0400 Subject: [PATCH 058/892] Make RawPtr take Ty and Mutbl separately --- src/intrinsic/simd.rs | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/intrinsic/simd.rs b/src/intrinsic/simd.rs index e9af34059a0ec..60361a44c2d74 100644 --- a/src/intrinsic/simd.rs +++ b/src/intrinsic/simd.rs @@ -796,16 +796,16 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( // This counts how many pointers fn ptr_count(t: Ty<'_>) -> usize { - match t.kind() { - ty::RawPtr(p) => 1 + ptr_count(p.ty), + match *t.kind() { + ty::RawPtr(p_ty, _) => 1 + ptr_count(p_ty), _ => 0, } } // Non-ptr type fn non_ptr(t: Ty<'_>) -> Ty<'_> { - match t.kind() { - ty::RawPtr(p) => non_ptr(p.ty), + match *t.kind() { + ty::RawPtr(p_ty, _) => non_ptr(p_ty), _ => t, } } @@ -814,8 +814,8 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( // to the element type of the first argument let (_, element_ty0) = arg_tys[0].simd_size_and_type(bx.tcx()); let (_, element_ty1) = arg_tys[1].simd_size_and_type(bx.tcx()); - let (pointer_count, underlying_ty) = match element_ty1.kind() { - ty::RawPtr(p) if p.ty == in_elem => (ptr_count(element_ty1), non_ptr(element_ty1)), + let (pointer_count, underlying_ty) = match *element_ty1.kind() { + ty::RawPtr(p_ty, _) if p_ty == in_elem => (ptr_count(element_ty1), non_ptr(element_ty1)), _ => { require!( false, @@ -910,16 +910,16 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( // This counts how many pointers fn ptr_count(t: Ty<'_>) -> usize { - match t.kind() { - ty::RawPtr(p) => 1 + ptr_count(p.ty), + match *t.kind() { + ty::RawPtr(p_ty, _) => 1 + ptr_count(p_ty), _ => 0, } } // Non-ptr type fn non_ptr(t: Ty<'_>) -> Ty<'_> { - match t.kind() { - ty::RawPtr(p) => non_ptr(p.ty), + match *t.kind() { + ty::RawPtr(p_ty, _) => non_ptr(p_ty), _ => t, } } @@ -929,8 +929,8 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( let (_, element_ty0) = arg_tys[0].simd_size_and_type(bx.tcx()); let (_, element_ty1) = arg_tys[1].simd_size_and_type(bx.tcx()); let (_, element_ty2) = arg_tys[2].simd_size_and_type(bx.tcx()); - let (pointer_count, underlying_ty) = match element_ty1.kind() { - ty::RawPtr(p) if p.ty == in_elem && p.mutbl == hir::Mutability::Mut => { + let (pointer_count, underlying_ty) = match *element_ty1.kind() { + ty::RawPtr(p_ty, mutbl) if p_ty == in_elem && mutbl == hir::Mutability::Mut => { (ptr_count(element_ty1), non_ptr(element_ty1)) } _ => { From ab1ea400a8ac464bb6e39b5b3376e2a0bfcdd3df Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 20 Mar 2024 14:18:38 +0100 Subject: [PATCH 059/892] Format code --- build_system/src/build.rs | 25 +---- build_system/src/cargo.rs | 27 +---- build_system/src/clean.rs | 8 +- build_system/src/config.rs | 62 +++-------- build_system/src/prepare.rs | 66 +++-------- build_system/src/test.rs | 214 +++++++++--------------------------- build_system/src/utils.rs | 50 ++------- 7 files changed, 99 insertions(+), 353 deletions(-) diff --git a/build_system/src/build.rs b/build_system/src/build.rs index a4ea5107a0505..5d3e355a52516 100644 --- a/build_system/src/build.rs +++ b/build_system/src/build.rs @@ -151,15 +151,7 @@ pub fn build_sysroot(env: &HashMap, config: &ConfigInfo) -> Resu // Copy the source files to the sysroot (Rust for Linux needs this). let sysroot_src_path = start_dir.join("sysroot/lib/rustlib/src/rust"); create_dir(&sysroot_src_path)?; - run_command( - &[ - &"cp", - &"-r", - &start_dir.join("sysroot_src/library/"), - &sysroot_src_path, - ], - None, - )?; + run_command(&[&"cp", &"-r", &start_dir.join("sysroot_src/library/"), &sysroot_src_path], None)?; Ok(()) } @@ -167,20 +159,11 @@ 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(), - ); + 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()); if args.config_info.no_default_features { - env.insert( - "RUSTFLAGS".to_string(), - "-Csymbol-mangling-version=v0".to_string(), - ); + env.insert("RUSTFLAGS".to_string(), "-Csymbol-mangling-version=v0".to_string()); } let mut command: Vec<&dyn AsRef> = vec![&"cargo", &"rustc"]; diff --git a/build_system/src/cargo.rs b/build_system/src/cargo.rs index 1cfcdba6b1cd1..e4ea79b06f221 100644 --- a/build_system/src/cargo.rs +++ b/build_system/src/cargo.rs @@ -16,9 +16,7 @@ fn args() -> Result>, String> { } let args = std::env::args().skip(2).collect::>(); if args.is_empty() { - return Err( - "Expected at least one argument for `cargo` subcommand, found none".to_string(), - ); + return Err("Expected at least one argument for `cargo` subcommand, found none".to_string()); } Ok(Some(args)) } @@ -48,17 +46,10 @@ pub fn run() -> Result<(), String> { let current_exe = std::env::current_exe() .and_then(|path| path.canonicalize()) .map_err(|error| format!("Failed to get current exe path: {:?}", error))?; - let mut parent_dir = current_exe - .components() - .map(|comp| comp.as_os_str()) - .collect::>(); + let mut parent_dir = current_exe.components().map(|comp| comp.as_os_str()).collect::>(); // We run this script from "build_system/target/release/y", so we need to remove these elements. for to_remove in &["y", "release", "target", "build_system"] { - if parent_dir - .last() - .map(|part| part == to_remove) - .unwrap_or(false) - { + if parent_dir.last().map(|part| part == to_remove).unwrap_or(false) { parent_dir.pop(); } else { return Err(format!( @@ -69,11 +60,7 @@ pub fn run() -> Result<(), String> { } let parent_dir = PathBuf::from(parent_dir.join(&OsStr::new("/"))); std::env::set_current_dir(&parent_dir).map_err(|error| { - format!( - "Failed to go to `{}` folder: {:?}", - parent_dir.display(), - error - ) + format!("Failed to go to `{}` folder: {:?}", parent_dir.display(), error) })?; let mut env: HashMap = std::env::vars().collect(); @@ -92,11 +79,7 @@ pub fn run() -> Result<(), String> { // We go back to the original folder since we now have set up everything we needed. std::env::set_current_dir(¤t_dir).map_err(|error| { - format!( - "Failed to go back to `{}` folder: {:?}", - current_dir.display(), - error - ) + format!("Failed to go back to `{}` folder: {:?}", current_dir.display(), error) })?; let rustflags = env.get("RUSTFLAGS").cloned().unwrap_or_default(); diff --git a/build_system/src/clean.rs b/build_system/src/clean.rs index cd8e691a0ed9f..22055ab9841d4 100644 --- a/build_system/src/clean.rs +++ b/build_system/src/clean.rs @@ -42,12 +42,8 @@ fn usage() { } fn clean_all() -> Result<(), String> { - let dirs_to_remove = [ - "target", - "build_sysroot/sysroot", - "build_sysroot/sysroot_src", - "build_sysroot/target", - ]; + let dirs_to_remove = + ["target", "build_sysroot/sysroot", "build_sysroot/sysroot_src", "build_sysroot/target"]; for dir in dirs_to_remove { let _ = remove_dir_all(dir); } diff --git a/build_system/src/config.rs b/build_system/src/config.rs index 2e6d1b038c108..274767ea0b17a 100644 --- a/build_system/src/config.rs +++ b/build_system/src/config.rs @@ -1,5 +1,6 @@ use crate::utils::{ - create_dir, create_symlink, get_os_name, run_command_with_output, rustc_version_info, split_args, + create_dir, create_symlink, get_os_name, run_command_with_output, rustc_version_info, + split_args, }; use std::collections::HashMap; use std::env as std_env; @@ -26,11 +27,7 @@ impl Channel { } fn failed_config_parsing(config_file: &Path, err: &str) -> Result { - Err(format!( - "Failed to parse `{}`: {}", - config_file.display(), - err - )) + Err(format!("Failed to parse `{}`: {}", config_file.display(), err)) } #[derive(Default)] @@ -48,11 +45,7 @@ impl ConfigFile { ) })?; let toml = Toml::parse(&content).map_err(|err| { - format!( - "Error occurred around `{}`: {:?}", - &content[err.start..=err.end], - err.kind - ) + format!("Error occurred around `{}`: {:?}", &content[err.start..=err.end], err.kind) })?; let mut config = Self::default(); for (key, value) in toml.iter() { @@ -181,11 +174,7 @@ impl ConfigInfo { }, "--use-backend" => match args.next() { Some(backend) if !backend.is_empty() => self.backend = Some(backend), - _ => { - return Err( - "Expected an argument after `--use-backend`, found nothing".into() - ) - } + _ => return Err("Expected an argument after `--use-backend`, found nothing".into()), }, "--no-default-features" => self.no_default_features = true, _ => return Ok(false), @@ -231,11 +220,7 @@ impl ConfigInfo { create_dir(&output_dir)?; } let output_dir = output_dir.canonicalize().map_err(|err| { - format!( - "Failed to get absolute path of `{}`: {:?}", - output_dir.display(), - err - ) + format!("Failed to get absolute path of `{}`: {:?}", output_dir.display(), err) })?; let libgccjit_so_name = "libgccjit.so"; @@ -269,10 +254,7 @@ impl ConfigInfo { println!("Downloaded libgccjit.so version {} successfully!", commit); // We need to create a link named `libgccjit.so.0` because that's what the linker is // looking for. - create_symlink( - &libgccjit_so, - output_dir.join(&format!("{}.0", libgccjit_so_name)), - )?; + create_symlink(&libgccjit_so, output_dir.join(&format!("{}.0", libgccjit_so_name)))?; } self.gcc_path = output_dir.display().to_string(); @@ -292,10 +274,7 @@ impl ConfigInfo { Some(config_file) => config_file.into(), None => self.compute_path("config.toml"), }; - let ConfigFile { - gcc_path, - download_gccjit, - } = ConfigFile::new(&config_file)?; + let ConfigFile { gcc_path, download_gccjit } = ConfigFile::new(&config_file)?; if let Some(true) = download_gccjit { self.download_gccjit_if_needed()?; @@ -304,10 +283,7 @@ impl ConfigInfo { self.gcc_path = match gcc_path { Some(path) => path, None => { - return Err(format!( - "missing `gcc-path` value from `{}`", - config_file.display(), - )) + return Err(format!("missing `gcc-path` value from `{}`", config_file.display(),)) } }; Ok(()) @@ -387,17 +363,15 @@ impl ConfigInfo { .join(&format!("librustc_codegen_gcc.{}", self.dylib_ext)) .display() .to_string(); - self.sysroot_path = current_dir - .join("build_sysroot/sysroot") - .display() - .to_string(); + self.sysroot_path = current_dir.join("build_sysroot/sysroot").display().to_string(); if let Some(backend) = &self.backend { // This option is only used in the rust compiler testsuite. The sysroot is handled // by its build system directly so no need to set it ourselves. rustflags.push(format!("-Zcodegen-backend={}", backend)); } else { rustflags.extend_from_slice(&[ - "--sysroot".to_string(), self.sysroot_path.clone(), + "--sysroot".to_string(), + self.sysroot_path.clone(), format!("-Zcodegen-backend={}", self.cg_backend_path), ]); } @@ -436,10 +410,8 @@ impl ConfigInfo { // display metadata load errors env.insert("RUSTC_LOG".to_string(), "warn".to_string()); - let sysroot = current_dir.join(&format!( - "build_sysroot/sysroot/lib/rustlib/{}/lib", - self.target_triple, - )); + let sysroot = current_dir + .join(&format!("build_sysroot/sysroot/lib/rustlib/{}/lib", self.target_triple,)); let ld_library_path = format!( "{target}:{sysroot}:{gcc_path}", target = self.cargo_target_dir, @@ -517,11 +489,7 @@ fn download_gccjit( &"--retry", &"3", &"-SRfL", - if with_progress_bar { - &"--progress-bar" - } else { - &"-s" - }, + if with_progress_bar { &"--progress-bar" } else { &"-s" }, &url.as_str(), ], Some(&output_dir), diff --git a/build_system/src/prepare.rs b/build_system/src/prepare.rs index fd577fa94341f..4b6756a2eefbe 100644 --- a/build_system/src/prepare.rs +++ b/build_system/src/prepare.rs @@ -1,6 +1,7 @@ use crate::rustc_info::get_rustc_path; use crate::utils::{ - cargo_install, create_dir, git_clone_root_dir, remove_file, run_command, run_command_with_output, walk_dir, + cargo_install, create_dir, git_clone_root_dir, remove_file, run_command, + run_command_with_output, walk_dir, }; use std::fs; @@ -32,21 +33,14 @@ fn prepare_libcore( let sysroot_dir = sysroot_path.join("sysroot_src"); if sysroot_dir.is_dir() { if let Err(error) = fs::remove_dir_all(&sysroot_dir) { - return Err(format!( - "Failed to remove `{}`: {:?}", - sysroot_dir.display(), - error, - )); + return Err(format!("Failed to remove `{}`: {:?}", sysroot_dir.display(), error,)); } } let sysroot_library_dir = sysroot_dir.join("library"); create_dir(&sysroot_library_dir)?; - run_command( - &[&"cp", &"-r", &rustlib_dir.join("library"), &sysroot_dir], - None, - )?; + run_command(&[&"cp", &"-r", &rustlib_dir.join("library"), &sysroot_dir], None)?; println!("[GIT] init (cwd): `{}`", sysroot_dir.display()); run_command(&[&"git", &"init"], Some(&sysroot_dir))?; @@ -57,26 +51,11 @@ fn prepare_libcore( // This is needed on systems where nothing is configured. // git really needs something here, or it will fail. // Even using --author is not enough. - run_command( - &[&"git", &"config", &"user.email", &"none@example.com"], - Some(&sysroot_dir), - )?; - run_command( - &[&"git", &"config", &"user.name", &"None"], - Some(&sysroot_dir), - )?; - run_command( - &[&"git", &"config", &"core.autocrlf", &"false"], - Some(&sysroot_dir), - )?; - run_command( - &[&"git", &"config", &"commit.gpgSign", &"false"], - Some(&sysroot_dir), - )?; - run_command( - &[&"git", &"commit", &"-m", &"Initial commit", &"-q"], - Some(&sysroot_dir), - )?; + run_command(&[&"git", &"config", &"user.email", &"none@example.com"], Some(&sysroot_dir))?; + run_command(&[&"git", &"config", &"user.name", &"None"], Some(&sysroot_dir))?; + run_command(&[&"git", &"config", &"core.autocrlf", &"false"], Some(&sysroot_dir))?; + run_command(&[&"git", &"config", &"commit.gpgSign", &"false"], Some(&sysroot_dir))?; + run_command(&[&"git", &"commit", &"-m", &"Initial commit", &"-q"], Some(&sysroot_dir))?; let mut patches = Vec::new(); walk_dir( @@ -114,13 +93,7 @@ fn prepare_libcore( run_command_with_output(&[&"git", &"apply", &path], Some(&sysroot_dir))?; run_command_with_output(&[&"git", &"add", &"-A"], Some(&sysroot_dir))?; run_command_with_output( - &[ - &"git", - &"commit", - &"--no-gpg-sign", - &"-m", - &format!("Patch {}", path.display()), - ], + &[&"git", &"commit", &"--no-gpg-sign", &"-m", &format!("Patch {}", path.display())], Some(&sysroot_dir), )?; } @@ -139,13 +112,7 @@ fn prepare_rand() -> Result<(), String> { run_command_with_output(&[&"git", &"apply", &path], Some(rand_dir))?; run_command_with_output(&[&"git", &"add", &"-A"], Some(rand_dir))?; run_command_with_output( - &[ - &"git", - &"commit", - &"--no-gpg-sign", - &"-m", - &format!("Patch {}", path.display()), - ], + &[&"git", &"commit", &"--no-gpg-sign", &"-m", &format!("Patch {}", path.display())], Some(rand_dir), )?; @@ -159,10 +126,7 @@ fn build_raytracer(repo_dir: &Path) -> Result<(), String> { if mv_target.is_file() { remove_file(&mv_target)?; } - run_command( - &[&"mv", &"target/debug/main", &"raytracer_cg_llvm"], - Some(repo_dir), - )?; + run_command(&[&"mv", &"target/debug/main", &"raytracer_cg_llvm"], Some(repo_dir))?; Ok(()) } @@ -207,11 +171,7 @@ impl PrepareArg { a => return Err(format!("Unknown argument `{a}`")), } } - Ok(Some(Self { - cross_compile, - only_libcore, - libgccjit12_patches, - })) + Ok(Some(Self { cross_compile, only_libcore, libgccjit12_patches })) } fn usage() { diff --git a/build_system/src/test.rs b/build_system/src/test.rs index c0cb6c8f2397b..b27f28795d7b6 100644 --- a/build_system/src/test.rs +++ b/build_system/src/test.rs @@ -1,8 +1,9 @@ use crate::build; use crate::config::{Channel, ConfigInfo}; use crate::utils::{ - create_dir, get_toolchain, git_clone, git_clone_root_dir, remove_file, run_command, run_command_with_env, - run_command_with_output_and_env, rustc_version_info, split_args, walk_dir, + create_dir, get_toolchain, git_clone, git_clone_root_dir, remove_file, run_command, + run_command_with_env, run_command_with_output_and_env, rustc_version_info, split_args, + walk_dir, }; use std::collections::{BTreeSet, HashMap}; @@ -19,46 +20,23 @@ type Runners = HashMap<&'static str, (&'static str, Runner)>; fn get_runners() -> Runners { let mut runners = HashMap::new(); - runners.insert( - "--test-rustc", - ("Run all rustc tests", test_rustc as Runner), - ); - runners.insert( - "--test-successful-rustc", - ("Run successful rustc tests", test_successful_rustc), - ); - runners.insert( - "--test-failing-rustc", - ("Run failing rustc tests", test_failing_rustc), - ); - runners.insert( - "--projects", - ("Run the tests of popular crates", test_projects), - ); + runners.insert("--test-rustc", ("Run all rustc tests", test_rustc as Runner)); + runners + .insert("--test-successful-rustc", ("Run successful rustc tests", test_successful_rustc)); + runners.insert("--test-failing-rustc", ("Run failing rustc tests", test_failing_rustc)); + runners.insert("--projects", ("Run the tests of popular crates", test_projects)); runners.insert("--test-libcore", ("Run libcore tests", test_libcore)); runners.insert("--clean", ("Empty cargo target directory", clean)); runners.insert("--build-sysroot", ("Build sysroot", build_sysroot)); runners.insert("--std-tests", ("Run std tests", std_tests)); runners.insert("--asm-tests", ("Run asm tests", asm_tests)); - runners.insert( - "--extended-tests", - ("Run extended sysroot tests", extended_sysroot_tests), - ); - runners.insert( - "--extended-rand-tests", - ("Run extended rand tests", extended_rand_tests), - ); + runners.insert("--extended-tests", ("Run extended sysroot tests", extended_sysroot_tests)); + runners.insert("--extended-rand-tests", ("Run extended rand tests", extended_rand_tests)); runners.insert( "--extended-regex-example-tests", - ( - "Run extended regex example tests", - extended_regex_example_tests, - ), - ); - runners.insert( - "--extended-regex-tests", - ("Run extended regex tests", extended_regex_tests), + ("Run extended regex example tests", extended_regex_example_tests), ); + runners.insert("--extended-regex-tests", ("Run extended regex tests", extended_regex_tests)); runners.insert("--mini-tests", ("Run mini tests", mini_tests)); runners @@ -71,15 +49,9 @@ fn get_number_after_arg( match args.next() { Some(nb) if !nb.is_empty() => match usize::from_str(&nb) { Ok(nb) => Ok(nb), - Err(_) => Err(format!( - "Expected a number after `{}`, found `{}`", - option, nb - )), + Err(_) => Err(format!("Expected a number after `{}`, found `{}`", option, nb)), }, - _ => Err(format!( - "Expected a number after `{}`, found nothing", - option - )), + _ => Err(format!("Expected a number after `{}`, found nothing", option)), } } @@ -130,9 +102,7 @@ impl TestArg { match arg.as_str() { "--features" => match args.next() { Some(feature) if !feature.is_empty() => { - test_arg - .flags - .extend_from_slice(&["--features".into(), feature]); + test_arg.flags.extend_from_slice(&["--features".into(), feature]); } _ => { return Err("Expected an argument after `--features`, found nothing".into()) @@ -303,13 +273,8 @@ fn maybe_run_command_in_vm( let sudo_command: &[&dyn AsRef] = &[&"sudo", &"cp", &exe, &vm_exe_path]; run_command_with_env(sudo_command, None, Some(env))?; - let mut vm_command: Vec<&dyn AsRef> = vec![ - &"sudo", - &"chroot", - &vm_dir, - &"qemu-m68k-static", - &inside_vm_exe_path, - ]; + let mut vm_command: Vec<&dyn AsRef> = + vec![&"sudo", &"chroot", &vm_dir, &"qemu-m68k-static", &inside_vm_exe_path]; vm_command.extend_from_slice(command); run_command_with_output_and_env(&vm_command, Some(&vm_parent_dir), Some(env))?; Ok(()) @@ -398,11 +363,7 @@ fn std_tests(env: &Env, args: &TestArg) -> Result<(), String> { } run_command_with_env(&command, None, Some(env))?; maybe_run_command_in_vm( - &[ - &cargo_target_dir.join("std_example"), - &"--target", - &args.config_info.target_triple, - ], + &[&cargo_target_dir.join("std_example"), &"--target", &args.config_info.target_triple], env, args, )?; @@ -426,11 +387,7 @@ fn std_tests(env: &Env, args: &TestArg) -> Result<(), String> { command.push(test_flag); } run_command_with_env(&command, None, Some(env))?; - maybe_run_command_in_vm( - &[&cargo_target_dir.join("subslice-patterns-const-eval")], - env, - args, - )?; + maybe_run_command_in_vm(&[&cargo_target_dir.join("subslice-patterns-const-eval")], env, args)?; // FIXME: create a function "display_if_not_quiet" or something along the line. println!("[AOT] track-caller-attribute"); @@ -446,11 +403,7 @@ fn std_tests(env: &Env, args: &TestArg) -> Result<(), String> { command.push(test_flag); } run_command_with_env(&command, None, Some(env))?; - maybe_run_command_in_vm( - &[&cargo_target_dir.join("track-caller-attribute")], - env, - args, - )?; + maybe_run_command_in_vm(&[&cargo_target_dir.join("track-caller-attribute")], env, args)?; // FIXME: create a function "display_if_not_quiet" or something along the line. println!("[AOT] mod_bench"); @@ -476,11 +429,7 @@ fn setup_rustc(env: &mut Env, args: &TestArg) -> Result { ); let rust_dir_path = Path::new(crate::BUILD_DIR).join("rust"); // If the repository was already cloned, command will fail, so doesn't matter. - let _ = git_clone( - "https://github.com/rust-lang/rust.git", - Some(&rust_dir_path), - false, - ); + let _ = git_clone("https://github.com/rust-lang/rust.git", Some(&rust_dir_path), false); let rust_dir: Option<&Path> = Some(&rust_dir_path); run_command(&[&"git", &"checkout", &"--", &"tests/"], rust_dir)?; run_command_with_output_and_env(&[&"git", &"fetch"], rust_dir, Some(env))?; @@ -510,12 +459,8 @@ fn setup_rustc(env: &mut Env, args: &TestArg) -> Result { } })?; let rustc = String::from_utf8( - run_command_with_env( - &[&"rustup", &toolchain, &"which", &"rustc"], - rust_dir, - Some(env), - )? - .stdout, + run_command_with_env(&[&"rustup", &toolchain, &"which", &"rustc"], rust_dir, Some(env))? + .stdout, ) .map_err(|error| format!("Failed to retrieve rustc path: {:?}", error)) .and_then(|rustc| { @@ -572,13 +517,7 @@ download-ci-llvm = false llvm_filecheck = llvm_filecheck.trim(), ), ) - .map_err(|error| { - format!( - "Failed to write into `{}`: {:?}", - file_path.display(), - error - ) - })?; + .map_err(|error| format!("Failed to write into `{}`: {:?}", file_path.display(), error))?; Ok(rust_dir_path) } @@ -590,11 +529,8 @@ fn asm_tests(env: &Env, args: &TestArg) -> Result<(), String> { env.insert("COMPILETEST_FORCE_STAGE0".to_string(), "1".to_string()); - let extra = if args.is_using_gcc_master_branch() { - "" - } else { - " -Csymbol-mangling-version=v0" - }; + let extra = + if args.is_using_gcc_master_branch() { "" } else { " -Csymbol-mangling-version=v0" }; let rustc_args = &format!( r#"-Zpanic-abort-tests \ @@ -761,10 +697,8 @@ fn extended_rand_tests(env: &Env, args: &TestArg) -> Result<(), String> { } let mut env = env.clone(); // newer aho_corasick versions throw a deprecation warning - let rustflags = format!( - "{} --cap-lints warn", - env.get("RUSTFLAGS").cloned().unwrap_or_default() - ); + let rustflags = + format!("{} --cap-lints warn", env.get("RUSTFLAGS").cloned().unwrap_or_default()); env.insert("RUSTFLAGS".to_string(), rustflags); let path = Path::new(crate::BUILD_DIR).join("rand"); @@ -786,18 +720,11 @@ fn extended_regex_example_tests(env: &Env, args: &TestArg) -> Result<(), String> println!("[TEST] rust-lang/regex example shootout-regex-dna"); let mut env = env.clone(); // newer aho_corasick versions throw a deprecation warning - let rustflags = format!( - "{} --cap-lints warn", - env.get("RUSTFLAGS").cloned().unwrap_or_default() - ); + let rustflags = + format!("{} --cap-lints warn", env.get("RUSTFLAGS").cloned().unwrap_or_default()); env.insert("RUSTFLAGS".to_string(), rustflags); // Make sure `[codegen mono items] start` doesn't poison the diff - run_cargo_command( - &[&"build", &"--example", &"shootout-regex-dna"], - Some(&path), - &env, - args, - )?; + run_cargo_command(&[&"build", &"--example", &"shootout-regex-dna"], Some(&path), &env, args)?; run_cargo_command_with_callback( &[&"run", &"--example", &"shootout-regex-dna"], @@ -808,10 +735,8 @@ fn extended_regex_example_tests(env: &Env, args: &TestArg) -> Result<(), String> // FIXME: rewrite this with `child.stdin.write_all()` because // `examples/regexdna-input.txt` is very small. let mut command: Vec<&dyn AsRef> = vec![&"bash", &"-c"]; - let cargo_args = cargo_command - .iter() - .map(|s| s.as_ref().to_str().unwrap()) - .collect::>(); + let cargo_args = + cargo_command.iter().map(|s| s.as_ref().to_str().unwrap()).collect::>(); let bash_command = format!( "cat examples/regexdna-input.txt | {} | grep -v 'Spawned thread' > res.txt", cargo_args.join(" "), @@ -839,10 +764,8 @@ fn extended_regex_tests(env: &Env, args: &TestArg) -> Result<(), String> { println!("[TEST] rust-lang/regex tests"); let mut env = env.clone(); // newer aho_corasick versions throw a deprecation warning - let rustflags = format!( - "{} --cap-lints warn", - env.get("RUSTFLAGS").cloned().unwrap_or_default() - ); + let rustflags = + format!("{} --cap-lints warn", env.get("RUSTFLAGS").cloned().unwrap_or_default()); env.insert("RUSTFLAGS".to_string(), rustflags); let path = Path::new(crate::BUILD_DIR).join("regex"); run_cargo_command( @@ -897,6 +820,7 @@ fn should_not_remove_test(file: &str) -> bool { .any(|to_ignore| file.ends_with(to_ignore)) } +#[rustfmt::skip] fn should_remove_test(file_path: &Path) -> Result { // Tests generating errors. let file = File::open(file_path) @@ -914,8 +838,8 @@ fn should_remove_test(file_path: &Path) -> Result { "//~", "thread", ] - .iter() - .any(|check| line.contains(check)) + .iter() + .any(|check| line.contains(check)) { return Ok(true); } @@ -923,11 +847,7 @@ fn should_remove_test(file_path: &Path) -> Result { return Ok(true); } } - if file_path - .display() - .to_string() - .contains("ambiguous-4-extern.rs") - { + if file_path.display().to_string().contains("ambiguous-4-extern.rs") { eprintln!("nothing found for {file_path:?}"); } Ok(false) @@ -970,21 +890,13 @@ 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) - { + if dir.file_name().map(|name| name == "auxiliary").unwrap_or(true) { return Ok(()); } walk_dir(dir, dir_handling, file_handling) } fn file_handling(file_path: &Path) -> Result<(), String> { - if !file_path - .extension() - .map(|extension| extension == "rs") - .unwrap_or(false) - { + if !file_path.extension().map(|extension| extension == "rs").unwrap_or(false) { return Ok(()); } let path_str = file_path.display().to_string().replace("\\", "/"); @@ -1017,10 +929,7 @@ where if nb_parts > 0 { let current_part = args.current_part.unwrap(); // FIXME: create a function "display_if_not_quiet" or something along the line. - println!( - "Splitting ui_test into {} parts (and running part {})", - nb_parts, current_part - ); + println!("Splitting ui_test into {} parts (and running part {})", nb_parts, current_part); let out = String::from_utf8( run_command( &[ @@ -1060,11 +969,8 @@ where println!("[TEST] rustc test suite"); env.insert("COMPILETEST_FORCE_STAGE0".to_string(), "1".to_string()); - let extra = if args.is_using_gcc_master_branch() { - "" - } else { - " -Csymbol-mangling-version=v0" - }; + let extra = + if args.is_using_gcc_master_branch() { "" } else { " -Csymbol-mangling-version=v0" }; let rustc_args = format!( "{} -Zcodegen-backend={} --sysroot {}{}", @@ -1118,18 +1024,11 @@ fn test_failing_rustc(env: &Env, args: &TestArg) -> Result<(), String> { // Putting back only the failing ones. let path = "tests/failing-ui-tests.txt"; if let Ok(files) = std::fs::read_to_string(path) { - for file in files - .split('\n') - .map(|line| line.trim()) - .filter(|line| !line.is_empty()) - { + for file in files.split('\n').map(|line| line.trim()).filter(|line| !line.is_empty()) { run_command(&[&"git", &"checkout", &"--", &file], Some(&rust_path))?; } } else { - println!( - "Failed to read `{}`, not putting back failing ui tests", - path - ); + println!("Failed to read `{}`, not putting back failing ui tests", path); } Ok(true) }) @@ -1140,19 +1039,12 @@ fn test_successful_rustc(env: &Env, args: &TestArg) -> Result<(), String> { // Removing the failing tests. let path = "tests/failing-ui-tests.txt"; if let Ok(files) = std::fs::read_to_string(path) { - for file in files - .split('\n') - .map(|line| line.trim()) - .filter(|line| !line.is_empty()) - { + for file in files.split('\n').map(|line| line.trim()).filter(|line| !line.is_empty()) { let path = rust_path.join(file); remove_file(&path)?; } } else { - println!( - "Failed to read `{}`, not putting back failing ui tests", - path - ); + println!("Failed to read `{}`, not putting back failing ui tests", path); } Ok(true) }) @@ -1179,14 +1071,8 @@ 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(), - ); + 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()); } build_if_no_backend(&env, &args)?; diff --git a/build_system/src/utils.rs b/build_system/src/utils.rs index cd7c035e690c6..c5e7f532a7ddc 100644 --- a/build_system/src/utils.rs +++ b/build_system/src/utils.rs @@ -37,13 +37,8 @@ fn check_exit_status( } let mut error = format!( "Command `{}`{} exited with status {:?}", - input - .iter() - .map(|s| s.as_ref().to_str().unwrap()) - .collect::>() - .join(" "), - cwd.map(|cwd| format!(" (running in folder `{}`)", cwd.display())) - .unwrap_or_default(), + input.iter().map(|s| s.as_ref().to_str().unwrap()).collect::>().join(" "), + cwd.map(|cwd| format!(" (running in folder `{}`)", cwd.display())).unwrap_or_default(), exit_status.code() ); let input = input.iter().map(|i| i.as_ref()).collect::>(); @@ -68,11 +63,7 @@ fn check_exit_status( fn command_error(input: &[&dyn AsRef], cwd: &Option<&Path>, error: D) -> String { format!( "Command `{}`{} failed to run: {error:?}", - input - .iter() - .map(|s| s.as_ref().to_str().unwrap()) - .collect::>() - .join(" "), + input.iter().map(|s| s.as_ref().to_str().unwrap()).collect::>().join(" "), cwd.as_ref() .map(|cwd| format!(" (running in folder `{}`)", cwd.display(),)) .unwrap_or_default(), @@ -88,9 +79,8 @@ pub fn run_command_with_env( cwd: Option<&Path>, env: Option<&HashMap>, ) -> Result { - let output = get_command_inner(input, cwd, env) - .output() - .map_err(|e| command_error(input, &cwd, e))?; + let output = + get_command_inner(input, cwd, env).output().map_err(|e| command_error(input, &cwd, e))?; check_exit_status(input, cwd, output.status, Some(&output), true)?; Ok(output) } @@ -164,10 +154,7 @@ pub fn cargo_install(to_install: &str) -> Result<(), String> { pub fn get_os_name() -> Result { let output = run_command(&[&"uname"], None)?; - let name = std::str::from_utf8(&output.stdout) - .unwrap_or("") - .trim() - .to_string(); + let name = std::str::from_utf8(&output.stdout).unwrap_or("").trim().to_string(); if !name.is_empty() { Ok(name) } else { @@ -274,11 +261,7 @@ fn git_clone_inner( command.push(&"1"); } run_command_with_output(&command, None)?; - Ok(CloneResult { - ran_clone: true, - repo_name, - repo_dir: dest.display().to_string(), - }) + Ok(CloneResult { ran_clone: true, repo_name, repo_dir: dest.display().to_string() }) } fn get_repo_name(url: &str) -> String { @@ -324,12 +307,7 @@ pub fn git_clone_root_dir( ) -> Result { let repo_name = get_repo_name(to_clone); - git_clone_inner( - to_clone, - &dest_parent_dir.join(&repo_name), - shallow_clone, - repo_name, - ) + git_clone_inner(to_clone, &dest_parent_dir.join(&repo_name), shallow_clone, repo_name) } pub fn walk_dir(dir: P, mut dir_cb: D, mut file_cb: F) -> Result<(), String> @@ -389,11 +367,7 @@ pub fn split_args(args: &str) -> Result, String> { } } if !found_end { - return Err(format!( - "Didn't find `{}` at the end of `{}`", - end, - &args[start..] - )); + return Err(format!("Didn't find `{}` at the end of `{}`", end, &args[start..])); } } else if c == '\\' { // We skip the escaped character. @@ -409,11 +383,7 @@ pub fn split_args(args: &str) -> Result, String> { pub fn remove_file + ?Sized>(file_path: &P) -> Result<(), String> { std::fs::remove_file(file_path).map_err(|error| { - format!( - "Failed to remove `{}`: {:?}", - file_path.as_ref().display(), - error - ) + format!("Failed to remove `{}`: {:?}", file_path.as_ref().display(), error) }) } From cde105a651a3f3249d16780f4ff0173ec8f6b87b Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 20 Mar 2024 15:15:20 +0100 Subject: [PATCH 060/892] Move `build_sysroot` folder into `build_system` --- .github/workflows/release.yml | 4 ++-- .github/workflows/stdarch.yml | 8 +++---- .gitignore | 4 ---- .../build_sysroot}/Cargo.toml | 2 +- .../src => build_system/build_sysroot}/lib.rs | 0 build_system/src/build.rs | 24 +++++++++++++++---- build_system/src/clean.rs | 16 +++++++++---- build_system/src/config.rs | 12 +++++----- build_system/src/prepare.rs | 8 +++---- build_system/src/test.rs | 13 +++++----- build_system/src/utils.rs | 17 +++++++++++++ tests/lang_tests_common.rs | 2 +- 12 files changed, 73 insertions(+), 37 deletions(-) rename {build_sysroot => build_system/build_sysroot}/Cargo.toml (93%) rename {build_sysroot/src => build_system/build_sysroot}/lib.rs (100%) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 28336998ffcd7..60a71d7d3dd78 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -62,12 +62,12 @@ jobs: git config --global user.email "user@example.com" git config --global user.name "User" ./y.sh prepare - # FIXME(antoyo): we cannot enable LTO for stdarch tests currently because of some failing LTO tests using proc-macros. - echo -n 'lto = "fat"' >> build_sysroot/Cargo.toml - name: Add more failing tests because of undefined symbol errors (FIXME) run: cat tests/failing-lto-tests.txt >> tests/failing-ui-tests.txt - name: Run tests 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 }} diff --git a/.github/workflows/stdarch.yml b/.github/workflows/stdarch.yml index 41a9318007f15..25eb5c1b69f28 100644 --- a/.github/workflows/stdarch.yml +++ b/.github/workflows/stdarch.yml @@ -89,12 +89,12 @@ jobs: - name: Run stdarch tests if: ${{ !matrix.cargo_runner }} run: | - cd build_sysroot/sysroot_src/library/stdarch/ - CHANNEL=release TARGET=x86_64-unknown-linux-gnu CG_RUSTFLAGS="-Ainternal_features" ../../../../y.sh cargo test + cd build/build_sysroot/sysroot_src/library/stdarch/ + CHANNEL=release TARGET=x86_64-unknown-linux-gnu CG_RUSTFLAGS="-Ainternal_features" ../../../../../y.sh cargo test - name: Run stdarch tests if: ${{ matrix.cargo_runner }} run: | - cd build_sysroot/sysroot_src/library/stdarch/ + cd build/build_sysroot/sysroot_src/library/stdarch/ # FIXME: these tests fail when the sysroot is compiled with LTO because of a missing symbol in proc-macro. - STDARCH_TEST_EVERYTHING=1 CHANNEL=release CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_RUNNER="${{ matrix.cargo_runner }}" TARGET=x86_64-unknown-linux-gnu CG_RUSTFLAGS="-Ainternal_features" ../../../../y.sh cargo test -- --skip rtm --skip tbm --skip sse4a + STDARCH_TEST_EVERYTHING=1 CHANNEL=release CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_RUNNER="${{ matrix.cargo_runner }}" TARGET=x86_64-unknown-linux-gnu CG_RUSTFLAGS="-Ainternal_features" ../../../../../y.sh cargo test -- --skip rtm --skip tbm --skip sse4a diff --git a/.gitignore b/.gitignore index bf975f92014da..c1e6631a281ba 100644 --- a/.gitignore +++ b/.gitignore @@ -6,10 +6,6 @@ perf.data perf.data.old *.events *.string* -/build_sysroot/sysroot -/build_sysroot/sysroot_src -/build_sysroot/Cargo.lock -/build_sysroot/test_target/Cargo.lock gimple* *asm res diff --git a/build_sysroot/Cargo.toml b/build_system/build_sysroot/Cargo.toml similarity index 93% rename from build_sysroot/Cargo.toml rename to build_system/build_sysroot/Cargo.toml index f46c9c8ce157e..05503128f2af0 100644 --- a/build_sysroot/Cargo.toml +++ b/build_system/build_sysroot/Cargo.toml @@ -1,5 +1,5 @@ [package] -authors = ["bjorn3 "] +authors = ["rustc_codegen_gcc devs"] name = "sysroot" version = "0.0.0" resolver = "2" diff --git a/build_sysroot/src/lib.rs b/build_system/build_sysroot/lib.rs similarity index 100% rename from build_sysroot/src/lib.rs rename to build_system/build_sysroot/lib.rs diff --git a/build_system/src/build.rs b/build_system/src/build.rs index 5d3e355a52516..6313e4ffccb97 100644 --- a/build_system/src/build.rs +++ b/build_system/src/build.rs @@ -1,5 +1,7 @@ use crate::config::{Channel, ConfigInfo}; -use crate::utils::{create_dir, run_command, run_command_with_output_and_env, walk_dir}; +use crate::utils::{ + copy_file, create_dir, get_sysroot_dir, run_command, run_command_with_output_and_env, walk_dir, +}; use std::collections::HashMap; use std::ffi::OsStr; use std::fs; @@ -101,10 +103,24 @@ fn cleanup_sysroot_previous_build(start_dir: &Path) { let _ = fs::remove_dir_all(start_dir.join("sysroot")); } +pub fn create_build_sysroot_content(start_dir: &Path) -> Result<(), String> { + if !start_dir.is_dir() { + create_dir(start_dir)?; + } + copy_file("build_system/build_sysroot/Cargo.toml", &start_dir.join("Cargo.toml"))?; + + let src_dir = start_dir.join("src"); + if !src_dir.is_dir() { + create_dir(&src_dir)?; + } + copy_file("build_system/build_sysroot/lib.rs", &start_dir.join("src/lib.rs")) +} + pub fn build_sysroot(env: &HashMap, config: &ConfigInfo) -> Result<(), String> { - let start_dir = Path::new("build_sysroot"); + let start_dir = get_sysroot_dir(); cleanup_sysroot_previous_build(&start_dir); + create_build_sysroot_content(&start_dir)?; // Builds libs let mut rustflags = env.get("RUSTFLAGS").cloned().unwrap_or_default(); @@ -115,7 +131,6 @@ pub fn build_sysroot(env: &HashMap, config: &ConfigInfo) -> Resu if config.no_default_features { rustflags.push_str(" -Csymbol-mangling-version=v0"); } - let mut env = env.clone(); let mut args: Vec<&dyn AsRef> = vec![&"cargo", &"build", &"--target", &config.target]; @@ -132,8 +147,9 @@ pub fn build_sysroot(env: &HashMap, config: &ConfigInfo) -> Resu "debug" }; + let mut env = env.clone(); env.insert("RUSTFLAGS".to_string(), rustflags); - run_command_with_output_and_env(&args, Some(start_dir), Some(&env))?; + run_command_with_output_and_env(&args, Some(&start_dir), Some(&env))?; // Copy files to sysroot let sysroot_path = start_dir.join(format!("sysroot/lib/rustlib/{}/lib/", config.target_triple)); diff --git a/build_system/src/clean.rs b/build_system/src/clean.rs index 22055ab9841d4..55f55acf73ea0 100644 --- a/build_system/src/clean.rs +++ b/build_system/src/clean.rs @@ -1,4 +1,4 @@ -use crate::utils::{remove_file, run_command}; +use crate::utils::{get_sysroot_dir, remove_file, run_command}; use std::fs::remove_dir_all; use std::path::Path; @@ -42,8 +42,13 @@ fn usage() { } fn clean_all() -> Result<(), String> { - let dirs_to_remove = - ["target", "build_sysroot/sysroot", "build_sysroot/sysroot_src", "build_sysroot/target"]; + let build_sysroot = get_sysroot_dir(); + let dirs_to_remove = [ + "target".into(), + build_sysroot.join("sysroot"), + build_sysroot.join("sysroot_src"), + build_sysroot.join("target"), + ]; for dir in dirs_to_remove { let _ = remove_dir_all(dir); } @@ -52,10 +57,11 @@ fn clean_all() -> Result<(), String> { let _ = remove_dir_all(Path::new(crate::BUILD_DIR).join(dir)); } - let files_to_remove = ["build_sysroot/Cargo.lock", "perf.data", "perf.data.old"]; + let files_to_remove = + [build_sysroot.join("Cargo.lock"), "perf.data".into(), "perf.data.old".into()]; for file in files_to_remove { - let _ = remove_file(file); + let _ = remove_file(&file); } println!("Successfully ran `clean all`"); diff --git a/build_system/src/config.rs b/build_system/src/config.rs index 274767ea0b17a..041d75915fb0b 100644 --- a/build_system/src/config.rs +++ b/build_system/src/config.rs @@ -1,6 +1,6 @@ use crate::utils::{ - create_dir, create_symlink, get_os_name, run_command_with_output, rustc_version_info, - split_args, + create_dir, create_symlink, get_os_name, get_sysroot_dir, run_command_with_output, + rustc_version_info, split_args, }; use std::collections::HashMap; use std::env as std_env; @@ -363,7 +363,8 @@ impl ConfigInfo { .join(&format!("librustc_codegen_gcc.{}", self.dylib_ext)) .display() .to_string(); - self.sysroot_path = current_dir.join("build_sysroot/sysroot").display().to_string(); + self.sysroot_path = + current_dir.join(&get_sysroot_dir()).join("sysroot").display().to_string(); if let Some(backend) = &self.backend { // This option is only used in the rust compiler testsuite. The sysroot is handled // by its build system directly so no need to set it ourselves. @@ -392,8 +393,6 @@ impl ConfigInfo { rustflags.push("-Csymbol-mangling-version=v0".to_string()); } - - // Since we don't support ThinLTO, disable LTO completely when not trying to do LTO. // TODO(antoyo): remove when we can handle ThinLTO. if !env.contains_key(&"FAT_LTO".to_string()) { @@ -411,7 +410,8 @@ impl ConfigInfo { env.insert("RUSTC_LOG".to_string(), "warn".to_string()); let sysroot = current_dir - .join(&format!("build_sysroot/sysroot/lib/rustlib/{}/lib", self.target_triple,)); + .join(&get_sysroot_dir()) + .join(&format!("sysroot/lib/rustlib/{}/lib", self.target_triple)); let ld_library_path = format!( "{target}:{sysroot}:{gcc_path}", target = self.cargo_target_dir, diff --git a/build_system/src/prepare.rs b/build_system/src/prepare.rs index 4b6756a2eefbe..9f405daa68762 100644 --- a/build_system/src/prepare.rs +++ b/build_system/src/prepare.rs @@ -1,6 +1,6 @@ use crate::rustc_info::get_rustc_path; use crate::utils::{ - cargo_install, create_dir, git_clone_root_dir, remove_file, run_command, + cargo_install, create_dir, get_sysroot_dir, git_clone_root_dir, remove_file, run_command, run_command_with_output, walk_dir, }; @@ -89,7 +89,7 @@ fn prepare_libcore( patches.sort(); for file_path in patches { println!("[GIT] apply `{}`", file_path.display()); - let path = Path::new("../..").join(file_path); + let path = Path::new("../../..").join(file_path); run_command_with_output(&[&"git", &"apply", &path], Some(&sysroot_dir))?; run_command_with_output(&[&"git", &"add", &"-A"], Some(&sysroot_dir))?; run_command_with_output( @@ -192,8 +192,8 @@ pub fn run() -> Result<(), String> { Some(a) => a, None => return Ok(()), }; - let sysroot_path = Path::new("build_sysroot"); - prepare_libcore(sysroot_path, args.libgccjit12_patches, args.cross_compile)?; + let sysroot_path = get_sysroot_dir(); + prepare_libcore(&sysroot_path, args.libgccjit12_patches, args.cross_compile)?; if !args.only_libcore { cargo_install("hyperfine")?; diff --git a/build_system/src/test.rs b/build_system/src/test.rs index b27f28795d7b6..c9cfa13e8759d 100644 --- a/build_system/src/test.rs +++ b/build_system/src/test.rs @@ -1,9 +1,9 @@ use crate::build; use crate::config::{Channel, ConfigInfo}; use crate::utils::{ - create_dir, get_toolchain, git_clone, git_clone_root_dir, remove_file, run_command, - run_command_with_env, run_command_with_output_and_env, rustc_version_info, split_args, - walk_dir, + create_dir, get_sysroot_dir, get_toolchain, git_clone, git_clone_root_dir, remove_file, + run_command, run_command_with_env, run_command_with_output_and_env, rustc_version_info, + split_args, walk_dir, }; use std::collections::{BTreeSet, HashMap}; @@ -535,12 +535,13 @@ fn asm_tests(env: &Env, args: &TestArg) -> Result<(), String> { let rustc_args = &format!( r#"-Zpanic-abort-tests \ -Zcodegen-backend="{pwd}/target/{channel}/librustc_codegen_gcc.{dylib_ext}" \ - --sysroot "{pwd}/build_sysroot/sysroot" -Cpanic=abort{extra}"#, + --sysroot "{pwd}/{sysroot_dir}" -Cpanic=abort{extra}"#, pwd = std::env::current_dir() .map_err(|error| format!("`current_dir` failed: {:?}", error))? .display(), channel = args.config_info.channel.as_str(), dylib_ext = args.config_info.dylib_ext, + sysroot_dir = args.config_info.sysroot_path, extra = extra, ); @@ -671,9 +672,9 @@ fn test_projects(env: &Env, args: &TestArg) -> Result<(), String> { fn test_libcore(env: &Env, args: &TestArg) -> Result<(), String> { // FIXME: create a function "display_if_not_quiet" or something along the line. println!("[TEST] libcore"); - let path = Path::new("build_sysroot/sysroot_src/library/core/tests"); + let path = get_sysroot_dir().join("sysroot_src/library/core/tests"); let _ = remove_dir_all(path.join("target")); - run_cargo_command(&[&"test"], Some(path), env, args)?; + run_cargo_command(&[&"test"], Some(&path), env, args)?; Ok(()) } diff --git a/build_system/src/utils.rs b/build_system/src/utils.rs index c5e7f532a7ddc..45a3ac81b44d4 100644 --- a/build_system/src/utils.rs +++ b/build_system/src/utils.rs @@ -296,6 +296,19 @@ pub fn create_dir>(path: P) -> Result<(), String> { }) } +pub fn copy_file, T: AsRef>(from: F, to: T) -> Result<(), String> { + fs::copy(&from, &to) + .map_err(|error| { + format!( + "Failed to copy file `{}` into `{}`: {:?}", + from.as_ref().display(), + to.as_ref().display(), + error + ) + }) + .map(|_| ()) +} + /// This function differs from `git_clone` in how it handles *where* the repository will be cloned. /// In `git_clone`, it is cloned in the provided path. In this function, the path you provide is /// the parent folder. So if you pass "a" as folder and try to clone "b.git", it will be cloned into @@ -403,6 +416,10 @@ pub fn create_symlink, Q: AsRef>(original: P, link: Q) -> R }) } +pub fn get_sysroot_dir() -> PathBuf { + Path::new(crate::BUILD_DIR).join("build_sysroot") +} + #[cfg(test)] mod tests { use super::*; diff --git a/tests/lang_tests_common.rs b/tests/lang_tests_common.rs index d321ffc8ff544..c0fb5fa40733d 100644 --- a/tests/lang_tests_common.rs +++ b/tests/lang_tests_common.rs @@ -79,7 +79,7 @@ pub fn main_inner(profile: Profile) { compiler.args([ &format!("-Zcodegen-backend={}/target/debug/librustc_codegen_gcc.so", current_dir), "--sysroot", - &format!("{}/build_sysroot/sysroot/", current_dir), + &format!("{}/build/build_sysroot/sysroot/", current_dir), "-Zno-parallel-llvm", "-C", "link-arg=-lc", From 52f6d5d5893b74755e044072ebfbaded230c3526 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 21 Mar 2024 17:09:37 +0100 Subject: [PATCH 061/892] Run test commands in the provided order --- build_system/src/test.rs | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/build_system/src/test.rs b/build_system/src/test.rs index c9cfa13e8759d..86e6f1a95e9f2 100644 --- a/build_system/src/test.rs +++ b/build_system/src/test.rs @@ -6,7 +6,7 @@ use crate::utils::{ split_args, walk_dir, }; -use std::collections::{BTreeSet, HashMap}; +use std::collections::HashMap; use std::ffi::OsStr; use std::fs::{remove_dir_all, File}; use std::io::{BufRead, BufReader}; @@ -82,7 +82,7 @@ fn show_usage() { struct TestArg { build_only: bool, use_system_gcc: bool, - runners: BTreeSet, + runners: Vec, flags: Vec, nb_parts: Option, current_part: Option, @@ -127,8 +127,8 @@ impl TestArg { show_usage(); return Ok(None); } - x if runners.contains_key(x) => { - test_arg.runners.insert(x.into()); + x if runners.contains_key(x) && !test_arg.runners.iter().any(|runner| runner == x) => { + test_arg.runners.push(x.into()); } arg => { if !test_arg.config_info.parse_argument(arg, &mut args)? { @@ -535,7 +535,7 @@ fn asm_tests(env: &Env, args: &TestArg) -> Result<(), String> { let rustc_args = &format!( r#"-Zpanic-abort-tests \ -Zcodegen-backend="{pwd}/target/{channel}/librustc_codegen_gcc.{dylib_ext}" \ - --sysroot "{pwd}/{sysroot_dir}" -Cpanic=abort{extra}"#, + --sysroot "{sysroot_dir}" -Cpanic=abort{extra}"#, pwd = std::env::current_dir() .map_err(|error| format!("`current_dir` failed: {:?}", error))? .display(), @@ -974,11 +974,11 @@ where if args.is_using_gcc_master_branch() { "" } else { " -Csymbol-mangling-version=v0" }; let rustc_args = format!( - "{} -Zcodegen-backend={} --sysroot {}{}", - env.get("TEST_FLAGS").unwrap_or(&String::new()), - args.config_info.cg_backend_path, - args.config_info.sysroot_path, - extra, + "{test_flags} -Zcodegen-backend={backend} --sysroot {sysroot}{extra}", + test_flags = env.get("TEST_FLAGS").unwrap_or(&String::new()), + backend = args.config_info.cg_backend_path, + sysroot = args.config_info.sysroot_path, + extra = extra, ); env.get_mut("RUSTFLAGS").unwrap().clear(); From 7ccd8ce6938cc6f44b3451d7a865b6e0d406d2d4 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 21 Mar 2024 17:46:23 +0100 Subject: [PATCH 062/892] Add fmt check on `build_system` --- .github/workflows/ci.yml | 5 ++++- build_system/src/test.rs | 4 +++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 44730bab4ed15..75694ebd9cea8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -96,7 +96,10 @@ jobs: ./y.sh test --release --clean --build-sysroot ${{ matrix.commands }} - name: Check formatting - run: cargo fmt -- --check + run: | + cargo fmt -- --check + cd build_system + cargo fmt -- --check - name: clippy run: | diff --git a/build_system/src/test.rs b/build_system/src/test.rs index 86e6f1a95e9f2..8ce615ff17a45 100644 --- a/build_system/src/test.rs +++ b/build_system/src/test.rs @@ -127,7 +127,9 @@ impl TestArg { show_usage(); return Ok(None); } - x if runners.contains_key(x) && !test_arg.runners.iter().any(|runner| runner == x) => { + x if runners.contains_key(x) + && !test_arg.runners.iter().any(|runner| runner == x) => + { test_arg.runners.push(x.into()); } arg => { From f16a006c233f408ae9be5f7ccc1dd2bbee467b68 Mon Sep 17 00:00:00 2001 From: Shashank Trivedi <100513286+lordshashank@users.noreply.github.com> Date: Sat, 23 Mar 2024 01:02:34 +0530 Subject: [PATCH 063/892] CI cargo test added (#6) --- .github/workflows/ci.yml | 9 ++++++++- tests/hello-world/Cargo.toml | 4 ++++ tests/hello-world/src/main.rs | 3 +++ 3 files changed, 15 insertions(+), 1 deletion(-) create mode 100644 tests/hello-world/Cargo.toml create mode 100644 tests/hello-world/src/main.rs diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 44730bab4ed15..9b2c7ab5e30f5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -80,7 +80,14 @@ jobs: ./y.sh prepare --only-libcore ./y.sh build cargo test - ./y.sh clean all + + - name: Run y.sh cargo build + run: | + ./y.sh cargo build --manifest-path tests/hello-world/Cargo.toml + + - name: Clean + run: | + ./y.sh clean all - name: Prepare dependencies run: | diff --git a/tests/hello-world/Cargo.toml b/tests/hello-world/Cargo.toml new file mode 100644 index 0000000000000..a3b6813443f72 --- /dev/null +++ b/tests/hello-world/Cargo.toml @@ -0,0 +1,4 @@ +[package] +name = "hello_world" + +[dependencies] \ No newline at end of file diff --git a/tests/hello-world/src/main.rs b/tests/hello-world/src/main.rs new file mode 100644 index 0000000000000..fbedd92052549 --- /dev/null +++ b/tests/hello-world/src/main.rs @@ -0,0 +1,3 @@ +fn main() { + println!("Hello, world!"); +} \ No newline at end of file From da070d356932612ab9564d99d10de7924240566c Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 22 Mar 2024 20:24:44 +0100 Subject: [PATCH 064/892] Clean up `y.sh` path in CI --- .github/workflows/stdarch.yml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/.github/workflows/stdarch.yml b/.github/workflows/stdarch.yml index 25eb5c1b69f28..dc52c94376c5f 100644 --- a/.github/workflows/stdarch.yml +++ b/.github/workflows/stdarch.yml @@ -89,12 +89,10 @@ jobs: - name: Run stdarch tests if: ${{ !matrix.cargo_runner }} run: | - cd build/build_sysroot/sysroot_src/library/stdarch/ - CHANNEL=release TARGET=x86_64-unknown-linux-gnu CG_RUSTFLAGS="-Ainternal_features" ../../../../../y.sh cargo test + CHANNEL=release TARGET=x86_64-unknown-linux-gnu CG_RUSTFLAGS="-Ainternal_features" cargo test --manifest-path build/build_sysroot/sysroot_src/library/stdarch/Cargo.toml - name: Run stdarch tests if: ${{ matrix.cargo_runner }} run: | - cd build/build_sysroot/sysroot_src/library/stdarch/ # FIXME: these tests fail when the sysroot is compiled with LTO because of a missing symbol in proc-macro. - STDARCH_TEST_EVERYTHING=1 CHANNEL=release CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_RUNNER="${{ matrix.cargo_runner }}" TARGET=x86_64-unknown-linux-gnu CG_RUSTFLAGS="-Ainternal_features" ../../../../../y.sh cargo test -- --skip rtm --skip tbm --skip sse4a + STDARCH_TEST_EVERYTHING=1 CHANNEL=release CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_RUNNER="${{ matrix.cargo_runner }}" TARGET=x86_64-unknown-linux-gnu CG_RUSTFLAGS="-Ainternal_features" cargo test --manifest-path build/build_sysroot/sysroot_src/library/stdarch/Cargo.toml -- --skip rtm --skip tbm --skip sse4a From 95c7fde6b116daf2bd9078216f560b65edc87737 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Sat, 23 Mar 2024 19:13:52 +1100 Subject: [PATCH 065/892] Unbox and unwrap the contents of `StatementKind::Coverage` The payload of coverage statements was historically a structure with several fields, so it was boxed to avoid bloating `StatementKind`. Now that the payload is a single relatively-small enum, we can replace `Box` with just `CoverageKind`. This patch also adds a size assertion for `StatementKind`, to avoid accidentally bloating it in the future. --- src/coverageinfo.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/coverageinfo.rs b/src/coverageinfo.rs index 849e9886ef39d..4e44f78f23c26 100644 --- a/src/coverageinfo.rs +++ b/src/coverageinfo.rs @@ -1,11 +1,11 @@ use rustc_codegen_ssa::traits::CoverageInfoBuilderMethods; -use rustc_middle::mir::Coverage; +use rustc_middle::mir::coverage::CoverageKind; use rustc_middle::ty::Instance; use crate::builder::Builder; impl<'a, 'gcc, 'tcx> CoverageInfoBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> { - fn add_coverage(&mut self, _instance: Instance<'tcx>, _coverage: &Coverage) { + fn add_coverage(&mut self, _instance: Instance<'tcx>, _kind: &CoverageKind) { // TODO(antoyo) } } From 9c81910732dadc599d4692e9420b99872c40c81c Mon Sep 17 00:00:00 2001 From: mubarak23 Date: Sat, 23 Mar 2024 13:27:33 +0100 Subject: [PATCH 066/892] fix rebase --- tests/failing-ui-tests.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/failing-ui-tests.txt b/tests/failing-ui-tests.txt index 2ee64f4d9fb43..c451db9b480db 100644 --- a/tests/failing-ui-tests.txt +++ b/tests/failing-ui-tests.txt @@ -28,6 +28,9 @@ tests/ui/mir/mir_calls_to_shims.rs tests/ui/mir/mir_drop_order.rs tests/ui/mir/mir_let_chains_drop_order.rs tests/ui/oom_unwind.rs +tests/ui/panic-runtime/abort-link-to-unwinding-crates.rs +tests/ui/panic-runtime/abort.rs +tests/ui/panic-runtime/link-to-abort.rs tests/ui/unwind-no-uwtable.rs tests/ui/parser/unclosed-delimiter-in-dep.rs tests/ui/runtime/rt-explody-panic-payloads.rs @@ -53,6 +56,7 @@ tests/ui/const_prop/ice-issue-111353.rs tests/ui/process/println-with-broken-pipe.rs tests/ui/lto/thin-lto-inlines2.rs tests/ui/lto/weak-works.rs +tests/ui/panic-runtime/lto-abort.rs tests/ui/lto/thin-lto-inlines.rs tests/ui/lto/thin-lto-global-allocator.rs tests/ui/lto/msvc-imp-present.rs From 56eab3c484ee56043d26d3ea3f2dd0d37fd67b0f Mon Sep 17 00:00:00 2001 From: mubarak23 Date: Sat, 23 Mar 2024 18:09:18 +0100 Subject: [PATCH 067/892] remove trailing space --- tests/failing-ui-tests.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/failing-ui-tests.txt b/tests/failing-ui-tests.txt index c451db9b480db..f33f58c763bd0 100644 --- a/tests/failing-ui-tests.txt +++ b/tests/failing-ui-tests.txt @@ -29,7 +29,7 @@ tests/ui/mir/mir_drop_order.rs tests/ui/mir/mir_let_chains_drop_order.rs tests/ui/oom_unwind.rs tests/ui/panic-runtime/abort-link-to-unwinding-crates.rs -tests/ui/panic-runtime/abort.rs +tests/ui/panic-runtime/abort.rs tests/ui/panic-runtime/link-to-abort.rs tests/ui/unwind-no-uwtable.rs tests/ui/parser/unclosed-delimiter-in-dep.rs From 0319a80c5b37383ba90c5c5cd3e412b0477e3b91 Mon Sep 17 00:00:00 2001 From: mubarak23 Date: Sat, 23 Mar 2024 19:21:45 +0100 Subject: [PATCH 068/892] remove more test that have passed --- tests/failing-ui-tests.txt | 3 --- 1 file changed, 3 deletions(-) diff --git a/tests/failing-ui-tests.txt b/tests/failing-ui-tests.txt index f33f58c763bd0..c39b89d884fb5 100644 --- a/tests/failing-ui-tests.txt +++ b/tests/failing-ui-tests.txt @@ -33,9 +33,7 @@ tests/ui/panic-runtime/abort.rs tests/ui/panic-runtime/link-to-abort.rs tests/ui/unwind-no-uwtable.rs tests/ui/parser/unclosed-delimiter-in-dep.rs -tests/ui/runtime/rt-explody-panic-payloads.rs tests/ui/simd/intrinsic/ptr-cast.rs -tests/ui/binding/fn-arg-incomplete-pattern-drop-order.rs tests/ui/consts/missing_span_in_backtrace.rs tests/ui/drop/dynamic-drop.rs tests/ui/dyn-star/box.rs @@ -65,7 +63,6 @@ tests/ui/lto/all-crates.rs tests/ui/async-await/deep-futures-are-freeze.rs tests/ui/closures/capture-unsized-by-ref.rs tests/ui/coroutine/resume-after-return.rs -tests/ui/macros/rfc-2011-nicer-assert-messages/all-expr-kinds.rs tests/ui/simd/masked-load-store.rs tests/ui/simd/repr_packed.rs tests/ui/async-await/in-trait/dont-project-to-specializable-projection.rs From abbe1ba6f2e09a79ceee53bd6645265c6bb8f0f2 Mon Sep 17 00:00:00 2001 From: Matthew Maurer Date: Fri, 15 Mar 2024 19:45:46 +0000 Subject: [PATCH 069/892] CFI: Use Instance at callsites We already use `Instance` at declaration sites when available to glean additional information about possible abstractions of the type in use. This does the same when possible at callsites as well. The primary purpose of this change is to allow CFI to alter how it generates type information for indirect calls through `Virtual` instances. --- src/asm.rs | 2 +- src/builder.rs | 6 ++++-- src/intrinsic/mod.rs | 11 ++++++----- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/src/asm.rs b/src/asm.rs index 9b679019e96ce..06b14a1f118a3 100644 --- a/src/asm.rs +++ b/src/asm.rs @@ -541,7 +541,7 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> { let builtin_unreachable: RValue<'gcc> = unsafe { std::mem::transmute(builtin_unreachable) }; - self.call(self.type_void(), None, None, builtin_unreachable, &[], None); + self.call(self.type_void(), None, None, builtin_unreachable, &[], None, None); } // Write results to outputs. diff --git a/src/builder.rs b/src/builder.rs index f5cda81f6ab86..43cc46cfe682f 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -25,7 +25,7 @@ use rustc_middle::ty::layout::{ FnAbiError, FnAbiOfHelpers, FnAbiRequest, HasParamEnv, HasTyCtxt, LayoutError, LayoutOfHelpers, TyAndLayout, }; -use rustc_middle::ty::{ParamEnv, Ty, TyCtxt}; +use rustc_middle::ty::{ParamEnv, Ty, TyCtxt, Instance}; use rustc_span::def_id::DefId; use rustc_span::Span; use rustc_target::abi::{ @@ -592,12 +592,13 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { then: Block<'gcc>, catch: Block<'gcc>, _funclet: Option<&Funclet>, + instance: Option>, ) -> RValue<'gcc> { let try_block = self.current_func().new_block("try"); let current_block = self.block.clone(); self.block = try_block; - let call = self.call(typ, fn_attrs, None, func, args, None); // TODO(antoyo): use funclet here? + let call = self.call(typ, fn_attrs, None, func, args, None, instance); // TODO(antoyo): use funclet here? self.block = current_block; let return_value = @@ -1667,6 +1668,7 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { func: RValue<'gcc>, args: &[RValue<'gcc>], funclet: Option<&Funclet>, + _instance: Option>, ) -> RValue<'gcc> { // FIXME(antoyo): remove when having a proper API. let gcc_func = unsafe { std::mem::transmute(func) }; diff --git a/src/intrinsic/mod.rs b/src/intrinsic/mod.rs index a6c8b72e851b2..cebd45c09aa39 100644 --- a/src/intrinsic/mod.rs +++ b/src/intrinsic/mod.rs @@ -133,6 +133,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'a, 'gcc, 'tcx> { func, &args.iter().map(|arg| arg.immediate()).collect::>(), None, + None, ) } sym::likely => self.expect(args[0].immediate(), true), @@ -401,7 +402,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'a, 'gcc, 'tcx> { fn abort(&mut self) { let func = self.context.get_builtin_function("abort"); let func: RValue<'gcc> = unsafe { std::mem::transmute(func) }; - self.call(self.type_void(), None, None, func, &[], None); + self.call(self.type_void(), None, None, func, &[], None, None); } fn assume(&mut self, value: Self::Value) { @@ -1103,7 +1104,7 @@ fn try_intrinsic<'a, 'b, 'gcc, 'tcx>( dest: RValue<'gcc>, ) { if bx.sess().panic_strategy() == PanicStrategy::Abort { - bx.call(bx.type_void(), None, None, try_func, &[data], None); + bx.call(bx.type_void(), None, None, try_func, &[data], None, None); // Return 0 unconditionally from the intrinsic call; // we can never unwind. let ret_align = bx.tcx.data_layout.i32_align.abi; @@ -1177,21 +1178,21 @@ fn codegen_gnu_try<'gcc>( let zero = bx.cx.context.new_rvalue_zero(bx.int_type); let ptr = bx.cx.context.new_call(None, eh_pointer_builtin, &[zero]); let catch_ty = bx.type_func(&[bx.type_i8p(), bx.type_i8p()], bx.type_void()); - bx.call(catch_ty, None, None, catch_func, &[data, ptr], None); + bx.call(catch_ty, None, None, catch_func, &[data, ptr], None, None); bx.ret(bx.const_i32(1)); // NOTE: the blocks must be filled before adding the try/catch, otherwise gcc will not // generate a try/catch. // FIXME(antoyo): add a check in the libgccjit API to prevent this. bx.switch_to_block(current_block); - bx.invoke(try_func_ty, None, None, try_func, &[data], then, catch, None); + bx.invoke(try_func_ty, None, None, try_func, &[data], then, catch, None, None); }); let func = unsafe { std::mem::transmute(func) }; // Note that no invoke is used here because by definition this function // can't panic (that's what it's catching). - let ret = bx.call(llty, None, None, func, &[try_func, data, catch_func], None); + let ret = bx.call(llty, None, None, func, &[try_func, data, catch_func], None, None); let i32_align = bx.tcx().data_layout.i32_align.abi; bx.store(ret, dest, i32_align); } From a67cd0c4fdeabb9c870bfbe797212f08fc283e2d Mon Sep 17 00:00:00 2001 From: mubarak23 Date: Sat, 23 Mar 2024 22:18:22 +0100 Subject: [PATCH 070/892] add fn-arg-incomplete-pattern-drop-order.rs to the list --- tests/failing-lto-tests.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/failing-lto-tests.txt b/tests/failing-lto-tests.txt index 6e1ed99c6f7a9..b9126fb73a775 100644 --- a/tests/failing-lto-tests.txt +++ b/tests/failing-lto-tests.txt @@ -30,3 +30,4 @@ tests/ui/macros/rfc-2011-nicer-assert-messages/feature-gate-generic_assert.rs tests/ui/macros/stringify.rs tests/ui/reexport-test-harness-main.rs tests/ui/rfcs/rfc-1937-termination-trait/termination-trait-in-test.rs +tests/ui/binding/fn-arg-incomplete-pattern-drop-order.rs From 1a05106f94391a94bcf221645311bbb5b747ac7c Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Sun, 5 Mar 2023 20:19:41 -0800 Subject: [PATCH 071/892] Add+Use `mir::BinOp::Cmp` --- src/common.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/common.rs b/src/common.rs index d243d7088ada9..78d943192db07 100644 --- a/src/common.rs +++ b/src/common.rs @@ -94,6 +94,10 @@ impl<'gcc, 'tcx> ConstMethods<'tcx> for CodegenCx<'gcc, 'tcx> { self.const_int(self.type_i32(), i as i64) } + fn const_i8(&self, i: i8) -> RValue<'gcc> { + self.const_int(self.type_i8(), i as i64) + } + fn const_u32(&self, i: u32) -> RValue<'gcc> { self.const_uint(self.type_u32(), i as u64) } From 94ca8283af4e33dfbb2bec16becd1a5445689f51 Mon Sep 17 00:00:00 2001 From: Robert Zakrzewski Date: Sun, 24 Mar 2024 12:23:54 +0100 Subject: [PATCH 072/892] add missing mappings from register classes to dummy output types fix formatting Replace LLVM with GCC --- src/asm.rs | 49 ++++++++++++++++++++++++++++++------------------- 1 file changed, 30 insertions(+), 19 deletions(-) diff --git a/src/asm.rs b/src/asm.rs index 72d572465f404..b446843a106c2 100644 --- a/src/asm.rs +++ b/src/asm.rs @@ -694,10 +694,12 @@ fn reg_to_gcc(reg: InlineAsmRegOrRegClass) -> ConstraintOrRegister { fn dummy_output_type<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, reg: InlineAsmRegClass) -> Type<'gcc> { match reg { InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::reg) => cx.type_i32(), - InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::preg) => unimplemented!(), InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::vreg) | InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::vreg_low16) => { - unimplemented!() + cx.type_vector(cx.type_i64(), 2) + } + InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::preg) => { + unreachable!("clobber-only") } InlineAsmRegClass::Arm(ArmInlineAsmRegClass::reg) => cx.type_i32(), InlineAsmRegClass::Arm(ArmInlineAsmRegClass::sreg) @@ -708,21 +710,13 @@ fn dummy_output_type<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, reg: InlineAsmRegCl InlineAsmRegClass::Arm(ArmInlineAsmRegClass::qreg) | InlineAsmRegClass::Arm(ArmInlineAsmRegClass::qreg_low8) | InlineAsmRegClass::Arm(ArmInlineAsmRegClass::qreg_low4) => { - unimplemented!() + cx.type_vector(cx.type_i64(), 2) } - InlineAsmRegClass::Avr(_) => unimplemented!(), - InlineAsmRegClass::Bpf(_) => unimplemented!(), InlineAsmRegClass::Hexagon(HexagonInlineAsmRegClass::reg) => cx.type_i32(), InlineAsmRegClass::LoongArch(LoongArchInlineAsmRegClass::reg) => cx.type_i32(), InlineAsmRegClass::LoongArch(LoongArchInlineAsmRegClass::freg) => cx.type_f32(), - InlineAsmRegClass::M68k(M68kInlineAsmRegClass::reg) => cx.type_i32(), - InlineAsmRegClass::M68k(M68kInlineAsmRegClass::reg_addr) => cx.type_i32(), - InlineAsmRegClass::M68k(M68kInlineAsmRegClass::reg_data) => cx.type_i32(), - InlineAsmRegClass::CSKY(CSKYInlineAsmRegClass::reg) => cx.type_i32(), - InlineAsmRegClass::CSKY(CSKYInlineAsmRegClass::freg) => cx.type_f32(), InlineAsmRegClass::Mips(MipsInlineAsmRegClass::reg) => cx.type_i32(), InlineAsmRegClass::Mips(MipsInlineAsmRegClass::freg) => cx.type_f32(), - InlineAsmRegClass::Msp430(_) => unimplemented!(), InlineAsmRegClass::Nvptx(NvptxInlineAsmRegClass::reg16) => cx.type_i16(), InlineAsmRegClass::Nvptx(NvptxInlineAsmRegClass::reg32) => cx.type_i32(), InlineAsmRegClass::Nvptx(NvptxInlineAsmRegClass::reg64) => cx.type_i64(), @@ -735,26 +729,43 @@ fn dummy_output_type<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, reg: InlineAsmRegCl } InlineAsmRegClass::RiscV(RiscVInlineAsmRegClass::reg) => cx.type_i32(), InlineAsmRegClass::RiscV(RiscVInlineAsmRegClass::freg) => cx.type_f32(), - InlineAsmRegClass::RiscV(RiscVInlineAsmRegClass::vreg) => cx.type_f32(), + InlineAsmRegClass::RiscV(RiscVInlineAsmRegClass::vreg) => { + unreachable!("clobber-only") + } InlineAsmRegClass::X86(X86InlineAsmRegClass::reg) | InlineAsmRegClass::X86(X86InlineAsmRegClass::reg_abcd) => cx.type_i32(), InlineAsmRegClass::X86(X86InlineAsmRegClass::reg_byte) => cx.type_i8(), - InlineAsmRegClass::X86(X86InlineAsmRegClass::mmx_reg) => unimplemented!(), InlineAsmRegClass::X86(X86InlineAsmRegClass::xmm_reg) | InlineAsmRegClass::X86(X86InlineAsmRegClass::ymm_reg) | InlineAsmRegClass::X86(X86InlineAsmRegClass::zmm_reg) => cx.type_f32(), - InlineAsmRegClass::X86(X86InlineAsmRegClass::x87_reg) => unimplemented!(), InlineAsmRegClass::X86(X86InlineAsmRegClass::kreg) => cx.type_i16(), - InlineAsmRegClass::X86(X86InlineAsmRegClass::kreg0) => cx.type_i16(), - InlineAsmRegClass::X86(X86InlineAsmRegClass::tmm_reg) => unimplemented!(), - InlineAsmRegClass::Wasm(WasmInlineAsmRegClass::local) => cx.type_i32(), - InlineAsmRegClass::SpirV(SpirVInlineAsmRegClass::reg) => { - bug!("LLVM backend does not support SPIR-V") + InlineAsmRegClass::X86(X86InlineAsmRegClass::x87_reg) + | InlineAsmRegClass::X86(X86InlineAsmRegClass::mmx_reg) + | InlineAsmRegClass::X86(X86InlineAsmRegClass::kreg0) + | InlineAsmRegClass::X86(X86InlineAsmRegClass::tmm_reg) => { + unreachable!("clobber-only") } + InlineAsmRegClass::Wasm(WasmInlineAsmRegClass::local) => cx.type_i32(), + InlineAsmRegClass::Bpf(BpfInlineAsmRegClass::reg) => cx.type_i64(), + InlineAsmRegClass::Bpf(BpfInlineAsmRegClass::wreg) => cx.type_i32(), + InlineAsmRegClass::Avr(AvrInlineAsmRegClass::reg) => cx.type_i8(), + InlineAsmRegClass::Avr(AvrInlineAsmRegClass::reg_upper) => cx.type_i8(), + InlineAsmRegClass::Avr(AvrInlineAsmRegClass::reg_pair) => cx.type_i16(), + InlineAsmRegClass::Avr(AvrInlineAsmRegClass::reg_iw) => cx.type_i16(), + InlineAsmRegClass::Avr(AvrInlineAsmRegClass::reg_ptr) => cx.type_i16(), InlineAsmRegClass::S390x( S390xInlineAsmRegClass::reg | S390xInlineAsmRegClass::reg_addr, ) => cx.type_i32(), InlineAsmRegClass::S390x(S390xInlineAsmRegClass::freg) => cx.type_f64(), + InlineAsmRegClass::Msp430(Msp430InlineAsmRegClass::reg) => cx.type_i16(), + InlineAsmRegClass::M68k(M68kInlineAsmRegClass::reg) => cx.type_i32(), + InlineAsmRegClass::M68k(M68kInlineAsmRegClass::reg_addr) => cx.type_i32(), + InlineAsmRegClass::M68k(M68kInlineAsmRegClass::reg_data) => cx.type_i32(), + InlineAsmRegClass::CSKY(CSKYInlineAsmRegClass::reg) => cx.type_i32(), + InlineAsmRegClass::CSKY(CSKYInlineAsmRegClass::freg) => cx.type_f32(), + InlineAsmRegClass::SpirV(SpirVInlineAsmRegClass::reg) => { + bug!("GCC backend does not support SPIR-V") + } InlineAsmRegClass::Err => unreachable!(), } } From 2a88451d6b35306ce870b6489e2cbdbad94975fc Mon Sep 17 00:00:00 2001 From: Shashank Trivedi <100513286+lordshashank@users.noreply.github.com> Date: Mon, 25 Mar 2024 21:09:26 +0530 Subject: [PATCH 073/892] run-make tests initialized (#7) --- build_system/src/test.rs | 353 +++++++++++++++++++------------ tests/failing-run-make-tests.txt | 43 ++++ tests/failing-ui-tests.txt | 8 + 3 files changed, 274 insertions(+), 130 deletions(-) create mode 100644 tests/failing-run-make-tests.txt diff --git a/build_system/src/test.rs b/build_system/src/test.rs index 8ce615ff17a45..f1b7b8d19b6ae 100644 --- a/build_system/src/test.rs +++ b/build_system/src/test.rs @@ -856,7 +856,12 @@ fn should_remove_test(file_path: &Path) -> Result { Ok(false) } -fn test_rustc_inner(env: &Env, args: &TestArg, prepare_files_callback: F) -> Result<(), String> +fn test_rustc_inner( + env: &Env, + args: &TestArg, + prepare_files_callback: F, + test_type: &str, +) -> Result<(), String> where F: Fn(&Path) -> Result, { @@ -865,111 +870,106 @@ where let mut env = env.clone(); let rust_path = setup_rustc(&mut env, args)?; - walk_dir( - rust_path.join("tests/ui"), - |dir| { - let dir_name = dir.file_name().and_then(|name| name.to_str()).unwrap_or(""); - if [ - "abi", - "extern", - "unsized-locals", - "proc-macro", - "threads-sendsync", - "borrowck", - "test-attrs", - ] - .iter() - .any(|name| *name == dir_name) - { - std::fs::remove_dir_all(dir).map_err(|error| { - format!("Failed to remove folder `{}`: {:?}", dir.display(), error) - })?; - } - Ok(()) - }, - |_| Ok(()), - )?; - - // 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(()); - } - walk_dir(dir, dir_handling, file_handling) - } - fn file_handling(file_path: &Path) -> Result<(), String> { - if !file_path.extension().map(|extension| extension == "rs").unwrap_or(false) { - return Ok(()); - } - let path_str = file_path.display().to_string().replace("\\", "/"); - if should_not_remove_test(&path_str) { - return Ok(()); - } else if should_remove_test(file_path)? { - return remove_file(&file_path); - } - Ok(()) + if !prepare_files_callback(&rust_path)? { + // FIXME: create a function "display_if_not_quiet" or something along the line. + println!("Keeping all {} tests", test_type); } - remove_file(&rust_path.join("tests/ui/consts/const_cmp_type_id.rs"))?; - remove_file(&rust_path.join("tests/ui/consts/issue-73976-monomorphic.rs"))?; - // this test is oom-killed in the CI. - remove_file(&rust_path.join("tests/ui/consts/issue-miri-1910.rs"))?; - // Tests generating errors. - remove_file(&rust_path.join("tests/ui/consts/issue-94675.rs"))?; - remove_file(&rust_path.join("tests/ui/mir/mir_heavy_promoted.rs"))?; - remove_file(&rust_path.join("tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail.rs"))?; - remove_file(&rust_path.join("tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop.rs"))?; + if test_type == "ui" { + walk_dir( + rust_path.join("tests/ui"), + |dir| { + let dir_name = dir.file_name().and_then(|name| name.to_str()).unwrap_or(""); + if [ + "abi", + "extern", + "unsized-locals", + "proc-macro", + "threads-sendsync", + "borrowck", + "test-attrs", + ] + .iter() + .any(|name| *name == dir_name) + { + std::fs::remove_dir_all(dir).map_err(|error| { + format!("Failed to remove folder `{}`: {:?}", dir.display(), error) + })?; + } + Ok(()) + }, + |_| Ok(()), + )?; - walk_dir(rust_path.join("tests/ui"), dir_handling, file_handling)?; + // 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(()); + } + walk_dir(dir, dir_handling, file_handling) + } + fn file_handling(file_path: &Path) -> Result<(), String> { + if !file_path.extension().map(|extension| extension == "rs").unwrap_or(false) { + return Ok(()); + } + let path_str = file_path.display().to_string().replace("\\", "/"); + if should_not_remove_test(&path_str) { + return Ok(()); + } else if should_remove_test(file_path)? { + return remove_file(&file_path); + } + Ok(()) + } - if !prepare_files_callback(&rust_path)? { - // FIXME: create a function "display_if_not_quiet" or something along the line. - println!("Keeping all UI tests"); - } + walk_dir(rust_path.join("tests/ui"), dir_handling, file_handling)?; - let nb_parts = args.nb_parts.unwrap_or(0); - if nb_parts > 0 { - let current_part = args.current_part.unwrap(); - // FIXME: create a function "display_if_not_quiet" or something along the line. - println!("Splitting ui_test into {} parts (and running part {})", nb_parts, current_part); - let out = String::from_utf8( - run_command( - &[ - &"find", - &"tests/ui", - &"-type", - &"f", - &"-name", - &"*.rs", - &"-not", - &"-path", - &"*/auxiliary/*", - ], - Some(&rust_path), - )? - .stdout, - ) - .map_err(|error| format!("Failed to retrieve output of find command: {:?}", error))?; - let mut files = out - .split('\n') - .map(|line| line.trim()) - .filter(|line| !line.is_empty()) - .collect::>(); - // To ensure it'll be always the same sub files, we sort the content. - files.sort(); - // We increment the number of tests by one because if this is an odd number, we would skip - // one test. - let count = files.len() / nb_parts + 1; - let start = current_part * count; - // We remove the files we don't want to test. - for path in files.iter().skip(start).take(count) { - remove_file(&rust_path.join(path))?; + let nb_parts = args.nb_parts.unwrap_or(0); + if nb_parts > 0 { + let current_part = args.current_part.unwrap(); + // FIXME: create a function "display_if_not_quiet" or something along the line. + println!( + "Splitting ui_test into {} parts (and running part {})", + nb_parts, current_part + ); + let out = String::from_utf8( + run_command( + &[ + &"find", + &"tests/ui", + &"-type", + &"f", + &"-name", + &"*.rs", + &"-not", + &"-path", + &"*/auxiliary/*", + ], + Some(&rust_path), + )? + .stdout, + ) + .map_err(|error| format!("Failed to retrieve output of find command: {:?}", error))?; + let mut files = out + .split('\n') + .map(|line| line.trim()) + .filter(|line| !line.is_empty()) + .collect::>(); + // To ensure it'll be always the same sub files, we sort the content. + files.sort(); + // We increment the number of tests by one because if this is an odd number, we would skip + // one test. + let count = files.len() / nb_parts + 1; + // We remove the files we don't want to test. + let start = current_part * count; + for path in files.iter().skip(start).take(count) { + remove_file(&rust_path.join(path))?; + } } } // FIXME: create a function "display_if_not_quiet" or something along the line. - println!("[TEST] rustc test suite"); + println!("[TEST] rustc {} test suite", test_type); env.insert("COMPILETEST_FORCE_STAGE0".to_string(), "1".to_string()); let extra = @@ -984,6 +984,7 @@ where ); env.get_mut("RUSTFLAGS").unwrap().clear(); + run_command_with_output_and_env( &[ &"./x.py", @@ -992,7 +993,7 @@ where &"always", &"--stage", &"0", - &"tests/ui", + &format!("tests/{}", test_type), &"--rustc-args", &rustc_args, ], @@ -1003,54 +1004,146 @@ where } fn test_rustc(env: &Env, args: &TestArg) -> Result<(), String> { - test_rustc_inner(env, args, |_| Ok(false)) + test_rustc_inner(env, args, |_| Ok(false), "run-make")?; + test_rustc_inner(env, args, |_| Ok(false), "ui") } fn test_failing_rustc(env: &Env, args: &TestArg) -> Result<(), String> { - test_rustc_inner(env, args, |rust_path| { - // Removing all tests. - run_command( - &[ - &"find", - &"tests/ui", - &"-type", - &"f", - &"-name", - &"*.rs", - &"-not", - &"-path", - &"*/auxiliary/*", - &"-delete", - ], - Some(rust_path), - )?; + let result1 = test_rustc_inner( + env, + args, + prepare_files_callback_failing("tests/failing-run-make-tests.txt", "run-make"), + "run-make", + ); + + let result2 = test_rustc_inner( + env, + args, + prepare_files_callback_failing("tests/failing-ui-tests.txt", "ui"), + "ui", + ); + + result1.and(result2) +} + +fn test_successful_rustc(env: &Env, args: &TestArg) -> Result<(), String> { + test_rustc_inner( + env, + args, + prepare_files_callback_success("tests/failing-ui-tests.txt", "ui"), + "ui", + )?; + test_rustc_inner( + env, + args, + prepare_files_callback_success("tests/failing-run-make-tests.txt", "run-make"), + "run-make", + ) +} + +fn prepare_files_callback_failing<'a>( + file_path: &'a str, + test_type: &'a str, +) -> impl Fn(&Path) -> Result + 'a { + move |rust_path| { + let files = std::fs::read_to_string(file_path).unwrap_or_default(); + let first_file_name = files.lines().next().unwrap_or(""); + // If the first line ends with a `/`, we treat all lines in the file as a directory. + if first_file_name.ends_with('/') { + // Treat as directory + // Removing all tests. + run_command( + &[ + &"find", + &format!("tests/{}", test_type), + &"-mindepth", + &"1", + &"-type", + &"d", + &"-exec", + &"rm", + &"-rf", + &"{}", + &"+", + ], + Some(rust_path), + )?; + } else { + // Treat as file + // Removing all tests. + run_command( + &[ + &"find", + &format!("tests/{}", test_type), + &"-type", + &"f", + &"-name", + &"*.rs", + &"-not", + &"-path", + &"*/auxiliary/*", + &"-delete", + ], + Some(rust_path), + )?; + } + // Putting back only the failing ones. - let path = "tests/failing-ui-tests.txt"; - if let Ok(files) = std::fs::read_to_string(path) { + if let Ok(files) = std::fs::read_to_string(&file_path) { for file in files.split('\n').map(|line| line.trim()).filter(|line| !line.is_empty()) { run_command(&[&"git", &"checkout", &"--", &file], Some(&rust_path))?; } } else { - println!("Failed to read `{}`, not putting back failing ui tests", path); + println!( + "Failed to read `{}`, not putting back failing {} tests", + file_path, test_type + ); } + Ok(true) - }) + } } -fn test_successful_rustc(env: &Env, args: &TestArg) -> Result<(), String> { - test_rustc_inner(env, args, |rust_path| { - // Removing the failing tests. - let path = "tests/failing-ui-tests.txt"; - if let Ok(files) = std::fs::read_to_string(path) { - for file in files.split('\n').map(|line| line.trim()).filter(|line| !line.is_empty()) { - let path = rust_path.join(file); - remove_file(&path)?; +fn prepare_files_callback_success<'a>( + file_path: &'a str, + test_type: &'a str, +) -> impl Fn(&Path) -> Result + 'a { + move |rust_path| { + let files = std::fs::read_to_string(file_path).unwrap_or_default(); + let first_file_name = files.lines().next().unwrap_or(""); + // If the first line ends with a `/`, we treat all lines in the file as a directory. + if first_file_name.ends_with('/') { + // Removing the failing tests. + if let Ok(files) = std::fs::read_to_string(file_path) { + for file in + 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) { + println!("Failed to remove directory `{}`: {}", path.display(), e); + } + } + } else { + println!( + "Failed to read `{}`, not putting back failing {} tests", + file_path, test_type + ); } } else { - println!("Failed to read `{}`, not putting back failing ui tests", path); + // Removing the failing tests. + if let Ok(files) = std::fs::read_to_string(file_path) { + for file in + files.split('\n').map(|line| line.trim()).filter(|line| !line.is_empty()) + { + let path = rust_path.join(file); + remove_file(&path)?; + } + } else { + println!("Failed to read `{}`, not putting back failing ui tests", file_path); + } } Ok(true) - }) + } } fn run_all(env: &Env, args: &TestArg) -> Result<(), String> { diff --git a/tests/failing-run-make-tests.txt b/tests/failing-run-make-tests.txt new file mode 100644 index 0000000000000..058261a3ceea0 --- /dev/null +++ b/tests/failing-run-make-tests.txt @@ -0,0 +1,43 @@ +tests/run-make/a-b-a-linker-guard/ +tests/run-make/CURRENT_RUSTC_VERSION/ +tests/run-make/cross-lang-lto/ +tests/run-make/cross-lang-lto-upstream-rlibs/ +tests/run-make/doctests-keep-binaries/ +tests/run-make/doctests-runtool/ +tests/run-make/emit-shared-files/ +tests/run-make/exit-code/ +tests/run-make/issue-22131/ +tests/run-make/issue-38237/ +tests/run-make/issue-64153/ +tests/run-make/llvm-ident/ +tests/run-make/native-link-modifier-bundle/ +tests/run-make/remap-path-prefix-dwarf/ +tests/run-make/repr128-dwarf/ +tests/run-make/rlib-format-packed-bundled-libs/ +tests/run-make/rlib-format-packed-bundled-libs-2/ +tests/run-make/rustdoc-determinism/ +tests/run-make/rustdoc-error-lines/ +tests/run-make/rustdoc-map-file/ +tests/run-make/rustdoc-output-path/ +tests/run-make/rustdoc-scrape-examples-invalid-expr/ +tests/run-make/rustdoc-scrape-examples-multiple/ +tests/run-make/rustdoc-scrape-examples-ordering/ +tests/run-make/rustdoc-scrape-examples-remap/ +tests/run-make/rustdoc-scrape-examples-test/ +tests/run-make/rustdoc-scrape-examples-whitespace/ +tests/run-make/rustdoc-scrape-examples-macros/ +tests/run-make/rustdoc-with-out-dir-option/ +tests/run-make/rustdoc-verify-output-files/ +tests/run-make/rustdoc-themes/ +tests/run-make/rustdoc-with-short-out-dir-option/ +tests/run-make/rustdoc-with-output-option/ +tests/run-make/arguments-non-c-like-enum/ +tests/run-make/c-link-to-rust-staticlib/ +tests/run-make/foreign-double-unwind/ +tests/run-make/foreign-exceptions/ +tests/run-make/glibc-staticlib-args/ +tests/run-make/issue-36710/ +tests/run-make/issue-68794-textrel-on-minimal-lib/ +tests/run-make/lto-smoke-c/ +tests/run-make/return-non-c-like-enum/ + diff --git a/tests/failing-ui-tests.txt b/tests/failing-ui-tests.txt index c39b89d884fb5..0b749918a3a7a 100644 --- a/tests/failing-ui-tests.txt +++ b/tests/failing-ui-tests.txt @@ -70,3 +70,11 @@ tests/ui/consts/try-operator.rs tests/ui/coroutine/unwind-abort-mix.rs tests/ui/type-alias-impl-trait/rpit_tait_equality_in_canonical_query.rs tests/ui/impl-trait/equality-in-canonical-query.rs +tests/ui/consts/issue-miri-1910.rs +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 + From 111b3395a8bdb52e78cef2b2a2e2c9ad6f06719c Mon Sep 17 00:00:00 2001 From: Robert Zakrzewski Date: Wed, 27 Mar 2024 22:37:19 +0100 Subject: [PATCH 074/892] Execute tests using a target defined as a JSON spec (#12) --- .github/workflows/m68k.yml | 7 +++++++ target_specs/m68k-unknown-linux-gnu.json | 26 ++++++++++++++++++++++++ 2 files changed, 33 insertions(+) create mode 100644 target_specs/m68k-unknown-linux-gnu.json diff --git a/.github/workflows/m68k.yml b/.github/workflows/m68k.yml index a8c6b614ce815..47a235b0218c6 100644 --- a/.github/workflows/m68k.yml +++ b/.github/workflows/m68k.yml @@ -88,6 +88,13 @@ jobs: sudo mount debian-m68k.img vm sudo cp $(which qemu-m68k-static) vm/usr/bin/ + - name: Build sample project with target defined as JSON spec + run: | + ./y.sh prepare --only-libcore --cross + ./y.sh build --target-triple m68k-unknown-linux-gnu --target ${{ github.workspace }}/target_specs/m68k-unknown-linux-gnu.json + ./y.sh cargo build --manifest-path=./tests/hello-world/Cargo.toml --target ${{ github.workspace }}/target_specs/m68k-unknown-linux-gnu.json + ./y.sh clean all + - name: Build run: | ./y.sh prepare --only-libcore --cross diff --git a/target_specs/m68k-unknown-linux-gnu.json b/target_specs/m68k-unknown-linux-gnu.json new file mode 100644 index 0000000000000..95ea06106fb1b --- /dev/null +++ b/target_specs/m68k-unknown-linux-gnu.json @@ -0,0 +1,26 @@ +{ + "arch": "m68k", + "cpu": "M68020", + "crt-static-respected": true, + "data-layout": "E-m:e-p:32:16:32-i8:8:8-i16:16:16-i32:16:32-n8:16:32-a:0:16-S16", + "dynamic-linking": true, + "env": "gnu", + "has-rpath": true, + "has-thread-local": true, + "llvm-target": "m68k-unknown-linux-gnu", + "max-atomic-width": 32, + "os": "linux", + "position-independent-executables": true, + "relro-level": "full", + "supported-split-debuginfo": [ + "packed", + "unpacked", + "off" + ], + "target-endian": "big", + "target-family": [ + "unix" + ], + "target-mcount": "_mcount", + "target-pointer-width": "32" +} From cc98f86d4d227c4dac7fc66b7c3bd328473de0e7 Mon Sep 17 00:00:00 2001 From: Aria Beingessner Date: Sun, 3 Mar 2024 14:44:15 -0500 Subject: [PATCH 075/892] stabilize ptr.is_aligned, move ptr.is_aligned_to to a new feature gate This is an alternative to #121920 --- .../libgccjit12/0001-core-Disable-portable-simd-test.patch | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/patches/libgccjit12/0001-core-Disable-portable-simd-test.patch b/patches/libgccjit12/0001-core-Disable-portable-simd-test.patch index 914ae986b50e7..36d0789d2a23b 100644 --- a/patches/libgccjit12/0001-core-Disable-portable-simd-test.patch +++ b/patches/libgccjit12/0001-core-Disable-portable-simd-test.patch @@ -14,7 +14,7 @@ index d0a119c..76fdece 100644 @@ -89,7 +89,6 @@ #![feature(never_type)] #![feature(unwrap_infallible)] - #![feature(pointer_is_aligned)] + #![feature(pointer_is_aligned_to)] -#![feature(portable_simd)] #![feature(ptr_metadata)] #![feature(lazy_cell)] @@ -27,6 +27,6 @@ index d0a119c..76fdece 100644 mod slice; mod str; mod str_lossy; --- +-- 2.42.1 From 03f299bce00001fa0e1841af5db1c6fc5472a0b6 Mon Sep 17 00:00:00 2001 From: Antoni Boucher Date: Sat, 30 Mar 2024 08:14:53 -0400 Subject: [PATCH 076/892] Fix VM artifact link --- .github/workflows/m68k.yml | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/.github/workflows/m68k.yml b/.github/workflows/m68k.yml index 47a235b0218c6..25a5d2cf3d78e 100644 --- a/.github/workflows/m68k.yml +++ b/.github/workflows/m68k.yml @@ -54,13 +54,7 @@ jobs: run: curl -LO https://github.com/cross-cg-gcc-tools/cross-gcc/releases/latest/download/gcc-m68k-13.deb - name: Download VM artifact - uses: dawidd6/action-download-artifact@v2 - with: - workflow: m68k.yml - name: debian-m68k - repo: cross-cg-gcc-tools/vms - branch: master - event: push + run: curl -LO https://github.com/cross-cg-gcc-tools/vms/releases/latest/download/debian-m68k.img - name: Setup path to libgccjit run: | From 92be47bef5e1f35cd84097f4bca5170e9d05dbcd Mon Sep 17 00:00:00 2001 From: Antoni Boucher Date: Sat, 30 Mar 2024 08:16:03 -0400 Subject: [PATCH 077/892] Add back y.sh to run stdarch tests --- .github/workflows/stdarch.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/stdarch.yml b/.github/workflows/stdarch.yml index dc52c94376c5f..e285e9119f700 100644 --- a/.github/workflows/stdarch.yml +++ b/.github/workflows/stdarch.yml @@ -89,10 +89,10 @@ jobs: - name: Run stdarch tests if: ${{ !matrix.cargo_runner }} run: | - CHANNEL=release TARGET=x86_64-unknown-linux-gnu CG_RUSTFLAGS="-Ainternal_features" cargo test --manifest-path build/build_sysroot/sysroot_src/library/stdarch/Cargo.toml + CHANNEL=release TARGET=x86_64-unknown-linux-gnu CG_RUSTFLAGS="-Ainternal_features" ./y.sh cargo test --manifest-path build/build_sysroot/sysroot_src/library/stdarch/Cargo.toml - name: Run stdarch tests if: ${{ matrix.cargo_runner }} run: | # FIXME: these tests fail when the sysroot is compiled with LTO because of a missing symbol in proc-macro. - STDARCH_TEST_EVERYTHING=1 CHANNEL=release CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_RUNNER="${{ matrix.cargo_runner }}" TARGET=x86_64-unknown-linux-gnu CG_RUSTFLAGS="-Ainternal_features" cargo test --manifest-path build/build_sysroot/sysroot_src/library/stdarch/Cargo.toml -- --skip rtm --skip tbm --skip sse4a + STDARCH_TEST_EVERYTHING=1 CHANNEL=release CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_RUNNER="${{ matrix.cargo_runner }}" TARGET=x86_64-unknown-linux-gnu CG_RUSTFLAGS="-Ainternal_features" ./y.sh cargo test --manifest-path build/build_sysroot/sysroot_src/library/stdarch/Cargo.toml -- --skip rtm --skip tbm --skip sse4a From c7ac792687283b8c48fae679bc8cf65387181fa4 Mon Sep 17 00:00:00 2001 From: Antoni Boucher Date: Sat, 30 Mar 2024 08:18:56 -0400 Subject: [PATCH 078/892] Add newlines --- tests/hello-world/Cargo.toml | 2 +- tests/hello-world/src/main.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/hello-world/Cargo.toml b/tests/hello-world/Cargo.toml index a3b6813443f72..0b8cdc63fbe84 100644 --- a/tests/hello-world/Cargo.toml +++ b/tests/hello-world/Cargo.toml @@ -1,4 +1,4 @@ [package] name = "hello_world" -[dependencies] \ No newline at end of file +[dependencies] diff --git a/tests/hello-world/src/main.rs b/tests/hello-world/src/main.rs index fbedd92052549..e7a11a969c037 100644 --- a/tests/hello-world/src/main.rs +++ b/tests/hello-world/src/main.rs @@ -1,3 +1,3 @@ fn main() { println!("Hello, world!"); -} \ No newline at end of file +} From 0b43e03ca9bbc2325528075a64d4aed6375f430b Mon Sep 17 00:00:00 2001 From: Spencer Will Date: Thu, 4 Apr 2024 20:02:42 -0400 Subject: [PATCH 079/892] Add applicability visually --- util/gh-pages/index.html | 27 ++++++++++++++++++++++++++- util/gh-pages/script.js | 10 ++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/util/gh-pages/index.html b/util/gh-pages/index.html index c88c298d5d787..6fb94c14a7ed4 100644 --- a/util/gh-pages/index.html +++ b/util/gh-pages/index.html @@ -496,7 +496,32 @@

Clippy Lints

- +
+ + +
diff --git a/util/gh-pages/script.js b/util/gh-pages/script.js index f59245e556cd2..fa72b7de0a4d7 100644 --- a/util/gh-pages/script.js +++ b/util/gh-pages/script.js @@ -156,6 +156,16 @@ Object.entries(versionFilterKeyMap).map(([key, value]) => [value, key]) ); + const APPLICABILITIES_DEFAULT = { + unspecified: true, + unresolved: true, + machineApplicable: true, + maybeIncorrect: true, + hasPlaceholders: true + }; + + $scope.applicabilities = APPLICABILITIES_DEFAULT; + // loadFromURLParameters retrieves filter settings from the URL parameters and assigns them // to corresponding $scope variables. function loadFromURLParameters() { From 5eb8d854d12573a841fd5dba71578656aa69f830 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 5 Apr 2024 17:18:55 +0200 Subject: [PATCH 080/892] Rename `cargo.rs` into `rust_tools.rs` to prepare the addition of the `rustc` command --- build_system/src/main.rs | 4 ++-- build_system/src/{cargo.rs => rust_tools.rs} | 20 ++++++++++++-------- 2 files changed, 14 insertions(+), 10 deletions(-) rename build_system/src/{cargo.rs => rust_tools.rs} (89%) diff --git a/build_system/src/main.rs b/build_system/src/main.rs index 48ffbc7a9075a..99d466f2b86d2 100644 --- a/build_system/src/main.rs +++ b/build_system/src/main.rs @@ -2,12 +2,12 @@ use std::env; use std::process; mod build; -mod cargo; mod clean; mod clone_gcc; mod config; mod info; mod prepare; +mod rust_tools; mod rustc_info; mod test; mod utils; @@ -75,7 +75,7 @@ fn main() { }; if let Err(e) = match command { - Command::Cargo => cargo::run(), + Command::Cargo => rust_tools::run_cargo(), Command::Clean => clean::run(), Command::Prepare => prepare::run(), Command::Build => build::run(), diff --git a/build_system/src/cargo.rs b/build_system/src/rust_tools.rs similarity index 89% rename from build_system/src/cargo.rs rename to build_system/src/rust_tools.rs index e4ea79b06f221..80885d0c6c700 100644 --- a/build_system/src/cargo.rs +++ b/build_system/src/rust_tools.rs @@ -8,32 +8,36 @@ use std::collections::HashMap; use std::ffi::OsStr; use std::path::PathBuf; -fn args() -> Result>, String> { +fn args(command: &str) -> Result>, String> { // We skip the binary and the "cargo" option. if let Some("--help") = std::env::args().skip(2).next().as_deref() { - usage(); + usage(command); return Ok(None); } let args = std::env::args().skip(2).collect::>(); if args.is_empty() { - return Err("Expected at least one argument for `cargo` subcommand, found none".to_string()); + return Err(format!( + "Expected at least one argument for `{}` subcommand, found none", + command + )); } Ok(Some(args)) } -fn usage() { +fn usage(command: &str) { println!( r#" -`cargo` command help: +`{}` command help: [args] : Arguments to be passed to the cargo command --help : Show this help -"# +"#, + command, ) } -pub fn run() -> Result<(), String> { - let args = match args()? { +pub fn run_cargo() -> Result<(), String> { + let args = match args("cargo")? { Some(a) => a, None => return Ok(()), }; From 040afd36f385e3569844a88273982599f4a48787 Mon Sep 17 00:00:00 2001 From: Michael Baikov Date: Sat, 6 Apr 2024 09:07:54 -0400 Subject: [PATCH 081/892] Save/restore more items in cache with incremental compilation --- src/back/write.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/back/write.rs b/src/back/write.rs index 76a619a1af782..3ea5be1ee562b 100644 --- a/src/back/write.rs +++ b/src/back/write.rs @@ -158,6 +158,8 @@ pub(crate) unsafe fn codegen( config.emit_obj != EmitObj::None, cgcx.target_can_use_split_dwarf && cgcx.split_debuginfo == SplitDebuginfo::Unpacked, config.emit_bc, + config.emit_asm, + config.emit_ir, &cgcx.output_filenames, )) } From 00ad2634d5ec8f718db5ea1520b6de2375ecf237 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 5 Apr 2024 17:32:19 +0200 Subject: [PATCH 082/892] Add `rustc` command to build system --- build_system/src/main.rs | 4 ++ build_system/src/rust_tools.rs | 126 ++++++++++++++++++++------------- 2 files changed, 79 insertions(+), 51 deletions(-) diff --git a/build_system/src/main.rs b/build_system/src/main.rs index 99d466f2b86d2..1bfba0f9828e6 100644 --- a/build_system/src/main.rs +++ b/build_system/src/main.rs @@ -29,6 +29,7 @@ fn usage() { Available commands for build_system: cargo : Run cargo command + rustc : Run rustc command clean : Run clean command prepare : Run prepare command build : Run build command @@ -45,6 +46,7 @@ pub enum Command { CloneGcc, Prepare, Build, + Rustc, Test, Info, } @@ -56,6 +58,7 @@ fn main() { let command = match env::args().nth(1).as_deref() { Some("cargo") => Command::Cargo, + Some("rustc") => Command::Rustc, Some("clean") => Command::Clean, Some("prepare") => Command::Prepare, Some("build") => Command::Build, @@ -76,6 +79,7 @@ fn main() { if let Err(e) = match command { Command::Cargo => rust_tools::run_cargo(), + Command::Rustc => rust_tools::run_rustc(), Command::Clean => clean::run(), Command::Prepare => prepare::run(), Command::Build => build::run(), diff --git a/build_system/src/rust_tools.rs b/build_system/src/rust_tools.rs index 80885d0c6c700..242fa7ef94982 100644 --- a/build_system/src/rust_tools.rs +++ b/build_system/src/rust_tools.rs @@ -9,7 +9,7 @@ use std::ffi::OsStr; use std::path::PathBuf; fn args(command: &str) -> Result>, String> { - // We skip the binary and the "cargo" option. + // We skip the binary and the "cargo"/"rustc" option. if let Some("--help") = std::env::args().skip(2).next().as_deref() { usage(command); return Ok(None); @@ -36,66 +36,90 @@ fn usage(command: &str) { ) } -pub fn run_cargo() -> Result<(), String> { - let args = match args("cargo")? { - Some(a) => a, - None => return Ok(()), - }; +struct RustcTools { + env: HashMap, + args: Vec, + toolchain: String, + config: ConfigInfo, +} - // We first need to go to the original location to ensure that the config setup will go as - // expected. - let current_dir = std::env::current_dir() - .and_then(|path| path.canonicalize()) - .map_err(|error| format!("Failed to get current directory path: {:?}", error))?; - let current_exe = std::env::current_exe() - .and_then(|path| path.canonicalize()) - .map_err(|error| format!("Failed to get current exe path: {:?}", error))?; - let mut parent_dir = current_exe.components().map(|comp| comp.as_os_str()).collect::>(); - // We run this script from "build_system/target/release/y", so we need to remove these elements. - for to_remove in &["y", "release", "target", "build_system"] { - if parent_dir.last().map(|part| part == to_remove).unwrap_or(false) { - parent_dir.pop(); - } else { - return Err(format!( - "Build script not executed from `build_system/target/release/y` (in path {})", - current_exe.display(), - )); +impl RustcTools { + fn new(command: &str) -> Result, String> { + let Some(args) = args(command)? else { return Ok(None) }; + + // We first need to go to the original location to ensure that the config setup will go as + // expected. + let current_dir = std::env::current_dir() + .and_then(|path| path.canonicalize()) + .map_err(|error| format!("Failed to get current directory path: {:?}", error))?; + let current_exe = std::env::current_exe() + .and_then(|path| path.canonicalize()) + .map_err(|error| format!("Failed to get current exe path: {:?}", error))?; + let mut parent_dir = + current_exe.components().map(|comp| comp.as_os_str()).collect::>(); + // We run this script from "build_system/target/release/y", so we need to remove these elements. + for to_remove in &["y", "release", "target", "build_system"] { + if parent_dir.last().map(|part| part == to_remove).unwrap_or(false) { + parent_dir.pop(); + } else { + return Err(format!( + "Build script not executed from `build_system/target/release/y` (in path {})", + current_exe.display(), + )); + } } - } - let parent_dir = PathBuf::from(parent_dir.join(&OsStr::new("/"))); - std::env::set_current_dir(&parent_dir).map_err(|error| { - format!("Failed to go to `{}` folder: {:?}", parent_dir.display(), error) - })?; + let parent_dir = PathBuf::from(parent_dir.join(&OsStr::new("/"))); + std::env::set_current_dir(&parent_dir).map_err(|error| { + format!("Failed to go to `{}` folder: {:?}", parent_dir.display(), error) + })?; - let mut env: HashMap = std::env::vars().collect(); - ConfigInfo::default().setup(&mut env, false)?; - let toolchain = get_toolchain()?; + let mut env: HashMap = std::env::vars().collect(); + let mut config = ConfigInfo::default(); + config.setup(&mut env, false)?; + let toolchain = get_toolchain()?; - let toolchain_version = rustc_toolchain_version_info(&toolchain)?; - let default_version = rustc_version_info(None)?; - if toolchain_version != default_version { - println!( - "rustc_codegen_gcc is built for {} but the default rustc version is {}.", - toolchain_version.short, default_version.short, - ); - println!("Using {}.", toolchain_version.short); - } + let toolchain_version = rustc_toolchain_version_info(&toolchain)?; + let default_version = rustc_version_info(None)?; + if toolchain_version != default_version { + println!( + "rustc_codegen_gcc is built for {} but the default rustc version is {}.", + toolchain_version.short, default_version.short, + ); + println!("Using {}.", toolchain_version.short); + } - // We go back to the original folder since we now have set up everything we needed. - std::env::set_current_dir(¤t_dir).map_err(|error| { - format!("Failed to go back to `{}` folder: {:?}", current_dir.display(), error) - })?; + // We go back to the original folder since we now have set up everything we needed. + std::env::set_current_dir(¤t_dir).map_err(|error| { + format!("Failed to go back to `{}` folder: {:?}", current_dir.display(), error) + })?; + let toolchain = format!("+{}", toolchain); + Ok(Some(Self { toolchain, args, env, config })) + } +} - let rustflags = env.get("RUSTFLAGS").cloned().unwrap_or_default(); - env.insert("RUSTDOCFLAGS".to_string(), rustflags); - let toolchain = format!("+{}", toolchain); - let mut command: Vec<&dyn AsRef> = vec![&"cargo", &toolchain]; - for arg in &args { +pub fn run_cargo() -> Result<(), String> { + let Some(mut tools) = RustcTools::new("cargo")? else { return Ok(()) }; + let rustflags = tools.env.get("RUSTFLAGS").cloned().unwrap_or_default(); + tools.env.insert("RUSTDOCFLAGS".to_string(), rustflags); + let mut command: Vec<&dyn AsRef> = vec![&"cargo", &tools.toolchain]; + for arg in &tools.args { command.push(arg); } - if run_command_with_output_and_env_no_err(&command, None, Some(&env)).is_err() { + if run_command_with_output_and_env_no_err(&command, None, Some(&tools.env)).is_err() { std::process::exit(1); } Ok(()) } + +pub fn run_rustc() -> Result<(), String> { + let Some(tools) = RustcTools::new("rustc")? else { return Ok(()) }; + let mut command = tools.config.rustc_command_vec(); + for arg in &tools.args { + command.push(arg); + } + if run_command_with_output_and_env_no_err(&command, None, Some(&tools.env)).is_err() { + std::process::exit(1); + } + Ok(()) +} From 2a991102977fd6f51d16612e10bd82d74b932e9a Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 5 Apr 2024 17:35:41 +0200 Subject: [PATCH 083/892] Update documentation to recommend using `y.sh rustc` instead of `rustc` and all its flags --- Readme.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/Readme.md b/Readme.md index da6e91587fdaf..9291607995920 100644 --- a/Readme.md +++ b/Readme.md @@ -118,7 +118,13 @@ error: failed to copy bitcode to object file: No such file or directory (os erro ### Rustc -> You should prefer using the Cargo method. +If you want to run `rustc` directly, you can do so with: + +```bash +$ ./y.sh rustc my_crate.rs +``` + +You can do the same manually (although we don't recommend it): ```bash $ LIBRARY_PATH="[gcc-path value]" LD_LIBRARY_PATH="[gcc-path value]" rustc +$(cat $CG_GCCJIT_DIR/rust-toolchain | grep 'channel' | cut -d '=' -f 2 | sed 's/"//g' | sed 's/ //g') -Cpanic=abort -Zcodegen-backend=$CG_GCCJIT_DIR/target/release/librustc_codegen_gcc.so --sysroot $CG_GCCJIT_DIR/build_sysroot/sysroot my_crate.rs From e4ce248af46d2bd3ce59a6dcb82c431bfed4162b Mon Sep 17 00:00:00 2001 From: Spencer Will Date: Tue, 9 Apr 2024 15:00:12 -0400 Subject: [PATCH 084/892] Complete filter functionality. Formatted upper filters to take more visual column space. Force filter wrapping with flex for small screens. --- util/gh-pages/index.html | 7 ++++--- util/gh-pages/script.js | 38 +++++++++++++++++++++++++++++++------- 2 files changed, 35 insertions(+), 10 deletions(-) diff --git a/util/gh-pages/index.html b/util/gh-pages/index.html index 6fb94c14a7ed4..8de36fc40051c 100644 --- a/util/gh-pages/index.html +++ b/util/gh-pages/index.html @@ -103,6 +103,7 @@ @media (min-width: 405px) { #upper-filters { display: flex; + flex-wrap: wrap; } } @@ -404,7 +405,7 @@

Clippy Lints

-
+
-
+
Clippy Lints
-
+

diff --git a/util/gh-pages/script.js b/util/gh-pages/script.js index fa72b7de0a4d7..99868b04492f1 100644 --- a/util/gh-pages/script.js +++ b/util/gh-pages/script.js @@ -156,15 +156,17 @@ Object.entries(versionFilterKeyMap).map(([key, value]) => [value, key]) ); - const APPLICABILITIES_DEFAULT = { - unspecified: true, - unresolved: true, - machineApplicable: true, - maybeIncorrect: true, - hasPlaceholders: true + const APPLICABILITIES_FILTER_DEFAULT = { + Unspecified: true, + Unresolved: true, + MachineApplicable: true, + MaybeIncorrect: true, + HasPlaceholders: true }; - $scope.applicabilities = APPLICABILITIES_DEFAULT; + $scope.applicabilities = { + ...APPLICABILITIES_FILTER_DEFAULT + } // loadFromURLParameters retrieves filter settings from the URL parameters and assigns them // to corresponding $scope variables. @@ -192,6 +194,7 @@ handleParameter('levels', $scope.levels, LEVEL_FILTERS_DEFAULT); handleParameter('groups', $scope.groups, GROUPS_FILTER_DEFAULT); + handleParameter('applicabilities', $scope.applicabilities, APPLICABILITIES_FILTER_DEFAULT); // Handle 'versions' parameter separately because it needs additional processing if (urlParameters.versions) { @@ -259,6 +262,7 @@ updateURLParameter($scope.levels, 'levels', LEVEL_FILTERS_DEFAULT); updateURLParameter($scope.groups, 'groups', GROUPS_FILTER_DEFAULT); updateVersionURLParameter($scope.versionFilters); + updateURLParameter($scope.applicabilities, 'applicabilities', APPLICABILITIES_FILTER_DEFAULT); } // Add $watches to automatically update URL parameters when the data changes @@ -280,6 +284,13 @@ } }, true); + $scope.$watch('applicabilities', function (newVal, oldVal) { + console.log("Test"); + if (newVal !== oldVal) { + updateURLParameter(newVal, 'applicabilities', APPLICABILITIES_FILTER_DEFAULT) + } + }, true); + // Watch for changes in the URL path and update the search and lint display $scope.$watch(function () { return $location.path(); }, function (newPath) { const searchParameter = newPath.substring(1); @@ -337,6 +348,15 @@ } }; + $scope.toggleApplicabilities = function (value) { + const applicabilities = $scope.applicabilities; + for (const key in applicabilities) { + if (applicabilities.hasOwnProperty(key)) { + applicabilities[key] = value; + } + } + } + $scope.resetGroupsToDefault = function () { $scope.groups = { ...GROUPS_FILTER_DEFAULT @@ -440,6 +460,10 @@ return true; } + $scope.byApplicabilities = function (lint) { + return $scope.applicabilities[lint.applicability.applicability]; + }; + // Show details for one lint $scope.openLint = function (lint) { $scope.open[lint.id] = true; From 86921925823fabe1f58f4c40350761043037eb97 Mon Sep 17 00:00:00 2001 From: Shashank Trivedi <100513286+lordshashank@users.noreply.github.com> Date: Wed, 10 Apr 2024 17:53:51 +0530 Subject: [PATCH 085/892] build sysroot flag (#16) --- .github/workflows/ci.yml | 2 +- .github/workflows/gcc12.yml | 2 +- .github/workflows/m68k.yml | 4 ++-- .github/workflows/release.yml | 2 +- .github/workflows/stdarch.yml | 2 +- Readme.md | 2 +- build_system/src/build.rs | 14 ++++++++++---- doc/tips.md | 4 ++-- 8 files changed, 19 insertions(+), 13 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index eca08c7d74993..69a0707c1f2a1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -78,7 +78,7 @@ jobs: - name: Build run: | ./y.sh prepare --only-libcore - ./y.sh build + ./y.sh build --sysroot cargo test - name: Run y.sh cargo build diff --git a/.github/workflows/gcc12.yml b/.github/workflows/gcc12.yml index f7bb156049233..44dca6be6a19a 100644 --- a/.github/workflows/gcc12.yml +++ b/.github/workflows/gcc12.yml @@ -67,7 +67,7 @@ jobs: - name: Build run: | ./y.sh prepare --only-libcore --libgccjit12-patches - ./y.sh build --no-default-features --sysroot-panic-abort + ./y.sh build --sysroot --no-default-features --sysroot-panic-abort cargo test --no-default-features ./y.sh clean all diff --git a/.github/workflows/m68k.yml b/.github/workflows/m68k.yml index 25a5d2cf3d78e..34e4f2b0d4128 100644 --- a/.github/workflows/m68k.yml +++ b/.github/workflows/m68k.yml @@ -85,14 +85,14 @@ jobs: - name: Build sample project with target defined as JSON spec run: | ./y.sh prepare --only-libcore --cross - ./y.sh build --target-triple m68k-unknown-linux-gnu --target ${{ github.workspace }}/target_specs/m68k-unknown-linux-gnu.json + ./y.sh build --sysroot --target-triple m68k-unknown-linux-gnu --target ${{ github.workspace }}/target_specs/m68k-unknown-linux-gnu.json ./y.sh cargo build --manifest-path=./tests/hello-world/Cargo.toml --target ${{ github.workspace }}/target_specs/m68k-unknown-linux-gnu.json ./y.sh clean all - name: Build run: | ./y.sh prepare --only-libcore --cross - ./y.sh build --target-triple m68k-unknown-linux-gnu + ./y.sh build --sysroot --target-triple m68k-unknown-linux-gnu CG_GCC_TEST_TARGET=m68k-unknown-linux-gnu cargo test ./y.sh clean all diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 60a71d7d3dd78..84394b2957c44 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -53,7 +53,7 @@ jobs: - name: Build run: | ./y.sh prepare --only-libcore - EMBED_LTO_BITCODE=1 ./y.sh build --release --release-sysroot + EMBED_LTO_BITCODE=1 ./y.sh build --sysroot --release --release-sysroot cargo test ./y.sh clean all diff --git a/.github/workflows/stdarch.yml b/.github/workflows/stdarch.yml index e285e9119f700..20341ae53d7ee 100644 --- a/.github/workflows/stdarch.yml +++ b/.github/workflows/stdarch.yml @@ -58,7 +58,7 @@ jobs: - name: Build run: | ./y.sh prepare --only-libcore - ./y.sh build --release --release-sysroot + ./y.sh build --sysroot --release --release-sysroot - name: Set env (part 2) run: | diff --git a/Readme.md b/Readme.md index 9291607995920..1599977014504 100644 --- a/Readme.md +++ b/Readme.md @@ -80,7 +80,7 @@ Then you can run commands like this: ```bash $ ./y.sh prepare # download and patch sysroot src and install hyperfine for benchmarking -$ ./y.sh build --release +$ ./y.sh build --sysroot --release ``` To run the tests: diff --git a/build_system/src/build.rs b/build_system/src/build.rs index 6313e4ffccb97..ae2ad1a19a9ba 100644 --- a/build_system/src/build.rs +++ b/build_system/src/build.rs @@ -11,6 +11,7 @@ use std::path::Path; struct BuildArg { flags: Vec, config_info: ConfigInfo, + build_sysroot: bool, } impl BuildArg { @@ -31,6 +32,9 @@ impl BuildArg { ); } } + "--sysroot" => { + build_arg.build_sysroot = true; + } "--help" => { Self::usage(); return Ok(None); @@ -50,7 +54,8 @@ impl BuildArg { r#" `build` command help: - --features [arg] : Add a new feature [arg]"# + --features [arg] : Add a new feature [arg] + --sysroot : Build with sysroot"# ); ConfigInfo::show_usage(); println!(" --help : Show this help"); @@ -205,9 +210,10 @@ fn build_codegen(args: &mut BuildArg) -> Result<(), String> { let _ = fs::remove_dir_all("target/out"); let gccjit_target = "target/out/gccjit"; create_dir(gccjit_target)?; - - println!("[BUILD] sysroot"); - build_sysroot(&env, &args.config_info)?; + if args.build_sysroot { + println!("[BUILD] sysroot"); + build_sysroot(&env, &args.config_info)?; + } Ok(()) } diff --git a/doc/tips.md b/doc/tips.md index 1379f5130be02..6cc81871d0267 100644 --- a/doc/tips.md +++ b/doc/tips.md @@ -54,13 +54,13 @@ generate it in [gimple.md](./doc/gimple.md). * Run `./y.sh prepare --cross` so that the sysroot is patched for the cross-compiling case. * Set the path to the cross-compiling libgccjit in `gcc-path` (in `config.toml`). - * Make sure you have the linker for your target (for instance `m68k-unknown-linux-gnu-gcc`) in your `$PATH`. Currently, the linker name is hardcoded as being `$TARGET-gcc`. Specify the target when building the sysroot: `./y.sh build --target-triple m68k-unknown-linux-gnu`. + * Make sure you have the linker for your target (for instance `m68k-unknown-linux-gnu-gcc`) in your `$PATH`. Currently, the linker name is hardcoded as being `$TARGET-gcc`. Specify the target when building the sysroot: `./y.sh build --sysroot --target-triple m68k-unknown-linux-gnu`. * Build your project by specifying the target: `OVERWRITE_TARGET_TRIPLE=m68k-unknown-linux-gnu ../y.sh cargo build --target m68k-unknown-linux-gnu`. If the target is not yet supported by the Rust compiler, create a [target specification file](https://docs.rust-embedded.org/embedonomicon/custom-target.html) (note that the `arch` specified in this file must be supported by the rust compiler). Then, you can use it the following way: - * Add the target specification file using `--target` as an **absolute** path to build the sysroot: `./y.sh build --target-triple m68k-unknown-linux-gnu --target $(pwd)/m68k-unknown-linux-gnu.json` + * Add the target specification file using `--target` as an **absolute** path to build the sysroot: `./y.sh build --sysroot --target-triple m68k-unknown-linux-gnu --target $(pwd)/m68k-unknown-linux-gnu.json` * Build your project by specifying the target specification file: `OVERWRITE_TARGET_TRIPLE=m68k-unknown-linux-gnu ../y.sh cargo build --target path/to/m68k-unknown-linux-gnu.json`. If you get the following error: From b9b05d5a23eca37bc2707da517b7c882d3eb59d4 Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Wed, 10 Apr 2024 22:07:21 -0700 Subject: [PATCH 086/892] Make `PlaceRef` hold a `PlaceValue` for the non-layout fields (like `OperandRef` does) --- src/builder.rs | 24 ++++++++++++------------ src/intrinsic/mod.rs | 10 +++++----- src/intrinsic/simd.rs | 2 +- 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/builder.rs b/src/builder.rs index 43cc46cfe682f..ce2c18c68a800 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -974,7 +974,7 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { &mut self, place: PlaceRef<'tcx, RValue<'gcc>>, ) -> OperandRef<'tcx, RValue<'gcc>> { - assert_eq!(place.llextra.is_some(), place.layout.is_unsized()); + assert_eq!(place.val.llextra.is_some(), place.layout.is_unsized()); if place.layout.is_zst() { return OperandRef::zero_sized(place.layout); @@ -999,10 +999,10 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { } } - let val = if let Some(llextra) = place.llextra { - OperandValue::Ref(place.llval, Some(llextra), place.align) + let val = if let Some(llextra) = place.val.llextra { + OperandValue::Ref(place.val.llval, Some(llextra), place.val.align) } else if place.layout.is_gcc_immediate() { - let load = self.load(place.layout.gcc_type(self), place.llval, place.align); + let load = self.load(place.layout.gcc_type(self), place.val.llval, place.val.align); if let abi::Abi::Scalar(ref scalar) = place.layout.abi { scalar_load_metadata(self, load, scalar); } @@ -1012,9 +1012,9 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { let mut load = |i, scalar: &abi::Scalar, align| { let llptr = if i == 0 { - place.llval + place.val.llval } else { - self.inbounds_ptradd(place.llval, self.const_usize(b_offset.bytes())) + self.inbounds_ptradd(place.val.llval, self.const_usize(b_offset.bytes())) }; let llty = place.layout.scalar_pair_element_gcc_type(self, i); let load = self.load(llty, llptr, align); @@ -1027,11 +1027,11 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { }; OperandValue::Pair( - load(0, a, place.align), - load(1, b, place.align.restrict_for_offset(b_offset)), + load(0, a, place.val.align), + load(1, b, place.val.align.restrict_for_offset(b_offset)), ) } else { - OperandValue::Ref(place.llval, None, place.align) + OperandValue::Ref(place.val.llval, None, place.val.align) }; OperandRef { val, layout: place.layout } @@ -1045,8 +1045,8 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { ) { let zero = self.const_usize(0); let count = self.const_usize(count); - let start = dest.project_index(self, zero).llval; - let end = dest.project_index(self, count).llval; + let start = dest.project_index(self, zero).val.llval; + let end = dest.project_index(self, count).val.llval; let header_bb = self.append_sibling_block("repeat_loop_header"); let body_bb = self.append_sibling_block("repeat_loop_body"); @@ -1064,7 +1064,7 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { self.cond_br(keep_going, body_bb, next_bb); self.switch_to_block(body_bb); - let align = dest.align.restrict_for_offset(dest.layout.field(self.cx(), 0).size); + let align = dest.val.align.restrict_for_offset(dest.layout.field(self.cx(), 0).size); cg_elem.val.store(self, PlaceRef::new_sized_aligned(current_val, cg_elem.layout, align)); let next = self.inbounds_gep( diff --git a/src/intrinsic/mod.rs b/src/intrinsic/mod.rs index cebd45c09aa39..57cb81a8ecea9 100644 --- a/src/intrinsic/mod.rs +++ b/src/intrinsic/mod.rs @@ -354,7 +354,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'a, 'gcc, 'tcx> { let block = self.llbb(); let extended_asm = block.add_extended_asm(None, ""); - extended_asm.add_input_operand(None, "r", result.llval); + extended_asm.add_input_operand(None, "r", result.val.llval); extended_asm.add_clobber("memory"); extended_asm.set_volatile_flag(true); @@ -388,8 +388,8 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'a, 'gcc, 'tcx> { if !fn_abi.ret.is_ignore() { if let PassMode::Cast { cast: ty, .. } = &fn_abi.ret.mode { let ptr_llty = self.type_ptr_to(ty.gcc_type(self)); - let ptr = self.pointercast(result.llval, ptr_llty); - self.store(llval, ptr, result.align); + let ptr = self.pointercast(result.val.llval, ptr_llty); + self.store(llval, ptr, result.val.align); } else { OperandRef::from_immediate_or_packed_pair(self, llval, result.layout) .val @@ -511,7 +511,7 @@ impl<'gcc, 'tcx> ArgAbiExt<'gcc, 'tcx> for ArgAbi<'tcx, Ty<'tcx>> { let can_store_through_cast_ptr = false; if can_store_through_cast_ptr { let cast_ptr_llty = bx.type_ptr_to(cast.gcc_type(bx)); - let cast_dst = bx.pointercast(dst.llval, cast_ptr_llty); + let cast_dst = bx.pointercast(dst.val.llval, cast_ptr_llty); bx.store(val, cast_dst, self.layout.align.abi); } else { // The actual return type is a struct, but the ABI @@ -539,7 +539,7 @@ impl<'gcc, 'tcx> ArgAbiExt<'gcc, 'tcx> for ArgAbi<'tcx, Ty<'tcx>> { // ... and then memcpy it to the intended destination. bx.memcpy( - dst.llval, + dst.val.llval, self.layout.align.abi, llscratch, scratch_align, diff --git a/src/intrinsic/simd.rs b/src/intrinsic/simd.rs index 60361a44c2d74..6039a4aaf013e 100644 --- a/src/intrinsic/simd.rs +++ b/src/intrinsic/simd.rs @@ -82,7 +82,7 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( let place = PlaceRef::alloca(bx, args[0].layout); args[0].val.store(bx, place); let int_ty = bx.type_ix(expected_bytes * 8); - let ptr = bx.pointercast(place.llval, bx.cx.type_ptr_to(int_ty)); + let ptr = bx.pointercast(place.val.llval, bx.cx.type_ptr_to(int_ty)); bx.load(int_ty, ptr, Align::ONE) } _ => return_error!(InvalidMonomorphization::InvalidBitmask { From cccf379a5bd7096b970277db70f72055ff01a5e8 Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Wed, 10 Apr 2024 23:08:34 -0700 Subject: [PATCH 087/892] Put `PlaceValue` into `OperandValue::Ref`, rather than 3 tuple fields --- src/builder.rs | 7 ++++--- src/intrinsic/mod.rs | 11 ++++++++--- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/builder.rs b/src/builder.rs index ce2c18c68a800..6253816d37d11 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -999,8 +999,9 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { } } - let val = if let Some(llextra) = place.val.llextra { - OperandValue::Ref(place.val.llval, Some(llextra), place.val.align) + let val = if let Some(_) = place.val.llextra { + // FIXME: Merge with the `else` below? + OperandValue::Ref(place.val) } else if place.layout.is_gcc_immediate() { let load = self.load(place.layout.gcc_type(self), place.val.llval, place.val.align); if let abi::Abi::Scalar(ref scalar) = place.layout.abi { @@ -1031,7 +1032,7 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { load(1, b, place.val.align.restrict_for_offset(b_offset)), ) } else { - OperandValue::Ref(place.val.llval, None, place.val.align) + OperandValue::Ref(place.val) }; OperandRef { val, layout: place.layout } diff --git a/src/intrinsic/mod.rs b/src/intrinsic/mod.rs index 57cb81a8ecea9..bee6bda007c3f 100644 --- a/src/intrinsic/mod.rs +++ b/src/intrinsic/mod.rs @@ -11,7 +11,7 @@ use rustc_codegen_ssa::base::wants_msvc_seh; 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; +use rustc_codegen_ssa::mir::place::{PlaceRef, PlaceValue}; use rustc_codegen_ssa::traits::{ ArgAbiMethods, BuilderMethods, ConstMethods, IntrinsicCallMethods, }; @@ -502,7 +502,7 @@ impl<'gcc, 'tcx> ArgAbiExt<'gcc, 'tcx> for ArgAbi<'tcx, Ty<'tcx>> { return; } if self.is_sized_indirect() { - OperandValue::Ref(val, None, self.layout.align.abi).store(bx, dst) + OperandValue::Ref(PlaceValue::new_sized(val, self.layout.align.abi)).store(bx, dst) } else if self.is_unsized_indirect() { bug!("unsized `ArgAbi` must be handled through `store_fn_arg`"); } else if let PassMode::Cast { ref cast, .. } = self.mode { @@ -571,7 +571,12 @@ impl<'gcc, 'tcx> ArgAbiExt<'gcc, 'tcx> for ArgAbi<'tcx, Ty<'tcx>> { OperandValue::Pair(next(), next()).store(bx, dst); } PassMode::Indirect { meta_attrs: Some(_), .. } => { - OperandValue::Ref(next(), Some(next()), self.layout.align.abi).store(bx, dst); + let place_val = PlaceValue { + llval: next(), + llextra: Some(next()), + align: self.layout.align.abi, + }; + OperandValue::Ref(place_val).store(bx, dst); } PassMode::Direct(_) | PassMode::Indirect { meta_attrs: None, .. } From c8a7e6e5e6dff1e42483390e43514b986f635e66 Mon Sep 17 00:00:00 2001 From: Spencer Will Date: Thu, 11 Apr 2024 17:27:55 -0400 Subject: [PATCH 088/892] Remove debug helper. Co-authored-by: Fridtjof Stoldt --- util/gh-pages/script.js | 1 - 1 file changed, 1 deletion(-) diff --git a/util/gh-pages/script.js b/util/gh-pages/script.js index 99868b04492f1..793ddb94f171f 100644 --- a/util/gh-pages/script.js +++ b/util/gh-pages/script.js @@ -285,7 +285,6 @@ }, true); $scope.$watch('applicabilities', function (newVal, oldVal) { - console.log("Test"); if (newVal !== oldVal) { updateURLParameter(newVal, 'applicabilities', APPLICABILITIES_FILTER_DEFAULT) } From 4ea338942b3da2e3bf51d4eae1df39e4bd3d11c7 Mon Sep 17 00:00:00 2001 From: Erik Desjardins Date: Sat, 24 Feb 2024 00:48:20 -0500 Subject: [PATCH 089/892] use [N x i8] for alloca types --- src/builder.rs | 20 ++++---------------- src/intrinsic/mod.rs | 2 +- src/intrinsic/simd.rs | 4 ++-- 3 files changed, 7 insertions(+), 19 deletions(-) diff --git a/src/builder.rs b/src/builder.rs index 43cc46cfe682f..cf1aa3f479347 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -898,26 +898,14 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { self.gcc_checked_binop(oop, typ, lhs, rhs) } - fn alloca(&mut self, ty: Type<'gcc>, align: Align) -> RValue<'gcc> { - // FIXME(antoyo): this check that we don't call get_aligned() a second time on a type. - // Ideally, we shouldn't need to do this check. - let aligned_type = if ty == self.cx.u128_type || ty == self.cx.i128_type { - ty - } else { - ty.get_aligned(align.bytes()) - }; + fn alloca(&mut self, size: Size, align: Align) -> RValue<'gcc> { + let ty = self.cx.type_array(self.cx.type_i8(), size.bytes()).get_aligned(align.bytes()); // TODO(antoyo): It might be better to return a LValue, but fixing the rustc API is non-trivial. self.stack_var_count.set(self.stack_var_count.get() + 1); - self.current_func() - .new_local( - self.location, - aligned_type, - &format!("stack_var_{}", self.stack_var_count.get()), - ) - .get_address(self.location) + self.current_func().new_local(None, ty, &format!("stack_var_{}", self.stack_var_count.get())).get_address(None) } - fn byte_array_alloca(&mut self, _len: RValue<'gcc>, _align: Align) -> RValue<'gcc> { + fn dynamic_alloca(&mut self, _len: RValue<'gcc>, _align: Align) -> RValue<'gcc> { unimplemented!(); } diff --git a/src/intrinsic/mod.rs b/src/intrinsic/mod.rs index cebd45c09aa39..0c50b2bb5fe48 100644 --- a/src/intrinsic/mod.rs +++ b/src/intrinsic/mod.rs @@ -531,7 +531,7 @@ impl<'gcc, 'tcx> ArgAbiExt<'gcc, 'tcx> for ArgAbi<'tcx, Ty<'tcx>> { // We instead thus allocate some scratch space... let scratch_size = cast.size(bx); let scratch_align = cast.align(bx); - let llscratch = bx.alloca(cast.gcc_type(bx), scratch_align); + let llscratch = bx.alloca(scratch_size, scratch_align); bx.lifetime_start(llscratch, scratch_size); // ... where we first store the value... diff --git a/src/intrinsic/simd.rs b/src/intrinsic/simd.rs index 60361a44c2d74..1d9ff257a76fa 100644 --- a/src/intrinsic/simd.rs +++ b/src/intrinsic/simd.rs @@ -18,7 +18,7 @@ use rustc_middle::span_bug; use rustc_middle::ty::layout::HasTyCtxt; use rustc_middle::ty::{self, Ty}; use rustc_span::{sym, Span, Symbol}; -use rustc_target::abi::Align; +use rustc_target::abi::{Align, Size}; use crate::builder::Builder; #[cfg(not(feature = "master"))] @@ -558,7 +558,7 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( let ze = bx.zext(result, bx.type_ix(expected_bytes * 8)); // Convert the integer to a byte array - let ptr = bx.alloca(bx.type_ix(expected_bytes * 8), Align::ONE); + let ptr = bx.alloca(Size::from_bytes(expected_bytes), Align::ONE); bx.store(ze, ptr, Align::ONE); let array_ty = bx.type_array(bx.type_i8(), expected_bytes); let ptr = bx.pointercast(ptr, bx.cx.type_ptr_to(array_ty)); From 50a147152d2bacf6b7c7e3fdccdf302a131b851d Mon Sep 17 00:00:00 2001 From: Erik Desjardins Date: Fri, 12 Apr 2024 08:29:06 -0400 Subject: [PATCH 090/892] restore location in gcc alloca codegen --- src/builder.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/builder.rs b/src/builder.rs index cf1aa3f479347..8d6c16ebe0457 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -902,7 +902,13 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { let ty = self.cx.type_array(self.cx.type_i8(), size.bytes()).get_aligned(align.bytes()); // TODO(antoyo): It might be better to return a LValue, but fixing the rustc API is non-trivial. self.stack_var_count.set(self.stack_var_count.get() + 1); - self.current_func().new_local(None, ty, &format!("stack_var_{}", self.stack_var_count.get())).get_address(None) + self.current_func() + .new_local( + self.location, + ty, + &format!("stack_var_{}", self.stack_var_count.get()), + ) + .get_address(self.location) } fn dynamic_alloca(&mut self, _len: RValue<'gcc>, _align: Align) -> RValue<'gcc> { From a3cd6e7a31bee1e807855a64052dc2b9a0e71f40 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 13 Apr 2024 21:31:57 +0200 Subject: [PATCH 091/892] Default to `download-gccjit` instead of `gcc-path` --- config.example.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/config.example.toml b/config.example.toml index dcc414b731001..890387dc24266 100644 --- a/config.example.toml +++ b/config.example.toml @@ -1,2 +1,2 @@ -gcc-path = "gcc-build/gcc" -# download-gccjit = true +#gcc-path = "gcc-build/gcc" +download-gccjit = true From 6f36e825946ef7f0938fa2a1bcb3fcd5321c4a18 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 15 Apr 2024 17:45:04 +0200 Subject: [PATCH 092/892] static_mut_refs: use raw pointers to remove the remaining FIXME --- example/mini_core_hello_world.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/example/mini_core_hello_world.rs b/example/mini_core_hello_world.rs index add77880716c8..5a7ddc4cd7fa5 100644 --- a/example/mini_core_hello_world.rs +++ b/example/mini_core_hello_world.rs @@ -2,7 +2,7 @@ #![feature( no_core, unboxed_closures, start, lang_items, never_type, linkage, - extern_types, thread_local + extern_types, thread_local, raw_ref_op )] #![no_core] #![allow(dead_code, internal_features, non_camel_case_types)] @@ -99,9 +99,7 @@ fn start( static mut NUM: u8 = 6 * 7; -// FIXME: Use `SyncUnsafeCell` instead of allowing `static_mut_refs` lint -#[allow(static_mut_refs)] -static NUM_REF: &'static u8 = unsafe { &NUM }; +static NUM_REF: &'static u8 = unsafe { &* &raw const NUM }; macro_rules! assert { ($e:expr) => { From 5584f5f1a22aceb3d686cfa1165c6d160c994586 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=82=A2=E3=83=AC=E3=83=BC=E3=82=AF?= Date: Tue, 16 Apr 2024 22:59:47 +0100 Subject: [PATCH 093/892] updated build system script commands (#490) updated build system script commands --- build_system/src/build.rs | 4 +++- build_system/src/main.rs | 25 +++++++++++++++---------- 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/build_system/src/build.rs b/build_system/src/build.rs index 6313e4ffccb97..92f4b890e3482 100644 --- a/build_system/src/build.rs +++ b/build_system/src/build.rs @@ -14,9 +14,10 @@ struct BuildArg { } impl BuildArg { + /// Creates a new `BuildArg` instance by parsing command-line arguments. fn new() -> Result, String> { let mut build_arg = Self::default(); - // We skip binary name and the `build` command. + // Skip binary name and the `build` command. let mut args = std::env::args().skip(2); while let Some(arg) = args.next() { @@ -211,6 +212,7 @@ fn build_codegen(args: &mut BuildArg) -> Result<(), String> { Ok(()) } +/// Executes the build process. pub fn run() -> Result<(), String> { let mut args = match BuildArg::new()? { Some(args) => args, diff --git a/build_system/src/main.rs b/build_system/src/main.rs index 1bfba0f9828e6..9a30490f62157 100644 --- a/build_system/src/main.rs +++ b/build_system/src/main.rs @@ -26,17 +26,22 @@ macro_rules! arg_error { fn usage() { println!( "\ -Available commands for build_system: +rustc_codegen_gcc build system - cargo : Run cargo command - rustc : Run rustc command - clean : Run clean command - prepare : Run prepare command - build : Run build command - test : Run test command - info : Run info command - clone-gcc : Run clone-gcc command - --help : Show this message" +Usage: build_system [command] [options] + +Options: + --help : Displays this help message. + +Commands: + 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. + 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 50a0d5b8166f927142288ba0ce5ca0bbe250923a Mon Sep 17 00:00:00 2001 From: darc Date: Wed, 17 Apr 2024 10:02:10 -0500 Subject: [PATCH 094/892] Fix passing custom CG_RUSTFLAGS when building sysroot --- build_system/src/build.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/build_system/src/build.rs b/build_system/src/build.rs index 2ae325c6c0067..a17adb3cd06a9 100644 --- a/build_system/src/build.rs +++ b/build_system/src/build.rs @@ -153,6 +153,11 @@ pub fn build_sysroot(env: &HashMap, config: &ConfigInfo) -> Resu "debug" }; + if let Ok(cg_rustflags) = std::env::var("CG_RUSTFLAGS") { + rustflags.push(' '); + rustflags.push_str(&cg_rustflags); + } + let mut env = env.clone(); env.insert("RUSTFLAGS".to_string(), rustflags); run_command_with_output_and_env(&args, Some(&start_dir), Some(&env))?; From 6e5395a4147f50c95b3f5952fcb62648a124cb88 Mon Sep 17 00:00:00 2001 From: Gerson <71728860+Gerson2102@users.noreply.github.com> Date: Wed, 17 Apr 2024 09:31:18 -0600 Subject: [PATCH 095/892] Updating readme instructions (#489) --- Readme.md | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/Readme.md b/Readme.md index 1599977014504..607a16cc20975 100644 --- a/Readme.md +++ b/Readme.md @@ -12,6 +12,10 @@ This is a GCC codegen for rustc, which means it can be loaded by the existing ru The primary goal of this project is to be able to compile Rust code on platforms unsupported by LLVM. A secondary goal is to check if using the gcc backend will provide any run-time speed improvement for the programs compiled using rustc. +### Dependencies + +**rustup:** Follow the instructions on the official [website](https://www.rust-lang.org/tools/install) + ## Building **This requires a patched libgccjit in order to work. @@ -91,10 +95,16 @@ $ ./y.sh test --release ## Usage -`$CG_GCCJIT_DIR` is the directory you cloned this repo into in the following instructions: +You have to run these commands, in the corresponding order: ```bash -export CG_GCCJIT_DIR=[the full path to rustc_codegen_gcc] +$ ./y.sh prepare +$ ./y.sh build --sysroot +``` +To check if all is working correctly, run: + + ```bash +$ ./y.sh cargo build --manifest-path tests/hello-world/Cargo.toml ``` ### Cargo From 356027b7097abb90538a5794da30af16326518d9 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?= Date: Wed, 17 Apr 2024 19:21:11 +0000 Subject: [PATCH 096/892] ast_passes/validation: update module docs - Syntax extensions are replaced by proc macros. - Add rationale for why AST validation pass need to be run post-expansion and why the pass is needed in the first place. --- compiler/rustc_ast_passes/src/ast_validation.rs | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index 495e90e967b93..0592837e42caa 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -1,10 +1,13 @@ -// Validate AST before lowering it to HIR. -// -// This pass is supposed to catch things that fit into AST data structures, -// but not permitted by the language. It runs after expansion when AST is frozen, -// so it can check for erroneous constructions produced by syntax extensions. -// This pass is supposed to perform only simple checks not requiring name resolution -// or type checking or some other kind of complex analysis. +//! Validate AST before lowering it to HIR. +//! +//! This pass intends to check that the constructed AST is *syntactically valid* to allow the rest +//! of the compiler to assume that the AST is valid. These checks cannot be performed during parsing +//! because attribute macros are allowed to accept certain pieces of invalid syntax such as `async +//! fn` within a trait (before async-fn-in-trait was introduced). +//! +//! These checks are run post-expansion, after AST is frozen, to be able to check for erroneous +//! constructions produced by proc macros. This pass is only intended for simple checks that do not +//! require name resolution or type checking, or other kinds of complex analysis. use itertools::{Either, Itertools}; use rustc_ast::ptr::P; From 0e3521605dff967199347565dde4d4daeb36fe6d 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?= Date: Wed, 17 Apr 2024 19:37:27 +0000 Subject: [PATCH 097/892] ast_passes/validation: update attribute macro example --- compiler/rustc_ast_passes/src/ast_validation.rs | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index 0592837e42caa..eadfd3b98e24a 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -2,8 +2,15 @@ //! //! This pass intends to check that the constructed AST is *syntactically valid* to allow the rest //! of the compiler to assume that the AST is valid. These checks cannot be performed during parsing -//! because attribute macros are allowed to accept certain pieces of invalid syntax such as `async -//! fn` within a trait (before async-fn-in-trait was introduced). +//! because attribute macros are allowed to accept certain pieces of invalid syntax such as a +//! function without body outside of a trait definition: +//! +//! ```ignore (illustrative) +//! #[my_attribute] +//! mod foo { +//! fn missing_body(); +//! } +//! ``` //! //! These checks are run post-expansion, after AST is frozen, to be able to check for erroneous //! constructions produced by proc macros. This pass is only intended for simple checks that do not From 0a298ed00bcd1c134ca60c0c81f1192dc5f5b8d1 Mon Sep 17 00:00:00 2001 From: Michael Baikov Date: Sat, 6 Apr 2024 11:22:21 -0400 Subject: [PATCH 098/892] Show files produced by --emit foo in json artifact notifications --- src/driver/aot.rs | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/driver/aot.rs b/src/driver/aot.rs index e8c96486041b1..aff9448a89c30 100644 --- a/src/driver/aot.rs +++ b/src/driver/aot.rs @@ -287,6 +287,29 @@ fn produce_final_output_artifacts( } } + if sess.opts.json_artifact_notifications { + if codegen_results.modules.len() == 1 { + codegen_results.modules[0].for_each_output(|_path, ty| { + if sess.opts.output_types.contains_key(&ty) { + let descr = ty.shorthand(); + // for single cgu file is renamed to drop cgu specific suffix + // so we regenerate it the same way + let path = crate_output.path(ty); + sess.dcx().emit_artifact_notification(path.as_path(), descr); + } + }); + } else { + for module in &codegen_results.modules { + module.for_each_output(|path, ty| { + if sess.opts.output_types.contains_key(&ty) { + let descr = ty.shorthand(); + sess.dcx().emit_artifact_notification(&path, descr); + } + }); + } + } + } + // We leave the following files around by default: // - #crate#.o // - #crate#.crate.metadata.o From 7cd561efd6e8097bb9075dbf05a2cd8d37696cb8 Mon Sep 17 00:00:00 2001 From: Antoni Boucher Date: Fri, 19 Apr 2024 20:55:59 -0400 Subject: [PATCH 099/892] Fix check for main function already declared --- src/context.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/context.rs b/src/context.rs index 1b9cfd3652c81..d37fa7833fcc5 100644 --- a/src/context.rs +++ b/src/context.rs @@ -526,7 +526,7 @@ impl<'gcc, 'tcx> MiscMethods<'tcx> for CodegenCx<'gcc, 'tcx> { fn declare_c_main(&self, fn_type: Self::Type) -> Option { let entry_name = self.sess().target.entry_name.as_ref(); - if self.get_declared_value(entry_name).is_none() { + if !self.functions.borrow().contains_key(entry_name) { Some(self.declare_entry_fn(entry_name, fn_type, ())) } else { // If the symbol already exists, it is an error: for example, the user wrote From 9b628f8e82dfb02bf6870624eb4acdca7a20947e Mon Sep 17 00:00:00 2001 From: Antoni Boucher Date: Fri, 19 Apr 2024 20:57:40 -0400 Subject: [PATCH 100/892] Fix panic when calling get_fn for a variable --- src/context.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/context.rs b/src/context.rs index 1b9cfd3652c81..d04c7532b3ccc 100644 --- a/src/context.rs +++ b/src/context.rs @@ -432,6 +432,8 @@ impl<'gcc, 'tcx> MiscMethods<'tcx> for CodegenCx<'gcc, 'tcx> { let func = if self.intrinsics.borrow().contains_key(func_name) { self.intrinsics.borrow()[func_name] + } else if let Some(variable) = self.get_declared_value(func_name) { + return variable; } else { get_fn(self, instance) }; From 89ee0f997c8c30081e819e9b101d54befb038163 Mon Sep 17 00:00:00 2001 From: Antoni Boucher Date: Fri, 19 Apr 2024 20:58:35 -0400 Subject: [PATCH 101/892] Implement more type kinds --- src/type_.rs | 12 +++++++++++- tests/failing-ui-tests.txt | 1 - 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/type_.rs b/src/type_.rs index 8fe3328ec55f6..d0d3c21f0cf09 100644 --- a/src/type_.rs +++ b/src/type_.rs @@ -170,9 +170,19 @@ impl<'gcc, 'tcx> BaseTypeMethods<'tcx> for CodegenCx<'gcc, 'tcx> { TypeKind::Double } else if typ.is_vector() { TypeKind::Vector + } else if typ.get_pointee().is_some() { + TypeKind::Pointer + } else if typ.dyncast_array().is_some() { + TypeKind::Array + } else if typ.is_struct().is_some() { + TypeKind::Struct + } else if typ.dyncast_function_ptr_type().is_some() { + TypeKind::Function + } else if typ == self.type_void() { + TypeKind::Void } else { // TODO(antoyo): support other types. - TypeKind::Void + unimplemented!(); } } diff --git a/tests/failing-ui-tests.txt b/tests/failing-ui-tests.txt index 0b749918a3a7a..5df9381ecc77a 100644 --- a/tests/failing-ui-tests.txt +++ b/tests/failing-ui-tests.txt @@ -36,7 +36,6 @@ tests/ui/parser/unclosed-delimiter-in-dep.rs tests/ui/simd/intrinsic/ptr-cast.rs tests/ui/consts/missing_span_in_backtrace.rs tests/ui/drop/dynamic-drop.rs -tests/ui/dyn-star/box.rs tests/ui/issues/issue-40883.rs tests/ui/issues/issue-43853.rs tests/ui/issues/issue-47364.rs From dd50f454c8090c65ee6c551facf8d3dbf0de79c9 Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Sat, 20 Apr 2024 03:22:54 +0000 Subject: [PATCH 102/892] Fixup `rustc_codegen_gcc` test signature --- example/example.rs | 7 ++++--- example/mini_core.rs | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/example/example.rs b/example/example.rs index 5878e8548d926..7c21b73b630e8 100644 --- a/example/example.rs +++ b/example/example.rs @@ -153,9 +153,10 @@ fn array_as_slice(arr: &[u8; 3]) -> &[u8] { arr } -unsafe fn use_ctlz_nonzero(a: u16) -> u16 { - intrinsics::ctlz_nonzero(a) -} +// FIXME: fix the intrinsic implementation to work with the new ->u32 signature +// unsafe fn use_ctlz_nonzero(a: u16) -> u32 { +// intrinsics::ctlz_nonzero(a) +// } fn ptr_as_usize(ptr: *const u8) -> usize { ptr as usize diff --git a/example/mini_core.rs b/example/mini_core.rs index 4665009e191e6..8ffa66a489464 100644 --- a/example/mini_core.rs +++ b/example/mini_core.rs @@ -593,7 +593,7 @@ pub mod intrinsics { pub fn min_align_of_val(val: *const T) -> usize; pub fn copy(src: *const T, dst: *mut T, count: usize); pub fn transmute(e: T) -> U; - pub fn ctlz_nonzero(x: T) -> T; + pub fn ctlz_nonzero(x: T) -> u32; #[rustc_safe_intrinsic] pub fn needs_drop() -> bool; #[rustc_safe_intrinsic] From f9a0c3fb0f6e555358236affbd969a35dbe28ac9 Mon Sep 17 00:00:00 2001 From: Antoni Boucher Date: Fri, 19 Apr 2024 20:56:23 -0400 Subject: [PATCH 103/892] Fix PassMode::Indirect with params --- src/abi.rs | 15 ++++++++++++--- tests/failing-ui-tests.txt | 2 -- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/abi.rs b/src/abi.rs index b098594dbcc35..166dd080cf209 100644 --- a/src/abi.rs +++ b/src/abi.rs @@ -4,6 +4,7 @@ use gccjit::{ToLValue, ToRValue, Type}; use rustc_codegen_ssa::traits::{AbiBuilderMethods, BaseTypeMethods}; use rustc_data_structures::fx::FxHashSet; use rustc_middle::bug; +use rustc_middle::ty::layout::LayoutOf; use rustc_middle::ty::Ty; #[cfg(feature = "master")] use rustc_session::config; @@ -184,9 +185,17 @@ impl<'gcc, 'tcx> FnAbiGccExt<'gcc, 'tcx> for FnAbi<'tcx, Ty<'tcx>> { } PassMode::Indirect { attrs, meta_attrs: Some(meta_attrs), on_stack } => { assert!(!on_stack); - let ty = - apply_attrs(cx.type_ptr_to(arg.memory_ty(cx)), &attrs, argument_tys.len()); - apply_attrs(ty, &meta_attrs, argument_tys.len()) + // Construct the type of a (wide) pointer to `ty`, and pass its two fields. + // Any two ABI-compatible unsized types have the same metadata type and + // moreover the same metadata value leads to the same dynamic size and + // alignment, so this respects ABI compatibility. + let ptr_ty = Ty::new_mut_ptr(cx.tcx, arg.layout.ty); + let ptr_layout = cx.layout_of(ptr_ty); + let typ1 = ptr_layout.scalar_pair_element_gcc_type(cx, 0); + let typ2 = ptr_layout.scalar_pair_element_gcc_type(cx, 1); + argument_tys.push(apply_attrs(typ1, &attrs, argument_tys.len())); + argument_tys.push(apply_attrs(typ2, &meta_attrs, argument_tys.len())); + continue; } }; argument_tys.push(arg_ty); diff --git a/tests/failing-ui-tests.txt b/tests/failing-ui-tests.txt index 0b749918a3a7a..31d742183b4fa 100644 --- a/tests/failing-ui-tests.txt +++ b/tests/failing-ui-tests.txt @@ -50,7 +50,6 @@ tests/ui/coroutine/panic-safe.rs tests/ui/issues/issue-14875.rs tests/ui/issues/issue-29948.rs tests/ui/panics/nested_panic_caught.rs -tests/ui/const_prop/ice-issue-111353.rs tests/ui/process/println-with-broken-pipe.rs tests/ui/lto/thin-lto-inlines2.rs tests/ui/lto/weak-works.rs @@ -61,7 +60,6 @@ tests/ui/lto/msvc-imp-present.rs tests/ui/lto/lto-thin-rustc-loads-linker-plugin.rs tests/ui/lto/all-crates.rs tests/ui/async-await/deep-futures-are-freeze.rs -tests/ui/closures/capture-unsized-by-ref.rs tests/ui/coroutine/resume-after-return.rs tests/ui/simd/masked-load-store.rs tests/ui/simd/repr_packed.rs From 2d082aedf73cfa457c726716829871820c9bb9d9 Mon Sep 17 00:00:00 2001 From: Ben Kimock Date: Wed, 3 Apr 2024 14:09:21 -0400 Subject: [PATCH 104/892] Stabilize the size of incr comp object file names --- src/context.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/context.rs b/src/context.rs index 16a85b4e8fa09..4a1f5188a8013 100644 --- a/src/context.rs +++ b/src/context.rs @@ -6,7 +6,8 @@ use gccjit::{ use rustc_codegen_ssa::base::wants_msvc_seh; use rustc_codegen_ssa::errors as ssa_errors; use rustc_codegen_ssa::traits::{BackendTypes, BaseTypeMethods, MiscMethods}; -use rustc_data_structures::base_n; +use rustc_data_structures::base_n::ToBaseN; +use rustc_data_structures::base_n::ALPHANUMERIC_ONLY; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_middle::mir::mono::CodegenUnit; use rustc_middle::span_bug; @@ -621,7 +622,7 @@ impl<'b, 'tcx> CodegenCx<'b, 'tcx> { let mut name = String::with_capacity(prefix.len() + 6); name.push_str(prefix); name.push_str("."); - base_n::push_str(idx as u128, base_n::ALPHANUMERIC_ONLY, &mut name); + name.push_str(&(idx as u64).to_base(ALPHANUMERIC_ONLY)); name } } From df0639b6e12c98dc736acf81b9eccaf862ecc362 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Thu, 11 Apr 2024 13:15:34 +0000 Subject: [PATCH 105/892] Error on using `yield` without also using `#[coroutine]` on the closure And suggest adding the `#[coroutine]` to the closure --- example/std_example.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/example/std_example.rs b/example/std_example.rs index ad69409eb6590..8ab8fcc525e5c 100644 --- a/example/std_example.rs +++ b/example/std_example.rs @@ -1,5 +1,5 @@ #![allow(internal_features)] -#![feature(core_intrinsics, coroutines, coroutine_trait, is_sorted)] +#![feature(core_intrinsics, coroutines, coroutine_trait, is_sorted, stmt_expr_attributes)] #[cfg(feature="master")] #[cfg(target_arch="x86_64")] @@ -103,7 +103,7 @@ fn main() { test_simd(); } - Box::pin(move |mut _task_context| { + Box::pin(#[coroutine] move |mut _task_context| { yield (); }).as_mut().resume(0); From 04932ea22f51c6b4ed31463a5a6f4243f6b1b1e7 Mon Sep 17 00:00:00 2001 From: darc Date: Wed, 17 Apr 2024 15:21:55 -0500 Subject: [PATCH 106/892] Modify build_system's prepare stage to allow for custom sysroot source path --- build_system/src/prepare.rs | 66 +++++++++++++++++++++++++++---------- doc/tips.md | 8 +++++ 2 files changed, 56 insertions(+), 18 deletions(-) diff --git a/build_system/src/prepare.rs b/build_system/src/prepare.rs index 9f405daa68762..a085d86361672 100644 --- a/build_system/src/prepare.rs +++ b/build_system/src/prepare.rs @@ -5,29 +5,41 @@ use crate::utils::{ }; use std::fs; -use std::path::Path; +use std::path::{Path, PathBuf}; fn prepare_libcore( sysroot_path: &Path, libgccjit12_patches: bool, cross_compile: bool, + sysroot_source: Option, ) -> Result<(), String> { - let rustc_path = match get_rustc_path() { - Some(path) => path, - None => return Err("`rustc` path not found".to_string()), - }; + let rustlib_dir: PathBuf; - let parent = match rustc_path.parent() { - Some(path) => path, - None => return Err(format!("No parent for `{}`", rustc_path.display())), - }; + if let Some(path) = sysroot_source { + rustlib_dir = Path::new(&path) + .canonicalize() + .map_err(|error| format!("Failed to canonicalize path: {:?}", error))?; + if !rustlib_dir.is_dir() { + return Err(format!("Custom sysroot path {:?} not found", rustlib_dir)); + } + } else { + let rustc_path = match get_rustc_path() { + Some(path) => path, + None => return Err("`rustc` path not found".to_string()), + }; + + let parent = match rustc_path.parent() { + Some(path) => path, + None => return Err(format!("No parent for `{}`", rustc_path.display())), + }; - let rustlib_dir = parent - .join("../lib/rustlib/src/rust") - .canonicalize() - .map_err(|error| format!("Failed to canonicalize path: {:?}", error))?; - if !rustlib_dir.is_dir() { - return Err("Please install `rust-src` component".to_string()); + rustlib_dir = parent + .join("../lib/rustlib/src/rust") + .canonicalize() + .map_err(|error| format!("Failed to canonicalize path: {:?}", error))?; + if !rustlib_dir.is_dir() { + return Err("Please install `rust-src` component".to_string()); + } } let sysroot_dir = sysroot_path.join("sysroot_src"); @@ -151,6 +163,7 @@ struct PrepareArg { cross_compile: bool, only_libcore: bool, libgccjit12_patches: bool, + sysroot_source: Option, } impl PrepareArg { @@ -158,12 +171,23 @@ impl PrepareArg { let mut only_libcore = false; let mut cross_compile = false; let mut libgccjit12_patches = false; + let mut sysroot_source = None; - for arg in std::env::args().skip(2) { + let mut args = std::env::args().skip(2); + while let Some(arg) = args.next() { match arg.as_str() { "--only-libcore" => only_libcore = true, "--cross" => cross_compile = true, "--libgccjit12-patches" => libgccjit12_patches = true, + "--sysroot-source" => { + if let Some(path) = args.next() { + sysroot_source = Some(path); + } else { + return Err( + "Expected a value after `--sysroot-source`, found nothing".to_string() + ); + } + } "--help" => { Self::usage(); return Ok(None); @@ -171,7 +195,7 @@ impl PrepareArg { a => return Err(format!("Unknown argument `{a}`")), } } - Ok(Some(Self { cross_compile, only_libcore, libgccjit12_patches })) + Ok(Some(Self { cross_compile, only_libcore, libgccjit12_patches, sysroot_source })) } fn usage() { @@ -182,6 +206,7 @@ impl PrepareArg { --only-libcore : Only setup libcore and don't clone other repositories --cross : Apply the patches needed to do cross-compilation --libgccjit12-patches : Apply patches needed for libgccjit12 + --sysroot-source : Specify custom path for sysroot source --help : Show this help"# ) } @@ -193,7 +218,12 @@ pub fn run() -> Result<(), String> { None => return Ok(()), }; let sysroot_path = get_sysroot_dir(); - prepare_libcore(&sysroot_path, args.libgccjit12_patches, args.cross_compile)?; + prepare_libcore( + &sysroot_path, + args.libgccjit12_patches, + args.cross_compile, + args.sysroot_source, + )?; if !args.only_libcore { cargo_install("hyperfine")?; diff --git a/doc/tips.md b/doc/tips.md index 6cc81871d0267..86c22db186e01 100644 --- a/doc/tips.md +++ b/doc/tips.md @@ -35,6 +35,14 @@ COLLECT_NO_DEMANGLE=1 * Build the stage2 compiler (`rustup toolchain link debug-current build/x86_64-unknown-linux-gnu/stage2`). * Clean and rebuild the codegen with `debug-current` in the file `rust-toolchain`. +### How to use a custom sysroot source path + +If you wish to build a custom sysroot, pass the path of your sysroot source to `--sysroot-source` during the `prepare` step, like so: + +``` +./y.sh prepare --sysroot-source /path/to/custom/source +``` + ### How to use [mem-trace](https://github.com/antoyo/mem-trace) `rustc` needs to be built without `jemalloc` so that `mem-trace` can overload `malloc` since `jemalloc` is linked statically, so a `LD_PRELOAD`-ed library won't a chance to intercept the calls to `malloc`. From 65e8717e4559bdfd30a0c6a05eb7f1241f53221e Mon Sep 17 00:00:00 2001 From: Antoni Boucher Date: Wed, 24 Apr 2024 20:01:57 -0400 Subject: [PATCH 107/892] Some fixes for aarch64 --- src/attributes.rs | 8 +++++++- src/builder.rs | 2 +- src/intrinsic/llvm.rs | 22 +++++++++++++++------- 3 files changed, 23 insertions(+), 9 deletions(-) diff --git a/src/attributes.rs b/src/attributes.rs index 2ce0c83008f16..27f21107eda70 100644 --- a/src/attributes.rs +++ b/src/attributes.rs @@ -128,6 +128,12 @@ pub fn from_fn_attrs<'gcc, 'tcx>( .join(","); if !target_features.is_empty() { #[cfg(feature = "master")] - func.add_attribute(FnAttribute::Target(&target_features)); + match cx.sess().target.arch.as_ref() { + "x86" | "x86_64" | "powerpc" => { + func.add_attribute(FnAttribute::Target(&target_features)) + } + // The target attribute is not supported on other targets in GCC. + _ => (), + } } } diff --git a/src/builder.rs b/src/builder.rs index 385ca7a44a7d2..e9c16a0e4a71f 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -1129,7 +1129,7 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { // the following cast is required to avoid this error: // gcc_jit_context_new_call: mismatching types for argument 2 of function "__atomic_store_4": assignment to param arg1 (type: int) from loadedValue3577 (type: unsigned int __attribute__((aligned(4)))) let int_type = atomic_store.get_param(1).to_rvalue().get_type(); - let value = self.context.new_cast(self.location, value, int_type); + let value = self.context.new_bitcast(self.location, value, int_type); self.llbb().add_eval( self.location, self.context.new_call(self.location, atomic_store, &[ptr, value, ordering]), diff --git a/src/intrinsic/llvm.rs b/src/intrinsic/llvm.rs index c845ee5fe5fd6..a127048221901 100644 --- a/src/intrinsic/llvm.rs +++ b/src/intrinsic/llvm.rs @@ -629,14 +629,22 @@ pub fn intrinsic<'gcc, 'tcx>(name: &str, cx: &CodegenCx<'gcc, 'tcx>) -> Function #[cfg(feature = "master")] pub fn intrinsic<'gcc, 'tcx>(name: &str, cx: &CodegenCx<'gcc, 'tcx>) -> Function<'gcc> { - if name == "llvm.prefetch" { - let gcc_name = "__builtin_prefetch"; - let func = cx.context.get_builtin_function(gcc_name); - cx.functions.borrow_mut().insert(gcc_name.to_string(), func); - return func; - } - let gcc_name = match name { + "llvm.prefetch" => { + let gcc_name = "__builtin_prefetch"; + let func = cx.context.get_builtin_function(gcc_name); + cx.functions.borrow_mut().insert(gcc_name.to_string(), func); + return func; + } + + "llvm.aarch64.isb" => { + // FIXME: GCC doesn't support __builtin_arm_isb yet, check if this builtin is OK. + let gcc_name = "__atomic_thread_fence"; + let func = cx.context.get_builtin_function(gcc_name); + cx.functions.borrow_mut().insert(gcc_name.to_string(), func); + return func; + } + "llvm.x86.xgetbv" => "__builtin_ia32_xgetbv", // NOTE: this doc specifies the equivalent GCC builtins: http://huonw.github.io/llvmint/llvmint/x86/index.html "llvm.sqrt.v2f64" => "__builtin_ia32_sqrtpd", From 4267ff065675a63f6bb32ee18148ac05b3b256b8 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 26 Apr 2024 14:02:19 +0200 Subject: [PATCH 108/892] Download artifacts from `rust-lang/gcc` instead of old `antoyo/gcc` --- .github/workflows/ci.yml | 2 +- .github/workflows/failures.yml | 2 +- .github/workflows/release.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 69a0707c1f2a1..835e055e8c586 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -53,7 +53,7 @@ jobs: run: rustup component add rustfmt clippy - name: Download artifact - run: curl -LO https://github.com/antoyo/gcc/releases/latest/download/${{ matrix.libgccjit_version.gcc }} + run: curl -LO https://github.com/rust-lang/gcc/releases/latest/download/${{ matrix.libgccjit_version.gcc }} - name: Setup path to libgccjit run: | diff --git a/.github/workflows/failures.yml b/.github/workflows/failures.yml index 2bca694e83284..9fa6f416c141e 100644 --- a/.github/workflows/failures.yml +++ b/.github/workflows/failures.yml @@ -56,7 +56,7 @@ jobs: - name: Download artifact if: matrix.libgccjit_version.gcc != 'libgccjit12.so' - run: curl -LO https://github.com/antoyo/gcc/releases/latest/download/gcc-13.deb + run: curl -LO https://github.com/rust-lang/gcc/releases/latest/download/gcc-13.deb - name: Setup path to libgccjit if: matrix.libgccjit_version.gcc != 'libgccjit12.so' diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 84394b2957c44..d5242926eb4db 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -37,7 +37,7 @@ jobs: run: sudo apt-get install ninja-build ripgrep - name: Download artifact - run: curl -LO https://github.com/antoyo/gcc/releases/latest/download/gcc-13.deb + run: curl -LO https://github.com/rust-lang/gcc/releases/latest/download/gcc-13.deb - name: Setup path to libgccjit run: | From 9ed0543964e25d57ce2842d99e6b07d72537f8fe Mon Sep 17 00:00:00 2001 From: Antoni Boucher Date: Mon, 29 Apr 2024 11:07:54 -0400 Subject: [PATCH 109/892] Some more fixes and workarounds for Aarch64 --- src/int.rs | 2 +- src/lib.rs | 9 +++++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/int.rs b/src/int.rs index 1b812b4d137f2..b92db7a742467 100644 --- a/src/int.rs +++ b/src/int.rs @@ -926,7 +926,7 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { return self.context.new_cast(None, value, dest_typ); } - debug_assert!(value_type.dyncast_array().is_some()); + debug_assert!(dest_typ.dyncast_array().is_some()); let name_suffix = match self.type_kind(value_type) { TypeKind::Float => "sfti", TypeKind::Double => "dfti", diff --git a/src/lib.rs b/src/lib.rs index 616b1944798cc..af110e3ab5e69 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -468,6 +468,7 @@ pub fn target_features( allow_unstable: bool, target_info: &LockedTargetInfo, ) -> Vec { + // TODO(antoyo): use global_gcc_features. sess.target .supported_target_features() .iter() @@ -478,8 +479,12 @@ pub fn target_features( None } }) - .filter(|_feature| { - target_info.cpu_supports(_feature) + .filter(|feature| { + // TODO: we disable Neon for now since we don't support the LLVM intrinsics for it. + if *feature == "neon" { + return false; + } + target_info.cpu_supports(feature) /* adx, aes, avx, avx2, avx512bf16, avx512bitalg, avx512bw, avx512cd, avx512dq, avx512er, avx512f, avx512fp16, avx512ifma, avx512pf, avx512vbmi, avx512vbmi2, avx512vl, avx512vnni, avx512vp2intersect, avx512vpopcntdq, From 3d90595054e1da5905024098aa15aceb193e5925 Mon Sep 17 00:00:00 2001 From: klensy Date: Tue, 23 Apr 2024 13:17:57 +0300 Subject: [PATCH 110/892] DependencyList: remove outdated comment --- compiler/rustc_middle/src/middle/dependency_format.rs | 3 --- 1 file changed, 3 deletions(-) diff --git a/compiler/rustc_middle/src/middle/dependency_format.rs b/compiler/rustc_middle/src/middle/dependency_format.rs index e7d0cffc85cfb..e4750147456d1 100644 --- a/compiler/rustc_middle/src/middle/dependency_format.rs +++ b/compiler/rustc_middle/src/middle/dependency_format.rs @@ -10,9 +10,6 @@ use rustc_session::config::CrateType; /// A list of dependencies for a certain crate type. /// /// The length of this vector is the same as the number of external crates used. -/// The value is None if the crate does not need to be linked (it was found -/// statically in another dylib), or Some(kind) if it needs to be linked as -/// `kind` (either static or dynamic). pub type DependencyList = Vec; /// A mapping of all required dependencies for a particular flavor of output. From 9e40b546eb6cd75aaca9bacf39f2463e5b5ffe86 Mon Sep 17 00:00:00 2001 From: klensy Date: Tue, 23 Apr 2024 13:34:12 +0300 Subject: [PATCH 111/892] add fixme --- compiler/rustc_middle/src/middle/dependency_format.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/compiler/rustc_middle/src/middle/dependency_format.rs b/compiler/rustc_middle/src/middle/dependency_format.rs index e4750147456d1..a3aff9a110130 100644 --- a/compiler/rustc_middle/src/middle/dependency_format.rs +++ b/compiler/rustc_middle/src/middle/dependency_format.rs @@ -4,6 +4,9 @@ //! For all the gory details, see the provider of the `dependency_formats` //! query. +// FIXME: move this file to rustc_metadata::dependency_format, but +// this will introduce circular dependency between rustc_metadata and rustc_middle + use rustc_macros::{Decodable, Encodable, HashStable}; use rustc_session::config::CrateType; From 766f59d7f212e7efaa1c316ecc99b8af0d0e7c66 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 30 Apr 2024 22:07:48 +0200 Subject: [PATCH 112/892] Stop swallowing signals in build_system when running sub-commands --- build_system/src/utils.rs | 50 +++++++++++++++++++++++++++------------ 1 file changed, 35 insertions(+), 15 deletions(-) diff --git a/build_system/src/utils.rs b/build_system/src/utils.rs index 45a3ac81b44d4..cdda9d4a81e6b 100644 --- a/build_system/src/utils.rs +++ b/build_system/src/utils.rs @@ -1,10 +1,42 @@ use std::collections::HashMap; +#[cfg(unix)] +use std::ffi::c_int; use std::ffi::OsStr; use std::fmt::Debug; use std::fs; +#[cfg(unix)] +use std::os::unix::process::ExitStatusExt; use std::path::{Path, PathBuf}; use std::process::{Command, ExitStatus, Output}; +#[cfg(unix)] +extern "C" { + fn raise(signal: c_int) -> c_int; +} + +fn exec_command( + input: &[&dyn AsRef], + cwd: Option<&Path>, + env: Option<&HashMap>, +) -> Result { + let status = get_command_inner(input, cwd, env) + .spawn() + .map_err(|e| command_error(input, &cwd, e))? + .wait() + .map_err(|e| command_error(input, &cwd, e))?; + #[cfg(unix)] + { + if let Some(signal) = status.signal() { + unsafe { + raise(signal as _); + } + // In case the signal didn't kill the current process. + return Err(command_error(input, &cwd, format!("Process received signal {}", signal))); + } + } + Ok(status) +} + fn get_command_inner( input: &[&dyn AsRef], cwd: Option<&Path>, @@ -89,11 +121,7 @@ pub fn run_command_with_output( input: &[&dyn AsRef], cwd: Option<&Path>, ) -> Result<(), String> { - let exit_status = get_command_inner(input, cwd, None) - .spawn() - .map_err(|e| command_error(input, &cwd, e))? - .wait() - .map_err(|e| command_error(input, &cwd, e))?; + let exit_status = exec_command(input, cwd, None)?; check_exit_status(input, cwd, exit_status, None, true)?; Ok(()) } @@ -103,11 +131,7 @@ pub fn run_command_with_output_and_env( cwd: Option<&Path>, env: Option<&HashMap>, ) -> Result<(), String> { - let exit_status = get_command_inner(input, cwd, env) - .spawn() - .map_err(|e| command_error(input, &cwd, e))? - .wait() - .map_err(|e| command_error(input, &cwd, e))?; + let exit_status = exec_command(input, cwd, env)?; check_exit_status(input, cwd, exit_status, None, true)?; Ok(()) } @@ -117,11 +141,7 @@ pub fn run_command_with_output_and_env_no_err( cwd: Option<&Path>, env: Option<&HashMap>, ) -> Result<(), String> { - let exit_status = get_command_inner(input, cwd, env) - .spawn() - .map_err(|e| command_error(input, &cwd, e))? - .wait() - .map_err(|e| command_error(input, &cwd, e))?; + let exit_status = exec_command(input, cwd, env)?; check_exit_status(input, cwd, exit_status, None, false)?; Ok(()) } From 2b875f09274c97df5f4d34cac98ad48cf5ce7bbc Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Mon, 29 Apr 2024 09:27:34 -0400 Subject: [PATCH 113/892] Step bootstrap cfgs --- example/mini_core.rs | 1 - src/lib.rs | 1 - 2 files changed, 2 deletions(-) diff --git a/example/mini_core.rs b/example/mini_core.rs index 8ffa66a489464..a48c0a4450c29 100644 --- a/example/mini_core.rs +++ b/example/mini_core.rs @@ -420,7 +420,6 @@ pub fn panic(_msg: &'static str) -> ! { macro_rules! panic_const { ($($lang:ident = $message:expr,)+) => { - #[cfg(not(bootstrap))] pub mod panic_const { use super::*; diff --git a/src/lib.rs b/src/lib.rs index 345c22394f21a..3f2fadce9e4d5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -23,7 +23,6 @@ trusted_len, hash_raw_entry )] -#![cfg_attr(bootstrap, feature(associated_type_bounds))] #![allow(broken_intra_doc_links)] #![recursion_limit = "256"] #![warn(rust_2018_idioms)] From 3ea32a746df732f864bb60cab44afe6b71ba799d Mon Sep 17 00:00:00 2001 From: Waffle Lapkin Date: Thu, 2 May 2024 17:49:23 +0200 Subject: [PATCH 114/892] Inline & delete `Ty::new_unit`, since it's just a field access --- src/intrinsic/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/intrinsic/mod.rs b/src/intrinsic/mod.rs index b7aec97ad8c27..451e5258ebd19 100644 --- a/src/intrinsic/mod.rs +++ b/src/intrinsic/mod.rs @@ -1223,7 +1223,7 @@ fn get_rust_try_fn<'a, 'gcc, 'tcx>( tcx, ty::Binder::dummy(tcx.mk_fn_sig( iter::once(i8p), - Ty::new_unit(tcx), + tcx.types.unit, false, rustc_hir::Unsafety::Unsafe, Abi::Rust, @@ -1234,7 +1234,7 @@ fn get_rust_try_fn<'a, 'gcc, 'tcx>( tcx, ty::Binder::dummy(tcx.mk_fn_sig( [i8p, i8p].iter().cloned(), - Ty::new_unit(tcx), + tcx.types.unit, false, rustc_hir::Unsafety::Unsafe, Abi::Rust, From 5166efc3eb83ed95a9ff608530798f4653448586 Mon Sep 17 00:00:00 2001 From: Antoni Boucher Date: Thu, 2 May 2024 17:07:58 -0400 Subject: [PATCH 115/892] Fix segfault in tests due to a bug in libc 0.2.154 We now keep the Cargo.lock to fix the version of libc to 0.2.153. --- build_system/build_sysroot/Cargo.lock | 433 ++++++++++++++++++++++++++ build_system/src/build.rs | 1 + 2 files changed, 434 insertions(+) create mode 100644 build_system/build_sysroot/Cargo.lock diff --git a/build_system/build_sysroot/Cargo.lock b/build_system/build_sysroot/Cargo.lock new file mode 100644 index 0000000000000..d6ec1f87d0103 --- /dev/null +++ b/build_system/build_sysroot/Cargo.lock @@ -0,0 +1,433 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "addr2line" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +dependencies = [ + "compiler_builtins", + "gimli", + "rustc-std-workspace-alloc", + "rustc-std-workspace-core", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +dependencies = [ + "compiler_builtins", + "rustc-std-workspace-core", +] + +[[package]] +name = "alloc" +version = "0.0.0" +dependencies = [ + "compiler_builtins", + "core", +] + +[[package]] +name = "allocator-api2" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +dependencies = [ + "compiler_builtins", + "rustc-std-workspace-core", +] + +[[package]] +name = "compiler_builtins" +version = "0.1.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f11973008a8cf741fe6d22f339eba21fd0ca81e2760a769ba8243ed6c21edd7e" +dependencies = [ + "rustc-std-workspace-core", +] + +[[package]] +name = "core" +version = "0.0.0" + +[[package]] +name = "dlmalloc" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3264b043b8e977326c1ee9e723da2c1f8d09a99df52cacf00b4dbce5ac54414d" +dependencies = [ + "cfg-if", + "compiler_builtins", + "libc", + "rustc-std-workspace-core", + "windows-sys", +] + +[[package]] +name = "fortanix-sgx-abi" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57cafc2274c10fab234f176b25903ce17e690fca7597090d50880e047a0389c5" +dependencies = [ + "compiler_builtins", + "rustc-std-workspace-core", +] + +[[package]] +name = "getopts" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14dbbfd5c71d70241ecf9e6f13737f7b5ce823821063188d7e46c41d371eebd5" +dependencies = [ + "rustc-std-workspace-core", + "rustc-std-workspace-std", + "unicode-width", +] + +[[package]] +name = "gimli" +version = "0.28.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" +dependencies = [ + "compiler_builtins", + "rustc-std-workspace-alloc", + "rustc-std-workspace-core", +] + +[[package]] +name = "hashbrown" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" +dependencies = [ + "allocator-api2", + "compiler_builtins", + "rustc-std-workspace-alloc", + "rustc-std-workspace-core", +] + +[[package]] +name = "hermit-abi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" +dependencies = [ + "compiler_builtins", + "rustc-std-workspace-alloc", + "rustc-std-workspace-core", +] + +[[package]] +name = "libc" +version = "0.2.153" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" +dependencies = [ + "rustc-std-workspace-core", +] + +[[package]] +name = "memchr" +version = "2.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" +dependencies = [ + "compiler_builtins", + "rustc-std-workspace-core", +] + +[[package]] +name = "miniz_oxide" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7" +dependencies = [ + "adler", + "compiler_builtins", + "rustc-std-workspace-alloc", + "rustc-std-workspace-core", +] + +[[package]] +name = "object" +version = "0.32.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" +dependencies = [ + "compiler_builtins", + "memchr", + "rustc-std-workspace-alloc", + "rustc-std-workspace-core", +] + +[[package]] +name = "panic_abort" +version = "0.0.0" +dependencies = [ + "alloc", + "cfg-if", + "compiler_builtins", + "core", + "libc", +] + +[[package]] +name = "panic_unwind" +version = "0.0.0" +dependencies = [ + "alloc", + "cfg-if", + "compiler_builtins", + "core", + "libc", + "unwind", +] + +[[package]] +name = "proc_macro" +version = "0.0.0" +dependencies = [ + "core", + "std", +] + +[[package]] +name = "r-efi" +version = "4.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c47196f636c4cc0634b73b0405323d177753c2e15e866952c64ea22902567a34" +dependencies = [ + "compiler_builtins", + "rustc-std-workspace-core", +] + +[[package]] +name = "r-efi-alloc" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31d6f09fe2b6ad044bc3d2c34ce4979796581afd2f1ebc185837e02421e02fd7" +dependencies = [ + "compiler_builtins", + "r-efi", + "rustc-std-workspace-core", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" +dependencies = [ + "compiler_builtins", + "rustc-std-workspace-core", +] + +[[package]] +name = "rustc-std-workspace-alloc" +version = "1.99.0" +dependencies = [ + "alloc", +] + +[[package]] +name = "rustc-std-workspace-core" +version = "1.99.0" +dependencies = [ + "core", +] + +[[package]] +name = "rustc-std-workspace-std" +version = "1.99.0" +dependencies = [ + "std", +] + +[[package]] +name = "std" +version = "0.0.0" +dependencies = [ + "addr2line", + "alloc", + "cfg-if", + "compiler_builtins", + "core", + "dlmalloc", + "fortanix-sgx-abi", + "hashbrown", + "hermit-abi", + "libc", + "miniz_oxide", + "object", + "panic_abort", + "panic_unwind", + "r-efi", + "r-efi-alloc", + "rustc-demangle", + "std_detect", + "unwind", + "wasi", +] + +[[package]] +name = "std_detect" +version = "0.1.5" +dependencies = [ + "cfg-if", + "compiler_builtins", + "rustc-std-workspace-alloc", + "rustc-std-workspace-core", +] + +[[package]] +name = "sysroot" +version = "0.0.0" +dependencies = [ + "alloc", + "compiler_builtins", + "core", + "proc_macro", + "std", + "test", +] + +[[package]] +name = "test" +version = "0.0.0" +dependencies = [ + "core", + "getopts", + "libc", + "panic_abort", + "panic_unwind", + "std", +] + +[[package]] +name = "unicode-width" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68f5e5f3158ecfd4b8ff6fe086db7c8467a2dfdac97fe420f2b7c4aa97af66d6" +dependencies = [ + "compiler_builtins", + "rustc-std-workspace-core", + "rustc-std-workspace-std", +] + +[[package]] +name = "unwind" +version = "0.0.0" +dependencies = [ + "cfg-if", + "compiler_builtins", + "core", + "libc", + "unwinding", +] + +[[package]] +name = "unwinding" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37a19a21a537f635c16c7576f22d0f2f7d63353c1337ad4ce0d8001c7952a25b" +dependencies = [ + "compiler_builtins", + "gimli", + "rustc-std-workspace-core", +] + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +dependencies = [ + "compiler_builtins", + "rustc-std-workspace-alloc", + "rustc-std-workspace-core", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" +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.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" diff --git a/build_system/src/build.rs b/build_system/src/build.rs index a17adb3cd06a9..ac428b4cec057 100644 --- a/build_system/src/build.rs +++ b/build_system/src/build.rs @@ -114,6 +114,7 @@ pub fn create_build_sysroot_content(start_dir: &Path) -> Result<(), String> { create_dir(start_dir)?; } copy_file("build_system/build_sysroot/Cargo.toml", &start_dir.join("Cargo.toml"))?; + copy_file("build_system/build_sysroot/Cargo.lock", &start_dir.join("Cargo.lock"))?; let src_dir = start_dir.join("src"); if !src_dir.is_dir() { From bd7c57b8cdfc045eeb4f6866a6abedd757e20e02 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 2 May 2024 15:20:40 +0200 Subject: [PATCH 116/892] Add `fmt` command --- build_system/src/fmt.rs | 35 +++++++++++++++++++++++++++++++++++ build_system/src/main.rs | 7 ++++++- 2 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 build_system/src/fmt.rs diff --git a/build_system/src/fmt.rs b/build_system/src/fmt.rs new file mode 100644 index 0000000000000..43644ba19b38a --- /dev/null +++ b/build_system/src/fmt.rs @@ -0,0 +1,35 @@ +use crate::utils::run_command_with_output; +use std::ffi::OsStr; +use std::path::Path; + +fn show_usage() { + println!( + r#" +`fmt` command help: + + --check : Pass `--check` argument to `cargo fmt` commands + --help : Show this help"# + ); +} + +pub fn run() -> Result<(), String> { + let mut check = false; + // We skip binary name and the `info` command. + let mut args = std::env::args().skip(2); + while let Some(arg) = args.next() { + match arg.as_str() { + "--help" => { + show_usage(); + return Ok(()); + } + "--check" => check = true, + _ => return Err(format!("Unknown option {}", arg)), + } + } + + let cmd: &[&dyn AsRef] = + if check { &[&"cargo", &"fmt", &"--check"] } else { &[&"cargo", &"fmt"] }; + + run_command_with_output(cmd, Some(&Path::new(".")))?; + run_command_with_output(cmd, Some(&Path::new("build_system"))) +} diff --git a/build_system/src/main.rs b/build_system/src/main.rs index 9a30490f62157..d678fd75344d5 100644 --- a/build_system/src/main.rs +++ b/build_system/src/main.rs @@ -5,6 +5,7 @@ mod build; mod clean; mod clone_gcc; mod config; +mod fmt; mod info; mod prepare; mod rust_tools; @@ -41,7 +42,8 @@ Commands: 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." + clone-gcc : Clones the GCC compiler from a specified source. + fmt : Runs rustfmt" ); } @@ -54,6 +56,7 @@ pub enum Command { Rustc, Test, Info, + Fmt, } fn main() { @@ -70,6 +73,7 @@ fn main() { Some("test") => Command::Test, Some("info") => Command::Info, Some("clone-gcc") => Command::CloneGcc, + Some("fmt") => Command::Fmt, Some("--help") => { usage(); process::exit(0); @@ -91,6 +95,7 @@ fn main() { Command::Test => test::run(), Command::Info => info::run(), Command::CloneGcc => clone_gcc::run(), + Command::Fmt => fmt::run(), } { eprintln!("Command failed to run: {e}"); process::exit(1); From 7e369b314bf7f08640febc341731ebd8b8a34236 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 2 May 2024 15:21:30 +0200 Subject: [PATCH 117/892] Simplify `fmt` check in CI --- .github/workflows/ci.yml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 835e055e8c586..cd366dbae1609 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -103,10 +103,7 @@ jobs: ./y.sh test --release --clean --build-sysroot ${{ matrix.commands }} - name: Check formatting - run: | - cargo fmt -- --check - cd build_system - cargo fmt -- --check + run: ./y.sh fmt --check - name: clippy run: | From 9aec5c5bcecad566a76fc7dbb819aa0e58a23671 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Tue, 9 Apr 2024 23:17:45 +0000 Subject: [PATCH 118/892] Add test for fn pointer duplication. --- tests/ui/mir/auxiliary/static_fnptr.rs | 10 ++++++++++ tests/ui/mir/static_fnptr.rs | 14 ++++++++++++++ 2 files changed, 24 insertions(+) create mode 100644 tests/ui/mir/auxiliary/static_fnptr.rs create mode 100644 tests/ui/mir/static_fnptr.rs diff --git a/tests/ui/mir/auxiliary/static_fnptr.rs b/tests/ui/mir/auxiliary/static_fnptr.rs new file mode 100644 index 0000000000000..a48ee6c012105 --- /dev/null +++ b/tests/ui/mir/auxiliary/static_fnptr.rs @@ -0,0 +1,10 @@ +//@ compile-flags:-O + +fn foo() {} + +pub static ADDR: fn() = foo; + +#[inline(always)] +pub fn bar(x: fn()) -> bool { + x == ADDR +} diff --git a/tests/ui/mir/static_fnptr.rs b/tests/ui/mir/static_fnptr.rs new file mode 100644 index 0000000000000..571dcf4463e12 --- /dev/null +++ b/tests/ui/mir/static_fnptr.rs @@ -0,0 +1,14 @@ +//@ run-pass +//@ compile-flags:-Cno-prepopulate-passes -Copt-level=0 +//@ aux-build:static_fnptr.rs + +extern crate static_fnptr; +use static_fnptr::{ADDR, bar}; + +fn baz() -> bool { + bar(ADDR) +} + +fn main() { + assert!(baz()) +} From d223ba6233455544818e0998d3352de8e237c896 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Wed, 10 Apr 2024 10:15:26 +0000 Subject: [PATCH 119/892] Document test. --- tests/ui/mir/static_fnptr.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/ui/mir/static_fnptr.rs b/tests/ui/mir/static_fnptr.rs index 571dcf4463e12..6b1ec021629b8 100644 --- a/tests/ui/mir/static_fnptr.rs +++ b/tests/ui/mir/static_fnptr.rs @@ -1,3 +1,10 @@ +//! Verify that we correctly handle fn pointer provenance in MIR optimizations. +//! By asking to inline `static_fnptr::bar`, we have two copies of `static_fnptr::foo`, one in the +//! auxiliary crate and one in the local crate CGU. +//! `baz` must only consider the versions from upstream crate, and not try to compare with the +//! address of the CGU-local copy. +//! Related issue: #123670 + //@ run-pass //@ compile-flags:-Cno-prepopulate-passes -Copt-level=0 //@ aux-build:static_fnptr.rs From 4c779d75bff7c7c83f4955c3f448198f6dd3c1db Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sat, 4 May 2024 19:27:27 +0000 Subject: [PATCH 120/892] Mark `foo` as explicitly inline. --- tests/ui/mir/auxiliary/static_fnptr.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/ui/mir/auxiliary/static_fnptr.rs b/tests/ui/mir/auxiliary/static_fnptr.rs index a48ee6c012105..8c7347175f4b8 100644 --- a/tests/ui/mir/auxiliary/static_fnptr.rs +++ b/tests/ui/mir/auxiliary/static_fnptr.rs @@ -1,5 +1,6 @@ //@ compile-flags:-O +#[inline] fn foo() {} pub static ADDR: fn() = foo; From f26221a936de0f4156b4ec9489ec7d9af78392ad Mon Sep 17 00:00:00 2001 From: beetrees Date: Mon, 6 May 2024 13:27:40 +0100 Subject: [PATCH 121/892] Refactor float `Primitive`s to a separate `Float` type --- src/type_of.rs | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/type_of.rs b/src/type_of.rs index 8f9bfbbd18fb0..90e139494b8a7 100644 --- a/src/type_of.rs +++ b/src/type_of.rs @@ -8,8 +8,8 @@ use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::{self, Ty, TypeVisitableExt}; use rustc_target::abi::call::{CastTarget, FnAbi, Reg}; use rustc_target::abi::{ - self, Abi, Align, FieldsShape, Int, Integer, PointeeInfo, Pointer, Size, TyAbiInterface, - Variants, F128, F16, F32, F64, + self, Abi, Align, FieldsShape, Float, Int, Integer, PointeeInfo, Pointer, Size, TyAbiInterface, + Variants, }; use crate::abi::{FnAbiGcc, FnAbiGccExt, GccType}; @@ -283,10 +283,7 @@ impl<'tcx> LayoutGccExt<'tcx> for TyAndLayout<'tcx> { match scalar.primitive() { Int(i, true) => cx.type_from_integer(i), Int(i, false) => cx.type_from_unsigned_integer(i), - F16 => cx.type_f16(), - F32 => cx.type_f32(), - F64 => cx.type_f64(), - F128 => cx.type_f128(), + Float(f) => cx.type_from_float(f), Pointer(address_space) => { // If we know the alignment, pick something better than i8. let pointee = if let Some(pointee) = self.pointee_info_at(cx, offset) { From 6b7db50d8902c38e2560207250e02a19134cf48f Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 8 May 2024 16:56:02 +1000 Subject: [PATCH 122/892] Simplify `use crate::rustc_foo::bar` occurrences. They can just be written as `use rustc_foo::bar`, which is far more standard. (I didn't even know that a `crate::` prefix was valid.) --- src/debuginfo.rs | 3 +-- src/type_of.rs | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/debuginfo.rs b/src/debuginfo.rs index aed15769025f1..1d0a6d9f09bb9 100644 --- a/src/debuginfo.rs +++ b/src/debuginfo.rs @@ -1,10 +1,9 @@ -use crate::rustc_index::Idx; use gccjit::{Location, RValue}; use rustc_codegen_ssa::mir::debuginfo::{DebugScope, FunctionDebugContext, VariableKind}; use rustc_codegen_ssa::traits::{DebugInfoBuilderMethods, DebugInfoMethods}; use rustc_data_structures::sync::Lrc; use rustc_index::bit_set::BitSet; -use rustc_index::IndexVec; +use rustc_index::{Idx, IndexVec}; use rustc_middle::mir::{self, Body, SourceScope}; use rustc_middle::ty::{Instance, PolyExistentialTraitRef, Ty}; use rustc_session::config::DebugInfo; diff --git a/src/type_of.rs b/src/type_of.rs index 8f9bfbbd18fb0..01056c1e42de8 100644 --- a/src/type_of.rs +++ b/src/type_of.rs @@ -1,7 +1,7 @@ use std::fmt::Write; -use crate::rustc_codegen_ssa::traits::{BaseTypeMethods, DerivedTypeMethods, LayoutTypeMethods}; use gccjit::{Struct, Type}; +use rustc_codegen_ssa::traits::{BaseTypeMethods, DerivedTypeMethods, LayoutTypeMethods}; use rustc_middle::bug; use rustc_middle::ty::layout::{LayoutOf, TyAndLayout}; use rustc_middle::ty::print::with_no_trimmed_paths; @@ -205,7 +205,7 @@ impl<'tcx> LayoutGccExt<'tcx> for TyAndLayout<'tcx> { /// of that field's type - this is useful for taking the address of /// that field and ensuring the struct has the right alignment. fn gcc_type<'gcc>(&self, cx: &CodegenCx<'gcc, 'tcx>) -> Type<'gcc> { - use crate::rustc_middle::ty::layout::FnAbiOf; + use rustc_middle::ty::layout::FnAbiOf; // This must produce the same result for `repr(transparent)` wrappers as for the inner type! // In other words, this should generally not look at the type at all, but only at the // layout. From a0b4d735e33811941e0eceb4cbedc8aaec6af3d3 Mon Sep 17 00:00:00 2001 From: Andy Sadler Date: Wed, 8 May 2024 20:51:21 -0500 Subject: [PATCH 123/892] simd: implement pointer provenance intrinsics This adds support for the simd variants of the pointer provenance intrinsics, which are `simd_cast_ptr`, `simd_expose_addr`, and `simd_from_exposed_addr`. The preconditions for each intrinsic are adapted from rustc_codegen_llvm to preserve compatibility. Each of these intrinsics are implemented as calling the non-simd variant of each intrinsic on each lane. This is enough to enable the UI test `ui/simd/intrinsic/ptr-cast.rs` to pass. Signed-off-by: Andy Sadler --- src/intrinsic/simd.rs | 135 +++++++++++++++++++++++++++++++++++++ tests/failing-ui-tests.txt | 1 - 2 files changed, 135 insertions(+), 1 deletion(-) diff --git a/src/intrinsic/simd.rs b/src/intrinsic/simd.rs index 6d8ed519b4cc9..a8d7c37dc8717 100644 --- a/src/intrinsic/simd.rs +++ b/src/intrinsic/simd.rs @@ -434,6 +434,141 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( return Ok(bx.vector_select(args[0].immediate(), args[1].immediate(), args[2].immediate())); } + if name == sym::simd_cast_ptr { + require_simd!(ret_ty, InvalidMonomorphization::SimdReturn { span, name, ty: ret_ty }); + let (out_len, out_elem) = ret_ty.simd_size_and_type(bx.tcx()); + + require!( + in_len == out_len, + InvalidMonomorphization::ReturnLengthInputType { + span, + name, + in_len, + in_ty, + ret_ty, + out_len + } + ); + + match *in_elem.kind() { + ty::RawPtr(p) => { + let metadata = p.ty.ptr_metadata_ty(bx.tcx, |ty| { + bx.tcx.normalize_erasing_regions(ty::ParamEnv::reveal_all(), ty) + }); + require!( + metadata.is_unit(), + InvalidMonomorphization::CastFatPointer { span, name, ty: in_elem } + ); + } + _ => { + return_error!(InvalidMonomorphization::ExpectedPointer { span, name, ty: in_elem }) + } + } + match *out_elem.kind() { + ty::RawPtr(p) => { + let metadata = p.ty.ptr_metadata_ty(bx.tcx, |ty| { + bx.tcx.normalize_erasing_regions(ty::ParamEnv::reveal_all(), ty) + }); + require!( + metadata.is_unit(), + InvalidMonomorphization::CastFatPointer { span, name, ty: out_elem } + ); + } + _ => { + return_error!(InvalidMonomorphization::ExpectedPointer { span, name, ty: out_elem }) + } + } + + let arg = args[0].immediate(); + let elem_type = llret_ty.dyncast_vector().expect("vector return type").get_element_type(); + let values: Vec<_> = (0..in_len) + .map(|i| { + let idx = bx.gcc_int(bx.usize_type, i as _); + let value = bx.extract_element(arg, idx); + bx.pointercast(value, elem_type) + }) + .collect(); + return Ok(bx.context.new_rvalue_from_vector(bx.location, llret_ty, &values)); + } + + if name == sym::simd_expose_addr { + require_simd!(ret_ty, InvalidMonomorphization::SimdReturn { span, name, ty: ret_ty }); + let (out_len, out_elem) = ret_ty.simd_size_and_type(bx.tcx()); + + require!( + in_len == out_len, + InvalidMonomorphization::ReturnLengthInputType { + span, + name, + in_len, + in_ty, + ret_ty, + out_len + } + ); + + match *in_elem.kind() { + ty::RawPtr(_) => {} + _ => { + return_error!(InvalidMonomorphization::ExpectedPointer { span, name, ty: in_elem }) + } + } + match *out_elem.kind() { + ty::Uint(ty::UintTy::Usize) => {} + _ => return_error!(InvalidMonomorphization::ExpectedUsize { span, name, ty: out_elem }), + } + + let arg = args[0].immediate(); + let elem_type = llret_ty.dyncast_vector().expect("vector return type").get_element_type(); + let values: Vec<_> = (0..in_len) + .map(|i| { + let idx = bx.gcc_int(bx.usize_type, i as _); + let value = bx.extract_element(arg, idx); + bx.ptrtoint(value, elem_type) + }) + .collect(); + return Ok(bx.context.new_rvalue_from_vector(bx.location, llret_ty, &values)); + } + + if name == sym::simd_from_exposed_addr { + require_simd!(ret_ty, InvalidMonomorphization::SimdReturn { span, name, ty: ret_ty }); + let (out_len, out_elem) = ret_ty.simd_size_and_type(bx.tcx()); + + require!( + in_len == out_len, + InvalidMonomorphization::ReturnLengthInputType { + span, + name, + in_len, + in_ty, + ret_ty, + out_len + } + ); + + match *in_elem.kind() { + ty::Uint(ty::UintTy::Usize) => {} + _ => return_error!(InvalidMonomorphization::ExpectedUsize { span, name, ty: in_elem }), + } + match *out_elem.kind() { + ty::RawPtr(_) => {} + _ => { + return_error!(InvalidMonomorphization::ExpectedPointer { span, name, ty: out_elem }) + } + } + + let arg = args[0].immediate(); + let elem_type = llret_ty.dyncast_vector().expect("vector return type").get_element_type(); + let values: Vec<_> = (0..in_len) + .map(|i| { + let idx = bx.gcc_int(bx.usize_type, i as _); + let value = bx.extract_element(arg, idx); + bx.inttoptr(value, elem_type) + }) + .collect(); + return Ok(bx.context.new_rvalue_from_vector(bx.location, llret_ty, &values)); + } + #[cfg(feature = "master")] if name == sym::simd_cast || name == sym::simd_as { require_simd!(ret_ty, InvalidMonomorphization::SimdReturn { span, name, ty: ret_ty }); diff --git a/tests/failing-ui-tests.txt b/tests/failing-ui-tests.txt index 4f0c9814e73ee..1521a4d254701 100644 --- a/tests/failing-ui-tests.txt +++ b/tests/failing-ui-tests.txt @@ -33,7 +33,6 @@ tests/ui/panic-runtime/abort.rs tests/ui/panic-runtime/link-to-abort.rs tests/ui/unwind-no-uwtable.rs tests/ui/parser/unclosed-delimiter-in-dep.rs -tests/ui/simd/intrinsic/ptr-cast.rs tests/ui/consts/missing_span_in_backtrace.rs tests/ui/drop/dynamic-drop.rs tests/ui/issues/issue-40883.rs From 7ad734687c37bc833819def591ad25138dc4602d Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Thu, 9 May 2024 18:27:27 +0200 Subject: [PATCH 124/892] codegen: memmove/memset cannot be non-temporal --- src/builder.rs | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/src/builder.rs b/src/builder.rs index 23a5e5ff8730c..4a3b6f678c444 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -1301,19 +1301,13 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { fn memmove( &mut self, dst: RValue<'gcc>, - dst_align: Align, + _dst_align: Align, src: RValue<'gcc>, - src_align: Align, + _src_align: Align, size: RValue<'gcc>, flags: MemFlags, ) { - if flags.contains(MemFlags::NONTEMPORAL) { - // HACK(nox): This is inefficient but there is no nontemporal memmove. - let val = self.load(src.get_type().get_pointee().expect("get_pointee"), src, src_align); - let ptr = self.pointercast(dst, self.type_ptr_to(self.val_ty(val))); - self.store_with_flags(val, ptr, dst_align, flags); - return; - } + assert!(!flags.contains(MemFlags::NONTEMPORAL), "non-temporal memmove not supported"); let size = self.intcast(size, self.type_size_t(), false); let _is_volatile = flags.contains(MemFlags::VOLATILE); let dst = self.pointercast(dst, self.type_i8p()); @@ -1335,6 +1329,7 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { _align: Align, flags: MemFlags, ) { + assert!(!flags.contains(MemFlags::NONTEMPORAL), "non-temporal memset not supported"); let _is_volatile = flags.contains(MemFlags::VOLATILE); let ptr = self.pointercast(ptr, self.type_i8p()); let memset = self.context.get_builtin_function("memset"); From dff9164ac5a0118e78285869c16f35447b720354 Mon Sep 17 00:00:00 2001 From: y21 <30553356+y21@users.noreply.github.com> Date: Thu, 2 May 2024 23:32:53 +0200 Subject: [PATCH 125/892] consider `copy_deref` a possible borrower --- clippy_utils/src/mir/possible_borrower.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clippy_utils/src/mir/possible_borrower.rs b/clippy_utils/src/mir/possible_borrower.rs index 06229ac938f9a..b3210fa155c70 100644 --- a/clippy_utils/src/mir/possible_borrower.rs +++ b/clippy_utils/src/mir/possible_borrower.rs @@ -69,7 +69,7 @@ impl<'a, 'b, 'tcx> mir::visit::Visitor<'tcx> for PossibleBorrowerVisitor<'a, 'b, fn visit_assign(&mut self, place: &mir::Place<'tcx>, rvalue: &mir::Rvalue<'_>, _location: mir::Location) { let lhs = place.local; match rvalue { - mir::Rvalue::Ref(_, _, borrowed) => { + mir::Rvalue::Ref(_, _, borrowed) | mir::Rvalue::CopyForDeref(borrowed) => { self.possible_borrower.add(borrowed.local, lhs); }, other => { From 20d1bb1867e6b5b5c79d1af7cb56b91e290d0283 Mon Sep 17 00:00:00 2001 From: y21 <30553356+y21@users.noreply.github.com> Date: Thu, 2 May 2024 23:38:31 +0200 Subject: [PATCH 126/892] [`assigning_clones`]: bail out when the source borrows from target --- clippy_lints/src/assigning_clones.rs | 65 +++++++++++++++++++++++++++- tests/ui/assigning_clones.fixed | 29 +++++++++++++ tests/ui/assigning_clones.rs | 29 +++++++++++++ 3 files changed, 122 insertions(+), 1 deletion(-) diff --git a/clippy_lints/src/assigning_clones.rs b/clippy_lints/src/assigning_clones.rs index 9202c46e8b6ba..4819471746f0d 100644 --- a/clippy_lints/src/assigning_clones.rs +++ b/clippy_lints/src/assigning_clones.rs @@ -1,16 +1,18 @@ use clippy_config::msrvs::{self, Msrv}; use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::macros::HirNode; +use clippy_utils::mir::{enclosing_mir, PossibleBorrowerMap}; use clippy_utils::sugg::Sugg; use clippy_utils::{is_trait_method, local_is_initialized, path_to_local}; use rustc_errors::Applicability; use rustc_hir::{self as hir, Expr, ExprKind}; use rustc_lint::{LateContext, LateLintPass}; +use rustc_middle::mir; use rustc_middle::ty::{self, Instance, Mutability}; use rustc_session::impl_lint_pass; use rustc_span::def_id::DefId; use rustc_span::symbol::sym; -use rustc_span::{ExpnKind, SyntaxContext}; +use rustc_span::{ExpnKind, Span, SyntaxContext}; declare_clippy_lint! { /// ### What it does @@ -144,6 +146,7 @@ fn extract_call<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) -> Option< }; Some(CallCandidate { + span: expr.span, target, kind, method_def_id: resolved_method.def_id(), @@ -215,6 +218,10 @@ fn is_ok_to_suggest<'tcx>(cx: &LateContext<'tcx>, lhs: &Expr<'tcx>, call: &CallC return false; }; + if clone_source_borrows_from_dest(cx, lhs, call.span) { + return false; + } + // Now take a look if the impl block defines an implementation for the method that we're interested // in. If not, then we're using a default implementation, which is not interesting, so we will // not suggest the lint. @@ -222,6 +229,61 @@ fn is_ok_to_suggest<'tcx>(cx: &LateContext<'tcx>, lhs: &Expr<'tcx>, call: &CallC implemented_fns.contains_key(&provided_fn.def_id) } +/// Checks if the data being cloned borrows from the place that is being assigned to: +/// +/// ``` +/// let mut s = String::new(); +/// let s2 = &s; +/// s = s2.to_owned(); +/// ``` +/// +/// This cannot be written `s2.clone_into(&mut s)` because it has conflicting borrows. +fn clone_source_borrows_from_dest(cx: &LateContext<'_>, lhs: &Expr<'_>, call_span: Span) -> bool { + let Some(mir) = enclosing_mir(cx.tcx, lhs.hir_id) else { + return false; + }; + let PossibleBorrowerMap { map: borrow_map, .. } = PossibleBorrowerMap::new(cx, mir); + + // The operation `dest = src.to_owned()` in MIR is split up across 3 blocks. + // For the doc example above that would be roughly: + // + // bb0: + // s2 = &s + // s_temp = ToOwned::to_owned(move s2) -> bb1 + // + // bb1: + // drop(s) -> bb2 // drop the old string + // + // bb2: + // s = s_temp + for bb in mir.basic_blocks.iter() { + let terminator = bb.terminator(); + + // Look for the to_owned/clone call. + if terminator.source_info.span == call_span + && let mir::TerminatorKind::Call { + args, + target: Some(drop_bb), + .. + } = &terminator.kind + && let [source] = &**args + && let mir::Operand::Move(source) = &source.node + // Block 2 only has the `drop()` terminator from to the assignment + && let drop_bb = &mir.basic_blocks[*drop_bb] + && let mir::TerminatorKind::Drop { target: assign_bb, .. } = drop_bb.terminator().kind + // Block 3 has the final assignment to the original local + && let assign_bb = &mir.basic_blocks[assign_bb] + && let [assignment, ..] = &*assign_bb.statements + && let mir::StatementKind::Assign(box (borrowed, _)) = &assignment.kind + && let Some(borrowers) = borrow_map.get(&borrowed.local) + && borrowers.contains(source.local) + { + return true; + } + } + false +} + fn suggest<'tcx>( cx: &LateContext<'tcx>, ctxt: SyntaxContext, @@ -255,6 +317,7 @@ enum TargetTrait { #[derive(Debug)] struct CallCandidate<'tcx> { + span: Span, target: TargetTrait, kind: CallKind<'tcx>, // DefId of the called method from an impl block that implements the target trait diff --git a/tests/ui/assigning_clones.fixed b/tests/ui/assigning_clones.fixed index 70ab43b49b3a7..64a1f02eb051f 100644 --- a/tests/ui/assigning_clones.fixed +++ b/tests/ui/assigning_clones.fixed @@ -272,3 +272,32 @@ impl<'a> Add for &'a mut HasCloneFrom { self } } + +mod borrowck_conflicts { + //! Cases where clone_into and friends cannot be used because the src/dest have conflicting + //! borrows. + use std::path::PathBuf; + + fn issue12444(mut name: String) { + let parts = name.split(", ").collect::>(); + let first = *parts.first().unwrap(); + name = first.to_owned(); + } + + fn issue12444_simple() { + let mut s = String::new(); + let s2 = &s; + s = s2.to_owned(); + } + + fn issue12460(mut name: String) { + if let Some(stripped_name) = name.strip_prefix("baz-") { + name = stripped_name.to_owned(); + } + } + + fn issue12749() { + let mut path = PathBuf::from("/a/b/c"); + path = path.components().as_path().to_owned(); + } +} diff --git a/tests/ui/assigning_clones.rs b/tests/ui/assigning_clones.rs index 9699fed100c8f..b92452c35772f 100644 --- a/tests/ui/assigning_clones.rs +++ b/tests/ui/assigning_clones.rs @@ -272,3 +272,32 @@ impl<'a> Add for &'a mut HasCloneFrom { self } } + +mod borrowck_conflicts { + //! Cases where clone_into and friends cannot be used because the src/dest have conflicting + //! borrows. + use std::path::PathBuf; + + fn issue12444(mut name: String) { + let parts = name.split(", ").collect::>(); + let first = *parts.first().unwrap(); + name = first.to_owned(); + } + + fn issue12444_simple() { + let mut s = String::new(); + let s2 = &s; + s = s2.to_owned(); + } + + fn issue12460(mut name: String) { + if let Some(stripped_name) = name.strip_prefix("baz-") { + name = stripped_name.to_owned(); + } + } + + fn issue12749() { + let mut path = PathBuf::from("/a/b/c"); + path = path.components().as_path().to_owned(); + } +} From 60508f546a07fa51169736766b7e16676724c496 Mon Sep 17 00:00:00 2001 From: y21 <30553356+y21@users.noreply.github.com> Date: Fri, 3 May 2024 01:45:49 +0200 Subject: [PATCH 127/892] deal with non-`Drop` types and add a test case for projections --- clippy_lints/src/assigning_clones.rs | 39 ++++++++++++++++++---------- tests/ui/assigning_clones.fixed | 27 +++++++++++++++++++ tests/ui/assigning_clones.rs | 27 +++++++++++++++++++ 3 files changed, 80 insertions(+), 13 deletions(-) diff --git a/clippy_lints/src/assigning_clones.rs b/clippy_lints/src/assigning_clones.rs index 4819471746f0d..920d1bae0b17c 100644 --- a/clippy_lints/src/assigning_clones.rs +++ b/clippy_lints/src/assigning_clones.rs @@ -239,12 +239,23 @@ fn is_ok_to_suggest<'tcx>(cx: &LateContext<'tcx>, lhs: &Expr<'tcx>, call: &CallC /// /// This cannot be written `s2.clone_into(&mut s)` because it has conflicting borrows. fn clone_source_borrows_from_dest(cx: &LateContext<'_>, lhs: &Expr<'_>, call_span: Span) -> bool { + /// If this basic block only exists to drop a local as part of an assignment, returns its + /// successor. Otherwise returns the basic block that was passed in. + fn skip_drop_block(mir: &mir::Body<'_>, bb: mir::BasicBlock) -> mir::BasicBlock { + if let mir::TerminatorKind::Drop { target, .. } = mir.basic_blocks[bb].terminator().kind { + target + } else { + bb + } + } + let Some(mir) = enclosing_mir(cx.tcx, lhs.hir_id) else { return false; }; let PossibleBorrowerMap { map: borrow_map, .. } = PossibleBorrowerMap::new(cx, mir); - // The operation `dest = src.to_owned()` in MIR is split up across 3 blocks. + // The operation `dest = src.to_owned()` in MIR is split up across 3 blocks *if* the type has `Drop` + // code. For types that don't, the second basic block is simply skipped. // For the doc example above that would be roughly: // // bb0: @@ -260,26 +271,28 @@ fn clone_source_borrows_from_dest(cx: &LateContext<'_>, lhs: &Expr<'_>, call_spa let terminator = bb.terminator(); // Look for the to_owned/clone call. - if terminator.source_info.span == call_span - && let mir::TerminatorKind::Call { - args, - target: Some(drop_bb), - .. - } = &terminator.kind + if terminator.source_info.span != call_span { + continue; + } + + if let mir::TerminatorKind::Call { ref args, target: Some(assign_bb), .. } = terminator.kind && let [source] = &**args && let mir::Operand::Move(source) = &source.node - // Block 2 only has the `drop()` terminator from to the assignment - && let drop_bb = &mir.basic_blocks[*drop_bb] - && let mir::TerminatorKind::Drop { target: assign_bb, .. } = drop_bb.terminator().kind - // Block 3 has the final assignment to the original local - && let assign_bb = &mir.basic_blocks[assign_bb] - && let [assignment, ..] = &*assign_bb.statements + && let assign_bb = skip_drop_block(mir, assign_bb) + // Skip any storage statements as they are just noise + && let Some(assignment) = mir.basic_blocks[assign_bb].statements + .iter() + .find(|stmt| { + !matches!(stmt.kind, mir::StatementKind::StorageDead(_) | mir::StatementKind::StorageLive(_)) + }) && let mir::StatementKind::Assign(box (borrowed, _)) = &assignment.kind && let Some(borrowers) = borrow_map.get(&borrowed.local) && borrowers.contains(source.local) { return true; } + + return false; } false } diff --git a/tests/ui/assigning_clones.fixed b/tests/ui/assigning_clones.fixed index 64a1f02eb051f..60f6a385fc506 100644 --- a/tests/ui/assigning_clones.fixed +++ b/tests/ui/assigning_clones.fixed @@ -290,6 +290,33 @@ mod borrowck_conflicts { s = s2.to_owned(); } + fn issue12444_nodrop_projections() { + struct NoDrop; + + impl Clone for NoDrop { + fn clone(&self) -> Self { + todo!() + } + fn clone_from(&mut self, other: &Self) { + todo!() + } + } + + let mut s = NoDrop; + let s2 = &s; + s = s2.clone(); + + let mut s = (NoDrop, NoDrop); + let s2 = &s.0; + s.0 = s2.clone(); + + // This *could* emit a warning, but PossibleBorrowerMap only works with locals so it + // considers `s` fully borrowed + let mut s = (NoDrop, NoDrop); + let s2 = &s.1; + s.0 = s2.clone(); + } + fn issue12460(mut name: String) { if let Some(stripped_name) = name.strip_prefix("baz-") { name = stripped_name.to_owned(); diff --git a/tests/ui/assigning_clones.rs b/tests/ui/assigning_clones.rs index b92452c35772f..6eb85be511a89 100644 --- a/tests/ui/assigning_clones.rs +++ b/tests/ui/assigning_clones.rs @@ -290,6 +290,33 @@ mod borrowck_conflicts { s = s2.to_owned(); } + fn issue12444_nodrop_projections() { + struct NoDrop; + + impl Clone for NoDrop { + fn clone(&self) -> Self { + todo!() + } + fn clone_from(&mut self, other: &Self) { + todo!() + } + } + + let mut s = NoDrop; + let s2 = &s; + s = s2.clone(); + + let mut s = (NoDrop, NoDrop); + let s2 = &s.0; + s.0 = s2.clone(); + + // This *could* emit a warning, but PossibleBorrowerMap only works with locals so it + // considers `s` fully borrowed + let mut s = (NoDrop, NoDrop); + let s2 = &s.1; + s.0 = s2.clone(); + } + fn issue12460(mut name: String) { if let Some(stripped_name) = name.strip_prefix("baz-") { name = stripped_name.to_owned(); From ed7d97e4c8806d0fced2fbcec44b668d5528efbe Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Mon, 13 May 2024 13:26:33 +0000 Subject: [PATCH 128/892] Merge commit '3270432f4b0583104c8b9b6f695bf97d6bbf3ac2' into sync_cg_clif-2024-05-13 --- .github/workflows/abi-cafe.yml | 8 ++ .github/workflows/main.yml | 16 +++ .github/workflows/rustc.yml | 4 +- .gitignore | 4 - build_system/Cargo.toml | 3 + build_system/build_sysroot.rs | 37 +++++- build_system/main.rs | 8 +- build_system/tests.rs | 2 +- example/mini_core_hello_world.rs | 10 ++ example/std_example.rs | 29 +++++ patches/stdlib-lock.toml | 4 +- rust-toolchain | 2 +- scripts/test_rustc_tests.sh | 4 +- src/abi/mod.rs | 6 +- src/base.rs | 37 +++++- src/concurrency_limiter.rs | 21 +--- src/config.rs | 9 +- src/constant.rs | 2 +- src/discriminant.rs | 45 ++++--- src/driver/aot.rs | 72 +++++------ src/driver/jit.rs | 23 ++-- src/driver/mod.rs | 16 ++- src/global_asm.rs | 2 +- src/inline_asm.rs | 201 +++++++++++++++++++++++++------ src/intrinsics/llvm_x86.rs | 52 ++++++++ src/lib.rs | 6 +- src/main_shim.rs | 2 +- src/value_and_place.rs | 8 -- y.cmd | 4 +- y.ps1 | 7 +- y.sh | 3 +- 31 files changed, 481 insertions(+), 166 deletions(-) mode change 100644 => 100755 y.ps1 diff --git a/.github/workflows/abi-cafe.yml b/.github/workflows/abi-cafe.yml index a745f2801cc4e..b7063f35a3e80 100644 --- a/.github/workflows/abi-cafe.yml +++ b/.github/workflows/abi-cafe.yml @@ -51,6 +51,14 @@ jobs: if: matrix.env.TARGET_TRIPLE == 'x86_64-pc-windows-gnu' run: rustup set default-host x86_64-pc-windows-gnu + - name: Use x86_64 compiler on macOS + if: matrix.os == 'macos-latest' && matrix.env.TARGET_TRIPLE == 'x86_64-apple-darwin' + run: rustup set default-host x86_64-apple-darwin + + - name: Select XCode version + if: matrix.os == 'macos-latest' + run: sudo xcode-select -s /Applications/Xcode_14.3.1.app + - name: Prepare dependencies run: ./y.sh prepare diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 14aa850ff5cb7..1f5a6513f63b1 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -98,12 +98,20 @@ jobs: if: matrix.os == 'windows-latest' && matrix.env.TARGET_TRIPLE == 'x86_64-pc-windows-gnu' run: rustup set default-host x86_64-pc-windows-gnu + - name: Use x86_64 compiler on macOS + if: matrix.os == 'macos-latest' && matrix.env.TARGET_TRIPLE == 'x86_64-apple-darwin' + run: rustup set default-host x86_64-apple-darwin + - name: Install toolchain and emulator if: matrix.apt_deps != null run: | sudo apt-get update sudo apt-get install -y ${{ matrix.apt_deps }} + - name: Select XCode version + if: matrix.os == 'macos-latest' + run: sudo xcode-select -s /Applications/Xcode_14.3.1.app + - name: Prepare dependencies run: ./y.sh prepare @@ -230,12 +238,20 @@ jobs: if: matrix.os == 'windows-latest' && matrix.env.TARGET_TRIPLE == 'x86_64-pc-windows-gnu' run: rustup set default-host x86_64-pc-windows-gnu + - name: Use x86_64 compiler on macOS + if: matrix.os == 'macos-latest' && matrix.env.TARGET_TRIPLE == 'x86_64-apple-darwin' + run: rustup set default-host x86_64-apple-darwin + - name: Install MinGW toolchain if: matrix.os == 'ubuntu-latest' && matrix.env.TARGET_TRIPLE == 'x86_64-pc-windows-gnu' run: | sudo apt-get update sudo apt-get install -y gcc-mingw-w64-x86-64 + - name: Select XCode version + if: matrix.os == 'macos-latest' + run: sudo xcode-select -s /Applications/Xcode_14.3.1.app + - name: Prepare dependencies run: ./y.sh prepare diff --git a/.github/workflows/rustc.yml b/.github/workflows/rustc.yml index 75ea94ee79790..70c214ce8b147 100644 --- a/.github/workflows/rustc.yml +++ b/.github/workflows/rustc.yml @@ -20,7 +20,7 @@ jobs: uses: actions/cache@v4 with: path: build/cg_clif - key: ${{ runner.os }}-cargo-build-target-${{ hashFiles('rust-toolchain', '**/Cargo.lock') }} + key: ${{ runner.os }}-rustc-test-cargo-build-target-${{ hashFiles('rust-toolchain', 'Cargo.lock') }} - name: Prepare dependencies run: ./y.sh prepare @@ -43,7 +43,7 @@ jobs: uses: actions/cache@v4 with: path: build/cg_clif - key: ${{ runner.os }}-cargo-build-target-${{ hashFiles('rust-toolchain', '**/Cargo.lock') }} + key: ${{ runner.os }}-rustc-test-cargo-build-target-${{ hashFiles('rust-toolchain', 'Cargo.lock') }} - name: Install ripgrep run: | diff --git a/.gitignore b/.gitignore index 7915fa138f8fc..5a38f2acb0e2f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,4 @@ # Build artifacts during normal use -/y.bin -/y.bin.dSYM -/y.exe -/y.pdb /download /build /dist diff --git a/build_system/Cargo.toml b/build_system/Cargo.toml index f47b9bc554041..feed2b6eafe82 100644 --- a/build_system/Cargo.toml +++ b/build_system/Cargo.toml @@ -11,3 +11,6 @@ path = "main.rs" unstable-features = [] # for rust-analyzer # Do not add any dependencies + +[profile.dev] +debug = 1 diff --git a/build_system/build_sysroot.rs b/build_system/build_sysroot.rs index 10c3f9cfa2ce3..196ff8fda7544 100644 --- a/build_system/build_sysroot.rs +++ b/build_system/build_sysroot.rs @@ -267,12 +267,16 @@ fn build_clif_sysroot_for_triple( prefix.to_str().unwrap() )); } + rustflags.push("-Zunstable-options".to_owned()); + for (name, values) in EXTRA_CHECK_CFGS { + rustflags.push(check_cfg_arg(name, *values)); + } compiler.rustflags.extend(rustflags); let mut build_cmd = STANDARD_LIBRARY.build(&compiler, dirs); if channel == "release" { build_cmd.arg("--release"); } - build_cmd.arg("--features").arg("compiler-builtins-no-asm backtrace panic-unwind"); + build_cmd.arg("--features").arg("backtrace panic-unwind"); build_cmd.env("CARGO_PROFILE_RELEASE_DEBUG", "true"); build_cmd.env("__CARGO_DEFAULT_LIB_METADATA", "cg_clif"); if compiler.triple.contains("apple") { @@ -326,3 +330,34 @@ fn build_rtstartup(dirs: &Dirs, compiler: &Compiler) -> Option { Some(target_libs) } + +// Copied from https://github.com/rust-lang/rust/blob/4fd98a4b1b100f5329c6efae18031791f64372d2/src/bootstrap/src/utils/helpers.rs#L569-L585 +/// Create a `--check-cfg` argument invocation for a given name +/// and it's values. +fn check_cfg_arg(name: &str, values: Option<&[&str]>) -> String { + // Creating a string of the values by concatenating each value: + // ',values("tvos","watchos")' or '' (nothing) when there are no values. + let next = match values { + Some(values) => { + let mut tmp = values.iter().flat_map(|val| [",", "\"", val, "\""]).collect::(); + + tmp.insert_str(1, "values("); + tmp.push(')'); + tmp + } + None => "".to_string(), + }; + format!("--check-cfg=cfg({name}{next})") +} + +const EXTRA_CHECK_CFGS: &[(&str, Option<&[&str]>)] = &[ + ("bootstrap", None), + ("stdarch_intel_sde", None), + ("no_fp_fmt_parse", None), + ("no_global_oom_handling", None), + ("no_rc", None), + ("no_sync", None), + ("netbsd10", None), + ("backtrace_in_libstd", None), + ("target_arch", Some(&["xtensa"])), +]; diff --git a/build_system/main.rs b/build_system/main.rs index cdd2bae03f8f1..7dbf608f991e4 100644 --- a/build_system/main.rs +++ b/build_system/main.rs @@ -147,9 +147,11 @@ fn main() { let rustup_toolchain_name = match (env::var("CARGO"), env::var("RUSTC"), env::var("RUSTDOC")) { (Ok(_), Ok(_), Ok(_)) => None, - (Err(_), Err(_), Err(_)) => Some(rustc_info::get_toolchain_name()), - _ => { - eprintln!("All of CARGO, RUSTC and RUSTDOC need to be set or none must be set"); + (_, Err(_), Err(_)) => Some(rustc_info::get_toolchain_name()), + vars => { + eprintln!( + "If RUSTC or RUSTDOC is set, both need to be set and in addition CARGO needs to be set: {vars:?}" + ); process::exit(1); } }; diff --git a/build_system/tests.rs b/build_system/tests.rs index 76104901474c2..278f334796a9b 100644 --- a/build_system/tests.rs +++ b/build_system/tests.rs @@ -77,7 +77,7 @@ const BASE_SYSROOT_SUITE: &[TestCase] = &[ ), TestCase::build_lib("build.alloc_system", "example/alloc_system.rs", "lib"), TestCase::build_bin_and_run("aot.alloc_example", "example/alloc_example.rs", &[]), - TestCase::jit_bin("jit.std_example", "example/std_example.rs", ""), + TestCase::jit_bin("jit.std_example", "example/std_example.rs", "arg"), TestCase::build_bin_and_run("aot.std_example", "example/std_example.rs", &["arg"]), TestCase::build_bin_and_run("aot.dst_field_align", "example/dst-field-align.rs", &[]), TestCase::build_bin_and_run( diff --git a/example/mini_core_hello_world.rs b/example/mini_core_hello_world.rs index efa4be7e15ac3..aab20f672487b 100644 --- a/example/mini_core_hello_world.rs +++ b/example/mini_core_hello_world.rs @@ -4,6 +4,7 @@ never_type, linkage, extern_types, + naked_functions, thread_local, repr_simd, raw_ref_op @@ -340,6 +341,7 @@ fn main() { ))] unsafe { global_asm_test(); + naked_test(); } // Both statics have a reference that points to the same anonymous allocation. @@ -395,6 +397,14 @@ global_asm! { " } +#[cfg(all(not(jit), not(no_unstable_features), target_arch = "x86_64"))] +#[naked] +extern "C" fn naked_test() { + unsafe { + asm!("ret", options(noreturn)); + } +} + #[repr(C)] enum c_void { _1, diff --git a/example/std_example.rs b/example/std_example.rs index 90d4ab721daef..7347b2e77899f 100644 --- a/example/std_example.rs +++ b/example/std_example.rs @@ -210,6 +210,21 @@ struct I64X2(i64, i64); #[allow(improper_ctypes_definitions)] extern "C" fn foo(_a: I64X2) {} +#[cfg(target_arch = "x86_64")] +#[target_feature(enable = "sse4.2")] +#[cfg(not(jit))] +unsafe fn test_crc32() { + assert!(is_x86_feature_detected!("sse4.2")); + + let a = 42u32; + let b = 0xdeadbeefu64; + + assert_eq!(_mm_crc32_u8(a, b as u8), 4135334616); + assert_eq!(_mm_crc32_u16(a, b as u16), 1200687288); + assert_eq!(_mm_crc32_u32(a, b as u32), 2543798776); + assert_eq!(_mm_crc32_u64(a as u64, b as u64), 241952147); +} + #[cfg(target_arch = "x86_64")] #[target_feature(enable = "sse2")] unsafe fn test_simd() { @@ -244,10 +259,14 @@ unsafe fn test_simd() { test_mm256_shuffle_epi8(); test_mm256_permute2x128_si256(); + test_mm256_permutevar8x32_epi32(); #[rustfmt::skip] let mask1 = _mm_movemask_epi8(dbg!(_mm_setr_epi8(255u8 as i8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0))); assert_eq!(mask1, 1); + + #[cfg(not(jit))] + test_crc32(); } #[cfg(target_arch = "x86_64")] @@ -447,6 +466,16 @@ unsafe fn test_mm256_permute2x128_si256() { assert_eq_m256i(r, e); } +#[cfg(target_arch = "x86_64")] +#[target_feature(enable = "avx2")] +unsafe fn test_mm256_permutevar8x32_epi32() { + let a = _mm256_setr_epi32(100, 200, 300, 400, 500, 600, 700, 800); + let idx = _mm256_setr_epi32(7, 6, 5, 4, 3, 2, 1, 0); + let r = _mm256_setr_epi32(800, 700, 600, 500, 400, 300, 200, 100); + let e = _mm256_permutevar8x32_epi32(a, idx); + assert_eq_m256i(r, e); +} + fn test_checked_mul() { let u: Option = u8::from_str_radix("1000", 10).ok(); assert_eq!(u, None); diff --git a/patches/stdlib-lock.toml b/patches/stdlib-lock.toml index a72fa2c62a96c..c8c7b45bc9a6f 100644 --- a/patches/stdlib-lock.toml +++ b/patches/stdlib-lock.toml @@ -42,9 +42,9 @@ checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" [[package]] name = "cc" -version = "1.0.90" +version = "1.0.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cd6604a82acf3039f1144f54b8eb34e91ffba622051189e71b781822d5ee1f5" +checksum = "099a5357d84c4c61eb35fc8eafa9a79a902c2f76911e5747ced4e032edd8d9b4" [[package]] name = "cfg-if" diff --git a/rust-toolchain b/rust-toolchain index de340cf8c35cc..a2ba79cbe9038 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2024-04-23" +channel = "nightly-2024-05-13" components = ["rust-src", "rustc-dev", "llvm-tools"] diff --git a/scripts/test_rustc_tests.sh b/scripts/test_rustc_tests.sh index 8580f4557e883..689cda21643cb 100755 --- a/scripts/test_rustc_tests.sh +++ b/scripts/test_rustc_tests.sh @@ -44,6 +44,7 @@ rm tests/incremental/hashes/statics.rs # same rm tests/ui/abi/mir/mir_codegen_calls_variadic.rs # requires float varargs rm tests/ui/abi/variadic-ffi.rs # requires callee side vararg support rm -r tests/run-make/c-link-to-rust-va-list-fn # requires callee side vararg support +rm tests/ui/delegation/fn-header.rs # unsized locals rm -r tests/run-pass-valgrind/unsized-locals @@ -87,6 +88,7 @@ rm -r tests/run-make/no-builtins-attribute # same rm tests/ui/abi/stack-protector.rs # requires stack protector support rm -r tests/run-make/emit-stack-sizes # requires support for -Z emit-stack-sizes rm -r tests/run-make/optimization-remarks-dir # remarks are LLVM specific +rm -r tests/run-make/print-to-output # requires --print relocation-models # requires asm, llvm-ir and/or llvm-bc emit support # ============================================= @@ -151,7 +153,7 @@ index 9607ff02f96..b7d97caf9a2 100644 let mut cmd = setup_common(); - let target_rpath_dir = env::var_os("TARGET_RPATH_DIR").unwrap(); - cmd.arg(format!("-L{}", target_rpath_dir.to_string_lossy())); - Self { cmd } + Self { cmd, stdin: None } } EOF diff --git a/src/abi/mod.rs b/src/abi/mod.rs index 6f346af25c6dd..4bcef15ad0475 100644 --- a/src/abi/mod.rs +++ b/src/abi/mod.rs @@ -412,7 +412,7 @@ pub(crate) fn codegen_terminator_call<'tcx>( Err(instance) => Some(instance), } } - InstanceDef::DropGlue(_, None) => { + InstanceDef::DropGlue(_, None) | ty::InstanceDef::AsyncDropGlueCtorShim(_, None) => { // empty drop glue - a nop. let dest = target.expect("Non terminating drop_in_place_real???"); let ret_block = fx.get_block(dest); @@ -597,7 +597,9 @@ pub(crate) fn codegen_drop<'tcx>( let ty = drop_place.layout().ty; let drop_instance = Instance::resolve_drop_in_place(fx.tcx, ty).polymorphize(fx.tcx); - if let ty::InstanceDef::DropGlue(_, None) = drop_instance.def { + if let ty::InstanceDef::DropGlue(_, None) | ty::InstanceDef::AsyncDropGlueCtorShim(_, None) = + drop_instance.def + { // we don't actually need to drop anything } else { match ty.kind() { diff --git a/src/base.rs b/src/base.rs index 8874efadec9d9..5846689643fdd 100644 --- a/src/base.rs +++ b/src/base.rs @@ -6,6 +6,7 @@ use cranelift_frontend::{FunctionBuilder, FunctionBuilderContext}; use cranelift_module::ModuleError; use rustc_ast::InlineAsmOptions; use rustc_index::IndexVec; +use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; use rustc_middle::ty::adjustment::PointerCoercion; use rustc_middle::ty::layout::FnAbiOf; use rustc_middle::ty::print::with_no_trimmed_paths; @@ -14,6 +15,7 @@ use rustc_monomorphize::is_call_from_compiler_builtins_to_upstream_monomorphizat use crate::constant::ConstantCx; use crate::debuginfo::{FunctionDebugContext, TypeDebugContext}; +use crate::inline_asm::codegen_naked_asm; use crate::prelude::*; use crate::pretty_clif::CommentWriter; @@ -32,7 +34,7 @@ pub(crate) fn codegen_fn<'tcx>( cached_func: Function, module: &mut dyn Module, instance: Instance<'tcx>, -) -> CodegenedFunction { +) -> Option { debug_assert!(!instance.args.has_infer()); let symbol_name = tcx.symbol_name(instance).name.to_string(); @@ -48,6 +50,37 @@ pub(crate) fn codegen_fn<'tcx>( String::from_utf8_lossy(&buf).into_owned() }); + if tcx.codegen_fn_attrs(instance.def_id()).flags.contains(CodegenFnAttrFlags::NAKED) { + assert_eq!(mir.basic_blocks.len(), 1); + assert!(mir.basic_blocks[START_BLOCK].statements.is_empty()); + + match &mir.basic_blocks[START_BLOCK].terminator().kind { + TerminatorKind::InlineAsm { + template, + operands, + options, + line_spans: _, + targets: _, + unwind: _, + } => { + codegen_naked_asm( + tcx, + cx, + module, + instance, + mir.basic_blocks[START_BLOCK].terminator().source_info.span, + &symbol_name, + template, + operands, + *options, + ); + } + _ => unreachable!(), + } + + return None; + } + // Declare function let sig = get_function_sig(tcx, module.target_config().default_call_conv, instance); let func_id = module.declare_function(&symbol_name, Linkage::Local, &sig).unwrap(); @@ -128,7 +161,7 @@ pub(crate) fn codegen_fn<'tcx>( // Verify function verify_func(tcx, &clif_comments, &func); - CodegenedFunction { symbol_name, func_id, func, clif_comments, func_debug_cx } + Some(CodegenedFunction { symbol_name, func_id, func, clif_comments, func_debug_cx }) } pub(crate) fn compile_fn( diff --git a/src/concurrency_limiter.rs b/src/concurrency_limiter.rs index 9678969134a8d..a73860cf18b2d 100644 --- a/src/concurrency_limiter.rs +++ b/src/concurrency_limiter.rs @@ -6,7 +6,7 @@ use rustc_session::Session; // FIXME don't panic when a worker thread panics pub(super) struct ConcurrencyLimiter { - helper_thread: Option, + helper_thread: Option>, state: Arc>, available_token_condvar: Arc, finished: bool, @@ -39,14 +39,14 @@ impl ConcurrencyLimiter { }) .unwrap(); ConcurrencyLimiter { - helper_thread: Some(helper_thread), + helper_thread: Some(Mutex::new(helper_thread)), state, available_token_condvar, finished: false, } } - pub(super) fn acquire(&mut self, dcx: &rustc_errors::DiagCtxt) -> ConcurrencyLimiterToken { + pub(super) fn acquire(&self, dcx: &rustc_errors::DiagCtxt) -> ConcurrencyLimiterToken { let mut state = self.state.lock().unwrap(); loop { state.assert_invariants(); @@ -73,16 +73,11 @@ impl ConcurrencyLimiter { } } - self.helper_thread.as_mut().unwrap().request_token(); + self.helper_thread.as_ref().unwrap().lock().unwrap().request_token(); state = self.available_token_condvar.wait(state).unwrap(); } } - pub(super) fn job_already_done(&mut self) { - let mut state = self.state.lock().unwrap(); - state.job_already_done(); - } - pub(crate) fn finished(mut self) { self.helper_thread.take(); @@ -190,14 +185,6 @@ mod state { self.assert_invariants(); } - pub(super) fn job_already_done(&mut self) { - self.assert_invariants(); - self.pending_jobs -= 1; - self.assert_invariants(); - self.drop_excess_capacity(); - self.assert_invariants(); - } - pub(super) fn poison(&mut self, error: String) { self.poisoned = true; self.stored_error = Some(error); diff --git a/src/config.rs b/src/config.rs index 9e92d656c76ef..12bce680d9e11 100644 --- a/src/config.rs +++ b/src/config.rs @@ -64,8 +64,13 @@ impl Default for BackendConfig { BackendConfig { codegen_mode: CodegenMode::Aot, jit_args: { - let args = std::env::var("CG_CLIF_JIT_ARGS").unwrap_or_else(|_| String::new()); - args.split(' ').map(|arg| arg.to_string()).collect() + match std::env::var("CG_CLIF_JIT_ARGS") { + Ok(args) => args.split(' ').map(|arg| arg.to_string()).collect(), + Err(std::env::VarError::NotPresent) => vec![], + Err(std::env::VarError::NotUnicode(s)) => { + panic!("CG_CLIF_JIT_ARGS not unicode: {:?}", s); + } + } }, enable_verifier: cfg!(debug_assertions) || bool_env_var("CG_CLIF_ENABLE_VERIFIER"), disable_incr_cache: bool_env_var("CG_CLIF_DISABLE_INCR_CACHE"), diff --git a/src/constant.rs b/src/constant.rs index cdf499a22f8dd..64e83e43d3272 100644 --- a/src/constant.rs +++ b/src/constant.rs @@ -258,7 +258,7 @@ fn data_id_for_static( ) -> DataId { let attrs = tcx.codegen_fn_attrs(def_id); - let instance = Instance::mono(tcx, def_id).polymorphize(tcx); + let instance = Instance::mono(tcx, def_id); let symbol_name = tcx.symbol_name(instance).name; if let Some(import_linkage) = attrs.import_linkage { diff --git a/src/discriminant.rs b/src/discriminant.rs index 670384663e83f..e7ac084558a5a 100644 --- a/src/discriminant.rs +++ b/src/discriminant.rs @@ -28,16 +28,20 @@ pub(crate) fn codegen_set_discriminant<'tcx>( } => { let ptr = place.place_field(fx, FieldIdx::new(tag_field)); let to = layout.ty.discriminant_for_variant(fx.tcx, variant_index).unwrap().val; - let to = if ptr.layout().abi.is_signed() { - ty::ScalarInt::try_from_int( - ptr.layout().size.sign_extend(to) as i128, - ptr.layout().size, - ) - .unwrap() - } else { - ty::ScalarInt::try_from_uint(to, ptr.layout().size).unwrap() + let to = match ptr.layout().ty.kind() { + ty::Uint(UintTy::U128) | ty::Int(IntTy::I128) => { + let lsb = fx.bcx.ins().iconst(types::I64, to as u64 as i64); + let msb = fx.bcx.ins().iconst(types::I64, (to >> 64) as u64 as i64); + fx.bcx.ins().iconcat(lsb, msb) + } + ty::Uint(_) | ty::Int(_) => { + let clif_ty = fx.clif_type(ptr.layout().ty).unwrap(); + let raw_val = ptr.layout().size.truncate(to); + fx.bcx.ins().iconst(clif_ty, raw_val as i64) + } + _ => unreachable!(), }; - let discr = CValue::const_val(fx, ptr.layout(), to); + let discr = CValue::by_val(to, ptr.layout()); ptr.write_cvalue(fx, discr); } Variants::Multiple { @@ -85,16 +89,21 @@ pub(crate) fn codegen_get_discriminant<'tcx>( .ty .discriminant_for_variant(fx.tcx, *index) .map_or(u128::from(index.as_u32()), |discr| discr.val); - let discr_val = if dest_layout.abi.is_signed() { - ty::ScalarInt::try_from_int( - dest_layout.size.sign_extend(discr_val) as i128, - dest_layout.size, - ) - .unwrap() - } else { - ty::ScalarInt::try_from_uint(discr_val, dest_layout.size).unwrap() + + let val = match dest_layout.ty.kind() { + ty::Uint(UintTy::U128) | ty::Int(IntTy::I128) => { + let lsb = fx.bcx.ins().iconst(types::I64, discr_val as u64 as i64); + let msb = fx.bcx.ins().iconst(types::I64, (discr_val >> 64) as u64 as i64); + fx.bcx.ins().iconcat(lsb, msb) + } + ty::Uint(_) | ty::Int(_) => { + let clif_ty = fx.clif_type(dest_layout.ty).unwrap(); + let raw_val = dest_layout.size.truncate(discr_val); + fx.bcx.ins().iconst(clif_ty, raw_val as i64) + } + _ => unreachable!(), }; - let res = CValue::const_val(fx, dest_layout, discr_val); + let res = CValue::by_val(val, dest_layout); dest.write_cvalue(fx, res); return; } diff --git a/src/driver/aot.rs b/src/driver/aot.rs index e8c96486041b1..fce4690f97dc9 100644 --- a/src/driver/aot.rs +++ b/src/driver/aot.rs @@ -15,6 +15,7 @@ use rustc_codegen_ssa::errors as ssa_errors; use rustc_codegen_ssa::{CodegenResults, CompiledModule, CrateInfo, ModuleKind}; use rustc_data_structures::profiling::SelfProfilerRef; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; +use rustc_data_structures::sync::{par_map, IntoDynSyncSend}; use rustc_metadata::fs::copy_to_stdout; use rustc_metadata::EncodedMetadata; use rustc_middle::dep_graph::{WorkProduct, WorkProductId}; @@ -481,15 +482,16 @@ fn module_codegen( for (mono_item, _) in mono_items { match mono_item { MonoItem::Fn(inst) => { - let codegened_function = crate::base::codegen_fn( + if let Some(codegened_function) = crate::base::codegen_fn( tcx, &mut cx, &mut type_dbg, Function::new(), &mut module, inst, - ); - codegened_functions.push(codegened_function); + ) { + codegened_functions.push(codegened_function); + } } MonoItem::Static(def_id) => { let data_id = crate::constant::codegen_static(tcx, &mut module, def_id); @@ -604,39 +606,39 @@ pub(crate) fn run_aot( let global_asm_config = Arc::new(crate::global_asm::GlobalAsmConfig::new(tcx)); - let mut concurrency_limiter = ConcurrencyLimiter::new(tcx.sess, cgus.len()); + let (todo_cgus, done_cgus) = + cgus.into_iter().enumerate().partition::, _>(|&(i, _)| match cgu_reuse[i] { + _ if backend_config.disable_incr_cache => true, + CguReuse::No => true, + CguReuse::PreLto | CguReuse::PostLto => false, + }); + + let concurrency_limiter = IntoDynSyncSend(ConcurrencyLimiter::new(tcx.sess, todo_cgus.len())); let modules = tcx.sess.time("codegen mono items", || { - cgus.iter() - .enumerate() - .map(|(i, cgu)| { - let cgu_reuse = - if backend_config.disable_incr_cache { CguReuse::No } else { cgu_reuse[i] }; - match cgu_reuse { - CguReuse::No => { - let dep_node = cgu.codegen_dep_node(tcx); - tcx.dep_graph - .with_task( - dep_node, - tcx, - ( - backend_config.clone(), - global_asm_config.clone(), - cgu.name(), - concurrency_limiter.acquire(tcx.dcx()), - ), - module_codegen, - Some(rustc_middle::dep_graph::hash_result), - ) - .0 - } - CguReuse::PreLto | CguReuse::PostLto => { - concurrency_limiter.job_already_done(); - OngoingModuleCodegen::Sync(reuse_workproduct_for_cgu(tcx, cgu)) - } - } - }) - .collect::>() + let mut modules: Vec<_> = par_map(todo_cgus, |(_, cgu)| { + let dep_node = cgu.codegen_dep_node(tcx); + tcx.dep_graph + .with_task( + dep_node, + tcx, + ( + backend_config.clone(), + global_asm_config.clone(), + cgu.name(), + concurrency_limiter.acquire(tcx.dcx()), + ), + module_codegen, + Some(rustc_middle::dep_graph::hash_result), + ) + .0 + }); + modules.extend( + done_cgus + .into_iter() + .map(|(_, cgu)| OngoingModuleCodegen::Sync(reuse_workproduct_for_cgu(tcx, cgu))), + ); + modules }); let mut allocator_module = make_module(tcx.sess, &backend_config, "allocator_shim".to_string()); @@ -705,6 +707,6 @@ pub(crate) fn run_aot( metadata_module, metadata, crate_info: CrateInfo::new(tcx, target_cpu), - concurrency_limiter, + concurrency_limiter: concurrency_limiter.0, }) } diff --git a/src/driver/jit.rs b/src/driver/jit.rs index 929fa92596dc6..4b149131b61aa 100644 --- a/src/driver/jit.rs +++ b/src/driver/jit.rs @@ -83,13 +83,6 @@ fn create_jit_module( ); crate::allocator::codegen(tcx, &mut jit_module, &mut cx.unwind_context); - crate::main_shim::maybe_create_entry_wrapper( - tcx, - &mut jit_module, - &mut cx.unwind_context, - true, - true, - ); (jit_module, cx) } @@ -153,6 +146,14 @@ pub(crate) fn run_jit(tcx: TyCtxt<'_>, backend_config: BackendConfig) -> ! { tcx.dcx().fatal("Inline asm is not supported in JIT mode"); } + crate::main_shim::maybe_create_entry_wrapper( + tcx, + &mut jit_module, + &mut cx.unwind_context, + true, + true, + ); + tcx.dcx().abort_if_errors(); jit_module.finalize_definitions().unwrap(); @@ -231,16 +232,16 @@ pub(crate) fn codegen_and_compile_fn<'tcx>( crate::PrintOnPanic(|| format!("{:?} {}", instance, tcx.symbol_name(instance).name)); let cached_func = std::mem::replace(&mut cached_context.func, Function::new()); - let codegened_func = crate::base::codegen_fn( + if let Some(codegened_func) = crate::base::codegen_fn( tcx, cx, &mut TypeDebugContext::default(), cached_func, module, instance, - ); - - crate::base::compile_fn(cx, cached_context, module, codegened_func); + ) { + crate::base::compile_fn(cx, cached_context, module, codegened_func); + } }); } diff --git a/src/driver/mod.rs b/src/driver/mod.rs index 12e90b5841034..fb0eed07c1971 100644 --- a/src/driver/mod.rs +++ b/src/driver/mod.rs @@ -5,6 +5,7 @@ //! [`codegen_static`]: crate::constant::codegen_static use rustc_data_structures::profiling::SelfProfilerRef; +use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; use rustc_middle::mir::mono::{MonoItem, MonoItemData}; use crate::prelude::*; @@ -33,7 +34,20 @@ fn predefine_mono_items<'tcx>( data.visibility, is_compiler_builtins, ); - module.declare_function(name, linkage, &sig).unwrap(); + let is_naked = tcx + .codegen_fn_attrs(instance.def_id()) + .flags + .contains(CodegenFnAttrFlags::NAKED); + module + .declare_function( + name, + // Naked functions are defined in a separate object + // file from the codegen unit rustc expects them to + // be defined in. + if is_naked { Linkage::Import } else { linkage }, + &sig, + ) + .unwrap(); } MonoItem::Static(_) | MonoItem::GlobalAsm(_) => {} } diff --git a/src/global_asm.rs b/src/global_asm.rs index 5a0cd3990f2a7..0c99a5ce12f6e 100644 --- a/src/global_asm.rs +++ b/src/global_asm.rs @@ -81,7 +81,7 @@ pub(crate) fn codegen_global_asm_item(tcx: TyCtxt<'_>, global_asm: &mut String, ); } - let instance = Instance::mono(tcx, def_id).polymorphize(tcx); + let instance = Instance::mono(tcx, def_id); let symbol = tcx.symbol_name(instance); global_asm.push_str(symbol.name); } diff --git a/src/inline_asm.rs b/src/inline_asm.rs index 28b92f730da34..2de804f5e0423 100644 --- a/src/inline_asm.rs +++ b/src/inline_asm.rs @@ -127,7 +127,7 @@ pub(crate) fn codegen_inline_asm_terminator<'tcx>( } InlineAsmOperand::SymStatic { def_id } => { assert!(fx.tcx.is_static(def_id)); - let instance = Instance::mono(fx.tcx, def_id).polymorphize(fx.tcx); + let instance = Instance::mono(fx.tcx, def_id); CInlineAsmOperand::Symbol { symbol: fx.tcx.symbol_name(instance).name.to_owned() } } InlineAsmOperand::Label { .. } => { @@ -169,6 +169,7 @@ pub(crate) fn codegen_inline_asm_inner<'tcx>( stack_slots_input: Vec::new(), stack_slots_output: Vec::new(), stack_slot_size: Size::from_bytes(0), + is_naked: false, }; asm_gen.allocate_registers(); asm_gen.allocate_stack_slots(); @@ -209,6 +210,121 @@ pub(crate) fn codegen_inline_asm_inner<'tcx>( call_inline_asm(fx, &asm_name, asm_gen.stack_slot_size, inputs, outputs); } +pub(crate) fn codegen_naked_asm<'tcx>( + tcx: TyCtxt<'tcx>, + cx: &mut crate::CodegenCx, + module: &mut dyn Module, + instance: Instance<'tcx>, + span: Span, + symbol_name: &str, + template: &[InlineAsmTemplatePiece], + operands: &[InlineAsmOperand<'tcx>], + options: InlineAsmOptions, +) { + // FIXME add .eh_frame unwind info directives + + let operands = operands + .iter() + .map(|operand| match *operand { + InlineAsmOperand::In { .. } + | InlineAsmOperand::Out { .. } + | InlineAsmOperand::InOut { .. } => { + span_bug!(span, "invalid operand type for naked asm") + } + InlineAsmOperand::Const { ref value } => { + let cv = instance.instantiate_mir_and_normalize_erasing_regions( + tcx, + ty::ParamEnv::reveal_all(), + ty::EarlyBinder::bind(value.const_), + ); + let const_value = cv + .eval(tcx, ty::ParamEnv::reveal_all(), value.span) + .expect("erroneous constant missed by mono item collection"); + + let value = rustc_codegen_ssa::common::asm_const_to_str( + tcx, + span, + const_value, + RevealAllLayoutCx(tcx).layout_of(cv.ty()), + ); + CInlineAsmOperand::Const { value } + } + InlineAsmOperand::SymFn { ref value } => { + if cfg!(not(feature = "inline_asm_sym")) { + tcx.dcx() + .span_err(span, "asm! and global_asm! sym operands are not yet supported"); + } + + let const_ = instance.instantiate_mir_and_normalize_erasing_regions( + tcx, + ty::ParamEnv::reveal_all(), + ty::EarlyBinder::bind(value.const_), + ); + if let ty::FnDef(def_id, args) = *const_.ty().kind() { + let instance = ty::Instance::resolve_for_fn_ptr( + tcx, + ty::ParamEnv::reveal_all(), + def_id, + args, + ) + .unwrap(); + let symbol = tcx.symbol_name(instance); + + // Pass a wrapper rather than the function itself as the function itself may not + // be exported from the main codegen unit and may thus be unreachable from the + // object file created by an external assembler. + let inline_asm_index = cx.inline_asm_index.get(); + cx.inline_asm_index.set(inline_asm_index + 1); + let wrapper_name = format!( + "__inline_asm_{}_wrapper_n{}", + cx.cgu_name.as_str().replace('.', "__").replace('-', "_"), + inline_asm_index + ); + let sig = + get_function_sig(tcx, module.target_config().default_call_conv, instance); + create_wrapper_function( + module, + &mut cx.unwind_context, + sig, + &wrapper_name, + symbol.name, + ); + + CInlineAsmOperand::Symbol { symbol: wrapper_name } + } else { + span_bug!(span, "invalid type for asm sym (fn)"); + } + } + InlineAsmOperand::SymStatic { def_id } => { + assert!(tcx.is_static(def_id)); + let instance = Instance::mono(tcx, def_id); + CInlineAsmOperand::Symbol { symbol: tcx.symbol_name(instance).name.to_owned() } + } + InlineAsmOperand::Label { .. } => { + span_bug!(span, "asm! label operands are not yet supported"); + } + }) + .collect::>(); + + let asm_gen = InlineAssemblyGenerator { + tcx, + arch: tcx.sess.asm_arch.unwrap(), + enclosing_def_id: instance.def_id(), + template, + operands: &operands, + options, + registers: Vec::new(), + stack_slots_clobber: Vec::new(), + stack_slots_input: Vec::new(), + stack_slots_output: Vec::new(), + stack_slot_size: Size::from_bytes(0), + is_naked: true, + }; + + let generated_asm = asm_gen.generate_asm_wrapper(symbol_name); + cx.global_asm.push_str(&generated_asm); +} + struct InlineAssemblyGenerator<'a, 'tcx> { tcx: TyCtxt<'tcx>, arch: InlineAsmArch, @@ -221,10 +337,13 @@ struct InlineAssemblyGenerator<'a, 'tcx> { stack_slots_input: Vec>, stack_slots_output: Vec>, stack_slot_size: Size, + is_naked: bool, } impl<'tcx> InlineAssemblyGenerator<'_, 'tcx> { fn allocate_registers(&mut self) { + assert!(!self.is_naked); + let sess = self.tcx.sess; let map = allocatable_registers( self.arch, @@ -348,6 +467,8 @@ impl<'tcx> InlineAssemblyGenerator<'_, 'tcx> { } fn allocate_stack_slots(&mut self) { + assert!(!self.is_naked); + let mut slot_size = Size::from_bytes(0); let mut slots_clobber = vec![None; self.operands.len()]; let mut slots_input = vec![None; self.operands.len()]; @@ -468,30 +589,32 @@ impl<'tcx> InlineAssemblyGenerator<'_, 'tcx> { if is_x86 { generated_asm.push_str(".intel_syntax noprefix\n"); } - Self::prologue(&mut generated_asm, self.arch); + if !self.is_naked { + Self::prologue(&mut generated_asm, self.arch); + + // Save clobbered registers + if !self.options.contains(InlineAsmOptions::NORETURN) { + for (reg, slot) in self + .registers + .iter() + .zip(self.stack_slots_clobber.iter().copied()) + .filter_map(|(r, s)| r.zip(s)) + { + Self::save_register(&mut generated_asm, self.arch, reg, slot); + } + } - // Save clobbered registers - if !self.options.contains(InlineAsmOptions::NORETURN) { + // Write input registers for (reg, slot) in self .registers .iter() - .zip(self.stack_slots_clobber.iter().copied()) + .zip(self.stack_slots_input.iter().copied()) .filter_map(|(r, s)| r.zip(s)) { - Self::save_register(&mut generated_asm, self.arch, reg, slot); + Self::restore_register(&mut generated_asm, self.arch, reg, slot); } } - // Write input registers - for (reg, slot) in self - .registers - .iter() - .zip(self.stack_slots_input.iter().copied()) - .filter_map(|(r, s)| r.zip(s)) - { - Self::restore_register(&mut generated_asm, self.arch, reg, slot); - } - if is_x86 && self.options.contains(InlineAsmOptions::ATT_SYNTAX) { generated_asm.push_str(".att_syntax\n"); } @@ -553,30 +676,32 @@ impl<'tcx> InlineAssemblyGenerator<'_, 'tcx> { generated_asm.push_str(".intel_syntax noprefix\n"); } - if !self.options.contains(InlineAsmOptions::NORETURN) { - // Read output registers - for (reg, slot) in self - .registers - .iter() - .zip(self.stack_slots_output.iter().copied()) - .filter_map(|(r, s)| r.zip(s)) - { - Self::save_register(&mut generated_asm, self.arch, reg, slot); - } + if !self.is_naked { + if !self.options.contains(InlineAsmOptions::NORETURN) { + // Read output registers + for (reg, slot) in self + .registers + .iter() + .zip(self.stack_slots_output.iter().copied()) + .filter_map(|(r, s)| r.zip(s)) + { + Self::save_register(&mut generated_asm, self.arch, reg, slot); + } - // Restore clobbered registers - for (reg, slot) in self - .registers - .iter() - .zip(self.stack_slots_clobber.iter().copied()) - .filter_map(|(r, s)| r.zip(s)) - { - Self::restore_register(&mut generated_asm, self.arch, reg, slot); - } + // Restore clobbered registers + for (reg, slot) in self + .registers + .iter() + .zip(self.stack_slots_clobber.iter().copied()) + .filter_map(|(r, s)| r.zip(s)) + { + Self::restore_register(&mut generated_asm, self.arch, reg, slot); + } - Self::epilogue(&mut generated_asm, self.arch); - } else { - Self::epilogue_noreturn(&mut generated_asm, self.arch); + Self::epilogue(&mut generated_asm, self.arch); + } else { + Self::epilogue_noreturn(&mut generated_asm, self.arch); + } } if is_x86 { diff --git a/src/intrinsics/llvm_x86.rs b/src/intrinsics/llvm_x86.rs index 8df83c706a100..27b55ecc72eef 100644 --- a/src/intrinsics/llvm_x86.rs +++ b/src/intrinsics/llvm_x86.rs @@ -374,6 +374,21 @@ pub(crate) fn codegen_x86_llvm_intrinsic_call<'tcx>( } } } + "llvm.x86.avx2.permd" => { + // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm256_permutevar8x32_epi32 + intrinsic_args!(fx, args => (a, idx); intrinsic); + + for j in 0..=7 { + let index = idx.value_typed_lane(fx, fx.tcx.types.u32, j).load_scalar(fx); + let index = fx.bcx.ins().uextend(fx.pointer_type, index); + let value = a.value_lane_dyn(fx, index).load_scalar(fx); + ret.place_typed_lane(fx, fx.tcx.types.u32, j).to_ptr().store( + fx, + value, + MemFlags::trusted(), + ); + } + } "llvm.x86.avx2.vperm2i128" | "llvm.x86.avx.vperm2f128.ps.256" | "llvm.x86.avx.vperm2f128.pd.256" => { @@ -832,6 +847,43 @@ pub(crate) fn codegen_x86_llvm_intrinsic_call<'tcx>( } } + "llvm.x86.sse42.crc32.32.8" + | "llvm.x86.sse42.crc32.32.16" + | "llvm.x86.sse42.crc32.32.32" + | "llvm.x86.sse42.crc32.64.64" => { + // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#ig_expand=1419&text=_mm_crc32_u32 + intrinsic_args!(fx, args => (crc, v); intrinsic); + + let crc = crc.load_scalar(fx); + let v = v.load_scalar(fx); + + let asm = match intrinsic { + "llvm.x86.sse42.crc32.32.8" => "crc32 eax, dl", + "llvm.x86.sse42.crc32.32.16" => "crc32 eax, dx", + "llvm.x86.sse42.crc32.32.32" => "crc32 eax, edx", + "llvm.x86.sse42.crc32.64.64" => "crc32 rax, rdx", + _ => unreachable!(), + }; + + codegen_inline_asm_inner( + fx, + &[InlineAsmTemplatePiece::String(asm.to_string())], + &[ + CInlineAsmOperand::InOut { + reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::ax)), + _late: true, + in_value: crc, + out_place: Some(ret), + }, + CInlineAsmOperand::In { + reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::dx)), + value: v, + }, + ], + InlineAsmOptions::NOSTACK | InlineAsmOptions::PURE | InlineAsmOptions::NOMEM, + ); + } + "llvm.x86.sse42.pcmpestri128" => { // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_cmpestri&ig_expand=939 intrinsic_args!(fx, args => (a, la, b, lb, _imm8); intrinsic); diff --git a/src/lib.rs b/src/lib.rs index e72951b6f3447..39bbad16b0c00 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -331,9 +331,9 @@ fn build_isa(sess: &Session, backend_config: &BackendConfig) -> Arc CValue<'tcx> { let clif_ty = fx.clif_type(layout.ty).unwrap(); - if let ty::Bool = layout.ty.kind() { - assert!( - const_val == ty::ScalarInt::FALSE || const_val == ty::ScalarInt::TRUE, - "Invalid bool 0x{:032X}", - const_val - ); - } - let val = match layout.ty.kind() { ty::Uint(UintTy::U128) | ty::Int(IntTy::I128) => { let const_val = const_val.assert_bits(layout.size); diff --git a/y.cmd b/y.cmd index e9b688645a4d8..42106849163b5 100644 --- a/y.cmd +++ b/y.cmd @@ -1,8 +1,6 @@ @echo off echo [BUILD] build system >&2 -mkdir build 2>nul -rustc build_system/main.rs -o build\y.exe -Cdebuginfo=1 --edition 2021 || goto :error -build\y.exe %* || goto :error +cargo run --manifest-path build_system/Cargo.toml -- %* || goto :error goto :EOF :error diff --git a/y.ps1 b/y.ps1 old mode 100644 new mode 100755 index 02ef0fcbd50f1..821f0ec6e5777 --- a/y.ps1 +++ b/y.ps1 @@ -1,12 +1,7 @@ $ErrorActionPreference = "Stop" $host.ui.WriteErrorLine("[BUILD] build system") -New-Item -ItemType Directory -Force -Path build | Out-Null -& rustc build_system/main.rs -o build\y.exe -Cdebuginfo=1 --edition 2021 -if ($LASTEXITCODE -ne 0) { - exit $LASTEXITCODE -} -& build\y.exe $args +& cargo run --manifest-path build_system/Cargo.toml -- $args if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE } diff --git a/y.sh b/y.sh index bc925a23e2a88..b9152d2cc6de0 100755 --- a/y.sh +++ b/y.sh @@ -2,5 +2,4 @@ set -e echo "[BUILD] build system" 1>&2 -rustc build_system/main.rs -o y.bin -Cdebuginfo=1 --edition 2021 -exec ./y.bin "$@" +exec cargo run --manifest-path build_system/Cargo.toml -- "$@" From 8aa7112c82416cfaf0fb63db2467d45fdb0407bc Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Fri, 17 May 2024 14:17:48 -0300 Subject: [PATCH 129/892] Rename Unsafe to Safety --- src/value_and_place.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/value_and_place.rs b/src/value_and_place.rs index b6d6d211e658c..4146137c2263a 100644 --- a/src/value_and_place.rs +++ b/src/value_and_place.rs @@ -872,7 +872,7 @@ pub(crate) fn assert_assignable<'tcx>( let FnSig { inputs_and_output: types_from, c_variadic: c_variadic_from, - unsafety: unsafety_from, + safety: unsafety_from, abi: abi_from, } = from_sig; let to_sig = fx @@ -881,7 +881,7 @@ pub(crate) fn assert_assignable<'tcx>( let FnSig { inputs_and_output: types_to, c_variadic: c_variadic_to, - unsafety: unsafety_to, + safety: unsafety_to, abi: abi_to, } = to_sig; let mut types_from = types_from.iter(); From 21f58e4bc41a7311343c21b9aa3ee82ff1b6089f Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Fri, 17 May 2024 14:17:48 -0300 Subject: [PATCH 130/892] Rename Unsafe to Safety --- src/intrinsic/mod.rs | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/intrinsic/mod.rs b/src/intrinsic/mod.rs index 451e5258ebd19..43f12b514affa 100644 --- a/src/intrinsic/mod.rs +++ b/src/intrinsic/mod.rs @@ -670,11 +670,7 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { let step3 = self.or(left, right); // Fourth step. - if width == 8 { - step3 - } else { - self.gcc_bswap(step3, width) - } + if width == 8 { step3 } else { self.gcc_bswap(step3, width) } } 128 => { // TODO(antoyo): find a more efficient implementation? @@ -1225,7 +1221,7 @@ fn get_rust_try_fn<'a, 'gcc, 'tcx>( iter::once(i8p), tcx.types.unit, false, - rustc_hir::Unsafety::Unsafe, + rustc_hir::Safety::Unsafe, Abi::Rust, )), ); @@ -1236,7 +1232,7 @@ fn get_rust_try_fn<'a, 'gcc, 'tcx>( [i8p, i8p].iter().cloned(), tcx.types.unit, false, - rustc_hir::Unsafety::Unsafe, + rustc_hir::Safety::Unsafe, Abi::Rust, )), ); @@ -1245,7 +1241,7 @@ fn get_rust_try_fn<'a, 'gcc, 'tcx>( [try_fn_ty, i8p, catch_fn_ty], tcx.types.i32, false, - rustc_hir::Unsafety::Unsafe, + rustc_hir::Safety::Unsafe, Abi::Rust, )); let rust_try = gen_fn(cx, "__rust_try", rust_fn_sig, codegen); From 6965b4a8bd9f06aa956db21058092da9421f4ceb Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Thu, 16 May 2024 02:07:31 -0700 Subject: [PATCH 131/892] Remove `Rvalue::CheckedBinaryOp` --- src/base.rs | 13 +++++-------- src/codegen_i128.rs | 2 ++ src/num.rs | 3 +++ 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/base.rs b/src/base.rs index 5846689643fdd..8d778f736d671 100644 --- a/src/base.rs +++ b/src/base.rs @@ -609,14 +609,11 @@ fn codegen_stmt<'tcx>( let lhs = codegen_operand(fx, &lhs_rhs.0); let rhs = codegen_operand(fx, &lhs_rhs.1); - let res = crate::num::codegen_binop(fx, bin_op, lhs, rhs); - lval.write_cvalue(fx, res); - } - Rvalue::CheckedBinaryOp(bin_op, ref lhs_rhs) => { - let lhs = codegen_operand(fx, &lhs_rhs.0); - let rhs = codegen_operand(fx, &lhs_rhs.1); - - let res = crate::num::codegen_checked_int_binop(fx, bin_op, lhs, rhs); + let res = if let Some(bin_op) = bin_op.overflowing_to_wrapping() { + crate::num::codegen_checked_int_binop(fx, bin_op, lhs, rhs) + } else { + crate::num::codegen_binop(fx, bin_op, lhs, rhs) + }; lval.write_cvalue(fx, res); } Rvalue::UnaryOp(un_op, ref operand) => { diff --git a/src/codegen_i128.rs b/src/codegen_i128.rs index 4a5ef352151f3..e16b77648d12f 100644 --- a/src/codegen_i128.rs +++ b/src/codegen_i128.rs @@ -70,6 +70,7 @@ pub(crate) fn maybe_codegen<'tcx>( } BinOp::Lt | BinOp::Le | BinOp::Eq | BinOp::Ge | BinOp::Gt | BinOp::Ne | BinOp::Cmp => None, BinOp::Shl | BinOp::ShlUnchecked | BinOp::Shr | BinOp::ShrUnchecked => None, + BinOp::AddWithOverflow | BinOp::SubWithOverflow | BinOp::MulWithOverflow => unreachable!(), } } @@ -132,6 +133,7 @@ pub(crate) fn maybe_codegen_checked<'tcx>( Some(out_place.to_cvalue(fx)) } BinOp::AddUnchecked | BinOp::SubUnchecked | BinOp::MulUnchecked => unreachable!(), + BinOp::AddWithOverflow | BinOp::SubWithOverflow | BinOp::MulWithOverflow => unreachable!(), BinOp::Offset => unreachable!("offset should only be used on pointers, not 128bit ints"), BinOp::Div | BinOp::Rem => unreachable!(), BinOp::Cmp => unreachable!(), diff --git a/src/num.rs b/src/num.rs index 4d96a26ea4fa8..fb18f45d7dcad 100644 --- a/src/num.rs +++ b/src/num.rs @@ -179,6 +179,9 @@ pub(crate) fn codegen_int_binop<'tcx>( } } BinOp::Offset => unreachable!("Offset is not an integer operation"), + BinOp::AddWithOverflow | BinOp::SubWithOverflow | BinOp::MulWithOverflow => { + unreachable!("Overflow binops handled by `codegen_checked_int_binop`") + } // Compare binops handles by `codegen_binop`. BinOp::Eq | BinOp::Ne | BinOp::Lt | BinOp::Le | BinOp::Gt | BinOp::Ge | BinOp::Cmp => { unreachable!("{:?}({:?}, {:?})", bin_op, in_lhs.layout().ty, in_rhs.layout().ty); From bff31bdcbc016c425f5027d7b15e3a1aad8a717c Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sun, 19 May 2024 13:22:06 +0000 Subject: [PATCH 132/892] Rustup to rustc 1.80.0-nightly (b1ec1bd65 2024-05-18) --- rust-toolchain | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-toolchain b/rust-toolchain index a2ba79cbe9038..9726708ce106d 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2024-05-13" +channel = "nightly-2024-05-19" components = ["rust-src", "rustc-dev", "llvm-tools"] From 8cea8a78409ae5db5ac5d9f15bd4497d5bba0734 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sun, 19 May 2024 13:37:01 +0000 Subject: [PATCH 133/892] Fix rustc test suite --- scripts/test_rustc_tests.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/test_rustc_tests.sh b/scripts/test_rustc_tests.sh index 689cda21643cb..ec29efa05fb13 100755 --- a/scripts/test_rustc_tests.sh +++ b/scripts/test_rustc_tests.sh @@ -60,13 +60,13 @@ rm tests/ui/asm/x86_64/goto.rs # inline asm labels not supported # requires LTO rm -r tests/run-make/cdylib -rm -r tests/run-make/issue-14500 rm -r tests/run-make/issue-64153 rm -r tests/run-make/codegen-options-parsing rm -r tests/run-make/lto-* rm -r tests/run-make/reproducible-build-2 rm -r tests/run-make/issue-109934-lto-debuginfo rm -r tests/run-make/no-builtins-lto +rm -r tests/run-make/reachable-extern-fn-available-lto # optimization tests # ================== From 7a53ba2e764d4e953ec654b73a6222163482db88 Mon Sep 17 00:00:00 2001 From: Jubilee Young Date: Sun, 19 May 2024 18:50:42 -0700 Subject: [PATCH 134/892] cg_clif: support simd_ctpop --- src/intrinsics/simd.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/intrinsics/simd.rs b/src/intrinsics/simd.rs index 452b5988dab4c..b17f191ce267e 100644 --- a/src/intrinsics/simd.rs +++ b/src/intrinsics/simd.rs @@ -348,6 +348,7 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>( | sym::simd_bswap | sym::simd_bitreverse | sym::simd_ctlz + | sym::simd_ctpop | sym::simd_cttz => { intrinsic_args!(fx, args => (a); intrinsic); @@ -367,6 +368,7 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>( (ty::Uint(_) | ty::Int(_), sym::simd_bswap) => fx.bcx.ins().bswap(lane), (ty::Uint(_) | ty::Int(_), sym::simd_bitreverse) => fx.bcx.ins().bitrev(lane), (ty::Uint(_) | ty::Int(_), sym::simd_ctlz) => fx.bcx.ins().clz(lane), + (ty::Uint(_) | ty::Int(_), sym::simd_ctpop) => fx.bcx.ins().popcnt(lane), (ty::Uint(_) | ty::Int(_), sym::simd_cttz) => fx.bcx.ins().ctz(lane), _ => unreachable!(), From 39daa5a182dfd6eabd803066cce09353116628e2 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Mon, 20 May 2024 20:26:12 +0000 Subject: [PATCH 135/892] Update to Cranelift 0.108 --- Cargo.lock | 54 ++++++++++++++++++++++++++++-------------------------- Cargo.toml | 12 ++++++------ 2 files changed, 34 insertions(+), 32 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 33fe52ddbdd64..b95ab0a7f177a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -46,18 +46,18 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "cranelift-bforest" -version = "0.107.0" +version = "0.108.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79b27922a6879b5b5361d0a084cb0b1941bf109a98540addcb932da13b68bed4" +checksum = "f75f0946f5e307e5dbf22e8bc0bd9bc5336a4f0240a4af4751c007a0cbf84917" dependencies = [ "cranelift-entity", ] [[package]] name = "cranelift-codegen" -version = "0.107.0" +version = "0.108.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "304c455b28bf56372729acb356afbb55d622f2b0f2f7837aa5e57c138acaac4d" +checksum = "a6b0a01705ef466bbc64e10af820f935f77256bcb14a40dde1e10b7a0969ce11" dependencies = [ "bumpalo", "cranelift-bforest", @@ -70,45 +70,46 @@ dependencies = [ "hashbrown 0.14.3", "log", "regalloc2", + "rustc-hash", "smallvec", "target-lexicon", ] [[package]] name = "cranelift-codegen-meta" -version = "0.107.0" +version = "0.108.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1653c56b99591d07f67c5ca7f9f25888948af3f4b97186bff838d687d666f613" +checksum = "2cdaeff01606190dcccd13cf3d80b8d5f1f197812ba7bba1196ae08bd8e82592" dependencies = [ "cranelift-codegen-shared", ] [[package]] name = "cranelift-codegen-shared" -version = "0.107.0" +version = "0.108.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5b6a9cf6b6eb820ee3f973a0db313c05dc12d370f37b4fe9630286e1672573f" +checksum = "cefa0243350ce9667f3320579c8a2c3dd3d1f9943e8ab2eb1d4ca533ccc1db57" [[package]] name = "cranelift-control" -version = "0.107.0" +version = "0.108.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9d06e6bf30075fb6bed9e034ec046475093392eea1aff90eb5c44c4a033d19a" +checksum = "fa46a2d3331aa33cbd399665d6ea0f431f726a55fb69fdf897035cf5fe0a3301" dependencies = [ "arbitrary", ] [[package]] name = "cranelift-entity" -version = "0.107.0" +version = "0.108.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29be04f931b73cdb9694874a295027471817f26f26d2f0ebe5454153176b6e3a" +checksum = "9e8f7cc083e6d01d656283f293ec361ce7bae05eca896f3a932d42dad1850578" [[package]] name = "cranelift-frontend" -version = "0.107.0" +version = "0.108.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a07fd7393041d7faa2f37426f5dc7fc04003b70988810e8c063beefeff1cd8f9" +checksum = "8490d83b85eeec14ebf3b4c0b0ebc33600f1943514b1406a7b99b85d8b80e4c0" dependencies = [ "cranelift-codegen", "log", @@ -118,15 +119,15 @@ dependencies = [ [[package]] name = "cranelift-isle" -version = "0.107.0" +version = "0.108.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f341d7938caa6dff8149dac05bb2b53fc680323826b83b4cf175ab9f5139a3c9" +checksum = "e617871f2347ca078a31d61acaf7de961852447e6009afa5be6e4df6d5785dd4" [[package]] name = "cranelift-jit" -version = "0.107.0" +version = "0.108.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42733555e06433f1461570e09dbd756dafc228b4dac75c597cdbdc518de07522" +checksum = "2d396c6f5cde59c1e408d813426d2332031692152432e12f4de63a936c6c10c7" dependencies = [ "anyhow", "cranelift-codegen", @@ -144,9 +145,9 @@ dependencies = [ [[package]] name = "cranelift-module" -version = "0.107.0" +version = "0.108.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84950af02bb85f3da764d53a953b43bb29a732e793d4fe24637a61591be9a024" +checksum = "7067c2b072829bb35f19f9e99eb42b6982faf4339adb2946797728ff0bd6a089" dependencies = [ "anyhow", "cranelift-codegen", @@ -155,9 +156,9 @@ dependencies = [ [[package]] name = "cranelift-native" -version = "0.107.0" +version = "0.108.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82af6066e6448d26eeabb7aa26a43f7ff79f8217b06bade4ee6ef230aecc8880" +checksum = "add05ee8162778fd7b545e0935f4a5c0c95afdac003362e040ef0229227ae967" dependencies = [ "cranelift-codegen", "libc", @@ -166,9 +167,9 @@ dependencies = [ [[package]] name = "cranelift-object" -version = "0.107.0" +version = "0.108.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00af56107039ed150391df6f753298c7b08f2b6a2e0727d216b5fa599d684d8b" +checksum = "d8a09bc240fb04674e01382ca505b34e71ea0ee8499a7960cd85f70359873852" dependencies = [ "anyhow", "cranelift-codegen", @@ -410,10 +411,11 @@ checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" [[package]] name = "wasmtime-jit-icache-coherence" -version = "20.0.0" +version = "21.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a9f93a3289057b26dc75eb84d6e60d7694f7d169c7c09597495de6e016a13ff" +checksum = "e6ce46bf24b027e1ede83d14ed544c736d7e939a849c4429551eb27842356c77" dependencies = [ + "anyhow", "cfg-if", "libc", "windows-sys", diff --git a/Cargo.toml b/Cargo.toml index 2015cdbcc2a74..6aaff55023b07 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,12 +8,12 @@ crate-type = ["dylib"] [dependencies] # These have to be in sync with each other -cranelift-codegen = { version = "0.107.0", default-features = false, features = ["std", "unwind", "all-arch"] } -cranelift-frontend = { version = "0.107.0" } -cranelift-module = { version = "0.107.0" } -cranelift-native = { version = "0.107.0" } -cranelift-jit = { version = "0.107.0", optional = true } -cranelift-object = { version = "0.107.0" } +cranelift-codegen = { version = "0.108.0", default-features = false, features = ["std", "unwind", "all-arch"] } +cranelift-frontend = { version = "0.108.0" } +cranelift-module = { version = "0.108.0" } +cranelift-native = { version = "0.108.0" } +cranelift-jit = { version = "0.108.0", optional = true } +cranelift-object = { version = "0.108.0" } target-lexicon = "0.12.0" gimli = { version = "0.28", default-features = false, features = ["write"]} object = { version = "0.33", default-features = false, features = ["std", "read_core", "write", "archive", "coff", "elf", "macho", "pe"] } From 994b58fee7e66c25d4b13a8a95feaff650088301 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 15 Apr 2024 10:45:37 -0400 Subject: [PATCH 136/892] Okay actually check only alias TYPES --- compiler/rustc_trait_selection/src/traits/wf.rs | 12 +++--------- tests/ui/higher-ranked/well-formed-aliases.rs | 8 ++++++++ tests/ui/higher-ranked/well-formed-aliases.stderr | 12 ++++++++++++ 3 files changed, 23 insertions(+), 9 deletions(-) create mode 100644 tests/ui/higher-ranked/well-formed-aliases.rs create mode 100644 tests/ui/higher-ranked/well-formed-aliases.stderr diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index f4189ff090204..57efd2996e409 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -435,12 +435,6 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { } } - /// Pushes the obligations required for an alias (except inherent) to be WF - /// into `self.out`. - fn compute_alias_ty(&mut self, data: ty::AliasTy<'tcx>) { - self.compute_alias_term(data.into()); - } - /// Pushes the obligations required for an alias (except inherent) to be WF /// into `self.out`. fn compute_alias_term(&mut self, data: ty::AliasTerm<'tcx>) { @@ -498,7 +492,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { self.out.extend(obligations); } - self.compute_projection_args(data.args); + data.args.visit_with(self); } fn compute_projection_args(&mut self, args: GenericArgsRef<'tcx>) { @@ -702,8 +696,8 @@ impl<'a, 'tcx> TypeVisitor> for WfPredicates<'a, 'tcx> { } ty::Alias(ty::Projection | ty::Opaque | ty::Weak, data) => { - self.compute_alias_ty(data); - return; // Subtree handled by compute_projection. + let obligations = self.nominal_obligations(data.def_id, data.args); + self.out.extend(obligations); } ty::Alias(ty::Inherent, data) => { self.compute_inherent_projection(data); diff --git a/tests/ui/higher-ranked/well-formed-aliases.rs b/tests/ui/higher-ranked/well-formed-aliases.rs new file mode 100644 index 0000000000000..60e013a54bcd5 --- /dev/null +++ b/tests/ui/higher-ranked/well-formed-aliases.rs @@ -0,0 +1,8 @@ +trait Trait { + type Gat; +} + +fn test(f: for<'a> fn(<&'a T as Trait>::Gat<&'a [str]>)) where for<'a> &'a T: Trait {} +//~^ ERROR the size for values of type `str` cannot be known at compilation time + +fn main() {} diff --git a/tests/ui/higher-ranked/well-formed-aliases.stderr b/tests/ui/higher-ranked/well-formed-aliases.stderr new file mode 100644 index 0000000000000..4a6f4e961d995 --- /dev/null +++ b/tests/ui/higher-ranked/well-formed-aliases.stderr @@ -0,0 +1,12 @@ +error[E0277]: the size for values of type `str` cannot be known at compilation time + --> $DIR/well-formed-aliases.rs:5:52 + | +LL | fn test(f: for<'a> fn(<&'a T as Trait>::Gat<&'a [str]>)) where for<'a> &'a T: Trait {} + | ^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `str` + = note: slice and array elements must have `Sized` type + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. From cae9e7ec6a0f99f1eb1cc4feadbc7105feb60719 Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Wed, 22 May 2024 00:56:57 -0700 Subject: [PATCH 137/892] Stop using `to_hir_binop` in codegen --- src/intrinsic/simd.rs | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/intrinsic/simd.rs b/src/intrinsic/simd.rs index 0c7cffbe7308b..1625e6ecdb701 100644 --- a/src/intrinsic/simd.rs +++ b/src/intrinsic/simd.rs @@ -14,6 +14,7 @@ use rustc_codegen_ssa::mir::operand::OperandRef; use rustc_codegen_ssa::mir::place::PlaceRef; use rustc_codegen_ssa::traits::{BaseTypeMethods, BuilderMethods}; use rustc_hir as hir; +use rustc_middle::mir::BinOp; use rustc_middle::span_bug; use rustc_middle::ty::layout::HasTyCtxt; use rustc_middle::ty::{self, Ty}; @@ -122,12 +123,12 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( let in_ty = arg_tys[0]; let comparison = match name { - sym::simd_eq => Some(hir::BinOpKind::Eq), - sym::simd_ne => Some(hir::BinOpKind::Ne), - sym::simd_lt => Some(hir::BinOpKind::Lt), - sym::simd_le => Some(hir::BinOpKind::Le), - sym::simd_gt => Some(hir::BinOpKind::Gt), - sym::simd_ge => Some(hir::BinOpKind::Ge), + sym::simd_eq => Some(BinOp::Eq), + sym::simd_ne => Some(BinOp::Ne), + sym::simd_lt => Some(BinOp::Lt), + sym::simd_le => Some(BinOp::Le), + sym::simd_gt => Some(BinOp::Gt), + sym::simd_ge => Some(BinOp::Ge), _ => None, }; From 29fc479a302a97a4c923076cc6211151aa802691 Mon Sep 17 00:00:00 2001 From: Augie Fackler Date: Fri, 19 Jan 2024 14:42:43 -0500 Subject: [PATCH 138/892] rustc_codegen_llvm: add support for writing summary bitcode Typical uses of ThinLTO don't have any use for this as a standalone file, but distributed ThinLTO uses this to make the linker phase more efficient. With clang you'd do something like `clang -flto=thin -fthin-link-bitcode=foo.indexing.o -c foo.c` and then get both foo.o (full of bitcode) and foo.indexing.o (just the summary or index part of the bitcode). That's then usable by a two-stage linking process that's more friendly to distributed build systems like bazel, which is why I'm working on this area. I talked some to @teresajohnson about naming in this area, as things seem to be a little confused between various blog posts and build systems. "bitcode index" and "bitcode summary" tend to be a little too ambiguous, and she tends to use "thin link bitcode" and "minimized bitcode" (which matches the descriptions in LLVM). Since the clang option is thin-link-bitcode, I went with that to try and not add a new spelling in the world. Per @dtolnay, you can work around the lack of this by using `lld --thinlto-index-only` to do the indexing on regular .o files of bitcode, but that is a bit wasteful on actions when we already have all the information in rustc and could just write out the matching minimized bitcode. I didn't test that at all in our infrastructure, because by the time I learned that I already had this patch largely written. --- src/lib.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/lib.rs b/src/lib.rs index 3f2fadce9e4d5..d786d5116ce73 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -335,6 +335,10 @@ impl ThinBufferMethods for ThinBuffer { fn data(&self) -> &[u8] { unimplemented!(); } + + fn thin_link_data(&self) -> &[u8] { + unimplemented!(); + } } pub struct GccContext { From 715f2264a9cfc79bab3e6c5bc4f2f7608c4a7af4 Mon Sep 17 00:00:00 2001 From: Augie Fackler Date: Fri, 19 Jan 2024 14:42:43 -0500 Subject: [PATCH 139/892] rustc_codegen_llvm: add support for writing summary bitcode Typical uses of ThinLTO don't have any use for this as a standalone file, but distributed ThinLTO uses this to make the linker phase more efficient. With clang you'd do something like `clang -flto=thin -fthin-link-bitcode=foo.indexing.o -c foo.c` and then get both foo.o (full of bitcode) and foo.indexing.o (just the summary or index part of the bitcode). That's then usable by a two-stage linking process that's more friendly to distributed build systems like bazel, which is why I'm working on this area. I talked some to @teresajohnson about naming in this area, as things seem to be a little confused between various blog posts and build systems. "bitcode index" and "bitcode summary" tend to be a little too ambiguous, and she tends to use "thin link bitcode" and "minimized bitcode" (which matches the descriptions in LLVM). Since the clang option is thin-link-bitcode, I went with that to try and not add a new spelling in the world. Per @dtolnay, you can work around the lack of this by using `lld --thinlto-index-only` to do the indexing on regular .o files of bitcode, but that is a bit wasteful on actions when we already have all the information in rustc and could just write out the matching minimized bitcode. I didn't test that at all in our infrastructure, because by the time I learned that I already had this patch largely written. --- src/driver/aot.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/driver/aot.rs b/src/driver/aot.rs index fce4690f97dc9..394c810176ab2 100644 --- a/src/driver/aot.rs +++ b/src/driver/aot.rs @@ -200,7 +200,7 @@ fn produce_final_output_artifacts( // to get rid of it. for output_type in crate_output.outputs.keys() { match *output_type { - OutputType::Bitcode => { + OutputType::Bitcode | OutputType::ThinLinkBitcode => { // Cranelift doesn't have bitcode // user_wants_bitcode = true; // // Copy to .bc, but always keep the .0.bc. There is a later From 8bb463ae11586bb40a4e26cac1a2e2485cd98e58 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 23 May 2024 12:25:11 +0000 Subject: [PATCH 140/892] Rustup to rustc 1.80.0-nightly (9cdfe285c 2024-05-22) --- rust-toolchain | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-toolchain b/rust-toolchain index 9726708ce106d..a1a7214c9060c 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2024-05-19" +channel = "nightly-2024-05-23" components = ["rust-src", "rustc-dev", "llvm-tools"] From ba8c695326e24498ff8794da1c5bf5c7d2c43f04 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 23 May 2024 12:40:09 +0000 Subject: [PATCH 141/892] Stop passing --check-cfg to rustc The standard library now has the right configs in it's Cargo.toml --- build_system/build_sysroot.rs | 35 ----------------------------------- 1 file changed, 35 deletions(-) diff --git a/build_system/build_sysroot.rs b/build_system/build_sysroot.rs index 196ff8fda7544..dfbe0f51e7be2 100644 --- a/build_system/build_sysroot.rs +++ b/build_system/build_sysroot.rs @@ -267,10 +267,6 @@ fn build_clif_sysroot_for_triple( prefix.to_str().unwrap() )); } - rustflags.push("-Zunstable-options".to_owned()); - for (name, values) in EXTRA_CHECK_CFGS { - rustflags.push(check_cfg_arg(name, *values)); - } compiler.rustflags.extend(rustflags); let mut build_cmd = STANDARD_LIBRARY.build(&compiler, dirs); if channel == "release" { @@ -330,34 +326,3 @@ fn build_rtstartup(dirs: &Dirs, compiler: &Compiler) -> Option { Some(target_libs) } - -// Copied from https://github.com/rust-lang/rust/blob/4fd98a4b1b100f5329c6efae18031791f64372d2/src/bootstrap/src/utils/helpers.rs#L569-L585 -/// Create a `--check-cfg` argument invocation for a given name -/// and it's values. -fn check_cfg_arg(name: &str, values: Option<&[&str]>) -> String { - // Creating a string of the values by concatenating each value: - // ',values("tvos","watchos")' or '' (nothing) when there are no values. - let next = match values { - Some(values) => { - let mut tmp = values.iter().flat_map(|val| [",", "\"", val, "\""]).collect::(); - - tmp.insert_str(1, "values("); - tmp.push(')'); - tmp - } - None => "".to_string(), - }; - format!("--check-cfg=cfg({name}{next})") -} - -const EXTRA_CHECK_CFGS: &[(&str, Option<&[&str]>)] = &[ - ("bootstrap", None), - ("stdarch_intel_sde", None), - ("no_fp_fmt_parse", None), - ("no_global_oom_handling", None), - ("no_rc", None), - ("no_sync", None), - ("netbsd10", None), - ("backtrace_in_libstd", None), - ("target_arch", Some(&["xtensa"])), -]; From 4a79b06f83fa370848ea6a3adb8093f485ee8d06 Mon Sep 17 00:00:00 2001 From: Augie Fackler Date: Thu, 23 May 2024 15:23:21 -0400 Subject: [PATCH 142/892] rustc_codegen_gcc: fix changed method signature --- src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index d786d5116ce73..b1785e150adc5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -418,7 +418,7 @@ impl WriteBackendMethods for GccCodegenBackend { back::write::codegen(cgcx, dcx, module, config) } - fn prepare_thin(_module: ModuleCodegen) -> (String, Self::ThinBuffer) { + fn prepare_thin(_module: ModuleCodegen, _emit_summary: bool) -> (String, Self::ThinBuffer) { unimplemented!(); } From b13943ed4227ac0b51aeb117aae1fa4793c11916 Mon Sep 17 00:00:00 2001 From: Gerson <71728860+Gerson2102@users.noreply.github.com> Date: Mon, 27 May 2024 10:08:20 -0600 Subject: [PATCH 143/892] adding more env vars (#523) --- Readme.md | 32 ++++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/Readme.md b/Readme.md index 607a16cc20975..01b00273ccb36 100644 --- a/Readme.md +++ b/Readme.md @@ -16,6 +16,10 @@ A secondary goal is to check if using the gcc backend will provide any run-time **rustup:** Follow the instructions on the official [website](https://www.rust-lang.org/tools/install) +**DejaGnu:** Consider to install DejaGnu which is necessary for running the libgccjit test suite. [website](https://www.gnu.org/software/dejagnu/#downloading) + + + ## Building **This requires a patched libgccjit in order to work. @@ -143,16 +147,32 @@ $ LIBRARY_PATH="[gcc-path value]" LD_LIBRARY_PATH="[gcc-path value]" rustc +$(ca ## Env vars
-
CG_GCCJIT_INCR_CACHE_DISABLED
-
Don't cache object files in the incremental cache. Useful during development of cg_gccjit - to make it possible to use incremental mode for all analyses performed by rustc without caching - object files when their content should have been changed by a change to cg_gccjit.
-
CG_GCCJIT_DISPLAY_CG_TIME
-
Display the time it took to perform codegen for a crate
+
CG_GCCJIT_DUMP_ALL_MODULES
+
Enables dumping of all compilation modules. When set to "1", a dump is created for each module during compilation and stored in `/tmp/reproducers/`.
+
CG_GCCJIT_DUMP_MODULE
+
Enables dumping of a specific module. When set with the module name, e.g., `CG_GCCJIT_DUMP_MODULE=module_name`, a dump of that specific module is created in `/tmp/reproducers/`.
CG_RUSTFLAGS
Send additional flags to rustc. Can be used to build the sysroot without unwinding by setting `CG_RUSTFLAGS=-Cpanic=abort`.
CG_GCCJIT_DUMP_TO_FILE
Dump a C-like representation to /tmp/gccjit_dumps and enable debug info in order to debug this C-like representation.
+
CG_GCCJIT_DUMP_RTL
+
Dumps RTL (Register Transfer Language) for virtual registers.
+
CG_GCCJIT_DUMP_RTL_ALL
+
Dumps all RTL passes.
+
CG_GCCJIT_DUMP_TREE_ALL
+
Dumps all tree (GIMPLE) passes.
+
CG_GCCJIT_DUMP_IPA_ALL
+
Dumps all Interprocedural Analysis (IPA) passes.
+
CG_GCCJIT_DUMP_CODE
+
Dumps the final generated code.
+
CG_GCCJIT_DUMP_GIMPLE
+
Dumps the initial GIMPLE representation.
+
CG_GCCJIT_DUMP_EVERYTHING
+
Enables dumping of all intermediate representations and passes.
+
CG_GCCJIT_KEEP_INTERMEDIATES
+
Keeps intermediate files generated during the compilation process.
+
CG_GCCJIT_VERBOSE
+
Enables verbose output from the GCC driver.
## Extra documentation From 9ddcc594113d9d8a3b9181c4436b767251b876c5 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Sun, 17 Mar 2024 17:42:37 -0400 Subject: [PATCH 144/892] Omit non-needs_drop drop_in_place in vtables This replaces the drop_in_place reference with null in vtables. On librustc_driver.so, this drops about ~17k dynamic relocations from the output, since many vtables can now be placed in read-only memory, rather than having a relocated pointer included. This makes a tradeoff by adding a null check at vtable call sites. That's hard to avoid without changing the vtable format (e.g., to use a pc-relative relocation instead of an absolute address, and avoid the dynamic relocation that way). But it seems likely that the check is cheap at runtime. --- src/abi/mod.rs | 16 ++++++++++++++++ src/base.rs | 5 +---- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/src/abi/mod.rs b/src/abi/mod.rs index 4bcef15ad0475..bd5a88769059f 100644 --- a/src/abi/mod.rs +++ b/src/abi/mod.rs @@ -593,6 +593,7 @@ pub(crate) fn codegen_drop<'tcx>( fx: &mut FunctionCx<'_, '_, 'tcx>, source_info: mir::SourceInfo, drop_place: CPlace<'tcx>, + target: BasicBlock, ) { let ty = drop_place.layout().ty; let drop_instance = Instance::resolve_drop_in_place(fx.tcx, ty).polymorphize(fx.tcx); @@ -620,6 +621,12 @@ pub(crate) fn codegen_drop<'tcx>( let ptr = ptr.get_addr(fx); let drop_fn = crate::vtable::drop_fn_of_obj(fx, vtable); + let is_null = fx.bcx.ins().icmp_imm(IntCC::Equal, drop_fn, 0); + let target_block = fx.get_block(target); + let continued = fx.bcx.create_block(); + fx.bcx.ins().brif(is_null, target_block, &[], continued, &[]); + fx.bcx.switch_to_block(continued); + // FIXME(eddyb) perhaps move some of this logic into // `Instance::resolve_drop_in_place`? let virtual_drop = Instance { @@ -659,6 +666,12 @@ pub(crate) fn codegen_drop<'tcx>( let (data, vtable) = drop_place.to_cvalue(fx).dyn_star_force_data_on_stack(fx); let drop_fn = crate::vtable::drop_fn_of_obj(fx, vtable); + let is_null = fx.bcx.ins().icmp_imm(IntCC::Equal, drop_fn, 0); + let target_block = fx.get_block(target); + let continued = fx.bcx.create_block(); + fx.bcx.ins().brif(is_null, target_block, &[], continued, &[]); + fx.bcx.switch_to_block(continued); + let virtual_drop = Instance { def: ty::InstanceDef::Virtual(drop_instance.def_id(), 0), args: drop_instance.args, @@ -697,4 +710,7 @@ pub(crate) fn codegen_drop<'tcx>( } } } + + let target_block = fx.get_block(target); + fx.bcx.ins().jump(target_block, &[]); } diff --git a/src/base.rs b/src/base.rs index 8d778f736d671..c394844e62593 100644 --- a/src/base.rs +++ b/src/base.rs @@ -548,10 +548,7 @@ fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) { } TerminatorKind::Drop { place, target, unwind: _, replace: _ } => { let drop_place = codegen_place(fx, *place); - crate::abi::codegen_drop(fx, source_info, drop_place); - - let target_block = fx.get_block(*target); - fx.bcx.ins().jump(target_block, &[]); + crate::abi::codegen_drop(fx, source_info, drop_place, *target); } }; } From e7eeeb92dad5369fa26a553fc08acb2949ebdb3d Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 28 May 2024 12:03:35 +0200 Subject: [PATCH 145/892] Improve Readme.md format --- Readme.md | 41 +++++++++++++---------------------------- 1 file changed, 13 insertions(+), 28 deletions(-) diff --git a/Readme.md b/Readme.md index 01b00273ccb36..bd552b84f9282 100644 --- a/Readme.md +++ b/Readme.md @@ -146,34 +146,19 @@ $ LIBRARY_PATH="[gcc-path value]" LD_LIBRARY_PATH="[gcc-path value]" rustc +$(ca ## Env vars -
-
CG_GCCJIT_DUMP_ALL_MODULES
-
Enables dumping of all compilation modules. When set to "1", a dump is created for each module during compilation and stored in `/tmp/reproducers/`.
-
CG_GCCJIT_DUMP_MODULE
-
Enables dumping of a specific module. When set with the module name, e.g., `CG_GCCJIT_DUMP_MODULE=module_name`, a dump of that specific module is created in `/tmp/reproducers/`.
-
CG_RUSTFLAGS
-
Send additional flags to rustc. Can be used to build the sysroot without unwinding by setting `CG_RUSTFLAGS=-Cpanic=abort`.
-
CG_GCCJIT_DUMP_TO_FILE
-
Dump a C-like representation to /tmp/gccjit_dumps and enable debug info in order to debug this C-like representation.
-
CG_GCCJIT_DUMP_RTL
-
Dumps RTL (Register Transfer Language) for virtual registers.
-
CG_GCCJIT_DUMP_RTL_ALL
-
Dumps all RTL passes.
-
CG_GCCJIT_DUMP_TREE_ALL
-
Dumps all tree (GIMPLE) passes.
-
CG_GCCJIT_DUMP_IPA_ALL
-
Dumps all Interprocedural Analysis (IPA) passes.
-
CG_GCCJIT_DUMP_CODE
-
Dumps the final generated code.
-
CG_GCCJIT_DUMP_GIMPLE
-
Dumps the initial GIMPLE representation.
-
CG_GCCJIT_DUMP_EVERYTHING
-
Enables dumping of all intermediate representations and passes.
-
CG_GCCJIT_KEEP_INTERMEDIATES
-
Keeps intermediate files generated during the compilation process.
-
CG_GCCJIT_VERBOSE
-
Enables verbose output from the GCC driver.
-
+ * _**CG_GCCJIT_DUMP_ALL_MODULES**_: Enables dumping of all compilation modules. When set to "1", a dump is created for each module during compilation and stored in `/tmp/reproducers/`. + * _**CG_GCCJIT_DUMP_MODULE**_: Enables dumping of a specific module. When set with the module name, e.g., `CG_GCCJIT_DUMP_MODULE=module_name`, a dump of that specific module is created in `/tmp/reproducers/`. + * _**CG_RUSTFLAGS**_: Send additional flags to rustc. Can be used to build the sysroot without unwinding by setting `CG_RUSTFLAGS=-Cpanic=abort`. + * _**CG_GCCJIT_DUMP_TO_FILE**_: Dump a C-like representation to /tmp/gccjit_dumps and enable debug info in order to debug this C-like representation. + * _**CG_GCCJIT_DUMP_RTL**_: Dumps RTL (Register Transfer Language) for virtual registers. + * _**CG_GCCJIT_DUMP_RTL_ALL**_: Dumps all RTL passes. + * _**CG_GCCJIT_DUMP_TREE_ALL**_: Dumps all tree (GIMPLE) passes. + * _**CG_GCCJIT_DUMP_IPA_ALL**_: Dumps all Interprocedural Analysis (IPA) passes. + * _**CG_GCCJIT_DUMP_CODE**_: Dumps the final generated code. + * _**CG_GCCJIT_DUMP_GIMPLE**_: Dumps the initial GIMPLE representation. + * _**CG_GCCJIT_DUMP_EVERYTHING**_: Enables dumping of all intermediate representations and passes. + * _**CG_GCCJIT_KEEP_INTERMEDIATES**_: Keeps intermediate files generated during the compilation process. + * _**CG_GCCJIT_VERBOSE**_: Enables verbose output from the GCC driver. ## Extra documentation From 676fec7c651870268d47fdab098bae900fac07e4 Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Sun, 21 Apr 2024 16:11:01 -0700 Subject: [PATCH 146/892] Add an intrinsic for `ptr::metadata` --- src/base.rs | 38 +++++++++++++++++++++++++------------- src/constant.rs | 2 +- src/value_and_place.rs | 8 ++++++++ 3 files changed, 34 insertions(+), 14 deletions(-) diff --git a/src/base.rs b/src/base.rs index 8d778f736d671..de1cd9c75c16e 100644 --- a/src/base.rs +++ b/src/base.rs @@ -619,22 +619,34 @@ fn codegen_stmt<'tcx>( Rvalue::UnaryOp(un_op, ref operand) => { let operand = codegen_operand(fx, operand); let layout = operand.layout(); - let val = operand.load_scalar(fx); let res = match un_op { - UnOp::Not => match layout.ty.kind() { - ty::Bool => { - let res = fx.bcx.ins().icmp_imm(IntCC::Equal, val, 0); - CValue::by_val(res, layout) + UnOp::Not => { + let val = operand.load_scalar(fx); + match layout.ty.kind() { + ty::Bool => { + let res = fx.bcx.ins().icmp_imm(IntCC::Equal, val, 0); + CValue::by_val(res, layout) + } + ty::Uint(_) | ty::Int(_) => { + CValue::by_val(fx.bcx.ins().bnot(val), layout) + } + _ => unreachable!("un op Not for {:?}", layout.ty), } - ty::Uint(_) | ty::Int(_) => { - CValue::by_val(fx.bcx.ins().bnot(val), layout) + } + UnOp::Neg => { + let val = operand.load_scalar(fx); + match layout.ty.kind() { + ty::Int(_) => CValue::by_val(fx.bcx.ins().ineg(val), layout), + ty::Float(_) => CValue::by_val(fx.bcx.ins().fneg(val), layout), + _ => unreachable!("un op Neg for {:?}", layout.ty), } - _ => unreachable!("un op Not for {:?}", layout.ty), - }, - UnOp::Neg => match layout.ty.kind() { - ty::Int(_) => CValue::by_val(fx.bcx.ins().ineg(val), layout), - ty::Float(_) => CValue::by_val(fx.bcx.ins().fneg(val), layout), - _ => unreachable!("un op Neg for {:?}", layout.ty), + } + UnOp::PtrMetadata => match layout.abi { + Abi::Scalar(_) => CValue::zst(dest_layout), + Abi::ScalarPair(_, _) => { + CValue::by_val(operand.load_scalar_pair(fx).1, dest_layout) + } + _ => bug!("Unexpected `PtrToMetadata` operand: {operand:?}"), }, }; lval.write_cvalue(fx, res); diff --git a/src/constant.rs b/src/constant.rs index 64e83e43d3272..ba98f2e772cbf 100644 --- a/src/constant.rs +++ b/src/constant.rs @@ -100,7 +100,7 @@ pub(crate) fn codegen_const_value<'tcx>( assert!(layout.is_sized(), "unsized const value"); if layout.is_zst() { - return CValue::by_ref(crate::Pointer::dangling(layout.align.pref), layout); + return CValue::zst(layout); } match const_val { diff --git a/src/value_and_place.rs b/src/value_and_place.rs index 4146137c2263a..512a96450a4b6 100644 --- a/src/value_and_place.rs +++ b/src/value_and_place.rs @@ -95,6 +95,14 @@ impl<'tcx> CValue<'tcx> { CValue(CValueInner::ByValPair(value, extra), layout) } + /// Create an instance of a ZST + /// + /// The is represented by a dangling pointer of suitable alignment. + pub(crate) fn zst(layout: TyAndLayout<'tcx>) -> CValue<'tcx> { + assert!(layout.is_zst()); + CValue::by_ref(crate::Pointer::dangling(layout.align.pref), layout) + } + pub(crate) fn layout(&self) -> TyAndLayout<'tcx> { self.1 } From a25596584988c972546d60fe1b3ffe75cbcc0cf6 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 30 May 2024 16:34:21 +0000 Subject: [PATCH 147/892] Rustup to rustc 1.80.0-nightly (debd22da6 2024-05-29) --- patches/stdlib-lock.toml | 23 +++++++++++++++++------ rust-toolchain | 2 +- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/patches/stdlib-lock.toml b/patches/stdlib-lock.toml index c8c7b45bc9a6f..1bac8a93240b7 100644 --- a/patches/stdlib-lock.toml +++ b/patches/stdlib-lock.toml @@ -4,12 +4,12 @@ version = 3 [[package]] name = "addr2line" -version = "0.21.0" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +checksum = "6e4503c46a5c0c7844e948c9a4d6acd9f50cccb4de1c48eb9e291ea17470c678" dependencies = [ "compiler_builtins", - "gimli", + "gimli 0.29.0", "rustc-std-workspace-alloc", "rustc-std-workspace-core", ] @@ -133,6 +133,17 @@ dependencies = [ "rustc-std-workspace-core", ] +[[package]] +name = "gimli" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd" +dependencies = [ + "compiler_builtins", + "rustc-std-workspace-alloc", + "rustc-std-workspace-core", +] + [[package]] name = "hashbrown" version = "0.14.3" @@ -286,9 +297,9 @@ dependencies = [ [[package]] name = "rustc-demangle" -version = "0.1.23" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" +checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" dependencies = [ "compiler_builtins", "rustc-std-workspace-core", @@ -430,7 +441,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "37a19a21a537f635c16c7576f22d0f2f7d63353c1337ad4ce0d8001c7952a25b" dependencies = [ "compiler_builtins", - "gimli", + "gimli 0.28.1", "rustc-std-workspace-core", ] diff --git a/rust-toolchain b/rust-toolchain index a1a7214c9060c..44a196c18ae17 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2024-05-23" +channel = "nightly-2024-05-30" components = ["rust-src", "rustc-dev", "llvm-tools"] From ab10da27a11133add161bc6f9b2b7580ba455d58 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 30 May 2024 16:42:52 +0000 Subject: [PATCH 148/892] Fix rustc test suite --- scripts/test_rustc_tests.sh | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/scripts/test_rustc_tests.sh b/scripts/test_rustc_tests.sh index ec29efa05fb13..980bb2e666039 100755 --- a/scripts/test_rustc_tests.sh +++ b/scripts/test_rustc_tests.sh @@ -36,9 +36,8 @@ rm tests/ui/parser/unclosed-delimiter-in-dep.rs # submodule contains //~ERROR rm tests/ui/asm/x86_64/evex512-implicit-feature.rs # unimplemented AVX512 x86 vendor intrinsic # exotic linkages -rm tests/ui/issues/issue-33992.rs # unsupported linkages -rm tests/incremental/hashes/function_interfaces.rs # same -rm tests/incremental/hashes/statics.rs # same +rm tests/incremental/hashes/function_interfaces.rs +rm tests/incremental/hashes/statics.rs # variadic arguments rm tests/ui/abi/mir/mir_codegen_calls_variadic.rs # requires float varargs @@ -93,7 +92,6 @@ rm -r tests/run-make/print-to-output # requires --print relocation-models # requires asm, llvm-ir and/or llvm-bc emit support # ============================================= rm -r tests/run-make/emit-named-files -rm -r tests/run-make/issue-30063 rm -r tests/run-make/multiple-emits rm -r tests/run-make/output-type-permutations rm -r tests/run-make/emit-to-stdout From eccab8ba39e9c5a3dfcf146105909039b64b0577 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bennet=20Ble=C3=9Fmann?= Date: Sat, 1 Jun 2024 13:29:55 +0200 Subject: [PATCH 149/892] prevent libgccjit.so download on unsupported os/arch (#529) prevent libgccjit.so download on unsupported os/arch (#529) Co-authored-by: Guillaume Gomez --- build_system/src/config.rs | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/build_system/src/config.rs b/build_system/src/config.rs index 041d75915fb0b..081e7d2e250e0 100644 --- a/build_system/src/config.rs +++ b/build_system/src/config.rs @@ -231,13 +231,7 @@ impl ConfigInfo { let tempfile = output_dir.join(&tempfile_name); let is_in_ci = std::env::var("GITHUB_ACTIONS").is_ok(); - let url = format!( - "https://github.com/antoyo/gcc/releases/download/master-{}/libgccjit.so", - commit, - ); - - println!("Downloading `{}`...", url); - download_gccjit(url, &output_dir, tempfile_name, !is_in_ci)?; + download_gccjit(&commit, &output_dir, tempfile_name, !is_in_ci)?; let libgccjit_so = output_dir.join(libgccjit_so_name); // If we reach this point, it means the file was correctly downloaded, so let's @@ -469,11 +463,27 @@ impl ConfigInfo { } fn download_gccjit( - url: String, + commit: &str, output_dir: &Path, tempfile_name: String, with_progress_bar: bool, ) -> Result<(), String> { + let url = if std::env::consts::OS == "linux" && std::env::consts::ARCH == "x86_64" { + format!("https://github.com/rust-lang/gcc/releases/download/master-{}/libgccjit.so", commit) + } else { + eprintln!( + "\ +Pre-compiled libgccjit.so not available for this os or architecture. +Please compile it yourself and update the `config.toml` file +to `download-gccjit = false` and set `gcc-path` to the appropriate directory." + ); + return Err(String::from( + "no appropriate pre-compiled libgccjit.so available for download", + )); + }; + + println!("Downloading `{}`...", url); + // Try curl. If that fails and we are on windows, fallback to PowerShell. let mut ret = run_command_with_output( &[ From b2d39816ba6960088b5090f8e29c33ed33e50296 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 31 May 2024 14:13:46 -0400 Subject: [PATCH 150/892] Uplift TypeRelation and Relate --- src/type_of.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/type_of.rs b/src/type_of.rs index 2155cabe171c2..a88d50cb43403 100644 --- a/src/type_of.rs +++ b/src/type_of.rs @@ -5,7 +5,7 @@ use rustc_codegen_ssa::traits::{BaseTypeMethods, DerivedTypeMethods, LayoutTypeM use rustc_middle::bug; use rustc_middle::ty::layout::{LayoutOf, TyAndLayout}; use rustc_middle::ty::print::with_no_trimmed_paths; -use rustc_middle::ty::{self, Ty, TypeVisitableExt}; +use rustc_middle::ty::{self, CoroutineArgsExt, Ty, TypeVisitableExt}; use rustc_target::abi::call::{CastTarget, FnAbi, Reg}; use rustc_target::abi::{ self, Abi, Align, FieldsShape, Float, Int, Integer, PointeeInfo, Pointer, Size, TyAbiInterface, From 8f1d41e2a0cf73f6ecb1737f0c70a07bc8989bfa Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sun, 2 Jun 2024 11:18:51 +0200 Subject: [PATCH 151/892] Implement _rdtsc x86 vendor intrinsic Fixes rust-lang/rustc_codegen_cranelift#1493 --- src/intrinsics/llvm_x86.rs | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/src/intrinsics/llvm_x86.rs b/src/intrinsics/llvm_x86.rs index 27b55ecc72eef..03dca0656ef1e 100644 --- a/src/intrinsics/llvm_x86.rs +++ b/src/intrinsics/llvm_x86.rs @@ -1416,6 +1416,36 @@ pub(crate) fn codegen_x86_llvm_intrinsic_call<'tcx>( ret.write_cvalue(fx, res); } + "llvm.x86.rdtsc" => { + // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_rdtsc&ig_expand=5273 + + let res_place = CPlace::new_stack_slot( + fx, + fx.layout_of(Ty::new_tup(fx.tcx, &[fx.tcx.types.u32, fx.tcx.types.u32])), + ); + let eax_place = res_place.place_field(fx, FieldIdx::new(0)); + let edx_place = res_place.place_field(fx, FieldIdx::new(1)); + codegen_inline_asm_inner( + fx, + &[InlineAsmTemplatePiece::String("rdtsc".to_string())], + &[ + CInlineAsmOperand::Out { + reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::ax)), + late: true, + place: Some(eax_place), + }, + CInlineAsmOperand::Out { + reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::dx)), + late: true, + place: Some(edx_place), + }, + ], + InlineAsmOptions::NOSTACK | InlineAsmOptions::NOMEM, + ); + let res = res_place.to_cvalue(fx); + ret.write_cvalue_transmute(fx, res); + } + _ => { fx.tcx .dcx() From 5e60afb6cc733bd78ffd0e4f6233309c2cd4ea99 Mon Sep 17 00:00:00 2001 From: John Arundel Date: Mon, 3 Jun 2024 12:33:03 +0100 Subject: [PATCH 152/892] [ arc_with_non_send_sync ]: fix doc nits --- clippy_lints/src/arc_with_non_send_sync.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clippy_lints/src/arc_with_non_send_sync.rs b/clippy_lints/src/arc_with_non_send_sync.rs index 389338973894b..d57ab539fff42 100644 --- a/clippy_lints/src/arc_with_non_send_sync.rs +++ b/clippy_lints/src/arc_with_non_send_sync.rs @@ -17,7 +17,7 @@ declare_clippy_lint! { /// `Arc` is a thread-safe `Rc` and guarantees that updates to the reference counter /// use atomic operations. To send an `Arc` across thread boundaries and /// share ownership between multiple threads, `T` must be [both `Send` and `Sync`](https://doc.rust-lang.org/std/sync/struct.Arc.html#thread-safety), - /// so either `T` should be made `Send + Sync` or an `Rc` should be used instead of an `Arc` + /// so either `T` should be made `Send + Sync` or an `Rc` should be used instead of an `Arc`. /// /// ### Example /// ```no_run From eb449c133903c6b274580f8e365a3f287670d667 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Tue, 4 Jun 2024 16:02:36 +0200 Subject: [PATCH 153/892] Move error on -Cinstrument-coverage earlier and elaborate that it is LLVM specific cc rust-lang/rustc_codegen_cranelift#1494 --- src/lib.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index 39bbad16b0c00..9eece684b1a6e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -172,7 +172,7 @@ impl CodegenBackend for CraneliftCodegenBackend { } fn init(&self, sess: &Session) { - use rustc_session::config::Lto; + use rustc_session::config::{InstrumentCoverage, Lto}; match sess.lto() { Lto::No | Lto::ThinLocal => {} Lto::Thin | Lto::Fat => { @@ -180,6 +180,11 @@ impl CodegenBackend for CraneliftCodegenBackend { } } + if sess.opts.cg.instrument_coverage() != InstrumentCoverage::No { + sess.dcx() + .fatal("`-Cinstrument-coverage` is LLVM specific and not supported by Cranelift"); + } + let mut config = self.config.borrow_mut(); if config.is_none() { let new_config = BackendConfig::from_opts(&sess.opts.cg.llvm_args) From 97d47f7077d631c0eb8dac000638496a2c2a5ee2 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Tue, 4 Jun 2024 16:21:13 +0200 Subject: [PATCH 154/892] Fix rustc tests --- scripts/test_rustc_tests.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/scripts/test_rustc_tests.sh b/scripts/test_rustc_tests.sh index 980bb2e666039..6c45a4ccf7962 100755 --- a/scripts/test_rustc_tests.sh +++ b/scripts/test_rustc_tests.sh @@ -67,6 +67,11 @@ rm -r tests/run-make/issue-109934-lto-debuginfo rm -r tests/run-make/no-builtins-lto rm -r tests/run-make/reachable-extern-fn-available-lto +# coverage instrumentation +rm tests/ui/consts/precise-drop-with-coverage.rs +rm tests/ui/issues/issue-85461.rs +rm -r tests/ui/instrument-coverage/ + # optimization tests # ================== rm tests/ui/codegen/issue-28950.rs # depends on stack size optimizations From 406770001e8a2379e0175cecce11016a4448835a Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Tue, 4 Jun 2024 16:26:14 +0200 Subject: [PATCH 155/892] Don't require the bench job to pass for a new release cc rust-lang/rust#125493 --- .github/workflows/main.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 1f5a6513f63b1..a0c7ccdec0d59 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -282,7 +282,8 @@ jobs: runs-on: ubuntu-latest timeout-minutes: 10 if: ${{ github.ref == 'refs/heads/master' }} - needs: [rustfmt, test, bench, dist] + # FIXME add the bench job back to the dependency list once rust-lang/rust#125493 gets merged + needs: [rustfmt, test, dist] permissions: contents: write # for creating the dev tag and release From 632e5df38aab0b6d0c2a5f57cb1e214910bfe2b0 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Tue, 4 Jun 2024 16:41:37 +0200 Subject: [PATCH 156/892] Remove unreachable fatal error --- src/base.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/base.rs b/src/base.rs index 963e5de91cefe..e04501d5705b8 100644 --- a/src/base.rs +++ b/src/base.rs @@ -907,7 +907,7 @@ fn codegen_stmt<'tcx>( | StatementKind::PlaceMention(..) | StatementKind::AscribeUserType(..) => {} - StatementKind::Coverage { .. } => fx.tcx.dcx().fatal("-Zcoverage is unimplemented"), + StatementKind::Coverage { .. } => unreachable!(), StatementKind::Intrinsic(ref intrinsic) => match &**intrinsic { // We ignore `assume` intrinsics, they are only useful for optimizations NonDivergingIntrinsic::Assume(_) => {} From 5d0ec8d16210412210291987d74d9ea1fa75153c Mon Sep 17 00:00:00 2001 From: Boxy Date: Tue, 4 Jun 2024 07:01:58 +0100 Subject: [PATCH 157/892] Misc fixes to cranelift/clippy/miri --- src/intrinsics/simd.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/intrinsics/simd.rs b/src/intrinsics/simd.rs index b17f191ce267e..65eeaf156d844 100644 --- a/src/intrinsics/simd.rs +++ b/src/intrinsics/simd.rs @@ -133,6 +133,7 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>( .expect_const() .eval(fx.tcx, ty::ParamEnv::reveal_all(), span) .unwrap() + .1 .unwrap_branch(); assert_eq!(x.layout(), y.layout()); From 7ab4af336cdb8b13cb39e192913f84e8b7f30dda Mon Sep 17 00:00:00 2001 From: John Arundel Date: Mon, 3 Jun 2024 12:34:05 +0100 Subject: [PATCH 158/892] [ needless_for_each ]: fix doc nits --- clippy_lints/src/needless_for_each.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/clippy_lints/src/needless_for_each.rs b/clippy_lints/src/needless_for_each.rs index 630018238f4c4..143acc2b1cb76 100644 --- a/clippy_lints/src/needless_for_each.rs +++ b/clippy_lints/src/needless_for_each.rs @@ -25,14 +25,14 @@ declare_clippy_lint! { /// ```no_run /// let v = vec![0, 1, 2]; /// v.iter().for_each(|elem| { - /// println!("{}", elem); + /// println!("{elem}"); /// }) /// ``` /// Use instead: /// ```no_run /// let v = vec![0, 1, 2]; - /// for elem in v.iter() { - /// println!("{}", elem); + /// for elem in &v { + /// println!("{elem}"); /// } /// ``` /// From 35d284fcbf947089315beccb6d1af7396d09d5d3 Mon Sep 17 00:00:00 2001 From: John Arundel Date: Mon, 3 Jun 2024 12:36:01 +0100 Subject: [PATCH 159/892] [ allow_attributes ]: fix doc nits --- clippy_lints/src/allow_attributes.rs | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/clippy_lints/src/allow_attributes.rs b/clippy_lints/src/allow_attributes.rs index 123d0e51eeee2..990f724ab9d9f 100644 --- a/clippy_lints/src/allow_attributes.rs +++ b/clippy_lints/src/allow_attributes.rs @@ -10,20 +10,19 @@ use rustc_session::declare_lint_pass; declare_clippy_lint! { /// ### What it does /// Checks for usage of the `#[allow]` attribute and suggests replacing it with - /// the `#[expect]` (See [RFC 2383](https://rust-lang.github.io/rfcs/2383-lint-reasons.html)) + /// `#[expect]`. (See [RFC 2383](https://rust-lang.github.io/rfcs/2383-lint-reasons.html)) /// - /// The expect attribute is still unstable and requires the `lint_reasons` + /// The expect attribute is still unstable and requires the `lint_reasons` feature /// on nightly. It can be enabled by adding `#![feature(lint_reasons)]` to /// the crate root. /// - /// This lint only warns outer attributes (`#[allow]`), as inner attributes + /// This lint only warns on outer attributes (`#[allow]`), as inner attributes /// (`#![allow]`) are usually used to enable or disable lints on a global scale. /// /// ### Why restrict this? - /// `#[allow]` attributes can linger after their reason for existence is gone. - /// `#[expect]` attributes suppress the lint emission, but emit a warning if - /// the expectation is unfulfilled. This can be useful to be notified when the - /// lint is no longer triggered, which may indicate the attribute can be removed. + /// The `#[allow]` attribute does not warn when the expected lint is no longer triggered, + /// whereas `#[expect]` calls attention to this fact. This can be a useful reminder to + /// remove attributes that are no longer needed. /// /// ### Example /// ```rust,ignore From 8da5d64669c18b52c4edaaf71a739585d97a5767 Mon Sep 17 00:00:00 2001 From: John Arundel Date: Mon, 3 Jun 2024 12:38:25 +0100 Subject: [PATCH 160/892] [ allow_attributes_without_reason ]: fix doc nits --- clippy_lints/src/attrs/mod.rs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/clippy_lints/src/attrs/mod.rs b/clippy_lints/src/attrs/mod.rs index 83c828e8e223e..bd10ebbe5f5db 100644 --- a/clippy_lints/src/attrs/mod.rs +++ b/clippy_lints/src/attrs/mod.rs @@ -270,13 +270,14 @@ declare_clippy_lint! { declare_clippy_lint! { /// ### What it does - /// Checks for attributes that allow lints without a reason. - /// - /// (This requires the `lint_reasons` feature) + /// Checks for attributes that allow lints without specifying the reason + /// they should be allowed. (This requires the `lint_reasons` feature.) /// /// ### Why restrict this? - /// Justifying each `allow` helps readers understand the reasoning, - /// and may allow removing `allow` attributes if their purpose is obsolete. + /// There should always be a specific reason to allow a lint. This reason + /// should be documented using the `reason` parameter, so that readers can + /// understand why the `allow` is required, or remove it if it's no + /// longer needed. /// /// ### Example /// ```no_run From 7c86db4ea5f051e0b355e37959264bd9998a17a9 Mon Sep 17 00:00:00 2001 From: John Arundel Date: Mon, 3 Jun 2024 12:41:21 +0100 Subject: [PATCH 161/892] [ mut_range_bound ]: fix doc nits --- clippy_lints/src/loops/mod.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/clippy_lints/src/loops/mod.rs b/clippy_lints/src/loops/mod.rs index 0868294215305..64ea591993dab 100644 --- a/clippy_lints/src/loops/mod.rs +++ b/clippy_lints/src/loops/mod.rs @@ -356,10 +356,10 @@ declare_clippy_lint! { declare_clippy_lint! { /// ### What it does - /// Checks for loops which have a range bound that is a mutable variable + /// Checks for loops with a range bound that is a mutable variable. /// /// ### Why is this bad? - /// One might think that modifying the mutable variable changes the loop bounds + /// One might think that modifying the mutable variable changes the loop bounds. It doesn't. /// /// ### Known problems /// False positive when mutation is followed by a `break`, but the `break` is not immediately @@ -381,7 +381,7 @@ declare_clippy_lint! { /// let mut foo = 42; /// for i in 0..foo { /// foo -= 1; - /// println!("{}", i); // prints numbers from 0 to 42, not 0 to 21 + /// println!("{i}"); // prints numbers from 0 to 41, not 0 to 21 /// } /// ``` #[clippy::version = "pre 1.29.0"] From 63cb28ed481e2f3096af20293a24f231d063b301 Mon Sep 17 00:00:00 2001 From: Folkert Date: Thu, 6 Jun 2024 22:33:43 +0200 Subject: [PATCH 162/892] add `llvm.x86.sse2.cvtps2dq` --- example/std_example.rs | 38 ++++++++++++++++++++++++++++++++++++++ src/intrinsics/llvm_x86.rs | 11 ++++++++++- 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/example/std_example.rs b/example/std_example.rs index 7347b2e77899f..6cedd84adfe52 100644 --- a/example/std_example.rs +++ b/example/std_example.rs @@ -251,6 +251,9 @@ unsafe fn test_simd() { test_mm_add_epi8(); test_mm_add_pd(); test_mm_cvtepi8_epi16(); + #[cfg(not(jit))] + test_mm_cvtps_epi32(); + test_mm_cvttps_epi32(); test_mm_cvtsi128_si64(); test_mm_extract_epi8(); @@ -476,6 +479,41 @@ unsafe fn test_mm256_permutevar8x32_epi32() { assert_eq_m256i(r, e); } +#[cfg(target_arch = "x86_64")] +#[target_feature(enable = "avx2")] +#[cfg(not(jit))] +unsafe fn test_mm_cvtps_epi32() { + let floats: [f32; 4] = [1.5, -2.5, i32::MAX as f32 + 1.0, f32::NAN]; + + let float_vec = _mm_loadu_ps(floats.as_ptr()); + let int_vec = _mm_cvtps_epi32(float_vec); + + let mut ints: [i32; 4] = [0; 4]; + _mm_storeu_si128(ints.as_mut_ptr() as *mut __m128i, int_vec); + + // this is very different from `floats.map(|f| f as i32)`! + let expected_ints: [i32; 4] = [2, -2, i32::MIN, i32::MIN]; + + assert_eq!(ints, expected_ints); +} + +#[cfg(target_arch = "x86_64")] +#[target_feature(enable = "avx2")] +unsafe fn test_mm_cvttps_epi32() { + let floats: [f32; 4] = [1.5, -2.5, i32::MAX as f32 + 1.0, f32::NAN]; + + let float_vec = _mm_loadu_ps(floats.as_ptr()); + let int_vec = _mm_cvttps_epi32(float_vec); + + let mut ints: [i32; 4] = [0; 4]; + _mm_storeu_si128(ints.as_mut_ptr() as *mut __m128i, int_vec); + + // this is very different from `floats.map(|f| f as i32)`! + let expected_ints: [i32; 4] = [1, -2, i32::MIN, i32::MIN]; + + assert_eq!(ints, expected_ints); +} + fn test_checked_mul() { let u: Option = u8::from_str_radix("1000", 10).ok(); assert_eq!(u, None); diff --git a/src/intrinsics/llvm_x86.rs b/src/intrinsics/llvm_x86.rs index 03dca0656ef1e..166b260b38af7 100644 --- a/src/intrinsics/llvm_x86.rs +++ b/src/intrinsics/llvm_x86.rs @@ -459,11 +459,20 @@ pub(crate) fn codegen_x86_llvm_intrinsic_call<'tcx>( intrinsic_args!(fx, args => (a); intrinsic); let a = a.load_scalar(fx); + let value = fx.bcx.ins().x86_cvtt2dq(types::I32X4, a); + let cvalue = CValue::by_val(value, ret.layout()); + ret.write_cvalue(fx, cvalue); + } + "llvm.x86.sse2.cvtps2dq" => { + // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_cvtps_epi32 + intrinsic_args!(fx, args => (a); intrinsic); + let a = a.load_scalar(fx); + // Using inline asm instead of fcvt_to_sint_sat as unrepresentable values are turned // into 0x80000000 for which Cranelift doesn't have a native instruction. codegen_inline_asm_inner( fx, - &[InlineAsmTemplatePiece::String(format!("cvttps2dq xmm0, xmm0"))], + &[InlineAsmTemplatePiece::String(format!("cvtps2dq xmm0, xmm0"))], &[CInlineAsmOperand::InOut { reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::xmm0)), _late: true, From 059eaf1386e36791785275e22d00b999a5dc12f4 Mon Sep 17 00:00:00 2001 From: Jason Newcomb Date: Fri, 7 Jun 2024 23:44:36 -0400 Subject: [PATCH 163/892] Fix ICE in `upper_case_acronyms` and remove most of the string allocations. --- clippy_lints/src/upper_case_acronyms.rs | 102 ++++++++++++++---------- tests/ui/crashes/ice-12284.rs | 10 +++ 2 files changed, 69 insertions(+), 43 deletions(-) create mode 100644 tests/ui/crashes/ice-12284.rs diff --git a/clippy_lints/src/upper_case_acronyms.rs b/clippy_lints/src/upper_case_acronyms.rs index f376d3496461f..72392f8e1f741 100644 --- a/clippy_lints/src/upper_case_acronyms.rs +++ b/clippy_lints/src/upper_case_acronyms.rs @@ -1,5 +1,5 @@ use clippy_utils::diagnostics::span_lint_hir_and_then; -use itertools::Itertools; +use core::mem::replace; use rustc_errors::Applicability; use rustc_hir::{HirId, Item, ItemKind}; use rustc_lint::{LateContext, LateLintPass, LintContext}; @@ -56,55 +56,71 @@ impl UpperCaseAcronyms { impl_lint_pass!(UpperCaseAcronyms => [UPPER_CASE_ACRONYMS]); -fn correct_ident(ident: &str) -> String { - let ident = ident.chars().rev().collect::(); - let fragments = ident - .split_inclusive(|x: char| !x.is_ascii_lowercase()) - .rev() - .map(|x| x.chars().rev().collect::()); - - let mut ident = fragments.clone().next().unwrap(); - for (ref prev, ref curr) in fragments.tuple_windows() { - if <[&String; 2]>::from((prev, curr)) - .iter() - .all(|s| s.len() == 1 && s.chars().next().unwrap().is_ascii_uppercase()) - { - ident.push_str(&curr.to_ascii_lowercase()); +fn contains_acronym(s: &str) -> bool { + let mut count = 0; + for c in s.chars() { + if c.is_ascii_uppercase() { + count += 1; + if count == 3 { + return true; + } } else { - ident.push_str(curr); + count = 0; } } - ident + count == 2 } fn check_ident(cx: &LateContext<'_>, ident: &Ident, hir_id: HirId, be_aggressive: bool) { - let span = ident.span; - let ident = ident.as_str(); - let corrected = correct_ident(ident); - // warn if we have pure-uppercase idents - // assume that two-letter words are some kind of valid abbreviation like FP for false positive - // (and don't warn) - if (ident.chars().all(|c| c.is_ascii_uppercase()) && ident.len() > 2) - // otherwise, warn if we have SOmeTHING lIKE THIs but only warn with the aggressive - // upper-case-acronyms-aggressive config option enabled - || (be_aggressive && ident != corrected) + let s = ident.as_str(); + + // By default, only warn for upper case identifiers with at least 3 characters. + let replacement = if s.len() > 2 && s.bytes().all(|c| c.is_ascii_uppercase()) { + let mut r = String::with_capacity(s.len()); + let mut s = s.chars(); + r.push(s.next().unwrap()); + r.extend(s.map(|c| c.to_ascii_lowercase())); + r + } else if be_aggressive + // Only lint if the ident starts with an upper case character. + && let unprefixed = s.trim_start_matches('_') + && unprefixed.starts_with(|c: char| c.is_ascii_uppercase()) + && contains_acronym(unprefixed) { - span_lint_hir_and_then( - cx, - UPPER_CASE_ACRONYMS, - hir_id, - span, - format!("name `{ident}` contains a capitalized acronym"), - |diag| { - diag.span_suggestion( - span, - "consider making the acronym lowercase, except the initial letter", - corrected, - Applicability::MaybeIncorrect, - ); - }, - ); - } + let mut r = String::with_capacity(s.len()); + let mut s = s.chars(); + let mut prev_upper = false; + while let Some(c) = s.next() { + r.push( + if replace(&mut prev_upper, c.is_ascii_uppercase()) + && s.clone().next().map_or(true, |c| c.is_ascii_uppercase()) + { + c.to_ascii_lowercase() + } else { + c + }, + ); + } + r + } else { + return; + }; + + span_lint_hir_and_then( + cx, + UPPER_CASE_ACRONYMS, + hir_id, + ident.span, + format!("name `{ident}` contains a capitalized acronym"), + |diag| { + diag.span_suggestion( + ident.span, + "consider making the acronym lowercase, except the initial letter", + replacement, + Applicability::MaybeIncorrect, + ); + }, + ); } impl LateLintPass<'_> for UpperCaseAcronyms { diff --git a/tests/ui/crashes/ice-12284.rs b/tests/ui/crashes/ice-12284.rs new file mode 100644 index 0000000000000..8d1dbface8eba --- /dev/null +++ b/tests/ui/crashes/ice-12284.rs @@ -0,0 +1,10 @@ +#![allow(incomplete_features)] +#![feature(unnamed_fields)] + +#[repr(C)] +struct Foo { + _: struct { + }, +} + +fn main() {} From 70ca9a1e7eb5bed75eb09f29303681b173731cc9 Mon Sep 17 00:00:00 2001 From: Renato Lochetti Date: Sat, 8 Jun 2024 14:34:59 +0100 Subject: [PATCH 164/892] Lint `manual_unwrap_or` for it let cases --- clippy_lints/src/matches/manual_unwrap_or.rs | 111 +++++++++++++------ clippy_lints/src/matches/mod.rs | 10 +- tests/ui/manual_unwrap_or.fixed | 52 +++++++++ tests/ui/manual_unwrap_or.rs | 60 ++++++++++ tests/ui/manual_unwrap_or.stderr | 40 +++++-- tests/ui/manual_unwrap_or_default.fixed | 2 +- tests/ui/manual_unwrap_or_default.rs | 2 +- tests/ui/match_result_ok.fixed | 7 +- tests/ui/match_result_ok.rs | 7 +- tests/ui/match_result_ok.stderr | 6 +- tests/ui/option_if_let_else.fixed | 3 +- tests/ui/option_if_let_else.rs | 3 +- tests/ui/option_if_let_else.stderr | 50 ++++----- 13 files changed, 276 insertions(+), 77 deletions(-) diff --git a/clippy_lints/src/matches/manual_unwrap_or.rs b/clippy_lints/src/matches/manual_unwrap_or.rs index 9edd6c9540424..0940fc3219bb6 100644 --- a/clippy_lints/src/matches/manual_unwrap_or.rs +++ b/clippy_lints/src/matches/manual_unwrap_or.rs @@ -3,46 +3,78 @@ use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::source::{indent_of, reindent_multiline, snippet_opt}; use clippy_utils::ty::is_type_diagnostic_item; use clippy_utils::usage::contains_return_break_continue_macro; -use clippy_utils::{is_res_lang_ctor, path_to_local_id, sugg}; +use clippy_utils::{is_res_lang_ctor, path_to_local_id, peel_blocks, sugg}; use rustc_errors::Applicability; use rustc_hir::def::{DefKind, Res}; use rustc_hir::LangItem::{OptionNone, ResultErr}; -use rustc_hir::{Arm, Expr, PatKind}; +use rustc_hir::{Arm, Expr, Pat, PatKind}; use rustc_lint::LateContext; +use rustc_middle::ty::Ty; use rustc_span::sym; use super::MANUAL_UNWRAP_OR; -pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'tcx>, scrutinee: &'tcx Expr<'_>, arms: &'tcx [Arm<'_>]) { +pub(super) fn check_match<'tcx>( + cx: &LateContext<'tcx>, + expr: &'tcx Expr<'tcx>, + scrutinee: &'tcx Expr<'_>, + arms: &'tcx [Arm<'_>], +) { let ty = cx.typeck_results().expr_ty(scrutinee); - if let Some(ty_name) = if is_type_diagnostic_item(cx, ty, sym::Option) { + if let Some((or_arm, unwrap_arm)) = applicable_or_arm(cx, arms) { + check_and_lint(cx, expr, unwrap_arm.pat, scrutinee, unwrap_arm.body, or_arm.body, ty); + } +} + +pub(super) fn check_if_let<'tcx>( + cx: &LateContext<'tcx>, + expr: &'tcx Expr<'_>, + let_pat: &'tcx Pat<'_>, + let_expr: &'tcx Expr<'_>, + then_expr: &'tcx Expr<'_>, + else_expr: &'tcx Expr<'_>, +) { + let ty = cx.typeck_results().expr_ty(let_expr); + check_and_lint(cx, expr, let_pat, let_expr, then_expr, peel_blocks(else_expr), ty); +} + +fn check_and_lint<'tcx>( + cx: &LateContext<'tcx>, + expr: &'tcx Expr<'_>, + let_pat: &'tcx Pat<'_>, + let_expr: &'tcx Expr<'_>, + then_expr: &'tcx Expr<'_>, + else_expr: &'tcx Expr<'_>, + ty: Ty<'tcx>, +) { + if let PatKind::TupleStruct(ref qpath, [unwrap_pat], _) = let_pat.kind + && let Res::Def(DefKind::Ctor(..), ctor_id) = cx.qpath_res(qpath, let_pat.hir_id) + && let Some(variant_id) = cx.tcx.opt_parent(ctor_id) + && (cx.tcx.lang_items().option_some_variant() == Some(variant_id) + || cx.tcx.lang_items().result_ok_variant() == Some(variant_id)) + && let PatKind::Binding(_, binding_hir_id, ..) = unwrap_pat.kind + && path_to_local_id(peel_blocks(then_expr), binding_hir_id) + && cx.typeck_results().expr_adjustments(then_expr).is_empty() + && let Some(ty_name) = find_type_name(cx, ty) + && let Some(or_body_snippet) = snippet_opt(cx, else_expr.span) + && let Some(indent) = indent_of(cx, expr.span) + && constant_simple(cx, cx.typeck_results(), else_expr).is_some() + { + lint(cx, expr, let_expr, ty_name, or_body_snippet, indent); + } +} + +fn find_type_name<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option<&'static str> { + if is_type_diagnostic_item(cx, ty, sym::Option) { Some("Option") } else if is_type_diagnostic_item(cx, ty, sym::Result) { Some("Result") } else { None - } && let Some(or_arm) = applicable_or_arm(cx, arms) - && let Some(or_body_snippet) = snippet_opt(cx, or_arm.body.span) - && let Some(indent) = indent_of(cx, expr.span) - && constant_simple(cx, cx.typeck_results(), or_arm.body).is_some() - { - let reindented_or_body = reindent_multiline(or_body_snippet.into(), true, Some(indent)); - - let mut app = Applicability::MachineApplicable; - let suggestion = sugg::Sugg::hir_with_context(cx, scrutinee, expr.span.ctxt(), "..", &mut app).maybe_par(); - span_lint_and_sugg( - cx, - MANUAL_UNWRAP_OR, - expr.span, - format!("this pattern reimplements `{ty_name}::unwrap_or`"), - "replace with", - format!("{suggestion}.unwrap_or({reindented_or_body})",), - app, - ); } } -fn applicable_or_arm<'a>(cx: &LateContext<'_>, arms: &'a [Arm<'a>]) -> Option<&'a Arm<'a>> { +fn applicable_or_arm<'a>(cx: &LateContext<'_>, arms: &'a [Arm<'a>]) -> Option<(&'a Arm<'a>, &'a Arm<'a>)> { if arms.len() == 2 && arms.iter().all(|arm| arm.guard.is_none()) && let Some((idx, or_arm)) = arms.iter().enumerate().find(|(_, arm)| match arm.pat.kind { @@ -54,18 +86,33 @@ fn applicable_or_arm<'a>(cx: &LateContext<'_>, arms: &'a [Arm<'a>]) -> Option<&' _ => false, }) && let unwrap_arm = &arms[1 - idx] - && let PatKind::TupleStruct(ref qpath, [unwrap_pat], _) = unwrap_arm.pat.kind - && let Res::Def(DefKind::Ctor(..), ctor_id) = cx.qpath_res(qpath, unwrap_arm.pat.hir_id) - && let Some(variant_id) = cx.tcx.opt_parent(ctor_id) - && (cx.tcx.lang_items().option_some_variant() == Some(variant_id) - || cx.tcx.lang_items().result_ok_variant() == Some(variant_id)) - && let PatKind::Binding(_, binding_hir_id, ..) = unwrap_pat.kind - && path_to_local_id(unwrap_arm.body, binding_hir_id) - && cx.typeck_results().expr_adjustments(unwrap_arm.body).is_empty() && !contains_return_break_continue_macro(or_arm.body) { - Some(or_arm) + Some((or_arm, unwrap_arm)) } else { None } } + +fn lint<'tcx>( + cx: &LateContext<'tcx>, + expr: &Expr<'tcx>, + scrutinee: &'tcx Expr<'_>, + ty_name: &str, + or_body_snippet: String, + indent: usize, +) { + let reindented_or_body = reindent_multiline(or_body_snippet.into(), true, Some(indent)); + + let mut app = Applicability::MachineApplicable; + let suggestion = sugg::Sugg::hir_with_context(cx, scrutinee, expr.span.ctxt(), "..", &mut app).maybe_par(); + span_lint_and_sugg( + cx, + MANUAL_UNWRAP_OR, + expr.span, + format!("this pattern reimplements `{ty_name}::unwrap_or`"), + "replace with", + format!("{suggestion}.unwrap_or({reindented_or_body})",), + app, + ); +} diff --git a/clippy_lints/src/matches/mod.rs b/clippy_lints/src/matches/mod.rs index 691ecd57535ac..bf7156cc53ec3 100644 --- a/clippy_lints/src/matches/mod.rs +++ b/clippy_lints/src/matches/mod.rs @@ -1069,7 +1069,7 @@ impl<'tcx> LateLintPass<'tcx> for Matches { redundant_guards::check(cx, arms, &self.msrv); if !in_constant(cx, expr.hir_id) { - manual_unwrap_or::check(cx, expr, ex, arms); + manual_unwrap_or::check_match(cx, expr, ex, arms); manual_map::check_match(cx, expr, ex, arms); manual_filter::check_match(cx, ex, arms, expr); } @@ -1097,6 +1097,14 @@ impl<'tcx> LateLintPass<'tcx> for Matches { ); } if !in_constant(cx, expr.hir_id) { + manual_unwrap_or::check_if_let( + cx, + expr, + if_let.let_pat, + if_let.let_expr, + if_let.if_then, + else_expr, + ); manual_map::check_if_let(cx, expr, if_let.let_pat, if_let.let_expr, if_let.if_then, else_expr); manual_filter::check_if_let( cx, diff --git a/tests/ui/manual_unwrap_or.fixed b/tests/ui/manual_unwrap_or.fixed index dffd44b6a7c1b..74afa00e12f27 100644 --- a/tests/ui/manual_unwrap_or.fixed +++ b/tests/ui/manual_unwrap_or.fixed @@ -68,6 +68,32 @@ fn option_unwrap_or() { Some(s) => s, None => &format!("{} {}!", "hello", "world"), }; + + Some(1).unwrap_or(42); + + //don't lint + if let Some(x) = Some(1) { + x + 1 + } else { + 42 + }; + if let Some(x) = Some(1) { + x + } else { + return; + }; + for j in 0..4 { + if let Some(x) = Some(j) { + x + } else { + continue; + }; + if let Some(x) = Some(j) { + x + } else { + break; + }; + } } fn result_unwrap_or() { @@ -138,6 +164,32 @@ fn result_unwrap_or() { Ok(s) => s, Err(s) => "Bob", }; + + Ok::(1).unwrap_or(42); + + //don't lint + if let Ok(x) = Ok::(1) { + x + 1 + } else { + 42 + }; + if let Ok(x) = Ok::(1) { + x + } else { + return; + }; + for j in 0..4 { + if let Ok(x) = Ok::(j) { + x + } else { + continue; + }; + if let Ok(x) = Ok::(j) { + x + } else { + break; + }; + } } // don't lint in const fn diff --git a/tests/ui/manual_unwrap_or.rs b/tests/ui/manual_unwrap_or.rs index 67427132c1a85..2d01b8ceaaa75 100644 --- a/tests/ui/manual_unwrap_or.rs +++ b/tests/ui/manual_unwrap_or.rs @@ -83,6 +83,36 @@ fn option_unwrap_or() { Some(s) => s, None => &format!("{} {}!", "hello", "world"), }; + + if let Some(x) = Some(1) { + x + } else { + 42 + }; + + //don't lint + if let Some(x) = Some(1) { + x + 1 + } else { + 42 + }; + if let Some(x) = Some(1) { + x + } else { + return; + }; + for j in 0..4 { + if let Some(x) = Some(j) { + x + } else { + continue; + }; + if let Some(x) = Some(j) { + x + } else { + break; + }; + } } fn result_unwrap_or() { @@ -177,6 +207,36 @@ fn result_unwrap_or() { Ok(s) => s, Err(s) => "Bob", }; + + if let Ok(x) = Ok::(1) { + x + } else { + 42 + }; + + //don't lint + if let Ok(x) = Ok::(1) { + x + 1 + } else { + 42 + }; + if let Ok(x) = Ok::(1) { + x + } else { + return; + }; + for j in 0..4 { + if let Ok(x) = Ok::(j) { + x + } else { + continue; + }; + if let Ok(x) = Ok::(j) { + x + } else { + break; + }; + } } // don't lint in const fn diff --git a/tests/ui/manual_unwrap_or.stderr b/tests/ui/manual_unwrap_or.stderr index 33a099680ce0e..c93a8952a0805 100644 --- a/tests/ui/manual_unwrap_or.stderr +++ b/tests/ui/manual_unwrap_or.stderr @@ -58,8 +58,18 @@ LL | | None => "Alice", LL | | }; | |_____^ help: replace with: `Some("Bob").unwrap_or("Alice")` +error: this pattern reimplements `Option::unwrap_or` + --> tests/ui/manual_unwrap_or.rs:87:5 + | +LL | / if let Some(x) = Some(1) { +LL | | x +LL | | } else { +LL | | 42 +LL | | }; + | |_____^ help: replace with: `Some(1).unwrap_or(42)` + error: this pattern reimplements `Result::unwrap_or` - --> tests/ui/manual_unwrap_or.rs:90:5 + --> tests/ui/manual_unwrap_or.rs:120:5 | LL | / match Ok::(1) { LL | | Ok(i) => i, @@ -68,7 +78,7 @@ LL | | }; | |_____^ help: replace with: `Ok::(1).unwrap_or(42)` error: this pattern reimplements `Result::unwrap_or` - --> tests/ui/manual_unwrap_or.rs:97:5 + --> tests/ui/manual_unwrap_or.rs:127:5 | LL | / match a { LL | | Ok(i) => i, @@ -77,7 +87,7 @@ LL | | }; | |_____^ help: replace with: `a.unwrap_or(42)` error: this pattern reimplements `Result::unwrap_or` - --> tests/ui/manual_unwrap_or.rs:103:5 + --> tests/ui/manual_unwrap_or.rs:133:5 | LL | / match Ok(1) as Result { LL | | Ok(i) => i, @@ -86,7 +96,7 @@ LL | | }; | |_____^ help: replace with: `(Ok(1) as Result).unwrap_or(42)` error: this pattern reimplements `Option::unwrap_or` - --> tests/ui/manual_unwrap_or.rs:116:5 + --> tests/ui/manual_unwrap_or.rs:146:5 | LL | / match s.method() { LL | | Some(i) => i, @@ -95,7 +105,7 @@ LL | | }; | |_____^ help: replace with: `s.method().unwrap_or(42)` error: this pattern reimplements `Result::unwrap_or` - --> tests/ui/manual_unwrap_or.rs:122:5 + --> tests/ui/manual_unwrap_or.rs:152:5 | LL | / match Ok::(1) { LL | | Err(_) => 42, @@ -104,7 +114,7 @@ LL | | }; | |_____^ help: replace with: `Ok::(1).unwrap_or(42)` error: this pattern reimplements `Result::unwrap_or` - --> tests/ui/manual_unwrap_or.rs:128:5 + --> tests/ui/manual_unwrap_or.rs:158:5 | LL | / match Ok::(1) { LL | | Ok(i) => i, @@ -113,7 +123,7 @@ LL | | }; | |_____^ help: replace with: `Ok::(1).unwrap_or(1 + 42)` error: this pattern reimplements `Result::unwrap_or` - --> tests/ui/manual_unwrap_or.rs:135:5 + --> tests/ui/manual_unwrap_or.rs:165:5 | LL | / match Ok::(1) { LL | | Ok(i) => i, @@ -134,7 +144,7 @@ LL ~ }); | error: this pattern reimplements `Result::unwrap_or` - --> tests/ui/manual_unwrap_or.rs:145:5 + --> tests/ui/manual_unwrap_or.rs:175:5 | LL | / match Ok::<&str, &str>("Bob") { LL | | Ok(i) => i, @@ -142,8 +152,18 @@ LL | | Err(_) => "Alice", LL | | }; | |_____^ help: replace with: `Ok::<&str, &str>("Bob").unwrap_or("Alice")` +error: this pattern reimplements `Result::unwrap_or` + --> tests/ui/manual_unwrap_or.rs:211:5 + | +LL | / if let Ok(x) = Ok::(1) { +LL | | x +LL | | } else { +LL | | 42 +LL | | }; + | |_____^ help: replace with: `Ok::(1).unwrap_or(42)` + error: this pattern reimplements `Option::unwrap_or` - --> tests/ui/manual_unwrap_or.rs:205:17 + --> tests/ui/manual_unwrap_or.rs:265:17 | LL | let _ = match some_macro!() { | _________________^ @@ -152,5 +172,5 @@ LL | | None => 0, LL | | }; | |_________^ help: replace with: `some_macro!().unwrap_or(0)` -error: aborting due to 14 previous errors +error: aborting due to 16 previous errors diff --git a/tests/ui/manual_unwrap_or_default.fixed b/tests/ui/manual_unwrap_or_default.fixed index 663de1a5f0677..70575d64d6695 100644 --- a/tests/ui/manual_unwrap_or_default.fixed +++ b/tests/ui/manual_unwrap_or_default.fixed @@ -1,5 +1,5 @@ #![warn(clippy::manual_unwrap_or_default)] -#![allow(clippy::unnecessary_literal_unwrap)] +#![allow(clippy::unnecessary_literal_unwrap, clippy::manual_unwrap_or)] fn main() { let x: Option> = None; diff --git a/tests/ui/manual_unwrap_or_default.rs b/tests/ui/manual_unwrap_or_default.rs index 75ffe09be9d4d..58ba04490e0ed 100644 --- a/tests/ui/manual_unwrap_or_default.rs +++ b/tests/ui/manual_unwrap_or_default.rs @@ -1,5 +1,5 @@ #![warn(clippy::manual_unwrap_or_default)] -#![allow(clippy::unnecessary_literal_unwrap)] +#![allow(clippy::unnecessary_literal_unwrap, clippy::manual_unwrap_or)] fn main() { let x: Option> = None; diff --git a/tests/ui/match_result_ok.fixed b/tests/ui/match_result_ok.fixed index 76b26f5e4386d..117e0bc68ccc0 100644 --- a/tests/ui/match_result_ok.fixed +++ b/tests/ui/match_result_ok.fixed @@ -1,6 +1,11 @@ #![warn(clippy::match_result_ok)] #![allow(dead_code)] -#![allow(clippy::boxed_local, clippy::uninlined_format_args, clippy::manual_unwrap_or_default)] +#![allow( + clippy::boxed_local, + clippy::uninlined_format_args, + clippy::manual_unwrap_or_default, + clippy::manual_unwrap_or +)] // Checking `if` cases diff --git a/tests/ui/match_result_ok.rs b/tests/ui/match_result_ok.rs index d6f2475ba79c8..f8a5269024da5 100644 --- a/tests/ui/match_result_ok.rs +++ b/tests/ui/match_result_ok.rs @@ -1,6 +1,11 @@ #![warn(clippy::match_result_ok)] #![allow(dead_code)] -#![allow(clippy::boxed_local, clippy::uninlined_format_args, clippy::manual_unwrap_or_default)] +#![allow( + clippy::boxed_local, + clippy::uninlined_format_args, + clippy::manual_unwrap_or_default, + clippy::manual_unwrap_or +)] // Checking `if` cases diff --git a/tests/ui/match_result_ok.stderr b/tests/ui/match_result_ok.stderr index 0d42d59dc0136..b5b91cbe55344 100644 --- a/tests/ui/match_result_ok.stderr +++ b/tests/ui/match_result_ok.stderr @@ -1,5 +1,5 @@ error: matching on `Some` with `ok()` is redundant - --> tests/ui/match_result_ok.rs:8:5 + --> tests/ui/match_result_ok.rs:13:5 | LL | if let Some(y) = x.parse().ok() { y } else { 0 } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -12,7 +12,7 @@ LL | if let Ok(y) = x.parse() { y } else { 0 } | ~~~~~~~~~~~~~~~~~~~~~~~~ error: matching on `Some` with `ok()` is redundant - --> tests/ui/match_result_ok.rs:18:9 + --> tests/ui/match_result_ok.rs:23:9 | LL | if let Some(y) = x . parse() . ok () { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -23,7 +23,7 @@ LL | if let Ok(y) = x . parse() { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: matching on `Some` with `ok()` is redundant - --> tests/ui/match_result_ok.rs:44:5 + --> tests/ui/match_result_ok.rs:49:5 | LL | while let Some(a) = wat.next().ok() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/option_if_let_else.fixed b/tests/ui/option_if_let_else.fixed index eeab801b7da81..0ac89bf0d8eaf 100644 --- a/tests/ui/option_if_let_else.fixed +++ b/tests/ui/option_if_let_else.fixed @@ -4,7 +4,8 @@ clippy::equatable_if_let, clippy::let_unit_value, clippy::redundant_locals, - clippy::manual_unwrap_or_default + clippy::manual_unwrap_or_default, + clippy::manual_unwrap_or )] fn bad1(string: Option<&str>) -> (bool, &str) { diff --git a/tests/ui/option_if_let_else.rs b/tests/ui/option_if_let_else.rs index 3e5b96d7c3162..b4f1b2cd1f7ff 100644 --- a/tests/ui/option_if_let_else.rs +++ b/tests/ui/option_if_let_else.rs @@ -4,7 +4,8 @@ clippy::equatable_if_let, clippy::let_unit_value, clippy::redundant_locals, - clippy::manual_unwrap_or_default + clippy::manual_unwrap_or_default, + clippy::manual_unwrap_or )] fn bad1(string: Option<&str>) -> (bool, &str) { diff --git a/tests/ui/option_if_let_else.stderr b/tests/ui/option_if_let_else.stderr index f5359a0c34f99..37ef791edb008 100644 --- a/tests/ui/option_if_let_else.stderr +++ b/tests/ui/option_if_let_else.stderr @@ -1,5 +1,5 @@ error: use Option::map_or instead of an if let/else - --> tests/ui/option_if_let_else.rs:11:5 + --> tests/ui/option_if_let_else.rs:12:5 | LL | / if let Some(x) = string { LL | | (true, x) @@ -12,19 +12,19 @@ LL | | } = help: to override `-D warnings` add `#[allow(clippy::option_if_let_else)]` error: use Option::map_or instead of an if let/else - --> tests/ui/option_if_let_else.rs:29:13 + --> tests/ui/option_if_let_else.rs:30:13 | LL | let _ = if let Some(s) = *string { s.len() } else { 0 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `string.map_or(0, |s| s.len())` error: use Option::map_or instead of an if let/else - --> tests/ui/option_if_let_else.rs:30:13 + --> tests/ui/option_if_let_else.rs:31:13 | LL | let _ = if let Some(s) = &num { s } else { &0 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `num.as_ref().map_or(&0, |s| s)` error: use Option::map_or instead of an if let/else - --> tests/ui/option_if_let_else.rs:31:13 + --> tests/ui/option_if_let_else.rs:32:13 | LL | let _ = if let Some(s) = &mut num { | _____________^ @@ -44,13 +44,13 @@ LL ~ }); | error: use Option::map_or instead of an if let/else - --> tests/ui/option_if_let_else.rs:37:13 + --> tests/ui/option_if_let_else.rs:38:13 | LL | let _ = if let Some(ref s) = num { s } else { &0 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `num.as_ref().map_or(&0, |s| s)` error: use Option::map_or instead of an if let/else - --> tests/ui/option_if_let_else.rs:38:13 + --> tests/ui/option_if_let_else.rs:39:13 | LL | let _ = if let Some(mut s) = num { | _____________^ @@ -70,7 +70,7 @@ LL ~ }); | error: use Option::map_or instead of an if let/else - --> tests/ui/option_if_let_else.rs:44:13 + --> tests/ui/option_if_let_else.rs:45:13 | LL | let _ = if let Some(ref mut s) = num { | _____________^ @@ -90,7 +90,7 @@ LL ~ }); | error: use Option::map_or instead of an if let/else - --> tests/ui/option_if_let_else.rs:53:5 + --> tests/ui/option_if_let_else.rs:54:5 | LL | / if let Some(x) = arg { LL | | let y = x * x; @@ -109,7 +109,7 @@ LL + }) | error: use Option::map_or_else instead of an if let/else - --> tests/ui/option_if_let_else.rs:66:13 + --> tests/ui/option_if_let_else.rs:67:13 | LL | let _ = if let Some(x) = arg { | _____________^ @@ -121,7 +121,7 @@ LL | | }; | |_____^ help: try: `arg.map_or_else(side_effect, |x| x)` error: use Option::map_or_else instead of an if let/else - --> tests/ui/option_if_let_else.rs:75:13 + --> tests/ui/option_if_let_else.rs:76:13 | LL | let _ = if let Some(x) = arg { | _____________^ @@ -144,7 +144,7 @@ LL ~ }, |x| x * x * x * x); | error: use Option::map_or_else instead of an if let/else - --> tests/ui/option_if_let_else.rs:108:13 + --> tests/ui/option_if_let_else.rs:109:13 | LL | / if let Some(idx) = s.find('.') { LL | | vec![s[..idx].to_string(), s[idx..].to_string()] @@ -154,7 +154,7 @@ LL | | } | |_____________^ help: try: `s.find('.').map_or_else(|| vec![s.to_string()], |idx| vec![s[..idx].to_string(), s[idx..].to_string()])` error: use Option::map_or_else instead of an if let/else - --> tests/ui/option_if_let_else.rs:119:5 + --> tests/ui/option_if_let_else.rs:120:5 | LL | / if let Ok(binding) = variable { LL | | println!("Ok {binding}"); @@ -177,13 +177,13 @@ LL + }) | error: use Option::map_or instead of an if let/else - --> tests/ui/option_if_let_else.rs:143:13 + --> tests/ui/option_if_let_else.rs:144:13 | LL | let _ = if let Some(x) = optional { x + 2 } else { 5 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `optional.map_or(5, |x| x + 2)` error: use Option::map_or instead of an if let/else - --> tests/ui/option_if_let_else.rs:153:13 + --> tests/ui/option_if_let_else.rs:154:13 | LL | let _ = if let Some(x) = Some(0) { | _____________^ @@ -205,13 +205,13 @@ LL ~ }); | error: use Option::map_or instead of an if let/else - --> tests/ui/option_if_let_else.rs:181:13 + --> tests/ui/option_if_let_else.rs:182:13 | LL | let _ = if let Some(x) = Some(0) { s.len() + x } else { s.len() }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Some(0).map_or(s.len(), |x| s.len() + x)` error: use Option::map_or instead of an if let/else - --> tests/ui/option_if_let_else.rs:185:13 + --> tests/ui/option_if_let_else.rs:186:13 | LL | let _ = if let Some(x) = Some(0) { | _____________^ @@ -231,7 +231,7 @@ LL ~ }); | error: use Option::map_or instead of an if let/else - --> tests/ui/option_if_let_else.rs:224:13 + --> tests/ui/option_if_let_else.rs:225:13 | LL | let _ = match s { | _____________^ @@ -241,7 +241,7 @@ LL | | }; | |_____^ help: try: `s.map_or(1, |string| string.len())` error: use Option::map_or instead of an if let/else - --> tests/ui/option_if_let_else.rs:228:13 + --> tests/ui/option_if_let_else.rs:229:13 | LL | let _ = match Some(10) { | _____________^ @@ -251,7 +251,7 @@ LL | | }; | |_____^ help: try: `Some(10).map_or(5, |a| a + 1)` error: use Option::map_or instead of an if let/else - --> tests/ui/option_if_let_else.rs:234:13 + --> tests/ui/option_if_let_else.rs:235:13 | LL | let _ = match res { | _____________^ @@ -261,7 +261,7 @@ LL | | }; | |_____^ help: try: `res.map_or(1, |a| a + 1)` error: use Option::map_or instead of an if let/else - --> tests/ui/option_if_let_else.rs:238:13 + --> tests/ui/option_if_let_else.rs:239:13 | LL | let _ = match res { | _____________^ @@ -271,13 +271,13 @@ LL | | }; | |_____^ help: try: `res.map_or(1, |a| a + 1)` error: use Option::map_or instead of an if let/else - --> tests/ui/option_if_let_else.rs:242:13 + --> tests/ui/option_if_let_else.rs:243:13 | LL | let _ = if let Ok(a) = res { a + 1 } else { 5 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `res.map_or(5, |a| a + 1)` error: use Option::map_or instead of an if let/else - --> tests/ui/option_if_let_else.rs:259:17 + --> tests/ui/option_if_let_else.rs:260:17 | LL | let _ = match initial { | _________________^ @@ -287,7 +287,7 @@ LL | | }; | |_________^ help: try: `initial.as_ref().map_or(42, |value| do_something(value))` error: use Option::map_or instead of an if let/else - --> tests/ui/option_if_let_else.rs:266:17 + --> tests/ui/option_if_let_else.rs:267:17 | LL | let _ = match initial { | _________________^ @@ -297,7 +297,7 @@ LL | | }; | |_________^ help: try: `initial.as_mut().map_or(42, |value| do_something2(value))` error: use Option::map_or_else instead of an if let/else - --> tests/ui/option_if_let_else.rs:289:24 + --> tests/ui/option_if_let_else.rs:290:24 | LL | let mut _hashmap = if let Some(hm) = &opt { | ________________________^ @@ -308,7 +308,7 @@ LL | | }; | |_____^ help: try: `opt.as_ref().map_or_else(HashMap::new, |hm| hm.clone())` error: use Option::map_or_else instead of an if let/else - --> tests/ui/option_if_let_else.rs:295:19 + --> tests/ui/option_if_let_else.rs:296:19 | LL | let mut _hm = if let Some(hm) = &opt { hm.clone() } else { new_map!() }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.as_ref().map_or_else(|| new_map!(), |hm| hm.clone())` From 6210c26a5adcf9d9d469ef8c9820d937c42dc1e4 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 8 Jun 2024 11:26:56 +0200 Subject: [PATCH 165/892] offset_of: allow (unstably) taking the offset of slice tail fields --- src/base.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/base.rs b/src/base.rs index 963e5de91cefe..6d26ca0b899b2 100644 --- a/src/base.rs +++ b/src/base.rs @@ -832,9 +832,10 @@ fn codegen_stmt<'tcx>( let val = match null_op { NullOp::SizeOf => layout.size.bytes(), NullOp::AlignOf => layout.align.abi.bytes(), - NullOp::OffsetOf(fields) => { - layout.offset_of_subfield(fx, fields.iter()).bytes() - } + NullOp::OffsetOf(fields) => fx + .tcx + .offset_of_subfield(ParamEnv::reveal_all(), layout, fields.iter()) + .bytes(), NullOp::UbChecks => { let val = fx.tcx.sess.ub_checks(); let val = CValue::by_val( From 0eb782ba13d34c75de2c3d72343a1c946e57d7d3 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 8 Jun 2024 16:13:45 +0200 Subject: [PATCH 166/892] ScalarInt: size mismatches are a bug, do not delay the panic --- src/constant.rs | 6 +++--- src/intrinsics/llvm_x86.rs | 10 +++++----- src/intrinsics/simd.rs | 11 +++-------- src/value_and_place.rs | 4 ++-- 4 files changed, 13 insertions(+), 18 deletions(-) diff --git a/src/constant.rs b/src/constant.rs index ba98f2e772cbf..a53598018f4a4 100644 --- a/src/constant.rs +++ b/src/constant.rs @@ -110,7 +110,7 @@ pub(crate) fn codegen_const_value<'tcx>( if fx.clif_type(layout.ty).is_some() { return CValue::const_val(fx, layout, int); } else { - let raw_val = int.size().truncate(int.assert_bits(int.size())); + let raw_val = int.size().truncate(int.to_bits(int.size())); let val = match int.size().bytes() { 1 => fx.bcx.ins().iconst(types::I8, raw_val as i64), 2 => fx.bcx.ins().iconst(types::I16, raw_val as i64), @@ -501,12 +501,12 @@ pub(crate) fn mir_operand_get_const_val<'tcx>( Ordering::Equal => scalar_int, Ordering::Less => match ty.kind() { ty::Uint(_) => ScalarInt::try_from_uint( - scalar_int.assert_uint(scalar_int.size()), + scalar_int.to_uint(scalar_int.size()), fx.layout_of(*ty).size, ) .unwrap(), ty::Int(_) => ScalarInt::try_from_int( - scalar_int.assert_int(scalar_int.size()), + scalar_int.to_int(scalar_int.size()), fx.layout_of(*ty).size, ) .unwrap(), diff --git a/src/intrinsics/llvm_x86.rs b/src/intrinsics/llvm_x86.rs index 27b55ecc72eef..d454f3c1de7e4 100644 --- a/src/intrinsics/llvm_x86.rs +++ b/src/intrinsics/llvm_x86.rs @@ -902,7 +902,7 @@ pub(crate) fn codegen_x86_llvm_intrinsic_call<'tcx>( .span_fatal(span, "Index argument for `_mm_cmpestri` is not a constant"); }; - let imm8 = imm8.try_to_u8().unwrap_or_else(|_| panic!("kind not scalar: {:?}", imm8)); + let imm8 = imm8.to_u8(); codegen_inline_asm_inner( fx, @@ -955,7 +955,7 @@ pub(crate) fn codegen_x86_llvm_intrinsic_call<'tcx>( .span_fatal(span, "Index argument for `_mm_cmpestrm` is not a constant"); }; - let imm8 = imm8.try_to_u8().unwrap_or_else(|_| panic!("kind not scalar: {:?}", imm8)); + let imm8 = imm8.to_u8(); codegen_inline_asm_inner( fx, @@ -1003,7 +1003,7 @@ pub(crate) fn codegen_x86_llvm_intrinsic_call<'tcx>( ); }; - let imm8 = imm8.try_to_u8().unwrap_or_else(|_| panic!("kind not scalar: {:?}", imm8)); + let imm8 = imm8.to_u8(); codegen_inline_asm_inner( fx, @@ -1040,7 +1040,7 @@ pub(crate) fn codegen_x86_llvm_intrinsic_call<'tcx>( ); }; - let imm8 = imm8.try_to_u8().unwrap_or_else(|_| panic!("kind not scalar: {:?}", imm8)); + let imm8 = imm8.to_u8(); codegen_inline_asm_inner( fx, @@ -1195,7 +1195,7 @@ pub(crate) fn codegen_x86_llvm_intrinsic_call<'tcx>( .span_fatal(span, "Func argument for `_mm_sha1rnds4_epu32` is not a constant"); }; - let func = func.try_to_u8().unwrap_or_else(|_| panic!("kind not scalar: {:?}", func)); + let func = func.to_u8(); codegen_inline_asm_inner( fx, diff --git a/src/intrinsics/simd.rs b/src/intrinsics/simd.rs index 65eeaf156d844..ca910dccb0d06 100644 --- a/src/intrinsics/simd.rs +++ b/src/intrinsics/simd.rs @@ -147,8 +147,7 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>( let total_len = lane_count * 2; - let indexes = - idx.iter().map(|idx| idx.unwrap_leaf().try_to_u32().unwrap()).collect::>(); + let indexes = idx.iter().map(|idx| idx.unwrap_leaf().to_u32()).collect::>(); for &idx in &indexes { assert!(u64::from(idx) < total_len, "idx {} out of range 0..{}", idx, total_len); @@ -282,9 +281,7 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>( fx.tcx.dcx().span_fatal(span, "Index argument for `simd_insert` is not a constant"); }; - let idx: u32 = idx_const - .try_to_u32() - .unwrap_or_else(|_| panic!("kind not scalar: {:?}", idx_const)); + let idx: u32 = idx_const.to_u32(); let (lane_count, _lane_ty) = base.layout().ty.simd_size_and_type(fx.tcx); if u64::from(idx) >= lane_count { fx.tcx.dcx().span_fatal( @@ -330,9 +327,7 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>( return; }; - let idx = idx_const - .try_to_u32() - .unwrap_or_else(|_| panic!("kind not scalar: {:?}", idx_const)); + let idx = idx_const.to_u32(); let (lane_count, _lane_ty) = v.layout().ty.simd_size_and_type(fx.tcx); if u64::from(idx) >= lane_count { fx.tcx.dcx().span_fatal( diff --git a/src/value_and_place.rs b/src/value_and_place.rs index 512a96450a4b6..1aa28daeafc7e 100644 --- a/src/value_and_place.rs +++ b/src/value_and_place.rs @@ -327,7 +327,7 @@ impl<'tcx> CValue<'tcx> { let val = match layout.ty.kind() { ty::Uint(UintTy::U128) | ty::Int(IntTy::I128) => { - let const_val = const_val.assert_bits(layout.size); + let const_val = const_val.to_bits(layout.size); let lsb = fx.bcx.ins().iconst(types::I64, const_val as u64 as i64); let msb = fx.bcx.ins().iconst(types::I64, (const_val >> 64) as u64 as i64); fx.bcx.ins().iconcat(lsb, msb) @@ -339,7 +339,7 @@ impl<'tcx> CValue<'tcx> { | ty::Ref(..) | ty::RawPtr(..) | ty::FnPtr(..) => { - let raw_val = const_val.size().truncate(const_val.assert_bits(layout.size)); + let raw_val = const_val.size().truncate(const_val.to_bits(layout.size)); fx.bcx.ins().iconst(clif_ty, raw_val as i64) } ty::Float(FloatTy::F32) => { From d565d3d23d226b91fb2041c35c782469798c7e58 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 8 Jun 2024 16:13:45 +0200 Subject: [PATCH 167/892] ScalarInt: size mismatches are a bug, do not delay the panic --- src/common.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common.rs b/src/common.rs index 78d943192db07..548c23cc7948a 100644 --- a/src/common.rs +++ b/src/common.rs @@ -166,7 +166,7 @@ impl<'gcc, 'tcx> ConstMethods<'tcx> for CodegenCx<'gcc, 'tcx> { let bitsize = if layout.is_bool() { 1 } else { layout.size(self).bits() }; match cv { Scalar::Int(int) => { - let data = int.assert_bits(layout.size(self)); + let data = int.to_bits(layout.size(self)); // FIXME(antoyo): there's some issues with using the u128 code that follows, so hard-code // the paths for floating-point values. From a63b83eb4e46433216dac0558b978619c6746ea8 Mon Sep 17 00:00:00 2001 From: Shashank Trivedi <100513286+lordshashank@users.noreply.github.com> Date: Tue, 11 Jun 2024 02:43:44 +0530 Subject: [PATCH 168/892] ui pattern failure tests (#524) --- .github/workflows/failures.yml | 9 ++ build_system/src/build.rs | 17 ++-- build_system/src/prepare.rs | 15 ++-- build_system/src/test.rs | 150 +++++++++++++++++++++------------ build_system/src/utils.rs | 10 ++- tests/failing-ice-tests.txt | 36 ++++++++ 6 files changed, 170 insertions(+), 67 deletions(-) create mode 100644 tests/failing-ice-tests.txt diff --git a/.github/workflows/failures.yml b/.github/workflows/failures.yml index 9fa6f416c141e..66129f805d4c8 100644 --- a/.github/workflows/failures.yml +++ b/.github/workflows/failures.yml @@ -98,3 +98,12 @@ jobs: run: | ${{ matrix.libgccjit_version.env_extra }} ./y.sh test --release --clean --build-sysroot --test-failing-rustc ${{ matrix.libgccjit_version.extra }} | tee output_log rg --text "test result" output_log >> $GITHUB_STEP_SUMMARY + + - name: Run failing ui pattern tests for ICE + 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 + 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 + fi diff --git a/build_system/src/build.rs b/build_system/src/build.rs index ac428b4cec057..d465ab7e50662 100644 --- a/build_system/src/build.rs +++ b/build_system/src/build.rs @@ -68,7 +68,7 @@ fn cleanup_sysroot_previous_build(start_dir: &Path) { // Clean target dir except for build scripts and incremental cache let _ = walk_dir( start_dir.join("target"), - |dir: &Path| { + &mut |dir: &Path| { for top in &["debug", "release"] { let _ = fs::remove_dir_all(dir.join(top).join("build")); let _ = fs::remove_dir_all(dir.join(top).join("deps")); @@ -77,7 +77,7 @@ fn cleanup_sysroot_previous_build(start_dir: &Path) { let _ = walk_dir( dir.join(top), - |sub_dir: &Path| { + &mut |sub_dir: &Path| { if sub_dir .file_name() .map(|filename| filename.to_str().unwrap().starts_with("libsysroot")) @@ -87,7 +87,7 @@ fn cleanup_sysroot_previous_build(start_dir: &Path) { } Ok(()) }, - |file: &Path| { + &mut |file: &Path| { if file .file_name() .map(|filename| filename.to_str().unwrap().starts_with("libsysroot")) @@ -97,11 +97,13 @@ fn cleanup_sysroot_previous_build(start_dir: &Path) { } Ok(()) }, + false, ); } Ok(()) }, - |_| Ok(()), + &mut |_| Ok(()), + false, ); let _ = fs::remove_file(start_dir.join("Cargo.lock")); @@ -166,14 +168,15 @@ pub fn build_sysroot(env: &HashMap, config: &ConfigInfo) -> Resu // Copy files to sysroot let sysroot_path = start_dir.join(format!("sysroot/lib/rustlib/{}/lib/", config.target_triple)); create_dir(&sysroot_path)?; - let copier = |dir_to_copy: &Path| { + let mut copier = |dir_to_copy: &Path| { // FIXME: should not use shell command! run_command(&[&"cp", &"-r", &dir_to_copy, &sysroot_path], None).map(|_| ()) }; walk_dir( start_dir.join(&format!("target/{}/{}/deps", config.target_triple, channel)), - copier, - copier, + &mut copier.clone(), + &mut copier, + false, )?; // Copy the source files to the sysroot (Rust for Linux needs this). diff --git a/build_system/src/prepare.rs b/build_system/src/prepare.rs index a085d86361672..00aa632165e22 100644 --- a/build_system/src/prepare.rs +++ b/build_system/src/prepare.rs @@ -72,30 +72,33 @@ fn prepare_libcore( let mut patches = Vec::new(); walk_dir( "patches", - |_| Ok(()), - |file_path: &Path| { + &mut |_| Ok(()), + &mut |file_path: &Path| { patches.push(file_path.to_path_buf()); Ok(()) }, + false, )?; if cross_compile { walk_dir( "patches/cross_patches", - |_| Ok(()), - |file_path: &Path| { + &mut |_| Ok(()), + &mut |file_path: &Path| { patches.push(file_path.to_path_buf()); Ok(()) }, + false, )?; } if libgccjit12_patches { walk_dir( "patches/libgccjit12", - |_| Ok(()), - |file_path: &Path| { + &mut |_| Ok(()), + &mut |file_path: &Path| { patches.push(file_path.to_path_buf()); Ok(()) }, + false, )?; } patches.sort(); diff --git a/build_system/src/test.rs b/build_system/src/test.rs index f1b7b8d19b6ae..462d20d728d12 100644 --- a/build_system/src/test.rs +++ b/build_system/src/test.rs @@ -23,6 +23,10 @@ fn get_runners() -> Runners { runners.insert("--test-rustc", ("Run all rustc tests", test_rustc as Runner)); runners .insert("--test-successful-rustc", ("Run successful rustc tests", test_successful_rustc)); + runners.insert( + "--test-failing-ui-pattern-tests", + ("Run failing ui pattern tests", test_failing_ui_pattern_tests), + ); runners.insert("--test-failing-rustc", ("Run failing rustc tests", test_failing_rustc)); runners.insert("--projects", ("Run the tests of popular crates", test_projects)); runners.insert("--test-libcore", ("Run libcore tests", test_libcore)); @@ -808,7 +812,7 @@ fn extended_sysroot_tests(env: &Env, args: &TestArg) -> Result<(), String> { Ok(()) } -fn should_not_remove_test(file: &str) -> bool { +fn valid_ui_error_pattern_test(file: &str) -> bool { // contains //~ERROR, but shouldn't be removed [ "issues/auxiliary/issue-3136-a.rs", @@ -824,7 +828,7 @@ fn should_not_remove_test(file: &str) -> bool { } #[rustfmt::skip] -fn should_remove_test(file_path: &Path) -> Result { +fn contains_ui_error_patterns(file_path: &Path) -> Result { // Tests generating errors. let file = File::open(file_path) .map_err(|error| format!("Failed to read `{}`: {:?}", file_path.display(), error))?; @@ -856,10 +860,19 @@ fn should_remove_test(file_path: &Path) -> Result { Ok(false) } +// # Parameters +// +// * `env`: An environment variable that provides context for the function. +// * `args`: The arguments passed to the test. This could include things like the flags, config etc. +// * `prepare_files_callback`: A callback function that prepares the files needed for the test. Its used to remove/retain tests giving Error to run various rust test suits. +// * `run_error_pattern_test`: A boolean that determines whether to run only error pattern tests. +// * `test_type`: A string that indicates the type of the test being run. +// fn test_rustc_inner( env: &Env, args: &TestArg, prepare_files_callback: F, + run_error_pattern_test: bool, test_type: &str, ) -> Result<(), String> where @@ -876,54 +889,71 @@ where } if test_type == "ui" { - walk_dir( - rust_path.join("tests/ui"), - |dir| { - let dir_name = dir.file_name().and_then(|name| name.to_str()).unwrap_or(""); - if [ - "abi", - "extern", - "unsized-locals", - "proc-macro", - "threads-sendsync", - "borrowck", - "test-attrs", - ] - .iter() - .any(|name| *name == dir_name) - { - std::fs::remove_dir_all(dir).map_err(|error| { - format!("Failed to remove folder `{}`: {:?}", dir.display(), error) - })?; + if run_error_pattern_test { + // After we removed the error tests that are known to panic with rustc_codegen_gcc, we now remove the passing tests since this runs the error tests. + walk_dir( + rust_path.join("tests/ui"), + &mut |_dir| Ok(()), + &mut |file_path| { + if contains_ui_error_patterns(file_path)? { + Ok(()) + } else { + remove_file(file_path).map_err(|e| e.to_string()) + } + }, + true, + )?; + } else { + walk_dir( + rust_path.join("tests/ui"), + &mut |dir| { + let dir_name = dir.file_name().and_then(|name| name.to_str()).unwrap_or(""); + if [ + "abi", + "extern", + "unsized-locals", + "proc-macro", + "threads-sendsync", + "borrowck", + "test-attrs", + ] + .iter() + .any(|name| *name == dir_name) + { + std::fs::remove_dir_all(dir).map_err(|error| { + format!("Failed to remove folder `{}`: {:?}", dir.display(), error) + })?; + } + Ok(()) + }, + &mut |_| Ok(()), + false, + )?; + + // 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(()); } - Ok(()) - }, - |_| Ok(()), - )?; - // 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(()); + walk_dir(dir, &mut dir_handling, &mut file_handling, false) } - walk_dir(dir, dir_handling, file_handling) - } - fn file_handling(file_path: &Path) -> Result<(), String> { - if !file_path.extension().map(|extension| extension == "rs").unwrap_or(false) { - return Ok(()); - } - let path_str = file_path.display().to_string().replace("\\", "/"); - if should_not_remove_test(&path_str) { - return Ok(()); - } else if should_remove_test(file_path)? { - return remove_file(&file_path); + fn file_handling(file_path: &Path) -> Result<(), String> { + 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)? { + return remove_file(&file_path); + } + Ok(()) } - Ok(()) - } - - walk_dir(rust_path.join("tests/ui"), dir_handling, file_handling)?; + walk_dir(rust_path.join("tests/ui"), &mut dir_handling, &mut file_handling, false)?; + } let nb_parts = args.nb_parts.unwrap_or(0); if nb_parts > 0 { let current_part = args.current_part.unwrap(); @@ -1004,22 +1034,24 @@ where } fn test_rustc(env: &Env, args: &TestArg) -> Result<(), String> { - test_rustc_inner(env, args, |_| Ok(false), "run-make")?; - test_rustc_inner(env, args, |_| Ok(false), "ui") + test_rustc_inner(env, args, |_| Ok(false), false, "run-make")?; + test_rustc_inner(env, args, |_| Ok(false), false, "ui") } fn test_failing_rustc(env: &Env, args: &TestArg) -> Result<(), String> { let result1 = test_rustc_inner( env, args, - prepare_files_callback_failing("tests/failing-run-make-tests.txt", "run-make"), + retain_files_callback("tests/failing-run-make-tests.txt", "run-make"), + false, "run-make", ); let result2 = test_rustc_inner( env, args, - prepare_files_callback_failing("tests/failing-ui-tests.txt", "ui"), + retain_files_callback("tests/failing-ui-tests.txt", "ui"), + false, "ui", ); @@ -1030,18 +1062,30 @@ fn test_successful_rustc(env: &Env, args: &TestArg) -> Result<(), String> { test_rustc_inner( env, args, - prepare_files_callback_success("tests/failing-ui-tests.txt", "ui"), + remove_files_callback("tests/failing-ui-tests.txt", "ui"), + false, "ui", )?; test_rustc_inner( env, args, - prepare_files_callback_success("tests/failing-run-make-tests.txt", "run-make"), + remove_files_callback("tests/failing-run-make-tests.txt", "run-make"), + false, "run-make", ) } -fn prepare_files_callback_failing<'a>( +fn test_failing_ui_pattern_tests(env: &Env, args: &TestArg) -> Result<(), String> { + test_rustc_inner( + env, + args, + remove_files_callback("tests/failing-ice-tests.txt", "ui"), + true, + "ui", + ) +} + +fn retain_files_callback<'a>( file_path: &'a str, test_type: &'a str, ) -> impl Fn(&Path) -> Result + 'a { @@ -1104,7 +1148,7 @@ fn prepare_files_callback_failing<'a>( } } -fn prepare_files_callback_success<'a>( +fn remove_files_callback<'a>( file_path: &'a str, test_type: &'a str, ) -> impl Fn(&Path) -> Result + 'a { diff --git a/build_system/src/utils.rs b/build_system/src/utils.rs index cdda9d4a81e6b..3bba8df6c6504 100644 --- a/build_system/src/utils.rs +++ b/build_system/src/utils.rs @@ -343,7 +343,12 @@ pub fn git_clone_root_dir( git_clone_inner(to_clone, &dest_parent_dir.join(&repo_name), shallow_clone, repo_name) } -pub fn walk_dir(dir: P, mut dir_cb: D, mut file_cb: F) -> Result<(), String> +pub fn walk_dir( + dir: P, + dir_cb: &mut D, + file_cb: &mut F, + recursive: bool, +) -> Result<(), String> where P: AsRef, D: FnMut(&Path) -> Result<(), String>, @@ -358,6 +363,9 @@ where let entry_path = entry.path(); if entry_path.is_dir() { dir_cb(&entry_path)?; + if recursive { + walk_dir(entry_path, dir_cb, file_cb, recursive)?; // Recursive call + } } else { file_cb(&entry_path)?; } diff --git a/tests/failing-ice-tests.txt b/tests/failing-ice-tests.txt new file mode 100644 index 0000000000000..2084f86b62e19 --- /dev/null +++ b/tests/failing-ice-tests.txt @@ -0,0 +1,36 @@ +tests/ui/treat-err-as-bug/span_delayed_bug.rs +tests/ui/treat-err-as-bug/err.rs +tests/ui/simd/not-out-of-bounds.rs +tests/ui/simd/monomorphize-shuffle-index.rs +tests/ui/simd/masked-load-store-build-fail.rs +tests/ui/simd/intrinsic/generic-shuffle.rs +tests/ui/simd/intrinsic/generic-elements.rs +tests/ui/simd/intrinsic/generic-cast.rs +tests/ui/simd/intrinsic/generic-arithmetic-saturating-2.rs +tests/ui/simd/intrinsic/generic-arithmetic-2.rs +tests/ui/panics/default-backtrace-ice.rs +tests/ui/mir/lint/storage-live.rs +tests/ui/layout/valid_range_oob.rs +tests/ui/higher-ranked/trait-bounds/future.rs +tests/ui/consts/const-eval/const-eval-query-stack.rs +tests/ui/simd/masked-load-store.rs +tests/ui/simd/issue-39720.rs +tests/ui/simd/intrinsic/ptr-cast.rs +tests/ui/sepcomp/sepcomp-statics.rs +tests/ui/sepcomp/sepcomp-fns.rs +tests/ui/sepcomp/sepcomp-fns-backwards.rs +tests/ui/sepcomp/sepcomp-extern.rs +tests/ui/sepcomp/sepcomp-cci.rs +tests/ui/lto/thin-lto-inlines2.rs +tests/ui/lto/weak-works.rs +tests/ui/lto/thin-lto-inlines.rs +tests/ui/lto/thin-lto-global-allocator.rs +tests/ui/lto/msvc-imp-present.rs +tests/ui/lto/dylib-works.rs +tests/ui/lto/all-crates.rs +tests/ui/issues/issue-47364.rs +tests/ui/functions-closures/parallel-codegen-closures.rs +tests/ui/sepcomp/sepcomp-unwind.rs +tests/ui/extern/issue-64655-extern-rust-must-allow-unwind.rs +tests/ui/extern/issue-64655-allow-unwind-when-calling-panic-directly.rs +tests/ui/unwind-no-uwtable.rs From c06cbc8dbe87e6824e8c7b2e5714756abec7f89f Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Tue, 11 Jun 2024 12:18:15 +0000 Subject: [PATCH 169/892] Rustup to rustc 1.81.0-nightly (b5b13568f 2024-06-10) --- patches/stdlib-lock.toml | 6 ++---- rust-toolchain | 2 +- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/patches/stdlib-lock.toml b/patches/stdlib-lock.toml index 1bac8a93240b7..aea0a779b1e11 100644 --- a/patches/stdlib-lock.toml +++ b/patches/stdlib-lock.toml @@ -200,9 +200,9 @@ dependencies = [ [[package]] name = "object" -version = "0.32.1" +version = "0.36.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" +checksum = "576dfe1fc8f9df304abb159d767a29d0476f7750fbf8aa7ad07816004a207434" dependencies = [ "compiler_builtins", "memchr", @@ -407,8 +407,6 @@ dependencies = [ "core", "getopts", "libc", - "panic_abort", - "panic_unwind", "std", ] diff --git a/rust-toolchain b/rust-toolchain index 44a196c18ae17..35d7372a196ee 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2024-05-30" +channel = "nightly-2024-06-11" components = ["rust-src", "rustc-dev", "llvm-tools"] From ee188cabc298e9aff8e81f096b9e33830a0f9afb Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Tue, 11 Jun 2024 13:47:34 +0000 Subject: [PATCH 170/892] Fix rustc test suite --- scripts/test_rustc_tests.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/test_rustc_tests.sh b/scripts/test_rustc_tests.sh index 6c45a4ccf7962..fce46459cac4d 100755 --- a/scripts/test_rustc_tests.sh +++ b/scripts/test_rustc_tests.sh @@ -102,7 +102,7 @@ rm -r tests/run-make/output-type-permutations rm -r tests/run-make/emit-to-stdout rm -r tests/run-make/compressed-debuginfo rm -r tests/run-make/symbols-include-type-name - +rm -r tests/run-make/notify-all-emit-artifacts # giving different but possibly correct results # ============================================= @@ -154,9 +154,9 @@ index 9607ff02f96..b7d97caf9a2 100644 /// Construct a \`rustdoc\` invocation with \`-L \$(TARGET_RPATH_DIR)\` set. pub fn new() -> Self { let mut cmd = setup_common(); -- let target_rpath_dir = env::var_os("TARGET_RPATH_DIR").unwrap(); +- let target_rpath_dir = env_var_os("TARGET_RPATH_DIR"); - cmd.arg(format!("-L{}", target_rpath_dir.to_string_lossy())); - Self { cmd, stdin: None } + Self { cmd } } EOF From 02b20f88710e36c953cc46f08607ad9c82a11794 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 11 Jun 2024 15:01:57 +1000 Subject: [PATCH 171/892] Update a cranelift patch file for formatting changes. PR #125443 will reformat all the use declarations in the repo. This would break a patch kept in `rustc_codegen_cranelift` that gets applied to `library/std/src/sys/pal/windows/rand.rs`. So this commit formats the use declarations in `library/std/src/sys/pal/windows/rand.rs` in advance of #125443 and updates the patch file accordingly. The motivation is that #125443 is a huge change and we want to get fiddly little changes like this out of the way so it can be nothing more than an `x fmt --all`. --- patches/0029-stdlib-rawdylib-processprng.patch | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/patches/0029-stdlib-rawdylib-processprng.patch b/patches/0029-stdlib-rawdylib-processprng.patch index 6af11e54d88af..584dbdb647f60 100644 --- a/patches/0029-stdlib-rawdylib-processprng.patch +++ b/patches/0029-stdlib-rawdylib-processprng.patch @@ -12,7 +12,7 @@ diff --git a/library/std/src/sys/pal/windows/c.rs b/library/std/src/sys/pal/wind index ad8e01bfa9b..9ca8e4c16ce 100644 --- a/library/std/src/sys/pal/windows/c.rs +++ b/library/std/src/sys/pal/windows/c.rs -@@ -323,7 +323,7 @@ pub unsafe fn NtWriteFile( +@@ -312,7 +312,7 @@ pub unsafe fn NtWriteFile( // Use raw-dylib to import ProcessPrng as we can't rely on there being an import library. cfg_if::cfg_if! { @@ -26,8 +26,8 @@ index e427546222a..f2fe42a4d51 100644 --- a/library/std/src/sys/pal/windows/rand.rs +++ b/library/std/src/sys/pal/windows/rand.rs @@ -2,7 +2,7 @@ - use core::mem; - use core::ptr; + + use crate::sys::c; -#[cfg(not(target_vendor = "win7"))] +#[cfg(any())] From 0b7375f2a04076b64ab071ea0f538f6ca0ebb0c8 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 12 Jun 2024 13:49:36 +1000 Subject: [PATCH 172/892] Use `tidy` to sort crate attributes for all compiler crates. We already do this for a number of crates, e.g. `rustc_middle`, `rustc_span`, `rustc_metadata`, `rustc_span`, `rustc_errors`. For the ones we don't, in many cases the attributes are a mess. - There is no consistency about order of attribute kinds (e.g. `allow`/`deny`/`feature`). - Within attribute kind groups (e.g. the `feature` attributes), sometimes the order is alphabetical, and sometimes there is no particular order. - Sometimes the attributes of a particular kind aren't even grouped all together, e.g. there might be a `feature`, then an `allow`, then another `feature`. This commit extends the existing sorting to all compiler crates, increasing consistency. If any new attribute line is added there is now only one place it can go -- no need for arbitrary decisions. Exceptions: - `rustc_log`, `rustc_next_trait_solver` and `rustc_type_ir_macros`, because they have no crate attributes. - `rustc_codegen_gcc`, because it's quasi-external to rustc (e.g. it's ignored in `rustfmt.toml`). --- src/lib.rs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 39bbad16b0c00..0fea3fd425391 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,13 +1,16 @@ +// tidy-alphabetical-start +#![allow(rustc::diagnostic_outside_of_impl)] +#![allow(rustc::untranslatable_diagnostic)] #![cfg_attr(doc, allow(internal_features))] -#![cfg_attr(doc, feature(rustdoc_internals))] #![cfg_attr(doc, doc(rust_logo))] +#![cfg_attr(doc, feature(rustdoc_internals))] +// Note: please avoid adding other feature gates where possible #![feature(rustc_private)] // Note: please avoid adding other feature gates where possible -#![allow(rustc::diagnostic_outside_of_impl)] -#![allow(rustc::untranslatable_diagnostic)] #![warn(rust_2018_idioms)] -#![warn(unused_lifetimes)] #![warn(unreachable_pub)] +#![warn(unused_lifetimes)] +// tidy-alphabetical-end extern crate jobserver; #[macro_use] From 4e0af7cc6176b7410fa95c3324381c2baa9ad769 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Mon, 10 Jun 2024 16:17:38 +0000 Subject: [PATCH 173/892] Require any function with a tait in its signature to actually constrain a hidden type --- example/issue-72793.rs | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/example/issue-72793.rs b/example/issue-72793.rs index 166b006004385..2e08fbca8ef27 100644 --- a/example/issue-72793.rs +++ b/example/issue-72793.rs @@ -2,20 +2,23 @@ #![feature(type_alias_impl_trait)] -trait T { - type Item; -} +mod helper { + pub trait T { + type Item; + } -type Alias<'a> = impl T; + pub type Alias<'a> = impl T; -struct S; -impl<'a> T for &'a S { - type Item = &'a (); -} + struct S; + impl<'a> T for &'a S { + type Item = &'a (); + } -fn filter_positive<'a>() -> Alias<'a> { - &S + pub fn filter_positive<'a>() -> Alias<'a> { + &S + } } +use helper::*; fn with_positive(fun: impl Fn(Alias<'_>)) { fun(filter_positive()); From c3d463333f87821938c3fa6e71af8e455b9bf6c4 Mon Sep 17 00:00:00 2001 From: Waffle Lapkin Date: Thu, 23 May 2024 18:02:13 +0200 Subject: [PATCH 174/892] Fixup clippy tests Don't depend on the fact that `!` falls back to `()` and so panic-ish things can be used in `-> impl ImplementedForUnit` functions --- tests/ui/new_ret_no_self.rs | 5 +---- tests/ui/new_ret_no_self.stderr | 3 +-- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/tests/ui/new_ret_no_self.rs b/tests/ui/new_ret_no_self.rs index b944f531ef660..175b14d815a2c 100644 --- a/tests/ui/new_ret_no_self.rs +++ b/tests/ui/new_ret_no_self.rs @@ -390,9 +390,7 @@ mod issue7344 { impl RetImplTraitSelf2 { // should not trigger lint - fn new(t: T) -> impl Trait2<(), Self> { - unimplemented!() - } + fn new(t: T) -> impl Trait2<(), Self> {} } struct RetImplTraitNoSelf2(T); @@ -401,7 +399,6 @@ mod issue7344 { // should trigger lint fn new(t: T) -> impl Trait2<(), i32> { //~^ ERROR: methods called `new` usually return `Self` - unimplemented!() } } diff --git a/tests/ui/new_ret_no_self.stderr b/tests/ui/new_ret_no_self.stderr index d440a9f45fcdb..3597ad65838f6 100644 --- a/tests/ui/new_ret_no_self.stderr +++ b/tests/ui/new_ret_no_self.stderr @@ -96,11 +96,10 @@ LL | | } | |_________^ error: methods called `new` usually return `Self` - --> tests/ui/new_ret_no_self.rs:402:9 + --> tests/ui/new_ret_no_self.rs:400:9 | LL | / fn new(t: T) -> impl Trait2<(), i32> { LL | | -LL | | unimplemented!() LL | | } | |_________^ From 3bff119f63b804c3cacb3cd0217ac9e37660c732 Mon Sep 17 00:00:00 2001 From: Philipp Krones Date: Thu, 13 Jun 2024 12:30:48 +0200 Subject: [PATCH 175/892] Merge commit '3e5a02b13b1244545454752c6629b767522a44b1' into clippy-subtree-update --- CHANGELOG.md | 65 +++- Cargo.toml | 2 +- README.md | 4 +- book/src/configuration.md | 2 +- book/src/development/basics.md | 2 +- book/src/development/defining_lints.md | 4 +- .../proposals/syntax-tree-patterns.md | 12 +- clippy_config/Cargo.toml | 2 +- clippy_dummy/PUBLISH.md | 2 +- clippy_dummy/crates-readme.md | 4 +- clippy_lints/Cargo.toml | 2 +- clippy_lints/src/attrs/maybe_misused_cfg.rs | 51 --- .../src/attrs/mismatched_target_os.rs | 90 ----- clippy_lints/src/attrs/mod.rs | 73 +--- clippy_lints/src/blocks_in_conditions.rs | 32 +- clippy_lints/src/booleans.rs | 54 ++- .../src/cargo/lint_groups_priority.rs | 60 ++- clippy_lints/src/casts/cast_sign_loss.rs | 6 +- clippy_lints/src/casts/unnecessary_cast.rs | 4 +- clippy_lints/src/cognitive_complexity.rs | 4 +- clippy_lints/src/collection_is_never_read.rs | 4 +- clippy_lints/src/copies.rs | 6 +- clippy_lints/src/declared_lints.rs | 7 +- clippy_lints/src/deprecated_lints.rs | 26 ++ clippy_lints/src/doc/missing_headers.rs | 2 +- clippy_lints/src/eta_reduction.rs | 31 +- clippy_lints/src/float_literal.rs | 2 +- clippy_lints/src/floating_point_arithmetic.rs | 5 +- clippy_lints/src/format_args.rs | 4 +- clippy_lints/src/functions/must_use.rs | 4 +- .../src/functions/not_unsafe_ptr_arg_deref.rs | 4 +- clippy_lints/src/implicit_return.rs | 4 +- clippy_lints/src/implied_bounds_in_impls.rs | 8 +- clippy_lints/src/indexing_slicing.rs | 50 ++- .../src/integer_division_remainder_used.rs | 2 +- clippy_lints/src/iter_without_into_iter.rs | 34 +- clippy_lints/src/legacy_numeric_constants.rs | 2 +- clippy_lints/src/lib.deprecated.rs | 8 + clippy_lints/src/lib.rs | 4 + clippy_lints/src/manual_unwrap_or_default.rs | 13 +- clippy_lints/src/matches/redundant_guards.rs | 4 +- .../src/matches/redundant_pattern_match.rs | 4 +- .../src/methods/collapsible_str_replace.rs | 4 +- clippy_lints/src/methods/mod.rs | 62 ++- .../methods/needless_character_iteration.rs | 124 ++++++ .../src/methods/option_map_unwrap_or.rs | 2 +- .../src/methods/path_buf_push_overwrite.rs | 2 +- clippy_lints/src/methods/search_is_some.rs | 12 +- .../src/methods/single_char_insert_string.rs | 47 ++- .../src/methods/single_char_pattern.rs | 64 ---- .../src/methods/single_char_push_string.rs | 46 ++- clippy_lints/src/methods/str_splitn.rs | 4 +- .../src/methods/unnecessary_filter_map.rs | 4 +- .../src/methods/unnecessary_iter_cloned.rs | 4 +- .../methods/unnecessary_result_map_or_else.rs | 19 +- clippy_lints/src/methods/utils.rs | 63 +--- .../src/misc_early/zero_prefixed_literal.rs | 4 +- .../src/missing_asserts_for_indexing.rs | 4 +- clippy_lints/src/missing_const_for_fn.rs | 21 +- clippy_lints/src/missing_fields_in_debug.rs | 4 +- .../src/multiple_unsafe_ops_per_block.rs | 4 +- clippy_lints/src/needless_bool.rs | 13 +- clippy_lints/src/needless_late_init.rs | 6 +- clippy_lints/src/needless_maybe_sized.rs | 164 ++++++++ clippy_lints/src/needless_pass_by_ref_mut.rs | 4 +- clippy_lints/src/non_canonical_impls.rs | 10 +- clippy_lints/src/non_copy_const.rs | 32 +- .../src/operators/assign_op_pattern.rs | 4 +- clippy_lints/src/panic_in_result_fn.rs | 2 +- clippy_lints/src/redundant_async_block.rs | 4 +- clippy_lints/src/reference.rs | 3 + clippy_lints/src/returns.rs | 4 +- .../src/significant_drop_tightening.rs | 50 +-- clippy_lints/src/string_patterns.rs | 227 +++++++++++ clippy_lints/src/strings.rs | 10 +- clippy_lints/src/suspicious_trait_impl.rs | 4 +- .../missing_transmute_annotations.rs | 1 - clippy_lints/src/transmute/mod.rs | 2 +- .../src/undocumented_unsafe_blocks.rs | 4 +- clippy_lints/src/unused_self.rs | 2 +- clippy_lints/src/unwrap_in_result.rs | 2 +- clippy_lints/src/utils/author.rs | 2 +- .../internal_lints/lint_without_lint_pass.rs | 4 +- .../internal_lints/metadata_collector.rs | 2 +- clippy_lints/src/zero_repeat_side_effects.rs | 6 +- clippy_utils/Cargo.toml | 2 +- clippy_utils/src/consts.rs | 14 +- clippy_utils/src/hir_utils.rs | 12 +- clippy_utils/src/lib.rs | 24 +- clippy_utils/src/macros.rs | 10 +- clippy_utils/src/ptr.rs | 4 +- clippy_utils/src/qualify_min_const_fn.rs | 10 +- clippy_utils/src/source.rs | 45 +++ clippy_utils/src/ty.rs | 43 ++- clippy_utils/src/ty/type_certainty/mod.rs | 14 +- clippy_utils/src/usage.rs | 8 +- clippy_utils/src/visitors.rs | 14 +- declare_clippy_lint/Cargo.toml | 2 +- lintcheck/README.md | 4 +- rust-toolchain | 2 +- .../lint_groups_priority/fail/Cargo.stderr | 49 +-- .../lint_groups_priority/fail/Cargo.toml | 4 - .../lint_groups_priority/pass/Cargo.toml | 7 + tests/ui-toml/private-doc-errors/doc_lints.rs | 2 +- .../private-doc-errors/doc_lints.stderr | 2 +- .../ui-toml/type_repetition_in_bounds/main.rs | 1 + .../type_repetition_in_bounds/main.stderr | 2 +- tests/ui/author.stdout | 2 +- tests/ui/author/blocks.stdout | 6 +- tests/ui/author/call.stdout | 2 +- tests/ui/author/if.stdout | 2 +- tests/ui/author/issue_3849.stdout | 2 +- tests/ui/author/loop.stdout | 2 +- tests/ui/author/macro_in_closure.stdout | 2 +- tests/ui/author/matches.stdout | 4 +- tests/ui/auxiliary/proc_macro_derive.rs | 13 + tests/ui/auxiliary/proc_macros.rs | 6 +- tests/ui/blocks_in_conditions.fixed | 13 + tests/ui/blocks_in_conditions.rs | 13 + tests/ui/blocks_in_conditions_closure.rs | 89 ----- tests/ui/blocks_in_conditions_closure.stderr | 39 -- tests/ui/cfg_features.fixed | 29 -- tests/ui/cfg_features.rs | 29 -- tests/ui/cfg_features.stderr | 53 --- tests/ui/crashes/ice-9445.rs | 2 - tests/ui/crashes/ice-9445.stderr | 7 +- tests/ui/crashes/mut_mut_macro.rs | 33 -- .../enums.stderr | 43 +-- .../others.stderr | 27 +- .../traits.stderr | 26 +- tests/ui/deprecated.rs | 2 + tests/ui/deprecated.stderr | 14 +- tests/ui/deref_addrof.fixed | 4 + tests/ui/deref_addrof.rs | 4 + tests/ui/deref_addrof.stderr | 12 +- tests/ui/doc_unsafe.stderr | 10 +- tests/ui/double_neg.rs | 2 +- tests/ui/eta.fixed | 11 + tests/ui/eta.rs | 11 + tests/ui/eta.stderr | 14 +- tests/ui/floating_point_log.fixed | 15 + tests/ui/floating_point_log.rs | 15 + tests/ui/format_args.fixed | 1 + tests/ui/format_args.rs | 1 + tests/ui/format_args.stderr | 16 +- tests/ui/indexing_slicing_index.rs | 20 + tests/ui/indexing_slicing_index.stderr | 32 +- tests/ui/indexing_slicing_slice.rs | 129 ++++++- tests/ui/indexing_slicing_slice.stderr | 58 ++- tests/ui/infinite_loops.rs | 2 +- tests/ui/iter_over_hash_type.rs | 2 +- tests/ui/manual_pattern_char_comparison.fixed | 49 +++ tests/ui/manual_pattern_char_comparison.rs | 49 +++ .../ui/manual_pattern_char_comparison.stderr | 59 +++ tests/ui/manual_unwrap_or_default.fixed | 6 + tests/ui/manual_unwrap_or_default.rs | 15 + tests/ui/manual_unwrap_or_default.stderr | 25 +- tests/ui/match_same_arms2.fixed | 17 + tests/ui/match_same_arms2.rs | 18 + tests/ui/match_same_arms2.stderr | 18 +- tests/ui/mismatched_target_os_non_unix.fixed | 25 -- tests/ui/mismatched_target_os_non_unix.rs | 25 -- tests/ui/mismatched_target_os_non_unix.stderr | 37 -- tests/ui/mismatched_target_os_unix.fixed | 60 --- tests/ui/mismatched_target_os_unix.rs | 60 --- tests/ui/mismatched_target_os_unix.stderr | 184 --------- .../ui/missing_const_for_fn/could_be_const.rs | 30 ++ .../could_be_const.stderr | 27 +- tests/ui/missing_fields_in_debug.rs | 18 + tests/ui/missing_fields_in_debug.stderr | 16 +- tests/ui/needless_bool/fixable.fixed | 12 + tests/ui/needless_bool/fixable.rs | 12 + tests/ui/needless_bool/fixable.stderr | 20 +- tests/ui/needless_character_iteration.fixed | 57 +++ tests/ui/needless_character_iteration.rs | 65 ++++ tests/ui/needless_character_iteration.stderr | 67 ++++ tests/ui/needless_maybe_sized.fixed | 116 ++++++ tests/ui/needless_maybe_sized.rs | 119 ++++++ tests/ui/needless_maybe_sized.stderr | 353 ++++++++++++++++++ tests/ui/non_canonical_clone_impl.fixed | 20 + tests/ui/non_canonical_clone_impl.rs | 20 + tests/ui/non_canonical_clone_impl.stderr | 8 +- tests/ui/nonminimal_bool_methods.fixed | 2 - tests/ui/nonminimal_bool_methods.rs | 2 - tests/ui/nonminimal_bool_methods.stderr | 32 +- tests/ui/or_fun_call.fixed | 7 + tests/ui/or_fun_call.rs | 7 + tests/ui/overly_complex_bool_expr.fixed | 10 + tests/ui/overly_complex_bool_expr.rs | 10 + tests/ui/panic_in_result_fn.rs | 5 + tests/ui/panic_in_result_fn.stderr | 18 +- tests/ui/search_is_some.rs | 1 + tests/ui/search_is_some.stderr | 16 +- tests/ui/single_char_add_str.fixed | 10 + tests/ui/single_char_add_str.rs | 10 + tests/ui/single_char_add_str.stderr | 58 ++- tests/ui/str_to_string.fixed | 9 + tests/ui/str_to_string.stderr | 7 +- tests/ui/type_repetition_in_bounds.rs | 6 +- tests/ui/type_repetition_in_bounds.stderr | 10 +- tests/ui/unnecessary_clippy_cfg.rs | 8 +- tests/ui/unnecessary_clippy_cfg.stderr | 28 +- tests/ui/unwrap_in_result.rs | 5 + tests/ui/unwrap_in_result.stderr | 18 +- tests/ui/useless_conversion_try.rs | 6 +- tests/ui/useless_conversion_try.stderr | 18 +- util/gh-pages/script.js | 2 +- 207 files changed, 3098 insertions(+), 1667 deletions(-) delete mode 100644 clippy_lints/src/attrs/maybe_misused_cfg.rs delete mode 100644 clippy_lints/src/attrs/mismatched_target_os.rs create mode 100644 clippy_lints/src/methods/needless_character_iteration.rs delete mode 100644 clippy_lints/src/methods/single_char_pattern.rs create mode 100644 clippy_lints/src/needless_maybe_sized.rs create mode 100644 clippy_lints/src/string_patterns.rs delete mode 100644 tests/ui/blocks_in_conditions_closure.rs delete mode 100644 tests/ui/blocks_in_conditions_closure.stderr delete mode 100644 tests/ui/cfg_features.fixed delete mode 100644 tests/ui/cfg_features.rs delete mode 100644 tests/ui/cfg_features.stderr delete mode 100644 tests/ui/crashes/mut_mut_macro.rs create mode 100644 tests/ui/manual_pattern_char_comparison.fixed create mode 100644 tests/ui/manual_pattern_char_comparison.rs create mode 100644 tests/ui/manual_pattern_char_comparison.stderr delete mode 100644 tests/ui/mismatched_target_os_non_unix.fixed delete mode 100644 tests/ui/mismatched_target_os_non_unix.rs delete mode 100644 tests/ui/mismatched_target_os_non_unix.stderr delete mode 100644 tests/ui/mismatched_target_os_unix.fixed delete mode 100644 tests/ui/mismatched_target_os_unix.rs delete mode 100644 tests/ui/mismatched_target_os_unix.stderr create mode 100644 tests/ui/needless_character_iteration.fixed create mode 100644 tests/ui/needless_character_iteration.rs create mode 100644 tests/ui/needless_character_iteration.stderr create mode 100644 tests/ui/needless_maybe_sized.fixed create mode 100644 tests/ui/needless_maybe_sized.rs create mode 100644 tests/ui/needless_maybe_sized.stderr create mode 100644 tests/ui/str_to_string.fixed diff --git a/CHANGELOG.md b/CHANGELOG.md index d5115f70f6620..d7bcd7a19687d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,11 +6,69 @@ document. ## Unreleased / Beta / In Rust Nightly -[93f0a9a9...master](https://github.com/rust-lang/rust-clippy/compare/93f0a9a9...master) +[ca3b3937...master](https://github.com/rust-lang/rust-clippy/compare/ca3b3937...master) + +## Rust 1.79 + +Current stable, released 2024-06-13 + +[View all 102 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2024-03-08T11%3A13%3A58Z..2024-04-18T15%3A50%3A50Z+base%3Amaster) + +### New Lints + +* Added [`legacy_numeric_constants`] to `style` + [#12312](https://github.com/rust-lang/rust-clippy/pull/12312) +* Added [`missing_transmute_annotations`] to `suspicious` + [#12239](https://github.com/rust-lang/rust-clippy/pull/12239) +* Added [`integer_division_remainder_used`] to `restriction` + [#12451](https://github.com/rust-lang/rust-clippy/pull/12451) +* Added [`duplicated_attributes`] to `suspicious` + [#12378](https://github.com/rust-lang/rust-clippy/pull/12378) +* Added [`manual_unwrap_or_default`] to `suspicious` + [#12440](https://github.com/rust-lang/rust-clippy/pull/12440) +* Added [`zero_repeat_side_effects`] to `suspicious` + [#12449](https://github.com/rust-lang/rust-clippy/pull/12449) +* Added [`const_is_empty`] to `suspicious` + [#12310](https://github.com/rust-lang/rust-clippy/pull/12310) + +### Moves and Deprecations + +* Moved [`box_default`] to `style` (From `perf`) + [#12601](https://github.com/rust-lang/rust-clippy/pull/12601) +* Moved [`manual_clamp`] to `complexity` (From `nursery` now warn-by-default) + [#12543](https://github.com/rust-lang/rust-clippy/pull/12543) +* Moved [`readonly_write_lock`] to `perf` (From `nursery` now warn-by-default) + [#12479](https://github.com/rust-lang/rust-clippy/pull/12479) + +### Enhancements + +* [`module_name_repetitions`]: Added the [`allowed-prefixes`] configuration to allow common prefixes. + [#12573](https://github.com/rust-lang/rust-clippy/pull/12573) +* [`cast_sign_loss`], [`cast_possible_truncation`], [`cast_lossless`]: Are now allowed in macros + [#12631](https://github.com/rust-lang/rust-clippy/pull/12631) +* [`manual_clamp`]: Now only lints on constant min and max values + [#12543](https://github.com/rust-lang/rust-clippy/pull/12543) +* [`assigning_clones`]: Now considers the [`msrv`] configuration + [#12511](https://github.com/rust-lang/rust-clippy/pull/12511) +* [`needless_return`], [`useless_let_if_seq`], [`mut_mut`], [`read_zero_byte_vec`], [`unused_io_amount`], + [`unused_peekable`]: Now respects `#[allow]` attributes on the affected statement instead + [#12446](https://github.com/rust-lang/rust-clippy/pull/12446) + +### False Positive Fixes + +* [`cast_lossless`]: No longer lints when casting to `u128` + [#12496](https://github.com/rust-lang/rust-clippy/pull/12496) +* [`std_instead_of_core`] No longer lints on modules that are only in `std` + [#12447](https://github.com/rust-lang/rust-clippy/pull/12447) + +### ICE Fixes + +* [`needless_return`]: No longer crashes on non-ascii characters + [#12493](https://github.com/rust-lang/rust-clippy/pull/12493) ## Rust 1.78 -Current stable, released 2024-05-02 +Released 2024-05-02 [View all 112 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2024-01-26T05%3A46%3A23Z..2024-03-07T16%3A25%3A52Z+base%3Amaster) @@ -5474,6 +5532,7 @@ Released 2018-09-13 [`manual_next_back`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_next_back [`manual_non_exhaustive`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_non_exhaustive [`manual_ok_or`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_ok_or +[`manual_pattern_char_comparison`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_pattern_char_comparison [`manual_range_contains`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_range_contains [`manual_range_patterns`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_range_patterns [`manual_rem_euclid`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_rem_euclid @@ -5567,6 +5626,7 @@ Released 2018-09-13 [`needless_borrow`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_borrow [`needless_borrowed_reference`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_borrowed_reference [`needless_borrows_for_generic_args`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_borrows_for_generic_args +[`needless_character_iteration`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_character_iteration [`needless_collect`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_collect [`needless_continue`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_continue [`needless_doctest_main`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_doctest_main @@ -5576,6 +5636,7 @@ Released 2018-09-13 [`needless_late_init`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_late_init [`needless_lifetimes`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_lifetimes [`needless_match`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_match +[`needless_maybe_sized`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_maybe_sized [`needless_option_as_deref`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_option_as_deref [`needless_option_take`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_option_take [`needless_parens_on_range_literals`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_parens_on_range_literals diff --git a/Cargo.toml b/Cargo.toml index b48f3ab3919cc..4378849905514 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "clippy" -version = "0.1.80" +version = "0.1.81" description = "A bunch of helpful lints to avoid common pitfalls in Rust" repository = "https://github.com/rust-lang/rust-clippy" readme = "README.md" diff --git a/README.md b/README.md index fa18447090c19..ec76a6dfb08e9 100644 --- a/README.md +++ b/README.md @@ -172,7 +172,7 @@ You can add options to your code to `allow`/`warn`/`deny` Clippy lints: Note: `allow` means to suppress the lint for your code. With `warn` the lint will only emit a warning, while with `deny` the lint will emit an error, when -triggering for your code. An error causes clippy to exit with an error code, so +triggering for your code. An error causes Clippy to exit with an error code, so is useful in scripts like CI/CD. If you do not want to include your lint levels in your code, you can globally @@ -238,7 +238,7 @@ define the `CLIPPY_DISABLE_DOCS_LINKS` environment variable. ### Specifying the minimum supported Rust version Projects that intend to support old versions of Rust can disable lints pertaining to newer features by -specifying the minimum supported Rust version (MSRV) in the clippy configuration file. +specifying the minimum supported Rust version (MSRV) in the Clippy configuration file. ```toml msrv = "1.30.0" diff --git a/book/src/configuration.md b/book/src/configuration.md index ea549e4df4a51..b130544318980 100644 --- a/book/src/configuration.md +++ b/book/src/configuration.md @@ -99,7 +99,7 @@ For more details and options, refer to the Cargo documentation. ### Specifying the minimum supported Rust version Projects that intend to support old versions of Rust can disable lints pertaining to newer features by specifying the -minimum supported Rust version (MSRV) in the clippy configuration file. +minimum supported Rust version (MSRV) in the Clippy configuration file. ```toml msrv = "1.30.0" diff --git a/book/src/development/basics.md b/book/src/development/basics.md index f4c109ff11917..166b6aab9fb3b 100644 --- a/book/src/development/basics.md +++ b/book/src/development/basics.md @@ -107,7 +107,7 @@ More about [intellij] command usage and reasons. ## lintcheck -`cargo lintcheck` will build and run clippy on a fixed set of crates and +`cargo lintcheck` will build and run Clippy on a fixed set of crates and generate a log of the results. You can `git diff` the updated log against its previous version and see what impact your lint made on a small set of crates. If you add a new lint, please audit the resulting warnings and make sure there diff --git a/book/src/development/defining_lints.md b/book/src/development/defining_lints.md index 806ed0845f031..ceabb255e2d0b 100644 --- a/book/src/development/defining_lints.md +++ b/book/src/development/defining_lints.md @@ -163,11 +163,11 @@ declare_clippy_lint! { /// /// ### Example /// ```rust - /// // example code where clippy issues a warning + /// // example code where Clippy issues a warning /// ``` /// Use instead: /// ```rust - /// // example code which does not raise clippy warning + /// // example code which does not raise Clippy warning /// ``` #[clippy::version = "1.70.0"] // <- In which version was this implemented, keep it up to date! pub LINT_NAME, // <- The lint name IN_ALL_CAPS diff --git a/book/src/development/proposals/syntax-tree-patterns.md b/book/src/development/proposals/syntax-tree-patterns.md index 285488cec55c2..92fbf733a8faf 100644 --- a/book/src/development/proposals/syntax-tree-patterns.md +++ b/book/src/development/proposals/syntax-tree-patterns.md @@ -428,7 +428,7 @@ selection of possible matches is produced by the pattern syntax. In the second stage, the named subpattern references can be used to do additional tests like asserting that a node hasn't been created as part of a macro expansion. -## Implementing clippy lints using patterns +## Implementing Clippy lints using patterns As a "real-world" example, I re-implemented the `collapsible_if` lint using patterns. The code can be found @@ -572,7 +572,7 @@ The pattern syntax and the *PatternTree* are independent of specific syntax tree implementations (rust ast / hir, syn, ...). When looking at the different pattern examples in the previous sections, it can be seen that the patterns don't contain any information specific to a certain syntax tree implementation. -In contrast, clippy lints currently match against ast / hir syntax tree nodes +In contrast, Clippy lints currently match against ast / hir syntax tree nodes and therefore directly depend on their implementation. The connection between the *PatternTree* and specific syntax tree @@ -690,7 +690,7 @@ change, only the `IsMatch` trait implementations need to be adapted and existing lints can remain unchanged. This also means that if the `IsMatch` trait implementations were integrated into the compiler, updating the `IsMatch` implementations would be required for the compiler to compile successfully. This -could reduce the number of times clippy breaks because of changes in the +could reduce the number of times Clippy breaks because of changes in the compiler. Another advantage of the pattern's independence is that converting an `EarlyLintPass` lint into a `LatePassLint` wouldn't require rewriting the whole pattern matching code. In fact, the pattern might work just fine without any @@ -777,7 +777,7 @@ complexity to solve a relatively minor problem. The issue of users not knowing about the *PatternTree* structure could be solved by a tool that, given a rust program, generates a pattern that matches only this -program (similar to the clippy author lint). +program (similar to the Clippy author lint). For some simple cases (like the first example above), it might be possible to successfully mix Rust and pattern syntax. This space could be further explored @@ -789,7 +789,7 @@ The pattern syntax is heavily inspired by regular expressions (repetitions, alternatives, sequences, ...). From what I've seen until now, other linters also implement lints that directly -work on syntax tree data structures, just like clippy does currently. I would +work on syntax tree data structures, just like Clippy does currently. I would therefore consider the pattern syntax to be *new*, but please correct me if I'm wrong. @@ -982,5 +982,5 @@ pattern!{ } ``` -In the future, clippy could use this system to also provide lints for custom +In the future, Clippy could use this system to also provide lints for custom syntaxes like those found in macros. diff --git a/clippy_config/Cargo.toml b/clippy_config/Cargo.toml index 7f7dc9d6cfb0e..be0b048ac0c76 100644 --- a/clippy_config/Cargo.toml +++ b/clippy_config/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "clippy_config" -version = "0.1.80" +version = "0.1.81" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/clippy_dummy/PUBLISH.md b/clippy_dummy/PUBLISH.md index 8e420ec959a26..f0021f1594f0b 100644 --- a/clippy_dummy/PUBLISH.md +++ b/clippy_dummy/PUBLISH.md @@ -1,5 +1,5 @@ This is a dummy crate to publish to crates.io. It primarily exists to ensure -that folks trying to install clippy from crates.io get redirected to the +that folks trying to install Clippy from crates.io get redirected to the `rustup` technique. Before publishing, be sure to rename `clippy_dummy` to `clippy` in `Cargo.toml`, diff --git a/clippy_dummy/crates-readme.md b/clippy_dummy/crates-readme.md index 0decae8b9103d..a8ec0a1c36cdf 100644 --- a/clippy_dummy/crates-readme.md +++ b/clippy_dummy/crates-readme.md @@ -1,9 +1,9 @@ -Installing clippy via crates.io is deprecated. Please use the following: +Installing Clippy via crates.io is deprecated. Please use the following: ```terminal rustup component add clippy ``` -on a Rust version 1.29 or later. You may need to run `rustup self update` if it complains about a missing clippy binary. +on a Rust version 1.29 or later. You may need to run `rustup self update` if it complains about a missing Clippy binary. See [the homepage](https://github.com/rust-lang/rust-clippy/#clippy) for more information diff --git a/clippy_lints/Cargo.toml b/clippy_lints/Cargo.toml index 5e3a119337ccd..5708ffba08fd5 100644 --- a/clippy_lints/Cargo.toml +++ b/clippy_lints/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "clippy_lints" -version = "0.1.80" +version = "0.1.81" description = "A bunch of helpful lints to avoid common pitfalls in Rust" repository = "https://github.com/rust-lang/rust-clippy" readme = "README.md" diff --git a/clippy_lints/src/attrs/maybe_misused_cfg.rs b/clippy_lints/src/attrs/maybe_misused_cfg.rs deleted file mode 100644 index e6b2e835be867..0000000000000 --- a/clippy_lints/src/attrs/maybe_misused_cfg.rs +++ /dev/null @@ -1,51 +0,0 @@ -use super::{Attribute, MAYBE_MISUSED_CFG}; -use clippy_utils::diagnostics::span_lint_and_sugg; -use rustc_ast::{MetaItemKind, NestedMetaItem}; -use rustc_errors::Applicability; -use rustc_lint::EarlyContext; -use rustc_span::sym; - -pub(super) fn check(cx: &EarlyContext<'_>, attr: &Attribute) { - if attr.has_name(sym::cfg) - && let Some(items) = attr.meta_item_list() - { - check_nested_misused_cfg(cx, &items); - } -} - -fn check_nested_misused_cfg(cx: &EarlyContext<'_>, items: &[NestedMetaItem]) { - for item in items { - if let NestedMetaItem::MetaItem(meta) = item { - if let Some(ident) = meta.ident() - && ident.name.as_str() == "features" - && let Some(val) = meta.value_str() - { - span_lint_and_sugg( - cx, - MAYBE_MISUSED_CFG, - meta.span, - "'feature' may be misspelled as 'features'", - "did you mean", - format!("feature = \"{val}\""), - Applicability::MaybeIncorrect, - ); - } - if let MetaItemKind::List(list) = &meta.kind { - check_nested_misused_cfg(cx, list); - // If this is not a list, then we check for `cfg(test)`. - } else if let Some(ident) = meta.ident() - && matches!(ident.name.as_str(), "tests" | "Test") - { - span_lint_and_sugg( - cx, - MAYBE_MISUSED_CFG, - meta.span, - format!("'test' may be misspelled as '{}'", ident.name.as_str()), - "did you mean", - "test".to_string(), - Applicability::MaybeIncorrect, - ); - } - } - } -} diff --git a/clippy_lints/src/attrs/mismatched_target_os.rs b/clippy_lints/src/attrs/mismatched_target_os.rs deleted file mode 100644 index b1cc0a763c5e9..0000000000000 --- a/clippy_lints/src/attrs/mismatched_target_os.rs +++ /dev/null @@ -1,90 +0,0 @@ -use super::{Attribute, MISMATCHED_TARGET_OS}; -use clippy_utils::diagnostics::span_lint_and_then; -use rustc_ast::{MetaItemKind, NestedMetaItem}; -use rustc_errors::Applicability; -use rustc_lint::EarlyContext; -use rustc_span::{sym, Span}; - -static UNIX_SYSTEMS: &[&str] = &[ - "android", - "dragonfly", - "emscripten", - "freebsd", - "fuchsia", - "haiku", - "illumos", - "ios", - "l4re", - "linux", - "macos", - "netbsd", - "openbsd", - "redox", - "solaris", - "vxworks", -]; - -// NOTE: windows is excluded from the list because it's also a valid target family. -static NON_UNIX_SYSTEMS: &[&str] = &["hermit", "none", "wasi"]; - -pub(super) fn check(cx: &EarlyContext<'_>, attr: &Attribute) { - fn find_os(name: &str) -> Option<&'static str> { - UNIX_SYSTEMS - .iter() - .chain(NON_UNIX_SYSTEMS.iter()) - .find(|&&os| os == name) - .copied() - } - - fn is_unix(name: &str) -> bool { - UNIX_SYSTEMS.iter().any(|&os| os == name) - } - - fn find_mismatched_target_os(items: &[NestedMetaItem]) -> Vec<(&str, Span)> { - let mut mismatched = Vec::new(); - - for item in items { - if let NestedMetaItem::MetaItem(meta) = item { - match &meta.kind { - MetaItemKind::List(list) => { - mismatched.extend(find_mismatched_target_os(list)); - }, - MetaItemKind::Word => { - if let Some(ident) = meta.ident() - && let Some(os) = find_os(ident.name.as_str()) - { - mismatched.push((os, ident.span)); - } - }, - MetaItemKind::NameValue(..) => {}, - } - } - } - - mismatched - } - - if attr.has_name(sym::cfg) - && let Some(list) = attr.meta_item_list() - && let mismatched = find_mismatched_target_os(&list) - && !mismatched.is_empty() - { - let mess = "operating system used in target family position"; - - span_lint_and_then(cx, MISMATCHED_TARGET_OS, attr.span, mess, |diag| { - // Avoid showing the unix suggestion multiple times in case - // we have more than one mismatch for unix-like systems - let mut unix_suggested = false; - - for (os, span) in mismatched { - let sugg = format!("target_os = \"{os}\""); - diag.span_suggestion(span, "try", sugg, Applicability::MaybeIncorrect); - - if !unix_suggested && is_unix(os) { - diag.help("did you mean `unix`?"); - unix_suggested = true; - } - } - }); - } -} diff --git a/clippy_lints/src/attrs/mod.rs b/clippy_lints/src/attrs/mod.rs index a24bd5ed44be4..e4c98a32fd673 100644 --- a/clippy_lints/src/attrs/mod.rs +++ b/clippy_lints/src/attrs/mod.rs @@ -7,8 +7,6 @@ mod deprecated_semver; mod duplicated_attributes; mod empty_line_after; mod inline_always; -mod maybe_misused_cfg; -mod mismatched_target_os; mod mixed_attributes_style; mod non_minimal_cfg; mod should_panic_without_expect; @@ -270,39 +268,6 @@ declare_clippy_lint! { "usage of `cfg_attr(rustfmt)` instead of tool attributes" } -declare_clippy_lint! { - /// ### What it does - /// Checks for cfg attributes having operating systems used in target family position. - /// - /// ### Why is this bad? - /// The configuration option will not be recognised and the related item will not be included - /// by the conditional compilation engine. - /// - /// ### Example - /// ```no_run - /// #[cfg(linux)] - /// fn conditional() { } - /// ``` - /// - /// Use instead: - /// ```no_run - /// # mod hidden { - /// #[cfg(target_os = "linux")] - /// fn conditional() { } - /// # } - /// - /// // or - /// - /// #[cfg(unix)] - /// fn conditional() { } - /// ``` - /// Check the [Rust Reference](https://doc.rust-lang.org/reference/conditional-compilation.html#target_os) for more details. - #[clippy::version = "1.45.0"] - pub MISMATCHED_TARGET_OS, - correctness, - "usage of `cfg(operating_system)` instead of `cfg(target_os = \"operating_system\")`" -} - declare_clippy_lint! { /// ### What it does /// Checks for attributes that allow lints without a reason. @@ -391,38 +356,6 @@ declare_clippy_lint! { "ensure that all `cfg(any())` and `cfg(all())` have more than one condition" } -declare_clippy_lint! { - /// ### What it does - /// Checks for `#[cfg(features = "...")]` and suggests to replace it with - /// `#[cfg(feature = "...")]`. - /// - /// It also checks if `cfg(test)` was misspelled. - /// - /// ### Why is this bad? - /// Misspelling `feature` as `features` or `test` as `tests` can be sometimes hard to spot. It - /// may cause conditional compilation not work quietly. - /// - /// ### Example - /// ```no_run - /// #[cfg(features = "some-feature")] - /// fn conditional() { } - /// #[cfg(tests)] - /// mod tests { } - /// ``` - /// - /// Use instead: - /// ```no_run - /// #[cfg(feature = "some-feature")] - /// fn conditional() { } - /// #[cfg(test)] - /// mod tests { } - /// ``` - #[clippy::version = "1.69.0"] - pub MAYBE_MISUSED_CFG, - suspicious, - "prevent from misusing the wrong attr name" -} - declare_clippy_lint! { /// ### What it does /// Checks for `#[cfg_attr(feature = "cargo-clippy", ...)]` and for @@ -530,7 +463,7 @@ declare_clippy_lint! { /// #[allow(dead_code)] /// fn foo() {} /// ``` - #[clippy::version = "1.78.0"] + #[clippy::version = "1.79.0"] pub DUPLICATED_ATTRIBUTES, suspicious, "duplicated attribute" @@ -612,11 +545,9 @@ pub struct EarlyAttributes { impl_lint_pass!(EarlyAttributes => [ DEPRECATED_CFG_ATTR, - MISMATCHED_TARGET_OS, EMPTY_LINE_AFTER_OUTER_ATTR, EMPTY_LINE_AFTER_DOC_COMMENTS, NON_MINIMAL_CFG, - MAYBE_MISUSED_CFG, DEPRECATED_CLIPPY_CFG_ATTR, UNNECESSARY_CLIPPY_CFG, ]); @@ -629,9 +560,7 @@ impl EarlyLintPass for EarlyAttributes { fn check_attribute(&mut self, cx: &EarlyContext<'_>, attr: &Attribute) { deprecated_cfg_attr::check(cx, attr, &self.msrv); deprecated_cfg_attr::check_clippy(cx, attr); - mismatched_target_os::check(cx, attr); non_minimal_cfg::check(cx, attr); - maybe_misused_cfg::check(cx, attr); } extract_msrv_attr!(EarlyContext); diff --git a/clippy_lints/src/blocks_in_conditions.rs b/clippy_lints/src/blocks_in_conditions.rs index 171f303186012..eb05dc96cdebf 100644 --- a/clippy_lints/src/blocks_in_conditions.rs +++ b/clippy_lints/src/blocks_in_conditions.rs @@ -1,15 +1,11 @@ -use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg}; +use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::source::snippet_block_with_applicability; -use clippy_utils::ty::implements_trait; -use clippy_utils::visitors::{for_each_expr, Descend}; -use clippy_utils::{get_parent_expr, higher, is_from_proc_macro}; -use core::ops::ControlFlow; +use clippy_utils::{higher, is_from_proc_macro}; use rustc_errors::Applicability; use rustc_hir::{BlockCheckMode, Expr, ExprKind, MatchSource}; use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_middle::lint::in_external_macro; use rustc_session::declare_lint_pass; -use rustc_span::sym; declare_clippy_lint! { /// ### What it does @@ -124,30 +120,6 @@ impl<'tcx> LateLintPass<'tcx> for BlocksInConditions { ); } } - } else { - let _: Option = for_each_expr(cond, |e| { - if let ExprKind::Closure(closure) = e.kind { - // do not lint if the closure is called using an iterator (see #1141) - if let Some(parent) = get_parent_expr(cx, e) - && let ExprKind::MethodCall(_, self_arg, _, _) = &parent.kind - && let caller = cx.typeck_results().expr_ty(self_arg) - && let Some(iter_id) = cx.tcx.get_diagnostic_item(sym::Iterator) - && implements_trait(cx, caller, iter_id, &[]) - { - return ControlFlow::Continue(Descend::No); - } - - let body = cx.tcx.hir().body(closure.body); - let ex = &body.value; - if let ExprKind::Block(block, _) = ex.kind { - if !body.value.span.from_expansion() && !block.stmts.is_empty() { - span_lint(cx, BLOCKS_IN_CONDITIONS, ex.span, complex_block_message.clone()); - return ControlFlow::Continue(Descend::No); - } - } - } - ControlFlow::Continue(Descend::Yes) - }); } } } diff --git a/clippy_lints/src/booleans.rs b/clippy_lints/src/booleans.rs index b6341b3fe8e7c..a1c6c0b608f72 100644 --- a/clippy_lints/src/booleans.rs +++ b/clippy_lints/src/booleans.rs @@ -174,6 +174,25 @@ fn check_inverted_bool_in_condition( ); } +fn check_simplify_not(cx: &LateContext<'_>, expr: &Expr<'_>) { + if let ExprKind::Unary(UnOp::Not, inner) = &expr.kind + && !expr.span.from_expansion() + && !inner.span.from_expansion() + && let Some(suggestion) = simplify_not(cx, inner) + && cx.tcx.lint_level_at_node(NONMINIMAL_BOOL, expr.hir_id).0 != Level::Allow + { + span_lint_and_sugg( + cx, + NONMINIMAL_BOOL, + expr.span, + "this boolean expression can be simplified", + "try", + suggestion, + Applicability::MachineApplicable, + ); + } +} + struct NonminimalBoolVisitor<'a, 'tcx> { cx: &'a LateContext<'tcx>, } @@ -232,6 +251,11 @@ impl<'a, 'tcx, 'v> Hir2Qmm<'a, 'tcx, 'v> { _ => (), } } + + if self.cx.typeck_results().expr_ty(e).is_never() { + return Err("contains never type".to_owned()); + } + for (n, expr) in self.terminals.iter().enumerate() { if eq_expr_value(self.cx, e, expr) { #[expect(clippy::cast_possible_truncation)] @@ -542,8 +566,7 @@ impl<'a, 'tcx> NonminimalBoolVisitor<'a, 'tcx> { } }; if improvements.is_empty() { - let mut visitor = NotSimplificationVisitor { cx: self.cx }; - visitor.visit_expr(e); + check_simplify_not(self.cx, e); } else { nonminimal_bool_lint( improvements @@ -586,30 +609,3 @@ fn implements_ord(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { .get_diagnostic_item(sym::Ord) .map_or(false, |id| implements_trait(cx, ty, id, &[])) } - -struct NotSimplificationVisitor<'a, 'tcx> { - cx: &'a LateContext<'tcx>, -} - -impl<'a, 'tcx> Visitor<'tcx> for NotSimplificationVisitor<'a, 'tcx> { - fn visit_expr(&mut self, expr: &'tcx Expr<'_>) { - if let ExprKind::Unary(UnOp::Not, inner) = &expr.kind - && !expr.span.from_expansion() - && !inner.span.from_expansion() - && let Some(suggestion) = simplify_not(self.cx, inner) - && self.cx.tcx.lint_level_at_node(NONMINIMAL_BOOL, expr.hir_id).0 != Level::Allow - { - span_lint_and_sugg( - self.cx, - NONMINIMAL_BOOL, - expr.span, - "this boolean expression can be simplified", - "try", - suggestion, - Applicability::MachineApplicable, - ); - } - - walk_expr(self, expr); - } -} diff --git a/clippy_lints/src/cargo/lint_groups_priority.rs b/clippy_lints/src/cargo/lint_groups_priority.rs index 0d9eaac882f79..e924542fea2aa 100644 --- a/clippy_lints/src/cargo/lint_groups_priority.rs +++ b/clippy_lints/src/cargo/lint_groups_priority.rs @@ -71,12 +71,6 @@ struct CargoToml { workspace: Workspace, } -#[derive(Default, Debug)] -struct LintsAndGroups { - lints: Vec>, - groups: Vec<(Spanned, Spanned)>, -} - fn toml_span(range: Range, file: &SourceFile) -> Span { Span::new( file.start_pos + BytePos::from_usize(range.start), @@ -86,27 +80,28 @@ fn toml_span(range: Range, file: &SourceFile) -> Span { ) } -fn check_table(cx: &LateContext<'_>, table: LintTable, groups: &FxHashSet<&str>, file: &SourceFile) { - let mut by_priority = BTreeMap::<_, LintsAndGroups>::new(); +fn check_table(cx: &LateContext<'_>, table: LintTable, known_groups: &FxHashSet<&str>, file: &SourceFile) { + let mut lints = Vec::new(); + let mut groups = Vec::new(); for (name, config) in table { - let lints_and_groups = by_priority.entry(config.as_ref().priority()).or_default(); - if groups.contains(name.get_ref().as_str()) { - lints_and_groups.groups.push((name, config)); + if name.get_ref() == "warnings" { + continue; + } + + if known_groups.contains(name.get_ref().as_str()) { + groups.push((name, config)); } else { - lints_and_groups.lints.push(name); + lints.push((name, config.into_inner())); } } - let low_priority = by_priority - .iter() - .find(|(_, lints_and_groups)| !lints_and_groups.lints.is_empty()) - .map_or(-1, |(&lowest_lint_priority, _)| lowest_lint_priority - 1); - for (priority, LintsAndGroups { lints, groups }) in by_priority { - let Some(last_lint_alphabetically) = lints.last() else { - continue; - }; - - for (group, config) in groups { + for (group, group_config) in groups { + let priority = group_config.get_ref().priority(); + let level = group_config.get_ref().level(); + if let Some((conflict, _)) = lints + .iter() + .rfind(|(_, lint_config)| lint_config.priority() == priority && lint_config.level() != level) + { span_lint_and_then( cx, LINT_GROUPS_PRIORITY, @@ -116,22 +111,23 @@ fn check_table(cx: &LateContext<'_>, table: LintTable, groups: &FxHashSet<&str>, group.as_ref() ), |diag| { - let config_span = toml_span(config.span(), file); - if config.as_ref().is_implicit() { + let config_span = toml_span(group_config.span(), file); + + if group_config.as_ref().is_implicit() { diag.span_label(config_span, "has an implicit priority of 0"); } - // add the label to next lint after this group that has the same priority - let lint = lints - .iter() - .filter(|lint| lint.span().start > group.span().start) - .min_by_key(|lint| lint.span().start) - .unwrap_or(last_lint_alphabetically); - diag.span_label(toml_span(lint.span(), file), "has the same priority as this lint"); + diag.span_label(toml_span(conflict.span(), file), "has the same priority as this lint"); diag.note("the order of the lints in the table is ignored by Cargo"); + let mut suggestion = String::new(); + let low_priority = lints + .iter() + .map(|(_, config)| config.priority().saturating_sub(1)) + .min() + .unwrap_or(-1); Serialize::serialize( &LintConfigTable { - level: config.as_ref().level().into(), + level: level.into(), priority: Some(low_priority), }, toml::ser::ValueSerializer::new(&mut suggestion), diff --git a/clippy_lints/src/casts/cast_sign_loss.rs b/clippy_lints/src/casts/cast_sign_loss.rs index 864489ee3fcd5..8bbd41b0db1ee 100644 --- a/clippy_lints/src/casts/cast_sign_loss.rs +++ b/clippy_lints/src/casts/cast_sign_loss.rs @@ -3,7 +3,7 @@ use std::ops::ControlFlow; use clippy_utils::consts::{constant, Constant}; use clippy_utils::diagnostics::span_lint; -use clippy_utils::visitors::{for_each_expr, Descend}; +use clippy_utils::visitors::{for_each_expr_without_closures, Descend}; use clippy_utils::{method_chain_args, sext}; use rustc_hir::{BinOpKind, Expr, ExprKind}; use rustc_lint::LateContext; @@ -266,7 +266,7 @@ fn expr_add_sign(cx: &LateContext<'_>, expr: &Expr<'_>) -> Sign { fn exprs_with_muldiv_binop_peeled<'e>(expr: &'e Expr<'_>) -> Vec<&'e Expr<'e>> { let mut res = vec![]; - for_each_expr(expr, |sub_expr| -> ControlFlow { + for_each_expr_without_closures(expr, |sub_expr| -> ControlFlow { // We don't check for mul/div/rem methods here, but we could. if let ExprKind::Binary(op, lhs, _rhs) = sub_expr.kind { if matches!(op.node, BinOpKind::Mul | BinOpKind::Div) { @@ -315,7 +315,7 @@ fn exprs_with_muldiv_binop_peeled<'e>(expr: &'e Expr<'_>) -> Vec<&'e Expr<'e>> { fn exprs_with_add_binop_peeled<'e>(expr: &'e Expr<'_>) -> Vec<&'e Expr<'e>> { let mut res = vec![]; - for_each_expr(expr, |sub_expr| -> ControlFlow { + for_each_expr_without_closures(expr, |sub_expr| -> ControlFlow { // We don't check for add methods here, but we could. if let ExprKind::Binary(op, _lhs, _rhs) = sub_expr.kind { if matches!(op.node, BinOpKind::Add) { diff --git a/clippy_lints/src/casts/unnecessary_cast.rs b/clippy_lints/src/casts/unnecessary_cast.rs index a7f7bf7854e65..fb0b0cba6a662 100644 --- a/clippy_lints/src/casts/unnecessary_cast.rs +++ b/clippy_lints/src/casts/unnecessary_cast.rs @@ -1,7 +1,7 @@ use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::numeric_literal::NumericLiteral; use clippy_utils::source::snippet_opt; -use clippy_utils::visitors::{for_each_expr, Visitable}; +use clippy_utils::visitors::{for_each_expr_without_closures, Visitable}; use clippy_utils::{get_parent_expr, is_hir_ty_cfg_dependant, is_ty_alias, path_to_local}; use rustc_ast::{LitFloatType, LitIntType, LitKind}; use rustc_errors::Applicability; @@ -245,7 +245,7 @@ fn fp_ty_mantissa_nbits(typ: Ty<'_>) -> u32 { /// TODO: Maybe we should move this to `clippy_utils` so others won't need to go down this dark, /// dark path reimplementing this (or something similar). fn is_cast_from_ty_alias<'tcx>(cx: &LateContext<'tcx>, expr: impl Visitable<'tcx>, cast_from: Ty<'tcx>) -> bool { - for_each_expr(expr, |expr| { + for_each_expr_without_closures(expr, |expr| { // Calls are a `Path`, and usage of locals are a `Path`. So, this checks // - call() as i32 // - local as i32 diff --git a/clippy_lints/src/cognitive_complexity.rs b/clippy_lints/src/cognitive_complexity.rs index ee1bb63b50d30..e41abf422349d 100644 --- a/clippy_lints/src/cognitive_complexity.rs +++ b/clippy_lints/src/cognitive_complexity.rs @@ -3,7 +3,7 @@ use clippy_utils::diagnostics::span_lint_and_help; use clippy_utils::source::snippet_opt; use clippy_utils::ty::is_type_diagnostic_item; -use clippy_utils::visitors::for_each_expr; +use clippy_utils::visitors::for_each_expr_without_closures; use clippy_utils::{get_async_fn_body, is_async_fn, LimitStack}; use core::ops::ControlFlow; use rustc_ast::ast::Attribute; @@ -65,7 +65,7 @@ impl CognitiveComplexity { let mut cc = 1u64; let mut returns = 0u64; - let _: Option = for_each_expr(expr, |e| { + let _: Option = for_each_expr_without_closures(expr, |e| { match e.kind { ExprKind::If(_, _, _) => { cc += 1; diff --git a/clippy_lints/src/collection_is_never_read.rs b/clippy_lints/src/collection_is_never_read.rs index 70856b808810b..28d9f68d504cc 100644 --- a/clippy_lints/src/collection_is_never_read.rs +++ b/clippy_lints/src/collection_is_never_read.rs @@ -1,6 +1,6 @@ use clippy_utils::diagnostics::span_lint; use clippy_utils::ty::{is_type_diagnostic_item, is_type_lang_item}; -use clippy_utils::visitors::{for_each_expr_with_closures, Visitable}; +use clippy_utils::visitors::{for_each_expr, Visitable}; use clippy_utils::{get_enclosing_block, path_to_local_id}; use core::ops::ControlFlow; use rustc_hir::{Body, ExprKind, HirId, LangItem, LetStmt, Node, PatKind}; @@ -82,7 +82,7 @@ fn has_no_read_access<'tcx, T: Visitable<'tcx>>(cx: &LateContext<'tcx>, id: HirI let mut has_read_access = false; // Inspect all expressions and sub-expressions in the block. - for_each_expr_with_closures(cx, block, |expr| { + for_each_expr(cx, block, |expr| { // Ignore expressions that are not simply `id`. if !path_to_local_id(expr, id) { return ControlFlow::Continue(()); diff --git a/clippy_lints/src/copies.rs b/clippy_lints/src/copies.rs index ccf1d9d6f8c0d..480df675d7544 100644 --- a/clippy_lints/src/copies.rs +++ b/clippy_lints/src/copies.rs @@ -1,7 +1,7 @@ use clippy_utils::diagnostics::{span_lint_and_note, span_lint_and_then}; use clippy_utils::source::{first_line_of_span, indent_of, reindent_multiline, snippet, snippet_opt}; use clippy_utils::ty::{needs_ordered_drop, InteriorMut}; -use clippy_utils::visitors::for_each_expr; +use clippy_utils::visitors::for_each_expr_without_closures; use clippy_utils::{ capture_local_usage, eq_expr_value, find_binding_init, get_enclosing_block, hash_expr, hash_stmt, if_sequence, is_else_clause, is_lint_allowed, path_to_local, search_same, ContainsName, HirEqInterExpr, SpanlessEq, @@ -362,7 +362,7 @@ fn eq_binding_names(s: &Stmt<'_>, names: &[(HirId, Symbol)]) -> bool { /// Checks if the statement modifies or moves any of the given locals. fn modifies_any_local<'tcx>(cx: &LateContext<'tcx>, s: &'tcx Stmt<'_>, locals: &HirIdSet) -> bool { - for_each_expr(s, |e| { + for_each_expr_without_closures(s, |e| { if let Some(id) = path_to_local(e) && locals.contains(&id) && !capture_local_usage(cx, e).is_imm_ref() @@ -413,7 +413,7 @@ fn scan_block_for_eq<'tcx>( let mut cond_locals = HirIdSet::default(); for &cond in conds { - let _: Option = for_each_expr(cond, |e| { + let _: Option = for_each_expr_without_closures(cond, |e| { if let Some(id) = path_to_local(e) { cond_locals.insert(id); } diff --git a/clippy_lints/src/declared_lints.rs b/clippy_lints/src/declared_lints.rs index df2ef465700d4..7e43a99e9f24f 100644 --- a/clippy_lints/src/declared_lints.rs +++ b/clippy_lints/src/declared_lints.rs @@ -58,8 +58,6 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[ crate::attrs::EMPTY_LINE_AFTER_DOC_COMMENTS_INFO, crate::attrs::EMPTY_LINE_AFTER_OUTER_ATTR_INFO, crate::attrs::INLINE_ALWAYS_INFO, - crate::attrs::MAYBE_MISUSED_CFG_INFO, - crate::attrs::MISMATCHED_TARGET_OS_INFO, crate::attrs::MIXED_ATTRIBUTES_STYLE_INFO, crate::attrs::NON_MINIMAL_CFG_INFO, crate::attrs::SHOULD_PANIC_WITHOUT_EXPECT_INFO, @@ -419,6 +417,7 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[ crate::methods::MAP_UNWRAP_OR_INFO, crate::methods::MUT_MUTEX_LOCK_INFO, crate::methods::NAIVE_BYTECOUNT_INFO, + crate::methods::NEEDLESS_CHARACTER_ITERATION_INFO, crate::methods::NEEDLESS_COLLECT_INFO, crate::methods::NEEDLESS_OPTION_AS_DEREF_INFO, crate::methods::NEEDLESS_OPTION_TAKE_INFO, @@ -449,7 +448,6 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[ crate::methods::SEEK_TO_START_INSTEAD_OF_REWIND_INFO, crate::methods::SHOULD_IMPLEMENT_TRAIT_INFO, crate::methods::SINGLE_CHAR_ADD_STR_INFO, - crate::methods::SINGLE_CHAR_PATTERN_INFO, crate::methods::SKIP_WHILE_NEXT_INFO, crate::methods::STABLE_SORT_PRIMITIVE_INFO, crate::methods::STRING_EXTEND_CHARS_INFO, @@ -531,6 +529,7 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[ crate::needless_for_each::NEEDLESS_FOR_EACH_INFO, crate::needless_if::NEEDLESS_IF_INFO, crate::needless_late_init::NEEDLESS_LATE_INIT_INFO, + crate::needless_maybe_sized::NEEDLESS_MAYBE_SIZED_INFO, crate::needless_parens_on_range_literals::NEEDLESS_PARENS_ON_RANGE_LITERALS_INFO, crate::needless_pass_by_ref_mut::NEEDLESS_PASS_BY_REF_MUT_INFO, crate::needless_pass_by_value::NEEDLESS_PASS_BY_VALUE_INFO, @@ -656,6 +655,8 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[ crate::std_instead_of_core::ALLOC_INSTEAD_OF_CORE_INFO, crate::std_instead_of_core::STD_INSTEAD_OF_ALLOC_INFO, crate::std_instead_of_core::STD_INSTEAD_OF_CORE_INFO, + crate::string_patterns::MANUAL_PATTERN_CHAR_COMPARISON_INFO, + crate::string_patterns::SINGLE_CHAR_PATTERN_INFO, crate::strings::STRING_ADD_INFO, crate::strings::STRING_ADD_ASSIGN_INFO, crate::strings::STRING_FROM_UTF8_AS_BYTES_INFO, diff --git a/clippy_lints/src/deprecated_lints.rs b/clippy_lints/src/deprecated_lints.rs index 9aa5af3190fb2..a0900f46f6aa6 100644 --- a/clippy_lints/src/deprecated_lints.rs +++ b/clippy_lints/src/deprecated_lints.rs @@ -215,3 +215,29 @@ declare_deprecated_lint! { pub WRONG_PUB_SELF_CONVENTION, "set the `avoid-breaking-exported-api` config option to `false` to enable the `wrong_self_convention` lint for public items" } + +declare_deprecated_lint! { + /// ### What it does + /// Nothing. This lint has been deprecated. + /// + /// ### Deprecation reason + /// This lint has been superseded by rustc's own [`unexpected_cfgs`] lint that is able to detect the `#[cfg(features)]` and `#[cfg(tests)]` typos. + /// + /// [`unexpected_cfgs`]: https://doc.rust-lang.org/rustc/lints/listing/warn-by-default.html#unexpected-cfgs + #[clippy::version = "1.80.0"] + pub MAYBE_MISUSED_CFG, + "this lint has been replaced by `unexpected_cfgs`" +} + +declare_deprecated_lint! { + /// ### What it does + /// Nothing. This lint has been deprecated. + /// + /// ### Deprecation reason + /// This lint has been superseded by rustc's own [`unexpected_cfgs`] lint that is able to detect invalid `#[cfg(linux)]` attributes. + /// + /// [`unexpected_cfgs`]: https://doc.rust-lang.org/rustc/lints/listing/warn-by-default.html#unexpected-cfgs + #[clippy::version = "1.80.0"] + pub MISMATCHED_TARGET_OS, + "this lint has been replaced by `unexpected_cfgs`" +} diff --git a/clippy_lints/src/doc/missing_headers.rs b/clippy_lints/src/doc/missing_headers.rs index 010fab803d99c..e3d7484072612 100644 --- a/clippy_lints/src/doc/missing_headers.rs +++ b/clippy_lints/src/doc/missing_headers.rs @@ -37,7 +37,7 @@ pub fn check( cx, MISSING_SAFETY_DOC, span, - "unsafe function's docs miss `# Safety` section", + "unsafe function's docs are missing a `# Safety` section", ), (true, Safety::Safe) => span_lint( cx, diff --git a/clippy_lints/src/eta_reduction.rs b/clippy_lints/src/eta_reduction.rs index 48c4c4206fe88..42ec2c00823c8 100644 --- a/clippy_lints/src/eta_reduction.rs +++ b/clippy_lints/src/eta_reduction.rs @@ -9,8 +9,8 @@ use rustc_hir::{BindingMode, Expr, ExprKind, FnRetTy, Param, PatKind, QPath, Saf use rustc_infer::infer::TyCtxtInferExt; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::ty::{ - self, Binder, ClosureArgs, ClosureKind, FnSig, GenericArg, GenericArgKind, List, Region, RegionKind, Ty, - TypeVisitableExt, TypeckResults, TyCtxt, + self, Binder, ClosureArgs, ClosureKind, FnSig, GenericArg, GenericArgKind, List, Region, RegionKind, Ty, TyCtxt, + TypeVisitableExt, TypeckResults, }; use rustc_session::declare_lint_pass; use rustc_span::symbol::sym; @@ -123,7 +123,8 @@ impl<'tcx> LateLintPass<'tcx> for EtaReduction { ExprKind::Path(QPath::Resolved(..) | QPath::TypeRelative(..)) ) => { - let callee_ty = typeck.expr_ty(callee).peel_refs(); + let callee_ty_raw = typeck.expr_ty(callee); + let callee_ty = callee_ty_raw.peel_refs(); if matches!(type_diagnostic_name(cx, callee_ty), Some(sym::Arc | sym::Rc)) || !check_inputs(typeck, body.params, None, args) { @@ -170,15 +171,25 @@ impl<'tcx> LateLintPass<'tcx> for EtaReduction { { span_lint_and_then(cx, REDUNDANT_CLOSURE, expr.span, "redundant closure", |diag| { if let Some(mut snippet) = snippet_opt(cx, callee.span) { - if let Ok((ClosureKind::FnMut, _)) = cx.tcx.infer_ctxt().build().type_implements_fn_trait( - cx.param_env, - Binder::bind_with_vars(callee_ty_adjusted, List::empty()), - ty::PredicatePolarity::Positive, - ) && path_to_local(callee).map_or(false, |l| { + if path_to_local(callee).map_or(false, |l| { + // FIXME: Do we really need this `local_used_in` check? + // Isn't it checking something like... `callee(callee)`? + // If somehow this check is needed, add some test for it, + // 'cuz currently nothing changes after deleting this check. local_used_in(cx, l, args) || local_used_after_expr(cx, l, expr) }) { - // Mutable closure is used after current expr; we cannot consume it. - snippet = format!("&mut {snippet}"); + match cx.tcx.infer_ctxt().build().type_implements_fn_trait( + cx.param_env, + Binder::bind_with_vars(callee_ty_adjusted, List::empty()), + ty::PredicatePolarity::Positive, + ) { + // Mutable closure is used after current expr; we cannot consume it. + Ok((ClosureKind::FnMut, _)) => snippet = format!("&mut {snippet}"), + Ok((ClosureKind::Fn, _)) if !callee_ty_raw.is_ref() => { + snippet = format!("&{snippet}"); + }, + _ => (), + } } diag.span_suggestion( expr.span, diff --git a/clippy_lints/src/float_literal.rs b/clippy_lints/src/float_literal.rs index 4ec9bd757ff45..4d301daabe4c5 100644 --- a/clippy_lints/src/float_literal.rs +++ b/clippy_lints/src/float_literal.rs @@ -103,7 +103,7 @@ impl<'tcx> LateLintPass<'tcx> for FloatLiteral { return; } - if is_whole && !sym_str.contains(|c| c == 'e' || c == 'E') { + if is_whole && !sym_str.contains(['e', 'E']) { // Normalize the literal by stripping the fractional portion if sym_str.split('.').next().unwrap() != float_str { // If the type suffix is missing the suggestion would be diff --git a/clippy_lints/src/floating_point_arithmetic.rs b/clippy_lints/src/floating_point_arithmetic.rs index 46d47e217b04a..68bdf88d0a7e4 100644 --- a/clippy_lints/src/floating_point_arithmetic.rs +++ b/clippy_lints/src/floating_point_arithmetic.rs @@ -2,7 +2,8 @@ use clippy_utils::consts::Constant::{Int, F32, F64}; use clippy_utils::consts::{constant, constant_simple, Constant}; use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::{ - eq_expr_value, get_parent_expr, higher, in_constant, is_no_std_crate, numeric_literal, peel_blocks, sugg, + eq_expr_value, get_parent_expr, higher, in_constant, is_inherent_method_call, is_no_std_crate, numeric_literal, + peel_blocks, sugg, }; use rustc_errors::Applicability; use rustc_hir::{BinOpKind, Expr, ExprKind, PathSegment, UnOp}; @@ -759,7 +760,7 @@ impl<'tcx> LateLintPass<'tcx> for FloatingPointArithmetic { if let ExprKind::MethodCall(path, receiver, args, _) = &expr.kind { let recv_ty = cx.typeck_results().expr_ty(receiver); - if recv_ty.is_floating_point() && !is_no_std_crate(cx) { + if recv_ty.is_floating_point() && !is_no_std_crate(cx) && is_inherent_method_call(cx, expr) { match path.ident.name.as_str() { "ln" => check_ln1p(cx, expr, receiver), "log" => check_log_base(cx, expr, receiver, args), diff --git a/clippy_lints/src/format_args.rs b/clippy_lints/src/format_args.rs index 86115807aa4d1..99def199af0c2 100644 --- a/clippy_lints/src/format_args.rs +++ b/clippy_lints/src/format_args.rs @@ -424,14 +424,14 @@ impl<'a, 'tcx> FormatArgsExpr<'a, 'tcx> { count_needed_derefs(receiver_ty, cx.typeck_results().expr_adjustments(receiver).iter()) && implements_trait(cx, target, display_trait_id, &[]) && let Some(sized_trait_id) = cx.tcx.lang_items().sized_trait() - && let Some(receiver_snippet) = snippet_opt(cx, receiver.span) + && let Some(receiver_snippet) = snippet_opt(cx, receiver.span.source_callsite()) { let needs_ref = !implements_trait(cx, receiver_ty, sized_trait_id, &[]); if n_needed_derefs == 0 && !needs_ref { span_lint_and_sugg( cx, TO_STRING_IN_FORMAT_ARGS, - to_string_span.with_lo(receiver.span.hi()), + to_string_span.with_lo(receiver.span.source_callsite().hi()), format!("`to_string` applied to a type that implements `Display` in `{name}!` args"), "remove this", String::new(), diff --git a/clippy_lints/src/functions/must_use.rs b/clippy_lints/src/functions/must_use.rs index e7ec2b3151e6a..cce8617821e2c 100644 --- a/clippy_lints/src/functions/must_use.rs +++ b/clippy_lints/src/functions/must_use.rs @@ -14,7 +14,7 @@ use clippy_utils::attrs::is_proc_macro; use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_then}; use clippy_utils::source::snippet_opt; use clippy_utils::ty::is_must_use_ty; -use clippy_utils::visitors::for_each_expr; +use clippy_utils::visitors::for_each_expr_without_closures; use clippy_utils::{return_ty, trait_ref_of_method}; use core::ops::ControlFlow; @@ -226,7 +226,7 @@ fn is_mutated_static(e: &hir::Expr<'_>) -> bool { } fn mutates_static<'tcx>(cx: &LateContext<'tcx>, body: &'tcx hir::Body<'_>) -> bool { - for_each_expr(body.value, |e| { + for_each_expr_without_closures(body.value, |e| { use hir::ExprKind::{AddrOf, Assign, AssignOp, Call, MethodCall}; match e.kind { diff --git a/clippy_lints/src/functions/not_unsafe_ptr_arg_deref.rs b/clippy_lints/src/functions/not_unsafe_ptr_arg_deref.rs index b44a5f20ef68e..1aeefe73cf68f 100644 --- a/clippy_lints/src/functions/not_unsafe_ptr_arg_deref.rs +++ b/clippy_lints/src/functions/not_unsafe_ptr_arg_deref.rs @@ -5,7 +5,7 @@ use rustc_span::def_id::LocalDefId; use clippy_utils::diagnostics::span_lint; use clippy_utils::ty::type_is_unsafe_function; -use clippy_utils::visitors::for_each_expr_with_closures; +use clippy_utils::visitors::for_each_expr; use clippy_utils::{iter_input_pats, path_to_local}; use core::ops::ControlFlow; @@ -49,7 +49,7 @@ fn check_raw_ptr<'tcx>( if !raw_ptrs.is_empty() { let typeck = cx.tcx.typeck_body(body.id()); - let _: Option = for_each_expr_with_closures(cx, body.value, |e| { + let _: Option = for_each_expr(cx, body.value, |e| { match e.kind { hir::ExprKind::Call(f, args) if type_is_unsafe_function(cx, typeck.expr_ty(f)) => { for arg in args { diff --git a/clippy_lints/src/implicit_return.rs b/clippy_lints/src/implicit_return.rs index cc342007ec617..2f543781c44c1 100644 --- a/clippy_lints/src/implicit_return.rs +++ b/clippy_lints/src/implicit_return.rs @@ -1,6 +1,6 @@ use clippy_utils::diagnostics::span_lint_hir_and_then; use clippy_utils::source::{snippet_with_applicability, snippet_with_context, walk_span_to_context}; -use clippy_utils::visitors::for_each_expr; +use clippy_utils::visitors::for_each_expr_without_closures; use clippy_utils::{get_async_fn_body, is_async_fn}; use core::ops::ControlFlow; use rustc_errors::Applicability; @@ -153,7 +153,7 @@ fn lint_implicit_returns( ExprKind::Loop(block, ..) => { let mut add_return = false; - let _: Option = for_each_expr(block, |e| { + let _: Option = for_each_expr_without_closures(block, |e| { if let ExprKind::Break(dest, sub_expr) = e.kind { if dest.target_id.ok() == Some(expr.hir_id) { if call_site_span.is_none() && e.span.ctxt() == ctxt { diff --git a/clippy_lints/src/implied_bounds_in_impls.rs b/clippy_lints/src/implied_bounds_in_impls.rs index 2b389d4f9b194..170ecf896b4e1 100644 --- a/clippy_lints/src/implied_bounds_in_impls.rs +++ b/clippy_lints/src/implied_bounds_in_impls.rs @@ -3,8 +3,8 @@ use clippy_utils::source::snippet; use rustc_errors::{Applicability, SuggestionStyle}; use rustc_hir::def_id::DefId; use rustc_hir::{ - GenericArg, GenericBound, GenericBounds, ItemKind, PredicateOrigin, TraitBoundModifier, TyKind, AssocItemConstraint, - WherePredicate, + AssocItemConstraint, GenericArg, GenericBound, GenericBounds, ItemKind, PredicateOrigin, TraitBoundModifier, + TyKind, WherePredicate, }; use rustc_hir_analysis::lower_ty; use rustc_lint::{LateContext, LateLintPass}; @@ -83,8 +83,8 @@ fn emit_lint( let mut sugg = vec![(implied_span_extended, String::new())]; - // We also might need to include associated item constraints that were specified in the implied bound, - // but omitted in the implied-by bound: + // We also might need to include associated item constraints that were specified in the implied + // bound, but omitted in the implied-by bound: // `fn f() -> impl Deref + DerefMut` // If we're going to suggest removing `Deref<..>`, we'll need to put `` on `DerefMut` let omitted_constraints: Vec<_> = implied_constraints diff --git a/clippy_lints/src/indexing_slicing.rs b/clippy_lints/src/indexing_slicing.rs index e3e79749bea60..d54f2af65cdea 100644 --- a/clippy_lints/src/indexing_slicing.rs +++ b/clippy_lints/src/indexing_slicing.rs @@ -2,12 +2,14 @@ use clippy_utils::consts::{constant, Constant}; use clippy_utils::diagnostics::{span_lint, span_lint_and_then}; -use clippy_utils::higher; +use clippy_utils::ty::{deref_chain, get_adt_inherent_method}; +use clippy_utils::{higher, is_from_proc_macro}; use rustc_ast::ast::RangeLimits; use rustc_hir::{Expr, ExprKind}; use rustc_lint::{LateContext, LateLintPass}; -use rustc_middle::ty; +use rustc_middle::ty::{self, Ty}; use rustc_session::impl_lint_pass; +use rustc_span::sym; declare_clippy_lint! { /// ### What it does @@ -100,11 +102,21 @@ impl IndexingSlicing { impl<'tcx> LateLintPass<'tcx> for IndexingSlicing { fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { - if self.suppress_restriction_lint_in_const && cx.tcx.hir().is_inside_const_context(expr.hir_id) { + if (self.suppress_restriction_lint_in_const && cx.tcx.hir().is_inside_const_context(expr.hir_id)) + || is_from_proc_macro(cx, expr) + { return; } - if let ExprKind::Index(array, index, _) = &expr.kind { + if let ExprKind::Index(array, index, _) = &expr.kind + && let expr_ty = cx.typeck_results().expr_ty(array) + && let mut deref = deref_chain(cx, expr_ty) + && deref.any(|l| { + l.peel_refs().is_slice() + || l.peel_refs().is_array() + || ty_has_applicable_get_function(cx, l.peel_refs(), expr_ty, expr) + }) + { let note = "the suggestion might not be applicable in constant blocks"; let ty = cx.typeck_results().expr_ty(array).peel_refs(); if let Some(range) = higher::Range::hir(index) { @@ -231,3 +243,33 @@ fn to_const_range(cx: &LateContext<'_>, range: higher::Range<'_>, array_size: u1 (start, end) } + +/// Checks if the output Ty of the `get` method on this Ty (if any) matches the Ty returned by the +/// indexing operation (if any). +fn ty_has_applicable_get_function<'tcx>( + cx: &LateContext<'tcx>, + ty: Ty<'tcx>, + array_ty: Ty<'tcx>, + index_expr: &Expr<'_>, +) -> bool { + if let ty::Adt(_, _) = array_ty.kind() + && let Some(get_output_ty) = get_adt_inherent_method(cx, ty, sym!(get)).map(|m| { + cx.tcx + .fn_sig(m.def_id) + .skip_binder() + .output() + .skip_binder() + }) + && let ty::Adt(def, args) = get_output_ty.kind() + && cx.tcx.is_diagnostic_item(sym::Option, def.0.did) + && let Some(option_generic_param) = args.first() + && let generic_ty = option_generic_param.expect_ty().peel_refs() + // FIXME: ideally this would handle type params and projections properly, for now just assume it's the same type + && (cx.typeck_results().expr_ty(index_expr).peel_refs() == generic_ty.peel_refs() + || matches!(generic_ty.peel_refs().kind(), ty::Param(_) | ty::Alias(_, _))) + { + true + } else { + false + } +} diff --git a/clippy_lints/src/integer_division_remainder_used.rs b/clippy_lints/src/integer_division_remainder_used.rs index cf598d5045ec3..a1215491b48c3 100644 --- a/clippy_lints/src/integer_division_remainder_used.rs +++ b/clippy_lints/src/integer_division_remainder_used.rs @@ -22,7 +22,7 @@ declare_clippy_lint! { /// ```no_run /// let my_div = 10 >> 1; /// ``` - #[clippy::version = "1.78.0"] + #[clippy::version = "1.79.0"] pub INTEGER_DIVISION_REMAINDER_USED, restriction, "use of disallowed default division and remainder operations" diff --git a/clippy_lints/src/iter_without_into_iter.rs b/clippy_lints/src/iter_without_into_iter.rs index 601d0e151aae8..6b03f2597b083 100644 --- a/clippy_lints/src/iter_without_into_iter.rs +++ b/clippy_lints/src/iter_without_into_iter.rs @@ -1,7 +1,7 @@ use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::get_parent_as_impl; use clippy_utils::source::snippet; -use clippy_utils::ty::{implements_trait, make_normalized_projection}; +use clippy_utils::ty::{deref_chain, get_adt_inherent_method, implements_trait, make_normalized_projection}; use rustc_ast::Mutability; use rustc_errors::Applicability; use rustc_hir::{FnRetTy, ImplItemKind, ImplicitSelfKind, ItemKind, TyKind}; @@ -9,8 +9,7 @@ use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_middle::lint::in_external_macro; use rustc_middle::ty::{self, Ty}; use rustc_session::declare_lint_pass; -use rustc_span::{sym, Symbol}; -use std::iter; +use rustc_span::sym; declare_clippy_lint! { /// ### What it does @@ -124,33 +123,6 @@ fn is_ty_exported(cx: &LateContext<'_>, ty: Ty<'_>) -> bool { .is_some_and(|did| cx.effective_visibilities.is_exported(did)) } -/// Returns the deref chain of a type, starting with the type itself. -fn deref_chain<'cx, 'tcx>(cx: &'cx LateContext<'tcx>, ty: Ty<'tcx>) -> impl Iterator> + 'cx { - iter::successors(Some(ty), |&ty| { - if let Some(deref_did) = cx.tcx.lang_items().deref_trait() - && implements_trait(cx, ty, deref_did, &[]) - { - make_normalized_projection(cx.tcx, cx.param_env, deref_did, sym::Target, [ty]) - } else { - None - } - }) -} - -fn adt_has_inherent_method(cx: &LateContext<'_>, ty: Ty<'_>, method_name: Symbol) -> bool { - if let Some(ty_did) = ty.ty_adt_def().map(ty::AdtDef::did) { - cx.tcx.inherent_impls(ty_did).into_iter().flatten().any(|&did| { - cx.tcx - .associated_items(did) - .filter_by_name_unhygienic(method_name) - .next() - .is_some_and(|item| item.kind == ty::AssocKind::Fn) - }) - } else { - false - } -} - impl LateLintPass<'_> for IterWithoutIntoIter { fn check_item(&mut self, cx: &LateContext<'_>, item: &rustc_hir::Item<'_>) { if !in_external_macro(cx.sess(), item.span) @@ -167,7 +139,7 @@ impl LateLintPass<'_> for IterWithoutIntoIter { } && !deref_chain(cx, ty).any(|ty| { // We can't check inherent impls for slices, but we know that they have an `iter(_mut)` method - ty.peel_refs().is_slice() || adt_has_inherent_method(cx, ty, expected_method_name) + ty.peel_refs().is_slice() || get_adt_inherent_method(cx, ty, expected_method_name).is_some() }) && let Some(iter_assoc_span) = imp.items.iter().find_map(|item| { if item.ident.name == sym!(IntoIter) { diff --git a/clippy_lints/src/legacy_numeric_constants.rs b/clippy_lints/src/legacy_numeric_constants.rs index 00124dcdd91dc..eadfeb6e34181 100644 --- a/clippy_lints/src/legacy_numeric_constants.rs +++ b/clippy_lints/src/legacy_numeric_constants.rs @@ -28,7 +28,7 @@ declare_clippy_lint! { /// ```rust /// let eps = f32::EPSILON; /// ``` - #[clippy::version = "1.72.0"] + #[clippy::version = "1.79.0"] pub LEGACY_NUMERIC_CONSTANTS, style, "checks for usage of legacy std numeric constants and methods" diff --git a/clippy_lints/src/lib.deprecated.rs b/clippy_lints/src/lib.deprecated.rs index 80bde1b11384b..0d21261822dd0 100644 --- a/clippy_lints/src/lib.deprecated.rs +++ b/clippy_lints/src/lib.deprecated.rs @@ -67,4 +67,12 @@ "clippy::wrong_pub_self_convention", "set the `avoid-breaking-exported-api` config option to `false` to enable the `wrong_self_convention` lint for public items", ); + store.register_removed( + "clippy::maybe_misused_cfg", + "this lint has been replaced by `unexpected_cfgs`", + ); + store.register_removed( + "clippy::mismatched_target_os", + "this lint has been replaced by `unexpected_cfgs`", + ); } diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index 3328d642bd855..c65581d5203e9 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -251,6 +251,7 @@ mod needless_else; mod needless_for_each; mod needless_if; mod needless_late_init; +mod needless_maybe_sized; mod needless_parens_on_range_literals; mod needless_pass_by_ref_mut; mod needless_pass_by_value; @@ -325,6 +326,7 @@ mod size_of_in_element_count; mod size_of_ref; mod slow_vector_initialization; mod std_instead_of_core; +mod string_patterns; mod strings; mod strlen_on_c_strings; mod suspicious_operation_groupings; @@ -1058,6 +1060,7 @@ pub fn register_lints(store: &mut rustc_lint::LintStore, conf: &'static Conf) { store.register_late_pass(|_| Box::new(no_mangle_with_rust_abi::NoMangleWithRustAbi)); store.register_late_pass(|_| Box::new(collection_is_never_read::CollectionIsNeverRead)); store.register_late_pass(|_| Box::new(missing_assert_message::MissingAssertMessage)); + store.register_late_pass(|_| Box::new(needless_maybe_sized::NeedlessMaybeSized)); store.register_late_pass(|_| Box::new(redundant_async_block::RedundantAsyncBlock)); store.register_late_pass(|_| Box::new(let_with_type_underscore::UnderscoreTyped)); store.register_late_pass(|_| Box::new(allow_attributes::AllowAttribute)); @@ -1165,6 +1168,7 @@ pub fn register_lints(store: &mut rustc_lint::LintStore, conf: &'static Conf) { ..Default::default() }) }); + store.register_late_pass(|_| Box::new(string_patterns::StringPatterns)); // add lints here, do not remove this comment, it's used in `new_lint` } diff --git a/clippy_lints/src/manual_unwrap_or_default.rs b/clippy_lints/src/manual_unwrap_or_default.rs index 84fb183e3f798..17399fb2cc212 100644 --- a/clippy_lints/src/manual_unwrap_or_default.rs +++ b/clippy_lints/src/manual_unwrap_or_default.rs @@ -43,7 +43,7 @@ declare_clippy_lint! { /// let x: Option> = Some(Vec::new()); /// let y: Vec = x.unwrap_or_default(); /// ``` - #[clippy::version = "1.78.0"] + #[clippy::version = "1.79.0"] pub MANUAL_UNWRAP_OR_DEFAULT, suspicious, "check if a `match` or `if let` can be simplified with `unwrap_or_default`" @@ -57,7 +57,8 @@ fn get_some<'tcx>(cx: &LateContext<'tcx>, pat: &Pat<'tcx>) -> Option { // Since it comes from a pattern binding, we need to get the parent to actually match // against it. && let Some(def_id) = cx.tcx.opt_parent(def_id) - && cx.tcx.lang_items().get(LangItem::OptionSome) == Some(def_id) + && (cx.tcx.lang_items().get(LangItem::OptionSome) == Some(def_id) + || cx.tcx.lang_items().get(LangItem::ResultOk) == Some(def_id)) { let mut bindings = Vec::new(); pat.each_binding(|_, id, _, _| bindings.push(id)); @@ -80,6 +81,14 @@ fn get_none<'tcx>(cx: &LateContext<'tcx>, arm: &Arm<'tcx>) -> Option<&'tcx Expr< && cx.tcx.lang_items().get(LangItem::OptionNone) == Some(def_id) { Some(arm.body) + } else if let PatKind::TupleStruct(QPath::Resolved(_, path), _, _)= arm.pat.kind + && let Some(def_id) = path.res.opt_def_id() + // Since it comes from a pattern binding, we need to get the parent to actually match + // against it. + && let Some(def_id) = cx.tcx.opt_parent(def_id) + && cx.tcx.lang_items().get(LangItem::ResultErr) == Some(def_id) + { + Some(arm.body) } else if let PatKind::Wild = arm.pat.kind { // We consider that the `Some` check will filter it out if it's not right. Some(arm.body) diff --git a/clippy_lints/src/matches/redundant_guards.rs b/clippy_lints/src/matches/redundant_guards.rs index a75cf37945f77..c2c0fbf439d51 100644 --- a/clippy_lints/src/matches/redundant_guards.rs +++ b/clippy_lints/src/matches/redundant_guards.rs @@ -2,7 +2,7 @@ use clippy_config::msrvs::Msrv; use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::macros::matching_root_macro_call; use clippy_utils::source::snippet; -use clippy_utils::visitors::{for_each_expr, is_local_used}; +use clippy_utils::visitors::{for_each_expr_without_closures, is_local_used}; use clippy_utils::{in_constant, path_to_local}; use rustc_ast::{BorrowKind, LitKind}; use rustc_errors::Applicability; @@ -249,7 +249,7 @@ fn emit_redundant_guards<'tcx>( /// an error in the future, and rustc already actively warns against this (see rust#41620), /// so we don't consider those as usable within patterns for linting purposes. fn expr_can_be_pat(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { - for_each_expr(expr, |expr| { + for_each_expr_without_closures(expr, |expr| { if match expr.kind { ExprKind::ConstBlock(..) => cx.tcx.features().inline_const_pat, ExprKind::Call(c, ..) if let ExprKind::Path(qpath) = c.kind => { diff --git a/clippy_lints/src/matches/redundant_pattern_match.rs b/clippy_lints/src/matches/redundant_pattern_match.rs index 78973984fb0bb..0e4b2d9d34a02 100644 --- a/clippy_lints/src/matches/redundant_pattern_match.rs +++ b/clippy_lints/src/matches/redundant_pattern_match.rs @@ -3,7 +3,7 @@ use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then}; use clippy_utils::source::{snippet, walk_span_to_context}; use clippy_utils::sugg::{make_unop, Sugg}; use clippy_utils::ty::{is_type_diagnostic_item, needs_ordered_drop}; -use clippy_utils::visitors::{any_temporaries_need_ordered_drop, for_each_expr}; +use clippy_utils::visitors::{any_temporaries_need_ordered_drop, for_each_expr_without_closures}; use clippy_utils::{higher, is_expn_of, is_trait_method}; use rustc_ast::ast::LitKind; use rustc_errors::Applicability; @@ -283,7 +283,7 @@ pub(super) fn check_match<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, op // to see that there aren't any let chains anywhere in the guard, as that would break // if we suggest `t.is_none() && (let X = y && z)` for: // `match t { None if let X = y && z => true, _ => false }` - let has_nested_let_chain = for_each_expr(guard, |expr| { + let has_nested_let_chain = for_each_expr_without_closures(guard, |expr| { if matches!(expr.kind, ExprKind::Let(..)) { ControlFlow::Break(()) } else { diff --git a/clippy_lints/src/methods/collapsible_str_replace.rs b/clippy_lints/src/methods/collapsible_str_replace.rs index 5409ede6008b6..1fab6c0e499d4 100644 --- a/clippy_lints/src/methods/collapsible_str_replace.rs +++ b/clippy_lints/src/methods/collapsible_str_replace.rs @@ -1,6 +1,6 @@ use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::source::snippet; -use clippy_utils::visitors::for_each_expr; +use clippy_utils::visitors::for_each_expr_without_closures; use clippy_utils::{eq_expr_value, get_parent_expr}; use core::ops::ControlFlow; use rustc_errors::Applicability; @@ -46,7 +46,7 @@ fn collect_replace_calls<'tcx>( let mut methods = VecDeque::new(); let mut from_args = VecDeque::new(); - let _: Option<()> = for_each_expr(expr, |e| { + let _: Option<()> = for_each_expr_without_closures(expr, |e| { if let Some(("replace", _, [from, to], _, _)) = method_call(e) { if eq_expr_value(cx, to_arg, to) && cx.typeck_results().expr_ty(from).peel_refs().is_char() { methods.push_front(e); diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs index 75a86c0c83448..6200716afbe99 100644 --- a/clippy_lints/src/methods/mod.rs +++ b/clippy_lints/src/methods/mod.rs @@ -66,6 +66,7 @@ mod map_flatten; mod map_identity; mod map_unwrap_or; mod mut_mutex_lock; +mod needless_character_iteration; mod needless_collect; mod needless_option_as_deref; mod needless_option_take; @@ -93,7 +94,6 @@ mod seek_from_current; mod seek_to_start_instead_of_rewind; mod single_char_add_str; mod single_char_insert_string; -mod single_char_pattern; mod single_char_push_string; mod skip_while_next; mod stable_sort_primitive; @@ -1140,38 +1140,6 @@ declare_clippy_lint! { "not returning type containing `Self` in a `new` method" } -declare_clippy_lint! { - /// ### What it does - /// Checks for string methods that receive a single-character - /// `str` as an argument, e.g., `_.split("x")`. - /// - /// ### Why is this bad? - /// While this can make a perf difference on some systems, - /// benchmarks have proven inconclusive. But at least using a - /// char literal makes it clear that we are looking at a single - /// character. - /// - /// ### Known problems - /// Does not catch multi-byte unicode characters. This is by - /// design, on many machines, splitting by a non-ascii char is - /// actually slower. Please do your own measurements instead of - /// relying solely on the results of this lint. - /// - /// ### Example - /// ```rust,ignore - /// _.split("x"); - /// ``` - /// - /// Use instead: - /// ```rust,ignore - /// _.split('x'); - /// ``` - #[clippy::version = "pre 1.29.0"] - pub SINGLE_CHAR_PATTERN, - pedantic, - "using a single-character str where a char could be used, e.g., `_.split(\"x\")`" -} - declare_clippy_lint! { /// ### What it does /// Checks for calling `.step_by(0)` on iterators which panics. @@ -4084,12 +4052,33 @@ declare_clippy_lint! { /// ```no_run /// println!("the string is empty"); /// ``` - #[clippy::version = "1.78.0"] + #[clippy::version = "1.79.0"] pub CONST_IS_EMPTY, suspicious, "is_empty() called on strings known at compile time" } +declare_clippy_lint! { + /// ### What it does + /// Checks if an iterator is used to check if a string is ascii. + /// + /// ### Why is this bad? + /// The `str` type already implements the `is_ascii` method. + /// + /// ### Example + /// ```no_run + /// "foo".chars().all(|c| c.is_ascii()); + /// ``` + /// Use instead: + /// ```no_run + /// "foo".is_ascii(); + /// ``` + #[clippy::version = "1.80.0"] + pub NEEDLESS_CHARACTER_ITERATION, + suspicious, + "is_ascii() called on a char iterator" +} + pub struct Methods { avoid_breaking_exported_api: bool, msrv: Msrv, @@ -4147,7 +4136,6 @@ impl_lint_pass!(Methods => [ FLAT_MAP_OPTION, INEFFICIENT_TO_STRING, NEW_RET_NO_SELF, - SINGLE_CHAR_PATTERN, SINGLE_CHAR_ADD_STR, SEARCH_IS_SOME, FILTER_NEXT, @@ -4255,6 +4243,7 @@ impl_lint_pass!(Methods => [ UNNECESSARY_RESULT_MAP_OR_ELSE, MANUAL_C_STR_LITERALS, UNNECESSARY_GET_THEN_CHECK, + NEEDLESS_CHARACTER_ITERATION, ]); /// Extracts a method call name, args, and `Span` of the method name. @@ -4301,7 +4290,6 @@ impl<'tcx> LateLintPass<'tcx> for Methods { inefficient_to_string::check(cx, expr, method_call.ident.name, receiver, args); single_char_add_str::check(cx, expr, receiver, args); into_iter_on_ref::check(cx, expr, method_span, method_call.ident.name, receiver); - single_char_pattern::check(cx, expr, method_call.ident.name, receiver, args); unnecessary_to_owned::check(cx, expr, method_call.ident.name, receiver, args, &self.msrv); }, ExprKind::Binary(op, lhs, rhs) if op.node == hir::BinOpKind::Eq || op.node == hir::BinOpKind::Ne => { @@ -4462,6 +4450,7 @@ impl Methods { }, ("all", [arg]) => { unused_enumerate_index::check(cx, expr, recv, arg); + needless_character_iteration::check(cx, expr, recv, arg, true); if let Some(("cloned", recv2, [], _, _)) = method_call(recv) { iter_overeager_cloned::check( cx, @@ -4482,6 +4471,7 @@ impl Methods { }, ("any", [arg]) => { unused_enumerate_index::check(cx, expr, recv, arg); + needless_character_iteration::check(cx, expr, recv, arg, false); match method_call(recv) { Some(("cloned", recv2, [], _, _)) => iter_overeager_cloned::check( cx, diff --git a/clippy_lints/src/methods/needless_character_iteration.rs b/clippy_lints/src/methods/needless_character_iteration.rs new file mode 100644 index 0000000000000..e3d7820771547 --- /dev/null +++ b/clippy_lints/src/methods/needless_character_iteration.rs @@ -0,0 +1,124 @@ +use rustc_errors::Applicability; +use rustc_hir::{Closure, Expr, ExprKind, HirId, StmtKind, UnOp}; +use rustc_lint::LateContext; +use rustc_middle::ty; +use rustc_span::Span; + +use super::utils::get_last_chain_binding_hir_id; +use super::NEEDLESS_CHARACTER_ITERATION; +use clippy_utils::diagnostics::span_lint_and_sugg; +use clippy_utils::source::snippet_opt; +use clippy_utils::{match_def_path, path_to_local_id, peel_blocks}; + +fn peels_expr_ref<'a, 'tcx>(mut expr: &'a Expr<'tcx>) -> &'a Expr<'tcx> { + while let ExprKind::AddrOf(_, _, e) = expr.kind { + expr = e; + } + expr +} + +fn handle_expr( + cx: &LateContext<'_>, + expr: &Expr<'_>, + first_param: HirId, + span: Span, + before_chars: Span, + revert: bool, + is_all: bool, +) { + match expr.kind { + ExprKind::MethodCall(method, receiver, [], _) => { + // If we have `!is_ascii`, then only `.any()` should warn. And if the condition is + // `is_ascii`, then only `.all()` should warn. + if revert != is_all + && method.ident.name.as_str() == "is_ascii" + && path_to_local_id(receiver, first_param) + && let char_arg_ty = cx.typeck_results().expr_ty_adjusted(receiver).peel_refs() + && *char_arg_ty.kind() == ty::Char + && let Some(snippet) = snippet_opt(cx, before_chars) + { + span_lint_and_sugg( + cx, + NEEDLESS_CHARACTER_ITERATION, + span, + "checking if a string is ascii using iterators", + "try", + format!("{}{snippet}.is_ascii()", if revert { "!" } else { "" }), + Applicability::MachineApplicable, + ); + } + }, + ExprKind::Block(block, _) => { + if block.stmts.iter().any(|stmt| !matches!(stmt.kind, StmtKind::Let(_))) { + // If there is something else than let bindings, then better not emit the lint. + return; + } + if let Some(block_expr) = block.expr + // First we ensure that this is a "binding chain" (each statement is a binding + // of the previous one) and that it is a binding of the closure argument. + && let Some(last_chain_binding_id) = + get_last_chain_binding_hir_id(first_param, block.stmts) + { + handle_expr( + cx, + block_expr, + last_chain_binding_id, + span, + before_chars, + revert, + is_all, + ); + } + }, + ExprKind::Unary(UnOp::Not, expr) => handle_expr(cx, expr, first_param, span, before_chars, !revert, is_all), + ExprKind::Call(fn_path, [arg]) => { + // If we have `!is_ascii`, then only `.any()` should warn. And if the condition is + // `is_ascii`, then only `.all()` should warn. + if revert != is_all + && let ExprKind::Path(path) = fn_path.kind + && let Some(fn_def_id) = cx.qpath_res(&path, fn_path.hir_id).opt_def_id() + && match_def_path(cx, fn_def_id, &["core", "char", "methods", "", "is_ascii"]) + && path_to_local_id(peels_expr_ref(arg), first_param) + && let Some(snippet) = snippet_opt(cx, before_chars) + { + span_lint_and_sugg( + cx, + NEEDLESS_CHARACTER_ITERATION, + span, + "checking if a string is ascii using iterators", + "try", + format!("{}{snippet}.is_ascii()", if revert { "!" } else { "" }), + Applicability::MachineApplicable, + ); + } + }, + _ => {}, + } +} + +pub(super) fn check(cx: &LateContext<'_>, call_expr: &Expr<'_>, recv: &Expr<'_>, closure_arg: &Expr<'_>, is_all: bool) { + if let ExprKind::Closure(&Closure { body, .. }) = closure_arg.kind + && let body = cx.tcx.hir().body(body) + && let Some(first_param) = body.params.first() + && let ExprKind::MethodCall(method, mut recv, [], _) = recv.kind + && method.ident.name.as_str() == "chars" + && let str_ty = cx.typeck_results().expr_ty_adjusted(recv).peel_refs() + && *str_ty.kind() == ty::Str + { + let expr_start = recv.span; + while let ExprKind::MethodCall(_, new_recv, _, _) = recv.kind { + recv = new_recv; + } + let body_expr = peel_blocks(body.value); + + handle_expr( + cx, + body_expr, + first_param.pat.hir_id, + recv.span.with_hi(call_expr.span.hi()), + recv.span.with_hi(expr_start.hi()), + false, + is_all, + ); + } +} diff --git a/clippy_lints/src/methods/option_map_unwrap_or.rs b/clippy_lints/src/methods/option_map_unwrap_or.rs index ca331f3e7568a..3d326bc99f95c 100644 --- a/clippy_lints/src/methods/option_map_unwrap_or.rs +++ b/clippy_lints/src/methods/option_map_unwrap_or.rs @@ -60,7 +60,7 @@ pub(super) fn check<'tcx>( let map = cx.tcx.hir(); let body = map.body_owned_by(map.enclosing_body_owner(expr.hir_id)); - reference_visitor.visit_body(&body); + reference_visitor.visit_body(body); if reference_visitor.found_reference { return; diff --git a/clippy_lints/src/methods/path_buf_push_overwrite.rs b/clippy_lints/src/methods/path_buf_push_overwrite.rs index 04a27cc98f3c3..2d3007e50b81c 100644 --- a/clippy_lints/src/methods/path_buf_push_overwrite.rs +++ b/clippy_lints/src/methods/path_buf_push_overwrite.rs @@ -27,7 +27,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, arg: &'t lit.span, "calling `push` with '/' or '\\' (file system root) will overwrite the previous path definition", "try", - format!("\"{}\"", pushed_path_lit.trim_start_matches(|c| c == '/' || c == '\\')), + format!("\"{}\"", pushed_path_lit.trim_start_matches(['/', '\\'])), Applicability::MachineApplicable, ); } diff --git a/clippy_lints/src/methods/search_is_some.rs b/clippy_lints/src/methods/search_is_some.rs index f5f1e94bbf455..3b2dd285b8c99 100644 --- a/clippy_lints/src/methods/search_is_some.rs +++ b/clippy_lints/src/methods/search_is_some.rs @@ -2,7 +2,7 @@ use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_sugg}; use clippy_utils::source::{snippet, snippet_with_applicability}; use clippy_utils::sugg::deref_closure_args; use clippy_utils::ty::is_type_lang_item; -use clippy_utils::{get_parent_expr, is_trait_method, strip_pat_refs}; +use clippy_utils::{is_receiver_of_method_call, is_trait_method, strip_pat_refs}; use hir::ExprKind; use rustc_errors::Applicability; use rustc_hir as hir; @@ -156,13 +156,3 @@ pub(super) fn check<'tcx>( } } } - -fn is_receiver_of_method_call(cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> bool { - if let Some(parent_expr) = get_parent_expr(cx, expr) - && let ExprKind::MethodCall(_, receiver, ..) = parent_expr.kind - && receiver.hir_id == expr.hir_id - { - return true; - } - false -} diff --git a/clippy_lints/src/methods/single_char_insert_string.rs b/clippy_lints/src/methods/single_char_insert_string.rs index 20ec2b74d81e4..e2f76ac114c6a 100644 --- a/clippy_lints/src/methods/single_char_insert_string.rs +++ b/clippy_lints/src/methods/single_char_insert_string.rs @@ -1,8 +1,8 @@ -use super::utils::get_hint_if_single_char_arg; use clippy_utils::diagnostics::span_lint_and_sugg; -use clippy_utils::source::snippet_with_applicability; +use clippy_utils::source::{snippet_with_applicability, str_literal_to_char_literal}; +use rustc_ast::BorrowKind; use rustc_errors::Applicability; -use rustc_hir as hir; +use rustc_hir::{self as hir, ExprKind}; use rustc_lint::LateContext; use super::SINGLE_CHAR_ADD_STR; @@ -10,7 +10,7 @@ use super::SINGLE_CHAR_ADD_STR; /// lint for length-1 `str`s as argument for `insert_str` pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, receiver: &hir::Expr<'_>, args: &[hir::Expr<'_>]) { let mut applicability = Applicability::MachineApplicable; - if let Some(extension_string) = get_hint_if_single_char_arg(cx, &args[1], &mut applicability, false) { + if let Some(extension_string) = str_literal_to_char_literal(cx, &args[1], &mut applicability, false) { let base_string_snippet = snippet_with_applicability(cx, receiver.span.source_callsite(), "_", &mut applicability); let pos_arg = snippet_with_applicability(cx, args[0].span, "..", &mut applicability); @@ -25,4 +25,43 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, receiver: &hir:: applicability, ); } + + if let ExprKind::AddrOf(BorrowKind::Ref, _, arg) = &args[1].kind + && let ExprKind::MethodCall(path_segment, method_arg, _, _) = &arg.kind + && path_segment.ident.name == rustc_span::sym::to_string + && (is_ref_char(cx, method_arg) || is_char(cx, method_arg)) + { + let base_string_snippet = + snippet_with_applicability(cx, receiver.span.source_callsite(), "..", &mut applicability); + let extension_string = + snippet_with_applicability(cx, method_arg.span.source_callsite(), "..", &mut applicability); + let pos_arg = snippet_with_applicability(cx, args[0].span, "..", &mut applicability); + let deref_string = if is_ref_char(cx, method_arg) { "*" } else { "" }; + + let sugg = format!("{base_string_snippet}.insert({pos_arg}, {deref_string}{extension_string})"); + span_lint_and_sugg( + cx, + SINGLE_CHAR_ADD_STR, + expr.span, + "calling `insert_str()` using a single-character converted to string", + "consider using `insert` without `to_string()`", + sugg, + applicability, + ); + } +} + +fn is_ref_char(cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> bool { + if cx.typeck_results().expr_ty(expr).is_ref() + && let rustc_middle::ty::Ref(_, ty, _) = cx.typeck_results().expr_ty(expr).kind() + && ty.is_char() + { + return true; + } + + false +} + +fn is_char(cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> bool { + cx.typeck_results().expr_ty(expr).is_char() } diff --git a/clippy_lints/src/methods/single_char_pattern.rs b/clippy_lints/src/methods/single_char_pattern.rs deleted file mode 100644 index 982a7901c4537..0000000000000 --- a/clippy_lints/src/methods/single_char_pattern.rs +++ /dev/null @@ -1,64 +0,0 @@ -use super::utils::get_hint_if_single_char_arg; -use clippy_utils::diagnostics::span_lint_and_sugg; -use rustc_errors::Applicability; -use rustc_hir as hir; -use rustc_lint::LateContext; -use rustc_middle::ty; -use rustc_span::symbol::Symbol; - -use super::SINGLE_CHAR_PATTERN; - -const PATTERN_METHODS: [(&str, usize); 22] = [ - ("contains", 0), - ("starts_with", 0), - ("ends_with", 0), - ("find", 0), - ("rfind", 0), - ("split", 0), - ("split_inclusive", 0), - ("rsplit", 0), - ("split_terminator", 0), - ("rsplit_terminator", 0), - ("splitn", 1), - ("rsplitn", 1), - ("split_once", 0), - ("rsplit_once", 0), - ("matches", 0), - ("rmatches", 0), - ("match_indices", 0), - ("rmatch_indices", 0), - ("trim_start_matches", 0), - ("trim_end_matches", 0), - ("replace", 0), - ("replacen", 0), -]; - -/// lint for length-1 `str`s for methods in `PATTERN_METHODS` -pub(super) fn check( - cx: &LateContext<'_>, - _expr: &hir::Expr<'_>, - method_name: Symbol, - receiver: &hir::Expr<'_>, - args: &[hir::Expr<'_>], -) { - for &(method, pos) in &PATTERN_METHODS { - if let ty::Ref(_, ty, _) = cx.typeck_results().expr_ty_adjusted(receiver).kind() - && ty.is_str() - && method_name.as_str() == method - && args.len() > pos - && let arg = &args[pos] - && let mut applicability = Applicability::MachineApplicable - && let Some(hint) = get_hint_if_single_char_arg(cx, arg, &mut applicability, true) - { - span_lint_and_sugg( - cx, - SINGLE_CHAR_PATTERN, - arg.span, - "single-character string constant used as pattern", - "consider using a `char`", - hint, - applicability, - ); - } - } -} diff --git a/clippy_lints/src/methods/single_char_push_string.rs b/clippy_lints/src/methods/single_char_push_string.rs index 97c13825bc104..4ae8634305da6 100644 --- a/clippy_lints/src/methods/single_char_push_string.rs +++ b/clippy_lints/src/methods/single_char_push_string.rs @@ -1,8 +1,8 @@ -use super::utils::get_hint_if_single_char_arg; use clippy_utils::diagnostics::span_lint_and_sugg; -use clippy_utils::source::snippet_with_applicability; +use clippy_utils::source::{snippet_with_applicability, str_literal_to_char_literal}; +use rustc_ast::BorrowKind; use rustc_errors::Applicability; -use rustc_hir as hir; +use rustc_hir::{self as hir, ExprKind}; use rustc_lint::LateContext; use super::SINGLE_CHAR_ADD_STR; @@ -10,7 +10,7 @@ use super::SINGLE_CHAR_ADD_STR; /// lint for length-1 `str`s as argument for `push_str` pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, receiver: &hir::Expr<'_>, args: &[hir::Expr<'_>]) { let mut applicability = Applicability::MachineApplicable; - if let Some(extension_string) = get_hint_if_single_char_arg(cx, &args[0], &mut applicability, false) { + if let Some(extension_string) = str_literal_to_char_literal(cx, &args[0], &mut applicability, false) { let base_string_snippet = snippet_with_applicability(cx, receiver.span.source_callsite(), "..", &mut applicability); let sugg = format!("{base_string_snippet}.push({extension_string})"); @@ -24,4 +24,42 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, receiver: &hir:: applicability, ); } + + if let ExprKind::AddrOf(BorrowKind::Ref, _, arg) = &args[0].kind + && let ExprKind::MethodCall(path_segment, method_arg, _, _) = &arg.kind + && path_segment.ident.name == rustc_span::sym::to_string + && (is_ref_char(cx, method_arg) || is_char(cx, method_arg)) + { + let base_string_snippet = + snippet_with_applicability(cx, receiver.span.source_callsite(), "..", &mut applicability); + let extension_string = + snippet_with_applicability(cx, method_arg.span.source_callsite(), "..", &mut applicability); + let deref_string = if is_ref_char(cx, method_arg) { "*" } else { "" }; + + let sugg = format!("{base_string_snippet}.push({deref_string}{extension_string})"); + span_lint_and_sugg( + cx, + SINGLE_CHAR_ADD_STR, + expr.span, + "calling `push_str()` using a single-character converted to string", + "consider using `push` without `to_string()`", + sugg, + applicability, + ); + } +} + +fn is_ref_char(cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> bool { + if cx.typeck_results().expr_ty(expr).is_ref() + && let rustc_middle::ty::Ref(_, ty, _) = cx.typeck_results().expr_ty(expr).kind() + && ty.is_char() + { + return true; + } + + false +} + +fn is_char(cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> bool { + cx.typeck_results().expr_ty(expr).is_char() } diff --git a/clippy_lints/src/methods/str_splitn.rs b/clippy_lints/src/methods/str_splitn.rs index e8c12bbeea0e4..4f42fb73547a7 100644 --- a/clippy_lints/src/methods/str_splitn.rs +++ b/clippy_lints/src/methods/str_splitn.rs @@ -3,7 +3,7 @@ use clippy_utils::consts::{constant, Constant}; use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then}; use clippy_utils::source::snippet_with_context; use clippy_utils::usage::local_used_after_expr; -use clippy_utils::visitors::{for_each_expr_with_closures, Descend}; +use clippy_utils::visitors::{for_each_expr, Descend}; use clippy_utils::{is_diag_item_method, match_def_path, path_to_local_id, paths}; use core::ops::ControlFlow; use rustc_errors::Applicability; @@ -209,7 +209,7 @@ fn indirect_usage<'tcx>( }) = stmt.kind { let mut path_to_binding = None; - let _: Option = for_each_expr_with_closures(cx, init_expr, |e| { + let _: Option = for_each_expr(cx, init_expr, |e| { if path_to_local_id(e, binding) { path_to_binding = Some(e); } diff --git a/clippy_lints/src/methods/unnecessary_filter_map.rs b/clippy_lints/src/methods/unnecessary_filter_map.rs index daf99d9861424..c9b9d98dbe607 100644 --- a/clippy_lints/src/methods/unnecessary_filter_map.rs +++ b/clippy_lints/src/methods/unnecessary_filter_map.rs @@ -2,7 +2,7 @@ use super::utils::clone_or_copy_needed; use clippy_utils::diagnostics::span_lint; use clippy_utils::ty::is_copy; use clippy_utils::usage::mutated_variables; -use clippy_utils::visitors::{for_each_expr, Descend}; +use clippy_utils::visitors::{for_each_expr_without_closures, Descend}; use clippy_utils::{is_res_lang_ctor, is_trait_method, path_res, path_to_local_id}; use core::ops::ControlFlow; use rustc_hir as hir; @@ -26,7 +26,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'tcx>, a let (mut found_mapping, mut found_filtering) = check_expression(cx, arg_id, body.value); - let _: Option = for_each_expr(body.value, |e| { + let _: Option = for_each_expr_without_closures(body.value, |e| { if let hir::ExprKind::Ret(Some(e)) = &e.kind { let (found_mapping_res, found_filtering_res) = check_expression(cx, arg_id, e); found_mapping |= found_mapping_res; diff --git a/clippy_lints/src/methods/unnecessary_iter_cloned.rs b/clippy_lints/src/methods/unnecessary_iter_cloned.rs index d1300dd43c283..70885e46e955e 100644 --- a/clippy_lints/src/methods/unnecessary_iter_cloned.rs +++ b/clippy_lints/src/methods/unnecessary_iter_cloned.rs @@ -3,7 +3,7 @@ use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::higher::ForLoop; use clippy_utils::source::snippet_opt; use clippy_utils::ty::{get_iterator_item_ty, implements_trait}; -use clippy_utils::visitors::for_each_expr; +use clippy_utils::visitors::for_each_expr_without_closures; use clippy_utils::{can_mut_borrow_both, fn_def_id, get_parent_expr, path_to_local}; use core::ops::ControlFlow; use rustc_errors::Applicability; @@ -61,7 +61,7 @@ pub fn check_for_loop_iter( fn is_caller_or_fields_change(cx: &LateContext<'_>, body: &Expr<'_>, caller: &Expr<'_>) -> bool { let mut change = false; if let ExprKind::Block(block, ..) = body.kind { - for_each_expr(block, |e| { + for_each_expr_without_closures(block, |e| { match e.kind { ExprKind::Assign(assignee, _, _) | ExprKind::AssignOp(_, assignee, _) => { change |= !can_mut_borrow_both(cx, caller, assignee); diff --git a/clippy_lints/src/methods/unnecessary_result_map_or_else.rs b/clippy_lints/src/methods/unnecessary_result_map_or_else.rs index cdfaa690d5f4b..c14a87c153414 100644 --- a/clippy_lints/src/methods/unnecessary_result_map_or_else.rs +++ b/clippy_lints/src/methods/unnecessary_result_map_or_else.rs @@ -4,10 +4,11 @@ use clippy_utils::source::snippet; use clippy_utils::ty::is_type_diagnostic_item; use rustc_errors::Applicability; use rustc_hir as hir; -use rustc_hir::{Closure, Expr, ExprKind, HirId, QPath, Stmt, StmtKind}; +use rustc_hir::{Closure, Expr, ExprKind, HirId, QPath}; use rustc_lint::LateContext; use rustc_span::symbol::sym; +use super::utils::get_last_chain_binding_hir_id; use super::UNNECESSARY_RESULT_MAP_OR_ELSE; fn emit_lint(cx: &LateContext<'_>, expr: &Expr<'_>, recv: &Expr<'_>, def_arg: &Expr<'_>) { @@ -25,22 +26,6 @@ fn emit_lint(cx: &LateContext<'_>, expr: &Expr<'_>, recv: &Expr<'_>, def_arg: &E ); } -fn get_last_chain_binding_hir_id(mut hir_id: HirId, statements: &[Stmt<'_>]) -> Option { - for stmt in statements { - if let StmtKind::Let(local) = stmt.kind - && let Some(init) = local.init - && let ExprKind::Path(QPath::Resolved(_, path)) = init.kind - && let hir::def::Res::Local(local_hir_id) = path.res - && local_hir_id == hir_id - { - hir_id = local.pat.hir_id; - } else { - return None; - } - } - Some(hir_id) -} - fn handle_qpath( cx: &LateContext<'_>, expr: &Expr<'_>, diff --git a/clippy_lints/src/methods/utils.rs b/clippy_lints/src/methods/utils.rs index 1a55b7160fb18..0d2b0a3131763 100644 --- a/clippy_lints/src/methods/utils.rs +++ b/clippy_lints/src/methods/utils.rs @@ -1,10 +1,7 @@ -use clippy_utils::source::snippet_with_applicability; use clippy_utils::ty::is_type_diagnostic_item; use clippy_utils::{get_parent_expr, path_to_local_id, usage}; -use rustc_ast::ast; -use rustc_errors::Applicability; use rustc_hir::intravisit::{walk_expr, Visitor}; -use rustc_hir::{BorrowKind, Expr, ExprKind, HirId, Mutability, Pat}; +use rustc_hir::{BorrowKind, Expr, ExprKind, HirId, Mutability, Pat, QPath, Stmt, StmtKind}; use rustc_lint::LateContext; use rustc_middle::hir::nested_filter; use rustc_middle::ty::{self, Ty}; @@ -49,48 +46,6 @@ pub(super) fn derefs_to_slice<'tcx>( } } -pub(super) fn get_hint_if_single_char_arg( - cx: &LateContext<'_>, - arg: &Expr<'_>, - applicability: &mut Applicability, - ascii_only: bool, -) -> Option { - if let ExprKind::Lit(lit) = &arg.kind - && let ast::LitKind::Str(r, style) = lit.node - && let string = r.as_str() - && let len = if ascii_only { - string.len() - } else { - string.chars().count() - } - && len == 1 - { - let snip = snippet_with_applicability(cx, arg.span, string, applicability); - let ch = if let ast::StrStyle::Raw(nhash) = style { - let nhash = nhash as usize; - // for raw string: r##"a"## - &snip[(nhash + 2)..(snip.len() - 1 - nhash)] - } else { - // for regular string: "a" - &snip[1..(snip.len() - 1)] - }; - - let hint = format!( - "'{}'", - match ch { - "'" => "\\'", - r"\" => "\\\\", - "\\\"" => "\"", // no need to escape `"` in `'"'` - _ => ch, - } - ); - - Some(hint) - } else { - None - } -} - /// The core logic of `check_for_loop_iter` in `unnecessary_iter_cloned.rs`, this function wraps a /// use of `CloneOrCopyVisitor`. pub(super) fn clone_or_copy_needed<'tcx>( @@ -175,3 +130,19 @@ impl<'cx, 'tcx> CloneOrCopyVisitor<'cx, 'tcx> { .any(|hir_id| path_to_local_id(expr, *hir_id)) } } + +pub(super) fn get_last_chain_binding_hir_id(mut hir_id: HirId, statements: &[Stmt<'_>]) -> Option { + for stmt in statements { + if let StmtKind::Let(local) = stmt.kind + && let Some(init) = local.init + && let ExprKind::Path(QPath::Resolved(_, path)) = init.kind + && let rustc_hir::def::Res::Local(local_hir_id) = path.res + && local_hir_id == hir_id + { + hir_id = local.pat.hir_id; + } else { + return None; + } + } + Some(hir_id) +} diff --git a/clippy_lints/src/misc_early/zero_prefixed_literal.rs b/clippy_lints/src/misc_early/zero_prefixed_literal.rs index 4f9578d1b2576..61f4684c9e379 100644 --- a/clippy_lints/src/misc_early/zero_prefixed_literal.rs +++ b/clippy_lints/src/misc_early/zero_prefixed_literal.rs @@ -6,7 +6,7 @@ use rustc_span::Span; use super::ZERO_PREFIXED_LITERAL; pub(super) fn check(cx: &EarlyContext<'_>, lit_span: Span, lit_snip: &str) { - let trimmed_lit_snip = lit_snip.trim_start_matches(|c| c == '_' || c == '0'); + let trimmed_lit_snip = lit_snip.trim_start_matches(['_', '0']); span_lint_and_then( cx, ZERO_PREFIXED_LITERAL, @@ -20,7 +20,7 @@ pub(super) fn check(cx: &EarlyContext<'_>, lit_span: Span, lit_snip: &str) { Applicability::MaybeIncorrect, ); // do not advise to use octal form if the literal cannot be expressed in base 8. - if !lit_snip.contains(|c| c == '8' || c == '9') { + if !lit_snip.contains(['8', '9']) { diag.span_suggestion( lit_span, "if you mean to use an octal constant, use `0o`", diff --git a/clippy_lints/src/missing_asserts_for_indexing.rs b/clippy_lints/src/missing_asserts_for_indexing.rs index 752723a0c68ee..94c91b095171f 100644 --- a/clippy_lints/src/missing_asserts_for_indexing.rs +++ b/clippy_lints/src/missing_asserts_for_indexing.rs @@ -4,7 +4,7 @@ use std::ops::ControlFlow; use clippy_utils::comparisons::{normalize_comparison, Rel}; use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::source::snippet; -use clippy_utils::visitors::for_each_expr; +use clippy_utils::visitors::for_each_expr_without_closures; use clippy_utils::{eq_expr_value, hash_expr, higher}; use rustc_ast::{LitKind, RangeLimits}; use rustc_data_structures::packed::Pu128; @@ -405,7 +405,7 @@ impl LateLintPass<'_> for MissingAssertsForIndexing { fn check_body(&mut self, cx: &LateContext<'_>, body: &Body<'_>) { let mut map = UnhashMap::default(); - for_each_expr(body.value, |expr| { + for_each_expr_without_closures(body.value, |expr| { check_index(cx, expr, &mut map); check_assert(cx, expr, &mut map); ControlFlow::::Continue(()) diff --git a/clippy_lints/src/missing_const_for_fn.rs b/clippy_lints/src/missing_const_for_fn.rs index 9ba19e0a86581..4592324809fa2 100644 --- a/clippy_lints/src/missing_const_for_fn.rs +++ b/clippy_lints/src/missing_const_for_fn.rs @@ -1,7 +1,6 @@ use clippy_config::msrvs::{self, Msrv}; use clippy_utils::diagnostics::span_lint; use clippy_utils::qualify_min_const_fn::is_min_const_fn; -use clippy_utils::ty::has_drop; use clippy_utils::{fn_has_unsatisfiable_preds, is_entrypoint_fn, is_from_proc_macro, trait_ref_of_method}; use rustc_hir as hir; use rustc_hir::def_id::CRATE_DEF_ID; @@ -121,10 +120,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingConstForFn { } }, FnKind::Method(_, sig, ..) => { - if trait_ref_of_method(cx, def_id).is_some() - || already_const(sig.header) - || method_accepts_droppable(cx, def_id) - { + if trait_ref_of_method(cx, def_id).is_some() || already_const(sig.header) { return; } }, @@ -151,26 +147,13 @@ impl<'tcx> LateLintPass<'tcx> for MissingConstForFn { let mir = cx.tcx.optimized_mir(def_id); - if let Err((span, err)) = is_min_const_fn(cx.tcx, mir, &self.msrv) { - if cx.tcx.is_const_fn_raw(def_id.to_def_id()) { - cx.tcx.dcx().span_err(span, err); - } - } else { + if let Ok(()) = is_min_const_fn(cx.tcx, mir, &self.msrv) { span_lint(cx, MISSING_CONST_FOR_FN, span, "this could be a `const fn`"); } } extract_msrv_attr!(LateContext); } -/// Returns true if any of the method parameters is a type that implements `Drop`. The method -/// can't be made const then, because `drop` can't be const-evaluated. -fn method_accepts_droppable(cx: &LateContext<'_>, def_id: LocalDefId) -> bool { - let sig = cx.tcx.fn_sig(def_id).instantiate_identity().skip_binder(); - - // If any of the params are droppable, return true - sig.inputs().iter().any(|&ty| has_drop(cx, ty)) -} - // We don't have to lint on something that's already `const` #[must_use] fn already_const(header: hir::FnHeader) -> bool { diff --git a/clippy_lints/src/missing_fields_in_debug.rs b/clippy_lints/src/missing_fields_in_debug.rs index a64faa124f086..77595b121aadb 100644 --- a/clippy_lints/src/missing_fields_in_debug.rs +++ b/clippy_lints/src/missing_fields_in_debug.rs @@ -110,7 +110,7 @@ fn should_lint<'tcx>( // Is there a call to `DebugStruct::debug_struct`? Do lint if there is. let mut has_debug_struct = false; - for_each_expr(block, |expr| { + for_each_expr(cx, block, |expr| { if let ExprKind::MethodCall(path, recv, ..) = &expr.kind { let recv_ty = typeck_results.expr_ty(recv).peel_refs(); @@ -165,7 +165,7 @@ fn check_struct<'tcx>( let mut has_direct_field_access = false; let mut field_accesses = FxHashSet::default(); - for_each_expr(block, |expr| { + for_each_expr(cx, block, |expr| { if let ExprKind::Field(target, ident) = expr.kind && let target_ty = typeck_results.expr_ty_adjusted(target).peel_refs() && target_ty == self_ty diff --git a/clippy_lints/src/multiple_unsafe_ops_per_block.rs b/clippy_lints/src/multiple_unsafe_ops_per_block.rs index 5b4ef852f0d9b..da74a7c7145a6 100644 --- a/clippy_lints/src/multiple_unsafe_ops_per_block.rs +++ b/clippy_lints/src/multiple_unsafe_ops_per_block.rs @@ -1,5 +1,5 @@ use clippy_utils::diagnostics::span_lint_and_then; -use clippy_utils::visitors::{for_each_expr_with_closures, Descend, Visitable}; +use clippy_utils::visitors::{for_each_expr, Descend, Visitable}; use core::ops::ControlFlow::Continue; use hir::def::{DefKind, Res}; use hir::{BlockCheckMode, ExprKind, QPath, Safety, UnOp}; @@ -96,7 +96,7 @@ fn collect_unsafe_exprs<'tcx>( node: impl Visitable<'tcx>, unsafe_ops: &mut Vec<(&'static str, Span)>, ) { - for_each_expr_with_closures(cx, node, |expr| { + for_each_expr(cx, node, |expr| { match expr.kind { ExprKind::InlineAsm(_) => unsafe_ops.push(("inline assembly used here", expr.span)), diff --git a/clippy_lints/src/needless_bool.rs b/clippy_lints/src/needless_bool.rs index e1866eaa18a7c..9cb4fa41c73f1 100644 --- a/clippy_lints/src/needless_bool.rs +++ b/clippy_lints/src/needless_bool.rs @@ -6,8 +6,8 @@ use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg}; use clippy_utils::source::snippet_with_applicability; use clippy_utils::sugg::Sugg; use clippy_utils::{ - higher, is_block_like, is_else_clause, is_expn_of, is_parent_stmt, peel_blocks, peel_blocks_with_stmt, - span_extract_comment, SpanlessEq, + get_parent_expr, higher, is_block_like, is_else_clause, is_expn_of, is_parent_stmt, is_receiver_of_method_call, + peel_blocks, peel_blocks_with_stmt, span_extract_comment, SpanlessEq, }; use rustc_ast::ast::LitKind; use rustc_errors::Applicability; @@ -154,7 +154,10 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessBool { snip = snip.blockify(); } - if condition_needs_parentheses(cond) && is_parent_stmt(cx, e.hir_id) { + if (condition_needs_parentheses(cond) && is_parent_stmt(cx, e.hir_id)) + || is_receiver_of_method_call(cx, e) + || is_as_argument(cx, e) + { snip = snip.maybe_par(); } @@ -442,3 +445,7 @@ fn fetch_assign<'tcx>(expr: &'tcx Expr<'tcx>) -> Option<(&'tcx Expr<'tcx>, bool) None } } + +fn is_as_argument(cx: &LateContext<'_>, e: &Expr<'_>) -> bool { + matches!(get_parent_expr(cx, e).map(|e| e.kind), Some(ExprKind::Cast(_, _))) +} diff --git a/clippy_lints/src/needless_late_init.rs b/clippy_lints/src/needless_late_init.rs index 5a0ae1a4d6d29..4bfc30fa5cf80 100644 --- a/clippy_lints/src/needless_late_init.rs +++ b/clippy_lints/src/needless_late_init.rs @@ -2,7 +2,7 @@ use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::path_to_local; use clippy_utils::source::snippet_opt; use clippy_utils::ty::needs_ordered_drop; -use clippy_utils::visitors::{for_each_expr, for_each_expr_with_closures, is_local_used}; +use clippy_utils::visitors::{for_each_expr, for_each_expr_without_closures, is_local_used}; use core::ops::ControlFlow; use rustc_errors::{Applicability, MultiSpan}; use rustc_hir::{ @@ -63,7 +63,7 @@ declare_clippy_lint! { declare_lint_pass!(NeedlessLateInit => [NEEDLESS_LATE_INIT]); fn contains_assign_expr<'tcx>(cx: &LateContext<'tcx>, stmt: &'tcx Stmt<'tcx>) -> bool { - for_each_expr_with_closures(cx, stmt, |e| { + for_each_expr(cx, stmt, |e| { if matches!(e.kind, ExprKind::Assign(..)) { ControlFlow::Break(()) } else { @@ -74,7 +74,7 @@ fn contains_assign_expr<'tcx>(cx: &LateContext<'tcx>, stmt: &'tcx Stmt<'tcx>) -> } fn contains_let(cond: &Expr<'_>) -> bool { - for_each_expr(cond, |e| { + for_each_expr_without_closures(cond, |e| { if matches!(e.kind, ExprKind::Let(_)) { ControlFlow::Break(()) } else { diff --git a/clippy_lints/src/needless_maybe_sized.rs b/clippy_lints/src/needless_maybe_sized.rs new file mode 100644 index 0000000000000..06ae1723a03d4 --- /dev/null +++ b/clippy_lints/src/needless_maybe_sized.rs @@ -0,0 +1,164 @@ +use clippy_utils::diagnostics::span_lint_and_then; +use rustc_errors::Applicability; +use rustc_hir::def_id::{DefId, DefIdMap}; +use rustc_hir::{GenericBound, Generics, PolyTraitRef, TraitBoundModifier, WherePredicate}; +use rustc_lint::{LateContext, LateLintPass}; +use rustc_middle::ty::{ClauseKind, PredicatePolarity}; +use rustc_session::declare_lint_pass; +use rustc_span::symbol::Ident; + +declare_clippy_lint! { + /// ### What it does + /// Lints `?Sized` bounds applied to type parameters that cannot be unsized + /// + /// ### Why is this bad? + /// The `?Sized` bound is misleading because it cannot be satisfied by an + /// unsized type + /// + /// ### Example + /// ```rust + /// // `T` cannot be unsized because `Clone` requires it to be `Sized` + /// fn f(t: &T) {} + /// ``` + /// Use instead: + /// ```rust + /// fn f(t: &T) {} + /// + /// // or choose alternative bounds for `T` so that it can be unsized + /// ``` + #[clippy::version = "1.79.0"] + pub NEEDLESS_MAYBE_SIZED, + suspicious, + "a `?Sized` bound that is unusable due to a `Sized` requirement" +} +declare_lint_pass!(NeedlessMaybeSized => [NEEDLESS_MAYBE_SIZED]); + +#[allow(clippy::struct_field_names)] +struct Bound<'tcx> { + /// The [`DefId`] of the type parameter the bound refers to + param: DefId, + ident: Ident, + + trait_bound: &'tcx PolyTraitRef<'tcx>, + modifier: TraitBoundModifier, + + predicate_pos: usize, + bound_pos: usize, +} + +/// Finds all of the [`Bound`]s that refer to a type parameter and are not from a macro expansion +fn type_param_bounds<'tcx>(generics: &'tcx Generics<'tcx>) -> impl Iterator> { + generics + .predicates + .iter() + .enumerate() + .filter_map(|(predicate_pos, predicate)| { + let WherePredicate::BoundPredicate(bound_predicate) = predicate else { + return None; + }; + + let (param, ident) = bound_predicate.bounded_ty.as_generic_param()?; + + Some( + bound_predicate + .bounds + .iter() + .enumerate() + .filter_map(move |(bound_pos, bound)| match bound { + &GenericBound::Trait(ref trait_bound, modifier) => Some(Bound { + param, + ident, + trait_bound, + modifier, + predicate_pos, + bound_pos, + }), + GenericBound::Outlives(_) => None, + }) + .filter(|bound| !bound.trait_bound.span.from_expansion()), + ) + }) + .flatten() +} + +/// Searches the supertraits of the trait referred to by `trait_bound` recursively, returning the +/// path taken to find a `Sized` bound if one is found +fn path_to_sized_bound(cx: &LateContext<'_>, trait_bound: &PolyTraitRef<'_>) -> Option> { + fn search(cx: &LateContext<'_>, path: &mut Vec) -> bool { + let trait_def_id = *path.last().unwrap(); + + if Some(trait_def_id) == cx.tcx.lang_items().sized_trait() { + return true; + } + + for &(predicate, _) in cx.tcx.super_predicates_of(trait_def_id).predicates { + if let ClauseKind::Trait(trait_predicate) = predicate.kind().skip_binder() + && trait_predicate.polarity == PredicatePolarity::Positive + && !path.contains(&trait_predicate.def_id()) + { + path.push(trait_predicate.def_id()); + if search(cx, path) { + return true; + } + path.pop(); + } + } + + false + } + + let mut path = vec![trait_bound.trait_ref.trait_def_id()?]; + search(cx, &mut path).then_some(path) +} + +impl LateLintPass<'_> for NeedlessMaybeSized { + fn check_generics(&mut self, cx: &LateContext<'_>, generics: &Generics<'_>) { + let Some(sized_trait) = cx.tcx.lang_items().sized_trait() else { + return; + }; + + let maybe_sized_params: DefIdMap<_> = type_param_bounds(generics) + .filter(|bound| { + bound.trait_bound.trait_ref.trait_def_id() == Some(sized_trait) + && bound.modifier == TraitBoundModifier::Maybe + }) + .map(|bound| (bound.param, bound)) + .collect(); + + for bound in type_param_bounds(generics) { + if bound.modifier == TraitBoundModifier::None + && let Some(sized_bound) = maybe_sized_params.get(&bound.param) + && let Some(path) = path_to_sized_bound(cx, bound.trait_bound) + { + span_lint_and_then( + cx, + NEEDLESS_MAYBE_SIZED, + sized_bound.trait_bound.span, + "`?Sized` bound is ignored because of a `Sized` requirement", + |diag| { + let ty_param = sized_bound.ident; + diag.span_note( + bound.trait_bound.span, + format!("`{ty_param}` cannot be unsized because of the bound"), + ); + + for &[current_id, next_id] in path.array_windows() { + let current = cx.tcx.item_name(current_id); + let next = cx.tcx.item_name(next_id); + diag.note(format!("...because `{current}` has the bound `{next}`")); + } + + diag.span_suggestion_verbose( + generics.span_for_bound_removal(sized_bound.predicate_pos, sized_bound.bound_pos), + "change the bounds that require `Sized`, or remove the `?Sized` bound", + "", + Applicability::MaybeIncorrect, + ); + }, + ); + + return; + } + } + } +} diff --git a/clippy_lints/src/needless_pass_by_ref_mut.rs b/clippy_lints/src/needless_pass_by_ref_mut.rs index da6ed5fb96f12..57ba0da533190 100644 --- a/clippy_lints/src/needless_pass_by_ref_mut.rs +++ b/clippy_lints/src/needless_pass_by_ref_mut.rs @@ -1,7 +1,7 @@ use super::needless_pass_by_value::requires_exact_signature; use clippy_utils::diagnostics::span_lint_hir_and_then; use clippy_utils::source::snippet; -use clippy_utils::visitors::for_each_expr_with_closures; +use clippy_utils::visitors::for_each_expr; use clippy_utils::{inherits_cfg, is_from_proc_macro, is_self}; use rustc_data_structures::fx::{FxHashSet, FxIndexMap}; use rustc_errors::Applicability; @@ -205,7 +205,7 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByRefMut<'tcx> { // We retrieve all the closures declared in the function because they will not be found // by `euv::Delegate`. let mut closures: FxHashSet = FxHashSet::default(); - for_each_expr_with_closures(cx, body, |expr| { + for_each_expr(cx, body, |expr| { if let ExprKind::Closure(closure) = expr.kind { closures.insert(closure.def_id); } diff --git a/clippy_lints/src/non_canonical_impls.rs b/clippy_lints/src/non_canonical_impls.rs index 932d6fe54d660..de6a1a36f3e92 100644 --- a/clippy_lints/src/non_canonical_impls.rs +++ b/clippy_lints/src/non_canonical_impls.rs @@ -1,10 +1,11 @@ use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then}; use clippy_utils::ty::implements_trait; -use clippy_utils::{is_res_lang_ctor, last_path_segment, path_res, std_or_core}; +use clippy_utils::{is_from_proc_macro, is_res_lang_ctor, last_path_segment, path_res, std_or_core}; use rustc_errors::Applicability; use rustc_hir::def_id::LocalDefId; use rustc_hir::{Expr, ExprKind, ImplItem, ImplItemKind, LangItem, Node, UnOp}; -use rustc_lint::{LateContext, LateLintPass}; +use rustc_lint::{LateContext, LateLintPass, LintContext}; +use rustc_middle::lint::in_external_macro; use rustc_middle::ty::EarlyBinder; use rustc_session::declare_lint_pass; use rustc_span::sym; @@ -111,7 +112,7 @@ declare_lint_pass!(NonCanonicalImpls => [NON_CANONICAL_CLONE_IMPL, NON_CANONICAL impl LateLintPass<'_> for NonCanonicalImpls { #[expect(clippy::too_many_lines)] - fn check_impl_item(&mut self, cx: &LateContext<'_>, impl_item: &ImplItem<'_>) { + fn check_impl_item<'tcx>(&mut self, cx: &LateContext<'tcx>, impl_item: &ImplItem<'tcx>) { let Node::Item(item) = cx.tcx.parent_hir_node(impl_item.hir_id()) else { return; }; @@ -128,6 +129,9 @@ impl LateLintPass<'_> for NonCanonicalImpls { let ExprKind::Block(block, ..) = body.value.kind else { return; }; + if in_external_macro(cx.sess(), block.span) || is_from_proc_macro(cx, impl_item) { + return; + } if cx.tcx.is_diagnostic_item(sym::Clone, trait_impl.def_id) && let Some(copy_def_id) = cx.tcx.get_diagnostic_item(sym::Copy) diff --git a/clippy_lints/src/non_copy_const.rs b/clippy_lints/src/non_copy_const.rs index 20a97645af95d..5cb8e7bfab2a9 100644 --- a/clippy_lints/src/non_copy_const.rs +++ b/clippy_lints/src/non_copy_const.rs @@ -7,7 +7,7 @@ use std::ptr; use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::in_constant; use clippy_utils::macros::macro_backtrace; -use clippy_utils::ty::InteriorMut; +use clippy_utils::ty::{implements_trait, InteriorMut}; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::DefId; use rustc_hir::{ @@ -18,7 +18,7 @@ use rustc_middle::mir::interpret::{ErrorHandled, EvalToValTreeResult, GlobalId}; use rustc_middle::ty::adjustment::Adjust; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_session::impl_lint_pass; -use rustc_span::{sym, InnerSpan, Span, DUMMY_SP}; +use rustc_span::{sym, Span, DUMMY_SP}; use rustc_target::abi::VariantIdx; // FIXME: this is a correctness problem but there's no suitable @@ -127,19 +127,19 @@ declare_clippy_lint! { } #[derive(Copy, Clone)] -enum Source { - Item { item: Span }, +enum Source<'tcx> { + Item { item: Span, ty: Ty<'tcx> }, Assoc { item: Span }, Expr { expr: Span }, } -impl Source { +impl Source<'_> { #[must_use] fn lint(&self) -> (&'static Lint, &'static str, Span) { match self { - Self::Item { item } | Self::Assoc { item, .. } => ( + Self::Item { item, .. } | Self::Assoc { item, .. } => ( DECLARE_INTERIOR_MUTABLE_CONST, - "a `const` item should never be interior mutable", + "a `const` item should not be interior mutable", *item, ), Self::Expr { expr } => ( @@ -151,16 +151,24 @@ impl Source { } } -fn lint(cx: &LateContext<'_>, source: Source) { +fn lint<'tcx>(cx: &LateContext<'tcx>, source: Source<'tcx>) { let (lint, msg, span) = source.lint(); span_lint_and_then(cx, lint, span, msg, |diag| { if span.from_expansion() { return; // Don't give suggestions into macros. } match source { - Source::Item { .. } => { - let const_kw_span = span.from_inner(InnerSpan::new(0, 5)); - diag.span_label(const_kw_span, "make this a static item (maybe with lazy_static)"); + Source::Item { ty, .. } => { + let Some(sync_trait) = cx.tcx.lang_items().sync_trait() else { + return; + }; + if implements_trait(cx, ty, sync_trait, &[]) { + diag.help("consider making this a static item"); + } else { + diag.help( + "consider making this `Sync` so that it can go in a static item or using a `thread_local`", + ); + } }, Source::Assoc { .. } => (), Source::Expr { .. } => { @@ -311,7 +319,7 @@ impl<'tcx> LateLintPass<'tcx> for NonCopyConst<'tcx> { && self.interior_mut.is_interior_mut_ty(cx, ty) && Self::is_value_unfrozen_poly(cx, body_id, ty) { - lint(cx, Source::Item { item: it.span }); + lint(cx, Source::Item { item: it.span, ty }); } } } diff --git a/clippy_lints/src/operators/assign_op_pattern.rs b/clippy_lints/src/operators/assign_op_pattern.rs index 910e584a7a0f9..641d881d974b8 100644 --- a/clippy_lints/src/operators/assign_op_pattern.rs +++ b/clippy_lints/src/operators/assign_op_pattern.rs @@ -1,7 +1,7 @@ use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::source::snippet_opt; use clippy_utils::ty::implements_trait; -use clippy_utils::visitors::for_each_expr; +use clippy_utils::visitors::for_each_expr_without_closures; use clippy_utils::{binop_traits, eq_expr_value, trait_ref_of_method}; use core::ops::ControlFlow; use rustc_errors::Applicability; @@ -62,7 +62,7 @@ pub(super) fn check<'tcx>( }; let mut found = false; - let found_multiple = for_each_expr(e, |e| { + let found_multiple = for_each_expr_without_closures(e, |e| { if eq_expr_value(cx, assignee, e) { if found { return ControlFlow::Break(()); diff --git a/clippy_lints/src/panic_in_result_fn.rs b/clippy_lints/src/panic_in_result_fn.rs index 806638c0505ba..381975199d285 100644 --- a/clippy_lints/src/panic_in_result_fn.rs +++ b/clippy_lints/src/panic_in_result_fn.rs @@ -64,7 +64,7 @@ impl<'tcx> LateLintPass<'tcx> for PanicInResultFn { fn lint_impl_body<'tcx>(cx: &LateContext<'tcx>, impl_span: Span, body: &'tcx hir::Body<'tcx>) { let mut panics = Vec::new(); - let _: Option = for_each_expr(body.value, |e| { + let _: Option = for_each_expr(cx, body.value, |e| { let Some(macro_call) = root_macro_call_first_node(cx, e) else { return ControlFlow::Continue(Descend::Yes); }; diff --git a/clippy_lints/src/redundant_async_block.rs b/clippy_lints/src/redundant_async_block.rs index 0ed957f1f2fb3..313e4083256bc 100644 --- a/clippy_lints/src/redundant_async_block.rs +++ b/clippy_lints/src/redundant_async_block.rs @@ -4,7 +4,7 @@ use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::peel_blocks; use clippy_utils::source::{snippet, walk_span_to_context}; use clippy_utils::ty::implements_trait; -use clippy_utils::visitors::for_each_expr; +use clippy_utils::visitors::for_each_expr_without_closures; use rustc_errors::Applicability; use rustc_hir::{ Closure, ClosureKind, CoroutineDesugaring, CoroutineKind, CoroutineSource, Expr, ExprKind, MatchSource, @@ -107,7 +107,7 @@ fn desugar_await<'tcx>(expr: &'tcx Expr<'_>) -> Option<&'tcx Expr<'tcx>> { if let ExprKind::Match(match_value, _, MatchSource::AwaitDesugar) = expr.kind && let ExprKind::Call(_, [into_future_arg]) = match_value.kind && let ctxt = expr.span.ctxt() - && for_each_expr(into_future_arg, |e| { + && for_each_expr_without_closures(into_future_arg, |e| { walk_span_to_context(e.span, ctxt).map_or(ControlFlow::Break(()), |_| ControlFlow::Continue(())) }) .is_none() diff --git a/clippy_lints/src/reference.rs b/clippy_lints/src/reference.rs index 16086ba6637c3..8f32cf5f2a1db 100644 --- a/clippy_lints/src/reference.rs +++ b/clippy_lints/src/reference.rs @@ -48,6 +48,9 @@ impl EarlyLintPass for DerefAddrOf { fn check_expr(&mut self, cx: &EarlyContext<'_>, e: &Expr) { if let ExprKind::Unary(UnOp::Deref, ref deref_target) = e.kind && let ExprKind::AddrOf(_, ref mutability, ref addrof_target) = without_parens(deref_target).kind + // NOTE(tesuji): `*&` forces rustc to const-promote the array to `.rodata` section. + // See #12854 for details. + && !matches!(addrof_target.kind, ExprKind::Array(_)) && deref_target.span.eq_ctxt(e.span) && !addrof_target.span.from_expansion() { diff --git a/clippy_lints/src/returns.rs b/clippy_lints/src/returns.rs index 48d6fb3c0378a..c11da3147ef4a 100644 --- a/clippy_lints/src/returns.rs +++ b/clippy_lints/src/returns.rs @@ -1,7 +1,7 @@ use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_hir_and_then}; use clippy_utils::source::{snippet_opt, snippet_with_context}; use clippy_utils::sugg::has_enclosing_paren; -use clippy_utils::visitors::{for_each_expr_with_closures, Descend}; +use clippy_utils::visitors::{for_each_expr, Descend}; use clippy_utils::{ binary_expr_needs_parentheses, fn_def_id, is_from_proc_macro, is_inside_let_else, is_res_lang_ctor, path_res, path_to_local_id, span_contains_cfg, span_find_starting_semi, @@ -436,7 +436,7 @@ fn emit_return_lint( } fn last_statement_borrows<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) -> bool { - for_each_expr_with_closures(cx, expr, |e| { + for_each_expr(cx, expr, |e| { if let Some(def_id) = fn_def_id(cx, e) && cx .tcx diff --git a/clippy_lints/src/significant_drop_tightening.rs b/clippy_lints/src/significant_drop_tightening.rs index 038eb92d652b4..979d6dc77aede 100644 --- a/clippy_lints/src/significant_drop_tightening.rs +++ b/clippy_lints/src/significant_drop_tightening.rs @@ -1,7 +1,7 @@ use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::source::{indent_of, snippet}; use clippy_utils::{expr_or_init, get_attr, path_to_local, peel_hir_expr_unary}; -use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap}; +use rustc_data_structures::fx::{FxHashMap, FxIndexMap}; use rustc_errors::Applicability; use rustc_hir::def::{DefKind, Res}; use rustc_hir::intravisit::{walk_expr, Visitor}; @@ -12,6 +12,7 @@ use rustc_session::impl_lint_pass; use rustc_span::symbol::Ident; use rustc_span::{sym, Span, DUMMY_SP}; use std::borrow::Cow; +use std::collections::hash_map::Entry; declare_clippy_lint! { /// ### What it does @@ -57,7 +58,6 @@ impl_lint_pass!(SignificantDropTightening<'_> => [SIGNIFICANT_DROP_TIGHTENING]); pub struct SignificantDropTightening<'tcx> { apas: FxIndexMap, /// Auxiliary structure used to avoid having to verify the same type multiple times. - seen_types: FxHashSet>, type_cache: FxHashMap, bool>, } @@ -74,7 +74,7 @@ impl<'tcx> LateLintPass<'tcx> for SignificantDropTightening<'tcx> { self.apas.clear(); let initial_dummy_stmt = dummy_stmt_expr(body.value); let mut ap = AuxParams::new(&mut self.apas, &initial_dummy_stmt); - StmtsChecker::new(&mut ap, cx, &mut self.seen_types, &mut self.type_cache).visit_body(body); + StmtsChecker::new(&mut ap, cx, &mut self.type_cache).visit_body(body); for apa in ap.apas.values() { if apa.counter <= 1 || !apa.has_expensive_expr_after_last_attr { continue; @@ -142,28 +142,25 @@ impl<'tcx> LateLintPass<'tcx> for SignificantDropTightening<'tcx> { /// Checks the existence of the `#[has_significant_drop]` attribute. struct AttrChecker<'cx, 'others, 'tcx> { cx: &'cx LateContext<'tcx>, - seen_types: &'others mut FxHashSet>, type_cache: &'others mut FxHashMap, bool>, } impl<'cx, 'others, 'tcx> AttrChecker<'cx, 'others, 'tcx> { - pub(crate) fn new( - cx: &'cx LateContext<'tcx>, - seen_types: &'others mut FxHashSet>, - type_cache: &'others mut FxHashMap, bool>, - ) -> Self { - seen_types.clear(); - Self { - cx, - seen_types, - type_cache, - } + pub(crate) fn new(cx: &'cx LateContext<'tcx>, type_cache: &'others mut FxHashMap, bool>) -> Self { + Self { cx, type_cache } } fn has_sig_drop_attr(&mut self, ty: Ty<'tcx>) -> bool { - // The borrow checker prevents us from using something fancier like or_insert_with. - if let Some(ty) = self.type_cache.get(&ty) { - return *ty; + let ty = self + .cx + .tcx + .try_normalize_erasing_regions(self.cx.param_env, ty) + .unwrap_or(ty); + match self.type_cache.entry(ty) { + Entry::Occupied(e) => return *e.get(), + Entry::Vacant(e) => { + e.insert(false); + }, } let value = self.has_sig_drop_attr_uncached(ty); self.type_cache.insert(ty, value); @@ -185,7 +182,7 @@ impl<'cx, 'others, 'tcx> AttrChecker<'cx, 'others, 'tcx> { rustc_middle::ty::Adt(a, b) => { for f in a.all_fields() { let ty = f.ty(self.cx.tcx, b); - if !self.has_seen_ty(ty) && self.has_sig_drop_attr(ty) { + if self.has_sig_drop_attr(ty) { return true; } } @@ -205,16 +202,11 @@ impl<'cx, 'others, 'tcx> AttrChecker<'cx, 'others, 'tcx> { _ => false, } } - - fn has_seen_ty(&mut self, ty: Ty<'tcx>) -> bool { - !self.seen_types.insert(ty) - } } struct StmtsChecker<'ap, 'lc, 'others, 'stmt, 'tcx> { ap: &'ap mut AuxParams<'others, 'stmt, 'tcx>, cx: &'lc LateContext<'tcx>, - seen_types: &'others mut FxHashSet>, type_cache: &'others mut FxHashMap, bool>, } @@ -222,15 +214,9 @@ impl<'ap, 'lc, 'others, 'stmt, 'tcx> StmtsChecker<'ap, 'lc, 'others, 'stmt, 'tcx fn new( ap: &'ap mut AuxParams<'others, 'stmt, 'tcx>, cx: &'lc LateContext<'tcx>, - seen_types: &'others mut FxHashSet>, type_cache: &'others mut FxHashMap, bool>, ) -> Self { - Self { - ap, - cx, - seen_types, - type_cache, - } + Self { ap, cx, type_cache } } fn manage_has_expensive_expr_after_last_attr(&mut self) { @@ -288,7 +274,7 @@ impl<'ap, 'lc, 'others, 'stmt, 'tcx> Visitor<'tcx> for StmtsChecker<'ap, 'lc, 'o apa.counter = apa.counter.wrapping_add(1); apa.has_expensive_expr_after_last_attr = false; }; - let mut ac = AttrChecker::new(self.cx, self.seen_types, self.type_cache); + let mut ac = AttrChecker::new(self.cx, self.type_cache); if ac.has_sig_drop_attr(self.cx.typeck_results().expr_ty(expr)) { if let hir::StmtKind::Let(local) = self.ap.curr_stmt.kind && let hir::PatKind::Binding(_, hir_id, ident, _) = local.pat.kind diff --git a/clippy_lints/src/string_patterns.rs b/clippy_lints/src/string_patterns.rs new file mode 100644 index 0000000000000..64b5b8f9f27b4 --- /dev/null +++ b/clippy_lints/src/string_patterns.rs @@ -0,0 +1,227 @@ +use std::ops::ControlFlow; + +use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then}; +use clippy_utils::eager_or_lazy::switch_to_eager_eval; +use clippy_utils::macros::matching_root_macro_call; +use clippy_utils::path_to_local_id; +use clippy_utils::source::{snippet, str_literal_to_char_literal}; +use clippy_utils::visitors::{for_each_expr, Descend}; +use itertools::Itertools; +use rustc_ast::{BinOpKind, LitKind}; +use rustc_errors::Applicability; +use rustc_hir::{Expr, ExprKind, PatKind}; +use rustc_lint::{LateContext, LateLintPass}; +use rustc_middle::ty; +use rustc_session::declare_lint_pass; +use rustc_span::{sym, Span}; + +declare_clippy_lint! { + /// ### What it does + /// Checks for manual `char` comparison in string patterns + /// + /// ### Why is this bad? + /// This can be written more concisely using a `char` or an array of `char`. + /// This is more readable and more optimized when comparing to only one `char`. + /// + /// ### Example + /// ```no_run + /// "Hello World!".trim_end_matches(|c| c == '.' || c == ',' || c == '!' || c == '?'); + /// ``` + /// Use instead: + /// ```no_run + /// "Hello World!".trim_end_matches(['.', ',', '!', '?']); + /// ``` + #[clippy::version = "1.80.0"] + pub MANUAL_PATTERN_CHAR_COMPARISON, + style, + "manual char comparison in string patterns" +} + +declare_clippy_lint! { + /// ### What it does + /// Checks for string methods that receive a single-character + /// `str` as an argument, e.g., `_.split("x")`. + /// + /// ### Why is this bad? + /// While this can make a perf difference on some systems, + /// benchmarks have proven inconclusive. But at least using a + /// char literal makes it clear that we are looking at a single + /// character. + /// + /// ### Known problems + /// Does not catch multi-byte unicode characters. This is by + /// design, on many machines, splitting by a non-ascii char is + /// actually slower. Please do your own measurements instead of + /// relying solely on the results of this lint. + /// + /// ### Example + /// ```rust,ignore + /// _.split("x"); + /// ``` + /// + /// Use instead: + /// ```rust,ignore + /// _.split('x'); + /// ``` + #[clippy::version = "pre 1.29.0"] + pub SINGLE_CHAR_PATTERN, + pedantic, + "using a single-character str where a char could be used, e.g., `_.split(\"x\")`" +} + +declare_lint_pass!(StringPatterns => [MANUAL_PATTERN_CHAR_COMPARISON, SINGLE_CHAR_PATTERN]); + +const PATTERN_METHODS: [(&str, usize); 22] = [ + ("contains", 0), + ("starts_with", 0), + ("ends_with", 0), + ("find", 0), + ("rfind", 0), + ("split", 0), + ("split_inclusive", 0), + ("rsplit", 0), + ("split_terminator", 0), + ("rsplit_terminator", 0), + ("splitn", 1), + ("rsplitn", 1), + ("split_once", 0), + ("rsplit_once", 0), + ("matches", 0), + ("rmatches", 0), + ("match_indices", 0), + ("rmatch_indices", 0), + ("trim_start_matches", 0), + ("trim_end_matches", 0), + ("replace", 0), + ("replacen", 0), +]; + +fn check_single_char_pattern_lint(cx: &LateContext<'_>, arg: &Expr<'_>) { + let mut applicability = Applicability::MachineApplicable; + if let Some(hint) = str_literal_to_char_literal(cx, arg, &mut applicability, true) { + span_lint_and_sugg( + cx, + SINGLE_CHAR_PATTERN, + arg.span, + "single-character string constant used as pattern", + "consider using a `char`", + hint, + applicability, + ); + } +} + +fn get_char_span<'tcx>(cx: &'_ LateContext<'tcx>, expr: &'tcx Expr<'_>) -> Option { + if cx.typeck_results().expr_ty_adjusted(expr).is_char() + && !expr.span.from_expansion() + && switch_to_eager_eval(cx, expr) + { + Some(expr.span) + } else { + None + } +} + +fn check_manual_pattern_char_comparison(cx: &LateContext<'_>, method_arg: &Expr<'_>) { + if let ExprKind::Closure(closure) = method_arg.kind + && let body = cx.tcx.hir().body(closure.body) + && let Some(PatKind::Binding(_, binding, ..)) = body.params.first().map(|p| p.pat.kind) + { + let mut set_char_spans: Vec = Vec::new(); + + // We want to retrieve all the comparisons done. + // They are ordered in a nested way and so we need to traverse the AST to collect them all. + if for_each_expr(cx, body.value, |sub_expr| -> ControlFlow<(), Descend> { + match sub_expr.kind { + ExprKind::Binary(op, left, right) if op.node == BinOpKind::Eq => { + if path_to_local_id(left, binding) + && let Some(span) = get_char_span(cx, right) + { + set_char_spans.push(span); + ControlFlow::Continue(Descend::No) + } else if path_to_local_id(right, binding) + && let Some(span) = get_char_span(cx, left) + { + set_char_spans.push(span); + ControlFlow::Continue(Descend::No) + } else { + ControlFlow::Break(()) + } + }, + ExprKind::Binary(op, _, _) if op.node == BinOpKind::Or => ControlFlow::Continue(Descend::Yes), + ExprKind::Match(match_value, [arm, _], _) => { + if matching_root_macro_call(cx, sub_expr.span, sym::matches_macro).is_none() + || arm.guard.is_some() + || !path_to_local_id(match_value, binding) + { + return ControlFlow::Break(()); + } + if arm.pat.walk_short(|pat| match pat.kind { + PatKind::Lit(expr) if let ExprKind::Lit(lit) = expr.kind => { + if let LitKind::Char(_) = lit.node { + set_char_spans.push(lit.span); + } + true + }, + PatKind::Or(_) => true, + _ => false, + }) { + ControlFlow::Continue(Descend::No) + } else { + ControlFlow::Break(()) + } + }, + _ => ControlFlow::Break(()), + } + }) + .is_some() + { + return; + } + span_lint_and_then( + cx, + MANUAL_PATTERN_CHAR_COMPARISON, + method_arg.span, + "this manual char comparison can be written more succinctly", + |diag| { + if let [set_char_span] = set_char_spans[..] { + diag.span_suggestion( + method_arg.span, + "consider using a `char`", + snippet(cx, set_char_span, "c"), + Applicability::MachineApplicable, + ); + } else { + diag.span_suggestion( + method_arg.span, + "consider using an array of `char`", + format!( + "[{}]", + set_char_spans.into_iter().map(|span| snippet(cx, span, "c")).join(", ") + ), + Applicability::MachineApplicable, + ); + } + }, + ); + } +} + +impl<'tcx> LateLintPass<'tcx> for StringPatterns { + fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { + if !expr.span.from_expansion() + && let ExprKind::MethodCall(method, receiver, args, _) = expr.kind + && let ty::Ref(_, ty, _) = cx.typeck_results().expr_ty_adjusted(receiver).kind() + && ty.is_str() + && let method_name = method.ident.name.as_str() + && let Some(&(_, pos)) = PATTERN_METHODS + .iter() + .find(|(array_method_name, _)| *array_method_name == method_name) + && let Some(arg) = args.get(pos) + { + check_single_char_pattern_lint(cx, arg); + + check_manual_pattern_char_comparison(cx, arg); + } + } +} diff --git a/clippy_lints/src/strings.rs b/clippy_lints/src/strings.rs index f8d36d6b92f61..7da661485abfc 100644 --- a/clippy_lints/src/strings.rs +++ b/clippy_lints/src/strings.rs @@ -399,13 +399,17 @@ impl<'tcx> LateLintPass<'tcx> for StrToString { && let ty::Ref(_, ty, ..) = ty.kind() && ty.is_str() { - span_lint_and_help( + let mut applicability = Applicability::MachineApplicable; + let snippet = snippet_with_applicability(cx, self_arg.span, "..", &mut applicability); + + span_lint_and_sugg( cx, STR_TO_STRING, expr.span, "`to_string()` called on a `&str`", - None, - "consider using `.to_owned()`", + "try", + format!("{snippet}.to_owned()"), + applicability, ); } } diff --git a/clippy_lints/src/suspicious_trait_impl.rs b/clippy_lints/src/suspicious_trait_impl.rs index 3f030b8033187..744d6392e065c 100644 --- a/clippy_lints/src/suspicious_trait_impl.rs +++ b/clippy_lints/src/suspicious_trait_impl.rs @@ -1,5 +1,5 @@ use clippy_utils::diagnostics::span_lint; -use clippy_utils::visitors::for_each_expr; +use clippy_utils::visitors::for_each_expr_without_closures; use clippy_utils::{binop_traits, trait_ref_of_method, BINOP_TRAITS, OP_ASSIGN_TRAITS}; use core::ops::ControlFlow; use rustc_hir as hir; @@ -95,7 +95,7 @@ impl<'tcx> LateLintPass<'tcx> for SuspiciousImpl { fn count_binops(expr: &hir::Expr<'_>) -> u32 { let mut count = 0u32; - let _: Option = for_each_expr(expr, |e| { + let _: Option = for_each_expr_without_closures(expr, |e| { if matches!( e.kind, hir::ExprKind::Binary(..) diff --git a/clippy_lints/src/transmute/missing_transmute_annotations.rs b/clippy_lints/src/transmute/missing_transmute_annotations.rs index f98ea59a15d87..b2892d136fa3a 100644 --- a/clippy_lints/src/transmute/missing_transmute_annotations.rs +++ b/clippy_lints/src/transmute/missing_transmute_annotations.rs @@ -31,7 +31,6 @@ fn get_parent_local_binding_ty<'tcx>(cx: &LateContext<'tcx>, expr_hir_id: HirId) fn is_function_block(cx: &LateContext<'_>, expr_hir_id: HirId) -> bool { let def_id = cx.tcx.hir().enclosing_body_owner(expr_hir_id); if let Some(body) = cx.tcx.hir().maybe_body_owned_by(def_id) { - let body = cx.tcx.hir().body(body.id()); return body.value.peel_blocks().hir_id == expr_hir_id; } false diff --git a/clippy_lints/src/transmute/mod.rs b/clippy_lints/src/transmute/mod.rs index 598032ccdebed..aa329ec33668d 100644 --- a/clippy_lints/src/transmute/mod.rs +++ b/clippy_lints/src/transmute/mod.rs @@ -546,7 +546,7 @@ declare_clippy_lint! { /// let x = std::mem::transmute::<[u16; 2], i32>([1u16, 2u16]); /// # } /// ``` - #[clippy::version = "1.77.0"] + #[clippy::version = "1.79.0"] pub MISSING_TRANSMUTE_ANNOTATIONS, suspicious, "warns if a transmute call doesn't have all generics specified" diff --git a/clippy_lints/src/undocumented_unsafe_blocks.rs b/clippy_lints/src/undocumented_unsafe_blocks.rs index 6cf9229fdd083..93a1089a97073 100644 --- a/clippy_lints/src/undocumented_unsafe_blocks.rs +++ b/clippy_lints/src/undocumented_unsafe_blocks.rs @@ -3,7 +3,7 @@ use std::ops::ControlFlow; use clippy_utils::diagnostics::span_lint_and_help; use clippy_utils::is_lint_allowed; use clippy_utils::source::walk_span_to_context; -use clippy_utils::visitors::{for_each_expr_with_closures, Descend}; +use clippy_utils::visitors::{for_each_expr, Descend}; use hir::HirId; use rustc_data_structures::sync::Lrc; use rustc_hir as hir; @@ -296,7 +296,7 @@ fn expr_has_unnecessary_safety_comment<'tcx>( } // this should roughly be the reverse of `block_parents_have_safety_comment` - if for_each_expr_with_closures(cx, expr, |expr| match expr.kind { + if for_each_expr(cx, expr, |expr| match expr.kind { hir::ExprKind::Block( Block { rules: BlockCheckMode::UnsafeBlock(UnsafeSource::UserProvided), diff --git a/clippy_lints/src/unused_self.rs b/clippy_lints/src/unused_self.rs index a67f53f00aee7..3e6102f5982fa 100644 --- a/clippy_lints/src/unused_self.rs +++ b/clippy_lints/src/unused_self.rs @@ -59,7 +59,7 @@ impl<'tcx> LateLintPass<'tcx> for UnusedSelf { let parent_item = cx.tcx.hir().expect_item(parent); let assoc_item = cx.tcx.associated_item(impl_item.owner_id); let contains_todo = |cx, body: &'_ Body<'_>| -> bool { - clippy_utils::visitors::for_each_expr(body.value, |e| { + clippy_utils::visitors::for_each_expr_without_closures(body.value, |e| { if let Some(macro_call) = root_macro_call_first_node(cx, e) { if cx.tcx.item_name(macro_call.def_id).as_str() == "todo" { ControlFlow::Break(()) diff --git a/clippy_lints/src/unwrap_in_result.rs b/clippy_lints/src/unwrap_in_result.rs index 197ab0f173bd8..f77badd97b7a3 100644 --- a/clippy_lints/src/unwrap_in_result.rs +++ b/clippy_lints/src/unwrap_in_result.rs @@ -77,7 +77,7 @@ fn lint_impl_body<'tcx>(cx: &LateContext<'tcx>, impl_span: Span, impl_item: &'tc let body = cx.tcx.hir().body(body_id); let typeck = cx.tcx.typeck(impl_item.owner_id.def_id); let mut result = Vec::new(); - let _: Option = for_each_expr(body.value, |e| { + let _: Option = for_each_expr(cx, body.value, |e| { // check for `expect` if let Some(arglists) = method_chain_args(e, &["expect"]) { let receiver_ty = typeck.expr_ty(arglists[0].0).peel_refs(); diff --git a/clippy_lints/src/utils/author.rs b/clippy_lints/src/utils/author.rs index 18a31abddd0af..e9d69407df8b5 100644 --- a/clippy_lints/src/utils/author.rs +++ b/clippy_lints/src/utils/author.rs @@ -733,7 +733,7 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> { match stmt.value.kind { StmtKind::Let(local) => { bind!(self, local); - kind!("Local({local})"); + kind!("Let({local})"); self.option(field!(local.init), "init", |init| { self.expr(init); }); diff --git a/clippy_lints/src/utils/internal_lints/lint_without_lint_pass.rs b/clippy_lints/src/utils/internal_lints/lint_without_lint_pass.rs index 9be225759df95..84f84781e7126 100644 --- a/clippy_lints/src/utils/internal_lints/lint_without_lint_pass.rs +++ b/clippy_lints/src/utils/internal_lints/lint_without_lint_pass.rs @@ -213,7 +213,7 @@ impl<'tcx> LateLintPass<'tcx> for LintWithoutLintPass { output: &mut self.registered_lints, cx, }; - let body_id = cx.tcx.hir().body_owned_by( + let body = cx.tcx.hir().body_owned_by( impl_item_refs .iter() .find(|iiref| iiref.ident.as_str() == "get_lints") @@ -222,7 +222,7 @@ impl<'tcx> LateLintPass<'tcx> for LintWithoutLintPass { .owner_id .def_id, ); - collector.visit_expr(cx.tcx.hir().body(body_id).value); + collector.visit_expr(body.value); } } } diff --git a/clippy_lints/src/utils/internal_lints/metadata_collector.rs b/clippy_lints/src/utils/internal_lints/metadata_collector.rs index 5c1ebb922f125..1c149f2045629 100644 --- a/clippy_lints/src/utils/internal_lints/metadata_collector.rs +++ b/clippy_lints/src/utils/internal_lints/metadata_collector.rs @@ -719,7 +719,7 @@ fn get_lint_group_and_level_or_lint( Some(sym::clippy), &std::iter::once(Ident::with_dummy_span(sym::clippy)).collect(), ); - if let CheckLintNameResult::Tool(Ok(lint_lst)) = result { + if let CheckLintNameResult::Tool(lint_lst, None) = result { if let Some(group) = get_lint_group(cx, lint_lst[0]) { if EXCLUDED_LINT_GROUPS.contains(&group.as_str()) { return None; diff --git a/clippy_lints/src/zero_repeat_side_effects.rs b/clippy_lints/src/zero_repeat_side_effects.rs index 8796b8f61d16a..ad041e55bdafb 100644 --- a/clippy_lints/src/zero_repeat_side_effects.rs +++ b/clippy_lints/src/zero_repeat_side_effects.rs @@ -1,7 +1,7 @@ use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::higher::VecArgs; use clippy_utils::source::snippet; -use clippy_utils::visitors::for_each_expr; +use clippy_utils::visitors::for_each_expr_without_closures; use rustc_ast::LitKind; use rustc_errors::Applicability; use rustc_hir::{ExprKind, Node}; @@ -36,7 +36,7 @@ declare_clippy_lint! { /// side_effect(); /// let a: [i32; 0] = []; /// ``` - #[clippy::version = "1.75.0"] + #[clippy::version = "1.79.0"] pub ZERO_REPEAT_SIDE_EFFECTS, suspicious, "usage of zero-sized initializations of arrays or vecs causing side effects" @@ -65,7 +65,7 @@ impl LateLintPass<'_> for ZeroRepeatSideEffects { fn inner_check(cx: &LateContext<'_>, expr: &'_ rustc_hir::Expr<'_>, inner_expr: &'_ rustc_hir::Expr<'_>, is_vec: bool) { // check if expr is a call or has a call inside it - if for_each_expr(inner_expr, |x| { + if for_each_expr_without_closures(inner_expr, |x| { if let ExprKind::Call(_, _) | ExprKind::MethodCall(_, _, _, _) = x.kind { std::ops::ControlFlow::Break(()) } else { diff --git a/clippy_utils/Cargo.toml b/clippy_utils/Cargo.toml index ab883c25338ba..3a3aeb8821643 100644 --- a/clippy_utils/Cargo.toml +++ b/clippy_utils/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "clippy_utils" -version = "0.1.80" +version = "0.1.81" edition = "2021" publish = false diff --git a/clippy_utils/src/consts.rs b/clippy_utils/src/consts.rs index e9e1aa7e4453f..cfd142fe1ff63 100644 --- a/clippy_utils/src/consts.rs +++ b/clippy_utils/src/consts.rs @@ -412,7 +412,8 @@ impl<'a, 'tcx> ConstEvalLateContext<'a, 'tcx> { /// Simple constant folding: Insert an expression, get a constant or none. pub fn expr(&mut self, e: &Expr<'_>) -> Option> { match e.kind { - ExprKind::ConstBlock(ConstBlock { body, .. }) => self.expr(self.lcx.tcx.hir().body(body).value), ExprKind::DropTemps(e) => self.expr(e), + ExprKind::ConstBlock(ConstBlock { body, .. }) => self.expr(self.lcx.tcx.hir().body(body).value), + ExprKind::DropTemps(e) => self.expr(e), ExprKind::Path(ref qpath) => { self.fetch_path_and_apply(qpath, e.hir_id, self.typeck_results.expr_ty(e), |this, result| { let result = mir_to_const(this.lcx, result)?; @@ -490,7 +491,8 @@ impl<'a, 'tcx> ConstEvalLateContext<'a, 'tcx> { /// leaves the local crate. pub fn expr_is_empty(&mut self, e: &Expr<'_>) -> Option { match e.kind { - ExprKind::ConstBlock(ConstBlock { body, .. }) => self.expr_is_empty(self.lcx.tcx.hir().body(body).value), ExprKind::DropTemps(e) => self.expr_is_empty(e), + ExprKind::ConstBlock(ConstBlock { body, .. }) => self.expr_is_empty(self.lcx.tcx.hir().body(body).value), + ExprKind::DropTemps(e) => self.expr_is_empty(e), ExprKind::Path(ref qpath) => { if !self .typeck_results @@ -811,12 +813,8 @@ pub fn mir_to_const<'tcx>(lcx: &LateContext<'tcx>, result: mir::Const<'tcx>) -> ty::Adt(adt_def, _) if adt_def.is_struct() => Some(Constant::Adt(result)), ty::Bool => Some(Constant::Bool(int == ScalarInt::TRUE)), ty::Uint(_) | ty::Int(_) => Some(Constant::Int(int.to_bits(int.size()))), - ty::Float(FloatTy::F32) => Some(Constant::F32(f32::from_bits( - int.try_into().expect("invalid f32 bit representation"), - ))), - ty::Float(FloatTy::F64) => Some(Constant::F64(f64::from_bits( - int.try_into().expect("invalid f64 bit representation"), - ))), + ty::Float(FloatTy::F32) => Some(Constant::F32(f32::from_bits(int.into()))), + ty::Float(FloatTy::F64) => Some(Constant::F64(f64::from_bits(int.into()))), ty::RawPtr(_, _) => Some(Constant::RawPtr(int.to_bits(int.size()))), _ => None, }, diff --git a/clippy_utils/src/hir_utils.rs b/clippy_utils/src/hir_utils.rs index 36634817fc91e..50dd8430ac069 100644 --- a/clippy_utils/src/hir_utils.rs +++ b/clippy_utils/src/hir_utils.rs @@ -7,9 +7,9 @@ use rustc_data_structures::fx::FxHasher; use rustc_hir::def::Res; use rustc_hir::MatchSource::TryDesugar; use rustc_hir::{ - ArrayLen, BinOpKind, BindingMode, Block, BodyId, Closure, Expr, ExprField, ExprKind, FnRetTy, GenericArg, - GenericArgs, HirId, HirIdMap, InlineAsmOperand, LetExpr, Lifetime, LifetimeName, Pat, PatField, PatKind, Path, - PathSegment, PrimTy, QPath, Stmt, StmtKind, Ty, TyKind, AssocItemConstraint, + ArrayLen, AssocItemConstraint, BinOpKind, BindingMode, Block, BodyId, Closure, Expr, ExprField, ExprKind, FnRetTy, + GenericArg, GenericArgs, HirId, HirIdMap, InlineAsmOperand, LetExpr, Lifetime, LifetimeName, Pat, PatField, + PatKind, Path, PathSegment, PrimTy, QPath, Stmt, StmtKind, Ty, TyKind, }; use rustc_lexer::{tokenize, TokenKind}; use rustc_lint::LateContext; @@ -519,7 +519,11 @@ impl HirEqInterExpr<'_, '_, '_> { } fn eq_assoc_type_binding(&mut self, left: &AssocItemConstraint<'_>, right: &AssocItemConstraint<'_>) -> bool { - left.ident.name == right.ident.name && self.eq_ty(left.ty().expect("expected assoc type binding"), right.ty().expect("expected assoc type binding")) + left.ident.name == right.ident.name + && self.eq_ty( + left.ty().expect("expected assoc type binding"), + right.ty().expect("expected assoc type binding"), + ) } fn check_ctxt(&mut self, left: SyntaxContext, right: SyntaxContext) -> bool { diff --git a/clippy_utils/src/lib.rs b/clippy_utils/src/lib.rs index 2f6bf92096776..7dc341ec8d71b 100644 --- a/clippy_utils/src/lib.rs +++ b/clippy_utils/src/lib.rs @@ -126,7 +126,7 @@ use visitors::Visitable; use crate::consts::{constant, mir_to_const, Constant}; use crate::higher::Range; use crate::ty::{adt_and_variant_of_res, can_partially_move_ty, expr_sig, is_copy, is_recursively_primitive_type}; -use crate::visitors::for_each_expr; +use crate::visitors::for_each_expr_without_closures; use rustc_middle::hir::nested_filter; @@ -321,6 +321,15 @@ pub fn match_trait_method(cx: &LateContext<'_>, expr: &Expr<'_>, path: &[&str]) .map_or(false, |trt_id| match_def_path(cx, trt_id, path)) } +/// Checks if the given method call expression calls an inherent method. +pub fn is_inherent_method_call(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { + if let Some(method_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id) { + cx.tcx.trait_of_item(method_id).is_none() + } else { + false + } +} + /// Checks if a method is defined in an impl of a diagnostic item pub fn is_diag_item_method(cx: &LateContext<'_>, def_id: DefId, diag_item: Symbol) -> bool { if let Some(impl_did) = cx.tcx.impl_of_method(def_id) { @@ -1313,7 +1322,7 @@ pub fn contains_name<'tcx>(name: Symbol, expr: &'tcx Expr<'_>, cx: &LateContext< /// Returns `true` if `expr` contains a return expression pub fn contains_return<'tcx>(expr: impl Visitable<'tcx>) -> bool { - for_each_expr(expr, |e| { + for_each_expr_without_closures(expr, |e| { if matches!(e.kind, ExprKind::Ret(..)) { ControlFlow::Break(()) } else { @@ -3392,3 +3401,14 @@ pub fn binary_expr_needs_parentheses(expr: &Expr<'_>) -> bool { contains_block(expr, false) } + +/// Returns true if the specified expression is in a receiver position. +pub fn is_receiver_of_method_call(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { + if let Some(parent_expr) = get_parent_expr(cx, expr) + && let ExprKind::MethodCall(_, receiver, ..) = parent_expr.kind + && receiver.hir_id == expr.hir_id + { + return true; + } + false +} diff --git a/clippy_utils/src/macros.rs b/clippy_utils/src/macros.rs index 8daab9b0d92cf..455239cc37f35 100644 --- a/clippy_utils/src/macros.rs +++ b/clippy_utils/src/macros.rs @@ -1,6 +1,6 @@ #![allow(clippy::similar_names)] // `expr` and `expn` -use crate::visitors::{for_each_expr, Descend}; +use crate::visitors::{for_each_expr_without_closures, Descend}; use arrayvec::ArrayVec; use rustc_ast::{FormatArgs, FormatArgument, FormatPlaceholder}; @@ -323,7 +323,7 @@ fn find_assert_args_inner<'a, const N: usize>( Some(inner_name) => find_assert_within_debug_assert(cx, expr, expn, Symbol::intern(inner_name))?, }; let mut args = ArrayVec::new(); - let panic_expn = for_each_expr(expr, |e| { + let panic_expn = for_each_expr_without_closures(expr, |e| { if args.is_full() { match PanicExpn::parse(e) { Some(expn) => ControlFlow::Break(expn), @@ -349,7 +349,7 @@ fn find_assert_within_debug_assert<'a>( expn: ExpnId, assert_name: Symbol, ) -> Option<(&'a Expr<'a>, ExpnId)> { - for_each_expr(expr, |e| { + for_each_expr_without_closures(expr, |e| { if !e.span.from_expansion() { return ControlFlow::Continue(Descend::No); } @@ -397,7 +397,7 @@ impl FormatArgsStorage { /// /// See also [`find_format_arg_expr`] pub fn get(&self, cx: &LateContext<'_>, start: &Expr<'_>, expn_id: ExpnId) -> Option<&FormatArgs> { - let format_args_expr = for_each_expr(start, |expr| { + let format_args_expr = for_each_expr_without_closures(start, |expr| { let ctxt = expr.span.ctxt(); if ctxt.outer_expn().is_descendant_of(expn_id) { if macro_backtrace(expr.span) @@ -439,7 +439,7 @@ pub fn find_format_arg_expr<'hir, 'ast>( parent: _, } = target.expr.span.data(); - for_each_expr(start, |expr| { + for_each_expr_without_closures(start, |expr| { // When incremental compilation is enabled spans gain a parent during AST to HIR lowering, // since we're comparing an AST span to a HIR one we need to ignore the parent field let data = expr.span.data(); diff --git a/clippy_utils/src/ptr.rs b/clippy_utils/src/ptr.rs index 88837d8a143ed..991ea428dc33b 100644 --- a/clippy_utils/src/ptr.rs +++ b/clippy_utils/src/ptr.rs @@ -1,5 +1,5 @@ use crate::source::snippet; -use crate::visitors::{for_each_expr, Descend}; +use crate::visitors::{for_each_expr_without_closures, Descend}; use crate::{path_to_local_id, strip_pat_refs}; use core::ops::ControlFlow; use rustc_hir::{Body, BodyId, ExprKind, HirId, PatKind}; @@ -31,7 +31,7 @@ fn extract_clone_suggestions<'tcx>( body: &'tcx Body<'_>, ) -> Option)>> { let mut spans = Vec::new(); - for_each_expr(body, |e| { + for_each_expr_without_closures(body, |e| { if let ExprKind::MethodCall(seg, recv, [], _) = e.kind && path_to_local_id(recv, id) { diff --git a/clippy_utils/src/qualify_min_const_fn.rs b/clippy_utils/src/qualify_min_const_fn.rs index 81e94725a70cb..42b10f69c0cdf 100644 --- a/clippy_utils/src/qualify_min_const_fn.rs +++ b/clippy_utils/src/qualify_min_const_fn.rs @@ -40,9 +40,13 @@ pub fn is_min_const_fn<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>, msrv: &Msrv) )?; for bb in &*body.basic_blocks { - check_terminator(tcx, body, bb.terminator(), msrv)?; - for stmt in &bb.statements { - check_statement(tcx, body, def_id, stmt, msrv)?; + // Cleanup blocks are ignored entirely by const eval, so we can too: + // https://github.com/rust-lang/rust/blob/1dea922ea6e74f99a0e97de5cdb8174e4dea0444/compiler/rustc_const_eval/src/transform/check_consts/check.rs#L382 + if !bb.is_cleanup { + check_terminator(tcx, body, bb.terminator(), msrv)?; + for stmt in &bb.statements { + check_statement(tcx, body, def_id, stmt, msrv)?; + } } } Ok(()) diff --git a/clippy_utils/src/source.rs b/clippy_utils/src/source.rs index fd67e039c29a9..e2e5cde947d83 100644 --- a/clippy_utils/src/source.rs +++ b/clippy_utils/src/source.rs @@ -2,6 +2,7 @@ #![allow(clippy::module_name_repetitions)] +use rustc_ast::{LitKind, StrStyle}; use rustc_data_structures::sync::Lrc; use rustc_errors::Applicability; use rustc_hir::{BlockCheckMode, Expr, ExprKind, UnsafeSource}; @@ -500,6 +501,50 @@ pub fn expand_past_previous_comma(cx: &LateContext<'_>, span: Span) -> Span { extended.with_lo(extended.lo() - BytePos(1)) } +/// Converts `expr` to a `char` literal if it's a `str` literal containing a single +/// character (or a single byte with `ascii_only`) +pub fn str_literal_to_char_literal( + cx: &LateContext<'_>, + expr: &Expr<'_>, + applicability: &mut Applicability, + ascii_only: bool, +) -> Option { + if let ExprKind::Lit(lit) = &expr.kind + && let LitKind::Str(r, style) = lit.node + && let string = r.as_str() + && let len = if ascii_only { + string.len() + } else { + string.chars().count() + } + && len == 1 + { + let snip = snippet_with_applicability(cx, expr.span, string, applicability); + let ch = if let StrStyle::Raw(nhash) = style { + let nhash = nhash as usize; + // for raw string: r##"a"## + &snip[(nhash + 2)..(snip.len() - 1 - nhash)] + } else { + // for regular string: "a" + &snip[1..(snip.len() - 1)] + }; + + let hint = format!( + "'{}'", + match ch { + "'" => "\\'", + r"\" => "\\\\", + "\\\"" => "\"", // no need to escape `"` in `'"'` + _ => ch, + } + ); + + Some(hint) + } else { + None + } +} + #[cfg(test)] mod test { use super::{reindent_multiline, without_block_comments}; diff --git a/clippy_utils/src/ty.rs b/clippy_utils/src/ty.rs index 6e5626297c959..7d4332a3d9de8 100644 --- a/clippy_utils/src/ty.rs +++ b/clippy_utils/src/ty.rs @@ -17,9 +17,9 @@ use rustc_middle::mir::ConstValue; use rustc_middle::traits::EvaluationResult; use rustc_middle::ty::layout::ValidityRequirement; use rustc_middle::ty::{ - self, AdtDef, AliasTy, AssocKind, Binder, BoundRegion, FnSig, GenericArg, GenericArgKind, GenericArgsRef, - GenericParamDefKind, IntTy, ParamEnv, Region, RegionKind, TraitRef, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, - TypeVisitableExt, TypeVisitor, UintTy, Upcast, VariantDef, VariantDiscr, + self, AdtDef, AliasTy, AssocItem, AssocKind, Binder, BoundRegion, FnSig, GenericArg, GenericArgKind, + GenericArgsRef, GenericParamDefKind, IntTy, ParamEnv, Region, RegionKind, TraitRef, Ty, TyCtxt, TypeSuperVisitable, + TypeVisitable, TypeVisitableExt, TypeVisitor, UintTy, Upcast, VariantDef, VariantDiscr, }; use rustc_span::symbol::Ident; use rustc_span::{sym, Span, Symbol, DUMMY_SP}; @@ -861,7 +861,6 @@ impl core::ops::Add for EnumValue { } /// Attempts to read the given constant as though it were an enum value. -#[expect(clippy::cast_possible_truncation, clippy::cast_possible_wrap)] pub fn read_explicit_enum_value(tcx: TyCtxt<'_>, id: DefId) -> Option { if let Ok(ConstValue::Scalar(Scalar::Int(value))) = tcx.const_eval_poly(id) { match tcx.type_of(id).instantiate_identity().kind() { @@ -1314,3 +1313,39 @@ pub fn normalize_with_regions<'tcx>(tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx> pub fn is_manually_drop(ty: Ty<'_>) -> bool { ty.ty_adt_def().map_or(false, AdtDef::is_manually_drop) } + +/// Returns the deref chain of a type, starting with the type itself. +pub fn deref_chain<'cx, 'tcx>(cx: &'cx LateContext<'tcx>, ty: Ty<'tcx>) -> impl Iterator> + 'cx { + iter::successors(Some(ty), |&ty| { + if let Some(deref_did) = cx.tcx.lang_items().deref_trait() + && implements_trait(cx, ty, deref_did, &[]) + { + make_normalized_projection(cx.tcx, cx.param_env, deref_did, sym::Target, [ty]) + } else { + None + } + }) +} + +/// Checks if a Ty<'_> has some inherent method Symbol. +/// This does not look for impls in the type's `Deref::Target` type. +/// If you need this, you should wrap this call in `clippy_utils::ty::deref_chain().any(...)`. +pub fn get_adt_inherent_method<'a>(cx: &'a LateContext<'_>, ty: Ty<'_>, method_name: Symbol) -> Option<&'a AssocItem> { + if let Some(ty_did) = ty.ty_adt_def().map(AdtDef::did) { + cx.tcx + .inherent_impls(ty_did) + .into_iter() + .flatten() + .map(|&did| { + cx.tcx + .associated_items(did) + .filter_by_name_unhygienic(method_name) + .next() + .filter(|item| item.kind == AssocKind::Fn) + }) + .next() + .flatten() + } else { + None + } +} diff --git a/clippy_utils/src/ty/type_certainty/mod.rs b/clippy_utils/src/ty/type_certainty/mod.rs index 8021930345026..cba61c841efc7 100644 --- a/clippy_utils/src/ty/type_certainty/mod.rs +++ b/clippy_utils/src/ty/type_certainty/mod.rs @@ -206,8 +206,18 @@ fn path_segment_certainty( // Checking `res_generics_def_id(..)` before calling `generics_of` avoids an ICE. if cx.tcx.res_generics_def_id(path_segment.res).is_some() { let generics = cx.tcx.generics_of(def_id); - let count = generics.own_params.len() - usize::from(generics.host_effect_index.is_some()); - let lhs = if (parent_certainty.is_certain() || generics.parent_count == 0) && count == 0 { + + let own_count = generics.own_params.len() + - usize::from(generics.host_effect_index.is_some_and(|index| { + // Check that the host index actually belongs to this resolution. + // E.g. for `Add::add`, host_effect_index is `Some(2)`, but it's part of the parent `Add` + // trait's generics. + // Add params: [Self#0, Rhs#1, host#2] parent_count=0, count=3 + // Add::add params: [] parent_count=3, count=3 + // (3..3).contains(&host_effect_index) => false + (generics.parent_count..generics.count()).contains(&index) + })); + let lhs = if (parent_certainty.is_certain() || generics.parent_count == 0) && own_count == 0 { Certainty::Certain(None) } else { Certainty::Uncertain diff --git a/clippy_utils/src/usage.rs b/clippy_utils/src/usage.rs index 2a25d51d8e509..fbf3d95365acb 100644 --- a/clippy_utils/src/usage.rs +++ b/clippy_utils/src/usage.rs @@ -1,4 +1,4 @@ -use crate::visitors::{for_each_expr, for_each_expr_with_closures, Descend, Visitable}; +use crate::visitors::{for_each_expr, for_each_expr_without_closures, Descend, Visitable}; use crate::{self as utils, get_enclosing_loop_or_multi_call_closure}; use core::ops::ControlFlow; use hir::def::Res; @@ -145,7 +145,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BindingUsageFinder<'a, 'tcx> { } pub fn contains_return_break_continue_macro(expression: &Expr<'_>) -> bool { - for_each_expr(expression, |e| { + for_each_expr_without_closures(expression, |e| { match e.kind { ExprKind::Ret(..) | ExprKind::Break(..) | ExprKind::Continue(..) => ControlFlow::Break(()), // Something special could be done here to handle while or for loop @@ -159,7 +159,7 @@ pub fn contains_return_break_continue_macro(expression: &Expr<'_>) -> bool { } pub fn local_used_in<'tcx>(cx: &LateContext<'tcx>, local_id: HirId, v: impl Visitable<'tcx>) -> bool { - for_each_expr_with_closures(cx, v, |e| { + for_each_expr(cx, v, |e| { if utils::path_to_local_id(e, local_id) { ControlFlow::Break(()) } else { @@ -184,7 +184,7 @@ pub fn local_used_after_expr(cx: &LateContext<'_>, local_id: HirId, after: &Expr let loop_start = get_enclosing_loop_or_multi_call_closure(cx, after).map(|e| e.hir_id); let mut past_expr = false; - for_each_expr_with_closures(cx, block, |e| { + for_each_expr(cx, block, |e| { if past_expr { if utils::path_to_local_id(e, local_id) { ControlFlow::Break(()) diff --git a/clippy_utils/src/visitors.rs b/clippy_utils/src/visitors.rs index 90b56297bb556..3a39e178515db 100644 --- a/clippy_utils/src/visitors.rs +++ b/clippy_utils/src/visitors.rs @@ -100,7 +100,7 @@ visitable_ref!(Stmt, visit_stmt); /// Calls the given function once for each expression contained. This does not enter any bodies or /// nested items. -pub fn for_each_expr<'tcx, B, C: Continue>( +pub fn for_each_expr_without_closures<'tcx, B, C: Continue>( node: impl Visitable<'tcx>, f: impl FnMut(&'tcx Expr<'tcx>) -> ControlFlow, ) -> Option { @@ -134,7 +134,7 @@ pub fn for_each_expr<'tcx, B, C: Continue>( /// Calls the given function once for each expression contained. This will enter bodies, but not /// nested items. -pub fn for_each_expr_with_closures<'tcx, B, C: Continue>( +pub fn for_each_expr<'tcx, B, C: Continue>( cx: &LateContext<'tcx>, node: impl Visitable<'tcx>, f: impl FnMut(&'tcx Expr<'tcx>) -> ControlFlow, @@ -181,7 +181,7 @@ pub fn for_each_expr_with_closures<'tcx, B, C: Continue>( /// returns `true` if expr contains match expr desugared from try fn contains_try(expr: &Expr<'_>) -> bool { - for_each_expr(expr, |e| { + for_each_expr_without_closures(expr, |e| { if matches!(e.kind, ExprKind::Match(_, _, hir::MatchSource::TryDesugar(_))) { ControlFlow::Break(()) } else { @@ -286,7 +286,7 @@ where /// Checks if the given resolved path is used in the given body. pub fn is_res_used(cx: &LateContext<'_>, res: Res, body: BodyId) -> bool { - for_each_expr_with_closures(cx, cx.tcx.hir().body(body).value, |e| { + for_each_expr(cx, cx.tcx.hir().body(body).value, |e| { if let ExprKind::Path(p) = &e.kind { if cx.qpath_res(p, e.hir_id) == res { return ControlFlow::Break(()); @@ -299,7 +299,7 @@ pub fn is_res_used(cx: &LateContext<'_>, res: Res, body: BodyId) -> bool { /// Checks if the given local is used. pub fn is_local_used<'tcx>(cx: &LateContext<'tcx>, visitable: impl Visitable<'tcx>, id: HirId) -> bool { - for_each_expr_with_closures(cx, visitable, |e| { + for_each_expr(cx, visitable, |e| { if path_to_local_id(e, id) { ControlFlow::Break(()) } else { @@ -757,7 +757,7 @@ pub fn for_each_local_assignment<'tcx, B>( } pub fn contains_break_or_continue(expr: &Expr<'_>) -> bool { - for_each_expr(expr, |e| { + for_each_expr_without_closures(expr, |e| { if matches!(e.kind, ExprKind::Break(..) | ExprKind::Continue(..)) { ControlFlow::Break(()) } else { @@ -776,7 +776,7 @@ pub fn local_used_once<'tcx>( ) -> Option<&'tcx Expr<'tcx>> { let mut expr = None; - let cf = for_each_expr_with_closures(cx, visitable, |e| { + let cf = for_each_expr(cx, visitable, |e| { if path_to_local_id(e, id) && expr.replace(e).is_some() { ControlFlow::Break(()) } else { diff --git a/declare_clippy_lint/Cargo.toml b/declare_clippy_lint/Cargo.toml index c8c734c3a7c9f..86d945c14a58a 100644 --- a/declare_clippy_lint/Cargo.toml +++ b/declare_clippy_lint/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "declare_clippy_lint" -version = "0.1.80" +version = "0.1.81" edition = "2021" publish = false diff --git a/lintcheck/README.md b/lintcheck/README.md index 37cc045380949..61b581ba0faec 100644 --- a/lintcheck/README.md +++ b/lintcheck/README.md @@ -1,6 +1,6 @@ ## `cargo lintcheck` -Runs clippy on a fixed set of crates read from +Runs Clippy on a fixed set of crates read from `lintcheck/lintcheck_crates.toml` and saves logs of the lint warnings into the repo. We can then check the diff and spot new or disappearing warnings. @@ -84,7 +84,7 @@ This lets us spot bad suggestions or false positives automatically in some cases > Note: Fix mode implies `--all-targets`, so it can fix as much code as it can. -Please note that the target dir should be cleaned afterwards since clippy will modify +Please note that the target dir should be cleaned afterwards since Clippy will modify the downloaded sources which can lead to unexpected results when running lintcheck again afterwards. ### Recursive mode diff --git a/rust-toolchain b/rust-toolchain index dd8b9ece773e7..842c2f3de0d10 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2024-05-30" +channel = "nightly-2024-06-13" components = ["cargo", "llvm-tools", "rust-src", "rust-std", "rustc", "rustc-dev", "rustfmt"] diff --git a/tests/ui-cargo/lint_groups_priority/fail/Cargo.stderr b/tests/ui-cargo/lint_groups_priority/fail/Cargo.stderr index 9177e99f8e6e6..4fe7f6f7a9edb 100644 --- a/tests/ui-cargo/lint_groups_priority/fail/Cargo.stderr +++ b/tests/ui-cargo/lint_groups_priority/fail/Cargo.stderr @@ -1,17 +1,18 @@ error: lint group `rust_2018_idioms` has the same priority (0) as a lint - --> Cargo.toml:7:1 - | -7 | rust_2018_idioms = "warn" - | ^^^^^^^^^^^^^^^^ ------ has an implicit priority of 0 -8 | bare_trait_objects = "allow" - | ------------------ has the same priority as this lint - | - = note: the order of the lints in the table is ignored by Cargo - = note: `#[deny(clippy::lint_groups_priority)]` on by default + --> Cargo.toml:7:1 + | +7 | rust_2018_idioms = "warn" + | ^^^^^^^^^^^^^^^^ ------ has an implicit priority of 0 +... +12 | unused_attributes = { level = "allow" } + | ----------------- has the same priority as this lint + | + = note: the order of the lints in the table is ignored by Cargo + = note: `#[deny(clippy::lint_groups_priority)]` on by default help: to have lints override the group set `rust_2018_idioms` to a lower priority - | -7 | rust_2018_idioms = { level = "warn", priority = -1 } - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + | +7 | rust_2018_idioms = { level = "warn", priority = -1 } + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: lint group `unused` has the same priority (0) as a lint --> Cargo.toml:10:1 @@ -29,45 +30,45 @@ help: to have lints override the group set `unused` to a lower priority | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: lint group `pedantic` has the same priority (-1) as a lint - --> Cargo.toml:19:1 + --> Cargo.toml:15:1 | -19 | pedantic = { level = "warn", priority = -1 } +15 | pedantic = { level = "warn", priority = -1 } | ^^^^^^^^ -20 | similar_names = { level = "allow", priority = -1 } +16 | similar_names = { level = "allow", priority = -1 } | ------------- has the same priority as this lint | = note: the order of the lints in the table is ignored by Cargo help: to have lints override the group set `pedantic` to a lower priority | -19 | pedantic = { level = "warn", priority = -2 } +15 | pedantic = { level = "warn", priority = -2 } | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: lint group `rust_2018_idioms` has the same priority (0) as a lint - --> Cargo.toml:23:1 + --> Cargo.toml:19:1 | -23 | rust_2018_idioms = "warn" +19 | rust_2018_idioms = "warn" | ^^^^^^^^^^^^^^^^ ------ has an implicit priority of 0 -24 | bare_trait_objects = "allow" +20 | bare_trait_objects = "allow" | ------------------ has the same priority as this lint | = note: the order of the lints in the table is ignored by Cargo help: to have lints override the group set `rust_2018_idioms` to a lower priority | -23 | rust_2018_idioms = { level = "warn", priority = -1 } +19 | rust_2018_idioms = { level = "warn", priority = -1 } | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: lint group `pedantic` has the same priority (0) as a lint - --> Cargo.toml:27:1 + --> Cargo.toml:23:1 | -27 | pedantic = "warn" +23 | pedantic = "warn" | ^^^^^^^^ ------ has an implicit priority of 0 -28 | similar_names = "allow" +24 | similar_names = "allow" | ------------- has the same priority as this lint | = note: the order of the lints in the table is ignored by Cargo help: to have lints override the group set `pedantic` to a lower priority | -27 | pedantic = { level = "warn", priority = -1 } +23 | pedantic = { level = "warn", priority = -1 } | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: could not compile `fail` (lib) due to 5 previous errors diff --git a/tests/ui-cargo/lint_groups_priority/fail/Cargo.toml b/tests/ui-cargo/lint_groups_priority/fail/Cargo.toml index e4d4af9cd234a..c87662f822e16 100644 --- a/tests/ui-cargo/lint_groups_priority/fail/Cargo.toml +++ b/tests/ui-cargo/lint_groups_priority/fail/Cargo.toml @@ -11,10 +11,6 @@ unused = { level = "deny" } unused_braces = { level = "allow", priority = 1 } unused_attributes = { level = "allow" } -# `warnings` is not a group so the order it is passed does not matter -warnings = "deny" -deprecated = "allow" - [lints.clippy] pedantic = { level = "warn", priority = -1 } similar_names = { level = "allow", priority = -1 } diff --git a/tests/ui-cargo/lint_groups_priority/pass/Cargo.toml b/tests/ui-cargo/lint_groups_priority/pass/Cargo.toml index e9fcf803d9369..979c915cf0c13 100644 --- a/tests/ui-cargo/lint_groups_priority/pass/Cargo.toml +++ b/tests/ui-cargo/lint_groups_priority/pass/Cargo.toml @@ -3,6 +3,13 @@ name = "pass" version = "0.1.0" publish = false +[lints.rust] +# Warnings does not conflict with any group or lint +warnings = "deny" +# Groups & lints at the same level do not conflict +rust_2018_idioms = "warn" +unsafe_code = "warn" + [lints.clippy] pedantic = { level = "warn", priority = -1 } style = { level = "warn", priority = 1 } diff --git a/tests/ui-toml/private-doc-errors/doc_lints.rs b/tests/ui-toml/private-doc-errors/doc_lints.rs index ae4c3f84c2966..79c8751468de2 100644 --- a/tests/ui-toml/private-doc-errors/doc_lints.rs +++ b/tests/ui-toml/private-doc-errors/doc_lints.rs @@ -47,7 +47,7 @@ pub mod __macro { pub struct T; impl T { pub unsafe fn f() {} - //~^ ERROR: unsafe function's docs miss `# Safety` section + //~^ ERROR: unsafe function's docs are missing a `# Safety` section } } diff --git a/tests/ui-toml/private-doc-errors/doc_lints.stderr b/tests/ui-toml/private-doc-errors/doc_lints.stderr index 65ec1a7bebbf1..a8ee09b9df78f 100644 --- a/tests/ui-toml/private-doc-errors/doc_lints.stderr +++ b/tests/ui-toml/private-doc-errors/doc_lints.stderr @@ -51,7 +51,7 @@ note: the lint level is defined here LL | clippy::missing_panics_doc | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: unsafe function's docs miss `# Safety` section +error: unsafe function's docs are missing a `# Safety` section --> tests/ui-toml/private-doc-errors/doc_lints.rs:49:9 | LL | pub unsafe fn f() {} diff --git a/tests/ui-toml/type_repetition_in_bounds/main.rs b/tests/ui-toml/type_repetition_in_bounds/main.rs index 2454c10382df7..7f93d2071c9db 100644 --- a/tests/ui-toml/type_repetition_in_bounds/main.rs +++ b/tests/ui-toml/type_repetition_in_bounds/main.rs @@ -1,3 +1,4 @@ +#![allow(clippy::needless_maybe_sized)] #![warn(clippy::type_repetition_in_bounds)] fn f() diff --git a/tests/ui-toml/type_repetition_in_bounds/main.stderr b/tests/ui-toml/type_repetition_in_bounds/main.stderr index 6005f76b94be8..c5102c39d1cff 100644 --- a/tests/ui-toml/type_repetition_in_bounds/main.stderr +++ b/tests/ui-toml/type_repetition_in_bounds/main.stderr @@ -1,5 +1,5 @@ error: this type has already been used as a bound predicate - --> tests/ui-toml/type_repetition_in_bounds/main.rs:13:5 + --> tests/ui-toml/type_repetition_in_bounds/main.rs:14:5 | LL | T: Unpin + PartialEq, | ^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/author.stdout b/tests/ui/author.stdout index d448db097a7e7..eed704e82fe1b 100644 --- a/tests/ui/author.stdout +++ b/tests/ui/author.stdout @@ -1,4 +1,4 @@ -if let StmtKind::Local(local) = stmt.kind +if let StmtKind::Let(local) = stmt.kind && let Some(init) = local.init && let ExprKind::Cast(expr, cast_ty) = init.kind && let TyKind::Path(ref qpath) = cast_ty.kind diff --git a/tests/ui/author/blocks.stdout b/tests/ui/author/blocks.stdout index 80b928dd6cb56..6bf48d5ba4ef8 100644 --- a/tests/ui/author/blocks.stdout +++ b/tests/ui/author/blocks.stdout @@ -1,12 +1,12 @@ if let ExprKind::Block(block, None) = expr.kind && block.stmts.len() == 3 - && let StmtKind::Local(local) = block.stmts[0].kind + && let StmtKind::Let(local) = block.stmts[0].kind && let Some(init) = local.init && let ExprKind::Lit(ref lit) = init.kind && let LitKind::Int(42, LitIntType::Signed(IntTy::I32)) = lit.node && let PatKind::Binding(BindingMode::NONE, _, name, None) = local.pat.kind && name.as_str() == "x" - && let StmtKind::Local(local1) = block.stmts[1].kind + && let StmtKind::Let(local1) = block.stmts[1].kind && let Some(init1) = local1.init && let ExprKind::Lit(ref lit1) = init1.kind && let LitKind::Float(_, LitFloatType::Suffixed(FloatTy::F32)) = lit1.node @@ -22,7 +22,7 @@ if let ExprKind::Block(block, None) = expr.kind } if let ExprKind::Block(block, None) = expr.kind && block.stmts.len() == 1 - && let StmtKind::Local(local) = block.stmts[0].kind + && let StmtKind::Let(local) = block.stmts[0].kind && let Some(init) = local.init && let ExprKind::Call(func, args) = init.kind && let ExprKind::Path(ref qpath) = func.kind diff --git a/tests/ui/author/call.stdout b/tests/ui/author/call.stdout index f040f6330a64d..59d4da490fe54 100644 --- a/tests/ui/author/call.stdout +++ b/tests/ui/author/call.stdout @@ -1,4 +1,4 @@ -if let StmtKind::Local(local) = stmt.kind +if let StmtKind::Let(local) = stmt.kind && let Some(init) = local.init && let ExprKind::Call(func, args) = init.kind && let ExprKind::Path(ref qpath) = func.kind diff --git a/tests/ui/author/if.stdout b/tests/ui/author/if.stdout index 5d79618820d80..a85dcddd3315f 100644 --- a/tests/ui/author/if.stdout +++ b/tests/ui/author/if.stdout @@ -1,4 +1,4 @@ -if let StmtKind::Local(local) = stmt.kind +if let StmtKind::Let(local) = stmt.kind && let Some(init) = local.init && let ExprKind::If(cond, then, Some(else_expr)) = init.kind && let ExprKind::DropTemps(expr) = cond.kind diff --git a/tests/ui/author/issue_3849.stdout b/tests/ui/author/issue_3849.stdout index 32a3127b85a3e..a5a8c0304ee40 100644 --- a/tests/ui/author/issue_3849.stdout +++ b/tests/ui/author/issue_3849.stdout @@ -1,4 +1,4 @@ -if let StmtKind::Local(local) = stmt.kind +if let StmtKind::Let(local) = stmt.kind && let Some(init) = local.init && let ExprKind::Call(func, args) = init.kind && let ExprKind::Path(ref qpath) = func.kind diff --git a/tests/ui/author/loop.stdout b/tests/ui/author/loop.stdout index 631105a2238de..609d24910610c 100644 --- a/tests/ui/author/loop.stdout +++ b/tests/ui/author/loop.stdout @@ -12,7 +12,7 @@ if let Some(higher::ForLoop { pat: pat, arg: arg, body: body, .. }) = higher::Fo && let LitKind::Int(10, LitIntType::Unsuffixed) = lit1.node && let ExprKind::Block(block, None) = body.kind && block.stmts.len() == 1 - && let StmtKind::Local(local) = block.stmts[0].kind + && let StmtKind::Let(local) = block.stmts[0].kind && let Some(init) = local.init && let ExprKind::Path(ref qpath1) = init.kind && match_qpath(qpath1, &["y"]) diff --git a/tests/ui/author/macro_in_closure.stdout b/tests/ui/author/macro_in_closure.stdout index b90c830e03079..66caf382d897b 100644 --- a/tests/ui/author/macro_in_closure.stdout +++ b/tests/ui/author/macro_in_closure.stdout @@ -1,4 +1,4 @@ -if let StmtKind::Local(local) = stmt.kind +if let StmtKind::Let(local) = stmt.kind && let Some(init) = local.init && let ExprKind::Closure { capture_clause: CaptureBy::Ref, fn_decl: fn_decl, body: body_id, closure_kind: ClosureKind::Closure, .. } = init.kind && let FnRetTy::DefaultReturn(_) = fn_decl.output diff --git a/tests/ui/author/matches.stdout b/tests/ui/author/matches.stdout index 30e4a9b2560ac..91b3b6f6877eb 100644 --- a/tests/ui/author/matches.stdout +++ b/tests/ui/author/matches.stdout @@ -1,4 +1,4 @@ -if let StmtKind::Local(local) = stmt.kind +if let StmtKind::Let(local) = stmt.kind && let Some(init) = local.init && let ExprKind::Match(scrutinee, arms, MatchSource::Normal) = init.kind && let ExprKind::Lit(ref lit) = scrutinee.kind @@ -16,7 +16,7 @@ if let StmtKind::Local(local) = stmt.kind && arms[1].guard.is_none() && let ExprKind::Block(block, None) = arms[1].body.kind && block.stmts.len() == 1 - && let StmtKind::Local(local1) = block.stmts[0].kind + && let StmtKind::Let(local1) = block.stmts[0].kind && let Some(init1) = local1.init && let ExprKind::Lit(ref lit4) = init1.kind && let LitKind::Int(3, LitIntType::Unsuffixed) = lit4.node diff --git a/tests/ui/auxiliary/proc_macro_derive.rs b/tests/ui/auxiliary/proc_macro_derive.rs index 79a95d775b11e..4c3df47226909 100644 --- a/tests/ui/auxiliary/proc_macro_derive.rs +++ b/tests/ui/auxiliary/proc_macro_derive.rs @@ -169,3 +169,16 @@ pub fn derive_ignored_unit_pattern(_: TokenStream) -> TokenStream { } } } + +#[proc_macro_derive(NonCanonicalClone)] +pub fn non_canonical_clone_derive(_: TokenStream) -> TokenStream { + quote! { + struct NonCanonicalClone; + impl Clone for NonCanonicalClone { + fn clone(&self) -> Self { + todo!() + } + } + impl Copy for NonCanonicalClone {} + } +} diff --git a/tests/ui/auxiliary/proc_macros.rs b/tests/ui/auxiliary/proc_macros.rs index 6e6919cd295c4..ed7412f7c4076 100644 --- a/tests/ui/auxiliary/proc_macros.rs +++ b/tests/ui/auxiliary/proc_macros.rs @@ -58,7 +58,7 @@ fn group_with_span(delimiter: Delimiter, stream: TokenStream, span: Span) -> Gro const ESCAPE_CHAR: char = '$'; /// Takes a single token followed by a sequence of tokens. Returns the sequence of tokens with their -/// span set to that of the first token. Tokens may be escaped with either `#ident` or `#(tokens)`. +/// span set to that of the first token. Tokens may be escaped with either `$ident` or `$(tokens)`. #[proc_macro] pub fn with_span(input: TokenStream) -> TokenStream { let mut iter = input.into_iter(); @@ -72,7 +72,7 @@ pub fn with_span(input: TokenStream) -> TokenStream { } /// Takes a sequence of tokens and return the tokens with the span set such that they appear to be -/// from an external macro. Tokens may be escaped with either `#ident` or `#(tokens)`. +/// from an external macro. Tokens may be escaped with either `$ident` or `$(tokens)`. #[proc_macro] pub fn external(input: TokenStream) -> TokenStream { let mut res = TokenStream::new(); @@ -84,7 +84,7 @@ pub fn external(input: TokenStream) -> TokenStream { } /// Copies all the tokens, replacing all their spans with the given span. Tokens can be escaped -/// either by `#ident` or `#(tokens)`. +/// either by `$ident` or `$(tokens)`. fn write_with_span(s: Span, mut input: IntoIter, out: &mut TokenStream) -> Result<()> { while let Some(tt) = input.next() { match tt { diff --git a/tests/ui/blocks_in_conditions.fixed b/tests/ui/blocks_in_conditions.fixed index a2da5f9c5fb98..af8e65270d091 100644 --- a/tests/ui/blocks_in_conditions.fixed +++ b/tests/ui/blocks_in_conditions.fixed @@ -117,4 +117,17 @@ mod issue_12016 { } } +fn in_closure() { + let v = vec![1, 2, 3]; + if v.into_iter() + .filter(|x| { + let y = x + 1; + y > 3 + }) + .any(|x| x == 5) + { + println!("contains 4!"); + } +} + fn main() {} diff --git a/tests/ui/blocks_in_conditions.rs b/tests/ui/blocks_in_conditions.rs index 608ca4cf267f6..6adae951a2901 100644 --- a/tests/ui/blocks_in_conditions.rs +++ b/tests/ui/blocks_in_conditions.rs @@ -117,4 +117,17 @@ mod issue_12016 { } } +fn in_closure() { + let v = vec![1, 2, 3]; + if v.into_iter() + .filter(|x| { + let y = x + 1; + y > 3 + }) + .any(|x| x == 5) + { + println!("contains 4!"); + } +} + fn main() {} diff --git a/tests/ui/blocks_in_conditions_closure.rs b/tests/ui/blocks_in_conditions_closure.rs deleted file mode 100644 index db31e4ae1a9a1..0000000000000 --- a/tests/ui/blocks_in_conditions_closure.rs +++ /dev/null @@ -1,89 +0,0 @@ -#![warn(clippy::blocks_in_conditions)] -#![allow( - unused, - clippy::let_and_return, - clippy::needless_if, - clippy::unnecessary_literal_unwrap -)] - -fn predicate bool, T>(pfn: F, val: T) -> bool { - pfn(val) -} - -fn pred_test() { - let v = 3; - let sky = "blue"; - // This is a sneaky case, where the block isn't directly in the condition, - // but is actually inside a closure that the condition is using. - // The same principle applies -- add some extra expressions to make sure - // linter isn't confused by them. - if v == 3 - && sky == "blue" - && predicate( - |x| { - //~^ ERROR: in an `if` condition, avoid complex blocks or closures with blocks - //~| NOTE: `-D clippy::blocks-in-conditions` implied by `-D warnings` - let target = 3; - x == target - }, - v, - ) - {} - - if predicate( - |x| { - //~^ ERROR: in an `if` condition, avoid complex blocks or closures with blocks; in - let target = 3; - x == target - }, - v, - ) {} -} - -fn closure_without_block() { - if predicate(|x| x == 3, 6) {} -} - -fn macro_in_closure() { - let option = Some(true); - - if option.unwrap_or_else(|| unimplemented!()) { - unimplemented!() - } -} - -fn closure(_: impl FnMut()) -> bool { - true -} - -fn function_with_empty_closure() { - if closure(|| {}) {} -} - -// issue #11814 -fn match_with_pred() { - let v = 3; - match Some(predicate( - |x| { - //~^ ERROR: in a `match` scrutinee, avoid complex blocks or closures with blocks - let target = 3; - x == target - }, - v, - )) { - Some(true) => 1, - Some(false) => 2, - None => 3, - }; -} - -#[rustfmt::skip] -fn main() { - let mut range = 0..10; - range.all(|i| {i < 10} ); - - let v = vec![1, 2, 3]; - if v.into_iter().any(|x| {x == 4}) { - println!("contains 4!"); - } -} diff --git a/tests/ui/blocks_in_conditions_closure.stderr b/tests/ui/blocks_in_conditions_closure.stderr deleted file mode 100644 index 2faae680ec021..0000000000000 --- a/tests/ui/blocks_in_conditions_closure.stderr +++ /dev/null @@ -1,39 +0,0 @@ -error: in an `if` condition, avoid complex blocks or closures with blocks; instead, move the block or closure higher and bind it with a `let` - --> tests/ui/blocks_in_conditions_closure.rs:23:17 - | -LL | |x| { - | _________________^ -LL | | -LL | | -LL | | let target = 3; -LL | | x == target -LL | | }, - | |_____________^ - | - = note: `-D clippy::blocks-in-conditions` implied by `-D warnings` - = help: to override `-D warnings` add `#[allow(clippy::blocks_in_conditions)]` - -error: in an `if` condition, avoid complex blocks or closures with blocks; instead, move the block or closure higher and bind it with a `let` - --> tests/ui/blocks_in_conditions_closure.rs:34:13 - | -LL | |x| { - | _____________^ -LL | | -LL | | let target = 3; -LL | | x == target -LL | | }, - | |_________^ - -error: in a `match` scrutinee, avoid complex blocks or closures with blocks; instead, move the block or closure higher and bind it with a `let` - --> tests/ui/blocks_in_conditions_closure.rs:67:13 - | -LL | |x| { - | _____________^ -LL | | -LL | | let target = 3; -LL | | x == target -LL | | }, - | |_________^ - -error: aborting due to 3 previous errors - diff --git a/tests/ui/cfg_features.fixed b/tests/ui/cfg_features.fixed deleted file mode 100644 index 0fe38f169f9c8..0000000000000 --- a/tests/ui/cfg_features.fixed +++ /dev/null @@ -1,29 +0,0 @@ -#![warn(clippy::maybe_misused_cfg)] - -fn main() { - #[cfg(feature = "not-really-a-feature")] - //~^ ERROR: 'feature' may be misspelled as 'features' - //~| NOTE: `-D clippy::maybe-misused-cfg` implied by `-D warnings` - let _ = 1 + 2; - - #[cfg(all(feature = "right", feature = "wrong"))] - //~^ ERROR: 'feature' may be misspelled as 'features' - let _ = 1 + 2; - - #[cfg(all(feature = "wrong1", any(feature = "right", feature = "wrong2", feature, features)))] - //~^ ERROR: 'feature' may be misspelled as 'features' - //~| ERROR: 'feature' may be misspelled as 'features' - let _ = 1 + 2; - - #[cfg(test)] - //~^ ERROR: 'test' may be misspelled as 'tests' - let _ = 2; - #[cfg(test)] - //~^ ERROR: 'test' may be misspelled as 'Test' - let _ = 2; - - #[cfg(all(test, test))] - //~^ ERROR: 'test' may be misspelled as 'tests' - //~| ERROR: 'test' may be misspelled as 'Test' - let _ = 2; -} diff --git a/tests/ui/cfg_features.rs b/tests/ui/cfg_features.rs deleted file mode 100644 index 9c0db035eac41..0000000000000 --- a/tests/ui/cfg_features.rs +++ /dev/null @@ -1,29 +0,0 @@ -#![warn(clippy::maybe_misused_cfg)] - -fn main() { - #[cfg(features = "not-really-a-feature")] - //~^ ERROR: 'feature' may be misspelled as 'features' - //~| NOTE: `-D clippy::maybe-misused-cfg` implied by `-D warnings` - let _ = 1 + 2; - - #[cfg(all(feature = "right", features = "wrong"))] - //~^ ERROR: 'feature' may be misspelled as 'features' - let _ = 1 + 2; - - #[cfg(all(features = "wrong1", any(feature = "right", features = "wrong2", feature, features)))] - //~^ ERROR: 'feature' may be misspelled as 'features' - //~| ERROR: 'feature' may be misspelled as 'features' - let _ = 1 + 2; - - #[cfg(tests)] - //~^ ERROR: 'test' may be misspelled as 'tests' - let _ = 2; - #[cfg(Test)] - //~^ ERROR: 'test' may be misspelled as 'Test' - let _ = 2; - - #[cfg(all(tests, Test))] - //~^ ERROR: 'test' may be misspelled as 'tests' - //~| ERROR: 'test' may be misspelled as 'Test' - let _ = 2; -} diff --git a/tests/ui/cfg_features.stderr b/tests/ui/cfg_features.stderr deleted file mode 100644 index d576271f1a291..0000000000000 --- a/tests/ui/cfg_features.stderr +++ /dev/null @@ -1,53 +0,0 @@ -error: 'feature' may be misspelled as 'features' - --> tests/ui/cfg_features.rs:4:11 - | -LL | #[cfg(features = "not-really-a-feature")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: did you mean: `feature = "not-really-a-feature"` - | - = note: `-D clippy::maybe-misused-cfg` implied by `-D warnings` - = help: to override `-D warnings` add `#[allow(clippy::maybe_misused_cfg)]` - -error: 'feature' may be misspelled as 'features' - --> tests/ui/cfg_features.rs:9:34 - | -LL | #[cfg(all(feature = "right", features = "wrong"))] - | ^^^^^^^^^^^^^^^^^^ help: did you mean: `feature = "wrong"` - -error: 'feature' may be misspelled as 'features' - --> tests/ui/cfg_features.rs:13:15 - | -LL | #[cfg(all(features = "wrong1", any(feature = "right", features = "wrong2", feature, features)))] - | ^^^^^^^^^^^^^^^^^^^ help: did you mean: `feature = "wrong1"` - -error: 'feature' may be misspelled as 'features' - --> tests/ui/cfg_features.rs:13:59 - | -LL | #[cfg(all(features = "wrong1", any(feature = "right", features = "wrong2", feature, features)))] - | ^^^^^^^^^^^^^^^^^^^ help: did you mean: `feature = "wrong2"` - -error: 'test' may be misspelled as 'tests' - --> tests/ui/cfg_features.rs:18:11 - | -LL | #[cfg(tests)] - | ^^^^^ help: did you mean: `test` - -error: 'test' may be misspelled as 'Test' - --> tests/ui/cfg_features.rs:21:11 - | -LL | #[cfg(Test)] - | ^^^^ help: did you mean: `test` - -error: 'test' may be misspelled as 'tests' - --> tests/ui/cfg_features.rs:25:15 - | -LL | #[cfg(all(tests, Test))] - | ^^^^^ help: did you mean: `test` - -error: 'test' may be misspelled as 'Test' - --> tests/ui/cfg_features.rs:25:22 - | -LL | #[cfg(all(tests, Test))] - | ^^^^ help: did you mean: `test` - -error: aborting due to 8 previous errors - diff --git a/tests/ui/crashes/ice-9445.rs b/tests/ui/crashes/ice-9445.rs index b6afbd33c79fb..c67b22f6f8c47 100644 --- a/tests/ui/crashes/ice-9445.rs +++ b/tests/ui/crashes/ice-9445.rs @@ -1,5 +1,3 @@ const UNINIT: core::mem::MaybeUninit> = core::mem::MaybeUninit::uninit(); -//~^ ERROR: a `const` item should never be interior mutable -//~| NOTE: `-D clippy::declare-interior-mutable-const` implied by `-D warnings` fn main() {} diff --git a/tests/ui/crashes/ice-9445.stderr b/tests/ui/crashes/ice-9445.stderr index d6957e9549d69..76689cd6f5c22 100644 --- a/tests/ui/crashes/ice-9445.stderr +++ b/tests/ui/crashes/ice-9445.stderr @@ -1,11 +1,10 @@ -error: a `const` item should never be interior mutable +error: a `const` item should not be interior mutable --> tests/ui/crashes/ice-9445.rs:1:1 | LL | const UNINIT: core::mem::MaybeUninit> = core::mem::MaybeUninit::uninit(); - | -----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | - | make this a static item (maybe with lazy_static) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | + = help: consider making this `Sync` so that it can go in a static item or using a `thread_local` = note: `-D clippy::declare-interior-mutable-const` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::declare_interior_mutable_const)]` diff --git a/tests/ui/crashes/mut_mut_macro.rs b/tests/ui/crashes/mut_mut_macro.rs deleted file mode 100644 index 92821b6ecbbab..0000000000000 --- a/tests/ui/crashes/mut_mut_macro.rs +++ /dev/null @@ -1,33 +0,0 @@ -#![deny(clippy::mut_mut, clippy::zero_ptr)] -#![allow(dead_code)] - -// FIXME: compiletest + extern crates doesn't work together. To make this test work, it would need -// the following three lines and the lazy_static crate. -// -// #[macro_use] -// extern crate lazy_static; -// use std::collections::HashMap; - -/// ensure that we don't suggest `is_null` inside constants -/// FIXME: once const fn is stable, suggest these functions again in constants - -const BAA: *const i32 = 0 as *const i32; -static mut BAR: *const i32 = BAA; -static mut FOO: *const i32 = 0 as *const i32; - -#[allow(unused_variables, unused_mut)] -fn main() { - /* - lazy_static! { - static ref MUT_MAP : HashMap = { - let mut m = HashMap::new(); - m.insert(0, "zero"); - m - }; - static ref MUT_COUNT : usize = MUT_MAP.len(); - } - assert_eq!(*MUT_COUNT, 1); - */ - // FIXME: don't lint in array length, requires `check_body` - //let _ = [""; (42.0 < f32::NAN) as usize]; -} diff --git a/tests/ui/declare_interior_mutable_const/enums.stderr b/tests/ui/declare_interior_mutable_const/enums.stderr index 6c0dce6b5eafb..22329172c3af0 100644 --- a/tests/ui/declare_interior_mutable_const/enums.stderr +++ b/tests/ui/declare_interior_mutable_const/enums.stderr @@ -1,87 +1,84 @@ -error: a `const` item should never be interior mutable +error: a `const` item should not be interior mutable --> tests/ui/declare_interior_mutable_const/enums.rs:12:1 | LL | const UNFROZEN_VARIANT: OptionalCell = OptionalCell::Unfrozen(Cell::new(true)); - | -----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | - | make this a static item (maybe with lazy_static) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | + = help: consider making this `Sync` so that it can go in a static item or using a `thread_local` = note: `-D clippy::declare-interior-mutable-const` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::declare_interior_mutable_const)]` -error: a `const` item should never be interior mutable +error: a `const` item should not be interior mutable --> tests/ui/declare_interior_mutable_const/enums.rs:23:1 | LL | const UNFROZEN_VARIANT_FROM_FN: OptionalCell = unfrozen_variant(); - | -----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | - | make this a static item (maybe with lazy_static) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider making this `Sync` so that it can go in a static item or using a `thread_local` -error: a `const` item should never be interior mutable +error: a `const` item should not be interior mutable --> tests/ui/declare_interior_mutable_const/enums.rs:45:1 | -LL | const NESTED_UNFROZEN_VARIANT: NestedOutermost = NestedOutermost { - | ^---- - | | - | _make this a static item (maybe with lazy_static) - | | +LL | / const NESTED_UNFROZEN_VARIANT: NestedOutermost = NestedOutermost { LL | | LL | | outer: NestedOuter::NestedInner(NestedInner { LL | | inner: NestedInnermost::Unfrozen(AtomicUsize::new(2)), LL | | }), LL | | }; | |__^ + | + = help: consider making this a static item -error: a `const` item should never be interior mutable +error: a `const` item should not be interior mutable --> tests/ui/declare_interior_mutable_const/enums.rs:60:5 | LL | const TO_BE_UNFROZEN_VARIANT: OptionalCell; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: a `const` item should never be interior mutable +error: a `const` item should not be interior mutable --> tests/ui/declare_interior_mutable_const/enums.rs:61:5 | LL | const TO_BE_FROZEN_VARIANT: OptionalCell; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: a `const` item should never be interior mutable +error: a `const` item should not be interior mutable --> tests/ui/declare_interior_mutable_const/enums.rs:64:5 | LL | const DEFAULTED_ON_UNFROZEN_VARIANT: OptionalCell = OptionalCell::Unfrozen(Cell::new(false)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: a `const` item should never be interior mutable +error: a `const` item should not be interior mutable --> tests/ui/declare_interior_mutable_const/enums.rs:90:5 | LL | const TO_BE_UNFROZEN_VARIANT: Option = Some(Self::ToBeUnfrozen::new(4)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: a `const` item should never be interior mutable +error: a `const` item should not be interior mutable --> tests/ui/declare_interior_mutable_const/enums.rs:102:5 | LL | const UNFROZEN_VARIANT: BothOfCellAndGeneric = BothOfCellAndGeneric::Unfrozen(Cell::new(std::ptr::null())); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: a `const` item should never be interior mutable +error: a `const` item should not be interior mutable --> tests/ui/declare_interior_mutable_const/enums.rs:105:5 | LL | const GENERIC_VARIANT: BothOfCellAndGeneric = BothOfCellAndGeneric::Generic(std::ptr::null()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: a `const` item should never be interior mutable +error: a `const` item should not be interior mutable --> tests/ui/declare_interior_mutable_const/enums.rs:111:5 | LL | const NO_ENUM: Cell<*const T> = Cell::new(std::ptr::null()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: a `const` item should never be interior mutable +error: a `const` item should not be interior mutable --> tests/ui/declare_interior_mutable_const/enums.rs:118:5 | LL | / const UNFROZEN_VARIANT: BothOfCellAndGeneric = LL | | BothOfCellAndGeneric::Unfrozen(Cell::new(std::ptr::null())); | |____________________________________________________________________^ -error: a `const` item should never be interior mutable +error: a `const` item should not be interior mutable --> tests/ui/declare_interior_mutable_const/enums.rs:120:5 | LL | const GENERIC_VARIANT: BothOfCellAndGeneric = BothOfCellAndGeneric::Generic(std::ptr::null()); diff --git a/tests/ui/declare_interior_mutable_const/others.stderr b/tests/ui/declare_interior_mutable_const/others.stderr index 9dba0c952214b..1f2b9561ce509 100644 --- a/tests/ui/declare_interior_mutable_const/others.stderr +++ b/tests/ui/declare_interior_mutable_const/others.stderr @@ -1,31 +1,30 @@ -error: a `const` item should never be interior mutable +error: a `const` item should not be interior mutable --> tests/ui/declare_interior_mutable_const/others.rs:9:1 | LL | const ATOMIC: AtomicUsize = AtomicUsize::new(5); - | -----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | - | make this a static item (maybe with lazy_static) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | + = help: consider making this a static item = note: `-D clippy::declare-interior-mutable-const` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::declare_interior_mutable_const)]` -error: a `const` item should never be interior mutable +error: a `const` item should not be interior mutable --> tests/ui/declare_interior_mutable_const/others.rs:10:1 | LL | const CELL: Cell = Cell::new(6); - | -----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | - | make this a static item (maybe with lazy_static) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider making this `Sync` so that it can go in a static item or using a `thread_local` -error: a `const` item should never be interior mutable +error: a `const` item should not be interior mutable --> tests/ui/declare_interior_mutable_const/others.rs:11:1 | LL | const ATOMIC_TUPLE: ([AtomicUsize; 1], Vec, u8) = ([ATOMIC], Vec::new(), 7); - | -----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | - | make this a static item (maybe with lazy_static) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider making this a static item -error: a `const` item should never be interior mutable +error: a `const` item should not be interior mutable --> tests/ui/declare_interior_mutable_const/others.rs:16:9 | LL | const $name: $ty = $e; @@ -36,7 +35,7 @@ LL | declare_const!(_ONCE: Once = Once::new()); | = note: this error originates in the macro `declare_const` (in Nightly builds, run with -Z macro-backtrace for more info) -error: a `const` item should never be interior mutable +error: a `const` item should not be interior mutable --> tests/ui/declare_interior_mutable_const/others.rs:44:13 | LL | const _BAZ: Cell = Cell::new(0); diff --git a/tests/ui/declare_interior_mutable_const/traits.stderr b/tests/ui/declare_interior_mutable_const/traits.stderr index 1d1e9e2002fa6..4a793d985e5ec 100644 --- a/tests/ui/declare_interior_mutable_const/traits.stderr +++ b/tests/ui/declare_interior_mutable_const/traits.stderr @@ -1,4 +1,4 @@ -error: a `const` item should never be interior mutable +error: a `const` item should not be interior mutable --> tests/ui/declare_interior_mutable_const/traits.rs:16:5 | LL | const ATOMIC: AtomicUsize; @@ -7,7 +7,7 @@ LL | const ATOMIC: AtomicUsize; = note: `-D clippy::declare-interior-mutable-const` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::declare_interior_mutable_const)]` -error: a `const` item should never be interior mutable +error: a `const` item should not be interior mutable --> tests/ui/declare_interior_mutable_const/traits.rs:9:9 | LL | const $name: $ty = $e; @@ -18,67 +18,67 @@ LL | declare_const!(ANOTHER_ATOMIC: AtomicUsize = Self::ATOMIC); | = note: this error originates in the macro `declare_const` (in Nightly builds, run with -Z macro-backtrace for more info) -error: a `const` item should never be interior mutable +error: a `const` item should not be interior mutable --> tests/ui/declare_interior_mutable_const/traits.rs:44:5 | LL | const TO_BE_CONCRETE: AtomicUsize = AtomicUsize::new(11); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: a `const` item should never be interior mutable +error: a `const` item should not be interior mutable --> tests/ui/declare_interior_mutable_const/traits.rs:69:5 | LL | const TO_BE_UNFROZEN: Self::ToBeUnfrozen = AtomicUsize::new(13); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: a `const` item should never be interior mutable +error: a `const` item should not be interior mutable --> tests/ui/declare_interior_mutable_const/traits.rs:70:5 | LL | const WRAPPED_TO_BE_UNFROZEN: Wrapper = Wrapper(AtomicUsize::new(14)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: a `const` item should never be interior mutable +error: a `const` item should not be interior mutable --> tests/ui/declare_interior_mutable_const/traits.rs:89:5 | LL | const BOUNDED: T::ToBeBounded; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: a `const` item should never be interior mutable +error: a `const` item should not be interior mutable --> tests/ui/declare_interior_mutable_const/traits.rs:117:5 | LL | const SELF: Self = AtomicUsize::new(17); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: a `const` item should never be interior mutable +error: a `const` item should not be interior mutable --> tests/ui/declare_interior_mutable_const/traits.rs:118:5 | LL | const WRAPPED_SELF: Option = Some(AtomicUsize::new(21)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: a `const` item should never be interior mutable +error: a `const` item should not be interior mutable --> tests/ui/declare_interior_mutable_const/traits.rs:124:5 | LL | const DIRECT: Cell; | ^^^^^^^^^^^^^^^^^^^^^^ -error: a `const` item should never be interior mutable +error: a `const` item should not be interior mutable --> tests/ui/declare_interior_mutable_const/traits.rs:125:5 | LL | const INDIRECT: Cell<*const T>; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: a `const` item should never be interior mutable +error: a `const` item should not be interior mutable --> tests/ui/declare_interior_mutable_const/traits.rs:129:5 | LL | const DIRECT: Cell = Cell::new(T::DEFAULT); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: a `const` item should never be interior mutable +error: a `const` item should not be interior mutable --> tests/ui/declare_interior_mutable_const/traits.rs:141:5 | LL | const ATOMIC: AtomicUsize = AtomicUsize::new(18); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: a `const` item should never be interior mutable +error: a `const` item should not be interior mutable --> tests/ui/declare_interior_mutable_const/traits.rs:147:5 | LL | const BOUNDED_ASSOC_TYPE: T::ToBeBounded = AtomicUsize::new(19); diff --git a/tests/ui/deprecated.rs b/tests/ui/deprecated.rs index 07270bd76362a..d3c34fb371674 100644 --- a/tests/ui/deprecated.rs +++ b/tests/ui/deprecated.rs @@ -18,5 +18,7 @@ #![warn(clippy::filter_map)] #![warn(clippy::pub_enum_variant_names)] #![warn(clippy::wrong_pub_self_convention)] +#![warn(clippy::maybe_misused_cfg)] +#![warn(clippy::mismatched_target_os)] fn main() {} diff --git a/tests/ui/deprecated.stderr b/tests/ui/deprecated.stderr index a9cf04bea5257..49b90c70c06ef 100644 --- a/tests/ui/deprecated.stderr +++ b/tests/ui/deprecated.stderr @@ -97,5 +97,17 @@ error: lint `clippy::wrong_pub_self_convention` has been removed: set the `avoid LL | #![warn(clippy::wrong_pub_self_convention)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 16 previous errors +error: lint `clippy::maybe_misused_cfg` has been removed: this lint has been replaced by `unexpected_cfgs` + --> tests/ui/deprecated.rs:21:9 + | +LL | #![warn(clippy::maybe_misused_cfg)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: lint `clippy::mismatched_target_os` has been removed: this lint has been replaced by `unexpected_cfgs` + --> tests/ui/deprecated.rs:22:9 + | +LL | #![warn(clippy::mismatched_target_os)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 18 previous errors diff --git a/tests/ui/deref_addrof.fixed b/tests/ui/deref_addrof.fixed index aa1cf19b76f93..b6278c6ca8a52 100644 --- a/tests/ui/deref_addrof.fixed +++ b/tests/ui/deref_addrof.fixed @@ -43,6 +43,10 @@ fn main() { let b = *aref; let _ = unsafe { *core::ptr::addr_of!(a) }; + + let _repeat = [0; 64]; + // do NOT lint for array as sematic differences with/out `*&`. + let _arr = *&[0, 1, 2, 3, 4]; } #[derive(Copy, Clone)] diff --git a/tests/ui/deref_addrof.rs b/tests/ui/deref_addrof.rs index 38796aef390e3..572b0fdb10273 100644 --- a/tests/ui/deref_addrof.rs +++ b/tests/ui/deref_addrof.rs @@ -43,6 +43,10 @@ fn main() { let b = **&aref; let _ = unsafe { *core::ptr::addr_of!(a) }; + + let _repeat = *&[0; 64]; + // do NOT lint for array as sematic differences with/out `*&`. + let _arr = *&[0, 1, 2, 3, 4]; } #[derive(Copy, Clone)] diff --git a/tests/ui/deref_addrof.stderr b/tests/ui/deref_addrof.stderr index 5e3cb417aa0e1..20069f746c81c 100644 --- a/tests/ui/deref_addrof.stderr +++ b/tests/ui/deref_addrof.stderr @@ -50,7 +50,13 @@ LL | let b = **&aref; | ^^^^^^ help: try: `aref` error: immediately dereferencing a reference - --> tests/ui/deref_addrof.rs:53:17 + --> tests/ui/deref_addrof.rs:47:19 + | +LL | let _repeat = *&[0; 64]; + | ^^^^^^^^^ help: try: `[0; 64]` + +error: immediately dereferencing a reference + --> tests/ui/deref_addrof.rs:57:17 | LL | inline!(*& $(@expr self)) | ^^^^^^^^^^^^^^^^ help: try: `$(@expr self)` @@ -58,12 +64,12 @@ LL | inline!(*& $(@expr self)) = note: this error originates in the macro `__inline_mac_impl` (in Nightly builds, run with -Z macro-backtrace for more info) error: immediately dereferencing a reference - --> tests/ui/deref_addrof.rs:57:17 + --> tests/ui/deref_addrof.rs:61:17 | LL | inline!(*&mut $(@expr self)) | ^^^^^^^^^^^^^^^^^^^ help: try: `$(@expr self)` | = note: this error originates in the macro `__inline_mac_impl` (in Nightly builds, run with -Z macro-backtrace for more info) -error: aborting due to 10 previous errors +error: aborting due to 11 previous errors diff --git a/tests/ui/doc_unsafe.stderr b/tests/ui/doc_unsafe.stderr index 4fcbe716951f6..929afbceb879d 100644 --- a/tests/ui/doc_unsafe.stderr +++ b/tests/ui/doc_unsafe.stderr @@ -1,4 +1,4 @@ -error: unsafe function's docs miss `# Safety` section +error: unsafe function's docs are missing a `# Safety` section --> tests/ui/doc_unsafe.rs:9:1 | LL | pub unsafe fn destroy_the_planet() { @@ -7,13 +7,13 @@ LL | pub unsafe fn destroy_the_planet() { = note: `-D clippy::missing-safety-doc` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::missing_safety_doc)]` -error: unsafe function's docs miss `# Safety` section +error: unsafe function's docs are missing a `# Safety` section --> tests/ui/doc_unsafe.rs:32:5 | LL | pub unsafe fn republished() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: unsafe function's docs miss `# Safety` section +error: unsafe function's docs are missing a `# Safety` section --> tests/ui/doc_unsafe.rs:40:5 | LL | unsafe fn woefully_underdocumented(self); @@ -25,13 +25,13 @@ error: docs for unsafe trait missing `# Safety` section LL | pub unsafe trait UnsafeTrait { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: unsafe function's docs miss `# Safety` section +error: unsafe function's docs are missing a `# Safety` section --> tests/ui/doc_unsafe.rs:76:5 | LL | pub unsafe fn more_undocumented_unsafe() -> Self { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: unsafe function's docs miss `# Safety` section +error: unsafe function's docs are missing a `# Safety` section --> tests/ui/doc_unsafe.rs:92:9 | LL | pub unsafe fn whee() { diff --git a/tests/ui/double_neg.rs b/tests/ui/double_neg.rs index da82890443eb8..3be8c62887381 100644 --- a/tests/ui/double_neg.rs +++ b/tests/ui/double_neg.rs @@ -5,6 +5,6 @@ fn main() { -x; -(-x); --x; - //~^ ERROR: `--x` could be misinterpreted as pre-decrement by C programmers, is usuall + //~^ 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/tests/ui/eta.fixed b/tests/ui/eta.fixed index da28ec2e653a7..7126f2799455f 100644 --- a/tests/ui/eta.fixed +++ b/tests/ui/eta.fixed @@ -471,3 +471,14 @@ mod issue_10854 { } } } + +mod issue_12853 { + fn f_by_value(f: F) { + let x = Box::new(|| None.map(&f)); + x(); + } + fn f_by_ref(f: &F) { + let x = Box::new(|| None.map(f)); + x(); + } +} diff --git a/tests/ui/eta.rs b/tests/ui/eta.rs index f924100f8f419..0787abf5f3e37 100644 --- a/tests/ui/eta.rs +++ b/tests/ui/eta.rs @@ -471,3 +471,14 @@ mod issue_10854 { } } } + +mod issue_12853 { + fn f_by_value(f: F) { + let x = Box::new(|| None.map(|x| f(x))); + x(); + } + fn f_by_ref(f: &F) { + let x = Box::new(|| None.map(|x| f(x))); + x(); + } +} diff --git a/tests/ui/eta.stderr b/tests/ui/eta.stderr index d9a8768a68217..c757601042f16 100644 --- a/tests/ui/eta.stderr +++ b/tests/ui/eta.stderr @@ -190,5 +190,17 @@ error: redundant closure LL | test.map(|t| t.method()) | ^^^^^^^^^^^^^^ help: replace the closure with the method itself: `crate::issue_10854::d::Test::method` -error: aborting due to 31 previous errors +error: redundant closure + --> tests/ui/eta.rs:477:38 + | +LL | let x = Box::new(|| None.map(|x| f(x))); + | ^^^^^^^^ help: replace the closure with the function itself: `&f` + +error: redundant closure + --> tests/ui/eta.rs:481:38 + | +LL | let x = Box::new(|| None.map(|x| f(x))); + | ^^^^^^^^ help: replace the closure with the function itself: `f` + +error: aborting due to 33 previous errors diff --git a/tests/ui/floating_point_log.fixed b/tests/ui/floating_point_log.fixed index 01f0fc5c671ad..15cc47eef0dd0 100644 --- a/tests/ui/floating_point_log.fixed +++ b/tests/ui/floating_point_log.fixed @@ -55,4 +55,19 @@ fn check_ln1p() { let _ = (1.0 + x - 2.0).ln(); } +fn issue12881() { + pub trait MyLog { + fn log(&self) -> Self; + } + + impl MyLog for f32 { + fn log(&self) -> Self { + 4. + } + } + + let x = 2.0; + x.log(); +} + fn main() {} diff --git a/tests/ui/floating_point_log.rs b/tests/ui/floating_point_log.rs index 197e3e1ff9097..1241af8285932 100644 --- a/tests/ui/floating_point_log.rs +++ b/tests/ui/floating_point_log.rs @@ -55,4 +55,19 @@ fn check_ln1p() { let _ = (1.0 + x - 2.0).ln(); } +fn issue12881() { + pub trait MyLog { + fn log(&self) -> Self; + } + + impl MyLog for f32 { + fn log(&self) -> Self { + 4. + } + } + + let x = 2.0; + x.log(); +} + fn main() {} diff --git a/tests/ui/format_args.fixed b/tests/ui/format_args.fixed index cab20b11e0731..4d812f6bf1dce 100644 --- a/tests/ui/format_args.fixed +++ b/tests/ui/format_args.fixed @@ -104,6 +104,7 @@ fn main() { println!("{foo}{bar}", foo = "foo", bar = "bar"); println!("{foo}{bar}", bar = "bar", foo = "foo"); println!("{foo}{bar}", bar = "bar", foo = "foo"); + println!("{}", my_other_macro!()); // negative tests println!("error: something failed at {}", Somewhere.to_string()); diff --git a/tests/ui/format_args.rs b/tests/ui/format_args.rs index bc3645cb2c2bc..d242623feb62a 100644 --- a/tests/ui/format_args.rs +++ b/tests/ui/format_args.rs @@ -104,6 +104,7 @@ fn main() { println!("{foo}{bar}", foo = "foo", bar = "bar".to_string()); println!("{foo}{bar}", bar = "bar".to_string(), foo = "foo"); println!("{foo}{bar}", bar = "bar", foo = "foo".to_string()); + println!("{}", my_other_macro!().to_string()); // negative tests println!("error: something failed at {}", Somewhere.to_string()); diff --git a/tests/ui/format_args.stderr b/tests/ui/format_args.stderr index f20cf9eca2f9d..91a45e2700811 100644 --- a/tests/ui/format_args.stderr +++ b/tests/ui/format_args.stderr @@ -127,29 +127,35 @@ error: `to_string` applied to a type that implements `Display` in `println!` arg LL | println!("{foo}{bar}", bar = "bar", foo = "foo".to_string()); | ^^^^^^^^^^^^ help: remove this +error: `to_string` applied to a type that implements `Display` in `println!` args + --> tests/ui/format_args.rs:107:37 + | +LL | println!("{}", my_other_macro!().to_string()); + | ^^^^^^^^^^^^ help: remove this + error: `to_string` applied to a type that implements `Display` in `print!` args - --> tests/ui/format_args.rs:118:37 + --> tests/ui/format_args.rs:119:37 | LL | print!("{}", (Location::caller().to_string())); | ^^^^^^^^^^^^ help: remove this error: `to_string` applied to a type that implements `Display` in `print!` args - --> tests/ui/format_args.rs:119:39 + --> tests/ui/format_args.rs:120:39 | LL | print!("{}", ((Location::caller()).to_string())); | ^^^^^^^^^^^^ help: remove this error: `to_string` applied to a type that implements `Display` in `format!` args - --> tests/ui/format_args.rs:147:38 + --> tests/ui/format_args.rs:148:38 | LL | let x = format!("{} {}", a, b.to_string()); | ^^^^^^^^^^^^ help: remove this error: `to_string` applied to a type that implements `Display` in `println!` args - --> tests/ui/format_args.rs:161:24 + --> tests/ui/format_args.rs:162:24 | LL | println!("{}", original[..10].to_string()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use this: `&original[..10]` -error: aborting due to 25 previous errors +error: aborting due to 26 previous errors diff --git a/tests/ui/indexing_slicing_index.rs b/tests/ui/indexing_slicing_index.rs index 2e726141649e7..2af5fcc82a9bf 100644 --- a/tests/ui/indexing_slicing_index.rs +++ b/tests/ui/indexing_slicing_index.rs @@ -1,4 +1,5 @@ //@compile-flags: -Zdeduplicate-diagnostics=yes +//@aux-build: proc_macros.rs #![warn(clippy::indexing_slicing)] // We also check the out_of_bounds_indexing lint here, because it lints similar things and @@ -11,6 +12,9 @@ clippy::useless_vec )] +extern crate proc_macros; +use proc_macros::with_span; + const ARR: [i32; 2] = [1, 2]; const REF: &i32 = &ARR[idx()]; // This should be linted, since `suppress-restriction-lint-in-const` default is false. //~^ ERROR: indexing may panic @@ -22,6 +26,22 @@ const fn idx4() -> usize { 4 } +with_span!( + span + + fn dont_lint_proc_macro_array() { + let x = [1, 2, 3, 4]; + let index: usize = 1; + x[index]; + x[10]; + + let x = vec![0; 5]; + let index: usize = 1; + x[index]; + x[10]; + } +); + fn main() { let x = [1, 2, 3, 4]; let index: usize = 1; diff --git a/tests/ui/indexing_slicing_index.stderr b/tests/ui/indexing_slicing_index.stderr index 386f91becf14d..71677584d25bb 100644 --- a/tests/ui/indexing_slicing_index.stderr +++ b/tests/ui/indexing_slicing_index.stderr @@ -1,5 +1,5 @@ error: indexing may panic - --> tests/ui/indexing_slicing_index.rs:15:20 + --> tests/ui/indexing_slicing_index.rs:19:20 | LL | const REF: &i32 = &ARR[idx()]; // This should be linted, since `suppress-restriction-lint-in-const` default is false. | ^^^^^^^^^^ @@ -10,19 +10,19 @@ LL | const REF: &i32 = &ARR[idx()]; // This should be linted, since `suppress-re = help: to override `-D warnings` add `#[allow(clippy::indexing_slicing)]` error[E0080]: evaluation of `main::{constant#3}` failed - --> tests/ui/indexing_slicing_index.rs:47:14 + --> tests/ui/indexing_slicing_index.rs:67:14 | LL | const { &ARR[idx4()] }; | ^^^^^^^^^^^ index out of bounds: the length is 2 but the index is 4 note: erroneous constant encountered - --> tests/ui/indexing_slicing_index.rs:47:5 + --> tests/ui/indexing_slicing_index.rs:67:5 | LL | const { &ARR[idx4()] }; | ^^^^^^^^^^^^^^^^^^^^^^ error: indexing may panic - --> tests/ui/indexing_slicing_index.rs:28:5 + --> tests/ui/indexing_slicing_index.rs:48:5 | LL | x[index]; | ^^^^^^^^ @@ -30,7 +30,7 @@ LL | x[index]; = help: consider using `.get(n)` or `.get_mut(n)` instead error: index is out of bounds - --> tests/ui/indexing_slicing_index.rs:31:5 + --> tests/ui/indexing_slicing_index.rs:51:5 | LL | x[4]; | ^^^^ @@ -39,13 +39,13 @@ LL | x[4]; = help: to override `-D warnings` add `#[allow(clippy::out_of_bounds_indexing)]` error: index is out of bounds - --> tests/ui/indexing_slicing_index.rs:33:5 + --> tests/ui/indexing_slicing_index.rs:53:5 | LL | x[1 << 3]; | ^^^^^^^^^ error: indexing may panic - --> tests/ui/indexing_slicing_index.rs:44:14 + --> tests/ui/indexing_slicing_index.rs:64:14 | LL | const { &ARR[idx()] }; | ^^^^^^^^^^ @@ -54,7 +54,7 @@ LL | const { &ARR[idx()] }; = note: the suggestion might not be applicable in constant blocks error: indexing may panic - --> tests/ui/indexing_slicing_index.rs:47:14 + --> tests/ui/indexing_slicing_index.rs:67:14 | LL | const { &ARR[idx4()] }; | ^^^^^^^^^^^ @@ -63,13 +63,13 @@ LL | const { &ARR[idx4()] }; = note: the suggestion might not be applicable in constant blocks error: index is out of bounds - --> tests/ui/indexing_slicing_index.rs:54:5 + --> tests/ui/indexing_slicing_index.rs:74:5 | LL | y[4]; | ^^^^ error: indexing may panic - --> tests/ui/indexing_slicing_index.rs:57:5 + --> tests/ui/indexing_slicing_index.rs:77:5 | LL | v[0]; | ^^^^ @@ -77,7 +77,7 @@ LL | v[0]; = help: consider using `.get(n)` or `.get_mut(n)` instead error: indexing may panic - --> tests/ui/indexing_slicing_index.rs:59:5 + --> tests/ui/indexing_slicing_index.rs:79:5 | LL | v[10]; | ^^^^^ @@ -85,7 +85,7 @@ LL | v[10]; = help: consider using `.get(n)` or `.get_mut(n)` instead error: indexing may panic - --> tests/ui/indexing_slicing_index.rs:61:5 + --> tests/ui/indexing_slicing_index.rs:81:5 | LL | v[1 << 3]; | ^^^^^^^^^ @@ -93,13 +93,13 @@ LL | v[1 << 3]; = help: consider using `.get(n)` or `.get_mut(n)` instead error: index is out of bounds - --> tests/ui/indexing_slicing_index.rs:69:5 + --> tests/ui/indexing_slicing_index.rs:89:5 | LL | x[N]; | ^^^^ error: indexing may panic - --> tests/ui/indexing_slicing_index.rs:72:5 + --> tests/ui/indexing_slicing_index.rs:92:5 | LL | v[N]; | ^^^^ @@ -107,7 +107,7 @@ LL | v[N]; = help: consider using `.get(n)` or `.get_mut(n)` instead error: indexing may panic - --> tests/ui/indexing_slicing_index.rs:74:5 + --> tests/ui/indexing_slicing_index.rs:94:5 | LL | v[M]; | ^^^^ @@ -115,7 +115,7 @@ LL | v[M]; = help: consider using `.get(n)` or `.get_mut(n)` instead error: index is out of bounds - --> tests/ui/indexing_slicing_index.rs:78:13 + --> tests/ui/indexing_slicing_index.rs:98:13 | LL | let _ = x[4]; | ^^^^ diff --git a/tests/ui/indexing_slicing_slice.rs b/tests/ui/indexing_slicing_slice.rs index fc591021ed6b0..f37bcc4aa0caf 100644 --- a/tests/ui/indexing_slicing_slice.rs +++ b/tests/ui/indexing_slicing_slice.rs @@ -1,8 +1,111 @@ +//@aux-build: proc_macros.rs + #![warn(clippy::indexing_slicing)] // We also check the out_of_bounds_indexing lint here, because it lints similar things and // we want to avoid false positives. #![warn(clippy::out_of_bounds_indexing)] -#![allow(clippy::no_effect, clippy::unnecessary_operation, clippy::useless_vec)] +#![allow( + clippy::no_effect, + clippy::unnecessary_operation, + clippy::useless_vec, + unused_must_use, + unused +)] +#![warn(clippy::indexing_slicing)] + +extern crate proc_macros; +use proc_macros::with_span; + +use std::ops::Index; + +struct BoolMap { + false_value: T, + true_value: T, +} + +impl Index for BoolMap { + type Output = T; + fn index(&self, index: bool) -> &T { + if index { &self.true_value } else { &self.false_value } + } +} + +struct BoolMapWithGet { + false_value: T, + true_value: T, +} + +impl Index for BoolMapWithGet { + type Output = T; + fn index(&self, index: bool) -> &Self::Output { + if index { &self.true_value } else { &self.false_value } + } +} + +impl BoolMapWithGet { + fn get(&self, index: bool) -> Option<&T> { + if index { + Some(&self.true_value) + } else { + Some(&self.false_value) + } + } +} + +struct S(T); +impl S { + fn get() -> Option { + unimplemented!() + } +} +impl Index for S { + type Output = T; + fn index(&self, _index: i32) -> &Self::Output { + &self.0 + } +} + +struct Y(T); +impl Y { + fn get() -> Option { + unimplemented!() + } +} +impl Index for Y { + type Output = T; + fn index(&self, _index: i32) -> &Self::Output { + &self.0 + } +} + +struct Z(T); +impl Z { + fn get() -> T2 { + unimplemented!() + } +} +impl Index for Z { + type Output = T; + fn index(&self, _index: i32) -> &Self::Output { + &self.0 + } +} + +with_span!( + span + + fn dont_lint_proc_macro() { + let x = [1, 2, 3, 4]; + let index: usize = 1; + &x[index..]; + &x[..10]; + + let x = vec![0; 5]; + let index: usize = 1; + &x[index..]; + &x[..10]; + } +); fn main() { let x = [1, 2, 3, 4]; @@ -51,4 +154,28 @@ fn main() { //~^ ERROR: slicing may panic &v[..]; // Ok, should not produce stderr. + + let map = BoolMap { + false_value: 2, + true_value: 4, + }; + + map[true]; // Ok, because `get` does not exist (custom indexing) + + let map_with_get = BoolMapWithGet { + false_value: 2, + true_value: 4, + }; + + // Lint on this, because `get` does exist with same signature + map_with_get[true]; + + let s = S::(1); + s[0]; + + let y = Y::(1); + y[0]; + + let z = Z::(1); + z[0]; } diff --git a/tests/ui/indexing_slicing_slice.stderr b/tests/ui/indexing_slicing_slice.stderr index 790d4a41f5b1e..1e72506746ecb 100644 --- a/tests/ui/indexing_slicing_slice.stderr +++ b/tests/ui/indexing_slicing_slice.stderr @@ -1,5 +1,5 @@ error: slicing may panic - --> tests/ui/indexing_slicing_slice.rs:12:6 + --> tests/ui/indexing_slicing_slice.rs:115:6 | LL | &x[index..]; | ^^^^^^^^^^ @@ -9,7 +9,7 @@ LL | &x[index..]; = help: to override `-D warnings` add `#[allow(clippy::indexing_slicing)]` error: slicing may panic - --> tests/ui/indexing_slicing_slice.rs:14:6 + --> tests/ui/indexing_slicing_slice.rs:117:6 | LL | &x[..index]; | ^^^^^^^^^^ @@ -17,7 +17,7 @@ LL | &x[..index]; = help: consider using `.get(..n)`or `.get_mut(..n)` instead error: slicing may panic - --> tests/ui/indexing_slicing_slice.rs:16:6 + --> tests/ui/indexing_slicing_slice.rs:119:6 | LL | &x[index_from..index_to]; | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -25,7 +25,7 @@ LL | &x[index_from..index_to]; = help: consider using `.get(n..m)` or `.get_mut(n..m)` instead error: slicing may panic - --> tests/ui/indexing_slicing_slice.rs:18:6 + --> tests/ui/indexing_slicing_slice.rs:121:6 | LL | &x[index_from..][..index_to]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -33,7 +33,7 @@ LL | &x[index_from..][..index_to]; = help: consider using `.get(..n)`or `.get_mut(..n)` instead error: slicing may panic - --> tests/ui/indexing_slicing_slice.rs:18:6 + --> tests/ui/indexing_slicing_slice.rs:121:6 | LL | &x[index_from..][..index_to]; | ^^^^^^^^^^^^^^^ @@ -41,7 +41,7 @@ LL | &x[index_from..][..index_to]; = help: consider using `.get(n..)` or .get_mut(n..)` instead error: slicing may panic - --> tests/ui/indexing_slicing_slice.rs:21:6 + --> tests/ui/indexing_slicing_slice.rs:124:6 | LL | &x[5..][..10]; | ^^^^^^^^^^^^ @@ -49,7 +49,7 @@ LL | &x[5..][..10]; = help: consider using `.get(..n)`or `.get_mut(..n)` instead error: range is out of bounds - --> tests/ui/indexing_slicing_slice.rs:21:8 + --> tests/ui/indexing_slicing_slice.rs:124:8 | LL | &x[5..][..10]; | ^ @@ -58,7 +58,7 @@ LL | &x[5..][..10]; = help: to override `-D warnings` add `#[allow(clippy::out_of_bounds_indexing)]` error: slicing may panic - --> tests/ui/indexing_slicing_slice.rs:25:6 + --> tests/ui/indexing_slicing_slice.rs:128:6 | LL | &x[0..][..3]; | ^^^^^^^^^^^ @@ -66,7 +66,7 @@ LL | &x[0..][..3]; = help: consider using `.get(..n)`or `.get_mut(..n)` instead error: slicing may panic - --> tests/ui/indexing_slicing_slice.rs:27:6 + --> tests/ui/indexing_slicing_slice.rs:130:6 | LL | &x[1..][..5]; | ^^^^^^^^^^^ @@ -74,19 +74,19 @@ LL | &x[1..][..5]; = help: consider using `.get(..n)`or `.get_mut(..n)` instead error: range is out of bounds - --> tests/ui/indexing_slicing_slice.rs:35:12 + --> tests/ui/indexing_slicing_slice.rs:138:12 | LL | &y[0..=4]; | ^ error: range is out of bounds - --> tests/ui/indexing_slicing_slice.rs:37:11 + --> tests/ui/indexing_slicing_slice.rs:140:11 | LL | &y[..=4]; | ^ error: slicing may panic - --> tests/ui/indexing_slicing_slice.rs:43:6 + --> tests/ui/indexing_slicing_slice.rs:146:6 | LL | &v[10..100]; | ^^^^^^^^^^ @@ -94,7 +94,7 @@ LL | &v[10..100]; = help: consider using `.get(n..m)` or `.get_mut(n..m)` instead error: slicing may panic - --> tests/ui/indexing_slicing_slice.rs:45:6 + --> tests/ui/indexing_slicing_slice.rs:148:6 | LL | &x[10..][..100]; | ^^^^^^^^^^^^^^ @@ -102,13 +102,13 @@ LL | &x[10..][..100]; = help: consider using `.get(..n)`or `.get_mut(..n)` instead error: range is out of bounds - --> tests/ui/indexing_slicing_slice.rs:45:8 + --> tests/ui/indexing_slicing_slice.rs:148:8 | LL | &x[10..][..100]; | ^^ error: slicing may panic - --> tests/ui/indexing_slicing_slice.rs:48:6 + --> tests/ui/indexing_slicing_slice.rs:151:6 | LL | &v[10..]; | ^^^^^^^ @@ -116,12 +116,36 @@ LL | &v[10..]; = help: consider using `.get(n..)` or .get_mut(n..)` instead error: slicing may panic - --> tests/ui/indexing_slicing_slice.rs:50:6 + --> tests/ui/indexing_slicing_slice.rs:153:6 | LL | &v[..100]; | ^^^^^^^^ | = help: consider using `.get(..n)`or `.get_mut(..n)` instead -error: aborting due to 16 previous errors +error: indexing may panic + --> tests/ui/indexing_slicing_slice.rs:171:5 + | +LL | map_with_get[true]; + | ^^^^^^^^^^^^^^^^^^ + | + = help: consider using `.get(n)` or `.get_mut(n)` instead + +error: indexing may panic + --> tests/ui/indexing_slicing_slice.rs:174:5 + | +LL | s[0]; + | ^^^^ + | + = help: consider using `.get(n)` or `.get_mut(n)` instead + +error: indexing may panic + --> tests/ui/indexing_slicing_slice.rs:177:5 + | +LL | y[0]; + | ^^^^ + | + = help: consider using `.get(n)` or `.get_mut(n)` instead + +error: aborting due to 19 previous errors diff --git a/tests/ui/infinite_loops.rs b/tests/ui/infinite_loops.rs index 52fbbaa8e31e9..b2d522fa011b7 100644 --- a/tests/ui/infinite_loops.rs +++ b/tests/ui/infinite_loops.rs @@ -137,7 +137,7 @@ fn can_break_both_inner_and_outer(cond: bool) { } fn break_wrong_loop(cond: bool) { - // 'inner has statement to break 'outer loop, but it was breaked early by a labeled child loop + // 'inner has statement to break 'outer loop, but it was broken out of early by a labeled child loop 'outer: loop { loop { //~^ ERROR: infinite loop detected diff --git a/tests/ui/iter_over_hash_type.rs b/tests/ui/iter_over_hash_type.rs index 7000c8bf96f8d..65bae1df42188 100644 --- a/tests/ui/iter_over_hash_type.rs +++ b/tests/ui/iter_over_hash_type.rs @@ -59,7 +59,7 @@ fn main() { let _ = x; } - // shouldnt fire + // shouldn't fire for x in &vec { let _ = x; } diff --git a/tests/ui/manual_pattern_char_comparison.fixed b/tests/ui/manual_pattern_char_comparison.fixed new file mode 100644 index 0000000000000..588226b87e87f --- /dev/null +++ b/tests/ui/manual_pattern_char_comparison.fixed @@ -0,0 +1,49 @@ +#![warn(clippy::manual_pattern_char_comparison)] + +struct NotStr; + +impl NotStr { + fn find(&self, _: impl FnMut(char) -> bool) {} +} + +fn main() { + let sentence = "Hello, world!"; + sentence.trim_end_matches(['.', ',', '!', '?']); + sentence.split(['\n', 'X']); + sentence.split(['\n', 'X']); + sentence.splitn(3, 'X'); + sentence.splitn(3, |c: char| c.is_whitespace() || c == 'X'); + let char_compare = 'X'; + sentence.splitn(3, char_compare); + sentence.split(['\n', 'X', 'Y']); + sentence.splitn(3, 'X'); + sentence.splitn(3, ['X', 'W']); + sentence.find('🎈'); + + let not_str = NotStr; + not_str.find(|c: char| c == 'X'); + + "".find(|c| c == 'a' || c > 'z'); + + let x = true; + "".find(|c| c == 'a' || x || c == 'b'); + + let d = 'd'; + "".find(|c| c == 'a' || d == 'b'); + + "".find(|c| match c { + 'a' | 'b' => true, + _ => c.is_ascii(), + }); + + "".find(|c| matches!(c, 'a' | 'b' if false)); + + "".find(|c| matches!(c, 'a' | '1'..'4')); + "".find(|c| c == 'a' || matches!(c, '1'..'4')); + macro_rules! m { + ($e:expr) => { + $e == '?' + }; + } + "".find(|c| m!(c)); +} diff --git a/tests/ui/manual_pattern_char_comparison.rs b/tests/ui/manual_pattern_char_comparison.rs new file mode 100644 index 0000000000000..5078f3ee27f36 --- /dev/null +++ b/tests/ui/manual_pattern_char_comparison.rs @@ -0,0 +1,49 @@ +#![warn(clippy::manual_pattern_char_comparison)] + +struct NotStr; + +impl NotStr { + fn find(&self, _: impl FnMut(char) -> bool) {} +} + +fn main() { + let sentence = "Hello, world!"; + sentence.trim_end_matches(|c: char| c == '.' || c == ',' || c == '!' || c == '?'); + sentence.split(|c: char| c == '\n' || c == 'X'); + sentence.split(|c| c == '\n' || c == 'X'); + sentence.splitn(3, |c: char| c == 'X'); + sentence.splitn(3, |c: char| c.is_whitespace() || c == 'X'); + let char_compare = 'X'; + sentence.splitn(3, |c: char| c == char_compare); + sentence.split(|c: char| matches!(c, '\n' | 'X' | 'Y')); + sentence.splitn(3, |c: char| matches!(c, 'X')); + sentence.splitn(3, |c: char| matches!(c, 'X' | 'W')); + sentence.find(|c| c == '🎈'); + + let not_str = NotStr; + not_str.find(|c: char| c == 'X'); + + "".find(|c| c == 'a' || c > 'z'); + + let x = true; + "".find(|c| c == 'a' || x || c == 'b'); + + let d = 'd'; + "".find(|c| c == 'a' || d == 'b'); + + "".find(|c| match c { + 'a' | 'b' => true, + _ => c.is_ascii(), + }); + + "".find(|c| matches!(c, 'a' | 'b' if false)); + + "".find(|c| matches!(c, 'a' | '1'..'4')); + "".find(|c| c == 'a' || matches!(c, '1'..'4')); + macro_rules! m { + ($e:expr) => { + $e == '?' + }; + } + "".find(|c| m!(c)); +} diff --git a/tests/ui/manual_pattern_char_comparison.stderr b/tests/ui/manual_pattern_char_comparison.stderr new file mode 100644 index 0000000000000..b6b51794a11f5 --- /dev/null +++ b/tests/ui/manual_pattern_char_comparison.stderr @@ -0,0 +1,59 @@ +error: this manual char comparison can be written more succinctly + --> tests/ui/manual_pattern_char_comparison.rs:11:31 + | +LL | sentence.trim_end_matches(|c: char| c == '.' || c == ',' || c == '!' || c == '?'); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using an array of `char`: `['.', ',', '!', '?']` + | + = note: `-D clippy::manual-pattern-char-comparison` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::manual_pattern_char_comparison)]` + +error: this manual char comparison can be written more succinctly + --> tests/ui/manual_pattern_char_comparison.rs:12:20 + | +LL | sentence.split(|c: char| c == '\n' || c == 'X'); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using an array of `char`: `['\n', 'X']` + +error: this manual char comparison can be written more succinctly + --> tests/ui/manual_pattern_char_comparison.rs:13:20 + | +LL | sentence.split(|c| c == '\n' || c == 'X'); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using an array of `char`: `['\n', 'X']` + +error: this manual char comparison can be written more succinctly + --> tests/ui/manual_pattern_char_comparison.rs:14:24 + | +LL | sentence.splitn(3, |c: char| c == 'X'); + | ^^^^^^^^^^^^^^^^^^ help: consider using a `char`: `'X'` + +error: this manual char comparison can be written more succinctly + --> tests/ui/manual_pattern_char_comparison.rs:17:24 + | +LL | sentence.splitn(3, |c: char| c == char_compare); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using a `char`: `char_compare` + +error: this manual char comparison can be written more succinctly + --> tests/ui/manual_pattern_char_comparison.rs:18:20 + | +LL | sentence.split(|c: char| matches!(c, '\n' | 'X' | 'Y')); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using an array of `char`: `['\n', 'X', 'Y']` + +error: this manual char comparison can be written more succinctly + --> tests/ui/manual_pattern_char_comparison.rs:19:24 + | +LL | sentence.splitn(3, |c: char| matches!(c, 'X')); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using a `char`: `'X'` + +error: this manual char comparison can be written more succinctly + --> tests/ui/manual_pattern_char_comparison.rs:20:24 + | +LL | sentence.splitn(3, |c: char| matches!(c, 'X' | 'W')); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using an array of `char`: `['X', 'W']` + +error: this manual char comparison can be written more succinctly + --> tests/ui/manual_pattern_char_comparison.rs:21:19 + | +LL | sentence.find(|c| c == '🎈'); + | ^^^^^^^^^^^^^ help: consider using a `char`: `'🎈'` + +error: aborting due to 9 previous errors + diff --git a/tests/ui/manual_unwrap_or_default.fixed b/tests/ui/manual_unwrap_or_default.fixed index d6e736ba9cc2b..663de1a5f0677 100644 --- a/tests/ui/manual_unwrap_or_default.fixed +++ b/tests/ui/manual_unwrap_or_default.fixed @@ -26,6 +26,12 @@ fn main() { Some(x) => x, None => &[], }; + + let x: Result = Ok(String::new()); + x.unwrap_or_default(); + + let x: Result = Ok(String::new()); + x.unwrap_or_default(); } // Issue #12531 diff --git a/tests/ui/manual_unwrap_or_default.rs b/tests/ui/manual_unwrap_or_default.rs index 462d5d90ee771..75ffe09be9d4d 100644 --- a/tests/ui/manual_unwrap_or_default.rs +++ b/tests/ui/manual_unwrap_or_default.rs @@ -47,6 +47,21 @@ fn main() { Some(x) => x, None => &[], }; + + let x: Result = Ok(String::new()); + match x { + //~^ ERROR: match can be simplified with `.unwrap_or_default()` + Ok(v) => v, + Err(_) => String::new(), + }; + + let x: Result = Ok(String::new()); + if let Ok(v) = x { + //~^ ERROR: if let can be simplified with `.unwrap_or_default()` + v + } else { + String::new() + }; } // Issue #12531 diff --git a/tests/ui/manual_unwrap_or_default.stderr b/tests/ui/manual_unwrap_or_default.stderr index 3f1da444301f6..9e3b1be5cb9be 100644 --- a/tests/ui/manual_unwrap_or_default.stderr +++ b/tests/ui/manual_unwrap_or_default.stderr @@ -53,7 +53,28 @@ LL | | }; | |_____^ help: replace it with: `x.unwrap_or_default()` error: match can be simplified with `.unwrap_or_default()` - --> tests/ui/manual_unwrap_or_default.rs:56:20 + --> tests/ui/manual_unwrap_or_default.rs:52:5 + | +LL | / match x { +LL | | +LL | | Ok(v) => v, +LL | | Err(_) => String::new(), +LL | | }; + | |_____^ help: replace it with: `x.unwrap_or_default()` + +error: if let can be simplified with `.unwrap_or_default()` + --> tests/ui/manual_unwrap_or_default.rs:59:5 + | +LL | / if let Ok(v) = x { +LL | | +LL | | v +LL | | } else { +LL | | String::new() +LL | | }; + | |_____^ help: replace it with: `x.unwrap_or_default()` + +error: match can be simplified with `.unwrap_or_default()` + --> tests/ui/manual_unwrap_or_default.rs:71:20 | LL | Some(_) => match *b { | ____________________^ @@ -62,5 +83,5 @@ LL | | _ => 0, LL | | }, | |_________^ help: replace it with: `(*b).unwrap_or_default()` -error: aborting due to 6 previous errors +error: aborting due to 8 previous errors diff --git a/tests/ui/match_same_arms2.fixed b/tests/ui/match_same_arms2.fixed index fba0cf33b3c26..09e960ddd6a98 100644 --- a/tests/ui/match_same_arms2.fixed +++ b/tests/ui/match_same_arms2.fixed @@ -239,3 +239,20 @@ fn main() { _ => false, }; } + +// issue #8919, fixed on https://github.com/rust-lang/rust/pull/97312 +mod with_lifetime { + enum MaybeStaticStr<'a> { + Static(&'static str), + Borrowed(&'a str), + } + + impl<'a> MaybeStaticStr<'a> { + fn get(&self) -> &'a str { + match *self { + MaybeStaticStr::Borrowed(s) | MaybeStaticStr::Static(s) => s, + //~^ ERROR: this match arm has an identical body to another arm + } + } + } +} diff --git a/tests/ui/match_same_arms2.rs b/tests/ui/match_same_arms2.rs index 8a4e3b325bbff..cc7425135cc45 100644 --- a/tests/ui/match_same_arms2.rs +++ b/tests/ui/match_same_arms2.rs @@ -262,3 +262,21 @@ fn main() { _ => false, }; } + +// issue #8919, fixed on https://github.com/rust-lang/rust/pull/97312 +mod with_lifetime { + enum MaybeStaticStr<'a> { + Static(&'static str), + Borrowed(&'a str), + } + + impl<'a> MaybeStaticStr<'a> { + fn get(&self) -> &'a str { + match *self { + MaybeStaticStr::Static(s) => s, + MaybeStaticStr::Borrowed(s) => s, + //~^ ERROR: this match arm has an identical body to another arm + } + } + } +} diff --git a/tests/ui/match_same_arms2.stderr b/tests/ui/match_same_arms2.stderr index 3d15176ccf997..a5d137c658b79 100644 --- a/tests/ui/match_same_arms2.stderr +++ b/tests/ui/match_same_arms2.stderr @@ -221,5 +221,21 @@ help: and remove this obsolete arm LL - 0 => cfg!(not_enable), | -error: aborting due to 13 previous errors +error: this match arm has an identical body to another arm + --> tests/ui/match_same_arms2.rs:277:17 + | +LL | MaybeStaticStr::Borrowed(s) => s, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: try changing either arm body +help: or try merging the arm patterns + | +LL | MaybeStaticStr::Borrowed(s) | MaybeStaticStr::Static(s) => s, + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +help: and remove this obsolete arm + | +LL - MaybeStaticStr::Static(s) => s, + | + +error: aborting due to 14 previous errors diff --git a/tests/ui/mismatched_target_os_non_unix.fixed b/tests/ui/mismatched_target_os_non_unix.fixed deleted file mode 100644 index de02b2bee31fc..0000000000000 --- a/tests/ui/mismatched_target_os_non_unix.fixed +++ /dev/null @@ -1,25 +0,0 @@ -#![warn(clippy::mismatched_target_os)] -#![allow(unused)] - -#[cfg(target_os = "hermit")] -fn hermit() {} - -#[cfg(target_os = "wasi")] -fn wasi() {} - -#[cfg(target_os = "none")] -fn none() {} - -// list with conditions -#[cfg(all(not(windows), target_os = "wasi"))] -fn list() {} - -// windows is a valid target family, should be ignored -#[cfg(windows)] -fn windows() {} - -// correct use, should be ignored -#[cfg(target_os = "hermit")] -fn correct() {} - -fn main() {} diff --git a/tests/ui/mismatched_target_os_non_unix.rs b/tests/ui/mismatched_target_os_non_unix.rs deleted file mode 100644 index a960518751bfc..0000000000000 --- a/tests/ui/mismatched_target_os_non_unix.rs +++ /dev/null @@ -1,25 +0,0 @@ -#![warn(clippy::mismatched_target_os)] -#![allow(unused)] - -#[cfg(hermit)] -fn hermit() {} - -#[cfg(wasi)] -fn wasi() {} - -#[cfg(none)] -fn none() {} - -// list with conditions -#[cfg(all(not(windows), wasi))] -fn list() {} - -// windows is a valid target family, should be ignored -#[cfg(windows)] -fn windows() {} - -// correct use, should be ignored -#[cfg(target_os = "hermit")] -fn correct() {} - -fn main() {} diff --git a/tests/ui/mismatched_target_os_non_unix.stderr b/tests/ui/mismatched_target_os_non_unix.stderr deleted file mode 100644 index 7f7a4e9d6f623..0000000000000 --- a/tests/ui/mismatched_target_os_non_unix.stderr +++ /dev/null @@ -1,37 +0,0 @@ -error: operating system used in target family position - --> tests/ui/mismatched_target_os_non_unix.rs:4:1 - | -LL | #[cfg(hermit)] - | ^^^^^^------^^ - | | - | help: try: `target_os = "hermit"` - | - = note: `-D clippy::mismatched-target-os` implied by `-D warnings` - = help: to override `-D warnings` add `#[allow(clippy::mismatched_target_os)]` - -error: operating system used in target family position - --> tests/ui/mismatched_target_os_non_unix.rs:7:1 - | -LL | #[cfg(wasi)] - | ^^^^^^----^^ - | | - | help: try: `target_os = "wasi"` - -error: operating system used in target family position - --> tests/ui/mismatched_target_os_non_unix.rs:10:1 - | -LL | #[cfg(none)] - | ^^^^^^----^^ - | | - | help: try: `target_os = "none"` - -error: operating system used in target family position - --> tests/ui/mismatched_target_os_non_unix.rs:14:1 - | -LL | #[cfg(all(not(windows), wasi))] - | ^^^^^^^^^^^^^^^^^^^^^^^^----^^^ - | | - | help: try: `target_os = "wasi"` - -error: aborting due to 4 previous errors - diff --git a/tests/ui/mismatched_target_os_unix.fixed b/tests/ui/mismatched_target_os_unix.fixed deleted file mode 100644 index b945c4d9619da..0000000000000 --- a/tests/ui/mismatched_target_os_unix.fixed +++ /dev/null @@ -1,60 +0,0 @@ -#![warn(clippy::mismatched_target_os)] -#![allow(unused)] - -#[cfg(target_os = "linux")] -fn linux() {} - -#[cfg(target_os = "freebsd")] -fn freebsd() {} - -#[cfg(target_os = "dragonfly")] -fn dragonfly() {} - -#[cfg(target_os = "openbsd")] -fn openbsd() {} - -#[cfg(target_os = "netbsd")] -fn netbsd() {} - -#[cfg(target_os = "macos")] -fn macos() {} - -#[cfg(target_os = "ios")] -fn ios() {} - -#[cfg(target_os = "android")] -fn android() {} - -#[cfg(target_os = "emscripten")] -fn emscripten() {} - -#[cfg(target_os = "fuchsia")] -fn fuchsia() {} - -#[cfg(target_os = "haiku")] -fn haiku() {} - -#[cfg(target_os = "illumos")] -fn illumos() {} - -#[cfg(target_os = "l4re")] -fn l4re() {} - -#[cfg(target_os = "redox")] -fn redox() {} - -#[cfg(target_os = "solaris")] -fn solaris() {} - -#[cfg(target_os = "vxworks")] -fn vxworks() {} - -// list with conditions -#[cfg(all(not(any(target_os = "solaris", target_os = "linux")), target_os = "freebsd"))] -fn list() {} - -// correct use, should be ignored -#[cfg(target_os = "freebsd")] -fn correct() {} - -fn main() {} diff --git a/tests/ui/mismatched_target_os_unix.rs b/tests/ui/mismatched_target_os_unix.rs deleted file mode 100644 index 34307facd6549..0000000000000 --- a/tests/ui/mismatched_target_os_unix.rs +++ /dev/null @@ -1,60 +0,0 @@ -#![warn(clippy::mismatched_target_os)] -#![allow(unused)] - -#[cfg(linux)] -fn linux() {} - -#[cfg(freebsd)] -fn freebsd() {} - -#[cfg(dragonfly)] -fn dragonfly() {} - -#[cfg(openbsd)] -fn openbsd() {} - -#[cfg(netbsd)] -fn netbsd() {} - -#[cfg(macos)] -fn macos() {} - -#[cfg(ios)] -fn ios() {} - -#[cfg(android)] -fn android() {} - -#[cfg(emscripten)] -fn emscripten() {} - -#[cfg(fuchsia)] -fn fuchsia() {} - -#[cfg(haiku)] -fn haiku() {} - -#[cfg(illumos)] -fn illumos() {} - -#[cfg(l4re)] -fn l4re() {} - -#[cfg(redox)] -fn redox() {} - -#[cfg(solaris)] -fn solaris() {} - -#[cfg(vxworks)] -fn vxworks() {} - -// list with conditions -#[cfg(all(not(any(solaris, linux)), freebsd))] -fn list() {} - -// correct use, should be ignored -#[cfg(target_os = "freebsd")] -fn correct() {} - -fn main() {} diff --git a/tests/ui/mismatched_target_os_unix.stderr b/tests/ui/mismatched_target_os_unix.stderr deleted file mode 100644 index 3071bad1324b8..0000000000000 --- a/tests/ui/mismatched_target_os_unix.stderr +++ /dev/null @@ -1,184 +0,0 @@ -error: operating system used in target family position - --> tests/ui/mismatched_target_os_unix.rs:4:1 - | -LL | #[cfg(linux)] - | ^^^^^^-----^^ - | | - | help: try: `target_os = "linux"` - | - = help: did you mean `unix`? - = note: `-D clippy::mismatched-target-os` implied by `-D warnings` - = help: to override `-D warnings` add `#[allow(clippy::mismatched_target_os)]` - -error: operating system used in target family position - --> tests/ui/mismatched_target_os_unix.rs:7:1 - | -LL | #[cfg(freebsd)] - | ^^^^^^-------^^ - | | - | help: try: `target_os = "freebsd"` - | - = help: did you mean `unix`? - -error: operating system used in target family position - --> tests/ui/mismatched_target_os_unix.rs:10:1 - | -LL | #[cfg(dragonfly)] - | ^^^^^^---------^^ - | | - | help: try: `target_os = "dragonfly"` - | - = help: did you mean `unix`? - -error: operating system used in target family position - --> tests/ui/mismatched_target_os_unix.rs:13:1 - | -LL | #[cfg(openbsd)] - | ^^^^^^-------^^ - | | - | help: try: `target_os = "openbsd"` - | - = help: did you mean `unix`? - -error: operating system used in target family position - --> tests/ui/mismatched_target_os_unix.rs:16:1 - | -LL | #[cfg(netbsd)] - | ^^^^^^------^^ - | | - | help: try: `target_os = "netbsd"` - | - = help: did you mean `unix`? - -error: operating system used in target family position - --> tests/ui/mismatched_target_os_unix.rs:19:1 - | -LL | #[cfg(macos)] - | ^^^^^^-----^^ - | | - | help: try: `target_os = "macos"` - | - = help: did you mean `unix`? - -error: operating system used in target family position - --> tests/ui/mismatched_target_os_unix.rs:22:1 - | -LL | #[cfg(ios)] - | ^^^^^^---^^ - | | - | help: try: `target_os = "ios"` - | - = help: did you mean `unix`? - -error: operating system used in target family position - --> tests/ui/mismatched_target_os_unix.rs:25:1 - | -LL | #[cfg(android)] - | ^^^^^^-------^^ - | | - | help: try: `target_os = "android"` - | - = help: did you mean `unix`? - -error: operating system used in target family position - --> tests/ui/mismatched_target_os_unix.rs:28:1 - | -LL | #[cfg(emscripten)] - | ^^^^^^----------^^ - | | - | help: try: `target_os = "emscripten"` - | - = help: did you mean `unix`? - -error: operating system used in target family position - --> tests/ui/mismatched_target_os_unix.rs:31:1 - | -LL | #[cfg(fuchsia)] - | ^^^^^^-------^^ - | | - | help: try: `target_os = "fuchsia"` - | - = help: did you mean `unix`? - -error: operating system used in target family position - --> tests/ui/mismatched_target_os_unix.rs:34:1 - | -LL | #[cfg(haiku)] - | ^^^^^^-----^^ - | | - | help: try: `target_os = "haiku"` - | - = help: did you mean `unix`? - -error: operating system used in target family position - --> tests/ui/mismatched_target_os_unix.rs:37:1 - | -LL | #[cfg(illumos)] - | ^^^^^^-------^^ - | | - | help: try: `target_os = "illumos"` - | - = help: did you mean `unix`? - -error: operating system used in target family position - --> tests/ui/mismatched_target_os_unix.rs:40:1 - | -LL | #[cfg(l4re)] - | ^^^^^^----^^ - | | - | help: try: `target_os = "l4re"` - | - = help: did you mean `unix`? - -error: operating system used in target family position - --> tests/ui/mismatched_target_os_unix.rs:43:1 - | -LL | #[cfg(redox)] - | ^^^^^^-----^^ - | | - | help: try: `target_os = "redox"` - | - = help: did you mean `unix`? - -error: operating system used in target family position - --> tests/ui/mismatched_target_os_unix.rs:46:1 - | -LL | #[cfg(solaris)] - | ^^^^^^-------^^ - | | - | help: try: `target_os = "solaris"` - | - = help: did you mean `unix`? - -error: operating system used in target family position - --> tests/ui/mismatched_target_os_unix.rs:49:1 - | -LL | #[cfg(vxworks)] - | ^^^^^^-------^^ - | | - | help: try: `target_os = "vxworks"` - | - = help: did you mean `unix`? - -error: operating system used in target family position - --> tests/ui/mismatched_target_os_unix.rs:53:1 - | -LL | #[cfg(all(not(any(solaris, linux)), freebsd))] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = help: did you mean `unix`? -help: try - | -LL | #[cfg(all(not(any(target_os = "solaris", linux)), freebsd))] - | ~~~~~~~~~~~~~~~~~~~~~ -help: try - | -LL | #[cfg(all(not(any(solaris, target_os = "linux")), freebsd))] - | ~~~~~~~~~~~~~~~~~~~ -help: try - | -LL | #[cfg(all(not(any(solaris, linux)), target_os = "freebsd"))] - | ~~~~~~~~~~~~~~~~~~~~~ - -error: aborting due to 17 previous errors - diff --git a/tests/ui/missing_const_for_fn/could_be_const.rs b/tests/ui/missing_const_for_fn/could_be_const.rs index 06dbbeb31c0d5..58e639cc7fd1f 100644 --- a/tests/ui/missing_const_for_fn/could_be_const.rs +++ b/tests/ui/missing_const_for_fn/could_be_const.rs @@ -141,3 +141,33 @@ mod msrv { let _ = unsafe { bar.val }; } } + +mod issue12677 { + pub struct Wrapper { + pub strings: Vec, + } + + impl Wrapper { + #[must_use] + pub fn new(strings: Vec) -> Self { + Self { strings } + } + + #[must_use] + pub fn empty() -> Self { + Self { strings: Vec::new() } + } + } + + pub struct Other { + pub text: String, + pub vec: Vec, + } + + impl Other { + pub fn new(text: String) -> Self { + let vec = Vec::new(); + Self { text, vec } + } + } +} diff --git a/tests/ui/missing_const_for_fn/could_be_const.stderr b/tests/ui/missing_const_for_fn/could_be_const.stderr index b2cade3056373..1c61c3e871324 100644 --- a/tests/ui/missing_const_for_fn/could_be_const.stderr +++ b/tests/ui/missing_const_for_fn/could_be_const.stderr @@ -130,5 +130,30 @@ LL | | let _ = unsafe { bar.val }; LL | | } | |_____^ -error: aborting due to 14 previous errors +error: this could be a `const fn` + --> tests/ui/missing_const_for_fn/could_be_const.rs:152:9 + | +LL | / pub fn new(strings: Vec) -> Self { +LL | | Self { strings } +LL | | } + | |_________^ + +error: this could be a `const fn` + --> tests/ui/missing_const_for_fn/could_be_const.rs:157:9 + | +LL | / pub fn empty() -> Self { +LL | | Self { strings: Vec::new() } +LL | | } + | |_________^ + +error: this could be a `const fn` + --> tests/ui/missing_const_for_fn/could_be_const.rs:168:9 + | +LL | / pub fn new(text: String) -> Self { +LL | | let vec = Vec::new(); +LL | | Self { text, vec } +LL | | } + | |_________^ + +error: aborting due to 17 previous errors diff --git a/tests/ui/missing_fields_in_debug.rs b/tests/ui/missing_fields_in_debug.rs index e91e8ab7f475e..68867ec819d14 100644 --- a/tests/ui/missing_fields_in_debug.rs +++ b/tests/ui/missing_fields_in_debug.rs @@ -4,6 +4,7 @@ use std::fmt; use std::marker::PhantomData; use std::ops::Deref; +use std::thread::LocalKey; struct NamedStruct1Ignored { data: u8, @@ -191,4 +192,21 @@ impl fmt::Debug for WithPD { } } +struct InClosure { + a: u8, + b: String, +} + +impl fmt::Debug for InClosure { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let mut d = f.debug_struct("InClosure"); + d.field("a", &self.a); + let mut c = || { + d.field("b", &self.b); + }; + c(); + d.finish() + } +} + fn main() {} diff --git a/tests/ui/missing_fields_in_debug.stderr b/tests/ui/missing_fields_in_debug.stderr index 6f8a9abe9228d..8c1810909dd86 100644 --- a/tests/ui/missing_fields_in_debug.stderr +++ b/tests/ui/missing_fields_in_debug.stderr @@ -1,5 +1,5 @@ error: manual `Debug` impl does not include all fields - --> tests/ui/missing_fields_in_debug.rs:13:1 + --> tests/ui/missing_fields_in_debug.rs:14:1 | LL | / impl fmt::Debug for NamedStruct1Ignored { LL | | @@ -11,7 +11,7 @@ LL | | } | |_^ | note: this field is unused - --> tests/ui/missing_fields_in_debug.rs:10:5 + --> tests/ui/missing_fields_in_debug.rs:11:5 | LL | hidden: u32, | ^^^^^^^^^^^ @@ -21,7 +21,7 @@ LL | hidden: u32, = help: to override `-D warnings` add `#[allow(clippy::missing_fields_in_debug)]` error: manual `Debug` impl does not include all fields - --> tests/ui/missing_fields_in_debug.rs:32:1 + --> tests/ui/missing_fields_in_debug.rs:33:1 | LL | / impl fmt::Debug for NamedStructMultipleIgnored { LL | | @@ -33,17 +33,17 @@ LL | | } | |_^ | note: this field is unused - --> tests/ui/missing_fields_in_debug.rs:26:5 + --> tests/ui/missing_fields_in_debug.rs:27:5 | LL | hidden: u32, | ^^^^^^^^^^^ note: this field is unused - --> tests/ui/missing_fields_in_debug.rs:27:5 + --> tests/ui/missing_fields_in_debug.rs:28:5 | LL | hidden2: String, | ^^^^^^^^^^^^^^^ note: this field is unused - --> tests/ui/missing_fields_in_debug.rs:29:5 + --> tests/ui/missing_fields_in_debug.rs:30:5 | LL | hidden4: ((((u8), u16), u32), u64), | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -51,7 +51,7 @@ LL | hidden4: ((((u8), u16), u32), u64), = help: consider calling `.finish_non_exhaustive()` if you intend to ignore fields error: manual `Debug` impl does not include all fields - --> tests/ui/missing_fields_in_debug.rs:94:1 + --> tests/ui/missing_fields_in_debug.rs:95:1 | LL | / impl fmt::Debug for MultiExprDebugImpl { LL | | @@ -63,7 +63,7 @@ LL | | } | |_^ | note: this field is unused - --> tests/ui/missing_fields_in_debug.rs:90:5 + --> tests/ui/missing_fields_in_debug.rs:91:5 | LL | b: String, | ^^^^^^^^^ diff --git a/tests/ui/needless_bool/fixable.fixed b/tests/ui/needless_bool/fixable.fixed index 3059de8f89c49..ec63c4fd6a268 100644 --- a/tests/ui/needless_bool/fixable.fixed +++ b/tests/ui/needless_bool/fixable.fixed @@ -131,3 +131,15 @@ fn needless_bool_condition() -> bool { foo() } + +fn issue12846() { + let a = true; + let b = false; + + // parentheses are needed here + let _x = (a && b).then(|| todo!()); + let _x = (a && b) as u8; + + // parentheses are not needed here + let _x = a.then(|| todo!()); +} diff --git a/tests/ui/needless_bool/fixable.rs b/tests/ui/needless_bool/fixable.rs index b2cbe86e2235b..8694aa7159080 100644 --- a/tests/ui/needless_bool/fixable.rs +++ b/tests/ui/needless_bool/fixable.rs @@ -191,3 +191,15 @@ fn needless_bool_condition() -> bool { foo() } + +fn issue12846() { + let a = true; + let b = false; + + // parentheses are needed here + let _x = if a && b { true } else { false }.then(|| todo!()); + let _x = if a && b { true } else { false } as u8; + + // parentheses are not needed here + let _x = if a { true } else { false }.then(|| todo!()); +} diff --git a/tests/ui/needless_bool/fixable.stderr b/tests/ui/needless_bool/fixable.stderr index 9746e931f50f0..99b5b99834486 100644 --- a/tests/ui/needless_bool/fixable.stderr +++ b/tests/ui/needless_bool/fixable.stderr @@ -191,5 +191,23 @@ error: this if-then-else expression returns a bool literal LL | if unsafe { no(4) } & 1 != 0 { true } else { false } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: you can reduce it to: `(unsafe { no(4) } & 1 != 0)` -error: aborting due to 21 previous errors +error: this if-then-else expression returns a bool literal + --> tests/ui/needless_bool/fixable.rs:200:14 + | +LL | let _x = if a && b { true } else { false }.then(|| todo!()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: you can reduce it to: `(a && b)` + +error: this if-then-else expression returns a bool literal + --> tests/ui/needless_bool/fixable.rs:201:14 + | +LL | let _x = if a && b { true } else { false } as u8; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: you can reduce it to: `(a && b)` + +error: this if-then-else expression returns a bool literal + --> tests/ui/needless_bool/fixable.rs:204:14 + | +LL | let _x = if a { true } else { false }.then(|| todo!()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: you can reduce it to: `a` + +error: aborting due to 24 previous errors diff --git a/tests/ui/needless_character_iteration.fixed b/tests/ui/needless_character_iteration.fixed new file mode 100644 index 0000000000000..f0bf84a41d7ed --- /dev/null +++ b/tests/ui/needless_character_iteration.fixed @@ -0,0 +1,57 @@ +#![warn(clippy::needless_character_iteration)] +#![allow(clippy::map_identity, clippy::unnecessary_operation)] + +#[derive(Default)] +struct S { + field: &'static str, +} + +impl S { + fn field(&self) -> &str { + self.field + } +} + +fn magic(_: char) {} + +fn main() { + "foo".is_ascii(); + //~^ ERROR: checking if a string is ascii using iterators + !"foo".is_ascii(); + //~^ ERROR: checking if a string is ascii using iterators + "foo".is_ascii(); + //~^ ERROR: checking if a string is ascii using iterators + !"foo".is_ascii(); + //~^ ERROR: checking if a string is ascii using iterators + + let s = String::new(); + s.is_ascii(); + //~^ ERROR: checking if a string is ascii using iterators + !"foo".to_string().is_ascii(); + //~^ ERROR: checking if a string is ascii using iterators + + "foo".is_ascii(); + !"foo".is_ascii(); + + S::default().field().is_ascii(); + //~^ ERROR: checking if a string is ascii using iterators + + // Should not lint! + "foo".chars().all(|c| { + let x = c; + magic(x); + x.is_ascii() + }); + + // Should not lint! + "foo".chars().all(|c| c.is_ascii() && c.is_alphabetic()); + + // Should not lint! + "foo".chars().map(|c| c).all(|c| !char::is_ascii(&c)); + + // Should not lint! + "foo".chars().all(|c| !c.is_ascii()); + + // Should not lint! + "foo".chars().any(|c| c.is_ascii()); +} diff --git a/tests/ui/needless_character_iteration.rs b/tests/ui/needless_character_iteration.rs new file mode 100644 index 0000000000000..2805d2438b4ab --- /dev/null +++ b/tests/ui/needless_character_iteration.rs @@ -0,0 +1,65 @@ +#![warn(clippy::needless_character_iteration)] +#![allow(clippy::map_identity, clippy::unnecessary_operation)] + +#[derive(Default)] +struct S { + field: &'static str, +} + +impl S { + fn field(&self) -> &str { + self.field + } +} + +fn magic(_: char) {} + +fn main() { + "foo".chars().all(|c| c.is_ascii()); + //~^ ERROR: checking if a string is ascii using iterators + "foo".chars().any(|c| !c.is_ascii()); + //~^ ERROR: checking if a string is ascii using iterators + "foo".chars().all(|c| char::is_ascii(&c)); + //~^ ERROR: checking if a string is ascii using iterators + "foo".chars().any(|c| !char::is_ascii(&c)); + //~^ ERROR: checking if a string is ascii using iterators + + let s = String::new(); + s.chars().all(|c| c.is_ascii()); + //~^ ERROR: checking if a string is ascii using iterators + "foo".to_string().chars().any(|c| !c.is_ascii()); + //~^ ERROR: checking if a string is ascii using iterators + + "foo".chars().all(|c| { + //~^ ERROR: checking if a string is ascii using iterators + let x = c; + x.is_ascii() + }); + "foo".chars().any(|c| { + //~^ ERROR: checking if a string is ascii using iterators + let x = c; + !x.is_ascii() + }); + + S::default().field().chars().all(|x| x.is_ascii()); + //~^ ERROR: checking if a string is ascii using iterators + + // Should not lint! + "foo".chars().all(|c| { + let x = c; + magic(x); + x.is_ascii() + }); + + // Should not lint! + "foo".chars().all(|c| c.is_ascii() && c.is_alphabetic()); + + // Should not lint! + "foo".chars().map(|c| c).all(|c| !char::is_ascii(&c)); + + // Should not lint! + "foo".chars().all(|c| !c.is_ascii()); + + // Should not lint! + "foo".chars().any(|c| c.is_ascii()); +} diff --git a/tests/ui/needless_character_iteration.stderr b/tests/ui/needless_character_iteration.stderr new file mode 100644 index 0000000000000..7966033555f5b --- /dev/null +++ b/tests/ui/needless_character_iteration.stderr @@ -0,0 +1,67 @@ +error: checking if a string is ascii using iterators + --> tests/ui/needless_character_iteration.rs:18:5 + | +LL | "foo".chars().all(|c| c.is_ascii()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `"foo".is_ascii()` + | + = note: `-D clippy::needless-character-iteration` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::needless_character_iteration)]` + +error: checking if a string is ascii using iterators + --> tests/ui/needless_character_iteration.rs:20:5 + | +LL | "foo".chars().any(|c| !c.is_ascii()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `!"foo".is_ascii()` + +error: checking if a string is ascii using iterators + --> tests/ui/needless_character_iteration.rs:22:5 + | +LL | "foo".chars().all(|c| char::is_ascii(&c)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `"foo".is_ascii()` + +error: checking if a string is ascii using iterators + --> tests/ui/needless_character_iteration.rs:24:5 + | +LL | "foo".chars().any(|c| !char::is_ascii(&c)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `!"foo".is_ascii()` + +error: checking if a string is ascii using iterators + --> tests/ui/needless_character_iteration.rs:28:5 + | +LL | s.chars().all(|c| c.is_ascii()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `s.is_ascii()` + +error: checking if a string is ascii using iterators + --> tests/ui/needless_character_iteration.rs:30:5 + | +LL | "foo".to_string().chars().any(|c| !c.is_ascii()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `!"foo".to_string().is_ascii()` + +error: checking if a string is ascii using iterators + --> tests/ui/needless_character_iteration.rs:33:5 + | +LL | / "foo".chars().all(|c| { +LL | | +LL | | let x = c; +LL | | x.is_ascii() +LL | | }); + | |______^ help: try: `"foo".is_ascii()` + +error: checking if a string is ascii using iterators + --> tests/ui/needless_character_iteration.rs:38:5 + | +LL | / "foo".chars().any(|c| { +LL | | +LL | | let x = c; +LL | | !x.is_ascii() +LL | | }); + | |______^ help: try: `!"foo".is_ascii()` + +error: checking if a string is ascii using iterators + --> tests/ui/needless_character_iteration.rs:44:5 + | +LL | S::default().field().chars().all(|x| x.is_ascii()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `S::default().field().is_ascii()` + +error: aborting due to 9 previous errors + diff --git a/tests/ui/needless_maybe_sized.fixed b/tests/ui/needless_maybe_sized.fixed new file mode 100644 index 0000000000000..4d24a7cee619b --- /dev/null +++ b/tests/ui/needless_maybe_sized.fixed @@ -0,0 +1,116 @@ +//@aux-build:proc_macros.rs + +#![allow(unused, clippy::multiple_bound_locations)] +#![warn(clippy::needless_maybe_sized)] + +extern crate proc_macros; +use proc_macros::external; + +fn directly(t: &T) {} + +trait A: Sized {} +trait B: A {} + +fn depth_1(t: &T) {} +fn depth_2(t: &T) {} + +// We only need to show one +fn multiple_paths(t: &T) {} + +fn in_where(t: &T) +where + T: Sized, +{ +} + +fn mixed_1(t: &T) +{ +} + +fn mixed_2(t: &T) +where + T: Sized, +{ +} + +fn mixed_3(t: &T) +where + T: Sized, +{ +} + +struct Struct(T); + +impl Struct { + fn method(&self) {} +} + +enum Enum { + Variant(&'static T), +} + +union Union<'a, T: Sized> { + a: &'a T, +} + +trait Trait { + fn trait_method() {} + + type GAT; + + type Assoc: Sized + ?Sized; // False negative +} + +trait SecondInTrait: Send + Sized {} +fn second_in_trait() {} + +fn impl_trait(_: &(impl Sized)) {} + +trait GenericTrait: Sized {} +fn in_generic_trait, U>() {} + +mod larger_graph { + // C1 C2 Sized + // \ /\ / + // B1 B2 + // \ / + // A1 + + trait C1 {} + trait C2 {} + trait B1: C1 + C2 {} + trait B2: C2 + Sized {} + trait A1: B1 + B2 {} + + fn larger_graph() {} +} + +// Should not lint + +fn sized() {} +fn maybe_sized() {} + +struct SeparateBounds(T); +impl SeparateBounds {} + +trait P {} +trait Q: P {} + +fn ok_depth_1() {} +fn ok_depth_2() {} + +external! { + fn in_macro(t: &T) {} + + fn with_local_clone(t: &T) {} +} + +#[derive(Clone)] +struct InDerive { + t: T, +} + +struct Refined(T); +impl Refined {} + +fn main() {} diff --git a/tests/ui/needless_maybe_sized.rs b/tests/ui/needless_maybe_sized.rs new file mode 100644 index 0000000000000..ef66f9a4f2aec --- /dev/null +++ b/tests/ui/needless_maybe_sized.rs @@ -0,0 +1,119 @@ +//@aux-build:proc_macros.rs + +#![allow(unused, clippy::multiple_bound_locations)] +#![warn(clippy::needless_maybe_sized)] + +extern crate proc_macros; +use proc_macros::external; + +fn directly(t: &T) {} + +trait A: Sized {} +trait B: A {} + +fn depth_1(t: &T) {} +fn depth_2(t: &T) {} + +// We only need to show one +fn multiple_paths(t: &T) {} + +fn in_where(t: &T) +where + T: Sized + ?Sized, +{ +} + +fn mixed_1(t: &T) +where + T: ?Sized, +{ +} + +fn mixed_2(t: &T) +where + T: Sized, +{ +} + +fn mixed_3(t: &T) +where + T: Sized, + T: ?Sized, +{ +} + +struct Struct(T); + +impl Struct { + fn method(&self) {} +} + +enum Enum { + Variant(&'static T), +} + +union Union<'a, T: Sized + ?Sized> { + a: &'a T, +} + +trait Trait { + fn trait_method() {} + + type GAT; + + type Assoc: Sized + ?Sized; // False negative +} + +trait SecondInTrait: Send + Sized {} +fn second_in_trait() {} + +fn impl_trait(_: &(impl Sized + ?Sized)) {} + +trait GenericTrait: Sized {} +fn in_generic_trait + ?Sized, U>() {} + +mod larger_graph { + // C1 C2 Sized + // \ /\ / + // B1 B2 + // \ / + // A1 + + trait C1 {} + trait C2 {} + trait B1: C1 + C2 {} + trait B2: C2 + Sized {} + trait A1: B1 + B2 {} + + fn larger_graph() {} +} + +// Should not lint + +fn sized() {} +fn maybe_sized() {} + +struct SeparateBounds(T); +impl SeparateBounds {} + +trait P {} +trait Q: P {} + +fn ok_depth_1() {} +fn ok_depth_2() {} + +external! { + fn in_macro(t: &T) {} + + fn with_local_clone(t: &T) {} +} + +#[derive(Clone)] +struct InDerive { + t: T, +} + +struct Refined(T); +impl Refined {} + +fn main() {} diff --git a/tests/ui/needless_maybe_sized.stderr b/tests/ui/needless_maybe_sized.stderr new file mode 100644 index 0000000000000..3b1d2b49b0622 --- /dev/null +++ b/tests/ui/needless_maybe_sized.stderr @@ -0,0 +1,353 @@ +error: `?Sized` bound is ignored because of a `Sized` requirement + --> tests/ui/needless_maybe_sized.rs:9:24 + | +LL | fn directly(t: &T) {} + | ^^^^^^ + | +note: `T` cannot be unsized because of the bound + --> tests/ui/needless_maybe_sized.rs:9:16 + | +LL | fn directly(t: &T) {} + | ^^^^^ + = note: `-D clippy::needless-maybe-sized` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::needless_maybe_sized)]` +help: change the bounds that require `Sized`, or remove the `?Sized` bound + | +LL - fn directly(t: &T) {} +LL + fn directly(t: &T) {} + | + +error: `?Sized` bound is ignored because of a `Sized` requirement + --> tests/ui/needless_maybe_sized.rs:14:19 + | +LL | fn depth_1(t: &T) {} + | ^^^^^^ + | +note: `T` cannot be unsized because of the bound + --> tests/ui/needless_maybe_sized.rs:14:15 + | +LL | fn depth_1(t: &T) {} + | ^ + = note: ...because `A` has the bound `Sized` +help: change the bounds that require `Sized`, or remove the `?Sized` bound + | +LL - fn depth_1(t: &T) {} +LL + fn depth_1(t: &T) {} + | + +error: `?Sized` bound is ignored because of a `Sized` requirement + --> tests/ui/needless_maybe_sized.rs:15:19 + | +LL | fn depth_2(t: &T) {} + | ^^^^^^ + | +note: `T` cannot be unsized because of the bound + --> tests/ui/needless_maybe_sized.rs:15:15 + | +LL | fn depth_2(t: &T) {} + | ^ + = note: ...because `B` has the bound `A` + = note: ...because `A` has the bound `Sized` +help: change the bounds that require `Sized`, or remove the `?Sized` bound + | +LL - fn depth_2(t: &T) {} +LL + fn depth_2(t: &T) {} + | + +error: `?Sized` bound is ignored because of a `Sized` requirement + --> tests/ui/needless_maybe_sized.rs:18:30 + | +LL | fn multiple_paths(t: &T) {} + | ^^^^^^ + | +note: `T` cannot be unsized because of the bound + --> tests/ui/needless_maybe_sized.rs:18:22 + | +LL | fn multiple_paths(t: &T) {} + | ^ + = note: ...because `A` has the bound `Sized` +help: change the bounds that require `Sized`, or remove the `?Sized` bound + | +LL - fn multiple_paths(t: &T) {} +LL + fn multiple_paths(t: &T) {} + | + +error: `?Sized` bound is ignored because of a `Sized` requirement + --> tests/ui/needless_maybe_sized.rs:22:16 + | +LL | T: Sized + ?Sized, + | ^^^^^^ + | +note: `T` cannot be unsized because of the bound + --> tests/ui/needless_maybe_sized.rs:22:8 + | +LL | T: Sized + ?Sized, + | ^^^^^ +help: change the bounds that require `Sized`, or remove the `?Sized` bound + | +LL - T: Sized + ?Sized, +LL + T: Sized, + | + +error: `?Sized` bound is ignored because of a `Sized` requirement + --> tests/ui/needless_maybe_sized.rs:28:8 + | +LL | T: ?Sized, + | ^^^^^^ + | +note: `T` cannot be unsized because of the bound + --> tests/ui/needless_maybe_sized.rs:26:15 + | +LL | fn mixed_1(t: &T) + | ^^^^^ +help: change the bounds that require `Sized`, or remove the `?Sized` bound + | +LL - where +LL - T: ?Sized, + | + +error: `?Sized` bound is ignored because of a `Sized` requirement + --> tests/ui/needless_maybe_sized.rs:32:15 + | +LL | fn mixed_2(t: &T) + | ^^^^^^ + | +note: `T` cannot be unsized because of the bound + --> tests/ui/needless_maybe_sized.rs:34:8 + | +LL | T: Sized, + | ^^^^^ +help: change the bounds that require `Sized`, or remove the `?Sized` bound + | +LL - fn mixed_2(t: &T) +LL + fn mixed_2(t: &T) + | + +error: `?Sized` bound is ignored because of a `Sized` requirement + --> tests/ui/needless_maybe_sized.rs:41:8 + | +LL | T: ?Sized, + | ^^^^^^ + | +note: `T` cannot be unsized because of the bound + --> tests/ui/needless_maybe_sized.rs:40:8 + | +LL | T: Sized, + | ^^^^^ +help: change the bounds that require `Sized`, or remove the `?Sized` bound + | +LL - T: Sized, +LL - T: ?Sized, +LL + T: Sized, + | + +error: `?Sized` bound is ignored because of a `Sized` requirement + --> tests/ui/needless_maybe_sized.rs:45:26 + | +LL | struct Struct(T); + | ^^^^^^ + | +note: `T` cannot be unsized because of the bound + --> tests/ui/needless_maybe_sized.rs:45:18 + | +LL | struct Struct(T); + | ^^^^^ +help: change the bounds that require `Sized`, or remove the `?Sized` bound + | +LL - struct Struct(T); +LL + struct Struct(T); + | + +error: `?Sized` bound is ignored because of a `Sized` requirement + --> tests/ui/needless_maybe_sized.rs:47:17 + | +LL | impl Struct { + | ^^^^^^ + | +note: `T` cannot be unsized because of the bound + --> tests/ui/needless_maybe_sized.rs:47:9 + | +LL | impl Struct { + | ^^^^^ +help: change the bounds that require `Sized`, or remove the `?Sized` bound + | +LL - impl Struct { +LL + impl Struct { + | + +error: `?Sized` bound is ignored because of a `Sized` requirement + --> tests/ui/needless_maybe_sized.rs:48:26 + | +LL | fn method(&self) {} + | ^^^^^^ + | +note: `U` cannot be unsized because of the bound + --> tests/ui/needless_maybe_sized.rs:48:18 + | +LL | fn method(&self) {} + | ^^^^^ +help: change the bounds that require `Sized`, or remove the `?Sized` bound + | +LL - fn method(&self) {} +LL + fn method(&self) {} + | + +error: `?Sized` bound is ignored because of a `Sized` requirement + --> tests/ui/needless_maybe_sized.rs:51:22 + | +LL | enum Enum { + | ^^^^^^ + | +note: `T` cannot be unsized because of the bound + --> tests/ui/needless_maybe_sized.rs:51:14 + | +LL | enum Enum { + | ^^^^^ +help: change the bounds that require `Sized`, or remove the `?Sized` bound + | +LL - enum Enum { +LL + enum Enum { + | + +error: `?Sized` bound is ignored because of a `Sized` requirement + --> tests/ui/needless_maybe_sized.rs:55:28 + | +LL | union Union<'a, T: Sized + ?Sized> { + | ^^^^^^ + | +note: `T` cannot be unsized because of the bound + --> tests/ui/needless_maybe_sized.rs:55:20 + | +LL | union Union<'a, T: Sized + ?Sized> { + | ^^^^^ +help: change the bounds that require `Sized`, or remove the `?Sized` bound + | +LL - union Union<'a, T: Sized + ?Sized> { +LL + union Union<'a, T: Sized> { + | + +error: `?Sized` bound is ignored because of a `Sized` requirement + --> tests/ui/needless_maybe_sized.rs:59:24 + | +LL | trait Trait { + | ^^^^^^ + | +note: `T` cannot be unsized because of the bound + --> tests/ui/needless_maybe_sized.rs:59:16 + | +LL | trait Trait { + | ^^^^^ +help: change the bounds that require `Sized`, or remove the `?Sized` bound + | +LL - trait Trait { +LL + trait Trait { + | + +error: `?Sized` bound is ignored because of a `Sized` requirement + --> tests/ui/needless_maybe_sized.rs:60:32 + | +LL | fn trait_method() {} + | ^^^^^^ + | +note: `U` cannot be unsized because of the bound + --> tests/ui/needless_maybe_sized.rs:60:24 + | +LL | fn trait_method() {} + | ^^^^^ +help: change the bounds that require `Sized`, or remove the `?Sized` bound + | +LL - fn trait_method() {} +LL + fn trait_method() {} + | + +error: `?Sized` bound is ignored because of a `Sized` requirement + --> tests/ui/needless_maybe_sized.rs:62:25 + | +LL | type GAT; + | ^^^^^^ + | +note: `U` cannot be unsized because of the bound + --> tests/ui/needless_maybe_sized.rs:62:17 + | +LL | type GAT; + | ^^^^^ +help: change the bounds that require `Sized`, or remove the `?Sized` bound + | +LL - type GAT; +LL + type GAT; + | + +error: `?Sized` bound is ignored because of a `Sized` requirement + --> tests/ui/needless_maybe_sized.rs:68:23 + | +LL | fn second_in_trait() {} + | ^^^^^^ + | +note: `T` cannot be unsized because of the bound + --> tests/ui/needless_maybe_sized.rs:68:32 + | +LL | fn second_in_trait() {} + | ^^^^^^^^^^^^^ + = note: ...because `SecondInTrait` has the bound `Sized` +help: change the bounds that require `Sized`, or remove the `?Sized` bound + | +LL - fn second_in_trait() {} +LL + fn second_in_trait() {} + | + +error: `?Sized` bound is ignored because of a `Sized` requirement + --> tests/ui/needless_maybe_sized.rs:70:33 + | +LL | fn impl_trait(_: &(impl Sized + ?Sized)) {} + | ^^^^^^ + | +note: `impl Sized + ?Sized` cannot be unsized because of the bound + --> tests/ui/needless_maybe_sized.rs:70:25 + | +LL | fn impl_trait(_: &(impl Sized + ?Sized)) {} + | ^^^^^ +help: change the bounds that require `Sized`, or remove the `?Sized` bound + | +LL - fn impl_trait(_: &(impl Sized + ?Sized)) {} +LL + fn impl_trait(_: &(impl Sized)) {} + | + +error: `?Sized` bound is ignored because of a `Sized` requirement + --> tests/ui/needless_maybe_sized.rs:73:42 + | +LL | fn in_generic_trait + ?Sized, U>() {} + | ^^^^^^ + | +note: `T` cannot be unsized because of the bound + --> tests/ui/needless_maybe_sized.rs:73:24 + | +LL | fn in_generic_trait + ?Sized, U>() {} + | ^^^^^^^^^^^^^^^ + = note: ...because `GenericTrait` has the bound `Sized` +help: change the bounds that require `Sized`, or remove the `?Sized` bound + | +LL - fn in_generic_trait + ?Sized, U>() {} +LL + fn in_generic_trait, U>() {} + | + +error: `?Sized` bound is ignored because of a `Sized` requirement + --> tests/ui/needless_maybe_sized.rs:88:29 + | +LL | fn larger_graph() {} + | ^^^^^^ + | +note: `T` cannot be unsized because of the bound + --> tests/ui/needless_maybe_sized.rs:88:24 + | +LL | fn larger_graph() {} + | ^^ + = note: ...because `A1` has the bound `B2` + = note: ...because `B2` has the bound `Sized` +help: change the bounds that require `Sized`, or remove the `?Sized` bound + | +LL - fn larger_graph() {} +LL + fn larger_graph() {} + | + +error: aborting due to 20 previous errors + diff --git a/tests/ui/non_canonical_clone_impl.fixed b/tests/ui/non_canonical_clone_impl.fixed index 7d1be412e54fd..11616f28825b0 100644 --- a/tests/ui/non_canonical_clone_impl.fixed +++ b/tests/ui/non_canonical_clone_impl.fixed @@ -1,7 +1,11 @@ +//@aux-build:proc_macro_derive.rs #![allow(clippy::clone_on_copy, unused)] #![allow(clippy::assigning_clones)] #![no_main] +extern crate proc_macros; +use proc_macros::with_span; + // lint struct A(u32); @@ -95,3 +99,19 @@ impl Clone for Uwu { } impl Copy for Uwu {} + +// should skip proc macros, see https://github.com/rust-lang/rust-clippy/issues/12788 +#[derive(proc_macro_derive::NonCanonicalClone)] +pub struct G; + +with_span!( + span + + #[derive(Copy)] + struct H; + impl Clone for H { + fn clone(&self) -> Self { + todo!() + } + } +); diff --git a/tests/ui/non_canonical_clone_impl.rs b/tests/ui/non_canonical_clone_impl.rs index beae05efb2fbc..a36c7ed44c247 100644 --- a/tests/ui/non_canonical_clone_impl.rs +++ b/tests/ui/non_canonical_clone_impl.rs @@ -1,7 +1,11 @@ +//@aux-build:proc_macro_derive.rs #![allow(clippy::clone_on_copy, unused)] #![allow(clippy::assigning_clones)] #![no_main] +extern crate proc_macros; +use proc_macros::with_span; + // lint struct A(u32); @@ -105,3 +109,19 @@ impl Clone for Uwu { } impl Copy for Uwu {} + +// should skip proc macros, see https://github.com/rust-lang/rust-clippy/issues/12788 +#[derive(proc_macro_derive::NonCanonicalClone)] +pub struct G; + +with_span!( + span + + #[derive(Copy)] + struct H; + impl Clone for H { + fn clone(&self) -> Self { + todo!() + } + } +); diff --git a/tests/ui/non_canonical_clone_impl.stderr b/tests/ui/non_canonical_clone_impl.stderr index 6bfc99d988bb7..f7cad58150f7d 100644 --- a/tests/ui/non_canonical_clone_impl.stderr +++ b/tests/ui/non_canonical_clone_impl.stderr @@ -1,5 +1,5 @@ error: non-canonical implementation of `clone` on a `Copy` type - --> tests/ui/non_canonical_clone_impl.rs:10:29 + --> tests/ui/non_canonical_clone_impl.rs:14:29 | LL | fn clone(&self) -> Self { | _____________________________^ @@ -11,7 +11,7 @@ LL | | } = help: to override `-D warnings` add `#[allow(clippy::non_canonical_clone_impl)]` error: unnecessary implementation of `clone_from` on a `Copy` type - --> tests/ui/non_canonical_clone_impl.rs:14:5 + --> tests/ui/non_canonical_clone_impl.rs:18:5 | LL | / fn clone_from(&mut self, source: &Self) { LL | | source.clone(); @@ -20,7 +20,7 @@ LL | | } | |_____^ help: remove it error: non-canonical implementation of `clone` on a `Copy` type - --> tests/ui/non_canonical_clone_impl.rs:81:29 + --> tests/ui/non_canonical_clone_impl.rs:85:29 | LL | fn clone(&self) -> Self { | _____________________________^ @@ -29,7 +29,7 @@ LL | | } | |_____^ help: change this to: `{ *self }` error: unnecessary implementation of `clone_from` on a `Copy` type - --> tests/ui/non_canonical_clone_impl.rs:85:5 + --> tests/ui/non_canonical_clone_impl.rs:89:5 | LL | / fn clone_from(&mut self, source: &Self) { LL | | source.clone(); diff --git a/tests/ui/nonminimal_bool_methods.fixed b/tests/ui/nonminimal_bool_methods.fixed index aba599678e391..cc91ba6ec66e1 100644 --- a/tests/ui/nonminimal_bool_methods.fixed +++ b/tests/ui/nonminimal_bool_methods.fixed @@ -1,5 +1,3 @@ -//@compile-flags: -Zdeduplicate-diagnostics=yes - #![allow(unused, clippy::diverging_sub_expression, clippy::needless_if)] #![warn(clippy::nonminimal_bool)] diff --git a/tests/ui/nonminimal_bool_methods.rs b/tests/ui/nonminimal_bool_methods.rs index 35f22db1d36ab..c812f6f0ca4f5 100644 --- a/tests/ui/nonminimal_bool_methods.rs +++ b/tests/ui/nonminimal_bool_methods.rs @@ -1,5 +1,3 @@ -//@compile-flags: -Zdeduplicate-diagnostics=yes - #![allow(unused, clippy::diverging_sub_expression, clippy::needless_if)] #![warn(clippy::nonminimal_bool)] diff --git a/tests/ui/nonminimal_bool_methods.stderr b/tests/ui/nonminimal_bool_methods.stderr index 18da4e0d380bc..d7adc0638b373 100644 --- a/tests/ui/nonminimal_bool_methods.stderr +++ b/tests/ui/nonminimal_bool_methods.stderr @@ -1,5 +1,5 @@ error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool_methods.rs:10:13 + --> tests/ui/nonminimal_bool_methods.rs:8:13 | LL | let _ = !a.is_some(); | ^^^^^^^^^^^^ help: try: `a.is_none()` @@ -8,91 +8,91 @@ LL | let _ = !a.is_some(); = help: to override `-D warnings` add `#[allow(clippy::nonminimal_bool)]` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool_methods.rs:12:13 + --> tests/ui/nonminimal_bool_methods.rs:10:13 | LL | let _ = !a.is_none(); | ^^^^^^^^^^^^ help: try: `a.is_some()` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool_methods.rs:14:13 + --> tests/ui/nonminimal_bool_methods.rs:12:13 | LL | let _ = !b.is_err(); | ^^^^^^^^^^^ help: try: `b.is_ok()` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool_methods.rs:16:13 + --> tests/ui/nonminimal_bool_methods.rs:14:13 | LL | let _ = !b.is_ok(); | ^^^^^^^^^^ help: try: `b.is_err()` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool_methods.rs:18:13 + --> tests/ui/nonminimal_bool_methods.rs:16:13 | LL | let _ = !(a.is_some() && !c); | ^^^^^^^^^^^^^^^^^^^^ help: try: `a.is_none() || c` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool_methods.rs:19:13 + --> tests/ui/nonminimal_bool_methods.rs:17:13 | LL | let _ = !(a.is_some() || !c); | ^^^^^^^^^^^^^^^^^^^^ help: try: `a.is_none() && c` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool_methods.rs:20:26 + --> tests/ui/nonminimal_bool_methods.rs:18:26 | LL | let _ = !(!c ^ c) || !a.is_some(); | ^^^^^^^^^^^^ help: try: `a.is_none()` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool_methods.rs:21:25 + --> tests/ui/nonminimal_bool_methods.rs:19:25 | LL | let _ = (!c ^ c) || !a.is_some(); | ^^^^^^^^^^^^ help: try: `a.is_none()` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool_methods.rs:22:23 + --> tests/ui/nonminimal_bool_methods.rs:20:23 | LL | let _ = !c ^ c || !a.is_some(); | ^^^^^^^^^^^^ help: try: `a.is_none()` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool_methods.rs:94:8 + --> tests/ui/nonminimal_bool_methods.rs:92:8 | LL | if !res.is_ok() {} | ^^^^^^^^^^^^ help: try: `res.is_err()` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool_methods.rs:95:8 + --> tests/ui/nonminimal_bool_methods.rs:93:8 | LL | if !res.is_err() {} | ^^^^^^^^^^^^^ help: try: `res.is_ok()` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool_methods.rs:98:8 + --> tests/ui/nonminimal_bool_methods.rs:96:8 | LL | if !res.is_some() {} | ^^^^^^^^^^^^^^ help: try: `res.is_none()` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool_methods.rs:99:8 + --> tests/ui/nonminimal_bool_methods.rs:97:8 | LL | if !res.is_none() {} | ^^^^^^^^^^^^^^ help: try: `res.is_some()` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool_methods.rs:115:8 + --> tests/ui/nonminimal_bool_methods.rs:113:8 | LL | if !(a as u64 >= b) {} | ^^^^^^^^^^^^^^^^ help: try: `(a as u64) < b` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool_methods.rs:116:8 + --> tests/ui/nonminimal_bool_methods.rs:114:8 | LL | if !((a as u64) >= b) {} | ^^^^^^^^^^^^^^^^^^ help: try: `(a as u64) < b` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool_methods.rs:117:8 + --> tests/ui/nonminimal_bool_methods.rs:115:8 | LL | if !(a as u64 <= b) {} | ^^^^^^^^^^^^^^^^ help: try: `a as u64 > b` diff --git a/tests/ui/or_fun_call.fixed b/tests/ui/or_fun_call.fixed index e7ba54864ab0e..7657ef470c589 100644 --- a/tests/ui/or_fun_call.fixed +++ b/tests/ui/or_fun_call.fixed @@ -311,4 +311,11 @@ mod lazy { } } +fn host_effect() { + // #12877 - make sure we don't ICE in type_certainty + use std::ops::Add; + + Add::::add(1, 1).add(i32::MIN); +} + fn main() {} diff --git a/tests/ui/or_fun_call.rs b/tests/ui/or_fun_call.rs index 196632133d52a..97cf496d3ac7c 100644 --- a/tests/ui/or_fun_call.rs +++ b/tests/ui/or_fun_call.rs @@ -311,4 +311,11 @@ mod lazy { } } +fn host_effect() { + // #12877 - make sure we don't ICE in type_certainty + use std::ops::Add; + + Add::::add(1, 1).add(i32::MIN); +} + fn main() {} diff --git a/tests/ui/overly_complex_bool_expr.fixed b/tests/ui/overly_complex_bool_expr.fixed index e44f6063156a7..439b1145431c6 100644 --- a/tests/ui/overly_complex_bool_expr.fixed +++ b/tests/ui/overly_complex_bool_expr.fixed @@ -37,3 +37,13 @@ fn check_expect() { #[expect(clippy::overly_complex_bool_expr)] let _ = a < b && a >= b; } + +#[allow(clippy::never_loop)] +fn check_never_type() { + loop { + _ = (break) || true; + } + loop { + _ = (return) || true; + } +} diff --git a/tests/ui/overly_complex_bool_expr.rs b/tests/ui/overly_complex_bool_expr.rs index f010a8537e7f7..b96fd1adf1180 100644 --- a/tests/ui/overly_complex_bool_expr.rs +++ b/tests/ui/overly_complex_bool_expr.rs @@ -37,3 +37,13 @@ fn check_expect() { #[expect(clippy::overly_complex_bool_expr)] let _ = a < b && a >= b; } + +#[allow(clippy::never_loop)] +fn check_never_type() { + loop { + _ = (break) || true; + } + loop { + _ = (return) || true; + } +} diff --git a/tests/ui/panic_in_result_fn.rs b/tests/ui/panic_in_result_fn.rs index 41e2f5226899d..aaaf9a109acbb 100644 --- a/tests/ui/panic_in_result_fn.rs +++ b/tests/ui/panic_in_result_fn.rs @@ -56,6 +56,11 @@ fn function_result_with_panic() -> Result // should emit lint panic!("error"); } +fn in_closure() -> Result { + let c = || panic!(); + c() +} + fn todo() { println!("something"); } diff --git a/tests/ui/panic_in_result_fn.stderr b/tests/ui/panic_in_result_fn.stderr index cd2234bdfb13c..2d49b5ab1b8f1 100644 --- a/tests/ui/panic_in_result_fn.stderr +++ b/tests/ui/panic_in_result_fn.stderr @@ -34,5 +34,21 @@ note: return Err() instead of panicking LL | panic!("error"); | ^^^^^^^^^^^^^^^ -error: aborting due to 2 previous errors +error: used `panic!()` or assertion in a function that returns `Result` + --> tests/ui/panic_in_result_fn.rs:59:1 + | +LL | / fn in_closure() -> Result { +LL | | let c = || panic!(); +LL | | c() +LL | | } + | |_^ + | + = help: `panic!()` or assertions should not be used in a function that returns `Result` as `Result` is expected to return an error instead of crashing +note: return Err() instead of panicking + --> tests/ui/panic_in_result_fn.rs:60:16 + | +LL | let c = || panic!(); + | ^^^^^^^^ + +error: aborting due to 3 previous errors diff --git a/tests/ui/search_is_some.rs b/tests/ui/search_is_some.rs index e8a0920b645d1..9a9aaba56adc5 100644 --- a/tests/ui/search_is_some.rs +++ b/tests/ui/search_is_some.rs @@ -1,5 +1,6 @@ //@aux-build:option_helpers.rs #![warn(clippy::search_is_some)] +#![allow(clippy::manual_pattern_char_comparison)] #![allow(clippy::useless_vec)] #![allow(dead_code)] extern crate option_helpers; diff --git a/tests/ui/search_is_some.stderr b/tests/ui/search_is_some.stderr index b5f84d23284ac..b5ef553417701 100644 --- a/tests/ui/search_is_some.stderr +++ b/tests/ui/search_is_some.stderr @@ -1,5 +1,5 @@ error: called `is_some()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some.rs:15:13 + --> tests/ui/search_is_some.rs:16:13 | LL | let _ = v.iter().find(|&x| { | _____________^ @@ -13,7 +13,7 @@ LL | | ).is_some(); = help: to override `-D warnings` add `#[allow(clippy::search_is_some)]` error: called `is_some()` after searching an `Iterator` with `position` - --> tests/ui/search_is_some.rs:21:13 + --> tests/ui/search_is_some.rs:22:13 | LL | let _ = v.iter().position(|&x| { | _____________^ @@ -25,7 +25,7 @@ LL | | ).is_some(); = help: this is more succinctly expressed by calling `any()` error: called `is_some()` after searching an `Iterator` with `rposition` - --> tests/ui/search_is_some.rs:27:13 + --> tests/ui/search_is_some.rs:28:13 | LL | let _ = v.iter().rposition(|&x| { | _____________^ @@ -37,13 +37,13 @@ LL | | ).is_some(); = help: this is more succinctly expressed by calling `any()` error: called `is_some()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some.rs:42:20 + --> tests/ui/search_is_some.rs:43:20 | LL | let _ = (0..1).find(some_closure).is_some(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(some_closure)` error: called `is_none()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some.rs:52:13 + --> tests/ui/search_is_some.rs:53:13 | LL | let _ = v.iter().find(|&x| { | _____________^ @@ -55,7 +55,7 @@ LL | | ).is_none(); = help: this is more succinctly expressed by calling `any()` with negation error: called `is_none()` after searching an `Iterator` with `position` - --> tests/ui/search_is_some.rs:58:13 + --> tests/ui/search_is_some.rs:59:13 | LL | let _ = v.iter().position(|&x| { | _____________^ @@ -67,7 +67,7 @@ LL | | ).is_none(); = help: this is more succinctly expressed by calling `any()` with negation error: called `is_none()` after searching an `Iterator` with `rposition` - --> tests/ui/search_is_some.rs:64:13 + --> tests/ui/search_is_some.rs:65:13 | LL | let _ = v.iter().rposition(|&x| { | _____________^ @@ -79,7 +79,7 @@ LL | | ).is_none(); = help: this is more succinctly expressed by calling `any()` with negation error: called `is_none()` after searching an `Iterator` with `find` - --> tests/ui/search_is_some.rs:79:13 + --> tests/ui/search_is_some.rs:80:13 | LL | let _ = (0..1).find(some_closure).is_none(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!(0..1).any(some_closure)` diff --git a/tests/ui/single_char_add_str.fixed b/tests/ui/single_char_add_str.fixed index eafd17f538744..aef15252b1bce 100644 --- a/tests/ui/single_char_add_str.fixed +++ b/tests/ui/single_char_add_str.fixed @@ -21,6 +21,12 @@ fn main() { string.push('\u{0052}'); string.push('a'); + let c_ref = &'a'; + string.push(*c_ref); + let c = 'a'; + string.push(c); + string.push('a'); + get_string!().push('ö'); // `insert_str` tests @@ -41,5 +47,9 @@ fn main() { string.insert(Y, '"'); string.insert(Y, '\''); + string.insert(0, *c_ref); + string.insert(0, c); + string.insert(0, 'a'); + get_string!().insert(1, '?'); } diff --git a/tests/ui/single_char_add_str.rs b/tests/ui/single_char_add_str.rs index 5326c7cf24c64..7f97250dacd48 100644 --- a/tests/ui/single_char_add_str.rs +++ b/tests/ui/single_char_add_str.rs @@ -21,6 +21,12 @@ fn main() { string.push_str("\u{0052}"); string.push_str(r##"a"##); + let c_ref = &'a'; + string.push_str(&c_ref.to_string()); + let c = 'a'; + string.push_str(&c.to_string()); + string.push_str(&'a'.to_string()); + get_string!().push_str("ö"); // `insert_str` tests @@ -41,5 +47,9 @@ fn main() { string.insert_str(Y, r##"""##); string.insert_str(Y, r##"'"##); + string.insert_str(0, &c_ref.to_string()); + string.insert_str(0, &c.to_string()); + string.insert_str(0, &'a'.to_string()); + get_string!().insert_str(1, "?"); } diff --git a/tests/ui/single_char_add_str.stderr b/tests/ui/single_char_add_str.stderr index 89d75f20f55a7..7791c67578aa2 100644 --- a/tests/ui/single_char_add_str.stderr +++ b/tests/ui/single_char_add_str.stderr @@ -31,65 +31,101 @@ error: calling `push_str()` using a single-character string literal LL | string.push_str(r##"a"##); | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `push` with a character literal: `string.push('a')` +error: calling `push_str()` using a single-character converted to string + --> tests/ui/single_char_add_str.rs:25:5 + | +LL | string.push_str(&c_ref.to_string()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `push` without `to_string()`: `string.push(*c_ref)` + +error: calling `push_str()` using a single-character converted to string + --> tests/ui/single_char_add_str.rs:27:5 + | +LL | string.push_str(&c.to_string()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `push` without `to_string()`: `string.push(c)` + +error: calling `push_str()` using a single-character converted to string + --> tests/ui/single_char_add_str.rs:28:5 + | +LL | string.push_str(&'a'.to_string()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `push` without `to_string()`: `string.push('a')` + error: calling `push_str()` using a single-character string literal - --> tests/ui/single_char_add_str.rs:24:5 + --> tests/ui/single_char_add_str.rs:30:5 | LL | get_string!().push_str("ö"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `push` with a character literal: `get_string!().push('ö')` error: calling `insert_str()` using a single-character string literal - --> tests/ui/single_char_add_str.rs:29:5 + --> tests/ui/single_char_add_str.rs:35:5 | LL | string.insert_str(0, "R"); | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `insert` with a character literal: `string.insert(0, 'R')` error: calling `insert_str()` using a single-character string literal - --> tests/ui/single_char_add_str.rs:30:5 + --> tests/ui/single_char_add_str.rs:36:5 | LL | string.insert_str(1, "'"); | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `insert` with a character literal: `string.insert(1, '\'')` error: calling `insert_str()` using a single-character string literal - --> tests/ui/single_char_add_str.rs:35:5 + --> tests/ui/single_char_add_str.rs:41:5 | LL | string.insert_str(0, "\x52"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `insert` with a character literal: `string.insert(0, '\x52')` error: calling `insert_str()` using a single-character string literal - --> tests/ui/single_char_add_str.rs:36:5 + --> tests/ui/single_char_add_str.rs:42:5 | LL | string.insert_str(0, "\u{0052}"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `insert` with a character literal: `string.insert(0, '\u{0052}')` error: calling `insert_str()` using a single-character string literal - --> tests/ui/single_char_add_str.rs:38:5 + --> tests/ui/single_char_add_str.rs:44:5 | LL | string.insert_str(x, r##"a"##); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `insert` with a character literal: `string.insert(x, 'a')` error: calling `insert_str()` using a single-character string literal - --> tests/ui/single_char_add_str.rs:40:5 + --> tests/ui/single_char_add_str.rs:46:5 | LL | string.insert_str(Y, r##"a"##); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `insert` with a character literal: `string.insert(Y, 'a')` error: calling `insert_str()` using a single-character string literal - --> tests/ui/single_char_add_str.rs:41:5 + --> tests/ui/single_char_add_str.rs:47:5 | LL | string.insert_str(Y, r##"""##); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `insert` with a character literal: `string.insert(Y, '"')` error: calling `insert_str()` using a single-character string literal - --> tests/ui/single_char_add_str.rs:42:5 + --> tests/ui/single_char_add_str.rs:48:5 | LL | string.insert_str(Y, r##"'"##); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `insert` with a character literal: `string.insert(Y, '\'')` +error: calling `insert_str()` using a single-character converted to string + --> tests/ui/single_char_add_str.rs:50:5 + | +LL | string.insert_str(0, &c_ref.to_string()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `insert` without `to_string()`: `string.insert(0, *c_ref)` + +error: calling `insert_str()` using a single-character converted to string + --> tests/ui/single_char_add_str.rs:51:5 + | +LL | string.insert_str(0, &c.to_string()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `insert` without `to_string()`: `string.insert(0, c)` + +error: calling `insert_str()` using a single-character converted to string + --> tests/ui/single_char_add_str.rs:52:5 + | +LL | string.insert_str(0, &'a'.to_string()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `insert` without `to_string()`: `string.insert(0, 'a')` + error: calling `insert_str()` using a single-character string literal - --> tests/ui/single_char_add_str.rs:44:5 + --> tests/ui/single_char_add_str.rs:54:5 | LL | get_string!().insert_str(1, "?"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `insert` with a character literal: `get_string!().insert(1, '?')` -error: aborting due to 15 previous errors +error: aborting due to 21 previous errors diff --git a/tests/ui/str_to_string.fixed b/tests/ui/str_to_string.fixed new file mode 100644 index 0000000000000..52e40b45a8bdd --- /dev/null +++ b/tests/ui/str_to_string.fixed @@ -0,0 +1,9 @@ +#![warn(clippy::str_to_string)] + +fn main() { + let hello = "hello world".to_owned(); + //~^ ERROR: `to_string()` called on a `&str` + let msg = &hello[..]; + msg.to_owned(); + //~^ ERROR: `to_string()` called on a `&str` +} diff --git a/tests/ui/str_to_string.stderr b/tests/ui/str_to_string.stderr index 13b73622d6982..a761d96cd6b12 100644 --- a/tests/ui/str_to_string.stderr +++ b/tests/ui/str_to_string.stderr @@ -2,9 +2,8 @@ error: `to_string()` called on a `&str` --> tests/ui/str_to_string.rs:4:17 | LL | let hello = "hello world".to_string(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `"hello world".to_owned()` | - = help: consider using `.to_owned()` = note: `-D clippy::str-to-string` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::str_to_string)]` @@ -12,9 +11,7 @@ error: `to_string()` called on a `&str` --> tests/ui/str_to_string.rs:7:5 | LL | msg.to_string(); - | ^^^^^^^^^^^^^^^ - | - = help: consider using `.to_owned()` + | ^^^^^^^^^^^^^^^ help: try: `msg.to_owned()` error: aborting due to 2 previous errors diff --git a/tests/ui/type_repetition_in_bounds.rs b/tests/ui/type_repetition_in_bounds.rs index 0039c805b7df8..d325887bfba3f 100644 --- a/tests/ui/type_repetition_in_bounds.rs +++ b/tests/ui/type_repetition_in_bounds.rs @@ -1,5 +1,9 @@ #![deny(clippy::type_repetition_in_bounds)] -#![allow(clippy::extra_unused_type_parameters, clippy::multiple_bound_locations)] +#![allow( + clippy::extra_unused_type_parameters, + clippy::multiple_bound_locations, + clippy::needless_maybe_sized +)] use serde::Deserialize; use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Sub, SubAssign}; diff --git a/tests/ui/type_repetition_in_bounds.stderr b/tests/ui/type_repetition_in_bounds.stderr index e9c6b41aaa8ec..77944c9504579 100644 --- a/tests/ui/type_repetition_in_bounds.stderr +++ b/tests/ui/type_repetition_in_bounds.stderr @@ -1,5 +1,5 @@ error: this type has already been used as a bound predicate - --> tests/ui/type_repetition_in_bounds.rs:10:5 + --> tests/ui/type_repetition_in_bounds.rs:14:5 | LL | T: Clone, | ^^^^^^^^ @@ -12,7 +12,7 @@ LL | #![deny(clippy::type_repetition_in_bounds)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: this type has already been used as a bound predicate - --> tests/ui/type_repetition_in_bounds.rs:28:5 + --> tests/ui/type_repetition_in_bounds.rs:32:5 | LL | Self: Copy + Default + Ord, | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -20,7 +20,7 @@ LL | Self: Copy + Default + Ord, = help: consider combining the bounds: `Self: Clone + Copy + Default + Ord` error: this type has already been used as a bound predicate - --> tests/ui/type_repetition_in_bounds.rs:103:5 + --> tests/ui/type_repetition_in_bounds.rs:107:5 | LL | T: Clone, | ^^^^^^^^ @@ -28,7 +28,7 @@ LL | T: Clone, = help: consider combining the bounds: `T: ?Sized + Clone` error: this type has already been used as a bound predicate - --> tests/ui/type_repetition_in_bounds.rs:109:5 + --> tests/ui/type_repetition_in_bounds.rs:113:5 | LL | T: ?Sized, | ^^^^^^^^^ @@ -36,7 +36,7 @@ LL | T: ?Sized, = help: consider combining the bounds: `T: Clone + ?Sized` error: this type has already been used as a bound predicate - --> tests/ui/type_repetition_in_bounds.rs:135:9 + --> tests/ui/type_repetition_in_bounds.rs:139:9 | LL | T: Trait, Box<[String]>, bool> + 'static, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/unnecessary_clippy_cfg.rs b/tests/ui/unnecessary_clippy_cfg.rs index ff960520f5e72..9915f8b843efd 100644 --- a/tests/ui/unnecessary_clippy_cfg.rs +++ b/tests/ui/unnecessary_clippy_cfg.rs @@ -5,18 +5,18 @@ //~^ ERROR: no need to put clippy lints behind a `clippy` cfg #![cfg_attr(clippy, deny(dead_code, clippy::non_minimal_cfg))] //~^ ERROR: no need to put clippy lints behind a `clippy` cfg -#![cfg_attr(clippy, deny(dead_code, clippy::non_minimal_cfg, clippy::maybe_misused_cfg))] +#![cfg_attr(clippy, deny(dead_code, clippy::non_minimal_cfg))] //~^ ERROR: no need to put clippy lints behind a `clippy` cfg -#![cfg_attr(clippy, deny(clippy::non_minimal_cfg, clippy::maybe_misused_cfg))] +#![cfg_attr(clippy, deny(clippy::non_minimal_cfg))] //~^ ERROR: no need to put clippy lints behind a `clippy` cfg #[cfg_attr(clippy, deny(clippy::non_minimal_cfg))] //~^ ERROR: no need to put clippy lints behind a `clippy` cfg #[cfg_attr(clippy, deny(dead_code, clippy::non_minimal_cfg))] //~^ ERROR: no need to put clippy lints behind a `clippy` cfg -#[cfg_attr(clippy, deny(dead_code, clippy::non_minimal_cfg, clippy::maybe_misused_cfg))] +#[cfg_attr(clippy, deny(dead_code, clippy::non_minimal_cfg))] //~^ ERROR: no need to put clippy lints behind a `clippy` cfg -#[cfg_attr(clippy, deny(clippy::non_minimal_cfg, clippy::maybe_misused_cfg))] +#[cfg_attr(clippy, deny(clippy::non_minimal_cfg))] //~^ ERROR: no need to put clippy lints behind a `clippy` cfg pub struct Bar; diff --git a/tests/ui/unnecessary_clippy_cfg.stderr b/tests/ui/unnecessary_clippy_cfg.stderr index 3d58c9eb5daec..16a8616529565 100644 --- a/tests/ui/unnecessary_clippy_cfg.stderr +++ b/tests/ui/unnecessary_clippy_cfg.stderr @@ -18,16 +18,16 @@ LL | #[cfg_attr(clippy, deny(dead_code, clippy::non_minimal_cfg))] error: no need to put clippy lints behind a `clippy` cfg --> tests/ui/unnecessary_clippy_cfg.rs:17:36 | -LL | #[cfg_attr(clippy, deny(dead_code, clippy::non_minimal_cfg, clippy::maybe_misused_cfg))] - | ^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[cfg_attr(clippy, deny(dead_code, clippy::non_minimal_cfg))] + | ^^^^^^^^^^^^^^^^^^^^^^^ | - = note: write instead: `#[deny(clippy::non_minimal_cfg,clippy::maybe_misused_cfg)]` + = note: write instead: `#[deny(clippy::non_minimal_cfg)]` error: no need to put clippy lints behind a `clippy` cfg --> tests/ui/unnecessary_clippy_cfg.rs:19:1 | -LL | #[cfg_attr(clippy, deny(clippy::non_minimal_cfg, clippy::maybe_misused_cfg))] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `#[deny(clippy::non_minimal_cfg, clippy::maybe_misused_cfg)]` +LL | #[cfg_attr(clippy, deny(clippy::non_minimal_cfg))] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `#[deny(clippy::non_minimal_cfg)]` error: no need to put clippy lints behind a `clippy` cfg --> tests/ui/unnecessary_clippy_cfg.rs:4:1 @@ -46,21 +46,21 @@ LL | #![cfg_attr(clippy, deny(dead_code, clippy::non_minimal_cfg))] error: no need to put clippy lints behind a `clippy` cfg --> tests/ui/unnecessary_clippy_cfg.rs:8:37 | -LL | #![cfg_attr(clippy, deny(dead_code, clippy::non_minimal_cfg, clippy::maybe_misused_cfg))] - | ^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #![cfg_attr(clippy, deny(dead_code, clippy::non_minimal_cfg))] + | ^^^^^^^^^^^^^^^^^^^^^^^ | - = note: write instead: `#![deny(clippy::non_minimal_cfg,clippy::maybe_misused_cfg)]` + = note: write instead: `#![deny(clippy::non_minimal_cfg)]` error: no need to put clippy lints behind a `clippy` cfg --> tests/ui/unnecessary_clippy_cfg.rs:10:1 | -LL | #![cfg_attr(clippy, deny(clippy::non_minimal_cfg, clippy::maybe_misused_cfg))] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `#![deny(clippy::non_minimal_cfg, clippy::maybe_misused_cfg)]` +LL | #![cfg_attr(clippy, deny(clippy::non_minimal_cfg))] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `#![deny(clippy::non_minimal_cfg)]` error: duplicated attribute --> tests/ui/unnecessary_clippy_cfg.rs:8:26 | -LL | #![cfg_attr(clippy, deny(dead_code, clippy::non_minimal_cfg, clippy::maybe_misused_cfg))] +LL | #![cfg_attr(clippy, deny(dead_code, clippy::non_minimal_cfg))] | ^^^^^^^^^ | note: first defined here @@ -71,7 +71,7 @@ LL | #![cfg_attr(clippy, deny(dead_code, clippy::non_minimal_cfg))] help: remove this attribute --> tests/ui/unnecessary_clippy_cfg.rs:8:26 | -LL | #![cfg_attr(clippy, deny(dead_code, clippy::non_minimal_cfg, clippy::maybe_misused_cfg))] +LL | #![cfg_attr(clippy, deny(dead_code, clippy::non_minimal_cfg))] | ^^^^^^^^^ = note: `-D clippy::duplicated-attributes` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::duplicated_attributes)]` @@ -79,7 +79,7 @@ LL | #![cfg_attr(clippy, deny(dead_code, clippy::non_minimal_cfg, clippy::maybe_ error: duplicated attribute --> tests/ui/unnecessary_clippy_cfg.rs:17:25 | -LL | #[cfg_attr(clippy, deny(dead_code, clippy::non_minimal_cfg, clippy::maybe_misused_cfg))] +LL | #[cfg_attr(clippy, deny(dead_code, clippy::non_minimal_cfg))] | ^^^^^^^^^ | note: first defined here @@ -90,7 +90,7 @@ LL | #[cfg_attr(clippy, deny(dead_code, clippy::non_minimal_cfg))] help: remove this attribute --> tests/ui/unnecessary_clippy_cfg.rs:17:25 | -LL | #[cfg_attr(clippy, deny(dead_code, clippy::non_minimal_cfg, clippy::maybe_misused_cfg))] +LL | #[cfg_attr(clippy, deny(dead_code, clippy::non_minimal_cfg))] | ^^^^^^^^^ error: aborting due to 10 previous errors diff --git a/tests/ui/unwrap_in_result.rs b/tests/ui/unwrap_in_result.rs index a19db46c667d0..62c6d959c84b6 100644 --- a/tests/ui/unwrap_in_result.rs +++ b/tests/ui/unwrap_in_result.rs @@ -38,6 +38,11 @@ impl A { } None } + + fn in_closure(a: Option) -> Option { + let c = || a.unwrap(); + Some(c()) + } } fn main() { diff --git a/tests/ui/unwrap_in_result.stderr b/tests/ui/unwrap_in_result.stderr index 29c7a9373aa7b..752177aaca57e 100644 --- a/tests/ui/unwrap_in_result.stderr +++ b/tests/ui/unwrap_in_result.stderr @@ -38,5 +38,21 @@ note: potential non-recoverable error(s) LL | let i = i_str.parse::().expect("not a number"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 2 previous errors +error: used unwrap or expect in a function that returns result or option + --> tests/ui/unwrap_in_result.rs:42:5 + | +LL | / fn in_closure(a: Option) -> Option { +LL | | let c = || a.unwrap(); +LL | | Some(c()) +LL | | } + | |_____^ + | + = help: unwrap and expect should not be used in a function that returns result or option +note: potential non-recoverable error(s) + --> tests/ui/unwrap_in_result.rs:43:20 + | +LL | let c = || a.unwrap(); + | ^^^^^^^^^^ + +error: aborting due to 3 previous errors diff --git a/tests/ui/useless_conversion_try.rs b/tests/ui/useless_conversion_try.rs index 803d3b39f375d..23edeae12b83a 100644 --- a/tests/ui/useless_conversion_try.rs +++ b/tests/ui/useless_conversion_try.rs @@ -1,5 +1,9 @@ #![deny(clippy::useless_conversion)] -#![allow(clippy::needless_if, clippy::unnecessary_fallible_conversions)] +#![allow( + clippy::needless_if, + clippy::unnecessary_fallible_conversions, + clippy::manual_unwrap_or_default +)] fn test_generic(val: T) -> T { let _ = T::try_from(val).unwrap(); diff --git a/tests/ui/useless_conversion_try.stderr b/tests/ui/useless_conversion_try.stderr index 11fb8f38ea5c2..30a43629dbd6a 100644 --- a/tests/ui/useless_conversion_try.stderr +++ b/tests/ui/useless_conversion_try.stderr @@ -1,5 +1,5 @@ error: useless conversion to the same type: `T` - --> tests/ui/useless_conversion_try.rs:5:13 + --> tests/ui/useless_conversion_try.rs:9:13 | LL | let _ = T::try_from(val).unwrap(); | ^^^^^^^^^^^^^^^^ @@ -12,7 +12,7 @@ LL | #![deny(clippy::useless_conversion)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: useless conversion to the same type: `T` - --> tests/ui/useless_conversion_try.rs:7:5 + --> tests/ui/useless_conversion_try.rs:11:5 | LL | val.try_into().unwrap() | ^^^^^^^^^^^^^^ @@ -20,7 +20,7 @@ LL | val.try_into().unwrap() = help: consider removing `.try_into()` error: useless conversion to the same type: `std::string::String` - --> tests/ui/useless_conversion_try.rs:30:21 + --> tests/ui/useless_conversion_try.rs:34:21 | LL | let _: String = "foo".to_string().try_into().unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -28,7 +28,7 @@ LL | let _: String = "foo".to_string().try_into().unwrap(); = help: consider removing `.try_into()` error: useless conversion to the same type: `std::string::String` - --> tests/ui/useless_conversion_try.rs:32:21 + --> tests/ui/useless_conversion_try.rs:36:21 | LL | let _: String = TryFrom::try_from("foo".to_string()).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -36,7 +36,7 @@ LL | let _: String = TryFrom::try_from("foo".to_string()).unwrap(); = help: consider removing `TryFrom::try_from()` error: useless conversion to the same type: `std::string::String` - --> tests/ui/useless_conversion_try.rs:34:13 + --> tests/ui/useless_conversion_try.rs:38:13 | LL | let _ = String::try_from("foo".to_string()).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -44,7 +44,7 @@ LL | let _ = String::try_from("foo".to_string()).unwrap(); = help: consider removing `String::try_from()` error: useless conversion to the same type: `std::string::String` - --> tests/ui/useless_conversion_try.rs:36:13 + --> tests/ui/useless_conversion_try.rs:40:13 | LL | let _ = String::try_from(format!("A: {:04}", 123)).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -52,7 +52,7 @@ LL | let _ = String::try_from(format!("A: {:04}", 123)).unwrap(); = help: consider removing `String::try_from()` error: useless conversion to the same type: `std::string::String` - --> tests/ui/useless_conversion_try.rs:38:21 + --> tests/ui/useless_conversion_try.rs:42:21 | LL | let _: String = format!("Hello {}", "world").try_into().unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -60,7 +60,7 @@ LL | let _: String = format!("Hello {}", "world").try_into().unwrap(); = help: consider removing `.try_into()` error: useless conversion to the same type: `std::string::String` - --> tests/ui/useless_conversion_try.rs:40:21 + --> tests/ui/useless_conversion_try.rs:44:21 | LL | let _: String = String::new().try_into().unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -68,7 +68,7 @@ LL | let _: String = String::new().try_into().unwrap(); = help: consider removing `.try_into()` error: useless conversion to the same type: `std::string::String` - --> tests/ui/useless_conversion_try.rs:42:27 + --> tests/ui/useless_conversion_try.rs:46:27 | LL | let _: String = match String::from("_").try_into() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/util/gh-pages/script.js b/util/gh-pages/script.js index 7fd779fe9a46e..7cca298df8e45 100644 --- a/util/gh-pages/script.js +++ b/util/gh-pages/script.js @@ -397,7 +397,7 @@ $scope.bySearch = function (lint, index, array) { let searchStr = $scope.search; // It can be `null` I haven't missed this value - if (searchStr == null || searchStr.length < 3) { + if (searchStr == null) { return true; } searchStr = searchStr.toLowerCase(); From fa9274c99be32c48ca118bab7af621b637b9be5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 12 Jun 2024 23:51:31 +0000 Subject: [PATCH 176/892] Tweak output of import suggestions When both `std::` and `core::` items are available, only suggest the `std::` ones. We ensure that in `no_std` crates we suggest `core::` items. Ensure that the list of items suggested to be imported are always in the order of local crate items, `std`/`core` items and finally foreign crate items. Tweak wording of import suggestion: if there are multiple items but they are all of the same kind, we use the kind name and not the generic "items". Fix #83564. --- tests/ui/crashes/ice-6252.stderr | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/tests/ui/crashes/ice-6252.stderr b/tests/ui/crashes/ice-6252.stderr index ce3b9495eb1ea..cd2031af1c6da 100644 --- a/tests/ui/crashes/ice-6252.stderr +++ b/tests/ui/crashes/ice-6252.stderr @@ -4,9 +4,7 @@ error[E0412]: cannot find type `PhantomData` in this scope LL | _n: PhantomData, | ^^^^^^^^^^^ not found in this scope | -help: consider importing one of these items - | -LL + use core::marker::PhantomData; +help: consider importing this struct | LL + use std::marker::PhantomData; | From d3f1618a73d3f14bfdd28d62c1d933755ccbad3e Mon Sep 17 00:00:00 2001 From: Pietro Albini Date: Fri, 14 Jun 2024 12:02:45 +0200 Subject: [PATCH 177/892] fix python bootstrap tests requiring a downloaded stage0 --- src/bootstrap/bootstrap_test.py | 19 +++++++++++++++++++ src/bootstrap/src/core/build_steps/test.rs | 2 ++ 2 files changed, 21 insertions(+) diff --git a/src/bootstrap/bootstrap_test.py b/src/bootstrap/bootstrap_test.py index 6da410ed2f279..706f2c5bf0701 100644 --- a/src/bootstrap/bootstrap_test.py +++ b/src/bootstrap/bootstrap_test.py @@ -138,6 +138,25 @@ def build_args(self, configure_args=None, args=None, env=None): if env is None: env = {} + # This test ends up invoking build_bootstrap_cmd, which searches for + # the Cargo binary and errors out if it cannot be found. This is not a + # problem in most cases, but there is a scenario where it would cause + # the test to fail. + # + # When a custom local Cargo is configured in config.toml (with the + # build.cargo setting), no Cargo is downloaded to any location known by + # bootstrap, and bootstrap relies on that setting to find it. + # + # In this test though we are not using the config.toml of the caller: + # we are generating a blank one instead. If we don't set build.cargo in + # it, the test will have no way to find Cargo, failing the test. + cargo_bin = os.environ.get("BOOTSTRAP_TEST_CARGO_BIN") + if cargo_bin is not None: + configure_args += ["--set", "build.cargo=" + cargo_bin] + rustc_bin = os.environ.get("BOOTSTRAP_TEST_RUSTC_BIN") + if rustc_bin is not None: + configure_args += ["--set", "build.rustc=" + rustc_bin] + env = env.copy() env["PATH"] = os.environ["PATH"] diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index 29cd90222b255..22a3f1efa2999 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -3040,6 +3040,8 @@ impl Step for Bootstrap { .args(["-m", "unittest", "bootstrap_test.py"]) .env("BUILD_DIR", &builder.out) .env("BUILD_PLATFORM", builder.build.build.triple) + .env("BOOTSTRAP_TEST_RUSTC_BIN", &builder.initial_rustc) + .env("BOOTSTRAP_TEST_CARGO_BIN", &builder.initial_cargo) .current_dir(builder.src.join("src/bootstrap/")); // NOTE: we intentionally don't pass test_args here because the args for unittest and cargo test are mutually incompatible. // Use `python -m unittest` manually if you want to pass arguments. From fcb6ff5171fd41c988a6c449f76ff34c2c2d5a43 Mon Sep 17 00:00:00 2001 From: Pietro Albini Date: Fri, 14 Jun 2024 12:34:22 +0200 Subject: [PATCH 178/892] fix rust bootstrap tests requiring a downloaded stage0 --- src/bootstrap/src/core/config/config.rs | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs index 36b44d0169c9c..6664c5b451c87 100644 --- a/src/bootstrap/src/core/config/config.rs +++ b/src/bootstrap/src/core/config/config.rs @@ -1189,7 +1189,19 @@ impl Config { pub fn parse(args: &[String]) -> Config { #[cfg(test)] fn get_toml(_: &Path) -> TomlConfig { - TomlConfig::default() + let mut default = TomlConfig::default(); + + // When configuring bootstrap for tests, make sure to set the rustc and Cargo to the + // same ones used to call the tests. If we don't do that, bootstrap will use its own + // detection logic to find a suitable rustc and Cargo, which doesn't work when the + // caller is specìfying a custom local rustc or Cargo in their config.toml. + default.build = Some(Build { + rustc: std::env::var_os("RUSTC").map(|v| v.into()), + cargo: std::env::var_os("CARGO").map(|v| v.into()), + ..Build::default() + }); + + default } #[cfg(not(test))] From 82f0dc95a00bfc1adb395f30f8d9c242fc53db37 Mon Sep 17 00:00:00 2001 From: DaniPopes <57450786+DaniPopes@users.noreply.github.com> Date: Fri, 14 Jun 2024 14:37:11 +0200 Subject: [PATCH 179/892] [`missing_const_for_fn`]: add machine-applicable suggestion --- clippy_lints/src/missing_const_for_fn.rs | 24 ++- .../missing_const_for_fn/could_be_const.fixed | 173 ++++++++++++++++++ .../could_be_const.stderr | 84 +++++++++ 3 files changed, 275 insertions(+), 6 deletions(-) create mode 100644 tests/ui/missing_const_for_fn/could_be_const.fixed diff --git a/clippy_lints/src/missing_const_for_fn.rs b/clippy_lints/src/missing_const_for_fn.rs index 4592324809fa2..bb0d714a31fd4 100644 --- a/clippy_lints/src/missing_const_for_fn.rs +++ b/clippy_lints/src/missing_const_for_fn.rs @@ -1,11 +1,11 @@ use clippy_config::msrvs::{self, Msrv}; -use clippy_utils::diagnostics::span_lint; +use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::qualify_min_const_fn::is_min_const_fn; use clippy_utils::{fn_has_unsatisfiable_preds, is_entrypoint_fn, is_from_proc_macro, trait_ref_of_method}; -use rustc_hir as hir; +use rustc_errors::Applicability; use rustc_hir::def_id::CRATE_DEF_ID; use rustc_hir::intravisit::FnKind; -use rustc_hir::{Body, Constness, FnDecl, GenericParamKind}; +use rustc_hir::{self as hir, Body, Constness, FnDecl, GenericParamKind}; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::lint::in_external_macro; use rustc_session::impl_lint_pass; @@ -120,7 +120,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingConstForFn { } }, FnKind::Method(_, sig, ..) => { - if trait_ref_of_method(cx, def_id).is_some() || already_const(sig.header) { + if already_const(sig.header) || trait_ref_of_method(cx, def_id).is_some() { return; } }, @@ -147,10 +147,22 @@ impl<'tcx> LateLintPass<'tcx> for MissingConstForFn { let mir = cx.tcx.optimized_mir(def_id); - if let Ok(()) = is_min_const_fn(cx.tcx, mir, &self.msrv) { - span_lint(cx, MISSING_CONST_FOR_FN, span, "this could be a `const fn`"); + if let Ok(()) = is_min_const_fn(cx.tcx, mir, &self.msrv) + && let hir::Node::Item(hir::Item { vis_span, .. }) | hir::Node::ImplItem(hir::ImplItem { vis_span, .. }) = + cx.tcx.hir_node_by_def_id(def_id) + { + let suggestion = if vis_span.is_empty() { "const " } else { " const" }; + span_lint_and_then(cx, MISSING_CONST_FOR_FN, span, "this could be a `const fn`", |diag| { + diag.span_suggestion_verbose( + vis_span.shrink_to_hi(), + "make the function `const`", + suggestion, + Applicability::MachineApplicable, + ); + }); } } + extract_msrv_attr!(LateContext); } diff --git a/tests/ui/missing_const_for_fn/could_be_const.fixed b/tests/ui/missing_const_for_fn/could_be_const.fixed new file mode 100644 index 0000000000000..921dcf0b16261 --- /dev/null +++ b/tests/ui/missing_const_for_fn/could_be_const.fixed @@ -0,0 +1,173 @@ +#![warn(clippy::missing_const_for_fn)] +#![allow(incomplete_features, clippy::let_and_return, clippy::missing_transmute_annotations)] +#![feature(const_mut_refs)] +#![feature(const_trait_impl)] + +use std::mem::transmute; + +struct Game { + guess: i32, +} + +impl Game { + // Could be const + pub const fn new() -> Self { + //~^ ERROR: this could be a `const fn` + //~| NOTE: `-D clippy::missing-const-for-fn` implied by `-D warnings` + Self { guess: 42 } + } + + const fn const_generic_params<'a, T, const N: usize>(&self, b: &'a [T; N]) -> &'a [T; N] { + //~^ ERROR: this could be a `const fn` + b + } +} + +// Could be const +const fn one() -> i32 { + //~^ ERROR: this could be a `const fn` + 1 +} + +// Could also be const +const fn two() -> i32 { + //~^ ERROR: this could be a `const fn` + let abc = 2; + abc +} + +// Could be const (since Rust 1.39) +const fn string() -> String { + //~^ ERROR: this could be a `const fn` + String::new() +} + +// Could be const +const unsafe fn four() -> i32 { + //~^ ERROR: this could be a `const fn` + 4 +} + +// Could also be const +const fn generic(t: T) -> T { + //~^ ERROR: this could be a `const fn` + t +} + +fn sub(x: u32) -> usize { + unsafe { transmute(&x) } +} + +const fn generic_arr(t: [T; 1]) -> T { + //~^ ERROR: this could be a `const fn` + t[0] +} + +mod with_drop { + pub struct A; + pub struct B; + impl Drop for A { + fn drop(&mut self) {} + } + + impl B { + // This can be const, because `a` is passed by reference + pub const fn b(self, a: &A) -> B { + //~^ ERROR: this could be a `const fn` + B + } + } +} + +#[clippy::msrv = "1.47.0"] +mod const_fn_stabilized_before_msrv { + // This could be const because `u8::is_ascii_digit` is a stable const function in 1.47. + const fn const_fn_stabilized_before_msrv(byte: u8) { + //~^ ERROR: this could be a `const fn` + byte.is_ascii_digit(); + } +} + +#[clippy::msrv = "1.45"] +fn msrv_1_45() -> i32 { + 45 +} + +#[clippy::msrv = "1.46"] +const fn msrv_1_46() -> i32 { + //~^ ERROR: this could be a `const fn` + 46 +} + +// Should not be const +fn main() {} + +struct D; + +impl const Drop for D { + fn drop(&mut self) { + todo!(); + } +} + +// Lint this, since it can be dropped in const contexts +// FIXME(effects) +fn d(this: D) {} + +mod msrv { + struct Foo(*const u8, &'static u8); + + impl Foo { + #[clippy::msrv = "1.58"] + const fn deref_ptr_can_be_const(self) -> usize { + //~^ ERROR: this could be a `const fn` + unsafe { *self.0 as usize } + } + + const fn deref_copied_val(self) -> usize { + //~^ ERROR: this could be a `const fn` + *self.1 as usize + } + } + + union Bar { + val: u8, + } + + #[clippy::msrv = "1.56"] + const fn union_access_can_be_const() { + //~^ ERROR: this could be a `const fn` + let bar = Bar { val: 1 }; + let _ = unsafe { bar.val }; + } +} + +mod issue12677 { + pub struct Wrapper { + pub strings: Vec, + } + + impl Wrapper { + #[must_use] + pub const fn new(strings: Vec) -> Self { + Self { strings } + } + + #[must_use] + pub const fn empty() -> Self { + Self { strings: Vec::new() } + } + } + + pub struct Other { + pub text: String, + pub vec: Vec, + } + + impl Other { + pub const fn new(text: String) -> Self { + let vec = Vec::new(); + Self { text, vec } + } + } +} diff --git a/tests/ui/missing_const_for_fn/could_be_const.stderr b/tests/ui/missing_const_for_fn/could_be_const.stderr index 1c61c3e871324..8999af761e314 100644 --- a/tests/ui/missing_const_for_fn/could_be_const.stderr +++ b/tests/ui/missing_const_for_fn/could_be_const.stderr @@ -10,6 +10,10 @@ LL | | } | = note: `-D clippy::missing-const-for-fn` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::missing_const_for_fn)]` +help: make the function `const` + | +LL | pub const fn new() -> Self { + | +++++ error: this could be a `const fn` --> tests/ui/missing_const_for_fn/could_be_const.rs:20:5 @@ -19,6 +23,11 @@ LL | | LL | | b LL | | } | |_____^ + | +help: make the function `const` + | +LL | const fn const_generic_params<'a, T, const N: usize>(&self, b: &'a [T; N]) -> &'a [T; N] { + | +++++ error: this could be a `const fn` --> tests/ui/missing_const_for_fn/could_be_const.rs:27:1 @@ -28,6 +37,11 @@ LL | | LL | | 1 LL | | } | |_^ + | +help: make the function `const` + | +LL | const fn one() -> i32 { + | +++++ error: this could be a `const fn` --> tests/ui/missing_const_for_fn/could_be_const.rs:33:1 @@ -38,6 +52,11 @@ LL | | let abc = 2; LL | | abc LL | | } | |_^ + | +help: make the function `const` + | +LL | const fn two() -> i32 { + | +++++ error: this could be a `const fn` --> tests/ui/missing_const_for_fn/could_be_const.rs:40:1 @@ -47,6 +66,11 @@ LL | | LL | | String::new() LL | | } | |_^ + | +help: make the function `const` + | +LL | const fn string() -> String { + | +++++ error: this could be a `const fn` --> tests/ui/missing_const_for_fn/could_be_const.rs:46:1 @@ -56,6 +80,11 @@ LL | | LL | | 4 LL | | } | |_^ + | +help: make the function `const` + | +LL | const unsafe fn four() -> i32 { + | +++++ error: this could be a `const fn` --> tests/ui/missing_const_for_fn/could_be_const.rs:52:1 @@ -65,6 +94,11 @@ LL | | LL | | t LL | | } | |_^ + | +help: make the function `const` + | +LL | const fn generic(t: T) -> T { + | +++++ error: this could be a `const fn` --> tests/ui/missing_const_for_fn/could_be_const.rs:61:1 @@ -74,6 +108,11 @@ LL | | LL | | t[0] LL | | } | |_^ + | +help: make the function `const` + | +LL | const fn generic_arr(t: [T; 1]) -> T { + | +++++ error: this could be a `const fn` --> tests/ui/missing_const_for_fn/could_be_const.rs:75:9 @@ -83,6 +122,11 @@ LL | | LL | | B LL | | } | |_________^ + | +help: make the function `const` + | +LL | pub const fn b(self, a: &A) -> B { + | +++++ error: this could be a `const fn` --> tests/ui/missing_const_for_fn/could_be_const.rs:85:5 @@ -92,6 +136,11 @@ LL | | LL | | byte.is_ascii_digit(); LL | | } | |_____^ + | +help: make the function `const` + | +LL | const fn const_fn_stabilized_before_msrv(byte: u8) { + | +++++ error: this could be a `const fn` --> tests/ui/missing_const_for_fn/could_be_const.rs:97:1 @@ -101,6 +150,11 @@ LL | | LL | | 46 LL | | } | |_^ + | +help: make the function `const` + | +LL | const fn msrv_1_46() -> i32 { + | +++++ error: this could be a `const fn` --> tests/ui/missing_const_for_fn/could_be_const.rs:122:9 @@ -110,6 +164,11 @@ LL | | LL | | unsafe { *self.0 as usize } LL | | } | |_________^ + | +help: make the function `const` + | +LL | const fn deref_ptr_can_be_const(self) -> usize { + | +++++ error: this could be a `const fn` --> tests/ui/missing_const_for_fn/could_be_const.rs:127:9 @@ -119,6 +178,11 @@ LL | | LL | | *self.1 as usize LL | | } | |_________^ + | +help: make the function `const` + | +LL | const fn deref_copied_val(self) -> usize { + | +++++ error: this could be a `const fn` --> tests/ui/missing_const_for_fn/could_be_const.rs:138:5 @@ -129,6 +193,11 @@ LL | | let bar = Bar { val: 1 }; LL | | let _ = unsafe { bar.val }; LL | | } | |_____^ + | +help: make the function `const` + | +LL | const fn union_access_can_be_const() { + | +++++ error: this could be a `const fn` --> tests/ui/missing_const_for_fn/could_be_const.rs:152:9 @@ -137,6 +206,11 @@ LL | / pub fn new(strings: Vec) -> Self { LL | | Self { strings } LL | | } | |_________^ + | +help: make the function `const` + | +LL | pub const fn new(strings: Vec) -> Self { + | +++++ error: this could be a `const fn` --> tests/ui/missing_const_for_fn/could_be_const.rs:157:9 @@ -145,6 +219,11 @@ LL | / pub fn empty() -> Self { LL | | Self { strings: Vec::new() } LL | | } | |_________^ + | +help: make the function `const` + | +LL | pub const fn empty() -> Self { + | +++++ error: this could be a `const fn` --> tests/ui/missing_const_for_fn/could_be_const.rs:168:9 @@ -154,6 +233,11 @@ LL | | let vec = Vec::new(); LL | | Self { text, vec } LL | | } | |_________^ + | +help: make the function `const` + | +LL | pub const fn new(text: String) -> Self { + | +++++ error: aborting due to 17 previous errors From c86767797182c7a4ff0e7644a42fb2a93e0ef422 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 14 Jun 2024 14:46:32 -0400 Subject: [PATCH 180/892] Use is_lang_item more aggressively --- src/inline_asm.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/inline_asm.rs b/src/inline_asm.rs index 2de804f5e0423..c6b26dd873bdc 100644 --- a/src/inline_asm.rs +++ b/src/inline_asm.rs @@ -4,6 +4,7 @@ use std::fmt::Write; use cranelift_codegen::isa::CallConv; use rustc_ast::ast::{InlineAsmOptions, InlineAsmTemplatePiece}; +use rustc_hir::LangItem; use rustc_span::sym; use rustc_target::asm::*; use target_lexicon::BinaryFormat; @@ -927,7 +928,7 @@ fn call_inline_asm<'tcx>( fn asm_clif_type<'tcx>(fx: &FunctionCx<'_, '_, 'tcx>, ty: Ty<'tcx>) -> Option { match ty.kind() { // Adapted from https://github.com/rust-lang/rust/blob/f3c66088610c1b80110297c2d9a8b5f9265b013f/compiler/rustc_hir_analysis/src/check/intrinsicck.rs#L136-L151 - ty::Adt(adt, args) if Some(adt.did()) == fx.tcx.lang_items().maybe_uninit() => { + ty::Adt(adt, args) if fx.tcx.is_lang_item(adt.did(), LangItem::MaybeUninit) => { let fields = &adt.non_enum_variant().fields; let ty = fields[FieldIdx::from_u32(1)].ty(fx.tcx, args); let ty::Adt(ty, args) = ty.kind() else { From 5ccfa787fd26da2e4fb5f4c6dca89c84342716ef Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 14 Jun 2024 20:35:45 -0400 Subject: [PATCH 181/892] Only compute vtable information during codegen --- src/unsize.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/unsize.rs b/src/unsize.rs index 4acbc8a27edb9..967aa53abbda5 100644 --- a/src/unsize.rs +++ b/src/unsize.rs @@ -39,8 +39,7 @@ pub(crate) fn unsized_info<'tcx>( } // trait upcasting coercion - let vptr_entry_idx = - fx.tcx.vtable_trait_upcasting_coercion_new_vptr_slot((source, target)); + let vptr_entry_idx = fx.tcx.supertrait_vtable_slot((source, target)); if let Some(entry_idx) = vptr_entry_idx { let entry_idx = u32::try_from(entry_idx).unwrap(); From 477b0c6a78328656d4223cfdcfda2c8a05cbbe9c Mon Sep 17 00:00:00 2001 From: Alex Macleod Date: Tue, 1 Nov 2022 14:42:20 +0000 Subject: [PATCH 182/892] lintcheck: Add JSON output, diff subcommand --- lintcheck/Cargo.toml | 2 + lintcheck/src/config.rs | 37 +++++++-- lintcheck/src/json.rs | 122 +++++++++++++++++++++++++++++ lintcheck/src/main.rs | 167 +++++++++++++++++++++++++--------------- 4 files changed, 261 insertions(+), 67 deletions(-) create mode 100644 lintcheck/src/json.rs diff --git a/lintcheck/Cargo.toml b/lintcheck/Cargo.toml index 8c5a409e25b15..623af922e2a8c 100644 --- a/lintcheck/Cargo.toml +++ b/lintcheck/Cargo.toml @@ -16,11 +16,13 @@ cargo_metadata = "0.15.3" clap = { version = "4.4", features = ["derive", "env"] } crates_io_api = "0.8.1" crossbeam-channel = "0.5.6" +diff = "0.1.13" flate2 = "1.0" indicatif = "0.17.3" rayon = "1.5.1" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0.85" +strip-ansi-escapes = "0.1.1" tar = "0.4" toml = "0.7.3" ureq = "2.2" diff --git a/lintcheck/src/config.rs b/lintcheck/src/config.rs index 3f712f453fa0a..c3540bbe4ce7a 100644 --- a/lintcheck/src/config.rs +++ b/lintcheck/src/config.rs @@ -1,8 +1,9 @@ -use clap::Parser; +use clap::{Parser, Subcommand, ValueEnum}; use std::num::NonZero; use std::path::PathBuf; -#[derive(Clone, Debug, Parser)] +#[derive(Parser, Clone, Debug)] +#[command(args_conflicts_with_subcommands = true)] pub(crate) struct LintcheckConfig { /// Number of threads to use (default: all unless --fix or --recursive) #[clap( @@ -35,12 +36,36 @@ pub(crate) struct LintcheckConfig { /// Apply a filter to only collect specified lints, this also overrides `allow` attributes #[clap(long = "filter", value_name = "clippy_lint_name", use_value_delimiter = true)] pub lint_filter: Vec, - /// Change the reports table to use markdown links - #[clap(long)] - pub markdown: bool, + /// Set the output format of the log file + #[clap(long, short, default_value = "text")] + pub format: OutputFormat, /// Run clippy on the dependencies of crates specified in crates-toml #[clap(long, conflicts_with("max_jobs"))] pub recursive: bool, + #[command(subcommand)] + pub subcommand: Option, +} + +#[derive(Subcommand, Clone, Debug)] +pub(crate) enum Commands { + Diff { old: PathBuf, new: PathBuf }, +} + +#[derive(ValueEnum, Debug, Clone, Copy, PartialEq, Eq)] +pub(crate) enum OutputFormat { + Text, + Markdown, + Json, +} + +impl OutputFormat { + fn file_extension(self) -> &'static str { + match self { + OutputFormat::Text => "txt", + OutputFormat::Markdown => "md", + OutputFormat::Json => "json", + } + } } impl LintcheckConfig { @@ -53,7 +78,7 @@ impl LintcheckConfig { config.lintcheck_results_path = PathBuf::from(format!( "lintcheck-logs/{}_logs.{}", filename.display(), - if config.markdown { "md" } else { "txt" } + config.format.file_extension(), )); // look at the --threads arg, if 0 is passed, use the threads count diff --git a/lintcheck/src/json.rs b/lintcheck/src/json.rs new file mode 100644 index 0000000000000..43d0413c7ceeb --- /dev/null +++ b/lintcheck/src/json.rs @@ -0,0 +1,122 @@ +use std::collections::HashMap; +use std::fmt::Write; +use std::fs; +use std::hash::Hash; +use std::path::Path; + +use crate::ClippyWarning; + +/// Creates the log file output for [`crate::config::OutputFormat::Json`] +pub(crate) fn output(clippy_warnings: &[ClippyWarning]) -> String { + serde_json::to_string(&clippy_warnings).unwrap() +} + +fn load_warnings(path: &Path) -> Vec { + let file = fs::read(path).unwrap_or_else(|e| panic!("failed to read {}: {e}", path.display())); + + serde_json::from_slice(&file).unwrap_or_else(|e| panic!("failed to deserialize {}: {e}", path.display())) +} + +/// Group warnings by their primary span location + lint name +fn create_map(warnings: &[ClippyWarning]) -> HashMap> { + let mut map = HashMap::<_, Vec<_>>::with_capacity(warnings.len()); + + for warning in warnings { + let span = warning.span(); + let key = (&warning.lint_type, &span.file_name, span.byte_start, span.byte_end); + + map.entry(key).or_default().push(warning); + } + + map +} + +fn print_warnings(title: &str, warnings: &[&ClippyWarning]) { + if warnings.is_empty() { + return; + } + + println!("### {title}"); + println!("```"); + for warning in warnings { + print!("{}", warning.diag); + } + println!("```"); +} + +fn print_changed_diff(changed: &[(&[&ClippyWarning], &[&ClippyWarning])]) { + fn render(warnings: &[&ClippyWarning]) -> String { + let mut rendered = String::new(); + for warning in warnings { + write!(&mut rendered, "{}", warning.diag).unwrap(); + } + rendered + } + + if changed.is_empty() { + return; + } + + println!("### Changed"); + println!("```diff"); + for &(old, new) in changed { + let old_rendered = render(old); + let new_rendered = render(new); + + for change in diff::lines(&old_rendered, &new_rendered) { + use diff::Result::{Both, Left, Right}; + + match change { + Both(unchanged, _) => { + println!(" {unchanged}"); + }, + Left(removed) => { + println!("-{removed}"); + }, + Right(added) => { + println!("+{added}"); + }, + } + } + } + println!("```"); +} + +pub(crate) fn diff(old_path: &Path, new_path: &Path) { + let old_warnings = load_warnings(old_path); + let new_warnings = load_warnings(new_path); + + let old_map = create_map(&old_warnings); + let new_map = create_map(&new_warnings); + + let mut added = Vec::new(); + let mut removed = Vec::new(); + let mut changed = Vec::new(); + + for (key, new) in &new_map { + if let Some(old) = old_map.get(key) { + if old != new { + changed.push((old.as_slice(), new.as_slice())); + } + } else { + added.extend(new); + } + } + + for (key, old) in &old_map { + if !new_map.contains_key(key) { + removed.extend(old); + } + } + + print!( + "{} added, {} removed, {} changed\n\n", + added.len(), + removed.len(), + changed.len() + ); + + print_warnings("Added", &added); + print_warnings("Removed", &removed); + print_changed_diff(&changed); +} diff --git a/lintcheck/src/main.rs b/lintcheck/src/main.rs index deb06094d83bd..985df9647d829 100644 --- a/lintcheck/src/main.rs +++ b/lintcheck/src/main.rs @@ -12,18 +12,20 @@ unused_lifetimes, unused_qualifications )] -#![allow(clippy::collapsible_else_if)] +#![allow(clippy::collapsible_else_if, clippy::needless_borrows_for_generic_args)] mod config; mod driver; +mod json; mod recursive; -use crate::config::LintcheckConfig; +use crate::config::{Commands, LintcheckConfig, OutputFormat}; use crate::recursive::LintcheckServer; use std::collections::{HashMap, HashSet}; use std::env::consts::EXE_SUFFIX; -use std::fmt::{self, Write as _}; +use std::fmt::{self, Display, Write as _}; +use std::hash::Hash; use std::io::{self, ErrorKind}; use std::path::{Path, PathBuf}; use std::process::{Command, ExitStatus}; @@ -31,7 +33,7 @@ use std::sync::atomic::{AtomicUsize, Ordering}; use std::time::Duration; use std::{env, fs, thread}; -use cargo_metadata::diagnostic::Diagnostic; +use cargo_metadata::diagnostic::{Diagnostic, DiagnosticSpan}; use cargo_metadata::Message; use rayon::prelude::*; use serde::{Deserialize, Serialize}; @@ -111,6 +113,17 @@ struct RustcIce { pub crate_name: String, pub ice_content: String, } + +impl Display for RustcIce { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!( + f, + "{}:\n{}\n========================================\n", + self.crate_name, self.ice_content + ) + } +} + impl RustcIce { pub fn from_stderr_and_status(crate_name: &str, status: ExitStatus, stderr: &str) -> Option { if status.code().unwrap_or(0) == 101 @@ -127,60 +140,58 @@ impl RustcIce { } /// A single warning that clippy issued while checking a `Crate` -#[derive(Debug)] +#[derive(Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] struct ClippyWarning { - file: String, - line: usize, - column: usize, + crate_name: String, + crate_version: String, lint_type: String, - message: String, + diag: Diagnostic, } #[allow(unused)] impl ClippyWarning { - fn new(diag: Diagnostic, crate_name: &str, crate_version: &str) -> Option { - let lint_type = diag.code?.code; + fn new(mut diag: Diagnostic, crate_name: &str, crate_version: &str) -> Option { + let lint_type = diag.code.clone()?.code; if !(lint_type.contains("clippy") || diag.message.contains("clippy")) || diag.message.contains("could not read cargo metadata") { return None; } - let span = diag.spans.into_iter().find(|span| span.is_primary)?; - - let file = if let Ok(stripped) = Path::new(&span.file_name).strip_prefix(env!("CARGO_HOME")) { - format!("$CARGO_HOME/{}", stripped.display()) - } else { - format!( - "target/lintcheck/sources/{crate_name}-{crate_version}/{}", - span.file_name - ) - }; + // --recursive bypasses cargo so we have to strip the rendered output ourselves + let rendered = diag.rendered.as_mut().unwrap(); + *rendered = String::from_utf8(strip_ansi_escapes::strip(&rendered).unwrap()).unwrap(); Some(Self { - file, - line: span.line_start, - column: span.column_start, + crate_name: crate_name.to_owned(), + crate_version: crate_version.to_owned(), lint_type, - message: diag.message, + diag, }) } - fn to_output(&self, markdown: bool) -> String { - let file_with_pos = format!("{}:{}:{}", &self.file, &self.line, &self.column); - if markdown { - let mut file = self.file.clone(); - if !file.starts_with('$') { - file.insert_str(0, "../"); - } + fn span(&self) -> &DiagnosticSpan { + self.diag.spans.iter().find(|span| span.is_primary).unwrap() + } - let mut output = String::from("| "); - let _: fmt::Result = write!(output, "[`{file_with_pos}`]({file}#L{})", self.line); - let _: fmt::Result = write!(output, r#" | `{:<50}` | "{}" |"#, self.lint_type, self.message); - output.push('\n'); - output - } else { - format!("{file_with_pos} {} \"{}\"\n", self.lint_type, self.message) + fn to_output(&self, format: OutputFormat) -> String { + let span = self.span(); + let mut file = span.file_name.clone(); + let file_with_pos = format!("{file}:{}:{}", span.line_start, span.line_end); + match format { + OutputFormat::Text => format!("{file_with_pos} {} \"{}\"\n", self.lint_type, self.diag.message), + OutputFormat::Markdown => { + if file.starts_with("target") { + file.insert_str(0, "../"); + } + + let mut output = String::from("| "); + write!(output, "[`{file_with_pos}`]({file}#L{})", span.line_start).unwrap(); + write!(output, r#" | `{:<50}` | "{}" |"#, self.lint_type, self.diag.message).unwrap(); + output.push('\n'); + output + }, + OutputFormat::Json => unreachable!("JSON output is handled via serde"), } } } @@ -333,7 +344,7 @@ impl CrateSource { impl Crate { /// Run `cargo clippy` on the `Crate` and collect and return all the lint warnings that clippy /// issued - #[allow(clippy::too_many_arguments)] + #[allow(clippy::too_many_arguments, clippy::too_many_lines)] fn run_clippy_lints( &self, cargo_clippy_path: &Path, @@ -372,7 +383,25 @@ impl Crate { vec!["--quiet", "--message-format=json", "--"] }; - let mut clippy_args = Vec::<&str>::new(); + let cargo_home = env!("CARGO_HOME"); + + // `src/lib.rs` -> `target/lintcheck/sources/crate-1.2.3/src/lib.rs` + let remap_relative = format!("={}", self.path.display()); + // Fallback for other sources, `~/.cargo/...` -> `$CARGO_HOME/...` + let remap_cargo_home = format!("{cargo_home}=$CARGO_HOME"); + // `~/.cargo/registry/src/github.com-1ecc6299db9ec823/crate-2.3.4/src/lib.rs` + // -> `crate-2.3.4/src/lib.rs` + let remap_crates_io = format!("{cargo_home}/registry/src/github.com-1ecc6299db9ec823/="); + + let mut clippy_args = vec![ + "--remap-path-prefix", + &remap_relative, + "--remap-path-prefix", + &remap_cargo_home, + "--remap-path-prefix", + &remap_crates_io, + ]; + if let Some(options) = &self.options { for opt in options { clippy_args.push(opt); @@ -554,10 +583,10 @@ fn read_crates(toml_path: &Path) -> (Vec, RecursiveOptions) { } /// Generate a short list of occurring lints-types and their count -fn gather_stats(clippy_warnings: &[ClippyWarning]) -> (String, HashMap<&String, usize>) { +fn gather_stats(warnings: &[ClippyWarning]) -> (String, HashMap<&String, usize>) { // count lint type occurrences let mut counter: HashMap<&String, usize> = HashMap::new(); - clippy_warnings + warnings .iter() .for_each(|wrn| *counter.entry(&wrn.lint_type).or_insert(0) += 1); @@ -595,6 +624,11 @@ fn main() { let config = LintcheckConfig::new(); + if let Some(Commands::Diff { old, new }) = config.subcommand { + json::diff(&old, &new); + return; + } + println!("Compiling clippy..."); build_clippy(); println!("Done compiling"); @@ -619,7 +653,6 @@ fn main() { // flatten into one big list of warnings let (crates, recursive_options) = read_crates(&config.sources_toml_path); - let old_stats = read_stats_from_file(&config.lintcheck_results_path); let counter = AtomicUsize::new(1); let lint_filter: Vec = config @@ -711,39 +744,51 @@ fn main() { } } + let text = match config.format { + OutputFormat::Text | OutputFormat::Markdown => output(&warnings, &raw_ices, clippy_ver, &config), + OutputFormat::Json => { + if !raw_ices.is_empty() { + for ice in raw_ices { + println!("{ice}"); + } + panic!("Some crates ICEd"); + } + + json::output(&warnings) + }, + }; + + println!("Writing logs to {}", config.lintcheck_results_path.display()); + fs::create_dir_all(config.lintcheck_results_path.parent().unwrap()).unwrap(); + fs::write(&config.lintcheck_results_path, text).unwrap(); +} + +/// Creates the log file output for [`OutputFormat::Text`] and [`OutputFormat::Markdown`] +fn output(warnings: &[ClippyWarning], ices: &[RustcIce], clippy_ver: String, config: &LintcheckConfig) -> String { // generate some stats - let (stats_formatted, new_stats) = gather_stats(&warnings); + let (stats_formatted, new_stats) = gather_stats(warnings); + let old_stats = read_stats_from_file(&config.lintcheck_results_path); - let mut all_msgs: Vec = warnings.iter().map(|warn| warn.to_output(config.markdown)).collect(); + let mut all_msgs: Vec = warnings.iter().map(|warn| warn.to_output(config.format)).collect(); all_msgs.sort(); all_msgs.push("\n\n### Stats:\n\n".into()); all_msgs.push(stats_formatted); - // save the text into lintcheck-logs/logs.txt let mut text = clippy_ver; // clippy version number on top text.push_str("\n### Reports\n\n"); - if config.markdown { + if config.format == OutputFormat::Markdown { text.push_str("| file | lint | message |\n"); text.push_str("| --- | --- | --- |\n"); } write!(text, "{}", all_msgs.join("")).unwrap(); text.push_str("\n\n### ICEs:\n"); - for ice in &raw_ices { - let _: fmt::Result = write!( - text, - "{}:\n{}\n========================================\n\n", - ice.crate_name, ice.ice_content - ); + for ice in ices { + writeln!(text, "{ice}").unwrap(); } - println!("Writing logs to {}", config.lintcheck_results_path.display()); - if !raw_ices.is_empty() { - println!("WARNING: at least one ICE reported, check log file"); - } - fs::create_dir_all(config.lintcheck_results_path.parent().unwrap()).unwrap(); - fs::write(&config.lintcheck_results_path, text).unwrap(); - print_stats(old_stats, new_stats, &config.lint_filter); + + text } /// read the previous stats from the lintcheck-log file From feb0671893505272bdad18be595ea2c4dcea2063 Mon Sep 17 00:00:00 2001 From: Alex Macleod Date: Fri, 24 Feb 2023 17:35:27 +0000 Subject: [PATCH 183/892] Add lintcheck diff github action --- .github/workflows/lintcheck.yml | 115 ++++++++++++++++++++++++++++++++ 1 file changed, 115 insertions(+) create mode 100644 .github/workflows/lintcheck.yml diff --git a/.github/workflows/lintcheck.yml b/.github/workflows/lintcheck.yml new file mode 100644 index 0000000000000..0816e5334e20f --- /dev/null +++ b/.github/workflows/lintcheck.yml @@ -0,0 +1,115 @@ +name: Lintcheck + +on: pull_request + +env: + RUST_BACKTRACE: 1 + CARGO_INCREMENTAL: 0 + +concurrency: + # For a given workflow, if we push to the same PR, cancel all previous builds on that PR. + group: "${{ github.workflow }}-${{ github.event.pull_request.number}}" + cancel-in-progress: true + +jobs: + # Generates `lintcheck-logs/base.json` and stores it in a cache + base: + runs-on: ubuntu-latest + + outputs: + key: ${{ steps.key.outputs.key }} + + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 2 + + # HEAD is the generated merge commit `refs/pull/N/merge` between the PR and `master`, `HEAD^` + # being the commit from `master` that is the base of the merge + - name: Checkout base + run: git checkout HEAD^ + + # Use the lintcheck from the PR to generate the JSON in case the PR modifies lintcheck in some + # way + - name: Checkout current lintcheck + run: | + rm -rf lintcheck + git checkout ${{ github.sha }} -- lintcheck + + - name: Create cache key + id: key + run: echo "key=lintcheck-base-${{ hashfiles('lintcheck/**') }}-$(git rev-parse HEAD)" >> "$GITHUB_OUTPUT" + + - name: Cache results + id: cache + uses: actions/cache@v4 + with: + path: lintcheck-logs/base.json + key: ${{ steps.key.outputs.key }} + + - name: Run lintcheck + if: steps.cache.outputs.cache-hit != 'true' + run: cargo lintcheck --format json + + - name: Rename JSON file + if: steps.cache.outputs.cache-hit != 'true' + run: mv lintcheck-logs/lintcheck_crates_logs.json lintcheck-logs/base.json + + # Generates `lintcheck-logs/head.json` and stores it in a cache + head: + runs-on: ubuntu-latest + + outputs: + key: ${{ steps.key.outputs.key }} + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Create cache key + id: key + run: echo "key=lintcheck-head-${{ github.sha }}" >> "$GITHUB_OUTPUT" + + - name: Cache results + id: cache + uses: actions/cache@v4 + with: + path: lintcheck-logs/head.json + key: ${{ steps.key.outputs.key }} + + - name: Run lintcheck + if: steps.cache.outputs.cache-hit != 'true' + run: cargo lintcheck --format json + + - name: Rename JSON file + if: steps.cache.outputs.cache-hit != 'true' + run: mv lintcheck-logs/lintcheck_crates_logs.json lintcheck-logs/head.json + + # Retrieves `lintcheck-logs/base.json` and `lintcheck-logs/head.json` from the cache and prints + # the diff to the GH actions step summary + diff: + runs-on: ubuntu-latest + + needs: [base, head] + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Restore base JSON + uses: actions/cache/restore@v4 + with: + key: ${{ needs.base.outputs.key }} + path: lintcheck-logs/base.json + fail-on-cache-miss: true + + - name: Restore head JSON + uses: actions/cache/restore@v4 + with: + key: ${{ needs.head.outputs.key }} + path: lintcheck-logs/head.json + fail-on-cache-miss: true + + - name: Diff results + run: cargo lintcheck diff lintcheck-logs/base.json lintcheck-logs/head.json >> $GITHUB_STEP_SUMMARY From 63388cbab88a7207d3a3959a92a9ac84e9211336 Mon Sep 17 00:00:00 2001 From: AurelienFT Date: Sat, 15 Jun 2024 21:45:35 +0200 Subject: [PATCH 184/892] add MSRV for manual_pattern_char_comparison --- book/src/lint_configuration.md | 1 + clippy_config/src/conf.rs | 2 +- clippy_lints/src/lib.rs | 2 +- clippy_lints/src/string_patterns.rs | 22 ++++++++++++++++--- tests/ui/manual_pattern_char_comparison.fixed | 12 ++++++++++ tests/ui/manual_pattern_char_comparison.rs | 12 ++++++++++ .../ui/manual_pattern_char_comparison.stderr | 8 ++++++- 7 files changed, 53 insertions(+), 6 deletions(-) diff --git a/book/src/lint_configuration.md b/book/src/lint_configuration.md index c8223007df7b3..adb5b0a54909b 100644 --- a/book/src/lint_configuration.md +++ b/book/src/lint_configuration.md @@ -693,6 +693,7 @@ The minimum rust version that the project supports. Defaults to the `rust-versio * [`manual_is_ascii_check`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_is_ascii_check) * [`manual_let_else`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_let_else) * [`manual_non_exhaustive`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_non_exhaustive) +* [`manual_pattern_char_comparison`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_pattern_char_comparison) * [`manual_range_contains`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_range_contains) * [`manual_rem_euclid`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_rem_euclid) * [`manual_retain`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_retain) diff --git a/clippy_config/src/conf.rs b/clippy_config/src/conf.rs index cfdf620b7d074..93ca535a7a461 100644 --- a/clippy_config/src/conf.rs +++ b/clippy_config/src/conf.rs @@ -265,7 +265,7 @@ define_Conf! { /// /// Suppress lints whenever the suggested change would cause breakage for other crates. (avoid_breaking_exported_api: bool = true), - /// Lint: MANUAL_SPLIT_ONCE, MANUAL_STR_REPEAT, CLONED_INSTEAD_OF_COPIED, REDUNDANT_FIELD_NAMES, OPTION_MAP_UNWRAP_OR, REDUNDANT_STATIC_LIFETIMES, FILTER_MAP_NEXT, CHECKED_CONVERSIONS, MANUAL_RANGE_CONTAINS, USE_SELF, MEM_REPLACE_WITH_DEFAULT, MANUAL_NON_EXHAUSTIVE, OPTION_AS_REF_DEREF, MAP_UNWRAP_OR, MATCH_LIKE_MATCHES_MACRO, MANUAL_STRIP, MISSING_CONST_FOR_FN, UNNESTED_OR_PATTERNS, FROM_OVER_INTO, PTR_AS_PTR, IF_THEN_SOME_ELSE_NONE, APPROX_CONSTANT, DEPRECATED_CFG_ATTR, INDEX_REFUTABLE_SLICE, MAP_CLONE, BORROW_AS_PTR, MANUAL_BITS, ERR_EXPECT, CAST_ABS_TO_UNSIGNED, UNINLINED_FORMAT_ARGS, MANUAL_CLAMP, MANUAL_LET_ELSE, UNCHECKED_DURATION_SUBTRACTION, COLLAPSIBLE_STR_REPLACE, SEEK_FROM_CURRENT, SEEK_REWIND, UNNECESSARY_LAZY_EVALUATIONS, TRANSMUTE_PTR_TO_REF, ALMOST_COMPLETE_RANGE, NEEDLESS_BORROW, DERIVABLE_IMPLS, MANUAL_IS_ASCII_CHECK, MANUAL_REM_EUCLID, MANUAL_RETAIN, TYPE_REPETITION_IN_BOUNDS, TUPLE_ARRAY_CONVERSIONS, MANUAL_TRY_FOLD, MANUAL_HASH_ONE, ITER_KV_MAP, MANUAL_C_STR_LITERALS, ASSIGNING_CLONES, LEGACY_NUMERIC_CONSTANTS. + /// Lint: MANUAL_SPLIT_ONCE, MANUAL_STR_REPEAT, CLONED_INSTEAD_OF_COPIED, REDUNDANT_FIELD_NAMES, OPTION_MAP_UNWRAP_OR, REDUNDANT_STATIC_LIFETIMES, FILTER_MAP_NEXT, CHECKED_CONVERSIONS, MANUAL_RANGE_CONTAINS, USE_SELF, MEM_REPLACE_WITH_DEFAULT, MANUAL_NON_EXHAUSTIVE, OPTION_AS_REF_DEREF, MAP_UNWRAP_OR, MATCH_LIKE_MATCHES_MACRO, MANUAL_STRIP, MISSING_CONST_FOR_FN, UNNESTED_OR_PATTERNS, FROM_OVER_INTO, PTR_AS_PTR, IF_THEN_SOME_ELSE_NONE, APPROX_CONSTANT, DEPRECATED_CFG_ATTR, INDEX_REFUTABLE_SLICE, MAP_CLONE, BORROW_AS_PTR, MANUAL_BITS, ERR_EXPECT, CAST_ABS_TO_UNSIGNED, UNINLINED_FORMAT_ARGS, MANUAL_CLAMP, MANUAL_LET_ELSE, UNCHECKED_DURATION_SUBTRACTION, COLLAPSIBLE_STR_REPLACE, SEEK_FROM_CURRENT, SEEK_REWIND, UNNECESSARY_LAZY_EVALUATIONS, TRANSMUTE_PTR_TO_REF, ALMOST_COMPLETE_RANGE, NEEDLESS_BORROW, DERIVABLE_IMPLS, MANUAL_IS_ASCII_CHECK, MANUAL_REM_EUCLID, MANUAL_RETAIN, TYPE_REPETITION_IN_BOUNDS, TUPLE_ARRAY_CONVERSIONS, MANUAL_TRY_FOLD, MANUAL_HASH_ONE, ITER_KV_MAP, MANUAL_C_STR_LITERALS, ASSIGNING_CLONES, LEGACY_NUMERIC_CONSTANTS, MANUAL_PATTERN_CHAR_COMPARISON. /// /// The minimum rust version that the project supports. Defaults to the `rust-version` field in `Cargo.toml` #[default_text = ""] diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index c65581d5203e9..50274a715ec14 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -1168,7 +1168,7 @@ pub fn register_lints(store: &mut rustc_lint::LintStore, conf: &'static Conf) { ..Default::default() }) }); - store.register_late_pass(|_| Box::new(string_patterns::StringPatterns)); + store.register_late_pass(move |_| Box::new(string_patterns::StringPatterns::new(msrv()))); // add lints here, do not remove this comment, it's used in `new_lint` } diff --git a/clippy_lints/src/string_patterns.rs b/clippy_lints/src/string_patterns.rs index 64b5b8f9f27b4..084a4b5973223 100644 --- a/clippy_lints/src/string_patterns.rs +++ b/clippy_lints/src/string_patterns.rs @@ -1,5 +1,6 @@ use std::ops::ControlFlow; +use clippy_config::msrvs::{self, Msrv}; use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then}; use clippy_utils::eager_or_lazy::switch_to_eager_eval; use clippy_utils::macros::matching_root_macro_call; @@ -12,7 +13,7 @@ use rustc_errors::Applicability; use rustc_hir::{Expr, ExprKind, PatKind}; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::ty; -use rustc_session::declare_lint_pass; +use rustc_session::impl_lint_pass; use rustc_span::{sym, Span}; declare_clippy_lint! { @@ -69,7 +70,18 @@ declare_clippy_lint! { "using a single-character str where a char could be used, e.g., `_.split(\"x\")`" } -declare_lint_pass!(StringPatterns => [MANUAL_PATTERN_CHAR_COMPARISON, SINGLE_CHAR_PATTERN]); +pub struct StringPatterns { + msrv: Msrv, +} + +impl StringPatterns { + #[must_use] + pub fn new(msrv: Msrv) -> Self { + Self { msrv } + } +} + +impl_lint_pass!(StringPatterns => [MANUAL_PATTERN_CHAR_COMPARISON, SINGLE_CHAR_PATTERN]); const PATTERN_METHODS: [(&str, usize); 22] = [ ("contains", 0), @@ -220,8 +232,12 @@ impl<'tcx> LateLintPass<'tcx> for StringPatterns { && let Some(arg) = args.get(pos) { check_single_char_pattern_lint(cx, arg); - + if !self.msrv.meets(msrvs::PATTERN_TRAIT_CHAR_ARRAY) { + return; + } check_manual_pattern_char_comparison(cx, arg); } } + + extract_msrv_attr!(LateContext); } diff --git a/tests/ui/manual_pattern_char_comparison.fixed b/tests/ui/manual_pattern_char_comparison.fixed index 588226b87e87f..6020d7071bdf3 100644 --- a/tests/ui/manual_pattern_char_comparison.fixed +++ b/tests/ui/manual_pattern_char_comparison.fixed @@ -47,3 +47,15 @@ fn main() { } "".find(|c| m!(c)); } + +#[clippy::msrv = "1.57"] +fn msrv_1_57() { + let sentence = "Hello, world!"; + sentence.trim_end_matches(|c: char| c == '.' || c == ',' || c == '!' || c == '?'); +} + +#[clippy::msrv = "1.58"] +fn msrv_1_58() { + let sentence = "Hello, world!"; + sentence.trim_end_matches(['.', ',', '!', '?']); +} \ No newline at end of file diff --git a/tests/ui/manual_pattern_char_comparison.rs b/tests/ui/manual_pattern_char_comparison.rs index 5078f3ee27f36..43e883cd325a2 100644 --- a/tests/ui/manual_pattern_char_comparison.rs +++ b/tests/ui/manual_pattern_char_comparison.rs @@ -47,3 +47,15 @@ fn main() { } "".find(|c| m!(c)); } + +#[clippy::msrv = "1.57"] +fn msrv_1_57() { + let sentence = "Hello, world!"; + sentence.trim_end_matches(|c: char| c == '.' || c == ',' || c == '!' || c == '?'); +} + +#[clippy::msrv = "1.58"] +fn msrv_1_58() { + let sentence = "Hello, world!"; + sentence.trim_end_matches(|c: char| c == '.' || c == ',' || c == '!' || c == '?'); +} diff --git a/tests/ui/manual_pattern_char_comparison.stderr b/tests/ui/manual_pattern_char_comparison.stderr index b6b51794a11f5..f185d7c8f6767 100644 --- a/tests/ui/manual_pattern_char_comparison.stderr +++ b/tests/ui/manual_pattern_char_comparison.stderr @@ -55,5 +55,11 @@ error: this manual char comparison can be written more succinctly LL | sentence.find(|c| c == '🎈'); | ^^^^^^^^^^^^^ help: consider using a `char`: `'🎈'` -error: aborting due to 9 previous errors +error: this manual char comparison can be written more succinctly + --> tests/ui/manual_pattern_char_comparison.rs:60:31 + | +LL | sentence.trim_end_matches(|c: char| c == '.' || c == ',' || c == '!' || c == '?'); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using an array of `char`: `['.', ',', '!', '?']` + +error: aborting due to 10 previous errors From 51c6630d4f70d3c371cbda470358f85e9e2c3918 Mon Sep 17 00:00:00 2001 From: AurelienFT Date: Sat, 15 Jun 2024 21:52:42 +0200 Subject: [PATCH 185/892] Change MSRV check for manual_pattern_char_comparison only for pattern arrays --- clippy_lints/src/string_patterns.rs | 11 ++++++----- tests/ui/manual_pattern_char_comparison.fixed | 2 +- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/clippy_lints/src/string_patterns.rs b/clippy_lints/src/string_patterns.rs index 084a4b5973223..7ba58942a175e 100644 --- a/clippy_lints/src/string_patterns.rs +++ b/clippy_lints/src/string_patterns.rs @@ -134,7 +134,7 @@ fn get_char_span<'tcx>(cx: &'_ LateContext<'tcx>, expr: &'tcx Expr<'_>) -> Optio } } -fn check_manual_pattern_char_comparison(cx: &LateContext<'_>, method_arg: &Expr<'_>) { +fn check_manual_pattern_char_comparison(cx: &LateContext<'_>, method_arg: &Expr<'_>, msrv: &Msrv) { if let ExprKind::Closure(closure) = method_arg.kind && let body = cx.tcx.hir().body(closure.body) && let Some(PatKind::Binding(_, binding, ..)) = body.params.first().map(|p| p.pat.kind) @@ -190,6 +190,9 @@ fn check_manual_pattern_char_comparison(cx: &LateContext<'_>, method_arg: &Expr< { return; } + if set_char_spans.len() > 1 && !msrv.meets(msrvs::PATTERN_TRAIT_CHAR_ARRAY) { + return; + } span_lint_and_then( cx, MANUAL_PATTERN_CHAR_COMPARISON, @@ -232,10 +235,8 @@ impl<'tcx> LateLintPass<'tcx> for StringPatterns { && let Some(arg) = args.get(pos) { check_single_char_pattern_lint(cx, arg); - if !self.msrv.meets(msrvs::PATTERN_TRAIT_CHAR_ARRAY) { - return; - } - check_manual_pattern_char_comparison(cx, arg); + + check_manual_pattern_char_comparison(cx, arg, &self.msrv); } } diff --git a/tests/ui/manual_pattern_char_comparison.fixed b/tests/ui/manual_pattern_char_comparison.fixed index 6020d7071bdf3..03e621d95ba16 100644 --- a/tests/ui/manual_pattern_char_comparison.fixed +++ b/tests/ui/manual_pattern_char_comparison.fixed @@ -58,4 +58,4 @@ fn msrv_1_57() { fn msrv_1_58() { let sentence = "Hello, world!"; sentence.trim_end_matches(['.', ',', '!', '?']); -} \ No newline at end of file +} From bcc7b0e7000ccd13736e6d9f039858fa2f919e28 Mon Sep 17 00:00:00 2001 From: Elijah Potter Date: Sat, 15 Jun 2024 13:55:16 -0600 Subject: [PATCH 186/892] Fix minor typo --- book/src/usage.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/book/src/usage.md b/book/src/usage.md index 36448e4cccfa4..7a0be6994fe1b 100644 --- a/book/src/usage.md +++ b/book/src/usage.md @@ -36,7 +36,7 @@ You can configure lint levels on the command line by adding cargo clippy -- -Aclippy::style -Wclippy::double_neg -Dclippy::perf ``` -For [CI] all warnings can be elevated to errors which will inturn fail +For [CI] all warnings can be elevated to errors which will in turn fail the build and cause Clippy to exit with a code other than `0`. ``` From 3a983c399aecc348c5f01a6dcaa03f4f8ac0ea7e Mon Sep 17 00:00:00 2001 From: Alex Macleod Date: Sun, 16 Jun 2024 18:28:00 +0000 Subject: [PATCH 187/892] Merge lintcheck popular-crates bin as a subcommand --- lintcheck/Cargo.toml | 13 +------ lintcheck/README.md | 6 +-- lintcheck/src/config.rs | 9 +++++ lintcheck/src/main.rs | 20 ++++++---- lintcheck/src/popular-crates.rs | 65 --------------------------------- lintcheck/src/popular_crates.rs | 52 ++++++++++++++++++++++++++ 6 files changed, 77 insertions(+), 88 deletions(-) delete mode 100644 lintcheck/src/popular-crates.rs create mode 100644 lintcheck/src/popular_crates.rs diff --git a/lintcheck/Cargo.toml b/lintcheck/Cargo.toml index 623af922e2a8c..e0e94d7fec3eb 100644 --- a/lintcheck/Cargo.toml +++ b/lintcheck/Cargo.toml @@ -11,30 +11,19 @@ publish = false default-run = "lintcheck" [dependencies] -anyhow = "1.0.69" cargo_metadata = "0.15.3" clap = { version = "4.4", features = ["derive", "env"] } -crates_io_api = "0.8.1" crossbeam-channel = "0.5.6" diff = "0.1.13" flate2 = "1.0" -indicatif = "0.17.3" rayon = "1.5.1" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0.85" strip-ansi-escapes = "0.1.1" tar = "0.4" toml = "0.7.3" -ureq = "2.2" +ureq = { version = "2.2", features = ["json"] } walkdir = "2.3" [features] deny-warnings = [] - -[[bin]] -name = "lintcheck" -path = "src/main.rs" - -[[bin]] -name = "popular-crates" -path = "src/popular-crates.rs" diff --git a/lintcheck/README.md b/lintcheck/README.md index 61b581ba0faec..2d6039caeef07 100644 --- a/lintcheck/README.md +++ b/lintcheck/README.md @@ -26,11 +26,11 @@ the repo root. The results will then be saved to `lintcheck-logs/custom_logs.toml`. The `custom.toml` file may be built using recently most -downloaded crates by using the `popular-crates` binary from the `lintcheck` -directory. For example, to retrieve the 100 recently most downloaded crates: +downloaded crates by using `cargo lintcheck popular`. For example, to retrieve +the 200 recently most downloaded crates: ``` -cargo run --release --bin popular-crates -- -n 100 custom.toml +cargo lintcheck popular -n 200 custom.toml ``` diff --git a/lintcheck/src/config.rs b/lintcheck/src/config.rs index c3540bbe4ce7a..e6cd7c9fdc2bf 100644 --- a/lintcheck/src/config.rs +++ b/lintcheck/src/config.rs @@ -48,7 +48,16 @@ pub(crate) struct LintcheckConfig { #[derive(Subcommand, Clone, Debug)] pub(crate) enum Commands { + /// Display a markdown diff between two lintcheck log files in JSON format Diff { old: PathBuf, new: PathBuf }, + /// Create a lintcheck crates TOML file containing the top N popular crates + Popular { + /// Output TOML file name + output: PathBuf, + /// Number of crate names to download + #[clap(short, long, default_value_t = 100)] + number: usize, + }, } #[derive(ValueEnum, Debug, Clone, Copy, PartialEq, Eq)] diff --git a/lintcheck/src/main.rs b/lintcheck/src/main.rs index 985df9647d829..c246883c7045f 100644 --- a/lintcheck/src/main.rs +++ b/lintcheck/src/main.rs @@ -17,6 +17,7 @@ mod config; mod driver; mod json; +mod popular_crates; mod recursive; use crate::config::{Commands, LintcheckConfig, OutputFormat}; @@ -43,21 +44,21 @@ const LINTCHECK_DOWNLOADS: &str = "target/lintcheck/downloads"; const LINTCHECK_SOURCES: &str = "target/lintcheck/sources"; /// List of sources to check, loaded from a .toml file -#[derive(Debug, Serialize, Deserialize)] +#[derive(Debug, Deserialize)] struct SourceList { crates: HashMap, #[serde(default)] recursive: RecursiveOptions, } -#[derive(Debug, Serialize, Deserialize, Default)] +#[derive(Debug, Deserialize, Default)] struct RecursiveOptions { ignore: HashSet, } /// A crate source stored inside the .toml /// will be translated into on one of the `CrateSource` variants -#[derive(Debug, Serialize, Deserialize)] +#[derive(Debug, Deserialize)] struct TomlCrate { name: String, versions: Option>, @@ -69,7 +70,7 @@ struct TomlCrate { /// Represents an archive we download from crates.io, or a git repo, or a local repo/folder /// Once processed (downloaded/extracted/cloned/copied...), this will be translated into a `Crate` -#[derive(Debug, Serialize, Deserialize, Eq, Hash, PartialEq, Ord, PartialOrd)] +#[derive(Debug, Deserialize, Eq, Hash, PartialEq, Ord, PartialOrd)] enum CrateSource { CratesIo { name: String, @@ -609,7 +610,6 @@ fn gather_stats(warnings: &[ClippyWarning]) -> (String, HashMap<&String, usize>) (stats_string, counter) } -#[allow(clippy::too_many_lines)] fn main() { // We're being executed as a `RUSTC_WRAPPER` as part of `--recursive` if let Ok(addr) = env::var("LINTCHECK_SERVER") { @@ -624,11 +624,15 @@ fn main() { let config = LintcheckConfig::new(); - if let Some(Commands::Diff { old, new }) = config.subcommand { - json::diff(&old, &new); - return; + match config.subcommand { + Some(Commands::Diff { old, new }) => json::diff(&old, &new), + Some(Commands::Popular { output, number }) => popular_crates::fetch(output, number).unwrap(), + None => lintcheck(config), } +} +#[allow(clippy::too_many_lines)] +fn lintcheck(config: LintcheckConfig) { println!("Compiling clippy..."); build_clippy(); println!("Done compiling"); diff --git a/lintcheck/src/popular-crates.rs b/lintcheck/src/popular-crates.rs deleted file mode 100644 index fdab984ad86cb..0000000000000 --- a/lintcheck/src/popular-crates.rs +++ /dev/null @@ -1,65 +0,0 @@ -#![deny(clippy::pedantic)] - -use clap::Parser; -use crates_io_api::{CratesQueryBuilder, Sort, SyncClient}; -use indicatif::ProgressBar; -use std::collections::HashSet; -use std::fs::File; -use std::io::{BufWriter, Write}; -use std::path::PathBuf; -use std::time::Duration; - -#[derive(Parser)] -struct Opts { - /// Output TOML file name - output: PathBuf, - /// Number of crate names to download - #[clap(short, long, default_value_t = 100)] - number: usize, - /// Do not output progress - #[clap(short, long)] - quiet: bool, -} - -fn main() -> anyhow::Result<()> { - let opts = Opts::parse(); - let mut output = BufWriter::new(File::create(opts.output)?); - output.write_all(b"[crates]\n")?; - let client = SyncClient::new( - "clippy/lintcheck (github.com/rust-lang/rust-clippy/)", - Duration::from_secs(1), - )?; - let mut seen_crates = HashSet::new(); - let pb = if opts.quiet { - None - } else { - Some(ProgressBar::new(opts.number as u64)) - }; - let mut query = CratesQueryBuilder::new() - .sort(Sort::RecentDownloads) - .page_size(100) - .build(); - while seen_crates.len() < opts.number { - let retrieved = client.crates(query.clone())?.crates; - if retrieved.is_empty() { - eprintln!("No more than {} crates available from API", seen_crates.len()); - break; - } - for c in retrieved { - if seen_crates.insert(c.name.clone()) { - output.write_all( - format!( - "{} = {{ name = '{}', versions = ['{}'] }}\n", - c.name, c.name, c.max_version - ) - .as_bytes(), - )?; - if let Some(pb) = &pb { - pb.inc(1); - } - } - } - query.set_page(query.page() + 1); - } - Ok(()) -} diff --git a/lintcheck/src/popular_crates.rs b/lintcheck/src/popular_crates.rs new file mode 100644 index 0000000000000..880a8bd81f083 --- /dev/null +++ b/lintcheck/src/popular_crates.rs @@ -0,0 +1,52 @@ +use serde::Deserialize; +use std::error::Error; +use std::fmt::Write; +use std::fs; +use std::path::PathBuf; + +#[derive(Deserialize, Debug)] +struct Page { + crates: Vec, + meta: Meta, +} + +#[derive(Deserialize, Debug)] +struct Crate { + name: String, + max_version: String, +} + +#[derive(Deserialize, Debug)] +struct Meta { + next_page: String, +} + +pub(crate) fn fetch(output: PathBuf, number: usize) -> Result<(), Box> { + let agent = ureq::builder() + .user_agent("clippy/lintcheck (github.com/rust-lang/rust-clippy/)") + .build(); + + let mut crates = Vec::with_capacity(number); + let mut query = "?sort=recent-downloads&per_page=100".to_string(); + while crates.len() < number { + let page: Page = agent + .get(&format!("https://crates.io/api/v1/crates{query}")) + .call()? + .into_json()?; + + query = page.meta.next_page; + crates.extend(page.crates); + crates.truncate(number); + + let width = number.ilog10() as usize + 1; + println!("Fetched {:>width$}/{number} crates", crates.len()); + } + + let mut out = "[crates]\n".to_string(); + for Crate { name, max_version } in crates { + writeln!(out, "{name} = {{ name = '{name}', versions = ['{max_version}'] }}").unwrap(); + } + fs::write(output, out)?; + + Ok(()) +} From 3405ce3bcaeb445bc780a5ad863524dea151a385 Mon Sep 17 00:00:00 2001 From: kyle oneill Date: Sun, 16 Jun 2024 15:54:48 -0400 Subject: [PATCH 188/892] Add field_scoped_visibility_modifiers lint --- CHANGELOG.md | 1 + clippy_lints/src/declared_lints.rs | 1 + .../src/field_scoped_visibility_modifiers.rs | 75 +++++++++++++++++++ clippy_lints/src/lib.rs | 2 + tests/ui/field_scoped_visibility_modifiers.rs | 21 ++++++ .../field_scoped_visibility_modifiers.stderr | 28 +++++++ 6 files changed, 128 insertions(+) create mode 100644 clippy_lints/src/field_scoped_visibility_modifiers.rs create mode 100644 tests/ui/field_scoped_visibility_modifiers.rs create mode 100644 tests/ui/field_scoped_visibility_modifiers.stderr diff --git a/CHANGELOG.md b/CHANGELOG.md index d7bcd7a19687d..4de3124bd3dac 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5362,6 +5362,7 @@ Released 2018-09-13 [`extra_unused_type_parameters`]: https://rust-lang.github.io/rust-clippy/master/index.html#extra_unused_type_parameters [`fallible_impl_from`]: https://rust-lang.github.io/rust-clippy/master/index.html#fallible_impl_from [`field_reassign_with_default`]: https://rust-lang.github.io/rust-clippy/master/index.html#field_reassign_with_default +[`field_scoped_visibility_modifiers`]: https://rust-lang.github.io/rust-clippy/master/index.html#field_scoped_visibility_modifiers [`filetype_is_file`]: https://rust-lang.github.io/rust-clippy/master/index.html#filetype_is_file [`filter_map`]: https://rust-lang.github.io/rust-clippy/master/index.html#filter_map [`filter_map_bool_then`]: https://rust-lang.github.io/rust-clippy/master/index.html#filter_map_bool_then diff --git a/clippy_lints/src/declared_lints.rs b/clippy_lints/src/declared_lints.rs index 7e43a99e9f24f..88986f9ad7278 100644 --- a/clippy_lints/src/declared_lints.rs +++ b/clippy_lints/src/declared_lints.rs @@ -178,6 +178,7 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[ crate::explicit_write::EXPLICIT_WRITE_INFO, crate::extra_unused_type_parameters::EXTRA_UNUSED_TYPE_PARAMETERS_INFO, crate::fallible_impl_from::FALLIBLE_IMPL_FROM_INFO, + crate::field_scoped_visibility_modifiers::FIELD_SCOPED_VISIBILITY_MODIFIERS_INFO, crate::float_literal::EXCESSIVE_PRECISION_INFO, crate::float_literal::LOSSY_FLOAT_LITERAL_INFO, crate::floating_point_arithmetic::IMPRECISE_FLOPS_INFO, diff --git a/clippy_lints/src/field_scoped_visibility_modifiers.rs b/clippy_lints/src/field_scoped_visibility_modifiers.rs new file mode 100644 index 0000000000000..bb74e345703ff --- /dev/null +++ b/clippy_lints/src/field_scoped_visibility_modifiers.rs @@ -0,0 +1,75 @@ +use clippy_utils::diagnostics::span_lint_and_help; +use rustc_ast::ast::{Item, ItemKind, VisibilityKind}; +use rustc_lint::{EarlyContext, EarlyLintPass}; +use rustc_session::declare_lint_pass; + +declare_clippy_lint! { + /// ### What it does + /// Checks for usage of scoped visibility modifiers, like `pub(crate)`, on fields. These + /// make a field visible within a scope between public and private. + /// + /// ### Why restrict this? + /// Scoped visibility modifiers cause a field to be accessible within some scope between + /// public and private, potentially within an entire crate. This allows for fields to be + /// non-private while upholding internal invariants, but can be a code smell. Scoped visibility + /// requires checking a greater area, potentially an entire crate, to verify that an invariant + /// is upheld, and global analysis requires a lot of effort. + /// + /// ### Example + /// ```no_run + /// pub mod public_module { + /// struct MyStruct { + /// pub(crate) first_field: bool, + /// pub(super) second_field: bool + /// } + /// } + /// ``` + /// Use instead: + /// ```no_run + /// pub mod public_module { + /// struct MyStruct { + /// first_field: bool, + /// second_field: bool + /// } + /// impl MyStruct { + /// pub(crate) fn get_first_field(&self) -> bool { + /// self.first_field + /// } + /// pub(super) fn get_second_field(&self) -> bool { + /// self.second_field + /// } + /// } + /// } + /// ``` + #[clippy::version = "1.78.0"] + pub FIELD_SCOPED_VISIBILITY_MODIFIERS, + restriction, + "checks for usage of a scoped visibility modifier, like `pub(crate)`, on fields" +} + +declare_lint_pass!(FieldScopedVisibilityModifiers => [FIELD_SCOPED_VISIBILITY_MODIFIERS]); + +impl EarlyLintPass for FieldScopedVisibilityModifiers { + fn check_item(&mut self, cx: &EarlyContext<'_>, item: &Item) { + let ItemKind::Struct(ref st, _) = item.kind else { + return; + }; + for field in st.fields() { + let VisibilityKind::Restricted { path, .. } = &field.vis.kind else { + continue; + }; + if !path.segments.is_empty() && path.segments[0].ident.name == rustc_span::symbol::kw::SelfLower { + // pub(self) is equivalent to not using pub at all, so we ignore it + continue; + } + span_lint_and_help( + cx, + FIELD_SCOPED_VISIBILITY_MODIFIERS, + field.vis.span, + "scoped visibility modifier on a field", + None, + "consider making the field private and adding a scoped visibility method for it", + ); + } + } +} diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index 50274a715ec14..1bd6dfe24617e 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -136,6 +136,7 @@ mod exit; mod explicit_write; mod extra_unused_type_parameters; mod fallible_impl_from; +mod field_scoped_visibility_modifiers; mod float_literal; mod floating_point_arithmetic; mod format; @@ -1169,6 +1170,7 @@ pub fn register_lints(store: &mut rustc_lint::LintStore, conf: &'static Conf) { }) }); store.register_late_pass(move |_| Box::new(string_patterns::StringPatterns::new(msrv()))); + store.register_early_pass(|| Box::new(field_scoped_visibility_modifiers::FieldScopedVisibilityModifiers)); // add lints here, do not remove this comment, it's used in `new_lint` } diff --git a/tests/ui/field_scoped_visibility_modifiers.rs b/tests/ui/field_scoped_visibility_modifiers.rs new file mode 100644 index 0000000000000..5789dbf9b1d72 --- /dev/null +++ b/tests/ui/field_scoped_visibility_modifiers.rs @@ -0,0 +1,21 @@ +#![warn(clippy::field_scoped_visibility_modifiers)] + +pub mod pub_module { + pub(in crate::pub_module) mod pub_in_path_module {} + pub(super) mod pub_super_module {} + struct MyStruct { + private_field: bool, + pub pub_field: bool, + pub(crate) pub_crate_field: bool, + pub(in crate::pub_module) pub_in_path_field: bool, + pub(super) pub_super_field: bool, + #[allow(clippy::needless_pub_self)] + pub(self) pub_self_field: bool, + } +} +pub(crate) mod pub_crate_module {} + +#[allow(clippy::needless_pub_self)] +pub(self) mod pub_self_module {} + +fn main() {} diff --git a/tests/ui/field_scoped_visibility_modifiers.stderr b/tests/ui/field_scoped_visibility_modifiers.stderr new file mode 100644 index 0000000000000..beea6c92107c7 --- /dev/null +++ b/tests/ui/field_scoped_visibility_modifiers.stderr @@ -0,0 +1,28 @@ +error: scoped visibility modifier on a field + --> tests/ui/field_scoped_visibility_modifiers.rs:9:9 + | +LL | pub(crate) pub_crate_field: bool, + | ^^^^^^^^^^ + | + = help: consider making the field private and adding a scoped visibility method for it + = note: `-D clippy::field-scoped-visibility-modifiers` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::field_scoped_visibility_modifiers)]` + +error: scoped visibility modifier on a field + --> tests/ui/field_scoped_visibility_modifiers.rs:10:9 + | +LL | pub(in crate::pub_module) pub_in_path_field: bool, + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider making the field private and adding a scoped visibility method for it + +error: scoped visibility modifier on a field + --> tests/ui/field_scoped_visibility_modifiers.rs:11:9 + | +LL | pub(super) pub_super_field: bool, + | ^^^^^^^^^^ + | + = help: consider making the field private and adding a scoped visibility method for it + +error: aborting due to 3 previous errors + From a002f93e51e66204e81779d7d449a50e30571c6c Mon Sep 17 00:00:00 2001 From: Jason Newcomb Date: Mon, 12 Feb 2024 18:33:10 -0500 Subject: [PATCH 189/892] `expr_use_ctxt` changes: * Delay the parsing of the use node * Mark when the `SyntaxContext` changes rather than return `None` * Return a default value if the HIR tree is broken rather than `None` --- clippy_lints/src/casts/ref_as_ptr.rs | 4 +- clippy_lints/src/dereference.rs | 46 +++-- .../src/needless_borrows_for_generic_args.rs | 8 +- clippy_utils/src/lib.rs | 164 ++++++++++-------- 4 files changed, 120 insertions(+), 102 deletions(-) diff --git a/clippy_lints/src/casts/ref_as_ptr.rs b/clippy_lints/src/casts/ref_as_ptr.rs index f42bafce4dde1..5f48b8bd2063e 100644 --- a/clippy_lints/src/casts/ref_as_ptr.rs +++ b/clippy_lints/src/casts/ref_as_ptr.rs @@ -22,9 +22,9 @@ pub(super) fn check<'tcx>( if matches!(cast_from.kind(), ty::Ref(..)) && let ty::RawPtr(_, to_mutbl) = cast_to.kind() - && let Some(use_cx) = expr_use_ctxt(cx, expr) + && let use_cx = expr_use_ctxt(cx, expr) // TODO: only block the lint if `cast_expr` is a temporary - && !matches!(use_cx.node, ExprUseNode::LetStmt(_) | ExprUseNode::ConstStatic(_)) + && !matches!(use_cx.use_node(cx), ExprUseNode::LetStmt(_) | ExprUseNode::ConstStatic(_)) { let core_or_std = if is_no_std_crate(cx) { "core" } else { "std" }; let fn_name = match to_mutbl { diff --git a/clippy_lints/src/dereference.rs b/clippy_lints/src/dereference.rs index d60320d828253..3c137b6b70fae 100644 --- a/clippy_lints/src/dereference.rs +++ b/clippy_lints/src/dereference.rs @@ -260,18 +260,13 @@ impl<'tcx> LateLintPass<'tcx> for Dereferencing<'tcx> { (None, kind) => { let expr_ty = typeck.expr_ty(expr); let use_cx = expr_use_ctxt(cx, expr); - let adjusted_ty = match &use_cx { - Some(use_cx) => match use_cx.adjustments { - [.., a] => a.target, - _ => expr_ty, - }, - _ => typeck.expr_ty_adjusted(expr), - }; + let adjusted_ty = use_cx.adjustments.last().map_or(expr_ty, |a| a.target); - match (use_cx, kind) { - (Some(use_cx), RefOp::Deref) => { + match kind { + RefOp::Deref if use_cx.same_ctxt => { + let use_node = use_cx.use_node(cx); let sub_ty = typeck.expr_ty(sub_expr); - if let ExprUseNode::FieldAccess(name) = use_cx.node + if let ExprUseNode::FieldAccess(name) = use_node && !use_cx.moved_before_use && !ty_contains_field(sub_ty, name.name) { @@ -288,9 +283,9 @@ impl<'tcx> LateLintPass<'tcx> for Dereferencing<'tcx> { } else if sub_ty.is_ref() // Linting method receivers would require verifying that name lookup // would resolve the same way. This is complicated by trait methods. - && !use_cx.node.is_recv() - && let Some(ty) = use_cx.node.defined_ty(cx) - && TyCoercionStability::for_defined_ty(cx, ty, use_cx.node.is_return()).is_deref_stable() + && !use_node.is_recv() + && let Some(ty) = use_node.defined_ty(cx) + && TyCoercionStability::for_defined_ty(cx, ty, use_node.is_return()).is_deref_stable() { self.state = Some(( State::ExplicitDeref { mutability: None }, @@ -301,7 +296,7 @@ impl<'tcx> LateLintPass<'tcx> for Dereferencing<'tcx> { )); } }, - (_, RefOp::Method { mutbl, is_ufcs }) + RefOp::Method { mutbl, is_ufcs } if !is_lint_allowed(cx, EXPLICIT_DEREF_METHODS, expr.hir_id) // Allow explicit deref in method chains. e.g. `foo.deref().bar()` && (is_ufcs || !in_postfix_position(cx, expr)) => @@ -319,7 +314,7 @@ impl<'tcx> LateLintPass<'tcx> for Dereferencing<'tcx> { }, )); }, - (Some(use_cx), RefOp::AddrOf(mutability)) => { + RefOp::AddrOf(mutability) if use_cx.same_ctxt => { // Find the number of times the borrow is auto-derefed. let mut iter = use_cx.adjustments.iter(); let mut deref_count = 0usize; @@ -338,10 +333,11 @@ impl<'tcx> LateLintPass<'tcx> for Dereferencing<'tcx> { }; }; - let stability = use_cx.node.defined_ty(cx).map_or(TyCoercionStability::None, |ty| { - TyCoercionStability::for_defined_ty(cx, ty, use_cx.node.is_return()) + let use_node = use_cx.use_node(cx); + let stability = use_node.defined_ty(cx).map_or(TyCoercionStability::None, |ty| { + TyCoercionStability::for_defined_ty(cx, ty, use_node.is_return()) }); - let can_auto_borrow = match use_cx.node { + let can_auto_borrow = match use_node { ExprUseNode::FieldAccess(_) if !use_cx.moved_before_use && matches!(sub_expr.kind, ExprKind::Field(..)) => { @@ -353,7 +349,7 @@ impl<'tcx> LateLintPass<'tcx> for Dereferencing<'tcx> { // deref through `ManuallyDrop<_>` will not compile. !adjust_derefs_manually_drop(use_cx.adjustments, expr_ty) }, - ExprUseNode::Callee | ExprUseNode::FieldAccess(_) => true, + ExprUseNode::Callee | ExprUseNode::FieldAccess(_) if !use_cx.moved_before_use => true, ExprUseNode::MethodArg(hir_id, _, 0) if !use_cx.moved_before_use => { // Check for calls to trait methods where the trait is implemented // on a reference. @@ -363,9 +359,7 @@ impl<'tcx> LateLintPass<'tcx> for Dereferencing<'tcx> { // priority. if let Some(fn_id) = typeck.type_dependent_def_id(hir_id) && let Some(trait_id) = cx.tcx.trait_of_item(fn_id) - && let arg_ty = cx - .tcx - .erase_regions(use_cx.adjustments.last().map_or(expr_ty, |a| a.target)) + && let arg_ty = cx.tcx.erase_regions(adjusted_ty) && let ty::Ref(_, sub_ty, _) = *arg_ty.kind() && let args = typeck.node_args_opt(hir_id).map(|args| &args[1..]).unwrap_or_default() @@ -443,7 +437,7 @@ impl<'tcx> LateLintPass<'tcx> for Dereferencing<'tcx> { count: deref_count - required_refs, msg, stability, - for_field_access: if let ExprUseNode::FieldAccess(name) = use_cx.node + for_field_access: if let ExprUseNode::FieldAccess(name) = use_node && !use_cx.moved_before_use { Some(name.name) @@ -453,7 +447,7 @@ impl<'tcx> LateLintPass<'tcx> for Dereferencing<'tcx> { }), StateData { first_expr: expr, - adjusted_ty: use_cx.adjustments.last().map_or(expr_ty, |a| a.target), + adjusted_ty, }, )); } else if stability.is_deref_stable() @@ -465,12 +459,12 @@ impl<'tcx> LateLintPass<'tcx> for Dereferencing<'tcx> { State::Borrow { mutability }, StateData { first_expr: expr, - adjusted_ty: use_cx.adjustments.last().map_or(expr_ty, |a| a.target), + adjusted_ty, }, )); } }, - (None, _) | (_, RefOp::Method { .. }) => (), + _ => {}, } }, ( diff --git a/clippy_lints/src/needless_borrows_for_generic_args.rs b/clippy_lints/src/needless_borrows_for_generic_args.rs index 4f99eaa40c29b..9c3ead855a7aa 100644 --- a/clippy_lints/src/needless_borrows_for_generic_args.rs +++ b/clippy_lints/src/needless_borrows_for_generic_args.rs @@ -80,11 +80,13 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessBorrowsForGenericArgs<'tcx> { fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { if matches!(expr.kind, ExprKind::AddrOf(..)) && !expr.span.from_expansion() - && let Some(use_cx) = expr_use_ctxt(cx, expr) + && let use_cx = expr_use_ctxt(cx, expr) + && use_cx.same_ctxt && !use_cx.is_ty_unified - && let Some(DefinedTy::Mir(ty)) = use_cx.node.defined_ty(cx) + && let use_node = use_cx.use_node(cx) + && let Some(DefinedTy::Mir(ty)) = use_node.defined_ty(cx) && let ty::Param(ty) = *ty.value.skip_binder().kind() - && let Some((hir_id, fn_id, i)) = match use_cx.node { + && let Some((hir_id, fn_id, i)) = match use_node { ExprUseNode::MethodArg(_, _, 0) => None, ExprUseNode::MethodArg(hir_id, None, i) => cx .typeck_results() diff --git a/clippy_utils/src/lib.rs b/clippy_utils/src/lib.rs index 7dc341ec8d71b..fda870f435a52 100644 --- a/clippy_utils/src/lib.rs +++ b/clippy_utils/src/lib.rs @@ -1,6 +1,7 @@ #![feature(array_chunks)] #![feature(box_patterns)] #![feature(control_flow_enum)] +#![feature(exhaustive_patterns)] #![feature(if_let_guard)] #![feature(let_chains)] #![feature(lint_reasons)] @@ -2664,13 +2665,80 @@ pub enum DefinedTy<'tcx> { /// The context an expressions value is used in. pub struct ExprUseCtxt<'tcx> { /// The parent node which consumes the value. - pub node: ExprUseNode<'tcx>, + pub node: Node<'tcx>, + /// The child id of the node the value came from. + pub child_id: HirId, /// Any adjustments applied to the type. pub adjustments: &'tcx [Adjustment<'tcx>], - /// Whether or not the type must unify with another code path. + /// Whether the type must unify with another code path. pub is_ty_unified: bool, - /// Whether or not the value will be moved before it's used. + /// Whether the value will be moved before it's used. pub moved_before_use: bool, + /// Whether the use site has the same `SyntaxContext` as the value. + pub same_ctxt: bool, +} +impl<'tcx> ExprUseCtxt<'tcx> { + pub fn use_node(&self, cx: &LateContext<'tcx>) -> ExprUseNode<'tcx> { + match self.node { + Node::LetStmt(l) => ExprUseNode::LetStmt(l), + Node::ExprField(field) => ExprUseNode::Field(field), + + Node::Item(&Item { + kind: ItemKind::Static(..) | ItemKind::Const(..), + owner_id, + .. + }) + | Node::TraitItem(&TraitItem { + kind: TraitItemKind::Const(..), + owner_id, + .. + }) + | Node::ImplItem(&ImplItem { + kind: ImplItemKind::Const(..), + owner_id, + .. + }) => ExprUseNode::ConstStatic(owner_id), + + Node::Item(&Item { + kind: ItemKind::Fn(..), + owner_id, + .. + }) + | Node::TraitItem(&TraitItem { + kind: TraitItemKind::Fn(..), + owner_id, + .. + }) + | Node::ImplItem(&ImplItem { + kind: ImplItemKind::Fn(..), + owner_id, + .. + }) => ExprUseNode::Return(owner_id), + + Node::Expr(use_expr) => match use_expr.kind { + ExprKind::Ret(_) => ExprUseNode::Return(OwnerId { + def_id: cx.tcx.hir().body_owner_def_id(cx.enclosing_body.unwrap()), + }), + + ExprKind::Closure(closure) => ExprUseNode::Return(OwnerId { def_id: closure.def_id }), + ExprKind::Call(func, args) => match args.iter().position(|arg| arg.hir_id == self.child_id) { + Some(i) => ExprUseNode::FnArg(func, i), + None => ExprUseNode::Callee, + }, + ExprKind::MethodCall(name, _, args, _) => ExprUseNode::MethodArg( + use_expr.hir_id, + name.args, + args.iter() + .position(|arg| arg.hir_id == self.child_id) + .map_or(0, |i| i + 1), + ), + ExprKind::Field(_, name) => ExprUseNode::FieldAccess(name), + ExprKind::AddrOf(kind, mutbl, _) => ExprUseNode::AddrOf(kind, mutbl), + _ => ExprUseNode::Other, + }, + _ => ExprUseNode::Other, + } + } } /// The node which consumes a value. @@ -2691,7 +2759,8 @@ pub enum ExprUseNode<'tcx> { Callee, /// Access of a field. FieldAccess(Ident), - Expr, + /// Borrow expression. + AddrOf(ast::BorrowKind, Mutability), Other, } impl<'tcx> ExprUseNode<'tcx> { @@ -2768,26 +2837,25 @@ impl<'tcx> ExprUseNode<'tcx> { let sig = cx.tcx.fn_sig(id).skip_binder(); Some(DefinedTy::Mir(cx.tcx.param_env(id).and(sig.input(i)))) }, - Self::LetStmt(_) | Self::FieldAccess(..) | Self::Callee | Self::Expr | Self::Other => None, + Self::LetStmt(_) | Self::FieldAccess(..) | Self::Callee | Self::Other | Self::AddrOf(..) => None, } } } /// Gets the context an expression's value is used in. -pub fn expr_use_ctxt<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'tcx>) -> Option> { +pub fn expr_use_ctxt<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'tcx>) -> ExprUseCtxt<'tcx> { let mut adjustments = [].as_slice(); let mut is_ty_unified = false; let mut moved_before_use = false; + let mut same_ctxt = true; let ctxt = e.span.ctxt(); - walk_to_expr_usage(cx, e, &mut |parent_id, parent, child_id| { + let node = walk_to_expr_usage(cx, e, &mut |parent_id, parent, child_id| -> ControlFlow { if adjustments.is_empty() && let Node::Expr(e) = cx.tcx.hir_node(child_id) { adjustments = cx.typeck_results().expr_adjustments(e); } - if cx.tcx.hir().span(parent_id).ctxt() != ctxt { - return ControlFlow::Break(()); - } + same_ctxt &= cx.tcx.hir().span(parent_id).ctxt() == ctxt; if let Node::Expr(e) = parent { match e.kind { ExprKind::If(e, _, _) | ExprKind::Match(e, _, _) if e.hir_id != child_id => { @@ -2803,71 +2871,25 @@ pub fn expr_use_ctxt<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'tcx>) -> Optio } } ControlFlow::Continue(()) - })? - .continue_value() - .map(|(use_node, child_id)| { - let node = match use_node { - Node::LetStmt(l) => ExprUseNode::LetStmt(l), - Node::ExprField(field) => ExprUseNode::Field(field), - - Node::Item(&Item { - kind: ItemKind::Static(..) | ItemKind::Const(..), - owner_id, - .. - }) - | Node::TraitItem(&TraitItem { - kind: TraitItemKind::Const(..), - owner_id, - .. - }) - | Node::ImplItem(&ImplItem { - kind: ImplItemKind::Const(..), - owner_id, - .. - }) => ExprUseNode::ConstStatic(owner_id), - - Node::Item(&Item { - kind: ItemKind::Fn(..), - owner_id, - .. - }) - | Node::TraitItem(&TraitItem { - kind: TraitItemKind::Fn(..), - owner_id, - .. - }) - | Node::ImplItem(&ImplItem { - kind: ImplItemKind::Fn(..), - owner_id, - .. - }) => ExprUseNode::Return(owner_id), - - Node::Expr(use_expr) => match use_expr.kind { - ExprKind::Ret(_) => ExprUseNode::Return(OwnerId { - def_id: cx.tcx.hir().body_owner_def_id(cx.enclosing_body.unwrap()), - }), - ExprKind::Closure(closure) => ExprUseNode::Return(OwnerId { def_id: closure.def_id }), - ExprKind::Call(func, args) => match args.iter().position(|arg| arg.hir_id == child_id) { - Some(i) => ExprUseNode::FnArg(func, i), - None => ExprUseNode::Callee, - }, - ExprKind::MethodCall(name, _, args, _) => ExprUseNode::MethodArg( - use_expr.hir_id, - name.args, - args.iter().position(|arg| arg.hir_id == child_id).map_or(0, |i| i + 1), - ), - ExprKind::Field(child, name) if child.hir_id == e.hir_id => ExprUseNode::FieldAccess(name), - _ => ExprUseNode::Expr, - }, - _ => ExprUseNode::Other, - }; - ExprUseCtxt { + }); + match node { + Some(ControlFlow::Continue((node, child_id))) => ExprUseCtxt { node, + child_id, adjustments, is_ty_unified, moved_before_use, - } - }) + same_ctxt, + }, + None => ExprUseCtxt { + node: Node::Crate(cx.tcx.hir().root_module()), + child_id: HirId::INVALID, + adjustments: &[], + is_ty_unified: true, + moved_before_use: true, + same_ctxt: false, + }, + } } /// Tokenizes the input while keeping the text associated with each token. From 22710f33a8ad99be51bb69f91339f8d815bd9e92 Mon Sep 17 00:00:00 2001 From: Jason Newcomb Date: Mon, 12 Feb 2024 18:33:22 -0500 Subject: [PATCH 190/892] Add lint `manual_inspect` --- CHANGELOG.md | 1 + clippy_config/src/msrvs.rs | 2 +- clippy_lints/src/declared_lints.rs | 1 + clippy_lints/src/methods/manual_inspect.rs | 233 +++++++++++++++++++++ clippy_lints/src/methods/mod.rs | 24 +++ clippy_utils/src/source.rs | 27 ++- clippy_utils/src/ty.rs | 14 ++ tests/ui/copy_iterator.rs | 1 + tests/ui/copy_iterator.stderr | 2 +- tests/ui/manual_inspect.fixed | 174 +++++++++++++++ tests/ui/manual_inspect.rs | 186 ++++++++++++++++ tests/ui/manual_inspect.stderr | 182 ++++++++++++++++ 12 files changed, 844 insertions(+), 3 deletions(-) create mode 100644 clippy_lints/src/methods/manual_inspect.rs create mode 100644 tests/ui/manual_inspect.fixed create mode 100644 tests/ui/manual_inspect.rs create mode 100644 tests/ui/manual_inspect.stderr diff --git a/CHANGELOG.md b/CHANGELOG.md index 4de3124bd3dac..3973edddb6d6b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5521,6 +5521,7 @@ Released 2018-09-13 [`manual_find_map`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_find_map [`manual_flatten`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_flatten [`manual_hash_one`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_hash_one +[`manual_inspect`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_inspect [`manual_instant_elapsed`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_instant_elapsed [`manual_is_ascii_check`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_is_ascii_check [`manual_is_finite`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_is_finite diff --git a/clippy_config/src/msrvs.rs b/clippy_config/src/msrvs.rs index a3e7d0c3fa5fe..5327a12564748 100644 --- a/clippy_config/src/msrvs.rs +++ b/clippy_config/src/msrvs.rs @@ -18,7 +18,7 @@ macro_rules! msrv_aliases { // names may refer to stabilized feature flags or library items msrv_aliases! { 1,77,0 { C_STR_LITERALS } - 1,76,0 { PTR_FROM_REF } + 1,76,0 { PTR_FROM_REF, OPTION_RESULT_INSPECT } 1,71,0 { TUPLE_ARRAY_CONVERSIONS, BUILD_HASHER_HASH_ONE } 1,70,0 { OPTION_RESULT_IS_VARIANT_AND, BINARY_HEAP_RETAIN } 1,68,0 { PATH_MAIN_SEPARATOR_STR } diff --git a/clippy_lints/src/declared_lints.rs b/clippy_lints/src/declared_lints.rs index 88986f9ad7278..8abe5d47b65ec 100644 --- a/clippy_lints/src/declared_lints.rs +++ b/clippy_lints/src/declared_lints.rs @@ -403,6 +403,7 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[ crate::methods::MANUAL_C_STR_LITERALS_INFO, crate::methods::MANUAL_FILTER_MAP_INFO, crate::methods::MANUAL_FIND_MAP_INFO, + crate::methods::MANUAL_INSPECT_INFO, crate::methods::MANUAL_IS_VARIANT_AND_INFO, crate::methods::MANUAL_NEXT_BACK_INFO, crate::methods::MANUAL_OK_OR_INFO, diff --git a/clippy_lints/src/methods/manual_inspect.rs b/clippy_lints/src/methods/manual_inspect.rs new file mode 100644 index 0000000000000..2f9b951c6a76c --- /dev/null +++ b/clippy_lints/src/methods/manual_inspect.rs @@ -0,0 +1,233 @@ +use clippy_config::msrvs::{self, Msrv}; +use clippy_utils::diagnostics::span_lint_and_then; +use clippy_utils::source::{get_source_text, with_leading_whitespace, SpanRange}; +use clippy_utils::ty::get_field_by_name; +use clippy_utils::visitors::{for_each_expr, for_each_expr_without_closures}; +use clippy_utils::{expr_use_ctxt, is_diag_item_method, is_diag_trait_item, path_to_local_id, ExprUseNode}; +use core::ops::ControlFlow; +use rustc_errors::Applicability; +use rustc_hir::{BindingMode, BorrowKind, ByRef, ClosureKind, Expr, ExprKind, Mutability, Node, PatKind}; +use rustc_lint::LateContext; +use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow, AutoBorrowMutability}; +use rustc_span::{sym, BytePos, Span, Symbol, DUMMY_SP}; + +use super::MANUAL_INSPECT; + +#[expect(clippy::too_many_lines)] +pub(crate) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, arg: &Expr<'_>, name: &str, name_span: Span, msrv: &Msrv) { + if let ExprKind::Closure(c) = arg.kind + && matches!(c.kind, ClosureKind::Closure) + && let typeck = cx.typeck_results() + && let Some(fn_id) = typeck.type_dependent_def_id(expr.hir_id) + && (is_diag_trait_item(cx, fn_id, sym::Iterator) + || (msrv.meets(msrvs::OPTION_RESULT_INSPECT) + && (is_diag_item_method(cx, fn_id, sym::Option) || is_diag_item_method(cx, fn_id, sym::Result)))) + && let body = cx.tcx.hir().body(c.body) + && let [param] = body.params + && let PatKind::Binding(BindingMode(ByRef::No, Mutability::Not), arg_id, _, None) = param.pat.kind + && let arg_ty = typeck.node_type(arg_id) + && let ExprKind::Block(block, _) = body.value.kind + && let Some(final_expr) = block.expr + && !block.stmts.is_empty() + && path_to_local_id(final_expr, arg_id) + && typeck.expr_adjustments(final_expr).is_empty() + { + let mut requires_copy = false; + let mut requires_deref = false; + + // The number of unprocessed return expressions. + let mut ret_count = 0u32; + + // The uses for which processing is delayed until after the visitor. + let mut delayed = vec![]; + + let ctxt = arg.span.ctxt(); + let can_lint = for_each_expr_without_closures(block.stmts, |e| { + if let ExprKind::Closure(c) = e.kind { + // Nested closures don't need to treat returns specially. + let _: Option = for_each_expr(cx, cx.tcx.hir().body(c.body).value, |e| { + if path_to_local_id(e, arg_id) { + let (kind, same_ctxt) = check_use(cx, e); + match (kind, same_ctxt && e.span.ctxt() == ctxt) { + (_, false) | (UseKind::Deref | UseKind::Return(..), true) => { + requires_copy = true; + requires_deref = true; + }, + (UseKind::AutoBorrowed, true) => {}, + (UseKind::WillAutoDeref, true) => { + requires_copy = true; + }, + (kind, true) => delayed.push(kind), + } + } + ControlFlow::Continue(()) + }); + } else if matches!(e.kind, ExprKind::Ret(_)) { + ret_count += 1; + } else if path_to_local_id(e, arg_id) { + let (kind, same_ctxt) = check_use(cx, e); + match (kind, same_ctxt && e.span.ctxt() == ctxt) { + (UseKind::Return(..), false) => { + return ControlFlow::Break(()); + }, + (_, false) | (UseKind::Deref, true) => { + requires_copy = true; + requires_deref = true; + }, + (UseKind::AutoBorrowed, true) => {}, + (UseKind::WillAutoDeref, true) => { + requires_copy = true; + }, + (kind @ UseKind::Return(_), true) => { + ret_count -= 1; + delayed.push(kind); + }, + (kind, true) => delayed.push(kind), + } + } + ControlFlow::Continue(()) + }) + .is_none(); + + if ret_count != 0 { + // A return expression that didn't return the original value was found. + return; + } + + let mut edits = Vec::with_capacity(delayed.len() + 3); + let mut addr_of_edits = Vec::with_capacity(delayed.len()); + for x in delayed { + match x { + UseKind::Return(s) => edits.push((with_leading_whitespace(cx, s).set_span_pos(s), String::new())), + UseKind::Borrowed(s) => { + if let Some(src) = get_source_text(cx, s) + && let Some(src) = src.as_str() + && let trim_src = src.trim_start_matches([' ', '\t', '\n', '\r', '(']) + && trim_src.starts_with('&') + { + let range = s.into_range(); + #[expect(clippy::cast_possible_truncation)] + let start = BytePos(range.start.0 + (src.len() - trim_src.len()) as u32); + addr_of_edits.push(((start..BytePos(start.0 + 1)).set_span_pos(s), String::new())); + } else { + requires_copy = true; + requires_deref = true; + } + }, + UseKind::FieldAccess(name, e) => { + let Some(mut ty) = get_field_by_name(cx.tcx, arg_ty.peel_refs(), name) else { + requires_copy = true; + continue; + }; + let mut prev_expr = e; + + for (_, parent) in cx.tcx.hir().parent_iter(e.hir_id) { + if let Node::Expr(e) = parent { + match e.kind { + ExprKind::Field(_, name) + if let Some(fty) = get_field_by_name(cx.tcx, ty.peel_refs(), name.name) => + { + ty = fty; + prev_expr = e; + continue; + }, + ExprKind::AddrOf(BorrowKind::Ref, ..) => break, + _ if matches!( + typeck.expr_adjustments(prev_expr).first(), + Some(Adjustment { + kind: Adjust::Borrow(AutoBorrow::Ref(_, AutoBorrowMutability::Not)) + | Adjust::Deref(_), + .. + }) + ) => + { + break; + }, + _ => {}, + } + } + requires_copy |= !ty.is_copy_modulo_regions(cx.tcx, cx.param_env); + break; + } + }, + // Already processed uses. + UseKind::AutoBorrowed | UseKind::WillAutoDeref | UseKind::Deref => {}, + } + } + + if can_lint + && (!requires_copy || arg_ty.is_copy_modulo_regions(cx.tcx, cx.param_env)) + // This case could be handled, but a fair bit of care would need to be taken. + && (!requires_deref || arg_ty.is_freeze(cx.tcx, cx.param_env)) + { + if requires_deref { + edits.push((param.span.shrink_to_lo(), "&".into())); + } else { + edits.extend(addr_of_edits); + } + edits.push(( + name_span, + String::from(match name { + "map" => "inspect", + "map_err" => "inspect_err", + _ => return, + }), + )); + edits.push(( + with_leading_whitespace(cx, final_expr.span).set_span_pos(final_expr.span), + String::new(), + )); + let app = if edits.iter().any(|(s, _)| s.from_expansion()) { + Applicability::MaybeIncorrect + } else { + Applicability::MachineApplicable + }; + span_lint_and_then(cx, MANUAL_INSPECT, name_span, "", |diag| { + diag.multipart_suggestion("try", edits, app); + }); + } + } +} + +enum UseKind<'tcx> { + AutoBorrowed, + WillAutoDeref, + Deref, + Return(Span), + Borrowed(Span), + FieldAccess(Symbol, &'tcx Expr<'tcx>), +} + +/// Checks how the value is used, and whether it was used in the same `SyntaxContext`. +fn check_use<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> (UseKind<'tcx>, bool) { + let use_cx = expr_use_ctxt(cx, e); + if use_cx + .adjustments + .first() + .is_some_and(|a| matches!(a.kind, Adjust::Deref(_))) + { + return (UseKind::AutoBorrowed, use_cx.same_ctxt); + } + let res = match use_cx.use_node(cx) { + ExprUseNode::Return(_) => { + if let ExprKind::Ret(Some(e)) = use_cx.node.expect_expr().kind { + UseKind::Return(e.span) + } else { + return (UseKind::Return(DUMMY_SP), false); + } + }, + ExprUseNode::FieldAccess(name) => UseKind::FieldAccess(name.name, use_cx.node.expect_expr()), + ExprUseNode::Callee | ExprUseNode::MethodArg(_, _, 0) + if use_cx + .adjustments + .first() + .is_some_and(|a| matches!(a.kind, Adjust::Borrow(AutoBorrow::Ref(_, AutoBorrowMutability::Not)))) => + { + UseKind::AutoBorrowed + }, + ExprUseNode::Callee | ExprUseNode::MethodArg(_, _, 0) => UseKind::WillAutoDeref, + ExprUseNode::AddrOf(BorrowKind::Ref, _) => UseKind::Borrowed(use_cx.node.expect_expr().span), + _ => UseKind::Deref, + }; + (res, use_cx.same_ctxt) +} diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs index 6200716afbe99..01438b8e8db09 100644 --- a/clippy_lints/src/methods/mod.rs +++ b/clippy_lints/src/methods/mod.rs @@ -53,6 +53,7 @@ mod iter_with_drain; mod iterator_step_by_zero; mod join_absolute_paths; mod manual_c_str_literals; +mod manual_inspect; mod manual_is_variant_and; mod manual_next_back; mod manual_ok_or; @@ -4079,6 +4080,27 @@ declare_clippy_lint! { "is_ascii() called on a char iterator" } +declare_clippy_lint! { + /// ### What it does + /// Checks for uses of `map` which return the original item. + /// + /// ### Why is this bad? + /// `inspect` is both clearer in intent and shorter. + /// + /// ### Example + /// ```no_run + /// let x = Some(0).map(|x| { println!("{x}"); x }); + /// ``` + /// Use instead: + /// ```no_run + /// let x = Some(0).inspect(|x| println!("{x}")); + /// ``` + #[clippy::version = "1.78.0"] + pub MANUAL_INSPECT, + complexity, + "use of `map` returning the original item" +} + pub struct Methods { avoid_breaking_exported_api: bool, msrv: Msrv, @@ -4244,6 +4266,7 @@ impl_lint_pass!(Methods => [ MANUAL_C_STR_LITERALS, UNNECESSARY_GET_THEN_CHECK, NEEDLESS_CHARACTER_ITERATION, + MANUAL_INSPECT, ]); /// Extracts a method call name, args, and `Span` of the method name. @@ -4747,6 +4770,7 @@ impl Methods { } } map_identity::check(cx, expr, recv, m_arg, name, span); + manual_inspect::check(cx, expr, m_arg, name, span, &self.msrv); }, ("map_or", [def, map]) => { option_map_or_none::check(cx, expr, recv, def, map); diff --git a/clippy_utils/src/source.rs b/clippy_utils/src/source.rs index b7ff7ebe91052..69b122cbfadae 100644 --- a/clippy_utils/src/source.rs +++ b/clippy_utils/src/source.rs @@ -14,8 +14,17 @@ use std::borrow::Cow; use std::ops::Range; /// A type which can be converted to the range portion of a `Span`. -pub trait SpanRange { +pub trait SpanRange: Sized { fn into_range(self) -> Range; + fn set_span_pos(self, sp: Span) -> Span { + let range = self.into_range(); + SpanData { + lo: range.start, + hi: range.end, + ..sp.data() + } + .span() + } } impl SpanRange for Span { fn into_range(self) -> Range { @@ -61,6 +70,22 @@ pub fn get_source_text(cx: &impl LintContext, sp: impl SpanRange) -> Option Range { + #[expect(clippy::needless_pass_by_value, clippy::cast_possible_truncation)] + fn f(src: SourceFileRange, sp: Range) -> Range { + let Some(text) = &src.sf.src else { + return sp; + }; + let len = src.range.start - text[..src.range.start].trim_end().len(); + BytePos(sp.start.0 - len as u32)..sp.end + } + let sp = sp.into_range(); + match get_source_text(cx, sp.clone()) { + Some(src) => f(src, sp), + None => sp, + } +} + /// Like `snippet_block`, but add braces if the expr is not an `ExprKind::Block`. pub fn expr_block( cx: &T, diff --git a/clippy_utils/src/ty.rs b/clippy_utils/src/ty.rs index 7d4332a3d9de8..3f5ed73c3ef8f 100644 --- a/clippy_utils/src/ty.rs +++ b/clippy_utils/src/ty.rs @@ -1349,3 +1349,17 @@ pub fn get_adt_inherent_method<'a>(cx: &'a LateContext<'_>, ty: Ty<'_>, method_n None } } + +/// Get's the type of a field by name. +pub fn get_field_by_name<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, name: Symbol) -> Option> { + match *ty.kind() { + ty::Adt(def, args) if def.is_union() || def.is_struct() => def + .non_enum_variant() + .fields + .iter() + .find(|f| f.name == name) + .map(|f| f.ty(tcx, args)), + ty::Tuple(args) => name.as_str().parse::().ok().and_then(|i| args.get(i).copied()), + _ => None, + } +} diff --git a/tests/ui/copy_iterator.rs b/tests/ui/copy_iterator.rs index c0e5fc3e44674..ea3a4face93fe 100644 --- a/tests/ui/copy_iterator.rs +++ b/tests/ui/copy_iterator.rs @@ -1,4 +1,5 @@ #![warn(clippy::copy_iterator)] +#![allow(clippy::manual_inspect)] #[derive(Copy, Clone)] struct Countdown(u8); diff --git a/tests/ui/copy_iterator.stderr b/tests/ui/copy_iterator.stderr index 533bddaadb5ec..990b1ce628dec 100644 --- a/tests/ui/copy_iterator.stderr +++ b/tests/ui/copy_iterator.stderr @@ -1,5 +1,5 @@ error: you are implementing `Iterator` on a `Copy` type - --> tests/ui/copy_iterator.rs:6:1 + --> tests/ui/copy_iterator.rs:7:1 | LL | / impl Iterator for Countdown { LL | | diff --git a/tests/ui/manual_inspect.fixed b/tests/ui/manual_inspect.fixed new file mode 100644 index 0000000000000..0e1b8fe3edb54 --- /dev/null +++ b/tests/ui/manual_inspect.fixed @@ -0,0 +1,174 @@ +#![warn(clippy::manual_inspect)] +#![allow(clippy::no_effect, clippy::op_ref)] + +fn main() { + let _ = Some(0).inspect(|&x| { + println!("{}", x); + }); + + let _ = Some(0).inspect(|&x| { + println!("{x}"); + }); + + let _ = Some(0).inspect(|&x| { + println!("{}", x * 5 + 1); + }); + + let _ = Some(0).inspect(|&x| { + if x == 0 { + panic!(); + } + }); + + let _ = Some(0).inspect(|&x| { + if &x == &0 { + let _y = x; + panic!(); + } + }); + + let _ = Some(0).map(|x| { + let y = x + 1; + if y > 5 { + return y; + } + x + }); + + { + #[derive(PartialEq)] + struct Foo(i32); + + let _ = Some(Foo(0)).map(|x| { + if x == Foo(0) { + panic!(); + } + x + }); + + let _ = Some(Foo(0)).map(|x| { + if &x == &Foo(0) { + let _y = x; + panic!(); + } + x + }); + } + + { + macro_rules! maybe_ret { + ($e:expr) => { + if $e == 0 { + return $e; + } + }; + } + + let _ = Some(0).map(|x| { + maybe_ret!(x); + x + }); + } + + let _ = Some((String::new(), 0u32)).inspect(|x| { + if x.1 == 0 { + let _x = x.1; + panic!(); + } + }); + + let _ = Some((String::new(), 0u32)).map(|x| { + if x.1 == 0 { + let _x = x.0; + panic!(); + } + x + }); + + let _ = Some(String::new()).map(|x| { + if x.is_empty() { + let _ = || { + let _x = x; + }; + panic!(); + } + x + }); + + let _ = Some(String::new()).inspect(|x| { + if x.is_empty() { + let _ = || { + let _x = x; + }; + return; + } + println!("test"); + }); + + let _ = Some(0).inspect(|&x| { + if x == 0 { + let _ = || { + let _x = x; + }; + panic!(); + } + }); + + { + use core::cell::Cell; + #[derive(Debug)] + struct Cell2(core::cell::Cell); + + let _ = Some(Cell2(Cell::new(0u32))).inspect(|x| { + x.0.set(1); + }); + + let _ = Some(Cell2(Cell::new(0u32))).map(|x| { + let y = &x; + if x.0.get() == 0 { + y.0.set(1) + } else { + println!("{x:?}"); + } + x + }); + } + + let _: Result<_, ()> = Ok(0).inspect(|&x| { + println!("{}", x); + }); + + let _: Result<(), _> = Err(0).inspect_err(|&x| { + println!("{}", x); + }); + + let _ = [0] + .into_iter() + .inspect(|&x| { + println!("{}", x); + }) + .count(); + + { + struct S(T); + impl S { + fn map(self, f: impl FnOnce(T) -> U) -> S { + S(f(self.0)) + } + + fn map_err(self, f: impl FnOnce(T) -> U) -> S { + S(f(self.0)) + } + } + + let _ = S(0).map(|x| { + println!("{}", x); + x + }); + + let _ = S(0).map_err(|x| { + println!("{}", x); + x + }); + } +} diff --git a/tests/ui/manual_inspect.rs b/tests/ui/manual_inspect.rs new file mode 100644 index 0000000000000..94cdfe3914006 --- /dev/null +++ b/tests/ui/manual_inspect.rs @@ -0,0 +1,186 @@ +#![warn(clippy::manual_inspect)] +#![allow(clippy::no_effect, clippy::op_ref)] + +fn main() { + let _ = Some(0).map(|x| { + println!("{}", x); + x + }); + + let _ = Some(0).map(|x| { + println!("{x}"); + x + }); + + let _ = Some(0).map(|x| { + println!("{}", x * 5 + 1); + x + }); + + let _ = Some(0).map(|x| { + if x == 0 { + panic!(); + } + x + }); + + let _ = Some(0).map(|x| { + if &x == &0 { + let _y = x; + panic!(); + } + x + }); + + let _ = Some(0).map(|x| { + let y = x + 1; + if y > 5 { + return y; + } + x + }); + + { + #[derive(PartialEq)] + struct Foo(i32); + + let _ = Some(Foo(0)).map(|x| { + if x == Foo(0) { + panic!(); + } + x + }); + + let _ = Some(Foo(0)).map(|x| { + if &x == &Foo(0) { + let _y = x; + panic!(); + } + x + }); + } + + { + macro_rules! maybe_ret { + ($e:expr) => { + if $e == 0 { + return $e; + } + }; + } + + let _ = Some(0).map(|x| { + maybe_ret!(x); + x + }); + } + + let _ = Some((String::new(), 0u32)).map(|x| { + if x.1 == 0 { + let _x = x.1; + panic!(); + } + x + }); + + let _ = Some((String::new(), 0u32)).map(|x| { + if x.1 == 0 { + let _x = x.0; + panic!(); + } + x + }); + + let _ = Some(String::new()).map(|x| { + if x.is_empty() { + let _ = || { + let _x = x; + }; + panic!(); + } + x + }); + + let _ = Some(String::new()).map(|x| { + if x.is_empty() { + let _ = || { + let _x = &x; + }; + return x; + } + println!("test"); + x + }); + + let _ = Some(0).map(|x| { + if x == 0 { + let _ = || { + let _x = x; + }; + panic!(); + } + x + }); + + { + use core::cell::Cell; + #[derive(Debug)] + struct Cell2(core::cell::Cell); + + let _ = Some(Cell2(Cell::new(0u32))).map(|x| { + x.0.set(1); + x + }); + + let _ = Some(Cell2(Cell::new(0u32))).map(|x| { + let y = &x; + if x.0.get() == 0 { + y.0.set(1) + } else { + println!("{x:?}"); + } + x + }); + } + + let _: Result<_, ()> = Ok(0).map(|x| { + println!("{}", x); + x + }); + + let _: Result<(), _> = Err(0).map_err(|x| { + println!("{}", x); + x + }); + + let _ = [0] + .into_iter() + .map(|x| { + println!("{}", x); + x + }) + .count(); + + { + struct S(T); + impl S { + fn map(self, f: impl FnOnce(T) -> U) -> S { + S(f(self.0)) + } + + fn map_err(self, f: impl FnOnce(T) -> U) -> S { + S(f(self.0)) + } + } + + let _ = S(0).map(|x| { + println!("{}", x); + x + }); + + let _ = S(0).map_err(|x| { + println!("{}", x); + x + }); + } +} diff --git a/tests/ui/manual_inspect.stderr b/tests/ui/manual_inspect.stderr new file mode 100644 index 0000000000000..efdf115b84e57 --- /dev/null +++ b/tests/ui/manual_inspect.stderr @@ -0,0 +1,182 @@ +error: + --> tests/ui/manual_inspect.rs:5:21 + | +LL | let _ = Some(0).map(|x| { + | ^^^ + | + = note: `-D clippy::manual-inspect` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::manual_inspect)]` +help: try + | +LL ~ let _ = Some(0).inspect(|&x| { +LL ~ println!("{}", x); + | + +error: + --> tests/ui/manual_inspect.rs:10:21 + | +LL | let _ = Some(0).map(|x| { + | ^^^ + | +help: try + | +LL ~ let _ = Some(0).inspect(|&x| { +LL ~ println!("{x}"); + | + +error: + --> tests/ui/manual_inspect.rs:15:21 + | +LL | let _ = Some(0).map(|x| { + | ^^^ + | +help: try + | +LL ~ let _ = Some(0).inspect(|&x| { +LL ~ println!("{}", x * 5 + 1); + | + +error: + --> tests/ui/manual_inspect.rs:20:21 + | +LL | let _ = Some(0).map(|x| { + | ^^^ + | +help: try + | +LL ~ let _ = Some(0).inspect(|&x| { +LL | if x == 0 { +LL | panic!(); +LL ~ } + | + +error: + --> tests/ui/manual_inspect.rs:27:21 + | +LL | let _ = Some(0).map(|x| { + | ^^^ + | +help: try + | +LL ~ let _ = Some(0).inspect(|&x| { +LL | if &x == &0 { +LL | let _y = x; +LL | panic!(); +LL ~ } + | + +error: + --> tests/ui/manual_inspect.rs:78:41 + | +LL | let _ = Some((String::new(), 0u32)).map(|x| { + | ^^^ + | +help: try + | +LL ~ let _ = Some((String::new(), 0u32)).inspect(|x| { +LL | if x.1 == 0 { +LL | let _x = x.1; +LL | panic!(); +LL ~ } + | + +error: + --> tests/ui/manual_inspect.rs:104:33 + | +LL | let _ = Some(String::new()).map(|x| { + | ^^^ + | +help: try + | +LL ~ let _ = Some(String::new()).inspect(|x| { +LL | if x.is_empty() { +LL | let _ = || { +LL ~ let _x = x; +LL | }; +LL ~ return; +LL | } +LL ~ println!("test"); + | + +error: + --> tests/ui/manual_inspect.rs:115:21 + | +LL | let _ = Some(0).map(|x| { + | ^^^ + | +help: try + | +LL ~ let _ = Some(0).inspect(|&x| { +LL | if x == 0 { + ... +LL | panic!(); +LL ~ } + | + +error: + --> tests/ui/manual_inspect.rs:130:46 + | +LL | let _ = Some(Cell2(Cell::new(0u32))).map(|x| { + | ^^^ + | +help: try + | +LL ~ let _ = Some(Cell2(Cell::new(0u32))).inspect(|x| { +LL ~ x.0.set(1); + | + +error: + --> tests/ui/manual_inspect.rs:146:34 + | +LL | let _: Result<_, ()> = Ok(0).map(|x| { + | ^^^ + | +help: try + | +LL ~ let _: Result<_, ()> = Ok(0).inspect(|&x| { +LL ~ println!("{}", x); + | + +error: + --> tests/ui/manual_inspect.rs:151:35 + | +LL | let _: Result<(), _> = Err(0).map_err(|x| { + | ^^^^^^^ + | +help: try + | +LL ~ let _: Result<(), _> = Err(0).inspect_err(|&x| { +LL ~ println!("{}", x); + | + +error: this call to `map()` won't have an effect on the call to `count()` + --> tests/ui/manual_inspect.rs:156:13 + | +LL | let _ = [0] + | _____________^ +LL | | .into_iter() +LL | | .map(|x| { +LL | | println!("{}", x); +LL | | x +LL | | }) +LL | | .count(); + | |________________^ + | + = help: make sure you did not confuse `map` with `filter`, `for_each` or `inspect` + = note: `-D clippy::suspicious-map` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::suspicious_map)]` + +error: + --> tests/ui/manual_inspect.rs:158:10 + | +LL | .map(|x| { + | ^^^ + | +help: try + | +LL ~ .inspect(|&x| { +LL ~ println!("{}", x); + | + +error: aborting due to 13 previous errors + From e18b31087414ebb01683b538077ee23582cbf82a Mon Sep 17 00:00:00 2001 From: Jason Newcomb Date: Sun, 16 Jun 2024 20:15:09 -0400 Subject: [PATCH 191/892] Add more types to `is_from_proc_macro` --- clippy_lints/src/allow_attributes.rs | 2 +- .../attrs/allow_attributes_without_reason.rs | 2 +- clippy_utils/src/check_proc_macro.rs | 84 +++++++++---------- 3 files changed, 44 insertions(+), 44 deletions(-) diff --git a/clippy_lints/src/allow_attributes.rs b/clippy_lints/src/allow_attributes.rs index 990f724ab9d9f..1f2a47e7f0923 100644 --- a/clippy_lints/src/allow_attributes.rs +++ b/clippy_lints/src/allow_attributes.rs @@ -57,7 +57,7 @@ impl LateLintPass<'_> for AllowAttribute { && let AttrStyle::Outer = attr.style && let Some(ident) = attr.ident() && ident.name == rustc_span::symbol::sym::allow - && !is_from_proc_macro(cx, &attr) + && !is_from_proc_macro(cx, attr) { span_lint_and_sugg( cx, diff --git a/clippy_lints/src/attrs/allow_attributes_without_reason.rs b/clippy_lints/src/attrs/allow_attributes_without_reason.rs index 4a22e17463fcc..6a5349bca66a0 100644 --- a/clippy_lints/src/attrs/allow_attributes_without_reason.rs +++ b/clippy_lints/src/attrs/allow_attributes_without_reason.rs @@ -22,7 +22,7 @@ pub(super) fn check<'cx>(cx: &LateContext<'cx>, name: Symbol, items: &[NestedMet } // Check if the attribute is in an external macro and therefore out of the developer's control - if in_external_macro(cx.sess(), attr.span) || is_from_proc_macro(cx, &attr) { + if in_external_macro(cx.sess(), attr.span) || is_from_proc_macro(cx, attr) { return; } diff --git a/clippy_utils/src/check_proc_macro.rs b/clippy_utils/src/check_proc_macro.rs index 553e899997504..7f2234b310b42 100644 --- a/clippy_utils/src/check_proc_macro.rs +++ b/clippy_utils/src/check_proc_macro.rs @@ -18,8 +18,8 @@ use rustc_ast::AttrStyle; use rustc_hir::intravisit::FnKind; use rustc_hir::{ Block, BlockCheckMode, Body, Closure, Destination, Expr, ExprKind, FieldDef, FnHeader, FnRetTy, HirId, Impl, - ImplItem, ImplItemKind, IsAuto, Item, ItemKind, LoopSource, MatchSource, MutTy, Node, QPath, Safety, TraitItem, - TraitItemKind, Ty, TyKind, UnOp, UnsafeSource, Variant, VariantData, YieldSource, + ImplItem, ImplItemKind, IsAuto, Item, ItemKind, Lit, LoopSource, MatchSource, MutTy, Node, Path, QPath, Safety, + TraitItem, TraitItemKind, Ty, TyKind, UnOp, UnsafeSource, Variant, VariantData, YieldSource, }; use rustc_lint::{LateContext, LintContext}; use rustc_middle::ty::TyCtxt; @@ -121,6 +121,26 @@ fn qpath_search_pat(path: &QPath<'_>) -> (Pat, Pat) { } } +fn path_search_pat(path: &Path<'_>) -> (Pat, Pat) { + let (head, tail) = match path.segments { + [head, .., tail] => (head, tail), + [p] => (p, p), + [] => return (Pat::Str(""), Pat::Str("")), + }; + ( + if head.ident.name == kw::PathRoot { + Pat::Str("::") + } else { + Pat::Sym(head.ident.name) + }, + if tail.args.is_some() { + Pat::Str(">") + } else { + Pat::Sym(tail.ident.name) + }, + ) +} + /// Get the search patterns to use for the given expression fn expr_search_pat(tcx: TyCtxt<'_>, e: &Expr<'_>) -> (Pat, Pat) { match e.kind { @@ -355,19 +375,21 @@ fn ty_search_pat(ty: &Ty<'_>) -> (Pat, Pat) { } } +fn ident_search_pat(ident: Ident) -> (Pat, Pat) { + (Pat::Sym(ident.name), Pat::Sym(ident.name)) +} + pub trait WithSearchPat<'cx> { type Context: LintContext; fn search_pat(&self, cx: &Self::Context) -> (Pat, Pat); fn span(&self) -> Span; } macro_rules! impl_with_search_pat { - ($cx:ident: $ty:ident with $fn:ident $(($tcx:ident))?) => { - impl<'cx> WithSearchPat<'cx> for $ty<'cx> { - type Context = $cx<'cx>; - #[allow(unused_variables)] - fn search_pat(&self, cx: &Self::Context) -> (Pat, Pat) { - $(let $tcx = cx.tcx;)? - $fn($($tcx,)? self) + (($cx_ident:ident: $cx_ty:ident<$cx_lt:lifetime>, $self:tt: $ty:ty) => $fn:ident($($args:tt)*)) => { + impl<$cx_lt> WithSearchPat<$cx_lt> for $ty { + type Context = $cx_ty<$cx_lt>; + fn search_pat(&$self, $cx_ident: &Self::Context) -> (Pat, Pat) { + $fn($($args)*) } fn span(&self) -> Span { self.span @@ -375,13 +397,17 @@ macro_rules! impl_with_search_pat { } }; } -impl_with_search_pat!(LateContext: Expr with expr_search_pat(tcx)); -impl_with_search_pat!(LateContext: Item with item_search_pat); -impl_with_search_pat!(LateContext: TraitItem with trait_item_search_pat); -impl_with_search_pat!(LateContext: ImplItem with impl_item_search_pat); -impl_with_search_pat!(LateContext: FieldDef with field_def_search_pat); -impl_with_search_pat!(LateContext: Variant with variant_search_pat); -impl_with_search_pat!(LateContext: Ty with ty_search_pat); +impl_with_search_pat!((cx: LateContext<'tcx>, self: Expr<'tcx>) => expr_search_pat(cx.tcx, self)); +impl_with_search_pat!((_cx: LateContext<'tcx>, self: Item<'_>) => item_search_pat(self)); +impl_with_search_pat!((_cx: LateContext<'tcx>, self: TraitItem<'_>) => trait_item_search_pat(self)); +impl_with_search_pat!((_cx: LateContext<'tcx>, self: ImplItem<'_>) => impl_item_search_pat(self)); +impl_with_search_pat!((_cx: LateContext<'tcx>, self: FieldDef<'_>) => field_def_search_pat(self)); +impl_with_search_pat!((_cx: LateContext<'tcx>, self: Variant<'_>) => variant_search_pat(self)); +impl_with_search_pat!((_cx: LateContext<'tcx>, self: Ty<'_>) => ty_search_pat(self)); +impl_with_search_pat!((_cx: LateContext<'tcx>, self: Attribute) => attr_search_pat(self)); +impl_with_search_pat!((_cx: LateContext<'tcx>, self: Ident) => ident_search_pat(*self)); +impl_with_search_pat!((_cx: LateContext<'tcx>, self: Lit) => lit_search_pat(&self.node)); +impl_with_search_pat!((_cx: LateContext<'tcx>, self: Path<'_>) => path_search_pat(self)); impl<'cx> WithSearchPat<'cx> for (&FnKind<'cx>, &Body<'cx>, HirId, Span) { type Context = LateContext<'cx>; @@ -395,32 +421,6 @@ impl<'cx> WithSearchPat<'cx> for (&FnKind<'cx>, &Body<'cx>, HirId, Span) { } } -// `Attribute` does not have the `hir` associated lifetime, so we cannot use the macro -impl<'cx> WithSearchPat<'cx> for &'cx Attribute { - type Context = LateContext<'cx>; - - fn search_pat(&self, _cx: &Self::Context) -> (Pat, Pat) { - attr_search_pat(self) - } - - fn span(&self) -> Span { - self.span - } -} - -// `Ident` does not have the `hir` associated lifetime, so we cannot use the macro -impl<'cx> WithSearchPat<'cx> for Ident { - type Context = LateContext<'cx>; - - fn search_pat(&self, _cx: &Self::Context) -> (Pat, Pat) { - (Pat::Sym(self.name), Pat::Sym(self.name)) - } - - fn span(&self) -> Span { - self.span - } -} - /// Checks if the item likely came from a proc-macro. /// /// This should be called after `in_external_macro` and the initial pattern matching of the ast as From f09650b347f6f0d38747662db4382729cd058247 Mon Sep 17 00:00:00 2001 From: Jason Newcomb Date: Sun, 16 Jun 2024 14:38:58 -0400 Subject: [PATCH 192/892] Use symbols when raising range expressions. --- clippy_utils/src/higher.rs | 63 ++++++++++++++++++++------------------ 1 file changed, 34 insertions(+), 29 deletions(-) diff --git a/clippy_utils/src/higher.rs b/clippy_utils/src/higher.rs index 801a98521590d..277ba8427e054 100644 --- a/clippy_utils/src/higher.rs +++ b/clippy_utils/src/higher.rs @@ -218,51 +218,56 @@ pub struct Range<'a> { impl<'a> Range<'a> { /// Higher a `hir` range to something similar to `ast::ExprKind::Range`. + #[allow(clippy::similar_names)] pub fn hir(expr: &'a Expr<'_>) -> Option> { - /// Finds the field named `name` in the field. Always return `Some` for - /// convenience. - fn get_field<'c>(name: &str, fields: &'c [hir::ExprField<'_>]) -> Option<&'c Expr<'c>> { - let expr = &fields.iter().find(|field| field.ident.name.as_str() == name)?.expr; - Some(expr) - } - match expr.kind { - ExprKind::Call(path, args) + ExprKind::Call(path, [arg1, arg2]) if matches!( path.kind, ExprKind::Path(QPath::LangItem(hir::LangItem::RangeInclusiveNew, ..)) ) => { Some(Range { - start: Some(&args[0]), - end: Some(&args[1]), + start: Some(arg1), + end: Some(arg2), limits: ast::RangeLimits::Closed, }) }, - ExprKind::Struct(path, fields, None) => match &path { - QPath::LangItem(hir::LangItem::RangeFull, ..) => Some(Range { + ExprKind::Struct(path, fields, None) => match (path, fields) { + (QPath::LangItem(hir::LangItem::RangeFull, ..), []) => Some(Range { start: None, end: None, limits: ast::RangeLimits::HalfOpen, }), - QPath::LangItem(hir::LangItem::RangeFrom, ..) => Some(Range { - start: Some(get_field("start", fields)?), - end: None, - limits: ast::RangeLimits::HalfOpen, - }), - QPath::LangItem(hir::LangItem::Range, ..) => Some(Range { - start: Some(get_field("start", fields)?), - end: Some(get_field("end", fields)?), - limits: ast::RangeLimits::HalfOpen, - }), - QPath::LangItem(hir::LangItem::RangeToInclusive, ..) => Some(Range { - start: None, - end: Some(get_field("end", fields)?), - limits: ast::RangeLimits::Closed, - }), - QPath::LangItem(hir::LangItem::RangeTo, ..) => Some(Range { + (QPath::LangItem(hir::LangItem::RangeFrom, ..), [field]) if field.ident.name == sym::start => { + Some(Range { + start: Some(field.expr), + end: None, + limits: ast::RangeLimits::HalfOpen, + }) + }, + (QPath::LangItem(hir::LangItem::Range, ..), [field1, field2]) => { + let (start, end) = match (field1.ident.name, field2.ident.name) { + (sym::start, sym::end) => (field1.expr, field2.expr), + (sym::end, sym::start) => (field2.expr, field1.expr), + _ => return None, + }; + Some(Range { + start: Some(start), + end: Some(end), + limits: ast::RangeLimits::HalfOpen, + }) + }, + (QPath::LangItem(hir::LangItem::RangeToInclusive, ..), [field]) if field.ident.name == sym::end => { + Some(Range { + start: None, + end: Some(field.expr), + limits: ast::RangeLimits::Closed, + }) + }, + (QPath::LangItem(hir::LangItem::RangeTo, ..), [field]) if field.ident.name == sym::end => Some(Range { start: None, - end: Some(get_field("end", fields)?), + end: Some(field.expr), limits: ast::RangeLimits::HalfOpen, }), _ => None, From 54aa510c32180887632cd262782c8efc6dfc6acb Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sun, 16 Jun 2024 21:35:16 -0400 Subject: [PATCH 193/892] Rename InstanceDef -> InstanceKind --- src/abi/mod.rs | 14 +++++++------- src/constant.rs | 2 +- src/intrinsics/mod.rs | 2 +- src/lib.rs | 2 +- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/abi/mod.rs b/src/abi/mod.rs index bd5a88769059f..695dbaf2804b1 100644 --- a/src/abi/mod.rs +++ b/src/abi/mod.rs @@ -399,7 +399,7 @@ pub(crate) fn codegen_terminator_call<'tcx>( } match instance.def { - InstanceDef::Intrinsic(_) => { + InstanceKind::Intrinsic(_) => { match crate::intrinsics::codegen_intrinsic_call( fx, instance, @@ -412,7 +412,7 @@ pub(crate) fn codegen_terminator_call<'tcx>( Err(instance) => Some(instance), } } - InstanceDef::DropGlue(_, None) | ty::InstanceDef::AsyncDropGlueCtorShim(_, None) => { + InstanceKind::DropGlue(_, None) | ty::InstanceKind::AsyncDropGlueCtorShim(_, None) => { // empty drop glue - a nop. let dest = target.expect("Non terminating drop_in_place_real???"); let ret_block = fx.get_block(dest); @@ -494,7 +494,7 @@ pub(crate) fn codegen_terminator_call<'tcx>( let (func_ref, first_arg_override) = match instance { // Trait object call - Some(Instance { def: InstanceDef::Virtual(_, idx), .. }) => { + Some(Instance { def: InstanceKind::Virtual(_, idx), .. }) => { if fx.clif_comments.enabled() { let nop_inst = fx.bcx.ins().nop(); fx.add_comment( @@ -598,7 +598,7 @@ pub(crate) fn codegen_drop<'tcx>( let ty = drop_place.layout().ty; let drop_instance = Instance::resolve_drop_in_place(fx.tcx, ty).polymorphize(fx.tcx); - if let ty::InstanceDef::DropGlue(_, None) | ty::InstanceDef::AsyncDropGlueCtorShim(_, None) = + if let ty::InstanceKind::DropGlue(_, None) | ty::InstanceKind::AsyncDropGlueCtorShim(_, None) = drop_instance.def { // we don't actually need to drop anything @@ -630,7 +630,7 @@ pub(crate) fn codegen_drop<'tcx>( // FIXME(eddyb) perhaps move some of this logic into // `Instance::resolve_drop_in_place`? let virtual_drop = Instance { - def: ty::InstanceDef::Virtual(drop_instance.def_id(), 0), + def: ty::InstanceKind::Virtual(drop_instance.def_id(), 0), args: drop_instance.args, }; let fn_abi = @@ -673,7 +673,7 @@ pub(crate) fn codegen_drop<'tcx>( fx.bcx.switch_to_block(continued); let virtual_drop = Instance { - def: ty::InstanceDef::Virtual(drop_instance.def_id(), 0), + def: ty::InstanceKind::Virtual(drop_instance.def_id(), 0), args: drop_instance.args, }; let fn_abi = @@ -684,7 +684,7 @@ pub(crate) fn codegen_drop<'tcx>( fx.bcx.ins().call_indirect(sig, drop_fn, &[data]); } _ => { - assert!(!matches!(drop_instance.def, InstanceDef::Virtual(_, _))); + assert!(!matches!(drop_instance.def, InstanceKind::Virtual(_, _))); let fn_abi = RevealAllLayoutCx(fx.tcx).fn_abi_of_instance(drop_instance, ty::List::empty()); diff --git a/src/constant.rs b/src/constant.rs index a53598018f4a4..87c5da3b7c3ed 100644 --- a/src/constant.rs +++ b/src/constant.rs @@ -50,7 +50,7 @@ pub(crate) fn codegen_tls_ref<'tcx>( ) -> CValue<'tcx> { let tls_ptr = if !def_id.is_local() && fx.tcx.needs_thread_local_shim(def_id) { let instance = ty::Instance { - def: ty::InstanceDef::ThreadLocalShim(def_id), + def: ty::InstanceKind::ThreadLocalShim(def_id), args: ty::GenericArgs::empty(), }; let func_ref = fx.get_function_ref(instance); diff --git a/src/intrinsics/mod.rs b/src/intrinsics/mod.rs index cafdc051db5ac..b21c559e6686c 100644 --- a/src/intrinsics/mod.rs +++ b/src/intrinsics/mod.rs @@ -1261,7 +1261,7 @@ fn codegen_regular_intrinsic_call<'tcx>( } // Unimplemented intrinsics must have a fallback body. The fallback body is obtained - // by converting the `InstanceDef::Intrinsic` to an `InstanceDef::Item`. + // by converting the `InstanceKind::Intrinsic` to an `InstanceKind::Item`. _ => { let intrinsic = fx.tcx.intrinsic(instance.def_id()).unwrap(); if intrinsic.must_be_overridden { diff --git a/src/lib.rs b/src/lib.rs index 0fea3fd425391..2edb34e7c20dc 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -98,7 +98,7 @@ mod prelude { pub(crate) use rustc_middle::mir::{self, *}; pub(crate) use rustc_middle::ty::layout::{LayoutOf, TyAndLayout}; pub(crate) use rustc_middle::ty::{ - self, FloatTy, Instance, InstanceDef, IntTy, ParamEnv, Ty, TyCtxt, UintTy, + self, FloatTy, Instance, InstanceKind, IntTy, ParamEnv, Ty, TyCtxt, UintTy, }; pub(crate) use rustc_span::Span; pub(crate) use rustc_target::abi::{Abi, FieldIdx, Scalar, Size, VariantIdx, FIRST_VARIANT}; From 4b16e265a78aa74fc4fe727ca18882ce684afbbb Mon Sep 17 00:00:00 2001 From: Jason Newcomb Date: Sat, 15 Jun 2024 15:14:50 -0400 Subject: [PATCH 194/892] Rework `octal_escapes`. --- clippy_lints/src/octal_escapes.rs | 161 +++++++++++--------------- tests/ui/octal_escapes.rs | 27 ++--- tests/ui/octal_escapes.stderr | 180 +++++++++++++++++------------- 3 files changed, 175 insertions(+), 193 deletions(-) diff --git a/clippy_lints/src/octal_escapes.rs b/clippy_lints/src/octal_escapes.rs index 2fc039ae886e4..0a7a2cd616ca9 100644 --- a/clippy_lints/src/octal_escapes.rs +++ b/clippy_lints/src/octal_escapes.rs @@ -1,12 +1,12 @@ use clippy_utils::diagnostics::span_lint_and_then; -use rustc_ast::ast::{Expr, ExprKind}; -use rustc_ast::token::{Lit, LitKind}; +use clippy_utils::source::get_source_text; +use rustc_ast::token::LitKind; +use rustc_ast::{Expr, ExprKind}; use rustc_errors::Applicability; use rustc_lint::{EarlyContext, EarlyLintPass, LintContext}; use rustc_middle::lint::in_external_macro; use rustc_session::declare_lint_pass; -use rustc_span::Span; -use std::fmt::Write; +use rustc_span::{BytePos, Pos, SpanData}; declare_clippy_lint! { /// ### What it does @@ -52,104 +52,69 @@ declare_lint_pass!(OctalEscapes => [OCTAL_ESCAPES]); impl EarlyLintPass for OctalEscapes { fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) { - if in_external_macro(cx.sess(), expr.span) { - return; - } - - if let ExprKind::Lit(token_lit) = &expr.kind { - if matches!(token_lit.kind, LitKind::Str) { - check_lit(cx, token_lit, expr.span, true); - } else if matches!(token_lit.kind, LitKind::ByteStr) { - check_lit(cx, token_lit, expr.span, false); - } - } - } -} - -fn check_lit(cx: &EarlyContext<'_>, lit: &Lit, span: Span, is_string: bool) { - let contents = lit.symbol.as_str(); - let mut iter = contents.char_indices().peekable(); - let mut found = vec![]; + if let ExprKind::Lit(lit) = &expr.kind + // The number of bytes from the start of the token to the start of literal's text. + && let start_offset = BytePos::from_u32(match lit.kind { + LitKind::Str => 1, + LitKind::ByteStr | LitKind::CStr => 2, + _ => return, + }) + && !in_external_macro(cx.sess(), expr.span) + { + let s = lit.symbol.as_str(); + let mut iter = s.as_bytes().iter(); + while let Some(&c) = iter.next() { + if c == b'\\' + // Always move the iterator to read the escape char. + && let Some(b'0') = iter.next() + { + // C-style octal escapes read from one to three characters. + // The first character (`0`) has already been read. + let (tail, len, c_hi, c_lo) = match *iter.as_slice() { + [c_hi @ b'0'..=b'7', c_lo @ b'0'..=b'7', ref tail @ ..] => (tail, 4, c_hi, c_lo), + [c_lo @ b'0'..=b'7', ref tail @ ..] => (tail, 3, b'0', c_lo), + _ => continue, + }; + iter = tail.iter(); + let offset = start_offset + BytePos::from_usize(s.len() - tail.len()); + let data = expr.span.data(); + let span = SpanData { + lo: data.lo + offset - BytePos::from_u32(len), + hi: data.lo + offset, + ..data + } + .span(); - // go through the string, looking for \0[0-7][0-7]? - while let Some((from, ch)) = iter.next() { - if ch == '\\' { - if let Some((_, '0')) = iter.next() { - // collect up to two further octal digits - if let Some((mut to, _)) = iter.next_if(|(_, ch)| matches!(ch, '0'..='7')) { - if iter.next_if(|(_, ch)| matches!(ch, '0'..='7')).is_some() { - to += 1; + // Last check to make sure the source text matches what we read from the string. + // Macros are involved somehow if this doesn't match. + if let Some(src) = get_source_text(cx, span) + && let Some(src) = src.as_str() + && match *src.as_bytes() { + [b'\\', b'0', lo] => lo == c_lo, + [b'\\', b'0', hi, lo] => hi == c_hi && lo == c_lo, + _ => false, + } + { + span_lint_and_then(cx, OCTAL_ESCAPES, span, "octal-looking escape in a literal", |diag| { + diag.help_once("octal escapes are not supported, `\\0` is always null") + .span_suggestion( + span, + "if an octal escape is intended, use a hex escape instead", + format!("\\x{:02x}", (((c_hi - b'0') << 3) | (c_lo - b'0'))), + Applicability::MaybeIncorrect, + ) + .span_suggestion( + span, + "if a null escape is intended, disambiguate using", + format!("\\x00{}{}", c_hi as char, c_lo as char), + Applicability::MaybeIncorrect, + ); + }); + } else { + break; } - found.push((from, to + 1)); } } } } - - if found.is_empty() { - return; - } - - span_lint_and_then( - cx, - OCTAL_ESCAPES, - span, - format!( - "octal-looking escape in {} literal", - if is_string { "string" } else { "byte string" } - ), - |diag| { - diag.help(format!( - "octal escapes are not supported, `\\0` is always a null {}", - if is_string { "character" } else { "byte" } - )); - - // Generate suggestions if the string is not too long (~ 5 lines) - if contents.len() < 400 { - // construct two suggestion strings, one with \x escapes with octal meaning - // as in C, and one with \x00 for null bytes. - let mut suggest_1 = if is_string { "\"" } else { "b\"" }.to_string(); - let mut suggest_2 = suggest_1.clone(); - let mut index = 0; - for (from, to) in found { - suggest_1.push_str(&contents[index..from]); - suggest_2.push_str(&contents[index..from]); - - // construct a replacement escape - // the maximum value is \077, or \x3f, so u8 is sufficient here - if let Ok(n) = u8::from_str_radix(&contents[from + 1..to], 8) { - write!(suggest_1, "\\x{n:02x}").unwrap(); - } - - // append the null byte as \x00 and the following digits literally - suggest_2.push_str("\\x00"); - suggest_2.push_str(&contents[from + 2..to]); - - index = to; - } - suggest_1.push_str(&contents[index..]); - suggest_2.push_str(&contents[index..]); - - suggest_1.push('"'); - suggest_2.push('"'); - // suggestion 1: equivalent hex escape - diag.span_suggestion( - span, - "if an octal escape was intended, use the hexadecimal representation instead", - suggest_1, - Applicability::MaybeIncorrect, - ); - // suggestion 2: unambiguous null byte - diag.span_suggestion( - span, - format!( - "if the null {} is intended, disambiguate using", - if is_string { "character" } else { "byte" } - ), - suggest_2, - Applicability::MaybeIncorrect, - ); - } - }, - ); } diff --git a/tests/ui/octal_escapes.rs b/tests/ui/octal_escapes.rs index 3915dfdb8418b..f2664e2fa67ff 100644 --- a/tests/ui/octal_escapes.rs +++ b/tests/ui/octal_escapes.rs @@ -2,25 +2,20 @@ #![warn(clippy::octal_escapes)] fn main() { - let _bad1 = "\033[0m"; - //~^ ERROR: octal-looking escape in string literal - let _bad2 = b"\033[0m"; - //~^ ERROR: octal-looking escape in byte string literal - let _bad3 = "\\\033[0m"; - //~^ ERROR: octal-looking escape in string literal + let _bad1 = "\033[0m"; //~ octal_escapes + let _bad2 = b"\033[0m"; //~ octal_escapes + let _bad3 = "\\\033[0m"; //~ octal_escapes // maximum 3 digits (\012 is the escape) - let _bad4 = "\01234567"; - //~^ ERROR: octal-looking escape in string literal - let _bad5 = "\0\03"; - //~^ ERROR: octal-looking escape in string literal + let _bad4 = "\01234567"; //~ octal_escapes + let _bad5 = "\0\03"; //~ octal_escapes let _bad6 = "Text-\055\077-MoreText"; - //~^ ERROR: octal-looking escape in string literal + //~^ octal_escapes + //~| octal_escapes let _bad7 = "EvenMoreText-\01\02-ShortEscapes"; - //~^ ERROR: octal-looking escape in string literal - let _bad8 = "锈\01锈"; - //~^ ERROR: octal-looking escape in string literal - let _bad9 = "锈\011锈"; - //~^ ERROR: octal-looking escape in string literal + //~^ octal_escapes + //~| octal_escapes + let _bad8 = "锈\01锈"; //~ octal_escapes + let _bad9 = "锈\011锈"; //~ octal_escapes let _good1 = "\\033[0m"; let _good2 = "\0\\0"; diff --git a/tests/ui/octal_escapes.stderr b/tests/ui/octal_escapes.stderr index 7ed9ee3ae2f4f..9343ba64a30b3 100644 --- a/tests/ui/octal_escapes.stderr +++ b/tests/ui/octal_escapes.stderr @@ -1,148 +1,170 @@ -error: octal-looking escape in string literal - --> tests/ui/octal_escapes.rs:5:17 +error: octal-looking escape in a literal + --> tests/ui/octal_escapes.rs:5:18 | LL | let _bad1 = "\033[0m"; - | ^^^^^^^^^ + | ^^^^ | - = help: octal escapes are not supported, `\0` is always a null character + = help: octal escapes are not supported, `\0` is always null = note: `-D clippy::octal-escapes` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::octal_escapes)]` -help: if an octal escape was intended, use the hexadecimal representation instead +help: if an octal escape is intended, use a hex escape instead | LL | let _bad1 = "\x1b[0m"; - | ~~~~~~~~~ -help: if the null character is intended, disambiguate using + | ~~~~ +help: if a null escape is intended, disambiguate using | LL | let _bad1 = "\x0033[0m"; - | ~~~~~~~~~~~ + | ~~~~~~ -error: octal-looking escape in byte string literal - --> tests/ui/octal_escapes.rs:7:17 +error: octal-looking escape in a literal + --> tests/ui/octal_escapes.rs:6:19 | LL | let _bad2 = b"\033[0m"; - | ^^^^^^^^^^ + | ^^^^ | - = help: octal escapes are not supported, `\0` is always a null byte -help: if an octal escape was intended, use the hexadecimal representation instead +help: if an octal escape is intended, use a hex escape instead | LL | let _bad2 = b"\x1b[0m"; - | ~~~~~~~~~~ -help: if the null byte is intended, disambiguate using + | ~~~~ +help: if a null escape is intended, disambiguate using | LL | let _bad2 = b"\x0033[0m"; - | ~~~~~~~~~~~~ + | ~~~~~~ -error: octal-looking escape in string literal - --> tests/ui/octal_escapes.rs:9:17 +error: octal-looking escape in a literal + --> tests/ui/octal_escapes.rs:7:20 | LL | let _bad3 = "\\\033[0m"; - | ^^^^^^^^^^^ + | ^^^^ | - = help: octal escapes are not supported, `\0` is always a null character -help: if an octal escape was intended, use the hexadecimal representation instead +help: if an octal escape is intended, use a hex escape instead | LL | let _bad3 = "\\\x1b[0m"; - | ~~~~~~~~~~~ -help: if the null character is intended, disambiguate using + | ~~~~ +help: if a null escape is intended, disambiguate using | LL | let _bad3 = "\\\x0033[0m"; - | ~~~~~~~~~~~~~ + | ~~~~~~ -error: octal-looking escape in string literal - --> tests/ui/octal_escapes.rs:12:17 +error: octal-looking escape in a literal + --> tests/ui/octal_escapes.rs:9:18 | LL | let _bad4 = "\01234567"; - | ^^^^^^^^^^^ + | ^^^^ | - = help: octal escapes are not supported, `\0` is always a null character -help: if an octal escape was intended, use the hexadecimal representation instead +help: if an octal escape is intended, use a hex escape instead | LL | let _bad4 = "\x0a34567"; - | ~~~~~~~~~~~ -help: if the null character is intended, disambiguate using + | ~~~~ +help: if a null escape is intended, disambiguate using | LL | let _bad4 = "\x001234567"; - | ~~~~~~~~~~~~~ + | ~~~~~~ -error: octal-looking escape in string literal - --> tests/ui/octal_escapes.rs:14:17 +error: octal-looking escape in a literal + --> tests/ui/octal_escapes.rs:10:20 | LL | let _bad5 = "\0\03"; - | ^^^^^^^ + | ^^^ | - = help: octal escapes are not supported, `\0` is always a null character -help: if an octal escape was intended, use the hexadecimal representation instead +help: if an octal escape is intended, use a hex escape instead | LL | let _bad5 = "\0\x03"; - | ~~~~~~~~ -help: if the null character is intended, disambiguate using + | ~~~~ +help: if a null escape is intended, disambiguate using | -LL | let _bad5 = "\0\x003"; - | ~~~~~~~~~ +LL | let _bad5 = "\0\x0003"; + | ~~~~~~ -error: octal-looking escape in string literal - --> tests/ui/octal_escapes.rs:16:17 +error: octal-looking escape in a literal + --> tests/ui/octal_escapes.rs:11:23 | LL | let _bad6 = "Text-\055\077-MoreText"; - | ^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^ | - = help: octal escapes are not supported, `\0` is always a null character -help: if an octal escape was intended, use the hexadecimal representation instead +help: if an octal escape is intended, use a hex escape instead | -LL | let _bad6 = "Text-\x2d\x3f-MoreText"; - | ~~~~~~~~~~~~~~~~~~~~~~~~ -help: if the null character is intended, disambiguate using +LL | let _bad6 = "Text-\x2d\077-MoreText"; + | ~~~~ +help: if a null escape is intended, disambiguate using | -LL | let _bad6 = "Text-\x0055\x0077-MoreText"; - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL | let _bad6 = "Text-\x0055\077-MoreText"; + | ~~~~~~ -error: octal-looking escape in string literal - --> tests/ui/octal_escapes.rs:18:17 +error: octal-looking escape in a literal + --> tests/ui/octal_escapes.rs:11:27 + | +LL | let _bad6 = "Text-\055\077-MoreText"; + | ^^^^ + | +help: if an octal escape is intended, use a hex escape instead + | +LL | let _bad6 = "Text-\055\x3f-MoreText"; + | ~~~~ +help: if a null escape is intended, disambiguate using + | +LL | let _bad6 = "Text-\055\x0077-MoreText"; + | ~~~~~~ + +error: octal-looking escape in a literal + --> tests/ui/octal_escapes.rs:14:31 + | +LL | let _bad7 = "EvenMoreText-\01\02-ShortEscapes"; + | ^^^ + | +help: if an octal escape is intended, use a hex escape instead + | +LL | let _bad7 = "EvenMoreText-\x01\02-ShortEscapes"; + | ~~~~ +help: if a null escape is intended, disambiguate using + | +LL | let _bad7 = "EvenMoreText-\x0001\02-ShortEscapes"; + | ~~~~~~ + +error: octal-looking escape in a literal + --> tests/ui/octal_escapes.rs:14:34 | LL | let _bad7 = "EvenMoreText-\01\02-ShortEscapes"; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^ | - = help: octal escapes are not supported, `\0` is always a null character -help: if an octal escape was intended, use the hexadecimal representation instead +help: if an octal escape is intended, use a hex escape instead | -LL | let _bad7 = "EvenMoreText-\x01\x02-ShortEscapes"; - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -help: if the null character is intended, disambiguate using +LL | let _bad7 = "EvenMoreText-\01\x02-ShortEscapes"; + | ~~~~ +help: if a null escape is intended, disambiguate using | -LL | let _bad7 = "EvenMoreText-\x001\x002-ShortEscapes"; - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL | let _bad7 = "EvenMoreText-\01\x0002-ShortEscapes"; + | ~~~~~~ -error: octal-looking escape in string literal - --> tests/ui/octal_escapes.rs:20:17 +error: octal-looking escape in a literal + --> tests/ui/octal_escapes.rs:17:19 | LL | let _bad8 = "锈\01锈"; - | ^^^^^^^^^ + | ^^^ | - = help: octal escapes are not supported, `\0` is always a null character -help: if an octal escape was intended, use the hexadecimal representation instead +help: if an octal escape is intended, use a hex escape instead | LL | let _bad8 = "锈\x01锈"; - | ~~~~~~~~~~ -help: if the null character is intended, disambiguate using + | ~~~~ +help: if a null escape is intended, disambiguate using | -LL | let _bad8 = "锈\x001锈"; - | ~~~~~~~~~~~ +LL | let _bad8 = "锈\x0001锈"; + | ~~~~~~ -error: octal-looking escape in string literal - --> tests/ui/octal_escapes.rs:22:17 +error: octal-looking escape in a literal + --> tests/ui/octal_escapes.rs:18:19 | LL | let _bad9 = "锈\011锈"; - | ^^^^^^^^^^ + | ^^^^ | - = help: octal escapes are not supported, `\0` is always a null character -help: if an octal escape was intended, use the hexadecimal representation instead +help: if an octal escape is intended, use a hex escape instead | LL | let _bad9 = "锈\x09锈"; - | ~~~~~~~~~~ -help: if the null character is intended, disambiguate using + | ~~~~ +help: if a null escape is intended, disambiguate using | LL | let _bad9 = "锈\x0011锈"; - | ~~~~~~~~~~~~ + | ~~~~~~ -error: aborting due to 9 previous errors +error: aborting due to 11 previous errors From 9e442c1dc22006536c1c71f5273d72d01d7f4ddd Mon Sep 17 00:00:00 2001 From: The Miri Cronjob Bot Date: Mon, 17 Jun 2024 05:02:59 +0000 Subject: [PATCH 195/892] 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 e49680ba75a5e..c1796cfd82a67 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version @@ -1 +1 @@ -f6b4b71ef10307201b52c17b0f9dcf9557cd90ba +e794b0f8557c187b5909d889aa35071f81e0a4cc From a4b36e5adbb50eb827053f036d335d4bd3e6829a Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Mon, 17 Jun 2024 07:57:10 +0000 Subject: [PATCH 196/892] Rustup to rustc 1.81.0-nightly (d7f6ebace 2024-06-16) --- patches/stdlib-lock.toml | 4 ++-- rust-toolchain | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/patches/stdlib-lock.toml b/patches/stdlib-lock.toml index aea0a779b1e11..9ea53e8f848d9 100644 --- a/patches/stdlib-lock.toml +++ b/patches/stdlib-lock.toml @@ -158,9 +158,9 @@ dependencies = [ [[package]] name = "hermit-abi" -version = "0.3.9" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" +checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc" dependencies = [ "compiler_builtins", "rustc-std-workspace-alloc", diff --git a/rust-toolchain b/rust-toolchain index 35d7372a196ee..3cb1f15bb3f21 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2024-06-11" +channel = "nightly-2024-06-17" components = ["rust-src", "rustc-dev", "llvm-tools"] From e24117653571901c8e1a2212fb93dd0cc4401aaf Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Mon, 17 Jun 2024 08:27:01 +0000 Subject: [PATCH 197/892] Fix rustc tests --- scripts/test_rustc_tests.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/scripts/test_rustc_tests.sh b/scripts/test_rustc_tests.sh index fce46459cac4d..62a1c61c9069d 100755 --- a/scripts/test_rustc_tests.sh +++ b/scripts/test_rustc_tests.sh @@ -89,6 +89,7 @@ rm -r tests/run-make/sepcomp-cci-copies # same rm -r tests/run-make/volatile-intrinsics # same rm -r tests/run-make/llvm-ident # same rm -r tests/run-make/no-builtins-attribute # same +rm -r tests/run-make/pgo-gen-no-imp-symbols # same rm tests/ui/abi/stack-protector.rs # requires stack protector support rm -r tests/run-make/emit-stack-sizes # requires support for -Z emit-stack-sizes rm -r tests/run-make/optimization-remarks-dir # remarks are LLVM specific @@ -103,6 +104,7 @@ rm -r tests/run-make/emit-to-stdout rm -r tests/run-make/compressed-debuginfo rm -r tests/run-make/symbols-include-type-name rm -r tests/run-make/notify-all-emit-artifacts +rm -r tests/run-make/reset-codegen-1 # giving different but possibly correct results # ============================================= @@ -125,6 +127,7 @@ rm -r tests/run-make/panic-abort-eh_frame # .eh_frame emitted with panic=abort # bugs in the test suite # ====================== rm tests/ui/process/nofile-limit.rs # TODO some AArch64 linking issue +rm -r tests/run-make/const_fn_mir # needs-unwind directive accidentally dropped rm tests/ui/stdio-is-blocking.rs # really slow with unoptimized libstd @@ -151,7 +154,7 @@ index 9607ff02f96..b7d97caf9a2 100644 --- a/src/tools/run-make-support/src/rustdoc.rs +++ b/src/tools/run-make-support/src/rustdoc.rs @@ -34,8 +34,6 @@ pub fn bare() -> Self { - /// Construct a \`rustdoc\` invocation with \`-L \$(TARGET_RPATH_DIR)\` set. + #[track_caller] pub fn new() -> Self { let mut cmd = setup_common(); - let target_rpath_dir = env_var_os("TARGET_RPATH_DIR"); From b8db9f0785dce07f6ee49eae3c493af5ea161c0a Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 17 Jun 2024 11:41:18 +0200 Subject: [PATCH 198/892] show proper UB when making a too large allocation request --- src/tools/miri/src/alloc_bytes.rs | 24 +++++++++++-------- src/tools/miri/src/shims/alloc.rs | 12 ---------- src/tools/miri/src/shims/foreign_items.rs | 24 +++++++++++++++---- src/tools/miri/tests/fail/alloc/too_large.rs | 10 ++++++++ .../miri/tests/fail/alloc/too_large.stderr | 15 ++++++++++++ 5 files changed, 59 insertions(+), 26 deletions(-) create mode 100644 src/tools/miri/tests/fail/alloc/too_large.rs create mode 100644 src/tools/miri/tests/fail/alloc/too_large.stderr diff --git a/src/tools/miri/src/alloc_bytes.rs b/src/tools/miri/src/alloc_bytes.rs index 97841a05cdebf..87579293001de 100644 --- a/src/tools/miri/src/alloc_bytes.rs +++ b/src/tools/miri/src/alloc_bytes.rs @@ -64,17 +64,19 @@ impl MiriAllocBytes { /// If `size == 0` we allocate using a different `alloc_layout` with `size = 1`, to ensure each allocation has a unique address. /// Returns `Err(alloc_layout)` if the allocation function returns a `ptr` where `ptr.is_null()`. fn alloc_with( - size: usize, - align: usize, + size: u64, + align: u64, alloc_fn: impl FnOnce(Layout) -> *mut u8, - ) -> Result { - let layout = Layout::from_size_align(size, align).unwrap(); + ) -> Result { + let size = usize::try_from(size).map_err(|_| ())?; + let align = usize::try_from(align).map_err(|_| ())?; + let layout = Layout::from_size_align(size, align).map_err(|_| ())?; // When size is 0 we allocate 1 byte anyway, to ensure each allocation has a unique address. let alloc_layout = if size == 0 { Layout::from_size_align(1, align).unwrap() } else { layout }; let ptr = alloc_fn(alloc_layout); if ptr.is_null() { - Err(alloc_layout) + Err(()) } else { // SAFETY: All `MiriAllocBytes` invariants are fulfilled. Ok(Self { ptr, layout }) @@ -86,11 +88,13 @@ impl AllocBytes for MiriAllocBytes { fn from_bytes<'a>(slice: impl Into>, align: Align) -> Self { let slice = slice.into(); let size = slice.len(); - let align = align.bytes_usize(); + let align = align.bytes(); // SAFETY: `alloc_fn` will only be used with `size != 0`. let alloc_fn = |layout| unsafe { alloc::alloc(layout) }; - let alloc_bytes = MiriAllocBytes::alloc_with(size, align, alloc_fn) - .unwrap_or_else(|layout| alloc::handle_alloc_error(layout)); + let alloc_bytes = MiriAllocBytes::alloc_with(size.try_into().unwrap(), align, alloc_fn) + .unwrap_or_else(|()| { + panic!("Miri ran out of memory: cannot create allocation of {size} bytes") + }); // SAFETY: `alloc_bytes.ptr` and `slice.as_ptr()` are non-null, properly aligned // and valid for the `size`-many bytes to be copied. unsafe { alloc_bytes.ptr.copy_from(slice.as_ptr(), size) }; @@ -98,8 +102,8 @@ impl AllocBytes for MiriAllocBytes { } fn zeroed(size: Size, align: Align) -> Option { - let size = size.bytes_usize(); - let align = align.bytes_usize(); + let size = size.bytes(); + let align = align.bytes(); // SAFETY: `alloc_fn` will only be used with `size != 0`. let alloc_fn = |layout| unsafe { alloc::alloc_zeroed(layout) }; MiriAllocBytes::alloc_with(size, align, alloc_fn).ok() diff --git a/src/tools/miri/src/shims/alloc.rs b/src/tools/miri/src/shims/alloc.rs index 7b0c54d763e41..a33657d33a2e1 100644 --- a/src/tools/miri/src/shims/alloc.rs +++ b/src/tools/miri/src/shims/alloc.rs @@ -5,18 +5,6 @@ use rustc_target::abi::{Align, Size}; use crate::*; -/// Check some basic requirements for this allocation request: -/// non-zero size, power-of-two alignment. -pub(super) fn check_alloc_request<'tcx>(size: u64, align: u64) -> InterpResult<'tcx> { - if size == 0 { - throw_ub_format!("creating allocation with size 0"); - } - if !align.is_power_of_two() { - throw_ub_format!("creating allocation with non-power-of-two alignment {}", align); - } - Ok(()) -} - impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {} pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { /// Returns the alignment that `malloc` would guarantee for requests of the given size. diff --git a/src/tools/miri/src/shims/foreign_items.rs b/src/tools/miri/src/shims/foreign_items.rs index 898fc111fd43f..b8d85a1950297 100644 --- a/src/tools/miri/src/shims/foreign_items.rs +++ b/src/tools/miri/src/shims/foreign_items.rs @@ -12,7 +12,7 @@ use rustc_target::{ spec::abi::Abi, }; -use super::alloc::{check_alloc_request, EvalContextExt as _}; +use super::alloc::EvalContextExt as _; use super::backtrace::EvalContextExt as _; use crate::*; use helpers::{ToHost, ToSoft}; @@ -204,6 +204,22 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { impl<'tcx> EvalContextExtPriv<'tcx> for crate::MiriInterpCx<'tcx> {} trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { + /// Check some basic requirements for this allocation request: + /// non-zero size, power-of-two alignment. + fn check_rustc_alloc_request(&self, size: u64, align: u64) -> InterpResult<'tcx> { + let this = self.eval_context_ref(); + if size == 0 { + throw_ub_format!("creating allocation with size 0"); + } + if i128::from(size) > this.tcx.data_layout.pointer_size.signed_int_max() { + throw_ub_format!("creating an allocation larger than half the address space"); + } + if !align.is_power_of_two() { + throw_ub_format!("creating allocation with non-power-of-two alignment {}", align); + } + Ok(()) + } + fn emulate_foreign_item_inner( &mut self, link_name: Symbol, @@ -462,7 +478,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { let size = this.read_target_usize(size)?; let align = this.read_target_usize(align)?; - check_alloc_request(size, align)?; + this.check_rustc_alloc_request(size, align)?; let memory_kind = match link_name.as_str() { "__rust_alloc" => MiriMemoryKind::Rust, @@ -496,7 +512,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { let size = this.read_target_usize(size)?; let align = this.read_target_usize(align)?; - check_alloc_request(size, align)?; + this.check_rustc_alloc_request(size, align)?; let ptr = this.allocate_ptr( Size::from_bytes(size), @@ -560,7 +576,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { let new_size = this.read_target_usize(new_size)?; // No need to check old_size; we anyway check that they match the allocation. - check_alloc_request(new_size, align)?; + this.check_rustc_alloc_request(new_size, align)?; let align = Align::from_bytes(align).unwrap(); let new_ptr = this.reallocate_ptr( diff --git a/src/tools/miri/tests/fail/alloc/too_large.rs b/src/tools/miri/tests/fail/alloc/too_large.rs new file mode 100644 index 0000000000000..4e28d2401d79f --- /dev/null +++ b/src/tools/miri/tests/fail/alloc/too_large.rs @@ -0,0 +1,10 @@ +extern "Rust" { + fn __rust_alloc(size: usize, align: usize) -> *mut u8; +} + +fn main() { + let bytes = isize::MAX as usize + 1; + unsafe { + __rust_alloc(bytes, 1); //~ERROR: larger than half the address space + } +} diff --git a/src/tools/miri/tests/fail/alloc/too_large.stderr b/src/tools/miri/tests/fail/alloc/too_large.stderr new file mode 100644 index 0000000000000..77dcf91d843f9 --- /dev/null +++ b/src/tools/miri/tests/fail/alloc/too_large.stderr @@ -0,0 +1,15 @@ +error: Undefined Behavior: creating an allocation larger than half the address space + --> $DIR/too_large.rs:LL:CC + | +LL | __rust_alloc(bytes, 1); + | ^^^^^^^^^^^^^^^^^^^^^^ creating an allocation larger than half the address space + | + = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior + = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information + = note: BACKTRACE: + = note: inside `main` at $DIR/too_large.rs:LL:CC + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to 1 previous error + From 54594d64a441fd8750a3be436bc1bdcb30b49d18 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 17 Jun 2024 12:19:12 +0200 Subject: [PATCH 199/892] tell people how to set miri flags --- src/tools/miri/cargo-miri/src/phases.rs | 6 ++++ src/tools/miri/src/diagnostics.rs | 29 +++++++++---------- src/tools/miri/src/eval.rs | 11 ++----- .../libc_pthread_create_main_terminate.stderr | 2 +- .../libc/aligned_alloc_size_zero_leak.stderr | 2 +- .../fail-dep/libc/fs/isolated_stdin.stderr | 4 +-- .../libc/malloc_zero_memory_leak.stderr | 2 +- .../libc/posix_memalign_size_zero_leak.stderr | 2 +- .../ptr_metadata_uninit_slice_len.stderr | 7 ++--- src/tools/miri/tests/fail/memleak.stderr | 2 +- .../miri/tests/fail/memleak_no_backtrace.rs | 2 +- .../tests/fail/memleak_no_backtrace.stderr | 4 ++- .../miri/tests/fail/memleak_rc.64bit.stderr | 25 ---------------- src/tools/miri/tests/fail/memleak_rc.rs | 2 +- ...leak_rc.32bit.stderr => memleak_rc.stderr} | 4 +-- .../tests/fail/shims/fs/isolated_file.stderr | 4 +-- .../miri/tests/fail/tls_macro_leak.stderr | 2 +- .../miri/tests/fail/tls_static_leak.stderr | 2 +- src/tools/miri/tests/pass/box.stack.stderr | 7 ++--- .../miri/tests/pass/extern_types.stack.stderr | 7 ++--- .../stacked-borrows/issue-miri-2389.stderr | 7 ++--- 21 files changed, 52 insertions(+), 81 deletions(-) delete mode 100644 src/tools/miri/tests/fail/memleak_rc.64bit.stderr rename src/tools/miri/tests/fail/{memleak_rc.32bit.stderr => memleak_rc.stderr} (86%) diff --git a/src/tools/miri/cargo-miri/src/phases.rs b/src/tools/miri/cargo-miri/src/phases.rs index 3c36f606d8452..8d48b9c8ad14b 100644 --- a/src/tools/miri/cargo-miri/src/phases.rs +++ b/src/tools/miri/cargo-miri/src/phases.rs @@ -23,6 +23,12 @@ Subcommands: clean Clean the Miri cache & target directory The cargo options are exactly the same as for `cargo run` and `cargo test`, respectively. +Furthermore, the following extra flags and environment variables are recognized for `run` and `test`: + + --many-seeds[=from..to] Run the program/tests many times with different seeds in the given range. + The range defaults to `0..64`. + + MIRIFLAGS Extra flags to pass to the Miri driver. Use this to pass `-Zmiri-...` flags. Examples: cargo miri run diff --git a/src/tools/miri/src/diagnostics.rs b/src/tools/miri/src/diagnostics.rs index 14e29aa423d8d..47f0913accee1 100644 --- a/src/tools/miri/src/diagnostics.rs +++ b/src/tools/miri/src/diagnostics.rs @@ -227,8 +227,8 @@ pub fn report_error<'tcx>( let helps = match info { UnsupportedInIsolation(_) => vec![ - (None, format!("pass the flag `-Zmiri-disable-isolation` to disable isolation;")), - (None, format!("or pass `-Zmiri-isolation-error=warn` to configure Miri to return an error code from isolated operations (if supported for that operation) and continue with a warning")), + (None, format!("set `MIRIFLAGS=-Zmiri-disable-isolation` to disable isolation;")), + (None, format!("or set `MIRIFLAGS=-Zmiri-isolation-error=warn` to make Miri return an error code from isolated operations (if supported for that operation) and continue with a warning")), ], UnsupportedForeignItem(_) => { vec![ @@ -463,19 +463,22 @@ pub fn report_leaks<'tcx>( ) { let mut any_pruned = false; for (id, kind, mut alloc) in leaks { + let mut title = format!( + "memory leaked: {id:?} ({}, size: {:?}, align: {:?})", + kind, + alloc.size().bytes(), + alloc.align.bytes() + ); let Some(backtrace) = alloc.extra.backtrace.take() else { + ecx.tcx.dcx().err(title); continue; }; + title.push_str(", allocated here:"); let (backtrace, pruned) = prune_stacktrace(backtrace, &ecx.machine); any_pruned |= pruned; report_msg( DiagLevel::Error, - format!( - "memory leaked: {id:?} ({}, size: {:?}, align: {:?}), allocated here:", - kind, - alloc.size().bytes(), - alloc.align.bytes() - ), + title, vec![], vec![], vec![], @@ -642,13 +645,9 @@ impl<'tcx> MiriMachine<'tcx> { ( None, format!( - "This program is using integer-to-pointer casts or (equivalently) `ptr::with_exposed_provenance`," + "This program is using integer-to-pointer casts or (equivalently) `ptr::with_exposed_provenance`, which means that Miri might miss pointer bugs in this program." ), ), - ( - None, - format!("which means that Miri might miss pointer bugs in this program."), - ), ( None, format!( @@ -664,13 +663,13 @@ impl<'tcx> MiriMachine<'tcx> { ( None, format!( - "You can then pass the `-Zmiri-strict-provenance` flag to Miri, to ensure you are not relying on `with_exposed_provenance` semantics." + "You can then set `MIRIFLAGS=-Zmiri-strict-provenance` to ensure you are not relying on `with_exposed_provenance` semantics." ), ), ( None, format!( - "Alternatively, the `-Zmiri-permissive-provenance` flag disables this warning." + "Alternatively, `MIRIFLAGS=-Zmiri-permissive-provenance` disables this warning." ), ), ], diff --git a/src/tools/miri/src/eval.rs b/src/tools/miri/src/eval.rs index 35f7f43f123f1..bd11439971c52 100644 --- a/src/tools/miri/src/eval.rs +++ b/src/tools/miri/src/eval.rs @@ -468,7 +468,7 @@ pub fn eval_entry<'tcx>( // Check for thread leaks. if !ecx.have_all_terminated() { tcx.dcx().err("the main thread terminated without waiting for all remaining threads"); - tcx.dcx().note("pass `-Zmiri-ignore-leaks` to disable this check"); + tcx.dcx().note("set `MIRIFLAGS=-Zmiri-ignore-leaks` to disable this check"); return None; } // Check for memory leaks. @@ -476,14 +476,7 @@ pub fn eval_entry<'tcx>( let leaks = ecx.find_leaked_allocations(&ecx.machine.static_roots); if !leaks.is_empty() { report_leaks(&ecx, leaks); - let leak_message = "the evaluated program leaked memory, pass `-Zmiri-ignore-leaks` to disable this check"; - if ecx.machine.collect_leak_backtraces { - // If we are collecting leak backtraces, each leak is a distinct error diagnostic. - tcx.dcx().note(leak_message); - } else { - // If we do not have backtraces, we just report an error without any span. - tcx.dcx().err(leak_message); - }; + tcx.dcx().note("set `MIRIFLAGS=-Zmiri-ignore-leaks` to disable this check"); // Ignore the provided return code - let the reported error // determine the return code. return None; diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_create_main_terminate.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_create_main_terminate.stderr index 078b7d2e0d846..9d6be16b83a4b 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_create_main_terminate.stderr +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_create_main_terminate.stderr @@ -1,6 +1,6 @@ error: the main thread terminated without waiting for all remaining threads -note: pass `-Zmiri-ignore-leaks` to disable this check +note: set `MIRIFLAGS=-Zmiri-ignore-leaks` to disable this check error: aborting due to 1 previous error diff --git a/src/tools/miri/tests/fail-dep/libc/aligned_alloc_size_zero_leak.stderr b/src/tools/miri/tests/fail-dep/libc/aligned_alloc_size_zero_leak.stderr index b0756d572120f..91c67823320a1 100644 --- a/src/tools/miri/tests/fail-dep/libc/aligned_alloc_size_zero_leak.stderr +++ b/src/tools/miri/tests/fail-dep/libc/aligned_alloc_size_zero_leak.stderr @@ -9,7 +9,7 @@ LL | aligned_alloc(2, 0); note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace -note: the evaluated program leaked memory, pass `-Zmiri-ignore-leaks` to disable this check +note: set `MIRIFLAGS=-Zmiri-ignore-leaks` to disable this check error: aborting due to 1 previous error diff --git a/src/tools/miri/tests/fail-dep/libc/fs/isolated_stdin.stderr b/src/tools/miri/tests/fail-dep/libc/fs/isolated_stdin.stderr index 1d6626dda704f..9abe145ea9ef7 100644 --- a/src/tools/miri/tests/fail-dep/libc/fs/isolated_stdin.stderr +++ b/src/tools/miri/tests/fail-dep/libc/fs/isolated_stdin.stderr @@ -4,8 +4,8 @@ error: unsupported operation: `read` from stdin not available when isolation is LL | libc::read(0, bytes.as_mut_ptr() as *mut libc::c_void, 512); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `read` from stdin not available when isolation is enabled | - = help: pass the flag `-Zmiri-disable-isolation` to disable isolation; - = help: or pass `-Zmiri-isolation-error=warn` to configure Miri to return an error code from isolated operations (if supported for that operation) and continue with a warning + = help: set `MIRIFLAGS=-Zmiri-disable-isolation` to disable isolation; + = help: or set `MIRIFLAGS=-Zmiri-isolation-error=warn` to make Miri return an error code from isolated operations (if supported for that operation) and continue with a warning = note: BACKTRACE: = note: inside `main` at $DIR/isolated_stdin.rs:LL:CC diff --git a/src/tools/miri/tests/fail-dep/libc/malloc_zero_memory_leak.stderr b/src/tools/miri/tests/fail-dep/libc/malloc_zero_memory_leak.stderr index 65ce0dcdcddea..657262b8d4136 100644 --- a/src/tools/miri/tests/fail-dep/libc/malloc_zero_memory_leak.stderr +++ b/src/tools/miri/tests/fail-dep/libc/malloc_zero_memory_leak.stderr @@ -9,7 +9,7 @@ LL | let _ptr = libc::malloc(0); note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace -note: the evaluated program leaked memory, pass `-Zmiri-ignore-leaks` to disable this check +note: set `MIRIFLAGS=-Zmiri-ignore-leaks` to disable this check error: aborting due to 1 previous error diff --git a/src/tools/miri/tests/fail-dep/libc/posix_memalign_size_zero_leak.stderr b/src/tools/miri/tests/fail-dep/libc/posix_memalign_size_zero_leak.stderr index 7ea0fa3146976..2639031f1cc50 100644 --- a/src/tools/miri/tests/fail-dep/libc/posix_memalign_size_zero_leak.stderr +++ b/src/tools/miri/tests/fail-dep/libc/posix_memalign_size_zero_leak.stderr @@ -9,7 +9,7 @@ LL | let _ = unsafe { libc::posix_memalign(&mut ptr, align, size) }; note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace -note: the evaluated program leaked memory, pass `-Zmiri-ignore-leaks` to disable this check +note: set `MIRIFLAGS=-Zmiri-ignore-leaks` to disable this check error: aborting due to 1 previous error diff --git a/src/tools/miri/tests/fail/intrinsics/ptr_metadata_uninit_slice_len.stderr b/src/tools/miri/tests/fail/intrinsics/ptr_metadata_uninit_slice_len.stderr index 4e2e721843238..217bc82010df9 100644 --- a/src/tools/miri/tests/fail/intrinsics/ptr_metadata_uninit_slice_len.stderr +++ b/src/tools/miri/tests/fail/intrinsics/ptr_metadata_uninit_slice_len.stderr @@ -4,12 +4,11 @@ warning: integer-to-pointer cast LL | (*p.as_mut_ptr().cast::<[*const i32; 2]>())[0] = 4 as *const i32; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ integer-to-pointer cast | - = help: This program is using integer-to-pointer casts or (equivalently) `ptr::with_exposed_provenance`, - = help: which means that Miri might miss pointer bugs in this program. + = help: This program is using integer-to-pointer casts or (equivalently) `ptr::with_exposed_provenance`, which means that Miri might miss pointer bugs in this program. = help: See https://doc.rust-lang.org/nightly/std/ptr/fn.with_exposed_provenance.html for more details on that operation. = help: To ensure that Miri does not miss bugs in your program, use Strict Provenance APIs (https://doc.rust-lang.org/nightly/std/ptr/index.html#strict-provenance, https://crates.io/crates/sptr) instead. - = help: You can then pass the `-Zmiri-strict-provenance` flag to Miri, to ensure you are not relying on `with_exposed_provenance` semantics. - = help: Alternatively, the `-Zmiri-permissive-provenance` flag disables this warning. + = help: You can then set `MIRIFLAGS=-Zmiri-strict-provenance` to ensure you are not relying on `with_exposed_provenance` semantics. + = help: Alternatively, `MIRIFLAGS=-Zmiri-permissive-provenance` disables this warning. = note: BACKTRACE: = note: inside `main` at $DIR/ptr_metadata_uninit_slice_len.rs:LL:CC diff --git a/src/tools/miri/tests/fail/memleak.stderr b/src/tools/miri/tests/fail/memleak.stderr index 8ba78ef66443e..a9ee76fbe8a78 100644 --- a/src/tools/miri/tests/fail/memleak.stderr +++ b/src/tools/miri/tests/fail/memleak.stderr @@ -18,7 +18,7 @@ LL | std::mem::forget(Box::new(42)); note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace -note: the evaluated program leaked memory, pass `-Zmiri-ignore-leaks` to disable this check +note: set `MIRIFLAGS=-Zmiri-ignore-leaks` to disable this check error: aborting due to 1 previous error diff --git a/src/tools/miri/tests/fail/memleak_no_backtrace.rs b/src/tools/miri/tests/fail/memleak_no_backtrace.rs index a1f8d9957ff8e..1f8d8ba7a7cf4 100644 --- a/src/tools/miri/tests/fail/memleak_no_backtrace.rs +++ b/src/tools/miri/tests/fail/memleak_no_backtrace.rs @@ -1,5 +1,5 @@ //@compile-flags: -Zmiri-disable-leak-backtraces -//@error-in-other-file: the evaluated program leaked memory +//@error-in-other-file: memory leaked //@normalize-stderr-test: ".*│.*" -> "$$stripped$$" fn main() { diff --git a/src/tools/miri/tests/fail/memleak_no_backtrace.stderr b/src/tools/miri/tests/fail/memleak_no_backtrace.stderr index 22e8c558061ae..6850928e1503c 100644 --- a/src/tools/miri/tests/fail/memleak_no_backtrace.stderr +++ b/src/tools/miri/tests/fail/memleak_no_backtrace.stderr @@ -1,4 +1,6 @@ -error: the evaluated program leaked memory, pass `-Zmiri-ignore-leaks` to disable this check +error: memory leaked: ALLOC (Rust heap, size: 4, align: 4) + +note: set `MIRIFLAGS=-Zmiri-ignore-leaks` to disable this check error: aborting due to 1 previous error diff --git a/src/tools/miri/tests/fail/memleak_rc.64bit.stderr b/src/tools/miri/tests/fail/memleak_rc.64bit.stderr deleted file mode 100644 index 1c85a0f9d9f69..0000000000000 --- a/src/tools/miri/tests/fail/memleak_rc.64bit.stderr +++ /dev/null @@ -1,25 +0,0 @@ -error: memory leaked: ALLOC (Rust heap, size: 32, align: 8), allocated here: - --> RUSTLIB/alloc/src/alloc.rs:LL:CC - | -LL | __rust_alloc(layout.size(), layout.align()) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: BACKTRACE: - = note: inside `std::alloc::alloc` at RUSTLIB/alloc/src/alloc.rs:LL:CC - = note: inside `std::alloc::Global::alloc_impl` at RUSTLIB/alloc/src/alloc.rs:LL:CC - = note: inside `::allocate` at RUSTLIB/alloc/src/alloc.rs:LL:CC - = note: inside `alloc::alloc::exchange_malloc` at RUSTLIB/alloc/src/alloc.rs:LL:CC - = note: inside `std::boxed::Box::>>>::new` at RUSTLIB/alloc/src/boxed.rs:LL:CC - = note: inside `std::rc::Rc::>>::new` at RUSTLIB/alloc/src/rc.rs:LL:CC -note: inside `main` - --> $DIR/memleak_rc.rs:LL:CC - | -LL | let x = Dummy(Rc::new(RefCell::new(None))); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace - -note: the evaluated program leaked memory, pass `-Zmiri-ignore-leaks` to disable this check - -error: aborting due to 1 previous error - diff --git a/src/tools/miri/tests/fail/memleak_rc.rs b/src/tools/miri/tests/fail/memleak_rc.rs index 0927612d08eac..2d12c1223cf28 100644 --- a/src/tools/miri/tests/fail/memleak_rc.rs +++ b/src/tools/miri/tests/fail/memleak_rc.rs @@ -1,6 +1,6 @@ //@error-in-other-file: memory leaked -//@stderr-per-bitwidth //@normalize-stderr-test: ".*│.*" -> "$$stripped$$" +//@normalize-stderr-test: "Rust heap, size: [0-9]+, align: [0-9]+" -> "Rust heap, SIZE, ALIGN" use std::cell::RefCell; use std::rc::Rc; diff --git a/src/tools/miri/tests/fail/memleak_rc.32bit.stderr b/src/tools/miri/tests/fail/memleak_rc.stderr similarity index 86% rename from src/tools/miri/tests/fail/memleak_rc.32bit.stderr rename to src/tools/miri/tests/fail/memleak_rc.stderr index 781e1458db9e3..dbf2daf818c6f 100644 --- a/src/tools/miri/tests/fail/memleak_rc.32bit.stderr +++ b/src/tools/miri/tests/fail/memleak_rc.stderr @@ -1,4 +1,4 @@ -error: memory leaked: ALLOC (Rust heap, size: 16, align: 4), allocated here: +error: memory leaked: ALLOC (Rust heap, SIZE, ALIGN), allocated here: --> RUSTLIB/alloc/src/alloc.rs:LL:CC | LL | __rust_alloc(layout.size(), layout.align()) @@ -19,7 +19,7 @@ LL | let x = Dummy(Rc::new(RefCell::new(None))); note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace -note: the evaluated program leaked memory, pass `-Zmiri-ignore-leaks` to disable this check +note: set `MIRIFLAGS=-Zmiri-ignore-leaks` to disable this check error: aborting due to 1 previous error diff --git a/src/tools/miri/tests/fail/shims/fs/isolated_file.stderr b/src/tools/miri/tests/fail/shims/fs/isolated_file.stderr index 1f08649428a4c..ec956f83348e3 100644 --- a/src/tools/miri/tests/fail/shims/fs/isolated_file.stderr +++ b/src/tools/miri/tests/fail/shims/fs/isolated_file.stderr @@ -4,8 +4,8 @@ error: unsupported operation: `open` not available when isolation is enabled LL | let fd = cvt_r(|| unsafe { open64(path.as_ptr(), flags, opts.mode as c_int) })?; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `open` not available when isolation is enabled | - = help: pass the flag `-Zmiri-disable-isolation` to disable isolation; - = help: or pass `-Zmiri-isolation-error=warn` to configure Miri to return an error code from isolated operations (if supported for that operation) and continue with a warning + = help: set `MIRIFLAGS=-Zmiri-disable-isolation` to disable isolation; + = help: or set `MIRIFLAGS=-Zmiri-isolation-error=warn` to make Miri return an error code from isolated operations (if supported for that operation) and continue with a warning = note: BACKTRACE: = note: inside closure at RUSTLIB/std/src/sys/pal/PLATFORM/fs.rs:LL:CC = note: inside `std::sys::pal::PLATFORM::cvt_r::` at RUSTLIB/std/src/sys/pal/PLATFORM/mod.rs:LL:CC diff --git a/src/tools/miri/tests/fail/tls_macro_leak.stderr b/src/tools/miri/tests/fail/tls_macro_leak.stderr index 40b21f8625a4a..c7c641a30f1bd 100644 --- a/src/tools/miri/tests/fail/tls_macro_leak.stderr +++ b/src/tools/miri/tests/fail/tls_macro_leak.stderr @@ -27,7 +27,7 @@ LL | | }); note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace -note: the evaluated program leaked memory, pass `-Zmiri-ignore-leaks` to disable this check +note: set `MIRIFLAGS=-Zmiri-ignore-leaks` to disable this check error: aborting due to 1 previous error diff --git a/src/tools/miri/tests/fail/tls_static_leak.stderr b/src/tools/miri/tests/fail/tls_static_leak.stderr index 580b52c151269..f7b90a1118c85 100644 --- a/src/tools/miri/tests/fail/tls_static_leak.stderr +++ b/src/tools/miri/tests/fail/tls_static_leak.stderr @@ -18,7 +18,7 @@ LL | TLS.set(Some(Box::leak(Box::new(123)))); note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace -note: the evaluated program leaked memory, pass `-Zmiri-ignore-leaks` to disable this check +note: set `MIRIFLAGS=-Zmiri-ignore-leaks` to disable this check error: aborting due to 1 previous error diff --git a/src/tools/miri/tests/pass/box.stack.stderr b/src/tools/miri/tests/pass/box.stack.stderr index 1a4d52ee3146f..341f84c8992df 100644 --- a/src/tools/miri/tests/pass/box.stack.stderr +++ b/src/tools/miri/tests/pass/box.stack.stderr @@ -4,12 +4,11 @@ warning: integer-to-pointer cast LL | let r2 = ((r as usize) + 0) as *mut i32; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ integer-to-pointer cast | - = help: This program is using integer-to-pointer casts or (equivalently) `ptr::with_exposed_provenance`, - = help: which means that Miri might miss pointer bugs in this program. + = help: This program is using integer-to-pointer casts or (equivalently) `ptr::with_exposed_provenance`, which means that Miri might miss pointer bugs in this program. = help: See https://doc.rust-lang.org/nightly/std/ptr/fn.with_exposed_provenance.html for more details on that operation. = help: To ensure that Miri does not miss bugs in your program, use Strict Provenance APIs (https://doc.rust-lang.org/nightly/std/ptr/index.html#strict-provenance, https://crates.io/crates/sptr) instead. - = help: You can then pass the `-Zmiri-strict-provenance` flag to Miri, to ensure you are not relying on `with_exposed_provenance` semantics. - = help: Alternatively, the `-Zmiri-permissive-provenance` flag disables this warning. + = help: You can then set `MIRIFLAGS=-Zmiri-strict-provenance` to ensure you are not relying on `with_exposed_provenance` semantics. + = help: Alternatively, `MIRIFLAGS=-Zmiri-permissive-provenance` disables this warning. = note: BACKTRACE: = note: inside `into_raw` at $DIR/box.rs:LL:CC note: inside `main` diff --git a/src/tools/miri/tests/pass/extern_types.stack.stderr b/src/tools/miri/tests/pass/extern_types.stack.stderr index 275d718129b4e..03a9167abbc7c 100644 --- a/src/tools/miri/tests/pass/extern_types.stack.stderr +++ b/src/tools/miri/tests/pass/extern_types.stack.stderr @@ -4,12 +4,11 @@ warning: integer-to-pointer cast LL | let x: &Foo = unsafe { &*(16 as *const Foo) }; | ^^^^^^^^^^^^^^^^^^ integer-to-pointer cast | - = help: This program is using integer-to-pointer casts or (equivalently) `ptr::with_exposed_provenance`, - = help: which means that Miri might miss pointer bugs in this program. + = help: This program is using integer-to-pointer casts or (equivalently) `ptr::with_exposed_provenance`, which means that Miri might miss pointer bugs in this program. = help: See https://doc.rust-lang.org/nightly/std/ptr/fn.with_exposed_provenance.html for more details on that operation. = help: To ensure that Miri does not miss bugs in your program, use Strict Provenance APIs (https://doc.rust-lang.org/nightly/std/ptr/index.html#strict-provenance, https://crates.io/crates/sptr) instead. - = help: You can then pass the `-Zmiri-strict-provenance` flag to Miri, to ensure you are not relying on `with_exposed_provenance` semantics. - = help: Alternatively, the `-Zmiri-permissive-provenance` flag disables this warning. + = help: You can then set `MIRIFLAGS=-Zmiri-strict-provenance` to ensure you are not relying on `with_exposed_provenance` semantics. + = help: Alternatively, `MIRIFLAGS=-Zmiri-permissive-provenance` disables this warning. = note: BACKTRACE: = note: inside `main` at $DIR/extern_types.rs:LL:CC diff --git a/src/tools/miri/tests/pass/stacked-borrows/issue-miri-2389.stderr b/src/tools/miri/tests/pass/stacked-borrows/issue-miri-2389.stderr index 7cbfad3942b32..b0e1adf27d183 100644 --- a/src/tools/miri/tests/pass/stacked-borrows/issue-miri-2389.stderr +++ b/src/tools/miri/tests/pass/stacked-borrows/issue-miri-2389.stderr @@ -4,12 +4,11 @@ warning: integer-to-pointer cast LL | let wildcard = &root0 as *const Cell as usize as *const Cell; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ integer-to-pointer cast | - = help: This program is using integer-to-pointer casts or (equivalently) `ptr::with_exposed_provenance`, - = help: which means that Miri might miss pointer bugs in this program. + = help: This program is using integer-to-pointer casts or (equivalently) `ptr::with_exposed_provenance`, which means that Miri might miss pointer bugs in this program. = help: See https://doc.rust-lang.org/nightly/std/ptr/fn.with_exposed_provenance.html for more details on that operation. = help: To ensure that Miri does not miss bugs in your program, use Strict Provenance APIs (https://doc.rust-lang.org/nightly/std/ptr/index.html#strict-provenance, https://crates.io/crates/sptr) instead. - = help: You can then pass the `-Zmiri-strict-provenance` flag to Miri, to ensure you are not relying on `with_exposed_provenance` semantics. - = help: Alternatively, the `-Zmiri-permissive-provenance` flag disables this warning. + = help: You can then set `MIRIFLAGS=-Zmiri-strict-provenance` to ensure you are not relying on `with_exposed_provenance` semantics. + = help: Alternatively, `MIRIFLAGS=-Zmiri-permissive-provenance` disables this warning. = note: BACKTRACE: = note: inside `main` at $DIR/issue-miri-2389.rs:LL:CC From 198bbf87a0ff94f7f297a1de8ee18fa3d3f34c1a Mon Sep 17 00:00:00 2001 From: xFrednet Date: Mon, 17 Jun 2024 15:22:06 +0200 Subject: [PATCH 200/892] Pause assignments to @xFrednet for summer break :beach_umbrella: I'm only removing myself from the assignment roulette as I want to allow `r? xFrednet` for `gh-pages` and other updates. So feel free to still `r?` me. --- triagebot.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/triagebot.toml b/triagebot.toml index 4d66b728b76df..ecada0514f7a9 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -32,7 +32,6 @@ users_on_vacation = [ "*" = [ "@Manishearth", "@llogiq", - "@xFrednet", "@Alexendoo", "@dswij", "@Jarcho", From 61fc1aec74542645d03b35b427b5706a108b4b04 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 5 Jun 2024 16:18:52 -0400 Subject: [PATCH 201/892] Rework precise capturing syntax --- clippy_lints/src/needless_maybe_sized.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clippy_lints/src/needless_maybe_sized.rs b/clippy_lints/src/needless_maybe_sized.rs index 06ae1723a03d4..4922c87b206c0 100644 --- a/clippy_lints/src/needless_maybe_sized.rs +++ b/clippy_lints/src/needless_maybe_sized.rs @@ -73,7 +73,7 @@ fn type_param_bounds<'tcx>(generics: &'tcx Generics<'tcx>) -> impl Iterator None, + GenericBound::Outlives(_) | GenericBound::Use(..) => None, }) .filter(|bound| !bound.trait_bound.span.from_expansion()), ) From 7218fdd2db0d5b5a1c05564ad1fd821de220c003 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 6 Jun 2024 09:01:45 -0400 Subject: [PATCH 202/892] Fix other tools --- clippy_utils/src/ast_utils.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/clippy_utils/src/ast_utils.rs b/clippy_utils/src/ast_utils.rs index c70f5c2df8420..fb43f7d80afff 100644 --- a/clippy_utils/src/ast_utils.rs +++ b/clippy_utils/src/ast_utils.rs @@ -724,11 +724,8 @@ pub fn eq_ty(l: &Ty, r: &Ty) -> bool { (Tup(l), Tup(r)) => over(l, r, |l, r| eq_ty(l, r)), (Path(lq, lp), Path(rq, rp)) => both(lq, rq, eq_qself) && eq_path(lp, rp), (TraitObject(lg, ls), TraitObject(rg, rs)) => ls == rs && over(lg, rg, eq_generic_bound), - (ImplTrait(_, lg, lc), ImplTrait(_, rg, rc)) => { + (ImplTrait(_, lg), ImplTrait(_, rg)) => { over(lg, rg, eq_generic_bound) - && both(lc, rc, |lc, rc| { - over(lc.0.as_slice(), rc.0.as_slice(), eq_precise_capture) - }) }, (Typeof(l), Typeof(r)) => eq_expr(&l.value, &r.value), (MacCall(l), MacCall(r)) => eq_mac_call(l, r), From 028f437abffc4943d085bd2b7be5e7a4ea73aac8 Mon Sep 17 00:00:00 2001 From: The Miri Cronjob Bot Date: Tue, 18 Jun 2024 04:56:47 +0000 Subject: [PATCH 203/892] 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 c1796cfd82a67..356d4767c7bea 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version @@ -1 +1 @@ -e794b0f8557c187b5909d889aa35071f81e0a4cc +c2932aaf9d20acbc9259c762f1a06f8767c6f13f From e28b998fe64155340b8a5e79619a71924a264cb7 Mon Sep 17 00:00:00 2001 From: Centri3 <114838443+Centri3@users.noreply.github.com> Date: Tue, 18 Jun 2024 02:28:20 -0500 Subject: [PATCH 204/892] Add myself back to reviewer rotation --- triagebot.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/triagebot.toml b/triagebot.toml index ecada0514f7a9..0f0e62670ffe4 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -22,7 +22,6 @@ contributing_url = "https://github.com/rust-lang/rust-clippy/blob/master/CONTRIB users_on_vacation = [ "matthiaskrgr", "giraffate", - "Centri3", ] [assign.owners] @@ -37,4 +36,5 @@ users_on_vacation = [ "@Jarcho", "@blyxyas", "@y21", + "@Centri3", ] From 527b3575ba8d03e2938752fc60a8401d8b8a7995 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 18 Jun 2024 10:35:56 +0000 Subject: [PATCH 205/892] Use a dedicated type instead of a reference for the diagnostic context This paves the way for tracking more state (e.g. error tainting) in the diagnostic context handle --- src/back/lto.rs | 11 ++++++----- src/back/write.rs | 6 +++--- src/errors.rs | 4 ++-- src/lib.rs | 21 +++++++++------------ 4 files changed, 20 insertions(+), 22 deletions(-) diff --git a/src/back/lto.rs b/src/back/lto.rs index 61e0f203ee0b2..ec70fbdddb0ff 100644 --- a/src/back/lto.rs +++ b/src/back/lto.rs @@ -28,7 +28,7 @@ use rustc_codegen_ssa::back::write::{CodegenContext, FatLtoInput}; use rustc_codegen_ssa::traits::*; use rustc_codegen_ssa::{looks_like_rust_object_file, ModuleCodegen, ModuleKind}; use rustc_data_structures::memmap::Mmap; -use rustc_errors::{DiagCtxt, FatalError}; +use rustc_errors::{DiagCtxtHandle, FatalError}; use rustc_hir::def_id::LOCAL_CRATE; use rustc_middle::dep_graph::WorkProduct; use rustc_middle::middle::exported_symbols::{SymbolExportInfo, SymbolExportLevel}; @@ -59,7 +59,7 @@ struct LtoData { fn prepare_lto( cgcx: &CodegenContext, - dcx: &DiagCtxt, + dcx: DiagCtxtHandle<'_>, ) -> Result { let export_threshold = match cgcx.lto { // We're just doing LTO for our one crate @@ -179,12 +179,13 @@ pub(crate) fn run_fat( cached_modules: Vec<(SerializedModule, WorkProduct)>, ) -> Result, FatalError> { let dcx = cgcx.create_dcx(); - let lto_data = prepare_lto(cgcx, &dcx)?; + let dcx = dcx.handle(); + let lto_data = prepare_lto(cgcx, dcx)?; /*let symbols_below_threshold = lto_data.symbols_below_threshold.iter().map(|c| c.as_ptr()).collect::>();*/ fat_lto( cgcx, - &dcx, + dcx, modules, cached_modules, lto_data.upstream_modules, @@ -195,7 +196,7 @@ pub(crate) fn run_fat( fn fat_lto( cgcx: &CodegenContext, - _dcx: &DiagCtxt, + _dcx: DiagCtxtHandle<'_>, modules: Vec>, cached_modules: Vec<(SerializedModule, WorkProduct)>, mut serialized_modules: Vec<(SerializedModule, CString)>, diff --git a/src/back/write.rs b/src/back/write.rs index 3ea5be1ee562b..b9c7f72d0b727 100644 --- a/src/back/write.rs +++ b/src/back/write.rs @@ -4,7 +4,7 @@ use gccjit::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}; -use rustc_errors::DiagCtxt; +use rustc_errors::DiagCtxtHandle; use rustc_fs_util::link_or_copy; use rustc_session::config::OutputType; use rustc_span::fatal_error::FatalError; @@ -15,7 +15,7 @@ use crate::{GccCodegenBackend, GccContext}; pub(crate) unsafe fn codegen( cgcx: &CodegenContext, - dcx: &DiagCtxt, + dcx: DiagCtxtHandle<'_>, module: ModuleCodegen, config: &ModuleConfig, ) -> Result { @@ -166,7 +166,7 @@ pub(crate) unsafe fn codegen( pub(crate) fn link( _cgcx: &CodegenContext, - _dcx: &DiagCtxt, + _dcx: DiagCtxtHandle<'_>, mut _modules: Vec>, ) -> Result, FatalError> { unimplemented!(); diff --git a/src/errors.rs b/src/errors.rs index aee2b077dba1f..5b31134239239 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -1,4 +1,4 @@ -use rustc_errors::{Diag, DiagCtxt, Diagnostic, EmissionGuarantee, Level}; +use rustc_errors::{Diag, DiagCtxtHandle, Diagnostic, EmissionGuarantee, Level}; use rustc_macros::{Diagnostic, Subdiagnostic}; use rustc_span::Span; @@ -90,7 +90,7 @@ pub(crate) struct TargetFeatureDisableOrEnable<'a> { pub(crate) struct MissingFeatures; impl Diagnostic<'_, G> for TargetFeatureDisableOrEnable<'_> { - fn into_diag(self, dcx: &'_ DiagCtxt, level: Level) -> Diag<'_, G> { + fn into_diag(self, dcx: DiagCtxtHandle<'_>, level: Level) -> Diag<'_, G> { let mut diag = Diag::new(dcx, level, fluent::codegen_gcc_target_feature_disable_or_enable); if let Some(span) = self.span { diag.span(span); diff --git a/src/lib.rs b/src/lib.rs index b1785e150adc5..24856506c4644 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -16,13 +16,7 @@ #![allow(internal_features)] #![doc(rust_logo)] #![feature(rustdoc_internals)] -#![feature( - rustc_private, - decl_macro, - never_type, - trusted_len, - hash_raw_entry -)] +#![feature(rustc_private, decl_macro, never_type, trusted_len, hash_raw_entry)] #![allow(broken_intra_doc_links)] #![recursion_limit = "256"] #![warn(rust_2018_idioms)] @@ -104,7 +98,7 @@ use rustc_codegen_ssa::traits::{ use rustc_codegen_ssa::{CodegenResults, CompiledModule, ModuleCodegen}; use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::sync::IntoDynSyncSend; -use rustc_errors::{DiagCtxt, ErrorGuaranteed}; +use rustc_errors::{DiagCtxtHandle, ErrorGuaranteed}; use rustc_metadata::EncodedMetadata; use rustc_middle::dep_graph::{WorkProduct, WorkProductId}; use rustc_middle::ty::TyCtxt; @@ -386,7 +380,7 @@ impl WriteBackendMethods for GccCodegenBackend { unsafe fn optimize( _cgcx: &CodegenContext, - _dcx: &DiagCtxt, + _dcx: DiagCtxtHandle<'_>, module: &ModuleCodegen, config: &ModuleConfig, ) -> Result<(), FatalError> { @@ -411,14 +405,17 @@ impl WriteBackendMethods for GccCodegenBackend { unsafe fn codegen( cgcx: &CodegenContext, - dcx: &DiagCtxt, + dcx: DiagCtxtHandle<'_>, module: ModuleCodegen, config: &ModuleConfig, ) -> Result { back::write::codegen(cgcx, dcx, module, config) } - fn prepare_thin(_module: ModuleCodegen, _emit_summary: bool) -> (String, Self::ThinBuffer) { + fn prepare_thin( + _module: ModuleCodegen, + _emit_summary: bool, + ) -> (String, Self::ThinBuffer) { unimplemented!(); } @@ -428,7 +425,7 @@ impl WriteBackendMethods for GccCodegenBackend { fn run_link( cgcx: &CodegenContext, - dcx: &DiagCtxt, + dcx: DiagCtxtHandle<'_>, modules: Vec>, ) -> Result, FatalError> { back::write::link(cgcx, dcx, modules) From afef64c1bd36a85f71f739e09c901cc6209c82bd Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 18 Jun 2024 10:35:56 +0000 Subject: [PATCH 206/892] Use a dedicated type instead of a reference for the diagnostic context This paves the way for tracking more state (e.g. error tainting) in the diagnostic context handle --- src/concurrency_limiter.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/concurrency_limiter.rs b/src/concurrency_limiter.rs index a73860cf18b2d..2093b49ff31a7 100644 --- a/src/concurrency_limiter.rs +++ b/src/concurrency_limiter.rs @@ -1,6 +1,7 @@ use std::sync::{Arc, Condvar, Mutex}; use jobserver::HelperThread; +use rustc_errors::DiagCtxtHandle; use rustc_session::Session; // FIXME don't panic when a worker thread panics @@ -46,7 +47,7 @@ impl ConcurrencyLimiter { } } - pub(super) fn acquire(&self, dcx: &rustc_errors::DiagCtxt) -> ConcurrencyLimiterToken { + pub(super) fn acquire(&self, dcx: DiagCtxtHandle<'_>) -> ConcurrencyLimiterToken { let mut state = self.state.lock().unwrap(); loop { state.assert_invariants(); From cb1bde07c147a33c3234d522bf63e9ce76772180 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 18 Jun 2024 11:10:18 +0000 Subject: [PATCH 207/892] Remove redundant argument from `subdiagnostic` method --- src/errors.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/errors.rs b/src/errors.rs index 5b31134239239..6bada3d334ce4 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -96,7 +96,7 @@ impl Diagnostic<'_, G> for TargetFeatureDisableOrEnable<'_ diag.span(span); }; if let Some(missing_features) = self.missing_features { - diag.subdiagnostic(dcx, missing_features); + diag.subdiagnostic(missing_features); } diag.arg("features", self.features.join(", ")); diag From 4b7ae63fbff1b74d91ef326da6abe82d05151b0b Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 18 Jun 2024 10:35:56 +0000 Subject: [PATCH 208/892] Use a dedicated type instead of a reference for the diagnostic context This paves the way for tracking more state (e.g. error tainting) in the diagnostic context handle --- src/driver.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/driver.rs b/src/driver.rs index f79da26964f37..6117e76897f2f 100644 --- a/src/driver.rs +++ b/src/driver.rs @@ -180,12 +180,12 @@ pub fn main() { rustc_driver::init_rustc_env_logger(&early_dcx); - let using_internal_features = rustc_driver::install_ice_hook(BUG_REPORT_URL, |handler| { + let using_internal_features = rustc_driver::install_ice_hook(BUG_REPORT_URL, |dcx| { // FIXME: this macro calls unwrap internally but is called in a panicking context! It's not // as simple as moving the call from the hook to main, because `install_ice_hook` doesn't // accept a generic closure. let version_info = rustc_tools_util::get_version_info!(); - handler.note(format!("Clippy version: {version_info}")); + dcx.handle().note(format!("Clippy version: {version_info}")); }); exit(rustc_driver::catch_with_exit_code(move || { From c5bd2e3b9070243409b22fd62f30408f2d1a905d Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Tue, 18 Jun 2024 16:14:35 +0000 Subject: [PATCH 209/892] Rustup to rustc 1.81.0-nightly (59e2c01c2 2024-06-17) --- rust-toolchain | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-toolchain b/rust-toolchain index 3cb1f15bb3f21..36d98a869db1e 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2024-06-17" +channel = "nightly-2024-06-18" components = ["rust-src", "rustc-dev", "llvm-tools"] From 729cb08d4c476410f296940e6d6487a4e81b88d2 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Tue, 18 Jun 2024 16:23:11 +0000 Subject: [PATCH 210/892] Fix rustc tests --- scripts/test_rustc_tests.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/test_rustc_tests.sh b/scripts/test_rustc_tests.sh index 62a1c61c9069d..a0d6916dc7ef9 100755 --- a/scripts/test_rustc_tests.sh +++ b/scripts/test_rustc_tests.sh @@ -78,6 +78,7 @@ rm tests/ui/codegen/issue-28950.rs # depends on stack size optimizations rm tests/ui/codegen/init-large-type.rs # same rm tests/ui/issues/issue-40883.rs # same rm -r tests/run-make/fmt-write-bloat/ # tests an optimization +rm tests/ui/statics/const_generics.rs # same # backend specific tests # ====================== From 1cb728280dfe7cc241eae34196f80c876aa9addc Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 18 Jun 2024 18:51:53 +0200 Subject: [PATCH 211/892] Re-enable `tests/run-make/const_fn_mir` (#1497) --- scripts/test_rustc_tests.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/scripts/test_rustc_tests.sh b/scripts/test_rustc_tests.sh index a0d6916dc7ef9..283889e9471c3 100755 --- a/scripts/test_rustc_tests.sh +++ b/scripts/test_rustc_tests.sh @@ -128,7 +128,6 @@ rm -r tests/run-make/panic-abort-eh_frame # .eh_frame emitted with panic=abort # bugs in the test suite # ====================== rm tests/ui/process/nofile-limit.rs # TODO some AArch64 linking issue -rm -r tests/run-make/const_fn_mir # needs-unwind directive accidentally dropped rm tests/ui/stdio-is-blocking.rs # really slow with unoptimized libstd From d9f1d557860138da64d52c0f536db395a99b9a4a Mon Sep 17 00:00:00 2001 From: The Miri Cronjob Bot Date: Wed, 19 Jun 2024 04:54:41 +0000 Subject: [PATCH 212/892] 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 356d4767c7bea..a2da736656d17 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version @@ -1 +1 @@ -c2932aaf9d20acbc9259c762f1a06f8767c6f13f +a1ca449981e3b8442e358026437b7bedb9a1458e From f22775b245f39fb0cec9b6279124a95b7fee7d03 Mon Sep 17 00:00:00 2001 From: onur-ozkan Date: Wed, 19 Jun 2024 19:34:28 +0300 Subject: [PATCH 213/892] ignore `llvm::Lld` step if `lld` is not enabled People are having trouble when they don't want to build `lld` for their custom distribution tarballs even with `lld = false` in their config.toml. This is because it is not controlled by `lld_enabled` flag. This change ensures that `llvm:Lld` is controlled by lld configuration. Signed-off-by: onur-ozkan --- src/bootstrap/src/core/build_steps/dist.rs | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs index 54136d2aebda2..3c555f0a211cf 100644 --- a/src/bootstrap/src/core/build_steps/dist.rs +++ b/src/bootstrap/src/core/build_steps/dist.rs @@ -2261,9 +2261,6 @@ impl Step for RustDev { builder.ensure(crate::core::build_steps::llvm::Llvm { target }); - // We want to package `lld` to use it with `download-ci-llvm`. - builder.ensure(crate::core::build_steps::llvm::Lld { target }); - let src_bindir = builder.llvm_out(target).join("bin"); // If updating this, you likely want to change // src/bootstrap/download-ci-llvm-stamp as well, otherwise local users @@ -2280,10 +2277,15 @@ impl Step for RustDev { } } - // We don't build LLD on some platforms, so only add it if it exists - let lld_path = builder.lld_out(target).join("bin").join(exe("lld", target)); - if lld_path.exists() { - tarball.add_file(lld_path, "bin", 0o755); + if builder.config.lld_enabled { + // We want to package `lld` to use it with `download-ci-llvm`. + let lld_out = builder.ensure(crate::core::build_steps::llvm::Lld { target }); + + // We don't build LLD on some platforms, so only add it if it exists + let lld_path = lld_out.join("bin").join(exe("lld", target)); + if lld_path.exists() { + tarball.add_file(lld_path, "bin", 0o755); + } } tarball.add_file(builder.llvm_filecheck(target), "bin", 0o755); From 8cde354f0bb0d686882b32883c36c252ee367967 Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Tue, 18 Jun 2024 11:46:26 -0500 Subject: [PATCH 214/892] Resolve Clippy `f16` and `f128` `unimplemented!`/`FIXME`s This removes the ICE codepaths for `f16` and `f128` in Clippy. `rustc_apfloat` is used as a dependency for the parsing of these types, since their `FromStr` implementation will not be available in the standard library for a while. --- clippy_lints/src/casts/cast_nan_to_int.rs | 1 + clippy_lints/src/float_literal.rs | 7 ++- clippy_lints/src/lib.rs | 2 + clippy_lints/src/manual_float_methods.rs | 2 + clippy_lints/src/operators/float_cmp.rs | 1 + .../src/operators/modulo_arithmetic.rs | 1 + clippy_lints/src/zero_div_zero.rs | 1 + clippy_utils/Cargo.toml | 2 + clippy_utils/src/consts.rs | 43 ++++++++++++++++--- clippy_utils/src/lib.rs | 2 + 10 files changed, 52 insertions(+), 10 deletions(-) diff --git a/clippy_lints/src/casts/cast_nan_to_int.rs b/clippy_lints/src/casts/cast_nan_to_int.rs index 1743ce71adde4..5bc8692c289f7 100644 --- a/clippy_lints/src/casts/cast_nan_to_int.rs +++ b/clippy_lints/src/casts/cast_nan_to_int.rs @@ -21,6 +21,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, cast_expr: &Expr<'_>, fn is_known_nan(cx: &LateContext<'_>, e: &Expr<'_>) -> bool { match constant(cx, cx.typeck_results(), e) { + // FIXME(f16_f128): add these types when nan checks are available on all platforms Some(Constant::F64(n)) => n.is_nan(), Some(Constant::F32(n)) => n.is_nan(), _ => false, diff --git a/clippy_lints/src/float_literal.rs b/clippy_lints/src/float_literal.rs index 4d301daabe4c5..2261fcdbdabc9 100644 --- a/clippy_lints/src/float_literal.rs +++ b/clippy_lints/src/float_literal.rs @@ -141,18 +141,17 @@ impl<'tcx> LateLintPass<'tcx> for FloatLiteral { #[must_use] fn max_digits(fty: FloatTy) -> u32 { match fty { - // FIXME(f16_f128): replace the magic numbers once `{f16,f128}::DIGITS` are available - FloatTy::F16 => 3, + FloatTy::F16 => f16::DIGITS, FloatTy::F32 => f32::DIGITS, FloatTy::F64 => f64::DIGITS, - FloatTy::F128 => 33, + FloatTy::F128 => f128::DIGITS, } } /// Counts the digits excluding leading zeros #[must_use] fn count_digits(s: &str) -> usize { - // Note that s does not contain the f32/64 suffix, and underscores have been stripped + // Note that s does not contain the `f{16,32,64,128}` suffix, and underscores have been stripped s.chars() .filter(|c| *c != '-' && *c != '.') .take_while(|c| *c != 'e' && *c != 'E') diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index c65581d5203e9..ef322786dbcd3 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -1,6 +1,8 @@ #![feature(array_windows)] #![feature(binary_heap_into_iter_sorted)] #![feature(box_patterns)] +#![feature(f128)] +#![feature(f16)] #![feature(if_let_guard)] #![feature(iter_intersperse)] #![feature(let_chains)] diff --git a/clippy_lints/src/manual_float_methods.rs b/clippy_lints/src/manual_float_methods.rs index 72cf1d7a3546e..89eea0b4456d4 100644 --- a/clippy_lints/src/manual_float_methods.rs +++ b/clippy_lints/src/manual_float_methods.rs @@ -156,6 +156,7 @@ impl<'tcx> LateLintPass<'tcx> for ManualFloatMethods { fn is_infinity(constant: &Constant<'_>) -> bool { match constant { + // FIXME(f16_f128): add f16 and f128 when constants are available Constant::F32(float) => *float == f32::INFINITY, Constant::F64(float) => *float == f64::INFINITY, _ => false, @@ -164,6 +165,7 @@ fn is_infinity(constant: &Constant<'_>) -> bool { fn is_neg_infinity(constant: &Constant<'_>) -> bool { match constant { + // FIXME(f16_f128): add f16 and f128 when constants are available Constant::F32(float) => *float == f32::NEG_INFINITY, Constant::F64(float) => *float == f64::NEG_INFINITY, _ => false, diff --git a/clippy_lints/src/operators/float_cmp.rs b/clippy_lints/src/operators/float_cmp.rs index 0561739d160f8..faab79de9d3cc 100644 --- a/clippy_lints/src/operators/float_cmp.rs +++ b/clippy_lints/src/operators/float_cmp.rs @@ -86,6 +86,7 @@ fn get_lint_and_message(is_local: bool, is_comparing_arrays: bool) -> (&'static fn is_allowed(val: &Constant<'_>) -> bool { match val { + // FIXME(f16_f128): add when equality check is available on all platforms &Constant::F32(f) => f == 0.0 || f.is_infinite(), &Constant::F64(f) => f == 0.0 || f.is_infinite(), Constant::Vec(vec) => vec.iter().all(|f| match f { diff --git a/clippy_lints/src/operators/modulo_arithmetic.rs b/clippy_lints/src/operators/modulo_arithmetic.rs index c56518ac72a46..d65fffac5a828 100644 --- a/clippy_lints/src/operators/modulo_arithmetic.rs +++ b/clippy_lints/src/operators/modulo_arithmetic.rs @@ -79,6 +79,7 @@ fn analyze_operand(operand: &Expr<'_>, cx: &LateContext<'_>, expr: &Expr<'_>) -> }, _ => {}, }, + // FIXME(f16_f128): add when casting is available on all platforms Some(Constant::F32(f)) => { return Some(floating_point_operand_info(&f)); }, diff --git a/clippy_lints/src/zero_div_zero.rs b/clippy_lints/src/zero_div_zero.rs index 662242f6196bc..60d8a13d3599d 100644 --- a/clippy_lints/src/zero_div_zero.rs +++ b/clippy_lints/src/zero_div_zero.rs @@ -38,6 +38,7 @@ impl<'tcx> LateLintPass<'tcx> for ZeroDiv { // do something like 0.0/(2.0 - 2.0), but it would be nice to warn on that case too. && let Some(lhs_value) = constant_simple(cx, cx.typeck_results(), left) && let Some(rhs_value) = constant_simple(cx, cx.typeck_results(), right) + // FIXME(f16_f128): add these types when eq is available on all platforms && (Constant::F32(0.0) == lhs_value || Constant::F64(0.0) == lhs_value) && (Constant::F32(0.0) == rhs_value || Constant::F64(0.0) == rhs_value) { diff --git a/clippy_utils/Cargo.toml b/clippy_utils/Cargo.toml index 3a3aeb8821643..6e53ff3ee6e98 100644 --- a/clippy_utils/Cargo.toml +++ b/clippy_utils/Cargo.toml @@ -9,6 +9,8 @@ clippy_config = { path = "../clippy_config" } arrayvec = { version = "0.7", default-features = false } itertools = "0.12" rustc-semver = "1.1" +# FIXME(f16_f128): remove when no longer needed for parsing +rustc_apfloat = "0.2.0" [features] deny-warnings = ["clippy_config/deny-warnings"] diff --git a/clippy_utils/src/consts.rs b/clippy_utils/src/consts.rs index cfd142fe1ff63..681c86f76d07c 100644 --- a/clippy_utils/src/consts.rs +++ b/clippy_utils/src/consts.rs @@ -3,6 +3,8 @@ use crate::source::{get_source_text, walk_span_to_context}; use crate::{clip, is_direct_expn_of, sext, unsext}; +use rustc_apfloat::ieee::{Half, Quad}; +use rustc_apfloat::Float; use rustc_ast::ast::{self, LitFloatType, LitKind}; use rustc_data_structures::sync::Lrc; use rustc_hir::def::{DefKind, Res}; @@ -33,10 +35,14 @@ pub enum Constant<'tcx> { Char(char), /// An integer's bit representation. Int(u128), + /// An `f16`. + F16(f16), /// An `f32`. F32(f32), /// An `f64`. F64(f64), + /// An `f128`. + F128(f128), /// `true` or `false`. Bool(bool), /// An array of constants. @@ -161,12 +167,19 @@ impl<'tcx> Hash for Constant<'tcx> { Self::Int(i) => { i.hash(state); }, + Self::F16(f) => { + // FIXME(f16_f128): once conversions to/from `f128` are available on all platforms, + f.to_bits().hash(state); + }, Self::F32(f) => { f64::from(f).to_bits().hash(state); }, Self::F64(f) => { f.to_bits().hash(state); }, + Self::F128(f) => { + f.to_bits().hash(state); + }, Self::Bool(b) => { b.hash(state); }, @@ -268,6 +281,16 @@ impl<'tcx> Constant<'tcx> { } self } + + fn parse_f16(s: &str) -> Self { + let f: Half = s.parse().unwrap(); + Self::F16(f16::from_bits(f.to_bits().try_into().unwrap())) + } + + fn parse_f128(s: &str) -> Self { + let f: Quad = s.parse().unwrap(); + Self::F128(f128::from_bits(f.to_bits())) + } } /// Parses a `LitKind` to a `Constant`. @@ -279,16 +302,17 @@ pub fn lit_to_mir_constant<'tcx>(lit: &LitKind, ty: Option>) -> Constan LitKind::Char(c) => Constant::Char(c), LitKind::Int(n, _) => Constant::Int(n.get()), LitKind::Float(ref is, LitFloatType::Suffixed(fty)) => match fty { - ast::FloatTy::F16 => unimplemented!("f16_f128"), + // FIXME(f16_f128): just use `parse()` directly when available for `f16`/`f128` + ast::FloatTy::F16 => Constant::parse_f16(is.as_str()), ast::FloatTy::F32 => Constant::F32(is.as_str().parse().unwrap()), ast::FloatTy::F64 => Constant::F64(is.as_str().parse().unwrap()), - ast::FloatTy::F128 => unimplemented!("f16_f128"), + ast::FloatTy::F128 => Constant::parse_f128(is.as_str()), }, LitKind::Float(ref is, LitFloatType::Unsuffixed) => match ty.expect("type of float is known").kind() { - ty::Float(FloatTy::F16) => unimplemented!("f16_f128"), + ty::Float(FloatTy::F16) => Constant::parse_f16(is.as_str()), ty::Float(FloatTy::F32) => Constant::F32(is.as_str().parse().unwrap()), ty::Float(FloatTy::F64) => Constant::F64(is.as_str().parse().unwrap()), - ty::Float(FloatTy::F128) => unimplemented!("f16_f128"), + ty::Float(FloatTy::F128) => Constant::parse_f128(is.as_str()), _ => bug!(), }, LitKind::Bool(b) => Constant::Bool(b), @@ -625,15 +649,19 @@ impl<'a, 'tcx> ConstEvalLateContext<'a, 'tcx> { match (lhs, index) { (Some(Constant::Vec(vec)), Some(Constant::Int(index))) => match vec.get(index as usize) { + Some(Constant::F16(x)) => Some(Constant::F16(*x)), Some(Constant::F32(x)) => Some(Constant::F32(*x)), Some(Constant::F64(x)) => Some(Constant::F64(*x)), + Some(Constant::F128(x)) => Some(Constant::F128(*x)), _ => None, }, (Some(Constant::Vec(vec)), _) => { if !vec.is_empty() && vec.iter().all(|x| *x == vec[0]) { match vec.first() { + Some(Constant::F16(x)) => Some(Constant::F16(*x)), Some(Constant::F32(x)) => Some(Constant::F32(*x)), Some(Constant::F64(x)) => Some(Constant::F64(*x)), + Some(Constant::F128(x)) => Some(Constant::F128(*x)), _ => None, } } else { @@ -760,6 +788,7 @@ impl<'a, 'tcx> ConstEvalLateContext<'a, 'tcx> { }, _ => None, }, + // FIXME(f16_f128): add these types when binary operations are available on all platforms (Constant::F32(l), Some(Constant::F32(r))) => match op.node { BinOpKind::Add => Some(Constant::F32(l + r)), BinOpKind::Sub => Some(Constant::F32(l - r)), @@ -813,8 +842,10 @@ pub fn mir_to_const<'tcx>(lcx: &LateContext<'tcx>, result: mir::Const<'tcx>) -> ty::Adt(adt_def, _) if adt_def.is_struct() => Some(Constant::Adt(result)), ty::Bool => Some(Constant::Bool(int == ScalarInt::TRUE)), ty::Uint(_) | ty::Int(_) => Some(Constant::Int(int.to_bits(int.size()))), + ty::Float(FloatTy::F16) => Some(Constant::F16(f16::from_bits(int.into()))), ty::Float(FloatTy::F32) => Some(Constant::F32(f32::from_bits(int.into()))), ty::Float(FloatTy::F64) => Some(Constant::F64(f64::from_bits(int.into()))), + ty::Float(FloatTy::F128) => Some(Constant::F128(f128::from_bits(int.into()))), ty::RawPtr(_, _) => Some(Constant::RawPtr(int.to_bits(int.size()))), _ => None, }, @@ -835,10 +866,10 @@ pub fn mir_to_const<'tcx>(lcx: &LateContext<'tcx>, result: mir::Const<'tcx>) -> let range = alloc_range(offset + size * idx, size); let val = alloc.read_scalar(&lcx.tcx, range, /* read_provenance */ false).ok()?; res.push(match flt { - FloatTy::F16 => unimplemented!("f16_f128"), + FloatTy::F16 => Constant::F16(f16::from_bits(val.to_u16().ok()?)), FloatTy::F32 => Constant::F32(f32::from_bits(val.to_u32().ok()?)), FloatTy::F64 => Constant::F64(f64::from_bits(val.to_u64().ok()?)), - FloatTy::F128 => unimplemented!("f16_f128"), + FloatTy::F128 => Constant::F128(f128::from_bits(val.to_u128().ok()?)), }); } Some(Constant::Vec(res)) diff --git a/clippy_utils/src/lib.rs b/clippy_utils/src/lib.rs index 7dc341ec8d71b..6848e8e5c3042 100644 --- a/clippy_utils/src/lib.rs +++ b/clippy_utils/src/lib.rs @@ -1,6 +1,8 @@ #![feature(array_chunks)] #![feature(box_patterns)] #![feature(control_flow_enum)] +#![feature(f128)] +#![feature(f16)] #![feature(if_let_guard)] #![feature(let_chains)] #![feature(lint_reasons)] From c693f31ee227a2897c85c7add66fbf92978b28cf Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Tue, 18 Jun 2024 12:34:49 -0500 Subject: [PATCH 215/892] Update float tests to include `f16` and `f128` --- .../conf_disallowed_methods.rs | 1 + .../conf_disallowed_methods.stderr | 20 +- tests/ui/arithmetic_side_effects.rs | 4 + tests/ui/arithmetic_side_effects.stderr | 260 +++++++++--------- tests/ui/cast.rs | 2 + tests/ui/cast.stderr | 184 ++++++------- tests/ui/cast_lossless_float.fixed | 2 + tests/ui/cast_lossless_float.rs | 2 + tests/ui/cast_lossless_float.stderr | 26 +- tests/ui/cast_nan_to_int.rs | 2 + tests/ui/cast_nan_to_int.stderr | 12 +- tests/ui/cast_size.64bit.stderr | 50 ++-- tests/ui/cast_size.rs | 13 +- tests/ui/endian_bytes.rs | 2 + tests/ui/endian_bytes.stderr | 172 ++++++------ tests/ui/float_cmp.rs | 2 + tests/ui/float_cmp.stderr | 12 +- tests/ui/float_equality_without_abs.rs | 3 + tests/ui/float_equality_without_abs.stderr | 22 +- tests/ui/floating_point_arithmetic_nostd.rs | 4 +- tests/ui/floating_point_exp.fixed | 2 + tests/ui/floating_point_exp.rs | 2 + tests/ui/floating_point_exp.stderr | 10 +- tests/ui/floating_point_log.fixed | 2 + tests/ui/floating_point_log.rs | 2 + tests/ui/floating_point_log.stderr | 58 ++-- tests/ui/floating_point_powf.fixed | 2 + tests/ui/floating_point_powf.rs | 2 + tests/ui/floating_point_powf.stderr | 62 ++--- tests/ui/lossy_float_literal.fixed | 24 ++ tests/ui/lossy_float_literal.rs | 24 ++ tests/ui/lossy_float_literal.stderr | 22 +- tests/ui/manual_float_methods.rs | 2 + tests/ui/manual_float_methods.stderr | 12 +- tests/ui/modulo_arithmetic_float.rs | 27 ++ tests/ui/modulo_arithmetic_float.stderr | 70 ++++- tests/ui/transmute.rs | 30 +- tests/ui/transmute.stderr | 116 +++++--- tests/ui/transmute_float_to_int.fixed | 12 + tests/ui/transmute_float_to_int.rs | 12 + tests/ui/transmute_float_to_int.stderr | 12 +- tests/ui/unused_rounding.fixed | 2 + tests/ui/unused_rounding.rs | 2 + tests/ui/unused_rounding.stderr | 10 +- 44 files changed, 792 insertions(+), 522 deletions(-) diff --git a/tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs b/tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs index 63fdea710cb6e..17fceae017801 100644 --- a/tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs +++ b/tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs @@ -40,6 +40,7 @@ fn main() { a.sort_unstable(); + // FIXME(f16_f128): add a clamp test once the function is available let _ = 2.0f32.clamp(3.0f32, 4.0f32); let _ = 2.0f64.clamp(3.0f64, 4.0f64); diff --git a/tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.stderr b/tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.stderr index 55e867d5f3938..4afbbf5f80791 100644 --- a/tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.stderr +++ b/tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.stderr @@ -28,61 +28,61 @@ LL | a.sort_unstable(); | ^^^^^^^^^^^^^^^^^ error: use of a disallowed method `f32::clamp` - --> tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs:43:13 + --> tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs:44:13 | LL | let _ = 2.0f32.clamp(3.0f32, 4.0f32); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: use of a disallowed method `regex::Regex::new` - --> tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs:46:61 + --> tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs:47:61 | LL | let indirect: fn(&str) -> Result = Regex::new; | ^^^^^^^^^^ error: use of a disallowed method `f32::clamp` - --> tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs:49:28 + --> tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs:50:28 | LL | let in_call = Box::new(f32::clamp); | ^^^^^^^^^^ error: use of a disallowed method `regex::Regex::new` - --> tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs:50:53 + --> tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs:51:53 | LL | let in_method_call = ["^", "$"].into_iter().map(Regex::new); | ^^^^^^^^^^ error: use of a disallowed method `futures::stream::select_all` - --> tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs:53:31 + --> tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs:54:31 | LL | let same_name_as_module = select_all(vec![empty::<()>()]); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: use of a disallowed method `conf_disallowed_methods::local_fn` - --> tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs:55:5 + --> tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs:56:5 | LL | local_fn(); | ^^^^^^^^^^ error: use of a disallowed method `conf_disallowed_methods::local_mod::f` - --> tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs:56:5 + --> tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs:57:5 | LL | local_mod::f(); | ^^^^^^^^^^^^^^ error: use of a disallowed method `conf_disallowed_methods::Struct::method` - --> tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs:58:5 + --> tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs:59:5 | LL | s.method(); | ^^^^^^^^^^ error: use of a disallowed method `conf_disallowed_methods::Trait::provided_method` - --> tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs:59:5 + --> tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs:60:5 | LL | s.provided_method(); | ^^^^^^^^^^^^^^^^^^^ error: use of a disallowed method `conf_disallowed_methods::Trait::implemented_method` - --> tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs:60:5 + --> tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs:61:5 | LL | s.implemented_method(); | ^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/arithmetic_side_effects.rs b/tests/ui/arithmetic_side_effects.rs index 33a91e8bbbe53..9d06e14e88c52 100644 --- a/tests/ui/arithmetic_side_effects.rs +++ b/tests/ui/arithmetic_side_effects.rs @@ -11,6 +11,8 @@ unconditional_panic )] #![feature(const_mut_refs)] +#![feature(f128)] +#![feature(f16)] #![warn(clippy::arithmetic_side_effects)] extern crate proc_macro_derive; @@ -162,8 +164,10 @@ pub fn association_with_structures_should_not_trigger_the_lint() { } pub fn hard_coded_allowed() { + let _ = 1f16 + 1f16; let _ = 1f32 + 1f32; let _ = 1f64 + 1f64; + let _ = 1f128 + 1f128; let _ = Saturating(0u32) + Saturating(0u32); let _ = String::new() + ""; diff --git a/tests/ui/arithmetic_side_effects.stderr b/tests/ui/arithmetic_side_effects.stderr index 8039c0bfa2484..78914667bf305 100644 --- a/tests/ui/arithmetic_side_effects.stderr +++ b/tests/ui/arithmetic_side_effects.stderr @@ -1,731 +1,743 @@ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:304:5 + --> tests/ui/arithmetic_side_effects.rs:167:13 | -LL | _n += 1; - | ^^^^^^^ +LL | let _ = 1f16 + 1f16; + | ^^^^^^^^^^^ | = note: `-D clippy::arithmetic-side-effects` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::arithmetic_side_effects)]` error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:305:5 + --> tests/ui/arithmetic_side_effects.rs:170:13 + | +LL | let _ = 1f128 + 1f128; + | ^^^^^^^^^^^^^ + +error: arithmetic operation that can potentially result in unexpected side-effects + --> tests/ui/arithmetic_side_effects.rs:308:5 + | +LL | _n += 1; + | ^^^^^^^ + +error: arithmetic operation that can potentially result in unexpected side-effects + --> tests/ui/arithmetic_side_effects.rs:309:5 | LL | _n += &1; | ^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:306:5 + --> tests/ui/arithmetic_side_effects.rs:310:5 | LL | _n -= 1; | ^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:307:5 + --> tests/ui/arithmetic_side_effects.rs:311:5 | LL | _n -= &1; | ^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:308:5 + --> tests/ui/arithmetic_side_effects.rs:312:5 | LL | _n /= 0; | ^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:309:5 + --> tests/ui/arithmetic_side_effects.rs:313:5 | LL | _n /= &0; | ^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:310:5 + --> tests/ui/arithmetic_side_effects.rs:314:5 | LL | _n %= 0; | ^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:311:5 + --> tests/ui/arithmetic_side_effects.rs:315:5 | LL | _n %= &0; | ^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:312:5 + --> tests/ui/arithmetic_side_effects.rs:316:5 | LL | _n *= 2; | ^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:313:5 + --> tests/ui/arithmetic_side_effects.rs:317:5 | LL | _n *= &2; | ^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:314:5 + --> tests/ui/arithmetic_side_effects.rs:318:5 | LL | _n += -1; | ^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:315:5 + --> tests/ui/arithmetic_side_effects.rs:319:5 | LL | _n += &-1; | ^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:316:5 + --> tests/ui/arithmetic_side_effects.rs:320:5 | LL | _n -= -1; | ^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:317:5 + --> tests/ui/arithmetic_side_effects.rs:321:5 | LL | _n -= &-1; | ^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:318:5 + --> tests/ui/arithmetic_side_effects.rs:322:5 | LL | _n /= -0; | ^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:319:5 + --> tests/ui/arithmetic_side_effects.rs:323:5 | LL | _n /= &-0; | ^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:320:5 + --> tests/ui/arithmetic_side_effects.rs:324:5 | LL | _n %= -0; | ^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:321:5 + --> tests/ui/arithmetic_side_effects.rs:325:5 | LL | _n %= &-0; | ^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:322:5 + --> tests/ui/arithmetic_side_effects.rs:326:5 | LL | _n *= -2; | ^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:323:5 + --> tests/ui/arithmetic_side_effects.rs:327:5 | LL | _n *= &-2; | ^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:324:5 + --> tests/ui/arithmetic_side_effects.rs:328:5 | LL | _custom += Custom; | ^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:325:5 + --> tests/ui/arithmetic_side_effects.rs:329:5 | LL | _custom += &Custom; | ^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:326:5 + --> tests/ui/arithmetic_side_effects.rs:330:5 | LL | _custom -= Custom; | ^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:327:5 + --> tests/ui/arithmetic_side_effects.rs:331:5 | LL | _custom -= &Custom; | ^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:328:5 + --> tests/ui/arithmetic_side_effects.rs:332:5 | LL | _custom /= Custom; | ^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:329:5 + --> tests/ui/arithmetic_side_effects.rs:333:5 | LL | _custom /= &Custom; | ^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:330:5 + --> tests/ui/arithmetic_side_effects.rs:334:5 | LL | _custom %= Custom; | ^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:331:5 + --> tests/ui/arithmetic_side_effects.rs:335:5 | LL | _custom %= &Custom; | ^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:332:5 + --> tests/ui/arithmetic_side_effects.rs:336:5 | LL | _custom *= Custom; | ^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:333:5 + --> tests/ui/arithmetic_side_effects.rs:337:5 | LL | _custom *= &Custom; | ^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:334:5 + --> tests/ui/arithmetic_side_effects.rs:338:5 | LL | _custom >>= Custom; | ^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:335:5 + --> tests/ui/arithmetic_side_effects.rs:339:5 | LL | _custom >>= &Custom; | ^^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:336:5 + --> tests/ui/arithmetic_side_effects.rs:340:5 | LL | _custom <<= Custom; | ^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:337:5 + --> tests/ui/arithmetic_side_effects.rs:341:5 | LL | _custom <<= &Custom; | ^^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:338:5 + --> tests/ui/arithmetic_side_effects.rs:342:5 | LL | _custom += -Custom; | ^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:339:5 + --> tests/ui/arithmetic_side_effects.rs:343:5 | LL | _custom += &-Custom; | ^^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:340:5 + --> tests/ui/arithmetic_side_effects.rs:344:5 | LL | _custom -= -Custom; | ^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:341:5 + --> tests/ui/arithmetic_side_effects.rs:345:5 | LL | _custom -= &-Custom; | ^^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:342:5 + --> tests/ui/arithmetic_side_effects.rs:346:5 | LL | _custom /= -Custom; | ^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:343:5 + --> tests/ui/arithmetic_side_effects.rs:347:5 | LL | _custom /= &-Custom; | ^^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:344:5 + --> tests/ui/arithmetic_side_effects.rs:348:5 | LL | _custom %= -Custom; | ^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:345:5 + --> tests/ui/arithmetic_side_effects.rs:349:5 | LL | _custom %= &-Custom; | ^^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:346:5 + --> tests/ui/arithmetic_side_effects.rs:350:5 | LL | _custom *= -Custom; | ^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:347:5 + --> tests/ui/arithmetic_side_effects.rs:351:5 | LL | _custom *= &-Custom; | ^^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:348:5 + --> tests/ui/arithmetic_side_effects.rs:352:5 | LL | _custom >>= -Custom; | ^^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:349:5 + --> tests/ui/arithmetic_side_effects.rs:353:5 | LL | _custom >>= &-Custom; | ^^^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:350:5 + --> tests/ui/arithmetic_side_effects.rs:354:5 | LL | _custom <<= -Custom; | ^^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:351:5 + --> tests/ui/arithmetic_side_effects.rs:355:5 | LL | _custom <<= &-Custom; | ^^^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:354:10 + --> tests/ui/arithmetic_side_effects.rs:358:10 | LL | _n = _n + 1; | ^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:355:10 + --> tests/ui/arithmetic_side_effects.rs:359:10 | LL | _n = _n + &1; | ^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:356:10 + --> tests/ui/arithmetic_side_effects.rs:360:10 | LL | _n = 1 + _n; | ^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:357:10 + --> tests/ui/arithmetic_side_effects.rs:361:10 | LL | _n = &1 + _n; | ^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:358:10 + --> tests/ui/arithmetic_side_effects.rs:362:10 | LL | _n = _n - 1; | ^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:359:10 + --> tests/ui/arithmetic_side_effects.rs:363:10 | LL | _n = _n - &1; | ^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:360:10 + --> tests/ui/arithmetic_side_effects.rs:364:10 | LL | _n = 1 - _n; | ^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:361:10 + --> tests/ui/arithmetic_side_effects.rs:365:10 | LL | _n = &1 - _n; | ^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:362:10 + --> tests/ui/arithmetic_side_effects.rs:366:10 | LL | _n = _n / 0; | ^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:363:10 + --> tests/ui/arithmetic_side_effects.rs:367:10 | LL | _n = _n / &0; | ^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:364:10 + --> tests/ui/arithmetic_side_effects.rs:368:10 | LL | _n = _n % 0; | ^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:365:10 + --> tests/ui/arithmetic_side_effects.rs:369:10 | LL | _n = _n % &0; | ^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:366:10 + --> tests/ui/arithmetic_side_effects.rs:370:10 | LL | _n = _n * 2; | ^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:367:10 + --> tests/ui/arithmetic_side_effects.rs:371:10 | LL | _n = _n * &2; | ^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:368:10 + --> tests/ui/arithmetic_side_effects.rs:372:10 | LL | _n = 2 * _n; | ^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:369:10 + --> tests/ui/arithmetic_side_effects.rs:373:10 | LL | _n = &2 * _n; | ^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:370:10 + --> tests/ui/arithmetic_side_effects.rs:374:10 | LL | _n = 23 + &85; | ^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:371:10 + --> tests/ui/arithmetic_side_effects.rs:375:10 | LL | _n = &23 + 85; | ^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:372:10 + --> tests/ui/arithmetic_side_effects.rs:376:10 | LL | _n = &23 + &85; | ^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:373:15 + --> tests/ui/arithmetic_side_effects.rs:377:15 | LL | _custom = _custom + _custom; | ^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:374:15 + --> tests/ui/arithmetic_side_effects.rs:378:15 | LL | _custom = _custom + &_custom; | ^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:375:15 + --> tests/ui/arithmetic_side_effects.rs:379:15 | LL | _custom = Custom + _custom; | ^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:376:15 + --> tests/ui/arithmetic_side_effects.rs:380:15 | LL | _custom = &Custom + _custom; | ^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:377:15 + --> tests/ui/arithmetic_side_effects.rs:381:15 | LL | _custom = _custom - Custom; | ^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:378:15 + --> tests/ui/arithmetic_side_effects.rs:382:15 | LL | _custom = _custom - &Custom; | ^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:379:15 + --> tests/ui/arithmetic_side_effects.rs:383:15 | LL | _custom = Custom - _custom; | ^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:380:15 + --> tests/ui/arithmetic_side_effects.rs:384:15 | LL | _custom = &Custom - _custom; | ^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:381:15 + --> tests/ui/arithmetic_side_effects.rs:385:15 | LL | _custom = _custom / Custom; | ^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:382:15 + --> tests/ui/arithmetic_side_effects.rs:386:15 | LL | _custom = _custom / &Custom; | ^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:383:15 + --> tests/ui/arithmetic_side_effects.rs:387:15 | LL | _custom = _custom % Custom; | ^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:384:15 + --> tests/ui/arithmetic_side_effects.rs:388:15 | LL | _custom = _custom % &Custom; | ^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:385:15 + --> tests/ui/arithmetic_side_effects.rs:389:15 | LL | _custom = _custom * Custom; | ^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:386:15 + --> tests/ui/arithmetic_side_effects.rs:390:15 | LL | _custom = _custom * &Custom; | ^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:387:15 + --> tests/ui/arithmetic_side_effects.rs:391:15 | LL | _custom = Custom * _custom; | ^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:388:15 + --> tests/ui/arithmetic_side_effects.rs:392:15 | LL | _custom = &Custom * _custom; | ^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:389:15 + --> tests/ui/arithmetic_side_effects.rs:393:15 | LL | _custom = Custom + &Custom; | ^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:390:15 + --> tests/ui/arithmetic_side_effects.rs:394:15 | LL | _custom = &Custom + Custom; | ^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:391:15 + --> tests/ui/arithmetic_side_effects.rs:395:15 | LL | _custom = &Custom + &Custom; | ^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:392:15 + --> tests/ui/arithmetic_side_effects.rs:396:15 | LL | _custom = _custom >> _custom; | ^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:393:15 + --> tests/ui/arithmetic_side_effects.rs:397:15 | LL | _custom = _custom >> &_custom; | ^^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:394:15 + --> tests/ui/arithmetic_side_effects.rs:398:15 | LL | _custom = Custom << _custom; | ^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:395:15 + --> tests/ui/arithmetic_side_effects.rs:399:15 | LL | _custom = &Custom << _custom; | ^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:398:23 + --> tests/ui/arithmetic_side_effects.rs:402:23 | LL | _n.saturating_div(0); | ^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:399:21 + --> tests/ui/arithmetic_side_effects.rs:403:21 | LL | _n.wrapping_div(0); | ^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:400:21 + --> tests/ui/arithmetic_side_effects.rs:404:21 | LL | _n.wrapping_rem(0); | ^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:401:28 + --> tests/ui/arithmetic_side_effects.rs:405:28 | LL | _n.wrapping_rem_euclid(0); | ^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:403:23 + --> tests/ui/arithmetic_side_effects.rs:407:23 | LL | _n.saturating_div(_n); | ^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:404:21 + --> tests/ui/arithmetic_side_effects.rs:408:21 | LL | _n.wrapping_div(_n); | ^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:405:21 + --> tests/ui/arithmetic_side_effects.rs:409:21 | LL | _n.wrapping_rem(_n); | ^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:406:28 + --> tests/ui/arithmetic_side_effects.rs:410:28 | LL | _n.wrapping_rem_euclid(_n); | ^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:409:10 + --> tests/ui/arithmetic_side_effects.rs:413:10 | LL | _n = -_n; | ^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:410:10 + --> tests/ui/arithmetic_side_effects.rs:414:10 | LL | _n = -&_n; | ^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:411:15 + --> tests/ui/arithmetic_side_effects.rs:415:15 | LL | _custom = -_custom; | ^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:412:15 + --> tests/ui/arithmetic_side_effects.rs:416:15 | LL | _custom = -&_custom; | ^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:421:5 + --> tests/ui/arithmetic_side_effects.rs:425:5 | LL | 1 + i; | ^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:422:5 + --> tests/ui/arithmetic_side_effects.rs:426:5 | LL | i * 2; | ^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:423:5 + --> tests/ui/arithmetic_side_effects.rs:427:5 | LL | 1 % i / 2; | ^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:424:5 + --> tests/ui/arithmetic_side_effects.rs:428:5 | LL | i - 2 + 2 - i; | ^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:425:5 + --> tests/ui/arithmetic_side_effects.rs:429:5 | LL | -i; | ^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:436:5 + --> tests/ui/arithmetic_side_effects.rs:440:5 | LL | i += 1; | ^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:437:5 + --> tests/ui/arithmetic_side_effects.rs:441:5 | LL | i -= 1; | ^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:438:5 + --> tests/ui/arithmetic_side_effects.rs:442:5 | LL | i *= 2; | ^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:440:5 + --> tests/ui/arithmetic_side_effects.rs:444:5 | LL | i /= 0; | ^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:442:5 + --> tests/ui/arithmetic_side_effects.rs:446:5 | LL | i /= var1; | ^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:443:5 + --> tests/ui/arithmetic_side_effects.rs:447:5 | LL | i /= var2; | ^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:445:5 + --> tests/ui/arithmetic_side_effects.rs:449:5 | LL | i %= 0; | ^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:447:5 + --> tests/ui/arithmetic_side_effects.rs:451:5 | LL | i %= var1; | ^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:448:5 + --> tests/ui/arithmetic_side_effects.rs:452:5 | LL | i %= var2; | ^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:458:5 + --> tests/ui/arithmetic_side_effects.rs:462:5 | LL | 10 / a | ^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:512:9 + --> tests/ui/arithmetic_side_effects.rs:516:9 | LL | x / maybe_zero | ^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:516:9 + --> tests/ui/arithmetic_side_effects.rs:520:9 | LL | x % maybe_zero | ^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:527:5 + --> tests/ui/arithmetic_side_effects.rs:531:5 | LL | one.add_assign(1); | ^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> tests/ui/arithmetic_side_effects.rs:531:5 + --> tests/ui/arithmetic_side_effects.rs:535:5 | LL | one.sub_assign(1); | ^^^^^^^^^^^^^^^^^ -error: aborting due to 121 previous errors +error: aborting due to 123 previous errors diff --git a/tests/ui/cast.rs b/tests/ui/cast.rs index 453d62ce60753..c39f65a43e39c 100644 --- a/tests/ui/cast.rs +++ b/tests/ui/cast.rs @@ -17,6 +17,8 @@ clippy::identity_op )] +// FIXME(f16_f128): add tests once const casting is available for these types + fn main() { // Test clippy::cast_precision_loss let x0 = 1i32; diff --git a/tests/ui/cast.stderr b/tests/ui/cast.stderr index 43c0d8f4ed738..452482fc88e28 100644 --- a/tests/ui/cast.stderr +++ b/tests/ui/cast.stderr @@ -1,5 +1,5 @@ error: casting `i32` to `f32` causes a loss of precision (`i32` is 32 bits wide, but `f32`'s mantissa is only 23 bits wide) - --> tests/ui/cast.rs:23:5 + --> tests/ui/cast.rs:25:5 | LL | x0 as f32; | ^^^^^^^^^ @@ -8,37 +8,37 @@ LL | x0 as f32; = help: to override `-D warnings` add `#[allow(clippy::cast_precision_loss)]` error: casting `i64` to `f32` causes a loss of precision (`i64` is 64 bits wide, but `f32`'s mantissa is only 23 bits wide) - --> tests/ui/cast.rs:27:5 + --> tests/ui/cast.rs:29:5 | LL | x1 as f32; | ^^^^^^^^^ error: casting `i64` to `f64` causes a loss of precision (`i64` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide) - --> tests/ui/cast.rs:29:5 + --> tests/ui/cast.rs:31:5 | LL | x1 as f64; | ^^^^^^^^^ error: casting `u32` to `f32` causes a loss of precision (`u32` is 32 bits wide, but `f32`'s mantissa is only 23 bits wide) - --> tests/ui/cast.rs:32:5 + --> tests/ui/cast.rs:34:5 | LL | x2 as f32; | ^^^^^^^^^ error: casting `u64` to `f32` causes a loss of precision (`u64` is 64 bits wide, but `f32`'s mantissa is only 23 bits wide) - --> tests/ui/cast.rs:35:5 + --> tests/ui/cast.rs:37:5 | LL | x3 as f32; | ^^^^^^^^^ error: casting `u64` to `f64` causes a loss of precision (`u64` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide) - --> tests/ui/cast.rs:37:5 + --> tests/ui/cast.rs:39:5 | LL | x3 as f64; | ^^^^^^^^^ error: casting `f32` to `i32` may truncate the value - --> tests/ui/cast.rs:40:5 + --> tests/ui/cast.rs:42:5 | LL | 1f32 as i32; | ^^^^^^^^^^^ @@ -48,7 +48,7 @@ LL | 1f32 as i32; = help: to override `-D warnings` add `#[allow(clippy::cast_possible_truncation)]` error: casting `f32` to `u32` may truncate the value - --> tests/ui/cast.rs:42:5 + --> tests/ui/cast.rs:44:5 | LL | 1f32 as u32; | ^^^^^^^^^^^ @@ -56,7 +56,7 @@ LL | 1f32 as u32; = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... error: casting `f32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:42:5 + --> tests/ui/cast.rs:44:5 | LL | 1f32 as u32; | ^^^^^^^^^^^ @@ -65,7 +65,7 @@ LL | 1f32 as u32; = help: to override `-D warnings` add `#[allow(clippy::cast_sign_loss)]` error: casting `f64` to `f32` may truncate the value - --> tests/ui/cast.rs:46:5 + --> tests/ui/cast.rs:48:5 | LL | 1f64 as f32; | ^^^^^^^^^^^ @@ -73,7 +73,7 @@ LL | 1f64 as f32; = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... error: casting `i32` to `i8` may truncate the value - --> tests/ui/cast.rs:48:5 + --> tests/ui/cast.rs:50:5 | LL | 1i32 as i8; | ^^^^^^^^^^ @@ -85,7 +85,7 @@ LL | i8::try_from(1i32); | ~~~~~~~~~~~~~~~~~~ error: casting `i32` to `u8` may truncate the value - --> tests/ui/cast.rs:50:5 + --> tests/ui/cast.rs:52:5 | LL | 1i32 as u8; | ^^^^^^^^^^ @@ -97,7 +97,7 @@ LL | u8::try_from(1i32); | ~~~~~~~~~~~~~~~~~~ error: casting `f64` to `isize` may truncate the value - --> tests/ui/cast.rs:52:5 + --> tests/ui/cast.rs:54:5 | LL | 1f64 as isize; | ^^^^^^^^^^^^^ @@ -105,7 +105,7 @@ LL | 1f64 as isize; = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... error: casting `f64` to `usize` may truncate the value - --> tests/ui/cast.rs:54:5 + --> tests/ui/cast.rs:56:5 | LL | 1f64 as usize; | ^^^^^^^^^^^^^ @@ -113,13 +113,13 @@ LL | 1f64 as usize; = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... error: casting `f64` to `usize` may lose the sign of the value - --> tests/ui/cast.rs:54:5 + --> tests/ui/cast.rs:56:5 | LL | 1f64 as usize; | ^^^^^^^^^^^^^ error: casting `u32` to `u16` may truncate the value - --> tests/ui/cast.rs:57:5 + --> tests/ui/cast.rs:59:5 | LL | 1f32 as u32 as u16; | ^^^^^^^^^^^^^^^^^^ @@ -131,7 +131,7 @@ LL | u16::try_from(1f32 as u32); | ~~~~~~~~~~~~~~~~~~~~~~~~~~ error: casting `f32` to `u32` may truncate the value - --> tests/ui/cast.rs:57:5 + --> tests/ui/cast.rs:59:5 | LL | 1f32 as u32 as u16; | ^^^^^^^^^^^ @@ -139,13 +139,13 @@ LL | 1f32 as u32 as u16; = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... error: casting `f32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:57:5 + --> tests/ui/cast.rs:59:5 | LL | 1f32 as u32 as u16; | ^^^^^^^^^^^ error: casting `i32` to `i8` may truncate the value - --> tests/ui/cast.rs:62:22 + --> tests/ui/cast.rs:64:22 | LL | let _x: i8 = 1i32 as _; | ^^^^^^^^^ @@ -157,7 +157,7 @@ LL | let _x: i8 = 1i32.try_into(); | ~~~~~~~~~~~~~~~ error: casting `f32` to `i32` may truncate the value - --> tests/ui/cast.rs:64:9 + --> tests/ui/cast.rs:66:9 | LL | 1f32 as i32; | ^^^^^^^^^^^ @@ -165,7 +165,7 @@ LL | 1f32 as i32; = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... error: casting `f64` to `i32` may truncate the value - --> tests/ui/cast.rs:66:9 + --> tests/ui/cast.rs:68:9 | LL | 1f64 as i32; | ^^^^^^^^^^^ @@ -173,7 +173,7 @@ LL | 1f64 as i32; = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... error: casting `f32` to `u8` may truncate the value - --> tests/ui/cast.rs:68:9 + --> tests/ui/cast.rs:70:9 | LL | 1f32 as u8; | ^^^^^^^^^^ @@ -181,13 +181,13 @@ LL | 1f32 as u8; = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... error: casting `f32` to `u8` may lose the sign of the value - --> tests/ui/cast.rs:68:9 + --> tests/ui/cast.rs:70:9 | LL | 1f32 as u8; | ^^^^^^^^^^ error: casting `u8` to `i8` may wrap around the value - --> tests/ui/cast.rs:73:5 + --> tests/ui/cast.rs:75:5 | LL | 1u8 as i8; | ^^^^^^^^^ @@ -196,31 +196,31 @@ LL | 1u8 as i8; = help: to override `-D warnings` add `#[allow(clippy::cast_possible_wrap)]` error: casting `u16` to `i16` may wrap around the value - --> tests/ui/cast.rs:76:5 + --> tests/ui/cast.rs:78:5 | LL | 1u16 as i16; | ^^^^^^^^^^^ error: casting `u32` to `i32` may wrap around the value - --> tests/ui/cast.rs:78:5 + --> tests/ui/cast.rs:80:5 | LL | 1u32 as i32; | ^^^^^^^^^^^ error: casting `u64` to `i64` may wrap around the value - --> tests/ui/cast.rs:80:5 + --> tests/ui/cast.rs:82:5 | LL | 1u64 as i64; | ^^^^^^^^^^^ error: casting `usize` to `isize` may wrap around the value - --> tests/ui/cast.rs:82:5 + --> tests/ui/cast.rs:84:5 | LL | 1usize as isize; | ^^^^^^^^^^^^^^^ error: casting `usize` to `i8` may truncate the value - --> tests/ui/cast.rs:85:5 + --> tests/ui/cast.rs:87:5 | LL | 1usize as i8; | ^^^^^^^^^^^^ @@ -232,7 +232,7 @@ LL | i8::try_from(1usize); | ~~~~~~~~~~~~~~~~~~~~ error: casting `usize` to `i16` may truncate the value - --> tests/ui/cast.rs:88:5 + --> tests/ui/cast.rs:90:5 | LL | 1usize as i16; | ^^^^^^^^^^^^^ @@ -244,7 +244,7 @@ LL | i16::try_from(1usize); | ~~~~~~~~~~~~~~~~~~~~~ error: casting `usize` to `i16` may wrap around the value on targets with 16-bit wide pointers - --> tests/ui/cast.rs:88:5 + --> tests/ui/cast.rs:90:5 | LL | 1usize as i16; | ^^^^^^^^^^^^^ @@ -253,7 +253,7 @@ LL | 1usize as i16; = note: for more information see https://doc.rust-lang.org/reference/types/numeric.html#machine-dependent-integer-types error: casting `usize` to `i32` may truncate the value on targets with 64-bit wide pointers - --> tests/ui/cast.rs:93:5 + --> tests/ui/cast.rs:95:5 | LL | 1usize as i32; | ^^^^^^^^^^^^^ @@ -265,19 +265,19 @@ LL | i32::try_from(1usize); | ~~~~~~~~~~~~~~~~~~~~~ error: casting `usize` to `i32` may wrap around the value on targets with 32-bit wide pointers - --> tests/ui/cast.rs:93:5 + --> tests/ui/cast.rs:95:5 | LL | 1usize as i32; | ^^^^^^^^^^^^^ error: casting `usize` to `i64` may wrap around the value on targets with 64-bit wide pointers - --> tests/ui/cast.rs:97:5 + --> tests/ui/cast.rs:99:5 | LL | 1usize as i64; | ^^^^^^^^^^^^^ error: casting `u16` to `isize` may wrap around the value on targets with 16-bit wide pointers - --> tests/ui/cast.rs:102:5 + --> tests/ui/cast.rs:104:5 | LL | 1u16 as isize; | ^^^^^^^^^^^^^ @@ -286,13 +286,13 @@ LL | 1u16 as isize; = note: for more information see https://doc.rust-lang.org/reference/types/numeric.html#machine-dependent-integer-types error: casting `u32` to `isize` may wrap around the value on targets with 32-bit wide pointers - --> tests/ui/cast.rs:106:5 + --> tests/ui/cast.rs:108:5 | LL | 1u32 as isize; | ^^^^^^^^^^^^^ error: casting `u64` to `isize` may truncate the value on targets with 32-bit wide pointers - --> tests/ui/cast.rs:109:5 + --> tests/ui/cast.rs:111:5 | LL | 1u64 as isize; | ^^^^^^^^^^^^^ @@ -304,55 +304,55 @@ LL | isize::try_from(1u64); | ~~~~~~~~~~~~~~~~~~~~~ error: casting `u64` to `isize` may wrap around the value on targets with 64-bit wide pointers - --> tests/ui/cast.rs:109:5 + --> tests/ui/cast.rs:111:5 | LL | 1u64 as isize; | ^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:114:5 + --> tests/ui/cast.rs:116:5 | LL | -1i32 as u32; | ^^^^^^^^^^^^ error: casting `isize` to `usize` may lose the sign of the value - --> tests/ui/cast.rs:117:5 + --> tests/ui/cast.rs:119:5 | LL | -1isize as usize; | ^^^^^^^^^^^^^^^^ error: casting `i8` to `u8` may lose the sign of the value - --> tests/ui/cast.rs:128:5 + --> tests/ui/cast.rs:130:5 | LL | (i8::MIN).abs() as u8; | ^^^^^^^^^^^^^^^^^^^^^ error: casting `i64` to `u64` may lose the sign of the value - --> tests/ui/cast.rs:132:5 + --> tests/ui/cast.rs:134:5 | LL | (-1i64).abs() as u64; | ^^^^^^^^^^^^^^^^^^^^ error: casting `isize` to `usize` may lose the sign of the value - --> tests/ui/cast.rs:133:5 + --> tests/ui/cast.rs:135:5 | LL | (-1isize).abs() as usize; | ^^^^^^^^^^^^^^^^^^^^^^^^ error: casting `i64` to `u64` may lose the sign of the value - --> tests/ui/cast.rs:140:5 + --> tests/ui/cast.rs:142:5 | LL | (unsafe { (-1i64).checked_abs().unwrap_unchecked() }) as u64; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: casting `i64` to `u64` may lose the sign of the value - --> tests/ui/cast.rs:155:5 + --> tests/ui/cast.rs:157:5 | LL | (unsafe { (-1i64).checked_isqrt().unwrap_unchecked() }) as u64; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: casting `i64` to `i8` may truncate the value - --> tests/ui/cast.rs:206:5 + --> tests/ui/cast.rs:208:5 | LL | (-99999999999i64).min(1) as i8; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -364,7 +364,7 @@ LL | i8::try_from((-99999999999i64).min(1)); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: casting `u64` to `u8` may truncate the value - --> tests/ui/cast.rs:220:5 + --> tests/ui/cast.rs:222:5 | LL | 999999u64.clamp(0, 256) as u8; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -376,7 +376,7 @@ LL | u8::try_from(999999u64.clamp(0, 256)); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: casting `main::E2` to `u8` may truncate the value - --> tests/ui/cast.rs:243:21 + --> tests/ui/cast.rs:245:21 | LL | let _ = self as u8; | ^^^^^^^^^^ @@ -388,7 +388,7 @@ LL | let _ = u8::try_from(self); | ~~~~~~~~~~~~~~~~~~ error: casting `main::E2::B` to `u8` will truncate the value - --> tests/ui/cast.rs:245:21 + --> tests/ui/cast.rs:247:21 | LL | let _ = Self::B as u8; | ^^^^^^^^^^^^^ @@ -397,7 +397,7 @@ LL | let _ = Self::B as u8; = help: to override `-D warnings` add `#[allow(clippy::cast_enum_truncation)]` error: casting `main::E5` to `i8` may truncate the value - --> tests/ui/cast.rs:287:21 + --> tests/ui/cast.rs:289:21 | LL | let _ = self as i8; | ^^^^^^^^^^ @@ -409,13 +409,13 @@ LL | let _ = i8::try_from(self); | ~~~~~~~~~~~~~~~~~~ error: casting `main::E5::A` to `i8` will truncate the value - --> tests/ui/cast.rs:289:21 + --> tests/ui/cast.rs:291:21 | LL | let _ = Self::A as i8; | ^^^^^^^^^^^^^ error: casting `main::E6` to `i16` may truncate the value - --> tests/ui/cast.rs:306:21 + --> tests/ui/cast.rs:308:21 | LL | let _ = self as i16; | ^^^^^^^^^^^ @@ -427,7 +427,7 @@ LL | let _ = i16::try_from(self); | ~~~~~~~~~~~~~~~~~~~ error: casting `main::E7` to `usize` may truncate the value on targets with 32-bit wide pointers - --> tests/ui/cast.rs:325:21 + --> tests/ui/cast.rs:327:21 | LL | let _ = self as usize; | ^^^^^^^^^^^^^ @@ -439,7 +439,7 @@ LL | let _ = usize::try_from(self); | ~~~~~~~~~~~~~~~~~~~~~ error: casting `main::E10` to `u16` may truncate the value - --> tests/ui/cast.rs:372:21 + --> tests/ui/cast.rs:374:21 | LL | let _ = self as u16; | ^^^^^^^^^^^ @@ -451,7 +451,7 @@ LL | let _ = u16::try_from(self); | ~~~~~~~~~~~~~~~~~~~ error: casting `u32` to `u8` may truncate the value - --> tests/ui/cast.rs:383:13 + --> tests/ui/cast.rs:385:13 | LL | let c = (q >> 16) as u8; | ^^^^^^^^^^^^^^^ @@ -463,7 +463,7 @@ LL | let c = u8::try_from(q >> 16); | ~~~~~~~~~~~~~~~~~~~~~ error: casting `u32` to `u8` may truncate the value - --> tests/ui/cast.rs:387:13 + --> tests/ui/cast.rs:389:13 | LL | let c = (q / 1000) as u8; | ^^^^^^^^^^^^^^^^ @@ -475,85 +475,85 @@ LL | let c = u8::try_from(q / 1000); | ~~~~~~~~~~~~~~~~~~~~~~ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:399:9 + --> tests/ui/cast.rs:401:9 | LL | (x * x) as u32; | ^^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:404:32 + --> tests/ui/cast.rs:406:32 | LL | let _a = |x: i32| -> u32 { (x * x * x * x) as u32 }; | ^^^^^^^^^^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:406:5 + --> tests/ui/cast.rs:408:5 | LL | (2_i32).checked_pow(3).unwrap() as u32; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:407:5 + --> tests/ui/cast.rs:409:5 | LL | (-2_i32).pow(3) as u32; | ^^^^^^^^^^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:412:5 + --> tests/ui/cast.rs:414:5 | LL | (-5_i32 % 2) as u32; | ^^^^^^^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:414:5 + --> tests/ui/cast.rs:416:5 | LL | (-5_i32 % -2) as u32; | ^^^^^^^^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:417:5 + --> tests/ui/cast.rs:419:5 | LL | (-2_i32 >> 1) as u32; | ^^^^^^^^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:421:5 + --> tests/ui/cast.rs:423:5 | LL | (x * x) as u32; | ^^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:422:5 + --> tests/ui/cast.rs:424:5 | LL | (x * x * x) as u32; | ^^^^^^^^^^^^^^^^^^ error: casting `i16` to `u16` may lose the sign of the value - --> tests/ui/cast.rs:426:5 + --> tests/ui/cast.rs:428:5 | LL | (y * y * y * y * -2) as u16; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: casting `i16` to `u16` may lose the sign of the value - --> tests/ui/cast.rs:428:5 + --> tests/ui/cast.rs:430:5 | LL | (y * y * y / y * 2) as u16; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: casting `i16` to `u16` may lose the sign of the value - --> tests/ui/cast.rs:429:5 + --> tests/ui/cast.rs:431:5 | LL | (y * y / y * 2) as u16; | ^^^^^^^^^^^^^^^^^^^^^^ error: casting `i16` to `u16` may lose the sign of the value - --> tests/ui/cast.rs:431:5 + --> tests/ui/cast.rs:433:5 | LL | (y / y * y * -2) as u16; | ^^^^^^^^^^^^^^^^^^^^^^^ error: equal expressions as operands to `/` - --> tests/ui/cast.rs:431:6 + --> tests/ui/cast.rs:433:6 | LL | (y / y * y * -2) as u16; | ^^^^^ @@ -561,97 +561,97 @@ LL | (y / y * y * -2) as u16; = note: `#[deny(clippy::eq_op)]` on by default error: casting `i16` to `u16` may lose the sign of the value - --> tests/ui/cast.rs:434:5 + --> tests/ui/cast.rs:436:5 | LL | (y + y + y + -2) as u16; | ^^^^^^^^^^^^^^^^^^^^^^^ error: casting `i16` to `u16` may lose the sign of the value - --> tests/ui/cast.rs:436:5 + --> tests/ui/cast.rs:438:5 | LL | (y + y + y + 2) as u16; | ^^^^^^^^^^^^^^^^^^^^^^ error: casting `i16` to `u16` may lose the sign of the value - --> tests/ui/cast.rs:440:5 + --> tests/ui/cast.rs:442:5 | LL | (z + -2) as u16; | ^^^^^^^^^^^^^^^ error: casting `i16` to `u16` may lose the sign of the value - --> tests/ui/cast.rs:442:5 + --> tests/ui/cast.rs:444:5 | LL | (z + z + 2) as u16; | ^^^^^^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:445:9 + --> tests/ui/cast.rs:447:9 | LL | (a * a * b * b * c * c) as u32; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:446:9 + --> tests/ui/cast.rs:448:9 | LL | (a * b * c) as u32; | ^^^^^^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:448:9 + --> tests/ui/cast.rs:450:9 | LL | (a * -b * c) as u32; | ^^^^^^^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:450:9 + --> tests/ui/cast.rs:452:9 | LL | (a * b * c * c) as u32; | ^^^^^^^^^^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:451:9 + --> tests/ui/cast.rs:453:9 | LL | (a * -2) as u32; | ^^^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:453:9 + --> tests/ui/cast.rs:455:9 | LL | (a * b * c * -2) as u32; | ^^^^^^^^^^^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:455:9 + --> tests/ui/cast.rs:457:9 | LL | (a / b) as u32; | ^^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:456:9 + --> tests/ui/cast.rs:458:9 | LL | (a / b * c) as u32; | ^^^^^^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:458:9 + --> tests/ui/cast.rs:460:9 | LL | (a / b + b * c) as u32; | ^^^^^^^^^^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:460:9 + --> tests/ui/cast.rs:462:9 | LL | a.saturating_pow(3) as u32; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:462:9 + --> tests/ui/cast.rs:464:9 | LL | (a.abs() * b.pow(2) / c.abs()) as u32 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:470:21 + --> tests/ui/cast.rs:472:21 | LL | let _ = i32::MIN as u32; // cast_sign_loss | ^^^^^^^^^^^^^^^ @@ -662,7 +662,7 @@ LL | m!(); = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info) error: casting `u32` to `u8` may truncate the value - --> tests/ui/cast.rs:471:21 + --> tests/ui/cast.rs:473:21 | LL | let _ = u32::MAX as u8; // cast_possible_truncation | ^^^^^^^^^^^^^^ @@ -678,7 +678,7 @@ LL | let _ = u8::try_from(u32::MAX); // cast_possible_truncation | ~~~~~~~~~~~~~~~~~~~~~~ error: casting `f64` to `f32` may truncate the value - --> tests/ui/cast.rs:472:21 + --> tests/ui/cast.rs:474:21 | LL | let _ = std::f64::consts::PI as f32; // cast_possible_truncation | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -690,7 +690,7 @@ LL | m!(); = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info) error: casting `i64` to `usize` may truncate the value on targets with 32-bit wide pointers - --> tests/ui/cast.rs:481:5 + --> tests/ui/cast.rs:483:5 | LL | bar.unwrap().unwrap() as usize | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -702,13 +702,13 @@ LL | usize::try_from(bar.unwrap().unwrap()) | error: casting `i64` to `usize` may lose the sign of the value - --> tests/ui/cast.rs:481:5 + --> tests/ui/cast.rs:483:5 | LL | bar.unwrap().unwrap() as usize | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: casting `u64` to `u8` may truncate the value - --> tests/ui/cast.rs:496:5 + --> tests/ui/cast.rs:498:5 | LL | (256 & 999999u64) as u8; | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -720,7 +720,7 @@ LL | u8::try_from(256 & 999999u64); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: casting `u64` to `u8` may truncate the value - --> tests/ui/cast.rs:498:5 + --> tests/ui/cast.rs:500:5 | LL | (255 % 999999u64) as u8; | ^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/cast_lossless_float.fixed b/tests/ui/cast_lossless_float.fixed index 96a67b1945ca6..163432631e137 100644 --- a/tests/ui/cast_lossless_float.fixed +++ b/tests/ui/cast_lossless_float.fixed @@ -1,6 +1,8 @@ #![allow(clippy::no_effect, clippy::unnecessary_operation, dead_code)] #![warn(clippy::cast_lossless)] +// FIXME(f16_f128): add tests for these types once const casting is available + type F32 = f32; type F64 = f64; diff --git a/tests/ui/cast_lossless_float.rs b/tests/ui/cast_lossless_float.rs index d37b2c1d920ea..afb2a3d890ee9 100644 --- a/tests/ui/cast_lossless_float.rs +++ b/tests/ui/cast_lossless_float.rs @@ -1,6 +1,8 @@ #![allow(clippy::no_effect, clippy::unnecessary_operation, dead_code)] #![warn(clippy::cast_lossless)] +// FIXME(f16_f128): add tests for these types once const casting is available + type F32 = f32; type F64 = f64; diff --git a/tests/ui/cast_lossless_float.stderr b/tests/ui/cast_lossless_float.stderr index ad7de760adfb8..f2ba4e3b99038 100644 --- a/tests/ui/cast_lossless_float.stderr +++ b/tests/ui/cast_lossless_float.stderr @@ -1,5 +1,5 @@ error: casting `i8` to `f32` may become silently lossy if you later change the type - --> tests/ui/cast_lossless_float.rs:10:13 + --> tests/ui/cast_lossless_float.rs:12:13 | LL | let _ = x0 as f32; | ^^^^^^^^^ help: try: `f32::from(x0)` @@ -8,73 +8,73 @@ LL | let _ = x0 as f32; = help: to override `-D warnings` add `#[allow(clippy::cast_lossless)]` error: casting `i8` to `f64` may become silently lossy if you later change the type - --> tests/ui/cast_lossless_float.rs:11:13 + --> tests/ui/cast_lossless_float.rs:13:13 | LL | let _ = x0 as f64; | ^^^^^^^^^ help: try: `f64::from(x0)` error: casting `i8` to `F32` may become silently lossy if you later change the type - --> tests/ui/cast_lossless_float.rs:12:13 + --> tests/ui/cast_lossless_float.rs:14:13 | LL | let _ = x0 as F32; | ^^^^^^^^^ help: try: `F32::from(x0)` error: casting `i8` to `F64` may become silently lossy if you later change the type - --> tests/ui/cast_lossless_float.rs:13:13 + --> tests/ui/cast_lossless_float.rs:15:13 | LL | let _ = x0 as F64; | ^^^^^^^^^ help: try: `F64::from(x0)` error: casting `u8` to `f32` may become silently lossy if you later change the type - --> tests/ui/cast_lossless_float.rs:15:13 + --> tests/ui/cast_lossless_float.rs:17:13 | LL | let _ = x1 as f32; | ^^^^^^^^^ help: try: `f32::from(x1)` error: casting `u8` to `f64` may become silently lossy if you later change the type - --> tests/ui/cast_lossless_float.rs:16:13 + --> tests/ui/cast_lossless_float.rs:18:13 | LL | let _ = x1 as f64; | ^^^^^^^^^ help: try: `f64::from(x1)` error: casting `i16` to `f32` may become silently lossy if you later change the type - --> tests/ui/cast_lossless_float.rs:18:13 + --> tests/ui/cast_lossless_float.rs:20:13 | LL | let _ = x2 as f32; | ^^^^^^^^^ help: try: `f32::from(x2)` error: casting `i16` to `f64` may become silently lossy if you later change the type - --> tests/ui/cast_lossless_float.rs:19:13 + --> tests/ui/cast_lossless_float.rs:21:13 | LL | let _ = x2 as f64; | ^^^^^^^^^ help: try: `f64::from(x2)` error: casting `u16` to `f32` may become silently lossy if you later change the type - --> tests/ui/cast_lossless_float.rs:21:13 + --> tests/ui/cast_lossless_float.rs:23:13 | LL | let _ = x3 as f32; | ^^^^^^^^^ help: try: `f32::from(x3)` error: casting `u16` to `f64` may become silently lossy if you later change the type - --> tests/ui/cast_lossless_float.rs:22:13 + --> tests/ui/cast_lossless_float.rs:24:13 | LL | let _ = x3 as f64; | ^^^^^^^^^ help: try: `f64::from(x3)` error: casting `i32` to `f64` may become silently lossy if you later change the type - --> tests/ui/cast_lossless_float.rs:24:13 + --> tests/ui/cast_lossless_float.rs:26:13 | LL | let _ = x4 as f64; | ^^^^^^^^^ help: try: `f64::from(x4)` error: casting `u32` to `f64` may become silently lossy if you later change the type - --> tests/ui/cast_lossless_float.rs:26:13 + --> tests/ui/cast_lossless_float.rs:28:13 | LL | let _ = x5 as f64; | ^^^^^^^^^ help: try: `f64::from(x5)` error: casting `f32` to `f64` may become silently lossy if you later change the type - --> tests/ui/cast_lossless_float.rs:29:13 + --> tests/ui/cast_lossless_float.rs:31:13 | LL | let _ = 1.0f32 as f64; | ^^^^^^^^^^^^^ help: try: `f64::from(1.0f32)` diff --git a/tests/ui/cast_nan_to_int.rs b/tests/ui/cast_nan_to_int.rs index 2d7467ff0400d..aee38da9a159c 100644 --- a/tests/ui/cast_nan_to_int.rs +++ b/tests/ui/cast_nan_to_int.rs @@ -1,3 +1,5 @@ +// FIXME(f16_f128): add tests when constants are available + #![warn(clippy::cast_nan_to_int)] #![allow(clippy::eq_op)] diff --git a/tests/ui/cast_nan_to_int.stderr b/tests/ui/cast_nan_to_int.stderr index 3cb46d1e79bb7..3aeb2d5452514 100644 --- a/tests/ui/cast_nan_to_int.stderr +++ b/tests/ui/cast_nan_to_int.stderr @@ -1,5 +1,5 @@ error: casting a known NaN to usize - --> tests/ui/cast_nan_to_int.rs:5:13 + --> tests/ui/cast_nan_to_int.rs:7:13 | LL | let _ = (0.0_f32 / -0.0) as usize; | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -9,7 +9,7 @@ LL | let _ = (0.0_f32 / -0.0) as usize; = help: to override `-D warnings` add `#[allow(clippy::cast_nan_to_int)]` error: casting a known NaN to usize - --> tests/ui/cast_nan_to_int.rs:8:13 + --> tests/ui/cast_nan_to_int.rs:10:13 | LL | let _ = (f64::INFINITY * -0.0) as usize; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -17,7 +17,7 @@ LL | let _ = (f64::INFINITY * -0.0) as usize; = note: this always evaluates to 0 error: casting a known NaN to usize - --> tests/ui/cast_nan_to_int.rs:11:13 + --> tests/ui/cast_nan_to_int.rs:13:13 | LL | let _ = (0.0 * f32::INFINITY) as usize; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -25,7 +25,7 @@ LL | let _ = (0.0 * f32::INFINITY) as usize; = note: this always evaluates to 0 error: casting a known NaN to usize - --> tests/ui/cast_nan_to_int.rs:15:13 + --> tests/ui/cast_nan_to_int.rs:17:13 | LL | let _ = (f64::INFINITY + f64::NEG_INFINITY) as usize; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -33,7 +33,7 @@ LL | let _ = (f64::INFINITY + f64::NEG_INFINITY) as usize; = note: this always evaluates to 0 error: casting a known NaN to usize - --> tests/ui/cast_nan_to_int.rs:18:13 + --> tests/ui/cast_nan_to_int.rs:20:13 | LL | let _ = (f32::INFINITY - f32::INFINITY) as usize; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -41,7 +41,7 @@ LL | let _ = (f32::INFINITY - f32::INFINITY) as usize; = note: this always evaluates to 0 error: casting a known NaN to usize - --> tests/ui/cast_nan_to_int.rs:21:13 + --> tests/ui/cast_nan_to_int.rs:23:13 | LL | let _ = (f32::INFINITY / f32::NEG_INFINITY) as usize; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/cast_size.64bit.stderr b/tests/ui/cast_size.64bit.stderr index 0dc4ca91529c6..bc37107d80e39 100644 --- a/tests/ui/cast_size.64bit.stderr +++ b/tests/ui/cast_size.64bit.stderr @@ -12,35 +12,35 @@ help: ... or use `try_from` and handle the error accordingly LL | i8::try_from(1isize); | ~~~~~~~~~~~~~~~~~~~~ -error: casting `isize` to `f64` causes a loss of precision on targets with 64-bit wide pointers (`isize` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide) - --> tests/ui/cast_size.rs:18:5 +error: casting `isize` to `f32` causes a loss of precision (`isize` is 32 or 64 bits wide, but `f32`'s mantissa is only 23 bits wide) + --> tests/ui/cast_size.rs:21:5 | -LL | x0 as f64; +LL | x0 as f32; | ^^^^^^^^^ | = note: `-D clippy::cast-precision-loss` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::cast_precision_loss)]` -error: casting `usize` to `f64` causes a loss of precision on targets with 64-bit wide pointers (`usize` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide) - --> tests/ui/cast_size.rs:19:5 +error: casting `usize` to `f32` causes a loss of precision (`usize` is 32 or 64 bits wide, but `f32`'s mantissa is only 23 bits wide) + --> tests/ui/cast_size.rs:22:5 | -LL | x1 as f64; +LL | x1 as f32; | ^^^^^^^^^ -error: casting `isize` to `f32` causes a loss of precision (`isize` is 32 or 64 bits wide, but `f32`'s mantissa is only 23 bits wide) - --> tests/ui/cast_size.rs:20:5 +error: casting `isize` to `f64` causes a loss of precision on targets with 64-bit wide pointers (`isize` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide) + --> tests/ui/cast_size.rs:23:5 | -LL | x0 as f32; +LL | x0 as f64; | ^^^^^^^^^ -error: casting `usize` to `f32` causes a loss of precision (`usize` is 32 or 64 bits wide, but `f32`'s mantissa is only 23 bits wide) - --> tests/ui/cast_size.rs:21:5 +error: casting `usize` to `f64` causes a loss of precision on targets with 64-bit wide pointers (`usize` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide) + --> tests/ui/cast_size.rs:24:5 | -LL | x1 as f32; +LL | x1 as f64; | ^^^^^^^^^ error: casting `isize` to `i32` may truncate the value on targets with 64-bit wide pointers - --> tests/ui/cast_size.rs:22:5 + --> tests/ui/cast_size.rs:28:5 | LL | 1isize as i32; | ^^^^^^^^^^^^^ @@ -52,7 +52,7 @@ LL | i32::try_from(1isize); | ~~~~~~~~~~~~~~~~~~~~~ error: casting `isize` to `u32` may truncate the value on targets with 64-bit wide pointers - --> tests/ui/cast_size.rs:23:5 + --> tests/ui/cast_size.rs:29:5 | LL | 1isize as u32; | ^^^^^^^^^^^^^ @@ -64,7 +64,7 @@ LL | u32::try_from(1isize); | ~~~~~~~~~~~~~~~~~~~~~ error: casting `usize` to `u32` may truncate the value on targets with 64-bit wide pointers - --> tests/ui/cast_size.rs:24:5 + --> tests/ui/cast_size.rs:30:5 | LL | 1usize as u32; | ^^^^^^^^^^^^^ @@ -76,7 +76,7 @@ LL | u32::try_from(1usize); | ~~~~~~~~~~~~~~~~~~~~~ error: casting `usize` to `i32` may truncate the value on targets with 64-bit wide pointers - --> tests/ui/cast_size.rs:25:5 + --> tests/ui/cast_size.rs:31:5 | LL | 1usize as i32; | ^^^^^^^^^^^^^ @@ -88,7 +88,7 @@ LL | i32::try_from(1usize); | ~~~~~~~~~~~~~~~~~~~~~ error: casting `usize` to `i32` may wrap around the value on targets with 32-bit wide pointers - --> tests/ui/cast_size.rs:25:5 + --> tests/ui/cast_size.rs:31:5 | LL | 1usize as i32; | ^^^^^^^^^^^^^ @@ -97,7 +97,7 @@ LL | 1usize as i32; = help: to override `-D warnings` add `#[allow(clippy::cast_possible_wrap)]` error: casting `i64` to `isize` may truncate the value on targets with 32-bit wide pointers - --> tests/ui/cast_size.rs:26:5 + --> tests/ui/cast_size.rs:32:5 | LL | 1i64 as isize; | ^^^^^^^^^^^^^ @@ -109,7 +109,7 @@ LL | isize::try_from(1i64); | ~~~~~~~~~~~~~~~~~~~~~ error: casting `i64` to `usize` may truncate the value on targets with 32-bit wide pointers - --> tests/ui/cast_size.rs:27:5 + --> tests/ui/cast_size.rs:33:5 | LL | 1i64 as usize; | ^^^^^^^^^^^^^ @@ -121,7 +121,7 @@ LL | usize::try_from(1i64); | ~~~~~~~~~~~~~~~~~~~~~ error: casting `u64` to `isize` may truncate the value on targets with 32-bit wide pointers - --> tests/ui/cast_size.rs:28:5 + --> tests/ui/cast_size.rs:34:5 | LL | 1u64 as isize; | ^^^^^^^^^^^^^ @@ -133,13 +133,13 @@ LL | isize::try_from(1u64); | ~~~~~~~~~~~~~~~~~~~~~ error: casting `u64` to `isize` may wrap around the value on targets with 64-bit wide pointers - --> tests/ui/cast_size.rs:28:5 + --> tests/ui/cast_size.rs:34:5 | LL | 1u64 as isize; | ^^^^^^^^^^^^^ error: casting `u64` to `usize` may truncate the value on targets with 32-bit wide pointers - --> tests/ui/cast_size.rs:29:5 + --> tests/ui/cast_size.rs:35:5 | LL | 1u64 as usize; | ^^^^^^^^^^^^^ @@ -151,19 +151,19 @@ LL | usize::try_from(1u64); | ~~~~~~~~~~~~~~~~~~~~~ error: casting `u32` to `isize` may wrap around the value on targets with 32-bit wide pointers - --> tests/ui/cast_size.rs:30:5 + --> tests/ui/cast_size.rs:36:5 | LL | 1u32 as isize; | ^^^^^^^^^^^^^ error: casting `i32` to `f32` causes a loss of precision (`i32` is 32 bits wide, but `f32`'s mantissa is only 23 bits wide) - --> tests/ui/cast_size.rs:35:5 + --> tests/ui/cast_size.rs:43:5 | LL | 999_999_999 as f32; | ^^^^^^^^^^^^^^^^^^ error: casting `usize` to `f64` causes a loss of precision on targets with 64-bit wide pointers (`usize` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide) - --> tests/ui/cast_size.rs:36:5 + --> tests/ui/cast_size.rs:44:5 | LL | 9_999_999_999_999_999usize as f64; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/cast_size.rs b/tests/ui/cast_size.rs index d063a70ccdfcf..d0ed8e57d7ae5 100644 --- a/tests/ui/cast_size.rs +++ b/tests/ui/cast_size.rs @@ -15,10 +15,16 @@ fn main() { 1isize as i8; let x0 = 1isize; let x1 = 1usize; - x0 as f64; - x1 as f64; + // FIXME(f16_f128): enable f16 and f128 conversions once const eval supports them + // x0 as f16; + // x1 as f16; x0 as f32; x1 as f32; + x0 as f64; + x1 as f64; + // x0 as f128; + // x1 as f128; + 1isize as i32; 1isize as u32; 1usize as u32; @@ -31,7 +37,10 @@ fn main() { 1u32 as usize; // Should not trigger any lint 1i32 as isize; // Neither should this 1i32 as usize; + // Big integer literal to float + // 999_999 as f16; 999_999_999 as f32; 9_999_999_999_999_999usize as f64; + // 999_999_999_999_999_999_999_999_999_999u128 as f128; } diff --git a/tests/ui/endian_bytes.rs b/tests/ui/endian_bytes.rs index 6bf014fc80951..580fc2fc24d76 100644 --- a/tests/ui/endian_bytes.rs +++ b/tests/ui/endian_bytes.rs @@ -2,6 +2,8 @@ #![allow(clippy::diverging_sub_expression)] #![no_main] +// FIXME(f16_f128): add these types when `{to_from}_*_bytes` are available + macro_rules! fn_body { () => { 2u8.to_ne_bytes(); diff --git a/tests/ui/endian_bytes.stderr b/tests/ui/endian_bytes.stderr index 3fc26dcab8869..fd19ec45872b4 100644 --- a/tests/ui/endian_bytes.stderr +++ b/tests/ui/endian_bytes.stderr @@ -1,5 +1,5 @@ error: usage of the `u8::to_ne_bytes` method - --> tests/ui/endian_bytes.rs:7:9 + --> tests/ui/endian_bytes.rs:9:9 | LL | 2u8.to_ne_bytes(); | ^^^^^^^^^^^^^^^^^ @@ -13,7 +13,7 @@ LL | fn host() { fn_body!(); } = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the `i8::to_ne_bytes` method - --> tests/ui/endian_bytes.rs:8:9 + --> tests/ui/endian_bytes.rs:10:9 | LL | 2i8.to_ne_bytes(); | ^^^^^^^^^^^^^^^^^ @@ -25,7 +25,7 @@ LL | fn host() { fn_body!(); } = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the `u16::to_ne_bytes` method - --> tests/ui/endian_bytes.rs:9:9 + --> tests/ui/endian_bytes.rs:11:9 | LL | 2u16.to_ne_bytes(); | ^^^^^^^^^^^^^^^^^^ @@ -37,7 +37,7 @@ LL | fn host() { fn_body!(); } = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the `i16::to_ne_bytes` method - --> tests/ui/endian_bytes.rs:10:9 + --> tests/ui/endian_bytes.rs:12:9 | LL | 2i16.to_ne_bytes(); | ^^^^^^^^^^^^^^^^^^ @@ -49,7 +49,7 @@ LL | fn host() { fn_body!(); } = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the `u32::to_ne_bytes` method - --> tests/ui/endian_bytes.rs:11:9 + --> tests/ui/endian_bytes.rs:13:9 | LL | 2u32.to_ne_bytes(); | ^^^^^^^^^^^^^^^^^^ @@ -61,7 +61,7 @@ LL | fn host() { fn_body!(); } = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the `i32::to_ne_bytes` method - --> tests/ui/endian_bytes.rs:12:9 + --> tests/ui/endian_bytes.rs:14:9 | LL | 2i32.to_ne_bytes(); | ^^^^^^^^^^^^^^^^^^ @@ -73,7 +73,7 @@ LL | fn host() { fn_body!(); } = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the `u64::to_ne_bytes` method - --> tests/ui/endian_bytes.rs:13:9 + --> tests/ui/endian_bytes.rs:15:9 | LL | 2u64.to_ne_bytes(); | ^^^^^^^^^^^^^^^^^^ @@ -85,7 +85,7 @@ LL | fn host() { fn_body!(); } = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the `i64::to_ne_bytes` method - --> tests/ui/endian_bytes.rs:14:9 + --> tests/ui/endian_bytes.rs:16:9 | LL | 2i64.to_ne_bytes(); | ^^^^^^^^^^^^^^^^^^ @@ -97,7 +97,7 @@ LL | fn host() { fn_body!(); } = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the `u128::to_ne_bytes` method - --> tests/ui/endian_bytes.rs:15:9 + --> tests/ui/endian_bytes.rs:17:9 | LL | 2u128.to_ne_bytes(); | ^^^^^^^^^^^^^^^^^^^ @@ -109,7 +109,7 @@ LL | fn host() { fn_body!(); } = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the `i128::to_ne_bytes` method - --> tests/ui/endian_bytes.rs:16:9 + --> tests/ui/endian_bytes.rs:18:9 | LL | 2i128.to_ne_bytes(); | ^^^^^^^^^^^^^^^^^^^ @@ -121,7 +121,7 @@ LL | fn host() { fn_body!(); } = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the `f32::to_ne_bytes` method - --> tests/ui/endian_bytes.rs:17:9 + --> tests/ui/endian_bytes.rs:19:9 | LL | 2.0f32.to_ne_bytes(); | ^^^^^^^^^^^^^^^^^^^^ @@ -133,7 +133,7 @@ LL | fn host() { fn_body!(); } = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the `f64::to_ne_bytes` method - --> tests/ui/endian_bytes.rs:18:9 + --> tests/ui/endian_bytes.rs:20:9 | LL | 2.0f64.to_ne_bytes(); | ^^^^^^^^^^^^^^^^^^^^ @@ -145,7 +145,7 @@ LL | fn host() { fn_body!(); } = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the `usize::to_ne_bytes` method - --> tests/ui/endian_bytes.rs:19:9 + --> tests/ui/endian_bytes.rs:21:9 | LL | 2usize.to_ne_bytes(); | ^^^^^^^^^^^^^^^^^^^^ @@ -157,7 +157,7 @@ LL | fn host() { fn_body!(); } = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the `isize::to_ne_bytes` method - --> tests/ui/endian_bytes.rs:20:9 + --> tests/ui/endian_bytes.rs:22:9 | LL | 2isize.to_ne_bytes(); | ^^^^^^^^^^^^^^^^^^^^ @@ -169,7 +169,7 @@ LL | fn host() { fn_body!(); } = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the function `u8::from_ne_bytes` - --> tests/ui/endian_bytes.rs:21:9 + --> tests/ui/endian_bytes.rs:23:9 | LL | u8::from_ne_bytes(todo!()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -181,7 +181,7 @@ LL | fn host() { fn_body!(); } = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the function `i8::from_ne_bytes` - --> tests/ui/endian_bytes.rs:22:9 + --> tests/ui/endian_bytes.rs:24:9 | LL | i8::from_ne_bytes(todo!()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -193,7 +193,7 @@ LL | fn host() { fn_body!(); } = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the function `u16::from_ne_bytes` - --> tests/ui/endian_bytes.rs:23:9 + --> tests/ui/endian_bytes.rs:25:9 | LL | u16::from_ne_bytes(todo!()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -205,7 +205,7 @@ LL | fn host() { fn_body!(); } = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the function `i16::from_ne_bytes` - --> tests/ui/endian_bytes.rs:24:9 + --> tests/ui/endian_bytes.rs:26:9 | LL | i16::from_ne_bytes(todo!()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -217,7 +217,7 @@ LL | fn host() { fn_body!(); } = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the function `u32::from_ne_bytes` - --> tests/ui/endian_bytes.rs:25:9 + --> tests/ui/endian_bytes.rs:27:9 | LL | u32::from_ne_bytes(todo!()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -229,7 +229,7 @@ LL | fn host() { fn_body!(); } = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the function `i32::from_ne_bytes` - --> tests/ui/endian_bytes.rs:26:9 + --> tests/ui/endian_bytes.rs:28:9 | LL | i32::from_ne_bytes(todo!()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -241,7 +241,7 @@ LL | fn host() { fn_body!(); } = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the function `u64::from_ne_bytes` - --> tests/ui/endian_bytes.rs:27:9 + --> tests/ui/endian_bytes.rs:29:9 | LL | u64::from_ne_bytes(todo!()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -253,7 +253,7 @@ LL | fn host() { fn_body!(); } = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the function `i64::from_ne_bytes` - --> tests/ui/endian_bytes.rs:28:9 + --> tests/ui/endian_bytes.rs:30:9 | LL | i64::from_ne_bytes(todo!()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -265,7 +265,7 @@ LL | fn host() { fn_body!(); } = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the function `u128::from_ne_bytes` - --> tests/ui/endian_bytes.rs:29:9 + --> tests/ui/endian_bytes.rs:31:9 | LL | u128::from_ne_bytes(todo!()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -277,7 +277,7 @@ LL | fn host() { fn_body!(); } = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the function `i128::from_ne_bytes` - --> tests/ui/endian_bytes.rs:30:9 + --> tests/ui/endian_bytes.rs:32:9 | LL | i128::from_ne_bytes(todo!()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -289,7 +289,7 @@ LL | fn host() { fn_body!(); } = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the function `usize::from_ne_bytes` - --> tests/ui/endian_bytes.rs:31:9 + --> tests/ui/endian_bytes.rs:33:9 | LL | usize::from_ne_bytes(todo!()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -301,7 +301,7 @@ LL | fn host() { fn_body!(); } = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the function `isize::from_ne_bytes` - --> tests/ui/endian_bytes.rs:32:9 + --> tests/ui/endian_bytes.rs:34:9 | LL | isize::from_ne_bytes(todo!()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -313,7 +313,7 @@ LL | fn host() { fn_body!(); } = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the function `f32::from_ne_bytes` - --> tests/ui/endian_bytes.rs:33:9 + --> tests/ui/endian_bytes.rs:35:9 | LL | f32::from_ne_bytes(todo!()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -325,7 +325,7 @@ LL | fn host() { fn_body!(); } = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the function `f64::from_ne_bytes` - --> tests/ui/endian_bytes.rs:34:9 + --> tests/ui/endian_bytes.rs:36:9 | LL | f64::from_ne_bytes(todo!()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -337,7 +337,7 @@ LL | fn host() { fn_body!(); } = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the `u8::to_le_bytes` method - --> tests/ui/endian_bytes.rs:36:9 + --> tests/ui/endian_bytes.rs:38:9 | LL | 2u8.to_le_bytes(); | ^^^^^^^^^^^^^^^^^ @@ -351,7 +351,7 @@ LL | fn little() { fn_body!(); } = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the `i8::to_le_bytes` method - --> tests/ui/endian_bytes.rs:37:9 + --> tests/ui/endian_bytes.rs:39:9 | LL | 2i8.to_le_bytes(); | ^^^^^^^^^^^^^^^^^ @@ -363,7 +363,7 @@ LL | fn little() { fn_body!(); } = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the `u16::to_le_bytes` method - --> tests/ui/endian_bytes.rs:38:9 + --> tests/ui/endian_bytes.rs:40:9 | LL | 2u16.to_le_bytes(); | ^^^^^^^^^^^^^^^^^^ @@ -375,7 +375,7 @@ LL | fn little() { fn_body!(); } = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the `i16::to_le_bytes` method - --> tests/ui/endian_bytes.rs:39:9 + --> tests/ui/endian_bytes.rs:41:9 | LL | 2i16.to_le_bytes(); | ^^^^^^^^^^^^^^^^^^ @@ -387,7 +387,7 @@ LL | fn little() { fn_body!(); } = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the `u32::to_le_bytes` method - --> tests/ui/endian_bytes.rs:40:9 + --> tests/ui/endian_bytes.rs:42:9 | LL | 2u32.to_le_bytes(); | ^^^^^^^^^^^^^^^^^^ @@ -399,7 +399,7 @@ LL | fn little() { fn_body!(); } = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the `i32::to_le_bytes` method - --> tests/ui/endian_bytes.rs:41:9 + --> tests/ui/endian_bytes.rs:43:9 | LL | 2i32.to_le_bytes(); | ^^^^^^^^^^^^^^^^^^ @@ -411,7 +411,7 @@ LL | fn little() { fn_body!(); } = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the `u64::to_le_bytes` method - --> tests/ui/endian_bytes.rs:42:9 + --> tests/ui/endian_bytes.rs:44:9 | LL | 2u64.to_le_bytes(); | ^^^^^^^^^^^^^^^^^^ @@ -423,7 +423,7 @@ LL | fn little() { fn_body!(); } = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the `i64::to_le_bytes` method - --> tests/ui/endian_bytes.rs:43:9 + --> tests/ui/endian_bytes.rs:45:9 | LL | 2i64.to_le_bytes(); | ^^^^^^^^^^^^^^^^^^ @@ -435,7 +435,7 @@ LL | fn little() { fn_body!(); } = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the `u128::to_le_bytes` method - --> tests/ui/endian_bytes.rs:44:9 + --> tests/ui/endian_bytes.rs:46:9 | LL | 2u128.to_le_bytes(); | ^^^^^^^^^^^^^^^^^^^ @@ -447,7 +447,7 @@ LL | fn little() { fn_body!(); } = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the `i128::to_le_bytes` method - --> tests/ui/endian_bytes.rs:45:9 + --> tests/ui/endian_bytes.rs:47:9 | LL | 2i128.to_le_bytes(); | ^^^^^^^^^^^^^^^^^^^ @@ -459,7 +459,7 @@ LL | fn little() { fn_body!(); } = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the `f32::to_le_bytes` method - --> tests/ui/endian_bytes.rs:46:9 + --> tests/ui/endian_bytes.rs:48:9 | LL | 2.0f32.to_le_bytes(); | ^^^^^^^^^^^^^^^^^^^^ @@ -471,7 +471,7 @@ LL | fn little() { fn_body!(); } = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the `f64::to_le_bytes` method - --> tests/ui/endian_bytes.rs:47:9 + --> tests/ui/endian_bytes.rs:49:9 | LL | 2.0f64.to_le_bytes(); | ^^^^^^^^^^^^^^^^^^^^ @@ -483,7 +483,7 @@ LL | fn little() { fn_body!(); } = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the `usize::to_le_bytes` method - --> tests/ui/endian_bytes.rs:48:9 + --> tests/ui/endian_bytes.rs:50:9 | LL | 2usize.to_le_bytes(); | ^^^^^^^^^^^^^^^^^^^^ @@ -495,7 +495,7 @@ LL | fn little() { fn_body!(); } = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the `isize::to_le_bytes` method - --> tests/ui/endian_bytes.rs:49:9 + --> tests/ui/endian_bytes.rs:51:9 | LL | 2isize.to_le_bytes(); | ^^^^^^^^^^^^^^^^^^^^ @@ -507,7 +507,7 @@ LL | fn little() { fn_body!(); } = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the function `u8::from_le_bytes` - --> tests/ui/endian_bytes.rs:50:9 + --> tests/ui/endian_bytes.rs:52:9 | LL | u8::from_le_bytes(todo!()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -519,7 +519,7 @@ LL | fn little() { fn_body!(); } = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the function `i8::from_le_bytes` - --> tests/ui/endian_bytes.rs:51:9 + --> tests/ui/endian_bytes.rs:53:9 | LL | i8::from_le_bytes(todo!()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -531,7 +531,7 @@ LL | fn little() { fn_body!(); } = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the function `u16::from_le_bytes` - --> tests/ui/endian_bytes.rs:52:9 + --> tests/ui/endian_bytes.rs:54:9 | LL | u16::from_le_bytes(todo!()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -543,7 +543,7 @@ LL | fn little() { fn_body!(); } = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the function `i16::from_le_bytes` - --> tests/ui/endian_bytes.rs:53:9 + --> tests/ui/endian_bytes.rs:55:9 | LL | i16::from_le_bytes(todo!()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -555,7 +555,7 @@ LL | fn little() { fn_body!(); } = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the function `u32::from_le_bytes` - --> tests/ui/endian_bytes.rs:54:9 + --> tests/ui/endian_bytes.rs:56:9 | LL | u32::from_le_bytes(todo!()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -567,7 +567,7 @@ LL | fn little() { fn_body!(); } = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the function `i32::from_le_bytes` - --> tests/ui/endian_bytes.rs:55:9 + --> tests/ui/endian_bytes.rs:57:9 | LL | i32::from_le_bytes(todo!()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -579,7 +579,7 @@ LL | fn little() { fn_body!(); } = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the function `u64::from_le_bytes` - --> tests/ui/endian_bytes.rs:56:9 + --> tests/ui/endian_bytes.rs:58:9 | LL | u64::from_le_bytes(todo!()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -591,7 +591,7 @@ LL | fn little() { fn_body!(); } = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the function `i64::from_le_bytes` - --> tests/ui/endian_bytes.rs:57:9 + --> tests/ui/endian_bytes.rs:59:9 | LL | i64::from_le_bytes(todo!()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -603,7 +603,7 @@ LL | fn little() { fn_body!(); } = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the function `u128::from_le_bytes` - --> tests/ui/endian_bytes.rs:58:9 + --> tests/ui/endian_bytes.rs:60:9 | LL | u128::from_le_bytes(todo!()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -615,7 +615,7 @@ LL | fn little() { fn_body!(); } = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the function `i128::from_le_bytes` - --> tests/ui/endian_bytes.rs:59:9 + --> tests/ui/endian_bytes.rs:61:9 | LL | i128::from_le_bytes(todo!()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -627,7 +627,7 @@ LL | fn little() { fn_body!(); } = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the function `usize::from_le_bytes` - --> tests/ui/endian_bytes.rs:60:9 + --> tests/ui/endian_bytes.rs:62:9 | LL | usize::from_le_bytes(todo!()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -639,7 +639,7 @@ LL | fn little() { fn_body!(); } = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the function `isize::from_le_bytes` - --> tests/ui/endian_bytes.rs:61:9 + --> tests/ui/endian_bytes.rs:63:9 | LL | isize::from_le_bytes(todo!()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -651,7 +651,7 @@ LL | fn little() { fn_body!(); } = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the function `f32::from_le_bytes` - --> tests/ui/endian_bytes.rs:62:9 + --> tests/ui/endian_bytes.rs:64:9 | LL | f32::from_le_bytes(todo!()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -663,7 +663,7 @@ LL | fn little() { fn_body!(); } = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the function `f64::from_le_bytes` - --> tests/ui/endian_bytes.rs:63:9 + --> tests/ui/endian_bytes.rs:65:9 | LL | f64::from_le_bytes(todo!()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -675,7 +675,7 @@ LL | fn little() { fn_body!(); } = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the `u8::to_ne_bytes` method - --> tests/ui/endian_bytes.rs:70:9 + --> tests/ui/endian_bytes.rs:72:9 | LL | 2u8.to_ne_bytes(); | ^^^^^^^^^^^^^^^^^ @@ -687,7 +687,7 @@ LL | fn host_encourage_little() { fn_body_smol!(); } = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the function `u8::from_ne_bytes` - --> tests/ui/endian_bytes.rs:71:9 + --> tests/ui/endian_bytes.rs:73:9 | LL | u8::from_ne_bytes(todo!()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -699,7 +699,7 @@ LL | fn host_encourage_little() { fn_body_smol!(); } = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the `u8::to_be_bytes` method - --> tests/ui/endian_bytes.rs:76:9 + --> tests/ui/endian_bytes.rs:78:9 | LL | 2u8.to_be_bytes(); | ^^^^^^^^^^^^^^^^^ @@ -713,7 +713,7 @@ LL | fn host_encourage_little() { fn_body_smol!(); } = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the function `u8::from_be_bytes` - --> tests/ui/endian_bytes.rs:77:9 + --> tests/ui/endian_bytes.rs:79:9 | LL | u8::from_be_bytes(todo!()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -725,7 +725,7 @@ LL | fn host_encourage_little() { fn_body_smol!(); } = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the `u8::to_ne_bytes` method - --> tests/ui/endian_bytes.rs:70:9 + --> tests/ui/endian_bytes.rs:72:9 | LL | 2u8.to_ne_bytes(); | ^^^^^^^^^^^^^^^^^ @@ -737,7 +737,7 @@ LL | fn host_encourage_big() { fn_body_smol!(); } = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the function `u8::from_ne_bytes` - --> tests/ui/endian_bytes.rs:71:9 + --> tests/ui/endian_bytes.rs:73:9 | LL | u8::from_ne_bytes(todo!()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -749,7 +749,7 @@ LL | fn host_encourage_big() { fn_body_smol!(); } = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the `u8::to_le_bytes` method - --> tests/ui/endian_bytes.rs:73:9 + --> tests/ui/endian_bytes.rs:75:9 | LL | 2u8.to_le_bytes(); | ^^^^^^^^^^^^^^^^^ @@ -761,7 +761,7 @@ LL | fn host_encourage_big() { fn_body_smol!(); } = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the function `u8::from_le_bytes` - --> tests/ui/endian_bytes.rs:74:9 + --> tests/ui/endian_bytes.rs:76:9 | LL | u8::from_le_bytes(todo!()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -773,7 +773,7 @@ LL | fn host_encourage_big() { fn_body_smol!(); } = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the `u8::to_ne_bytes` method - --> tests/ui/endian_bytes.rs:70:9 + --> tests/ui/endian_bytes.rs:72:9 | LL | 2u8.to_ne_bytes(); | ^^^^^^^^^^^^^^^^^ @@ -784,7 +784,7 @@ LL | fn no_help() { fn_body_smol!(); } = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the function `u8::from_ne_bytes` - --> tests/ui/endian_bytes.rs:71:9 + --> tests/ui/endian_bytes.rs:73:9 | LL | u8::from_ne_bytes(todo!()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -795,7 +795,7 @@ LL | fn no_help() { fn_body_smol!(); } = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the `u8::to_le_bytes` method - --> tests/ui/endian_bytes.rs:73:9 + --> tests/ui/endian_bytes.rs:75:9 | LL | 2u8.to_le_bytes(); | ^^^^^^^^^^^^^^^^^ @@ -806,7 +806,7 @@ LL | fn no_help() { fn_body_smol!(); } = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the function `u8::from_le_bytes` - --> tests/ui/endian_bytes.rs:74:9 + --> tests/ui/endian_bytes.rs:76:9 | LL | u8::from_le_bytes(todo!()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -817,7 +817,7 @@ LL | fn no_help() { fn_body_smol!(); } = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the `u8::to_be_bytes` method - --> tests/ui/endian_bytes.rs:76:9 + --> tests/ui/endian_bytes.rs:78:9 | LL | 2u8.to_be_bytes(); | ^^^^^^^^^^^^^^^^^ @@ -828,7 +828,7 @@ LL | fn no_help() { fn_body_smol!(); } = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the function `u8::from_be_bytes` - --> tests/ui/endian_bytes.rs:77:9 + --> tests/ui/endian_bytes.rs:79:9 | LL | u8::from_be_bytes(todo!()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -839,7 +839,7 @@ LL | fn no_help() { fn_body_smol!(); } = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the `u8::to_le_bytes` method - --> tests/ui/endian_bytes.rs:73:9 + --> tests/ui/endian_bytes.rs:75:9 | LL | 2u8.to_le_bytes(); | ^^^^^^^^^^^^^^^^^ @@ -851,7 +851,7 @@ LL | fn little_encourage_host() { fn_body_smol!(); } = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the function `u8::from_le_bytes` - --> tests/ui/endian_bytes.rs:74:9 + --> tests/ui/endian_bytes.rs:76:9 | LL | u8::from_le_bytes(todo!()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -863,7 +863,7 @@ LL | fn little_encourage_host() { fn_body_smol!(); } = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the `u8::to_be_bytes` method - --> tests/ui/endian_bytes.rs:76:9 + --> tests/ui/endian_bytes.rs:78:9 | LL | 2u8.to_be_bytes(); | ^^^^^^^^^^^^^^^^^ @@ -875,7 +875,7 @@ LL | fn little_encourage_host() { fn_body_smol!(); } = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the function `u8::from_be_bytes` - --> tests/ui/endian_bytes.rs:77:9 + --> tests/ui/endian_bytes.rs:79:9 | LL | u8::from_be_bytes(todo!()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -887,7 +887,7 @@ LL | fn little_encourage_host() { fn_body_smol!(); } = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the `u8::to_ne_bytes` method - --> tests/ui/endian_bytes.rs:70:9 + --> tests/ui/endian_bytes.rs:72:9 | LL | 2u8.to_ne_bytes(); | ^^^^^^^^^^^^^^^^^ @@ -899,7 +899,7 @@ LL | fn little_encourage_big() { fn_body_smol!(); } = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the function `u8::from_ne_bytes` - --> tests/ui/endian_bytes.rs:71:9 + --> tests/ui/endian_bytes.rs:73:9 | LL | u8::from_ne_bytes(todo!()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -911,7 +911,7 @@ LL | fn little_encourage_big() { fn_body_smol!(); } = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the `u8::to_le_bytes` method - --> tests/ui/endian_bytes.rs:73:9 + --> tests/ui/endian_bytes.rs:75:9 | LL | 2u8.to_le_bytes(); | ^^^^^^^^^^^^^^^^^ @@ -923,7 +923,7 @@ LL | fn little_encourage_big() { fn_body_smol!(); } = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the function `u8::from_le_bytes` - --> tests/ui/endian_bytes.rs:74:9 + --> tests/ui/endian_bytes.rs:76:9 | LL | u8::from_le_bytes(todo!()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -935,7 +935,7 @@ LL | fn little_encourage_big() { fn_body_smol!(); } = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the `u8::to_le_bytes` method - --> tests/ui/endian_bytes.rs:73:9 + --> tests/ui/endian_bytes.rs:75:9 | LL | 2u8.to_le_bytes(); | ^^^^^^^^^^^^^^^^^ @@ -947,7 +947,7 @@ LL | fn big_encourage_host() { fn_body_smol!(); } = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the function `u8::from_le_bytes` - --> tests/ui/endian_bytes.rs:74:9 + --> tests/ui/endian_bytes.rs:76:9 | LL | u8::from_le_bytes(todo!()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -959,7 +959,7 @@ LL | fn big_encourage_host() { fn_body_smol!(); } = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the `u8::to_be_bytes` method - --> tests/ui/endian_bytes.rs:76:9 + --> tests/ui/endian_bytes.rs:78:9 | LL | 2u8.to_be_bytes(); | ^^^^^^^^^^^^^^^^^ @@ -971,7 +971,7 @@ LL | fn big_encourage_host() { fn_body_smol!(); } = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the function `u8::from_be_bytes` - --> tests/ui/endian_bytes.rs:77:9 + --> tests/ui/endian_bytes.rs:79:9 | LL | u8::from_be_bytes(todo!()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -983,7 +983,7 @@ LL | fn big_encourage_host() { fn_body_smol!(); } = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the `u8::to_ne_bytes` method - --> tests/ui/endian_bytes.rs:70:9 + --> tests/ui/endian_bytes.rs:72:9 | LL | 2u8.to_ne_bytes(); | ^^^^^^^^^^^^^^^^^ @@ -995,7 +995,7 @@ LL | fn big_encourage_little() { fn_body_smol!(); } = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the function `u8::from_ne_bytes` - --> tests/ui/endian_bytes.rs:71:9 + --> tests/ui/endian_bytes.rs:73:9 | LL | u8::from_ne_bytes(todo!()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -1007,7 +1007,7 @@ LL | fn big_encourage_little() { fn_body_smol!(); } = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the `u8::to_be_bytes` method - --> tests/ui/endian_bytes.rs:76:9 + --> tests/ui/endian_bytes.rs:78:9 | LL | 2u8.to_be_bytes(); | ^^^^^^^^^^^^^^^^^ @@ -1019,7 +1019,7 @@ LL | fn big_encourage_little() { fn_body_smol!(); } = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info) error: usage of the function `u8::from_be_bytes` - --> tests/ui/endian_bytes.rs:77:9 + --> tests/ui/endian_bytes.rs:79:9 | LL | u8::from_be_bytes(todo!()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/float_cmp.rs b/tests/ui/float_cmp.rs index 5057c64373291..1923ad7c677e0 100644 --- a/tests/ui/float_cmp.rs +++ b/tests/ui/float_cmp.rs @@ -1,3 +1,5 @@ +// FIXME(f16_f128): const casting is not yet supported for these types. Add when available. + #![warn(clippy::float_cmp)] #![allow( unused, diff --git a/tests/ui/float_cmp.stderr b/tests/ui/float_cmp.stderr index 49b65184f7311..c8a0bde6e63a8 100644 --- a/tests/ui/float_cmp.stderr +++ b/tests/ui/float_cmp.stderr @@ -1,5 +1,5 @@ error: strict comparison of `f32` or `f64` - --> tests/ui/float_cmp.rs:70:5 + --> tests/ui/float_cmp.rs:72:5 | LL | ONE as f64 != 2.0; | ^^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(ONE as f64 - 2.0).abs() > error_margin` @@ -9,7 +9,7 @@ LL | ONE as f64 != 2.0; = help: to override `-D warnings` add `#[allow(clippy::float_cmp)]` error: strict comparison of `f32` or `f64` - --> tests/ui/float_cmp.rs:77:5 + --> tests/ui/float_cmp.rs:79:5 | LL | x == 1.0; | ^^^^^^^^ help: consider comparing them within some margin of error: `(x - 1.0).abs() < error_margin` @@ -17,7 +17,7 @@ LL | x == 1.0; = note: `f32::EPSILON` and `f64::EPSILON` are available for the `error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui/float_cmp.rs:82:5 + --> tests/ui/float_cmp.rs:84:5 | LL | twice(x) != twice(ONE as f64); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(twice(x) - twice(ONE as f64)).abs() > error_margin` @@ -25,7 +25,7 @@ LL | twice(x) != twice(ONE as f64); = note: `f32::EPSILON` and `f64::EPSILON` are available for the `error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui/float_cmp.rs:104:5 + --> tests/ui/float_cmp.rs:106:5 | LL | NON_ZERO_ARRAY[i] == NON_ZERO_ARRAY[j]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(NON_ZERO_ARRAY[i] - NON_ZERO_ARRAY[j]).abs() < error_margin` @@ -33,7 +33,7 @@ LL | NON_ZERO_ARRAY[i] == NON_ZERO_ARRAY[j]; = note: `f32::EPSILON` and `f64::EPSILON` are available for the `error_margin` error: strict comparison of `f32` or `f64` arrays - --> tests/ui/float_cmp.rs:111:5 + --> tests/ui/float_cmp.rs:113:5 | LL | a1 == a2; | ^^^^^^^^ @@ -41,7 +41,7 @@ LL | a1 == a2; = note: `f32::EPSILON` and `f64::EPSILON` are available for the `error_margin` error: strict comparison of `f32` or `f64` - --> tests/ui/float_cmp.rs:114:5 + --> tests/ui/float_cmp.rs:116:5 | LL | a1[0] == a2[0]; | ^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(a1[0] - a2[0]).abs() < error_margin` diff --git a/tests/ui/float_equality_without_abs.rs b/tests/ui/float_equality_without_abs.rs index 6363472d8990a..2b67c8bec1039 100644 --- a/tests/ui/float_equality_without_abs.rs +++ b/tests/ui/float_equality_without_abs.rs @@ -1,5 +1,8 @@ #![warn(clippy::float_equality_without_abs)] //@no-rustfix + +// FIXME(f16_f128): add tests for these types when abs is available + pub fn is_roughly_equal(a: f32, b: f32) -> bool { (a - b) < f32::EPSILON //~^ ERROR: float equality check without `.abs()` diff --git a/tests/ui/float_equality_without_abs.stderr b/tests/ui/float_equality_without_abs.stderr index 0124dd983a391..cdaaf0cdbcf7e 100644 --- a/tests/ui/float_equality_without_abs.stderr +++ b/tests/ui/float_equality_without_abs.stderr @@ -1,5 +1,5 @@ error: float equality check without `.abs()` - --> tests/ui/float_equality_without_abs.rs:4:5 + --> tests/ui/float_equality_without_abs.rs:7:5 | LL | (a - b) < f32::EPSILON | -------^^^^^^^^^^^^^^^ @@ -10,7 +10,7 @@ LL | (a - b) < f32::EPSILON = help: to override `-D warnings` add `#[allow(clippy::float_equality_without_abs)]` error: float equality check without `.abs()` - --> tests/ui/float_equality_without_abs.rs:15:13 + --> tests/ui/float_equality_without_abs.rs:18:13 | LL | let _ = (a - b) < f32::EPSILON; | -------^^^^^^^^^^^^^^^ @@ -18,7 +18,7 @@ LL | let _ = (a - b) < f32::EPSILON; | help: add `.abs()`: `(a - b).abs()` error: float equality check without `.abs()` - --> tests/ui/float_equality_without_abs.rs:17:13 + --> tests/ui/float_equality_without_abs.rs:20:13 | LL | let _ = a - b < f32::EPSILON; | -----^^^^^^^^^^^^^^^ @@ -26,7 +26,7 @@ LL | let _ = a - b < f32::EPSILON; | help: add `.abs()`: `(a - b).abs()` error: float equality check without `.abs()` - --> tests/ui/float_equality_without_abs.rs:19:13 + --> tests/ui/float_equality_without_abs.rs:22:13 | LL | let _ = a - b.abs() < f32::EPSILON; | -----------^^^^^^^^^^^^^^^ @@ -34,7 +34,7 @@ LL | let _ = a - b.abs() < f32::EPSILON; | help: add `.abs()`: `(a - b.abs()).abs()` error: float equality check without `.abs()` - --> tests/ui/float_equality_without_abs.rs:21:13 + --> tests/ui/float_equality_without_abs.rs:24:13 | LL | let _ = (a as f64 - b as f64) < f64::EPSILON; | ---------------------^^^^^^^^^^^^^^^ @@ -42,7 +42,7 @@ LL | let _ = (a as f64 - b as f64) < f64::EPSILON; | help: add `.abs()`: `(a as f64 - b as f64).abs()` error: float equality check without `.abs()` - --> tests/ui/float_equality_without_abs.rs:23:13 + --> tests/ui/float_equality_without_abs.rs:26:13 | LL | let _ = 1.0 - 2.0 < f32::EPSILON; | ---------^^^^^^^^^^^^^^^ @@ -50,7 +50,7 @@ LL | let _ = 1.0 - 2.0 < f32::EPSILON; | help: add `.abs()`: `(1.0 - 2.0).abs()` error: float equality check without `.abs()` - --> tests/ui/float_equality_without_abs.rs:26:13 + --> tests/ui/float_equality_without_abs.rs:29:13 | LL | let _ = f32::EPSILON > (a - b); | ^^^^^^^^^^^^^^^------- @@ -58,7 +58,7 @@ LL | let _ = f32::EPSILON > (a - b); | help: add `.abs()`: `(a - b).abs()` error: float equality check without `.abs()` - --> tests/ui/float_equality_without_abs.rs:28:13 + --> tests/ui/float_equality_without_abs.rs:31:13 | LL | let _ = f32::EPSILON > a - b; | ^^^^^^^^^^^^^^^----- @@ -66,7 +66,7 @@ LL | let _ = f32::EPSILON > a - b; | help: add `.abs()`: `(a - b).abs()` error: float equality check without `.abs()` - --> tests/ui/float_equality_without_abs.rs:30:13 + --> tests/ui/float_equality_without_abs.rs:33:13 | LL | let _ = f32::EPSILON > a - b.abs(); | ^^^^^^^^^^^^^^^----------- @@ -74,7 +74,7 @@ LL | let _ = f32::EPSILON > a - b.abs(); | help: add `.abs()`: `(a - b.abs()).abs()` error: float equality check without `.abs()` - --> tests/ui/float_equality_without_abs.rs:32:13 + --> tests/ui/float_equality_without_abs.rs:35:13 | LL | let _ = f64::EPSILON > (a as f64 - b as f64); | ^^^^^^^^^^^^^^^--------------------- @@ -82,7 +82,7 @@ LL | let _ = f64::EPSILON > (a as f64 - b as f64); | help: add `.abs()`: `(a as f64 - b as f64).abs()` error: float equality check without `.abs()` - --> tests/ui/float_equality_without_abs.rs:34:13 + --> tests/ui/float_equality_without_abs.rs:37:13 | LL | let _ = f32::EPSILON > 1.0 - 2.0; | ^^^^^^^^^^^^^^^--------- diff --git a/tests/ui/floating_point_arithmetic_nostd.rs b/tests/ui/floating_point_arithmetic_nostd.rs index a42c6383ccea2..47c113d61c041 100644 --- a/tests/ui/floating_point_arithmetic_nostd.rs +++ b/tests/ui/floating_point_arithmetic_nostd.rs @@ -3,8 +3,8 @@ #![warn(clippy::suboptimal_flops)] #![no_std] -// The following should not lint, as the suggested methods {f32,f64}.mul_add() -// and {f32,f64}::abs() are not available in no_std +// The following should not lint, as the suggested methods `{f16,f32,f64,f128}.mul_add()` +// and ``{f16,f32,f64,f128}::abs()` are not available in no_std pub fn mul_add() { let a: f64 = 1234.567; diff --git a/tests/ui/floating_point_exp.fixed b/tests/ui/floating_point_exp.fixed index 15072bb1ee9a5..fbd91cbc9d703 100644 --- a/tests/ui/floating_point_exp.fixed +++ b/tests/ui/floating_point_exp.fixed @@ -1,3 +1,5 @@ +// FIXME(f16_f128): add tests when exp is available + #![warn(clippy::imprecise_flops)] #![allow(clippy::unnecessary_cast)] diff --git a/tests/ui/floating_point_exp.rs b/tests/ui/floating_point_exp.rs index 7d8b17946d0a5..340bacaf56b5e 100644 --- a/tests/ui/floating_point_exp.rs +++ b/tests/ui/floating_point_exp.rs @@ -1,3 +1,5 @@ +// FIXME(f16_f128): add tests when exp is available + #![warn(clippy::imprecise_flops)] #![allow(clippy::unnecessary_cast)] diff --git a/tests/ui/floating_point_exp.stderr b/tests/ui/floating_point_exp.stderr index a19edf87e2448..6ce67254abc96 100644 --- a/tests/ui/floating_point_exp.stderr +++ b/tests/ui/floating_point_exp.stderr @@ -1,5 +1,5 @@ error: (e.pow(x) - 1) can be computed more accurately - --> tests/ui/floating_point_exp.rs:6:13 + --> tests/ui/floating_point_exp.rs:8:13 | LL | let _ = x.exp() - 1.0; | ^^^^^^^^^^^^^ help: consider using: `x.exp_m1()` @@ -8,25 +8,25 @@ LL | let _ = x.exp() - 1.0; = help: to override `-D warnings` add `#[allow(clippy::imprecise_flops)]` error: (e.pow(x) - 1) can be computed more accurately - --> tests/ui/floating_point_exp.rs:7:13 + --> tests/ui/floating_point_exp.rs:9:13 | LL | let _ = x.exp() - 1.0 + 2.0; | ^^^^^^^^^^^^^ help: consider using: `x.exp_m1()` error: (e.pow(x) - 1) can be computed more accurately - --> tests/ui/floating_point_exp.rs:8:13 + --> tests/ui/floating_point_exp.rs:10:13 | LL | let _ = (x as f32).exp() - 1.0 + 2.0; | ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(x as f32).exp_m1()` error: (e.pow(x) - 1) can be computed more accurately - --> tests/ui/floating_point_exp.rs:14:13 + --> tests/ui/floating_point_exp.rs:16:13 | LL | let _ = x.exp() - 1.0; | ^^^^^^^^^^^^^ help: consider using: `x.exp_m1()` error: (e.pow(x) - 1) can be computed more accurately - --> tests/ui/floating_point_exp.rs:15:13 + --> tests/ui/floating_point_exp.rs:17:13 | LL | let _ = x.exp() - 1.0 + 2.0; | ^^^^^^^^^^^^^ help: consider using: `x.exp_m1()` diff --git a/tests/ui/floating_point_log.fixed b/tests/ui/floating_point_log.fixed index 15cc47eef0dd0..75e9c40a5218c 100644 --- a/tests/ui/floating_point_log.fixed +++ b/tests/ui/floating_point_log.fixed @@ -1,6 +1,8 @@ #![allow(dead_code, clippy::double_parens, clippy::unnecessary_cast)] #![warn(clippy::suboptimal_flops, clippy::imprecise_flops)] +// FIXME(f16_f128): add tests for these types once math functions are available + const TWO: f32 = 2.0; const E: f32 = std::f32::consts::E; diff --git a/tests/ui/floating_point_log.rs b/tests/ui/floating_point_log.rs index 1241af8285932..d68369a386184 100644 --- a/tests/ui/floating_point_log.rs +++ b/tests/ui/floating_point_log.rs @@ -1,6 +1,8 @@ #![allow(dead_code, clippy::double_parens, clippy::unnecessary_cast)] #![warn(clippy::suboptimal_flops, clippy::imprecise_flops)] +// FIXME(f16_f128): add tests for these types once math functions are available + const TWO: f32 = 2.0; const E: f32 = std::f32::consts::E; diff --git a/tests/ui/floating_point_log.stderr b/tests/ui/floating_point_log.stderr index 3a449a98eadd5..19c28de8e39a1 100644 --- a/tests/ui/floating_point_log.stderr +++ b/tests/ui/floating_point_log.stderr @@ -1,5 +1,5 @@ error: logarithm for bases 2, 10 and e can be computed more accurately - --> tests/ui/floating_point_log.rs:9:13 + --> tests/ui/floating_point_log.rs:11:13 | LL | let _ = x.log(2f32); | ^^^^^^^^^^^ help: consider using: `x.log2()` @@ -8,55 +8,55 @@ LL | let _ = x.log(2f32); = help: to override `-D warnings` add `#[allow(clippy::suboptimal_flops)]` error: logarithm for bases 2, 10 and e can be computed more accurately - --> tests/ui/floating_point_log.rs:10:13 + --> tests/ui/floating_point_log.rs:12:13 | LL | let _ = x.log(10f32); | ^^^^^^^^^^^^ help: consider using: `x.log10()` error: logarithm for bases 2, 10 and e can be computed more accurately - --> tests/ui/floating_point_log.rs:11:13 + --> tests/ui/floating_point_log.rs:13:13 | LL | let _ = x.log(std::f32::consts::E); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.ln()` error: logarithm for bases 2, 10 and e can be computed more accurately - --> tests/ui/floating_point_log.rs:12:13 + --> tests/ui/floating_point_log.rs:14:13 | LL | let _ = x.log(TWO); | ^^^^^^^^^^ help: consider using: `x.log2()` error: logarithm for bases 2, 10 and e can be computed more accurately - --> tests/ui/floating_point_log.rs:13:13 + --> tests/ui/floating_point_log.rs:15:13 | LL | let _ = x.log(E); | ^^^^^^^^ help: consider using: `x.ln()` error: logarithm for bases 2, 10 and e can be computed more accurately - --> tests/ui/floating_point_log.rs:14:13 + --> tests/ui/floating_point_log.rs:16:13 | LL | let _ = (x as f32).log(2f32); | ^^^^^^^^^^^^^^^^^^^^ help: consider using: `(x as f32).log2()` error: logarithm for bases 2, 10 and e can be computed more accurately - --> tests/ui/floating_point_log.rs:17:13 + --> tests/ui/floating_point_log.rs:19:13 | LL | let _ = x.log(2f64); | ^^^^^^^^^^^ help: consider using: `x.log2()` error: logarithm for bases 2, 10 and e can be computed more accurately - --> tests/ui/floating_point_log.rs:18:13 + --> tests/ui/floating_point_log.rs:20:13 | LL | let _ = x.log(10f64); | ^^^^^^^^^^^^ help: consider using: `x.log10()` error: logarithm for bases 2, 10 and e can be computed more accurately - --> tests/ui/floating_point_log.rs:19:13 + --> tests/ui/floating_point_log.rs:21:13 | LL | let _ = x.log(std::f64::consts::E); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.ln()` error: ln(1 + x) can be computed more accurately - --> tests/ui/floating_point_log.rs:24:13 + --> tests/ui/floating_point_log.rs:26:13 | LL | let _ = (1f32 + 2.).ln(); | ^^^^^^^^^^^^^^^^ help: consider using: `2.0f32.ln_1p()` @@ -65,115 +65,115 @@ LL | let _ = (1f32 + 2.).ln(); = help: to override `-D warnings` add `#[allow(clippy::imprecise_flops)]` error: ln(1 + x) can be computed more accurately - --> tests/ui/floating_point_log.rs:25:13 + --> tests/ui/floating_point_log.rs:27:13 | LL | let _ = (1f32 + 2.0).ln(); | ^^^^^^^^^^^^^^^^^ help: consider using: `2.0f32.ln_1p()` error: ln(1 + x) can be computed more accurately - --> tests/ui/floating_point_log.rs:26:13 + --> tests/ui/floating_point_log.rs:28:13 | LL | let _ = (1.0 + x).ln(); | ^^^^^^^^^^^^^^ help: consider using: `x.ln_1p()` error: ln(1 + x) can be computed more accurately - --> tests/ui/floating_point_log.rs:27:13 + --> tests/ui/floating_point_log.rs:29:13 | LL | let _ = (1.0 + x / 2.0).ln(); | ^^^^^^^^^^^^^^^^^^^^ help: consider using: `(x / 2.0).ln_1p()` error: ln(1 + x) can be computed more accurately - --> tests/ui/floating_point_log.rs:28:13 + --> tests/ui/floating_point_log.rs:30:13 | LL | let _ = (1.0 + x.powi(3)).ln(); | ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.powi(3).ln_1p()` error: ln(1 + x) can be computed more accurately - --> tests/ui/floating_point_log.rs:29:13 + --> tests/ui/floating_point_log.rs:31:13 | LL | let _ = (1.0 + x.powi(3) / 2.0).ln(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(x.powi(3) / 2.0).ln_1p()` error: ln(1 + x) can be computed more accurately - --> tests/ui/floating_point_log.rs:30:13 + --> tests/ui/floating_point_log.rs:32:13 | LL | let _ = (1.0 + (std::f32::consts::E - 1.0)).ln(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(std::f32::consts::E - 1.0).ln_1p()` error: ln(1 + x) can be computed more accurately - --> tests/ui/floating_point_log.rs:31:13 + --> tests/ui/floating_point_log.rs:33:13 | LL | let _ = (x + 1.0).ln(); | ^^^^^^^^^^^^^^ help: consider using: `x.ln_1p()` error: ln(1 + x) can be computed more accurately - --> tests/ui/floating_point_log.rs:32:13 + --> tests/ui/floating_point_log.rs:34:13 | LL | let _ = (x.powi(3) + 1.0).ln(); | ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.powi(3).ln_1p()` error: ln(1 + x) can be computed more accurately - --> tests/ui/floating_point_log.rs:33:13 + --> tests/ui/floating_point_log.rs:35:13 | LL | let _ = (x + 2.0 + 1.0).ln(); | ^^^^^^^^^^^^^^^^^^^^ help: consider using: `(x + 2.0).ln_1p()` error: ln(1 + x) can be computed more accurately - --> tests/ui/floating_point_log.rs:34:13 + --> tests/ui/floating_point_log.rs:36:13 | LL | let _ = (x / 2.0 + 1.0).ln(); | ^^^^^^^^^^^^^^^^^^^^ help: consider using: `(x / 2.0).ln_1p()` error: ln(1 + x) can be computed more accurately - --> tests/ui/floating_point_log.rs:42:13 + --> tests/ui/floating_point_log.rs:44:13 | LL | let _ = (1f64 + 2.).ln(); | ^^^^^^^^^^^^^^^^ help: consider using: `2.0f64.ln_1p()` error: ln(1 + x) can be computed more accurately - --> tests/ui/floating_point_log.rs:43:13 + --> tests/ui/floating_point_log.rs:45:13 | LL | let _ = (1f64 + 2.0).ln(); | ^^^^^^^^^^^^^^^^^ help: consider using: `2.0f64.ln_1p()` error: ln(1 + x) can be computed more accurately - --> tests/ui/floating_point_log.rs:44:13 + --> tests/ui/floating_point_log.rs:46:13 | LL | let _ = (1.0 + x).ln(); | ^^^^^^^^^^^^^^ help: consider using: `x.ln_1p()` error: ln(1 + x) can be computed more accurately - --> tests/ui/floating_point_log.rs:45:13 + --> tests/ui/floating_point_log.rs:47:13 | LL | let _ = (1.0 + x / 2.0).ln(); | ^^^^^^^^^^^^^^^^^^^^ help: consider using: `(x / 2.0).ln_1p()` error: ln(1 + x) can be computed more accurately - --> tests/ui/floating_point_log.rs:46:13 + --> tests/ui/floating_point_log.rs:48:13 | LL | let _ = (1.0 + x.powi(3)).ln(); | ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.powi(3).ln_1p()` error: ln(1 + x) can be computed more accurately - --> tests/ui/floating_point_log.rs:47:13 + --> tests/ui/floating_point_log.rs:49:13 | LL | let _ = (x + 1.0).ln(); | ^^^^^^^^^^^^^^ help: consider using: `x.ln_1p()` error: ln(1 + x) can be computed more accurately - --> tests/ui/floating_point_log.rs:48:13 + --> tests/ui/floating_point_log.rs:50:13 | LL | let _ = (x.powi(3) + 1.0).ln(); | ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.powi(3).ln_1p()` error: ln(1 + x) can be computed more accurately - --> tests/ui/floating_point_log.rs:49:13 + --> tests/ui/floating_point_log.rs:51:13 | LL | let _ = (x + 2.0 + 1.0).ln(); | ^^^^^^^^^^^^^^^^^^^^ help: consider using: `(x + 2.0).ln_1p()` error: ln(1 + x) can be computed more accurately - --> tests/ui/floating_point_log.rs:50:13 + --> tests/ui/floating_point_log.rs:52:13 | LL | let _ = (x / 2.0 + 1.0).ln(); | ^^^^^^^^^^^^^^^^^^^^ help: consider using: `(x / 2.0).ln_1p()` diff --git a/tests/ui/floating_point_powf.fixed b/tests/ui/floating_point_powf.fixed index c2884ca318c6a..a44938fdf692b 100644 --- a/tests/ui/floating_point_powf.fixed +++ b/tests/ui/floating_point_powf.fixed @@ -1,6 +1,8 @@ #![warn(clippy::suboptimal_flops, clippy::imprecise_flops)] #![allow(clippy::unnecessary_cast)] +// FIXME(f16_f128): add tests for these types when `powf` is available + fn main() { let x = 3f32; let _ = x.exp2(); diff --git a/tests/ui/floating_point_powf.rs b/tests/ui/floating_point_powf.rs index 37d58af055133..80f6c1791d7c2 100644 --- a/tests/ui/floating_point_powf.rs +++ b/tests/ui/floating_point_powf.rs @@ -1,6 +1,8 @@ #![warn(clippy::suboptimal_flops, clippy::imprecise_flops)] #![allow(clippy::unnecessary_cast)] +// FIXME(f16_f128): add tests for these types when `powf` is available + fn main() { let x = 3f32; let _ = 2f32.powf(x); diff --git a/tests/ui/floating_point_powf.stderr b/tests/ui/floating_point_powf.stderr index bd3fa771fe50e..671383401b554 100644 --- a/tests/ui/floating_point_powf.stderr +++ b/tests/ui/floating_point_powf.stderr @@ -1,5 +1,5 @@ error: exponent for bases 2 and e can be computed more accurately - --> tests/ui/floating_point_powf.rs:6:13 + --> tests/ui/floating_point_powf.rs:8:13 | LL | let _ = 2f32.powf(x); | ^^^^^^^^^^^^ help: consider using: `x.exp2()` @@ -8,43 +8,43 @@ LL | let _ = 2f32.powf(x); = help: to override `-D warnings` add `#[allow(clippy::suboptimal_flops)]` error: exponent for bases 2 and e can be computed more accurately - --> tests/ui/floating_point_powf.rs:7:13 + --> tests/ui/floating_point_powf.rs:9:13 | LL | let _ = 2f32.powf(3.1); | ^^^^^^^^^^^^^^ help: consider using: `3.1f32.exp2()` error: exponent for bases 2 and e can be computed more accurately - --> tests/ui/floating_point_powf.rs:8:13 + --> tests/ui/floating_point_powf.rs:10:13 | LL | let _ = 2f32.powf(-3.1); | ^^^^^^^^^^^^^^^ help: consider using: `(-3.1f32).exp2()` error: exponent for bases 2 and e can be computed more accurately - --> tests/ui/floating_point_powf.rs:9:13 + --> tests/ui/floating_point_powf.rs:11:13 | LL | let _ = std::f32::consts::E.powf(x); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.exp()` error: exponent for bases 2 and e can be computed more accurately - --> tests/ui/floating_point_powf.rs:10:13 + --> tests/ui/floating_point_powf.rs:12:13 | LL | let _ = std::f32::consts::E.powf(3.1); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `3.1f32.exp()` error: exponent for bases 2 and e can be computed more accurately - --> tests/ui/floating_point_powf.rs:11:13 + --> tests/ui/floating_point_powf.rs:13:13 | LL | let _ = std::f32::consts::E.powf(-3.1); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(-3.1f32).exp()` error: square-root of a number can be computed more efficiently and accurately - --> tests/ui/floating_point_powf.rs:12:13 + --> tests/ui/floating_point_powf.rs:14:13 | LL | let _ = x.powf(1.0 / 2.0); | ^^^^^^^^^^^^^^^^^ help: consider using: `x.sqrt()` error: cube-root of a number can be computed more accurately - --> tests/ui/floating_point_powf.rs:13:13 + --> tests/ui/floating_point_powf.rs:15:13 | LL | let _ = x.powf(1.0 / 3.0); | ^^^^^^^^^^^^^^^^^ help: consider using: `x.cbrt()` @@ -53,139 +53,139 @@ LL | let _ = x.powf(1.0 / 3.0); = help: to override `-D warnings` add `#[allow(clippy::imprecise_flops)]` error: cube-root of a number can be computed more accurately - --> tests/ui/floating_point_powf.rs:14:13 + --> tests/ui/floating_point_powf.rs:16:13 | LL | let _ = (x as f32).powf(1.0 / 3.0); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(x as f32).cbrt()` error: exponentiation with integer powers can be computed more efficiently - --> tests/ui/floating_point_powf.rs:15:13 + --> tests/ui/floating_point_powf.rs:17:13 | LL | let _ = x.powf(3.0); | ^^^^^^^^^^^ help: consider using: `x.powi(3)` error: exponentiation with integer powers can be computed more efficiently - --> tests/ui/floating_point_powf.rs:16:13 + --> tests/ui/floating_point_powf.rs:18:13 | LL | let _ = x.powf(-2.0); | ^^^^^^^^^^^^ help: consider using: `x.powi(-2)` error: exponentiation with integer powers can be computed more efficiently - --> tests/ui/floating_point_powf.rs:17:13 + --> tests/ui/floating_point_powf.rs:19:13 | LL | let _ = x.powf(16_777_215.0); | ^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.powi(16_777_215)` error: exponentiation with integer powers can be computed more efficiently - --> tests/ui/floating_point_powf.rs:18:13 + --> tests/ui/floating_point_powf.rs:20:13 | LL | let _ = x.powf(-16_777_215.0); | ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.powi(-16_777_215)` error: exponentiation with integer powers can be computed more efficiently - --> tests/ui/floating_point_powf.rs:19:13 + --> tests/ui/floating_point_powf.rs:21:13 | LL | let _ = (x as f32).powf(-16_777_215.0); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(x as f32).powi(-16_777_215)` error: exponentiation with integer powers can be computed more efficiently - --> tests/ui/floating_point_powf.rs:20:13 + --> tests/ui/floating_point_powf.rs:22:13 | LL | let _ = (x as f32).powf(3.0); | ^^^^^^^^^^^^^^^^^^^^ help: consider using: `(x as f32).powi(3)` error: cube-root of a number can be computed more accurately - --> tests/ui/floating_point_powf.rs:21:13 + --> tests/ui/floating_point_powf.rs:23:13 | LL | let _ = (1.5_f32 + 1.0).powf(1.0 / 3.0); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(1.5_f32 + 1.0).cbrt()` error: cube-root of a number can be computed more accurately - --> tests/ui/floating_point_powf.rs:22:13 + --> tests/ui/floating_point_powf.rs:24:13 | LL | let _ = 1.5_f64.powf(1.0 / 3.0); | ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `1.5_f64.cbrt()` error: square-root of a number can be computed more efficiently and accurately - --> tests/ui/floating_point_powf.rs:23:13 + --> tests/ui/floating_point_powf.rs:25:13 | LL | let _ = 1.5_f64.powf(1.0 / 2.0); | ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `1.5_f64.sqrt()` error: exponentiation with integer powers can be computed more efficiently - --> tests/ui/floating_point_powf.rs:24:13 + --> tests/ui/floating_point_powf.rs:26:13 | LL | let _ = 1.5_f64.powf(3.0); | ^^^^^^^^^^^^^^^^^ help: consider using: `1.5_f64.powi(3)` error: exponent for bases 2 and e can be computed more accurately - --> tests/ui/floating_point_powf.rs:33:13 + --> tests/ui/floating_point_powf.rs:35:13 | LL | let _ = 2f64.powf(x); | ^^^^^^^^^^^^ help: consider using: `x.exp2()` error: exponent for bases 2 and e can be computed more accurately - --> tests/ui/floating_point_powf.rs:34:13 + --> tests/ui/floating_point_powf.rs:36:13 | LL | let _ = 2f64.powf(3.1); | ^^^^^^^^^^^^^^ help: consider using: `3.1f64.exp2()` error: exponent for bases 2 and e can be computed more accurately - --> tests/ui/floating_point_powf.rs:35:13 + --> tests/ui/floating_point_powf.rs:37:13 | LL | let _ = 2f64.powf(-3.1); | ^^^^^^^^^^^^^^^ help: consider using: `(-3.1f64).exp2()` error: exponent for bases 2 and e can be computed more accurately - --> tests/ui/floating_point_powf.rs:36:13 + --> tests/ui/floating_point_powf.rs:38:13 | LL | let _ = std::f64::consts::E.powf(x); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.exp()` error: exponent for bases 2 and e can be computed more accurately - --> tests/ui/floating_point_powf.rs:37:13 + --> tests/ui/floating_point_powf.rs:39:13 | LL | let _ = std::f64::consts::E.powf(3.1); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `3.1f64.exp()` error: exponent for bases 2 and e can be computed more accurately - --> tests/ui/floating_point_powf.rs:38:13 + --> tests/ui/floating_point_powf.rs:40:13 | LL | let _ = std::f64::consts::E.powf(-3.1); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(-3.1f64).exp()` error: square-root of a number can be computed more efficiently and accurately - --> tests/ui/floating_point_powf.rs:39:13 + --> tests/ui/floating_point_powf.rs:41:13 | LL | let _ = x.powf(1.0 / 2.0); | ^^^^^^^^^^^^^^^^^ help: consider using: `x.sqrt()` error: cube-root of a number can be computed more accurately - --> tests/ui/floating_point_powf.rs:40:13 + --> tests/ui/floating_point_powf.rs:42:13 | LL | let _ = x.powf(1.0 / 3.0); | ^^^^^^^^^^^^^^^^^ help: consider using: `x.cbrt()` error: exponentiation with integer powers can be computed more efficiently - --> tests/ui/floating_point_powf.rs:41:13 + --> tests/ui/floating_point_powf.rs:43:13 | LL | let _ = x.powf(3.0); | ^^^^^^^^^^^ help: consider using: `x.powi(3)` error: exponentiation with integer powers can be computed more efficiently - --> tests/ui/floating_point_powf.rs:42:13 + --> tests/ui/floating_point_powf.rs:44:13 | LL | let _ = x.powf(-2.0); | ^^^^^^^^^^^^ help: consider using: `x.powi(-2)` error: exponentiation with integer powers can be computed more efficiently - --> tests/ui/floating_point_powf.rs:43:13 + --> tests/ui/floating_point_powf.rs:45:13 | LL | let _ = x.powf(-2_147_483_648.0); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.powi(-2_147_483_648)` error: exponentiation with integer powers can be computed more efficiently - --> tests/ui/floating_point_powf.rs:44:13 + --> tests/ui/floating_point_powf.rs:46:13 | LL | let _ = x.powf(2_147_483_647.0); | ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.powi(2_147_483_647)` diff --git a/tests/ui/lossy_float_literal.fixed b/tests/ui/lossy_float_literal.fixed index 92a0084a6aebb..cc8c0b4a0d170 100644 --- a/tests/ui/lossy_float_literal.fixed +++ b/tests/ui/lossy_float_literal.fixed @@ -1,31 +1,55 @@ #![warn(clippy::lossy_float_literal)] #![allow(overflowing_literals, unused)] +#![feature(f128)] +#![feature(f16)] fn main() { // Lossy whole-number float literals + let _: f16 = 4_097.0; + let _: f16 = 4_097.; + let _: f16 = 4_097.000; + let _ = 4_097f16; + let _: f16 = -4_097.0; + let _: f32 = 16_777_216.0; let _: f32 = 16_777_220.0; let _: f32 = 16_777_220.0; let _: f32 = 16_777_220.0; let _ = 16_777_220_f32; let _: f32 = -16_777_220.0; + let _: f64 = 9_007_199_254_740_992.0; let _: f64 = 9_007_199_254_740_992.0; let _: f64 = 9_007_199_254_740_992.0; let _ = 9_007_199_254_740_992_f64; let _: f64 = -9_007_199_254_740_992.0; + let _: f128 = 10_384_593_717_069_655_257_060_992_658_440_193.0; + let _: f128 = 10_384_593_717_069_655_257_060_992_658_440_193.; + let _: f128 = 10_384_593_717_069_655_257_060_992_658_440_193.00; + let _ = 10_384_593_717_069_655_257_060_992_658_440_193f128; + let _: f128 = -10_384_593_717_069_655_257_060_992_658_440_193.0; + // Lossless whole number float literals + let _: f16 = 4_096.0; + let _: f16 = -4_096.0; + let _: f32 = 16_777_216.0; let _: f32 = 16_777_218.0; let _: f32 = 16_777_220.0; let _: f32 = -16_777_216.0; let _: f32 = -16_777_220.0; + let _: f64 = 16_777_217.0; let _: f64 = -16_777_217.0; let _: f64 = 9_007_199_254_740_992.0; let _: f64 = -9_007_199_254_740_992.0; + let _: f128 = 9_007_199_254_740_993.0; + let _: f128 = -9_007_199_254_740_993.0; + let _: f128 = 10_384_593_717_069_655_257_060_992_658_440_192.0; + let _: f128 = -10_384_593_717_069_655_257_060_992_658_440_192.0; + // Ignored whole number float literals let _: f32 = 1e25; let _: f32 = 1E25; diff --git a/tests/ui/lossy_float_literal.rs b/tests/ui/lossy_float_literal.rs index 5abef3c442eca..c84eef396d58a 100644 --- a/tests/ui/lossy_float_literal.rs +++ b/tests/ui/lossy_float_literal.rs @@ -1,31 +1,55 @@ #![warn(clippy::lossy_float_literal)] #![allow(overflowing_literals, unused)] +#![feature(f128)] +#![feature(f16)] fn main() { // Lossy whole-number float literals + let _: f16 = 4_097.0; + let _: f16 = 4_097.; + let _: f16 = 4_097.000; + let _ = 4_097f16; + let _: f16 = -4_097.0; + let _: f32 = 16_777_217.0; let _: f32 = 16_777_219.0; let _: f32 = 16_777_219.; let _: f32 = 16_777_219.000; let _ = 16_777_219f32; let _: f32 = -16_777_219.0; + let _: f64 = 9_007_199_254_740_993.0; let _: f64 = 9_007_199_254_740_993.; let _: f64 = 9_007_199_254_740_993.00; let _ = 9_007_199_254_740_993f64; let _: f64 = -9_007_199_254_740_993.0; + let _: f128 = 10_384_593_717_069_655_257_060_992_658_440_193.0; + let _: f128 = 10_384_593_717_069_655_257_060_992_658_440_193.; + let _: f128 = 10_384_593_717_069_655_257_060_992_658_440_193.00; + let _ = 10_384_593_717_069_655_257_060_992_658_440_193f128; + let _: f128 = -10_384_593_717_069_655_257_060_992_658_440_193.0; + // Lossless whole number float literals + let _: f16 = 4_096.0; + let _: f16 = -4_096.0; + let _: f32 = 16_777_216.0; let _: f32 = 16_777_218.0; let _: f32 = 16_777_220.0; let _: f32 = -16_777_216.0; let _: f32 = -16_777_220.0; + let _: f64 = 16_777_217.0; let _: f64 = -16_777_217.0; let _: f64 = 9_007_199_254_740_992.0; let _: f64 = -9_007_199_254_740_992.0; + let _: f128 = 9_007_199_254_740_993.0; + let _: f128 = -9_007_199_254_740_993.0; + let _: f128 = 10_384_593_717_069_655_257_060_992_658_440_192.0; + let _: f128 = -10_384_593_717_069_655_257_060_992_658_440_192.0; + // Ignored whole number float literals let _: f32 = 1e25; let _: f32 = 1E25; diff --git a/tests/ui/lossy_float_literal.stderr b/tests/ui/lossy_float_literal.stderr index 7904719141c18..b5a07418734c9 100644 --- a/tests/ui/lossy_float_literal.stderr +++ b/tests/ui/lossy_float_literal.stderr @@ -1,5 +1,5 @@ error: literal cannot be represented as the underlying type without loss of precision - --> tests/ui/lossy_float_literal.rs:6:18 + --> tests/ui/lossy_float_literal.rs:14:18 | LL | let _: f32 = 16_777_217.0; | ^^^^^^^^^^^^ help: consider changing the type or replacing it with: `16_777_216.0` @@ -8,61 +8,61 @@ LL | let _: f32 = 16_777_217.0; = help: to override `-D warnings` add `#[allow(clippy::lossy_float_literal)]` error: literal cannot be represented as the underlying type without loss of precision - --> tests/ui/lossy_float_literal.rs:7:18 + --> tests/ui/lossy_float_literal.rs:15:18 | LL | let _: f32 = 16_777_219.0; | ^^^^^^^^^^^^ help: consider changing the type or replacing it with: `16_777_220.0` error: literal cannot be represented as the underlying type without loss of precision - --> tests/ui/lossy_float_literal.rs:8:18 + --> tests/ui/lossy_float_literal.rs:16:18 | LL | let _: f32 = 16_777_219.; | ^^^^^^^^^^^ help: consider changing the type or replacing it with: `16_777_220.0` error: literal cannot be represented as the underlying type without loss of precision - --> tests/ui/lossy_float_literal.rs:9:18 + --> tests/ui/lossy_float_literal.rs:17:18 | LL | let _: f32 = 16_777_219.000; | ^^^^^^^^^^^^^^ help: consider changing the type or replacing it with: `16_777_220.0` error: literal cannot be represented as the underlying type without loss of precision - --> tests/ui/lossy_float_literal.rs:10:13 + --> tests/ui/lossy_float_literal.rs:18:13 | LL | let _ = 16_777_219f32; | ^^^^^^^^^^^^^ help: consider changing the type or replacing it with: `16_777_220_f32` error: literal cannot be represented as the underlying type without loss of precision - --> tests/ui/lossy_float_literal.rs:11:19 + --> tests/ui/lossy_float_literal.rs:19:19 | LL | let _: f32 = -16_777_219.0; | ^^^^^^^^^^^^ help: consider changing the type or replacing it with: `16_777_220.0` error: literal cannot be represented as the underlying type without loss of precision - --> tests/ui/lossy_float_literal.rs:12:18 + --> tests/ui/lossy_float_literal.rs:21:18 | LL | let _: f64 = 9_007_199_254_740_993.0; | ^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing the type or replacing it with: `9_007_199_254_740_992.0` error: literal cannot be represented as the underlying type without loss of precision - --> tests/ui/lossy_float_literal.rs:13:18 + --> tests/ui/lossy_float_literal.rs:22:18 | LL | let _: f64 = 9_007_199_254_740_993.; | ^^^^^^^^^^^^^^^^^^^^^^ help: consider changing the type or replacing it with: `9_007_199_254_740_992.0` error: literal cannot be represented as the underlying type without loss of precision - --> tests/ui/lossy_float_literal.rs:14:18 + --> tests/ui/lossy_float_literal.rs:23:18 | LL | let _: f64 = 9_007_199_254_740_993.00; | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing the type or replacing it with: `9_007_199_254_740_992.0` error: literal cannot be represented as the underlying type without loss of precision - --> tests/ui/lossy_float_literal.rs:15:13 + --> tests/ui/lossy_float_literal.rs:24:13 | LL | let _ = 9_007_199_254_740_993f64; | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing the type or replacing it with: `9_007_199_254_740_992_f64` error: literal cannot be represented as the underlying type without loss of precision - --> tests/ui/lossy_float_literal.rs:16:19 + --> tests/ui/lossy_float_literal.rs:25:19 | LL | let _: f64 = -9_007_199_254_740_993.0; | ^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing the type or replacing it with: `9_007_199_254_740_992.0` diff --git a/tests/ui/manual_float_methods.rs b/tests/ui/manual_float_methods.rs index 80781ecda721a..ee3daa12834b4 100644 --- a/tests/ui/manual_float_methods.rs +++ b/tests/ui/manual_float_methods.rs @@ -3,6 +3,8 @@ #![allow(clippy::needless_if, unused)] #![warn(clippy::manual_is_infinite, clippy::manual_is_finite)] +// FIXME(f16_f128): add tests for these types once constants are available + #[macro_use] extern crate proc_macros; diff --git a/tests/ui/manual_float_methods.stderr b/tests/ui/manual_float_methods.stderr index 930df0b97cb3f..70057620a4a82 100644 --- a/tests/ui/manual_float_methods.stderr +++ b/tests/ui/manual_float_methods.stderr @@ -1,5 +1,5 @@ error: manually checking if a float is infinite - --> tests/ui/manual_float_methods.rs:22:8 + --> tests/ui/manual_float_methods.rs:24:8 | LL | if x == f32::INFINITY || x == f32::NEG_INFINITY {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the dedicated method instead: `x.is_infinite()` @@ -8,7 +8,7 @@ LL | if x == f32::INFINITY || x == f32::NEG_INFINITY {} = help: to override `-D warnings` add `#[allow(clippy::manual_is_infinite)]` error: manually checking if a float is finite - --> tests/ui/manual_float_methods.rs:23:8 + --> tests/ui/manual_float_methods.rs:25:8 | LL | if x != f32::INFINITY && x != f32::NEG_INFINITY {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -29,13 +29,13 @@ LL | if !x.is_infinite() {} | ~~~~~~~~~~~~~~~~ error: manually checking if a float is infinite - --> tests/ui/manual_float_methods.rs:24:8 + --> tests/ui/manual_float_methods.rs:26:8 | LL | if x == INFINITE || x == NEG_INFINITE {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the dedicated method instead: `x.is_infinite()` error: manually checking if a float is finite - --> tests/ui/manual_float_methods.rs:25:8 + --> tests/ui/manual_float_methods.rs:27:8 | LL | if x != INFINITE && x != NEG_INFINITE {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -54,13 +54,13 @@ LL | if !x.is_infinite() {} | ~~~~~~~~~~~~~~~~ error: manually checking if a float is infinite - --> tests/ui/manual_float_methods.rs:27:8 + --> tests/ui/manual_float_methods.rs:29:8 | LL | if x == f64::INFINITY || x == f64::NEG_INFINITY {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the dedicated method instead: `x.is_infinite()` error: manually checking if a float is finite - --> tests/ui/manual_float_methods.rs:28:8 + --> tests/ui/manual_float_methods.rs:30:8 | LL | if x != f64::INFINITY && x != f64::NEG_INFINITY {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/modulo_arithmetic_float.rs b/tests/ui/modulo_arithmetic_float.rs index 37895ea09e72c..a5b63bed531b0 100644 --- a/tests/ui/modulo_arithmetic_float.rs +++ b/tests/ui/modulo_arithmetic_float.rs @@ -1,3 +1,5 @@ +#![feature(f128)] +#![feature(f16)] #![warn(clippy::modulo_arithmetic)] #![allow(clippy::no_effect, clippy::unnecessary_operation, clippy::modulo_one)] @@ -16,6 +18,19 @@ fn main() { //~^ ERROR: you are using modulo operator on constants with different signs: `3.400 % //~| NOTE: double check for expected result especially when interoperating with differ + // Lint on floating point numbers + let a_f16: f16 = -1.6; + let mut b_f16: f16 = 2.1; + a_f16 % b_f16; + //~^ ERROR: you are using modulo operator on types that might have different signs + //~| NOTE: double check for expected result especially when interoperating with differ + b_f16 % a_f16; + //~^ ERROR: you are using modulo operator on types that might have different signs + //~| NOTE: double check for expected result especially when interoperating with differ + b_f16 %= a_f16; + //~^ ERROR: you are using modulo operator on types that might have different signs + //~| NOTE: double check for expected result especially when interoperating with differ + // Lint on floating point numbers let a_f32: f32 = -1.6; let mut b_f32: f32 = 2.1; @@ -41,6 +56,18 @@ fn main() { //~^ ERROR: you are using modulo operator on types that might have different signs //~| NOTE: double check for expected result especially when interoperating with differ + let a_f128: f128 = -1.6; + let mut b_f128: f128 = 2.1; + a_f128 % b_f128; + //~^ ERROR: you are using modulo operator on types that might have different signs + //~| NOTE: double check for expected result especially when interoperating with differ + b_f128 % a_f128; + //~^ ERROR: you are using modulo operator on types that might have different signs + //~| NOTE: double check for expected result especially when interoperating with differ + b_f128 %= a_f128; + //~^ ERROR: you are using modulo operator on types that might have different signs + //~| NOTE: double check for expected result especially when interoperating with differ + // No lint when both sides are const and of the same sign 1.6 % 2.1; -1.6 % -2.1; diff --git a/tests/ui/modulo_arithmetic_float.stderr b/tests/ui/modulo_arithmetic_float.stderr index fa3a64cfb7146..2b4937552bdab 100644 --- a/tests/ui/modulo_arithmetic_float.stderr +++ b/tests/ui/modulo_arithmetic_float.stderr @@ -1,5 +1,5 @@ error: you are using modulo operator on constants with different signs: `-1.600 % 2.100` - --> tests/ui/modulo_arithmetic_float.rs:6:5 + --> tests/ui/modulo_arithmetic_float.rs:8:5 | LL | -1.6 % 2.1; | ^^^^^^^^^^ @@ -9,7 +9,7 @@ LL | -1.6 % 2.1; = help: to override `-D warnings` add `#[allow(clippy::modulo_arithmetic)]` error: you are using modulo operator on constants with different signs: `1.600 % -2.100` - --> tests/ui/modulo_arithmetic_float.rs:9:5 + --> tests/ui/modulo_arithmetic_float.rs:11:5 | LL | 1.6 % -2.1; | ^^^^^^^^^^ @@ -17,7 +17,7 @@ LL | 1.6 % -2.1; = note: double check for expected result especially when interoperating with different languages error: you are using modulo operator on constants with different signs: `-1.200 % 3.400` - --> tests/ui/modulo_arithmetic_float.rs:12:5 + --> tests/ui/modulo_arithmetic_float.rs:14:5 | LL | (1.1 - 2.3) % (1.1 + 2.3); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -25,7 +25,7 @@ LL | (1.1 - 2.3) % (1.1 + 2.3); = note: double check for expected result especially when interoperating with different languages error: you are using modulo operator on constants with different signs: `3.400 % -1.200` - --> tests/ui/modulo_arithmetic_float.rs:15:5 + --> tests/ui/modulo_arithmetic_float.rs:17:5 | LL | (1.1 + 2.3) % (1.1 - 2.3); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -33,7 +33,31 @@ LL | (1.1 + 2.3) % (1.1 - 2.3); = note: double check for expected result especially when interoperating with different languages error: you are using modulo operator on types that might have different signs - --> tests/ui/modulo_arithmetic_float.rs:22:5 + --> tests/ui/modulo_arithmetic_float.rs:24:5 + | +LL | a_f16 % b_f16; + | ^^^^^^^^^^^^^ + | + = note: double check for expected result especially when interoperating with different languages + +error: you are using modulo operator on types that might have different signs + --> tests/ui/modulo_arithmetic_float.rs:27:5 + | +LL | b_f16 % a_f16; + | ^^^^^^^^^^^^^ + | + = note: double check for expected result especially when interoperating with different languages + +error: you are using modulo operator on types that might have different signs + --> tests/ui/modulo_arithmetic_float.rs:30:5 + | +LL | b_f16 %= a_f16; + | ^^^^^^^^^^^^^^ + | + = note: double check for expected result especially when interoperating with different languages + +error: you are using modulo operator on types that might have different signs + --> tests/ui/modulo_arithmetic_float.rs:37:5 | LL | a_f32 % b_f32; | ^^^^^^^^^^^^^ @@ -41,7 +65,7 @@ LL | a_f32 % b_f32; = note: double check for expected result especially when interoperating with different languages error: you are using modulo operator on types that might have different signs - --> tests/ui/modulo_arithmetic_float.rs:25:5 + --> tests/ui/modulo_arithmetic_float.rs:40:5 | LL | b_f32 % a_f32; | ^^^^^^^^^^^^^ @@ -49,7 +73,7 @@ LL | b_f32 % a_f32; = note: double check for expected result especially when interoperating with different languages error: you are using modulo operator on types that might have different signs - --> tests/ui/modulo_arithmetic_float.rs:28:5 + --> tests/ui/modulo_arithmetic_float.rs:43:5 | LL | b_f32 %= a_f32; | ^^^^^^^^^^^^^^ @@ -57,7 +81,7 @@ LL | b_f32 %= a_f32; = note: double check for expected result especially when interoperating with different languages error: you are using modulo operator on types that might have different signs - --> tests/ui/modulo_arithmetic_float.rs:34:5 + --> tests/ui/modulo_arithmetic_float.rs:49:5 | LL | a_f64 % b_f64; | ^^^^^^^^^^^^^ @@ -65,7 +89,7 @@ LL | a_f64 % b_f64; = note: double check for expected result especially when interoperating with different languages error: you are using modulo operator on types that might have different signs - --> tests/ui/modulo_arithmetic_float.rs:37:5 + --> tests/ui/modulo_arithmetic_float.rs:52:5 | LL | b_f64 % a_f64; | ^^^^^^^^^^^^^ @@ -73,12 +97,36 @@ LL | b_f64 % a_f64; = note: double check for expected result especially when interoperating with different languages error: you are using modulo operator on types that might have different signs - --> tests/ui/modulo_arithmetic_float.rs:40:5 + --> tests/ui/modulo_arithmetic_float.rs:55:5 | LL | b_f64 %= a_f64; | ^^^^^^^^^^^^^^ | = note: double check for expected result especially when interoperating with different languages -error: aborting due to 10 previous errors +error: you are using modulo operator on types that might have different signs + --> tests/ui/modulo_arithmetic_float.rs:61:5 + | +LL | a_f128 % b_f128; + | ^^^^^^^^^^^^^^^ + | + = note: double check for expected result especially when interoperating with different languages + +error: you are using modulo operator on types that might have different signs + --> tests/ui/modulo_arithmetic_float.rs:64:5 + | +LL | b_f128 % a_f128; + | ^^^^^^^^^^^^^^^ + | + = note: double check for expected result especially when interoperating with different languages + +error: you are using modulo operator on types that might have different signs + --> tests/ui/modulo_arithmetic_float.rs:67:5 + | +LL | b_f128 %= a_f128; + | ^^^^^^^^^^^^^^^^ + | + = note: double check for expected result especially when interoperating with different languages + +error: aborting due to 16 previous errors diff --git a/tests/ui/transmute.rs b/tests/ui/transmute.rs index be6e071767d98..46629526367ec 100644 --- a/tests/ui/transmute.rs +++ b/tests/ui/transmute.rs @@ -1,3 +1,5 @@ +#![feature(f128)] +#![feature(f16)] #![allow( dead_code, clippy::borrow_as_ptr, @@ -117,20 +119,34 @@ fn int_to_bool() { #[warn(clippy::transmute_int_to_float)] mod int_to_float { fn test() { + let _: f16 = unsafe { std::mem::transmute(0_u16) }; + //~^ ERROR: transmute from a `u16` to a `f16` + //~| NOTE: `-D clippy::transmute-int-to-float` implied by `-D warnings` + let _: f16 = unsafe { std::mem::transmute(0_i16) }; + //~^ ERROR: transmute from a `i16` to a `f16` let _: f32 = unsafe { std::mem::transmute(0_u32) }; //~^ ERROR: transmute from a `u32` to a `f32` - //~| NOTE: `-D clippy::transmute-int-to-float` implied by `-D warnings` let _: f32 = unsafe { std::mem::transmute(0_i32) }; //~^ ERROR: transmute from a `i32` to a `f32` let _: f64 = unsafe { std::mem::transmute(0_u64) }; //~^ ERROR: transmute from a `u64` to a `f64` let _: f64 = unsafe { std::mem::transmute(0_i64) }; //~^ ERROR: transmute from a `i64` to a `f64` + let _: f128 = unsafe { std::mem::transmute(0_u128) }; + //~^ ERROR: transmute from a `u128` to a `f128` + let _: f128 = unsafe { std::mem::transmute(0_i128) }; + //~^ ERROR: transmute from a `i128` to a `f128` } mod issue_5747 { + const VALUE16: f16 = unsafe { std::mem::transmute(0_u16) }; const VALUE32: f32 = unsafe { std::mem::transmute(0_u32) }; const VALUE64: f64 = unsafe { std::mem::transmute(0_i64) }; + const VALUE128: f128 = unsafe { std::mem::transmute(0_i128) }; + + const fn from_bits_16(v: i16) -> f16 { + unsafe { std::mem::transmute(v) } + } const fn from_bits_32(v: i32) -> f32 { unsafe { std::mem::transmute(v) } @@ -139,6 +155,10 @@ mod int_to_float { const fn from_bits_64(v: u64) -> f64 { unsafe { std::mem::transmute(v) } } + + const fn from_bits_128(v: u128) -> f128 { + unsafe { std::mem::transmute(v) } + } } } @@ -158,10 +178,15 @@ mod num_to_bytes { //~^ ERROR: transmute from a `i32` to a `[u8; 4]` let _: [u8; 16] = std::mem::transmute(0i128); //~^ ERROR: transmute from a `i128` to a `[u8; 16]` + + let _: [u8; 2] = std::mem::transmute(0.0f16); + //~^ ERROR: transmute from a `f16` to a `[u8; 2]` let _: [u8; 4] = std::mem::transmute(0.0f32); //~^ ERROR: transmute from a `f32` to a `[u8; 4]` let _: [u8; 8] = std::mem::transmute(0.0f64); //~^ ERROR: transmute from a `f64` to a `[u8; 8]` + let _: [u8; 16] = std::mem::transmute(0.0f128); + //~^ ERROR: transmute from a `f128` to a `[u8; 16]` } } const fn test_const() { @@ -178,8 +203,11 @@ mod num_to_bytes { //~^ ERROR: transmute from a `i32` to a `[u8; 4]` let _: [u8; 16] = std::mem::transmute(0i128); //~^ ERROR: transmute from a `i128` to a `[u8; 16]` + + let _: [u8; 2] = std::mem::transmute(0.0f16); let _: [u8; 4] = std::mem::transmute(0.0f32); let _: [u8; 8] = std::mem::transmute(0.0f64); + let _: [u8; 16] = std::mem::transmute(0.0f128); } } } diff --git a/tests/ui/transmute.stderr b/tests/ui/transmute.stderr index 375e8f19dd6b4..0072f62962a7d 100644 --- a/tests/ui/transmute.stderr +++ b/tests/ui/transmute.stderr @@ -1,5 +1,5 @@ error: transmute from a reference to a pointer - --> tests/ui/transmute.rs:29:23 + --> tests/ui/transmute.rs:31:23 | LL | let _: *const T = core::intrinsics::transmute(t); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `t as *const T` @@ -8,61 +8,61 @@ LL | let _: *const T = core::intrinsics::transmute(t); = help: to override `-D warnings` add `#[allow(clippy::useless_transmute)]` error: transmute from a reference to a pointer - --> tests/ui/transmute.rs:33:21 + --> tests/ui/transmute.rs:35:21 | LL | let _: *mut T = core::intrinsics::transmute(t); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `t as *const T as *mut T` error: transmute from a reference to a pointer - --> tests/ui/transmute.rs:36:23 + --> tests/ui/transmute.rs:38:23 | LL | let _: *const U = core::intrinsics::transmute(t); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `t as *const T as *const U` error: transmute from a type (`std::vec::Vec`) to itself - --> tests/ui/transmute.rs:43:27 + --> tests/ui/transmute.rs:45:27 | LL | let _: Vec = core::intrinsics::transmute(my_vec()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: transmute from a type (`std::vec::Vec`) to itself - --> tests/ui/transmute.rs:46:27 + --> tests/ui/transmute.rs:48:27 | LL | let _: Vec = core::mem::transmute(my_vec()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: transmute from a type (`std::vec::Vec`) to itself - --> tests/ui/transmute.rs:49:27 + --> tests/ui/transmute.rs:51:27 | LL | let _: Vec = std::intrinsics::transmute(my_vec()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: transmute from a type (`std::vec::Vec`) to itself - --> tests/ui/transmute.rs:52:27 + --> tests/ui/transmute.rs:54:27 | LL | let _: Vec = std::mem::transmute(my_vec()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: transmute from a type (`std::vec::Vec`) to itself - --> tests/ui/transmute.rs:55:27 + --> tests/ui/transmute.rs:57:27 | LL | let _: Vec = my_transmute(my_vec()); | ^^^^^^^^^^^^^^^^^^^^^^ error: transmute from an integer to a pointer - --> tests/ui/transmute.rs:58:31 + --> tests/ui/transmute.rs:60:31 | LL | let _: *const usize = std::mem::transmute(5_isize); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `5_isize as *const usize` error: transmute from an integer to a pointer - --> tests/ui/transmute.rs:63:31 + --> tests/ui/transmute.rs:65:31 | LL | let _: *const usize = std::mem::transmute(1 + 1usize); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `(1 + 1usize) as *const usize` error: transmute from a type (`*const Usize`) to the type that it points to (`Usize`) - --> tests/ui/transmute.rs:95:24 + --> tests/ui/transmute.rs:97:24 | LL | let _: Usize = core::intrinsics::transmute(int_const_ptr); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -71,25 +71,25 @@ LL | let _: Usize = core::intrinsics::transmute(int_const_ptr); = help: to override `-D warnings` add `#[allow(clippy::crosspointer_transmute)]` error: transmute from a type (`*mut Usize`) to the type that it points to (`Usize`) - --> tests/ui/transmute.rs:99:24 + --> tests/ui/transmute.rs:101:24 | LL | let _: Usize = core::intrinsics::transmute(int_mut_ptr); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: transmute from a type (`Usize`) to a pointer to that type (`*const Usize`) - --> tests/ui/transmute.rs:102:31 + --> tests/ui/transmute.rs:104:31 | LL | let _: *const Usize = core::intrinsics::transmute(my_int()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: transmute from a type (`Usize`) to a pointer to that type (`*mut Usize`) - --> tests/ui/transmute.rs:105:29 + --> tests/ui/transmute.rs:107:29 | LL | let _: *mut Usize = core::intrinsics::transmute(my_int()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: transmute from a `u8` to a `bool` - --> tests/ui/transmute.rs:112:28 + --> tests/ui/transmute.rs:114:28 | LL | let _: bool = unsafe { std::mem::transmute(0_u8) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `0_u8 != 0` @@ -97,35 +97,59 @@ LL | let _: bool = unsafe { std::mem::transmute(0_u8) }; = note: `-D clippy::transmute-int-to-bool` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::transmute_int_to_bool)]` -error: transmute from a `u32` to a `f32` - --> tests/ui/transmute.rs:120:31 +error: transmute from a `u16` to a `f16` + --> tests/ui/transmute.rs:122:31 | -LL | let _: f32 = unsafe { std::mem::transmute(0_u32) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f32::from_bits(0_u32)` +LL | let _: f16 = unsafe { std::mem::transmute(0_u16) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f16::from_bits(0_u16)` | = note: `-D clippy::transmute-int-to-float` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::transmute_int_to_float)]` +error: transmute from a `i16` to a `f16` + --> tests/ui/transmute.rs:125:31 + | +LL | let _: f16 = unsafe { std::mem::transmute(0_i16) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f16::from_bits(0_i16 as u16)` + +error: transmute from a `u32` to a `f32` + --> tests/ui/transmute.rs:127:31 + | +LL | let _: f32 = unsafe { std::mem::transmute(0_u32) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f32::from_bits(0_u32)` + error: transmute from a `i32` to a `f32` - --> tests/ui/transmute.rs:123:31 + --> tests/ui/transmute.rs:129:31 | LL | let _: f32 = unsafe { std::mem::transmute(0_i32) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f32::from_bits(0_i32 as u32)` error: transmute from a `u64` to a `f64` - --> tests/ui/transmute.rs:125:31 + --> tests/ui/transmute.rs:131:31 | LL | let _: f64 = unsafe { std::mem::transmute(0_u64) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f64::from_bits(0_u64)` error: transmute from a `i64` to a `f64` - --> tests/ui/transmute.rs:127:31 + --> tests/ui/transmute.rs:133:31 | LL | let _: f64 = unsafe { std::mem::transmute(0_i64) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f64::from_bits(0_i64 as u64)` +error: transmute from a `u128` to a `f128` + --> tests/ui/transmute.rs:135:32 + | +LL | let _: f128 = unsafe { std::mem::transmute(0_u128) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f128::from_bits(0_u128)` + +error: transmute from a `i128` to a `f128` + --> tests/ui/transmute.rs:137:32 + | +LL | let _: f128 = unsafe { std::mem::transmute(0_i128) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f128::from_bits(0_i128 as u128)` + error: transmute from a `u8` to a `[u8; 1]` - --> tests/ui/transmute.rs:148:30 + --> tests/ui/transmute.rs:168:30 | LL | let _: [u8; 1] = std::mem::transmute(0u8); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0u8.to_ne_bytes()` @@ -134,85 +158,97 @@ LL | let _: [u8; 1] = std::mem::transmute(0u8); = help: to override `-D warnings` add `#[allow(clippy::transmute_num_to_bytes)]` error: transmute from a `u32` to a `[u8; 4]` - --> tests/ui/transmute.rs:151:30 + --> tests/ui/transmute.rs:171:30 | LL | let _: [u8; 4] = std::mem::transmute(0u32); | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0u32.to_ne_bytes()` error: transmute from a `u128` to a `[u8; 16]` - --> tests/ui/transmute.rs:153:31 + --> tests/ui/transmute.rs:173:31 | LL | let _: [u8; 16] = std::mem::transmute(0u128); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0u128.to_ne_bytes()` error: transmute from a `i8` to a `[u8; 1]` - --> tests/ui/transmute.rs:155:30 + --> tests/ui/transmute.rs:175:30 | LL | let _: [u8; 1] = std::mem::transmute(0i8); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0i8.to_ne_bytes()` error: transmute from a `i32` to a `[u8; 4]` - --> tests/ui/transmute.rs:157:30 + --> tests/ui/transmute.rs:177:30 | LL | let _: [u8; 4] = std::mem::transmute(0i32); | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0i32.to_ne_bytes()` error: transmute from a `i128` to a `[u8; 16]` - --> tests/ui/transmute.rs:159:31 + --> tests/ui/transmute.rs:179:31 | LL | let _: [u8; 16] = std::mem::transmute(0i128); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0i128.to_ne_bytes()` +error: transmute from a `f16` to a `[u8; 2]` + --> tests/ui/transmute.rs:182:30 + | +LL | let _: [u8; 2] = std::mem::transmute(0.0f16); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0.0f16.to_ne_bytes()` + error: transmute from a `f32` to a `[u8; 4]` - --> tests/ui/transmute.rs:161:30 + --> tests/ui/transmute.rs:184:30 | LL | let _: [u8; 4] = std::mem::transmute(0.0f32); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0.0f32.to_ne_bytes()` error: transmute from a `f64` to a `[u8; 8]` - --> tests/ui/transmute.rs:163:30 + --> tests/ui/transmute.rs:186:30 | LL | let _: [u8; 8] = std::mem::transmute(0.0f64); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0.0f64.to_ne_bytes()` +error: transmute from a `f128` to a `[u8; 16]` + --> tests/ui/transmute.rs:188:31 + | +LL | let _: [u8; 16] = std::mem::transmute(0.0f128); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0.0f128.to_ne_bytes()` + error: transmute from a `u8` to a `[u8; 1]` - --> tests/ui/transmute.rs:169:30 + --> tests/ui/transmute.rs:194:30 | LL | let _: [u8; 1] = std::mem::transmute(0u8); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0u8.to_ne_bytes()` error: transmute from a `u32` to a `[u8; 4]` - --> tests/ui/transmute.rs:171:30 + --> tests/ui/transmute.rs:196:30 | LL | let _: [u8; 4] = std::mem::transmute(0u32); | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0u32.to_ne_bytes()` error: transmute from a `u128` to a `[u8; 16]` - --> tests/ui/transmute.rs:173:31 + --> tests/ui/transmute.rs:198:31 | LL | let _: [u8; 16] = std::mem::transmute(0u128); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0u128.to_ne_bytes()` error: transmute from a `i8` to a `[u8; 1]` - --> tests/ui/transmute.rs:175:30 + --> tests/ui/transmute.rs:200:30 | LL | let _: [u8; 1] = std::mem::transmute(0i8); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0i8.to_ne_bytes()` error: transmute from a `i32` to a `[u8; 4]` - --> tests/ui/transmute.rs:177:30 + --> tests/ui/transmute.rs:202:30 | LL | let _: [u8; 4] = std::mem::transmute(0i32); | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0i32.to_ne_bytes()` error: transmute from a `i128` to a `[u8; 16]` - --> tests/ui/transmute.rs:179:31 + --> tests/ui/transmute.rs:204:31 | LL | let _: [u8; 16] = std::mem::transmute(0i128); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0i128.to_ne_bytes()` error: transmute from a `&[u8]` to a `&str` - --> tests/ui/transmute.rs:190:28 + --> tests/ui/transmute.rs:218:28 | LL | let _: &str = unsafe { std::mem::transmute(B) }; | ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::str::from_utf8(B).unwrap()` @@ -221,16 +257,16 @@ LL | let _: &str = unsafe { std::mem::transmute(B) }; = help: to override `-D warnings` add `#[allow(clippy::transmute_bytes_to_str)]` error: transmute from a `&mut [u8]` to a `&mut str` - --> tests/ui/transmute.rs:193:32 + --> tests/ui/transmute.rs:221:32 | LL | let _: &mut str = unsafe { std::mem::transmute(mb) }; | ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::str::from_utf8_mut(mb).unwrap()` error: transmute from a `&[u8]` to a `&str` - --> tests/ui/transmute.rs:195:30 + --> tests/ui/transmute.rs:223:30 | LL | const _: &str = unsafe { std::mem::transmute(B) }; | ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::str::from_utf8_unchecked(B)` -error: aborting due to 36 previous errors +error: aborting due to 42 previous errors diff --git a/tests/ui/transmute_float_to_int.fixed b/tests/ui/transmute_float_to_int.fixed index 82d5f7fdca105..4361a7407d115 100644 --- a/tests/ui/transmute_float_to_int.fixed +++ b/tests/ui/transmute_float_to_int.fixed @@ -1,5 +1,7 @@ #![warn(clippy::transmute_float_to_int)] #![allow(clippy::missing_transmute_annotations)] +#![feature(f128)] +#![feature(f16)] fn float_to_int() { let _: u32 = unsafe { 1f32.to_bits() }; @@ -18,8 +20,14 @@ fn float_to_int() { } mod issue_5747 { + const VALUE16: i16 = unsafe { std::mem::transmute(1f16) }; const VALUE32: i32 = unsafe { std::mem::transmute(1f32) }; const VALUE64: u64 = unsafe { std::mem::transmute(1f64) }; + const VALUE128: u128 = unsafe { std::mem::transmute(1f128) }; + + const fn to_bits_16(v: f16) -> u16 { + unsafe { std::mem::transmute(v) } + } const fn to_bits_32(v: f32) -> u32 { unsafe { std::mem::transmute(v) } @@ -28,6 +36,10 @@ mod issue_5747 { const fn to_bits_64(v: f64) -> i64 { unsafe { std::mem::transmute(v) } } + + const fn to_bits_128(v: f128) -> i128 { + unsafe { std::mem::transmute(v) } + } } fn main() {} diff --git a/tests/ui/transmute_float_to_int.rs b/tests/ui/transmute_float_to_int.rs index 9f056330adf97..363ce0bcb16d0 100644 --- a/tests/ui/transmute_float_to_int.rs +++ b/tests/ui/transmute_float_to_int.rs @@ -1,5 +1,7 @@ #![warn(clippy::transmute_float_to_int)] #![allow(clippy::missing_transmute_annotations)] +#![feature(f128)] +#![feature(f16)] fn float_to_int() { let _: u32 = unsafe { std::mem::transmute(1f32) }; @@ -18,8 +20,14 @@ fn float_to_int() { } mod issue_5747 { + const VALUE16: i16 = unsafe { std::mem::transmute(1f16) }; const VALUE32: i32 = unsafe { std::mem::transmute(1f32) }; const VALUE64: u64 = unsafe { std::mem::transmute(1f64) }; + const VALUE128: u128 = unsafe { std::mem::transmute(1f128) }; + + const fn to_bits_16(v: f16) -> u16 { + unsafe { std::mem::transmute(v) } + } const fn to_bits_32(v: f32) -> u32 { unsafe { std::mem::transmute(v) } @@ -28,6 +36,10 @@ mod issue_5747 { const fn to_bits_64(v: f64) -> i64 { unsafe { std::mem::transmute(v) } } + + const fn to_bits_128(v: f128) -> i128 { + unsafe { std::mem::transmute(v) } + } } fn main() {} diff --git a/tests/ui/transmute_float_to_int.stderr b/tests/ui/transmute_float_to_int.stderr index ac3aae5f8b78c..9cac75f72cdd7 100644 --- a/tests/ui/transmute_float_to_int.stderr +++ b/tests/ui/transmute_float_to_int.stderr @@ -1,5 +1,5 @@ error: transmute from a `f32` to a `u32` - --> tests/ui/transmute_float_to_int.rs:5:27 + --> tests/ui/transmute_float_to_int.rs:7:27 | LL | let _: u32 = unsafe { std::mem::transmute(1f32) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `1f32.to_bits()` @@ -8,31 +8,31 @@ LL | let _: u32 = unsafe { std::mem::transmute(1f32) }; = help: to override `-D warnings` add `#[allow(clippy::transmute_float_to_int)]` error: transmute from a `f32` to a `i32` - --> tests/ui/transmute_float_to_int.rs:8:27 + --> tests/ui/transmute_float_to_int.rs:10:27 | LL | let _: i32 = unsafe { std::mem::transmute(1f32) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `1f32.to_bits() as i32` error: transmute from a `f64` to a `u64` - --> tests/ui/transmute_float_to_int.rs:10:27 + --> tests/ui/transmute_float_to_int.rs:12:27 | LL | let _: u64 = unsafe { std::mem::transmute(1f64) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `1f64.to_bits()` error: transmute from a `f64` to a `i64` - --> tests/ui/transmute_float_to_int.rs:12:27 + --> tests/ui/transmute_float_to_int.rs:14:27 | LL | let _: i64 = unsafe { std::mem::transmute(1f64) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `1f64.to_bits() as i64` error: transmute from a `f64` to a `u64` - --> tests/ui/transmute_float_to_int.rs:14:27 + --> tests/ui/transmute_float_to_int.rs:16:27 | LL | let _: u64 = unsafe { std::mem::transmute(1.0) }; | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `1.0f64.to_bits()` error: transmute from a `f64` to a `u64` - --> tests/ui/transmute_float_to_int.rs:16:27 + --> tests/ui/transmute_float_to_int.rs:18:27 | LL | let _: u64 = unsafe { std::mem::transmute(-1.0) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(-1.0f64).to_bits()` diff --git a/tests/ui/unused_rounding.fixed b/tests/ui/unused_rounding.fixed index 02f970f42a420..7af2c8650a3dd 100644 --- a/tests/ui/unused_rounding.fixed +++ b/tests/ui/unused_rounding.fixed @@ -1,3 +1,5 @@ +// FIXME(f16_f128): add tests when math functions are available + #![warn(clippy::unused_rounding)] fn main() { diff --git a/tests/ui/unused_rounding.rs b/tests/ui/unused_rounding.rs index fd14c466f120a..1b0b22a9b6854 100644 --- a/tests/ui/unused_rounding.rs +++ b/tests/ui/unused_rounding.rs @@ -1,3 +1,5 @@ +// FIXME(f16_f128): add tests when math functions are available + #![warn(clippy::unused_rounding)] fn main() { diff --git a/tests/ui/unused_rounding.stderr b/tests/ui/unused_rounding.stderr index 75ad895012b37..c5ae2da75f84e 100644 --- a/tests/ui/unused_rounding.stderr +++ b/tests/ui/unused_rounding.stderr @@ -1,5 +1,5 @@ error: used the `ceil` method with a whole number float - --> tests/ui/unused_rounding.rs:4:13 + --> tests/ui/unused_rounding.rs:6:13 | LL | let _ = 1f32.ceil(); | ^^^^^^^^^^^ help: remove the `ceil` method call: `1f32` @@ -8,25 +8,25 @@ LL | let _ = 1f32.ceil(); = help: to override `-D warnings` add `#[allow(clippy::unused_rounding)]` error: used the `floor` method with a whole number float - --> tests/ui/unused_rounding.rs:5:13 + --> tests/ui/unused_rounding.rs:7:13 | LL | let _ = 1.0f64.floor(); | ^^^^^^^^^^^^^^ help: remove the `floor` method call: `1.0f64` error: used the `round` method with a whole number float - --> tests/ui/unused_rounding.rs:6:13 + --> tests/ui/unused_rounding.rs:8:13 | LL | let _ = 1.00f32.round(); | ^^^^^^^^^^^^^^^ help: remove the `round` method call: `1.00f32` error: used the `round` method with a whole number float - --> tests/ui/unused_rounding.rs:12:13 + --> tests/ui/unused_rounding.rs:14:13 | LL | let _ = 3.0_f32.round(); | ^^^^^^^^^^^^^^^ help: remove the `round` method call: `3.0_f32` error: used the `round` method with a whole number float - --> tests/ui/unused_rounding.rs:14:13 + --> tests/ui/unused_rounding.rs:16:13 | LL | let _ = 3_3.0_0_f32.round(); | ^^^^^^^^^^^^^^^^^^^ help: remove the `round` method call: `3_3.0_0_f32` From e79dc7656a5664a6daf1b4a1f521bf1c6c6b30a1 Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Fri, 14 Jun 2024 23:01:22 -0700 Subject: [PATCH 216/892] `bug!` more uses of these in runtime stuff --- src/base.rs | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/src/base.rs b/src/base.rs index 6d26ca0b899b2..b117dc496c2bb 100644 --- a/src/base.rs +++ b/src/base.rs @@ -677,21 +677,22 @@ fn codegen_stmt<'tcx>( CastKind::PointerCoercion(PointerCoercion::UnsafeFnPointer), ref operand, to_ty, - ) - | Rvalue::Cast( - CastKind::PointerCoercion(PointerCoercion::MutToConstPointer), - ref operand, - to_ty, - ) - | Rvalue::Cast( - CastKind::PointerCoercion(PointerCoercion::ArrayToPointer), - ref operand, - to_ty, ) => { let to_layout = fx.layout_of(fx.monomorphize(to_ty)); let operand = codegen_operand(fx, operand); lval.write_cvalue(fx, operand.cast_pointer_to(to_layout)); } + Rvalue::Cast( + CastKind::PointerCoercion( + PointerCoercion::MutToConstPointer | PointerCoercion::ArrayToPointer, + ), + .., + ) => { + bug!( + "{:?} is for borrowck, and should never appear in codegen", + to_place_and_rval.1 + ); + } Rvalue::Cast( CastKind::IntToInt | CastKind::FloatToFloat From b147b6d03de918bfdf9bf9207a4a36379e917a1d Mon Sep 17 00:00:00 2001 From: Renato Lochetti Date: Wed, 19 Jun 2024 19:16:09 +0100 Subject: [PATCH 217/892] Don't lint implicit_return on proc macros --- clippy_lints/src/implicit_return.rs | 6 +++++- tests/ui/implicit_return.fixed | 13 ++++++++++++ tests/ui/implicit_return.rs | 13 ++++++++++++ tests/ui/implicit_return.stderr | 32 ++++++++++++++--------------- 4 files changed, 47 insertions(+), 17 deletions(-) diff --git a/clippy_lints/src/implicit_return.rs b/clippy_lints/src/implicit_return.rs index 2f543781c44c1..a102b434cfabb 100644 --- a/clippy_lints/src/implicit_return.rs +++ b/clippy_lints/src/implicit_return.rs @@ -1,7 +1,7 @@ use clippy_utils::diagnostics::span_lint_hir_and_then; use clippy_utils::source::{snippet_with_applicability, snippet_with_context, walk_span_to_context}; use clippy_utils::visitors::for_each_expr_without_closures; -use clippy_utils::{get_async_fn_body, is_async_fn}; +use clippy_utils::{get_async_fn_body, is_async_fn, is_from_proc_macro}; use core::ops::ControlFlow; use rustc_errors::Applicability; use rustc_hir::intravisit::FnKind; @@ -245,6 +245,10 @@ impl<'tcx> LateLintPass<'tcx> for ImplicitReturn { } else { body.value }; + + if is_from_proc_macro(cx, expr) { + return; + } lint_implicit_returns(cx, expr, expr.span.ctxt(), None); } } diff --git a/tests/ui/implicit_return.fixed b/tests/ui/implicit_return.fixed index 897f1b7661638..a6aac351e3290 100644 --- a/tests/ui/implicit_return.fixed +++ b/tests/ui/implicit_return.fixed @@ -1,7 +1,12 @@ +//@aux-build: proc_macros.rs + #![feature(lint_reasons)] #![warn(clippy::implicit_return)] #![allow(clippy::needless_return, clippy::needless_bool, unused, clippy::never_loop)] +extern crate proc_macros; +use proc_macros::with_span; + fn test_end_of_fn() -> bool { if true { // no error! @@ -137,3 +142,11 @@ fn check_expect() -> bool { #[expect(clippy::implicit_return)] true } + +with_span!( + span + + fn dont_lint_proc_macro(x: usize) -> usize{ + x + } +); diff --git a/tests/ui/implicit_return.rs b/tests/ui/implicit_return.rs index fcff67b58071b..757c49f5e1cdd 100644 --- a/tests/ui/implicit_return.rs +++ b/tests/ui/implicit_return.rs @@ -1,7 +1,12 @@ +//@aux-build: proc_macros.rs + #![feature(lint_reasons)] #![warn(clippy::implicit_return)] #![allow(clippy::needless_return, clippy::needless_bool, unused, clippy::never_loop)] +extern crate proc_macros; +use proc_macros::with_span; + fn test_end_of_fn() -> bool { if true { // no error! @@ -137,3 +142,11 @@ fn check_expect() -> bool { #[expect(clippy::implicit_return)] true } + +with_span!( + span + + fn dont_lint_proc_macro(x: usize) -> usize{ + x + } +); diff --git a/tests/ui/implicit_return.stderr b/tests/ui/implicit_return.stderr index 3ffed273e0f16..3d7bd408cb64a 100644 --- a/tests/ui/implicit_return.stderr +++ b/tests/ui/implicit_return.stderr @@ -1,5 +1,5 @@ error: missing `return` statement - --> tests/ui/implicit_return.rs:11:5 + --> tests/ui/implicit_return.rs:16:5 | LL | true | ^^^^ help: add `return` as shown: `return true` @@ -8,85 +8,85 @@ LL | true = help: to override `-D warnings` add `#[allow(clippy::implicit_return)]` error: missing `return` statement - --> tests/ui/implicit_return.rs:15:15 + --> tests/ui/implicit_return.rs:20:15 | LL | if true { true } else { false } | ^^^^ help: add `return` as shown: `return true` error: missing `return` statement - --> tests/ui/implicit_return.rs:15:29 + --> tests/ui/implicit_return.rs:20:29 | LL | if true { true } else { false } | ^^^^^ help: add `return` as shown: `return false` error: missing `return` statement - --> tests/ui/implicit_return.rs:21:17 + --> tests/ui/implicit_return.rs:26:17 | LL | true => false, | ^^^^^ help: add `return` as shown: `return false` error: missing `return` statement - --> tests/ui/implicit_return.rs:22:20 + --> tests/ui/implicit_return.rs:27:20 | LL | false => { true }, | ^^^^ help: add `return` as shown: `return true` error: missing `return` statement - --> tests/ui/implicit_return.rs:35:9 + --> tests/ui/implicit_return.rs:40:9 | LL | break true; | ^^^^^^^^^^ help: change `break` to `return` as shown: `return true` error: missing `return` statement - --> tests/ui/implicit_return.rs:42:13 + --> tests/ui/implicit_return.rs:47:13 | LL | break true; | ^^^^^^^^^^ help: change `break` to `return` as shown: `return true` error: missing `return` statement - --> tests/ui/implicit_return.rs:50:13 + --> tests/ui/implicit_return.rs:55:13 | LL | break true; | ^^^^^^^^^^ help: change `break` to `return` as shown: `return true` error: missing `return` statement - --> tests/ui/implicit_return.rs:68:18 + --> tests/ui/implicit_return.rs:73:18 | LL | let _ = || { true }; | ^^^^ help: add `return` as shown: `return true` error: missing `return` statement - --> tests/ui/implicit_return.rs:69:16 + --> tests/ui/implicit_return.rs:74:16 | LL | let _ = || true; | ^^^^ help: add `return` as shown: `return true` error: missing `return` statement - --> tests/ui/implicit_return.rs:77:5 + --> tests/ui/implicit_return.rs:82:5 | LL | format!("test {}", "test") | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: add `return` as shown: `return format!("test {}", "test")` error: missing `return` statement - --> tests/ui/implicit_return.rs:86:5 + --> tests/ui/implicit_return.rs:91:5 | LL | m!(true, false) | ^^^^^^^^^^^^^^^ help: add `return` as shown: `return m!(true, false)` error: missing `return` statement - --> tests/ui/implicit_return.rs:92:13 + --> tests/ui/implicit_return.rs:97:13 | LL | break true; | ^^^^^^^^^^ help: change `break` to `return` as shown: `return true` error: missing `return` statement - --> tests/ui/implicit_return.rs:97:17 + --> tests/ui/implicit_return.rs:102:17 | LL | break 'outer false; | ^^^^^^^^^^^^^^^^^^ help: change `break` to `return` as shown: `return false` error: missing `return` statement - --> tests/ui/implicit_return.rs:112:5 + --> tests/ui/implicit_return.rs:117:5 | LL | / loop { LL | | m!(true); @@ -101,7 +101,7 @@ LL + } | error: missing `return` statement - --> tests/ui/implicit_return.rs:126:5 + --> tests/ui/implicit_return.rs:131:5 | LL | true | ^^^^ help: add `return` as shown: `return true` From ea29d6ad0bfb2b1544566369746aeaa85b5f9de5 Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Mon, 17 Jun 2024 19:15:03 +0200 Subject: [PATCH 218/892] We can traverse bindings before `lower_match_tree` now --- .../rustc_mir_build/src/build/matches/mod.rs | 71 ++++++++--------- .../rustc_mir_build/src/build/matches/util.rs | 77 ++++++++++++++++--- 2 files changed, 98 insertions(+), 50 deletions(-) diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs index 68244136d1adf..f182e1c57f416 100644 --- a/compiler/rustc_mir_build/src/build/matches/mod.rs +++ b/compiler/rustc_mir_build/src/build/matches/mod.rs @@ -21,6 +21,7 @@ use rustc_span::symbol::Symbol; use rustc_span::{BytePos, Pos, Span}; use rustc_target::abi::VariantIdx; use tracing::{debug, instrument}; +use util::visit_bindings; // helper functions, broken out by category: mod simplify; @@ -725,55 +726,49 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { set_match_place: bool, ) -> BlockAnd<()> { let mut candidate = Candidate::new(initializer.clone(), irrefutable_pat, false, self); - let fake_borrow_temps = self.lower_match_tree( - block, - irrefutable_pat.span, - &initializer, - irrefutable_pat.span, - false, - &mut [&mut candidate], - ); // For matches and function arguments, the place that is being matched // can be set when creating the variables. But the place for // let PATTERN = ... might not even exist until we do the assignment. // so we set it here instead. if set_match_place { - let mut next = Some(&candidate); - while let Some(candidate_ref) = next.take() { - for binding in &candidate_ref.extra_data.bindings { + // `try_to_place` may fail if it is unable to resolve the given `PlaceBuilder` inside a + // closure. In this case, we don't want to include a scrutinee place. + // `scrutinee_place_builder` will fail for destructured assignments. This is because a + // closure only captures the precise places that it will read and as a result a closure + // may not capture the entire tuple/struct and rather have individual places that will + // be read in the final MIR. + // Example: + // ``` + // let foo = (0, 1); + // let c = || { + // let (v1, v2) = foo; + // }; + // ``` + if let Some(place) = initializer.try_to_place(self) { + visit_bindings(&[&mut candidate], |binding: &Binding<'_>| { let local = self.var_local_id(binding.var_id, OutsideGuard); - // `try_to_place` may fail if it is unable to resolve the given - // `PlaceBuilder` inside a closure. In this case, we don't want to include - // a scrutinee place. `scrutinee_place_builder` will fail for destructured - // assignments. This is because a closure only captures the precise places - // that it will read and as a result a closure may not capture the entire - // tuple/struct and rather have individual places that will be read in the - // final MIR. - // Example: - // ``` - // let foo = (0, 1); - // let c = || { - // let (v1, v2) = foo; - // }; - // ``` - if let Some(place) = initializer.try_to_place(self) { - let LocalInfo::User(BindingForm::Var(VarBindingForm { - opt_match_place: Some((ref mut match_place, _)), - .. - })) = **self.local_decls[local].local_info.as_mut().assert_crate_local() - else { - bug!("Let binding to non-user variable.") - }; + if let LocalInfo::User(BindingForm::Var(VarBindingForm { + opt_match_place: Some((ref mut match_place, _)), + .. + })) = **self.local_decls[local].local_info.as_mut().assert_crate_local() + { *match_place = Some(place); - } - } - // All of the subcandidates should bind the same locals, so we - // only visit the first one. - next = candidate_ref.subcandidates.get(0) + } else { + bug!("Let binding to non-user variable.") + }; + }); } } + let fake_borrow_temps = self.lower_match_tree( + block, + irrefutable_pat.span, + &initializer, + irrefutable_pat.span, + false, + &mut [&mut candidate], + ); self.bind_pattern( self.source_info(irrefutable_pat.span), candidate, diff --git a/compiler/rustc_mir_build/src/build/matches/util.rs b/compiler/rustc_mir_build/src/build/matches/util.rs index 50f4ca2d819d3..e0ba736f1989c 100644 --- a/compiler/rustc_mir_build/src/build/matches/util.rs +++ b/compiler/rustc_mir_build/src/build/matches/util.rs @@ -1,3 +1,5 @@ +use std::marker::PhantomData; + use crate::build::expr::as_place::{PlaceBase, PlaceBuilder}; use crate::build::matches::{Binding, Candidate, FlatPat, MatchPair, TestCase}; use crate::build::Builder; @@ -267,18 +269,6 @@ impl<'pat, 'tcx> MatchPair<'pat, 'tcx> { } } -pub(super) struct FakeBorrowCollector<'a, 'b, 'tcx> { - cx: &'a mut Builder<'b, 'tcx>, - /// Base of the scrutinee place. Used to distinguish bindings inside the scrutinee place from - /// bindings inside deref patterns. - scrutinee_base: PlaceBase, - /// Store for each place the kind of borrow to take. In case of conflicts, we take the strongest - /// borrow (i.e. Deep > Shallow). - /// Invariant: for any place in `fake_borrows`, all the prefixes of this place that are - /// dereferences are also borrowed with the same of stronger borrow kind. - fake_borrows: FxIndexMap, FakeBorrowKind>, -} - /// Determine the set of places that have to be stable across match guards. /// /// Returns a list of places that need a fake borrow along with a local to store it. @@ -342,6 +332,18 @@ pub(super) fn collect_fake_borrows<'tcx>( .collect() } +pub(super) struct FakeBorrowCollector<'a, 'b, 'tcx> { + cx: &'a mut Builder<'b, 'tcx>, + /// Base of the scrutinee place. Used to distinguish bindings inside the scrutinee place from + /// bindings inside deref patterns. + scrutinee_base: PlaceBase, + /// Store for each place the kind of borrow to take. In case of conflicts, we take the strongest + /// borrow (i.e. Deep > Shallow). + /// Invariant: for any place in `fake_borrows`, all the prefixes of this place that are + /// dereferences are also borrowed with the same of stronger borrow kind. + fake_borrows: FxIndexMap, FakeBorrowKind>, +} + impl<'a, 'b, 'tcx> FakeBorrowCollector<'a, 'b, 'tcx> { // Fake borrow this place and its dereference prefixes. fn fake_borrow(&mut self, place: Place<'tcx>, kind: FakeBorrowKind) { @@ -455,6 +457,57 @@ impl<'a, 'b, 'tcx> FakeBorrowCollector<'a, 'b, 'tcx> { } } +/// Visit all the bindings of these candidates. Because or-alternatives bind the same variables, we +/// only explore the first one of each or-pattern. +pub(super) fn visit_bindings<'tcx>( + candidates: &[&mut Candidate<'_, 'tcx>], + f: impl FnMut(&Binding<'tcx>), +) { + let mut visitor = BindingsVisitor { f, phantom: PhantomData }; + for candidate in candidates.iter() { + visitor.visit_candidate(candidate); + } +} + +pub(super) struct BindingsVisitor<'tcx, F> { + f: F, + phantom: PhantomData<&'tcx ()>, +} + +impl<'tcx, F> BindingsVisitor<'tcx, F> +where + F: FnMut(&Binding<'tcx>), +{ + fn visit_candidate(&mut self, candidate: &Candidate<'_, 'tcx>) { + for binding in &candidate.extra_data.bindings { + (self.f)(binding) + } + for match_pair in &candidate.match_pairs { + self.visit_match_pair(match_pair); + } + } + + fn visit_flat_pat(&mut self, flat_pat: &FlatPat<'_, 'tcx>) { + for binding in &flat_pat.extra_data.bindings { + (self.f)(binding) + } + for match_pair in &flat_pat.match_pairs { + self.visit_match_pair(match_pair); + } + } + + fn visit_match_pair(&mut self, match_pair: &MatchPair<'_, 'tcx>) { + if let TestCase::Or { pats, .. } = &match_pair.test_case { + // All the or-alternatives should bind the same locals, so we only visit the first one. + self.visit_flat_pat(&pats[0]) + } else { + for subpair in &match_pair.subpairs { + self.visit_match_pair(subpair); + } + } + } +} + #[must_use] pub(crate) fn ref_pat_borrow_kind(ref_mutability: Mutability) -> BorrowKind { match ref_mutability { From 012626b32bee88181cca63ef592cad83b19c8fda Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Mon, 17 Jun 2024 19:29:14 +0200 Subject: [PATCH 219/892] Only one caller of `lower_match_tree` was using the fake borrows --- .../rustc_mir_build/src/build/matches/mod.rs | 48 +++++++------------ 1 file changed, 17 insertions(+), 31 deletions(-) diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs index f182e1c57f416..e9fc9361a719e 100644 --- a/compiler/rustc_mir_build/src/build/matches/mod.rs +++ b/compiler/rustc_mir_build/src/build/matches/mod.rs @@ -315,12 +315,19 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let match_start_span = span.shrink_to_lo().to(scrutinee_span); - let fake_borrow_temps = self.lower_match_tree( + // The set of places that we are creating fake borrows of. If there are no match guards then + // we don't need any fake borrows, so don't track them. + let fake_borrow_temps: Vec<(Place<'tcx>, Local, FakeBorrowKind)> = if match_has_guard { + util::collect_fake_borrows(self, &candidates, scrutinee_span, scrutinee_place.base()) + } else { + Vec::new() + }; + + self.lower_match_tree( block, scrutinee_span, &scrutinee_place, match_start_span, - match_has_guard, &mut candidates, ); @@ -377,30 +384,14 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { /// /// Modifies `candidates` to store the bindings and type ascriptions for /// that candidate. - /// - /// Returns the places that need fake borrows because we bind or test them. fn lower_match_tree<'pat>( &mut self, block: BasicBlock, scrutinee_span: Span, scrutinee_place_builder: &PlaceBuilder<'tcx>, match_start_span: Span, - match_has_guard: bool, candidates: &mut [&mut Candidate<'pat, 'tcx>], - ) -> Vec<(Place<'tcx>, Local, FakeBorrowKind)> { - // The set of places that we are creating fake borrows of. If there are no match guards then - // we don't need any fake borrows, so don't track them. - let fake_borrows: Vec<(Place<'tcx>, Local, FakeBorrowKind)> = if match_has_guard { - util::collect_fake_borrows( - self, - candidates, - scrutinee_span, - scrutinee_place_builder.base(), - ) - } else { - Vec::new() - }; - + ) { // See the doc comment on `match_candidates` for why we have an // otherwise block. Match checking will ensure this is actually // unreachable. @@ -452,8 +443,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { previous_candidate = Some(leaf_candidate); }); } - - fake_borrows } /// Lower the bindings, guards and arm bodies of a `match` expression. @@ -761,18 +750,17 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } } - let fake_borrow_temps = self.lower_match_tree( + self.lower_match_tree( block, irrefutable_pat.span, &initializer, irrefutable_pat.span, - false, &mut [&mut candidate], ); self.bind_pattern( self.source_info(irrefutable_pat.span), candidate, - fake_borrow_temps.as_slice(), + &[], irrefutable_pat.span, None, false, @@ -1995,12 +1983,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let mut guard_candidate = Candidate::new(expr_place_builder.clone(), pat, false, self); let mut otherwise_candidate = Candidate::new(expr_place_builder.clone(), &wildcard, false, self); - let fake_borrow_temps = self.lower_match_tree( + self.lower_match_tree( block, pat.span, &expr_place_builder, pat.span, - false, &mut [&mut guard_candidate, &mut otherwise_candidate], ); let expr_place = expr_place_builder.try_to_place(self); @@ -2015,7 +2002,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let post_guard_block = self.bind_pattern( self.source_info(pat.span), guard_candidate, - fake_borrow_temps.as_slice(), + &[], expr_span, None, false, @@ -2490,19 +2477,18 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let pat = Pat { ty: pattern.ty, span: else_block_span, kind: PatKind::Wild }; let mut wildcard = Candidate::new(scrutinee.clone(), &pat, false, this); let mut candidate = Candidate::new(scrutinee.clone(), pattern, false, this); - let fake_borrow_temps = this.lower_match_tree( + this.lower_match_tree( block, initializer_span, &scrutinee, pattern.span, - false, &mut [&mut candidate, &mut wildcard], ); // This block is for the matching case let matching = this.bind_pattern( this.source_info(pattern.span), candidate, - fake_borrow_temps.as_slice(), + &[], initializer_span, None, true, @@ -2511,7 +2497,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let failure = this.bind_pattern( this.source_info(else_block_span), wildcard, - fake_borrow_temps.as_slice(), + &[], initializer_span, None, true, From cef49f73e76a5f133452b589caa179e4bea8fad2 Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Mon, 17 Jun 2024 19:39:09 +0200 Subject: [PATCH 220/892] Small dedup --- .../rustc_mir_build/src/build/matches/mod.rs | 33 +++++++++---------- 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs index e9fc9361a719e..3826f58a6c918 100644 --- a/compiler/rustc_mir_build/src/build/matches/mod.rs +++ b/compiler/rustc_mir_build/src/build/matches/mod.rs @@ -2059,14 +2059,15 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { return self.cfg.start_new_block(); } - self.ascribe_types( - block, - parent_data - .iter() - .flat_map(|d| &d.ascriptions) - .cloned() - .chain(candidate.extra_data.ascriptions), - ); + let ascriptions = parent_data + .iter() + .flat_map(|d| &d.ascriptions) + .cloned() + .chain(candidate.extra_data.ascriptions); + let bindings = + parent_data.iter().flat_map(|d| &d.bindings).chain(&candidate.extra_data.bindings); + + self.ascribe_types(block, ascriptions); // rust-lang/rust#27282: The `autoref` business deserves some // explanation here. @@ -2153,12 +2154,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { && let Some(guard) = arm.guard { let tcx = self.tcx; - let bindings = - parent_data.iter().flat_map(|d| &d.bindings).chain(&candidate.extra_data.bindings); self.bind_matched_candidate_for_guard(block, schedule_drops, bindings.clone()); - let guard_frame = - GuardFrame { locals: bindings.map(|b| GuardFrameLocal::new(b.var_id)).collect() }; + let guard_frame = GuardFrame { + locals: bindings.clone().map(|b| GuardFrameLocal::new(b.var_id)).collect(), + }; debug!("entering guard building context: {:?}", guard_frame); self.guard_context.push(guard_frame); @@ -2231,11 +2231,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // ``` // // and that is clearly not correct. - let by_value_bindings = parent_data - .iter() - .flat_map(|d| &d.bindings) - .chain(&candidate.extra_data.bindings) - .filter(|binding| matches!(binding.binding_mode.0, ByRef::No)); + let by_value_bindings = + bindings.filter(|binding| matches!(binding.binding_mode.0, ByRef::No)); // Read all of the by reference bindings to ensure that the // place they refer to can't be modified by the guard. for binding in by_value_bindings.clone() { @@ -2259,7 +2256,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { self.bind_matched_candidate_for_arm_body( block, schedule_drops, - parent_data.iter().flat_map(|d| &d.bindings).chain(&candidate.extra_data.bindings), + bindings, storages_alive, ); block From 878ccd22fa6562afd6658f6558632ba8953ae22a Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Mon, 17 Jun 2024 19:46:07 +0200 Subject: [PATCH 221/892] There's nothing to bind for a wildcard This commit was obtained by repeatedly inlining and simplifying. --- compiler/rustc_mir_build/src/build/matches/mod.rs | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs index 3826f58a6c918..17b5e1b495578 100644 --- a/compiler/rustc_mir_build/src/build/matches/mod.rs +++ b/compiler/rustc_mir_build/src/build/matches/mod.rs @@ -2491,14 +2491,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { true, ); // This block is for the failure case - let failure = this.bind_pattern( - this.source_info(else_block_span), - wildcard, - &[], - initializer_span, - None, - true, - ); + let failure = wildcard.pre_binding_block.unwrap(); // If branch coverage is enabled, record this branch. this.visit_coverage_conditional_let(pattern, matching, failure); From c0c6c32a45e9ef05d99459a77e39072524ed1dc4 Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Mon, 17 Jun 2024 20:08:05 +0200 Subject: [PATCH 222/892] Move `lower_match_tree` --- .../rustc_mir_build/src/build/matches/mod.rs | 129 +++++++++--------- 1 file changed, 64 insertions(+), 65 deletions(-) diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs index 17b5e1b495578..8531ea891d2e3 100644 --- a/compiler/rustc_mir_build/src/build/matches/mod.rs +++ b/compiler/rustc_mir_build/src/build/matches/mod.rs @@ -380,71 +380,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { .collect() } - /// Create the decision tree for the match expression, starting from `block`. - /// - /// Modifies `candidates` to store the bindings and type ascriptions for - /// that candidate. - fn lower_match_tree<'pat>( - &mut self, - block: BasicBlock, - scrutinee_span: Span, - scrutinee_place_builder: &PlaceBuilder<'tcx>, - match_start_span: Span, - candidates: &mut [&mut Candidate<'pat, 'tcx>], - ) { - // See the doc comment on `match_candidates` for why we have an - // otherwise block. Match checking will ensure this is actually - // unreachable. - let otherwise_block = self.cfg.start_new_block(); - - // This will generate code to test scrutinee_place and - // branch to the appropriate arm block - self.match_candidates(match_start_span, scrutinee_span, block, otherwise_block, candidates); - - let source_info = self.source_info(scrutinee_span); - - // Matching on a `scrutinee_place` with an uninhabited type doesn't - // generate any memory reads by itself, and so if the place "expression" - // contains unsafe operations like raw pointer dereferences or union - // field projections, we wouldn't know to require an `unsafe` block - // around a `match` equivalent to `std::intrinsics::unreachable()`. - // See issue #47412 for this hole being discovered in the wild. - // - // HACK(eddyb) Work around the above issue by adding a dummy inspection - // of `scrutinee_place`, specifically by applying `ReadForMatch`. - // - // NOTE: ReadForMatch also checks that the scrutinee is initialized. - // This is currently needed to not allow matching on an uninitialized, - // uninhabited value. If we get never patterns, those will check that - // the place is initialized, and so this read would only be used to - // check safety. - let cause_matched_place = FakeReadCause::ForMatchedPlace(None); - - if let Some(scrutinee_place) = scrutinee_place_builder.try_to_place(self) { - self.cfg.push_fake_read( - otherwise_block, - source_info, - cause_matched_place, - scrutinee_place, - ); - } - - self.cfg.terminate(otherwise_block, source_info, TerminatorKind::Unreachable); - - // Link each leaf candidate to the `pre_binding_block` of the next one. - let mut previous_candidate: Option<&mut Candidate<'_, '_>> = None; - - for candidate in candidates { - candidate.visit_leaves(|leaf_candidate| { - if let Some(ref mut prev) = previous_candidate { - assert!(leaf_candidate.false_edge_start_block.is_some()); - prev.next_candidate_start_block = leaf_candidate.false_edge_start_block; - } - previous_candidate = Some(leaf_candidate); - }); - } - } - /// Lower the bindings, guards and arm bodies of a `match` expression. /// /// The decision tree should have already been created @@ -1275,6 +1210,70 @@ pub(crate) struct ArmHasGuard(pub(crate) bool); // Main matching algorithm impl<'a, 'tcx> Builder<'a, 'tcx> { + /// The entrypoint of the matching algorithm. Create the decision tree for the match expression, + /// starting from `block`. + /// + /// Modifies `candidates` to store the bindings and type ascriptions for + /// that candidate. + fn lower_match_tree<'pat>( + &mut self, + block: BasicBlock, + scrutinee_span: Span, + scrutinee_place_builder: &PlaceBuilder<'tcx>, + match_start_span: Span, + candidates: &mut [&mut Candidate<'pat, 'tcx>], + ) { + // See the doc comment on `match_candidates` for why we have an + // otherwise block. Match checking will ensure this is actually + // unreachable. + let otherwise_block = self.cfg.start_new_block(); + + // This will generate code to test scrutinee_place and branch to the appropriate arm block + self.match_candidates(match_start_span, scrutinee_span, block, otherwise_block, candidates); + + let source_info = self.source_info(scrutinee_span); + + // Matching on a `scrutinee_place` with an uninhabited type doesn't + // generate any memory reads by itself, and so if the place "expression" + // contains unsafe operations like raw pointer dereferences or union + // field projections, we wouldn't know to require an `unsafe` block + // around a `match` equivalent to `std::intrinsics::unreachable()`. + // See issue #47412 for this hole being discovered in the wild. + // + // HACK(eddyb) Work around the above issue by adding a dummy inspection + // of `scrutinee_place`, specifically by applying `ReadForMatch`. + // + // NOTE: ReadForMatch also checks that the scrutinee is initialized. + // This is currently needed to not allow matching on an uninitialized, + // uninhabited value. If we get never patterns, those will check that + // the place is initialized, and so this read would only be used to + // check safety. + let cause_matched_place = FakeReadCause::ForMatchedPlace(None); + + if let Some(scrutinee_place) = scrutinee_place_builder.try_to_place(self) { + self.cfg.push_fake_read( + otherwise_block, + source_info, + cause_matched_place, + scrutinee_place, + ); + } + + self.cfg.terminate(otherwise_block, source_info, TerminatorKind::Unreachable); + + // Link each leaf candidate to the `false_edge_start_block` of the next one. + let mut previous_candidate: Option<&mut Candidate<'_, '_>> = None; + for candidate in candidates { + candidate.visit_leaves(|leaf_candidate| { + if let Some(ref mut prev) = previous_candidate { + assert!(leaf_candidate.false_edge_start_block.is_some()); + prev.next_candidate_start_block = leaf_candidate.false_edge_start_block; + } + previous_candidate = Some(leaf_candidate); + }); + } + } + /// The main match algorithm. It begins with a set of candidates /// `candidates` and has the job of generating code to determine /// which of these candidates, if any, is the correct one. The From 8556604bc6f282fbc9442d91b2929ea3e354ef88 Mon Sep 17 00:00:00 2001 From: beetrees Date: Tue, 18 Jun 2024 17:42:32 +0100 Subject: [PATCH 223/892] Fix varargs support on `aarch64-apple-darwin` --- src/abi/mod.rs | 135 +++++++++++++++++++++++++++++++++++++------------ 1 file changed, 104 insertions(+), 31 deletions(-) diff --git a/src/abi/mod.rs b/src/abi/mod.rs index 695dbaf2804b1..0d7eee7afb41e 100644 --- a/src/abi/mod.rs +++ b/src/abi/mod.rs @@ -5,8 +5,9 @@ mod pass_mode; mod returning; use std::borrow::Cow; +use std::mem; -use cranelift_codegen::ir::SigRef; +use cranelift_codegen::ir::{ArgumentPurpose, SigRef}; use cranelift_codegen::isa::CallConv; use cranelift_module::ModuleError; use rustc_codegen_ssa::errors::CompilerBuiltinsCannotCall; @@ -17,7 +18,7 @@ use rustc_middle::ty::TypeVisitableExt; use rustc_monomorphize::is_call_from_compiler_builtins_to_upstream_monomorphization; use rustc_session::Session; use rustc_span::source_map::Spanned; -use rustc_target::abi::call::{Conv, FnAbi}; +use rustc_target::abi::call::{Conv, FnAbi, PassMode}; use rustc_target::spec::abi::Abi; use self::pass_mode::*; @@ -487,6 +488,7 @@ pub(crate) fn codegen_terminator_call<'tcx>( let args = args; assert_eq!(fn_abi.args.len(), args.len()); + #[derive(Copy, Clone)] enum CallTarget { Direct(FuncRef), Indirect(SigRef, Value), @@ -532,7 +534,7 @@ pub(crate) fn codegen_terminator_call<'tcx>( }; self::returning::codegen_with_call_return_arg(fx, &fn_abi.ret, ret_place, |fx, return_ptr| { - let call_args = return_ptr + let mut call_args = return_ptr .into_iter() .chain(first_arg_override.into_iter()) .chain( @@ -545,47 +547,118 @@ pub(crate) fn codegen_terminator_call<'tcx>( ) .collect::>(); - let call_inst = match func_ref { + // FIXME: Find a cleaner way to support varargs. + if fn_abi.c_variadic { + adjust_call_for_c_variadic(fx, &fn_abi, source_info, func_ref, &mut call_args); + } + + match func_ref { CallTarget::Direct(func_ref) => fx.bcx.ins().call(func_ref, &call_args), CallTarget::Indirect(sig, func_ptr) => { fx.bcx.ins().call_indirect(sig, func_ptr, &call_args) } + } + }); + + if let Some(dest) = target { + let ret_block = fx.get_block(dest); + fx.bcx.ins().jump(ret_block, &[]); + } else { + fx.bcx.ins().trap(TrapCode::UnreachableCodeReached); + } + + fn adjust_call_for_c_variadic<'tcx>( + fx: &mut FunctionCx<'_, '_, 'tcx>, + fn_abi: &FnAbi<'tcx, Ty<'tcx>>, + source_info: mir::SourceInfo, + target: CallTarget, + call_args: &mut Vec, + ) { + if fn_abi.conv != Conv::C { + fx.tcx.dcx().span_fatal( + source_info.span, + format!("Variadic call for non-C abi {:?}", fn_abi.conv), + ); + } + let sig_ref = match target { + CallTarget::Direct(func_ref) => fx.bcx.func.dfg.ext_funcs[func_ref].signature, + CallTarget::Indirect(sig_ref, _) => sig_ref, }; + // `mem::take()` the `params` so that `fx.bcx` can be used below. + let mut abi_params = mem::take(&mut fx.bcx.func.dfg.signatures[sig_ref].params); + + // Recalculate the parameters in the signature to ensure the signature contains the variadic arguments. + let has_return_arg = matches!(fn_abi.ret.mode, PassMode::Indirect { .. }); + // Drop everything except the return argument (if there is one). + abi_params.truncate(if has_return_arg { 1 } else { 0 }); + // Add the fixed arguments. + abi_params.extend( + fn_abi.args[..fn_abi.fixed_count as usize] + .iter() + .flat_map(|arg_abi| arg_abi.get_abi_param(fx.tcx).into_iter()), + ); + let fixed_arg_count = abi_params.len(); + // Add the variadic arguments. + abi_params.extend( + fn_abi.args[fn_abi.fixed_count as usize..] + .iter() + .flat_map(|arg_abi| arg_abi.get_abi_param(fx.tcx).into_iter()), + ); - // FIXME find a cleaner way to support varargs - if fn_sig.c_variadic() { - if !matches!(fn_sig.abi(), Abi::C { .. }) { + if fx.tcx.sess.target.is_like_osx && fx.tcx.sess.target.arch == "aarch64" { + // Add any padding arguments needed for Apple AArch64. + // There's no need to pad the argument list unless variadic arguments are actually being + // passed. + if abi_params.len() > fixed_arg_count { + // 128-bit integers take 2 registers, and everything else takes 1. + // FIXME: Add support for non-integer types + // This relies on the checks below to ensure all arguments are integer types and + // that the ABI is "C". + // The return argument isn't counted as it goes in its own dedicated register. + let integer_registers_used: usize = abi_params + [if has_return_arg { 1 } else { 0 }..fixed_arg_count] + .iter() + .map(|arg| if arg.value_type.bits() == 128 { 2 } else { 1 }) + .sum(); + // The ABI uses 8 registers before it starts pushing arguments to the stack. Pad out + // the registers if needed to ensure the variadic arguments are passed on the stack. + if integer_registers_used < 8 { + abi_params.splice( + fixed_arg_count..fixed_arg_count, + (integer_registers_used..8).map(|_| AbiParam::new(types::I64)), + ); + call_args.splice( + fixed_arg_count..fixed_arg_count, + (integer_registers_used..8).map(|_| fx.bcx.ins().iconst(types::I64, 0)), + ); + } + } + + // `StructArgument` is not currently used by the `aarch64` ABI, and is therefore not + // handled when calculating how many padding arguments to use. Assert that this remains + // the case. + assert!(abi_params.iter().all(|param| matches!( + param.purpose, + // The only purposes used are `Normal` and `StructReturn`. + ArgumentPurpose::Normal | ArgumentPurpose::StructReturn + ))); + } + + // Check all parameters are integers. + for param in abi_params.iter() { + if !param.value_type.is_int() { + // FIXME: Set %al to upperbound on float args once floats are supported. fx.tcx.dcx().span_fatal( source_info.span, - format!("Variadic call for non-C abi {:?}", fn_sig.abi()), + format!("Non int ty {:?} for variadic call", param.value_type), ); } - let sig_ref = fx.bcx.func.dfg.call_signature(call_inst).unwrap(); - let abi_params = call_args - .into_iter() - .map(|arg| { - let ty = fx.bcx.func.dfg.value_type(arg); - if !ty.is_int() { - // FIXME set %al to upperbound on float args once floats are supported - fx.tcx.dcx().span_fatal( - source_info.span, - format!("Non int ty {:?} for variadic call", ty), - ); - } - AbiParam::new(ty) - }) - .collect::>(); - fx.bcx.func.dfg.signatures[sig_ref].params = abi_params; } - call_inst - }); + assert_eq!(abi_params.len(), call_args.len()); - if let Some(dest) = target { - let ret_block = fx.get_block(dest); - fx.bcx.ins().jump(ret_block, &[]); - } else { - fx.bcx.ins().trap(TrapCode::UnreachableCodeReached); + // Put the `AbiParam`s back in the signature. + fx.bcx.func.dfg.signatures[sig_ref].params = abi_params; } } From b0fcf2e27aac8d5eae00b7236bbdba7f73ce03ab Mon Sep 17 00:00:00 2001 From: beetrees Date: Tue, 18 Jun 2024 17:43:18 +0100 Subject: [PATCH 224/892] Add `aarch64-apple-darwin` to CI --- .github/workflows/main.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index a0c7ccdec0d59..1fc7087170065 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -66,6 +66,9 @@ jobs: env: TARGET_TRIPLE: aarch64-unknown-linux-gnu apt_deps: gcc-aarch64-linux-gnu qemu-user + - os: macos-latest + env: + TARGET_TRIPLE: aarch64-apple-darwin - os: ubuntu-latest env: TARGET_TRIPLE: s390x-unknown-linux-gnu @@ -214,6 +217,9 @@ jobs: - os: macos-latest env: TARGET_TRIPLE: x86_64-apple-darwin + - os: macos-latest + env: + TARGET_TRIPLE: aarch64-apple-darwin # cross-compile from Linux to Windows using mingw - os: ubuntu-latest env: From 8c5d84d102003f3de9b244d3fb474a5943e5f0f4 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 20 Jun 2024 05:04:30 +1000 Subject: [PATCH 225/892] Add blank lines after module-level `//!` comments. Most modules have such a blank line, but some don't. Inserting the blank line makes it clearer that the `//!` comments are describing the entire module, rather than the `use` declaration(s) that immediately follows. --- tests/lang_tests_common.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/lang_tests_common.rs b/tests/lang_tests_common.rs index d321ffc8ff544..09307836fd424 100644 --- a/tests/lang_tests_common.rs +++ b/tests/lang_tests_common.rs @@ -1,4 +1,5 @@ //! The common code for `tests/lang_tests_*.rs` + use std::{ env::{self, current_dir}, path::{Path, PathBuf}, From d356c6804353f9130189fe72071481120f7bc232 Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Sun, 7 Apr 2024 04:08:25 -0400 Subject: [PATCH 226/892] Update documentation for `hint::assert_unchecked` Rearrange the sections and add an example to `core::hint::assert_unchecked`. --- library/core/src/hint.rs | 93 +++++++++++++++++++++++++++++++--------- 1 file changed, 73 insertions(+), 20 deletions(-) diff --git a/library/core/src/hint.rs b/library/core/src/hint.rs index 6e2d88c6b8337..b8db4ad8237bd 100644 --- a/library/core/src/hint.rs +++ b/library/core/src/hint.rs @@ -111,36 +111,89 @@ pub const unsafe fn unreachable_unchecked() -> ! { /// Makes a *soundness* promise to the compiler that `cond` holds. /// -/// This may allow the optimizer to simplify things, -/// but it might also make the generated code slower. -/// Either way, calling it will most likely make compilation take longer. +/// This may allow the optimizer to simplify things, but it might also make the generated code +/// slower. Either way, calling it will most likely make compilation take longer. /// -/// This is a situational tool for micro-optimization, and is allowed to do nothing. -/// Any use should come with a repeatable benchmark to show the value -/// and allow removing it later should the optimizer get smarter and no longer need it. +/// You may know this from other places as +/// [`llvm.assume`](https://llvm.org/docs/LangRef.html#llvm-assume-intrinsic) or, in C, +/// [`__builtin_assume`](https://clang.llvm.org/docs/LanguageExtensions.html#builtin-assume). /// -/// The more complicated the condition the less likely this is to be fruitful. -/// For example, `assert_unchecked(foo.is_sorted())` is a complex enough value -/// that the compiler is unlikely to be able to take advantage of it. +/// This promotes a correctness requirement to a soundness requirement. Don't do that without +/// very good reason. /// -/// There's also no need to `assert_unchecked` basic properties of things. For -/// example, the compiler already knows the range of `count_ones`, so there's no -/// benefit to `let n = u32::count_ones(x); assert_unchecked(n <= u32::BITS);`. +/// # Usage /// -/// If ever you're tempted to write `assert_unchecked(false)`, then you're -/// actually looking for [`unreachable_unchecked()`]. +/// This is a situational tool for micro-optimization, and is allowed to do nothing. Any use +/// should come with a repeatable benchmark to show the value, with the expectation to drop it +/// later should the optimizer get smarter and no longer need it. /// -/// You may know this from other places -/// as [`llvm.assume`](https://llvm.org/docs/LangRef.html#llvm-assume-intrinsic) -/// or [`__builtin_assume`](https://clang.llvm.org/docs/LanguageExtensions.html#builtin-assume). +/// The more complicated the condition, the less likely this is to be useful. For example, +/// `assert_unchecked(foo.is_sorted())` is a complex enough value that the compiler is unlikely +/// to be able to take advantage of it. /// -/// This promotes a correctness requirement to a soundness requirement. -/// Don't do that without very good reason. +/// There's also no need to `assert_unchecked` basic properties of things. For example, the +/// compiler already knows the range of `count_ones`, so there is no benefit to +/// `let n = u32::count_ones(x); assert_unchecked(n <= u32::BITS);`. +/// +/// `assert_unchecked` is logically equivalent to `if !cond { unreachable_unchecked(); }`. If +/// ever you are tempted to write `assert_unchecked(false)`, you should instead use +/// [`unreachable_unchecked()`] directly. /// /// # Safety /// -/// `cond` must be `true`. It's immediate UB to call this with `false`. +/// `cond` must be `true`. It is immediate UB to call this with `false`. +/// +/// # Example +/// +/// ``` +/// #![feature(hint_assert_unchecked)] +/// +/// use core::hint; +/// +/// /// # Safety +/// /// +/// /// `p` must be nonnull and valid +/// pub unsafe fn next_value(p: *const i32) -> i32 { +/// // SAFETY: caller invariants guarantee that `p` is not null +/// unsafe { hint::assert_unchecked(!p.is_null()) } +/// +/// if p.is_null() { +/// return -1; +/// } else { +/// // SAFETY: caller invariants guarantee that `p` is valid +/// unsafe { *p + 1 } +/// } +/// } +/// ``` +/// +/// Without the `assert_unchecked`, the above function produces the following with optimizations +/// enabled: +/// +/// ```asm +/// next_value: +/// test rdi, rdi +/// je .LBB0_1 +/// mov eax, dword ptr [rdi] +/// inc eax +/// ret +/// .LBB0_1: +/// mov eax, -1 +/// ret +/// ``` +/// +/// Adding the assertion allows the optimizer to remove the extra check: +/// +/// ```asm +/// next_value: +/// mov eax, dword ptr [rdi] +/// inc eax +/// ret +/// ``` /// +/// This example is quite unlike anything that would be used in the real world: it is redundant +/// to put an an assertion right next to code that checks the same thing, and dereferencing a +/// pointer already has the builtin assumption that it is nonnull. However, it illustrates the +/// kind of changes the optimizer can make even when the behavior is less obviously related. #[inline(always)] #[doc(alias = "assume")] #[track_caller] From 5745c220e65a83436bb0bf855dcf83aebffe8c73 Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Sun, 7 Apr 2024 04:30:49 -0400 Subject: [PATCH 227/892] Stabilize `hint_assert_unchecked` Make both `hint_assert_unchecked` and `const_hint_assert_unchecked` stable as `hint_assert_unchecked`. --- library/alloc/src/lib.rs | 1 - library/core/src/hint.rs | 8 +++----- library/core/src/intrinsics.rs | 2 +- library/core/src/lib.rs | 1 - library/std/src/lib.rs | 1 - tests/ui/consts/const-assert-unchecked-ub.rs | 6 +----- tests/ui/consts/const-assert-unchecked-ub.stderr | 2 +- 7 files changed, 6 insertions(+), 15 deletions(-) diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs index 895d1b8d59f2c..095e13ee98c98 100644 --- a/library/alloc/src/lib.rs +++ b/library/alloc/src/lib.rs @@ -126,7 +126,6 @@ #![feature(fmt_internals)] #![feature(fn_traits)] #![feature(hasher_prefixfree_extras)] -#![feature(hint_assert_unchecked)] #![feature(inplace_iteration)] #![feature(iter_advance_by)] #![feature(iter_next_chunk)] diff --git a/library/core/src/hint.rs b/library/core/src/hint.rs index b8db4ad8237bd..e637baf826ff2 100644 --- a/library/core/src/hint.rs +++ b/library/core/src/hint.rs @@ -146,8 +146,6 @@ pub const unsafe fn unreachable_unchecked() -> ! { /// # Example /// /// ``` -/// #![feature(hint_assert_unchecked)] -/// /// use core::hint; /// /// /// # Safety @@ -194,11 +192,11 @@ pub const unsafe fn unreachable_unchecked() -> ! { /// to put an an assertion right next to code that checks the same thing, and dereferencing a /// pointer already has the builtin assumption that it is nonnull. However, it illustrates the /// kind of changes the optimizer can make even when the behavior is less obviously related. +#[track_caller] #[inline(always)] #[doc(alias = "assume")] -#[track_caller] -#[unstable(feature = "hint_assert_unchecked", issue = "119131")] -#[rustc_const_unstable(feature = "const_hint_assert_unchecked", issue = "119131")] +#[stable(feature = "hint_assert_unchecked", since = "CURRENT_RUSTC_VERSION")] +#[rustc_const_stable(feature = "hint_assert_unchecked", since = "CURRENT_RUSTC_VERSION")] pub const unsafe fn assert_unchecked(cond: bool) { // SAFETY: The caller promised `cond` is true. unsafe { diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs index 6b5054a9f0612..598b7ac0f82c4 100644 --- a/library/core/src/intrinsics.rs +++ b/library/core/src/intrinsics.rs @@ -959,7 +959,7 @@ extern "rust-intrinsic" { /// not be used if the invariant can be discovered by the optimizer on its /// own, or if it does not enable any significant optimizations. /// -/// This intrinsic does not have a stable counterpart. +/// The stabilized version of this intrinsic is [`core::hint::assert_unchecked`]. #[rustc_const_stable(feature = "const_assume", since = "1.77.0")] #[rustc_nounwind] #[unstable(feature = "core_intrinsics", issue = "none")] diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index ef28bc99c4fc8..abd8e1d1d0b2e 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -130,7 +130,6 @@ #![feature(const_fmt_arguments_new)] #![feature(const_hash)] #![feature(const_heap)] -#![feature(const_hint_assert_unchecked)] #![feature(const_index_range_slice_index)] #![feature(const_int_from_str)] #![feature(const_intrinsic_copy)] diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index 1c226f9f08f10..1fcfbdcd12dfb 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -335,7 +335,6 @@ #![feature(fmt_internals)] #![feature(hasher_prefixfree_extras)] #![feature(hashmap_internals)] -#![feature(hint_assert_unchecked)] #![feature(ip)] #![feature(maybe_uninit_slice)] #![feature(maybe_uninit_uninit_array)] diff --git a/tests/ui/consts/const-assert-unchecked-ub.rs b/tests/ui/consts/const-assert-unchecked-ub.rs index 5c05b813048b8..ffc02eedcb7a7 100644 --- a/tests/ui/consts/const-assert-unchecked-ub.rs +++ b/tests/ui/consts/const-assert-unchecked-ub.rs @@ -1,10 +1,6 @@ -#![feature(hint_assert_unchecked)] -#![feature(const_hint_assert_unchecked)] - const _: () = unsafe { let n = u32::MAX.count_ones(); std::hint::assert_unchecked(n < 32); //~ ERROR evaluation of constant value failed }; -fn main() { -} +fn main() {} diff --git a/tests/ui/consts/const-assert-unchecked-ub.stderr b/tests/ui/consts/const-assert-unchecked-ub.stderr index 3957a3b1c246b..468f15f34728f 100644 --- a/tests/ui/consts/const-assert-unchecked-ub.stderr +++ b/tests/ui/consts/const-assert-unchecked-ub.stderr @@ -1,5 +1,5 @@ error[E0080]: evaluation of constant value failed - --> $DIR/const-assert-unchecked-ub.rs:6:5 + --> $DIR/const-assert-unchecked-ub.rs:3:5 | LL | std::hint::assert_unchecked(n < 32); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `assume` called with `false` From 9749d990ed6e8f471eab13c6d7bb6868783f2143 Mon Sep 17 00:00:00 2001 From: Kisaragi Marine Date: Thu, 20 Jun 2024 11:18:25 +0900 Subject: [PATCH 228/892] resolve `clippy::invalid_paths` on `bool::then` --- clippy_lints/src/utils/internal_lints/invalid_paths.rs | 1 + clippy_utils/src/paths.rs | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/clippy_lints/src/utils/internal_lints/invalid_paths.rs b/clippy_lints/src/utils/internal_lints/invalid_paths.rs index c62ae8d718dba..0beb0bb8ed4c1 100644 --- a/clippy_lints/src/utils/internal_lints/invalid_paths.rs +++ b/clippy_lints/src/utils/internal_lints/invalid_paths.rs @@ -69,6 +69,7 @@ pub fn check_path(cx: &LateContext<'_>, path: &[&str]) -> bool { SimplifiedType::Float(FloatTy::F64), SimplifiedType::Slice, SimplifiedType::Str, + SimplifiedType::Bool, ] .iter() .flat_map(|&ty| cx.tcx.incoherent_impls(ty).into_iter()) diff --git a/clippy_utils/src/paths.rs b/clippy_utils/src/paths.rs index 9bf068ee3cdee..3f66813801dc0 100644 --- a/clippy_utils/src/paths.rs +++ b/clippy_utils/src/paths.rs @@ -110,5 +110,4 @@ pub const VEC_POP: [&str; 4] = ["alloc", "vec", "Vec", "pop"]; pub const WAKER: [&str; 4] = ["core", "task", "wake", "Waker"]; pub const OPTION_UNWRAP: [&str; 4] = ["core", "option", "Option", "unwrap"]; pub const OPTION_EXPECT: [&str; 4] = ["core", "option", "Option", "expect"]; -#[expect(clippy::invalid_paths)] // not sure why it thinks this, it works so pub const BOOL_THEN: [&str; 4] = ["core", "bool", "", "then"]; From 3baafd2e8c385c6c976e628a1689fa9033345502 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 20 Jun 2024 04:25:17 +0000 Subject: [PATCH 229/892] Fix `...` in multline code-skips in suggestions When we have long code skips, we write `...` in the line number gutter. For suggestions, we were "centering" the `...` with the line, but that was consistent with what we do in every other case. --- tests/ui/bind_instead_of_map_multipart.stderr | 2 +- tests/ui/needless_collect_indirect.stderr | 2 +- tests/ui/needless_late_init.stderr | 2 +- tests/ui/needless_return.stderr | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/ui/bind_instead_of_map_multipart.stderr b/tests/ui/bind_instead_of_map_multipart.stderr index 73255651abea7..b15857c325ae5 100644 --- a/tests/ui/bind_instead_of_map_multipart.stderr +++ b/tests/ui/bind_instead_of_map_multipart.stderr @@ -62,7 +62,7 @@ LL | } LL | match s.len() { LL ~ 10 => 2, LL | 20 => { - ... +... LL | if foo() { LL ~ return 20; LL | } diff --git a/tests/ui/needless_collect_indirect.stderr b/tests/ui/needless_collect_indirect.stderr index 0cce718a1ac7a..f25c029375455 100644 --- a/tests/ui/needless_collect_indirect.stderr +++ b/tests/ui/needless_collect_indirect.stderr @@ -212,7 +212,7 @@ help: check if the original Iterator contains an element instead of collecting t | LL ~ LL | - ... +... LL | // Do lint LL ~ vec.iter().map(|k| k * k).any(|x| x == n); | diff --git a/tests/ui/needless_late_init.stderr b/tests/ui/needless_late_init.stderr index ce64861fa40a7..de048091cfbe5 100644 --- a/tests/ui/needless_late_init.stderr +++ b/tests/ui/needless_late_init.stderr @@ -215,7 +215,7 @@ help: move the declaration `x` here | LL ~ LL | // types that should be considered insignificant - ... +... LL | let y = Box::new(4); LL ~ let x = SignificantDrop; | diff --git a/tests/ui/needless_return.stderr b/tests/ui/needless_return.stderr index bf5a89d8b75d0..b49f199ba5ab9 100644 --- a/tests/ui/needless_return.stderr +++ b/tests/ui/needless_return.stderr @@ -518,7 +518,7 @@ help: remove `return` | LL ~ 10 LL | }, - ... +... LL | }, LL ~ } | From 68c84b612b370c292e9ad15acca7e16fa3112ad6 Mon Sep 17 00:00:00 2001 From: Tobias Decking Date: Sat, 15 Jun 2024 14:43:29 +0200 Subject: [PATCH 230/892] Implement LLVM x86 bmi intrinsics --- src/tools/miri/src/shims/x86/bmi.rs | 108 +++++++++ src/tools/miri/src/shims/x86/mod.rs | 6 + .../pass/shims/x86/intrinsics-x86-bmi.rs | 216 ++++++++++++++++++ 3 files changed, 330 insertions(+) create mode 100644 src/tools/miri/src/shims/x86/bmi.rs create mode 100644 src/tools/miri/tests/pass/shims/x86/intrinsics-x86-bmi.rs diff --git a/src/tools/miri/src/shims/x86/bmi.rs b/src/tools/miri/src/shims/x86/bmi.rs new file mode 100644 index 0000000000000..e70757f4397ee --- /dev/null +++ b/src/tools/miri/src/shims/x86/bmi.rs @@ -0,0 +1,108 @@ +use rustc_span::Symbol; +use rustc_target::spec::abi::Abi; + +use crate::*; + +impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {} +pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { + fn emulate_x86_bmi_intrinsic( + &mut self, + link_name: Symbol, + abi: Abi, + args: &[OpTy<'tcx>], + dest: &MPlaceTy<'tcx>, + ) -> InterpResult<'tcx, EmulateItemResult> { + let this = self.eval_context_mut(); + + // Prefix should have already been checked. + let unprefixed_name = link_name.as_str().strip_prefix("llvm.x86.bmi.").unwrap(); + + // The intrinsics are suffixed with the bit size of their operands. + let (is_64_bit, unprefixed_name) = if unprefixed_name.ends_with("64") { + (true, unprefixed_name.strip_suffix(".64").unwrap_or("")) + } else { + (false, unprefixed_name.strip_suffix(".32").unwrap_or("")) + }; + + // All intrinsics of the "bmi" namespace belong to the "bmi2" ISA extension. + // The exception is "bextr", which belongs to "bmi1". + let target_feature = if unprefixed_name == "bextr" { "bmi1" } else { "bmi2" }; + this.expect_target_feature_for_intrinsic(link_name, target_feature)?; + + if is_64_bit && this.tcx.sess.target.arch != "x86_64" { + return Ok(EmulateItemResult::NotSupported); + } + + let [left, right] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let left = this.read_scalar(left)?; + let right = this.read_scalar(right)?; + + let left = if is_64_bit { left.to_u64()? } else { u64::from(left.to_u32()?) }; + let right = if is_64_bit { right.to_u64()? } else { u64::from(right.to_u32()?) }; + + let result = match unprefixed_name { + // Extract a contigous range of bits from an unsigned integer. + // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_bextr_u32 + "bextr" => { + let start = u32::try_from(right & 0xff).unwrap(); + let len = u32::try_from((right >> 8) & 0xff).unwrap(); + let shifted = left.checked_shr(start).unwrap_or(0); + // Keep the `len` lowest bits of `shifted`, or all bits if `len` is too big. + if len >= 64 { shifted } else { shifted & 1u64.wrapping_shl(len).wrapping_sub(1) } + } + // Create a copy of an unsigned integer with bits above a certain index cleared. + // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_bzhi_u32 + "bzhi" => { + let index = u32::try_from(right & 0xff).unwrap(); + // Keep the `index` lowest bits of `left`, or all bits if `index` is too big. + if index >= 64 { left } else { left & 1u64.wrapping_shl(index).wrapping_sub(1) } + } + // Extract bit values of an unsigned integer at positions marked by a mask. + // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_pext_u32 + "pext" => { + let mut mask = right; + let mut i = 0u32; + let mut result = 0; + // Iterate over the mask one 1-bit at a time, from + // the least significant bit to the most significant bit. + while mask != 0 { + // Extract the bit marked by the mask's least significant set bit + // and put it at position `i` of the result. + result |= u64::from(left & (1 << mask.trailing_zeros()) != 0) << i; + i = i.wrapping_add(1); + // Clear the least significant set bit. + mask &= mask.wrapping_sub(1); + } + result + } + // Deposit bit values of an unsigned integer to positions marked by a mask. + // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_pdep_u32 + "pdep" => { + let mut mask = right; + let mut set = left; + let mut result = 0; + // Iterate over the mask one 1-bit at a time, from + // the least significant bit to the most significant bit. + while mask != 0 { + // Put rightmost bit of `set` at the position of the current `mask` bit. + result |= (set & 1) << mask.trailing_zeros(); + // Go to next bit of `set`. + set >>= 1; + // Clear the least significant set bit. + mask &= mask.wrapping_sub(1); + } + result + } + _ => return Ok(EmulateItemResult::NotSupported), + }; + + let result = if is_64_bit { + Scalar::from_u64(result) + } else { + Scalar::from_u32(u32::try_from(result).unwrap()) + }; + this.write_scalar(result, dest)?; + + Ok(EmulateItemResult::NeedsReturn) + } +} diff --git a/src/tools/miri/src/shims/x86/mod.rs b/src/tools/miri/src/shims/x86/mod.rs index b71aec02166be..704c45fdd6d39 100644 --- a/src/tools/miri/src/shims/x86/mod.rs +++ b/src/tools/miri/src/shims/x86/mod.rs @@ -14,6 +14,7 @@ use helpers::bool_to_simd_element; mod aesni; mod avx; mod avx2; +mod bmi; mod sse; mod sse2; mod sse3; @@ -113,6 +114,11 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { pclmulqdq(this, left, right, imm, dest)?; } + name if name.starts_with("bmi.") => { + return bmi::EvalContextExt::emulate_x86_bmi_intrinsic( + this, link_name, abi, args, dest, + ); + } name if name.starts_with("sse.") => { return sse::EvalContextExt::emulate_x86_sse_intrinsic( this, link_name, abi, args, dest, diff --git a/src/tools/miri/tests/pass/shims/x86/intrinsics-x86-bmi.rs b/src/tools/miri/tests/pass/shims/x86/intrinsics-x86-bmi.rs new file mode 100644 index 0000000000000..33424117c4542 --- /dev/null +++ b/src/tools/miri/tests/pass/shims/x86/intrinsics-x86-bmi.rs @@ -0,0 +1,216 @@ +// Ignore everything except x86 and x86_64 +// Any new targets that are added to CI should be ignored here. +// (We cannot use `cfg`-based tricks here since the `target-feature` flags below only work on x86.) +//@ignore-target-aarch64 +//@ignore-target-arm +//@ignore-target-avr +//@ignore-target-s390x +//@ignore-target-thumbv7em +//@ignore-target-wasm32 +//@compile-flags: -C target-feature=+bmi1,+bmi2 + +#[cfg(target_arch = "x86")] +use std::arch::x86::*; +#[cfg(target_arch = "x86_64")] +use std::arch::x86_64::*; + +fn main() { + // BMI1 and BMI2 are independent from each other, so both must be checked. + assert!(is_x86_feature_detected!("bmi1")); + assert!(is_x86_feature_detected!("bmi2")); + + unsafe { + test_bmi_32(); + test_bmi_64(); + } +} + +/// Test the 32-bit variants of the intrinsics. +unsafe fn test_bmi_32() { + unsafe fn test_bextr_u32() { + let r = _bextr_u32(0b0101_0000u32, 4, 4); + assert_eq!(r, 0b0000_0101u32); + + for i in 0..16 { + assert_eq!(_bextr_u32(u32::MAX, i, 4), 0b1111); + assert_eq!(_bextr_u32(u32::MAX, 4, i), (1 << i) - 1); + } + + // Ensure that indices larger than the bit count are covered. + // It is important to go above 32 in order to verify the bit selection + // of the instruction. + + for i in 0..256 { + // If the index is out of bounds, the original input won't be changed, thus the `min(32)`. + assert_eq!(_bextr_u32(u32::MAX, 0, i).count_ones(), i.min(32)); + } + + for i in 0..256 { + assert_eq!(_bextr_u32(u32::MAX, i, 0), 0); + } + + // Test cases with completly random values. These cases also test + // that the function works even if upper bits of the control value are set. + assert_eq!(_bextr2_u32(0x7408a392, 0x54ef705), 0x3a0451c); + assert_eq!(_bextr2_u32(0xbc5a3494, 0xdd193203), 0x178b4692); + assert_eq!(_bextr2_u32(0xc0332325, 0xf96e207), 0x1806646); + } + test_bextr_u32(); + + unsafe fn test_pext_u32() { + let n = 0b1011_1110_1001_0011u32; + + let m0 = 0b0110_0011_1000_0101u32; + let s0 = 0b0000_0000_0011_0101u32; + + let m1 = 0b1110_1011_1110_1111u32; + let s1 = 0b0001_0111_0100_0011u32; + + // Testing of random values. + assert_eq!(_pext_u32(n, m0), s0); + assert_eq!(_pext_u32(n, m1), s1); + assert_eq!(_pext_u32(0x12345678, 0xff00fff0), 0x00012567); + + // Testing of various identities. + assert_eq!(_pext_u32(u32::MAX, u32::MAX), u32::MAX); + assert_eq!(_pext_u32(u32::MAX, 0), 0); + assert_eq!(_pext_u32(0, u32::MAX), 0); + } + test_pext_u32(); + + unsafe fn test_pdep_u32() { + let n = 0b1011_1110_1001_0011u32; + + let m0 = 0b0110_0011_1000_0101u32; + let s0 = 0b0000_0010_0000_0101u32; + + let m1 = 0b1110_1011_1110_1111u32; + let s1 = 0b1110_1001_0010_0011u32; + + // Testing of random values. + assert_eq!(_pdep_u32(n, m0), s0); + assert_eq!(_pdep_u32(n, m1), s1); + assert_eq!(_pdep_u32(0x00012567, 0xff00fff0), 0x12005670); + + // Testing of various identities. + assert_eq!(_pdep_u32(u32::MAX, u32::MAX), u32::MAX); + assert_eq!(_pdep_u32(0, u32::MAX), 0); + assert_eq!(_pdep_u32(u32::MAX, 0), 0); + } + test_pdep_u32(); + + unsafe fn test_bzhi_u32() { + let n = 0b1111_0010u32; + let s = 0b0001_0010u32; + assert_eq!(_bzhi_u32(n, 5), s); + + // Ensure that indices larger than the bit count are covered. + // It is important to go above 32 in order to verify the bit selection + // of the instruction. + for i in 0..=512 { + // The instruction only takes the lowest eight bits to generate the index, hence `i & 0xff`. + // If the index is out of bounds, the original input won't be changed, thus the `min(32)`. + let expected = 1u32.checked_shl((i & 0xff).min(32)).unwrap_or(0).wrapping_sub(1); + let actual = _bzhi_u32(u32::MAX, i); + assert_eq!(expected, actual); + } + } + test_bzhi_u32(); +} + +#[cfg(not(target_arch = "x86_64"))] +unsafe fn test_bmi_64() {} + +/// Test the 64-bit variants of the intrinsics. +#[cfg(target_arch = "x86_64")] +unsafe fn test_bmi_64() { + unsafe fn test_bextr_u64() { + let r = _bextr_u64(0b0101_0000u64, 4, 4); + assert_eq!(r, 0b0000_0101u64); + + for i in 0..16 { + assert_eq!(_bextr_u64(u64::MAX, i, 4), 0b1111); + assert_eq!(_bextr_u64(u64::MAX, 32, i), (1 << i) - 1); + } + + // Ensure that indices larger than the bit count are covered. + // It is important to go above 64 in order to verify the bit selection + // of the instruction. + + for i in 0..256 { + // If the index is out of bounds, the original input won't be changed, thus the `min(64)`. + assert_eq!(_bextr_u64(u64::MAX, 0, i).count_ones(), i.min(64)); + } + + for i in 0..256 { + assert_eq!(_bextr_u64(u64::MAX, i, 0), 0); + } + + // Test cases with completly random values. These cases also test + // that the function works even if upper bits of the control value are set. + assert_eq!(_bextr2_u64(0x4ff6cfbcea75f055, 0x216642e228425719), 0x27fb67de75); + assert_eq!(_bextr2_u64(0xb05e991e6f6e1b6, 0xc76dd5d7f67dfc14), 0xb05e991e6f); + assert_eq!(_bextr2_u64(0x5a3a629e323d848f, 0x95ac507d20e7719), 0x2d1d314f19); + } + test_bextr_u64(); + + unsafe fn test_pext_u64() { + let n = 0b1011_1110_1001_0011u64; + + let m0 = 0b0110_0011_1000_0101u64; + let s0 = 0b0000_0000_0011_0101u64; + + let m1 = 0b1110_1011_1110_1111u64; + let s1 = 0b0001_0111_0100_0011u64; + + // Testing of random values. + assert_eq!(_pext_u64(n, m0), s0); + assert_eq!(_pext_u64(n, m1), s1); + assert_eq!(_pext_u64(0x12345678, 0xff00fff0), 0x00012567); + + // Testing of various identities. + assert_eq!(_pext_u64(u64::MAX, u64::MAX), u64::MAX); + assert_eq!(_pext_u64(u64::MAX, 0), 0); + assert_eq!(_pext_u64(0, u64::MAX), 0); + } + test_pext_u64(); + + unsafe fn test_pdep_u64() { + let n = 0b1011_1110_1001_0011u64; + + let m0 = 0b0110_0011_1000_0101u64; + let s0 = 0b0000_0010_0000_0101u64; + + let m1 = 0b1110_1011_1110_1111u64; + let s1 = 0b1110_1001_0010_0011u64; + + // Testing of random values. + assert_eq!(_pdep_u64(n, m0), s0); + assert_eq!(_pdep_u64(n, m1), s1); + assert_eq!(_pdep_u64(0x00012567, 0xff00fff0), 0x12005670); + + // Testing of various identities. + assert_eq!(_pdep_u64(u64::MAX, u64::MAX), u64::MAX); + assert_eq!(_pdep_u64(0, u64::MAX), 0); + assert_eq!(_pdep_u64(u64::MAX, 0), 0); + } + test_pdep_u64(); + + unsafe fn test_bzhi_u64() { + let n = 0b1111_0010u64; + let s = 0b0001_0010u64; + assert_eq!(_bzhi_u64(n, 5), s); + + // Ensure that indices larger than the bit count are covered. + // It is important to go above 255 in order to verify the bit selection + // of the instruction. + for i in 0..=512 { + // The instruction only takes the lowest eight bits to generate the index, hence `i & 0xff`. + // If the index is out of bounds, the original input won't be changed, thus the `min(64)`. + let expected = 1u64.checked_shl((i & 0xff).min(64)).unwrap_or(0).wrapping_sub(1); + let actual = _bzhi_u64(u64::MAX, i); + assert_eq!(expected, actual); + } + } + test_bzhi_u64(); +} From bb00657d168e347ac04b5f90e8e77edc14a03050 Mon Sep 17 00:00:00 2001 From: StackOverflowExcept1on <109800286+StackOverflowExcept1on@users.noreply.github.com> Date: Thu, 20 Jun 2024 13:05:45 +0300 Subject: [PATCH 231/892] Stabilize `PanicInfo::message()` and `PanicMessage` --- library/core/src/panic.rs | 2 +- library/core/src/panic/panic_info.rs | 10 +++++----- library/std/src/lib.rs | 1 - tests/run-make/wasm-exceptions-nostd/src/lib.rs | 1 - 4 files changed, 6 insertions(+), 8 deletions(-) diff --git a/library/core/src/panic.rs b/library/core/src/panic.rs index 56ede02673c03..37c338dd9b778 100644 --- a/library/core/src/panic.rs +++ b/library/core/src/panic.rs @@ -12,7 +12,7 @@ use crate::any::Any; pub use self::location::Location; #[stable(feature = "panic_hooks", since = "1.10.0")] pub use self::panic_info::PanicInfo; -#[unstable(feature = "panic_info_message", issue = "66745")] +#[stable(feature = "panic_info_message", since = "CURRENT_RUSTC_VERSION")] pub use self::panic_info::PanicMessage; #[stable(feature = "catch_unwind", since = "1.9.0")] pub use self::unwind_safe::{AssertUnwindSafe, RefUnwindSafe, UnwindSafe}; diff --git a/library/core/src/panic/panic_info.rs b/library/core/src/panic/panic_info.rs index 91953fd656b6a..6bbb9c3017110 100644 --- a/library/core/src/panic/panic_info.rs +++ b/library/core/src/panic/panic_info.rs @@ -24,7 +24,7 @@ pub struct PanicInfo<'a> { /// that were given to the `panic!()` macro. /// /// See [`PanicInfo::message`]. -#[unstable(feature = "panic_info_message", issue = "66745")] +#[stable(feature = "panic_info_message", since = "CURRENT_RUSTC_VERSION")] pub struct PanicMessage<'a> { message: fmt::Arguments<'a>, } @@ -57,7 +57,7 @@ impl<'a> PanicInfo<'a> { /// } /// ``` #[must_use] - #[unstable(feature = "panic_info_message", issue = "66745")] + #[stable(feature = "panic_info_message", since = "CURRENT_RUSTC_VERSION")] pub fn message(&self) -> PanicMessage<'_> { PanicMessage { message: self.message } } @@ -164,7 +164,7 @@ impl<'a> PanicMessage<'a> { /// For most cases with placeholders, this function will return `None`. /// /// See [`fmt::Arguments::as_str`] for details. - #[unstable(feature = "panic_info_message", issue = "66745")] + #[stable(feature = "panic_info_message", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "const_arguments_as_str", issue = "103900")] #[must_use] #[inline] @@ -173,7 +173,7 @@ impl<'a> PanicMessage<'a> { } } -#[unstable(feature = "panic_info_message", issue = "66745")] +#[stable(feature = "panic_info_message", since = "CURRENT_RUSTC_VERSION")] impl Display for PanicMessage<'_> { #[inline] fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { @@ -181,7 +181,7 @@ impl Display for PanicMessage<'_> { } } -#[unstable(feature = "panic_info_message", issue = "66745")] +#[stable(feature = "panic_info_message", since = "CURRENT_RUSTC_VERSION")] impl fmt::Debug for PanicMessage<'_> { #[inline] fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index 1c226f9f08f10..0f4064d10b56d 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -341,7 +341,6 @@ #![feature(maybe_uninit_uninit_array)] #![feature(maybe_uninit_write_slice)] #![feature(panic_can_unwind)] -#![feature(panic_info_message)] #![feature(panic_internals)] #![feature(pointer_is_aligned_to)] #![feature(portable_simd)] diff --git a/tests/run-make/wasm-exceptions-nostd/src/lib.rs b/tests/run-make/wasm-exceptions-nostd/src/lib.rs index 3ea8797d3a6dd..ef2f117e01af9 100644 --- a/tests/run-make/wasm-exceptions-nostd/src/lib.rs +++ b/tests/run-make/wasm-exceptions-nostd/src/lib.rs @@ -5,7 +5,6 @@ #![feature(core_intrinsics)] #![feature(lang_items)] #![feature(link_llvm_intrinsics)] -#![feature(panic_info_message)] extern crate alloc; From 2f9f204123b857606e7b65d217a3b71920fccf20 Mon Sep 17 00:00:00 2001 From: vohoanglong0107 Date: Wed, 28 Feb 2024 04:31:41 +0000 Subject: [PATCH 232/892] feat: unnecessary_min_max lint --- CHANGELOG.md | 1 + clippy_lints/src/declared_lints.rs | 1 + clippy_lints/src/methods/mod.rs | 30 +++ .../src/methods/unnecessary_min_or_max.rs | 90 +++++++++ clippy_utils/src/consts.rs | 17 +- tests/ui/auxiliary/external_consts.rs | 1 + tests/ui/cast.rs | 1 + tests/ui/cast.stderr | 184 +++++++++--------- tests/ui/unnecessary_min_or_max.fixed | 67 +++++++ tests/ui/unnecessary_min_or_max.rs | 67 +++++++ tests/ui/unnecessary_min_or_max.stderr | 107 ++++++++++ 11 files changed, 472 insertions(+), 94 deletions(-) create mode 100644 clippy_lints/src/methods/unnecessary_min_or_max.rs create mode 100644 tests/ui/auxiliary/external_consts.rs create mode 100644 tests/ui/unnecessary_min_or_max.fixed create mode 100644 tests/ui/unnecessary_min_or_max.rs create mode 100644 tests/ui/unnecessary_min_or_max.stderr diff --git a/CHANGELOG.md b/CHANGELOG.md index 3973edddb6d6b..fe9fbd486c9c8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5917,6 +5917,7 @@ Released 2018-09-13 [`unnecessary_lazy_evaluations`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_lazy_evaluations [`unnecessary_literal_unwrap`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_literal_unwrap [`unnecessary_map_on_constructor`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_map_on_constructor +[`unnecessary_min_or_max`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_min_or_max [`unnecessary_mut_passed`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_mut_passed [`unnecessary_operation`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_operation [`unnecessary_owned_empty_strings`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_owned_empty_strings diff --git a/clippy_lints/src/declared_lints.rs b/clippy_lints/src/declared_lints.rs index 8abe5d47b65ec..3b3d0db79dcc1 100644 --- a/clippy_lints/src/declared_lints.rs +++ b/clippy_lints/src/declared_lints.rs @@ -471,6 +471,7 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[ crate::methods::UNNECESSARY_JOIN_INFO, crate::methods::UNNECESSARY_LAZY_EVALUATIONS_INFO, crate::methods::UNNECESSARY_LITERAL_UNWRAP_INFO, + crate::methods::UNNECESSARY_MIN_OR_MAX_INFO, crate::methods::UNNECESSARY_RESULT_MAP_OR_ELSE_INFO, crate::methods::UNNECESSARY_SORT_BY_INFO, crate::methods::UNNECESSARY_TO_OWNED_INFO, diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs index 01438b8e8db09..1408f45482007 100644 --- a/clippy_lints/src/methods/mod.rs +++ b/clippy_lints/src/methods/mod.rs @@ -117,6 +117,7 @@ mod unnecessary_iter_cloned; mod unnecessary_join; mod unnecessary_lazy_eval; mod unnecessary_literal_unwrap; +mod unnecessary_min_or_max; mod unnecessary_result_map_or_else; mod unnecessary_sort_by; mod unnecessary_to_owned; @@ -3945,6 +3946,31 @@ declare_clippy_lint! { "cloning an `Option` via `as_ref().cloned()`" } +declare_clippy_lint! { + /// ### What it does + /// Checks for unnecessary calls to `min()` or `max()` in the following cases + /// - Either both side is constant + /// - One side is clearly larger than the other, like i32::MIN and an i32 variable + /// + /// ### Why is this bad? + /// + /// In the aformentioned cases it is not necessary to call `min()` or `max()` + /// to compare values, it may even cause confusion. + /// + /// ### Example + /// ```no_run + /// let _ = 0.min(7_u32); + /// ``` + /// Use instead: + /// ```no_run + /// let _ = 0; + /// ``` + #[clippy::version = "1.78.0"] + pub UNNECESSARY_MIN_OR_MAX, + complexity, + "using 'min()/max()' when there is no need for it" +} + declare_clippy_lint! { /// ### What it does /// Checks for usage of `.map_or_else()` "map closure" for `Result` type. @@ -4267,6 +4293,7 @@ impl_lint_pass!(Methods => [ UNNECESSARY_GET_THEN_CHECK, NEEDLESS_CHARACTER_ITERATION, MANUAL_INSPECT, + UNNECESSARY_MIN_OR_MAX, ]); /// Extracts a method call name, args, and `Span` of the method name. @@ -4566,6 +4593,9 @@ impl Methods { Some(("bytes", recv2, [], _, _)) => bytes_count_to_len::check(cx, expr, recv, recv2), _ => {}, }, + ("min" | "max", [arg]) => { + unnecessary_min_or_max::check(cx, expr, name, recv, arg); + }, ("drain", ..) => { if let Node::Stmt(Stmt { hir_id: _, kind, .. }) = cx.tcx.parent_hir_node(expr.hir_id) && matches!(kind, StmtKind::Semi(_)) diff --git a/clippy_lints/src/methods/unnecessary_min_or_max.rs b/clippy_lints/src/methods/unnecessary_min_or_max.rs new file mode 100644 index 0000000000000..78851d4122f12 --- /dev/null +++ b/clippy_lints/src/methods/unnecessary_min_or_max.rs @@ -0,0 +1,90 @@ +use std::cmp::Ordering; + +use super::UNNECESSARY_MIN_OR_MAX; +use clippy_utils::diagnostics::span_lint_and_sugg; + +use clippy_utils::consts::{constant, constant_with_source, Constant, ConstantSource, FullInt}; +use clippy_utils::source::snippet; + +use rustc_errors::Applicability; +use rustc_hir::Expr; +use rustc_lint::LateContext; +use rustc_middle::ty; +use rustc_span::Span; + +pub(super) fn check<'tcx>( + cx: &LateContext<'tcx>, + expr: &'tcx Expr<'_>, + name: &str, + recv: &'tcx Expr<'_>, + arg: &'tcx Expr<'_>, +) { + let typeck_results = cx.typeck_results(); + if let Some((left, ConstantSource::Local | ConstantSource::CoreConstant)) = + constant_with_source(cx, typeck_results, recv) + && let Some((right, ConstantSource::Local | ConstantSource::CoreConstant)) = + constant_with_source(cx, typeck_results, arg) + { + let Some(ord) = Constant::partial_cmp(cx.tcx, typeck_results.expr_ty(recv), &left, &right) else { + return; + }; + + lint(cx, expr, name, recv.span, arg.span, ord); + } else if let Some(extrema) = detect_extrema(cx, recv) { + let ord = match extrema { + Extrema::Minimum => Ordering::Less, + Extrema::Maximum => Ordering::Greater, + }; + lint(cx, expr, name, recv.span, arg.span, ord); + } else if let Some(extrema) = detect_extrema(cx, arg) { + let ord = match extrema { + Extrema::Minimum => Ordering::Greater, + Extrema::Maximum => Ordering::Less, + }; + lint(cx, expr, name, recv.span, arg.span, ord); + } +} + +fn lint(cx: &LateContext<'_>, expr: &Expr<'_>, name: &str, lhs: Span, rhs: Span, order: Ordering) { + let cmp_str = if order.is_ge() { "smaller" } else { "greater" }; + + let suggested_value = if (name == "min" && order.is_ge()) || (name == "max" && order.is_le()) { + snippet(cx, rhs, "..") + } else { + snippet(cx, lhs, "..") + }; + + span_lint_and_sugg( + cx, + UNNECESSARY_MIN_OR_MAX, + expr.span, + format!( + "`{}` is never {} than `{}` and has therefore no effect", + snippet(cx, lhs, ".."), + cmp_str, + snippet(cx, rhs, "..") + ), + "try", + suggested_value.to_string(), + Applicability::MachineApplicable, + ); +} + +#[derive(Debug)] +enum Extrema { + Minimum, + Maximum, +} +fn detect_extrema<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) -> Option { + let ty = cx.typeck_results().expr_ty(expr); + + let cv = constant(cx, cx.typeck_results(), expr)?; + + match (cv.int_value(cx, ty)?, ty.kind()) { + (FullInt::S(i), &ty::Int(ity)) if i == i128::MIN >> (128 - ity.bit_width()?) => Some(Extrema::Minimum), + (FullInt::S(i), &ty::Int(ity)) if i == i128::MAX >> (128 - ity.bit_width()?) => Some(Extrema::Maximum), + (FullInt::U(i), &ty::Uint(uty)) if i == u128::MAX >> (128 - uty.bit_width()?) => Some(Extrema::Maximum), + (FullInt::U(0), &ty::Uint(_)) => Some(Extrema::Minimum), + _ => None, + } +} diff --git a/clippy_utils/src/consts.rs b/clippy_utils/src/consts.rs index cfd142fe1ff63..8f6389ee07726 100644 --- a/clippy_utils/src/consts.rs +++ b/clippy_utils/src/consts.rs @@ -1,5 +1,6 @@ #![allow(clippy::float_cmp)] +use crate::macros::HirNode; use crate::source::{get_source_text, walk_span_to_context}; use crate::{clip, is_direct_expn_of, sext, unsext}; @@ -15,7 +16,7 @@ use rustc_middle::ty::{self, EarlyBinder, FloatTy, GenericArgsRef, IntTy, List, use rustc_middle::{bug, mir, span_bug}; use rustc_span::def_id::DefId; use rustc_span::symbol::{Ident, Symbol}; -use rustc_span::SyntaxContext; +use rustc_span::{sym, SyntaxContext}; use rustc_target::abi::Size; use std::cmp::Ordering; use std::hash::{Hash, Hasher}; @@ -302,6 +303,8 @@ pub enum ConstantSource { Local, /// The value is dependent on a defined constant. Constant, + /// The value is dependent on a constant defined in `core` crate. + CoreConstant, } impl ConstantSource { pub fn is_local(&self) -> bool { @@ -415,9 +418,19 @@ impl<'a, 'tcx> ConstEvalLateContext<'a, 'tcx> { ExprKind::ConstBlock(ConstBlock { body, .. }) => self.expr(self.lcx.tcx.hir().body(body).value), ExprKind::DropTemps(e) => self.expr(e), ExprKind::Path(ref qpath) => { + let is_core_crate = if let Some(def_id) = self.lcx.qpath_res(qpath, e.hir_id()).opt_def_id() { + self.lcx.tcx.crate_name(def_id.krate) == sym::core + } else { + false + }; self.fetch_path_and_apply(qpath, e.hir_id, self.typeck_results.expr_ty(e), |this, result| { let result = mir_to_const(this.lcx, result)?; - this.source = ConstantSource::Constant; + // If source is already Constant we wouldn't want to override it with CoreConstant + this.source = if is_core_crate && !matches!(this.source, ConstantSource::Constant) { + ConstantSource::CoreConstant + } else { + ConstantSource::Constant + }; Some(result) }) }, diff --git a/tests/ui/auxiliary/external_consts.rs b/tests/ui/auxiliary/external_consts.rs new file mode 100644 index 0000000000000..1885ba341f51e --- /dev/null +++ b/tests/ui/auxiliary/external_consts.rs @@ -0,0 +1 @@ +pub const MAGIC_NUMBER: i32 = 1; diff --git a/tests/ui/cast.rs b/tests/ui/cast.rs index 453d62ce60753..351325e9b00c3 100644 --- a/tests/ui/cast.rs +++ b/tests/ui/cast.rs @@ -12,6 +12,7 @@ #![allow( clippy::cast_abs_to_unsigned, clippy::no_effect, + clippy::unnecessary_min_or_max, clippy::unnecessary_operation, clippy::unnecessary_literal_unwrap, clippy::identity_op diff --git a/tests/ui/cast.stderr b/tests/ui/cast.stderr index 43c0d8f4ed738..f14c3c8d81d7c 100644 --- a/tests/ui/cast.stderr +++ b/tests/ui/cast.stderr @@ -1,5 +1,5 @@ error: casting `i32` to `f32` causes a loss of precision (`i32` is 32 bits wide, but `f32`'s mantissa is only 23 bits wide) - --> tests/ui/cast.rs:23:5 + --> tests/ui/cast.rs:24:5 | LL | x0 as f32; | ^^^^^^^^^ @@ -8,37 +8,37 @@ LL | x0 as f32; = help: to override `-D warnings` add `#[allow(clippy::cast_precision_loss)]` error: casting `i64` to `f32` causes a loss of precision (`i64` is 64 bits wide, but `f32`'s mantissa is only 23 bits wide) - --> tests/ui/cast.rs:27:5 + --> tests/ui/cast.rs:28:5 | LL | x1 as f32; | ^^^^^^^^^ error: casting `i64` to `f64` causes a loss of precision (`i64` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide) - --> tests/ui/cast.rs:29:5 + --> tests/ui/cast.rs:30:5 | LL | x1 as f64; | ^^^^^^^^^ error: casting `u32` to `f32` causes a loss of precision (`u32` is 32 bits wide, but `f32`'s mantissa is only 23 bits wide) - --> tests/ui/cast.rs:32:5 + --> tests/ui/cast.rs:33:5 | LL | x2 as f32; | ^^^^^^^^^ error: casting `u64` to `f32` causes a loss of precision (`u64` is 64 bits wide, but `f32`'s mantissa is only 23 bits wide) - --> tests/ui/cast.rs:35:5 + --> tests/ui/cast.rs:36:5 | LL | x3 as f32; | ^^^^^^^^^ error: casting `u64` to `f64` causes a loss of precision (`u64` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide) - --> tests/ui/cast.rs:37:5 + --> tests/ui/cast.rs:38:5 | LL | x3 as f64; | ^^^^^^^^^ error: casting `f32` to `i32` may truncate the value - --> tests/ui/cast.rs:40:5 + --> tests/ui/cast.rs:41:5 | LL | 1f32 as i32; | ^^^^^^^^^^^ @@ -48,7 +48,7 @@ LL | 1f32 as i32; = help: to override `-D warnings` add `#[allow(clippy::cast_possible_truncation)]` error: casting `f32` to `u32` may truncate the value - --> tests/ui/cast.rs:42:5 + --> tests/ui/cast.rs:43:5 | LL | 1f32 as u32; | ^^^^^^^^^^^ @@ -56,7 +56,7 @@ LL | 1f32 as u32; = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... error: casting `f32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:42:5 + --> tests/ui/cast.rs:43:5 | LL | 1f32 as u32; | ^^^^^^^^^^^ @@ -65,7 +65,7 @@ LL | 1f32 as u32; = help: to override `-D warnings` add `#[allow(clippy::cast_sign_loss)]` error: casting `f64` to `f32` may truncate the value - --> tests/ui/cast.rs:46:5 + --> tests/ui/cast.rs:47:5 | LL | 1f64 as f32; | ^^^^^^^^^^^ @@ -73,7 +73,7 @@ LL | 1f64 as f32; = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... error: casting `i32` to `i8` may truncate the value - --> tests/ui/cast.rs:48:5 + --> tests/ui/cast.rs:49:5 | LL | 1i32 as i8; | ^^^^^^^^^^ @@ -85,7 +85,7 @@ LL | i8::try_from(1i32); | ~~~~~~~~~~~~~~~~~~ error: casting `i32` to `u8` may truncate the value - --> tests/ui/cast.rs:50:5 + --> tests/ui/cast.rs:51:5 | LL | 1i32 as u8; | ^^^^^^^^^^ @@ -97,7 +97,7 @@ LL | u8::try_from(1i32); | ~~~~~~~~~~~~~~~~~~ error: casting `f64` to `isize` may truncate the value - --> tests/ui/cast.rs:52:5 + --> tests/ui/cast.rs:53:5 | LL | 1f64 as isize; | ^^^^^^^^^^^^^ @@ -105,7 +105,7 @@ LL | 1f64 as isize; = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... error: casting `f64` to `usize` may truncate the value - --> tests/ui/cast.rs:54:5 + --> tests/ui/cast.rs:55:5 | LL | 1f64 as usize; | ^^^^^^^^^^^^^ @@ -113,13 +113,13 @@ LL | 1f64 as usize; = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... error: casting `f64` to `usize` may lose the sign of the value - --> tests/ui/cast.rs:54:5 + --> tests/ui/cast.rs:55:5 | LL | 1f64 as usize; | ^^^^^^^^^^^^^ error: casting `u32` to `u16` may truncate the value - --> tests/ui/cast.rs:57:5 + --> tests/ui/cast.rs:58:5 | LL | 1f32 as u32 as u16; | ^^^^^^^^^^^^^^^^^^ @@ -131,7 +131,7 @@ LL | u16::try_from(1f32 as u32); | ~~~~~~~~~~~~~~~~~~~~~~~~~~ error: casting `f32` to `u32` may truncate the value - --> tests/ui/cast.rs:57:5 + --> tests/ui/cast.rs:58:5 | LL | 1f32 as u32 as u16; | ^^^^^^^^^^^ @@ -139,13 +139,13 @@ LL | 1f32 as u32 as u16; = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... error: casting `f32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:57:5 + --> tests/ui/cast.rs:58:5 | LL | 1f32 as u32 as u16; | ^^^^^^^^^^^ error: casting `i32` to `i8` may truncate the value - --> tests/ui/cast.rs:62:22 + --> tests/ui/cast.rs:63:22 | LL | let _x: i8 = 1i32 as _; | ^^^^^^^^^ @@ -157,7 +157,7 @@ LL | let _x: i8 = 1i32.try_into(); | ~~~~~~~~~~~~~~~ error: casting `f32` to `i32` may truncate the value - --> tests/ui/cast.rs:64:9 + --> tests/ui/cast.rs:65:9 | LL | 1f32 as i32; | ^^^^^^^^^^^ @@ -165,7 +165,7 @@ LL | 1f32 as i32; = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... error: casting `f64` to `i32` may truncate the value - --> tests/ui/cast.rs:66:9 + --> tests/ui/cast.rs:67:9 | LL | 1f64 as i32; | ^^^^^^^^^^^ @@ -173,7 +173,7 @@ LL | 1f64 as i32; = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... error: casting `f32` to `u8` may truncate the value - --> tests/ui/cast.rs:68:9 + --> tests/ui/cast.rs:69:9 | LL | 1f32 as u8; | ^^^^^^^^^^ @@ -181,13 +181,13 @@ LL | 1f32 as u8; = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... error: casting `f32` to `u8` may lose the sign of the value - --> tests/ui/cast.rs:68:9 + --> tests/ui/cast.rs:69:9 | LL | 1f32 as u8; | ^^^^^^^^^^ error: casting `u8` to `i8` may wrap around the value - --> tests/ui/cast.rs:73:5 + --> tests/ui/cast.rs:74:5 | LL | 1u8 as i8; | ^^^^^^^^^ @@ -196,31 +196,31 @@ LL | 1u8 as i8; = help: to override `-D warnings` add `#[allow(clippy::cast_possible_wrap)]` error: casting `u16` to `i16` may wrap around the value - --> tests/ui/cast.rs:76:5 + --> tests/ui/cast.rs:77:5 | LL | 1u16 as i16; | ^^^^^^^^^^^ error: casting `u32` to `i32` may wrap around the value - --> tests/ui/cast.rs:78:5 + --> tests/ui/cast.rs:79:5 | LL | 1u32 as i32; | ^^^^^^^^^^^ error: casting `u64` to `i64` may wrap around the value - --> tests/ui/cast.rs:80:5 + --> tests/ui/cast.rs:81:5 | LL | 1u64 as i64; | ^^^^^^^^^^^ error: casting `usize` to `isize` may wrap around the value - --> tests/ui/cast.rs:82:5 + --> tests/ui/cast.rs:83:5 | LL | 1usize as isize; | ^^^^^^^^^^^^^^^ error: casting `usize` to `i8` may truncate the value - --> tests/ui/cast.rs:85:5 + --> tests/ui/cast.rs:86:5 | LL | 1usize as i8; | ^^^^^^^^^^^^ @@ -232,7 +232,7 @@ LL | i8::try_from(1usize); | ~~~~~~~~~~~~~~~~~~~~ error: casting `usize` to `i16` may truncate the value - --> tests/ui/cast.rs:88:5 + --> tests/ui/cast.rs:89:5 | LL | 1usize as i16; | ^^^^^^^^^^^^^ @@ -244,7 +244,7 @@ LL | i16::try_from(1usize); | ~~~~~~~~~~~~~~~~~~~~~ error: casting `usize` to `i16` may wrap around the value on targets with 16-bit wide pointers - --> tests/ui/cast.rs:88:5 + --> tests/ui/cast.rs:89:5 | LL | 1usize as i16; | ^^^^^^^^^^^^^ @@ -253,7 +253,7 @@ LL | 1usize as i16; = note: for more information see https://doc.rust-lang.org/reference/types/numeric.html#machine-dependent-integer-types error: casting `usize` to `i32` may truncate the value on targets with 64-bit wide pointers - --> tests/ui/cast.rs:93:5 + --> tests/ui/cast.rs:94:5 | LL | 1usize as i32; | ^^^^^^^^^^^^^ @@ -265,19 +265,19 @@ LL | i32::try_from(1usize); | ~~~~~~~~~~~~~~~~~~~~~ error: casting `usize` to `i32` may wrap around the value on targets with 32-bit wide pointers - --> tests/ui/cast.rs:93:5 + --> tests/ui/cast.rs:94:5 | LL | 1usize as i32; | ^^^^^^^^^^^^^ error: casting `usize` to `i64` may wrap around the value on targets with 64-bit wide pointers - --> tests/ui/cast.rs:97:5 + --> tests/ui/cast.rs:98:5 | LL | 1usize as i64; | ^^^^^^^^^^^^^ error: casting `u16` to `isize` may wrap around the value on targets with 16-bit wide pointers - --> tests/ui/cast.rs:102:5 + --> tests/ui/cast.rs:103:5 | LL | 1u16 as isize; | ^^^^^^^^^^^^^ @@ -286,13 +286,13 @@ LL | 1u16 as isize; = note: for more information see https://doc.rust-lang.org/reference/types/numeric.html#machine-dependent-integer-types error: casting `u32` to `isize` may wrap around the value on targets with 32-bit wide pointers - --> tests/ui/cast.rs:106:5 + --> tests/ui/cast.rs:107:5 | LL | 1u32 as isize; | ^^^^^^^^^^^^^ error: casting `u64` to `isize` may truncate the value on targets with 32-bit wide pointers - --> tests/ui/cast.rs:109:5 + --> tests/ui/cast.rs:110:5 | LL | 1u64 as isize; | ^^^^^^^^^^^^^ @@ -304,55 +304,55 @@ LL | isize::try_from(1u64); | ~~~~~~~~~~~~~~~~~~~~~ error: casting `u64` to `isize` may wrap around the value on targets with 64-bit wide pointers - --> tests/ui/cast.rs:109:5 + --> tests/ui/cast.rs:110:5 | LL | 1u64 as isize; | ^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:114:5 + --> tests/ui/cast.rs:115:5 | LL | -1i32 as u32; | ^^^^^^^^^^^^ error: casting `isize` to `usize` may lose the sign of the value - --> tests/ui/cast.rs:117:5 + --> tests/ui/cast.rs:118:5 | LL | -1isize as usize; | ^^^^^^^^^^^^^^^^ error: casting `i8` to `u8` may lose the sign of the value - --> tests/ui/cast.rs:128:5 + --> tests/ui/cast.rs:129:5 | LL | (i8::MIN).abs() as u8; | ^^^^^^^^^^^^^^^^^^^^^ error: casting `i64` to `u64` may lose the sign of the value - --> tests/ui/cast.rs:132:5 + --> tests/ui/cast.rs:133:5 | LL | (-1i64).abs() as u64; | ^^^^^^^^^^^^^^^^^^^^ error: casting `isize` to `usize` may lose the sign of the value - --> tests/ui/cast.rs:133:5 + --> tests/ui/cast.rs:134:5 | LL | (-1isize).abs() as usize; | ^^^^^^^^^^^^^^^^^^^^^^^^ error: casting `i64` to `u64` may lose the sign of the value - --> tests/ui/cast.rs:140:5 + --> tests/ui/cast.rs:141:5 | LL | (unsafe { (-1i64).checked_abs().unwrap_unchecked() }) as u64; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: casting `i64` to `u64` may lose the sign of the value - --> tests/ui/cast.rs:155:5 + --> tests/ui/cast.rs:156:5 | LL | (unsafe { (-1i64).checked_isqrt().unwrap_unchecked() }) as u64; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: casting `i64` to `i8` may truncate the value - --> tests/ui/cast.rs:206:5 + --> tests/ui/cast.rs:207:5 | LL | (-99999999999i64).min(1) as i8; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -364,7 +364,7 @@ LL | i8::try_from((-99999999999i64).min(1)); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: casting `u64` to `u8` may truncate the value - --> tests/ui/cast.rs:220:5 + --> tests/ui/cast.rs:221:5 | LL | 999999u64.clamp(0, 256) as u8; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -376,7 +376,7 @@ LL | u8::try_from(999999u64.clamp(0, 256)); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: casting `main::E2` to `u8` may truncate the value - --> tests/ui/cast.rs:243:21 + --> tests/ui/cast.rs:244:21 | LL | let _ = self as u8; | ^^^^^^^^^^ @@ -388,7 +388,7 @@ LL | let _ = u8::try_from(self); | ~~~~~~~~~~~~~~~~~~ error: casting `main::E2::B` to `u8` will truncate the value - --> tests/ui/cast.rs:245:21 + --> tests/ui/cast.rs:246:21 | LL | let _ = Self::B as u8; | ^^^^^^^^^^^^^ @@ -397,7 +397,7 @@ LL | let _ = Self::B as u8; = help: to override `-D warnings` add `#[allow(clippy::cast_enum_truncation)]` error: casting `main::E5` to `i8` may truncate the value - --> tests/ui/cast.rs:287:21 + --> tests/ui/cast.rs:288:21 | LL | let _ = self as i8; | ^^^^^^^^^^ @@ -409,13 +409,13 @@ LL | let _ = i8::try_from(self); | ~~~~~~~~~~~~~~~~~~ error: casting `main::E5::A` to `i8` will truncate the value - --> tests/ui/cast.rs:289:21 + --> tests/ui/cast.rs:290:21 | LL | let _ = Self::A as i8; | ^^^^^^^^^^^^^ error: casting `main::E6` to `i16` may truncate the value - --> tests/ui/cast.rs:306:21 + --> tests/ui/cast.rs:307:21 | LL | let _ = self as i16; | ^^^^^^^^^^^ @@ -427,7 +427,7 @@ LL | let _ = i16::try_from(self); | ~~~~~~~~~~~~~~~~~~~ error: casting `main::E7` to `usize` may truncate the value on targets with 32-bit wide pointers - --> tests/ui/cast.rs:325:21 + --> tests/ui/cast.rs:326:21 | LL | let _ = self as usize; | ^^^^^^^^^^^^^ @@ -439,7 +439,7 @@ LL | let _ = usize::try_from(self); | ~~~~~~~~~~~~~~~~~~~~~ error: casting `main::E10` to `u16` may truncate the value - --> tests/ui/cast.rs:372:21 + --> tests/ui/cast.rs:373:21 | LL | let _ = self as u16; | ^^^^^^^^^^^ @@ -451,7 +451,7 @@ LL | let _ = u16::try_from(self); | ~~~~~~~~~~~~~~~~~~~ error: casting `u32` to `u8` may truncate the value - --> tests/ui/cast.rs:383:13 + --> tests/ui/cast.rs:384:13 | LL | let c = (q >> 16) as u8; | ^^^^^^^^^^^^^^^ @@ -463,7 +463,7 @@ LL | let c = u8::try_from(q >> 16); | ~~~~~~~~~~~~~~~~~~~~~ error: casting `u32` to `u8` may truncate the value - --> tests/ui/cast.rs:387:13 + --> tests/ui/cast.rs:388:13 | LL | let c = (q / 1000) as u8; | ^^^^^^^^^^^^^^^^ @@ -475,85 +475,85 @@ LL | let c = u8::try_from(q / 1000); | ~~~~~~~~~~~~~~~~~~~~~~ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:399:9 + --> tests/ui/cast.rs:400:9 | LL | (x * x) as u32; | ^^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:404:32 + --> tests/ui/cast.rs:405:32 | LL | let _a = |x: i32| -> u32 { (x * x * x * x) as u32 }; | ^^^^^^^^^^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:406:5 + --> tests/ui/cast.rs:407:5 | LL | (2_i32).checked_pow(3).unwrap() as u32; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:407:5 + --> tests/ui/cast.rs:408:5 | LL | (-2_i32).pow(3) as u32; | ^^^^^^^^^^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:412:5 + --> tests/ui/cast.rs:413:5 | LL | (-5_i32 % 2) as u32; | ^^^^^^^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:414:5 + --> tests/ui/cast.rs:415:5 | LL | (-5_i32 % -2) as u32; | ^^^^^^^^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:417:5 + --> tests/ui/cast.rs:418:5 | LL | (-2_i32 >> 1) as u32; | ^^^^^^^^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:421:5 + --> tests/ui/cast.rs:422:5 | LL | (x * x) as u32; | ^^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:422:5 + --> tests/ui/cast.rs:423:5 | LL | (x * x * x) as u32; | ^^^^^^^^^^^^^^^^^^ error: casting `i16` to `u16` may lose the sign of the value - --> tests/ui/cast.rs:426:5 + --> tests/ui/cast.rs:427:5 | LL | (y * y * y * y * -2) as u16; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: casting `i16` to `u16` may lose the sign of the value - --> tests/ui/cast.rs:428:5 + --> tests/ui/cast.rs:429:5 | LL | (y * y * y / y * 2) as u16; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: casting `i16` to `u16` may lose the sign of the value - --> tests/ui/cast.rs:429:5 + --> tests/ui/cast.rs:430:5 | LL | (y * y / y * 2) as u16; | ^^^^^^^^^^^^^^^^^^^^^^ error: casting `i16` to `u16` may lose the sign of the value - --> tests/ui/cast.rs:431:5 + --> tests/ui/cast.rs:432:5 | LL | (y / y * y * -2) as u16; | ^^^^^^^^^^^^^^^^^^^^^^^ error: equal expressions as operands to `/` - --> tests/ui/cast.rs:431:6 + --> tests/ui/cast.rs:432:6 | LL | (y / y * y * -2) as u16; | ^^^^^ @@ -561,97 +561,97 @@ LL | (y / y * y * -2) as u16; = note: `#[deny(clippy::eq_op)]` on by default error: casting `i16` to `u16` may lose the sign of the value - --> tests/ui/cast.rs:434:5 + --> tests/ui/cast.rs:435:5 | LL | (y + y + y + -2) as u16; | ^^^^^^^^^^^^^^^^^^^^^^^ error: casting `i16` to `u16` may lose the sign of the value - --> tests/ui/cast.rs:436:5 + --> tests/ui/cast.rs:437:5 | LL | (y + y + y + 2) as u16; | ^^^^^^^^^^^^^^^^^^^^^^ error: casting `i16` to `u16` may lose the sign of the value - --> tests/ui/cast.rs:440:5 + --> tests/ui/cast.rs:441:5 | LL | (z + -2) as u16; | ^^^^^^^^^^^^^^^ error: casting `i16` to `u16` may lose the sign of the value - --> tests/ui/cast.rs:442:5 + --> tests/ui/cast.rs:443:5 | LL | (z + z + 2) as u16; | ^^^^^^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:445:9 + --> tests/ui/cast.rs:446:9 | LL | (a * a * b * b * c * c) as u32; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:446:9 + --> tests/ui/cast.rs:447:9 | LL | (a * b * c) as u32; | ^^^^^^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:448:9 + --> tests/ui/cast.rs:449:9 | LL | (a * -b * c) as u32; | ^^^^^^^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:450:9 + --> tests/ui/cast.rs:451:9 | LL | (a * b * c * c) as u32; | ^^^^^^^^^^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:451:9 + --> tests/ui/cast.rs:452:9 | LL | (a * -2) as u32; | ^^^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:453:9 + --> tests/ui/cast.rs:454:9 | LL | (a * b * c * -2) as u32; | ^^^^^^^^^^^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:455:9 + --> tests/ui/cast.rs:456:9 | LL | (a / b) as u32; | ^^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:456:9 + --> tests/ui/cast.rs:457:9 | LL | (a / b * c) as u32; | ^^^^^^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:458:9 + --> tests/ui/cast.rs:459:9 | LL | (a / b + b * c) as u32; | ^^^^^^^^^^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:460:9 + --> tests/ui/cast.rs:461:9 | LL | a.saturating_pow(3) as u32; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:462:9 + --> tests/ui/cast.rs:463:9 | LL | (a.abs() * b.pow(2) / c.abs()) as u32 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: casting `i32` to `u32` may lose the sign of the value - --> tests/ui/cast.rs:470:21 + --> tests/ui/cast.rs:471:21 | LL | let _ = i32::MIN as u32; // cast_sign_loss | ^^^^^^^^^^^^^^^ @@ -662,7 +662,7 @@ LL | m!(); = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info) error: casting `u32` to `u8` may truncate the value - --> tests/ui/cast.rs:471:21 + --> tests/ui/cast.rs:472:21 | LL | let _ = u32::MAX as u8; // cast_possible_truncation | ^^^^^^^^^^^^^^ @@ -678,7 +678,7 @@ LL | let _ = u8::try_from(u32::MAX); // cast_possible_truncation | ~~~~~~~~~~~~~~~~~~~~~~ error: casting `f64` to `f32` may truncate the value - --> tests/ui/cast.rs:472:21 + --> tests/ui/cast.rs:473:21 | LL | let _ = std::f64::consts::PI as f32; // cast_possible_truncation | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -690,7 +690,7 @@ LL | m!(); = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info) error: casting `i64` to `usize` may truncate the value on targets with 32-bit wide pointers - --> tests/ui/cast.rs:481:5 + --> tests/ui/cast.rs:482:5 | LL | bar.unwrap().unwrap() as usize | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -702,13 +702,13 @@ LL | usize::try_from(bar.unwrap().unwrap()) | error: casting `i64` to `usize` may lose the sign of the value - --> tests/ui/cast.rs:481:5 + --> tests/ui/cast.rs:482:5 | LL | bar.unwrap().unwrap() as usize | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: casting `u64` to `u8` may truncate the value - --> tests/ui/cast.rs:496:5 + --> tests/ui/cast.rs:497:5 | LL | (256 & 999999u64) as u8; | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -720,7 +720,7 @@ LL | u8::try_from(256 & 999999u64); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: casting `u64` to `u8` may truncate the value - --> tests/ui/cast.rs:498:5 + --> tests/ui/cast.rs:499:5 | LL | (255 % 999999u64) as u8; | ^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/unnecessary_min_or_max.fixed b/tests/ui/unnecessary_min_or_max.fixed new file mode 100644 index 0000000000000..392f6dd1fee43 --- /dev/null +++ b/tests/ui/unnecessary_min_or_max.fixed @@ -0,0 +1,67 @@ +//@aux-build:external_consts.rs + +#![allow(unused)] +#![warn(clippy::unnecessary_min_or_max)] +#![allow(clippy::identity_op)] + +extern crate external_consts; + +const X: i32 = 1; + +fn main() { + // Both are Literals + let _ = (-6_i32); + let _ = 9; + let _ = 6; + let _ = 9_u32; + let _ = 6; + let _ = 7_u8; + + let x: u32 = 42; + // unsigned with zero + let _ = 0; + let _ = x; + let _ = 0_u32; + let _ = x; + + let x: i32 = 42; + // signed MIN + let _ = i32::MIN; + let _ = x; + let _ = i32::MIN; + let _ = x; + + let _ = i32::MIN - 0; + let _ = x; + + let _ = i32::MIN - 0; + + // The below cases shouldn't be lint + let mut min = u32::MAX; + for _ in 0..1000 { + min = min.min(random_u32()); + } + + let _ = 2.min(external_consts::MAGIC_NUMBER); + let _ = 2.max(external_consts::MAGIC_NUMBER); + let _ = external_consts::MAGIC_NUMBER.min(2); + let _ = external_consts::MAGIC_NUMBER.max(2); + + let _ = X.min(external_consts::MAGIC_NUMBER); + let _ = X.max(external_consts::MAGIC_NUMBER); + let _ = external_consts::MAGIC_NUMBER.min(X); + let _ = external_consts::MAGIC_NUMBER.max(X); + + let _ = X.max(12); + let _ = X.min(12); + let _ = 12.min(X); + let _ = 12.max(X); + let _ = (X + 1).max(12); + let _ = (X + 1).min(12); + let _ = 12.min(X - 1); + let _ = 12.max(X - 1); +} +fn random_u32() -> u32 { + // random number generator + 0 +} diff --git a/tests/ui/unnecessary_min_or_max.rs b/tests/ui/unnecessary_min_or_max.rs new file mode 100644 index 0000000000000..b03755e6d23d1 --- /dev/null +++ b/tests/ui/unnecessary_min_or_max.rs @@ -0,0 +1,67 @@ +//@aux-build:external_consts.rs + +#![allow(unused)] +#![warn(clippy::unnecessary_min_or_max)] +#![allow(clippy::identity_op)] + +extern crate external_consts; + +const X: i32 = 1; + +fn main() { + // Both are Literals + let _ = (-6_i32).min(9); + let _ = (-6_i32).max(9); + let _ = 9_u32.min(6); + let _ = 9_u32.max(6); + let _ = 6.min(7_u8); + let _ = 6.max(7_u8); + + let x: u32 = 42; + // unsigned with zero + let _ = 0.min(x); + let _ = 0.max(x); + let _ = x.min(0_u32); + let _ = x.max(0_u32); + + let x: i32 = 42; + // signed MIN + let _ = i32::MIN.min(x); + let _ = i32::MIN.max(x); + let _ = x.min(i32::MIN); + let _ = x.max(i32::MIN); + + let _ = x.min(i32::MIN - 0); + let _ = x.max(i32::MIN); + + let _ = x.min(i32::MIN - 0); + + // The below cases shouldn't be lint + let mut min = u32::MAX; + for _ in 0..1000 { + min = min.min(random_u32()); + } + + let _ = 2.min(external_consts::MAGIC_NUMBER); + let _ = 2.max(external_consts::MAGIC_NUMBER); + let _ = external_consts::MAGIC_NUMBER.min(2); + let _ = external_consts::MAGIC_NUMBER.max(2); + + let _ = X.min(external_consts::MAGIC_NUMBER); + let _ = X.max(external_consts::MAGIC_NUMBER); + let _ = external_consts::MAGIC_NUMBER.min(X); + let _ = external_consts::MAGIC_NUMBER.max(X); + + let _ = X.max(12); + let _ = X.min(12); + let _ = 12.min(X); + let _ = 12.max(X); + let _ = (X + 1).max(12); + let _ = (X + 1).min(12); + let _ = 12.min(X - 1); + let _ = 12.max(X - 1); +} +fn random_u32() -> u32 { + // random number generator + 0 +} diff --git a/tests/ui/unnecessary_min_or_max.stderr b/tests/ui/unnecessary_min_or_max.stderr new file mode 100644 index 0000000000000..f5cd31fbaf24b --- /dev/null +++ b/tests/ui/unnecessary_min_or_max.stderr @@ -0,0 +1,107 @@ +error: `(-6_i32)` is never greater than `9` and has therefore no effect + --> tests/ui/unnecessary_min_or_max.rs:13:13 + | +LL | let _ = (-6_i32).min(9); + | ^^^^^^^^^^^^^^^ help: try: `(-6_i32)` + | + = note: `-D clippy::unnecessary-min-or-max` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::unnecessary_min_or_max)]` + +error: `(-6_i32)` is never greater than `9` and has therefore no effect + --> tests/ui/unnecessary_min_or_max.rs:14:13 + | +LL | let _ = (-6_i32).max(9); + | ^^^^^^^^^^^^^^^ help: try: `9` + +error: `9_u32` is never smaller than `6` and has therefore no effect + --> tests/ui/unnecessary_min_or_max.rs:15:13 + | +LL | let _ = 9_u32.min(6); + | ^^^^^^^^^^^^ help: try: `6` + +error: `9_u32` is never smaller than `6` and has therefore no effect + --> tests/ui/unnecessary_min_or_max.rs:16:13 + | +LL | let _ = 9_u32.max(6); + | ^^^^^^^^^^^^ help: try: `9_u32` + +error: `6` is never greater than `7_u8` and has therefore no effect + --> tests/ui/unnecessary_min_or_max.rs:17:13 + | +LL | let _ = 6.min(7_u8); + | ^^^^^^^^^^^ help: try: `6` + +error: `6` is never greater than `7_u8` and has therefore no effect + --> tests/ui/unnecessary_min_or_max.rs:18:13 + | +LL | let _ = 6.max(7_u8); + | ^^^^^^^^^^^ help: try: `7_u8` + +error: `0` is never greater than `x` and has therefore no effect + --> tests/ui/unnecessary_min_or_max.rs:22:13 + | +LL | let _ = 0.min(x); + | ^^^^^^^^ help: try: `0` + +error: `0` is never greater than `x` and has therefore no effect + --> tests/ui/unnecessary_min_or_max.rs:23:13 + | +LL | let _ = 0.max(x); + | ^^^^^^^^ help: try: `x` + +error: `x` is never smaller than `0_u32` and has therefore no effect + --> tests/ui/unnecessary_min_or_max.rs:24:13 + | +LL | let _ = x.min(0_u32); + | ^^^^^^^^^^^^ help: try: `0_u32` + +error: `x` is never smaller than `0_u32` and has therefore no effect + --> tests/ui/unnecessary_min_or_max.rs:25:13 + | +LL | let _ = x.max(0_u32); + | ^^^^^^^^^^^^ help: try: `x` + +error: `i32::MIN` is never greater than `x` and has therefore no effect + --> tests/ui/unnecessary_min_or_max.rs:29:13 + | +LL | let _ = i32::MIN.min(x); + | ^^^^^^^^^^^^^^^ help: try: `i32::MIN` + +error: `i32::MIN` is never greater than `x` and has therefore no effect + --> tests/ui/unnecessary_min_or_max.rs:30:13 + | +LL | let _ = i32::MIN.max(x); + | ^^^^^^^^^^^^^^^ help: try: `x` + +error: `x` is never smaller than `i32::MIN` and has therefore no effect + --> tests/ui/unnecessary_min_or_max.rs:31:13 + | +LL | let _ = x.min(i32::MIN); + | ^^^^^^^^^^^^^^^ help: try: `i32::MIN` + +error: `x` is never smaller than `i32::MIN` and has therefore no effect + --> tests/ui/unnecessary_min_or_max.rs:32:13 + | +LL | let _ = x.max(i32::MIN); + | ^^^^^^^^^^^^^^^ help: try: `x` + +error: `x` is never smaller than `i32::MIN - 0` and has therefore no effect + --> tests/ui/unnecessary_min_or_max.rs:34:13 + | +LL | let _ = x.min(i32::MIN - 0); + | ^^^^^^^^^^^^^^^^^^^ help: try: `i32::MIN - 0` + +error: `x` is never smaller than `i32::MIN` and has therefore no effect + --> tests/ui/unnecessary_min_or_max.rs:35:13 + | +LL | let _ = x.max(i32::MIN); + | ^^^^^^^^^^^^^^^ help: try: `x` + +error: `x` is never smaller than `i32::MIN - 0` and has therefore no effect + --> tests/ui/unnecessary_min_or_max.rs:37:13 + | +LL | let _ = x.min(i32::MIN - 0); + | ^^^^^^^^^^^^^^^^^^^ help: try: `i32::MIN - 0` + +error: aborting due to 17 previous errors + From c7413154e1bfef6ec75157c589db0303e75bec30 Mon Sep 17 00:00:00 2001 From: Adwin White Date: Thu, 20 Jun 2024 17:21:19 +0800 Subject: [PATCH 233/892] Fix ICE caused by seeking past `i64::MAX` --- src/tools/miri/src/shims/unix/fs.rs | 9 +++++++- .../miri/tests/pass/issues/issue-miri-3680.rs | 21 +++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) create mode 100644 src/tools/miri/tests/pass/issues/issue-miri-3680.rs diff --git a/src/tools/miri/src/shims/unix/fs.rs b/src/tools/miri/src/shims/unix/fs.rs index 262e71756c64f..e34aa5c09dfe1 100644 --- a/src/tools/miri/src/shims/unix/fs.rs +++ b/src/tools/miri/src/shims/unix/fs.rs @@ -395,7 +395,14 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Isolation check is done via `FileDescriptor` trait. let seek_from = if whence == this.eval_libc_i32("SEEK_SET") { - SeekFrom::Start(u64::try_from(offset).unwrap()) + if offset < 0 { + // Negative offsets return `EINVAL`. + let einval = this.eval_libc("EINVAL"); + this.set_last_error(einval)?; + return Ok(Scalar::from_i64(-1)); + } else { + SeekFrom::Start(u64::try_from(offset).unwrap()) + } } else if whence == this.eval_libc_i32("SEEK_CUR") { SeekFrom::Current(i64::try_from(offset).unwrap()) } else if whence == this.eval_libc_i32("SEEK_END") { diff --git a/src/tools/miri/tests/pass/issues/issue-miri-3680.rs b/src/tools/miri/tests/pass/issues/issue-miri-3680.rs new file mode 100644 index 0000000000000..55b896c91adb7 --- /dev/null +++ b/src/tools/miri/tests/pass/issues/issue-miri-3680.rs @@ -0,0 +1,21 @@ +//@ignore-target-windows: File handling is not implemented yet +//@compile-flags: -Zmiri-disable-isolation + +use std::fs::remove_file; +use std::io::{ErrorKind, Seek}; + +#[path = "../../utils/mod.rs"] +mod utils; + +fn main() { + let path = utils::prepare("miri_test_fs_seek_i64_max_plus_1.txt"); + + let mut f = std::fs::File::create(&path).unwrap(); + let error = f.seek(std::io::SeekFrom::Start(i64::MAX as u64 + 1)).unwrap_err(); + + // It should be error due to negative offset. + assert_eq!(error.kind(), ErrorKind::InvalidInput); + + // Cleanup + remove_file(&path).unwrap(); +} From 2a378251fba001fa3b9f5b8cb1d57159d73db8b9 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Wed, 5 Jun 2024 16:00:13 +0200 Subject: [PATCH 234/892] Update to Cranelift 0.109 --- Cargo.lock | 56 +++++++++++++++++++++++------------------------ Cargo.toml | 14 ++++++------ src/common.rs | 2 ++ src/driver/jit.rs | 2 +- 4 files changed, 38 insertions(+), 36 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b95ab0a7f177a..e4959eed37a00 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -46,18 +46,18 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "cranelift-bforest" -version = "0.108.0" +version = "0.109.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f75f0946f5e307e5dbf22e8bc0bd9bc5336a4f0240a4af4751c007a0cbf84917" +checksum = "0b6b33d7e757a887989eb18b35712b2a67d96171ec3149d1bfb657b29b7b367c" dependencies = [ "cranelift-entity", ] [[package]] name = "cranelift-codegen" -version = "0.108.0" +version = "0.109.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6b0a01705ef466bbc64e10af820f935f77256bcb14a40dde1e10b7a0969ce11" +checksum = "b9acf15cb22be42d07c3b57d7856329cb228b7315d385346149df2566ad5e4aa" dependencies = [ "bumpalo", "cranelift-bforest", @@ -77,39 +77,39 @@ dependencies = [ [[package]] name = "cranelift-codegen-meta" -version = "0.108.0" +version = "0.109.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2cdaeff01606190dcccd13cf3d80b8d5f1f197812ba7bba1196ae08bd8e82592" +checksum = "e934d301392b73b3f8b0540391fb82465a0f179a3cee7c726482ac4727efcc97" dependencies = [ "cranelift-codegen-shared", ] [[package]] name = "cranelift-codegen-shared" -version = "0.108.0" +version = "0.109.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cefa0243350ce9667f3320579c8a2c3dd3d1f9943e8ab2eb1d4ca533ccc1db57" +checksum = "8afb2a2566b3d54b854dfb288b3b187f6d3d17d6f762c92898207eba302931da" [[package]] name = "cranelift-control" -version = "0.108.0" +version = "0.109.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa46a2d3331aa33cbd399665d6ea0f431f726a55fb69fdf897035cf5fe0a3301" +checksum = "0100f33b704cdacd01ad66ff41f8c5030d57cbff078e2a4e49ab1822591299fa" dependencies = [ "arbitrary", ] [[package]] name = "cranelift-entity" -version = "0.108.0" +version = "0.109.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e8f7cc083e6d01d656283f293ec361ce7bae05eca896f3a932d42dad1850578" +checksum = "a8cfdc315e5d18997093e040a8d234bea1ac1e118a716d3e30f40d449e78207b" [[package]] name = "cranelift-frontend" -version = "0.108.0" +version = "0.109.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8490d83b85eeec14ebf3b4c0b0ebc33600f1943514b1406a7b99b85d8b80e4c0" +checksum = "0f74b84f16af2e982b0c0c72233503d9d55cbfe3865dbe807ca28dc6642a28b5" dependencies = [ "cranelift-codegen", "log", @@ -119,15 +119,15 @@ dependencies = [ [[package]] name = "cranelift-isle" -version = "0.108.0" +version = "0.109.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e617871f2347ca078a31d61acaf7de961852447e6009afa5be6e4df6d5785dd4" +checksum = "adf306d3dde705fb94bd48082f01d38c4ededc74293a4c007805f610bf08bc6e" [[package]] name = "cranelift-jit" -version = "0.108.0" +version = "0.109.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d396c6f5cde59c1e408d813426d2332031692152432e12f4de63a936c6c10c7" +checksum = "f5c5cfb8bbd3339cd25cca30e7516ff8fe5cb1feeddde6980cc4d5ef34df97bb" dependencies = [ "anyhow", "cranelift-codegen", @@ -145,9 +145,9 @@ dependencies = [ [[package]] name = "cranelift-module" -version = "0.108.0" +version = "0.109.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7067c2b072829bb35f19f9e99eb42b6982faf4339adb2946797728ff0bd6a089" +checksum = "7c9b0d4269b36fd858e6d8f20cd4938941186fb831488c361888cb2d6b33a9a6" dependencies = [ "anyhow", "cranelift-codegen", @@ -156,9 +156,9 @@ dependencies = [ [[package]] name = "cranelift-native" -version = "0.108.0" +version = "0.109.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "add05ee8162778fd7b545e0935f4a5c0c95afdac003362e040ef0229227ae967" +checksum = "1ea0ebdef7aff4a79bcbc8b6495f31315f16b3bf311152f472eaa8d679352581" dependencies = [ "cranelift-codegen", "libc", @@ -167,9 +167,9 @@ dependencies = [ [[package]] name = "cranelift-object" -version = "0.108.0" +version = "0.109.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8a09bc240fb04674e01382ca505b34e71ea0ee8499a7960cd85f70359873852" +checksum = "19e33439ec20db058bc7cc3410f9748ab1ad90a35cef713d625c736f43e3820d" dependencies = [ "anyhow", "cranelift-codegen", @@ -279,9 +279,9 @@ checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" [[package]] name = "object" -version = "0.33.0" +version = "0.36.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8dd6c0cdf9429bce006e1362bfce61fa1bfd8c898a643ed8d2b471934701d3d" +checksum = "576dfe1fc8f9df304abb159d767a29d0476f7750fbf8aa7ad07816004a207434" dependencies = [ "crc32fast", "hashbrown 0.14.3", @@ -411,9 +411,9 @@ checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" [[package]] name = "wasmtime-jit-icache-coherence" -version = "21.0.0" +version = "22.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ce46bf24b027e1ede83d14ed544c736d7e939a849c4429551eb27842356c77" +checksum = "5afe2f0499542f9a4bcfa1b55bfdda803b6ade4e7c93c6b99e0f39dba44b0a91" dependencies = [ "anyhow", "cfg-if", diff --git a/Cargo.toml b/Cargo.toml index 6aaff55023b07..2969a6cf6ecaa 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,15 +8,15 @@ crate-type = ["dylib"] [dependencies] # These have to be in sync with each other -cranelift-codegen = { version = "0.108.0", default-features = false, features = ["std", "unwind", "all-arch"] } -cranelift-frontend = { version = "0.108.0" } -cranelift-module = { version = "0.108.0" } -cranelift-native = { version = "0.108.0" } -cranelift-jit = { version = "0.108.0", optional = true } -cranelift-object = { version = "0.108.0" } +cranelift-codegen = { version = "0.109.0", default-features = false, features = ["std", "unwind", "all-arch"] } +cranelift-frontend = { version = "0.109.0" } +cranelift-module = { version = "0.109.0" } +cranelift-native = { version = "0.109.0" } +cranelift-jit = { version = "0.109.0", optional = true } +cranelift-object = { version = "0.109.0" } target-lexicon = "0.12.0" gimli = { version = "0.28", default-features = false, features = ["write"]} -object = { version = "0.33", default-features = false, features = ["std", "read_core", "write", "archive", "coff", "elf", "macho", "pe"] } +object = { version = "0.36", default-features = false, features = ["std", "read_core", "write", "archive", "coff", "elf", "macho", "pe"] } indexmap = "2.0.0" libloading = { version = "0.8.0", optional = true } diff --git a/src/common.rs b/src/common.rs index 21d0cd2d30f2a..817498b195690 100644 --- a/src/common.rs +++ b/src/common.rs @@ -395,6 +395,7 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> { // FIXME Don't force the size to a multiple of bytes once Cranelift gets // a way to specify stack slot alignment. size: (size + abi_align - 1) / abi_align * abi_align, + align_shift: 4, }); Pointer::stack_slot(stack_slot) } else { @@ -405,6 +406,7 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> { // FIXME Don't force the size to a multiple of bytes once Cranelift gets // a way to specify stack slot alignment. size: (size + align) / abi_align * abi_align, + align_shift: 4, }); let base_ptr = self.bcx.ins().stack_addr(self.pointer_type, stack_slot, 0); let misalign_offset = self.bcx.ins().urem_imm(base_ptr, i64::from(align)); diff --git a/src/driver/jit.rs b/src/driver/jit.rs index 4b149131b61aa..ae0e45ae5312b 100644 --- a/src/driver/jit.rs +++ b/src/driver/jit.rs @@ -310,7 +310,7 @@ fn jit_fn(instance_ptr: *const Instance<'static>, trampoline_ptr: *const u8) -> fn dep_symbol_lookup_fn( sess: &Session, crate_info: CrateInfo, -) -> Box Option<*const u8>> { +) -> Box Option<*const u8> + Send> { use rustc_middle::middle::dependency_format::Linkage; let mut dylib_paths = Vec::new(); From 1031d4da55e9e4f96ace279281530bc8914472c4 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 20 Jun 2024 13:52:17 -0400 Subject: [PATCH 235/892] Add nightly style guide section for precise_capturing --- src/doc/style-guide/src/nightly.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/doc/style-guide/src/nightly.md b/src/doc/style-guide/src/nightly.md index 66e7fa3c9f89c..d870edf18882e 100644 --- a/src/doc/style-guide/src/nightly.md +++ b/src/doc/style-guide/src/nightly.md @@ -5,3 +5,15 @@ This chapter documents style and formatting for nightly-only syntax. The rest of Style and formatting for nightly-only syntax should be removed from this chapter and integrated into the appropriate sections of the style guide at the time of stabilization. There is no guarantee of the stability of this chapter in contrast to the rest of the style guide. Refer to the style team policy for nightly formatting procedure regarding breaking changes to this chapter. + +### `feature(precise_capturing)` + +A `use<'a, T>` precise capturing bound is formatted as if it were a single path segment with non-turbofished angle-bracketed args, like a trait bound whose identifier is `use`. + +``` +fn foo() -> impl Sized + use<'a> {} + +// is formatted analogously to: + +fn foo() -> impl Sized + Use<'a> {} +``` From f6661f5b9bb26fd733f70c8751e3263e267b65a4 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 20 Jun 2024 19:50:57 -0400 Subject: [PATCH 236/892] StaticForeignItem and StaticItem are the same --- clippy_utils/src/ast_utils.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/clippy_utils/src/ast_utils.rs b/clippy_utils/src/ast_utils.rs index fb43f7d80afff..785d5ed5dbeba 100644 --- a/clippy_utils/src/ast_utils.rs +++ b/clippy_utils/src/ast_utils.rs @@ -449,13 +449,13 @@ pub fn eq_foreign_item_kind(l: &ForeignItemKind, r: &ForeignItemKind) -> bool { use ForeignItemKind::*; match (l, r) { ( - Static(box StaticForeignItem { + Static(box StaticItem { ty: lt, mutability: lm, expr: le, safety: ls, }), - Static(box StaticForeignItem { + Static(box StaticItem { ty: rt, mutability: rm, expr: re, From 121b06bd0593369477a70dfee156f10055ca7638 Mon Sep 17 00:00:00 2001 From: The Miri Cronjob Bot Date: Fri, 21 Jun 2024 05:07:19 +0000 Subject: [PATCH 237/892] 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 a2da736656d17..1502fa120be65 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version @@ -1 +1 @@ -a1ca449981e3b8442e358026437b7bedb9a1458e +7a08f84627ff3035de4d66ff3209e5fc93165dcb From 79c9c8067d8e81f058904c3964bb8d71a2e1c849 Mon Sep 17 00:00:00 2001 From: Southball <6523469+southball@users.noreply.github.com> Date: Fri, 21 Jun 2024 14:22:51 +0900 Subject: [PATCH 238/892] Use strict ops instead of checked ops --- src/tools/miri/src/alloc_addresses/mod.rs | 2 +- src/tools/miri/src/eval.rs | 2 +- src/tools/miri/src/helpers.rs | 6 +-- src/tools/miri/src/shims/foreign_items.rs | 4 +- src/tools/miri/src/shims/time.rs | 2 +- src/tools/miri/src/shims/unix/env.rs | 6 +-- src/tools/miri/src/shims/unix/fd.rs | 2 +- src/tools/miri/src/shims/unix/socket.rs | 2 +- .../miri/src/shims/windows/foreign_items.rs | 4 +- src/tools/miri/src/shims/windows/handle.rs | 4 +- src/tools/miri/src/shims/x86/avx2.rs | 29 +++++++------ src/tools/miri/src/shims/x86/mod.rs | 41 ++++++++----------- src/tools/miri/src/shims/x86/sse2.rs | 14 +++---- src/tools/miri/src/shims/x86/ssse3.rs | 8 ++-- 14 files changed, 58 insertions(+), 68 deletions(-) diff --git a/src/tools/miri/src/alloc_addresses/mod.rs b/src/tools/miri/src/alloc_addresses/mod.rs index ae95d28d3eb65..d0f977f81433f 100644 --- a/src/tools/miri/src/alloc_addresses/mod.rs +++ b/src/tools/miri/src/alloc_addresses/mod.rs @@ -97,7 +97,7 @@ impl GlobalStateInner { fn align_addr(addr: u64, align: u64) -> u64 { match addr % align { 0 => addr, - rem => addr.checked_add(align).unwrap() - rem, + rem => addr.strict_add(align) - rem, } } diff --git a/src/tools/miri/src/eval.rs b/src/tools/miri/src/eval.rs index bd11439971c52..c0827cce26301 100644 --- a/src/tools/miri/src/eval.rs +++ b/src/tools/miri/src/eval.rs @@ -303,7 +303,7 @@ pub fn create_ecx<'tcx>( let mut argvs = Vec::>::with_capacity(config.args.len()); for arg in config.args.iter() { // Make space for `0` terminator. - let size = u64::try_from(arg.len()).unwrap().checked_add(1).unwrap(); + let size = u64::try_from(arg.len()).unwrap().strict_add(1); let arg_type = Ty::new_array(tcx, tcx.types.u8, size); let arg_place = ecx.allocate(ecx.layout_of(arg_type)?, MiriMemoryKind::Machine.into())?; diff --git a/src/tools/miri/src/helpers.rs b/src/tools/miri/src/helpers.rs index 843aff024958a..15aff010e0a96 100644 --- a/src/tools/miri/src/helpers.rs +++ b/src/tools/miri/src/helpers.rs @@ -963,7 +963,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // If `size` is smaller or equal than `bytes.len()`, writing `bytes` plus the required null // terminator to memory using the `ptr` pointer would cause an out-of-bounds access. let string_length = u64::try_from(c_str.len()).unwrap(); - let string_length = string_length.checked_add(1).unwrap(); + let string_length = string_length.strict_add(1); if size < string_length { return Ok((false, string_length)); } @@ -1027,7 +1027,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // If `size` is smaller or equal than `bytes.len()`, writing `bytes` plus the required // 0x0000 terminator to memory would cause an out-of-bounds access. let string_length = u64::try_from(wide_str.len()).unwrap(); - let string_length = string_length.checked_add(1).unwrap(); + let string_length = string_length.strict_add(1); if size < string_length { return Ok((false, string_length)); } @@ -1391,7 +1391,7 @@ pub(crate) fn windows_check_buffer_size((success, len): (bool, u64)) -> u32 { if success { // If the function succeeds, the return value is the number of characters stored in the target buffer, // not including the terminating null character. - u32::try_from(len.checked_sub(1).unwrap()).unwrap() + u32::try_from(len.strict_sub(1)).unwrap() } else { // If the target buffer was not large enough to hold the data, the return value is the buffer size, in characters, // required to hold the string and its terminating null character. diff --git a/src/tools/miri/src/shims/foreign_items.rs b/src/tools/miri/src/shims/foreign_items.rs index 5a293344cc849..f9ccc6ad4d2f6 100644 --- a/src/tools/miri/src/shims/foreign_items.rs +++ b/src/tools/miri/src/shims/foreign_items.rs @@ -402,7 +402,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { }); let (_, addr) = ptr.into_parts(); // we know the offset is absolute // Cannot panic since `align` is a power of 2 and hence non-zero. - if addr.bytes().checked_rem(align.bytes()).unwrap() != 0 { + if addr.bytes().strict_rem(align.bytes()) != 0 { throw_unsup_format!( "`miri_promise_symbolic_alignment`: pointer is not actually aligned" ); @@ -714,7 +714,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { // That is probably overly cautious, but there also is no fundamental // reason to have `strcpy` destroy pointer provenance. // This reads at least 1 byte, so we are already enforcing that this is a valid pointer. - let n = this.read_c_str(ptr_src)?.len().checked_add(1).unwrap(); + let n = this.read_c_str(ptr_src)?.len().strict_add(1); this.mem_copy(ptr_src, ptr_dest, Size::from_bytes(n), true)?; this.write_pointer(ptr_dest, dest)?; } diff --git a/src/tools/miri/src/shims/time.rs b/src/tools/miri/src/shims/time.rs index ae17196f0b78d..e8f906d37e842 100644 --- a/src/tools/miri/src/shims/time.rs +++ b/src/tools/miri/src/shims/time.rs @@ -165,7 +165,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { ("tm_hour", dt.hour().into()), ("tm_mday", dt.day().into()), ("tm_mon", dt.month0().into()), - ("tm_year", dt.year().checked_sub(1900).unwrap().into()), + ("tm_year", dt.year().strict_sub(1900).into()), ("tm_wday", dt.weekday().num_days_from_sunday().into()), ("tm_yday", dt.ordinal0().into()), ("tm_isdst", tm_isdst), diff --git a/src/tools/miri/src/shims/unix/env.rs b/src/tools/miri/src/shims/unix/env.rs index 2f78d0f42967a..405431f4327db 100644 --- a/src/tools/miri/src/shims/unix/env.rs +++ b/src/tools/miri/src/shims/unix/env.rs @@ -81,10 +81,8 @@ impl<'tcx> UnixEnvVars<'tcx> { return Ok(None); }; // The offset is used to strip the "{name}=" part of the string. - let var_ptr = var_ptr.offset( - Size::from_bytes(u64::try_from(name.len()).unwrap().checked_add(1).unwrap()), - ecx, - )?; + let var_ptr = var_ptr + .offset(Size::from_bytes(u64::try_from(name.len()).unwrap().strict_add(1)), ecx)?; Ok(Some(var_ptr)) } diff --git a/src/tools/miri/src/shims/unix/fd.rs b/src/tools/miri/src/shims/unix/fd.rs index b6ac841dc9f45..599f78e712a2a 100644 --- a/src/tools/miri/src/shims/unix/fd.rs +++ b/src/tools/miri/src/shims/unix/fd.rs @@ -240,7 +240,7 @@ impl FdTable { let new_fd = candidate_new_fd.unwrap_or_else(|| { // find_map ran out of BTreeMap entries before finding a free fd, use one plus the // maximum fd in the map - self.fds.last_key_value().map(|(fd, _)| fd.checked_add(1).unwrap()).unwrap_or(min_fd) + self.fds.last_key_value().map(|(fd, _)| fd.strict_add(1)).unwrap_or(min_fd) }); self.fds.try_insert(new_fd, file_handle).unwrap(); diff --git a/src/tools/miri/src/shims/unix/socket.rs b/src/tools/miri/src/shims/unix/socket.rs index c639ea2f84603..6d3d63b4efa02 100644 --- a/src/tools/miri/src/shims/unix/socket.rs +++ b/src/tools/miri/src/shims/unix/socket.rs @@ -116,7 +116,7 @@ impl FileDescription for SocketPair { }; let mut writebuf = writebuf.borrow_mut(); let data_size = writebuf.buf.len(); - let available_space = MAX_SOCKETPAIR_BUFFER_CAPACITY.checked_sub(data_size).unwrap(); + let available_space = MAX_SOCKETPAIR_BUFFER_CAPACITY.strict_sub(data_size); if available_space == 0 { if self.is_nonblock { // Non-blocking socketpair with a full buffer. diff --git a/src/tools/miri/src/shims/windows/foreign_items.rs b/src/tools/miri/src/shims/windows/foreign_items.rs index bfa14bcb5fad4..a8403669774d3 100644 --- a/src/tools/miri/src/shims/windows/foreign_items.rs +++ b/src/tools/miri/src/shims/windows/foreign_items.rs @@ -647,7 +647,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // If the function succeeds, the return value is the length of the string that // is copied to the buffer, in characters, not including the terminating null // character. - this.write_int(size_needed.checked_sub(1).unwrap(), dest)?; + this.write_int(size_needed.strict_sub(1), dest)?; } else { // If the buffer is too small to hold the module name, the string is truncated // to nSize characters including the terminating null character, the function @@ -689,7 +689,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { throw_unsup_format!("FormatMessageW: buffer not big enough"); } // The return value is the number of characters stored *excluding* the null terminator. - this.write_int(length.checked_sub(1).unwrap(), dest)?; + this.write_int(length.strict_sub(1), dest)?; } // Incomplete shims that we "stub out" just to get pre-main initialization code to work. diff --git a/src/tools/miri/src/shims/windows/handle.rs b/src/tools/miri/src/shims/windows/handle.rs index 58c8683ff2777..ec461a4cd3681 100644 --- a/src/tools/miri/src/shims/windows/handle.rs +++ b/src/tools/miri/src/shims/windows/handle.rs @@ -74,7 +74,7 @@ impl Handle { /// None of this layout is guaranteed to applications by Windows or Miri. fn to_packed(self) -> u32 { let disc_size = Self::packed_disc_size(); - let data_size = u32::BITS.checked_sub(disc_size).unwrap(); + let data_size = u32::BITS.strict_sub(disc_size); let discriminant = self.discriminant(); let data = self.data(); @@ -103,7 +103,7 @@ impl Handle { /// see docs for `to_packed` fn from_packed(handle: u32) -> Option { let disc_size = Self::packed_disc_size(); - let data_size = u32::BITS.checked_sub(disc_size).unwrap(); + let data_size = u32::BITS.strict_sub(disc_size); // the lower `data_size` bits of this mask are 1 #[allow(clippy::arithmetic_side_effects)] // cannot overflow diff --git a/src/tools/miri/src/shims/x86/avx2.rs b/src/tools/miri/src/shims/x86/avx2.rs index 016c525e57b41..efb0ed38fbc6e 100644 --- a/src/tools/miri/src/shims/x86/avx2.rs +++ b/src/tools/miri/src/shims/x86/avx2.rs @@ -75,7 +75,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { assert_eq!(dest_len, mask_len); let mask_item_size = mask.layout.field(this, 0).size; - let high_bit_offset = mask_item_size.bits().checked_sub(1).unwrap(); + let high_bit_offset = mask_item_size.bits().strict_sub(1); let scale = this.read_scalar(scale)?.to_i8()?; if !matches!(scale, 1 | 2 | 4 | 8) { @@ -93,8 +93,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let offset = i64::try_from(this.read_scalar(&offset)?.to_int(offset.layout.size)?) .unwrap(); - let ptr = slice - .wrapping_signed_offset(offset.checked_mul(scale).unwrap(), &this.tcx); + let ptr = slice.wrapping_signed_offset(offset.strict_mul(scale), &this.tcx); // Unaligned copy, which is what we want. this.mem_copy( ptr, @@ -127,19 +126,19 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { assert_eq!(dest_len.checked_mul(2).unwrap(), left_len); for i in 0..dest_len { - let j1 = i.checked_mul(2).unwrap(); + let j1 = i.strict_mul(2); let left1 = this.read_scalar(&this.project_index(&left, j1)?)?.to_i16()?; let right1 = this.read_scalar(&this.project_index(&right, j1)?)?.to_i16()?; - let j2 = j1.checked_add(1).unwrap(); + let j2 = j1.strict_add(1); let left2 = this.read_scalar(&this.project_index(&left, j2)?)?.to_i16()?; let right2 = this.read_scalar(&this.project_index(&right, j2)?)?.to_i16()?; let dest = this.project_index(&dest, i)?; // Multiplications are i16*i16->i32, which will not overflow. - let mul1 = i32::from(left1).checked_mul(right1.into()).unwrap(); - let mul2 = i32::from(left2).checked_mul(right2.into()).unwrap(); + let mul1 = i32::from(left1).strict_mul(right1.into()); + let mul2 = i32::from(left2).strict_mul(right2.into()); // However, this addition can overflow in the most extreme case // (-0x8000)*(-0x8000)+(-0x8000)*(-0x8000) = 0x80000000 let res = mul1.wrapping_add(mul2); @@ -164,19 +163,19 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { assert_eq!(dest_len.checked_mul(2).unwrap(), left_len); for i in 0..dest_len { - let j1 = i.checked_mul(2).unwrap(); + let j1 = i.strict_mul(2); let left1 = this.read_scalar(&this.project_index(&left, j1)?)?.to_u8()?; let right1 = this.read_scalar(&this.project_index(&right, j1)?)?.to_i8()?; - let j2 = j1.checked_add(1).unwrap(); + let j2 = j1.strict_add(1); let left2 = this.read_scalar(&this.project_index(&left, j2)?)?.to_u8()?; let right2 = this.read_scalar(&this.project_index(&right, j2)?)?.to_i8()?; let dest = this.project_index(&dest, i)?; // Multiplication of a u8 and an i8 into an i16 cannot overflow. - let mul1 = i16::from(left1).checked_mul(right1.into()).unwrap(); - let mul2 = i16::from(left2).checked_mul(right2.into()).unwrap(); + let mul1 = i16::from(left1).strict_mul(right1.into()); + let mul2 = i16::from(left2).strict_mul(right2.into()); let res = mul1.saturating_add(mul2); this.write_scalar(Scalar::from_i16(res), &dest)?; @@ -309,7 +308,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { for i in 0..2 { let dest = this.project_index(&dest, i)?; - let src = match (imm >> i.checked_mul(4).unwrap()) & 0b11 { + let src = match (imm >> i.strict_mul(4)) & 0b11 { 0 => this.project_index(&left, 0)?, 1 => this.project_index(&left, 1)?, 2 => this.project_index(&right, 0)?, @@ -343,7 +342,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let mut acc: u16 = 0; for j in 0..8 { - let src_index = i.checked_mul(8).unwrap().checked_add(j).unwrap(); + let src_index = i.strict_mul(8).strict_add(j); let left = this.project_index(&left, src_index)?; let left = this.read_scalar(&left)?.to_u8()?; @@ -351,7 +350,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let right = this.project_index(&right, src_index)?; let right = this.read_scalar(&right)?.to_u8()?; - acc = acc.checked_add(left.abs_diff(right).into()).unwrap(); + acc = acc.strict_add(left.abs_diff(right).into()); } this.write_scalar(Scalar::from_u64(acc.into()), &dest)?; @@ -377,7 +376,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let res = if right & 0x80 == 0 { // Shuffle each 128-bit (16-byte) block independently. - let j = u64::from(right % 16).checked_add(i & !15).unwrap(); + let j = u64::from(right % 16).strict_add(i & !15); this.read_scalar(&this.project_index(&left, j)?)? } else { // If the highest bit in `right` is 1, write zero. diff --git a/src/tools/miri/src/shims/x86/mod.rs b/src/tools/miri/src/shims/x86/mod.rs index 704c45fdd6d39..5db6d211a5095 100644 --- a/src/tools/miri/src/shims/x86/mod.rs +++ b/src/tools/miri/src/shims/x86/mod.rs @@ -441,8 +441,7 @@ fn apply_random_float_error( ) -> F { let rng = this.machine.rng.get_mut(); // generates rand(0, 2^64) * 2^(scale - 64) = rand(0, 1) * 2^scale - let err = - F::from_u128(rng.gen::().into()).value.scalbn(err_scale.checked_sub(64).unwrap()); + let err = F::from_u128(rng.gen::().into()).value.scalbn(err_scale.strict_sub(64)); // give it a random sign let err = if rng.gen::() { -err } else { err }; // multiple the value with (1+err) @@ -793,7 +792,7 @@ fn split_simd_to_128bit_chunks<'tcx, P: Projectable<'tcx, Provenance>>( assert_eq!(simd_layout.size.bits() % 128, 0); let num_chunks = simd_layout.size.bits() / 128; - let items_per_chunk = simd_len.checked_div(num_chunks).unwrap(); + let items_per_chunk = simd_len.strict_div(num_chunks); // Transmute to `[[T; items_per_chunk]; num_chunks]` let chunked_layout = this @@ -841,13 +840,11 @@ fn horizontal_bin_op<'tcx>( for j in 0..items_per_chunk { // `j` is the index in `dest` // `k` is the index of the 2-item chunk in `src` - let (k, src) = - if j < middle { (j, &left) } else { (j.checked_sub(middle).unwrap(), &right) }; + let (k, src) = if j < middle { (j, &left) } else { (j.strict_sub(middle), &right) }; // `base_i` is the index of the first item of the 2-item chunk in `src` - let base_i = k.checked_mul(2).unwrap(); + let base_i = k.strict_mul(2); let lhs = this.read_immediate(&this.project_index(src, base_i)?)?; - let rhs = - this.read_immediate(&this.project_index(src, base_i.checked_add(1).unwrap())?)?; + let rhs = this.read_immediate(&this.project_index(src, base_i.strict_add(1))?)?; let res = if saturating { Immediate::from(this.saturating_arith(which, &lhs, &rhs)?) @@ -900,7 +897,7 @@ fn conditional_dot_product<'tcx>( // for the initial value because the representation of 0.0 is all zero bits. let mut sum = ImmTy::from_int(0u8, element_layout); for j in 0..items_per_chunk { - if imm & (1 << j.checked_add(4).unwrap()) != 0 { + if imm & (1 << j.strict_add(4)) != 0 { let left = this.read_immediate(&this.project_index(&left, j)?)?; let right = this.read_immediate(&this.project_index(&right, j)?)?; @@ -971,7 +968,7 @@ fn test_high_bits_masked<'tcx>( assert_eq!(op_len, mask_len); - let high_bit_offset = op.layout.field(this, 0).size.bits().checked_sub(1).unwrap(); + let high_bit_offset = op.layout.field(this, 0).size.bits().strict_sub(1); let mut direct = true; let mut negated = true; @@ -1002,7 +999,7 @@ fn mask_load<'tcx>( assert_eq!(dest_len, mask_len); let mask_item_size = mask.layout.field(this, 0).size; - let high_bit_offset = mask_item_size.bits().checked_sub(1).unwrap(); + let high_bit_offset = mask_item_size.bits().strict_sub(1); let ptr = this.read_pointer(ptr)?; for i in 0..dest_len { @@ -1035,7 +1032,7 @@ fn mask_store<'tcx>( assert_eq!(value_len, mask_len); let mask_item_size = mask.layout.field(this, 0).size; - let high_bit_offset = mask_item_size.bits().checked_sub(1).unwrap(); + let high_bit_offset = mask_item_size.bits().strict_sub(1); let ptr = this.read_pointer(ptr)?; for i in 0..value_len { @@ -1082,10 +1079,10 @@ fn mpsadbw<'tcx>( let imm = this.read_scalar(imm)?.to_uint(imm.layout.size)?; // Bit 2 of `imm` specifies the offset for indices of `left`. // The offset is 0 when the bit is 0 or 4 when the bit is 1. - let left_offset = u64::try_from((imm >> 2) & 1).unwrap().checked_mul(4).unwrap(); + let left_offset = u64::try_from((imm >> 2) & 1).unwrap().strict_mul(4); // Bits 0..=1 of `imm` specify the offset for indices of // `right` in blocks of 4 elements. - let right_offset = u64::try_from(imm & 0b11).unwrap().checked_mul(4).unwrap(); + let right_offset = u64::try_from(imm & 0b11).unwrap().strict_mul(4); for i in 0..num_chunks { let left = this.project_index(&left, i)?; @@ -1093,18 +1090,16 @@ fn mpsadbw<'tcx>( let dest = this.project_index(&dest, i)?; for j in 0..dest_items_per_chunk { - let left_offset = left_offset.checked_add(j).unwrap(); + let left_offset = left_offset.strict_add(j); let mut res: u16 = 0; for k in 0..4 { let left = this - .read_scalar(&this.project_index(&left, left_offset.checked_add(k).unwrap())?)? + .read_scalar(&this.project_index(&left, left_offset.strict_add(k))?)? .to_u8()?; let right = this - .read_scalar( - &this.project_index(&right, right_offset.checked_add(k).unwrap())?, - )? + .read_scalar(&this.project_index(&right, right_offset.strict_add(k))?)? .to_u8()?; - res = res.checked_add(left.abs_diff(right).into()).unwrap(); + res = res.strict_add(left.abs_diff(right).into()); } this.write_scalar(Scalar::from_u16(res), &this.project_index(&dest, j)?)?; } @@ -1138,8 +1133,7 @@ fn pmulhrsw<'tcx>( let right = this.read_scalar(&this.project_index(&right, i)?)?.to_i16()?; let dest = this.project_index(&dest, i)?; - let res = - (i32::from(left).checked_mul(right.into()).unwrap() >> 14).checked_add(1).unwrap() >> 1; + let res = (i32::from(left).strict_mul(right.into()) >> 14).strict_add(1) >> 1; // The result of this operation can overflow a signed 16-bit integer. // When `left` and `right` are -0x8000, the result is 0x8000. @@ -1246,8 +1240,7 @@ fn pack_generic<'tcx>( let left = this.read_scalar(&this.project_index(&left, j)?)?; let right = this.read_scalar(&this.project_index(&right, j)?)?; let left_dest = this.project_index(&dest, j)?; - let right_dest = - this.project_index(&dest, j.checked_add(op_items_per_chunk).unwrap())?; + let right_dest = this.project_index(&dest, j.strict_add(op_items_per_chunk))?; let left_res = f(left)?; let right_res = f(right)?; diff --git a/src/tools/miri/src/shims/x86/sse2.rs b/src/tools/miri/src/shims/x86/sse2.rs index e10047fefe6a8..b9561ac070997 100644 --- a/src/tools/miri/src/shims/x86/sse2.rs +++ b/src/tools/miri/src/shims/x86/sse2.rs @@ -50,19 +50,19 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { assert_eq!(dest_len.checked_mul(2).unwrap(), left_len); for i in 0..dest_len { - let j1 = i.checked_mul(2).unwrap(); + let j1 = i.strict_mul(2); let left1 = this.read_scalar(&this.project_index(&left, j1)?)?.to_i16()?; let right1 = this.read_scalar(&this.project_index(&right, j1)?)?.to_i16()?; - let j2 = j1.checked_add(1).unwrap(); + let j2 = j1.strict_add(1); let left2 = this.read_scalar(&this.project_index(&left, j2)?)?.to_i16()?; let right2 = this.read_scalar(&this.project_index(&right, j2)?)?.to_i16()?; let dest = this.project_index(&dest, i)?; // Multiplications are i16*i16->i32, which will not overflow. - let mul1 = i32::from(left1).checked_mul(right1.into()).unwrap(); - let mul2 = i32::from(left2).checked_mul(right2.into()).unwrap(); + let mul1 = i32::from(left1).strict_mul(right1.into()); + let mul2 = i32::from(left2).strict_mul(right2.into()); // However, this addition can overflow in the most extreme case // (-0x8000)*(-0x8000)+(-0x8000)*(-0x8000) = 0x80000000 let res = mul1.wrapping_add(mul2); @@ -94,14 +94,14 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let dest = this.project_index(&dest, i)?; let mut res: u16 = 0; - let n = left_len.checked_div(dest_len).unwrap(); + let n = left_len.strict_div(dest_len); for j in 0..n { - let op_i = j.checked_add(i.checked_mul(n).unwrap()).unwrap(); + let op_i = j.strict_add(i.strict_mul(n)); let left = this.read_scalar(&this.project_index(&left, op_i)?)?.to_u8()?; let right = this.read_scalar(&this.project_index(&right, op_i)?)?.to_u8()?; - res = res.checked_add(left.abs_diff(right).into()).unwrap(); + res = res.strict_add(left.abs_diff(right).into()); } this.write_scalar(Scalar::from_u64(res.into()), &dest)?; diff --git a/src/tools/miri/src/shims/x86/ssse3.rs b/src/tools/miri/src/shims/x86/ssse3.rs index 6a815e4cea3c6..33bcbc2fa83d6 100644 --- a/src/tools/miri/src/shims/x86/ssse3.rs +++ b/src/tools/miri/src/shims/x86/ssse3.rs @@ -92,19 +92,19 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { assert_eq!(dest_len.checked_mul(2).unwrap(), left_len); for i in 0..dest_len { - let j1 = i.checked_mul(2).unwrap(); + let j1 = i.strict_mul(2); let left1 = this.read_scalar(&this.project_index(&left, j1)?)?.to_u8()?; let right1 = this.read_scalar(&this.project_index(&right, j1)?)?.to_i8()?; - let j2 = j1.checked_add(1).unwrap(); + let j2 = j1.strict_add(1); let left2 = this.read_scalar(&this.project_index(&left, j2)?)?.to_u8()?; let right2 = this.read_scalar(&this.project_index(&right, j2)?)?.to_i8()?; let dest = this.project_index(&dest, i)?; // Multiplication of a u8 and an i8 into an i16 cannot overflow. - let mul1 = i16::from(left1).checked_mul(right1.into()).unwrap(); - let mul2 = i16::from(left2).checked_mul(right2.into()).unwrap(); + let mul1 = i16::from(left1).strict_mul(right1.into()); + let mul2 = i16::from(left2).strict_mul(right2.into()); let res = mul1.saturating_add(mul2); this.write_scalar(Scalar::from_i16(res), &dest)?; From 1ee4a5ae0160bdd41a3aaa665ba482b8126df49c Mon Sep 17 00:00:00 2001 From: Southball <6523469+southball@users.noreply.github.com> Date: Fri, 21 Jun 2024 14:26:47 +0900 Subject: [PATCH 239/892] Fix some missing ones --- src/tools/miri/src/shims/x86/avx2.rs | 6 +++--- src/tools/miri/src/shims/x86/mod.rs | 4 ++-- src/tools/miri/src/shims/x86/sse2.rs | 2 +- src/tools/miri/src/shims/x86/ssse3.rs | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/tools/miri/src/shims/x86/avx2.rs b/src/tools/miri/src/shims/x86/avx2.rs index efb0ed38fbc6e..7f6c9336a9749 100644 --- a/src/tools/miri/src/shims/x86/avx2.rs +++ b/src/tools/miri/src/shims/x86/avx2.rs @@ -123,7 +123,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let (dest, dest_len) = this.mplace_to_simd(dest)?; assert_eq!(left_len, right_len); - assert_eq!(dest_len.checked_mul(2).unwrap(), left_len); + assert_eq!(dest_len.strict_mul(2), left_len); for i in 0..dest_len { let j1 = i.strict_mul(2); @@ -160,7 +160,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let (dest, dest_len) = this.mplace_to_simd(dest)?; assert_eq!(left_len, right_len); - assert_eq!(dest_len.checked_mul(2).unwrap(), left_len); + assert_eq!(dest_len.strict_mul(2), left_len); for i in 0..dest_len { let j1 = i.strict_mul(2); @@ -335,7 +335,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let (dest, dest_len) = this.mplace_to_simd(dest)?; assert_eq!(left_len, right_len); - assert_eq!(left_len, dest_len.checked_mul(8).unwrap()); + assert_eq!(left_len, dest_len.strict_mul(8)); for i in 0..dest_len { let dest = this.project_index(&dest, i)?; diff --git a/src/tools/miri/src/shims/x86/mod.rs b/src/tools/miri/src/shims/x86/mod.rs index 5db6d211a5095..03c186e629004 100644 --- a/src/tools/miri/src/shims/x86/mod.rs +++ b/src/tools/miri/src/shims/x86/mod.rs @@ -1074,7 +1074,7 @@ fn mpsadbw<'tcx>( let (_, _, right) = split_simd_to_128bit_chunks(this, right)?; let (_, dest_items_per_chunk, dest) = split_simd_to_128bit_chunks(this, dest)?; - assert_eq!(op_items_per_chunk, dest_items_per_chunk.checked_mul(2).unwrap()); + assert_eq!(op_items_per_chunk, dest_items_per_chunk.strict_mul(2)); let imm = this.read_scalar(imm)?.to_uint(imm.layout.size)?; // Bit 2 of `imm` specifies the offset for indices of `left`. @@ -1229,7 +1229,7 @@ fn pack_generic<'tcx>( let (_, _, right) = split_simd_to_128bit_chunks(this, right)?; let (_, dest_items_per_chunk, dest) = split_simd_to_128bit_chunks(this, dest)?; - assert_eq!(dest_items_per_chunk, op_items_per_chunk.checked_mul(2).unwrap()); + assert_eq!(dest_items_per_chunk, op_items_per_chunk.strict_mul(2)); for i in 0..num_chunks { let left = this.project_index(&left, i)?; diff --git a/src/tools/miri/src/shims/x86/sse2.rs b/src/tools/miri/src/shims/x86/sse2.rs index b9561ac070997..3efdd561d6c60 100644 --- a/src/tools/miri/src/shims/x86/sse2.rs +++ b/src/tools/miri/src/shims/x86/sse2.rs @@ -47,7 +47,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let (dest, dest_len) = this.mplace_to_simd(dest)?; assert_eq!(left_len, right_len); - assert_eq!(dest_len.checked_mul(2).unwrap(), left_len); + assert_eq!(dest_len.strict_mul(2), left_len); for i in 0..dest_len { let j1 = i.strict_mul(2); diff --git a/src/tools/miri/src/shims/x86/ssse3.rs b/src/tools/miri/src/shims/x86/ssse3.rs index 33bcbc2fa83d6..ecacaeb9af524 100644 --- a/src/tools/miri/src/shims/x86/ssse3.rs +++ b/src/tools/miri/src/shims/x86/ssse3.rs @@ -89,7 +89,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let (dest, dest_len) = this.mplace_to_simd(dest)?; assert_eq!(left_len, right_len); - assert_eq!(dest_len.checked_mul(2).unwrap(), left_len); + assert_eq!(dest_len.strict_mul(2), left_len); for i in 0..dest_len { let j1 = i.strict_mul(2); From 4baae5d8b3f5b681097c5afe9ad3e1494f223b1b Mon Sep 17 00:00:00 2001 From: Jason Newcomb Date: Wed, 19 Jun 2024 20:43:33 -0400 Subject: [PATCH 240/892] Add new `Span` utils to avoid both allocating and compressing/decompressing spans. --- clippy_lints/src/cognitive_complexity.rs | 22 +- clippy_lints/src/copies.rs | 16 +- clippy_lints/src/implicit_hasher.rs | 40 ++-- clippy_lints/src/matches/single_match.rs | 4 +- clippy_lints/src/methods/manual_inspect.rs | 31 ++- clippy_lints/src/missing_doc.rs | 7 +- clippy_lints/src/multiple_bound_locations.rs | 8 +- clippy_lints/src/needless_else.rs | 16 +- clippy_lints/src/needless_if.rs | 24 +- .../src/non_octal_unix_permissions.rs | 12 +- clippy_lints/src/octal_escapes.rs | 15 +- clippy_lints/src/ranges.rs | 19 +- clippy_utils/src/consts.rs | 8 +- clippy_utils/src/hir_utils.rs | 6 +- clippy_utils/src/source.rs | 224 ++++++++++++++---- 15 files changed, 296 insertions(+), 156 deletions(-) diff --git a/clippy_lints/src/cognitive_complexity.rs b/clippy_lints/src/cognitive_complexity.rs index e41abf422349d..60815f4f2afbb 100644 --- a/clippy_lints/src/cognitive_complexity.rs +++ b/clippy_lints/src/cognitive_complexity.rs @@ -1,7 +1,7 @@ //! calculate cognitive complexity and warn about overly complex functions use clippy_utils::diagnostics::span_lint_and_help; -use clippy_utils::source::snippet_opt; +use clippy_utils::source::{IntoSpan, SpanRangeExt}; use clippy_utils::ty::is_type_diagnostic_item; use clippy_utils::visitors::for_each_expr_without_closures; use clippy_utils::{get_async_fn_body, is_async_fn, LimitStack}; @@ -12,7 +12,7 @@ use rustc_hir::{Body, Expr, ExprKind, FnDecl}; use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_session::impl_lint_pass; use rustc_span::def_id::LocalDefId; -use rustc_span::{sym, BytePos, Span}; +use rustc_span::{sym, Span}; declare_clippy_lint! { /// ### What it does @@ -50,7 +50,6 @@ impl CognitiveComplexity { impl_lint_pass!(CognitiveComplexity => [COGNITIVE_COMPLEXITY]); impl CognitiveComplexity { - #[expect(clippy::cast_possible_truncation)] fn check<'tcx>( &mut self, cx: &LateContext<'tcx>, @@ -100,17 +99,12 @@ impl CognitiveComplexity { FnKind::ItemFn(ident, _, _) | FnKind::Method(ident, _) => ident.span, FnKind::Closure => { let header_span = body_span.with_hi(decl.output.span().lo()); - let pos = snippet_opt(cx, header_span).and_then(|snip| { - let low_offset = snip.find('|')?; - let high_offset = 1 + snip.get(low_offset + 1..)?.find('|')?; - let low = header_span.lo() + BytePos(low_offset as u32); - let high = low + BytePos(high_offset as u32 + 1); - - Some((low, high)) - }); - - if let Some((low, high)) = pos { - Span::new(low, high, header_span.ctxt(), header_span.parent()) + #[expect(clippy::range_plus_one)] + if let Some(range) = header_span.map_range(cx, |src, range| { + let mut idxs = src.get(range.clone())?.match_indices('|'); + Some(range.start + idxs.next()?.0..range.start + idxs.next()?.0 + 1) + }) { + range.with_ctxt(header_span.ctxt()) } else { return; } diff --git a/clippy_lints/src/copies.rs b/clippy_lints/src/copies.rs index 480df675d7544..d896452be9209 100644 --- a/clippy_lints/src/copies.rs +++ b/clippy_lints/src/copies.rs @@ -1,5 +1,5 @@ use clippy_utils::diagnostics::{span_lint_and_note, span_lint_and_then}; -use clippy_utils::source::{first_line_of_span, indent_of, reindent_multiline, snippet, snippet_opt}; +use clippy_utils::source::{first_line_of_span, indent_of, reindent_multiline, snippet, IntoSpan, SpanRangeExt}; use clippy_utils::ty::{needs_ordered_drop, InteriorMut}; use clippy_utils::visitors::for_each_expr_without_closures; use clippy_utils::{ @@ -14,7 +14,7 @@ use rustc_lint::{LateContext, LateLintPass}; use rustc_session::impl_lint_pass; use rustc_span::hygiene::walk_chain; use rustc_span::source_map::SourceMap; -use rustc_span::{BytePos, Span, Symbol}; +use rustc_span::{Span, Symbol}; use std::borrow::Cow; declare_clippy_lint! { @@ -266,12 +266,12 @@ fn lint_branches_sharing_code<'tcx>( let span = span.with_hi(last_block.span.hi()); // Improve formatting if the inner block has indention (i.e. normal Rust formatting) - let test_span = Span::new(span.lo() - BytePos(4), span.lo(), span.ctxt(), span.parent()); - let span = if snippet_opt(cx, test_span).map_or(false, |snip| snip == " ") { - span.with_lo(test_span.lo()) - } else { - span - }; + let span = span + .map_range(cx, |src, range| { + (range.start > 4 && src.get(range.start - 4..range.start)? == " ") + .then_some(range.start - 4..range.end) + }) + .map_or(span, |range| range.with_ctxt(span.ctxt())); (span, suggestion.to_string()) }); diff --git a/clippy_lints/src/implicit_hasher.rs b/clippy_lints/src/implicit_hasher.rs index ca830af3b2f36..344a04e6e7e82 100644 --- a/clippy_lints/src/implicit_hasher.rs +++ b/clippy_lints/src/implicit_hasher.rs @@ -14,7 +14,7 @@ use rustc_span::symbol::sym; use rustc_span::Span; use clippy_utils::diagnostics::{multispan_sugg, span_lint_and_then}; -use clippy_utils::source::{snippet, snippet_opt}; +use clippy_utils::source::{snippet, IntoSpan, SpanRangeExt}; use clippy_utils::ty::is_type_diagnostic_item; declare_clippy_lint! { @@ -59,10 +59,8 @@ declare_clippy_lint! { declare_lint_pass!(ImplicitHasher => [IMPLICIT_HASHER]); impl<'tcx> LateLintPass<'tcx> for ImplicitHasher { - #[expect(clippy::cast_possible_truncation, clippy::too_many_lines)] + #[expect(clippy::too_many_lines)] fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) { - use rustc_span::BytePos; - fn suggestion( cx: &LateContext<'_>, diag: &mut Diag<'_, ()>, @@ -123,10 +121,11 @@ impl<'tcx> LateLintPass<'tcx> for ImplicitHasher { } let generics_suggestion_span = impl_.generics.span.substitute_dummy({ - let pos = snippet_opt(cx, item.span.until(target.span())) - .and_then(|snip| Some(item.span.lo() + BytePos(snip.find("impl")? as u32 + 4))); - if let Some(pos) = pos { - Span::new(pos, pos, item.span.ctxt(), item.span.parent()) + let range = (item.span.lo()..target.span().lo()).map_range(cx, |src, range| { + Some(src.get(range.clone())?.find("impl")? + 4..range.end) + }); + if let Some(range) = range { + range.with_ctxt(item.span.ctxt()) } else { return; } @@ -163,21 +162,16 @@ impl<'tcx> LateLintPass<'tcx> for ImplicitHasher { continue; } let generics_suggestion_span = generics.span.substitute_dummy({ - let pos = snippet_opt( - cx, - Span::new( - item.span.lo(), - body.params[0].pat.span.lo(), - item.span.ctxt(), - item.span.parent(), - ), - ) - .and_then(|snip| { - let i = snip.find("fn")?; - Some(item.span.lo() + BytePos((i + snip[i..].find('(')?) as u32)) - }) - .expect("failed to create span for type parameters"); - Span::new(pos, pos, item.span.ctxt(), item.span.parent()) + let range = (item.span.lo()..body.params[0].pat.span.lo()).map_range(cx, |src, range| { + let (pre, post) = src.get(range.clone())?.split_once("fn")?; + let pos = post.find('(')? + pre.len() + 2; + Some(pos..pos) + }); + if let Some(range) = range { + range.with_ctxt(item.span.ctxt()) + } else { + return; + } }); let mut ctr_vis = ImplicitHasherConstructorVisitor::new(cx, target); diff --git a/clippy_lints/src/matches/single_match.rs b/clippy_lints/src/matches/single_match.rs index 69791414f72c6..99fdbcff890b4 100644 --- a/clippy_lints/src/matches/single_match.rs +++ b/clippy_lints/src/matches/single_match.rs @@ -1,5 +1,5 @@ use clippy_utils::diagnostics::span_lint_and_sugg; -use clippy_utils::source::{expr_block, get_source_text, snippet}; +use clippy_utils::source::{expr_block, snippet, SpanRangeExt}; use clippy_utils::ty::{implements_trait, is_type_diagnostic_item, peel_mid_ty_refs}; use clippy_utils::{is_lint_allowed, is_unit_expr, is_wild, peel_blocks, peel_hir_pat_refs, peel_n_hir_expr_refs}; use core::cmp::max; @@ -17,7 +17,7 @@ use super::{MATCH_BOOL, SINGLE_MATCH, SINGLE_MATCH_ELSE}; /// span, e.g. a string literal `"//"`, but we know that this isn't the case for empty /// match arms. fn empty_arm_has_comment(cx: &LateContext<'_>, span: Span) -> bool { - if let Some(ff) = get_source_text(cx, span) + if let Some(ff) = span.get_source_text(cx) && let Some(text) = ff.as_str() { text.as_bytes().windows(2).any(|w| w == b"//" || w == b"/*") diff --git a/clippy_lints/src/methods/manual_inspect.rs b/clippy_lints/src/methods/manual_inspect.rs index 2f9b951c6a76c..e3ce64c246a54 100644 --- a/clippy_lints/src/methods/manual_inspect.rs +++ b/clippy_lints/src/methods/manual_inspect.rs @@ -1,6 +1,6 @@ use clippy_config::msrvs::{self, Msrv}; use clippy_utils::diagnostics::span_lint_and_then; -use clippy_utils::source::{get_source_text, with_leading_whitespace, SpanRange}; +use clippy_utils::source::{IntoSpan, SpanRangeExt}; use clippy_utils::ty::get_field_by_name; use clippy_utils::visitors::{for_each_expr, for_each_expr_without_closures}; use clippy_utils::{expr_use_ctxt, is_diag_item_method, is_diag_trait_item, path_to_local_id, ExprUseNode}; @@ -9,7 +9,7 @@ use rustc_errors::Applicability; use rustc_hir::{BindingMode, BorrowKind, ByRef, ClosureKind, Expr, ExprKind, Mutability, Node, PatKind}; use rustc_lint::LateContext; use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow, AutoBorrowMutability}; -use rustc_span::{sym, BytePos, Span, Symbol, DUMMY_SP}; +use rustc_span::{sym, Span, Symbol, DUMMY_SP}; use super::MANUAL_INSPECT; @@ -98,17 +98,19 @@ pub(crate) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, arg: &Expr<'_>, name: let mut addr_of_edits = Vec::with_capacity(delayed.len()); for x in delayed { match x { - UseKind::Return(s) => edits.push((with_leading_whitespace(cx, s).set_span_pos(s), String::new())), + UseKind::Return(s) => edits.push((s.with_leading_whitespace(cx).with_ctxt(s.ctxt()), String::new())), UseKind::Borrowed(s) => { - if let Some(src) = get_source_text(cx, s) - && let Some(src) = src.as_str() - && let trim_src = src.trim_start_matches([' ', '\t', '\n', '\r', '(']) - && trim_src.starts_with('&') - { - let range = s.into_range(); - #[expect(clippy::cast_possible_truncation)] - let start = BytePos(range.start.0 + (src.len() - trim_src.len()) as u32); - addr_of_edits.push(((start..BytePos(start.0 + 1)).set_span_pos(s), String::new())); + #[expect(clippy::range_plus_one)] + let range = s.map_range(cx, |src, range| { + let src = src.get(range.clone())?; + let trimmed = src.trim_start_matches([' ', '\t', '\n', '\r', '(']); + trimmed.starts_with('&').then(|| { + let pos = range.start + src.len() - trimmed.len(); + pos..pos + 1 + }) + }); + if let Some(range) = range { + addr_of_edits.push((range.with_ctxt(s.ctxt()), String::new())); } else { requires_copy = true; requires_deref = true; @@ -174,7 +176,10 @@ pub(crate) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, arg: &Expr<'_>, name: }), )); edits.push(( - with_leading_whitespace(cx, final_expr.span).set_span_pos(final_expr.span), + final_expr + .span + .with_leading_whitespace(cx) + .with_ctxt(final_expr.span.ctxt()), String::new(), )); let app = if edits.iter().any(|(s, _)| s.from_expansion()) { diff --git a/clippy_lints/src/missing_doc.rs b/clippy_lints/src/missing_doc.rs index ca344dc5c8109..250fd5cbd483b 100644 --- a/clippy_lints/src/missing_doc.rs +++ b/clippy_lints/src/missing_doc.rs @@ -8,7 +8,7 @@ use clippy_utils::attrs::is_doc_hidden; use clippy_utils::diagnostics::span_lint; use clippy_utils::is_from_proc_macro; -use clippy_utils::source::snippet_opt; +use clippy_utils::source::SpanRangeExt; use rustc_ast::ast::{self, MetaItem, MetaItemKind}; use rustc_hir as hir; use rustc_hir::def_id::LocalDefId; @@ -266,8 +266,5 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc { } fn span_to_snippet_contains_docs(cx: &LateContext<'_>, search_span: Span) -> bool { - let Some(snippet) = snippet_opt(cx, search_span) else { - return false; - }; - snippet.lines().rev().any(|line| line.trim().starts_with("///")) + search_span.check_source_text(cx, |src| src.lines().rev().any(|line| line.trim().starts_with("///"))) } diff --git a/clippy_lints/src/multiple_bound_locations.rs b/clippy_lints/src/multiple_bound_locations.rs index d608f3bf7b4d5..d276e29bacecf 100644 --- a/clippy_lints/src/multiple_bound_locations.rs +++ b/clippy_lints/src/multiple_bound_locations.rs @@ -6,7 +6,7 @@ use rustc_session::declare_lint_pass; use rustc_span::Span; use clippy_utils::diagnostics::span_lint; -use clippy_utils::source::snippet_opt; +use clippy_utils::source::SpanRangeExt; declare_clippy_lint! { /// ### What it does @@ -54,8 +54,10 @@ impl EarlyLintPass for MultipleBoundLocations { match clause { WherePredicate::BoundPredicate(pred) => { if (!pred.bound_generic_params.is_empty() || !pred.bounds.is_empty()) - && let Some(name) = snippet_opt(cx, pred.bounded_ty.span) - && let Some(bound_span) = generic_params_with_bounds.get(name.as_str()) + && let Some(Some(bound_span)) = pred + .bounded_ty + .span + .with_source_text(cx, |src| generic_params_with_bounds.get(src)) { emit_lint(cx, *bound_span, pred.bounded_ty.span); } diff --git a/clippy_lints/src/needless_else.rs b/clippy_lints/src/needless_else.rs index b6aad69d1668c..f8bb72a16db2b 100644 --- a/clippy_lints/src/needless_else.rs +++ b/clippy_lints/src/needless_else.rs @@ -1,8 +1,8 @@ use clippy_utils::diagnostics::span_lint_and_sugg; -use clippy_utils::source::{snippet_opt, trim_span}; +use clippy_utils::source::{IntoSpan, SpanRangeExt}; use rustc_ast::ast::{Expr, ExprKind}; use rustc_errors::Applicability; -use rustc_lint::{EarlyContext, EarlyLintPass, LintContext}; +use rustc_lint::{EarlyContext, EarlyLintPass}; use rustc_session::declare_lint_pass; declare_clippy_lint! { @@ -41,16 +41,16 @@ impl EarlyLintPass for NeedlessElse { && !expr.span.from_expansion() && !else_clause.span.from_expansion() && block.stmts.is_empty() - && let Some(trimmed) = expr.span.trim_start(then_block.span) - && let span = trim_span(cx.sess().source_map(), trimmed) - && let Some(else_snippet) = snippet_opt(cx, span) - // Ignore else blocks that contain comments or #[cfg]s - && !else_snippet.contains(['/', '#']) + && let range = (then_block.span.hi()..expr.span.hi()).trim_start(cx) + && range.clone().check_source_text(cx, |src| { + // Ignore else blocks that contain comments or #[cfg]s + !src.contains(['/', '#']) + }) { span_lint_and_sugg( cx, NEEDLESS_ELSE, - span, + range.with_ctxt(expr.span.ctxt()), "this `else` branch is empty", "you can remove it", String::new(), diff --git a/clippy_lints/src/needless_if.rs b/clippy_lints/src/needless_if.rs index 51bee4b51f6f9..1d6233d432a75 100644 --- a/clippy_lints/src/needless_if.rs +++ b/clippy_lints/src/needless_if.rs @@ -1,7 +1,7 @@ use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::higher::If; use clippy_utils::is_from_proc_macro; -use clippy_utils::source::snippet_opt; +use clippy_utils::source::{snippet_opt, SpanRangeExt}; use rustc_errors::Applicability; use rustc_hir::{ExprKind, Stmt, StmtKind}; use rustc_lint::{LateContext, LateLintPass, LintContext}; @@ -39,18 +39,24 @@ declare_lint_pass!(NeedlessIf => [NEEDLESS_IF]); impl LateLintPass<'_> for NeedlessIf { fn check_stmt<'tcx>(&mut self, cx: &LateContext<'tcx>, stmt: &Stmt<'tcx>) { if let StmtKind::Expr(expr) = stmt.kind - && let Some(If {cond, then, r#else: None }) = If::hir(expr) + && let Some(If { + cond, + then, + r#else: None, + }) = If::hir(expr) && let ExprKind::Block(block, ..) = then.kind && block.stmts.is_empty() && block.expr.is_none() && !in_external_macro(cx.sess(), expr.span) - && let Some(then_snippet) = snippet_opt(cx, then.span) - // Ignore - // - empty macro expansions - // - empty reptitions in macro expansions - // - comments - // - #[cfg]'d out code - && then_snippet.chars().all(|ch| matches!(ch, '{' | '}') || ch.is_ascii_whitespace()) + && then.span.check_source_text(cx, |src| { + // Ignore + // - empty macro expansions + // - empty reptitions in macro expansions + // - comments + // - #[cfg]'d out code + src.bytes() + .all(|ch| matches!(ch, b'{' | b'}') || ch.is_ascii_whitespace()) + }) && let Some(cond_snippet) = snippet_opt(cx, cond.span) && !is_from_proc_macro(cx, expr) { diff --git a/clippy_lints/src/non_octal_unix_permissions.rs b/clippy_lints/src/non_octal_unix_permissions.rs index 2701d6bdca391..b915df527629e 100644 --- a/clippy_lints/src/non_octal_unix_permissions.rs +++ b/clippy_lints/src/non_octal_unix_permissions.rs @@ -1,5 +1,5 @@ use clippy_utils::diagnostics::span_lint_and_sugg; -use clippy_utils::source::{snippet_opt, snippet_with_applicability}; +use clippy_utils::source::{snippet_with_applicability, SpanRangeExt}; use clippy_utils::{match_def_path, paths}; use rustc_errors::Applicability; use rustc_hir::{Expr, ExprKind}; @@ -53,8 +53,9 @@ impl<'tcx> LateLintPass<'tcx> for NonOctalUnixPermissions { && cx.tcx.is_diagnostic_item(sym::FsPermissions, adt.did()))) && let ExprKind::Lit(_) = param.kind && param.span.eq_ctxt(expr.span) - && let Some(snip) = snippet_opt(cx, param.span) - && !(snip.starts_with("0o") || snip.starts_with("0b")) + && param + .span + .check_source_text(cx, |src| !matches!(src.as_bytes(), [b'0', b'o' | b'b', ..])) { show_error(cx, param); } @@ -65,8 +66,9 @@ impl<'tcx> LateLintPass<'tcx> for NonOctalUnixPermissions { && match_def_path(cx, def_id, &paths::PERMISSIONS_FROM_MODE) && let ExprKind::Lit(_) = param.kind && param.span.eq_ctxt(expr.span) - && let Some(snip) = snippet_opt(cx, param.span) - && !(snip.starts_with("0o") || snip.starts_with("0b")) + && param + .span + .check_source_text(cx, |src| !matches!(src.as_bytes(), [b'0', b'o' | b'b', ..])) { show_error(cx, param); } diff --git a/clippy_lints/src/octal_escapes.rs b/clippy_lints/src/octal_escapes.rs index 0a7a2cd616ca9..2eae9b23746df 100644 --- a/clippy_lints/src/octal_escapes.rs +++ b/clippy_lints/src/octal_escapes.rs @@ -1,5 +1,5 @@ use clippy_utils::diagnostics::span_lint_and_then; -use clippy_utils::source::get_source_text; +use clippy_utils::source::SpanRangeExt; use rustc_ast::token::LitKind; use rustc_ast::{Expr, ExprKind}; use rustc_errors::Applicability; @@ -87,14 +87,11 @@ impl EarlyLintPass for OctalEscapes { // Last check to make sure the source text matches what we read from the string. // Macros are involved somehow if this doesn't match. - if let Some(src) = get_source_text(cx, span) - && let Some(src) = src.as_str() - && match *src.as_bytes() { - [b'\\', b'0', lo] => lo == c_lo, - [b'\\', b'0', hi, lo] => hi == c_hi && lo == c_lo, - _ => false, - } - { + if span.check_source_text(cx, |src| match *src.as_bytes() { + [b'\\', b'0', lo] => lo == c_lo, + [b'\\', b'0', hi, lo] => hi == c_hi && lo == c_lo, + _ => false, + }) { span_lint_and_then(cx, OCTAL_ESCAPES, span, "octal-looking escape in a literal", |diag| { diag.help_once("octal escapes are not supported, `\\0` is always null") .span_suggestion( diff --git a/clippy_lints/src/ranges.rs b/clippy_lints/src/ranges.rs index 186e548d37304..4fdaa9f00a19c 100644 --- a/clippy_lints/src/ranges.rs +++ b/clippy_lints/src/ranges.rs @@ -1,7 +1,7 @@ use clippy_config::msrvs::{self, Msrv}; use clippy_utils::consts::{constant, Constant}; use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg, span_lint_and_then}; -use clippy_utils::source::{snippet, snippet_opt, snippet_with_applicability}; +use clippy_utils::source::{snippet, snippet_with_applicability, SpanRangeExt}; use clippy_utils::sugg::Sugg; use clippy_utils::{get_parent_expr, higher, in_constant, is_integer_const, path_to_local}; use rustc_ast::ast::RangeLimits; @@ -285,9 +285,10 @@ fn check_possible_range_contains( if let ExprKind::Binary(ref lhs_op, _left, new_lhs) = left.kind && op == lhs_op.node && let new_span = Span::new(new_lhs.span.lo(), right.span.hi(), expr.span.ctxt(), expr.span.parent()) - && let Some(snip) = &snippet_opt(cx, new_span) - // Do not continue if we have mismatched number of parens, otherwise the suggestion is wrong - && snip.matches('(').count() == snip.matches(')').count() + && new_span.check_source_text(cx, |src| { + // Do not continue if we have mismatched number of parens, otherwise the suggestion is wrong + src.matches('(').count() == src.matches(')').count() + }) { check_possible_range_contains(cx, op, new_lhs, right, expr, new_span); } @@ -363,17 +364,19 @@ fn check_exclusive_range_plus_one(cx: &LateContext<'_>, expr: &Expr<'_>) { |diag| { let start = start.map_or(String::new(), |x| Sugg::hir(cx, x, "x").maybe_par().to_string()); let end = Sugg::hir(cx, y, "y").maybe_par(); - if let Some(is_wrapped) = &snippet_opt(cx, span) { - if is_wrapped.starts_with('(') && is_wrapped.ends_with(')') { + match span.with_source_text(cx, |src| src.starts_with('(') && src.ends_with(')')) { + Some(true) => { diag.span_suggestion(span, "use", format!("({start}..={end})"), Applicability::MaybeIncorrect); - } else { + }, + Some(false) => { diag.span_suggestion( span, "use", format!("{start}..={end}"), Applicability::MachineApplicable, // snippet ); - } + }, + None => {}, } }, ); diff --git a/clippy_utils/src/consts.rs b/clippy_utils/src/consts.rs index 8f6389ee07726..867c93c278e6a 100644 --- a/clippy_utils/src/consts.rs +++ b/clippy_utils/src/consts.rs @@ -1,7 +1,7 @@ #![allow(clippy::float_cmp)] use crate::macros::HirNode; -use crate::source::{get_source_text, walk_span_to_context}; +use crate::source::{walk_span_to_context, SpanRangeExt}; use crate::{clip, is_direct_expn_of, sext, unsext}; use rustc_ast::ast::{self, LitFloatType, LitKind}; @@ -15,8 +15,8 @@ use rustc_middle::mir::ConstValue; use rustc_middle::ty::{self, EarlyBinder, FloatTy, GenericArgsRef, IntTy, List, ScalarInt, Ty, TyCtxt, UintTy}; use rustc_middle::{bug, mir, span_bug}; use rustc_span::def_id::DefId; +use rustc_span::sym; use rustc_span::symbol::{Ident, Symbol}; -use rustc_span::{sym, SyntaxContext}; use rustc_target::abi::Size; use std::cmp::Ordering; use std::hash::{Hash, Hasher}; @@ -664,11 +664,11 @@ impl<'a, 'tcx> ConstEvalLateContext<'a, 'tcx> { { // Try to detect any `cfg`ed statements or empty macro expansions. let span = block.span.data(); - if span.ctxt == SyntaxContext::root() { + if span.ctxt.is_root() { if let Some(expr_span) = walk_span_to_context(expr.span, span.ctxt) && let expr_lo = expr_span.lo() && expr_lo >= span.lo - && let Some(src) = get_source_text(self.lcx, span.lo..expr_lo) + && let Some(src) = (span.lo..expr_lo).get_source_text(self.lcx) && let Some(src) = src.as_str() { use rustc_lexer::TokenKind::{BlockComment, LineComment, OpenBrace, Semi, Whitespace}; diff --git a/clippy_utils/src/hir_utils.rs b/clippy_utils/src/hir_utils.rs index 50dd8430ac069..8706cec5d388a 100644 --- a/clippy_utils/src/hir_utils.rs +++ b/clippy_utils/src/hir_utils.rs @@ -1,6 +1,6 @@ use crate::consts::constant_simple; use crate::macros::macro_backtrace; -use crate::source::{get_source_text, snippet_opt, walk_span_to_context, SpanRange}; +use crate::source::{snippet_opt, walk_span_to_context, SpanRange, SpanRangeExt}; use crate::tokenize_with_text; use rustc_ast::ast::InlineAsmTemplatePiece; use rustc_data_structures::fx::FxHasher; @@ -1173,9 +1173,9 @@ fn eq_span_tokens( pred: impl Fn(TokenKind) -> bool, ) -> bool { fn f(cx: &LateContext<'_>, left: Range, right: Range, pred: impl Fn(TokenKind) -> bool) -> bool { - if let Some(lsrc) = get_source_text(cx, left) + if let Some(lsrc) = left.get_source_text(cx) && let Some(lsrc) = lsrc.as_str() - && let Some(rsrc) = get_source_text(cx, right) + && let Some(rsrc) = right.get_source_text(cx) && let Some(rsrc) = rsrc.as_str() { let pred = |t: &(_, _)| pred(t.0); diff --git a/clippy_utils/src/source.rs b/clippy_utils/src/source.rs index 69b122cbfadae..496c8f5b55373 100644 --- a/clippy_utils/src/source.rs +++ b/clippy_utils/src/source.rs @@ -9,22 +9,17 @@ use rustc_hir::{BlockCheckMode, Expr, ExprKind, UnsafeSource}; use rustc_lint::{LateContext, LintContext}; use rustc_session::Session; use rustc_span::source_map::{original_sp, SourceMap}; -use rustc_span::{hygiene, BytePos, Pos, SourceFile, SourceFileAndLine, Span, SpanData, SyntaxContext, DUMMY_SP}; +use rustc_span::{ + hygiene, BytePos, FileNameDisplayPreference, Pos, SourceFile, SourceFileAndLine, Span, SpanData, SyntaxContext, + DUMMY_SP, +}; use std::borrow::Cow; +use std::fmt; use std::ops::Range; -/// A type which can be converted to the range portion of a `Span`. +/// Conversion of a value into the range portion of a `Span`. pub trait SpanRange: Sized { fn into_range(self) -> Range; - fn set_span_pos(self, sp: Span) -> Span { - let range = self.into_range(); - SpanData { - lo: range.start, - hi: range.end, - ..sp.data() - } - .span() - } } impl SpanRange for Span { fn into_range(self) -> Range { @@ -43,6 +38,182 @@ impl SpanRange for Range { } } +/// Conversion of a value into a `Span` +pub trait IntoSpan: Sized { + fn into_span(self) -> Span; + fn with_ctxt(self, ctxt: SyntaxContext) -> Span; +} +impl IntoSpan for Span { + fn into_span(self) -> Span { + self + } + fn with_ctxt(self, ctxt: SyntaxContext) -> Span { + self.with_ctxt(ctxt) + } +} +impl IntoSpan for SpanData { + fn into_span(self) -> Span { + self.span() + } + fn with_ctxt(self, ctxt: SyntaxContext) -> Span { + Span::new(self.lo, self.hi, ctxt, self.parent) + } +} +impl IntoSpan for Range { + fn into_span(self) -> Span { + Span::with_root_ctxt(self.start, self.end) + } + fn with_ctxt(self, ctxt: SyntaxContext) -> Span { + Span::new(self.start, self.end, ctxt, None) + } +} + +pub trait SpanRangeExt: SpanRange { + /// Gets the source file, and range in the file, of the given span. Returns `None` if the span + /// extends through multiple files, or is malformed. + fn get_source_text(self, cx: &impl LintContext) -> Option { + get_source_text(cx.sess().source_map(), self.into_range()) + } + + /// Calls the given function with the source text referenced and returns the value. Returns + /// `None` if the source text cannot be retrieved. + fn with_source_text(self, cx: &impl LintContext, f: impl for<'a> FnOnce(&'a str) -> T) -> Option { + with_source_text(cx.sess().source_map(), self.into_range(), f) + } + + /// Checks if the referenced source text satisfies the given predicate. Returns `false` if the + /// source text cannot be retrieved. + fn check_source_text(self, cx: &impl LintContext, pred: impl for<'a> FnOnce(&'a str) -> bool) -> bool { + self.with_source_text(cx, pred).unwrap_or(false) + } + + /// Calls the given function with the both the text of the source file and the referenced range, + /// and returns the value. Returns `None` if the source text cannot be retrieved. + fn with_source_text_and_range( + self, + cx: &impl LintContext, + f: impl for<'a> FnOnce(&'a str, Range) -> T, + ) -> Option { + with_source_text_and_range(cx.sess().source_map(), self.into_range(), f) + } + + /// Calls the given function with the both the text of the source file and the referenced range, + /// and creates a new span with the returned range. Returns `None` if the source text cannot be + /// retrieved, or no result is returned. + /// + /// The new range must reside within the same source file. + fn map_range( + self, + cx: &impl LintContext, + f: impl for<'a> FnOnce(&'a str, Range) -> Option>, + ) -> Option> { + map_range(cx.sess().source_map(), self.into_range(), f) + } + + /// Extends the range to include all preceding whitespace characters. + fn with_leading_whitespace(self, cx: &impl LintContext) -> Range { + with_leading_whitespace(cx.sess().source_map(), self.into_range()) + } + + /// Trims the leading whitespace from the range. + fn trim_start(self, cx: &impl LintContext) -> Range { + trim_start(cx.sess().source_map(), self.into_range()) + } + + /// Writes the referenced source text to the given writer. Will return `Err` if the source text + /// could not be retrieved. + fn write_source_text_to(self, cx: &impl LintContext, dst: &mut impl fmt::Write) -> fmt::Result { + write_source_text_to(cx.sess().source_map(), self.into_range(), dst) + } + + /// Extracts the referenced source text as an owned string. + fn source_text_to_string(self, cx: &impl LintContext) -> Option { + self.with_source_text(cx, ToOwned::to_owned) + } +} +impl SpanRangeExt for T {} + +fn get_source_text(sm: &SourceMap, sp: Range) -> Option { + let start = sm.lookup_byte_offset(sp.start); + let end = sm.lookup_byte_offset(sp.end); + if !Lrc::ptr_eq(&start.sf, &end.sf) || start.pos > end.pos { + return None; + } + let range = start.pos.to_usize()..end.pos.to_usize(); + Some(SourceFileRange { sf: start.sf, range }) +} + +fn with_source_text(sm: &SourceMap, sp: Range, f: impl for<'a> FnOnce(&'a str) -> T) -> Option { + if let Some(src) = get_source_text(sm, sp) + && let Some(src) = src.as_str() + { + Some(f(src)) + } else { + None + } +} + +fn with_source_text_and_range( + sm: &SourceMap, + sp: Range, + f: impl for<'a> FnOnce(&'a str, Range) -> T, +) -> Option { + if let Some(src) = get_source_text(sm, sp) + && let Some(text) = &src.sf.src + { + Some(f(text, src.range)) + } else { + None + } +} + +#[expect(clippy::cast_possible_truncation)] +fn map_range( + sm: &SourceMap, + sp: Range, + f: impl for<'a> FnOnce(&'a str, Range) -> Option>, +) -> Option> { + if let Some(src) = get_source_text(sm, sp.clone()) + && let Some(text) = &src.sf.src + && let Some(range) = f(text, src.range.clone()) + { + debug_assert!( + range.start <= text.len() && range.end <= text.len(), + "Range `{range:?}` is outside the source file (file `{}`, length `{}`)", + src.sf.name.display(FileNameDisplayPreference::Local), + text.len(), + ); + debug_assert!(range.start <= range.end, "Range `{range:?}` has overlapping bounds"); + let dstart = (range.start as u32).wrapping_sub(src.range.start as u32); + let dend = (range.end as u32).wrapping_sub(src.range.start as u32); + Some(BytePos(sp.start.0.wrapping_add(dstart))..BytePos(sp.start.0.wrapping_add(dend))) + } else { + None + } +} + +fn with_leading_whitespace(sm: &SourceMap, sp: Range) -> Range { + map_range(sm, sp.clone(), |src, range| { + Some(src.get(..range.start)?.trim_end().len()..range.end) + }) + .unwrap_or(sp) +} + +fn trim_start(sm: &SourceMap, sp: Range) -> Range { + map_range(sm, sp.clone(), |src, range| { + let src = src.get(range.clone())?; + Some(range.start + (src.len() - src.trim_start().len())..range.end) + }) + .unwrap_or(sp) +} + +fn write_source_text_to(sm: &SourceMap, sp: Range, dst: &mut impl fmt::Write) -> fmt::Result { + match with_source_text(sm, sp, |src| dst.write_str(src)) { + Some(x) => x, + None => Err(fmt::Error), + } +} + pub struct SourceFileRange { pub sf: Lrc, pub range: Range, @@ -55,37 +226,6 @@ impl SourceFileRange { } } -/// Gets the source file, and range in the file, of the given span. Returns `None` if the span -/// extends through multiple files, or is malformed. -pub fn get_source_text(cx: &impl LintContext, sp: impl SpanRange) -> Option { - fn f(sm: &SourceMap, sp: Range) -> Option { - let start = sm.lookup_byte_offset(sp.start); - let end = sm.lookup_byte_offset(sp.end); - if !Lrc::ptr_eq(&start.sf, &end.sf) || start.pos > end.pos { - return None; - } - let range = start.pos.to_usize()..end.pos.to_usize(); - Some(SourceFileRange { sf: start.sf, range }) - } - f(cx.sess().source_map(), sp.into_range()) -} - -pub fn with_leading_whitespace(cx: &impl LintContext, sp: impl SpanRange) -> Range { - #[expect(clippy::needless_pass_by_value, clippy::cast_possible_truncation)] - fn f(src: SourceFileRange, sp: Range) -> Range { - let Some(text) = &src.sf.src else { - return sp; - }; - let len = src.range.start - text[..src.range.start].trim_end().len(); - BytePos(sp.start.0 - len as u32)..sp.end - } - let sp = sp.into_range(); - match get_source_text(cx, sp.clone()) { - Some(src) => f(src, sp), - None => sp, - } -} - /// Like `snippet_block`, but add braces if the expr is not an `ExprKind::Block`. pub fn expr_block( cx: &T, From 8a657f9ec4f565129fa543ffb0bd85ca58b98188 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 21 Jun 2024 09:40:30 +0200 Subject: [PATCH 241/892] don't rely on libc existing on Windows --- src/tools/miri/src/helpers.rs | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/tools/miri/src/helpers.rs b/src/tools/miri/src/helpers.rs index 843aff024958a..6fa1c16fec501 100644 --- a/src/tools/miri/src/helpers.rs +++ b/src/tools/miri/src/helpers.rs @@ -273,6 +273,11 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { /// Helper function to get a `libc` constant as a `Scalar`. fn eval_libc(&self, name: &str) -> Scalar { + if self.eval_context_ref().tcx.sess.target.os == "windows" { + panic!( + "`libc` crate is not reliably available on Windows targets; Miri should not use it there" + ); + } self.eval_path_scalar(&["libc", name]) } @@ -316,6 +321,11 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { /// Helper function to get the `TyAndLayout` of a `libc` type fn libc_ty_layout(&self, name: &str) -> TyAndLayout<'tcx> { let this = self.eval_context_ref(); + if this.tcx.sess.target.os == "windows" { + panic!( + "`libc` crate is not reliably available on Windows targets; Miri should not use it there" + ); + } let ty = this .resolve_path(&["libc", name], Namespace::TypeNS) .ty(*this.tcx, ty::ParamEnv::reveal_all()); @@ -1048,7 +1058,12 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { /// Always returns a `Vec` no matter the size of `wchar_t`. fn read_wchar_t_str(&self, ptr: Pointer) -> InterpResult<'tcx, Vec> { let this = self.eval_context_ref(); - let wchar_t = this.libc_ty_layout("wchar_t"); + let wchar_t = if this.tcx.sess.target.os == "windows" { + // We don't have libc on Windows so we have to hard-code the type ourselves. + this.machine.layouts.u16 + } else { + this.libc_ty_layout("wchar_t") + }; self.read_c_str_with_char_size(ptr, wchar_t.size, wchar_t.align.abi) } From aa5d7a0d8ae4654c8739db1d7ac75dc0e6e24434 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 21 Jun 2024 12:31:16 +0000 Subject: [PATCH 242/892] Update platform support table for the new arm64 macOS support Closes rust-lang/rustc_codegen_cranelift#1248 --- Readme.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Readme.md b/Readme.md index 00ea15cb38cc2..eb21e027dd0e0 100644 --- a/Readme.md +++ b/Readme.md @@ -70,7 +70,7 @@ For more docs on how to build and test see [build_system/usage.txt](build_system |FreeBSD|✅[^no-rustup]|❓|❓|❓| |AIX|❌[^xcoff]|N/A|N/A|❌[^xcoff]| |Other unixes|❓|❓|❓|❓| -|macOS|✅|❌[^apple-silicon]|N/A|N/A| +|macOS|✅|✅[^no-rustup]|N/A|N/A| |Windows|✅[^no-rustup]|❌|N/A|N/A| ✅: Fully supported and tested @@ -80,7 +80,6 @@ For more docs on how to build and test see [build_system/usage.txt](build_system Not all targets are available as rustup component for nightly. See notes in the platform support matrix. [^xcoff]: XCOFF object file format is not supported. -[^apple-silicon]: Tracked in [#1248](https://github.com/rust-lang/rustc_codegen_cranelift/issues/1248). [^no-rustup]: Not available as rustup component for nightly. You can build it yourself. ## Usage From 9afd75259155bdfb0ca707bf5ac6ea5faf50812f Mon Sep 17 00:00:00 2001 From: Tobias Decking Date: Thu, 20 Jun 2024 20:11:16 +0200 Subject: [PATCH 243/892] Implement LLVM x86 adx intrinsics --- src/tools/miri/src/shims/x86/mod.rs | 91 +++++++++++-------- .../pass/shims/x86/intrinsics-x86-adx.rs | 70 ++++++++++++++ 2 files changed, 123 insertions(+), 38 deletions(-) create mode 100644 src/tools/miri/tests/pass/shims/x86/intrinsics-x86-adx.rs diff --git a/src/tools/miri/src/shims/x86/mod.rs b/src/tools/miri/src/shims/x86/mod.rs index 704c45fdd6d39..74470fad352f7 100644 --- a/src/tools/miri/src/shims/x86/mod.rs +++ b/src/tools/miri/src/shims/x86/mod.rs @@ -35,63 +35,65 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Prefix should have already been checked. let unprefixed_name = link_name.as_str().strip_prefix("llvm.x86.").unwrap(); match unprefixed_name { - // Used to implement the `_addcarry_u32` and `_addcarry_u64` functions. - // Computes a + b with input and output carry. The input carry is an 8-bit - // value, which is interpreted as 1 if it is non-zero. The output carry is - // an 8-bit value that will be 0 or 1. + // Used to implement the `_addcarry_u{32, 64}` and the `_subborrow_u{32, 64}` functions. + // Computes a + b or a - b with input and output carry/borrow. The input carry/borrow is an 8-bit + // value, which is interpreted as 1 if it is non-zero. The output carry/borrow is an 8-bit value that will be 0 or 1. // https://www.intel.com/content/www/us/en/docs/cpp-compiler/developer-guide-reference/2021-8/addcarry-u32-addcarry-u64.html - "addcarry.32" | "addcarry.64" => { - if unprefixed_name == "addcarry.64" && this.tcx.sess.target.arch != "x86_64" { + // https://www.intel.com/content/www/us/en/docs/cpp-compiler/developer-guide-reference/2021-8/subborrow-u32-subborrow-u64.html + "addcarry.32" | "addcarry.64" | "subborrow.32" | "subborrow.64" => { + if unprefixed_name.ends_with("64") && this.tcx.sess.target.arch != "x86_64" { return Ok(EmulateItemResult::NotSupported); } - let [c_in, a, b] = this.check_shim(abi, Abi::Unadjusted, link_name, args)?; - let c_in = this.read_scalar(c_in)?.to_u8()? != 0; + let op = if unprefixed_name.starts_with("add") { + mir::BinOp::AddWithOverflow + } else { + mir::BinOp::SubWithOverflow + }; + + let [cb_in, a, b] = this.check_shim(abi, Abi::Unadjusted, link_name, args)?; + let cb_in = this.read_scalar(cb_in)?.to_u8()? != 0; let a = this.read_immediate(a)?; let b = this.read_immediate(b)?; - let (sum, overflow1) = - this.binary_op(mir::BinOp::AddWithOverflow, &a, &b)?.to_pair(this); - let (sum, overflow2) = this - .binary_op( - mir::BinOp::AddWithOverflow, - &sum, - &ImmTy::from_uint(c_in, a.layout), - )? - .to_pair(this); - let c_out = overflow1.to_scalar().to_bool()? | overflow2.to_scalar().to_bool()?; + let (sum, overflow1) = this.binary_op(op, &a, &b)?.to_pair(this); + let (sum, overflow2) = + this.binary_op(op, &sum, &ImmTy::from_uint(cb_in, a.layout))?.to_pair(this); + let cb_out = overflow1.to_scalar().to_bool()? | overflow2.to_scalar().to_bool()?; - this.write_scalar(Scalar::from_u8(c_out.into()), &this.project_field(dest, 0)?)?; - this.write_immediate(*sum, &this.project_field(dest, 1)?)?; + let d1 = this.project_field(dest, 0)?; + let d2 = this.project_field(dest, 1)?; + write_twice(this, &d1, Scalar::from_u8(cb_out.into()), &d2, sum)?; } - // Used to implement the `_subborrow_u32` and `_subborrow_u64` functions. - // Computes a - b with input and output borrow. The input borrow is an 8-bit - // value, which is interpreted as 1 if it is non-zero. The output borrow is - // an 8-bit value that will be 0 or 1. - // https://www.intel.com/content/www/us/en/docs/cpp-compiler/developer-guide-reference/2021-8/subborrow-u32-subborrow-u64.html - "subborrow.32" | "subborrow.64" => { - if unprefixed_name == "subborrow.64" && this.tcx.sess.target.arch != "x86_64" { + + // Used to implement the `_addcarryx_u{32, 64}` functions. They are semantically identical with the `_addcarry_u{32, 64}` functions, + // except for a slightly different type signature and the requirement for the "adx" target feature. + // https://www.intel.com/content/www/us/en/docs/cpp-compiler/developer-guide-reference/2021-8/addcarryx-u32-addcarryx-u64.html + "addcarryx.u32" | "addcarryx.u64" => { + this.expect_target_feature_for_intrinsic(link_name, "adx")?; + + if unprefixed_name.ends_with("64") && this.tcx.sess.target.arch != "x86_64" { return Ok(EmulateItemResult::NotSupported); } - let [b_in, a, b] = this.check_shim(abi, Abi::Unadjusted, link_name, args)?; - let b_in = this.read_scalar(b_in)?.to_u8()? != 0; + let [c_in, a, b, out] = this.check_shim(abi, Abi::Unadjusted, link_name, args)?; + let c_in = this.read_scalar(c_in)?.to_u8()? != 0; let a = this.read_immediate(a)?; let b = this.read_immediate(b)?; - let (sub, overflow1) = - this.binary_op(mir::BinOp::SubWithOverflow, &a, &b)?.to_pair(this); - let (sub, overflow2) = this + let (sum, overflow1) = + this.binary_op(mir::BinOp::AddWithOverflow, &a, &b)?.to_pair(this); + let (sum, overflow2) = this .binary_op( - mir::BinOp::SubWithOverflow, - &sub, - &ImmTy::from_uint(b_in, a.layout), + mir::BinOp::AddWithOverflow, + &sum, + &ImmTy::from_uint(c_in, a.layout), )? .to_pair(this); - let b_out = overflow1.to_scalar().to_bool()? | overflow2.to_scalar().to_bool()?; + let c_out = overflow1.to_scalar().to_bool()? | overflow2.to_scalar().to_bool()?; - this.write_scalar(Scalar::from_u8(b_out.into()), &this.project_field(dest, 0)?)?; - this.write_immediate(*sub, &this.project_field(dest, 1)?)?; + let out = this.deref_pointer_as(out, sum.layout)?; + write_twice(this, dest, Scalar::from_u8(c_out.into()), &out, sum)?; } // Used to implement the `_mm_pause` function. @@ -1366,3 +1368,16 @@ fn psign<'tcx>( Ok(()) } + +/// Write two values `v1` and `v2` to the places `d1` and `d2`. +fn write_twice<'tcx>( + this: &mut crate::MiriInterpCx<'tcx>, + d1: &MPlaceTy<'tcx>, + v1: Scalar, + d2: &MPlaceTy<'tcx>, + v2: ImmTy<'tcx>, +) -> InterpResult<'tcx, ()> { + this.write_scalar(v1, d1)?; + this.write_immediate(*v2, d2)?; + Ok(()) +} diff --git a/src/tools/miri/tests/pass/shims/x86/intrinsics-x86-adx.rs b/src/tools/miri/tests/pass/shims/x86/intrinsics-x86-adx.rs new file mode 100644 index 0000000000000..431e7f2c5eb60 --- /dev/null +++ b/src/tools/miri/tests/pass/shims/x86/intrinsics-x86-adx.rs @@ -0,0 +1,70 @@ +// Ignore everything except x86 and x86_64 +// Any new targets that are added to CI should be ignored here. +// (We cannot use `cfg`-based tricks here since the `target-feature` flags below only work on x86.) +//@ignore-target-aarch64 +//@ignore-target-arm +//@ignore-target-avr +//@ignore-target-s390x +//@ignore-target-thumbv7em +//@ignore-target-wasm32 +//@compile-flags: -C target-feature=+adx + +#[cfg(any(target_arch = "x86", target_arch = "x86_64"))] +mod x86 { + #[cfg(target_arch = "x86")] + use core::arch::x86 as arch; + #[cfg(target_arch = "x86_64")] + use core::arch::x86_64 as arch; + + fn adc(c_in: u8, a: u32, b: u32) -> (u8, u32) { + let mut sum = 0; + // SAFETY: There are no safety requirements for calling `_addcarry_u32`. + // It's just unsafe for API consistency with other intrinsics. + let c_out = unsafe { arch::_addcarryx_u32(c_in, a, b, &mut sum) }; + (c_out, sum) + } + + pub fn main() { + assert_eq!(adc(0, 1, 1), (0, 2)); + assert_eq!(adc(1, 1, 1), (0, 3)); + assert_eq!(adc(2, 1, 1), (0, 3)); // any non-zero carry acts as 1! + assert_eq!(adc(u8::MAX, 1, 1), (0, 3)); + assert_eq!(adc(0, u32::MAX, u32::MAX), (1, u32::MAX - 1)); + assert_eq!(adc(1, u32::MAX, u32::MAX), (1, u32::MAX)); + assert_eq!(adc(2, u32::MAX, u32::MAX), (1, u32::MAX)); + assert_eq!(adc(u8::MAX, u32::MAX, u32::MAX), (1, u32::MAX)); + } +} + +#[cfg(target_arch = "x86_64")] +mod x86_64 { + use core::arch::x86_64 as arch; + + fn adc(c_in: u8, a: u64, b: u64) -> (u8, u64) { + let mut sum = 0; + // SAFETY: There are no safety requirements for calling `_addcarry_u64`. + // It's just unsafe for API consistency with other intrinsics. + let c_out = unsafe { arch::_addcarryx_u64(c_in, a, b, &mut sum) }; + (c_out, sum) + } + + pub fn main() { + assert_eq!(adc(0, 1, 1), (0, 2)); + assert_eq!(adc(1, 1, 1), (0, 3)); + assert_eq!(adc(2, 1, 1), (0, 3)); // any non-zero carry acts as 1! + assert_eq!(adc(u8::MAX, 1, 1), (0, 3)); + assert_eq!(adc(0, u64::MAX, u64::MAX), (1, u64::MAX - 1)); + assert_eq!(adc(1, u64::MAX, u64::MAX), (1, u64::MAX)); + assert_eq!(adc(2, u64::MAX, u64::MAX), (1, u64::MAX)); + assert_eq!(adc(u8::MAX, u64::MAX, u64::MAX), (1, u64::MAX)); + } +} + +fn main() { + assert!(is_x86_feature_detected!("adx")); + + #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] + x86::main(); + #[cfg(target_arch = "x86_64")] + x86_64::main(); +} From d0977e3e2a5b15229df46d98d48e31b290aa68da Mon Sep 17 00:00:00 2001 From: Robert Zakrzewski Date: Wed, 10 Apr 2024 23:08:01 +0200 Subject: [PATCH 244/892] Add support for Float16, Float32, Float64 and Float128 Upgrade libgccjit.version Limit new Floatxx types to master branch only apply rustfmt Make new types available only when requested Make new types available only when requested Check if Float16 and Float128 are supported by the target platform Replace Float with Float32 and Double with Float64 if target dependent type is defined Add support for Float16|32|64|128 in the builder Fix cargo fmt errors Update gccjit wrapper update hash of ligccjit --- Cargo.lock | 8 +++--- libgccjit.version | 2 +- src/builder.rs | 18 ++++++++++++ src/type_.rs | 70 +++++++++++++++++++++++++++++++++++++++++++++-- 4 files changed, 90 insertions(+), 8 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ab2c7ca8a47c8..2ce9eb081eecc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -79,16 +79,16 @@ dependencies = [ [[package]] name = "gccjit" -version = "1.0.0" -source = "git+https://github.com/antoyo/gccjit.rs#9f8f67edc006d543b17529a001803ffece48349e" +version = "2.0.0" +source = "git+https://github.com/antoyo/gccjit.rs#f1545d7c2c13e42d78eaac8032d49ab8f7d43b6e" dependencies = [ "gccjit_sys", ] [[package]] name = "gccjit_sys" -version = "0.0.1" -source = "git+https://github.com/antoyo/gccjit.rs#9f8f67edc006d543b17529a001803ffece48349e" +version = "0.1.0" +source = "git+https://github.com/antoyo/gccjit.rs#f1545d7c2c13e42d78eaac8032d49ab8f7d43b6e" dependencies = [ "libc", ] diff --git a/libgccjit.version b/libgccjit.version index 41bec6df5d95c..adf9b64c826fc 100644 --- a/libgccjit.version +++ b/libgccjit.version @@ -1 +1 @@ -b6f163f52 +ac1853f579dbfdc53f2c22317e673ae99686eca2 diff --git a/src/builder.rs b/src/builder.rs index e9c16a0e4a71f..30343f2e17b48 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -748,6 +748,24 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { // FIXME(antoyo): this seems to produce the wrong result. return self.context.new_call(self.location, fmodf, &[a, b]); } + + #[cfg(feature = "master")] + match self.cx.type_kind(a_type) { + TypeKind::Half | TypeKind::Float => { + let fmodf = self.context.get_builtin_function("fmodf"); + return self.context.new_call(self.location, fmodf, &[a, b]); + } + TypeKind::Double => { + let fmod = self.context.get_builtin_function("fmod"); + return self.context.new_call(self.location, fmod, &[a, b]); + } + TypeKind::FP128 => { + let fmodl = self.context.get_builtin_function("fmodl"); + return self.context.new_call(self.location, fmodl, &[a, b]); + } + _ => (), + } + if let Some(vector_type) = a_type_unqualified.dyncast_vector() { assert_eq!(a_type_unqualified, b.get_type().unqualified()); diff --git a/src/type_.rs b/src/type_.rs index d0d3c21f0cf09..cc26f306d6de4 100644 --- a/src/type_.rs +++ b/src/type_.rs @@ -1,4 +1,6 @@ -use gccjit::{RValue, Struct, Type}; +use std::convert::TryInto; + +use gccjit::{CType, RValue, Struct, Type}; use rustc_codegen_ssa::common::TypeKind; use rustc_codegen_ssa::traits::{BaseTypeMethods, DerivedTypeMethods, TypeMembershipMethods}; use rustc_middle::ty::layout::TyAndLayout; @@ -120,10 +122,28 @@ impl<'gcc, 'tcx> BaseTypeMethods<'tcx> for CodegenCx<'gcc, 'tcx> { self.isize_type } + #[cfg(feature = "master")] + fn type_f16(&self) -> Type<'gcc> { + if self.context.get_target_info().supports_target_dependent_type(CType::Float16) { + return self.context.new_c_type(CType::Float16); + } + unimplemented!("f16") + } + + #[cfg(not(feature = "master"))] fn type_f16(&self) -> Type<'gcc> { - unimplemented!("f16_f128") + unimplemented!("f16") + } + + #[cfg(feature = "master")] + fn type_f32(&self) -> Type<'gcc> { + if self.context.get_target_info().supports_target_dependent_type(CType::Float32) { + return self.context.new_c_type(CType::Float32); + } + self.float_type } + #[cfg(not(feature = "master"))] fn type_f32(&self) -> Type<'gcc> { self.float_type } @@ -132,8 +152,17 @@ impl<'gcc, 'tcx> BaseTypeMethods<'tcx> for CodegenCx<'gcc, 'tcx> { self.double_type } + #[cfg(feature = "master")] + fn type_f128(&self) -> Type<'gcc> { + if self.context.get_target_info().supports_target_dependent_type(CType::Float128) { + return self.context.new_c_type(CType::Float128); + } + unimplemented!("f128") + } + + #[cfg(not(feature = "master"))] fn type_f128(&self) -> Type<'gcc> { - unimplemented!("f16_f128") + unimplemented!("f128") } fn type_func(&self, params: &[Type<'gcc>], return_type: Type<'gcc>) -> Type<'gcc> { @@ -161,6 +190,31 @@ impl<'gcc, 'tcx> BaseTypeMethods<'tcx> for CodegenCx<'gcc, 'tcx> { typ } + #[cfg(feature = "master")] + fn type_kind(&self, typ: Type<'gcc>) -> TypeKind { + if self.is_int_type_or_bool(typ) { + TypeKind::Integer + } else if typ.is_compatible_with(self.float_type) { + TypeKind::Float + } else if typ.is_compatible_with(self.double_type) { + TypeKind::Double + } else if typ.is_vector() { + TypeKind::Vector + } else if typ.is_floating_point() { + match typ.get_size() { + 2 => TypeKind::Half, + 4 => TypeKind::Float, + 8 => TypeKind::Double, + 16 => TypeKind::FP128, + _ => TypeKind::Void, + } + } else { + // TODO(antoyo): support other types. + TypeKind::Void + } + } + + #[cfg(not(feature = "master"))] fn type_kind(&self, typ: Type<'gcc>) -> TypeKind { if self.is_int_type_or_bool(typ) { TypeKind::Integer @@ -210,6 +264,16 @@ impl<'gcc, 'tcx> BaseTypeMethods<'tcx> for CodegenCx<'gcc, 'tcx> { unimplemented!(); } + #[cfg(feature = "master")] + fn float_width(&self, typ: Type<'gcc>) -> usize { + if typ.is_floating_point() { + (typ.get_size() * u8::BITS).try_into().unwrap() + } else { + panic!("Cannot get width of float type {:?}", typ); + } + } + + #[cfg(not(feature = "master"))] fn float_width(&self, typ: Type<'gcc>) -> usize { let f32 = self.context.new_type::(); let f64 = self.context.new_type::(); From a486dbfc17945e6bad43793aae37a9ef29c05efd Mon Sep 17 00:00:00 2001 From: Robert Zakrzewski Date: Sun, 5 May 2024 18:42:27 +0200 Subject: [PATCH 245/892] Upgrade libgccjit.version --- libgccjit.version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libgccjit.version b/libgccjit.version index adf9b64c826fc..71a61a4b8735f 100644 --- a/libgccjit.version +++ b/libgccjit.version @@ -1 +1 @@ -ac1853f579dbfdc53f2c22317e673ae99686eca2 +272d0ccced960394fe6ff2b40b01610208cb4940 From fa18a181f7bf0a7c1f5753de82c1e934a957894d Mon Sep 17 00:00:00 2001 From: Robert Zakrzewski Date: Sun, 5 May 2024 21:03:54 +0200 Subject: [PATCH 246/892] Temporary downgrade compiler_builtins library. From version 0.1.110 the no-f16-f128 feautes introduced incompatibility --- build_system/build_sysroot/Cargo.toml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/build_system/build_sysroot/Cargo.toml b/build_system/build_sysroot/Cargo.toml index 05503128f2af0..d0d21a044fd12 100644 --- a/build_system/build_sysroot/Cargo.toml +++ b/build_system/build_sysroot/Cargo.toml @@ -6,7 +6,8 @@ resolver = "2" [dependencies] core = { path = "./sysroot_src/library/core" } -compiler_builtins = "0.1" +# compiler_builtins = "0.1" +compiler_builtins = "=0.1.109" alloc = { path = "./sysroot_src/library/alloc" } std = { path = "./sysroot_src/library/std", features = ["panic_unwind", "backtrace"] } test = { path = "./sysroot_src/library/test" } From b94cb8c01ccb1c027dc2840483afa45c6325fd2b Mon Sep 17 00:00:00 2001 From: Robert Zakrzewski Date: Sun, 12 May 2024 17:40:14 +0200 Subject: [PATCH 247/892] Add missing types in the type_kind function reorder type_kind reorder type_kind reorder type_kind fix fix fix fix --- src/type_.rs | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/type_.rs b/src/type_.rs index cc26f306d6de4..36656c66a654d 100644 --- a/src/type_.rs +++ b/src/type_.rs @@ -194,12 +194,20 @@ impl<'gcc, 'tcx> BaseTypeMethods<'tcx> for CodegenCx<'gcc, 'tcx> { fn type_kind(&self, typ: Type<'gcc>) -> TypeKind { if self.is_int_type_or_bool(typ) { TypeKind::Integer + } else if typ.get_pointee().is_some() { + TypeKind::Pointer + } else if typ.is_vector() { + TypeKind::Vector + } else if typ.dyncast_array().is_some() { + TypeKind::Array + } else if typ.is_struct().is_some() { + TypeKind::Struct + } else if typ.dyncast_function_ptr_type().is_some() { + TypeKind::Function } else if typ.is_compatible_with(self.float_type) { TypeKind::Float } else if typ.is_compatible_with(self.double_type) { TypeKind::Double - } else if typ.is_vector() { - TypeKind::Vector } else if typ.is_floating_point() { match typ.get_size() { 2 => TypeKind::Half, @@ -208,9 +216,11 @@ impl<'gcc, 'tcx> BaseTypeMethods<'tcx> for CodegenCx<'gcc, 'tcx> { 16 => TypeKind::FP128, _ => TypeKind::Void, } + } else if typ == self.type_void() { + TypeKind::Void } else { // TODO(antoyo): support other types. - TypeKind::Void + unimplemented!(); } } From 0dad11feb9cf34f41d883f49518f9bf812314d57 Mon Sep 17 00:00:00 2001 From: Robert Zakrzewski Date: Fri, 24 May 2024 08:05:57 +0200 Subject: [PATCH 248/892] Do not use target dependent Float32 fix formatting --- src/type_.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/type_.rs b/src/type_.rs index 36656c66a654d..c65301495b198 100644 --- a/src/type_.rs +++ b/src/type_.rs @@ -137,9 +137,9 @@ impl<'gcc, 'tcx> BaseTypeMethods<'tcx> for CodegenCx<'gcc, 'tcx> { #[cfg(feature = "master")] fn type_f32(&self) -> Type<'gcc> { - if self.context.get_target_info().supports_target_dependent_type(CType::Float32) { - return self.context.new_c_type(CType::Float32); - } + // if self.context.get_target_info().supports_target_dependent_type(CType::Float32) { + // return self.context.new_c_type(CType::Float32); + // } self.float_type } From c4e7c04de9bc72190ef9911c7a481ebc2a406db7 Mon Sep 17 00:00:00 2001 From: Antoni Boucher Date: Thu, 13 Jun 2024 08:45:41 -0400 Subject: [PATCH 249/892] Fix location of check for sized floating-point types --- src/base.rs | 19 +++++++++++++++++-- src/context.rs | 9 +++++++++ src/lib.rs | 12 ++++++++++-- src/type_.rs | 15 +++++++++------ 4 files changed, 45 insertions(+), 10 deletions(-) diff --git a/src/base.rs b/src/base.rs index 79a29a1135a1b..ea2b0b791b7fd 100644 --- a/src/base.rs +++ b/src/base.rs @@ -2,7 +2,7 @@ use std::collections::HashSet; use std::env; use std::time::Instant; -use gccjit::{FunctionType, GlobalKind}; +use gccjit::{CType, FunctionType, GlobalKind}; use rustc_codegen_ssa::base::maybe_create_entry_wrapper; use rustc_codegen_ssa::mono_item::MonoItemExt; use rustc_codegen_ssa::traits::DebugInfoMethods; @@ -181,7 +181,22 @@ pub fn compile_codegen_unit( context.set_allow_unreachable_blocks(true); { - let cx = CodegenCx::new(&context, cgu, tcx, target_info.supports_128bit_int()); + // TODO: to make it less error-prone (calling get_target_info() will add the flag + // -fsyntax-only), forbid the compilation when get_target_info() is called on a + // context. + let f16_type_supported = target_info.supports_target_dependent_type(CType::Float16); + let f32_type_supported = target_info.supports_target_dependent_type(CType::Float32); + let f128_type_supported = target_info.supports_target_dependent_type(CType::Float128); + // TODO: improve this to avoid passing that many arguments. + let cx = CodegenCx::new( + &context, + cgu, + tcx, + target_info.supports_128bit_int(), + f16_type_supported, + f32_type_supported, + f128_type_supported, + ); let mono_items = cgu.items_in_deterministic_order(tcx); for &(mono_item, data) in &mono_items { diff --git a/src/context.rs b/src/context.rs index 890b4b15fc01e..53a2b09217a97 100644 --- a/src/context.rs +++ b/src/context.rs @@ -68,6 +68,9 @@ pub struct CodegenCx<'gcc, 'tcx> { pub sizet_type: Type<'gcc>, pub supports_128bit_integers: bool, + pub supports_f16_type: bool, + pub supports_f32_type: bool, + pub supports_f128_type: bool, pub float_type: Type<'gcc>, pub double_type: Type<'gcc>, @@ -130,6 +133,9 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { codegen_unit: &'tcx CodegenUnit<'tcx>, tcx: TyCtxt<'tcx>, supports_128bit_integers: bool, + supports_f16_type: bool, + supports_f32_type: bool, + supports_f128_type: bool, ) -> Self { let check_overflow = tcx.sess.overflow_checks(); @@ -305,6 +311,9 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { sizet_type, supports_128bit_integers, + supports_f16_type, + supports_f32_type, + supports_f128_type, float_type, double_type, diff --git a/src/lib.rs b/src/lib.rs index af110e3ab5e69..9b9b97b9595db 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -89,7 +89,6 @@ use std::sync::Arc; use std::sync::Mutex; use errors::LTONotSupported; -#[cfg(not(feature = "master"))] use gccjit::CType; use gccjit::{Context, OptimizationLevel}; #[cfg(feature = "master")] @@ -147,6 +146,10 @@ impl TargetInfo { fn supports_128bit_int(&self) -> bool { self.supports_128bit_integers.load(Ordering::SeqCst) } + + fn supports_target_dependent_type(&self, _typ: CType) -> bool { + false + } } #[derive(Clone)] @@ -168,6 +171,10 @@ impl LockedTargetInfo { 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) + } } #[derive(Clone)] @@ -438,7 +445,8 @@ impl WriteBackendMethods for GccCodegenBackend { pub fn __rustc_codegen_backend() -> Box { #[cfg(feature = "master")] let info = { - // Check whether the target supports 128-bit integers. + // Check whether the target supports 128-bit integers, and sized floating point types (like + // Float16). let context = Context::default(); Arc::new(Mutex::new(IntoDynSyncSend(context.get_target_info()))) }; diff --git a/src/type_.rs b/src/type_.rs index c65301495b198..7bcc71e581df9 100644 --- a/src/type_.rs +++ b/src/type_.rs @@ -1,6 +1,9 @@ +#[cfg(feature = "master")] use std::convert::TryInto; -use gccjit::{CType, RValue, Struct, Type}; +#[cfg(feature = "master")] +use gccjit::CType; +use gccjit::{RValue, Struct, Type}; use rustc_codegen_ssa::common::TypeKind; use rustc_codegen_ssa::traits::{BaseTypeMethods, DerivedTypeMethods, TypeMembershipMethods}; use rustc_middle::ty::layout::TyAndLayout; @@ -124,7 +127,7 @@ impl<'gcc, 'tcx> BaseTypeMethods<'tcx> for CodegenCx<'gcc, 'tcx> { #[cfg(feature = "master")] fn type_f16(&self) -> Type<'gcc> { - if self.context.get_target_info().supports_target_dependent_type(CType::Float16) { + if self.supports_f16_type { return self.context.new_c_type(CType::Float16); } unimplemented!("f16") @@ -137,9 +140,9 @@ impl<'gcc, 'tcx> BaseTypeMethods<'tcx> for CodegenCx<'gcc, 'tcx> { #[cfg(feature = "master")] fn type_f32(&self) -> Type<'gcc> { - // if self.context.get_target_info().supports_target_dependent_type(CType::Float32) { - // return self.context.new_c_type(CType::Float32); - // } + if self.supports_f32_type { + return self.context.new_c_type(CType::Float32); + } self.float_type } @@ -154,7 +157,7 @@ impl<'gcc, 'tcx> BaseTypeMethods<'tcx> for CodegenCx<'gcc, 'tcx> { #[cfg(feature = "master")] fn type_f128(&self) -> Type<'gcc> { - if self.context.get_target_info().supports_target_dependent_type(CType::Float128) { + if self.supports_f128_type { return self.context.new_c_type(CType::Float128); } unimplemented!("f128") From 55788e4a92fee3521fa9eb1eba1bbfbe27564e9d Mon Sep 17 00:00:00 2001 From: Robert Zakrzewski Date: Fri, 21 Jun 2024 14:53:24 +0200 Subject: [PATCH 250/892] Update libgccjit version with fixed is_same_type_as for vector types --- libgccjit.version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libgccjit.version b/libgccjit.version index 71a61a4b8735f..8cce735832139 100644 --- a/libgccjit.version +++ b/libgccjit.version @@ -1 +1 @@ -272d0ccced960394fe6ff2b40b01610208cb4940 +d61ce945badf4c9d8237a13ca135e3c46ad13be3 From 2eaac2388d6172922d0b8ac62979ff4fa6a2355c Mon Sep 17 00:00:00 2001 From: Robert Zakrzewski Date: Fri, 21 Jun 2024 16:42:21 +0200 Subject: [PATCH 251/892] Refactor type_f16|32|128 functions. Common type_kind() fix --- src/type_.rs | 25 +++++-------------------- 1 file changed, 5 insertions(+), 20 deletions(-) diff --git a/src/type_.rs b/src/type_.rs index 7bcc71e581df9..eaa16c448970e 100644 --- a/src/type_.rs +++ b/src/type_.rs @@ -125,47 +125,32 @@ impl<'gcc, 'tcx> BaseTypeMethods<'tcx> for CodegenCx<'gcc, 'tcx> { self.isize_type } - #[cfg(feature = "master")] fn type_f16(&self) -> Type<'gcc> { + #[cfg(feature = "master")] if self.supports_f16_type { return self.context.new_c_type(CType::Float16); } - unimplemented!("f16") - } - - #[cfg(not(feature = "master"))] - fn type_f16(&self) -> Type<'gcc> { - unimplemented!("f16") + bug!("unsupported float width 16") } - #[cfg(feature = "master")] fn type_f32(&self) -> Type<'gcc> { + #[cfg(feature = "master")] if self.supports_f32_type { return self.context.new_c_type(CType::Float32); } self.float_type } - #[cfg(not(feature = "master"))] - fn type_f32(&self) -> Type<'gcc> { - self.float_type - } - fn type_f64(&self) -> Type<'gcc> { self.double_type } - #[cfg(feature = "master")] fn type_f128(&self) -> Type<'gcc> { + #[cfg(feature = "master")] if self.supports_f128_type { return self.context.new_c_type(CType::Float128); } - unimplemented!("f128") - } - - #[cfg(not(feature = "master"))] - fn type_f128(&self) -> Type<'gcc> { - unimplemented!("f128") + bug!("unsupported float width 128") } fn type_func(&self, params: &[Type<'gcc>], return_type: Type<'gcc>) -> Type<'gcc> { From ed83f1acced66941bfc58ce4e884d46d9e96bf64 Mon Sep 17 00:00:00 2001 From: Tobias Decking Date: Fri, 21 Jun 2024 17:55:22 +0200 Subject: [PATCH 252/892] Move out addition logic --- src/tools/miri/src/shims/x86/mod.rs | 68 ++++++++++++----------------- 1 file changed, 29 insertions(+), 39 deletions(-) diff --git a/src/tools/miri/src/shims/x86/mod.rs b/src/tools/miri/src/shims/x86/mod.rs index 74470fad352f7..7bccf71f04374 100644 --- a/src/tools/miri/src/shims/x86/mod.rs +++ b/src/tools/miri/src/shims/x86/mod.rs @@ -45,25 +45,17 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { return Ok(EmulateItemResult::NotSupported); } + let [cb_in, a, b] = this.check_shim(abi, Abi::Unadjusted, link_name, args)?; + let op = if unprefixed_name.starts_with("add") { mir::BinOp::AddWithOverflow } else { mir::BinOp::SubWithOverflow }; - let [cb_in, a, b] = this.check_shim(abi, Abi::Unadjusted, link_name, args)?; - let cb_in = this.read_scalar(cb_in)?.to_u8()? != 0; - let a = this.read_immediate(a)?; - let b = this.read_immediate(b)?; - - let (sum, overflow1) = this.binary_op(op, &a, &b)?.to_pair(this); - let (sum, overflow2) = - this.binary_op(op, &sum, &ImmTy::from_uint(cb_in, a.layout))?.to_pair(this); - let cb_out = overflow1.to_scalar().to_bool()? | overflow2.to_scalar().to_bool()?; - - let d1 = this.project_field(dest, 0)?; - let d2 = this.project_field(dest, 1)?; - write_twice(this, &d1, Scalar::from_u8(cb_out.into()), &d2, sum)?; + let (sum, cb_out) = carrying_add(this, cb_in, a, b, op)?; + this.write_scalar(cb_out, &this.project_field(dest, 0)?)?; + this.write_immediate(*sum, &this.project_field(dest, 1)?)?; } // Used to implement the `_addcarryx_u{32, 64}` functions. They are semantically identical with the `_addcarry_u{32, 64}` functions, @@ -77,23 +69,10 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } let [c_in, a, b, out] = this.check_shim(abi, Abi::Unadjusted, link_name, args)?; - let c_in = this.read_scalar(c_in)?.to_u8()? != 0; - let a = this.read_immediate(a)?; - let b = this.read_immediate(b)?; - - let (sum, overflow1) = - this.binary_op(mir::BinOp::AddWithOverflow, &a, &b)?.to_pair(this); - let (sum, overflow2) = this - .binary_op( - mir::BinOp::AddWithOverflow, - &sum, - &ImmTy::from_uint(c_in, a.layout), - )? - .to_pair(this); - let c_out = overflow1.to_scalar().to_bool()? | overflow2.to_scalar().to_bool()?; - let out = this.deref_pointer_as(out, sum.layout)?; - write_twice(this, dest, Scalar::from_u8(c_out.into()), &out, sum)?; + let (sum, c_out) = carrying_add(this, c_in, a, b, mir::BinOp::AddWithOverflow)?; + this.write_scalar(c_out, dest)?; + this.write_immediate(*sum, &this.deref_pointer_as(out, sum.layout)?)?; } // Used to implement the `_mm_pause` function. @@ -1369,15 +1348,26 @@ fn psign<'tcx>( Ok(()) } -/// Write two values `v1` and `v2` to the places `d1` and `d2`. -fn write_twice<'tcx>( +/// Calcultates either `a + b + cb_in` or `a - b - cb_in` depending on the value +/// of `op` and returns both the sum and the overflow bit. `op` is expected to be +/// either one of `mir::BinOp::AddWithOverflow` and `mir::BinOp::SubWithOverflow`. +fn carrying_add<'tcx>( this: &mut crate::MiriInterpCx<'tcx>, - d1: &MPlaceTy<'tcx>, - v1: Scalar, - d2: &MPlaceTy<'tcx>, - v2: ImmTy<'tcx>, -) -> InterpResult<'tcx, ()> { - this.write_scalar(v1, d1)?; - this.write_immediate(*v2, d2)?; - Ok(()) + cb_in: &OpTy<'tcx>, + a: &OpTy<'tcx>, + b: &OpTy<'tcx>, + op: mir::BinOp, +) -> InterpResult<'tcx, (ImmTy<'tcx>, Scalar)> { + assert!(op == mir::BinOp::AddWithOverflow || op == mir::BinOp::SubWithOverflow); + + let cb_in = this.read_scalar(cb_in)?.to_u8()? != 0; + let a = this.read_immediate(a)?; + let b = this.read_immediate(b)?; + + let (sum, overflow1) = this.binary_op(op, &a, &b)?.to_pair(this); + let (sum, overflow2) = + this.binary_op(op, &sum, &ImmTy::from_uint(cb_in, a.layout))?.to_pair(this); + let cb_out = overflow1.to_scalar().to_bool()? | overflow2.to_scalar().to_bool()?; + + Ok((sum, Scalar::from_u8(cb_out.into()))) } From 54b45f7f93716970be87d257238bf571728c37a4 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 19 Jun 2024 17:26:52 +0200 Subject: [PATCH 253/892] Fix incorrect suggestion for `manual_unwrap_or_default` --- clippy_lints/src/manual_unwrap_or_default.rs | 9 ++------- tests/ui/manual_unwrap_or_default.fixed | 21 ++++++++++++++++++++ tests/ui/manual_unwrap_or_default.rs | 21 ++++++++++++++++++++ 3 files changed, 44 insertions(+), 7 deletions(-) diff --git a/clippy_lints/src/manual_unwrap_or_default.rs b/clippy_lints/src/manual_unwrap_or_default.rs index 17399fb2cc212..58b2ebebbf080 100644 --- a/clippy_lints/src/manual_unwrap_or_default.rs +++ b/clippy_lints/src/manual_unwrap_or_default.rs @@ -53,6 +53,7 @@ declare_lint_pass!(ManualUnwrapOrDefault => [MANUAL_UNWRAP_OR_DEFAULT]); fn get_some<'tcx>(cx: &LateContext<'tcx>, pat: &Pat<'tcx>) -> Option { if let PatKind::TupleStruct(QPath::Resolved(_, path), &[pat], _) = pat.kind + && let PatKind::Binding(_, pat_id, _, _) = pat.kind && let Some(def_id) = path.res.opt_def_id() // Since it comes from a pattern binding, we need to get the parent to actually match // against it. @@ -60,13 +61,7 @@ fn get_some<'tcx>(cx: &LateContext<'tcx>, pat: &Pat<'tcx>) -> Option { && (cx.tcx.lang_items().get(LangItem::OptionSome) == Some(def_id) || cx.tcx.lang_items().get(LangItem::ResultOk) == Some(def_id)) { - let mut bindings = Vec::new(); - pat.each_binding(|_, id, _, _| bindings.push(id)); - if let &[id] = bindings.as_slice() { - Some(id) - } else { - None - } + Some(pat_id) } else { None } diff --git a/tests/ui/manual_unwrap_or_default.fixed b/tests/ui/manual_unwrap_or_default.fixed index 70575d64d6695..832376fa5af15 100644 --- a/tests/ui/manual_unwrap_or_default.fixed +++ b/tests/ui/manual_unwrap_or_default.fixed @@ -78,3 +78,24 @@ fn issue_12569() { 0 }; } + +// Should not warn! +fn issue_12928() { + let x = Some((1, 2)); + let y = if let Some((a, _)) = x { a } else { 0 }; + let y = if let Some((a, ..)) = x { a } else { 0 }; + let x = Some([1, 2]); + let y = if let Some([a, _]) = x { a } else { 0 }; + let y = if let Some([a, ..]) = x { a } else { 0 }; + + struct X { + a: u8, + b: u8, + } + let x = Some(X { a: 0, b: 0 }); + let y = if let Some(X { a, .. }) = x { a } else { 0 }; + struct Y(u8, u8); + let x = Some(Y(0, 0)); + let y = if let Some(Y(a, _)) = x { a } else { 0 }; + let y = if let Some(Y(a, ..)) = x { a } else { 0 }; +} diff --git a/tests/ui/manual_unwrap_or_default.rs b/tests/ui/manual_unwrap_or_default.rs index 58ba04490e0ed..649f65c89fb0a 100644 --- a/tests/ui/manual_unwrap_or_default.rs +++ b/tests/ui/manual_unwrap_or_default.rs @@ -111,3 +111,24 @@ fn issue_12569() { 0 }; } + +// Should not warn! +fn issue_12928() { + let x = Some((1, 2)); + let y = if let Some((a, _)) = x { a } else { 0 }; + let y = if let Some((a, ..)) = x { a } else { 0 }; + let x = Some([1, 2]); + let y = if let Some([a, _]) = x { a } else { 0 }; + let y = if let Some([a, ..]) = x { a } else { 0 }; + + struct X { + a: u8, + b: u8, + } + let x = Some(X { a: 0, b: 0 }); + let y = if let Some(X { a, .. }) = x { a } else { 0 }; + struct Y(u8, u8); + let x = Some(Y(0, 0)); + let y = if let Some(Y(a, _)) = x { a } else { 0 }; + let y = if let Some(Y(a, ..)) = x { a } else { 0 }; +} From e9ea57814768cdae0b36065a731009afa7e36f31 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sat, 30 Mar 2024 12:01:57 +0000 Subject: [PATCH 254/892] Move vcall_visibility_metadata optimization hint out of a debuginfo generation method --- compiler/rustc_codegen_llvm/src/context.rs | 10 ++++++++++ .../rustc_codegen_llvm/src/debuginfo/metadata.rs | 14 +++++++------- compiler/rustc_codegen_ssa/src/meth.rs | 1 + compiler/rustc_codegen_ssa/src/traits/misc.rs | 7 +++++++ 4 files changed, 25 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs index 7d92888feeed4..57682d1cc8c4c 100644 --- a/compiler/rustc_codegen_llvm/src/context.rs +++ b/compiler/rustc_codegen_llvm/src/context.rs @@ -3,6 +3,7 @@ use crate::back::write::to_llvm_code_model; use crate::callee::get_fn; use crate::coverageinfo; use crate::debuginfo; +use crate::debuginfo::metadata::apply_vcall_visibility_metadata; use crate::llvm; use crate::llvm_util; use crate::type_::Type; @@ -522,6 +523,15 @@ impl<'ll, 'tcx> MiscMethods<'tcx> for CodegenCx<'ll, 'tcx> { &self.vtables } + fn apply_vcall_visibility_metadata( + &self, + ty: Ty<'tcx>, + poly_trait_ref: Option>, + vtable: &'ll Value, + ) { + apply_vcall_visibility_metadata(self, ty, poly_trait_ref, vtable); + } + fn get_fn(&self, instance: Instance<'tcx>) -> &'ll Value { get_fn(self, instance) } diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs index 8de4e0effad28..742bfd76590a4 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs @@ -1449,12 +1449,18 @@ fn build_vtable_type_di_node<'ll, 'tcx>( .di_node } -fn vcall_visibility_metadata<'ll, 'tcx>( +pub(crate) fn apply_vcall_visibility_metadata<'ll, 'tcx>( cx: &CodegenCx<'ll, 'tcx>, ty: Ty<'tcx>, trait_ref: Option>, vtable: &'ll Value, ) { + // FIXME(flip1995): The virtual function elimination optimization only works with full LTO in + // LLVM at the moment. + if !cx.sess().opts.unstable_opts.virtual_function_elimination || cx.sess().lto() != Lto::Fat { + return; + } + enum VCallVisibility { Public = 0, LinkageUnit = 1, @@ -1531,12 +1537,6 @@ pub fn create_vtable_di_node<'ll, 'tcx>( poly_trait_ref: Option>, vtable: &'ll Value, ) { - // FIXME(flip1995): The virtual function elimination optimization only works with full LTO in - // LLVM at the moment. - if cx.sess().opts.unstable_opts.virtual_function_elimination && cx.sess().lto() == Lto::Fat { - vcall_visibility_metadata(cx, ty, poly_trait_ref, vtable); - } - if cx.dbg_cx.is_none() { return; } diff --git a/compiler/rustc_codegen_ssa/src/meth.rs b/compiler/rustc_codegen_ssa/src/meth.rs index ddc6797388e77..febc8ee2be248 100644 --- a/compiler/rustc_codegen_ssa/src/meth.rs +++ b/compiler/rustc_codegen_ssa/src/meth.rs @@ -133,6 +133,7 @@ pub fn get_vtable<'tcx, Cx: CodegenMethods<'tcx>>( let align = cx.data_layout().pointer_align.abi; let vtable = cx.static_addr_of(vtable_const, align, Some("vtable")); + cx.apply_vcall_visibility_metadata(ty, trait_ref, vtable); cx.create_vtable_debuginfo(ty, trait_ref, vtable); cx.vtables().borrow_mut().insert((ty, trait_ref), vtable); vtable diff --git a/compiler/rustc_codegen_ssa/src/traits/misc.rs b/compiler/rustc_codegen_ssa/src/traits/misc.rs index 04e2b8796c46a..af3a998960491 100644 --- a/compiler/rustc_codegen_ssa/src/traits/misc.rs +++ b/compiler/rustc_codegen_ssa/src/traits/misc.rs @@ -9,6 +9,13 @@ pub trait MiscMethods<'tcx>: BackendTypes { fn vtables( &self, ) -> &RefCell, Option>), Self::Value>>; + fn apply_vcall_visibility_metadata( + &self, + _ty: Ty<'tcx>, + _poly_trait_ref: Option>, + _vtable: Self::Value, + ) { + } fn check_overflow(&self) -> bool; fn get_fn(&self, instance: Instance<'tcx>) -> Self::Function; fn get_fn_addr(&self, instance: Instance<'tcx>) -> Self::Value; From 7f445329ec3330f4334431b68b26325922391e5c Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sat, 30 Mar 2024 13:19:58 +0000 Subject: [PATCH 255/892] Remove PrintBackendInfo trait It is only implemented for a single type. Directly passing this type is simpler and avoids overhead from indirect calls. --- compiler/rustc_codegen_llvm/src/lib.rs | 24 ++++++++------- compiler/rustc_codegen_llvm/src/llvm_util.rs | 30 ++++++++++--------- .../rustc_codegen_ssa/src/traits/backend.rs | 20 +------------ compiler/rustc_codegen_ssa/src/traits/mod.rs | 4 +-- 4 files changed, 31 insertions(+), 47 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs index 4b7a264300711..ed0989a0ba413 100644 --- a/compiler/rustc_codegen_llvm/src/lib.rs +++ b/compiler/rustc_codegen_llvm/src/lib.rs @@ -274,10 +274,11 @@ impl CodegenBackend for LlvmCodegenBackend { |tcx, ()| llvm_util::global_llvm_features(tcx.sess, true) } - fn print(&self, req: &PrintRequest, out: &mut dyn PrintBackendInfo, sess: &Session) { + fn print(&self, req: &PrintRequest, out: &mut String, sess: &Session) { + use std::fmt::Write; match req.kind { PrintKind::RelocationModels => { - writeln!(out, "Available relocation models:"); + writeln!(out, "Available relocation models:").unwrap(); for name in &[ "static", "pic", @@ -288,25 +289,25 @@ impl CodegenBackend for LlvmCodegenBackend { "ropi-rwpi", "default", ] { - writeln!(out, " {name}"); + writeln!(out, " {name}").unwrap(); } - writeln!(out); + writeln!(out).unwrap(); } PrintKind::CodeModels => { - writeln!(out, "Available code models:"); + writeln!(out, "Available code models:").unwrap(); for name in &["tiny", "small", "kernel", "medium", "large"] { - writeln!(out, " {name}"); + writeln!(out, " {name}").unwrap(); } - writeln!(out); + writeln!(out).unwrap(); } PrintKind::TlsModels => { - writeln!(out, "Available TLS models:"); + writeln!(out, "Available TLS models:").unwrap(); for name in &["global-dynamic", "local-dynamic", "initial-exec", "local-exec", "emulated"] { - writeln!(out, " {name}"); + writeln!(out, " {name}").unwrap(); } - writeln!(out); + writeln!(out).unwrap(); } PrintKind::StackProtectorStrategies => { writeln!( @@ -332,7 +333,8 @@ impl CodegenBackend for LlvmCodegenBackend { none Do not generate stack canaries. "# - ); + ) + .unwrap(); } _other => llvm_util::print(req, out, sess), } diff --git a/compiler/rustc_codegen_llvm/src/llvm_util.rs b/compiler/rustc_codegen_llvm/src/llvm_util.rs index 7e0f264a4aedf..0e89e66be49a0 100644 --- a/compiler/rustc_codegen_llvm/src/llvm_util.rs +++ b/compiler/rustc_codegen_llvm/src/llvm_util.rs @@ -6,7 +6,6 @@ use crate::errors::{ use crate::llvm; use libc::c_int; use rustc_codegen_ssa::base::wants_wasm_eh; -use rustc_codegen_ssa::traits::PrintBackendInfo; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::small_c_str::SmallCStr; use rustc_fs_util::path_to_c_string; @@ -18,6 +17,7 @@ use rustc_target::spec::{MergeFunctions, PanicStrategy}; use rustc_target::target_features::RUSTC_SPECIFIC_FEATURES; use std::ffi::{c_char, c_void, CStr, CString}; +use std::fmt::Write; use std::path::Path; use std::ptr; use std::slice; @@ -372,7 +372,7 @@ fn llvm_target_features(tm: &llvm::TargetMachine) -> Vec<(&str, &str)> { ret } -fn print_target_features(out: &mut dyn PrintBackendInfo, sess: &Session, tm: &llvm::TargetMachine) { +fn print_target_features(out: &mut String, sess: &Session, tm: &llvm::TargetMachine) { let mut llvm_target_features = llvm_target_features(tm); let mut known_llvm_target_features = FxHashSet::<&'static str>::default(); let mut rustc_target_features = sess @@ -412,24 +412,26 @@ fn print_target_features(out: &mut dyn PrintBackendInfo, sess: &Session, tm: &ll .max() .unwrap_or(0); - writeln!(out, "Features supported by rustc for this target:"); + writeln!(out, "Features supported by rustc for this target:").unwrap(); for (feature, desc) in &rustc_target_features { - writeln!(out, " {feature:max_feature_len$} - {desc}."); + writeln!(out, " {feature:max_feature_len$} - {desc}.").unwrap(); } - writeln!(out, "\nCode-generation features supported by LLVM for this target:"); + writeln!(out, "\nCode-generation features supported by LLVM for this target:").unwrap(); for (feature, desc) in &llvm_target_features { - writeln!(out, " {feature:max_feature_len$} - {desc}."); + writeln!(out, " {feature:max_feature_len$} - {desc}.").unwrap(); } if llvm_target_features.is_empty() { - writeln!(out, " Target features listing is not supported by this LLVM version."); + writeln!(out, " Target features listing is not supported by this LLVM version.") + .unwrap(); } - writeln!(out, "\nUse +feature to enable a feature, or -feature to disable it."); - writeln!(out, "For example, rustc -C target-cpu=mycpu -C target-feature=+feature1,-feature2\n"); - writeln!(out, "Code-generation features cannot be used in cfg or #[target_feature],"); - writeln!(out, "and may be renamed or removed in a future version of LLVM or rustc.\n"); + writeln!(out, "\nUse +feature to enable a feature, or -feature to disable it.").unwrap(); + writeln!(out, "For example, rustc -C target-cpu=mycpu -C target-feature=+feature1,-feature2\n") + .unwrap(); + writeln!(out, "Code-generation features cannot be used in cfg or #[target_feature],").unwrap(); + writeln!(out, "and may be renamed or removed in a future version of LLVM or rustc.\n").unwrap(); } -pub(crate) fn print(req: &PrintRequest, mut out: &mut dyn PrintBackendInfo, sess: &Session) { +pub(crate) fn print(req: &PrintRequest, mut out: &mut String, sess: &Session) { require_inited(); let tm = create_informational_target_machine(sess); match req.kind { @@ -440,9 +442,9 @@ pub(crate) fn print(req: &PrintRequest, mut out: &mut dyn PrintBackendInfo, sess let cpu_cstring = CString::new(handle_native(sess.target.cpu.as_ref())) .unwrap_or_else(|e| bug!("failed to convert to cstring: {}", e)); unsafe extern "C" fn callback(out: *mut c_void, string: *const c_char, len: usize) { - let out = &mut *(out as *mut &mut dyn PrintBackendInfo); + let out = &mut *(out as *mut &mut String); let bytes = slice::from_raw_parts(string as *const u8, len); - write!(out, "{}", String::from_utf8_lossy(bytes)); + write!(out, "{}", String::from_utf8_lossy(bytes)).unwrap(); } unsafe { llvm::LLVMRustPrintTargetCPUs( diff --git a/compiler/rustc_codegen_ssa/src/traits/backend.rs b/compiler/rustc_codegen_ssa/src/traits/backend.rs index e8b9490d4010a..3770bd11cf9b2 100644 --- a/compiler/rustc_codegen_ssa/src/traits/backend.rs +++ b/compiler/rustc_codegen_ssa/src/traits/backend.rs @@ -22,8 +22,6 @@ use rustc_session::{ use rustc_span::symbol::Symbol; use rustc_target::abi::call::FnAbi; -use std::fmt; - pub trait BackendTypes { type Value: CodegenObject; type Function: CodegenObject; @@ -62,7 +60,7 @@ pub trait CodegenBackend { fn locale_resource(&self) -> &'static str; fn init(&self, _sess: &Session) {} - fn print(&self, _req: &PrintRequest, _out: &mut dyn PrintBackendInfo, _sess: &Session) {} + fn print(&self, _req: &PrintRequest, _out: &mut String, _sess: &Session) {} fn target_features(&self, _sess: &Session, _allow_unstable: bool) -> Vec { vec![] } @@ -150,19 +148,3 @@ pub trait ExtraBackendMethods: std::thread::Builder::new().name(name).spawn(f) } } - -pub trait PrintBackendInfo { - fn infallible_write_fmt(&mut self, args: fmt::Arguments<'_>); -} - -impl PrintBackendInfo for String { - fn infallible_write_fmt(&mut self, args: fmt::Arguments<'_>) { - fmt::Write::write_fmt(self, args).unwrap(); - } -} - -impl dyn PrintBackendInfo + '_ { - pub fn write_fmt(&mut self, args: fmt::Arguments<'_>) { - self.infallible_write_fmt(args); - } -} diff --git a/compiler/rustc_codegen_ssa/src/traits/mod.rs b/compiler/rustc_codegen_ssa/src/traits/mod.rs index 728c2bc8c49bc..8cb58bd4c704d 100644 --- a/compiler/rustc_codegen_ssa/src/traits/mod.rs +++ b/compiler/rustc_codegen_ssa/src/traits/mod.rs @@ -30,9 +30,7 @@ mod write; pub use self::abi::AbiBuilderMethods; pub use self::asm::{AsmBuilderMethods, AsmMethods, GlobalAsmOperandRef, InlineAsmOperandRef}; -pub use self::backend::{ - Backend, BackendTypes, CodegenBackend, ExtraBackendMethods, PrintBackendInfo, -}; +pub use self::backend::{Backend, BackendTypes, CodegenBackend, ExtraBackendMethods}; pub use self::builder::{BuilderMethods, OverflowOp}; pub use self::consts::ConstMethods; pub use self::coverageinfo::CoverageInfoBuilderMethods; From 98e8601ac3426c395c017f110e2ff8b05733a163 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sat, 30 Mar 2024 13:32:05 +0000 Subject: [PATCH 256/892] Remove const_bitcast from ConstMethods --- compiler/rustc_codegen_gcc/src/common.rs | 26 +++++++++---------- compiler/rustc_codegen_llvm/src/common.rs | 4 --- .../rustc_codegen_ssa/src/traits/consts.rs | 1 - 3 files changed, 13 insertions(+), 18 deletions(-) diff --git a/compiler/rustc_codegen_gcc/src/common.rs b/compiler/rustc_codegen_gcc/src/common.rs index 548c23cc7948a..230fe4f5871e8 100644 --- a/compiler/rustc_codegen_gcc/src/common.rs +++ b/compiler/rustc_codegen_gcc/src/common.rs @@ -28,6 +28,19 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { global // TODO(antoyo): set linkage. } + + pub fn const_bitcast(&self, value: RValue<'gcc>, typ: Type<'gcc>) -> RValue<'gcc> { + if value.get_type() == self.bool_type.make_pointer() { + if let Some(pointee) = typ.get_pointee() { + if pointee.dyncast_vector().is_some() { + panic!() + } + } + } + // NOTE: since bitcast makes a value non-constant, don't bitcast if not necessary as some + // SIMD builtins require a constant value. + self.bitcast_if_needed(value, typ) + } } pub fn bytes_in_context<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, bytes: &[u8]) -> RValue<'gcc> { @@ -239,19 +252,6 @@ impl<'gcc, 'tcx> ConstMethods<'tcx> for CodegenCx<'gcc, 'tcx> { const_alloc_to_gcc(self, alloc) } - fn const_bitcast(&self, value: RValue<'gcc>, typ: Type<'gcc>) -> RValue<'gcc> { - if value.get_type() == self.bool_type.make_pointer() { - if let Some(pointee) = typ.get_pointee() { - if pointee.dyncast_vector().is_some() { - panic!() - } - } - } - // NOTE: since bitcast makes a value non-constant, don't bitcast if not necessary as some - // SIMD builtins require a constant value. - self.bitcast_if_needed(value, typ) - } - fn const_ptr_byte_offset(&self, base_addr: Self::Value, offset: abi::Size) -> Self::Value { self.context .new_array_access(None, base_addr, self.const_usize(offset.bytes())) diff --git a/compiler/rustc_codegen_llvm/src/common.rs b/compiler/rustc_codegen_llvm/src/common.rs index 4ffc92eb63356..d42c6ed827aec 100644 --- a/compiler/rustc_codegen_llvm/src/common.rs +++ b/compiler/rustc_codegen_llvm/src/common.rs @@ -329,10 +329,6 @@ impl<'ll, 'tcx> ConstMethods<'tcx> for CodegenCx<'ll, 'tcx> { const_alloc_to_llvm(self, alloc, /*static*/ false) } - fn const_bitcast(&self, val: &'ll Value, ty: &'ll Type) -> &'ll Value { - self.const_bitcast(val, ty) - } - fn const_ptr_byte_offset(&self, base_addr: Self::Value, offset: abi::Size) -> Self::Value { unsafe { llvm::LLVMConstInBoundsGEP2( diff --git a/compiler/rustc_codegen_ssa/src/traits/consts.rs b/compiler/rustc_codegen_ssa/src/traits/consts.rs index 8cb17a5b37a89..3da732602c520 100644 --- a/compiler/rustc_codegen_ssa/src/traits/consts.rs +++ b/compiler/rustc_codegen_ssa/src/traits/consts.rs @@ -37,6 +37,5 @@ pub trait ConstMethods<'tcx>: BackendTypes { fn scalar_to_backend(&self, cv: Scalar, layout: abi::Scalar, llty: Self::Type) -> Self::Value; - fn const_bitcast(&self, val: Self::Value, ty: Self::Type) -> Self::Value; fn const_ptr_byte_offset(&self, val: Self::Value, offset: abi::Size) -> Self::Value; } From e32eb4c9e933d98455205348706620c51f25b69d Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sat, 30 Mar 2024 13:53:52 +0000 Subject: [PATCH 257/892] Dedup some intrinsic handling code for caller_location --- compiler/rustc_codegen_ssa/src/mir/block.rs | 37 +++++++-------------- 1 file changed, 12 insertions(+), 25 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index 57138d3b9dbdb..57a5393da251e 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -902,31 +902,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { // The arguments we'll be passing. Plus one to account for outptr, if used. let arg_count = fn_abi.args.len() + fn_abi.ret.is_indirect() as usize; - if matches!(intrinsic, Some(ty::IntrinsicDef { name: sym::caller_location, .. })) { - return if let Some(target) = target { - let location = - self.get_caller_location(bx, mir::SourceInfo { span: fn_span, ..source_info }); - - let mut llargs = Vec::with_capacity(arg_count); - let ret_dest = self.make_return_dest( - bx, - destination, - &fn_abi.ret, - &mut llargs, - intrinsic, - Some(target), - ); - assert_eq!(llargs, []); - if let ReturnDest::IndirectOperand(tmp, _) = ret_dest { - location.val.store(bx, tmp); - } - self.store_return(bx, ret_dest, &fn_abi.ret, location.immediate()); - helper.funclet_br(self, bx, target, mergeable_succ) - } else { - MergingSucc::False - }; - } - let instance = match intrinsic { None => instance, Some(intrinsic) => { @@ -971,6 +946,18 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { }) .collect(); + if matches!(intrinsic, ty::IntrinsicDef { name: sym::caller_location, .. }) { + let location = self + .get_caller_location(bx, mir::SourceInfo { span: fn_span, ..source_info }); + + assert_eq!(llargs, []); + if let ReturnDest::IndirectOperand(tmp, _) = ret_dest { + location.val.store(bx, tmp); + } + self.store_return(bx, ret_dest, &fn_abi.ret, location.immediate()); + return helper.funclet_br(self, bx, target.unwrap(), mergeable_succ); + } + let instance = *instance.as_ref().unwrap(); match Self::codegen_intrinsic_call(bx, instance, fn_abi, &args, dest, span) { Ok(()) => { From 9d25e851ced6f996bde9d53d51525787a5dc2ca6 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sat, 30 Mar 2024 13:32:05 +0000 Subject: [PATCH 258/892] Remove const_bitcast from ConstMethods --- src/common.rs | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/common.rs b/src/common.rs index 548c23cc7948a..230fe4f5871e8 100644 --- a/src/common.rs +++ b/src/common.rs @@ -28,6 +28,19 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { global // TODO(antoyo): set linkage. } + + pub fn const_bitcast(&self, value: RValue<'gcc>, typ: Type<'gcc>) -> RValue<'gcc> { + if value.get_type() == self.bool_type.make_pointer() { + if let Some(pointee) = typ.get_pointee() { + if pointee.dyncast_vector().is_some() { + panic!() + } + } + } + // NOTE: since bitcast makes a value non-constant, don't bitcast if not necessary as some + // SIMD builtins require a constant value. + self.bitcast_if_needed(value, typ) + } } pub fn bytes_in_context<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, bytes: &[u8]) -> RValue<'gcc> { @@ -239,19 +252,6 @@ impl<'gcc, 'tcx> ConstMethods<'tcx> for CodegenCx<'gcc, 'tcx> { const_alloc_to_gcc(self, alloc) } - fn const_bitcast(&self, value: RValue<'gcc>, typ: Type<'gcc>) -> RValue<'gcc> { - if value.get_type() == self.bool_type.make_pointer() { - if let Some(pointee) = typ.get_pointee() { - if pointee.dyncast_vector().is_some() { - panic!() - } - } - } - // NOTE: since bitcast makes a value non-constant, don't bitcast if not necessary as some - // SIMD builtins require a constant value. - self.bitcast_if_needed(value, typ) - } - fn const_ptr_byte_offset(&self, base_addr: Self::Value, offset: abi::Size) -> Self::Value { self.context .new_array_access(None, base_addr, self.const_usize(offset.bytes())) From 22b32432ca3e8296a7649ef8c3711c0310f8f426 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sat, 30 Mar 2024 13:58:06 +0000 Subject: [PATCH 259/892] Move all intrinsic handling code in codegen_call_terminators together --- compiler/rustc_codegen_ssa/src/mir/block.rs | 44 +++++++++------------ 1 file changed, 19 insertions(+), 25 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index 57a5393da251e..1eec1841a3753 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -751,7 +751,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { &mut self, helper: &TerminatorCodegenHelper<'tcx>, bx: &mut Bx, - intrinsic: Option, + intrinsic: ty::IntrinsicDef, instance: Option>, source_info: mir::SourceInfo, target: Option, @@ -761,8 +761,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { // Emit a panic or a no-op for `assert_*` intrinsics. // These are intrinsics that compile to panics so that we can get a message // which mentions the offending type, even from a const context. - let panic_intrinsic = intrinsic.and_then(|i| ValidityRequirement::from_intrinsic(i.name)); - if let Some(requirement) = panic_intrinsic { + if let Some(requirement) = ValidityRequirement::from_intrinsic(intrinsic.name) { let ty = instance.unwrap().args.type_at(0); let do_panic = !bx @@ -869,12 +868,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let sig = callee.layout.ty.fn_sig(bx.tcx()); let abi = sig.abi(); - // Handle intrinsics old codegen wants Expr's for, ourselves. - let intrinsic = match def { - Some(ty::InstanceKind::Intrinsic(def_id)) => Some(bx.tcx().intrinsic(def_id).unwrap()), - _ => None, - }; - let extra_args = &args[sig.inputs().skip_binder().len()..]; let extra_args = bx.tcx().mk_type_list_from_iter(extra_args.iter().map(|op_arg| { let op_ty = op_arg.node.ty(self.mir, bx.tcx()); @@ -886,25 +879,25 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { None => bx.fn_abi_of_fn_ptr(sig, extra_args), }; - if let Some(merging_succ) = self.codegen_panic_intrinsic( - &helper, - bx, - intrinsic, - instance, - source_info, - target, - unwind, - mergeable_succ, - ) { - return merging_succ; - } - // The arguments we'll be passing. Plus one to account for outptr, if used. let arg_count = fn_abi.args.len() + fn_abi.ret.is_indirect() as usize; - let instance = match intrinsic { - None => instance, - Some(intrinsic) => { + let instance = match def { + Some(ty::InstanceKind::Intrinsic(def_id)) => { + let intrinsic = bx.tcx().intrinsic(def_id).unwrap(); + if let Some(merging_succ) = self.codegen_panic_intrinsic( + &helper, + bx, + intrinsic, + instance, + source_info, + target, + unwind, + mergeable_succ, + ) { + return merging_succ; + } + let mut llargs = Vec::with_capacity(1); let ret_dest = self.make_return_dest( bx, @@ -984,6 +977,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } } } + _ => instance, }; let mut llargs = Vec::with_capacity(arg_count); From aacdce38f7f2298c5779446ffe17cae0068ccd37 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sat, 30 Mar 2024 14:25:13 +0000 Subject: [PATCH 260/892] Remove check_overflow method from MiscMethods It can be retrieved from the Session too. --- compiler/rustc_codegen_gcc/src/context.rs | 8 -------- compiler/rustc_codegen_llvm/src/context.rs | 8 -------- compiler/rustc_codegen_ssa/src/mir/block.rs | 2 +- compiler/rustc_codegen_ssa/src/traits/misc.rs | 1 - 4 files changed, 1 insertion(+), 18 deletions(-) diff --git a/compiler/rustc_codegen_gcc/src/context.rs b/compiler/rustc_codegen_gcc/src/context.rs index 4a1f5188a8013..6231b09552cea 100644 --- a/compiler/rustc_codegen_gcc/src/context.rs +++ b/compiler/rustc_codegen_gcc/src/context.rs @@ -27,7 +27,6 @@ use crate::callee::get_fn; use crate::common::SignType; pub struct CodegenCx<'gcc, 'tcx> { - pub check_overflow: bool, pub codegen_unit: &'tcx CodegenUnit<'tcx>, pub context: &'gcc Context<'gcc>, @@ -134,8 +133,6 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { tcx: TyCtxt<'tcx>, supports_128bit_integers: bool, ) -> Self { - let check_overflow = tcx.sess.overflow_checks(); - let create_type = |ctype, rust_type| { let layout = tcx.layout_of(ParamEnv::reveal_all().and(rust_type)).unwrap(); let align = layout.align.abi.bytes(); @@ -271,7 +268,6 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { } let mut cx = Self { - check_overflow, codegen_unit, context, current_func: RefCell::new(None), @@ -511,10 +507,6 @@ impl<'gcc, 'tcx> MiscMethods<'tcx> for CodegenCx<'gcc, 'tcx> { &self.tcx.sess } - fn check_overflow(&self) -> bool { - self.check_overflow - } - fn codegen_unit(&self) -> &'tcx CodegenUnit<'tcx> { self.codegen_unit } diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs index 57682d1cc8c4c..1a8e8efdae507 100644 --- a/compiler/rustc_codegen_llvm/src/context.rs +++ b/compiler/rustc_codegen_llvm/src/context.rs @@ -44,7 +44,6 @@ use std::str; /// All other LLVM data structures in the `CodegenCx` are tied to that `llvm::Context`. pub struct CodegenCx<'ll, 'tcx> { pub tcx: TyCtxt<'tcx>, - pub check_overflow: bool, pub use_dll_storage_attrs: bool, pub tls_model: llvm::ThreadLocalMode, @@ -442,8 +441,6 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> { // start) and then strongly recommending static linkage on Windows! let use_dll_storage_attrs = tcx.sess.target.is_like_windows; - let check_overflow = tcx.sess.overflow_checks(); - let tls_model = to_llvm_tls_model(tcx.sess.tls_model()); let (llcx, llmod) = (&*llvm_module.llcx, llvm_module.llmod()); @@ -467,7 +464,6 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> { CodegenCx { tcx, - check_overflow, use_dll_storage_attrs, tls_model, llmod, @@ -606,10 +602,6 @@ impl<'ll, 'tcx> MiscMethods<'tcx> for CodegenCx<'ll, 'tcx> { self.tcx.sess } - fn check_overflow(&self) -> bool { - self.check_overflow - } - fn codegen_unit(&self) -> &'tcx CodegenUnit<'tcx> { self.codegen_unit } diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index 1eec1841a3753..b1c22faf1ae9d 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -658,7 +658,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { // with #[rustc_inherit_overflow_checks] and inlined from // another crate (mostly core::num generic/#[inline] fns), // while the current crate doesn't use overflow checks. - if !bx.cx().check_overflow() && msg.is_optional_overflow_check() { + if !bx.sess().overflow_checks() && msg.is_optional_overflow_check() { const_cond = Some(expected); } diff --git a/compiler/rustc_codegen_ssa/src/traits/misc.rs b/compiler/rustc_codegen_ssa/src/traits/misc.rs index af3a998960491..0ace28ed3ba5e 100644 --- a/compiler/rustc_codegen_ssa/src/traits/misc.rs +++ b/compiler/rustc_codegen_ssa/src/traits/misc.rs @@ -16,7 +16,6 @@ pub trait MiscMethods<'tcx>: BackendTypes { _vtable: Self::Value, ) { } - fn check_overflow(&self) -> bool; fn get_fn(&self, instance: Instance<'tcx>) -> Self::Function; fn get_fn_addr(&self, instance: Instance<'tcx>) -> Self::Value; fn eh_personality(&self) -> Self::Value; From 887f57ff0bd0664bfb901321048302f0879e1be2 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sat, 30 Mar 2024 14:36:14 +0000 Subject: [PATCH 261/892] Remove type_i1 and type_struct from cg_ssa They are not representable by Cranelift --- compiler/rustc_codegen_gcc/src/type_.rs | 50 +++++++++---------- compiler/rustc_codegen_llvm/src/type_.rs | 28 +++++------ .../rustc_codegen_ssa/src/traits/type_.rs | 2 - 3 files changed, 39 insertions(+), 41 deletions(-) diff --git a/compiler/rustc_codegen_gcc/src/type_.rs b/compiler/rustc_codegen_gcc/src/type_.rs index 68471b028beb8..4caff2e63106a 100644 --- a/compiler/rustc_codegen_gcc/src/type_.rs +++ b/compiler/rustc_codegen_gcc/src/type_.rs @@ -89,13 +89,34 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { ty::FloatTy::F128 => self.type_f128(), } } -} -impl<'gcc, 'tcx> BaseTypeMethods<'tcx> for CodegenCx<'gcc, 'tcx> { - fn type_i1(&self) -> Type<'gcc> { + pub fn type_i1(&self) -> Type<'gcc> { self.bool_type } + pub fn type_struct(&self, fields: &[Type<'gcc>], packed: bool) -> Type<'gcc> { + let types = fields.to_vec(); + if let Some(typ) = self.struct_types.borrow().get(fields) { + return *typ; + } + let fields: Vec<_> = fields + .iter() + .enumerate() + .map(|(index, field)| { + self.context.new_field(None, *field, format!("field{}_TODO", index)) + }) + .collect(); + let typ = self.context.new_struct_type(None, "struct", &fields).as_type(); + if packed { + #[cfg(feature = "master")] + typ.set_packed(); + } + self.struct_types.borrow_mut().insert(types, typ); + typ + } +} + +impl<'gcc, 'tcx> BaseTypeMethods<'tcx> for CodegenCx<'gcc, 'tcx> { fn type_i8(&self) -> Type<'gcc> { self.i8_type } @@ -131,7 +152,7 @@ impl<'gcc, 'tcx> BaseTypeMethods<'tcx> for CodegenCx<'gcc, 'tcx> { fn type_f64(&self) -> Type<'gcc> { self.double_type } - + fn type_f128(&self) -> Type<'gcc> { unimplemented!("f16_f128") } @@ -140,27 +161,6 @@ impl<'gcc, 'tcx> BaseTypeMethods<'tcx> for CodegenCx<'gcc, 'tcx> { self.context.new_function_pointer_type(None, return_type, params, false) } - fn type_struct(&self, fields: &[Type<'gcc>], packed: bool) -> Type<'gcc> { - let types = fields.to_vec(); - if let Some(typ) = self.struct_types.borrow().get(fields) { - return *typ; - } - let fields: Vec<_> = fields - .iter() - .enumerate() - .map(|(index, field)| { - self.context.new_field(None, *field, format!("field{}_TODO", index)) - }) - .collect(); - let typ = self.context.new_struct_type(None, "struct", &fields).as_type(); - if packed { - #[cfg(feature = "master")] - typ.set_packed(); - } - self.struct_types.borrow_mut().insert(types, typ); - typ - } - fn type_kind(&self, typ: Type<'gcc>) -> TypeKind { if self.is_int_type_or_bool(typ) { TypeKind::Integer diff --git a/compiler/rustc_codegen_llvm/src/type_.rs b/compiler/rustc_codegen_llvm/src/type_.rs index a00f09dc40da6..f1141c57cedd7 100644 --- a/compiler/rustc_codegen_llvm/src/type_.rs +++ b/compiler/rustc_codegen_llvm/src/type_.rs @@ -127,13 +127,24 @@ impl<'ll> CodegenCx<'ll, '_> { pub(crate) fn type_variadic_func(&self, args: &[&'ll Type], ret: &'ll Type) -> &'ll Type { unsafe { llvm::LLVMFunctionType(ret, args.as_ptr(), args.len() as c_uint, True) } } -} -impl<'ll, 'tcx> BaseTypeMethods<'tcx> for CodegenCx<'ll, 'tcx> { - fn type_i1(&self) -> &'ll Type { + pub(crate) fn type_i1(&self) -> &'ll Type { unsafe { llvm::LLVMInt1TypeInContext(self.llcx) } } + pub(crate) fn type_struct(&self, els: &[&'ll Type], packed: bool) -> &'ll Type { + unsafe { + llvm::LLVMStructTypeInContext( + self.llcx, + els.as_ptr(), + els.len() as c_uint, + packed as Bool, + ) + } + } +} + +impl<'ll, 'tcx> BaseTypeMethods<'tcx> for CodegenCx<'ll, 'tcx> { fn type_i8(&self) -> &'ll Type { unsafe { llvm::LLVMInt8TypeInContext(self.llcx) } } @@ -178,17 +189,6 @@ impl<'ll, 'tcx> BaseTypeMethods<'tcx> for CodegenCx<'ll, 'tcx> { unsafe { llvm::LLVMFunctionType(ret, args.as_ptr(), args.len() as c_uint, False) } } - fn type_struct(&self, els: &[&'ll Type], packed: bool) -> &'ll Type { - unsafe { - llvm::LLVMStructTypeInContext( - self.llcx, - els.as_ptr(), - els.len() as c_uint, - packed as Bool, - ) - } - } - fn type_kind(&self, ty: &'ll Type) -> TypeKind { unsafe { llvm::LLVMRustGetTypeKind(ty).to_generic() } } diff --git a/compiler/rustc_codegen_ssa/src/traits/type_.rs b/compiler/rustc_codegen_ssa/src/traits/type_.rs index 403f6a7327715..e492bba969e1a 100644 --- a/compiler/rustc_codegen_ssa/src/traits/type_.rs +++ b/compiler/rustc_codegen_ssa/src/traits/type_.rs @@ -12,7 +12,6 @@ use rustc_target::abi::{AddressSpace, Float, Integer}; // This depends on `Backend` and not `BackendTypes`, because consumers will probably want to use // `LayoutOf` or `HasTyCtxt`. This way, they don't have to add a constraint on it themselves. pub trait BaseTypeMethods<'tcx>: Backend<'tcx> { - fn type_i1(&self) -> Self::Type; fn type_i8(&self) -> Self::Type; fn type_i16(&self) -> Self::Type; fn type_i32(&self) -> Self::Type; @@ -27,7 +26,6 @@ pub trait BaseTypeMethods<'tcx>: Backend<'tcx> { fn type_array(&self, ty: Self::Type, len: u64) -> Self::Type; fn type_func(&self, args: &[Self::Type], ret: Self::Type) -> Self::Type; - fn type_struct(&self, els: &[Self::Type], packed: bool) -> Self::Type; fn type_kind(&self, ty: Self::Type) -> TypeKind; fn type_ptr(&self) -> Self::Type; fn type_ptr_ext(&self, address_space: AddressSpace) -> Self::Type; From 8a1e58169ae2980f10a8e3cadecc80c54227423b Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sat, 30 Mar 2024 14:25:13 +0000 Subject: [PATCH 262/892] Remove check_overflow method from MiscMethods It can be retrieved from the Session too. --- src/context.rs | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/context.rs b/src/context.rs index 4a1f5188a8013..6231b09552cea 100644 --- a/src/context.rs +++ b/src/context.rs @@ -27,7 +27,6 @@ use crate::callee::get_fn; use crate::common::SignType; pub struct CodegenCx<'gcc, 'tcx> { - pub check_overflow: bool, pub codegen_unit: &'tcx CodegenUnit<'tcx>, pub context: &'gcc Context<'gcc>, @@ -134,8 +133,6 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { tcx: TyCtxt<'tcx>, supports_128bit_integers: bool, ) -> Self { - let check_overflow = tcx.sess.overflow_checks(); - let create_type = |ctype, rust_type| { let layout = tcx.layout_of(ParamEnv::reveal_all().and(rust_type)).unwrap(); let align = layout.align.abi.bytes(); @@ -271,7 +268,6 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { } let mut cx = Self { - check_overflow, codegen_unit, context, current_func: RefCell::new(None), @@ -511,10 +507,6 @@ impl<'gcc, 'tcx> MiscMethods<'tcx> for CodegenCx<'gcc, 'tcx> { &self.tcx.sess } - fn check_overflow(&self) -> bool { - self.check_overflow - } - fn codegen_unit(&self) -> &'tcx CodegenUnit<'tcx> { self.codegen_unit } From 84f45bb0930a0696f8d0bcb8b480bc194da80db1 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sat, 30 Mar 2024 17:29:32 +0000 Subject: [PATCH 263/892] Fix doc comment --- compiler/rustc_codegen_ssa/src/traits/type_.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/traits/type_.rs b/compiler/rustc_codegen_ssa/src/traits/type_.rs index e492bba969e1a..b1bad6cfa6f58 100644 --- a/compiler/rustc_codegen_ssa/src/traits/type_.rs +++ b/compiler/rustc_codegen_ssa/src/traits/type_.rs @@ -113,8 +113,8 @@ pub trait LayoutTypeMethods<'tcx>: Backend<'tcx> { /// The backend type used for a rust type when it's in an SSA register. /// /// For nearly all types this is the same as the [`Self::backend_type`], however - /// `bool` (and other `0`-or-`1` values) are kept as [`BaseTypeMethods::type_i1`] - /// in registers but as [`BaseTypeMethods::type_i8`] in memory. + /// `bool` (and other `0`-or-`1` values) are kept as `i1` in registers but as + /// [`BaseTypeMethods::type_i8`] in memory. /// /// Converting values between the two different backend types is done using /// [`from_immediate`](super::BuilderMethods::from_immediate) and From 994041a40c81abe88d463240f6dcebed17bd97db Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sat, 30 Mar 2024 14:36:14 +0000 Subject: [PATCH 264/892] Remove type_i1 and type_struct from cg_ssa They are not representable by Cranelift --- src/type_.rs | 50 +++++++++++++++++++++++++------------------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/src/type_.rs b/src/type_.rs index 68471b028beb8..4caff2e63106a 100644 --- a/src/type_.rs +++ b/src/type_.rs @@ -89,13 +89,34 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { ty::FloatTy::F128 => self.type_f128(), } } -} -impl<'gcc, 'tcx> BaseTypeMethods<'tcx> for CodegenCx<'gcc, 'tcx> { - fn type_i1(&self) -> Type<'gcc> { + pub fn type_i1(&self) -> Type<'gcc> { self.bool_type } + pub fn type_struct(&self, fields: &[Type<'gcc>], packed: bool) -> Type<'gcc> { + let types = fields.to_vec(); + if let Some(typ) = self.struct_types.borrow().get(fields) { + return *typ; + } + let fields: Vec<_> = fields + .iter() + .enumerate() + .map(|(index, field)| { + self.context.new_field(None, *field, format!("field{}_TODO", index)) + }) + .collect(); + let typ = self.context.new_struct_type(None, "struct", &fields).as_type(); + if packed { + #[cfg(feature = "master")] + typ.set_packed(); + } + self.struct_types.borrow_mut().insert(types, typ); + typ + } +} + +impl<'gcc, 'tcx> BaseTypeMethods<'tcx> for CodegenCx<'gcc, 'tcx> { fn type_i8(&self) -> Type<'gcc> { self.i8_type } @@ -131,7 +152,7 @@ impl<'gcc, 'tcx> BaseTypeMethods<'tcx> for CodegenCx<'gcc, 'tcx> { fn type_f64(&self) -> Type<'gcc> { self.double_type } - + fn type_f128(&self) -> Type<'gcc> { unimplemented!("f16_f128") } @@ -140,27 +161,6 @@ impl<'gcc, 'tcx> BaseTypeMethods<'tcx> for CodegenCx<'gcc, 'tcx> { self.context.new_function_pointer_type(None, return_type, params, false) } - fn type_struct(&self, fields: &[Type<'gcc>], packed: bool) -> Type<'gcc> { - let types = fields.to_vec(); - if let Some(typ) = self.struct_types.borrow().get(fields) { - return *typ; - } - let fields: Vec<_> = fields - .iter() - .enumerate() - .map(|(index, field)| { - self.context.new_field(None, *field, format!("field{}_TODO", index)) - }) - .collect(); - let typ = self.context.new_struct_type(None, "struct", &fields).as_type(); - if packed { - #[cfg(feature = "master")] - typ.set_packed(); - } - self.struct_types.borrow_mut().insert(types, typ); - typ - } - fn type_kind(&self, typ: Type<'gcc>) -> TypeKind { if self.is_int_type_or_bool(typ) { TypeKind::Integer From 790c238ef431639997730eb9e5f21fe043d4adf2 Mon Sep 17 00:00:00 2001 From: Oneirical Date: Fri, 21 Jun 2024 15:30:51 -0400 Subject: [PATCH 265/892] rewrite pdb-alt-path to rmake --- .../tidy/src/allowed_run_make_makefiles.txt | 1 - tests/run-make/pdb-alt-path/Makefile | 20 ---------- tests/run-make/pdb-alt-path/rmake.rs | 37 +++++++++++++++++++ 3 files changed, 37 insertions(+), 21 deletions(-) delete mode 100644 tests/run-make/pdb-alt-path/Makefile create mode 100644 tests/run-make/pdb-alt-path/rmake.rs diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index f32413540498d..3c6bb33813162 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -131,7 +131,6 @@ run-make/pass-linker-flags-flavor/Makefile run-make/pass-linker-flags-from-dep/Makefile run-make/pass-linker-flags/Makefile run-make/pass-non-c-like-enum-to-c/Makefile -run-make/pdb-alt-path/Makefile run-make/pdb-buildinfo-cl-cmd/Makefile run-make/pgo-gen-lto/Makefile run-make/pgo-gen-no-imp-symbols/Makefile diff --git a/tests/run-make/pdb-alt-path/Makefile b/tests/run-make/pdb-alt-path/Makefile deleted file mode 100644 index 7a0ae3bf2ef0d..0000000000000 --- a/tests/run-make/pdb-alt-path/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -include ../tools.mk - -# only-windows-msvc - -all: - # Test that we don't have the full path to the PDB file in the binary - $(RUSTC) main.rs -g --crate-name my_crate_name --crate-type bin -Cforce-frame-pointers - $(CGREP) "my_crate_name.pdb" < $(TMPDIR)/my_crate_name.exe - $(CGREP) -v "\\my_crate_name.pdb" < $(TMPDIR)/my_crate_name.exe - - # Test that backtraces still can find debuginfo by checking that they contain symbol names and - # source locations. - $(TMPDIR)/my_crate_name.exe &> $(TMPDIR)/backtrace.txt - $(CGREP) "my_crate_name::fn_in_backtrace" < $(TMPDIR)/backtrace.txt - $(CGREP) "main.rs:15" < $(TMPDIR)/backtrace.txt - - # Test that explicitly passed `-Clink-arg=/PDBALTPATH:...` is respected - $(RUSTC) main.rs -g --crate-name my_crate_name --crate-type bin -Clink-arg=/PDBALTPATH:abcdefg.pdb -Cforce-frame-pointers - $(CGREP) "abcdefg.pdb" < $(TMPDIR)/my_crate_name.exe - $(CGREP) -v "my_crate_name.pdb" < $(TMPDIR)/my_crate_name.exe diff --git a/tests/run-make/pdb-alt-path/rmake.rs b/tests/run-make/pdb-alt-path/rmake.rs new file mode 100644 index 0000000000000..197768d82c114 --- /dev/null +++ b/tests/run-make/pdb-alt-path/rmake.rs @@ -0,0 +1,37 @@ +// The information inside a .exe file contains a string of the PDB file name. +// This could be a security concern if the full path was exposed, as it could +// reveal information about the filesystem where the bin was first compiled. +// This should only be overridden by `-Clink-arg=/PDBALTPATH:...` - this test +// checks that no full file paths are exposed and that the override flag is respected. +// See https://github.com/rust-lang/rust/pull/121297 + +//@ only-windows-msvc + +fn main() { + // Test that we don't have the full path to the PDB file in the binary + rustc() + .input("main.rs") + .arg("-g") + .crate_name("my_crate_name") + .crate_type("bin") + .arg("-Cforce-frame-pointers") + .run(); + invalid_utf8_contains(bin_name("my_crate_name"), "my_crate_name.pdb"); + invalid_utf8_not_contains(bin_name("my_crate_name"), r#"\my_crate_name.pdb"#); + // Test that backtraces still can find debuginfo by checking that they contain symbol names and + // source locations. + let out = run(bin_name(my_crate_name)); + out.assert_stdout_contains("my_crate_name::fn_in_backtrace"); + out.assert_stdout_contains("main.rs:15"); + // Test that explicitly passed `-Clink-arg=/PDBALTPATH:...` is respected + rustc() + .input("main.rs") + .arg("-g") + .crate_name("my_crate_name") + .crate_type("bin") + .link_arg("/PDBALTPATH:abcdefg.pdb") + .arg("-Cforce-frame-pointers") + .run(); + invalid_utf8_contains(bin_name("my_crate_name"), "abcdefg.pdb"); + invalid_utf8_not_contains(bin_name("my_crate_name"), "my_crate_name.pdb"); +} From 9dff8a33e1abcf8f0455acf7befd5366cc3d800f Mon Sep 17 00:00:00 2001 From: Oneirical Date: Fri, 21 Jun 2024 15:46:34 -0400 Subject: [PATCH 266/892] rewrite mismatching-target-triples to rmake --- src/tools/tidy/src/allowed_run_make_makefiles.txt | 1 - .../run-make/mismatching-target-triples/Makefile | 11 ----------- .../run-make/mismatching-target-triples/rmake.rs | 15 +++++++++++++++ tests/run-make/pdb-alt-path/rmake.rs | 2 +- 4 files changed, 16 insertions(+), 13 deletions(-) delete mode 100644 tests/run-make/mismatching-target-triples/Makefile create mode 100644 tests/run-make/mismatching-target-triples/rmake.rs diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index 3c6bb33813162..f8b0742a55c87 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -111,7 +111,6 @@ run-make/many-crates-but-no-match/Makefile run-make/metadata-dep-info/Makefile run-make/min-global-align/Makefile run-make/mingw-export-call-convention/Makefile -run-make/mismatching-target-triples/Makefile run-make/missing-crate-dependency/Makefile run-make/mixing-libs/Makefile run-make/msvc-opt-minsize/Makefile diff --git a/tests/run-make/mismatching-target-triples/Makefile b/tests/run-make/mismatching-target-triples/Makefile deleted file mode 100644 index 409388e041478..0000000000000 --- a/tests/run-make/mismatching-target-triples/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -include ../tools.mk - -# Issue #10814 -# -# these are no_std to avoid having to have the standard library or any -# linkers/assemblers for the relevant platform - -all: - $(RUSTC) foo.rs --target=i686-unknown-linux-gnu - $(RUSTC) bar.rs --target=x86_64-unknown-linux-gnu 2>&1 \ - | $(CGREP) 'couldn'"'"'t find crate `foo` with expected target triple x86_64-unknown-linux-gnu' diff --git a/tests/run-make/mismatching-target-triples/rmake.rs b/tests/run-make/mismatching-target-triples/rmake.rs new file mode 100644 index 0000000000000..6f41eac8cdaf4 --- /dev/null +++ b/tests/run-make/mismatching-target-triples/rmake.rs @@ -0,0 +1,15 @@ +// In this test, foo links against 32-bit architecture, and then, bar, which depends +// on foo, links against 64-bit architecture, causing a metadata mismatch due to the +// differences in target architectures. This used to cause an internal compiler error, +// now replaced by a clearer normal error message. This test checks that this aforementioned +// error message is used. +// See https://github.com/rust-lang/rust/issues/10814 + +use run_make_support::rustc; + +fn main() { + rustc().input("foo.rs").target("i686-unknown-linux-gnu").run(); + rustc().input("bar.rs").target("x86_64-unknown-linux-gnu").run_fail().assert_stderr_contains( + r#"couldn't find crate `foo` with expected target triple x86_64-unknown-linux-gnu"#, + ); +} diff --git a/tests/run-make/pdb-alt-path/rmake.rs b/tests/run-make/pdb-alt-path/rmake.rs index 197768d82c114..15497be4ecfe2 100644 --- a/tests/run-make/pdb-alt-path/rmake.rs +++ b/tests/run-make/pdb-alt-path/rmake.rs @@ -5,7 +5,7 @@ // checks that no full file paths are exposed and that the override flag is respected. // See https://github.com/rust-lang/rust/pull/121297 -//@ only-windows-msvc +//@ only-windows fn main() { // Test that we don't have the full path to the PDB file in the binary From dabf5faff0bb0154d702561266826cc0cd53eec4 Mon Sep 17 00:00:00 2001 From: Robert Zakrzewski Date: Fri, 21 Jun 2024 22:10:52 +0200 Subject: [PATCH 267/892] Add support for Float64 --- src/base.rs | 2 ++ src/context.rs | 3 +++ src/type_.rs | 4 ++++ 3 files changed, 9 insertions(+) diff --git a/src/base.rs b/src/base.rs index ea2b0b791b7fd..e88fde8ebef71 100644 --- a/src/base.rs +++ b/src/base.rs @@ -186,6 +186,7 @@ pub fn compile_codegen_unit( // context. let f16_type_supported = target_info.supports_target_dependent_type(CType::Float16); 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); // TODO: improve this to avoid passing that many arguments. let cx = CodegenCx::new( @@ -195,6 +196,7 @@ pub fn compile_codegen_unit( target_info.supports_128bit_int(), f16_type_supported, f32_type_supported, + f64_type_supported, f128_type_supported, ); diff --git a/src/context.rs b/src/context.rs index 53a2b09217a97..6beed91270bd5 100644 --- a/src/context.rs +++ b/src/context.rs @@ -70,6 +70,7 @@ pub struct CodegenCx<'gcc, 'tcx> { pub supports_128bit_integers: bool, pub supports_f16_type: bool, pub supports_f32_type: bool, + pub supports_f64_type: bool, pub supports_f128_type: bool, pub float_type: Type<'gcc>, @@ -135,6 +136,7 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { supports_128bit_integers: bool, supports_f16_type: bool, supports_f32_type: bool, + supports_f64_type: bool, supports_f128_type: bool, ) -> Self { let check_overflow = tcx.sess.overflow_checks(); @@ -313,6 +315,7 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { supports_128bit_integers, supports_f16_type, supports_f32_type, + supports_f64_type, supports_f128_type, float_type, diff --git a/src/type_.rs b/src/type_.rs index eaa16c448970e..093ddbf8137c3 100644 --- a/src/type_.rs +++ b/src/type_.rs @@ -142,6 +142,10 @@ impl<'gcc, 'tcx> BaseTypeMethods<'tcx> for CodegenCx<'gcc, 'tcx> { } fn type_f64(&self) -> Type<'gcc> { + #[cfg(feature = "master")] + if self.supports_f64_type { + return self.context.new_c_type(CType::Float64); + } self.double_type } From eaacf0003cd3156c5afd4dd9ca35c5a0bdf6fa13 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 21 Jun 2024 17:02:31 +0200 Subject: [PATCH 268/892] CI: try to share setup code across actions --- src/tools/miri/.github/workflows/ci.yml | 87 +------------------ .../miri/.github/workflows/setup/action.yml | 52 +++++++++++ 2 files changed, 54 insertions(+), 85 deletions(-) create mode 100644 src/tools/miri/.github/workflows/setup/action.yml diff --git a/src/tools/miri/.github/workflows/ci.yml b/src/tools/miri/.github/workflows/ci.yml index 3bc4163ab5246..fc4e484fa3898 100644 --- a/src/tools/miri/.github/workflows/ci.yml +++ b/src/tools/miri/.github/workflows/ci.yml @@ -33,50 +33,7 @@ jobs: HOST_TARGET: ${{ matrix.host_target }} steps: - uses: actions/checkout@v4 - - - name: Show Rust version (stable toolchain) - run: | - rustup show - rustc -Vv - cargo -V - - # Cache the global cargo directory, but NOT the local `target` directory which - # we cannot reuse anyway when the nightly changes (and it grows quite large - # over time). - - name: Add cache for cargo - id: cache - uses: actions/cache@v4 - with: - path: | - # Taken from . - # Cache package/registry information - ~/.cargo/registry/index - ~/.cargo/registry/cache - ~/.cargo/git/db - # Cache installed binaries - ~/.cargo/bin - ~/.cargo/.crates.toml - ~/.cargo/.crates2.json - key: cargo-${{ runner.os }}-reset20240425-${{ hashFiles('**/Cargo.lock') }} - restore-keys: cargo-${{ runner.os }}-reset20240425 - - - name: Install tools - if: steps.cache.outputs.cache-hit != 'true' - run: cargo install -f rustup-toolchain-install-master hyperfine - - - name: Install miri toolchain - run: | - if [[ ${{ github.event_name }} == 'schedule' ]]; then - echo "Building against latest rustc git version" - git ls-remote https://github.com/rust-lang/rust/ HEAD | cut -f 1 > rust-version - fi - ./miri toolchain --host ${{ matrix.host_target }} - - - name: Show Rust version (miri toolchain) - run: | - rustup show - rustc -Vv - cargo -V + - uses: ./.github/workflows/setup # The `style` job only runs on Linux; this makes sure the Windows-host-specific # code is also covered by clippy. @@ -92,47 +49,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - # This is exactly duplicated from above. GHA is pretty terrible when it comes - # to avoiding code duplication. - - # Cache the global cargo directory, but NOT the local `target` directory which - # we cannot reuse anyway when the nightly changes (and it grows quite large - # over time). - - name: Add cache for cargo - id: cache - uses: actions/cache@v4 - with: - path: | - # Taken from . - # Cache package/registry information - ~/.cargo/registry/index - ~/.cargo/registry/cache - ~/.cargo/git/db - # Cache installed binaries - ~/.cargo/bin - ~/.cargo/.crates.toml - ~/.cargo/.crates2.json - key: cargo-${{ runner.os }}-reset20240331-${{ hashFiles('**/Cargo.lock') }} - restore-keys: cargo-${{ runner.os }}-reset20240331 - - - name: Install rustup-toolchain-install-master - if: steps.cache.outputs.cache-hit != 'true' - run: cargo install -f rustup-toolchain-install-master - - - name: Install "master" toolchain - run: | - if [[ ${{ github.event_name }} == 'schedule' ]]; then - echo "Building against latest rustc git version" - git ls-remote https://github.com/rust-lang/rust/ HEAD | cut -f 1 > rust-version - fi - ./miri toolchain - - - name: Show Rust version - run: | - rustup show - rustc -Vv - cargo -V + - uses: ./.github/workflows/setup - name: rustfmt run: ./miri fmt --check diff --git a/src/tools/miri/.github/workflows/setup/action.yml b/src/tools/miri/.github/workflows/setup/action.yml new file mode 100644 index 0000000000000..8f54b5b8d81a9 --- /dev/null +++ b/src/tools/miri/.github/workflows/setup/action.yml @@ -0,0 +1,52 @@ +name: "Miri CI setup" +description: "Sets up Miri CI" +runs: + using: "composite" + steps: + - name: Show Rust version (stable toolchain) + run: | + rustup show + rustc -Vv + cargo -V + shell: bash + + # Cache the global cargo directory, but NOT the local `target` directory which + # we cannot reuse anyway when the nightly changes (and it grows quite large + # over time). + - name: Add cache for cargo + id: cache + uses: actions/cache@v4 + with: + path: | + # Taken from . + # Cache package/registry information + ~/.cargo/registry/index + ~/.cargo/registry/cache + ~/.cargo/git/db + # Cache installed binaries + ~/.cargo/bin + ~/.cargo/.crates.toml + ~/.cargo/.crates2.json + key: cargo-${{ runner.os }}-${{ hashFiles('**/Cargo.lock', '.github/workflows/**/*.yml') }} + restore-keys: cargo-${{ runner.os }} + + - name: Install rustup-toolchain-install-master + if: steps.cache.outputs.cache-hit != 'true' + run: cargo install -f rustup-toolchain-install-master hyperfine + shell: bash + + - name: Install "master" toolchain + run: | + if [[ ${{ github.event_name }} == 'schedule' ]]; then + echo "Building against latest rustc git version" + git ls-remote https://github.com/rust-lang/rust/ HEAD | cut -f 1 > rust-version + fi + ./miri toolchain + shell: bash + + - name: Show Rust version (miri toolchain) + run: | + rustup show + rustc -Vv + cargo -V + shell: bash From 699b7d43c28b487b33acbc61510bf467e0dc2e6e Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 22 Jun 2024 15:04:45 +0200 Subject: [PATCH 269/892] ./miri: nicer error when building miri-script fails --- src/tools/miri/miri | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/tools/miri/miri b/src/tools/miri/miri index 5f71fc9443839..07383bb59ebcc 100755 --- a/src/tools/miri/miri +++ b/src/tools/miri/miri @@ -3,5 +3,6 @@ set -e # Instead of doing just `cargo run --manifest-path .. $@`, we invoke miri-script binary directly. Invoking `cargo run` goes through # rustup (that sets it's own environmental variables), which is undesirable. MIRI_SCRIPT_TARGET_DIR="$(dirname "$0")"/miri-script/target -cargo +stable build $CARGO_EXTRA_FLAGS -q --target-dir "$MIRI_SCRIPT_TARGET_DIR" --manifest-path "$(dirname "$0")"/miri-script/Cargo.toml +cargo +stable build $CARGO_EXTRA_FLAGS -q --target-dir "$MIRI_SCRIPT_TARGET_DIR" --manifest-path "$(dirname "$0")"/miri-script/Cargo.toml || \ + ( echo "Failed to build miri-script. Is the 'stable' toolchain installed?"; exit 1 ) "$MIRI_SCRIPT_TARGET_DIR"/debug/miri-script "$@" From dd2bd5bb7df300f655b596c287d6ca9eb642ff38 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 22 Jun 2024 17:02:38 +0200 Subject: [PATCH 270/892] evaluate arguments first, not inside the logic --- src/tools/miri/src/shims/x86/mod.rs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/tools/miri/src/shims/x86/mod.rs b/src/tools/miri/src/shims/x86/mod.rs index 7bccf71f04374..afaf59eaadbff 100644 --- a/src/tools/miri/src/shims/x86/mod.rs +++ b/src/tools/miri/src/shims/x86/mod.rs @@ -64,15 +64,20 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "addcarryx.u32" | "addcarryx.u64" => { this.expect_target_feature_for_intrinsic(link_name, "adx")?; - if unprefixed_name.ends_with("64") && this.tcx.sess.target.arch != "x86_64" { + let is_u64 = unprefixed_name.ends_with("64"); + if is_u64 && this.tcx.sess.target.arch != "x86_64" { return Ok(EmulateItemResult::NotSupported); } let [c_in, a, b, out] = this.check_shim(abi, Abi::Unadjusted, link_name, args)?; + let out = this.deref_pointer_as( + out, + if is_u64 { this.machine.layouts.u64 } else { this.machine.layouts.u32 }, + )?; let (sum, c_out) = carrying_add(this, c_in, a, b, mir::BinOp::AddWithOverflow)?; this.write_scalar(c_out, dest)?; - this.write_immediate(*sum, &this.deref_pointer_as(out, sum.layout)?)?; + this.write_immediate(*sum, &out)?; } // Used to implement the `_mm_pause` function. From 7b150a161e7c90cc067c1a709a63785b5dc2a5e9 Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Mon, 17 Jun 2024 20:16:53 +0200 Subject: [PATCH 271/892] Don't use fake wildcards when we can get the failure block directly This commit too was obtained by repeatedly inlining and simplifying. --- .../rustc_mir_build/src/build/matches/mod.rs | 109 +++++++------- .../issue_101867.main.built.after.mir | 21 +-- ...n_conditional.test_complex.built.after.mir | 138 ++++++++---------- 3 files changed, 125 insertions(+), 143 deletions(-) diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs index 8531ea891d2e3..3eacd598f66c2 100644 --- a/compiler/rustc_mir_build/src/build/matches/mod.rs +++ b/compiler/rustc_mir_build/src/build/matches/mod.rs @@ -329,6 +329,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { &scrutinee_place, match_start_span, &mut candidates, + false, ); self.lower_match_arms( @@ -691,6 +692,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { &initializer, irrefutable_pat.span, &mut [&mut candidate], + false, ); self.bind_pattern( self.source_info(irrefutable_pat.span), @@ -1215,6 +1217,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { /// /// Modifies `candidates` to store the bindings and type ascriptions for /// that candidate. + /// + /// `refutable` indicates whether the candidate list is refutable (for `if let` and `let else`) + /// or not (for `let` and `match`). In the refutable case we return the block to which we branch + /// on failure. fn lower_match_tree<'pat>( &mut self, block: BasicBlock, @@ -1222,45 +1228,14 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { scrutinee_place_builder: &PlaceBuilder<'tcx>, match_start_span: Span, candidates: &mut [&mut Candidate<'pat, 'tcx>], - ) { - // See the doc comment on `match_candidates` for why we have an - // otherwise block. Match checking will ensure this is actually - // unreachable. + refutable: bool, + ) -> BasicBlock { + // See the doc comment on `match_candidates` for why we have an otherwise block. let otherwise_block = self.cfg.start_new_block(); // This will generate code to test scrutinee_place and branch to the appropriate arm block self.match_candidates(match_start_span, scrutinee_span, block, otherwise_block, candidates); - let source_info = self.source_info(scrutinee_span); - - // Matching on a `scrutinee_place` with an uninhabited type doesn't - // generate any memory reads by itself, and so if the place "expression" - // contains unsafe operations like raw pointer dereferences or union - // field projections, we wouldn't know to require an `unsafe` block - // around a `match` equivalent to `std::intrinsics::unreachable()`. - // See issue #47412 for this hole being discovered in the wild. - // - // HACK(eddyb) Work around the above issue by adding a dummy inspection - // of `scrutinee_place`, specifically by applying `ReadForMatch`. - // - // NOTE: ReadForMatch also checks that the scrutinee is initialized. - // This is currently needed to not allow matching on an uninitialized, - // uninhabited value. If we get never patterns, those will check that - // the place is initialized, and so this read would only be used to - // check safety. - let cause_matched_place = FakeReadCause::ForMatchedPlace(None); - - if let Some(scrutinee_place) = scrutinee_place_builder.try_to_place(self) { - self.cfg.push_fake_read( - otherwise_block, - source_info, - cause_matched_place, - scrutinee_place, - ); - } - - self.cfg.terminate(otherwise_block, source_info, TerminatorKind::Unreachable); - // Link each leaf candidate to the `false_edge_start_block` of the next one. let mut previous_candidate: Option<&mut Candidate<'_, '_>> = None; for candidate in candidates { @@ -1272,6 +1247,46 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { previous_candidate = Some(leaf_candidate); }); } + + if refutable { + // In refutable cases there's always at least one candidate, and we want a false edge to + // the failure block. + previous_candidate.as_mut().unwrap().next_candidate_start_block = Some(otherwise_block) + } else { + // Match checking ensures `otherwise_block` is actually unreachable in irrefutable + // cases. + let source_info = self.source_info(scrutinee_span); + + // Matching on a `scrutinee_place` with an uninhabited type doesn't + // generate any memory reads by itself, and so if the place "expression" + // contains unsafe operations like raw pointer dereferences or union + // field projections, we wouldn't know to require an `unsafe` block + // around a `match` equivalent to `std::intrinsics::unreachable()`. + // See issue #47412 for this hole being discovered in the wild. + // + // HACK(eddyb) Work around the above issue by adding a dummy inspection + // of `scrutinee_place`, specifically by applying `ReadForMatch`. + // + // NOTE: ReadForMatch also checks that the scrutinee is initialized. + // This is currently needed to not allow matching on an uninitialized, + // uninhabited value. If we get never patterns, those will check that + // the place is initialized, and so this read would only be used to + // check safety. + let cause_matched_place = FakeReadCause::ForMatchedPlace(None); + + if let Some(scrutinee_place) = scrutinee_place_builder.try_to_place(self) { + self.cfg.push_fake_read( + otherwise_block, + source_info, + cause_matched_place, + scrutinee_place, + ); + } + + self.cfg.terminate(otherwise_block, source_info, TerminatorKind::Unreachable); + } + + otherwise_block } /// The main match algorithm. It begins with a set of candidates @@ -1978,21 +1993,18 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { ) -> BlockAnd<()> { let expr_span = self.thir[expr_id].span; let expr_place_builder = unpack!(block = self.lower_scrutinee(block, expr_id, expr_span)); - let wildcard = Pat::wildcard_from_ty(pat.ty); let mut guard_candidate = Candidate::new(expr_place_builder.clone(), pat, false, self); - let mut otherwise_candidate = - Candidate::new(expr_place_builder.clone(), &wildcard, false, self); - self.lower_match_tree( + let otherwise_block = self.lower_match_tree( block, pat.span, &expr_place_builder, pat.span, - &mut [&mut guard_candidate, &mut otherwise_candidate], + &mut [&mut guard_candidate], + true, ); let expr_place = expr_place_builder.try_to_place(self); let opt_expr_place = expr_place.as_ref().map(|place| (Some(place), expr_span)); - let otherwise_post_guard_block = otherwise_candidate.pre_binding_block.unwrap(); - self.break_for_else(otherwise_post_guard_block, self.source_info(expr_span)); + self.break_for_else(otherwise_block, self.source_info(expr_span)); if declare_bindings { self.declare_bindings(source_scope, pat.span.to(span), pat, None, opt_expr_place); @@ -2008,7 +2020,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { ); // If branch coverage is enabled, record this branch. - self.visit_coverage_conditional_let(pat, post_guard_block, otherwise_post_guard_block); + self.visit_coverage_conditional_let(pat, post_guard_block, otherwise_block); post_guard_block.unit() } @@ -2470,15 +2482,14 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let else_block_span = self.thir[else_block].span; let (matching, failure) = self.in_if_then_scope(*let_else_scope, else_block_span, |this| { let scrutinee = unpack!(block = this.lower_scrutinee(block, init_id, initializer_span)); - let pat = Pat { ty: pattern.ty, span: else_block_span, kind: PatKind::Wild }; - let mut wildcard = Candidate::new(scrutinee.clone(), &pat, false, this); let mut candidate = Candidate::new(scrutinee.clone(), pattern, false, this); - this.lower_match_tree( + let failure_block = this.lower_match_tree( block, initializer_span, &scrutinee, pattern.span, - &mut [&mut candidate, &mut wildcard], + &mut [&mut candidate], + true, ); // This block is for the matching case let matching = this.bind_pattern( @@ -2489,13 +2500,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { None, true, ); - // This block is for the failure case - let failure = wildcard.pre_binding_block.unwrap(); // If branch coverage is enabled, record this branch. - this.visit_coverage_conditional_let(pattern, matching, failure); + this.visit_coverage_conditional_let(pattern, matching, failure_block); - this.break_for_else(failure, this.source_info(initializer_span)); + this.break_for_else(failure_block, this.source_info(initializer_span)); matching.unit() }); matching.and(failure) diff --git a/tests/mir-opt/building/issue_101867.main.built.after.mir b/tests/mir-opt/building/issue_101867.main.built.after.mir index 0f7917dbb5cbf..5c50b3db5cad6 100644 --- a/tests/mir-opt/building/issue_101867.main.built.after.mir +++ b/tests/mir-opt/building/issue_101867.main.built.after.mir @@ -27,13 +27,13 @@ fn main() -> () { StorageLive(_5); PlaceMention(_1); _6 = discriminant(_1); - switchInt(move _6) -> [1: bb6, otherwise: bb4]; + switchInt(move _6) -> [1: bb4, otherwise: bb3]; } bb1: { StorageLive(_3); StorageLive(_4); - _4 = begin_panic::<&str>(const "explicit panic") -> bb10; + _4 = begin_panic::<&str>(const "explicit panic") -> bb8; } bb2: { @@ -43,12 +43,11 @@ fn main() -> () { } bb3: { - FakeRead(ForMatchedPlace(None), _1); - unreachable; + goto -> bb7; } bb4: { - goto -> bb9; + falseEdge -> [real: bb6, imaginary: bb3]; } bb5: { @@ -56,14 +55,6 @@ fn main() -> () { } bb6: { - falseEdge -> [real: bb8, imaginary: bb4]; - } - - bb7: { - goto -> bb4; - } - - bb8: { _5 = ((_1 as Some).0: u8); _0 = const (); StorageDead(_5); @@ -71,12 +62,12 @@ fn main() -> () { return; } - bb9: { + bb7: { StorageDead(_5); goto -> bb1; } - bb10 (cleanup): { + bb8 (cleanup): { resume; } } diff --git a/tests/mir-opt/building/logical_or_in_conditional.test_complex.built.after.mir b/tests/mir-opt/building/logical_or_in_conditional.test_complex.built.after.mir index fd8eb370ca958..3e16efe6980d9 100644 --- a/tests/mir-opt/building/logical_or_in_conditional.test_complex.built.after.mir +++ b/tests/mir-opt/building/logical_or_in_conditional.test_complex.built.after.mir @@ -19,22 +19,21 @@ fn test_complex() -> () { bb0: { StorageLive(_1); StorageLive(_2); - _2 = E::f() -> [return: bb1, unwind: bb38]; + _2 = E::f() -> [return: bb1, unwind: bb34]; } bb1: { PlaceMention(_2); _3 = discriminant(_2); - switchInt(move _3) -> [0: bb5, otherwise: bb3]; + switchInt(move _3) -> [0: bb3, otherwise: bb2]; } bb2: { - FakeRead(ForMatchedPlace(None), _2); - unreachable; + goto -> bb21; } bb3: { - goto -> bb23; + falseEdge -> [real: bb5, imaginary: bb2]; } bb4: { @@ -42,175 +41,158 @@ fn test_complex() -> () { } bb5: { - falseEdge -> [real: bb7, imaginary: bb3]; + StorageLive(_4); + _4 = always_true() -> [return: bb6, unwind: bb34]; } bb6: { - goto -> bb3; + switchInt(move _4) -> [0: bb8, otherwise: bb7]; } bb7: { - StorageLive(_4); - _4 = always_true() -> [return: bb8, unwind: bb38]; - } - - bb8: { - switchInt(move _4) -> [0: bb10, otherwise: bb9]; - } - - bb9: { StorageLive(_5); StorageLive(_6); StorageLive(_7); _7 = Droppy(const 0_u8); _6 = (_7.0: u8); _5 = Gt(move _6, const 0_u8); - switchInt(move _5) -> [0: bb12, otherwise: bb11]; + switchInt(move _5) -> [0: bb10, otherwise: bb9]; } - bb10: { - goto -> bb16; + bb8: { + goto -> bb14; } - bb11: { - drop(_7) -> [return: bb13, unwind: bb38]; + bb9: { + drop(_7) -> [return: bb11, unwind: bb34]; } - bb12: { - goto -> bb14; + bb10: { + goto -> bb12; } - bb13: { + bb11: { StorageDead(_7); StorageDead(_6); - goto -> bb20; + goto -> bb18; } - bb14: { - drop(_7) -> [return: bb15, unwind: bb38]; + bb12: { + drop(_7) -> [return: bb13, unwind: bb34]; } - bb15: { + bb13: { StorageDead(_7); StorageDead(_6); - goto -> bb16; + goto -> bb14; } - bb16: { + bb14: { StorageLive(_8); StorageLive(_9); StorageLive(_10); _10 = Droppy(const 1_u8); _9 = (_10.0: u8); _8 = Gt(move _9, const 1_u8); - switchInt(move _8) -> [0: bb18, otherwise: bb17]; + switchInt(move _8) -> [0: bb16, otherwise: bb15]; } - bb17: { - drop(_10) -> [return: bb19, unwind: bb38]; + bb15: { + drop(_10) -> [return: bb17, unwind: bb34]; } - bb18: { - goto -> bb21; + bb16: { + goto -> bb19; } - bb19: { + bb17: { StorageDead(_10); StorageDead(_9); - goto -> bb20; + goto -> bb18; } - bb20: { + bb18: { _1 = const (); - goto -> bb24; + goto -> bb22; } - bb21: { - drop(_10) -> [return: bb22, unwind: bb38]; + bb19: { + drop(_10) -> [return: bb20, unwind: bb34]; } - bb22: { + bb20: { StorageDead(_10); StorageDead(_9); - goto -> bb23; + goto -> bb21; } - bb23: { + bb21: { _1 = const (); - goto -> bb24; + goto -> bb22; } - bb24: { + bb22: { StorageDead(_8); StorageDead(_5); StorageDead(_4); StorageDead(_2); StorageDead(_1); StorageLive(_11); - _11 = always_true() -> [return: bb25, unwind: bb38]; + _11 = always_true() -> [return: bb23, unwind: bb34]; } - bb25: { - switchInt(move _11) -> [0: bb27, otherwise: bb26]; + bb23: { + switchInt(move _11) -> [0: bb25, otherwise: bb24]; } - bb26: { - goto -> bb36; + bb24: { + goto -> bb32; } - bb27: { - goto -> bb28; + bb25: { + goto -> bb26; } - bb28: { + bb26: { StorageLive(_12); - _12 = E::f() -> [return: bb29, unwind: bb38]; + _12 = E::f() -> [return: bb27, unwind: bb34]; } - bb29: { + bb27: { PlaceMention(_12); _13 = discriminant(_12); - switchInt(move _13) -> [1: bb33, otherwise: bb31]; - } - - bb30: { - FakeRead(ForMatchedPlace(None), _12); - unreachable; + switchInt(move _13) -> [1: bb29, otherwise: bb28]; } - bb31: { - goto -> bb36; - } - - bb32: { - goto -> bb30; + bb28: { + goto -> bb32; } - bb33: { - falseEdge -> [real: bb35, imaginary: bb31]; + bb29: { + falseEdge -> [real: bb31, imaginary: bb28]; } - bb34: { - goto -> bb31; + bb30: { + goto -> bb28; } - bb35: { + bb31: { _0 = const (); - goto -> bb37; + goto -> bb33; } - bb36: { + bb32: { _0 = const (); - goto -> bb37; + goto -> bb33; } - bb37: { + bb33: { StorageDead(_11); StorageDead(_12); return; } - bb38 (cleanup): { + bb34 (cleanup): { resume; } } From ff49c3769b0ec5b1abc628e55c7547e765086e6a Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Mon, 17 Jun 2024 20:51:35 +0200 Subject: [PATCH 272/892] Reuse `lower_let_expr` for `let .. else` lowering --- compiler/rustc_mir_build/src/build/block.rs | 63 ++++++++-------- .../rustc_mir_build/src/build/matches/mod.rs | 73 +++++-------------- 2 files changed, 49 insertions(+), 87 deletions(-) diff --git a/compiler/rustc_mir_build/src/build/block.rs b/compiler/rustc_mir_build/src/build/block.rs index c1d645aa42cb8..476969a1bd7ad 100644 --- a/compiler/rustc_mir_build/src/build/block.rs +++ b/compiler/rustc_mir_build/src/build/block.rs @@ -189,38 +189,37 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let initializer_span = this.thir[*initializer].span; let scope = (*init_scope, source_info); - let failure = unpack!( - block = this.in_scope(scope, *lint_level, |this| { - this.declare_bindings( - visibility_scope, - remainder_span, - pattern, - None, - Some((Some(&destination), initializer_span)), - ); - this.visit_primary_bindings( - pattern, - UserTypeProjections::none(), - &mut |this, _, _, node, span, _, _| { - this.storage_live_binding( - block, - node, - span, - OutsideGuard, - true, - ); - }, - ); - this.ast_let_else( - block, - *initializer, - initializer_span, - *else_block, - &last_remainder_scope, - pattern, - ) - }) - ); + let failure_and_block = this.in_scope(scope, *lint_level, |this| { + this.declare_bindings( + visibility_scope, + remainder_span, + pattern, + None, + Some((Some(&destination), initializer_span)), + ); + this.visit_primary_bindings( + pattern, + UserTypeProjections::none(), + &mut |this, _, _, node, span, _, _| { + this.storage_live_binding(block, node, span, OutsideGuard, true); + }, + ); + let else_block_span = this.thir[*else_block].span; + let (matching, failure) = + this.in_if_then_scope(last_remainder_scope, else_block_span, |this| { + this.lower_let_expr( + block, + *initializer, + pattern, + None, + initializer_span, + false, + true, + ) + }); + matching.and(failure) + }); + let failure = unpack!(block = failure_and_block); this.cfg.goto(failure, source_info, failure_entry); if let Some(source_scope) = visibility_scope { diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs index 3eacd598f66c2..f9333a165cef1 100644 --- a/compiler/rustc_mir_build/src/build/matches/mod.rs +++ b/compiler/rustc_mir_build/src/build/matches/mod.rs @@ -147,6 +147,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { Some(args.variable_source_info.scope), args.variable_source_info.span, args.declare_let_bindings, + false, ), _ => { let mut block = block; @@ -1981,48 +1982,50 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { impl<'a, 'tcx> Builder<'a, 'tcx> { /// If the bindings have already been declared, set `declare_bindings` to - /// `false` to avoid duplicated bindings declaration. Used for if-let guards. + /// `false` to avoid duplicated bindings declaration; used for if-let guards. pub(crate) fn lower_let_expr( &mut self, mut block: BasicBlock, expr_id: ExprId, pat: &Pat<'tcx>, source_scope: Option, - span: Span, + scope_span: Span, declare_bindings: bool, + storages_alive: bool, ) -> BlockAnd<()> { let expr_span = self.thir[expr_id].span; - let expr_place_builder = unpack!(block = self.lower_scrutinee(block, expr_id, expr_span)); - let mut guard_candidate = Candidate::new(expr_place_builder.clone(), pat, false, self); + let scrutinee = unpack!(block = self.lower_scrutinee(block, expr_id, expr_span)); + let mut candidate = Candidate::new(scrutinee.clone(), pat, false, self); let otherwise_block = self.lower_match_tree( block, + expr_span, + &scrutinee, pat.span, - &expr_place_builder, - pat.span, - &mut [&mut guard_candidate], + &mut [&mut candidate], true, ); - let expr_place = expr_place_builder.try_to_place(self); - let opt_expr_place = expr_place.as_ref().map(|place| (Some(place), expr_span)); + self.break_for_else(otherwise_block, self.source_info(expr_span)); if declare_bindings { - self.declare_bindings(source_scope, pat.span.to(span), pat, None, opt_expr_place); + let expr_place = scrutinee.try_to_place(self); + let opt_expr_place = expr_place.as_ref().map(|place| (Some(place), expr_span)); + self.declare_bindings(source_scope, pat.span.to(scope_span), pat, None, opt_expr_place); } - let post_guard_block = self.bind_pattern( + let success = self.bind_pattern( self.source_info(pat.span), - guard_candidate, + candidate, &[], expr_span, None, - false, + storages_alive, ); // If branch coverage is enabled, record this branch. - self.visit_coverage_conditional_let(pat, post_guard_block, otherwise_block); + self.visit_coverage_conditional_let(pat, success, otherwise_block); - post_guard_block.unit() + success.unit() } /// Initializes each of the bindings from the candidate by @@ -2469,44 +2472,4 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { debug!(?locals); self.var_indices.insert(var_id, locals); } - - pub(crate) fn ast_let_else( - &mut self, - mut block: BasicBlock, - init_id: ExprId, - initializer_span: Span, - else_block: BlockId, - let_else_scope: ®ion::Scope, - pattern: &Pat<'tcx>, - ) -> BlockAnd { - let else_block_span = self.thir[else_block].span; - let (matching, failure) = self.in_if_then_scope(*let_else_scope, else_block_span, |this| { - let scrutinee = unpack!(block = this.lower_scrutinee(block, init_id, initializer_span)); - let mut candidate = Candidate::new(scrutinee.clone(), pattern, false, this); - let failure_block = this.lower_match_tree( - block, - initializer_span, - &scrutinee, - pattern.span, - &mut [&mut candidate], - true, - ); - // This block is for the matching case - let matching = this.bind_pattern( - this.source_info(pattern.span), - candidate, - &[], - initializer_span, - None, - true, - ); - - // If branch coverage is enabled, record this branch. - this.visit_coverage_conditional_let(pattern, matching, failure_block); - - this.break_for_else(failure_block, this.source_info(initializer_span)); - matching.unit() - }); - matching.and(failure) - } } From beb1d35d7d63d331089620c60d591bab7e6495a5 Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Sat, 22 Jun 2024 18:21:03 +0200 Subject: [PATCH 273/892] Change comment to reflect switch to THIR unsafeck --- .../rustc_mir_build/src/build/matches/mod.rs | 24 ++++++++----------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs index f9333a165cef1..a92272c9809a2 100644 --- a/compiler/rustc_mir_build/src/build/matches/mod.rs +++ b/compiler/rustc_mir_build/src/build/matches/mod.rs @@ -1258,21 +1258,17 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // cases. let source_info = self.source_info(scrutinee_span); - // Matching on a `scrutinee_place` with an uninhabited type doesn't - // generate any memory reads by itself, and so if the place "expression" - // contains unsafe operations like raw pointer dereferences or union - // field projections, we wouldn't know to require an `unsafe` block - // around a `match` equivalent to `std::intrinsics::unreachable()`. - // See issue #47412 for this hole being discovered in the wild. - // - // HACK(eddyb) Work around the above issue by adding a dummy inspection - // of `scrutinee_place`, specifically by applying `ReadForMatch`. + // Matching on a scrutinee place of an uninhabited type doesn't generate any memory + // reads by itself, and so if the place is uninitialized we wouldn't know. In order to + // disallow the following: + // ```rust + // let x: !; + // match x {} + // ``` + // we add a dummy read on the place. // - // NOTE: ReadForMatch also checks that the scrutinee is initialized. - // This is currently needed to not allow matching on an uninitialized, - // uninhabited value. If we get never patterns, those will check that - // the place is initialized, and so this read would only be used to - // check safety. + // NOTE: If we require never patterns for empty matches, those will check that the place + // is initialized, and so this read would no longer be needed. let cause_matched_place = FakeReadCause::ForMatchedPlace(None); if let Some(scrutinee_place) = scrutinee_place_builder.try_to_place(self) { From 22bbff1c61ee32fd8621557b1cebcc4b39261f5f Mon Sep 17 00:00:00 2001 From: Ross Smyth <18294397+RossSmyth@users.noreply.github.com> Date: Sat, 22 Jun 2024 23:28:05 -0400 Subject: [PATCH 274/892] nicer batch file error when building miri-script fails --- src/tools/miri/miri.bat | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/tools/miri/miri.bat b/src/tools/miri/miri.bat index 18baa683f6517..98b59a56a0db4 100644 --- a/src/tools/miri/miri.bat +++ b/src/tools/miri/miri.bat @@ -5,7 +5,8 @@ set MIRI_SCRIPT_TARGET_DIR=%0\..\miri-script\target :: If any other steps are added, the "|| exit /b" must be appended to early :: return from the script. If not, it will continue execution. -cargo +stable build %CARGO_EXTRA_FLAGS% -q --target-dir %MIRI_SCRIPT_TARGET_DIR% --manifest-path %0\..\miri-script\Cargo.toml || exit /b +cargo +stable build %CARGO_EXTRA_FLAGS% -q --target-dir %MIRI_SCRIPT_TARGET_DIR% --manifest-path %0\..\miri-script\Cargo.toml ^ + || echo Failed to build miri-script. Is the 'stable' toolchain installed? & exit /b :: Forwards all arguments to this file to the executable. :: We invoke the binary directly to avoid going through rustup, which would set some extra From f91411b5ff5335601aa5acde43302ddfce8d4b82 Mon Sep 17 00:00:00 2001 From: The Miri Cronjob Bot Date: Sun, 23 Jun 2024 04:54:11 +0000 Subject: [PATCH 275/892] 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 1502fa120be65..97d37b0ebe596 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version @@ -1 +1 @@ -7a08f84627ff3035de4d66ff3209e5fc93165dcb +acb62737aca7045f331e7a05adc38bed213e278d From d73be701390c07ed99648404c08099420c38ca90 Mon Sep 17 00:00:00 2001 From: The Miri Cronjob Bot Date: Sun, 23 Jun 2024 05:02:48 +0000 Subject: [PATCH 276/892] fmt --- src/tools/miri/src/concurrency/thread.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/tools/miri/src/concurrency/thread.rs b/src/tools/miri/src/concurrency/thread.rs index 6a2b99825adc4..718daf93ea007 100644 --- a/src/tools/miri/src/concurrency/thread.rs +++ b/src/tools/miri/src/concurrency/thread.rs @@ -643,8 +643,7 @@ impl<'tcx> ThreadManager<'tcx> { if !self.threads[joined_thread_id].state.is_terminated() { trace!( "{:?} blocked on {:?} when trying to join", - self.active_thread, - joined_thread_id + self.active_thread, joined_thread_id ); // The joined thread is still running, we need to wait for it. // Unce we get unblocked, perform the appropriate synchronization. From 903a424ae2f9d1fc2c36718f71aa665c9507850a Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 23 Jun 2024 08:41:18 +0200 Subject: [PATCH 277/892] unix/foreign_items: move getpid to the right part of the file --- src/tools/miri/src/shims/unix/foreign_items.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/tools/miri/src/shims/unix/foreign_items.rs b/src/tools/miri/src/shims/unix/foreign_items.rs index 2282099fa0d23..53ad40cfd2ccc 100644 --- a/src/tools/miri/src/shims/unix/foreign_items.rs +++ b/src/tools/miri/src/shims/unix/foreign_items.rs @@ -51,7 +51,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // See `fn emulate_foreign_item_inner` in `shims/foreign_items.rs` for the general pattern. #[rustfmt::skip] match link_name.as_str() { - // Environment variables + // Environment related shims "getenv" => { let [name] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; let result = this.getenv(name)?; @@ -78,6 +78,11 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let result = this.chdir(path)?; this.write_scalar(Scalar::from_i32(result), dest)?; } + "getpid" => { + let [] = this.check_shim(abi, Abi::C { unwind: false}, link_name, args)?; + let result = this.getpid()?; + this.write_scalar(Scalar::from_i32(result), dest)?; + } // File descriptors "read" => { @@ -583,11 +588,6 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let ret = if complete { 0 } else { this.eval_libc_i32("ERANGE") }; this.write_int(ret, dest)?; } - "getpid" => { - let [] = this.check_shim(abi, Abi::C { unwind: false}, link_name, args)?; - let result = this.getpid()?; - this.write_scalar(Scalar::from_i32(result), dest)?; - } "getentropy" => { // This function is non-standard but exists with the same signature and behavior on // Linux, macOS, FreeBSD and Solaris/Illumos. From f1052eb253580ce2adbcc7a24b15e291e4f0c760 Mon Sep 17 00:00:00 2001 From: Jubilee Young Date: Sat, 4 May 2024 16:47:18 -0700 Subject: [PATCH 278/892] cg_clif: Define build opts from FramePointer --- src/lib.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 2edb34e7c20dc..06ca52b390320 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -271,9 +271,9 @@ fn build_isa(sess: &Session, backend_config: &BackendConfig) -> Arc Date: Sun, 23 Jun 2024 17:04:01 +0200 Subject: [PATCH 279/892] use short message format in integration test --- tests/integration.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/integration.rs b/tests/integration.rs index 7f4500826ff6c..19c5f3a41339e 100644 --- a/tests/integration.rs +++ b/tests/integration.rs @@ -55,6 +55,7 @@ fn integration_test() { "clippy", "--all-targets", "--all-features", + "--message-format=short", "--", "--cap-lints", "warn", From 2194304b057cc0ae66a9b225565e4cb9844d6269 Mon Sep 17 00:00:00 2001 From: Alex Macleod Date: Sat, 22 Jun 2024 12:33:51 +0000 Subject: [PATCH 280/892] Cache lintcheck binary in ci --- .github/workflows/lintcheck.yml | 85 ++++++++++++++++--------------- lintcheck/src/main.rs | 88 +++++++++++++-------------------- 2 files changed, 77 insertions(+), 96 deletions(-) diff --git a/.github/workflows/lintcheck.yml b/.github/workflows/lintcheck.yml index 0816e5334e20f..91c98b3a2560c 100644 --- a/.github/workflows/lintcheck.yml +++ b/.github/workflows/lintcheck.yml @@ -12,13 +12,10 @@ concurrency: cancel-in-progress: true jobs: - # Generates `lintcheck-logs/base.json` and stores it in a cache + # Runs lintcheck on the PR's target branch and stores the results as an artifact base: runs-on: ubuntu-latest - outputs: - key: ${{ steps.key.outputs.key }} - steps: - name: Checkout uses: actions/checkout@v4 @@ -37,57 +34,67 @@ jobs: rm -rf lintcheck git checkout ${{ github.sha }} -- lintcheck + - name: Cache lintcheck bin + id: cache-lintcheck-bin + uses: actions/cache@v4 + with: + path: target/debug/lintcheck + key: lintcheck-bin-${{ hashfiles('lintcheck/**') }} + + - name: Build lintcheck + if: steps.cache-lintcheck-bin.outputs.cache-hit != 'true' + run: cargo build --manifest-path=lintcheck/Cargo.toml + - name: Create cache key id: key run: echo "key=lintcheck-base-${{ hashfiles('lintcheck/**') }}-$(git rev-parse HEAD)" >> "$GITHUB_OUTPUT" - - name: Cache results - id: cache + - name: Cache results JSON + id: cache-json uses: actions/cache@v4 with: - path: lintcheck-logs/base.json + path: lintcheck-logs/lintcheck_crates_logs.json key: ${{ steps.key.outputs.key }} - name: Run lintcheck - if: steps.cache.outputs.cache-hit != 'true' - run: cargo lintcheck --format json + if: steps.cache-json.outputs.cache-hit != 'true' + run: ./target/debug/lintcheck --format json - - name: Rename JSON file - if: steps.cache.outputs.cache-hit != 'true' - run: mv lintcheck-logs/lintcheck_crates_logs.json lintcheck-logs/base.json + - name: Upload base JSON + uses: actions/upload-artifact@v4 + with: + name: base + path: lintcheck-logs/lintcheck_crates_logs.json - # Generates `lintcheck-logs/head.json` and stores it in a cache + # Runs lintcheck on the PR and stores the results as an artifact head: runs-on: ubuntu-latest - outputs: - key: ${{ steps.key.outputs.key }} - steps: - name: Checkout uses: actions/checkout@v4 - - name: Create cache key - id: key - run: echo "key=lintcheck-head-${{ github.sha }}" >> "$GITHUB_OUTPUT" - - - name: Cache results - id: cache + - name: Cache lintcheck bin + id: cache-lintcheck-bin uses: actions/cache@v4 with: - path: lintcheck-logs/head.json - key: ${{ steps.key.outputs.key }} + path: target/debug/lintcheck + key: lintcheck-bin-${{ hashfiles('lintcheck/**') }} + + - name: Build lintcheck + if: steps.cache-lintcheck-bin.outputs.cache-hit != 'true' + run: cargo build --manifest-path=lintcheck/Cargo.toml - name: Run lintcheck - if: steps.cache.outputs.cache-hit != 'true' - run: cargo lintcheck --format json + run: ./target/debug/lintcheck --format json - - name: Rename JSON file - if: steps.cache.outputs.cache-hit != 'true' - run: mv lintcheck-logs/lintcheck_crates_logs.json lintcheck-logs/head.json + - name: Upload head JSON + uses: actions/upload-artifact@v4 + with: + name: head + path: lintcheck-logs/lintcheck_crates_logs.json - # Retrieves `lintcheck-logs/base.json` and `lintcheck-logs/head.json` from the cache and prints - # the diff to the GH actions step summary + # Retrieves the head and base JSON results and prints the diff to the GH actions step summary diff: runs-on: ubuntu-latest @@ -97,19 +104,15 @@ jobs: - name: Checkout uses: actions/checkout@v4 - - name: Restore base JSON + - name: Restore lintcheck bin uses: actions/cache/restore@v4 with: - key: ${{ needs.base.outputs.key }} - path: lintcheck-logs/base.json + path: target/debug/lintcheck + key: lintcheck-bin-${{ hashfiles('lintcheck/**') }} fail-on-cache-miss: true - - name: Restore head JSON - uses: actions/cache/restore@v4 - with: - key: ${{ needs.head.outputs.key }} - path: lintcheck-logs/head.json - fail-on-cache-miss: true + - name: Download JSON + uses: actions/download-artifact@v4 - name: Diff results - run: cargo lintcheck diff lintcheck-logs/base.json lintcheck-logs/head.json >> $GITHUB_STEP_SUMMARY + run: ./target/debug/lintcheck diff {base,head}/lintcheck_crates_logs.json >> $GITHUB_STEP_SUMMARY diff --git a/lintcheck/src/main.rs b/lintcheck/src/main.rs index c246883c7045f..8dd6e95bb7deb 100644 --- a/lintcheck/src/main.rs +++ b/lintcheck/src/main.rs @@ -29,7 +29,7 @@ use std::fmt::{self, Display, Write as _}; use std::hash::Hash; use std::io::{self, ErrorKind}; use std::path::{Path, PathBuf}; -use std::process::{Command, ExitStatus}; +use std::process::{Command, ExitStatus, Stdio}; use std::sync::atomic::{AtomicUsize, Ordering}; use std::time::Duration; use std::{env, fs, thread}; @@ -348,7 +348,6 @@ impl Crate { #[allow(clippy::too_many_arguments, clippy::too_many_lines)] fn run_clippy_lints( &self, - cargo_clippy_path: &Path, clippy_driver_path: &Path, target_dir_index: &AtomicUsize, total_crates_to_lint: usize, @@ -374,25 +373,17 @@ impl Crate { ); } - let cargo_clippy_path = fs::canonicalize(cargo_clippy_path).unwrap(); - let shared_target_dir = clippy_project_root().join("target/lintcheck/shared_target_dir"); - let mut cargo_clippy_args = if config.fix { - vec!["--quiet", "--fix", "--"] - } else { - vec!["--quiet", "--message-format=json", "--"] - }; - let cargo_home = env!("CARGO_HOME"); // `src/lib.rs` -> `target/lintcheck/sources/crate-1.2.3/src/lib.rs` let remap_relative = format!("={}", self.path.display()); // Fallback for other sources, `~/.cargo/...` -> `$CARGO_HOME/...` let remap_cargo_home = format!("{cargo_home}=$CARGO_HOME"); - // `~/.cargo/registry/src/github.com-1ecc6299db9ec823/crate-2.3.4/src/lib.rs` + // `~/.cargo/registry/src/index.crates.io-6f17d22bba15001f/crate-2.3.4/src/lib.rs` // -> `crate-2.3.4/src/lib.rs` - let remap_crates_io = format!("{cargo_home}/registry/src/github.com-1ecc6299db9ec823/="); + let remap_crates_io = format!("{cargo_home}/registry/src/index.crates.io-6f17d22bba15001f/="); let mut clippy_args = vec![ "--remap-path-prefix", @@ -418,23 +409,23 @@ impl Crate { clippy_args.extend(lint_filter.iter().map(String::as_str)); } - if let Some(server) = server { - let target = shared_target_dir.join("recursive"); + let mut cmd = Command::new("cargo"); + cmd.arg(if config.fix { "fix" } else { "check" }) + .arg("--quiet") + .current_dir(&self.path) + .env("CLIPPY_ARGS", clippy_args.join("__CLIPPY_HACKERY__")); + if let Some(server) = server { // `cargo clippy` is a wrapper around `cargo check` that mainly sets `RUSTC_WORKSPACE_WRAPPER` to // `clippy-driver`. We do the same thing here with a couple changes: // // `RUSTC_WRAPPER` is used instead of `RUSTC_WORKSPACE_WRAPPER` so that we can lint all crate // dependencies rather than only workspace members // - // The wrapper is set to the `lintcheck` so we can force enable linting and ignore certain crates + // The wrapper is set to `lintcheck` itself so we can force enable linting and ignore certain crates // (see `crate::driver`) - let status = Command::new(env::var("CARGO").unwrap_or("cargo".into())) - .arg("check") - .arg("--quiet") - .current_dir(&self.path) - .env("CLIPPY_ARGS", clippy_args.join("__CLIPPY_HACKERY__")) - .env("CARGO_TARGET_DIR", target) + let status = cmd + .env("CARGO_TARGET_DIR", shared_target_dir.join("recursive")) .env("RUSTC_WRAPPER", env::current_exe().unwrap()) // Pass the absolute path so `crate::driver` can find `clippy-driver`, as it's executed in various // different working directories @@ -446,23 +437,19 @@ impl Crate { assert_eq!(status.code(), Some(0)); return Vec::new(); - } + }; - cargo_clippy_args.extend(clippy_args); + if !config.fix { + cmd.arg("--message-format=json"); + } - let all_output = Command::new(&cargo_clippy_path) + let all_output = cmd // use the looping index to create individual target dirs .env("CARGO_TARGET_DIR", shared_target_dir.join(format!("_{thread_index:?}"))) - .args(&cargo_clippy_args) - .current_dir(&self.path) + // Roughly equivalent to `cargo clippy`/`cargo clippy --fix` + .env("RUSTC_WORKSPACE_WRAPPER", clippy_driver_path) .output() - .unwrap_or_else(|error| { - panic!( - "Encountered error:\n{error:?}\ncargo_clippy_path: {}\ncrate path:{}\n", - &cargo_clippy_path.display(), - &self.path.display() - ); - }); + .unwrap(); let stdout = String::from_utf8_lossy(&all_output.stdout); let stderr = String::from_utf8_lossy(&all_output.stderr); let status = &all_output.status; @@ -509,15 +496,17 @@ impl Crate { } /// Builds clippy inside the repo to make sure we have a clippy executable we can use. -fn build_clippy() { - let status = Command::new(env::var("CARGO").unwrap_or("cargo".into())) - .arg("build") - .status() - .expect("Failed to build clippy!"); - if !status.success() { +fn build_clippy() -> String { + let output = Command::new("cargo") + .args(["run", "--bin=clippy-driver", "--", "--version"]) + .stderr(Stdio::inherit()) + .output() + .unwrap(); + if !output.status.success() { eprintln!("Error: Failed to compile Clippy!"); std::process::exit(1); } + String::from_utf8_lossy(&output.stdout).into_owned() } /// Read a `lintcheck_crates.toml` file @@ -633,26 +622,16 @@ fn main() { #[allow(clippy::too_many_lines)] fn lintcheck(config: LintcheckConfig) { - println!("Compiling clippy..."); - build_clippy(); - println!("Done compiling"); - - let cargo_clippy_path = fs::canonicalize(format!("target/debug/cargo-clippy{EXE_SUFFIX}")).unwrap(); + let clippy_ver = build_clippy(); let clippy_driver_path = fs::canonicalize(format!("target/debug/clippy-driver{EXE_SUFFIX}")).unwrap(); // assert that clippy is found assert!( - cargo_clippy_path.is_file(), - "target/debug/cargo-clippy binary not found! {}", - cargo_clippy_path.display() + clippy_driver_path.is_file(), + "target/debug/clippy-driver binary not found! {}", + clippy_driver_path.display() ); - let clippy_ver = Command::new(&cargo_clippy_path) - .arg("--version") - .output() - .map(|o| String::from_utf8_lossy(&o.stdout).into_owned()) - .expect("could not get clippy version!"); - // download and extract the crates, then run clippy on them and collect clippy's warnings // flatten into one big list of warnings @@ -715,7 +694,6 @@ fn lintcheck(config: LintcheckConfig) { .par_iter() .flat_map(|krate| { krate.run_clippy_lints( - &cargo_clippy_path, &clippy_driver_path, &counter, crates.len(), @@ -914,7 +892,7 @@ fn lintcheck_test() { "--crates-toml", "lintcheck/test_sources.toml", ]; - let status = Command::new(env::var("CARGO").unwrap_or("cargo".into())) + let status = Command::new("cargo") .args(args) .current_dir("..") // repo root .status(); From 5f37433b6cf063cc97356cb791b6f0eeb9200dff Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Sun, 23 Jun 2024 14:14:00 -0700 Subject: [PATCH 281/892] Add test of parenthesizing break value by AST pretty-printer --- tests/ui/unpretty/expanded-interpolation.rs | 20 +++++++++++++++++++ .../ui/unpretty/expanded-interpolation.stdout | 13 ++++++++++++ 2 files changed, 33 insertions(+) diff --git a/tests/ui/unpretty/expanded-interpolation.rs b/tests/ui/unpretty/expanded-interpolation.rs index 8f0e21ce870d3..1dc72c67f511e 100644 --- a/tests/ui/unpretty/expanded-interpolation.rs +++ b/tests/ui/unpretty/expanded-interpolation.rs @@ -18,6 +18,26 @@ macro_rules! stmt { ($stmt:stmt) => { $stmt }; } +fn break_labeled_loop() { + let no_paren = 'outer: loop { + break 'outer expr!('inner: loop { break 'inner 1; } + 1); + }; + + let paren_around_break_value = 'outer: loop { + break expr!('inner: loop { break 'inner 1; } + 1); + }; + + macro_rules! breaking { + ($value:expr) => { + break $value + }; + } + + let paren_around_break_value = loop { + breaking!('inner: loop { break 'inner 1; } + 1); + }; +} + fn if_let() { macro_rules! if_let { ($pat:pat, $expr:expr) => { diff --git a/tests/ui/unpretty/expanded-interpolation.stdout b/tests/ui/unpretty/expanded-interpolation.stdout index 73322b50f2d6e..ed075c9114ce6 100644 --- a/tests/ui/unpretty/expanded-interpolation.stdout +++ b/tests/ui/unpretty/expanded-interpolation.stdout @@ -20,6 +20,19 @@ macro_rules! expr { ($expr:expr) => { $expr }; } macro_rules! stmt { ($stmt:stmt) => { $stmt }; } +fn break_labeled_loop() { + let no_paren = + 'outer: loop { break 'outer 'inner: loop { break 'inner 1; } + 1; }; + + let paren_around_break_value = + 'outer: loop { break 'inner: loop { break 'inner 1; } + 1; }; + + macro_rules! breaking { ($value:expr) => { break $value }; } + + let paren_around_break_value = + loop { break 'inner: loop { break 'inner 1; } + 1; }; +} + fn if_let() { macro_rules! if_let { ($pat:pat, $expr:expr) => { if let $pat = $expr {} }; From 35ec4eb354c8bbbd97363228a03b5582c9ee4a65 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Sun, 23 Jun 2024 18:30:13 -0700 Subject: [PATCH 282/892] Rename the 2 unambiguous precedence levels to PREC_UNAMBIGUOUS --- clippy_lints/src/dereference.rs | 6 +++--- clippy_lints/src/matches/manual_utils.rs | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/clippy_lints/src/dereference.rs b/clippy_lints/src/dereference.rs index d60320d828253..f451758c33507 100644 --- a/clippy_lints/src/dereference.rs +++ b/clippy_lints/src/dereference.rs @@ -6,7 +6,7 @@ use clippy_utils::{ expr_use_ctxt, get_parent_expr, is_block_like, is_lint_allowed, path_to_local, DefinedTy, ExprUseNode, }; use core::mem; -use rustc_ast::util::parser::{PREC_POSTFIX, PREC_PREFIX}; +use rustc_ast::util::parser::{PREC_UNAMBIGUOUS, PREC_PREFIX}; use rustc_data_structures::fx::FxIndexMap; use rustc_errors::Applicability; use rustc_hir::intravisit::{walk_ty, Visitor}; @@ -1013,7 +1013,7 @@ fn report<'tcx>( let (precedence, calls_field) = match cx.tcx.parent_hir_node(data.first_expr.hir_id) { Node::Expr(e) => match e.kind { ExprKind::Call(callee, _) if callee.hir_id != data.first_expr.hir_id => (0, false), - ExprKind::Call(..) => (PREC_POSTFIX, matches!(expr.kind, ExprKind::Field(..))), + ExprKind::Call(..) => (PREC_UNAMBIGUOUS, matches!(expr.kind, ExprKind::Field(..))), _ => (e.precedence().order(), false), }, _ => (0, false), @@ -1160,7 +1160,7 @@ impl<'tcx> Dereferencing<'tcx> { }, Some(parent) if !parent.span.from_expansion() => { // Double reference might be needed at this point. - if parent.precedence().order() == PREC_POSTFIX { + if parent.precedence().order() == PREC_UNAMBIGUOUS { // Parentheses would be needed here, don't lint. *outer_pat = None; } else { diff --git a/clippy_lints/src/matches/manual_utils.rs b/clippy_lints/src/matches/manual_utils.rs index 183caab56c59a..be80aebed6dfb 100644 --- a/clippy_lints/src/matches/manual_utils.rs +++ b/clippy_lints/src/matches/manual_utils.rs @@ -7,7 +7,7 @@ use clippy_utils::{ can_move_expr_to_closure, is_else_clause, is_lint_allowed, is_res_lang_ctor, path_res, path_to_local_id, peel_blocks, peel_hir_expr_refs, peel_hir_expr_while, CaptureKind, }; -use rustc_ast::util::parser::PREC_POSTFIX; +use rustc_ast::util::parser::PREC_UNAMBIGUOUS; use rustc_errors::Applicability; use rustc_hir::def::Res; use rustc_hir::LangItem::{OptionNone, OptionSome}; @@ -117,7 +117,7 @@ where // it's being passed by value. let scrutinee = peel_hir_expr_refs(scrutinee).0; let (scrutinee_str, _) = snippet_with_context(cx, scrutinee.span, expr_ctxt, "..", &mut app); - let scrutinee_str = if scrutinee.span.eq_ctxt(expr.span) && scrutinee.precedence().order() < PREC_POSTFIX { + let scrutinee_str = if scrutinee.span.eq_ctxt(expr.span) && scrutinee.precedence().order() < PREC_UNAMBIGUOUS { format!("({scrutinee_str})") } else { scrutinee_str.into() From 732e6876eac8dda8a54cedfd8376bd8176bc388b Mon Sep 17 00:00:00 2001 From: The Miri Cronjob Bot Date: Mon, 24 Jun 2024 05:03:43 +0000 Subject: [PATCH 283/892] 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 97d37b0ebe596..11a1c43bae9a2 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version @@ -1 +1 @@ -acb62737aca7045f331e7a05adc38bed213e278d +d49994b060684af423339b55769439b2f444a7b9 From 82c5cdc6b1de77634d63faacd6b606c99e816316 Mon Sep 17 00:00:00 2001 From: wooden-worm <93303706+wooden-worm@users.noreply.github.com> Date: Sun, 23 Jun 2024 22:58:30 -0700 Subject: [PATCH 284/892] wasm64 build with target-feature=+simd128,+atomics --- .../crates/core_simd/src/swizzle_dyn.rs | 2 ++ library/std/src/lib.rs | 1 + library/std/src/sys/pal/wasm/atomics/futex.rs | 17 +++++++++-------- library/std/src/sys/pal/wasm/atomics/thread.rs | 8 ++++++-- 4 files changed, 18 insertions(+), 10 deletions(-) diff --git a/library/portable-simd/crates/core_simd/src/swizzle_dyn.rs b/library/portable-simd/crates/core_simd/src/swizzle_dyn.rs index 8a1079042f076..3b6388d0f2759 100644 --- a/library/portable-simd/crates/core_simd/src/swizzle_dyn.rs +++ b/library/portable-simd/crates/core_simd/src/swizzle_dyn.rs @@ -30,6 +30,8 @@ where use core::arch::arm::{uint8x8_t, vtbl1_u8}; #[cfg(target_arch = "wasm32")] use core::arch::wasm32 as wasm; + #[cfg(target_arch = "wasm64")] + use core::arch::wasm64 as wasm; #[cfg(target_arch = "x86")] use core::arch::x86; #[cfg(target_arch = "x86_64")] diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index 80f67838ac002..f67e4a050cfee 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -266,6 +266,7 @@ )] #![cfg_attr(any(windows, target_os = "uefi"), feature(round_char_boundary))] #![cfg_attr(target_family = "wasm", feature(stdarch_wasm_atomic_wait))] +#![cfg_attr(target_arch = "wasm64", feature(simd_wasm64))] #![cfg_attr( all(any(target_arch = "x86_64", target_arch = "x86"), target_os = "uefi"), feature(stdarch_x86_has_cpuid) diff --git a/library/std/src/sys/pal/wasm/atomics/futex.rs b/library/std/src/sys/pal/wasm/atomics/futex.rs index f4fbe9f48554b..a21b71efbbc69 100644 --- a/library/std/src/sys/pal/wasm/atomics/futex.rs +++ b/library/std/src/sys/pal/wasm/atomics/futex.rs @@ -1,4 +1,8 @@ -use crate::arch::wasm32; +#[cfg(target_arch = "wasm32")] +use core::arch::wasm32 as wasm; +#[cfg(target_arch = "wasm64")] +use core::arch::wasm64 as wasm; + use crate::sync::atomic::AtomicU32; use crate::time::Duration; @@ -10,11 +14,8 @@ use crate::time::Duration; pub fn futex_wait(futex: &AtomicU32, expected: u32, timeout: Option) -> bool { let timeout = timeout.and_then(|t| t.as_nanos().try_into().ok()).unwrap_or(-1); unsafe { - wasm32::memory_atomic_wait32( - futex as *const AtomicU32 as *mut i32, - expected as i32, - timeout, - ) < 2 + wasm::memory_atomic_wait32(futex as *const AtomicU32 as *mut i32, expected as i32, timeout) + < 2 } } @@ -23,12 +24,12 @@ pub fn futex_wait(futex: &AtomicU32, expected: u32, timeout: Option) - /// Returns true if this actually woke up such a thread, /// or false if no thread was waiting on this futex. pub fn futex_wake(futex: &AtomicU32) -> bool { - unsafe { wasm32::memory_atomic_notify(futex as *const AtomicU32 as *mut i32, 1) > 0 } + unsafe { wasm::memory_atomic_notify(futex as *const AtomicU32 as *mut i32, 1) > 0 } } /// Wake up all threads that are waiting on futex_wait on this futex. pub fn futex_wake_all(futex: &AtomicU32) { unsafe { - wasm32::memory_atomic_notify(futex as *const AtomicU32 as *mut i32, i32::MAX as u32); + wasm::memory_atomic_notify(futex as *const AtomicU32 as *mut i32, i32::MAX as u32); } } diff --git a/library/std/src/sys/pal/wasm/atomics/thread.rs b/library/std/src/sys/pal/wasm/atomics/thread.rs index 484bd08495eef..afdb159fe6f8b 100644 --- a/library/std/src/sys/pal/wasm/atomics/thread.rs +++ b/library/std/src/sys/pal/wasm/atomics/thread.rs @@ -19,7 +19,11 @@ impl Thread { pub fn set_name(_name: &CStr) {} pub fn sleep(dur: Duration) { - use crate::arch::wasm32; + #[cfg(target_arch = "wasm32")] + use core::arch::wasm32 as wasm; + #[cfg(target_arch = "wasm64")] + use core::arch::wasm64 as wasm; + use crate::cmp; // Use an atomic wait to block the current thread artificially with a @@ -31,7 +35,7 @@ impl Thread { while nanos > 0 { let amt = cmp::min(i64::MAX as u128, nanos); let mut x = 0; - let val = unsafe { wasm32::memory_atomic_wait32(&mut x, 0, amt as i64) }; + let val = unsafe { wasm::memory_atomic_wait32(&mut x, 0, amt as i64) }; debug_assert_eq!(val, 2); nanos -= amt; } From f071a205c7f3946835c834e252786f02046211f7 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 24 Jun 2024 08:43:16 +0200 Subject: [PATCH 285/892] tests for when a thread-local gets initialized in a tls dtor --- .../miri/tests/pass/tls/tls_macro_drop.rs | 102 ++++++++++++------ .../pass/tls/tls_macro_drop.stack.stdout | 3 + .../tests/pass/tls/tls_macro_drop.tree.stdout | 3 + .../pass/tls/tls_macro_drop_single_thread.rs | 36 +++---- .../tls/tls_macro_drop_single_thread.stderr | 3 - .../tls/tls_macro_drop_single_thread.stdout | 2 + 6 files changed, 91 insertions(+), 58 deletions(-) delete mode 100644 src/tools/miri/tests/pass/tls/tls_macro_drop_single_thread.stderr create mode 100644 src/tools/miri/tests/pass/tls/tls_macro_drop_single_thread.stdout diff --git a/src/tools/miri/tests/pass/tls/tls_macro_drop.rs b/src/tools/miri/tests/pass/tls/tls_macro_drop.rs index bd06eec9cd541..0d8a1cef511d8 100644 --- a/src/tools/miri/tests/pass/tls/tls_macro_drop.rs +++ b/src/tools/miri/tests/pass/tls/tls_macro_drop.rs @@ -4,27 +4,28 @@ use std::cell::RefCell; use std::thread; -struct TestCell { - value: RefCell, -} +/// Check that destructors of the library thread locals are executed immediately +/// after a thread terminates. +fn check_destructors() { + struct TestCell { + value: RefCell, + } -impl Drop for TestCell { - fn drop(&mut self) { - for _ in 0..10 { - thread::yield_now(); + impl Drop for TestCell { + fn drop(&mut self) { + for _ in 0..10 { + thread::yield_now(); + } + println!("Dropping: {} (should be before 'Continue main 1').", *self.value.borrow()) } - println!("Dropping: {} (should be before 'Continue main 1').", *self.value.borrow()) } -} -thread_local! { - static A: TestCell = TestCell { value: RefCell::new(0) }; - static A_CONST: TestCell = const { TestCell { value: RefCell::new(10) } }; -} + // Test both regular and `const` thread-locals. + thread_local! { + static A: TestCell = TestCell { value: RefCell::new(0) }; + static A_CONST: TestCell = const { TestCell { value: RefCell::new(10) } }; + } -/// Check that destructors of the library thread locals are executed immediately -/// after a thread terminates. -fn check_destructors() { // We use the same value for both of them, since destructor order differs between Miri on Linux // (which uses `register_dtor_fallback`, in the end using a single pthread_key to manage a // thread-local linked list of dtors to call), real Linux rustc (which uses @@ -44,26 +45,29 @@ fn check_destructors() { println!("Continue main 1.") } -struct JoinCell { - value: RefCell>>, -} +/// Check that the destructor can be blocked joining another thread. +fn check_blocking() { + struct JoinCell { + value: RefCell>>, + } -impl Drop for JoinCell { - fn drop(&mut self) { - for _ in 0..10 { - thread::yield_now(); + impl Drop for JoinCell { + fn drop(&mut self) { + for _ in 0..10 { + thread::yield_now(); + } + let join_handle = self.value.borrow_mut().take().unwrap(); + println!( + "Joining: {} (should be before 'Continue main 2').", + join_handle.join().unwrap() + ); } - let join_handle = self.value.borrow_mut().take().unwrap(); - println!("Joining: {} (should be before 'Continue main 2').", join_handle.join().unwrap()); } -} -thread_local! { - static B: JoinCell = JoinCell { value: RefCell::new(None) }; -} + thread_local! { + static B: JoinCell = JoinCell { value: RefCell::new(None) }; + } -/// Check that the destructor can be blocked joining another thread. -fn check_blocking() { thread::spawn(|| { B.with(|f| { assert!(f.value.borrow().is_none()); @@ -74,10 +78,36 @@ fn check_blocking() { .join() .unwrap(); println!("Continue main 2."); - // Preempt the main thread so that the destructor gets executed and can join - // the thread. - thread::yield_now(); - thread::yield_now(); +} + +fn check_tls_init_in_dtor() { + struct Bar; + + impl Drop for Bar { + fn drop(&mut self) { + println!("Bar dtor (should be before `Continue main 3`)."); + } + } + + struct Foo; + + impl Drop for Foo { + fn drop(&mut self) { + println!("Foo dtor (should be before `Bar dtor`)."); + // We initialize another thread-local inside the dtor, which is an interesting corner case. + thread_local!(static BAR: Bar = Bar); + BAR.with(|_| {}); + } + } + + thread_local!(static FOO: Foo = Foo); + + thread::spawn(|| { + FOO.with(|_| {}); + }) + .join() + .unwrap(); + println!("Continue main 3."); } // This test tests that TLS destructors have run before the thread joins. The @@ -248,6 +278,8 @@ fn dtors_in_dtors_in_dtors() { fn main() { check_destructors(); check_blocking(); + check_tls_init_in_dtor(); + join_orders_after_tls_destructors(); dtors_in_dtors_in_dtors(); } diff --git a/src/tools/miri/tests/pass/tls/tls_macro_drop.stack.stdout b/src/tools/miri/tests/pass/tls/tls_macro_drop.stack.stdout index b7877820a0ca9..3e17acc832835 100644 --- a/src/tools/miri/tests/pass/tls/tls_macro_drop.stack.stdout +++ b/src/tools/miri/tests/pass/tls/tls_macro_drop.stack.stdout @@ -3,3 +3,6 @@ Dropping: 8 (should be before 'Continue main 1'). Continue main 1. Joining: 7 (should be before 'Continue main 2'). Continue main 2. +Foo dtor (should be before `Bar dtor`). +Bar dtor (should be before `Continue main 3`). +Continue main 3. diff --git a/src/tools/miri/tests/pass/tls/tls_macro_drop.tree.stdout b/src/tools/miri/tests/pass/tls/tls_macro_drop.tree.stdout index b7877820a0ca9..3e17acc832835 100644 --- a/src/tools/miri/tests/pass/tls/tls_macro_drop.tree.stdout +++ b/src/tools/miri/tests/pass/tls/tls_macro_drop.tree.stdout @@ -3,3 +3,6 @@ Dropping: 8 (should be before 'Continue main 1'). Continue main 1. Joining: 7 (should be before 'Continue main 2'). Continue main 2. +Foo dtor (should be before `Bar dtor`). +Bar dtor (should be before `Continue main 3`). +Continue main 3. diff --git a/src/tools/miri/tests/pass/tls/tls_macro_drop_single_thread.rs b/src/tools/miri/tests/pass/tls/tls_macro_drop_single_thread.rs index f36c460ae5341..082a6f17838d5 100644 --- a/src/tools/miri/tests/pass/tls/tls_macro_drop_single_thread.rs +++ b/src/tools/miri/tests/pass/tls/tls_macro_drop_single_thread.rs @@ -1,31 +1,27 @@ -//! Check that destructors of the thread locals are executed on all OSes -//! (even when we do not support concurrency, and cannot run the other test). +//! Check that destructors of main thread thread locals are executed. -use std::cell::RefCell; +struct Bar; -struct TestCell { - value: RefCell, +impl Drop for Bar { + fn drop(&mut self) { + println!("Bar dtor"); + } } -impl Drop for TestCell { +struct Foo; + +impl Drop for Foo { fn drop(&mut self) { - eprintln!("Dropping: {}", *self.value.borrow()) + println!("Foo dtor"); + // We initialize another thread-local inside the dtor, which is an interesting corner case. + // Also we use a `const` thread-local here, just to also have that code path covered. + thread_local!(static BAR: Bar = const { Bar }); + BAR.with(|_| {}); } } -thread_local! { - static A: TestCell = TestCell { value: RefCell::new(0) }; - static A_CONST: TestCell = const { TestCell { value: RefCell::new(10) } }; -} +thread_local!(static FOO: Foo = Foo); fn main() { - A.with(|f| { - assert_eq!(*f.value.borrow(), 0); - *f.value.borrow_mut() = 5; - }); - A_CONST.with(|f| { - assert_eq!(*f.value.borrow(), 10); - *f.value.borrow_mut() = 5; // Same value as above since the drop order is different on different platforms - }); - eprintln!("Continue main.") + FOO.with(|_| {}); } diff --git a/src/tools/miri/tests/pass/tls/tls_macro_drop_single_thread.stderr b/src/tools/miri/tests/pass/tls/tls_macro_drop_single_thread.stderr deleted file mode 100644 index 09ec1c3c2c511..0000000000000 --- a/src/tools/miri/tests/pass/tls/tls_macro_drop_single_thread.stderr +++ /dev/null @@ -1,3 +0,0 @@ -Continue main. -Dropping: 5 -Dropping: 5 diff --git a/src/tools/miri/tests/pass/tls/tls_macro_drop_single_thread.stdout b/src/tools/miri/tests/pass/tls/tls_macro_drop_single_thread.stdout new file mode 100644 index 0000000000000..6160f2726492d --- /dev/null +++ b/src/tools/miri/tests/pass/tls/tls_macro_drop_single_thread.stdout @@ -0,0 +1,2 @@ +Foo dtor +Bar dtor From 879d143229d0d3ff80e7ee7573515f828859f525 Mon Sep 17 00:00:00 2001 From: Maybe Lapkin Date: Sun, 23 Jun 2024 21:55:41 +0200 Subject: [PATCH 286/892] Add `.ignore` file to make `config.toml` searchable in vscode --- .ignore | 2 ++ .reuse/dep5 | 1 + 2 files changed, 3 insertions(+) create mode 100644 .ignore diff --git a/.ignore b/.ignore new file mode 100644 index 0000000000000..40d1513978fc6 --- /dev/null +++ b/.ignore @@ -0,0 +1,2 @@ +# Make vscode *not* count `config.toml` as ignored, so it is included in search +!/config.toml diff --git a/.reuse/dep5 b/.reuse/dep5 index 06afec2b3faec..7b9365a5e48f7 100644 --- a/.reuse/dep5 +++ b/.reuse/dep5 @@ -35,6 +35,7 @@ Files: compiler/* .gitignore .gitmodules .mailmap + .ignore Copyright: The Rust Project Developers (see https://thanks.rust-lang.org) License: MIT or Apache-2.0 From dbf701838758bd70d51fa36dcb79e7d02e0e4352 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petteri=20R=C3=A4ty?= Date: Mon, 24 Jun 2024 11:12:10 +0300 Subject: [PATCH 287/892] Fix simd_gather documentation There is no idx in the function signature. --- library/core/src/intrinsics/simd.rs | 3 --- 1 file changed, 3 deletions(-) diff --git a/library/core/src/intrinsics/simd.rs b/library/core/src/intrinsics/simd.rs index 4be5e62ea5bc6..b892e11158822 100644 --- a/library/core/src/intrinsics/simd.rs +++ b/library/core/src/intrinsics/simd.rs @@ -263,9 +263,6 @@ extern "rust-intrinsic" { /// /// `V` must be a vector of integers with the same length as `T` (but any element size). /// - /// `idx` must be a constant: either naming a constant item, or an inline - /// `const {}` expression. - /// /// For each pointer in `ptr`, if the corresponding value in `mask` is `!0`, read the pointer. /// Otherwise if the corresponding value in `mask` is `0`, return the corresponding value from /// `val`. From 0f114ec41d5f1c5c4d2d77767014f0946c3f3cd5 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 24 Jun 2024 10:51:49 +0200 Subject: [PATCH 288/892] clarify the warning shown when optimizations are enabled --- src/tools/miri/src/bin/miri.rs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/tools/miri/src/bin/miri.rs b/src/tools/miri/src/bin/miri.rs index 829bfa7cd7086..9d8e44ce409e2 100644 --- a/src/tools/miri/src/bin/miri.rs +++ b/src/tools/miri/src/bin/miri.rs @@ -98,10 +98,9 @@ impl rustc_driver::Callbacks for MiriCompilerCalls { } if tcx.sess.opts.optimize != OptLevel::No { - tcx.dcx().warn("Miri does not support optimizations. If you have enabled optimizations \ - by selecting a Cargo profile (such as --release) which changes other profile settings \ - such as whether debug assertions and overflow checks are enabled, those settings are \ - still applied."); + tcx.dcx().warn("Miri does not support optimizations: the opt-level is ignored. The only effect \ + of selecting a Cargo profile that enables optimizations (such as --release) is to apply \ + its remaining settings, such as whether debug assertions and overflow checks are enabled."); } if tcx.sess.mir_opt_level() > 0 { tcx.dcx().warn("You have explicitly enabled MIR optimizations, overriding Miri's default \ From ba61c8f2a6ee3e874c1745d1471a16f4a1616290 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 24 Jun 2024 10:54:26 +0200 Subject: [PATCH 289/892] clarify the status of Tree Borrows --- src/tools/miri/README.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/tools/miri/README.md b/src/tools/miri/README.md index 4b4f2f83062f0..87b437a308034 100644 --- a/src/tools/miri/README.md +++ b/src/tools/miri/README.md @@ -425,8 +425,12 @@ to Miri failing to detect cases of undefined behavior in a program. value from a load. This can help diagnose problems that disappear under `-Zmiri-disable-weak-memory-emulation`. * `-Zmiri-tree-borrows` replaces [Stacked Borrows] with the [Tree Borrows] rules. - The soundness rules are already experimental without this flag, but even more - so with this flag. + Tree Borrows is even more experimental than Stacked Borrows. While Tree Borrows + is still sound in the sense of catching all aliasing violations that current versions + of the compiler might exploit, it is likely that the eventual final aliasing model + of Rust will be stricter than Tree Borrows. In other words, if you use Tree Borrows, + even if your code is accepted today, it might be declared UB in the future. + This is much less likely with Stacked Borrows. * `-Zmiri-force-page-size=` overrides the default page size for an architecture, in multiples of 1k. `4` is default for most targets. This value should always be a power of 2 and nonzero. * `-Zmiri-unique-is-unique` performs additional aliasing checks for `core::ptr::Unique` to ensure From 8c718e552433cc739989942440b866d1552d3ae0 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Wed, 29 May 2024 23:36:11 +0300 Subject: [PATCH 290/892] ast: Standardize visiting order for attributes and node IDs --- tests/ui/cfg_attr_cargo_clippy.stderr | 18 ++++----- tests/ui/tabs_in_doc_comments.stderr | 48 +++++++++++----------- tests/ui/unnecessary_clippy_cfg.stderr | 56 +++++++++++++------------- 3 files changed, 61 insertions(+), 61 deletions(-) diff --git a/tests/ui/cfg_attr_cargo_clippy.stderr b/tests/ui/cfg_attr_cargo_clippy.stderr index ddec0e648d10c..0a358f1a68475 100644 --- a/tests/ui/cfg_attr_cargo_clippy.stderr +++ b/tests/ui/cfg_attr_cargo_clippy.stderr @@ -1,12 +1,18 @@ error: `feature = "cargo-clippy"` was replaced by `clippy` - --> tests/ui/cfg_attr_cargo_clippy.rs:5:12 + --> tests/ui/cfg_attr_cargo_clippy.rs:3:13 | -LL | #[cfg_attr(feature = "cargo-clippy", derive(Debug))] - | ^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `clippy` +LL | #![cfg_attr(feature = "cargo-clippy", doc = "a")] + | ^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `clippy` | = note: `-D clippy::deprecated-clippy-cfg-attr` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::deprecated_clippy_cfg_attr)]` +error: `feature = "cargo-clippy"` was replaced by `clippy` + --> tests/ui/cfg_attr_cargo_clippy.rs:5:12 + | +LL | #[cfg_attr(feature = "cargo-clippy", derive(Debug))] + | ^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `clippy` + error: `feature = "cargo-clippy"` was replaced by `clippy` --> tests/ui/cfg_attr_cargo_clippy.rs:6:16 | @@ -37,11 +43,5 @@ error: `feature = "cargo-clippy"` was replaced by `clippy` LL | #[cfg(all(feature = "cargo-clippy"))] | ^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `clippy` -error: `feature = "cargo-clippy"` was replaced by `clippy` - --> tests/ui/cfg_attr_cargo_clippy.rs:3:13 - | -LL | #![cfg_attr(feature = "cargo-clippy", doc = "a")] - | ^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `clippy` - error: aborting due to 7 previous errors diff --git a/tests/ui/tabs_in_doc_comments.stderr b/tests/ui/tabs_in_doc_comments.stderr index 23d5dcd3a8dab..aef6c39145263 100644 --- a/tests/ui/tabs_in_doc_comments.stderr +++ b/tests/ui/tabs_in_doc_comments.stderr @@ -1,53 +1,53 @@ error: using tabs in doc comments is not recommended - --> tests/ui/tabs_in_doc_comments.rs:10:9 + --> tests/ui/tabs_in_doc_comments.rs:6:5 | -LL | /// - First String: - | ^^^^ help: consider using four spaces per tab +LL | /// - first one + | ^^^^ help: consider using four spaces per tab | = note: `-D clippy::tabs-in-doc-comments` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::tabs_in_doc_comments)]` error: using tabs in doc comments is not recommended - --> tests/ui/tabs_in_doc_comments.rs:11:9 + --> tests/ui/tabs_in_doc_comments.rs:6:13 | -LL | /// - needs to be inside here - | ^^^^^^^^ help: consider using four spaces per tab +LL | /// - first one + | ^^^^^^^^ help: consider using four spaces per tab error: using tabs in doc comments is not recommended - --> tests/ui/tabs_in_doc_comments.rs:14:9 + --> tests/ui/tabs_in_doc_comments.rs:7:5 | -LL | /// - Second String: - | ^^^^ help: consider using four spaces per tab +LL | /// - second one + | ^^^^ help: consider using four spaces per tab error: using tabs in doc comments is not recommended - --> tests/ui/tabs_in_doc_comments.rs:15:9 + --> tests/ui/tabs_in_doc_comments.rs:7:14 | -LL | /// - needs to be inside here - | ^^^^^^^^ help: consider using four spaces per tab +LL | /// - second one + | ^^^^ help: consider using four spaces per tab error: using tabs in doc comments is not recommended - --> tests/ui/tabs_in_doc_comments.rs:6:5 + --> tests/ui/tabs_in_doc_comments.rs:10:9 | -LL | /// - first one - | ^^^^ help: consider using four spaces per tab +LL | /// - First String: + | ^^^^ help: consider using four spaces per tab error: using tabs in doc comments is not recommended - --> tests/ui/tabs_in_doc_comments.rs:6:13 + --> tests/ui/tabs_in_doc_comments.rs:11:9 | -LL | /// - first one - | ^^^^^^^^ help: consider using four spaces per tab +LL | /// - needs to be inside here + | ^^^^^^^^ help: consider using four spaces per tab error: using tabs in doc comments is not recommended - --> tests/ui/tabs_in_doc_comments.rs:7:5 + --> tests/ui/tabs_in_doc_comments.rs:14:9 | -LL | /// - second one - | ^^^^ help: consider using four spaces per tab +LL | /// - Second String: + | ^^^^ help: consider using four spaces per tab error: using tabs in doc comments is not recommended - --> tests/ui/tabs_in_doc_comments.rs:7:14 + --> tests/ui/tabs_in_doc_comments.rs:15:9 | -LL | /// - second one - | ^^^^ help: consider using four spaces per tab +LL | /// - needs to be inside here + | ^^^^^^^^ help: consider using four spaces per tab error: aborting due to 8 previous errors diff --git a/tests/ui/unnecessary_clippy_cfg.stderr b/tests/ui/unnecessary_clippy_cfg.stderr index 16a8616529565..01f842a657de5 100644 --- a/tests/ui/unnecessary_clippy_cfg.stderr +++ b/tests/ui/unnecessary_clippy_cfg.stderr @@ -1,61 +1,61 @@ error: no need to put clippy lints behind a `clippy` cfg - --> tests/ui/unnecessary_clippy_cfg.rs:13:1 + --> tests/ui/unnecessary_clippy_cfg.rs:4:1 | -LL | #[cfg_attr(clippy, deny(clippy::non_minimal_cfg))] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `#[deny(clippy::non_minimal_cfg)]` +LL | #![cfg_attr(clippy, deny(clippy::non_minimal_cfg))] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `#![deny(clippy::non_minimal_cfg)]` | = note: `-D clippy::unnecessary-clippy-cfg` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::unnecessary_clippy_cfg)]` error: no need to put clippy lints behind a `clippy` cfg - --> tests/ui/unnecessary_clippy_cfg.rs:15:36 + --> tests/ui/unnecessary_clippy_cfg.rs:6:37 | -LL | #[cfg_attr(clippy, deny(dead_code, clippy::non_minimal_cfg))] - | ^^^^^^^^^^^^^^^^^^^^^^^ +LL | #![cfg_attr(clippy, deny(dead_code, clippy::non_minimal_cfg))] + | ^^^^^^^^^^^^^^^^^^^^^^^ | - = note: write instead: `#[deny(clippy::non_minimal_cfg)]` + = note: write instead: `#![deny(clippy::non_minimal_cfg)]` error: no need to put clippy lints behind a `clippy` cfg - --> tests/ui/unnecessary_clippy_cfg.rs:17:36 + --> tests/ui/unnecessary_clippy_cfg.rs:8:37 | -LL | #[cfg_attr(clippy, deny(dead_code, clippy::non_minimal_cfg))] - | ^^^^^^^^^^^^^^^^^^^^^^^ +LL | #![cfg_attr(clippy, deny(dead_code, clippy::non_minimal_cfg))] + | ^^^^^^^^^^^^^^^^^^^^^^^ | - = note: write instead: `#[deny(clippy::non_minimal_cfg)]` + = note: write instead: `#![deny(clippy::non_minimal_cfg)]` error: no need to put clippy lints behind a `clippy` cfg - --> tests/ui/unnecessary_clippy_cfg.rs:19:1 + --> tests/ui/unnecessary_clippy_cfg.rs:10:1 | -LL | #[cfg_attr(clippy, deny(clippy::non_minimal_cfg))] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `#[deny(clippy::non_minimal_cfg)]` +LL | #![cfg_attr(clippy, deny(clippy::non_minimal_cfg))] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `#![deny(clippy::non_minimal_cfg)]` error: no need to put clippy lints behind a `clippy` cfg - --> tests/ui/unnecessary_clippy_cfg.rs:4:1 + --> tests/ui/unnecessary_clippy_cfg.rs:13:1 | -LL | #![cfg_attr(clippy, deny(clippy::non_minimal_cfg))] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `#![deny(clippy::non_minimal_cfg)]` +LL | #[cfg_attr(clippy, deny(clippy::non_minimal_cfg))] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `#[deny(clippy::non_minimal_cfg)]` error: no need to put clippy lints behind a `clippy` cfg - --> tests/ui/unnecessary_clippy_cfg.rs:6:37 + --> tests/ui/unnecessary_clippy_cfg.rs:15:36 | -LL | #![cfg_attr(clippy, deny(dead_code, clippy::non_minimal_cfg))] - | ^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[cfg_attr(clippy, deny(dead_code, clippy::non_minimal_cfg))] + | ^^^^^^^^^^^^^^^^^^^^^^^ | - = note: write instead: `#![deny(clippy::non_minimal_cfg)]` + = note: write instead: `#[deny(clippy::non_minimal_cfg)]` error: no need to put clippy lints behind a `clippy` cfg - --> tests/ui/unnecessary_clippy_cfg.rs:8:37 + --> tests/ui/unnecessary_clippy_cfg.rs:17:36 | -LL | #![cfg_attr(clippy, deny(dead_code, clippy::non_minimal_cfg))] - | ^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[cfg_attr(clippy, deny(dead_code, clippy::non_minimal_cfg))] + | ^^^^^^^^^^^^^^^^^^^^^^^ | - = note: write instead: `#![deny(clippy::non_minimal_cfg)]` + = note: write instead: `#[deny(clippy::non_minimal_cfg)]` error: no need to put clippy lints behind a `clippy` cfg - --> tests/ui/unnecessary_clippy_cfg.rs:10:1 + --> tests/ui/unnecessary_clippy_cfg.rs:19:1 | -LL | #![cfg_attr(clippy, deny(clippy::non_minimal_cfg))] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `#![deny(clippy::non_minimal_cfg)]` +LL | #[cfg_attr(clippy, deny(clippy::non_minimal_cfg))] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `#[deny(clippy::non_minimal_cfg)]` error: duplicated attribute --> tests/ui/unnecessary_clippy_cfg.rs:8:26 From 39bf1dcce5b0e80fbdbcde30e618821f5c9b0bf0 Mon Sep 17 00:00:00 2001 From: Pavel Grigorenko Date: Mon, 24 Jun 2024 17:57:58 +0300 Subject: [PATCH 291/892] Small fixme in core now that split_first has no codegen issues --- library/core/src/num/dec2flt/common.rs | 4 +--- library/core/src/num/dec2flt/parse.rs | 4 +--- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/library/core/src/num/dec2flt/common.rs b/library/core/src/num/dec2flt/common.rs index 11a626485191c..c85727b493816 100644 --- a/library/core/src/num/dec2flt/common.rs +++ b/library/core/src/num/dec2flt/common.rs @@ -39,9 +39,7 @@ impl ByteSlice for [u8] { fn parse_digits(&self, mut func: impl FnMut(u8)) -> &Self { let mut s = self; - // FIXME: Can't use s.split_first() here yet, - // see https://github.com/rust-lang/rust/issues/109328 - while let [c, s_next @ ..] = s { + while let Some((c, s_next)) = s.split_first() { let c = c.wrapping_sub(b'0'); if c < 10 { func(c); diff --git a/library/core/src/num/dec2flt/parse.rs b/library/core/src/num/dec2flt/parse.rs index b0a23835c5bd4..975bb8ad6bc1f 100644 --- a/library/core/src/num/dec2flt/parse.rs +++ b/library/core/src/num/dec2flt/parse.rs @@ -51,9 +51,7 @@ fn try_parse_19digits(s_ref: &mut &[u8], x: &mut u64) { let mut s = *s_ref; while *x < MIN_19DIGIT_INT { - // FIXME: Can't use s.split_first() here yet, - // see https://github.com/rust-lang/rust/issues/109328 - if let [c, s_next @ ..] = s { + if let Some((c, s_next)) = s.split_first() { let digit = c.wrapping_sub(b'0'); if digit < 10 { From 606ada193f4b5d0ec3b22cf62837af7b98069b13 Mon Sep 17 00:00:00 2001 From: klensy Date: Mon, 24 Jun 2024 18:06:02 +0300 Subject: [PATCH 292/892] bump strip-ansi-escapes --- lintcheck/Cargo.toml | 2 +- lintcheck/src/main.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lintcheck/Cargo.toml b/lintcheck/Cargo.toml index e0e94d7fec3eb..ae9e77b8eed05 100644 --- a/lintcheck/Cargo.toml +++ b/lintcheck/Cargo.toml @@ -19,7 +19,7 @@ flate2 = "1.0" rayon = "1.5.1" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0.85" -strip-ansi-escapes = "0.1.1" +strip-ansi-escapes = "0.2.0" tar = "0.4" toml = "0.7.3" ureq = { version = "2.2", features = ["json"] } diff --git a/lintcheck/src/main.rs b/lintcheck/src/main.rs index 8dd6e95bb7deb..ec72e0eb5dcb5 100644 --- a/lintcheck/src/main.rs +++ b/lintcheck/src/main.rs @@ -161,7 +161,7 @@ impl ClippyWarning { // --recursive bypasses cargo so we have to strip the rendered output ourselves let rendered = diag.rendered.as_mut().unwrap(); - *rendered = String::from_utf8(strip_ansi_escapes::strip(&rendered).unwrap()).unwrap(); + *rendered = strip_ansi_escapes::strip_str(&rendered); Some(Self { crate_name: crate_name.to_owned(), From a155c389894bd36c81e3b2f031da5d30ebbd38e6 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 21 Jun 2024 13:33:08 -0400 Subject: [PATCH 293/892] Split out IntoIterator and non-Iterator constructors for AliasTy/AliasTerm/TraitRef/projection --- clippy_lints/src/bool_assert_comparison.rs | 2 +- clippy_lints/src/methods/needless_collect.rs | 4 ++-- clippy_lints/src/redundant_slicing.rs | 2 +- clippy_utils/src/ty.rs | 8 ++++---- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/clippy_lints/src/bool_assert_comparison.rs b/clippy_lints/src/bool_assert_comparison.rs index 58c1a2f270621..db5792188dd4b 100644 --- a/clippy_lints/src/bool_assert_comparison.rs +++ b/clippy_lints/src/bool_assert_comparison.rs @@ -61,7 +61,7 @@ fn is_impl_not_trait_with_bool_out<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) - ) }) .map_or(false, |assoc_item| { - let proj = Ty::new_projection(cx.tcx, assoc_item.def_id, cx.tcx.mk_args_trait(ty, [])); + let proj = Ty::new_projection_from_args(cx.tcx, assoc_item.def_id, cx.tcx.mk_args_trait(ty, [])); let nty = cx.tcx.normalize_erasing_regions(cx.param_env, proj); nty.is_bool() diff --git a/clippy_lints/src/methods/needless_collect.rs b/clippy_lints/src/methods/needless_collect.rs index f26f164fa54a4..46b457daf7074 100644 --- a/clippy_lints/src/methods/needless_collect.rs +++ b/clippy_lints/src/methods/needless_collect.rs @@ -206,7 +206,7 @@ fn iterates_same_ty<'tcx>(cx: &LateContext<'tcx>, iter_ty: Ty<'tcx>, collect_ty: && let Some(into_iter_item_proj) = make_projection(cx.tcx, into_iter_trait, sym::Item, [collect_ty]) && let Ok(into_iter_item_ty) = cx.tcx.try_normalize_erasing_regions( cx.param_env, - Ty::new_projection(cx.tcx, into_iter_item_proj.def_id, into_iter_item_proj.args), + Ty::new_projection_from_args(cx.tcx, into_iter_item_proj.def_id, into_iter_item_proj.args), ) { iter_item_ty == into_iter_item_ty @@ -235,7 +235,7 @@ fn is_contains_sig(cx: &LateContext<'_>, call_id: HirId, iter_expr: &Expr<'_>) - iter_trait, ) && let args = cx.tcx.mk_args(&[GenericArg::from(typeck.expr_ty_adjusted(iter_expr))]) - && let proj_ty = Ty::new_projection(cx.tcx, iter_item.def_id, args) + && let proj_ty = Ty::new_projection_from_args(cx.tcx, iter_item.def_id, args) && let Ok(item_ty) = cx.tcx.try_normalize_erasing_regions(cx.param_env, proj_ty) { item_ty == EarlyBinder::bind(search_ty).instantiate(cx.tcx, cx.typeck_results().node_args(call_id)) diff --git a/clippy_lints/src/redundant_slicing.rs b/clippy_lints/src/redundant_slicing.rs index 7f87d18e50238..82f22ad693d78 100644 --- a/clippy_lints/src/redundant_slicing.rs +++ b/clippy_lints/src/redundant_slicing.rs @@ -133,7 +133,7 @@ impl<'tcx> LateLintPass<'tcx> for RedundantSlicing { } else if let Some(target_id) = cx.tcx.lang_items().deref_target() { if let Ok(deref_ty) = cx.tcx.try_normalize_erasing_regions( cx.param_env, - Ty::new_projection(cx.tcx, target_id, cx.tcx.mk_args(&[GenericArg::from(indexed_ty)])), + Ty::new_projection_from_args(cx.tcx, target_id, cx.tcx.mk_args(&[GenericArg::from(indexed_ty)])), ) { if deref_ty == expr_ty { let snip = snippet_with_context(cx, indexed.span, ctxt, "..", &mut app).0; diff --git a/clippy_utils/src/ty.rs b/clippy_utils/src/ty.rs index 7d4332a3d9de8..3790a852f7edb 100644 --- a/clippy_utils/src/ty.rs +++ b/clippy_utils/src/ty.rs @@ -292,7 +292,7 @@ pub fn implements_trait_with_env_from_iter<'tcx>( let trait_ref = TraitRef::new( tcx, trait_id, - Some(GenericArg::from(ty)).into_iter().chain(args).chain(effect_arg), + [GenericArg::from(ty)].into_iter().chain(args).chain(effect_arg), ); debug_assert_matches!( @@ -1126,7 +1126,7 @@ pub fn make_projection<'tcx>( #[cfg(debug_assertions)] assert_generic_args_match(tcx, assoc_item.def_id, args); - Some(AliasTy::new(tcx, assoc_item.def_id, args)) + Some(AliasTy::new_from_args(tcx, assoc_item.def_id, args)) } helper( tcx, @@ -1165,7 +1165,7 @@ pub fn make_normalized_projection<'tcx>( ); return None; } - match tcx.try_normalize_erasing_regions(param_env, Ty::new_projection(tcx, ty.def_id, ty.args)) { + match tcx.try_normalize_erasing_regions(param_env, Ty::new_projection_from_args(tcx, ty.def_id, ty.args)) { Ok(ty) => Some(ty), Err(e) => { debug_assert!(false, "failed to normalize type `{ty}`: {e:#?}"); @@ -1289,7 +1289,7 @@ pub fn make_normalized_projection_with_regions<'tcx>( .infer_ctxt() .build() .at(&cause, param_env) - .query_normalize(Ty::new_projection(tcx, ty.def_id, ty.args)) + .query_normalize(Ty::new_projection_from_args(tcx, ty.def_id, ty.args)) { Ok(ty) => Some(ty.value), Err(e) => { From 8998ce24e0c1ce1b2bd44c0836546bba1cdf374f Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 21 Jun 2024 13:55:21 -0400 Subject: [PATCH 294/892] Replace Deref bounds on Interner in favor of a SliceLike trait --- clippy_lints/src/needless_borrows_for_generic_args.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clippy_lints/src/needless_borrows_for_generic_args.rs b/clippy_lints/src/needless_borrows_for_generic_args.rs index 4f99eaa40c29b..f4846a1753f7c 100644 --- a/clippy_lints/src/needless_borrows_for_generic_args.rs +++ b/clippy_lints/src/needless_borrows_for_generic_args.rs @@ -267,7 +267,7 @@ fn needless_borrow_count<'tcx>( return false; } - let predicate = EarlyBinder::bind(predicate).instantiate(cx.tcx, &args_with_referent_ty); + let predicate = EarlyBinder::bind(predicate).instantiate(cx.tcx, &args_with_referent_ty[..]); let obligation = Obligation::new(cx.tcx, ObligationCause::dummy(), cx.param_env, predicate); let infcx = cx.tcx.infer_ctxt().build(); infcx.predicate_must_hold_modulo_regions(&obligation) From 11acf83159edc94edeeafd75eff458d9d584b822 Mon Sep 17 00:00:00 2001 From: onur-ozkan Date: Fri, 14 Jun 2024 09:45:02 +0300 Subject: [PATCH 295/892] bootstrap: exclude cargo from package metadata Signed-off-by: onur-ozkan --- src/bootstrap/src/core/metadata.rs | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/src/bootstrap/src/core/metadata.rs b/src/bootstrap/src/core/metadata.rs index 08a96407a6917..12867cb46b811 100644 --- a/src/bootstrap/src/core/metadata.rs +++ b/src/bootstrap/src/core/metadata.rs @@ -66,9 +66,6 @@ pub fn build(build: &mut Build) { } /// Invokes `cargo metadata` to get package metadata of each workspace member. -/// -/// Note that `src/tools/cargo` is no longer a workspace member but we still -/// treat it as one here, by invoking an additional `cargo metadata` command. fn workspace_members(build: &Build) -> impl Iterator { let collect_metadata = |manifest_path| { let mut cargo = Command::new(&build.initial_cargo); @@ -89,12 +86,8 @@ fn workspace_members(build: &Build) -> impl Iterator { // Collects `metadata.packages` from all workspaces. let packages = collect_metadata("Cargo.toml"); - let cargo_packages = collect_metadata("src/tools/cargo/Cargo.toml"); let ra_packages = collect_metadata("src/tools/rust-analyzer/Cargo.toml"); let bootstrap_packages = collect_metadata("src/bootstrap/Cargo.toml"); - // We only care about the root package from `src/tool/cargo` workspace. - let cargo_package = cargo_packages.into_iter().find(|pkg| pkg.name == "cargo").into_iter(); - - packages.into_iter().chain(cargo_package).chain(ra_packages).chain(bootstrap_packages) + packages.into_iter().chain(ra_packages).chain(bootstrap_packages) } From 457ac5d570f1897ac4c59b3db5f86f26a17d14bb Mon Sep 17 00:00:00 2001 From: onur-ozkan Date: Fri, 14 Jun 2024 09:45:59 +0300 Subject: [PATCH 296/892] don't fetch/sync cargo submodule by default Signed-off-by: onur-ozkan --- src/bootstrap/src/lib.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs index dfc30298c28d2..afba907ee92b4 100644 --- a/src/bootstrap/src/lib.rs +++ b/src/bootstrap/src/lib.rs @@ -469,8 +469,7 @@ impl Build { // Make sure we update these before gathering metadata so we don't get an error about missing // Cargo.toml files. - let rust_submodules = - ["src/tools/cargo", "src/doc/book", "library/backtrace", "library/stdarch"]; + let rust_submodules = ["src/doc/book", "library/backtrace", "library/stdarch"]; for s in rust_submodules { build.update_submodule(Path::new(s)); } From 8c3ebf7a4dced401e58f544f1af187f8c41d3472 Mon Sep 17 00:00:00 2001 From: onur-ozkan Date: Fri, 14 Jun 2024 09:49:28 +0300 Subject: [PATCH 297/892] refactor `tool_doc` macro in bootstrap Signed-off-by: onur-ozkan --- src/bootstrap/src/core/build_steps/doc.rs | 42 ++++++++++------------- 1 file changed, 18 insertions(+), 24 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/doc.rs b/src/bootstrap/src/core/build_steps/doc.rs index 6748625f1323d..87c700dad063d 100644 --- a/src/bootstrap/src/core/build_steps/doc.rs +++ b/src/bootstrap/src/core/build_steps/doc.rs @@ -888,12 +888,11 @@ impl Step for Rustc { macro_rules! tool_doc { ( $tool: ident, - $should_run: literal, $path: literal, $(rustc_tool = $rustc_tool:literal, )? - $(in_tree = $in_tree:literal ,)? $(is_library = $is_library:expr,)? $(crates = $crates:expr)? + $(, submodule $(= $submodule:literal)? )? ) => { #[derive(Debug, Clone, Hash, PartialEq, Eq)] pub struct $tool { @@ -907,7 +906,7 @@ macro_rules! tool_doc { fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { let builder = run.builder; - run.crate_or_deps($should_run).default_condition(builder.config.compiler_docs) + run.path($path).default_condition(builder.config.compiler_docs) } fn make_run(run: RunConfig<'_>) { @@ -921,6 +920,15 @@ macro_rules! tool_doc { /// we do not merge it with the other documentation from std, test and /// proc_macros. This is largely just a wrapper around `cargo doc`. fn run(self, builder: &Builder<'_>) { + let source_type = SourceType::InTree; + $( + let _ = source_type; // silence the "unused variable" warning + let source_type = SourceType::Submodule; + + let path = Path::new(submodule_helper!( $path, submodule $( = $submodule )? )); + builder.update_submodule(&path); + )? + let stage = builder.top_stage; let target = self.target; @@ -941,12 +949,6 @@ macro_rules! tool_doc { builder.ensure(compile::Rustc::new(compiler, target)); } - let source_type = if true $(&& $in_tree)? { - SourceType::InTree - } else { - SourceType::Submodule - }; - // Build cargo command. let mut cargo = prepare_tool_cargo( builder, @@ -1008,21 +1010,14 @@ macro_rules! tool_doc { } } -tool_doc!(Rustdoc, "rustdoc-tool", "src/tools/rustdoc", crates = ["rustdoc", "rustdoc-json-types"]); -tool_doc!( - Rustfmt, - "rustfmt-nightly", - "src/tools/rustfmt", - crates = ["rustfmt-nightly", "rustfmt-config_proc_macro"] -); -tool_doc!(Clippy, "clippy", "src/tools/clippy", crates = ["clippy_config", "clippy_utils"]); -tool_doc!(Miri, "miri", "src/tools/miri", crates = ["miri"]); +tool_doc!(Rustdoc, "src/tools/rustdoc", crates = ["rustdoc", "rustdoc-json-types"]); +tool_doc!(Rustfmt, "src/tools/rustfmt", crates = ["rustfmt-nightly", "rustfmt-config_proc_macro"]); +tool_doc!(Clippy, "src/tools/clippy", crates = ["clippy_config", "clippy_utils"]); +tool_doc!(Miri, "src/tools/miri", crates = ["miri"]); tool_doc!( Cargo, - "cargo", "src/tools/cargo", rustc_tool = false, - in_tree = false, crates = [ "cargo", "cargo-credential", @@ -1034,12 +1029,12 @@ tool_doc!( "crates-io", "mdman", "rustfix", - ] + ], + submodule = "src/tools/cargo" ); -tool_doc!(Tidy, "tidy", "src/tools/tidy", rustc_tool = false, crates = ["tidy"]); +tool_doc!(Tidy, "src/tools/tidy", rustc_tool = false, crates = ["tidy"]); tool_doc!( Bootstrap, - "bootstrap", "src/bootstrap", rustc_tool = false, is_library = true, @@ -1047,7 +1042,6 @@ tool_doc!( ); tool_doc!( RunMakeSupport, - "run_make_support", "src/tools/run-make-support", rustc_tool = false, is_library = true, From 51f6e68559bdef1a1b16b3d026552eab51b5f389 Mon Sep 17 00:00:00 2001 From: onur-ozkan Date: Fri, 14 Jun 2024 12:32:34 +0300 Subject: [PATCH 298/892] handle cargo submodule in a lazy-load way Signed-off-by: onur-ozkan --- src/bootstrap/src/core/build_steps/test.rs | 3 +++ src/bootstrap/src/core/build_steps/tool.rs | 2 ++ src/bootstrap/src/core/build_steps/vendor.rs | 5 ++++- 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index efc09c41bf429..1ef5af7cc2daf 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -2983,6 +2983,9 @@ impl Step for Bootstrap { let compiler = builder.compiler(0, host); let _guard = builder.msg(Kind::Test, 0, "bootstrap", host, host); + // Some tests require cargo submodule to be present. + builder.build.update_submodule(Path::new("src/tools/cargo")); + let mut check_bootstrap = Command::new(builder.python()); check_bootstrap .args(["-m", "unittest", "bootstrap_test.py"]) diff --git a/src/bootstrap/src/core/build_steps/tool.rs b/src/bootstrap/src/core/build_steps/tool.rs index 850c8bfe2f8b9..d909a39b60a61 100644 --- a/src/bootstrap/src/core/build_steps/tool.rs +++ b/src/bootstrap/src/core/build_steps/tool.rs @@ -654,6 +654,8 @@ impl Step for Cargo { } fn run(self, builder: &Builder<'_>) -> PathBuf { + builder.build.update_submodule(Path::new("src/tools/cargo")); + builder.ensure(ToolBuild { compiler: self.compiler, target: self.target, diff --git a/src/bootstrap/src/core/build_steps/vendor.rs b/src/bootstrap/src/core/build_steps/vendor.rs index 68f1b1bef3f39..e92ab57619b6a 100644 --- a/src/bootstrap/src/core/build_steps/vendor.rs +++ b/src/bootstrap/src/core/build_steps/vendor.rs @@ -1,5 +1,5 @@ use crate::core::builder::{Builder, RunConfig, ShouldRun, Step}; -use std::path::PathBuf; +use std::path::{Path, PathBuf}; use std::process::Command; #[derive(Debug, Clone, Hash, PartialEq, Eq)] @@ -34,6 +34,9 @@ impl Step for Vendor { cmd.arg("--versioned-dirs"); } + // cargo submodule must be present for `x vendor` to work. + builder.build.update_submodule(Path::new("src/tools/cargo")); + // Sync these paths by default. for p in [ "src/tools/cargo/Cargo.toml", From ac670721c90985af11ddfe7d00b6ffcb8b5d226d Mon Sep 17 00:00:00 2001 From: Jubilee Young Date: Mon, 24 Jun 2024 16:22:47 -0700 Subject: [PATCH 299/892] test: dont optimize to invalid bitcasts --- tests/ui/simd/dont-invalid-bitcast-masks.rs | 17 ++++++++++++ tests/ui/simd/dont-invalid-bitcast-x86_64.rs | 27 ++++++++++++++++++++ 2 files changed, 44 insertions(+) create mode 100644 tests/ui/simd/dont-invalid-bitcast-masks.rs create mode 100644 tests/ui/simd/dont-invalid-bitcast-x86_64.rs diff --git a/tests/ui/simd/dont-invalid-bitcast-masks.rs b/tests/ui/simd/dont-invalid-bitcast-masks.rs new file mode 100644 index 0000000000000..3d8376207cd07 --- /dev/null +++ b/tests/ui/simd/dont-invalid-bitcast-masks.rs @@ -0,0 +1,17 @@ +//@ build-pass +//@ compile-flags: -Copt-level=3 + +// regression test for https://github.com/rust-lang/rust/issues/110722 +// in --release we were optimizing to invalid bitcasts, due to a combination of MIR inlining and +// mostly bad repr(simd) lowering which prevented even basic splats from working +#![crate_type = "rlib"] +#![feature(portable_simd)] +use std::simd::*; +use std::simd::num::*; + +pub unsafe fn mask_to_array(mask: u8) -> [i32; 8] { + let mut output = [0; 8]; + let m = masksizex8::from_bitmask(mask as _); + output.copy_from_slice(&m.to_int().cast::().to_array()); + output +} diff --git a/tests/ui/simd/dont-invalid-bitcast-x86_64.rs b/tests/ui/simd/dont-invalid-bitcast-x86_64.rs new file mode 100644 index 0000000000000..e6e435bcfc902 --- /dev/null +++ b/tests/ui/simd/dont-invalid-bitcast-x86_64.rs @@ -0,0 +1,27 @@ +//@ build-pass +//@ compile-flags: -Copt-level=3 +//@ only-x86_64 +// ignore-tidy-linelength + +// regression test for https://github.com/rust-lang/rust/issues/110707 +// in --release we were optimizing to invalid bitcasts, due to a combination of MIR inlining and +// mostly bad repr(simd) lowering which prevented even basic splats from working + +#![crate_type = "rlib"] +#![feature(portable_simd)] +use std::simd::*; +use std::arch::x86_64::*; + +#[target_feature(enable = "sse4.1")] +pub unsafe fn fast_round_sse(i: f32x8) -> f32x8 { + let a = i.to_array(); + let [low, high]: [[f32; 4]; 2] = + unsafe { std::mem::transmute::<[f32; 8], [[f32; 4]; 2]>(a) }; + + let low = f32x4::from(_mm_round_ps::<{_MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC}>(f32x4::from_array(low).into())); + let high = f32x4::from(_mm_round_ps::<{_MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC}>(f32x4::from_array(high).into())); + + let a: [f32; 8] = + unsafe { std::mem::transmute::<[[f32; 4]; 2], [f32; 8]>([low.to_array(), high.to_array()]) }; + f32x8::from_array(a) +} From a82f70eeee6d79fb4c3417da738279d3d7ff599a Mon Sep 17 00:00:00 2001 From: he1pa <18012015693@163.com> Date: Tue, 25 Jun 2024 18:04:21 +0800 Subject: [PATCH 300/892] Migrate some rustc_builtin_macros to SessionDiagnostic Signed-off-by: he1pa <18012015693@163.com> --- compiler/rustc_builtin_macros/messages.ftl | 11 +++++ compiler/rustc_builtin_macros/src/asm.rs | 13 +++--- compiler/rustc_builtin_macros/src/errors.rs | 40 +++++++++++++++++++ .../src/proc_macro_harness.rs | 24 +++++------ .../rustc_builtin_macros/src/source_util.rs | 11 +++-- 5 files changed, 76 insertions(+), 23 deletions(-) diff --git a/compiler/rustc_builtin_macros/messages.ftl b/compiler/rustc_builtin_macros/messages.ftl index 2d1269e1b6ad8..b56bfa98357b3 100644 --- a/compiler/rustc_builtin_macros/messages.ftl +++ b/compiler/rustc_builtin_macros/messages.ftl @@ -17,6 +17,9 @@ builtin_macros_asm_expected_other = expected operand, {$is_global_asm -> *[false] clobber_abi, options }, or additional template string +builtin_macros_asm_expected_string_literal = expected string literal + .label = not a string literal + builtin_macros_asm_explicit_register_name = explicit register arguments cannot have names builtin_macros_asm_mayunwind = asm labels are not allowed with the `may_unwind` option @@ -25,6 +28,8 @@ builtin_macros_asm_modifier_invalid = asm template modifier must be a single cha builtin_macros_asm_mutually_exclusive = the `{$opt1}` and `{$opt2}` options are mutually exclusive +builtin_macros_asm_no_matched_argument_name = there is no argument named `{$name}` + builtin_macros_asm_noreturn = asm outputs are not allowed with the `noreturn` option builtin_macros_asm_opt_already_provided = the `{$symbol}` option was already provided @@ -228,10 +233,16 @@ builtin_macros_only_one_argument = {$name} takes 1 argument builtin_macros_proc_macro = `proc-macro` crate types currently cannot export any items other than functions tagged with `#[proc_macro]`, `#[proc_macro_derive]`, or `#[proc_macro_attribute]` +builtin_macros_proc_macro_attribute_only_be_used_on_bare_functions = the `#[{$path}]` attribute may only be used on bare functions + +builtin_macros_proc_macro_attribute_only_usable_with_crate_type = the `#[{$path}]` attribute is only usable with crates of the `proc-macro` crate type + builtin_macros_requires_cfg_pattern = macro requires a cfg-pattern as an argument .label = cfg-pattern required +builtin_macros_source_uitls_expected_item = expected item, found `{$token}` + builtin_macros_takes_no_arguments = {$name} takes no arguments builtin_macros_test_bad_fn = {$kind} functions cannot be used for tests diff --git a/compiler/rustc_builtin_macros/src/asm.rs b/compiler/rustc_builtin_macros/src/asm.rs index 64238e81b2666..dd0f9aaf22104 100644 --- a/compiler/rustc_builtin_macros/src/asm.rs +++ b/compiler/rustc_builtin_macros/src/asm.rs @@ -390,9 +390,7 @@ fn parse_clobber_abi<'a>(p: &mut Parser<'a>, args: &mut AsmArgs) -> PResult<'a, } Err(opt_lit) => { let span = opt_lit.map_or(p.token.span, |lit| lit.span); - let mut err = p.dcx().struct_span_err(span, "expected string literal"); - err.span_label(span, "not a string literal"); - return Err(err); + return Err(p.dcx().create_err(errors::AsmExpectedStringLiteral { span })); } }; @@ -639,14 +637,13 @@ fn expand_preparsed_asm( match args.named_args.get(&Symbol::intern(name)) { Some(&idx) => Some(idx), None => { - let msg = format!("there is no argument named `{name}`"); let span = arg.position_span; ecx.dcx() - .struct_span_err( - template_span + .create_err(errors::AsmNoMatchedArgumentName { + name: name.to_owned(), + span: template_span .from_inner(InnerSpan::new(span.start, span.end)), - msg, - ) + }) .emit(); None } diff --git a/compiler/rustc_builtin_macros/src/errors.rs b/compiler/rustc_builtin_macros/src/errors.rs index ed2f98f2a393c..49d640436c2f3 100644 --- a/compiler/rustc_builtin_macros/src/errors.rs +++ b/compiler/rustc_builtin_macros/src/errors.rs @@ -728,6 +728,14 @@ pub(crate) struct AsmExpectedComma { pub(crate) span: Span, } +#[derive(Diagnostic)] +#[diag(builtin_macros_asm_expected_string_literal)] +pub(crate) struct AsmExpectedStringLiteral { + #[primary_span] + #[label] + pub(crate) span: Span, +} + #[derive(Diagnostic)] #[diag(builtin_macros_asm_underscore_input)] pub(crate) struct AsmUnderscoreInput { @@ -781,6 +789,14 @@ pub(crate) struct AsmNoReturn { pub(crate) outputs_sp: Vec, } +#[derive(Diagnostic)] +#[diag(builtin_macros_asm_no_matched_argument_name)] +pub(crate) struct AsmNoMatchedArgumentName { + pub(crate) name: String, + #[primary_span] + pub(crate) span: Span, +} + #[derive(Diagnostic)] #[diag(builtin_macros_asm_mayunwind)] pub(crate) struct AsmMayUnwind { @@ -872,3 +888,27 @@ pub(crate) struct TakesNoArguments<'a> { pub span: Span, pub name: &'a str, } + +#[derive(Diagnostic)] +#[diag(builtin_macros_proc_macro_attribute_only_be_used_on_bare_functions)] +pub(crate) struct AttributeOnlyBeUsedOnBareFunctions<'a> { + #[primary_span] + pub span: Span, + pub path: &'a str, +} + +#[derive(Diagnostic)] +#[diag(builtin_macros_proc_macro_attribute_only_usable_with_crate_type)] +pub(crate) struct AttributeOnlyUsableWithCrateType<'a> { + #[primary_span] + pub span: Span, + pub path: &'a str, +} + +#[derive(Diagnostic)] +#[diag(builtin_macros_source_uitls_expected_item)] +pub(crate) struct ExpectedItem<'a> { + #[primary_span] + pub span: Span, + pub token: &'a str, +} diff --git a/compiler/rustc_builtin_macros/src/proc_macro_harness.rs b/compiler/rustc_builtin_macros/src/proc_macro_harness.rs index 99d0191958d68..a8a595ea5796f 100644 --- a/compiler/rustc_builtin_macros/src/proc_macro_harness.rs +++ b/compiler/rustc_builtin_macros/src/proc_macro_harness.rs @@ -214,12 +214,12 @@ impl<'a> Visitor<'a> for CollectProcMacros<'a> { }; if !is_fn { - let msg = format!( - "the `#[{}]` attribute may only be used on bare functions", - pprust::path_to_string(&attr.get_normal_item().path), - ); - - self.dcx.span_err(attr.span, msg); + self.dcx + .create_err(errors::AttributeOnlyBeUsedOnBareFunctions { + span: attr.span, + path: &pprust::path_to_string(&attr.get_normal_item().path), + }) + .emit(); return; } @@ -228,12 +228,12 @@ impl<'a> Visitor<'a> for CollectProcMacros<'a> { } if !self.is_proc_macro_crate { - let msg = format!( - "the `#[{}]` attribute is only usable with crates of the `proc-macro` crate type", - pprust::path_to_string(&attr.get_normal_item().path), - ); - - self.dcx.span_err(attr.span, msg); + self.dcx + .create_err(errors::AttributeOnlyUsableWithCrateType { + span: attr.span, + path: &pprust::path_to_string(&attr.get_normal_item().path), + }) + .emit(); return; } diff --git a/compiler/rustc_builtin_macros/src/source_util.rs b/compiler/rustc_builtin_macros/src/source_util.rs index dc1d82df0c395..44db12cf69502 100644 --- a/compiler/rustc_builtin_macros/src/source_util.rs +++ b/compiler/rustc_builtin_macros/src/source_util.rs @@ -1,3 +1,4 @@ +use crate::errors; use crate::util::{ check_zero_tts, get_single_str_from_tts, get_single_str_spanned_from_tts, parse_expr, }; @@ -165,9 +166,13 @@ pub(crate) fn expand_include<'cx>( Ok(Some(item)) => ret.push(item), Ok(None) => { if self.p.token != token::Eof { - let token = pprust::token_to_string(&self.p.token); - let msg = format!("expected item, found `{token}`"); - self.p.dcx().span_err(self.p.token.span, msg); + self.p + .dcx() + .create_err(errors::ExpectedItem { + span: self.p.token.span, + token: &pprust::token_to_string(&self.p.token), + }) + .emit(); } break; From 16e1ad7327b070a11d4bbf01a343c24e2dd34553 Mon Sep 17 00:00:00 2001 From: Antoni Boucher Date: Tue, 25 Jun 2024 08:10:29 -0400 Subject: [PATCH 301/892] Fix clippy warnings --- src/context.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/context.rs b/src/context.rs index 6beed91270bd5..5ece10cc70d12 100644 --- a/src/context.rs +++ b/src/context.rs @@ -129,6 +129,7 @@ pub struct CodegenCx<'gcc, 'tcx> { } impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { + #[allow(clippy::too_many_arguments)] pub fn new( context: &'gcc Context<'gcc>, codegen_unit: &'tcx CodegenUnit<'tcx>, From 6896fa66198a4119dfe7d0350137c5fab99eea8b Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 8 Jun 2024 19:24:32 +0200 Subject: [PATCH 302/892] simd_bitmask intrinsic: add a non-power-of-2 multi-byte example --- library/core/src/intrinsics/simd.rs | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/library/core/src/intrinsics/simd.rs b/library/core/src/intrinsics/simd.rs index 4be5e62ea5bc6..6054ff8b2ccb5 100644 --- a/library/core/src/intrinsics/simd.rs +++ b/library/core/src/intrinsics/simd.rs @@ -463,7 +463,7 @@ extern "rust-intrinsic" { /// `T` must be an integer vector. /// /// `U` must be either the smallest unsigned integer with at least as many bits as the length - /// of `T`, or the smallest array of `u8` with as many bits as the length of `T`. + /// of `T`, or the smallest array of `u8` with at least as many bits as the length of `T`. /// /// Each element is truncated to a single bit and packed into the result. /// @@ -475,12 +475,19 @@ extern "rust-intrinsic" { /// * On little endian, the least significant bit corresponds to the first vector element. /// * On big endian, the least significant bit corresponds to the last vector element. /// - /// For example, `[!0, 0, !0, !0]` packs to `0b1101` on little endian and `0b1011` on big - /// endian. + /// For example, `[!0, 0, !0, !0]` packs to + /// - `0b1101u8` or `[0b1101]` on little endian, and + /// - `0b1011u8` or `[0b1011]` on big endian. /// - /// To consider a larger example, `[!0, 0, 0, 0, 0, 0, 0, 0, !0, !0, 0, 0, 0, 0, !0, 0]` packs - /// to `[0b00000001, 0b01000011]` or `0b0100001100000001` on little endian, and `[0b10000000, - /// 0b11000010]` or `0b1000000011000010` on big endian. + /// To consider a larger example, + /// `[!0, 0, 0, 0, 0, 0, 0, 0, !0, !0, 0, 0, 0, 0, !0, 0]` packs to + /// - `0b0100001100000001u16` or `[0b00000001, 0b01000011]` on little endian, and + /// - `0b1000000011000010u16` or `[0b10000000, 0b11000010]` on big endian. + /// + /// And finally, a non-power-of-2 example with multiple bytes: + /// `[!0, !0, 0, !0, 0, 0, !0, 0, !0, 0]` packs to + /// - `0b0101001011u16` or `[0b01001011, 0b01]` on little endian, and + /// - `0b1101001010u16` or `[0b11, 0b01001010]` on big endian. /// /// # Safety /// `x` must contain only `0` and `!0`. From 73db24970f86e6495db1548b235334ed98ba8a6a Mon Sep 17 00:00:00 2001 From: Antoni Boucher Date: Tue, 25 Jun 2024 08:43:48 -0400 Subject: [PATCH 303/892] Add comment about compiler_builtins --- build_system/build_sysroot/Cargo.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/build_system/build_sysroot/Cargo.toml b/build_system/build_sysroot/Cargo.toml index d0d21a044fd12..e466992362386 100644 --- a/build_system/build_sysroot/Cargo.toml +++ b/build_system/build_sysroot/Cargo.toml @@ -6,6 +6,7 @@ resolver = "2" [dependencies] core = { path = "./sysroot_src/library/core" } +# TODO: after the sync, revert to using version 0.1. # compiler_builtins = "0.1" compiler_builtins = "=0.1.109" alloc = { path = "./sysroot_src/library/alloc" } From 9274c63df3f584a58d4f916a4de2871c2e92621d Mon Sep 17 00:00:00 2001 From: Antoni Boucher Date: Tue, 25 Jun 2024 09:00:36 -0400 Subject: [PATCH 304/892] Change Void to unreachable --- src/type_.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/type_.rs b/src/type_.rs index 093ddbf8137c3..184367e9cde1c 100644 --- a/src/type_.rs +++ b/src/type_.rs @@ -206,7 +206,7 @@ impl<'gcc, 'tcx> BaseTypeMethods<'tcx> for CodegenCx<'gcc, 'tcx> { 4 => TypeKind::Float, 8 => TypeKind::Double, 16 => TypeKind::FP128, - _ => TypeKind::Void, + size => unreachable!("Floating-point type of size {}", size), } } else if typ == self.type_void() { TypeKind::Void From 1b4c281fe7c37218fe6444dd667d79651adf337c Mon Sep 17 00:00:00 2001 From: xFrednet Date: Sat, 10 Feb 2024 22:31:36 +0000 Subject: [PATCH 305/892] RFC 2383: Stabilize `lint_reasons` in Clippy :paperclips: --- CHANGELOG.md | 2 +- book/src/lint_configuration.md | 2 + clippy_config/src/conf.rs | 2 +- clippy_config/src/msrvs.rs | 1 + clippy_lints/src/allow_attributes.rs | 74 ------------ clippy_lints/src/attrs/allow_attributes.rs | 26 +++++ .../attrs/allow_attributes_without_reason.rs | 5 - clippy_lints/src/attrs/mod.rs | 71 ++++++++++-- clippy_lints/src/declared_lints.rs | 2 +- clippy_lints/src/lib.rs | 6 +- clippy_utils/src/lib.rs | 2 +- src/driver.rs | 2 +- tests/ui-cargo/duplicate_mod/fail/src/main.rs | 1 - .../default/test.stderr | 11 +- .../undocumented_unsafe_blocks.default.stderr | 74 ++++++------ ...undocumented_unsafe_blocks.disabled.stderr | 94 ++++++++-------- .../undocumented_unsafe_blocks.rs | 1 - tests/ui/allow_attributes.fixed | 13 ++- tests/ui/allow_attributes.rs | 13 ++- tests/ui/allow_attributes.stderr | 20 +++- tests/ui/allow_attributes_without_reason.rs | 13 ++- .../ui/allow_attributes_without_reason.stderr | 29 ++++- tests/ui/async_yields_async.fixed | 1 - tests/ui/async_yields_async.rs | 1 - tests/ui/async_yields_async.stderr | 12 +- tests/ui/boxed_local.rs | 1 - tests/ui/boxed_local.stderr | 8 +- .../ui/checked_unwrap/simple_conditionals.rs | 1 - .../checked_unwrap/simple_conditionals.stderr | 54 ++++----- tests/ui/default_numeric_fallback_i32.fixed | 1 - tests/ui/default_numeric_fallback_i32.rs | 1 - tests/ui/default_numeric_fallback_i32.stderr | 56 ++++----- tests/ui/derive_partial_eq_without_eq.fixed | 1 - tests/ui/derive_partial_eq_without_eq.rs | 1 - tests/ui/derive_partial_eq_without_eq.stderr | 26 ++--- tests/ui/expect_tool_lint_rfc_2383.rs | 1 - tests/ui/expect_tool_lint_rfc_2383.stderr | 12 +- tests/ui/implicit_return.fixed | 1 - tests/ui/implicit_return.rs | 1 - tests/ui/implicit_return.stderr | 32 +++--- tests/ui/let_unit.fixed | 1 - tests/ui/let_unit.rs | 1 - tests/ui/let_unit.stderr | 8 +- tests/ui/macro_use_imports.fixed | 1 - tests/ui/macro_use_imports.rs | 1 - tests/ui/macro_use_imports.stderr | 8 +- tests/ui/macro_use_imports_expect.rs | 1 - tests/ui/manual_non_exhaustive_enum.rs | 1 - tests/ui/manual_non_exhaustive_enum.stderr | 8 +- tests/ui/needless_borrow.fixed | 1 - tests/ui/needless_borrow.rs | 1 - tests/ui/needless_borrow.stderr | 56 ++++----- tests/ui/needless_pass_by_ref_mut.rs | 1 - tests/ui/needless_pass_by_ref_mut.stderr | 68 +++++------ tests/ui/needless_return.fixed | 1 - tests/ui/needless_return.rs | 1 - tests/ui/needless_return.stderr | 106 +++++++++--------- tests/ui/nonminimal_bool.rs | 2 - tests/ui/nonminimal_bool.stderr | 58 +++++----- tests/ui/overly_complex_bool_expr.fixed | 1 - tests/ui/overly_complex_bool_expr.rs | 1 - tests/ui/overly_complex_bool_expr.stderr | 20 ++-- tests/ui/ptr_arg.rs | 1 - tests/ui/ptr_arg.stderr | 48 ++++---- tests/ui/redundant_clone.fixed | 1 - tests/ui/redundant_clone.rs | 1 - tests/ui/redundant_clone.stderr | 60 +++++----- tests/ui/ref_binding_to_reference.rs | 1 - tests/ui/ref_binding_to_reference.stderr | 14 +-- tests/ui/same_name_method.rs | 1 - tests/ui/same_name_method.stderr | 24 ++-- tests/ui/unsafe_derive_deserialize.rs | 1 - tests/ui/unsafe_derive_deserialize.stderr | 8 +- tests/ui/used_underscore_binding.rs | 2 +- 74 files changed, 611 insertions(+), 573 deletions(-) delete mode 100644 clippy_lints/src/allow_attributes.rs create mode 100644 clippy_lints/src/attrs/allow_attributes.rs diff --git a/CHANGELOG.md b/CHANGELOG.md index d7bcd7a19687d..d1cd87473cef4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1943,7 +1943,7 @@ Released 2022-05-19 [#8218](https://github.com/rust-lang/rust-clippy/pull/8218) * [`needless_match`] [#8471](https://github.com/rust-lang/rust-clippy/pull/8471) -* [`allow_attributes_without_reason`] (Requires `#![feature(lint_reasons)]`) +* [`allow_attributes_without_reason`] [#8504](https://github.com/rust-lang/rust-clippy/pull/8504) * [`print_in_format_impl`] [#8253](https://github.com/rust-lang/rust-clippy/pull/8253) diff --git a/book/src/lint_configuration.md b/book/src/lint_configuration.md index c8223007df7b3..6dad3463aa47a 100644 --- a/book/src/lint_configuration.md +++ b/book/src/lint_configuration.md @@ -669,6 +669,8 @@ The minimum rust version that the project supports. Defaults to the `rust-versio --- **Affected lints:** +* [`allow_attributes`](https://rust-lang.github.io/rust-clippy/master/index.html#allow_attributes) +* [`allow_attributes_without_reason`](https://rust-lang.github.io/rust-clippy/master/index.html#allow_attributes_without_reason) * [`almost_complete_range`](https://rust-lang.github.io/rust-clippy/master/index.html#almost_complete_range) * [`approx_constant`](https://rust-lang.github.io/rust-clippy/master/index.html#approx_constant) * [`assigning_clones`](https://rust-lang.github.io/rust-clippy/master/index.html#assigning_clones) diff --git a/clippy_config/src/conf.rs b/clippy_config/src/conf.rs index cfdf620b7d074..279193e516e95 100644 --- a/clippy_config/src/conf.rs +++ b/clippy_config/src/conf.rs @@ -265,7 +265,7 @@ define_Conf! { /// /// Suppress lints whenever the suggested change would cause breakage for other crates. (avoid_breaking_exported_api: bool = true), - /// Lint: MANUAL_SPLIT_ONCE, MANUAL_STR_REPEAT, CLONED_INSTEAD_OF_COPIED, REDUNDANT_FIELD_NAMES, OPTION_MAP_UNWRAP_OR, REDUNDANT_STATIC_LIFETIMES, FILTER_MAP_NEXT, CHECKED_CONVERSIONS, MANUAL_RANGE_CONTAINS, USE_SELF, MEM_REPLACE_WITH_DEFAULT, MANUAL_NON_EXHAUSTIVE, OPTION_AS_REF_DEREF, MAP_UNWRAP_OR, MATCH_LIKE_MATCHES_MACRO, MANUAL_STRIP, MISSING_CONST_FOR_FN, UNNESTED_OR_PATTERNS, FROM_OVER_INTO, PTR_AS_PTR, IF_THEN_SOME_ELSE_NONE, APPROX_CONSTANT, DEPRECATED_CFG_ATTR, INDEX_REFUTABLE_SLICE, MAP_CLONE, BORROW_AS_PTR, MANUAL_BITS, ERR_EXPECT, CAST_ABS_TO_UNSIGNED, UNINLINED_FORMAT_ARGS, MANUAL_CLAMP, MANUAL_LET_ELSE, UNCHECKED_DURATION_SUBTRACTION, COLLAPSIBLE_STR_REPLACE, SEEK_FROM_CURRENT, SEEK_REWIND, UNNECESSARY_LAZY_EVALUATIONS, TRANSMUTE_PTR_TO_REF, ALMOST_COMPLETE_RANGE, NEEDLESS_BORROW, DERIVABLE_IMPLS, MANUAL_IS_ASCII_CHECK, MANUAL_REM_EUCLID, MANUAL_RETAIN, TYPE_REPETITION_IN_BOUNDS, TUPLE_ARRAY_CONVERSIONS, MANUAL_TRY_FOLD, MANUAL_HASH_ONE, ITER_KV_MAP, MANUAL_C_STR_LITERALS, ASSIGNING_CLONES, LEGACY_NUMERIC_CONSTANTS. + /// Lint: MANUAL_SPLIT_ONCE, MANUAL_STR_REPEAT, CLONED_INSTEAD_OF_COPIED, REDUNDANT_FIELD_NAMES, OPTION_MAP_UNWRAP_OR, REDUNDANT_STATIC_LIFETIMES, FILTER_MAP_NEXT, CHECKED_CONVERSIONS, MANUAL_RANGE_CONTAINS, USE_SELF, MEM_REPLACE_WITH_DEFAULT, MANUAL_NON_EXHAUSTIVE, OPTION_AS_REF_DEREF, MAP_UNWRAP_OR, MATCH_LIKE_MATCHES_MACRO, MANUAL_STRIP, MISSING_CONST_FOR_FN, UNNESTED_OR_PATTERNS, FROM_OVER_INTO, PTR_AS_PTR, IF_THEN_SOME_ELSE_NONE, APPROX_CONSTANT, DEPRECATED_CFG_ATTR, INDEX_REFUTABLE_SLICE, MAP_CLONE, BORROW_AS_PTR, MANUAL_BITS, ERR_EXPECT, CAST_ABS_TO_UNSIGNED, UNINLINED_FORMAT_ARGS, MANUAL_CLAMP, MANUAL_LET_ELSE, UNCHECKED_DURATION_SUBTRACTION, COLLAPSIBLE_STR_REPLACE, SEEK_FROM_CURRENT, SEEK_REWIND, UNNECESSARY_LAZY_EVALUATIONS, TRANSMUTE_PTR_TO_REF, ALMOST_COMPLETE_RANGE, NEEDLESS_BORROW, DERIVABLE_IMPLS, MANUAL_IS_ASCII_CHECK, MANUAL_REM_EUCLID, MANUAL_RETAIN, TYPE_REPETITION_IN_BOUNDS, TUPLE_ARRAY_CONVERSIONS, MANUAL_TRY_FOLD, MANUAL_HASH_ONE, ITER_KV_MAP, MANUAL_C_STR_LITERALS, ASSIGNING_CLONES, LEGACY_NUMERIC_CONSTANTS, ALLOW_ATTRIBUTES, ALLOW_ATTRIBUTES_WITHOUT_REASON. /// /// The minimum rust version that the project supports. Defaults to the `rust-version` field in `Cargo.toml` #[default_text = ""] diff --git a/clippy_config/src/msrvs.rs b/clippy_config/src/msrvs.rs index a3e7d0c3fa5fe..8bdb5b317e5d9 100644 --- a/clippy_config/src/msrvs.rs +++ b/clippy_config/src/msrvs.rs @@ -17,6 +17,7 @@ macro_rules! msrv_aliases { // names may refer to stabilized feature flags or library items msrv_aliases! { + 1,81,0 { LINT_REASONS_STABILIZATION } 1,77,0 { C_STR_LITERALS } 1,76,0 { PTR_FROM_REF } 1,71,0 { TUPLE_ARRAY_CONVERSIONS, BUILD_HASHER_HASH_ONE } diff --git a/clippy_lints/src/allow_attributes.rs b/clippy_lints/src/allow_attributes.rs deleted file mode 100644 index 123d0e51eeee2..0000000000000 --- a/clippy_lints/src/allow_attributes.rs +++ /dev/null @@ -1,74 +0,0 @@ -use ast::{AttrStyle, Attribute}; -use clippy_utils::diagnostics::span_lint_and_sugg; -use clippy_utils::is_from_proc_macro; -use rustc_ast as ast; -use rustc_errors::Applicability; -use rustc_lint::{LateContext, LateLintPass, LintContext}; -use rustc_middle::lint::in_external_macro; -use rustc_session::declare_lint_pass; - -declare_clippy_lint! { - /// ### What it does - /// Checks for usage of the `#[allow]` attribute and suggests replacing it with - /// the `#[expect]` (See [RFC 2383](https://rust-lang.github.io/rfcs/2383-lint-reasons.html)) - /// - /// The expect attribute is still unstable and requires the `lint_reasons` - /// on nightly. It can be enabled by adding `#![feature(lint_reasons)]` to - /// the crate root. - /// - /// This lint only warns outer attributes (`#[allow]`), as inner attributes - /// (`#![allow]`) are usually used to enable or disable lints on a global scale. - /// - /// ### Why restrict this? - /// `#[allow]` attributes can linger after their reason for existence is gone. - /// `#[expect]` attributes suppress the lint emission, but emit a warning if - /// the expectation is unfulfilled. This can be useful to be notified when the - /// lint is no longer triggered, which may indicate the attribute can be removed. - /// - /// ### Example - /// ```rust,ignore - /// #[allow(unused_mut)] - /// fn foo() -> usize { - /// let mut a = Vec::new(); - /// a.len() - /// } - /// ``` - /// Use instead: - /// ```rust,ignore - /// #![feature(lint_reasons)] - /// #[expect(unused_mut)] - /// fn foo() -> usize { - /// let mut a = Vec::new(); - /// a.len() - /// } - /// ``` - #[clippy::version = "1.70.0"] - pub ALLOW_ATTRIBUTES, - restriction, - "`#[allow]` will not trigger if a warning isn't found. `#[expect]` triggers if there are no warnings." -} - -declare_lint_pass!(AllowAttribute => [ALLOW_ATTRIBUTES]); - -impl LateLintPass<'_> for AllowAttribute { - // Separate each crate's features. - fn check_attribute<'cx>(&mut self, cx: &LateContext<'cx>, attr: &'cx Attribute) { - if !in_external_macro(cx.sess(), attr.span) - && cx.tcx.features().lint_reasons - && let AttrStyle::Outer = attr.style - && let Some(ident) = attr.ident() - && ident.name == rustc_span::symbol::sym::allow - && !is_from_proc_macro(cx, &attr) - { - span_lint_and_sugg( - cx, - ALLOW_ATTRIBUTES, - ident.span, - "#[allow] attribute found", - "replace it with", - "expect".into(), - Applicability::MachineApplicable, - ); - } - } -} diff --git a/clippy_lints/src/attrs/allow_attributes.rs b/clippy_lints/src/attrs/allow_attributes.rs new file mode 100644 index 0000000000000..c5b6980b0b900 --- /dev/null +++ b/clippy_lints/src/attrs/allow_attributes.rs @@ -0,0 +1,26 @@ +use clippy_utils::diagnostics::span_lint_and_sugg; +use clippy_utils::is_from_proc_macro; +use rustc_ast::{AttrStyle, Attribute}; +use rustc_errors::Applicability; +use rustc_lint::{LateContext, LintContext}; +use rustc_middle::lint::in_external_macro; +use super::ALLOW_ATTRIBUTES; + +// Separate each crate's features. +pub fn check<'cx>(cx: &LateContext<'cx>, attr: &'cx Attribute) { + if !in_external_macro(cx.sess(), attr.span) + && let AttrStyle::Outer = attr.style + && let Some(ident) = attr.ident() + && !is_from_proc_macro(cx, &attr) + { + span_lint_and_sugg( + cx, + ALLOW_ATTRIBUTES, + ident.span, + "#[allow] attribute found", + "replace it with", + "expect".into(), + Applicability::MachineApplicable, + ); + } +} diff --git a/clippy_lints/src/attrs/allow_attributes_without_reason.rs b/clippy_lints/src/attrs/allow_attributes_without_reason.rs index 4a22e17463fcc..8bf985a36c7a2 100644 --- a/clippy_lints/src/attrs/allow_attributes_without_reason.rs +++ b/clippy_lints/src/attrs/allow_attributes_without_reason.rs @@ -8,11 +8,6 @@ use rustc_span::sym; use rustc_span::symbol::Symbol; pub(super) fn check<'cx>(cx: &LateContext<'cx>, name: Symbol, items: &[NestedMetaItem], attr: &'cx Attribute) { - // Check for the feature - if !cx.tcx.features().lint_reasons { - return; - } - // Check if the reason is present if let Some(item) = items.last().and_then(NestedMetaItem::meta_item) && let MetaItemKind::NameValue(_) = &item.kind diff --git a/clippy_lints/src/attrs/mod.rs b/clippy_lints/src/attrs/mod.rs index e4c98a32fd673..da19f17998aff 100644 --- a/clippy_lints/src/attrs/mod.rs +++ b/clippy_lints/src/attrs/mod.rs @@ -1,6 +1,7 @@ //! checks for attributes mod allow_attributes_without_reason; +mod allow_attributes; mod blanket_clippy_restriction_lints; mod deprecated_cfg_attr; mod deprecated_semver; @@ -14,11 +15,11 @@ mod unnecessary_clippy_cfg; mod useless_attribute; mod utils; -use clippy_config::msrvs::Msrv; +use clippy_config::msrvs::{self, Msrv}; use rustc_ast::{Attribute, MetaItemKind, NestedMetaItem}; use rustc_hir::{ImplItem, Item, ItemKind, TraitItem}; use rustc_lint::{EarlyContext, EarlyLintPass, LateContext, LateLintPass}; -use rustc_session::{declare_lint_pass, impl_lint_pass}; +use rustc_session::impl_lint_pass; use rustc_span::sym; use utils::{is_lint_level, is_relevant_impl, is_relevant_item, is_relevant_trait}; @@ -272,23 +273,17 @@ declare_clippy_lint! { /// ### What it does /// Checks for attributes that allow lints without a reason. /// - /// (This requires the `lint_reasons` feature) - /// /// ### Why restrict this? /// Justifying each `allow` helps readers understand the reasoning, /// and may allow removing `allow` attributes if their purpose is obsolete. /// /// ### Example /// ```no_run - /// #![feature(lint_reasons)] - /// /// #![allow(clippy::some_lint)] /// ``` /// /// Use instead: /// ```no_run - /// #![feature(lint_reasons)] - /// /// #![allow(clippy::some_lint, reason = "False positive rust-lang/rust-clippy#1002020")] /// ``` #[clippy::version = "1.61.0"] @@ -297,6 +292,41 @@ declare_clippy_lint! { "ensures that all `allow` and `expect` attributes have a reason" } +declare_clippy_lint! { + /// ### What it does + /// Checks for usage of the `#[allow]` attribute and suggests replacing it with + /// the `#[expect]` (See [RFC 2383](https://rust-lang.github.io/rfcs/2383-lint-reasons.html)) + /// + /// This lint only warns outer attributes (`#[allow]`), as inner attributes + /// (`#![allow]`) are usually used to enable or disable lints on a global scale. + /// + /// ### Why is this bad? + /// `#[expect]` attributes suppress the lint emission, but emit a warning, if + /// the expectation is unfulfilled. This can be useful to be notified when the + /// lint is no longer triggered. + /// + /// ### Example + /// ```rust,ignore + /// #[allow(unused_mut)] + /// fn foo() -> usize { + /// let mut a = Vec::new(); + /// a.len() + /// } + /// ``` + /// Use instead: + /// ```rust,ignore + /// #[expect(unused_mut)] + /// fn foo() -> usize { + /// let mut a = Vec::new(); + /// a.len() + /// } + /// ``` + #[clippy::version = "1.70.0"] + pub ALLOW_ATTRIBUTES, + restriction, + "`#[allow]` will not trigger if a warning isn't found. `#[expect]` triggers if there are no warnings." +} + declare_clippy_lint! { /// ### What it does /// Checks for `#[should_panic]` attributes without specifying the expected panic message. @@ -469,7 +499,12 @@ declare_clippy_lint! { "duplicated attribute" } -declare_lint_pass!(Attributes => [ +#[derive(Clone)] +pub struct Attributes { + msrv: Msrv, +} + +impl_lint_pass!(Attributes => [ ALLOW_ATTRIBUTES_WITHOUT_REASON, INLINE_ALWAYS, DEPRECATED_SEMVER, @@ -480,6 +515,13 @@ declare_lint_pass!(Attributes => [ DUPLICATED_ATTRIBUTES, ]); +impl Attributes { + #[must_use] + pub fn new(msrv: Msrv) -> Self { + Self { msrv } + } +} + impl<'tcx> LateLintPass<'tcx> for Attributes { fn check_crate(&mut self, cx: &LateContext<'tcx>) { blanket_clippy_restriction_lints::check_command_line(cx); @@ -492,8 +534,15 @@ impl<'tcx> LateLintPass<'tcx> for Attributes { if is_lint_level(ident.name, attr.id) { blanket_clippy_restriction_lints::check(cx, ident.name, items); } + if matches!(ident.name, sym::allow) { + if self.msrv.meets(msrvs::LINT_REASONS_STABILIZATION) { + allow_attributes::check(cx, attr); + } + } if matches!(ident.name, sym::allow | sym::expect) { - allow_attributes_without_reason::check(cx, ident.name, items, attr); + if self.msrv.meets(msrvs::LINT_REASONS_STABILIZATION) { + allow_attributes_without_reason::check(cx, ident.name, items, attr); + } } if items.is_empty() || !attr.has_name(sym::deprecated) { return; @@ -537,6 +586,8 @@ impl<'tcx> LateLintPass<'tcx> for Attributes { inline_always::check(cx, item.span, item.ident.name, cx.tcx.hir().attrs(item.hir_id())); } } + + extract_msrv_attr!(LateContext); } pub struct EarlyAttributes { diff --git a/clippy_lints/src/declared_lints.rs b/clippy_lints/src/declared_lints.rs index 7e43a99e9f24f..76a0e450e59aa 100644 --- a/clippy_lints/src/declared_lints.rs +++ b/clippy_lints/src/declared_lints.rs @@ -38,7 +38,6 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[ #[cfg(feature = "internal")] crate::utils::internal_lints::unsorted_clippy_utils_paths::UNSORTED_CLIPPY_UTILS_PATHS_INFO, crate::absolute_paths::ABSOLUTE_PATHS_INFO, - crate::allow_attributes::ALLOW_ATTRIBUTES_INFO, crate::almost_complete_range::ALMOST_COMPLETE_RANGE_INFO, crate::approx_const::APPROX_CONSTANT_INFO, crate::arc_with_non_send_sync::ARC_WITH_NON_SEND_SYNC_INFO, @@ -49,6 +48,7 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[ crate::assertions_on_result_states::ASSERTIONS_ON_RESULT_STATES_INFO, crate::assigning_clones::ASSIGNING_CLONES_INFO, crate::async_yields_async::ASYNC_YIELDS_ASYNC_INFO, + crate::attrs::ALLOW_ATTRIBUTES_INFO, crate::attrs::ALLOW_ATTRIBUTES_WITHOUT_REASON_INFO, crate::attrs::BLANKET_CLIPPY_RESTRICTION_LINTS_INFO, crate::attrs::DEPRECATED_CFG_ATTR_INFO, diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index ef322786dbcd3..63461c14d7790 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -6,7 +6,7 @@ #![feature(if_let_guard)] #![feature(iter_intersperse)] #![feature(let_chains)] -#![feature(lint_reasons)] +#![cfg_attr(bootstrap, feature(lint_reasons))] #![feature(never_type)] #![feature(rustc_private)] #![feature(stmt_expr_attributes)] @@ -73,7 +73,6 @@ mod renamed_lints; // begin lints modules, do not remove this comment, it’s used in `update_lints` mod absolute_paths; -mod allow_attributes; mod almost_complete_range; mod approx_const; mod arc_with_non_send_sync; @@ -699,7 +698,7 @@ pub fn register_lints(store: &mut rustc_lint::LintStore, conf: &'static Conf) { store.register_late_pass(|_| Box::new(mut_reference::UnnecessaryMutPassed)); store.register_late_pass(|_| Box::>::default()); store.register_late_pass(|_| Box::new(len_zero::LenZero)); - store.register_late_pass(|_| Box::new(attrs::Attributes)); + store.register_late_pass(move |_| Box::new(attrs::Attributes::new(msrv()))); store.register_late_pass(|_| Box::new(blocks_in_conditions::BlocksInConditions)); store.register_late_pass(|_| Box::new(unicode::Unicode)); store.register_late_pass(|_| Box::new(uninit_vec::UninitVec)); @@ -1065,7 +1064,6 @@ pub fn register_lints(store: &mut rustc_lint::LintStore, conf: &'static Conf) { store.register_late_pass(|_| Box::new(needless_maybe_sized::NeedlessMaybeSized)); store.register_late_pass(|_| Box::new(redundant_async_block::RedundantAsyncBlock)); store.register_late_pass(|_| Box::new(let_with_type_underscore::UnderscoreTyped)); - store.register_late_pass(|_| Box::new(allow_attributes::AllowAttribute)); store.register_late_pass(move |_| Box::new(manual_main_separator_str::ManualMainSeparatorStr::new(msrv()))); store.register_late_pass(|_| Box::new(unnecessary_struct_initialization::UnnecessaryStruct)); store.register_late_pass(move |_| { diff --git a/clippy_utils/src/lib.rs b/clippy_utils/src/lib.rs index 6848e8e5c3042..ee43d95272a00 100644 --- a/clippy_utils/src/lib.rs +++ b/clippy_utils/src/lib.rs @@ -5,7 +5,7 @@ #![feature(f16)] #![feature(if_let_guard)] #![feature(let_chains)] -#![feature(lint_reasons)] +#![cfg_attr(bootstrap, feature(lint_reasons))] #![feature(never_type)] #![feature(rustc_private)] #![feature(assert_matches)] diff --git a/src/driver.rs b/src/driver.rs index 6117e76897f2f..9b1577f24b8e7 100644 --- a/src/driver.rs +++ b/src/driver.rs @@ -2,7 +2,7 @@ #![allow(rustc::untranslatable_diagnostic)] #![feature(rustc_private)] #![feature(let_chains)] -#![feature(lint_reasons)] +#![cfg_attr(bootstrap, feature(lint_reasons))] #![cfg_attr(feature = "deny-warnings", deny(warnings))] // warn on lints, that are included in `rust-lang/rust`s bootstrap #![warn(rust_2018_idioms, unused_lifetimes)] diff --git a/tests/ui-cargo/duplicate_mod/fail/src/main.rs b/tests/ui-cargo/duplicate_mod/fail/src/main.rs index 6478e65ac81ad..a99fe2e12bb27 100644 --- a/tests/ui-cargo/duplicate_mod/fail/src/main.rs +++ b/tests/ui-cargo/duplicate_mod/fail/src/main.rs @@ -1,4 +1,3 @@ -#![feature(lint_reasons)] mod a; diff --git a/tests/ui-toml/macro_metavars_in_unsafe/default/test.stderr b/tests/ui-toml/macro_metavars_in_unsafe/default/test.stderr index d6b97f6fde1e1..138eb60294949 100644 --- a/tests/ui-toml/macro_metavars_in_unsafe/default/test.stderr +++ b/tests/ui-toml/macro_metavars_in_unsafe/default/test.stderr @@ -1,3 +1,12 @@ +error: the feature `lint_reasons` has been stable since 1.81.0-dev and no longer requires an attribute to enable + --> tests/ui-toml/macro_metavars_in_unsafe/default/test.rs:2:24 + | +LL | #![feature(decl_macro, lint_reasons)] + | ^^^^^^^^^^^^ + | + = note: `-D stable-features` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(stable_features)]` + error: this macro expands metavariables in an unsafe block --> tests/ui-toml/macro_metavars_in_unsafe/default/test.rs:19:9 | @@ -183,5 +192,5 @@ LL | | } = help: consider expanding any metavariables outside of this block, e.g. by storing them in a variable = help: ... or also expand referenced metavariables in a safe context to require an unsafe block at callsite -error: aborting due to 14 previous errors +error: aborting due to 15 previous errors diff --git a/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.default.stderr b/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.default.stderr index 37d6905573706..a44c810b13502 100644 --- a/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.default.stderr +++ b/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.default.stderr @@ -1,5 +1,5 @@ error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:271:19 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:270:19 | LL | /* Safety: */ unsafe {} | ^^^^^^^^^ @@ -9,7 +9,7 @@ LL | /* Safety: */ unsafe {} = help: to override `-D warnings` add `#[allow(clippy::undocumented_unsafe_blocks)]` error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:275:5 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:274:5 | LL | unsafe {} | ^^^^^^^^^ @@ -17,7 +17,7 @@ LL | unsafe {} = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:279:14 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:278:14 | LL | let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }]; | ^^^^^^^^^^^^^ @@ -25,7 +25,7 @@ LL | let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }]; = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:279:29 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:278:29 | LL | let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }]; | ^^^^^^^^^^^^^ @@ -33,7 +33,7 @@ LL | let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }]; = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:279:48 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:278:48 | LL | let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }]; | ^^^^^^^^^^^^^ @@ -41,7 +41,7 @@ LL | let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }]; = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:283:18 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:282:18 | LL | let _ = (42, unsafe {}, "test", unsafe {}); | ^^^^^^^^^ @@ -49,7 +49,7 @@ LL | let _ = (42, unsafe {}, "test", unsafe {}); = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:283:37 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:282:37 | LL | let _ = (42, unsafe {}, "test", unsafe {}); | ^^^^^^^^^ @@ -57,7 +57,7 @@ LL | let _ = (42, unsafe {}, "test", unsafe {}); = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:287:14 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:286:14 | LL | let _ = *unsafe { &42 }; | ^^^^^^^^^^^^^^ @@ -65,7 +65,7 @@ LL | let _ = *unsafe { &42 }; = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:292:19 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:291:19 | LL | let _ = match unsafe {} { | ^^^^^^^^^ @@ -73,7 +73,7 @@ LL | let _ = match unsafe {} { = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:298:14 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:297:14 | LL | let _ = &unsafe {}; | ^^^^^^^^^ @@ -81,7 +81,7 @@ LL | let _ = &unsafe {}; = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:302:14 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:301:14 | LL | let _ = [unsafe {}; 5]; | ^^^^^^^^^ @@ -89,7 +89,7 @@ LL | let _ = [unsafe {}; 5]; = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:306:13 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:305:13 | LL | let _ = unsafe {}; | ^^^^^^^^^ @@ -97,7 +97,7 @@ LL | let _ = unsafe {}; = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:316:8 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:315:8 | LL | t!(unsafe {}); | ^^^^^^^^^ @@ -105,7 +105,7 @@ LL | t!(unsafe {}); = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:322:13 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:321:13 | LL | unsafe {} | ^^^^^^^^^ @@ -117,7 +117,7 @@ LL | t!(); = note: this error originates in the macro `t` (in Nightly builds, run with -Z macro-backtrace for more info) error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:330:5 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:329:5 | LL | unsafe {} // SAFETY: | ^^^^^^^^^ @@ -125,7 +125,7 @@ LL | unsafe {} // SAFETY: = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:334:5 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:333:5 | LL | unsafe { | ^^^^^^^^ @@ -133,7 +133,7 @@ LL | unsafe { = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:344:5 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:343:5 | LL | unsafe {}; | ^^^^^^^^^ @@ -141,7 +141,7 @@ LL | unsafe {}; = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:348:20 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:347:20 | LL | println!("{}", unsafe { String::from_utf8_unchecked(vec![]) }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -149,7 +149,7 @@ LL | println!("{}", unsafe { String::from_utf8_unchecked(vec![]) }); = help: consider adding a safety comment on the preceding line error: unsafe impl missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:355:5 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:354:5 | LL | unsafe impl A for () {} | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -157,7 +157,7 @@ LL | unsafe impl A for () {} = help: consider adding a safety comment on the preceding line error: unsafe impl missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:362:9 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:361:9 | LL | unsafe impl B for (u32) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -165,7 +165,7 @@ LL | unsafe impl B for (u32) {} = help: consider adding a safety comment on the preceding line error: unsafe impl missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:383:13 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:382:13 | LL | unsafe impl T for $t {} | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -177,7 +177,7 @@ LL | no_safety_comment!(()); = note: this error originates in the macro `no_safety_comment` (in Nightly builds, run with -Z macro-backtrace for more info) error: unsafe impl missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:408:13 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:407:13 | LL | unsafe impl T for $t {} | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -189,7 +189,7 @@ LL | no_safety_comment!(()); = note: this error originates in the macro `no_safety_comment` (in Nightly builds, run with -Z macro-backtrace for more info) error: unsafe impl missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:416:5 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:415:5 | LL | unsafe impl T for (i32) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -197,7 +197,7 @@ LL | unsafe impl T for (i32) {} = help: consider adding a safety comment on the preceding line error: unsafe impl missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:408:13 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:407:13 | LL | unsafe impl T for $t {} | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -209,7 +209,7 @@ LL | no_safety_comment!(u32); = note: this error originates in the macro `no_safety_comment` (in Nightly builds, run with -Z macro-backtrace for more info) error: unsafe impl missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:422:5 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:421:5 | LL | unsafe impl T for (bool) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -217,7 +217,7 @@ LL | unsafe impl T for (bool) {} = help: consider adding a safety comment on the preceding line error: unsafe impl missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:468:5 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:467:5 | LL | unsafe impl NoComment for () {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -225,7 +225,7 @@ LL | unsafe impl NoComment for () {} = help: consider adding a safety comment on the preceding line error: unsafe impl missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:472:19 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:471:19 | LL | /* SAFETY: */ unsafe impl InlineComment for () {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -233,7 +233,7 @@ LL | /* SAFETY: */ unsafe impl InlineComment for () {} = help: consider adding a safety comment on the preceding line error: unsafe impl missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:476:5 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:475:5 | LL | unsafe impl TrailingComment for () {} // SAFETY: | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -241,13 +241,13 @@ LL | unsafe impl TrailingComment for () {} // SAFETY: = help: consider adding a safety comment on the preceding line error: constant item has unnecessary safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:480:5 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:479:5 | LL | const BIG_NUMBER: i32 = 1000000; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | help: consider removing the safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:479:5 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:478:5 | LL | // SAFETY: | ^^^^^^^^^^ @@ -255,7 +255,7 @@ LL | // SAFETY: = help: to override `-D warnings` add `#[allow(clippy::unnecessary_safety_comment)]` error: unsafe impl missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:481:5 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:480:5 | LL | unsafe impl Interference for () {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -263,7 +263,7 @@ LL | unsafe impl Interference for () {} = help: consider adding a safety comment on the preceding line error: unsafe impl missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:488:5 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:487:5 | LL | unsafe impl ImplInFn for () {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -271,7 +271,7 @@ LL | unsafe impl ImplInFn for () {} = help: consider adding a safety comment on the preceding line error: unsafe impl missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:497:1 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:496:1 | LL | unsafe impl CrateRoot for () {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -279,7 +279,7 @@ LL | unsafe impl CrateRoot for () {} = help: consider adding a safety comment on the preceding line error: statement has unnecessary safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:510:5 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:509:5 | LL | / let _ = { LL | | if unsafe { true } { @@ -291,13 +291,13 @@ LL | | }; | |______^ | help: consider removing the safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:509:5 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:508:5 | LL | // SAFETY: this is more than one level away, so it should warn | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:511:12 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:510:12 | LL | if unsafe { true } { | ^^^^^^^^^^^^^^^ @@ -305,7 +305,7 @@ LL | if unsafe { true } { = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:514:23 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:513:23 | LL | let bar = unsafe {}; | ^^^^^^^^^ diff --git a/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.disabled.stderr b/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.disabled.stderr index 400fde997e9fc..db5ea5b628902 100644 --- a/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.disabled.stderr +++ b/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.disabled.stderr @@ -1,5 +1,5 @@ error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:271:19 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:270:19 | LL | /* Safety: */ unsafe {} | ^^^^^^^^^ @@ -9,7 +9,7 @@ LL | /* Safety: */ unsafe {} = help: to override `-D warnings` add `#[allow(clippy::undocumented_unsafe_blocks)]` error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:275:5 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:274:5 | LL | unsafe {} | ^^^^^^^^^ @@ -17,7 +17,7 @@ LL | unsafe {} = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:279:14 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:278:14 | LL | let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }]; | ^^^^^^^^^^^^^ @@ -25,7 +25,7 @@ LL | let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }]; = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:279:29 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:278:29 | LL | let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }]; | ^^^^^^^^^^^^^ @@ -33,7 +33,7 @@ LL | let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }]; = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:279:48 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:278:48 | LL | let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }]; | ^^^^^^^^^^^^^ @@ -41,7 +41,7 @@ LL | let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }]; = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:283:18 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:282:18 | LL | let _ = (42, unsafe {}, "test", unsafe {}); | ^^^^^^^^^ @@ -49,7 +49,7 @@ LL | let _ = (42, unsafe {}, "test", unsafe {}); = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:283:37 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:282:37 | LL | let _ = (42, unsafe {}, "test", unsafe {}); | ^^^^^^^^^ @@ -57,7 +57,7 @@ LL | let _ = (42, unsafe {}, "test", unsafe {}); = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:287:14 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:286:14 | LL | let _ = *unsafe { &42 }; | ^^^^^^^^^^^^^^ @@ -65,7 +65,7 @@ LL | let _ = *unsafe { &42 }; = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:292:19 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:291:19 | LL | let _ = match unsafe {} { | ^^^^^^^^^ @@ -73,7 +73,7 @@ LL | let _ = match unsafe {} { = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:298:14 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:297:14 | LL | let _ = &unsafe {}; | ^^^^^^^^^ @@ -81,7 +81,7 @@ LL | let _ = &unsafe {}; = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:302:14 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:301:14 | LL | let _ = [unsafe {}; 5]; | ^^^^^^^^^ @@ -89,7 +89,7 @@ LL | let _ = [unsafe {}; 5]; = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:306:13 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:305:13 | LL | let _ = unsafe {}; | ^^^^^^^^^ @@ -97,7 +97,7 @@ LL | let _ = unsafe {}; = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:316:8 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:315:8 | LL | t!(unsafe {}); | ^^^^^^^^^ @@ -105,7 +105,7 @@ LL | t!(unsafe {}); = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:322:13 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:321:13 | LL | unsafe {} | ^^^^^^^^^ @@ -117,7 +117,7 @@ LL | t!(); = note: this error originates in the macro `t` (in Nightly builds, run with -Z macro-backtrace for more info) error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:330:5 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:329:5 | LL | unsafe {} // SAFETY: | ^^^^^^^^^ @@ -125,7 +125,7 @@ LL | unsafe {} // SAFETY: = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:334:5 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:333:5 | LL | unsafe { | ^^^^^^^^ @@ -133,7 +133,7 @@ LL | unsafe { = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:344:5 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:343:5 | LL | unsafe {}; | ^^^^^^^^^ @@ -141,7 +141,7 @@ LL | unsafe {}; = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:348:20 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:347:20 | LL | println!("{}", unsafe { String::from_utf8_unchecked(vec![]) }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -149,7 +149,7 @@ LL | println!("{}", unsafe { String::from_utf8_unchecked(vec![]) }); = help: consider adding a safety comment on the preceding line error: unsafe impl missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:355:5 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:354:5 | LL | unsafe impl A for () {} | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -157,7 +157,7 @@ LL | unsafe impl A for () {} = help: consider adding a safety comment on the preceding line error: unsafe impl missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:362:9 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:361:9 | LL | unsafe impl B for (u32) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -165,7 +165,7 @@ LL | unsafe impl B for (u32) {} = help: consider adding a safety comment on the preceding line error: unsafe impl missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:383:13 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:382:13 | LL | unsafe impl T for $t {} | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -177,7 +177,7 @@ LL | no_safety_comment!(()); = note: this error originates in the macro `no_safety_comment` (in Nightly builds, run with -Z macro-backtrace for more info) error: unsafe impl missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:408:13 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:407:13 | LL | unsafe impl T for $t {} | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -189,7 +189,7 @@ LL | no_safety_comment!(()); = note: this error originates in the macro `no_safety_comment` (in Nightly builds, run with -Z macro-backtrace for more info) error: unsafe impl missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:416:5 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:415:5 | LL | unsafe impl T for (i32) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -197,7 +197,7 @@ LL | unsafe impl T for (i32) {} = help: consider adding a safety comment on the preceding line error: unsafe impl missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:408:13 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:407:13 | LL | unsafe impl T for $t {} | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -209,7 +209,7 @@ LL | no_safety_comment!(u32); = note: this error originates in the macro `no_safety_comment` (in Nightly builds, run with -Z macro-backtrace for more info) error: unsafe impl missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:422:5 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:421:5 | LL | unsafe impl T for (bool) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -217,7 +217,7 @@ LL | unsafe impl T for (bool) {} = help: consider adding a safety comment on the preceding line error: unsafe impl missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:468:5 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:467:5 | LL | unsafe impl NoComment for () {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -225,7 +225,7 @@ LL | unsafe impl NoComment for () {} = help: consider adding a safety comment on the preceding line error: unsafe impl missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:472:19 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:471:19 | LL | /* SAFETY: */ unsafe impl InlineComment for () {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -233,7 +233,7 @@ LL | /* SAFETY: */ unsafe impl InlineComment for () {} = help: consider adding a safety comment on the preceding line error: unsafe impl missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:476:5 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:475:5 | LL | unsafe impl TrailingComment for () {} // SAFETY: | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -241,13 +241,13 @@ LL | unsafe impl TrailingComment for () {} // SAFETY: = help: consider adding a safety comment on the preceding line error: constant item has unnecessary safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:480:5 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:479:5 | LL | const BIG_NUMBER: i32 = 1000000; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | help: consider removing the safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:479:5 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:478:5 | LL | // SAFETY: | ^^^^^^^^^^ @@ -255,7 +255,7 @@ LL | // SAFETY: = help: to override `-D warnings` add `#[allow(clippy::unnecessary_safety_comment)]` error: unsafe impl missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:481:5 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:480:5 | LL | unsafe impl Interference for () {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -263,7 +263,7 @@ LL | unsafe impl Interference for () {} = help: consider adding a safety comment on the preceding line error: unsafe impl missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:488:5 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:487:5 | LL | unsafe impl ImplInFn for () {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -271,7 +271,7 @@ LL | unsafe impl ImplInFn for () {} = help: consider adding a safety comment on the preceding line error: unsafe impl missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:497:1 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:496:1 | LL | unsafe impl CrateRoot for () {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -279,7 +279,7 @@ LL | unsafe impl CrateRoot for () {} = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:507:9 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:506:9 | LL | unsafe {}; | ^^^^^^^^^ @@ -287,7 +287,7 @@ LL | unsafe {}; = help: consider adding a safety comment on the preceding line error: statement has unnecessary safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:510:5 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:509:5 | LL | / let _ = { LL | | if unsafe { true } { @@ -299,13 +299,13 @@ LL | | }; | |______^ | help: consider removing the safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:509:5 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:508:5 | LL | // SAFETY: this is more than one level away, so it should warn | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:511:12 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:510:12 | LL | if unsafe { true } { | ^^^^^^^^^^^^^^^ @@ -313,7 +313,7 @@ LL | if unsafe { true } { = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:514:23 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:513:23 | LL | let bar = unsafe {}; | ^^^^^^^^^ @@ -321,7 +321,7 @@ LL | let bar = unsafe {}; = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:532:9 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:531:9 | LL | unsafe { a_function_with_a_very_long_name_to_break_the_line() }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -329,7 +329,7 @@ LL | unsafe { a_function_with_a_very_long_name_to_break_the_line() }; = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:536:9 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:535:9 | LL | unsafe { a_const_function_with_a_very_long_name_to_break_the_line() }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -337,7 +337,7 @@ LL | unsafe { a_const_function_with_a_very_long_name_to_break_the_line() = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:540:9 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:539:9 | LL | unsafe { a_const_function_with_a_very_long_name_to_break_the_line() }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -345,7 +345,7 @@ LL | unsafe { a_const_function_with_a_very_long_name_to_break_the_line() = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:546:5 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:545:5 | LL | unsafe {} | ^^^^^^^^^ @@ -353,7 +353,7 @@ LL | unsafe {} = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:550:5 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:549:5 | LL | unsafe { | ^^^^^^^^ @@ -361,7 +361,7 @@ LL | unsafe { = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:557:9 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:556:9 | LL | unsafe { a_function_with_a_very_long_name_to_break_the_line() }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -369,7 +369,7 @@ LL | unsafe { a_function_with_a_very_long_name_to_break_the_line() }; = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:562:9 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:561:9 | LL | unsafe { a_const_function_with_a_very_long_name_to_break_the_line() }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -377,7 +377,7 @@ LL | unsafe { a_const_function_with_a_very_long_name_to_break_the_line() = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:568:9 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:567:9 | LL | unsafe { a_const_function_with_a_very_long_name_to_break_the_line() }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -385,7 +385,7 @@ LL | unsafe { a_const_function_with_a_very_long_name_to_break_the_line() = help: consider adding a safety comment on the preceding line error: unsafe block missing a safety comment - --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:573:5 + --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:572:5 | LL | unsafe {} | ^^^^^^^^^ diff --git a/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs b/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs index e5ef9d35fb6b8..02170e1f74026 100644 --- a/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs +++ b/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs @@ -10,7 +10,6 @@ clippy::let_unit_value, clippy::missing_safety_doc )] -#![feature(lint_reasons)] extern crate proc_macro_unsafe; diff --git a/tests/ui/allow_attributes.fixed b/tests/ui/allow_attributes.fixed index b506a9890f5b9..49ee3ee17c70f 100644 --- a/tests/ui/allow_attributes.fixed +++ b/tests/ui/allow_attributes.fixed @@ -1,7 +1,6 @@ //@aux-build:proc_macros.rs #![allow(unused)] #![warn(clippy::allow_attributes)] -#![feature(lint_reasons)] #![no_main] extern crate proc_macros; @@ -47,3 +46,15 @@ fn ignore_proc_macro() { fn ignore_inner_attr() { #![allow(unused)] // Should not lint } + +#[clippy::msrv = "1.81"] +fn msrv_1_81() { + #[expect(unused)] + let x = 1; +} + +#[clippy::msrv = "1.80"] +fn msrv_1_80() { + #[allow(unused)] + let x = 1; +} diff --git a/tests/ui/allow_attributes.rs b/tests/ui/allow_attributes.rs index c7daa7abd9d41..854acf8348dcb 100644 --- a/tests/ui/allow_attributes.rs +++ b/tests/ui/allow_attributes.rs @@ -1,7 +1,6 @@ //@aux-build:proc_macros.rs #![allow(unused)] #![warn(clippy::allow_attributes)] -#![feature(lint_reasons)] #![no_main] extern crate proc_macros; @@ -47,3 +46,15 @@ fn ignore_proc_macro() { fn ignore_inner_attr() { #![allow(unused)] // Should not lint } + +#[clippy::msrv = "1.81"] +fn msrv_1_81() { + #[allow(unused)] + let x = 1; +} + +#[clippy::msrv = "1.80"] +fn msrv_1_80() { + #[allow(unused)] + let x = 1; +} diff --git a/tests/ui/allow_attributes.stderr b/tests/ui/allow_attributes.stderr index 9c99e88c796a5..10dac0bc80808 100644 --- a/tests/ui/allow_attributes.stderr +++ b/tests/ui/allow_attributes.stderr @@ -1,5 +1,5 @@ error: #[allow] attribute found - --> tests/ui/allow_attributes.rs:13:3 + --> tests/ui/allow_attributes.rs:12:3 | LL | #[allow(dead_code)] | ^^^^^ help: replace it with: `expect` @@ -8,10 +8,24 @@ LL | #[allow(dead_code)] = help: to override `-D warnings` add `#[allow(clippy::allow_attributes)]` error: #[allow] attribute found - --> tests/ui/allow_attributes.rs:22:30 + --> tests/ui/allow_attributes.rs:21:30 | LL | #[cfg_attr(panic = "unwind", allow(dead_code))] | ^^^^^ help: replace it with: `expect` -error: aborting due to 2 previous errors +error: #[allow] attribute found + --> tests/ui/allow_attributes.rs:52:7 + | +LL | #[allow(unused)] + | ^^^^^ help: replace it with: `expect` + +error: #[allow] attribute found + --> tests/ui/allow_attributes.rs:52:7 + | +LL | #[allow(unused)] + | ^^^^^ help: replace it with: `expect` + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: aborting due to 4 previous errors diff --git a/tests/ui/allow_attributes_without_reason.rs b/tests/ui/allow_attributes_without_reason.rs index 523148d658698..86f6b2c5742a9 100644 --- a/tests/ui/allow_attributes_without_reason.rs +++ b/tests/ui/allow_attributes_without_reason.rs @@ -1,5 +1,4 @@ //@aux-build:proc_macros.rs -#![feature(lint_reasons)] #![deny(clippy::allow_attributes_without_reason)] #![allow(unfulfilled_lint_expectations, clippy::duplicated_attributes)] @@ -42,3 +41,15 @@ pub fn trigger_fp_result() -> Result<(), &'static str> { Err("asdf")?; Ok(()) } + +#[clippy::msrv = "1.81"] +fn msrv_1_81() { + #[allow(unused)] + let _ = 1; +} + +#[clippy::msrv = "1.80"] +fn msrv_1_80() { + #[allow(unused)] + let _ = 1; +} diff --git a/tests/ui/allow_attributes_without_reason.stderr b/tests/ui/allow_attributes_without_reason.stderr index 770a771ec3d15..9bc3ca0f2afd3 100644 --- a/tests/ui/allow_attributes_without_reason.stderr +++ b/tests/ui/allow_attributes_without_reason.stderr @@ -1,18 +1,18 @@ error: `allow` attribute without specifying a reason - --> tests/ui/allow_attributes_without_reason.rs:4:1 + --> tests/ui/allow_attributes_without_reason.rs:3:1 | LL | #![allow(unfulfilled_lint_expectations, clippy::duplicated_attributes)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: try adding a reason at the end with `, reason = ".."` note: the lint level is defined here - --> tests/ui/allow_attributes_without_reason.rs:3:9 + --> tests/ui/allow_attributes_without_reason.rs:2:9 | LL | #![deny(clippy::allow_attributes_without_reason)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: `allow` attribute without specifying a reason - --> tests/ui/allow_attributes_without_reason.rs:10:1 + --> tests/ui/allow_attributes_without_reason.rs:9:1 | LL | #[allow(dead_code)] | ^^^^^^^^^^^^^^^^^^^ @@ -20,7 +20,7 @@ LL | #[allow(dead_code)] = help: try adding a reason at the end with `, reason = ".."` error: `allow` attribute without specifying a reason - --> tests/ui/allow_attributes_without_reason.rs:11:1 + --> tests/ui/allow_attributes_without_reason.rs:10:1 | LL | #[allow(dead_code, deprecated)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -28,12 +28,29 @@ LL | #[allow(dead_code, deprecated)] = help: try adding a reason at the end with `, reason = ".."` error: `expect` attribute without specifying a reason - --> tests/ui/allow_attributes_without_reason.rs:12:1 + --> tests/ui/allow_attributes_without_reason.rs:11:1 | LL | #[expect(dead_code)] | ^^^^^^^^^^^^^^^^^^^^ | = help: try adding a reason at the end with `, reason = ".."` -error: aborting due to 4 previous errors +error: `allow` attribute without specifying a reason + --> tests/ui/allow_attributes_without_reason.rs:47:5 + | +LL | #[allow(unused)] + | ^^^^^^^^^^^^^^^^ + | + = help: try adding a reason at the end with `, reason = ".."` + +error: `allow` attribute without specifying a reason + --> tests/ui/allow_attributes_without_reason.rs:47:5 + | +LL | #[allow(unused)] + | ^^^^^^^^^^^^^^^^ + | + = help: try adding a reason at the end with `, reason = ".."` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: aborting due to 6 previous errors diff --git a/tests/ui/async_yields_async.fixed b/tests/ui/async_yields_async.fixed index cfad78138053d..208651bab1fd1 100644 --- a/tests/ui/async_yields_async.fixed +++ b/tests/ui/async_yields_async.fixed @@ -1,4 +1,3 @@ -#![feature(lint_reasons)] #![feature(async_closure)] #![warn(clippy::async_yields_async)] #![allow(clippy::redundant_async_block)] diff --git a/tests/ui/async_yields_async.rs b/tests/ui/async_yields_async.rs index 7bc26647943f9..b124c994442ba 100644 --- a/tests/ui/async_yields_async.rs +++ b/tests/ui/async_yields_async.rs @@ -1,4 +1,3 @@ -#![feature(lint_reasons)] #![feature(async_closure)] #![warn(clippy::async_yields_async)] #![allow(clippy::redundant_async_block)] diff --git a/tests/ui/async_yields_async.stderr b/tests/ui/async_yields_async.stderr index 991ad7ae0ae2f..861c3f2ce4a5f 100644 --- a/tests/ui/async_yields_async.stderr +++ b/tests/ui/async_yields_async.stderr @@ -1,5 +1,5 @@ error: an async construct yields a type which is itself awaitable - --> tests/ui/async_yields_async.rs:39:9 + --> tests/ui/async_yields_async.rs:38:9 | LL | let _h = async { | _____________________- @@ -20,7 +20,7 @@ LL + }.await | error: an async construct yields a type which is itself awaitable - --> tests/ui/async_yields_async.rs:44:9 + --> tests/ui/async_yields_async.rs:43:9 | LL | let _i = async { | ____________________- @@ -33,7 +33,7 @@ LL | | }; | |_____- outer async construct error: an async construct yields a type which is itself awaitable - --> tests/ui/async_yields_async.rs:50:9 + --> tests/ui/async_yields_async.rs:49:9 | LL | let _j = async || { | ________________________- @@ -52,7 +52,7 @@ LL + }.await | error: an async construct yields a type which is itself awaitable - --> tests/ui/async_yields_async.rs:55:9 + --> tests/ui/async_yields_async.rs:54:9 | LL | let _k = async || { | _______________________- @@ -65,7 +65,7 @@ LL | | }; | |_____- outer async construct error: an async construct yields a type which is itself awaitable - --> tests/ui/async_yields_async.rs:57:23 + --> tests/ui/async_yields_async.rs:56:23 | LL | let _l = async || CustomFutureType; | ^^^^^^^^^^^^^^^^ @@ -75,7 +75,7 @@ LL | let _l = async || CustomFutureType; | help: consider awaiting this value: `CustomFutureType.await` error: an async construct yields a type which is itself awaitable - --> tests/ui/async_yields_async.rs:63:9 + --> tests/ui/async_yields_async.rs:62:9 | LL | let _m = async || { | _______________________- diff --git a/tests/ui/boxed_local.rs b/tests/ui/boxed_local.rs index e888154c46def..fbd9e12fc1891 100644 --- a/tests/ui/boxed_local.rs +++ b/tests/ui/boxed_local.rs @@ -1,4 +1,3 @@ -#![feature(lint_reasons)] #![allow( clippy::borrowed_box, clippy::needless_pass_by_value, diff --git a/tests/ui/boxed_local.stderr b/tests/ui/boxed_local.stderr index d3156c820b2c5..7710233fa4db8 100644 --- a/tests/ui/boxed_local.stderr +++ b/tests/ui/boxed_local.stderr @@ -1,5 +1,5 @@ error: local variable doesn't need to be boxed here - --> tests/ui/boxed_local.rs:40:13 + --> tests/ui/boxed_local.rs:39:13 | LL | fn warn_arg(x: Box) { | ^ @@ -8,19 +8,19 @@ LL | fn warn_arg(x: Box) { = help: to override `-D warnings` add `#[allow(clippy::boxed_local)]` error: local variable doesn't need to be boxed here - --> tests/ui/boxed_local.rs:123:12 + --> tests/ui/boxed_local.rs:122:12 | LL | pub fn new(_needs_name: Box>) -> () {} | ^^^^^^^^^^^ error: local variable doesn't need to be boxed here - --> tests/ui/boxed_local.rs:188:44 + --> tests/ui/boxed_local.rs:187:44 | LL | fn default_impl_x(self: Box, x: Box) -> u32 { | ^ error: local variable doesn't need to be boxed here - --> tests/ui/boxed_local.rs:196:16 + --> tests/ui/boxed_local.rs:195:16 | LL | fn foo(x: Box) {} | ^ diff --git a/tests/ui/checked_unwrap/simple_conditionals.rs b/tests/ui/checked_unwrap/simple_conditionals.rs index 02f80cc52ac72..c3c8562edffba 100644 --- a/tests/ui/checked_unwrap/simple_conditionals.rs +++ b/tests/ui/checked_unwrap/simple_conditionals.rs @@ -1,5 +1,4 @@ //@no-rustfix: overlapping suggestions -#![feature(lint_reasons)] #![deny(clippy::panicking_unwrap, clippy::unnecessary_unwrap)] #![allow( clippy::if_same_then_else, diff --git a/tests/ui/checked_unwrap/simple_conditionals.stderr b/tests/ui/checked_unwrap/simple_conditionals.stderr index bae6213376012..ddd600418afec 100644 --- a/tests/ui/checked_unwrap/simple_conditionals.stderr +++ b/tests/ui/checked_unwrap/simple_conditionals.stderr @@ -1,5 +1,5 @@ error: called `unwrap` on `x` after checking its variant with `is_some` - --> tests/ui/checked_unwrap/simple_conditionals.rs:47:9 + --> tests/ui/checked_unwrap/simple_conditionals.rs:46:9 | LL | if x.is_some() { | -------------- help: try: `if let Some(..) = x` @@ -8,13 +8,13 @@ LL | x.unwrap(); | ^^^^^^^^^^ | note: the lint level is defined here - --> tests/ui/checked_unwrap/simple_conditionals.rs:3:35 + --> tests/ui/checked_unwrap/simple_conditionals.rs:2:35 | LL | #![deny(clippy::panicking_unwrap, clippy::unnecessary_unwrap)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: called `expect` on `x` after checking its variant with `is_some` - --> tests/ui/checked_unwrap/simple_conditionals.rs:50:9 + --> tests/ui/checked_unwrap/simple_conditionals.rs:49:9 | LL | if x.is_some() { | -------------- help: try: `if let Some(..) = x` @@ -23,7 +23,7 @@ LL | x.expect("an error message"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: this call to `unwrap()` will always panic - --> tests/ui/checked_unwrap/simple_conditionals.rs:54:9 + --> tests/ui/checked_unwrap/simple_conditionals.rs:53:9 | LL | if x.is_some() { | ----------- because of this check @@ -32,13 +32,13 @@ LL | x.unwrap(); | ^^^^^^^^^^ | note: the lint level is defined here - --> tests/ui/checked_unwrap/simple_conditionals.rs:3:9 + --> tests/ui/checked_unwrap/simple_conditionals.rs:2:9 | LL | #![deny(clippy::panicking_unwrap, clippy::unnecessary_unwrap)] | ^^^^^^^^^^^^^^^^^^^^^^^^ error: this call to `expect()` will always panic - --> tests/ui/checked_unwrap/simple_conditionals.rs:57:9 + --> tests/ui/checked_unwrap/simple_conditionals.rs:56:9 | LL | if x.is_some() { | ----------- because of this check @@ -47,7 +47,7 @@ LL | x.expect("an error message"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: this call to `unwrap()` will always panic - --> tests/ui/checked_unwrap/simple_conditionals.rs:62:9 + --> tests/ui/checked_unwrap/simple_conditionals.rs:61:9 | LL | if x.is_none() { | ----------- because of this check @@ -56,7 +56,7 @@ LL | x.unwrap(); | ^^^^^^^^^^ error: called `unwrap` on `x` after checking its variant with `is_none` - --> tests/ui/checked_unwrap/simple_conditionals.rs:66:9 + --> tests/ui/checked_unwrap/simple_conditionals.rs:65:9 | LL | if x.is_none() { | -------------- help: try: `if let Some(..) = x` @@ -65,7 +65,7 @@ LL | x.unwrap(); | ^^^^^^^^^^ error: called `unwrap` on `x` after checking its variant with `is_some` - --> tests/ui/checked_unwrap/simple_conditionals.rs:14:13 + --> tests/ui/checked_unwrap/simple_conditionals.rs:13:13 | LL | if $a.is_some() { | --------------- help: try: `if let Some(..) = x` @@ -79,7 +79,7 @@ LL | m!(x); = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info) error: called `unwrap` on `x` after checking its variant with `is_ok` - --> tests/ui/checked_unwrap/simple_conditionals.rs:79:9 + --> tests/ui/checked_unwrap/simple_conditionals.rs:78:9 | LL | if x.is_ok() { | ------------ help: try: `if let Ok(..) = x` @@ -88,7 +88,7 @@ LL | x.unwrap(); | ^^^^^^^^^^ error: called `expect` on `x` after checking its variant with `is_ok` - --> tests/ui/checked_unwrap/simple_conditionals.rs:82:9 + --> tests/ui/checked_unwrap/simple_conditionals.rs:81:9 | LL | if x.is_ok() { | ------------ help: try: `if let Ok(..) = x` @@ -97,7 +97,7 @@ LL | x.expect("an error message"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: this call to `unwrap_err()` will always panic - --> tests/ui/checked_unwrap/simple_conditionals.rs:85:9 + --> tests/ui/checked_unwrap/simple_conditionals.rs:84:9 | LL | if x.is_ok() { | --------- because of this check @@ -106,7 +106,7 @@ LL | x.unwrap_err(); | ^^^^^^^^^^^^^^ error: this call to `unwrap()` will always panic - --> tests/ui/checked_unwrap/simple_conditionals.rs:89:9 + --> tests/ui/checked_unwrap/simple_conditionals.rs:88:9 | LL | if x.is_ok() { | --------- because of this check @@ -115,7 +115,7 @@ LL | x.unwrap(); | ^^^^^^^^^^ error: this call to `expect()` will always panic - --> tests/ui/checked_unwrap/simple_conditionals.rs:92:9 + --> tests/ui/checked_unwrap/simple_conditionals.rs:91:9 | LL | if x.is_ok() { | --------- because of this check @@ -124,7 +124,7 @@ LL | x.expect("an error message"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: called `unwrap_err` on `x` after checking its variant with `is_ok` - --> tests/ui/checked_unwrap/simple_conditionals.rs:95:9 + --> tests/ui/checked_unwrap/simple_conditionals.rs:94:9 | LL | if x.is_ok() { | ------------ help: try: `if let Err(..) = x` @@ -133,7 +133,7 @@ LL | x.unwrap_err(); | ^^^^^^^^^^^^^^ error: this call to `unwrap()` will always panic - --> tests/ui/checked_unwrap/simple_conditionals.rs:100:9 + --> tests/ui/checked_unwrap/simple_conditionals.rs:99:9 | LL | if x.is_err() { | ---------- because of this check @@ -142,7 +142,7 @@ LL | x.unwrap(); | ^^^^^^^^^^ error: called `unwrap_err` on `x` after checking its variant with `is_err` - --> tests/ui/checked_unwrap/simple_conditionals.rs:103:9 + --> tests/ui/checked_unwrap/simple_conditionals.rs:102:9 | LL | if x.is_err() { | ------------- help: try: `if let Err(..) = x` @@ -151,7 +151,7 @@ LL | x.unwrap_err(); | ^^^^^^^^^^^^^^ error: called `unwrap` on `x` after checking its variant with `is_err` - --> tests/ui/checked_unwrap/simple_conditionals.rs:107:9 + --> tests/ui/checked_unwrap/simple_conditionals.rs:106:9 | LL | if x.is_err() { | ------------- help: try: `if let Ok(..) = x` @@ -160,7 +160,7 @@ LL | x.unwrap(); | ^^^^^^^^^^ error: this call to `unwrap_err()` will always panic - --> tests/ui/checked_unwrap/simple_conditionals.rs:110:9 + --> tests/ui/checked_unwrap/simple_conditionals.rs:109:9 | LL | if x.is_err() { | ---------- because of this check @@ -169,7 +169,7 @@ LL | x.unwrap_err(); | ^^^^^^^^^^^^^^ error: called `unwrap` on `option` after checking its variant with `is_some` - --> tests/ui/checked_unwrap/simple_conditionals.rs:135:9 + --> tests/ui/checked_unwrap/simple_conditionals.rs:134:9 | LL | if option.is_some() { | ------------------- help: try: `if let Some(..) = &option` @@ -177,7 +177,7 @@ LL | option.as_ref().unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^ error: this call to `unwrap()` will always panic - --> tests/ui/checked_unwrap/simple_conditionals.rs:138:9 + --> tests/ui/checked_unwrap/simple_conditionals.rs:137:9 | LL | if option.is_some() { | ---------------- because of this check @@ -186,7 +186,7 @@ LL | option.as_ref().unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^ error: called `unwrap` on `result` after checking its variant with `is_ok` - --> tests/ui/checked_unwrap/simple_conditionals.rs:145:9 + --> tests/ui/checked_unwrap/simple_conditionals.rs:144:9 | LL | if result.is_ok() { | ----------------- help: try: `if let Ok(..) = &result` @@ -194,7 +194,7 @@ LL | result.as_ref().unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^ error: this call to `unwrap()` will always panic - --> tests/ui/checked_unwrap/simple_conditionals.rs:148:9 + --> tests/ui/checked_unwrap/simple_conditionals.rs:147:9 | LL | if result.is_ok() { | -------------- because of this check @@ -203,7 +203,7 @@ LL | result.as_ref().unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^ error: called `unwrap` on `option` after checking its variant with `is_some` - --> tests/ui/checked_unwrap/simple_conditionals.rs:154:9 + --> tests/ui/checked_unwrap/simple_conditionals.rs:153:9 | LL | if option.is_some() { | ------------------- help: try: `if let Some(..) = &mut option` @@ -211,7 +211,7 @@ LL | option.as_mut().unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^ error: this call to `unwrap()` will always panic - --> tests/ui/checked_unwrap/simple_conditionals.rs:157:9 + --> tests/ui/checked_unwrap/simple_conditionals.rs:156:9 | LL | if option.is_some() { | ---------------- because of this check @@ -220,7 +220,7 @@ LL | option.as_mut().unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^ error: called `unwrap` on `result` after checking its variant with `is_ok` - --> tests/ui/checked_unwrap/simple_conditionals.rs:163:9 + --> tests/ui/checked_unwrap/simple_conditionals.rs:162:9 | LL | if result.is_ok() { | ----------------- help: try: `if let Ok(..) = &mut result` @@ -228,7 +228,7 @@ LL | result.as_mut().unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^ error: this call to `unwrap()` will always panic - --> tests/ui/checked_unwrap/simple_conditionals.rs:166:9 + --> tests/ui/checked_unwrap/simple_conditionals.rs:165:9 | LL | if result.is_ok() { | -------------- because of this check diff --git a/tests/ui/default_numeric_fallback_i32.fixed b/tests/ui/default_numeric_fallback_i32.fixed index e7038082c089c..f28ae04fd0a4b 100644 --- a/tests/ui/default_numeric_fallback_i32.fixed +++ b/tests/ui/default_numeric_fallback_i32.fixed @@ -1,6 +1,5 @@ //@aux-build:proc_macros.rs -#![feature(lint_reasons)] #![warn(clippy::default_numeric_fallback)] #![allow( unused, diff --git a/tests/ui/default_numeric_fallback_i32.rs b/tests/ui/default_numeric_fallback_i32.rs index d8eeda7049194..78a5006444eeb 100644 --- a/tests/ui/default_numeric_fallback_i32.rs +++ b/tests/ui/default_numeric_fallback_i32.rs @@ -1,6 +1,5 @@ //@aux-build:proc_macros.rs -#![feature(lint_reasons)] #![warn(clippy::default_numeric_fallback)] #![allow( unused, diff --git a/tests/ui/default_numeric_fallback_i32.stderr b/tests/ui/default_numeric_fallback_i32.stderr index 9961a3669ef2b..67ab923ecf5fb 100644 --- a/tests/ui/default_numeric_fallback_i32.stderr +++ b/tests/ui/default_numeric_fallback_i32.stderr @@ -1,5 +1,5 @@ error: default numeric fallback might occur - --> tests/ui/default_numeric_fallback_i32.rs:21:17 + --> tests/ui/default_numeric_fallback_i32.rs:20:17 | LL | let x = 22; | ^^ help: consider adding suffix: `22_i32` @@ -8,145 +8,145 @@ LL | let x = 22; = help: to override `-D warnings` add `#[allow(clippy::default_numeric_fallback)]` error: default numeric fallback might occur - --> tests/ui/default_numeric_fallback_i32.rs:22:18 + --> tests/ui/default_numeric_fallback_i32.rs:21:18 | LL | let x = [1, 2, 3]; | ^ help: consider adding suffix: `1_i32` error: default numeric fallback might occur - --> tests/ui/default_numeric_fallback_i32.rs:22:21 + --> tests/ui/default_numeric_fallback_i32.rs:21:21 | LL | let x = [1, 2, 3]; | ^ help: consider adding suffix: `2_i32` error: default numeric fallback might occur - --> tests/ui/default_numeric_fallback_i32.rs:22:24 + --> tests/ui/default_numeric_fallback_i32.rs:21:24 | LL | let x = [1, 2, 3]; | ^ help: consider adding suffix: `3_i32` error: default numeric fallback might occur - --> tests/ui/default_numeric_fallback_i32.rs:23:28 + --> tests/ui/default_numeric_fallback_i32.rs:22:28 | LL | let x = if true { (1, 2) } else { (3, 4) }; | ^ help: consider adding suffix: `1_i32` error: default numeric fallback might occur - --> tests/ui/default_numeric_fallback_i32.rs:23:31 + --> tests/ui/default_numeric_fallback_i32.rs:22:31 | LL | let x = if true { (1, 2) } else { (3, 4) }; | ^ help: consider adding suffix: `2_i32` error: default numeric fallback might occur - --> tests/ui/default_numeric_fallback_i32.rs:23:44 + --> tests/ui/default_numeric_fallback_i32.rs:22:44 | LL | let x = if true { (1, 2) } else { (3, 4) }; | ^ help: consider adding suffix: `3_i32` error: default numeric fallback might occur - --> tests/ui/default_numeric_fallback_i32.rs:23:47 + --> tests/ui/default_numeric_fallback_i32.rs:22:47 | LL | let x = if true { (1, 2) } else { (3, 4) }; | ^ help: consider adding suffix: `4_i32` error: default numeric fallback might occur - --> tests/ui/default_numeric_fallback_i32.rs:24:23 + --> tests/ui/default_numeric_fallback_i32.rs:23:23 | LL | let x = match 1 { | ^ help: consider adding suffix: `1_i32` error: default numeric fallback might occur - --> tests/ui/default_numeric_fallback_i32.rs:25:13 + --> tests/ui/default_numeric_fallback_i32.rs:24:13 | LL | 1 => 1, | ^ help: consider adding suffix: `1_i32` error: default numeric fallback might occur - --> tests/ui/default_numeric_fallback_i32.rs:25:18 + --> tests/ui/default_numeric_fallback_i32.rs:24:18 | LL | 1 => 1, | ^ help: consider adding suffix: `1_i32` error: default numeric fallback might occur - --> tests/ui/default_numeric_fallback_i32.rs:26:18 + --> tests/ui/default_numeric_fallback_i32.rs:25:18 | LL | _ => 2, | ^ help: consider adding suffix: `2_i32` error: default numeric fallback might occur - --> tests/ui/default_numeric_fallback_i32.rs:45:21 + --> tests/ui/default_numeric_fallback_i32.rs:44:21 | LL | let y = 1; | ^ help: consider adding suffix: `1_i32` error: default numeric fallback might occur - --> tests/ui/default_numeric_fallback_i32.rs:53:21 + --> tests/ui/default_numeric_fallback_i32.rs:52:21 | LL | let y = 1; | ^ help: consider adding suffix: `1_i32` error: default numeric fallback might occur - --> tests/ui/default_numeric_fallback_i32.rs:59:21 + --> tests/ui/default_numeric_fallback_i32.rs:58:21 | LL | let y = 1; | ^ help: consider adding suffix: `1_i32` error: default numeric fallback might occur - --> tests/ui/default_numeric_fallback_i32.rs:67:21 + --> tests/ui/default_numeric_fallback_i32.rs:66:21 | LL | let y = 1; | ^ help: consider adding suffix: `1_i32` error: default numeric fallback might occur - --> tests/ui/default_numeric_fallback_i32.rs:83:27 + --> tests/ui/default_numeric_fallback_i32.rs:82:27 | LL | let f = || -> _ { 1 }; | ^ help: consider adding suffix: `1_i32` error: default numeric fallback might occur - --> tests/ui/default_numeric_fallback_i32.rs:87:29 + --> tests/ui/default_numeric_fallback_i32.rs:86:29 | LL | let f = || -> i32 { 1 }; | ^ help: consider adding suffix: `1_i32` error: default numeric fallback might occur - --> tests/ui/default_numeric_fallback_i32.rs:101:21 + --> tests/ui/default_numeric_fallback_i32.rs:100:21 | LL | generic_arg(1); | ^ help: consider adding suffix: `1_i32` error: default numeric fallback might occur - --> tests/ui/default_numeric_fallback_i32.rs:104:32 + --> tests/ui/default_numeric_fallback_i32.rs:103:32 | LL | let x: _ = generic_arg(1); | ^ help: consider adding suffix: `1_i32` error: default numeric fallback might occur - --> tests/ui/default_numeric_fallback_i32.rs:122:28 + --> tests/ui/default_numeric_fallback_i32.rs:121:28 | LL | GenericStruct { x: 1 }; | ^ help: consider adding suffix: `1_i32` error: default numeric fallback might occur - --> tests/ui/default_numeric_fallback_i32.rs:125:36 + --> tests/ui/default_numeric_fallback_i32.rs:124:36 | LL | let _ = GenericStruct { x: 1 }; | ^ help: consider adding suffix: `1_i32` error: default numeric fallback might occur - --> tests/ui/default_numeric_fallback_i32.rs:143:24 + --> tests/ui/default_numeric_fallback_i32.rs:142:24 | LL | GenericEnum::X(1); | ^ help: consider adding suffix: `1_i32` error: default numeric fallback might occur - --> tests/ui/default_numeric_fallback_i32.rs:163:23 + --> tests/ui/default_numeric_fallback_i32.rs:162:23 | LL | s.generic_arg(1); | ^ help: consider adding suffix: `1_i32` error: default numeric fallback might occur - --> tests/ui/default_numeric_fallback_i32.rs:173:25 + --> tests/ui/default_numeric_fallback_i32.rs:172:25 | LL | inline!(let x = 22;); | ^^ help: consider adding suffix: `22_i32` @@ -154,19 +154,19 @@ LL | inline!(let x = 22;); = note: this error originates in the macro `__inline_mac_fn_internal` (in Nightly builds, run with -Z macro-backtrace for more info) error: default numeric fallback might occur - --> tests/ui/default_numeric_fallback_i32.rs:215:29 + --> tests/ui/default_numeric_fallback_i32.rs:214:29 | LL | let data_i32 = vec![1, 2, 3]; | ^ help: consider adding suffix: `1_i32` error: default numeric fallback might occur - --> tests/ui/default_numeric_fallback_i32.rs:215:32 + --> tests/ui/default_numeric_fallback_i32.rs:214:32 | LL | let data_i32 = vec![1, 2, 3]; | ^ help: consider adding suffix: `2_i32` error: default numeric fallback might occur - --> tests/ui/default_numeric_fallback_i32.rs:215:35 + --> tests/ui/default_numeric_fallback_i32.rs:214:35 | LL | let data_i32 = vec![1, 2, 3]; | ^ help: consider adding suffix: `3_i32` diff --git a/tests/ui/derive_partial_eq_without_eq.fixed b/tests/ui/derive_partial_eq_without_eq.fixed index eb93eb8e8ed4e..e4a33193a1ab4 100644 --- a/tests/ui/derive_partial_eq_without_eq.fixed +++ b/tests/ui/derive_partial_eq_without_eq.fixed @@ -1,4 +1,3 @@ -#![feature(lint_reasons)] #![allow(unused)] #![warn(clippy::derive_partial_eq_without_eq)] diff --git a/tests/ui/derive_partial_eq_without_eq.rs b/tests/ui/derive_partial_eq_without_eq.rs index 42dc435bdd52a..a418b38e34999 100644 --- a/tests/ui/derive_partial_eq_without_eq.rs +++ b/tests/ui/derive_partial_eq_without_eq.rs @@ -1,4 +1,3 @@ -#![feature(lint_reasons)] #![allow(unused)] #![warn(clippy::derive_partial_eq_without_eq)] diff --git a/tests/ui/derive_partial_eq_without_eq.stderr b/tests/ui/derive_partial_eq_without_eq.stderr index 29cd7da6b77d0..7436114fadb2e 100644 --- a/tests/ui/derive_partial_eq_without_eq.stderr +++ b/tests/ui/derive_partial_eq_without_eq.stderr @@ -1,5 +1,5 @@ error: you are deriving `PartialEq` and can implement `Eq` - --> tests/ui/derive_partial_eq_without_eq.rs:12:17 + --> tests/ui/derive_partial_eq_without_eq.rs:11:17 | LL | #[derive(Debug, PartialEq)] | ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq` @@ -8,73 +8,73 @@ LL | #[derive(Debug, PartialEq)] = help: to override `-D warnings` add `#[allow(clippy::derive_partial_eq_without_eq)]` error: you are deriving `PartialEq` and can implement `Eq` - --> tests/ui/derive_partial_eq_without_eq.rs:70:10 + --> tests/ui/derive_partial_eq_without_eq.rs:69:10 | LL | #[derive(PartialEq)] | ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq` error: you are deriving `PartialEq` and can implement `Eq` - --> tests/ui/derive_partial_eq_without_eq.rs:76:10 + --> tests/ui/derive_partial_eq_without_eq.rs:75:10 | LL | #[derive(PartialEq)] | ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq` error: you are deriving `PartialEq` and can implement `Eq` - --> tests/ui/derive_partial_eq_without_eq.rs:82:10 + --> tests/ui/derive_partial_eq_without_eq.rs:81:10 | LL | #[derive(PartialEq)] | ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq` error: you are deriving `PartialEq` and can implement `Eq` - --> tests/ui/derive_partial_eq_without_eq.rs:85:10 + --> tests/ui/derive_partial_eq_without_eq.rs:84:10 | LL | #[derive(PartialEq)] | ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq` error: you are deriving `PartialEq` and can implement `Eq` - --> tests/ui/derive_partial_eq_without_eq.rs:91:10 + --> tests/ui/derive_partial_eq_without_eq.rs:90:10 | LL | #[derive(PartialEq)] | ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq` error: you are deriving `PartialEq` and can implement `Eq` - --> tests/ui/derive_partial_eq_without_eq.rs:97:10 + --> tests/ui/derive_partial_eq_without_eq.rs:96:10 | LL | #[derive(PartialEq)] | ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq` error: you are deriving `PartialEq` and can implement `Eq` - --> tests/ui/derive_partial_eq_without_eq.rs:110:17 + --> tests/ui/derive_partial_eq_without_eq.rs:109:17 | LL | #[derive(Debug, PartialEq, Clone)] | ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq` error: you are deriving `PartialEq` and can implement `Eq` - --> tests/ui/derive_partial_eq_without_eq.rs:113:10 + --> tests/ui/derive_partial_eq_without_eq.rs:112:10 | LL | #[derive(PartialEq)] | ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq` error: you are deriving `PartialEq` and can implement `Eq` - --> tests/ui/derive_partial_eq_without_eq.rs:120:14 + --> tests/ui/derive_partial_eq_without_eq.rs:119:14 | LL | #[derive(PartialEq)] | ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq` error: you are deriving `PartialEq` and can implement `Eq` - --> tests/ui/derive_partial_eq_without_eq.rs:123:14 + --> tests/ui/derive_partial_eq_without_eq.rs:122:14 | LL | #[derive(PartialEq)] | ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq` error: you are deriving `PartialEq` and can implement `Eq` - --> tests/ui/derive_partial_eq_without_eq.rs:183:14 + --> tests/ui/derive_partial_eq_without_eq.rs:182:14 | LL | #[derive(PartialEq)] | ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq` error: you are deriving `PartialEq` and can implement `Eq` - --> tests/ui/derive_partial_eq_without_eq.rs:191:14 + --> tests/ui/derive_partial_eq_without_eq.rs:190:14 | LL | #[derive(PartialEq)] | ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq` diff --git a/tests/ui/expect_tool_lint_rfc_2383.rs b/tests/ui/expect_tool_lint_rfc_2383.rs index 72097bfabd726..2634c56794e70 100644 --- a/tests/ui/expect_tool_lint_rfc_2383.rs +++ b/tests/ui/expect_tool_lint_rfc_2383.rs @@ -1,4 +1,3 @@ -#![feature(lint_reasons)] //! This file tests the `#[expect]` attribute implementation for tool lints. The same //! file is used to test clippy and rustdoc. Any changes to this file should be synced //! to the other test files as well. diff --git a/tests/ui/expect_tool_lint_rfc_2383.stderr b/tests/ui/expect_tool_lint_rfc_2383.stderr index 43e0b9279e4b1..f70d3408aa4d9 100644 --- a/tests/ui/expect_tool_lint_rfc_2383.stderr +++ b/tests/ui/expect_tool_lint_rfc_2383.stderr @@ -1,5 +1,5 @@ error: this lint expectation is unfulfilled - --> tests/ui/expect_tool_lint_rfc_2383.rs:31:14 + --> tests/ui/expect_tool_lint_rfc_2383.rs:30:14 | LL | #[expect(dead_code)] | ^^^^^^^^^ @@ -8,31 +8,31 @@ LL | #[expect(dead_code)] = help: to override `-D warnings` add `#[allow(unfulfilled_lint_expectations)]` error: this lint expectation is unfulfilled - --> tests/ui/expect_tool_lint_rfc_2383.rs:37:18 + --> tests/ui/expect_tool_lint_rfc_2383.rs:36:18 | LL | #[expect(invalid_nan_comparisons)] | ^^^^^^^^^^^^^^^^^^^^^^^ error: this lint expectation is unfulfilled - --> tests/ui/expect_tool_lint_rfc_2383.rs:108:14 + --> tests/ui/expect_tool_lint_rfc_2383.rs:107:14 | LL | #[expect(clippy::almost_swapped)] | ^^^^^^^^^^^^^^^^^^^^^^ error: this lint expectation is unfulfilled - --> tests/ui/expect_tool_lint_rfc_2383.rs:116:14 + --> tests/ui/expect_tool_lint_rfc_2383.rs:115:14 | LL | #[expect(clippy::bytes_nth)] | ^^^^^^^^^^^^^^^^^ error: this lint expectation is unfulfilled - --> tests/ui/expect_tool_lint_rfc_2383.rs:122:14 + --> tests/ui/expect_tool_lint_rfc_2383.rs:121:14 | LL | #[expect(clippy::if_same_then_else)] | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: this lint expectation is unfulfilled - --> tests/ui/expect_tool_lint_rfc_2383.rs:128:14 + --> tests/ui/expect_tool_lint_rfc_2383.rs:127:14 | LL | #[expect(clippy::overly_complex_bool_expr)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/implicit_return.fixed b/tests/ui/implicit_return.fixed index 897f1b7661638..ba73e64f18626 100644 --- a/tests/ui/implicit_return.fixed +++ b/tests/ui/implicit_return.fixed @@ -1,4 +1,3 @@ -#![feature(lint_reasons)] #![warn(clippy::implicit_return)] #![allow(clippy::needless_return, clippy::needless_bool, unused, clippy::never_loop)] diff --git a/tests/ui/implicit_return.rs b/tests/ui/implicit_return.rs index fcff67b58071b..522fc6a0a447c 100644 --- a/tests/ui/implicit_return.rs +++ b/tests/ui/implicit_return.rs @@ -1,4 +1,3 @@ -#![feature(lint_reasons)] #![warn(clippy::implicit_return)] #![allow(clippy::needless_return, clippy::needless_bool, unused, clippy::never_loop)] diff --git a/tests/ui/implicit_return.stderr b/tests/ui/implicit_return.stderr index 3ffed273e0f16..b2f7bc6943951 100644 --- a/tests/ui/implicit_return.stderr +++ b/tests/ui/implicit_return.stderr @@ -1,5 +1,5 @@ error: missing `return` statement - --> tests/ui/implicit_return.rs:11:5 + --> tests/ui/implicit_return.rs:10:5 | LL | true | ^^^^ help: add `return` as shown: `return true` @@ -8,85 +8,85 @@ LL | true = help: to override `-D warnings` add `#[allow(clippy::implicit_return)]` error: missing `return` statement - --> tests/ui/implicit_return.rs:15:15 + --> tests/ui/implicit_return.rs:14:15 | LL | if true { true } else { false } | ^^^^ help: add `return` as shown: `return true` error: missing `return` statement - --> tests/ui/implicit_return.rs:15:29 + --> tests/ui/implicit_return.rs:14:29 | LL | if true { true } else { false } | ^^^^^ help: add `return` as shown: `return false` error: missing `return` statement - --> tests/ui/implicit_return.rs:21:17 + --> tests/ui/implicit_return.rs:20:17 | LL | true => false, | ^^^^^ help: add `return` as shown: `return false` error: missing `return` statement - --> tests/ui/implicit_return.rs:22:20 + --> tests/ui/implicit_return.rs:21:20 | LL | false => { true }, | ^^^^ help: add `return` as shown: `return true` error: missing `return` statement - --> tests/ui/implicit_return.rs:35:9 + --> tests/ui/implicit_return.rs:34:9 | LL | break true; | ^^^^^^^^^^ help: change `break` to `return` as shown: `return true` error: missing `return` statement - --> tests/ui/implicit_return.rs:42:13 + --> tests/ui/implicit_return.rs:41:13 | LL | break true; | ^^^^^^^^^^ help: change `break` to `return` as shown: `return true` error: missing `return` statement - --> tests/ui/implicit_return.rs:50:13 + --> tests/ui/implicit_return.rs:49:13 | LL | break true; | ^^^^^^^^^^ help: change `break` to `return` as shown: `return true` error: missing `return` statement - --> tests/ui/implicit_return.rs:68:18 + --> tests/ui/implicit_return.rs:67:18 | LL | let _ = || { true }; | ^^^^ help: add `return` as shown: `return true` error: missing `return` statement - --> tests/ui/implicit_return.rs:69:16 + --> tests/ui/implicit_return.rs:68:16 | LL | let _ = || true; | ^^^^ help: add `return` as shown: `return true` error: missing `return` statement - --> tests/ui/implicit_return.rs:77:5 + --> tests/ui/implicit_return.rs:76:5 | LL | format!("test {}", "test") | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: add `return` as shown: `return format!("test {}", "test")` error: missing `return` statement - --> tests/ui/implicit_return.rs:86:5 + --> tests/ui/implicit_return.rs:85:5 | LL | m!(true, false) | ^^^^^^^^^^^^^^^ help: add `return` as shown: `return m!(true, false)` error: missing `return` statement - --> tests/ui/implicit_return.rs:92:13 + --> tests/ui/implicit_return.rs:91:13 | LL | break true; | ^^^^^^^^^^ help: change `break` to `return` as shown: `return true` error: missing `return` statement - --> tests/ui/implicit_return.rs:97:17 + --> tests/ui/implicit_return.rs:96:17 | LL | break 'outer false; | ^^^^^^^^^^^^^^^^^^ help: change `break` to `return` as shown: `return false` error: missing `return` statement - --> tests/ui/implicit_return.rs:112:5 + --> tests/ui/implicit_return.rs:111:5 | LL | / loop { LL | | m!(true); @@ -101,7 +101,7 @@ LL + } | error: missing `return` statement - --> tests/ui/implicit_return.rs:126:5 + --> tests/ui/implicit_return.rs:125:5 | LL | true | ^^^^ help: add `return` as shown: `return true` diff --git a/tests/ui/let_unit.fixed b/tests/ui/let_unit.fixed index 20940daffa7a4..3456e274f6a4d 100644 --- a/tests/ui/let_unit.fixed +++ b/tests/ui/let_unit.fixed @@ -1,4 +1,3 @@ -#![feature(lint_reasons)] #![warn(clippy::let_unit_value)] #![allow(unused, clippy::no_effect, clippy::needless_late_init, path_statements)] diff --git a/tests/ui/let_unit.rs b/tests/ui/let_unit.rs index dca66f2e3edb3..e2dafbcb77146 100644 --- a/tests/ui/let_unit.rs +++ b/tests/ui/let_unit.rs @@ -1,4 +1,3 @@ -#![feature(lint_reasons)] #![warn(clippy::let_unit_value)] #![allow(unused, clippy::no_effect, clippy::needless_late_init, path_statements)] diff --git a/tests/ui/let_unit.stderr b/tests/ui/let_unit.stderr index aafb77bcd0d65..2f62c33c88730 100644 --- a/tests/ui/let_unit.stderr +++ b/tests/ui/let_unit.stderr @@ -1,5 +1,5 @@ error: this let-binding has unit value - --> tests/ui/let_unit.rs:12:5 + --> tests/ui/let_unit.rs:11:5 | LL | let _x = println!("x"); | ^^^^^^^^^^^^^^^^^^^^^^^ help: omit the `let` binding: `println!("x");` @@ -8,7 +8,7 @@ LL | let _x = println!("x"); = help: to override `-D warnings` add `#[allow(clippy::let_unit_value)]` error: this let-binding has unit value - --> tests/ui/let_unit.rs:60:5 + --> tests/ui/let_unit.rs:59:5 | LL | / let _ = v LL | | .into_iter() @@ -31,7 +31,7 @@ LL + .unwrap(); | error: this let-binding has unit value - --> tests/ui/let_unit.rs:109:5 + --> tests/ui/let_unit.rs:108:5 | LL | / let x = match Some(0) { LL | | None => f2(1), @@ -52,7 +52,7 @@ LL + }; | error: this let-binding has unit value - --> tests/ui/let_unit.rs:190:9 + --> tests/ui/let_unit.rs:189:9 | LL | let res = returns_unit(); | ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/macro_use_imports.fixed b/tests/ui/macro_use_imports.fixed index 46c053b779e70..38ed5a957e73e 100644 --- a/tests/ui/macro_use_imports.fixed +++ b/tests/ui/macro_use_imports.fixed @@ -4,7 +4,6 @@ //@ignore-32bit -#![feature(lint_reasons)] #![allow(unused_imports, unreachable_code, unused_variables, dead_code, unused_attributes)] #![allow(clippy::single_component_path_imports)] #![warn(clippy::macro_use_imports)] diff --git a/tests/ui/macro_use_imports.rs b/tests/ui/macro_use_imports.rs index 47f5c9bf8845e..ae6cc16ed2769 100644 --- a/tests/ui/macro_use_imports.rs +++ b/tests/ui/macro_use_imports.rs @@ -4,7 +4,6 @@ //@ignore-32bit -#![feature(lint_reasons)] #![allow(unused_imports, unreachable_code, unused_variables, dead_code, unused_attributes)] #![allow(clippy::single_component_path_imports)] #![warn(clippy::macro_use_imports)] diff --git a/tests/ui/macro_use_imports.stderr b/tests/ui/macro_use_imports.stderr index a3733b1c0c96c..ea0670d366675 100644 --- a/tests/ui/macro_use_imports.stderr +++ b/tests/ui/macro_use_imports.stderr @@ -1,5 +1,5 @@ error: `macro_use` attributes are no longer needed in the Rust 2018 edition - --> tests/ui/macro_use_imports.rs:19:5 + --> tests/ui/macro_use_imports.rs:18:5 | LL | #[macro_use] | ^^^^^^^^^^^^ help: remove the attribute and import the macro directly, try: `use mac::{pub_macro, inner_mod_macro, function_macro, ty_macro, pub_in_private_macro};` @@ -8,19 +8,19 @@ LL | #[macro_use] = help: to override `-D warnings` add `#[allow(clippy::macro_use_imports)]` error: `macro_use` attributes are no longer needed in the Rust 2018 edition - --> tests/ui/macro_use_imports.rs:23:5 + --> tests/ui/macro_use_imports.rs:22:5 | LL | #[macro_use] | ^^^^^^^^^^^^ help: remove the attribute and import the macro directly, try: `use mac::{inner::mut_mut, inner::try_err};` error: `macro_use` attributes are no longer needed in the Rust 2018 edition - --> tests/ui/macro_use_imports.rs:25:5 + --> tests/ui/macro_use_imports.rs:24:5 | LL | #[macro_use] | ^^^^^^^^^^^^ help: remove the attribute and import the macro directly, try: `use mac::inner::nested::string_add;` error: `macro_use` attributes are no longer needed in the Rust 2018 edition - --> tests/ui/macro_use_imports.rs:21:5 + --> tests/ui/macro_use_imports.rs:20:5 | LL | #[macro_use] | ^^^^^^^^^^^^ help: remove the attribute and import the macro directly, try: `use mini_mac::ClippyMiniMacroTest;` diff --git a/tests/ui/macro_use_imports_expect.rs b/tests/ui/macro_use_imports_expect.rs index b9677851b92de..df6d5b9fbabf2 100644 --- a/tests/ui/macro_use_imports_expect.rs +++ b/tests/ui/macro_use_imports_expect.rs @@ -3,7 +3,6 @@ //@aux-build:proc_macro_derive.rs //@ignore-32bit -#![feature(lint_reasons)] #![allow(unused_imports, unreachable_code, unused_variables, dead_code, unused_attributes)] #![allow(clippy::single_component_path_imports)] #![warn(clippy::macro_use_imports)] diff --git a/tests/ui/manual_non_exhaustive_enum.rs b/tests/ui/manual_non_exhaustive_enum.rs index eb38753203110..31c3cc8013722 100644 --- a/tests/ui/manual_non_exhaustive_enum.rs +++ b/tests/ui/manual_non_exhaustive_enum.rs @@ -1,4 +1,3 @@ -#![feature(lint_reasons)] #![warn(clippy::manual_non_exhaustive)] #![allow(unused)] //@no-rustfix diff --git a/tests/ui/manual_non_exhaustive_enum.stderr b/tests/ui/manual_non_exhaustive_enum.stderr index ee43b8ddc0246..dc669568dd2d4 100644 --- a/tests/ui/manual_non_exhaustive_enum.stderr +++ b/tests/ui/manual_non_exhaustive_enum.stderr @@ -1,5 +1,5 @@ error: this seems like a manual implementation of the non-exhaustive pattern - --> tests/ui/manual_non_exhaustive_enum.rs:5:1 + --> tests/ui/manual_non_exhaustive_enum.rs:4:1 | LL | enum E { | ^----- @@ -15,7 +15,7 @@ LL | | } | |_^ | help: remove this variant - --> tests/ui/manual_non_exhaustive_enum.rs:10:5 + --> tests/ui/manual_non_exhaustive_enum.rs:9:5 | LL | _C, | ^^ @@ -23,7 +23,7 @@ LL | _C, = help: to override `-D warnings` add `#[allow(clippy::manual_non_exhaustive)]` error: this seems like a manual implementation of the non-exhaustive pattern - --> tests/ui/manual_non_exhaustive_enum.rs:30:1 + --> tests/ui/manual_non_exhaustive_enum.rs:29:1 | LL | enum NoUnderscore { | ^---------------- @@ -38,7 +38,7 @@ LL | | } | |_^ | help: remove this variant - --> tests/ui/manual_non_exhaustive_enum.rs:34:5 + --> tests/ui/manual_non_exhaustive_enum.rs:33:5 | LL | C, | ^ diff --git a/tests/ui/needless_borrow.fixed b/tests/ui/needless_borrow.fixed index 5121077b4cabb..cabdc22bda840 100644 --- a/tests/ui/needless_borrow.fixed +++ b/tests/ui/needless_borrow.fixed @@ -1,4 +1,3 @@ -#![feature(lint_reasons)] #![allow( unused, non_local_definitions, diff --git a/tests/ui/needless_borrow.rs b/tests/ui/needless_borrow.rs index e3a5cb280bada..50062589645f2 100644 --- a/tests/ui/needless_borrow.rs +++ b/tests/ui/needless_borrow.rs @@ -1,4 +1,3 @@ -#![feature(lint_reasons)] #![allow( unused, non_local_definitions, diff --git a/tests/ui/needless_borrow.stderr b/tests/ui/needless_borrow.stderr index 4b2b17e7e570a..bf0e265c25030 100644 --- a/tests/ui/needless_borrow.stderr +++ b/tests/ui/needless_borrow.stderr @@ -1,5 +1,5 @@ error: this expression creates a reference which is immediately dereferenced by the compiler - --> tests/ui/needless_borrow.rs:16:15 + --> tests/ui/needless_borrow.rs:15:15 | LL | let _ = x(&&a); // warn | ^^^ help: change this to: `&a` @@ -8,163 +8,163 @@ LL | let _ = x(&&a); // warn = help: to override `-D warnings` add `#[allow(clippy::needless_borrow)]` error: this expression creates a reference which is immediately dereferenced by the compiler - --> tests/ui/needless_borrow.rs:20:13 + --> tests/ui/needless_borrow.rs:19:13 | LL | mut_ref(&mut &mut b); // warn | ^^^^^^^^^^^ help: change this to: `&mut b` error: this expression creates a reference which is immediately dereferenced by the compiler - --> tests/ui/needless_borrow.rs:32:13 + --> tests/ui/needless_borrow.rs:31:13 | LL | &&a | ^^^ help: change this to: `&a` error: this expression creates a reference which is immediately dereferenced by the compiler - --> tests/ui/needless_borrow.rs:34:15 + --> tests/ui/needless_borrow.rs:33:15 | LL | 46 => &&a, | ^^^ help: change this to: `&a` error: this expression creates a reference which is immediately dereferenced by the compiler - --> tests/ui/needless_borrow.rs:40:27 + --> tests/ui/needless_borrow.rs:39:27 | LL | break &ref_a; | ^^^^^^ help: change this to: `ref_a` error: this expression creates a reference which is immediately dereferenced by the compiler - --> tests/ui/needless_borrow.rs:47:15 + --> tests/ui/needless_borrow.rs:46:15 | LL | let _ = x(&&&a); | ^^^^ help: change this to: `&a` error: this expression creates a reference which is immediately dereferenced by the compiler - --> tests/ui/needless_borrow.rs:48:15 + --> tests/ui/needless_borrow.rs:47:15 | LL | let _ = x(&mut &&a); | ^^^^^^^^ help: change this to: `&a` error: this expression creates a reference which is immediately dereferenced by the compiler - --> tests/ui/needless_borrow.rs:49:15 + --> tests/ui/needless_borrow.rs:48:15 | LL | let _ = x(&&&mut b); | ^^^^^^^^ help: change this to: `&mut b` error: this expression creates a reference which is immediately dereferenced by the compiler - --> tests/ui/needless_borrow.rs:50:15 + --> tests/ui/needless_borrow.rs:49:15 | LL | let _ = x(&&ref_a); | ^^^^^^^ help: change this to: `ref_a` error: this expression creates a reference which is immediately dereferenced by the compiler - --> tests/ui/needless_borrow.rs:53:11 + --> tests/ui/needless_borrow.rs:52:11 | LL | x(&b); | ^^ help: change this to: `b` error: this expression creates a reference which is immediately dereferenced by the compiler - --> tests/ui/needless_borrow.rs:60:13 + --> tests/ui/needless_borrow.rs:59:13 | LL | mut_ref(&mut x); | ^^^^^^ help: change this to: `x` error: this expression creates a reference which is immediately dereferenced by the compiler - --> tests/ui/needless_borrow.rs:61:13 + --> tests/ui/needless_borrow.rs:60:13 | LL | mut_ref(&mut &mut x); | ^^^^^^^^^^^ help: change this to: `x` error: this expression creates a reference which is immediately dereferenced by the compiler - --> tests/ui/needless_borrow.rs:62:23 + --> tests/ui/needless_borrow.rs:61:23 | LL | let y: &mut i32 = &mut x; | ^^^^^^ help: change this to: `x` error: this expression creates a reference which is immediately dereferenced by the compiler - --> tests/ui/needless_borrow.rs:63:23 + --> tests/ui/needless_borrow.rs:62:23 | LL | let y: &mut i32 = &mut &mut x; | ^^^^^^^^^^^ help: change this to: `x` error: this expression creates a reference which is immediately dereferenced by the compiler - --> tests/ui/needless_borrow.rs:72:14 + --> tests/ui/needless_borrow.rs:71:14 | LL | 0 => &mut x, | ^^^^^^ help: change this to: `x` error: this expression creates a reference which is immediately dereferenced by the compiler - --> tests/ui/needless_borrow.rs:78:14 + --> tests/ui/needless_borrow.rs:77:14 | LL | 0 => &mut x, | ^^^^^^ help: change this to: `x` error: this expression borrows a value the compiler would automatically borrow - --> tests/ui/needless_borrow.rs:90:13 + --> tests/ui/needless_borrow.rs:89:13 | LL | let _ = (&x).0; | ^^^^ help: change this to: `x` error: this expression borrows a value the compiler would automatically borrow - --> tests/ui/needless_borrow.rs:92:22 + --> tests/ui/needless_borrow.rs:91:22 | LL | let _ = unsafe { (&*x).0 }; | ^^^^^ help: change this to: `(*x)` error: this expression creates a reference which is immediately dereferenced by the compiler - --> tests/ui/needless_borrow.rs:102:5 + --> tests/ui/needless_borrow.rs:101:5 | LL | (&&()).foo(); | ^^^^^^ help: change this to: `(&())` error: this expression creates a reference which is immediately dereferenced by the compiler - --> tests/ui/needless_borrow.rs:111:5 + --> tests/ui/needless_borrow.rs:110:5 | LL | (&&5).foo(); | ^^^^^ help: change this to: `(&5)` error: this expression creates a reference which is immediately dereferenced by the compiler - --> tests/ui/needless_borrow.rs:137:23 + --> tests/ui/needless_borrow.rs:136:23 | LL | let x: (&str,) = (&"",); | ^^^ help: change this to: `""` error: this expression borrows a value the compiler would automatically borrow - --> tests/ui/needless_borrow.rs:179:13 + --> tests/ui/needless_borrow.rs:178:13 | LL | (&self.f)() | ^^^^^^^^^ help: change this to: `(self.f)` error: this expression borrows a value the compiler would automatically borrow - --> tests/ui/needless_borrow.rs:188:13 + --> tests/ui/needless_borrow.rs:187:13 | LL | (&mut self.f)() | ^^^^^^^^^^^^^ help: change this to: `(self.f)` error: this expression borrows a value the compiler would automatically borrow - --> tests/ui/needless_borrow.rs:225:22 + --> tests/ui/needless_borrow.rs:224:22 | LL | let _ = &mut (&mut { x.u }).x; | ^^^^^^^^^^^^^^ help: change this to: `{ x.u }` error: this expression borrows a value the compiler would automatically borrow - --> tests/ui/needless_borrow.rs:232:22 + --> tests/ui/needless_borrow.rs:231:22 | LL | let _ = &mut (&mut { x.u }).x; | ^^^^^^^^^^^^^^ help: change this to: `{ x.u }` error: this expression borrows a value the compiler would automatically borrow - --> tests/ui/needless_borrow.rs:236:22 + --> tests/ui/needless_borrow.rs:235:22 | LL | let _ = &mut (&mut x.u).x; | ^^^^^^^^^^ help: change this to: `x.u` error: this expression borrows a value the compiler would automatically borrow - --> tests/ui/needless_borrow.rs:237:22 + --> tests/ui/needless_borrow.rs:236:22 | LL | let _ = &mut (&mut { x.u }).x; | ^^^^^^^^^^^^^^ help: change this to: `{ x.u }` error: this expression creates a reference which is immediately dereferenced by the compiler - --> tests/ui/needless_borrow.rs:258:23 + --> tests/ui/needless_borrow.rs:257:23 | LL | option.unwrap_or((&x.0,)); | ^^^^ help: change this to: `x.0` diff --git a/tests/ui/needless_pass_by_ref_mut.rs b/tests/ui/needless_pass_by_ref_mut.rs index 3f5f55f400208..eee62122fdfda 100644 --- a/tests/ui/needless_pass_by_ref_mut.rs +++ b/tests/ui/needless_pass_by_ref_mut.rs @@ -5,7 +5,6 @@ clippy::ptr_arg )] #![warn(clippy::needless_pass_by_ref_mut)] -#![feature(lint_reasons)] //@no-rustfix use std::ptr::NonNull; diff --git a/tests/ui/needless_pass_by_ref_mut.stderr b/tests/ui/needless_pass_by_ref_mut.stderr index 21ca393dcb63c..51e3ba37dede1 100644 --- a/tests/ui/needless_pass_by_ref_mut.stderr +++ b/tests/ui/needless_pass_by_ref_mut.stderr @@ -1,5 +1,5 @@ error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:12:11 + --> tests/ui/needless_pass_by_ref_mut.rs:11:11 | LL | fn foo(s: &mut Vec, b: &u32, x: &mut u32) { | ^^^^^^^^^^^^^ help: consider changing to: `&Vec` @@ -8,79 +8,79 @@ LL | fn foo(s: &mut Vec, b: &u32, x: &mut u32) { = help: to override `-D warnings` add `#[allow(clippy::needless_pass_by_ref_mut)]` error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:37:12 + --> tests/ui/needless_pass_by_ref_mut.rs:36:12 | LL | fn foo6(s: &mut Vec) { | ^^^^^^^^^^^^^ help: consider changing to: `&Vec` error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:47:12 + --> tests/ui/needless_pass_by_ref_mut.rs:46:12 | LL | fn bar(&mut self) {} | ^^^^^^^^^ help: consider changing to: `&self` error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:50:29 + --> tests/ui/needless_pass_by_ref_mut.rs:49:29 | LL | fn mushroom(&self, vec: &mut Vec) -> usize { | ^^^^^^^^^^^^^ help: consider changing to: `&Vec` error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:127:16 + --> tests/ui/needless_pass_by_ref_mut.rs:126:16 | LL | async fn a1(x: &mut i32) { | ^^^^^^^^ help: consider changing to: `&i32` error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:131:16 + --> tests/ui/needless_pass_by_ref_mut.rs:130:16 | LL | async fn a2(x: &mut i32, y: String) { | ^^^^^^^^ help: consider changing to: `&i32` error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:135:16 + --> tests/ui/needless_pass_by_ref_mut.rs:134:16 | LL | async fn a3(x: &mut i32, y: String, z: String) { | ^^^^^^^^ help: consider changing to: `&i32` error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:139:16 + --> tests/ui/needless_pass_by_ref_mut.rs:138:16 | LL | async fn a4(x: &mut i32, y: i32) { | ^^^^^^^^ help: consider changing to: `&i32` error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:143:24 + --> tests/ui/needless_pass_by_ref_mut.rs:142:24 | LL | async fn a5(x: i32, y: &mut i32) { | ^^^^^^^^ help: consider changing to: `&i32` error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:147:24 + --> tests/ui/needless_pass_by_ref_mut.rs:146:24 | LL | async fn a6(x: i32, y: &mut i32) { | ^^^^^^^^ help: consider changing to: `&i32` error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:151:32 + --> tests/ui/needless_pass_by_ref_mut.rs:150:32 | LL | async fn a7(x: i32, y: i32, z: &mut i32) { | ^^^^^^^^ help: consider changing to: `&i32` error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:155:24 + --> tests/ui/needless_pass_by_ref_mut.rs:154:24 | LL | async fn a8(x: i32, a: &mut i32, y: i32, z: &mut i32) { | ^^^^^^^^ help: consider changing to: `&i32` error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:155:45 + --> tests/ui/needless_pass_by_ref_mut.rs:154:45 | LL | async fn a8(x: i32, a: &mut i32, y: i32, z: &mut i32) { | ^^^^^^^^ help: consider changing to: `&i32` error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:189:16 + --> tests/ui/needless_pass_by_ref_mut.rs:188:16 | LL | fn cfg_warn(s: &mut u32) {} | ^^^^^^^^ help: consider changing to: `&u32` @@ -88,7 +88,7 @@ LL | fn cfg_warn(s: &mut u32) {} = note: this is cfg-gated and may require further changes error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:195:20 + --> tests/ui/needless_pass_by_ref_mut.rs:194:20 | LL | fn cfg_warn(s: &mut u32) {} | ^^^^^^^^ help: consider changing to: `&u32` @@ -96,19 +96,19 @@ LL | fn cfg_warn(s: &mut u32) {} = note: this is cfg-gated and may require further changes error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:209:39 + --> tests/ui/needless_pass_by_ref_mut.rs:208:39 | LL | async fn inner_async2(x: &mut i32, y: &mut u32) { | ^^^^^^^^ help: consider changing to: `&u32` error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:217:26 + --> tests/ui/needless_pass_by_ref_mut.rs:216:26 | LL | async fn inner_async3(x: &mut i32, y: &mut u32) { | ^^^^^^^^ help: consider changing to: `&i32` error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:236:34 + --> tests/ui/needless_pass_by_ref_mut.rs:235:34 | LL | pub async fn call_in_closure1(n: &mut str) { | ^^^^^^^^ help: consider changing to: `&str` @@ -116,7 +116,7 @@ LL | pub async fn call_in_closure1(n: &mut str) { = warning: changing this function will impact semver compatibility error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:255:20 + --> tests/ui/needless_pass_by_ref_mut.rs:254:20 | LL | pub fn closure2(n: &mut usize) -> impl '_ + FnMut() -> usize { | ^^^^^^^^^^ help: consider changing to: `&usize` @@ -124,7 +124,7 @@ LL | pub fn closure2(n: &mut usize) -> impl '_ + FnMut() -> usize { = warning: changing this function will impact semver compatibility error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:266:26 + --> tests/ui/needless_pass_by_ref_mut.rs:265:26 | LL | pub async fn closure4(n: &mut usize) { | ^^^^^^^^^^ help: consider changing to: `&usize` @@ -132,85 +132,85 @@ LL | pub async fn closure4(n: &mut usize) { = warning: changing this function will impact semver compatibility error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:315:12 + --> tests/ui/needless_pass_by_ref_mut.rs:314:12 | LL | fn bar(&mut self) {} | ^^^^^^^^^ help: consider changing to: `&self` error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:317:18 + --> tests/ui/needless_pass_by_ref_mut.rs:316:18 | LL | async fn foo(&mut self, u: &mut i32, v: &mut u32) { | ^^^^^^^^^ help: consider changing to: `&self` error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:317:45 + --> tests/ui/needless_pass_by_ref_mut.rs:316:45 | LL | async fn foo(&mut self, u: &mut i32, v: &mut u32) { | ^^^^^^^^ help: consider changing to: `&u32` error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:325:46 + --> tests/ui/needless_pass_by_ref_mut.rs:324:46 | LL | async fn foo2(&mut self, u: &mut i32, v: &mut u32) { | ^^^^^^^^ help: consider changing to: `&u32` error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:341:18 + --> tests/ui/needless_pass_by_ref_mut.rs:340:18 | LL | fn _empty_tup(x: &mut (())) {} | ^^^^^^^^^ help: consider changing to: `&()` error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:342:19 + --> tests/ui/needless_pass_by_ref_mut.rs:341:19 | LL | fn _single_tup(x: &mut ((i32,))) {} | ^^^^^^^^^^^^^ help: consider changing to: `&(i32,)` error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:343:18 + --> tests/ui/needless_pass_by_ref_mut.rs:342:18 | LL | fn _multi_tup(x: &mut ((i32, u32))) {} | ^^^^^^^^^^^^^^^^^ help: consider changing to: `&(i32, u32)` error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:344:11 + --> tests/ui/needless_pass_by_ref_mut.rs:343:11 | LL | fn _fn(x: &mut (fn())) {} | ^^^^^^^^^^^ help: consider changing to: `&fn()` error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:346:23 + --> tests/ui/needless_pass_by_ref_mut.rs:345:23 | LL | fn _extern_rust_fn(x: &mut extern "Rust" fn()) {} | ^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing to: `&extern "Rust" fn()` error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:347:20 + --> tests/ui/needless_pass_by_ref_mut.rs:346:20 | LL | fn _extern_c_fn(x: &mut extern "C" fn()) {} | ^^^^^^^^^^^^^^^^^^^^ help: consider changing to: `&extern "C" fn()` error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:348:18 + --> tests/ui/needless_pass_by_ref_mut.rs:347:18 | LL | fn _unsafe_fn(x: &mut unsafe fn()) {} | ^^^^^^^^^^^^^^^^ help: consider changing to: `&unsafe fn()` error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:349:25 + --> tests/ui/needless_pass_by_ref_mut.rs:348:25 | LL | fn _unsafe_extern_fn(x: &mut unsafe extern "C" fn()) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing to: `&unsafe extern "C" fn()` error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:350:20 + --> tests/ui/needless_pass_by_ref_mut.rs:349:20 | LL | fn _fn_with_arg(x: &mut unsafe extern "C" fn(i32)) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing to: `&unsafe extern "C" fn(i32)` error: this argument is a mutable reference, but not used mutably - --> tests/ui/needless_pass_by_ref_mut.rs:351:20 + --> tests/ui/needless_pass_by_ref_mut.rs:350:20 | LL | fn _fn_with_ret(x: &mut unsafe extern "C" fn() -> (i32)) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing to: `&unsafe extern "C" fn() -> (i32)` diff --git a/tests/ui/needless_return.fixed b/tests/ui/needless_return.fixed index a9271cb399d8a..853f685f04c76 100644 --- a/tests/ui/needless_return.fixed +++ b/tests/ui/needless_return.fixed @@ -1,4 +1,3 @@ -#![feature(lint_reasons)] #![feature(yeet_expr)] #![allow(unused)] #![allow( diff --git a/tests/ui/needless_return.rs b/tests/ui/needless_return.rs index dc888bf667f15..e9c1e0e8ae8ed 100644 --- a/tests/ui/needless_return.rs +++ b/tests/ui/needless_return.rs @@ -1,4 +1,3 @@ -#![feature(lint_reasons)] #![feature(yeet_expr)] #![allow(unused)] #![allow( diff --git a/tests/ui/needless_return.stderr b/tests/ui/needless_return.stderr index b49f199ba5ab9..6c891fe7ad3f8 100644 --- a/tests/ui/needless_return.stderr +++ b/tests/ui/needless_return.stderr @@ -1,5 +1,5 @@ error: unneeded `return` statement - --> tests/ui/needless_return.rs:26:5 + --> tests/ui/needless_return.rs:25:5 | LL | return true; | ^^^^^^^^^^^ @@ -13,7 +13,7 @@ LL + true | error: unneeded `return` statement - --> tests/ui/needless_return.rs:30:5 + --> tests/ui/needless_return.rs:29:5 | LL | return true; | ^^^^^^^^^^^ @@ -25,7 +25,7 @@ LL + true | error: unneeded `return` statement - --> tests/ui/needless_return.rs:35:5 + --> tests/ui/needless_return.rs:34:5 | LL | return true;;; | ^^^^^^^^^^^ @@ -37,7 +37,7 @@ LL + true | error: unneeded `return` statement - --> tests/ui/needless_return.rs:40:5 + --> tests/ui/needless_return.rs:39:5 | LL | return true;; ; ; | ^^^^^^^^^^^ @@ -49,7 +49,7 @@ LL + true | error: unneeded `return` statement - --> tests/ui/needless_return.rs:45:9 + --> tests/ui/needless_return.rs:44:9 | LL | return true; | ^^^^^^^^^^^ @@ -61,7 +61,7 @@ LL + true | error: unneeded `return` statement - --> tests/ui/needless_return.rs:47:9 + --> tests/ui/needless_return.rs:46:9 | LL | return false; | ^^^^^^^^^^^^ @@ -73,7 +73,7 @@ LL + false | error: unneeded `return` statement - --> tests/ui/needless_return.rs:53:17 + --> tests/ui/needless_return.rs:52:17 | LL | true => return false, | ^^^^^^^^^^^^ @@ -84,7 +84,7 @@ LL | true => false, | ~~~~~ error: unneeded `return` statement - --> tests/ui/needless_return.rs:55:13 + --> tests/ui/needless_return.rs:54:13 | LL | return true; | ^^^^^^^^^^^ @@ -96,7 +96,7 @@ LL + true | error: unneeded `return` statement - --> tests/ui/needless_return.rs:62:9 + --> tests/ui/needless_return.rs:61:9 | LL | return true; | ^^^^^^^^^^^ @@ -108,7 +108,7 @@ LL + true | error: unneeded `return` statement - --> tests/ui/needless_return.rs:64:16 + --> tests/ui/needless_return.rs:63:16 | LL | let _ = || return true; | ^^^^^^^^^^^ @@ -119,7 +119,7 @@ LL | let _ = || true; | ~~~~ error: unneeded `return` statement - --> tests/ui/needless_return.rs:68:5 + --> tests/ui/needless_return.rs:67:5 | LL | return the_answer!(); | ^^^^^^^^^^^^^^^^^^^^ @@ -131,7 +131,7 @@ LL + the_answer!() | error: unneeded `return` statement - --> tests/ui/needless_return.rs:71:21 + --> tests/ui/needless_return.rs:70:21 | LL | fn test_void_fun() { | _____________________^ @@ -146,7 +146,7 @@ LL + fn test_void_fun() { | error: unneeded `return` statement - --> tests/ui/needless_return.rs:76:11 + --> tests/ui/needless_return.rs:75:11 | LL | if b { | ___________^ @@ -161,7 +161,7 @@ LL + if b { | error: unneeded `return` statement - --> tests/ui/needless_return.rs:78:13 + --> tests/ui/needless_return.rs:77:13 | LL | } else { | _____________^ @@ -176,7 +176,7 @@ LL + } else { | error: unneeded `return` statement - --> tests/ui/needless_return.rs:86:14 + --> tests/ui/needless_return.rs:85:14 | LL | _ => return, | ^^^^^^ @@ -187,7 +187,7 @@ LL | _ => (), | ~~ error: unneeded `return` statement - --> tests/ui/needless_return.rs:94:24 + --> tests/ui/needless_return.rs:93:24 | LL | let _ = 42; | ________________________^ @@ -202,7 +202,7 @@ LL + let _ = 42; | error: unneeded `return` statement - --> tests/ui/needless_return.rs:97:14 + --> tests/ui/needless_return.rs:96:14 | LL | _ => return, | ^^^^^^ @@ -213,7 +213,7 @@ LL | _ => (), | ~~ error: unneeded `return` statement - --> tests/ui/needless_return.rs:110:9 + --> tests/ui/needless_return.rs:109:9 | LL | return String::from("test"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -225,7 +225,7 @@ LL + String::from("test") | error: unneeded `return` statement - --> tests/ui/needless_return.rs:112:9 + --> tests/ui/needless_return.rs:111:9 | LL | return String::new(); | ^^^^^^^^^^^^^^^^^^^^ @@ -237,7 +237,7 @@ LL + String::new() | error: unneeded `return` statement - --> tests/ui/needless_return.rs:134:32 + --> tests/ui/needless_return.rs:133:32 | LL | bar.unwrap_or_else(|_| return) | ^^^^^^ @@ -248,7 +248,7 @@ LL | bar.unwrap_or_else(|_| {}) | ~~ error: unneeded `return` statement - --> tests/ui/needless_return.rs:138:21 + --> tests/ui/needless_return.rs:137:21 | LL | let _ = || { | _____________________^ @@ -263,7 +263,7 @@ LL + let _ = || { | error: unneeded `return` statement - --> tests/ui/needless_return.rs:141:20 + --> tests/ui/needless_return.rs:140:20 | LL | let _ = || return; | ^^^^^^ @@ -274,7 +274,7 @@ LL | let _ = || {}; | ~~ error: unneeded `return` statement - --> tests/ui/needless_return.rs:147:32 + --> tests/ui/needless_return.rs:146:32 | LL | res.unwrap_or_else(|_| return Foo) | ^^^^^^^^^^ @@ -285,7 +285,7 @@ LL | res.unwrap_or_else(|_| Foo) | ~~~ error: unneeded `return` statement - --> tests/ui/needless_return.rs:156:5 + --> tests/ui/needless_return.rs:155:5 | LL | return true; | ^^^^^^^^^^^ @@ -297,7 +297,7 @@ LL + true | error: unneeded `return` statement - --> tests/ui/needless_return.rs:160:5 + --> tests/ui/needless_return.rs:159:5 | LL | return true; | ^^^^^^^^^^^ @@ -309,7 +309,7 @@ LL + true | error: unneeded `return` statement - --> tests/ui/needless_return.rs:165:9 + --> tests/ui/needless_return.rs:164:9 | LL | return true; | ^^^^^^^^^^^ @@ -321,7 +321,7 @@ LL + true | error: unneeded `return` statement - --> tests/ui/needless_return.rs:167:9 + --> tests/ui/needless_return.rs:166:9 | LL | return false; | ^^^^^^^^^^^^ @@ -333,7 +333,7 @@ LL + false | error: unneeded `return` statement - --> tests/ui/needless_return.rs:173:17 + --> tests/ui/needless_return.rs:172:17 | LL | true => return false, | ^^^^^^^^^^^^ @@ -344,7 +344,7 @@ LL | true => false, | ~~~~~ error: unneeded `return` statement - --> tests/ui/needless_return.rs:175:13 + --> tests/ui/needless_return.rs:174:13 | LL | return true; | ^^^^^^^^^^^ @@ -356,7 +356,7 @@ LL + true | error: unneeded `return` statement - --> tests/ui/needless_return.rs:182:9 + --> tests/ui/needless_return.rs:181:9 | LL | return true; | ^^^^^^^^^^^ @@ -368,7 +368,7 @@ LL + true | error: unneeded `return` statement - --> tests/ui/needless_return.rs:184:16 + --> tests/ui/needless_return.rs:183:16 | LL | let _ = || return true; | ^^^^^^^^^^^ @@ -379,7 +379,7 @@ LL | let _ = || true; | ~~~~ error: unneeded `return` statement - --> tests/ui/needless_return.rs:188:5 + --> tests/ui/needless_return.rs:187:5 | LL | return the_answer!(); | ^^^^^^^^^^^^^^^^^^^^ @@ -391,7 +391,7 @@ LL + the_answer!() | error: unneeded `return` statement - --> tests/ui/needless_return.rs:191:33 + --> tests/ui/needless_return.rs:190:33 | LL | async fn async_test_void_fun() { | _________________________________^ @@ -406,7 +406,7 @@ LL + async fn async_test_void_fun() { | error: unneeded `return` statement - --> tests/ui/needless_return.rs:196:11 + --> tests/ui/needless_return.rs:195:11 | LL | if b { | ___________^ @@ -421,7 +421,7 @@ LL + if b { | error: unneeded `return` statement - --> tests/ui/needless_return.rs:198:13 + --> tests/ui/needless_return.rs:197:13 | LL | } else { | _____________^ @@ -436,7 +436,7 @@ LL + } else { | error: unneeded `return` statement - --> tests/ui/needless_return.rs:206:14 + --> tests/ui/needless_return.rs:205:14 | LL | _ => return, | ^^^^^^ @@ -447,7 +447,7 @@ LL | _ => (), | ~~ error: unneeded `return` statement - --> tests/ui/needless_return.rs:219:9 + --> tests/ui/needless_return.rs:218:9 | LL | return String::from("test"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -459,7 +459,7 @@ LL + String::from("test") | error: unneeded `return` statement - --> tests/ui/needless_return.rs:221:9 + --> tests/ui/needless_return.rs:220:9 | LL | return String::new(); | ^^^^^^^^^^^^^^^^^^^^ @@ -471,7 +471,7 @@ LL + String::new() | error: unneeded `return` statement - --> tests/ui/needless_return.rs:237:5 + --> tests/ui/needless_return.rs:236:5 | LL | return format!("Hello {}", "world!"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -483,7 +483,7 @@ LL + format!("Hello {}", "world!") | error: unneeded `return` statement - --> tests/ui/needless_return.rs:249:9 + --> tests/ui/needless_return.rs:248:9 | LL | return true; | ^^^^^^^^^^^ @@ -497,7 +497,7 @@ LL ~ } | error: unneeded `return` statement - --> tests/ui/needless_return.rs:251:9 + --> tests/ui/needless_return.rs:250:9 | LL | return false; | ^^^^^^^^^^^^ @@ -509,7 +509,7 @@ LL ~ } | error: unneeded `return` statement - --> tests/ui/needless_return.rs:258:13 + --> tests/ui/needless_return.rs:257:13 | LL | return 10; | ^^^^^^^^^ @@ -524,7 +524,7 @@ LL ~ } | error: unneeded `return` statement - --> tests/ui/needless_return.rs:261:13 + --> tests/ui/needless_return.rs:260:13 | LL | return 100; | ^^^^^^^^^^ @@ -537,7 +537,7 @@ LL ~ } | error: unneeded `return` statement - --> tests/ui/needless_return.rs:269:9 + --> tests/ui/needless_return.rs:268:9 | LL | return 0; | ^^^^^^^^ @@ -549,7 +549,7 @@ LL ~ } | error: unneeded `return` statement - --> tests/ui/needless_return.rs:276:13 + --> tests/ui/needless_return.rs:275:13 | LL | return *(x as *const isize); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -564,7 +564,7 @@ LL ~ } | error: unneeded `return` statement - --> tests/ui/needless_return.rs:278:13 + --> tests/ui/needless_return.rs:277:13 | LL | return !*(x as *const isize); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -577,7 +577,7 @@ LL ~ } | error: unneeded `return` statement - --> tests/ui/needless_return.rs:285:20 + --> tests/ui/needless_return.rs:284:20 | LL | let _ = 42; | ____________________^ @@ -594,7 +594,7 @@ LL + let _ = 42; | error: unneeded `return` statement - --> tests/ui/needless_return.rs:292:20 + --> tests/ui/needless_return.rs:291:20 | LL | let _ = 42; return; | ^^^^^^^ @@ -606,7 +606,7 @@ LL + let _ = 42; | error: unneeded `return` statement - --> tests/ui/needless_return.rs:304:9 + --> tests/ui/needless_return.rs:303:9 | LL | return Ok(format!("ok!")); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -618,7 +618,7 @@ LL + Ok(format!("ok!")) | error: unneeded `return` statement - --> tests/ui/needless_return.rs:306:9 + --> tests/ui/needless_return.rs:305:9 | LL | return Err(format!("err!")); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -630,7 +630,7 @@ LL + Err(format!("err!")) | error: unneeded `return` statement - --> tests/ui/needless_return.rs:312:9 + --> tests/ui/needless_return.rs:311:9 | LL | return if true { 1 } else { 2 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -642,7 +642,7 @@ LL + if true { 1 } else { 2 } | error: unneeded `return` statement - --> tests/ui/needless_return.rs:316:9 + --> tests/ui/needless_return.rs:315:9 | LL | return if b1 { 0 } else { 1 } | if b2 { 2 } else { 3 } | if b3 { 4 } else { 5 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -654,7 +654,7 @@ LL + (if b1 { 0 } else { 1 } | if b2 { 2 } else { 3 } | if b3 { 4 } else | error: unneeded `return` statement - --> tests/ui/needless_return.rs:337:5 + --> tests/ui/needless_return.rs:336:5 | LL | return { "a".to_string() } + "b" + { "c" }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/nonminimal_bool.rs b/tests/ui/nonminimal_bool.rs index 38157116e9105..d117e8bf9c7a1 100644 --- a/tests/ui/nonminimal_bool.rs +++ b/tests/ui/nonminimal_bool.rs @@ -1,6 +1,4 @@ //@no-rustfix: overlapping suggestions - -#![feature(lint_reasons)] #![allow( unused, clippy::diverging_sub_expression, diff --git a/tests/ui/nonminimal_bool.stderr b/tests/ui/nonminimal_bool.stderr index b6af06d845ae3..eafffdaf8a638 100644 --- a/tests/ui/nonminimal_bool.stderr +++ b/tests/ui/nonminimal_bool.stderr @@ -1,5 +1,5 @@ error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool.rs:19:13 + --> tests/ui/nonminimal_bool.rs:17:13 | LL | let _ = !true; | ^^^^^ help: try: `false` @@ -8,43 +8,43 @@ LL | let _ = !true; = help: to override `-D warnings` add `#[allow(clippy::nonminimal_bool)]` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool.rs:22:13 + --> tests/ui/nonminimal_bool.rs:20:13 | LL | let _ = !false; | ^^^^^^ help: try: `true` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool.rs:24:13 + --> tests/ui/nonminimal_bool.rs:22:13 | LL | let _ = !!a; | ^^^ help: try: `a` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool.rs:26:13 + --> tests/ui/nonminimal_bool.rs:24:13 | LL | let _ = false || a; | ^^^^^^^^^^ help: try: `a` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool.rs:31:13 + --> tests/ui/nonminimal_bool.rs:29:13 | LL | let _ = !(!a && b); | ^^^^^^^^^^ help: try: `a || !b` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool.rs:33:13 + --> tests/ui/nonminimal_bool.rs:31:13 | LL | let _ = !(!a || b); | ^^^^^^^^^^ help: try: `a && !b` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool.rs:35:13 + --> tests/ui/nonminimal_bool.rs:33:13 | LL | let _ = !a && !(b && c); | ^^^^^^^^^^^^^^^ help: try: `!(a || b && c)` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool.rs:44:13 + --> tests/ui/nonminimal_bool.rs:42:13 | LL | let _ = a == b && c == 5 && a == b; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -57,7 +57,7 @@ LL | let _ = a == b && c == 5; | ~~~~~~~~~~~~~~~~ error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool.rs:46:13 + --> tests/ui/nonminimal_bool.rs:44:13 | LL | let _ = a == b || c == 5 || a == b; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -70,7 +70,7 @@ LL | let _ = a == b || c == 5; | ~~~~~~~~~~~~~~~~ error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool.rs:48:13 + --> tests/ui/nonminimal_bool.rs:46:13 | LL | let _ = a == b && c == 5 && b == a; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -83,7 +83,7 @@ LL | let _ = a == b && c == 5; | ~~~~~~~~~~~~~~~~ error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool.rs:50:13 + --> tests/ui/nonminimal_bool.rs:48:13 | LL | let _ = a != b || !(a != b || c == d); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -96,7 +96,7 @@ LL | let _ = a != b || c != d; | ~~~~~~~~~~~~~~~~ error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool.rs:52:13 + --> tests/ui/nonminimal_bool.rs:50:13 | LL | let _ = a != b && !(a != b && c == d); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -109,43 +109,43 @@ LL | let _ = a != b && c != d; | ~~~~~~~~~~~~~~~~ error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool.rs:83:8 + --> tests/ui/nonminimal_bool.rs:81:8 | LL | if matches!(true, true) && true { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `matches!(true, true)` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool.rs:163:8 + --> tests/ui/nonminimal_bool.rs:161:8 | LL | if !(12 == a) {} | ^^^^^^^^^^ help: try: `12 != a` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool.rs:164:8 + --> tests/ui/nonminimal_bool.rs:162:8 | LL | if !(a == 12) {} | ^^^^^^^^^^ help: try: `a != 12` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool.rs:165:8 + --> tests/ui/nonminimal_bool.rs:163:8 | LL | if !(12 != a) {} | ^^^^^^^^^^ help: try: `12 == a` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool.rs:166:8 + --> tests/ui/nonminimal_bool.rs:164:8 | LL | if !(a != 12) {} | ^^^^^^^^^^ help: try: `a == 12` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool.rs:170:8 + --> tests/ui/nonminimal_bool.rs:168:8 | LL | if !b == true {} | ^^^^^^^^^^ help: try: `b != true` error: this comparison might be written more concisely - --> tests/ui/nonminimal_bool.rs:170:8 + --> tests/ui/nonminimal_bool.rs:168:8 | LL | if !b == true {} | ^^^^^^^^^^ help: try simplifying it as shown: `b != true` @@ -154,61 +154,61 @@ LL | if !b == true {} = help: to override `-D warnings` add `#[allow(clippy::bool_comparison)]` error: equality checks against true are unnecessary - --> tests/ui/nonminimal_bool.rs:170:8 + --> tests/ui/nonminimal_bool.rs:168:8 | LL | if !b == true {} | ^^^^^^^^^^ help: try simplifying it as shown: `!b` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool.rs:171:8 + --> tests/ui/nonminimal_bool.rs:169:8 | LL | if !b != true {} | ^^^^^^^^^^ help: try: `b == true` error: inequality checks against true can be replaced by a negation - --> tests/ui/nonminimal_bool.rs:171:8 + --> tests/ui/nonminimal_bool.rs:169:8 | LL | if !b != true {} | ^^^^^^^^^^ help: try simplifying it as shown: `!(!b)` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool.rs:172:8 + --> tests/ui/nonminimal_bool.rs:170:8 | LL | if true == !b {} | ^^^^^^^^^^ help: try: `true != b` error: this comparison might be written more concisely - --> tests/ui/nonminimal_bool.rs:172:8 + --> tests/ui/nonminimal_bool.rs:170:8 | LL | if true == !b {} | ^^^^^^^^^^ help: try simplifying it as shown: `true != b` error: equality checks against true are unnecessary - --> tests/ui/nonminimal_bool.rs:172:8 + --> tests/ui/nonminimal_bool.rs:170:8 | LL | if true == !b {} | ^^^^^^^^^^ help: try simplifying it as shown: `!b` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool.rs:173:8 + --> tests/ui/nonminimal_bool.rs:171:8 | LL | if true != !b {} | ^^^^^^^^^^ help: try: `true == b` error: inequality checks against true can be replaced by a negation - --> tests/ui/nonminimal_bool.rs:173:8 + --> tests/ui/nonminimal_bool.rs:171:8 | LL | if true != !b {} | ^^^^^^^^^^ help: try simplifying it as shown: `!(!b)` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool.rs:174:8 + --> tests/ui/nonminimal_bool.rs:172:8 | LL | if !b == !c {} | ^^^^^^^^ help: try: `b == c` error: this boolean expression can be simplified - --> tests/ui/nonminimal_bool.rs:175:8 + --> tests/ui/nonminimal_bool.rs:173:8 | LL | if !b != !c {} | ^^^^^^^^ help: try: `b != c` diff --git a/tests/ui/overly_complex_bool_expr.fixed b/tests/ui/overly_complex_bool_expr.fixed index 439b1145431c6..b21e91aa3ad40 100644 --- a/tests/ui/overly_complex_bool_expr.fixed +++ b/tests/ui/overly_complex_bool_expr.fixed @@ -1,4 +1,3 @@ -#![feature(lint_reasons)] #![allow(unused, clippy::diverging_sub_expression)] #![warn(clippy::overly_complex_bool_expr)] diff --git a/tests/ui/overly_complex_bool_expr.rs b/tests/ui/overly_complex_bool_expr.rs index b96fd1adf1180..35ef0a1240a5d 100644 --- a/tests/ui/overly_complex_bool_expr.rs +++ b/tests/ui/overly_complex_bool_expr.rs @@ -1,4 +1,3 @@ -#![feature(lint_reasons)] #![allow(unused, clippy::diverging_sub_expression)] #![warn(clippy::overly_complex_bool_expr)] diff --git a/tests/ui/overly_complex_bool_expr.stderr b/tests/ui/overly_complex_bool_expr.stderr index 21dd5ade53563..5a754236fe4b2 100644 --- a/tests/ui/overly_complex_bool_expr.stderr +++ b/tests/ui/overly_complex_bool_expr.stderr @@ -1,11 +1,11 @@ error: this boolean expression contains a logic bug - --> tests/ui/overly_complex_bool_expr.rs:11:13 + --> tests/ui/overly_complex_bool_expr.rs:10:13 | LL | let _ = a && b || a; | ^^^^^^^^^^^ help: it would look like the following: `a` | help: this expression can be optimized out by applying boolean operations to the outer expression - --> tests/ui/overly_complex_bool_expr.rs:11:18 + --> tests/ui/overly_complex_bool_expr.rs:10:18 | LL | let _ = a && b || a; | ^ @@ -13,49 +13,49 @@ LL | let _ = a && b || a; = help: to override `-D warnings` add `#[allow(clippy::overly_complex_bool_expr)]` error: this boolean expression contains a logic bug - --> tests/ui/overly_complex_bool_expr.rs:14:13 + --> tests/ui/overly_complex_bool_expr.rs:13:13 | LL | let _ = false && a; | ^^^^^^^^^^ help: it would look like the following: `false` | help: this expression can be optimized out by applying boolean operations to the outer expression - --> tests/ui/overly_complex_bool_expr.rs:14:22 + --> tests/ui/overly_complex_bool_expr.rs:13:22 | LL | let _ = false && a; | ^ error: this boolean expression contains a logic bug - --> tests/ui/overly_complex_bool_expr.rs:25:13 + --> tests/ui/overly_complex_bool_expr.rs:24:13 | LL | let _ = a == b && a != b; | ^^^^^^^^^^^^^^^^ help: it would look like the following: `false` | help: this expression can be optimized out by applying boolean operations to the outer expression - --> tests/ui/overly_complex_bool_expr.rs:25:13 + --> tests/ui/overly_complex_bool_expr.rs:24:13 | LL | let _ = a == b && a != b; | ^^^^^^ error: this boolean expression contains a logic bug - --> tests/ui/overly_complex_bool_expr.rs:27:13 + --> tests/ui/overly_complex_bool_expr.rs:26:13 | LL | let _ = a < b && a >= b; | ^^^^^^^^^^^^^^^ help: it would look like the following: `false` | help: this expression can be optimized out by applying boolean operations to the outer expression - --> tests/ui/overly_complex_bool_expr.rs:27:13 + --> tests/ui/overly_complex_bool_expr.rs:26:13 | LL | let _ = a < b && a >= b; | ^^^^^ error: this boolean expression contains a logic bug - --> tests/ui/overly_complex_bool_expr.rs:29:13 + --> tests/ui/overly_complex_bool_expr.rs:28:13 | LL | let _ = a > b && a <= b; | ^^^^^^^^^^^^^^^ help: it would look like the following: `false` | help: this expression can be optimized out by applying boolean operations to the outer expression - --> tests/ui/overly_complex_bool_expr.rs:29:13 + --> tests/ui/overly_complex_bool_expr.rs:28:13 | LL | let _ = a > b && a <= b; | ^^^^^ diff --git a/tests/ui/ptr_arg.rs b/tests/ui/ptr_arg.rs index 5d6e488972cdc..e6ef626812128 100644 --- a/tests/ui/ptr_arg.rs +++ b/tests/ui/ptr_arg.rs @@ -1,4 +1,3 @@ -#![feature(lint_reasons)] #![allow( unused, clippy::many_single_char_names, diff --git a/tests/ui/ptr_arg.stderr b/tests/ui/ptr_arg.stderr index 0342130c992be..1848ef80fc495 100644 --- a/tests/ui/ptr_arg.stderr +++ b/tests/ui/ptr_arg.stderr @@ -1,5 +1,5 @@ error: writing `&Vec` instead of `&[_]` involves a new object where a slice will do - --> tests/ui/ptr_arg.rs:14:14 + --> tests/ui/ptr_arg.rs:13:14 | LL | fn do_vec(x: &Vec) { | ^^^^^^^^^ help: change this to: `&[i64]` @@ -8,49 +8,49 @@ LL | fn do_vec(x: &Vec) { = help: to override `-D warnings` add `#[allow(clippy::ptr_arg)]` error: writing `&mut Vec` instead of `&mut [_]` involves a new object where a slice will do - --> tests/ui/ptr_arg.rs:20:18 + --> tests/ui/ptr_arg.rs:19:18 | LL | fn do_vec_mut(x: &mut Vec) { | ^^^^^^^^^^^^^ help: change this to: `&mut [i64]` error: writing `&mut Vec` instead of `&mut [_]` involves a new object where a slice will do - --> tests/ui/ptr_arg.rs:25:19 + --> tests/ui/ptr_arg.rs:24:19 | LL | fn do_vec_mut2(x: &mut Vec) { | ^^^^^^^^^^^^^ help: change this to: `&mut [i64]` error: writing `&String` instead of `&str` involves a new object where a slice will do - --> tests/ui/ptr_arg.rs:31:14 + --> tests/ui/ptr_arg.rs:30:14 | LL | fn do_str(x: &String) { | ^^^^^^^ help: change this to: `&str` error: writing `&mut String` instead of `&mut str` involves a new object where a slice will do - --> tests/ui/ptr_arg.rs:36:18 + --> tests/ui/ptr_arg.rs:35:18 | LL | fn do_str_mut(x: &mut String) { | ^^^^^^^^^^^ help: change this to: `&mut str` error: writing `&PathBuf` instead of `&Path` involves a new object where a slice will do - --> tests/ui/ptr_arg.rs:41:15 + --> tests/ui/ptr_arg.rs:40:15 | LL | fn do_path(x: &PathBuf) { | ^^^^^^^^ help: change this to: `&Path` error: writing `&mut PathBuf` instead of `&mut Path` involves a new object where a slice will do - --> tests/ui/ptr_arg.rs:46:19 + --> tests/ui/ptr_arg.rs:45:19 | LL | fn do_path_mut(x: &mut PathBuf) { | ^^^^^^^^^^^^ help: change this to: `&mut Path` error: writing `&Vec` instead of `&[_]` involves a new object where a slice will do - --> tests/ui/ptr_arg.rs:55:18 + --> tests/ui/ptr_arg.rs:54:18 | LL | fn do_vec(x: &Vec); | ^^^^^^^^^ help: change this to: `&[i64]` error: writing `&Vec` instead of `&[_]` involves a new object where a slice will do - --> tests/ui/ptr_arg.rs:69:14 + --> tests/ui/ptr_arg.rs:68:14 | LL | fn cloned(x: &Vec) -> Vec { | ^^^^^^^^ @@ -68,7 +68,7 @@ LL ~ x.to_owned() | error: writing `&String` instead of `&str` involves a new object where a slice will do - --> tests/ui/ptr_arg.rs:79:18 + --> tests/ui/ptr_arg.rs:78:18 | LL | fn str_cloned(x: &String) -> String { | ^^^^^^^ @@ -85,7 +85,7 @@ LL ~ x.to_owned() | error: writing `&PathBuf` instead of `&Path` involves a new object where a slice will do - --> tests/ui/ptr_arg.rs:88:19 + --> tests/ui/ptr_arg.rs:87:19 | LL | fn path_cloned(x: &PathBuf) -> PathBuf { | ^^^^^^^^ @@ -102,7 +102,7 @@ LL ~ x.to_path_buf() | error: writing `&String` instead of `&str` involves a new object where a slice will do - --> tests/ui/ptr_arg.rs:97:44 + --> tests/ui/ptr_arg.rs:96:44 | LL | fn false_positive_capacity(x: &Vec, y: &String) { | ^^^^^^^ @@ -117,19 +117,19 @@ LL ~ let c = y; | error: using a reference to `Cow` is not recommended - --> tests/ui/ptr_arg.rs:112:25 + --> tests/ui/ptr_arg.rs:111:25 | LL | fn test_cow_with_ref(c: &Cow<[i32]>) {} | ^^^^^^^^^^^ help: change this to: `&[i32]` error: writing `&String` instead of `&str` involves a new object where a slice will do - --> tests/ui/ptr_arg.rs:142:66 + --> tests/ui/ptr_arg.rs:141:66 | LL | fn some_allowed(#[allow(clippy::ptr_arg)] _v: &Vec, _s: &String) {} | ^^^^^^^ help: change this to: `&str` error: writing `&Vec` instead of `&[_]` involves a new object where a slice will do - --> tests/ui/ptr_arg.rs:172:21 + --> tests/ui/ptr_arg.rs:171:21 | LL | fn foo_vec(vec: &Vec) { | ^^^^^^^^ @@ -143,7 +143,7 @@ LL ~ let _ = vec.to_owned().clone(); | error: writing `&PathBuf` instead of `&Path` involves a new object where a slice will do - --> tests/ui/ptr_arg.rs:178:23 + --> tests/ui/ptr_arg.rs:177:23 | LL | fn foo_path(path: &PathBuf) { | ^^^^^^^^ @@ -157,7 +157,7 @@ LL ~ let _ = path.to_path_buf().clone(); | error: writing `&PathBuf` instead of `&Path` involves a new object where a slice will do - --> tests/ui/ptr_arg.rs:184:21 + --> tests/ui/ptr_arg.rs:183:21 | LL | fn foo_str(str: &PathBuf) { | ^^^^^^^^ @@ -171,43 +171,43 @@ LL ~ let _ = str.to_path_buf().clone(); | error: writing `&mut Vec` instead of `&mut [_]` involves a new object where a slice will do - --> tests/ui/ptr_arg.rs:191:29 + --> tests/ui/ptr_arg.rs:190:29 | LL | fn mut_vec_slice_methods(v: &mut Vec) { | ^^^^^^^^^^^^^ help: change this to: `&mut [u32]` error: writing `&mut Vec` instead of `&mut [_]` involves a new object where a slice will do - --> tests/ui/ptr_arg.rs:254:17 + --> tests/ui/ptr_arg.rs:253:17 | LL | fn dyn_trait(a: &mut Vec, b: &mut String, c: &mut PathBuf) { | ^^^^^^^^^^^^^ help: change this to: `&mut [u32]` error: writing `&mut String` instead of `&mut str` involves a new object where a slice will do - --> tests/ui/ptr_arg.rs:254:35 + --> tests/ui/ptr_arg.rs:253:35 | LL | fn dyn_trait(a: &mut Vec, b: &mut String, c: &mut PathBuf) { | ^^^^^^^^^^^ help: change this to: `&mut str` error: writing `&mut PathBuf` instead of `&mut Path` involves a new object where a slice will do - --> tests/ui/ptr_arg.rs:254:51 + --> tests/ui/ptr_arg.rs:253:51 | LL | fn dyn_trait(a: &mut Vec, b: &mut String, c: &mut PathBuf) { | ^^^^^^^^^^^^ help: change this to: `&mut Path` error: using a reference to `Cow` is not recommended - --> tests/ui/ptr_arg.rs:280:39 + --> tests/ui/ptr_arg.rs:279:39 | LL | fn cow_elided_lifetime<'a>(input: &'a Cow) -> &'a str { | ^^^^^^^^^^^^ help: change this to: `&str` error: using a reference to `Cow` is not recommended - --> tests/ui/ptr_arg.rs:286:36 + --> tests/ui/ptr_arg.rs:285:36 | LL | fn cow_bad_ret_ty_1<'a>(input: &'a Cow<'a, str>) -> &'static str { | ^^^^^^^^^^^^^^^^ help: change this to: `&str` error: using a reference to `Cow` is not recommended - --> tests/ui/ptr_arg.rs:290:40 + --> tests/ui/ptr_arg.rs:289:40 | LL | fn cow_bad_ret_ty_2<'a, 'b>(input: &'a Cow<'a, str>) -> &'b str { | ^^^^^^^^^^^^^^^^ help: change this to: `&str` diff --git a/tests/ui/redundant_clone.fixed b/tests/ui/redundant_clone.fixed index 867f5b2101714..1f79b5e53600d 100644 --- a/tests/ui/redundant_clone.fixed +++ b/tests/ui/redundant_clone.fixed @@ -1,5 +1,4 @@ // rustfix-only-machine-applicable -#![feature(lint_reasons)] #![warn(clippy::redundant_clone)] #![allow( clippy::drop_non_drop, diff --git a/tests/ui/redundant_clone.rs b/tests/ui/redundant_clone.rs index adcbd01e819ca..6909faebc9930 100644 --- a/tests/ui/redundant_clone.rs +++ b/tests/ui/redundant_clone.rs @@ -1,5 +1,4 @@ // rustfix-only-machine-applicable -#![feature(lint_reasons)] #![warn(clippy::redundant_clone)] #![allow( clippy::drop_non_drop, diff --git a/tests/ui/redundant_clone.stderr b/tests/ui/redundant_clone.stderr index 3c37288f55078..d66972bcb5b3a 100644 --- a/tests/ui/redundant_clone.stderr +++ b/tests/ui/redundant_clone.stderr @@ -1,11 +1,11 @@ error: redundant clone - --> tests/ui/redundant_clone.rs:15:42 + --> tests/ui/redundant_clone.rs:14:42 | LL | let _s = ["lorem", "ipsum"].join(" ").to_string(); | ^^^^^^^^^^^^ help: remove this | note: this value is dropped without further use - --> tests/ui/redundant_clone.rs:15:14 + --> tests/ui/redundant_clone.rs:14:14 | LL | let _s = ["lorem", "ipsum"].join(" ").to_string(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -13,169 +13,169 @@ LL | let _s = ["lorem", "ipsum"].join(" ").to_string(); = help: to override `-D warnings` add `#[allow(clippy::redundant_clone)]` error: redundant clone - --> tests/ui/redundant_clone.rs:18:15 + --> tests/ui/redundant_clone.rs:17:15 | LL | let _s = s.clone(); | ^^^^^^^^ help: remove this | note: this value is dropped without further use - --> tests/ui/redundant_clone.rs:18:14 + --> tests/ui/redundant_clone.rs:17:14 | LL | let _s = s.clone(); | ^ error: redundant clone - --> tests/ui/redundant_clone.rs:21:15 + --> tests/ui/redundant_clone.rs:20:15 | LL | let _s = s.to_string(); | ^^^^^^^^^^^^ help: remove this | note: this value is dropped without further use - --> tests/ui/redundant_clone.rs:21:14 + --> tests/ui/redundant_clone.rs:20:14 | LL | let _s = s.to_string(); | ^ error: redundant clone - --> tests/ui/redundant_clone.rs:24:15 + --> tests/ui/redundant_clone.rs:23:15 | LL | let _s = s.to_owned(); | ^^^^^^^^^^^ help: remove this | note: this value is dropped without further use - --> tests/ui/redundant_clone.rs:24:14 + --> tests/ui/redundant_clone.rs:23:14 | LL | let _s = s.to_owned(); | ^ error: redundant clone - --> tests/ui/redundant_clone.rs:26:42 + --> tests/ui/redundant_clone.rs:25:42 | LL | let _s = Path::new("/a/b/").join("c").to_owned(); | ^^^^^^^^^^^ help: remove this | note: this value is dropped without further use - --> tests/ui/redundant_clone.rs:26:14 + --> tests/ui/redundant_clone.rs:25:14 | LL | let _s = Path::new("/a/b/").join("c").to_owned(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: redundant clone - --> tests/ui/redundant_clone.rs:28:42 + --> tests/ui/redundant_clone.rs:27:42 | LL | let _s = Path::new("/a/b/").join("c").to_path_buf(); | ^^^^^^^^^^^^^^ help: remove this | note: this value is dropped without further use - --> tests/ui/redundant_clone.rs:28:14 + --> tests/ui/redundant_clone.rs:27:14 | LL | let _s = Path::new("/a/b/").join("c").to_path_buf(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: redundant clone - --> tests/ui/redundant_clone.rs:30:29 + --> tests/ui/redundant_clone.rs:29:29 | LL | let _s = OsString::new().to_owned(); | ^^^^^^^^^^^ help: remove this | note: this value is dropped without further use - --> tests/ui/redundant_clone.rs:30:14 + --> tests/ui/redundant_clone.rs:29:14 | LL | let _s = OsString::new().to_owned(); | ^^^^^^^^^^^^^^^ error: redundant clone - --> tests/ui/redundant_clone.rs:32:29 + --> tests/ui/redundant_clone.rs:31:29 | LL | let _s = OsString::new().to_os_string(); | ^^^^^^^^^^^^^^^ help: remove this | note: this value is dropped without further use - --> tests/ui/redundant_clone.rs:32:14 + --> tests/ui/redundant_clone.rs:31:14 | LL | let _s = OsString::new().to_os_string(); | ^^^^^^^^^^^^^^^ error: redundant clone - --> tests/ui/redundant_clone.rs:43:19 + --> tests/ui/redundant_clone.rs:42:19 | LL | let _t = tup.0.clone(); | ^^^^^^^^ help: remove this | note: this value is dropped without further use - --> tests/ui/redundant_clone.rs:43:14 + --> tests/ui/redundant_clone.rs:42:14 | LL | let _t = tup.0.clone(); | ^^^^^ error: redundant clone - --> tests/ui/redundant_clone.rs:75:25 + --> tests/ui/redundant_clone.rs:74:25 | LL | if b { (a.clone(), a.clone()) } else { (Alpha, a) } | ^^^^^^^^ help: remove this | note: this value is dropped without further use - --> tests/ui/redundant_clone.rs:75:24 + --> tests/ui/redundant_clone.rs:74:24 | LL | if b { (a.clone(), a.clone()) } else { (Alpha, a) } | ^ error: redundant clone - --> tests/ui/redundant_clone.rs:132:15 + --> tests/ui/redundant_clone.rs:131:15 | LL | let _s = s.clone(); | ^^^^^^^^ help: remove this | note: this value is dropped without further use - --> tests/ui/redundant_clone.rs:132:14 + --> tests/ui/redundant_clone.rs:131:14 | LL | let _s = s.clone(); | ^ error: redundant clone - --> tests/ui/redundant_clone.rs:133:15 + --> tests/ui/redundant_clone.rs:132:15 | LL | let _t = t.clone(); | ^^^^^^^^ help: remove this | note: this value is dropped without further use - --> tests/ui/redundant_clone.rs:133:14 + --> tests/ui/redundant_clone.rs:132:14 | LL | let _t = t.clone(); | ^ error: redundant clone - --> tests/ui/redundant_clone.rs:143:19 + --> tests/ui/redundant_clone.rs:142:19 | LL | let _f = f.clone(); | ^^^^^^^^ help: remove this | note: this value is dropped without further use - --> tests/ui/redundant_clone.rs:143:18 + --> tests/ui/redundant_clone.rs:142:18 | LL | let _f = f.clone(); | ^ error: redundant clone - --> tests/ui/redundant_clone.rs:155:14 + --> tests/ui/redundant_clone.rs:154:14 | LL | let y = x.clone().join("matthias"); | ^^^^^^^^ help: remove this | note: cloned value is neither consumed nor mutated - --> tests/ui/redundant_clone.rs:155:13 + --> tests/ui/redundant_clone.rs:154:13 | LL | let y = x.clone().join("matthias"); | ^^^^^^^^^ error: redundant clone - --> tests/ui/redundant_clone.rs:209:11 + --> tests/ui/redundant_clone.rs:208:11 | LL | foo(&x.clone(), move || { | ^^^^^^^^ help: remove this | note: this value is dropped without further use - --> tests/ui/redundant_clone.rs:209:10 + --> tests/ui/redundant_clone.rs:208:10 | LL | foo(&x.clone(), move || { | ^ diff --git a/tests/ui/ref_binding_to_reference.rs b/tests/ui/ref_binding_to_reference.rs index a4444c95e33c7..001ed31194909 100644 --- a/tests/ui/ref_binding_to_reference.rs +++ b/tests/ui/ref_binding_to_reference.rs @@ -1,6 +1,5 @@ // FIXME: run-rustfix waiting on multi-span suggestions //@no-rustfix -#![feature(lint_reasons)] #![warn(clippy::ref_binding_to_reference)] #![allow(clippy::needless_borrowed_reference, clippy::explicit_auto_deref)] diff --git a/tests/ui/ref_binding_to_reference.stderr b/tests/ui/ref_binding_to_reference.stderr index 96886f80265d8..25ab982238273 100644 --- a/tests/ui/ref_binding_to_reference.stderr +++ b/tests/ui/ref_binding_to_reference.stderr @@ -1,5 +1,5 @@ error: this pattern creates a reference to a reference - --> tests/ui/ref_binding_to_reference.rs:31:14 + --> tests/ui/ref_binding_to_reference.rs:30:14 | LL | Some(ref x) => x, | ^^^^^ @@ -12,7 +12,7 @@ LL | Some(x) => &x, | ~ ~~ error: this pattern creates a reference to a reference - --> tests/ui/ref_binding_to_reference.rs:39:14 + --> tests/ui/ref_binding_to_reference.rs:38:14 | LL | Some(ref x) => { | ^^^^^ @@ -27,7 +27,7 @@ LL ~ &x | error: this pattern creates a reference to a reference - --> tests/ui/ref_binding_to_reference.rs:50:14 + --> tests/ui/ref_binding_to_reference.rs:49:14 | LL | Some(ref x) => m2!(x), | ^^^^^ @@ -38,7 +38,7 @@ LL | Some(x) => m2!(&x), | ~ ~~ error: this pattern creates a reference to a reference - --> tests/ui/ref_binding_to_reference.rs:56:15 + --> tests/ui/ref_binding_to_reference.rs:55:15 | LL | let _ = |&ref x: &&String| { | ^^^^^ @@ -51,7 +51,7 @@ LL ~ let _: &&String = &x; | error: this pattern creates a reference to a reference - --> tests/ui/ref_binding_to_reference.rs:63:12 + --> tests/ui/ref_binding_to_reference.rs:62:12 | LL | fn f2<'a>(&ref x: &&'a String) -> &'a String { | ^^^^^ @@ -65,7 +65,7 @@ LL ~ x | error: this pattern creates a reference to a reference - --> tests/ui/ref_binding_to_reference.rs:71:11 + --> tests/ui/ref_binding_to_reference.rs:70:11 | LL | fn f(&ref x: &&String) { | ^^^^^ @@ -78,7 +78,7 @@ LL ~ let _: &&String = &x; | error: this pattern creates a reference to a reference - --> tests/ui/ref_binding_to_reference.rs:80:11 + --> tests/ui/ref_binding_to_reference.rs:79:11 | LL | fn f(&ref x: &&String) { | ^^^^^ diff --git a/tests/ui/same_name_method.rs b/tests/ui/same_name_method.rs index 26b1a299ba1cf..ba876c2b5a3f7 100644 --- a/tests/ui/same_name_method.rs +++ b/tests/ui/same_name_method.rs @@ -1,4 +1,3 @@ -#![feature(lint_reasons)] #![warn(clippy::same_name_method)] #![allow(dead_code, non_camel_case_types)] diff --git a/tests/ui/same_name_method.stderr b/tests/ui/same_name_method.stderr index 6c87a64b50514..fefdb5c9c23d0 100644 --- a/tests/ui/same_name_method.stderr +++ b/tests/ui/same_name_method.stderr @@ -1,11 +1,11 @@ error: method's name is the same as an existing method in a trait - --> tests/ui/same_name_method.rs:21:13 + --> tests/ui/same_name_method.rs:20:13 | LL | fn foo() {} | ^^^^^^^^^^^ | note: existing `foo` defined here - --> tests/ui/same_name_method.rs:26:13 + --> tests/ui/same_name_method.rs:25:13 | LL | fn foo() {} | ^^^^^^^^^^^ @@ -13,62 +13,62 @@ LL | fn foo() {} = help: to override `-D warnings` add `#[allow(clippy::same_name_method)]` error: method's name is the same as an existing method in a trait - --> tests/ui/same_name_method.rs:36:13 + --> tests/ui/same_name_method.rs:35:13 | LL | fn clone() {} | ^^^^^^^^^^^^^ | note: existing `clone` defined here - --> tests/ui/same_name_method.rs:32:18 + --> tests/ui/same_name_method.rs:31:18 | LL | #[derive(Clone)] | ^^^^^ = note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info) error: method's name is the same as an existing method in a trait - --> tests/ui/same_name_method.rs:47:13 + --> tests/ui/same_name_method.rs:46:13 | LL | fn foo() {} | ^^^^^^^^^^^ | note: existing `foo` defined here - --> tests/ui/same_name_method.rs:52:13 + --> tests/ui/same_name_method.rs:51:13 | LL | fn foo() {} | ^^^^^^^^^^^ error: method's name is the same as an existing method in a trait - --> tests/ui/same_name_method.rs:62:13 + --> tests/ui/same_name_method.rs:61:13 | LL | fn foo() {} | ^^^^^^^^^^^ | note: existing `foo` defined here - --> tests/ui/same_name_method.rs:66:9 + --> tests/ui/same_name_method.rs:65:9 | LL | impl T1 for S {} | ^^^^^^^^^^^^^^^^ error: method's name is the same as an existing method in a trait - --> tests/ui/same_name_method.rs:75:13 + --> tests/ui/same_name_method.rs:74:13 | LL | fn foo() {} | ^^^^^^^^^^^ | note: existing `foo` defined here - --> tests/ui/same_name_method.rs:80:9 + --> tests/ui/same_name_method.rs:79:9 | LL | impl T1 for S {} | ^^^^^^^^^^^^^^^^ error: method's name is the same as an existing method in a trait - --> tests/ui/same_name_method.rs:75:13 + --> tests/ui/same_name_method.rs:74:13 | LL | fn foo() {} | ^^^^^^^^^^^ | note: existing `foo` defined here - --> tests/ui/same_name_method.rs:82:9 + --> tests/ui/same_name_method.rs:81:9 | LL | impl T2 for S {} | ^^^^^^^^^^^^^^^^ diff --git a/tests/ui/unsafe_derive_deserialize.rs b/tests/ui/unsafe_derive_deserialize.rs index 5187e0790423c..14371bc203b3b 100644 --- a/tests/ui/unsafe_derive_deserialize.rs +++ b/tests/ui/unsafe_derive_deserialize.rs @@ -1,4 +1,3 @@ -#![feature(lint_reasons)] #![warn(clippy::unsafe_derive_deserialize)] #![allow(unused, clippy::missing_safety_doc)] diff --git a/tests/ui/unsafe_derive_deserialize.stderr b/tests/ui/unsafe_derive_deserialize.stderr index 06719f23d57f3..f2d4429f707a5 100644 --- a/tests/ui/unsafe_derive_deserialize.stderr +++ b/tests/ui/unsafe_derive_deserialize.stderr @@ -1,5 +1,5 @@ error: you are deriving `serde::Deserialize` on a type that has methods using `unsafe` - --> tests/ui/unsafe_derive_deserialize.rs:9:10 + --> tests/ui/unsafe_derive_deserialize.rs:8:10 | LL | #[derive(Deserialize)] | ^^^^^^^^^^^ @@ -10,7 +10,7 @@ LL | #[derive(Deserialize)] = note: this error originates in the derive macro `Deserialize` (in Nightly builds, run with -Z macro-backtrace for more info) error: you are deriving `serde::Deserialize` on a type that has methods using `unsafe` - --> tests/ui/unsafe_derive_deserialize.rs:18:10 + --> tests/ui/unsafe_derive_deserialize.rs:17:10 | LL | #[derive(Deserialize)] | ^^^^^^^^^^^ @@ -19,7 +19,7 @@ LL | #[derive(Deserialize)] = note: this error originates in the derive macro `Deserialize` (in Nightly builds, run with -Z macro-backtrace for more info) error: you are deriving `serde::Deserialize` on a type that has methods using `unsafe` - --> tests/ui/unsafe_derive_deserialize.rs:25:10 + --> tests/ui/unsafe_derive_deserialize.rs:24:10 | LL | #[derive(Deserialize)] | ^^^^^^^^^^^ @@ -28,7 +28,7 @@ LL | #[derive(Deserialize)] = note: this error originates in the derive macro `Deserialize` (in Nightly builds, run with -Z macro-backtrace for more info) error: you are deriving `serde::Deserialize` on a type that has methods using `unsafe` - --> tests/ui/unsafe_derive_deserialize.rs:34:10 + --> tests/ui/unsafe_derive_deserialize.rs:33:10 | LL | #[derive(Deserialize)] | ^^^^^^^^^^^ diff --git a/tests/ui/used_underscore_binding.rs b/tests/ui/used_underscore_binding.rs index a8f404b1400c9..84dccf28f3b22 100644 --- a/tests/ui/used_underscore_binding.rs +++ b/tests/ui/used_underscore_binding.rs @@ -1,5 +1,5 @@ //@aux-build:proc_macro_derive.rs -#![feature(rustc_private, lint_reasons)] +#![feature(rustc_private)] #![warn(clippy::used_underscore_binding)] #![allow(clippy::disallowed_names, clippy::eq_op, clippy::uninlined_format_args)] From 3bbec6aade8a14c301aa9d7c2c2b15b57eadf7fb Mon Sep 17 00:00:00 2001 From: xFrednet Date: Tue, 4 Jun 2024 11:02:03 +0200 Subject: [PATCH 306/892] `sudo CI=green` && Review changes <3 --- .../ui-toml/macro_metavars_in_unsafe/default/test.rs | 2 +- .../macro_metavars_in_unsafe/default/test.stderr | 11 +---------- 2 files changed, 2 insertions(+), 11 deletions(-) diff --git a/tests/ui-toml/macro_metavars_in_unsafe/default/test.rs b/tests/ui-toml/macro_metavars_in_unsafe/default/test.rs index f5e01b431ad98..a312df5a43a07 100644 --- a/tests/ui-toml/macro_metavars_in_unsafe/default/test.rs +++ b/tests/ui-toml/macro_metavars_in_unsafe/default/test.rs @@ -1,5 +1,5 @@ //! Tests macro_metavars_in_unsafe with default configuration -#![feature(decl_macro, lint_reasons)] +#![feature(decl_macro)] #![warn(clippy::macro_metavars_in_unsafe)] #![allow(clippy::no_effect)] diff --git a/tests/ui-toml/macro_metavars_in_unsafe/default/test.stderr b/tests/ui-toml/macro_metavars_in_unsafe/default/test.stderr index 138eb60294949..d6b97f6fde1e1 100644 --- a/tests/ui-toml/macro_metavars_in_unsafe/default/test.stderr +++ b/tests/ui-toml/macro_metavars_in_unsafe/default/test.stderr @@ -1,12 +1,3 @@ -error: the feature `lint_reasons` has been stable since 1.81.0-dev and no longer requires an attribute to enable - --> tests/ui-toml/macro_metavars_in_unsafe/default/test.rs:2:24 - | -LL | #![feature(decl_macro, lint_reasons)] - | ^^^^^^^^^^^^ - | - = note: `-D stable-features` implied by `-D warnings` - = help: to override `-D warnings` add `#[allow(stable_features)]` - error: this macro expands metavariables in an unsafe block --> tests/ui-toml/macro_metavars_in_unsafe/default/test.rs:19:9 | @@ -192,5 +183,5 @@ LL | | } = help: consider expanding any metavariables outside of this block, e.g. by storing them in a variable = help: ... or also expand referenced metavariables in a safe context to require an unsafe block at callsite -error: aborting due to 15 previous errors +error: aborting due to 14 previous errors From ac7595fdb1ee2aafecdd99cd8a3e56192639ada6 Mon Sep 17 00:00:00 2001 From: Matthew Maurer Date: Tue, 12 Dec 2023 13:32:43 -0800 Subject: [PATCH 307/892] Support for -Z patchable-function-entry `-Z patchable-function-entry` works like `-fpatchable-function-entry` on clang/gcc. The arguments are total nop count and function offset. See MCP rust-lang/compiler-team#704 --- compiler/rustc_codegen_llvm/src/attributes.rs | 26 +++++++++++++++++ compiler/rustc_interface/src/tests.rs | 1 + .../src/middle/codegen_fn_attrs.rs | 23 +++++++++++++++ compiler/rustc_session/src/config.rs | 29 ++++++++++++++++++- compiler/rustc_session/src/options.rs | 29 +++++++++++++++++++ .../patchable-function-entry.md | 24 +++++++++++++++ tests/codegen/patchable-function-entry.rs | 8 +++++ 7 files changed, 139 insertions(+), 1 deletion(-) create mode 100644 src/doc/unstable-book/src/compiler-flags/patchable-function-entry.md create mode 100644 tests/codegen/patchable-function-entry.rs diff --git a/compiler/rustc_codegen_llvm/src/attributes.rs b/compiler/rustc_codegen_llvm/src/attributes.rs index 48693895da13e..7cf789ab5d72e 100644 --- a/compiler/rustc_codegen_llvm/src/attributes.rs +++ b/compiler/rustc_codegen_llvm/src/attributes.rs @@ -53,6 +53,31 @@ fn inline_attr<'ll>(cx: &CodegenCx<'ll, '_>, inline: InlineAttr) -> Option<&'ll } } +#[inline] +fn patchable_function_entry_attrs<'ll>( + cx: &CodegenCx<'ll, '_>, +) -> SmallVec<[&'ll Attribute; 2]> { + let mut attrs = SmallVec::new(); + let patchable_spec = cx.tcx.sess.opts.unstable_opts.patchable_function_entry; + let entry = patchable_spec.entry(); + let prefix = patchable_spec.prefix(); + if entry > 0 { + attrs.push(llvm::CreateAttrStringValue( + cx.llcx, + "patchable-function-entry", + &format!("{}", entry), + )); + } + if prefix > 0 { + attrs.push(llvm::CreateAttrStringValue( + cx.llcx, + "patchable-function-prefix", + &format!("{}", prefix), + )); + } + attrs +} + /// Get LLVM sanitize attributes. #[inline] pub fn sanitize_attrs<'ll>( @@ -421,6 +446,7 @@ pub fn from_fn_attrs<'ll, 'tcx>( llvm::set_alignment(llfn, align); } to_add.extend(sanitize_attrs(cx, codegen_fn_attrs.no_sanitize)); + to_add.extend(patchable_function_entry_attrs(cx)); // Always annotate functions with the target-cpu they are compiled for. // Without this, ThinLTO won't inline Rust functions into Clang generated diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index 6ffc518097ef0..e4b50e7f5ff26 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -813,6 +813,7 @@ fn test_unstable_options_tracking_hash() { tracked!(packed_bundled_libs, true); tracked!(panic_abort_tests, true); tracked!(panic_in_drop, PanicStrategy::Abort); + tracked!(patchable_function_entry, PatchableFunctionEntry::from_nop_count_and_offset(3, 4)); tracked!(plt, Some(true)); tracked!(polonius, Polonius::Legacy); tracked!(precise_enum_drop_elaboration, false); diff --git a/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs b/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs index 3fa5054baed1e..0fce26dcbbdbb 100644 --- a/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs +++ b/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs @@ -47,6 +47,29 @@ pub struct CodegenFnAttrs { pub alignment: Option, } +#[derive(Copy, Clone, Debug, TyEncodable, TyDecodable, HashStable)] +pub struct PatchableFunctionEntry { + /// Nops to prepend to the function + prefix: u8, + /// Nops after entry, but before body + entry: u8, +} + +impl PatchableFunctionEntry { + pub fn from_config(config: rustc_session::config::PatchableFunctionEntry) -> Self { + Self { prefix: config.prefix(), entry: config.entry() } + } + pub fn from_prefix_and_entry(prefix: u8, entry: u8) -> Self { + Self { prefix, entry } + } + pub fn prefix(&self) -> u8 { + self.prefix + } + pub fn entry(&self) -> u8 { + self.entry + } +} + #[derive(Clone, Copy, PartialEq, Eq, TyEncodable, TyDecodable, HashStable)] pub struct CodegenFnAttrFlags(u32); bitflags::bitflags! { diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 839cc51efcea8..2534152267e14 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -2963,7 +2963,7 @@ pub(crate) mod dep_tracking { CrateType, DebugInfo, DebugInfoCompression, ErrorOutputType, FunctionReturn, InliningThreshold, InstrumentCoverage, InstrumentXRay, LinkerPluginLto, LocationDetail, LtoCli, NextSolverConfig, OomStrategy, OptLevel, OutFileName, OutputType, OutputTypes, - Polonius, RemapPathScopeComponents, ResolveDocLinks, SourceFileHashAlgorithm, + PatchableFunctionEntry, Polonius, RemapPathScopeComponents, ResolveDocLinks, SourceFileHashAlgorithm, SplitDwarfKind, SwitchWithOptPath, SymbolManglingVersion, WasiExecModel, }; use crate::lint; @@ -3071,6 +3071,7 @@ pub(crate) mod dep_tracking { OomStrategy, LanguageIdentifier, NextSolverConfig, + PatchableFunctionEntry, Polonius, InliningThreshold, FunctionReturn, @@ -3248,6 +3249,32 @@ impl DumpMonoStatsFormat { } } +/// `-Z patchable-function-entry` representation - how many nops to put before and after function +/// entry. +#[derive(Clone, Copy, PartialEq, Hash, Debug, Default)] +pub struct PatchableFunctionEntry { + /// Nops before the entry + prefix: u8, + /// Nops after the entry + entry: u8, +} + +impl PatchableFunctionEntry { + pub fn from_nop_count_and_offset(nop_count: u8, offset: u8) -> Option { + if nop_count < offset { + None + } else { + Some(Self { prefix: offset, entry: nop_count - offset }) + } + } + pub fn prefix(&self) -> u8 { + self.prefix + } + pub fn entry(&self) -> u8 { + self.entry + } +} + /// `-Zpolonius` values, enabling the borrow checker polonius analysis, and which version: legacy, /// or future prototype. #[derive(Clone, Copy, PartialEq, Hash, Debug, Default)] diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index 9a10adeb6d1a1..f4f8a16662d75 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -379,6 +379,8 @@ mod desc { pub const parse_passes: &str = "a space-separated list of passes, or `all`"; pub const parse_panic_strategy: &str = "either `unwind` or `abort`"; pub const parse_on_broken_pipe: &str = "either `kill`, `error`, or `inherit`"; + pub const parse_patchable_function_entry: &str = + "nop_count,entry_offset or nop_count (defaulting entry_offset=0)"; pub const parse_opt_panic_strategy: &str = parse_panic_strategy; pub const parse_oom_strategy: &str = "either `panic` or `abort`"; pub const parse_relro_level: &str = "one of: `full`, `partial`, or `off`"; @@ -723,6 +725,7 @@ mod parse { true } + pub(crate) fn parse_on_broken_pipe(slot: &mut OnBrokenPipe, v: Option<&str>) -> bool { match v { // OnBrokenPipe::Default can't be explicitly specified @@ -734,6 +737,30 @@ mod parse { true } + pub(crate) fn parse_patchable_function_entry( + slot: &mut PatchableFunctionEntry, + v: Option<&str>, + ) -> bool { + let mut nop_count = 0; + let mut offset = 0; + + if !parse_number(&mut nop_count, v) { + let parts = v.and_then(|v| v.split_once(',')).unzip(); + if !parse_number(&mut nop_count, parts.0) { + return false; + } + if !parse_number(&mut offset, parts.1) { + return false; + } + } + + if let Some(pfe) = PatchableFunctionEntry::from_nop_count_and_offset(nop_count, offset) { + *slot = pfe; + return true; + } + false + } + pub(crate) fn parse_oom_strategy(slot: &mut OomStrategy, v: Option<&str>) -> bool { match v { Some("panic") => *slot = OomStrategy::Panic, @@ -1859,6 +1886,8 @@ options! { "panic strategy for panics in drops"), parse_only: bool = (false, parse_bool, [UNTRACKED], "parse only; do not compile, assemble, or link (default: no)"), + patchable_function_entry: PatchableFunctionEntry = (PatchableFunctionEntry::default(), parse_patchable_function_entry, [TRACKED], + "nop padding at function entry"), plt: Option = (None, parse_opt_bool, [TRACKED], "whether to use the PLT when calling into shared libraries; only has effect for PIC code on systems with ELF binaries diff --git a/src/doc/unstable-book/src/compiler-flags/patchable-function-entry.md b/src/doc/unstable-book/src/compiler-flags/patchable-function-entry.md new file mode 100644 index 0000000000000..a701b9e37719c --- /dev/null +++ b/src/doc/unstable-book/src/compiler-flags/patchable-function-entry.md @@ -0,0 +1,24 @@ +# `patchable-function-entry` + +-------------------- + +The `-Z patchable-function-entry=M,N` or `-Z patchable-function-entry=M` +compiler flag enables nop padding of function entries with M nops, with +an offset for the entry of the function at N nops. In the second form, +N defaults to 0. + +As an illustrative example, `-Z patchable-function-entry=3,2` would produce: + +``` +nop +nop +function_label: +nop +//Actual function code begins here +``` + +This flag is used for hotpatching, especially in the Linux kernel. The flag +arguments are modeled after hte `-fpatchable-function-entry` flag as defined +for both [Clang](https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang-fpatchable-function-entry) +and [gcc](https://gcc.gnu.org/onlinedocs/gcc/Instrumentation-Options.html#index-fpatchable-function-entry) +and is intended to provide the same effect. diff --git a/tests/codegen/patchable-function-entry.rs b/tests/codegen/patchable-function-entry.rs new file mode 100644 index 0000000000000..f06739303d2e2 --- /dev/null +++ b/tests/codegen/patchable-function-entry.rs @@ -0,0 +1,8 @@ +// compile-flags: -Z patchable-function-entry=15,10 + +#![crate_type = "lib"] + +#[no_mangle] +pub fn foo() {} +// CHECK: @foo() unnamed_addr #0 +// CHECK: attributes #0 = { {{.*}}"patchable-function-entry"="5"{{.*}}"patchable-function-prefix"="10" {{.*}} } From 9b0ae75ecc485d668232c9c85f0090fb85668312 Mon Sep 17 00:00:00 2001 From: Matthew Maurer Date: Tue, 12 Dec 2023 13:37:04 -0800 Subject: [PATCH 308/892] Support `#[patchable_function_entries]` See [RFC](https://github.com/maurer/rust-rfcs/blob/patchable-function-entry/text/0000-patchable-function-entry.md) (yet to be numbered) TODO before submission: * Needs an RFC * Improve error reporting for malformed attributes --- compiler/rustc_codegen_llvm/src/attributes.rs | 9 ++++--- .../rustc_codegen_ssa/src/codegen_attrs.rs | 26 ++++++++++++++++++- compiler/rustc_feature/src/builtin_attrs.rs | 7 +++++ compiler/rustc_feature/src/unstable.rs | 3 +++ .../src/middle/codegen_fn_attrs.rs | 4 +++ compiler/rustc_span/src/symbol.rs | 3 +++ tests/codegen/patchable-function-entry.rs | 20 ++++++++++++++ .../feature-gate-patchable-function-entry.rs | 3 +++ ...ature-gate-patchable-function-entry.stderr | 12 +++++++++ 9 files changed, 83 insertions(+), 4 deletions(-) create mode 100644 tests/ui/feature-gates/feature-gate-patchable-function-entry.rs create mode 100644 tests/ui/feature-gates/feature-gate-patchable-function-entry.stderr diff --git a/compiler/rustc_codegen_llvm/src/attributes.rs b/compiler/rustc_codegen_llvm/src/attributes.rs index 7cf789ab5d72e..cd82894af18eb 100644 --- a/compiler/rustc_codegen_llvm/src/attributes.rs +++ b/compiler/rustc_codegen_llvm/src/attributes.rs @@ -2,7 +2,7 @@ use rustc_codegen_ssa::traits::*; use rustc_hir::def_id::DefId; -use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; +use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, PatchableFunctionEntry}; use rustc_middle::ty::{self, TyCtxt}; use rustc_session::config::{FunctionReturn, OptLevel}; use rustc_span::symbol::sym; @@ -56,9 +56,12 @@ fn inline_attr<'ll>(cx: &CodegenCx<'ll, '_>, inline: InlineAttr) -> Option<&'ll #[inline] fn patchable_function_entry_attrs<'ll>( cx: &CodegenCx<'ll, '_>, + attr: Option, ) -> SmallVec<[&'ll Attribute; 2]> { let mut attrs = SmallVec::new(); - let patchable_spec = cx.tcx.sess.opts.unstable_opts.patchable_function_entry; + let patchable_spec = attr.unwrap_or_else(|| { + PatchableFunctionEntry::from_config(cx.tcx.sess.opts.unstable_opts.patchable_function_entry) + }); let entry = patchable_spec.entry(); let prefix = patchable_spec.prefix(); if entry > 0 { @@ -446,7 +449,7 @@ pub fn from_fn_attrs<'ll, 'tcx>( llvm::set_alignment(llfn, align); } to_add.extend(sanitize_attrs(cx, codegen_fn_attrs.no_sanitize)); - to_add.extend(patchable_function_entry_attrs(cx)); + to_add.extend(patchable_function_entry_attrs(cx, codegen_fn_attrs.patchable_function_entry)); // Always annotate functions with the target-cpu they are compiled for. // Without this, ThinLTO won't inline Rust functions into Clang generated diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs index fb71cdaa8ff2a..8924ddb2aedd3 100644 --- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs +++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs @@ -5,7 +5,9 @@ use rustc_hir as hir; use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, LocalDefId, LOCAL_CRATE}; use rustc_hir::{lang_items, weak_lang_items::WEAK_LANG_ITEMS, LangItem}; -use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs}; +use rustc_middle::middle::codegen_fn_attrs::{ + CodegenFnAttrFlags, CodegenFnAttrs, PatchableFunctionEntry, +}; use rustc_middle::mir::mono::Linkage; use rustc_middle::query::Providers; use rustc_middle::ty::{self as ty, TyCtxt}; @@ -463,6 +465,28 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { None }; } + sym::patchable_function_entry => { + codegen_fn_attrs.patchable_function_entry = attr.meta_item_list().and_then(|l| { + let mut prefix = 0; + let mut entry = 0; + for item in l { + if let Some((sym, lit)) = item.name_value_literal() { + let val = match lit.kind { + // FIXME emit error if too many nops requested + rustc_ast::LitKind::Int(i, _) => i as u8, + _ => continue, + }; + match sym { + sym::prefix => prefix = val, + sym::entry => entry = val, + // FIXME possibly emit error here? + _ => continue, + } + } + } + Some(PatchableFunctionEntry::from_prefix_and_entry(prefix, entry)) + }) + } _ => {} } } diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index c53bf96513951..b5f9f2c715f4f 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -584,6 +584,13 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ pointee, Normal, template!(Word), ErrorFollowing, EncodeCrossCrate::No, derive_smart_pointer, experimental!(pointee) ), + + // FIXME RFC + // `#[patchable_function_entry(prefix(n), entry(n))]` + gated!( + patchable_function_entry, Normal, template!(List: "prefix(n), entry(n)"), ErrorPreceding, + experimental!(patchable_function_entry) + ), // ========================================================================== // Internal attributes: Stability, deprecation, and unsafe: diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index 2dfaac8f6e731..796475e766f6b 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -565,6 +565,9 @@ declare_features! ( (unstable, offset_of_slice, "CURRENT_RUSTC_VERSION", Some(126151)), /// Allows using `#[optimize(X)]`. (unstable, optimize_attribute, "1.34.0", Some(54882)), + /// Allows specifying nop padding on functions for dynamic patching. + // FIXME this needs an RFC # + (unstable, patchable_function_entry, "CURRENT_RUSTC_VERSION", Some(9999)), /// Allows postfix match `expr.match { ... }` (unstable, postfix_match, "1.79.0", Some(121618)), /// Allows `use<'a, 'b, A, B>` in `impl Trait + use<...>` for precise capture of generic args. diff --git a/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs b/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs index 0fce26dcbbdbb..23fe72c537a1c 100644 --- a/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs +++ b/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs @@ -45,6 +45,9 @@ pub struct CodegenFnAttrs { /// The `#[repr(align(...))]` attribute. Indicates the value of which the function should be /// aligned to. pub alignment: Option, + /// The `#[patchable_function_entry(...)]` attribute. Indicates how many nops should be around + /// the function entry. + pub patchable_function_entry: Option, } #[derive(Copy, Clone, Debug, TyEncodable, TyDecodable, HashStable)] @@ -147,6 +150,7 @@ impl CodegenFnAttrs { no_sanitize: SanitizerSet::empty(), instruction_set: None, alignment: None, + patchable_function_entry: None, } } diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 6d4a8c29bc902..ea7fe7e76c412 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -768,6 +768,7 @@ symbols! { enable, encode, end, + entry, enumerate_method, env, env_CFG_RELEASE: env!("CFG_RELEASE"), @@ -1383,6 +1384,7 @@ symbols! { passes, pat, pat_param, + patchable_function_entry, path, pattern_complexity, pattern_parentheses, @@ -1421,6 +1423,7 @@ symbols! { prefetch_read_instruction, prefetch_write_data, prefetch_write_instruction, + prefix, preg, prelude, prelude_import, diff --git a/tests/codegen/patchable-function-entry.rs b/tests/codegen/patchable-function-entry.rs index f06739303d2e2..dc20c0a2c6dad 100644 --- a/tests/codegen/patchable-function-entry.rs +++ b/tests/codegen/patchable-function-entry.rs @@ -1,8 +1,28 @@ +#![feature(patchable_function_entry)] // compile-flags: -Z patchable-function-entry=15,10 #![crate_type = "lib"] +// This should have the default, as set by the compile flags #[no_mangle] pub fn foo() {} + +// The attribute should override the compile flags +#[no_mangle] +#[patchable_function_entry(prefix(1), entry(2))] +pub fn bar() {} + +// If we override an attribute to 0 or unset, the attribute should go away +#[no_mangle] +#[patchable_function_entry(entry(0))] +pub fn baz() {} + // CHECK: @foo() unnamed_addr #0 +// CHECK: @bar() unnamed_addr #1 +// CHECK: @baz() unnamed_addr #2 + // CHECK: attributes #0 = { {{.*}}"patchable-function-entry"="5"{{.*}}"patchable-function-prefix"="10" {{.*}} } +// CHECK: attributes #1 = { {{.*}}"patchable-function-entry"="2"{{.*}}"patchable-function-prefix"="1" {{.*}} } +// CHECK-NOT: attributes #2 = { {{.*}}patchable-function-entry{{.*}} } +// CHECK-NOT: attributes #2 = { {{.*}}patchable-function-prefix{{.*}} } +// CHECK: attributes #2 = { {{.*}} } diff --git a/tests/ui/feature-gates/feature-gate-patchable-function-entry.rs b/tests/ui/feature-gates/feature-gate-patchable-function-entry.rs new file mode 100644 index 0000000000000..0e16e873a1eaa --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-patchable-function-entry.rs @@ -0,0 +1,3 @@ +#[patchable_function_entry(entry(1), prefix(1))] +//~^ ERROR: the `#[patchable_function_entry]` attribute is an experimental feature +fn main() {} diff --git a/tests/ui/feature-gates/feature-gate-patchable-function-entry.stderr b/tests/ui/feature-gates/feature-gate-patchable-function-entry.stderr new file mode 100644 index 0000000000000..c4d57d774e35d --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-patchable-function-entry.stderr @@ -0,0 +1,12 @@ +error[E0658]: the `#[patchable_function_entry]` attribute is an experimental feature + --> $DIR/feature-gate-patchable-function-entry.rs:1:1 + | +LL | #[patchable_function_entry(entry(1), prefix(1))] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #9999 for more information + = help: add `#![feature(patchable_function_entry)]` to the crate attributes to enable + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0658`. From e8516f8b52d8ae49c2e0b2ff2cb5faf28b1a6526 Mon Sep 17 00:00:00 2001 From: joboet Date: Tue, 25 Jun 2024 18:30:49 +0200 Subject: [PATCH 309/892] std: separate TLS key creation from TLS access Currently, `std` performs an atomic load to get the OS key on every access to `StaticKey` even when the key is already known. This PR thus replaces `StaticKey` with the platform-specific `get` and `set` function and a new `LazyKey` type that acts as a `LazyLock`, allowing the reuse of the retreived key for multiple accesses. --- library/std/src/sys/thread_local/guard/key.rs | 6 +- library/std/src/sys/thread_local/key/racy.rs | 56 +++---------------- library/std/src/sys/thread_local/key/tests.rs | 39 ++++++++----- library/std/src/sys/thread_local/key/unix.rs | 1 + .../std/src/sys/thread_local/key/windows.rs | 56 +++++++++---------- library/std/src/sys/thread_local/key/xous.rs | 2 +- library/std/src/sys/thread_local/mod.rs | 21 ++++--- library/std/src/sys/thread_local/os.rs | 44 +++++++-------- 8 files changed, 100 insertions(+), 125 deletions(-) diff --git a/library/std/src/sys/thread_local/guard/key.rs b/library/std/src/sys/thread_local/guard/key.rs index ee9d55ddd5e8e..67c3ca8862767 100644 --- a/library/std/src/sys/thread_local/guard/key.rs +++ b/library/std/src/sys/thread_local/guard/key.rs @@ -4,15 +4,15 @@ use crate::ptr; use crate::sys::thread_local::destructors; -use crate::sys::thread_local::key::StaticKey; +use crate::sys::thread_local::key::{set, LazyKey}; pub fn enable() { - static DTORS: StaticKey = StaticKey::new(Some(run)); + static DTORS: LazyKey = LazyKey::new(Some(run)); // Setting the key value to something other than NULL will result in the // destructor being run at thread exit. unsafe { - DTORS.set(ptr::without_provenance_mut(1)); + set(DTORS.force(), ptr::without_provenance_mut(1)); } unsafe extern "C" fn run(_: *mut u8) { diff --git a/library/std/src/sys/thread_local/key/racy.rs b/library/std/src/sys/thread_local/key/racy.rs index eda8b83bc7f03..69f11458c3289 100644 --- a/library/std/src/sys/thread_local/key/racy.rs +++ b/library/std/src/sys/thread_local/key/racy.rs @@ -1,4 +1,4 @@ -//! A `StaticKey` implementation using racy initialization. +//! A `LazyKey` implementation using racy initialization. //! //! Unfortunately, none of the platforms currently supported by `std` allows //! creating TLS keys at compile-time. Thus we need a way to lazily create keys. @@ -10,34 +10,12 @@ use crate::sync::atomic::{self, AtomicUsize, Ordering}; /// A type for TLS keys that are statically allocated. /// -/// This type is entirely `unsafe` to use as it does not protect against -/// use-after-deallocation or use-during-deallocation. -/// -/// The actual OS-TLS key is lazily allocated when this is used for the first -/// time. The key is also deallocated when the Rust runtime exits or `destroy` -/// is called, whichever comes first. -/// -/// # Examples -/// -/// ```ignore (cannot-doctest-private-modules) -/// use tls::os::{StaticKey, INIT}; -/// -/// // Use a regular global static to store the key. -/// static KEY: StaticKey = INIT; -/// -/// // The state provided via `get` and `set` is thread-local. -/// unsafe { -/// assert!(KEY.get().is_null()); -/// KEY.set(1 as *mut u8); -/// } -/// ``` -pub struct StaticKey { +/// This is basically a `LazyLock`, but avoids blocking and circular +/// dependencies with the rest of `std`. +pub struct LazyKey { /// Inner static TLS key (internals). key: AtomicUsize, /// Destructor for the TLS value. - /// - /// See `Key::new` for information about when the destructor runs and how - /// it runs. dtor: Option, } @@ -51,32 +29,14 @@ const KEY_SENTVAL: usize = 0; #[cfg(target_os = "nto")] const KEY_SENTVAL: usize = libc::PTHREAD_KEYS_MAX + 1; -impl StaticKey { +impl LazyKey { #[rustc_const_unstable(feature = "thread_local_internals", issue = "none")] - pub const fn new(dtor: Option) -> StaticKey { - StaticKey { key: atomic::AtomicUsize::new(KEY_SENTVAL), dtor } - } - - /// Gets the value associated with this TLS key - /// - /// This will lazily allocate a TLS key from the OS if one has not already - /// been allocated. - #[inline] - pub unsafe fn get(&self) -> *mut u8 { - unsafe { super::get(self.key()) } - } - - /// Sets this TLS key to a new value. - /// - /// This will lazily allocate a TLS key from the OS if one has not already - /// been allocated. - #[inline] - pub unsafe fn set(&self, val: *mut u8) { - unsafe { super::set(self.key(), val) } + pub const fn new(dtor: Option) -> LazyKey { + LazyKey { key: atomic::AtomicUsize::new(KEY_SENTVAL), dtor } } #[inline] - fn key(&self) -> super::Key { + pub fn force(&self) -> super::Key { match self.key.load(Ordering::Acquire) { KEY_SENTVAL => self.lazy_init() as super::Key, n => n as super::Key, diff --git a/library/std/src/sys/thread_local/key/tests.rs b/library/std/src/sys/thread_local/key/tests.rs index 24cad396da269..d82b34e71f0e4 100644 --- a/library/std/src/sys/thread_local/key/tests.rs +++ b/library/std/src/sys/thread_local/key/tests.rs @@ -1,18 +1,25 @@ -use super::StaticKey; +use super::{get, set, LazyKey}; use crate::ptr; #[test] fn smoke() { - static K1: StaticKey = StaticKey::new(None); - static K2: StaticKey = StaticKey::new(None); + static K1: LazyKey = LazyKey::new(None); + static K2: LazyKey = LazyKey::new(None); + + let k1 = K1.force(); + let k2 = K2.force(); + assert_ne!(k1, k2); + + assert_eq!(K1.force(), k1); + assert_eq!(K2.force(), k2); unsafe { - assert!(K1.get().is_null()); - assert!(K2.get().is_null()); - K1.set(ptr::without_provenance_mut(1)); - K2.set(ptr::without_provenance_mut(2)); - assert_eq!(K1.get() as usize, 1); - assert_eq!(K2.get() as usize, 2); + assert!(get(k1).is_null()); + assert!(get(k2).is_null()); + set(k1, ptr::without_provenance_mut(1)); + set(k2, ptr::without_provenance_mut(2)); + assert_eq!(get(k1) as usize, 1); + assert_eq!(get(k2) as usize, 2); } } @@ -26,25 +33,27 @@ fn destructors() { drop(unsafe { Arc::from_raw(ptr as *const ()) }); } - static KEY: StaticKey = StaticKey::new(Some(destruct)); + static KEY: LazyKey = LazyKey::new(Some(destruct)); let shared1 = Arc::new(()); let shared2 = Arc::clone(&shared1); + let key = KEY.force(); unsafe { - assert!(KEY.get().is_null()); - KEY.set(Arc::into_raw(shared1) as *mut u8); + assert!(get(key).is_null()); + set(key, Arc::into_raw(shared1) as *mut u8); } thread::spawn(move || unsafe { - assert!(KEY.get().is_null()); - KEY.set(Arc::into_raw(shared2) as *mut u8); + let key = KEY.force(); + assert!(get(key).is_null()); + set(key, Arc::into_raw(shared2) as *mut u8); }) .join() .unwrap(); // Leak the Arc, let the TLS destructor clean it up. - let shared1 = unsafe { ManuallyDrop::new(Arc::from_raw(KEY.get() as *const ())) }; + let shared1 = unsafe { ManuallyDrop::new(Arc::from_raw(get(key) as *const ())) }; assert_eq!( Arc::strong_count(&shared1), 1, diff --git a/library/std/src/sys/thread_local/key/unix.rs b/library/std/src/sys/thread_local/key/unix.rs index 13522d44b35dc..28e48a750b9bf 100644 --- a/library/std/src/sys/thread_local/key/unix.rs +++ b/library/std/src/sys/thread_local/key/unix.rs @@ -16,6 +16,7 @@ pub unsafe fn set(key: Key, value: *mut u8) { } #[inline] +#[cfg(any(not(target_thread_local), test))] pub unsafe fn get(key: Key) -> *mut u8 { unsafe { libc::pthread_getspecific(key) as *mut u8 } } diff --git a/library/std/src/sys/thread_local/key/windows.rs b/library/std/src/sys/thread_local/key/windows.rs index ad0e72c29edaf..baf23979c7c61 100644 --- a/library/std/src/sys/thread_local/key/windows.rs +++ b/library/std/src/sys/thread_local/key/windows.rs @@ -1,4 +1,4 @@ -//! Implementation of `StaticKey` for Windows. +//! Implementation of `LazyKey` for Windows. //! //! Windows has no native support for running destructors so we manage our own //! list of destructors to keep track of how to destroy keys. We then install a @@ -13,9 +13,9 @@ //! don't reach a fixed point after a short while then we just inevitably leak //! something. //! -//! The list is implemented as an atomic single-linked list of `StaticKey`s and +//! The list is implemented as an atomic single-linked list of `LazyKey`s and //! does not support unregistration. Unfortunately, this means that we cannot -//! use racy initialization for creating the keys in `StaticKey`, as that could +//! use racy initialization for creating the keys in `LazyKey`, as that could //! result in destructors being missed. Hence, we synchronize the creation of //! keys with destructors through [`INIT_ONCE`](c::INIT_ONCE) (`std`'s //! [`Once`](crate::sync::Once) cannot be used since it might use TLS itself). @@ -33,26 +33,26 @@ use crate::sync::atomic::{ use crate::sys::c; use crate::sys::thread_local::guard; -type Key = c::DWORD; +pub type Key = c::DWORD; type Dtor = unsafe extern "C" fn(*mut u8); -pub struct StaticKey { +pub struct LazyKey { /// The key value shifted up by one. Since TLS_OUT_OF_INDEXES == DWORD::MAX /// is not a valid key value, this allows us to use zero as sentinel value /// without risking overflow. key: AtomicU32, dtor: Option, - next: AtomicPtr, + next: AtomicPtr, /// Currently, destructors cannot be unregistered, so we cannot use racy /// initialization for keys. Instead, we need synchronize initialization. /// Use the Windows-provided `Once` since it does not require TLS. once: UnsafeCell, } -impl StaticKey { +impl LazyKey { #[inline] - pub const fn new(dtor: Option) -> StaticKey { - StaticKey { + pub const fn new(dtor: Option) -> LazyKey { + LazyKey { key: AtomicU32::new(0), dtor, next: AtomicPtr::new(ptr::null_mut()), @@ -61,18 +61,7 @@ impl StaticKey { } #[inline] - pub unsafe fn set(&'static self, val: *mut u8) { - let r = unsafe { c::TlsSetValue(self.key(), val.cast()) }; - debug_assert_eq!(r, c::TRUE); - } - - #[inline] - pub unsafe fn get(&'static self) -> *mut u8 { - unsafe { c::TlsGetValue(self.key()).cast() } - } - - #[inline] - fn key(&'static self) -> Key { + pub fn force(&'static self) -> Key { match self.key.load(Acquire) { 0 => unsafe { self.init() }, key => key - 1, @@ -141,17 +130,28 @@ impl StaticKey { } } -unsafe impl Send for StaticKey {} -unsafe impl Sync for StaticKey {} +unsafe impl Send for LazyKey {} +unsafe impl Sync for LazyKey {} + +#[inline] +pub unsafe fn set(key: Key, val: *mut u8) { + let r = unsafe { c::TlsSetValue(key, val.cast()) }; + debug_assert_eq!(r, c::TRUE); +} + +#[inline] +pub unsafe fn get(key: Key) -> *mut u8 { + unsafe { c::TlsGetValue(key).cast() } +} -static DTORS: AtomicPtr = AtomicPtr::new(ptr::null_mut()); +static DTORS: AtomicPtr = AtomicPtr::new(ptr::null_mut()); /// Should only be called once per key, otherwise loops or breaks may occur in /// the linked list. -unsafe fn register_dtor(key: &'static StaticKey) { +unsafe fn register_dtor(key: &'static LazyKey) { guard::enable(); - let this = <*const StaticKey>::cast_mut(key); + let this = <*const LazyKey>::cast_mut(key); // Use acquire ordering to pass along the changes done by the previously // registered keys when we store the new head with release ordering. let mut head = DTORS.load(Acquire); @@ -176,9 +176,9 @@ pub unsafe fn run_dtors() { let dtor = unsafe { (*cur).dtor.unwrap() }; cur = unsafe { (*cur).next.load(Relaxed) }; - // In StaticKey::init, we register the dtor before setting `key`. + // In LazyKey::init, we register the dtor before setting `key`. // So if one thread's `run_dtors` races with another thread executing `init` on the same - // `StaticKey`, we can encounter a key of 0 here. That means this key was never + // `LazyKey`, we can encounter a key of 0 here. That means this key was never // initialized in this thread so we can safely skip it. if pre_key == 0 { continue; diff --git a/library/std/src/sys/thread_local/key/xous.rs b/library/std/src/sys/thread_local/key/xous.rs index a23f6de95f7b5..5a837a33e190e 100644 --- a/library/std/src/sys/thread_local/key/xous.rs +++ b/library/std/src/sys/thread_local/key/xous.rs @@ -30,7 +30,7 @@ //! really. //! //! Perhaps one day we can fold the `Box` here into a static allocation, -//! expanding the `StaticKey` structure to contain not only a slot for the TLS +//! expanding the `LazyKey` structure to contain not only a slot for the TLS //! key but also a slot for the destructor queue on windows. An optimization for //! another day! diff --git a/library/std/src/sys/thread_local/mod.rs b/library/std/src/sys/thread_local/mod.rs index f74fd828cbe50..3d1b91a7ea095 100644 --- a/library/std/src/sys/thread_local/mod.rs +++ b/library/std/src/sys/thread_local/mod.rs @@ -36,7 +36,7 @@ cfg_if::cfg_if! { pub use native::{EagerStorage, LazyStorage, thread_local_inner}; } else { mod os; - pub use os::{Key, thread_local_inner}; + pub use os::{Storage, thread_local_inner}; } } @@ -126,28 +126,33 @@ pub(crate) mod key { mod unix; #[cfg(test)] mod tests; - pub(super) use racy::StaticKey; - use unix::{Key, create, destroy, get, set}; + pub(super) use racy::LazyKey; + pub(super) use unix::{Key, set}; + #[cfg(any(not(target_thread_local), test))] + pub(super) use unix::get; + use unix::{create, destroy}; } else if #[cfg(all(not(target_thread_local), target_os = "windows"))] { #[cfg(test)] mod tests; mod windows; - pub(super) use windows::{StaticKey, run_dtors}; + pub(super) use windows::{Key, LazyKey, get, run_dtors, set}; } else if #[cfg(all(target_vendor = "fortanix", target_env = "sgx"))] { mod racy; mod sgx; #[cfg(test)] mod tests; - pub(super) use racy::StaticKey; - use sgx::{Key, create, destroy, get, set}; + pub(super) use racy::LazyKey; + pub(super) use sgx::{Key, get, set}; + use sgx::{create, destroy}; } else if #[cfg(target_os = "xous")] { mod racy; #[cfg(test)] mod tests; mod xous; - pub(super) use racy::StaticKey; + pub(super) use racy::LazyKey; pub(crate) use xous::destroy_tls; - use xous::{Key, create, destroy, get, set}; + pub(super) use xous::{Key, get, set}; + use xous::{create, destroy}; } } } diff --git a/library/std/src/sys/thread_local/os.rs b/library/std/src/sys/thread_local/os.rs index 6980c897fdb53..625943bb25512 100644 --- a/library/std/src/sys/thread_local/os.rs +++ b/library/std/src/sys/thread_local/os.rs @@ -2,7 +2,7 @@ use super::abort_on_dtor_unwind; use crate::cell::Cell; use crate::marker::PhantomData; use crate::ptr; -use crate::sys::thread_local::key::StaticKey as OsKey; +use crate::sys::thread_local::key::{get, set, Key, LazyKey}; #[doc(hidden)] #[allow_internal_unstable(thread_local_internals)] @@ -22,12 +22,12 @@ pub macro thread_local_inner { unsafe { use $crate::thread::LocalKey; - use $crate::thread::local_impl::Key; + use $crate::thread::local_impl::Storage; // Inlining does not work on windows-gnu due to linking errors around // dllimports. See https://github.com/rust-lang/rust/issues/109797. LocalKey::new(#[cfg_attr(windows, inline(never))] |init| { - static VAL: Key<$t> = Key::new(); + static VAL: Storage<$t> = Storage::new(); VAL.get(init, __init) }) } @@ -41,22 +41,22 @@ pub macro thread_local_inner { /// Use a regular global static to store this key; the state provided will then be /// thread-local. #[allow(missing_debug_implementations)] -pub struct Key { - os: OsKey, +pub struct Storage { + key: LazyKey, marker: PhantomData>, } -unsafe impl Sync for Key {} +unsafe impl Sync for Storage {} struct Value { value: T, - key: &'static Key, + key: Key, } -impl Key { +impl Storage { #[rustc_const_unstable(feature = "thread_local_internals", issue = "none")] - pub const fn new() -> Key { - Key { os: OsKey::new(Some(destroy_value::)), marker: PhantomData } + pub const fn new() -> Storage { + Storage { key: LazyKey::new(Some(destroy_value::)), marker: PhantomData } } /// Get a pointer to the TLS value, potentially initializing it with the @@ -66,19 +66,19 @@ impl Key { /// The resulting pointer may not be used after reentrant inialialization /// or thread destruction has occurred. pub fn get(&'static self, i: Option<&mut Option>, f: impl FnOnce() -> T) -> *const T { - // SAFETY: (FIXME: get should actually be safe) - let ptr = unsafe { self.os.get() as *mut Value }; + let key = self.key.force(); + let ptr = unsafe { get(key) as *mut Value }; if ptr.addr() > 1 { // SAFETY: the check ensured the pointer is safe (its destructor // is not running) + it is coming from a trusted source (self). unsafe { &(*ptr).value } } else { - self.try_initialize(ptr, i, f) + unsafe { Self::try_initialize(key, ptr, i, f) } } } - fn try_initialize( - &'static self, + unsafe fn try_initialize( + key: Key, ptr: *mut Value, i: Option<&mut Option>, f: impl FnOnce() -> T, @@ -88,13 +88,13 @@ impl Key { return ptr::null(); } - let value = i.and_then(Option::take).unwrap_or_else(f); - let ptr = Box::into_raw(Box::new(Value { value, key: self })); - // SAFETY: (FIXME: get should actually be safe) - let old = unsafe { self.os.get() as *mut Value }; + let value = Box::new(Value { value: i.and_then(Option::take).unwrap_or_else(f), key }); + let ptr = Box::into_raw(value); + + let old = unsafe { get(key) as *mut Value }; // SAFETY: `ptr` is a correct pointer that can be destroyed by the key destructor. unsafe { - self.os.set(ptr as *mut u8); + set(key, ptr as *mut u8); } if !old.is_null() { // If the variable was recursively initialized, drop the old value. @@ -123,8 +123,8 @@ unsafe extern "C" fn destroy_value(ptr: *mut u8) { abort_on_dtor_unwind(|| { let ptr = unsafe { Box::from_raw(ptr as *mut Value) }; let key = ptr.key; - unsafe { key.os.set(ptr::without_provenance_mut(1)) }; + unsafe { set(key, ptr::without_provenance_mut(1)) }; drop(ptr); - unsafe { key.os.set(ptr::null_mut()) }; + unsafe { set(key, ptr::null_mut()) }; }); } From a2ed16cc061f4b25c673d0f53264e5c7c389eb9b Mon Sep 17 00:00:00 2001 From: Oneirical Date: Fri, 21 Jun 2024 16:00:53 -0400 Subject: [PATCH 310/892] rewrite mingw-export-call-convention to rmake --- src/tools/tidy/src/allowed_run_make_makefiles.txt | 1 - .../run-make/mingw-export-call-convention/Makefile | 9 --------- .../run-make/mingw-export-call-convention/rmake.rs | 13 +++++++++++++ tests/run-make/pdb-alt-path/rmake.rs | 14 ++++++++------ 4 files changed, 21 insertions(+), 16 deletions(-) delete mode 100644 tests/run-make/mingw-export-call-convention/Makefile create mode 100644 tests/run-make/mingw-export-call-convention/rmake.rs diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index f8b0742a55c87..a029c20dec30f 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -110,7 +110,6 @@ run-make/manual-link/Makefile run-make/many-crates-but-no-match/Makefile run-make/metadata-dep-info/Makefile run-make/min-global-align/Makefile -run-make/mingw-export-call-convention/Makefile run-make/missing-crate-dependency/Makefile run-make/mixing-libs/Makefile run-make/msvc-opt-minsize/Makefile diff --git a/tests/run-make/mingw-export-call-convention/Makefile b/tests/run-make/mingw-export-call-convention/Makefile deleted file mode 100644 index 4a60059cc5441..0000000000000 --- a/tests/run-make/mingw-export-call-convention/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -include ../tools.mk - -# only-windows-gnu - -all: - $(RUSTC) foo.rs - # FIXME: we should make sure __stdcall calling convention is used here - # but that only works with LLD right now - nm -g "$(call IMPLIB,foo)" | $(CGREP) bar diff --git a/tests/run-make/mingw-export-call-convention/rmake.rs b/tests/run-make/mingw-export-call-convention/rmake.rs new file mode 100644 index 0000000000000..d1fb745a64de9 --- /dev/null +++ b/tests/run-make/mingw-export-call-convention/rmake.rs @@ -0,0 +1,13 @@ +// On windows-gnu, symbol exporting used to fail to export names +// with no_mangle. #72049 brought this feature up to par with msvc, +// and this test checks that the symbol "bar" is successfully exported. +// See https://github.com/rust-lang/rust/issues/50176 + +//@ only-x86_64-pc-windows-gnu + +use run_make_support::{llvm_readobj, rustc}; + +fn main() { + rustc().input("foo.rs").run(); + llvm_readobj().arg("--all").input("libfoo.dll.a").run().assert_stdout_contains("bar"); +} diff --git a/tests/run-make/pdb-alt-path/rmake.rs b/tests/run-make/pdb-alt-path/rmake.rs index 15497be4ecfe2..6311d6d9ed7d0 100644 --- a/tests/run-make/pdb-alt-path/rmake.rs +++ b/tests/run-make/pdb-alt-path/rmake.rs @@ -5,7 +5,9 @@ // checks that no full file paths are exposed and that the override flag is respected. // See https://github.com/rust-lang/rust/pull/121297 -//@ only-windows +//@ only-x86_64-pc-windows-msvc + +use run_make_support::{bin_name, invalid_utf8_contains, invalid_utf8_not_contains, run, rustc}; fn main() { // Test that we don't have the full path to the PDB file in the binary @@ -16,11 +18,11 @@ fn main() { .crate_type("bin") .arg("-Cforce-frame-pointers") .run(); - invalid_utf8_contains(bin_name("my_crate_name"), "my_crate_name.pdb"); - invalid_utf8_not_contains(bin_name("my_crate_name"), r#"\my_crate_name.pdb"#); + invalid_utf8_contains(&bin_name("my_crate_name"), "my_crate_name.pdb"); + invalid_utf8_not_contains(&bin_name("my_crate_name"), r#"\my_crate_name.pdb"#); // Test that backtraces still can find debuginfo by checking that they contain symbol names and // source locations. - let out = run(bin_name(my_crate_name)); + let out = run(&bin_name("my_crate_name")); out.assert_stdout_contains("my_crate_name::fn_in_backtrace"); out.assert_stdout_contains("main.rs:15"); // Test that explicitly passed `-Clink-arg=/PDBALTPATH:...` is respected @@ -32,6 +34,6 @@ fn main() { .link_arg("/PDBALTPATH:abcdefg.pdb") .arg("-Cforce-frame-pointers") .run(); - invalid_utf8_contains(bin_name("my_crate_name"), "abcdefg.pdb"); - invalid_utf8_not_contains(bin_name("my_crate_name"), "my_crate_name.pdb"); + invalid_utf8_contains(&bin_name("my_crate_name"), "abcdefg.pdb"); + invalid_utf8_not_contains(&bin_name("my_crate_name"), "my_crate_name.pdb"); } From 7c56398e912ea9e81d8e56b2ca7459b4e62b6636 Mon Sep 17 00:00:00 2001 From: Florian Schmiderer Date: Thu, 2 May 2024 23:19:02 +0200 Subject: [PATCH 311/892] Updated code for changes to RFC, added additional error handling, added tests --- .../rustc_codegen_ssa/src/codegen_attrs.rs | 62 ++++++++++++----- compiler/rustc_feature/src/builtin_attrs.rs | 10 +-- compiler/rustc_feature/src/unstable.rs | 3 +- compiler/rustc_interface/src/tests.rs | 9 ++- compiler/rustc_session/src/config.rs | 14 ++-- compiler/rustc_session/src/options.rs | 18 ++--- compiler/rustc_span/src/symbol.rs | 4 +- .../patchable-function-entry.md | 12 ++-- tests/codegen/patchable-function-entry.rs | 28 -------- .../patchable-function-entry-both-flags.rs | 64 ++++++++++++++++++ .../patchable-function-entry-no-flag.rs | 39 +++++++++++ .../patchable-function-entry-one-flag.rs | 66 +++++++++++++++++++ .../feature-gate-patchable-function-entry.rs | 2 +- ...ature-gate-patchable-function-entry.stderr | 7 +- .../patchable-function-entry-attribute.rs | 17 +++++ .../patchable-function-entry-attribute.stderr | 32 +++++++++ .../patchable-function-entry-flags.rs | 2 + .../patchable-function-entry-flags.stderr | 2 + 18 files changed, 312 insertions(+), 79 deletions(-) delete mode 100644 tests/codegen/patchable-function-entry.rs create mode 100644 tests/codegen/patchable-function-entry/patchable-function-entry-both-flags.rs create mode 100644 tests/codegen/patchable-function-entry/patchable-function-entry-no-flag.rs create mode 100644 tests/codegen/patchable-function-entry/patchable-function-entry-one-flag.rs create mode 100644 tests/ui/patchable-function-entry/patchable-function-entry-attribute.rs create mode 100644 tests/ui/patchable-function-entry/patchable-function-entry-attribute.stderr create mode 100644 tests/ui/patchable-function-entry/patchable-function-entry-flags.rs create mode 100644 tests/ui/patchable-function-entry/patchable-function-entry-flags.stderr diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs index 8924ddb2aedd3..84041811bbbf2 100644 --- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs +++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs @@ -1,5 +1,6 @@ use rustc_ast::{ast, attr, MetaItemKind, NestedMetaItem}; use rustc_attr::{list_contains_name, InlineAttr, InstructionSetAttr, OptimizeAttr}; +use rustc_data_structures::packed::Pu128; use rustc_errors::{codes::*, struct_span_code_err}; use rustc_hir as hir; use rustc_hir::def::DefKind; @@ -467,24 +468,55 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { } sym::patchable_function_entry => { codegen_fn_attrs.patchable_function_entry = attr.meta_item_list().and_then(|l| { - let mut prefix = 0; - let mut entry = 0; + let mut prefix = None; + let mut entry = None; for item in l { - if let Some((sym, lit)) = item.name_value_literal() { - let val = match lit.kind { - // FIXME emit error if too many nops requested - rustc_ast::LitKind::Int(i, _) => i as u8, - _ => continue, - }; - match sym { - sym::prefix => prefix = val, - sym::entry => entry = val, - // FIXME possibly emit error here? - _ => continue, + let Some(meta_item) = item.meta_item() else { + tcx.dcx().span_err(item.span(), "Expected name value pair."); + continue; + }; + + let Some(name_value_lit) = meta_item.name_value_literal() else { + tcx.dcx().span_err(item.span(), "Expected name value pair."); + continue; + }; + + let attrib_to_write = match meta_item.name_or_empty() { + sym::prefix_nops => &mut prefix, + sym::entry_nops => &mut entry, + _ => { + tcx.dcx().span_err( + item.span(), + format!( + "Unexpected parameter name. Allowed names: {}, {}", + sym::prefix_nops, + sym::entry_nops + ), + ); + continue; } - } + }; + + let rustc_ast::LitKind::Int(Pu128(val @ 0..=255), _) = name_value_lit.kind + else { + tcx.dcx().span_err( + name_value_lit.span, + "Expected integer value between 0 and 255.", + ); + continue; + }; + + *attrib_to_write = Some(val.try_into().unwrap()); } - Some(PatchableFunctionEntry::from_prefix_and_entry(prefix, entry)) + + if let (None, None) = (prefix, entry) { + tcx.dcx().span_err(attr.span, "Must specify at least one parameter."); + } + + Some(PatchableFunctionEntry::from_prefix_and_entry( + prefix.unwrap_or(0), + entry.unwrap_or(0), + )) }) } _ => {} diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index b5f9f2c715f4f..9371a288f09f7 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -584,12 +584,12 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ pointee, Normal, template!(Word), ErrorFollowing, EncodeCrossCrate::No, derive_smart_pointer, experimental!(pointee) ), - - // FIXME RFC - // `#[patchable_function_entry(prefix(n), entry(n))]` + + // RFC 3543 + // `#[patchable_function_entry(prefix_nops = m, entry_nops = n)]` gated!( - patchable_function_entry, Normal, template!(List: "prefix(n), entry(n)"), ErrorPreceding, - experimental!(patchable_function_entry) + patchable_function_entry, Normal, template!(List: "prefix_nops = m, entry_nops = n"), ErrorPreceding, + EncodeCrossCrate::Yes, experimental!(patchable_function_entry) ), // ========================================================================== diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index 796475e766f6b..29c28b4efd2f8 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -566,8 +566,7 @@ declare_features! ( /// Allows using `#[optimize(X)]`. (unstable, optimize_attribute, "1.34.0", Some(54882)), /// Allows specifying nop padding on functions for dynamic patching. - // FIXME this needs an RFC # - (unstable, patchable_function_entry, "CURRENT_RUSTC_VERSION", Some(9999)), + (unstable, patchable_function_entry, "CURRENT_RUSTC_VERSION", Some(123115)), /// Allows postfix match `expr.match { ... }` (unstable, postfix_match, "1.79.0", Some(121618)), /// Allows `use<'a, 'b, A, B>` in `impl Trait + use<...>` for precise capture of generic args. diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index e4b50e7f5ff26..e23d556ad4610 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -8,8 +8,8 @@ use rustc_session::config::{ ErrorOutputType, ExternEntry, ExternLocation, Externs, FunctionReturn, InliningThreshold, Input, InstrumentCoverage, InstrumentXRay, LinkSelfContained, LinkerPluginLto, LocationDetail, LtoCli, NextSolverConfig, OomStrategy, Options, OutFileName, OutputType, OutputTypes, PAuthKey, - PacRet, Passes, Polonius, ProcMacroExecutionStrategy, Strip, SwitchWithOptPath, - SymbolManglingVersion, WasiExecModel, + PacRet, Passes, PatchableFunctionEntry, Polonius, ProcMacroExecutionStrategy, Strip, + SwitchWithOptPath, SymbolManglingVersion, WasiExecModel, }; use rustc_session::lint::Level; use rustc_session::search_paths::SearchPath; @@ -813,7 +813,10 @@ fn test_unstable_options_tracking_hash() { tracked!(packed_bundled_libs, true); tracked!(panic_abort_tests, true); tracked!(panic_in_drop, PanicStrategy::Abort); - tracked!(patchable_function_entry, PatchableFunctionEntry::from_nop_count_and_offset(3, 4)); + tracked!( + patchable_function_entry, + PatchableFunctionEntry::from_total_and_prefix_nops(10, 5).expect("total >= prefix") + ); tracked!(plt, Some(true)); tracked!(polonius, Polonius::Legacy); tracked!(precise_enum_drop_elaboration, false); diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 2534152267e14..e716abedf0733 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -2963,8 +2963,9 @@ pub(crate) mod dep_tracking { CrateType, DebugInfo, DebugInfoCompression, ErrorOutputType, FunctionReturn, InliningThreshold, InstrumentCoverage, InstrumentXRay, LinkerPluginLto, LocationDetail, LtoCli, NextSolverConfig, OomStrategy, OptLevel, OutFileName, OutputType, OutputTypes, - PatchableFunctionEntry, Polonius, RemapPathScopeComponents, ResolveDocLinks, SourceFileHashAlgorithm, - SplitDwarfKind, SwitchWithOptPath, SymbolManglingVersion, WasiExecModel, + PatchableFunctionEntry, Polonius, RemapPathScopeComponents, ResolveDocLinks, + SourceFileHashAlgorithm, SplitDwarfKind, SwitchWithOptPath, SymbolManglingVersion, + WasiExecModel, }; use crate::lint; use crate::utils::NativeLib; @@ -3260,11 +3261,14 @@ pub struct PatchableFunctionEntry { } impl PatchableFunctionEntry { - pub fn from_nop_count_and_offset(nop_count: u8, offset: u8) -> Option { - if nop_count < offset { + pub fn from_total_and_prefix_nops( + total_nops: u8, + prefix_nops: u8, + ) -> Option { + if total_nops < prefix_nops { None } else { - Some(Self { prefix: offset, entry: nop_count - offset }) + Some(Self { prefix: prefix_nops, entry: total_nops - prefix_nops }) } } pub fn prefix(&self) -> u8 { diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index f4f8a16662d75..80f7ca544f3c5 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -379,8 +379,7 @@ mod desc { pub const parse_passes: &str = "a space-separated list of passes, or `all`"; pub const parse_panic_strategy: &str = "either `unwind` or `abort`"; pub const parse_on_broken_pipe: &str = "either `kill`, `error`, or `inherit`"; - pub const parse_patchable_function_entry: &str = - "nop_count,entry_offset or nop_count (defaulting entry_offset=0)"; + pub const parse_patchable_function_entry: &str = "either two comma separated integers (total_nops,prefix_nops), with prefix_nops <= total_nops, or one integer (total_nops)"; pub const parse_opt_panic_strategy: &str = parse_panic_strategy; pub const parse_oom_strategy: &str = "either `panic` or `abort`"; pub const parse_relro_level: &str = "one of: `full`, `partial`, or `off`"; @@ -725,7 +724,6 @@ mod parse { true } - pub(crate) fn parse_on_broken_pipe(slot: &mut OnBrokenPipe, v: Option<&str>) -> bool { match v { // OnBrokenPipe::Default can't be explicitly specified @@ -741,20 +739,22 @@ mod parse { slot: &mut PatchableFunctionEntry, v: Option<&str>, ) -> bool { - let mut nop_count = 0; - let mut offset = 0; + let mut total_nops = 0; + let mut prefix_nops = 0; - if !parse_number(&mut nop_count, v) { + if !parse_number(&mut total_nops, v) { let parts = v.and_then(|v| v.split_once(',')).unzip(); - if !parse_number(&mut nop_count, parts.0) { + if !parse_number(&mut total_nops, parts.0) { return false; } - if !parse_number(&mut offset, parts.1) { + if !parse_number(&mut prefix_nops, parts.1) { return false; } } - if let Some(pfe) = PatchableFunctionEntry::from_nop_count_and_offset(nop_count, offset) { + if let Some(pfe) = + PatchableFunctionEntry::from_total_and_prefix_nops(total_nops, prefix_nops) + { *slot = pfe; return true; } diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index ea7fe7e76c412..3b6147c4c0f64 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -768,7 +768,7 @@ symbols! { enable, encode, end, - entry, + entry_nops, enumerate_method, env, env_CFG_RELEASE: env!("CFG_RELEASE"), @@ -1423,7 +1423,7 @@ symbols! { prefetch_read_instruction, prefetch_write_data, prefetch_write_instruction, - prefix, + prefix_nops, preg, prelude, prelude_import, diff --git a/src/doc/unstable-book/src/compiler-flags/patchable-function-entry.md b/src/doc/unstable-book/src/compiler-flags/patchable-function-entry.md index a701b9e37719c..4a9bf47a29011 100644 --- a/src/doc/unstable-book/src/compiler-flags/patchable-function-entry.md +++ b/src/doc/unstable-book/src/compiler-flags/patchable-function-entry.md @@ -2,14 +2,14 @@ -------------------- -The `-Z patchable-function-entry=M,N` or `-Z patchable-function-entry=M` -compiler flag enables nop padding of function entries with M nops, with -an offset for the entry of the function at N nops. In the second form, -N defaults to 0. +The `-Z patchable-function-entry=total_nops,prefix_nops` or `-Z patchable-function-entry=total_nops` +compiler flag enables nop padding of function entries with 'total_nops' nops, with +an offset for the entry of the function at 'prefix_nops' nops. In the second form, +'prefix_nops' defaults to 0. As an illustrative example, `-Z patchable-function-entry=3,2` would produce: -``` +```text nop nop function_label: @@ -18,7 +18,7 @@ nop ``` This flag is used for hotpatching, especially in the Linux kernel. The flag -arguments are modeled after hte `-fpatchable-function-entry` flag as defined +arguments are modeled after the `-fpatchable-function-entry` flag as defined for both [Clang](https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang-fpatchable-function-entry) and [gcc](https://gcc.gnu.org/onlinedocs/gcc/Instrumentation-Options.html#index-fpatchable-function-entry) and is intended to provide the same effect. diff --git a/tests/codegen/patchable-function-entry.rs b/tests/codegen/patchable-function-entry.rs deleted file mode 100644 index dc20c0a2c6dad..0000000000000 --- a/tests/codegen/patchable-function-entry.rs +++ /dev/null @@ -1,28 +0,0 @@ -#![feature(patchable_function_entry)] -// compile-flags: -Z patchable-function-entry=15,10 - -#![crate_type = "lib"] - -// This should have the default, as set by the compile flags -#[no_mangle] -pub fn foo() {} - -// The attribute should override the compile flags -#[no_mangle] -#[patchable_function_entry(prefix(1), entry(2))] -pub fn bar() {} - -// If we override an attribute to 0 or unset, the attribute should go away -#[no_mangle] -#[patchable_function_entry(entry(0))] -pub fn baz() {} - -// CHECK: @foo() unnamed_addr #0 -// CHECK: @bar() unnamed_addr #1 -// CHECK: @baz() unnamed_addr #2 - -// CHECK: attributes #0 = { {{.*}}"patchable-function-entry"="5"{{.*}}"patchable-function-prefix"="10" {{.*}} } -// CHECK: attributes #1 = { {{.*}}"patchable-function-entry"="2"{{.*}}"patchable-function-prefix"="1" {{.*}} } -// CHECK-NOT: attributes #2 = { {{.*}}patchable-function-entry{{.*}} } -// CHECK-NOT: attributes #2 = { {{.*}}patchable-function-prefix{{.*}} } -// CHECK: attributes #2 = { {{.*}} } diff --git a/tests/codegen/patchable-function-entry/patchable-function-entry-both-flags.rs b/tests/codegen/patchable-function-entry/patchable-function-entry-both-flags.rs new file mode 100644 index 0000000000000..72204c78a4906 --- /dev/null +++ b/tests/codegen/patchable-function-entry/patchable-function-entry-both-flags.rs @@ -0,0 +1,64 @@ +//@ compile-flags: -Z patchable-function-entry=15,10 + +#![feature(patchable_function_entry)] +#![crate_type = "lib"] + +// This should have the default, as set by the compile flags +#[no_mangle] +pub fn fun0() {} + +// The attribute should override the compile flags +#[no_mangle] +#[patchable_function_entry(prefix_nops = 1, entry_nops = 2)] +pub fn fun1() {} + +// If we override an attribute to 0 or unset, the attribute should go away +#[no_mangle] +#[patchable_function_entry(entry_nops = 0)] +pub fn fun2() {} + +// The attribute should override the compile flags +#[no_mangle] +#[patchable_function_entry(prefix_nops = 20, entry_nops = 1)] +pub fn fun3() {} + +// The attribute should override the compile flags +#[no_mangle] +#[patchable_function_entry(prefix_nops = 2, entry_nops = 19)] +pub fn fun4() {} + +// The attribute should override patchable-function-entry to 3 and +// patchable-function-prefix to the default of 0, clearing it entirely +#[no_mangle] +#[patchable_function_entry(entry_nops = 3)] +pub fn fun5() {} + +// The attribute should override patchable-function-prefix to 4 +// and patchable-function-entry to the default of 0, clearing it entirely +#[no_mangle] +#[patchable_function_entry(prefix_nops = 4)] +pub fn fun6() {} + +// CHECK: @fun0() unnamed_addr #0 +// CHECK: @fun1() unnamed_addr #1 +// CHECK: @fun2() unnamed_addr #2 +// CHECK: @fun3() unnamed_addr #3 +// CHECK: @fun4() unnamed_addr #4 +// CHECK: @fun5() unnamed_addr #5 +// CHECK: @fun6() unnamed_addr #6 + +// CHECK: attributes #0 = { {{.*}}"patchable-function-entry"="5"{{.*}}"patchable-function-prefix"="10" {{.*}} } +// CHECK: attributes #1 = { {{.*}}"patchable-function-entry"="2"{{.*}}"patchable-function-prefix"="1" {{.*}} } + +// CHECK-NOT: attributes #2 = { {{.*}}patchable-function-entry{{.*}} } +// CHECK-NOT: attributes #2 = { {{.*}}patchable-function-prefix{{.*}} } +// CHECK: attributes #2 = { {{.*}} } + +// CHECK: attributes #3 = { {{.*}}"patchable-function-entry"="1"{{.*}}"patchable-function-prefix"="20" {{.*}} } +// CHECK: attributes #4 = { {{.*}}"patchable-function-entry"="19"{{.*}}"patchable-function-prefix"="2" {{.*}} } + +// CHECK: attributes #5 = { {{.*}}"patchable-function-entry"="3"{{.*}} } +// CHECK-NOT: attributes #5 = { {{.*}}patchable-function-prefix{{.*}} } + +// CHECK: attributes #6 = { {{.*}}"patchable-function-prefix"="4"{{.*}} } +// CHECK-NOT: attributes #6 = { {{.*}}patchable-function-entry{{.*}} } diff --git a/tests/codegen/patchable-function-entry/patchable-function-entry-no-flag.rs b/tests/codegen/patchable-function-entry/patchable-function-entry-no-flag.rs new file mode 100644 index 0000000000000..3a7078fe55107 --- /dev/null +++ b/tests/codegen/patchable-function-entry/patchable-function-entry-no-flag.rs @@ -0,0 +1,39 @@ +#![feature(patchable_function_entry)] +#![crate_type = "lib"] + +// No patchable function entry should be set +#[no_mangle] +pub fn fun0() {} + +// The attribute should work even without compiler flags +#[no_mangle] +#[patchable_function_entry(prefix_nops = 1, entry_nops = 2)] +pub fn fun1() {} + +// The attribute should work even without compiler flags +// and only set patchable-function-entry to 3. +#[no_mangle] +#[patchable_function_entry(entry_nops = 3)] +pub fn fun2() {} + +// The attribute should work even without compiler flags +// and only set patchable-function-prefix to 4. +#[no_mangle] +#[patchable_function_entry(prefix_nops = 4)] +pub fn fun3() {} + +// CHECK: @fun0() unnamed_addr #0 +// CHECK: @fun1() unnamed_addr #1 +// CHECK: @fun2() unnamed_addr #2 +// CHECK: @fun3() unnamed_addr #3 + +// CHECK-NOT: attributes #0 = { {{.*}}patchable-function-entry{{.*}} } +// CHECK-NOT: attributes #0 = { {{.*}}patchable-function-prefix{{.*}} } + +// CHECK: attributes #1 = { {{.*}}"patchable-function-entry"="2"{{.*}}"patchable-function-prefix"="1" {{.*}} } + +// CHECK: attributes #2 = { {{.*}}"patchable-function-entry"="3"{{.*}} } +// CHECK-NOT: attributes #2 = { {{.*}}patchable-function-prefix{{.*}} } + +// CHECK: attributes #3 = { {{.*}}"patchable-function-prefix"="4"{{.*}} } +// CHECK-NOT: attributes #3 = { {{.*}}patchable-function-entry{{.*}} } diff --git a/tests/codegen/patchable-function-entry/patchable-function-entry-one-flag.rs b/tests/codegen/patchable-function-entry/patchable-function-entry-one-flag.rs new file mode 100644 index 0000000000000..8bdd61e461b81 --- /dev/null +++ b/tests/codegen/patchable-function-entry/patchable-function-entry-one-flag.rs @@ -0,0 +1,66 @@ +//@ compile-flags: -Z patchable-function-entry=15 + +#![feature(patchable_function_entry)] +#![crate_type = "lib"] + +// This should have the default, as set by the compile flags +#[no_mangle] +pub fn fun0() {} + +// The attribute should override the compile flags +#[no_mangle] +#[patchable_function_entry(prefix_nops = 1, entry_nops = 2)] +pub fn fun1() {} + +// If we override an attribute to 0 or unset, the attribute should go away +#[no_mangle] +#[patchable_function_entry(entry_nops = 0)] +pub fn fun2() {} + +// The attribute should override the compile flags +#[no_mangle] +#[patchable_function_entry(prefix_nops = 20, entry_nops = 1)] +pub fn fun3() {} + +// The attribute should override the compile flags +#[no_mangle] +#[patchable_function_entry(prefix_nops = 2, entry_nops = 19)] +pub fn fun4() {} + +// The attribute should override patchable-function-entry to 3 +// and patchable-function-prefix to the default of 0, clearing it entirely +#[no_mangle] +#[patchable_function_entry(entry_nops = 3)] +pub fn fun5() {} + +// The attribute should override patchable-function-prefix to 4 +// and patchable-function-entry to the default of 0, clearing it entirely +#[no_mangle] +#[patchable_function_entry(prefix_nops = 4)] +pub fn fun6() {} + +// CHECK: @fun0() unnamed_addr #0 +// CHECK: @fun1() unnamed_addr #1 +// CHECK: @fun2() unnamed_addr #2 +// CHECK: @fun3() unnamed_addr #3 +// CHECK: @fun4() unnamed_addr #4 +// CHECK: @fun5() unnamed_addr #5 +// CHECK: @fun6() unnamed_addr #6 + +// CHECK: attributes #0 = { {{.*}}"patchable-function-entry"="15" {{.*}} } +// CHECK-NOT: attributes #0 = { {{.*}}patchable-function-prefix{{.*}} } + +// CHECK: attributes #1 = { {{.*}}"patchable-function-entry"="2"{{.*}}"patchable-function-prefix"="1" {{.*}} } + +// CHECK-NOT: attributes #2 = { {{.*}}patchable-function-entry{{.*}} } +// CHECK-NOT: attributes #2 = { {{.*}}patchable-function-prefix{{.*}} } +// CHECK: attributes #2 = { {{.*}} } + +// CHECK: attributes #3 = { {{.*}}"patchable-function-entry"="1"{{.*}}"patchable-function-prefix"="20" {{.*}} } +// CHECK: attributes #4 = { {{.*}}"patchable-function-entry"="19"{{.*}}"patchable-function-prefix"="2" {{.*}} } + +// CHECK: attributes #5 = { {{.*}}"patchable-function-entry"="3"{{.*}} } +// CHECK-NOT: attributes #5 = { {{.*}}patchable-function-prefix{{.*}} } + +// CHECK: attributes #6 = { {{.*}}"patchable-function-prefix"="4"{{.*}} } +// CHECK-NOT: attributes #6 = { {{.*}}patchable-function-entry{{.*}} } diff --git a/tests/ui/feature-gates/feature-gate-patchable-function-entry.rs b/tests/ui/feature-gates/feature-gate-patchable-function-entry.rs index 0e16e873a1eaa..b9642c7bfd4a6 100644 --- a/tests/ui/feature-gates/feature-gate-patchable-function-entry.rs +++ b/tests/ui/feature-gates/feature-gate-patchable-function-entry.rs @@ -1,3 +1,3 @@ -#[patchable_function_entry(entry(1), prefix(1))] +#[patchable_function_entry(prefix_nops = 1, entry_nops = 1)] //~^ ERROR: the `#[patchable_function_entry]` attribute is an experimental feature fn main() {} diff --git a/tests/ui/feature-gates/feature-gate-patchable-function-entry.stderr b/tests/ui/feature-gates/feature-gate-patchable-function-entry.stderr index c4d57d774e35d..55fcdb4f7291e 100644 --- a/tests/ui/feature-gates/feature-gate-patchable-function-entry.stderr +++ b/tests/ui/feature-gates/feature-gate-patchable-function-entry.stderr @@ -1,11 +1,12 @@ error[E0658]: the `#[patchable_function_entry]` attribute is an experimental feature --> $DIR/feature-gate-patchable-function-entry.rs:1:1 | -LL | #[patchable_function_entry(entry(1), prefix(1))] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[patchable_function_entry(prefix_nops = 1, entry_nops = 1)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: see issue #9999 for more information + = note: see issue #123115 for more information = help: add `#![feature(patchable_function_entry)]` 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 1 previous error diff --git a/tests/ui/patchable-function-entry/patchable-function-entry-attribute.rs b/tests/ui/patchable-function-entry/patchable-function-entry-attribute.rs new file mode 100644 index 0000000000000..d7231ef416077 --- /dev/null +++ b/tests/ui/patchable-function-entry/patchable-function-entry-attribute.rs @@ -0,0 +1,17 @@ +#![feature(patchable_function_entry)] +fn main() {} + +#[patchable_function_entry(prefix_nops = 256, entry_nops = 0)]//~error: Expected integer value between 0 and 255. +pub fn too_high_pnops() {} + +#[patchable_function_entry(prefix_nops = "stringvalue", entry_nops = 0)]//~error: Expected integer value between 0 and 255. +pub fn non_int_nop() {} + +#[patchable_function_entry]//~error: malformed `patchable_function_entry` attribute input +pub fn malformed_attribute() {} + +#[patchable_function_entry(prefix_nops = 10, something = 0)]//~error: Unexpected parameter name. Allowed names: prefix_nops, entry_nops +pub fn unexpected_parameter_name() {} + +#[patchable_function_entry()]//~error: Must specify at least one parameter. +pub fn no_parameters_given() {} diff --git a/tests/ui/patchable-function-entry/patchable-function-entry-attribute.stderr b/tests/ui/patchable-function-entry/patchable-function-entry-attribute.stderr new file mode 100644 index 0000000000000..a270106925f44 --- /dev/null +++ b/tests/ui/patchable-function-entry/patchable-function-entry-attribute.stderr @@ -0,0 +1,32 @@ +error: malformed `patchable_function_entry` attribute input + --> $DIR/patchable-function-entry-attribute.rs:10:1 + | +LL | #[patchable_function_entry] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[patchable_function_entry(prefix_nops = m, entry_nops = n)]` + +error: Expected integer value between 0 and 255. + --> $DIR/patchable-function-entry-attribute.rs:4:42 + | +LL | #[patchable_function_entry(prefix_nops = 256, entry_nops = 0)] + | ^^^ + +error: Expected integer value between 0 and 255. + --> $DIR/patchable-function-entry-attribute.rs:7:42 + | +LL | #[patchable_function_entry(prefix_nops = "stringvalue", entry_nops = 0)] + | ^^^^^^^^^^^^^ + +error: Unexpected parameter name. Allowed names: prefix_nops, entry_nops + --> $DIR/patchable-function-entry-attribute.rs:13:46 + | +LL | #[patchable_function_entry(prefix_nops = 10, something = 0)] + | ^^^^^^^^^^^^^ + +error: Must specify at least one parameter. + --> $DIR/patchable-function-entry-attribute.rs:16:1 + | +LL | #[patchable_function_entry()] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 5 previous errors + diff --git a/tests/ui/patchable-function-entry/patchable-function-entry-flags.rs b/tests/ui/patchable-function-entry/patchable-function-entry-flags.rs new file mode 100644 index 0000000000000..cb5bc62b6b347 --- /dev/null +++ b/tests/ui/patchable-function-entry/patchable-function-entry-flags.rs @@ -0,0 +1,2 @@ +//@ compile-flags: -Z patchable-function-entry=1,2 +fn main() {} diff --git a/tests/ui/patchable-function-entry/patchable-function-entry-flags.stderr b/tests/ui/patchable-function-entry/patchable-function-entry-flags.stderr new file mode 100644 index 0000000000000..b09af94a61541 --- /dev/null +++ b/tests/ui/patchable-function-entry/patchable-function-entry-flags.stderr @@ -0,0 +1,2 @@ +error: incorrect value `1,2` for unstable option `patchable-function-entry` - either two comma separated integers (total_nops,prefix_nops), with prefix_nops <= total_nops, or one integer (total_nops) was expected + From 8a87f02138ad4dae9a57d71635f9be2bf5696202 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Tue, 25 Jun 2024 20:46:13 +0200 Subject: [PATCH 312/892] Improve error message in tidy --- src/tools/tidy/src/ext_tool_checks.rs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/tools/tidy/src/ext_tool_checks.rs b/src/tools/tidy/src/ext_tool_checks.rs index 995ad58cb6219..26af51bd2d744 100644 --- a/src/tools/tidy/src/ext_tool_checks.rs +++ b/src/tools/tidy/src/ext_tool_checks.rs @@ -267,11 +267,10 @@ fn create_venv_at_path(path: &Path) -> Result<(), Error> { let stderr = String::from_utf8_lossy(&out.stderr); let err = if stderr.contains("No module named virtualenv") { - Error::Generic( + Error::Generic(format!( "virtualenv not found: you may need to install it \ - (`python3 -m pip install venv`)" - .to_owned(), - ) + (`{sys_py} -m pip install virtualenv`)" + )) } else { Error::Generic(format!( "failed to create venv at '{}' using {sys_py}: {stderr}", From d5ff4f4f657766ca03d7b96553baae6aca053596 Mon Sep 17 00:00:00 2001 From: DaniPopes <57450786+DaniPopes@users.noreply.github.com> Date: Tue, 25 Jun 2024 22:34:40 +0200 Subject: [PATCH 313/892] Simplify `str::clone_into` Removes an `unsafe` in favor of just using `String` methods. --- library/alloc/src/str.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/library/alloc/src/str.rs b/library/alloc/src/str.rs index 3e23612d0c13c..3bb808a6c73ab 100644 --- a/library/alloc/src/str.rs +++ b/library/alloc/src/str.rs @@ -206,15 +206,16 @@ impl BorrowMut for String { #[stable(feature = "rust1", since = "1.0.0")] impl ToOwned for str { type Owned = String; + #[inline] fn to_owned(&self) -> String { unsafe { String::from_utf8_unchecked(self.as_bytes().to_owned()) } } + #[inline] fn clone_into(&self, target: &mut String) { - let mut b = mem::take(target).into_bytes(); - self.as_bytes().clone_into(&mut b); - *target = unsafe { String::from_utf8_unchecked(b) } + target.clear(); + target.push_str(self); } } From 2c9556d28aef345102a394ea1256d7713748388a Mon Sep 17 00:00:00 2001 From: joboet Date: Tue, 25 Jun 2024 23:43:19 +0200 Subject: [PATCH 314/892] fix UI test, simplify error message --- library/core/src/fmt/mod.rs | 6 ++++++ tests/ui/fmt/send-sync.stderr | 30 ++++++------------------------ 2 files changed, 12 insertions(+), 24 deletions(-) diff --git a/library/core/src/fmt/mod.rs b/library/core/src/fmt/mod.rs index c25bc5a1b13c9..3bcd4be183465 100644 --- a/library/core/src/fmt/mod.rs +++ b/library/core/src/fmt/mod.rs @@ -459,6 +459,12 @@ impl<'a> Arguments<'a> { } } +// Manually implementing these results in better error messages. +#[stable(feature = "rust1", since = "1.0.0")] +impl !Send for Arguments<'_> {} +#[stable(feature = "rust1", since = "1.0.0")] +impl !Sync for Arguments<'_> {} + #[stable(feature = "rust1", since = "1.0.0")] impl Debug for Arguments<'_> { fn fmt(&self, fmt: &mut Formatter<'_>) -> Result { diff --git a/tests/ui/fmt/send-sync.stderr b/tests/ui/fmt/send-sync.stderr index bebf575d9a71c..dff9b23ba677c 100644 --- a/tests/ui/fmt/send-sync.stderr +++ b/tests/ui/fmt/send-sync.stderr @@ -1,45 +1,27 @@ -error[E0277]: `core::fmt::rt::Opaque` cannot be shared between threads safely +error[E0277]: `Arguments<'_>` cannot be sent between threads safely --> $DIR/send-sync.rs:8:10 | LL | send(format_args!("{:?}", c)); - | ---- ^^^^^^^^^^^^^^^^^^^^^^^ `core::fmt::rt::Opaque` cannot be shared between threads safely + | ---- ^^^^^^^^^^^^^^^^^^^^^^^ `Arguments<'_>` cannot be sent between threads safely | | | required by a bound introduced by this call | - = help: within `[core::fmt::rt::Argument<'_>]`, the trait `Sync` is not implemented for `core::fmt::rt::Opaque`, which is required by `Arguments<'_>: Send` - = note: required because it appears within the type `&core::fmt::rt::Opaque` -note: required because it appears within the type `core::fmt::rt::ArgumentType<'_>` - --> $SRC_DIR/core/src/fmt/rt.rs:LL:COL -note: required because it appears within the type `core::fmt::rt::Argument<'_>` - --> $SRC_DIR/core/src/fmt/rt.rs:LL:COL - = note: required because it appears within the type `[core::fmt::rt::Argument<'_>]` - = note: required for `&[core::fmt::rt::Argument<'_>]` to implement `Send` -note: required because it appears within the type `Arguments<'_>` - --> $SRC_DIR/core/src/fmt/mod.rs:LL:COL + = help: the trait `Send` is not implemented for `Arguments<'_>` note: required by a bound in `send` --> $DIR/send-sync.rs:1:12 | LL | fn send(_: T) {} | ^^^^ required by this bound in `send` -error[E0277]: `core::fmt::rt::Opaque` cannot be shared between threads safely +error[E0277]: `Arguments<'_>` cannot be shared between threads safely --> $DIR/send-sync.rs:9:10 | LL | sync(format_args!("{:?}", c)); - | ---- ^^^^^^^^^^^^^^^^^^^^^^^ `core::fmt::rt::Opaque` cannot be shared between threads safely + | ---- ^^^^^^^^^^^^^^^^^^^^^^^ `Arguments<'_>` cannot be shared between threads safely | | | required by a bound introduced by this call | - = help: within `Arguments<'_>`, the trait `Sync` is not implemented for `core::fmt::rt::Opaque`, which is required by `Arguments<'_>: Sync` - = note: required because it appears within the type `&core::fmt::rt::Opaque` -note: required because it appears within the type `core::fmt::rt::ArgumentType<'_>` - --> $SRC_DIR/core/src/fmt/rt.rs:LL:COL -note: required because it appears within the type `core::fmt::rt::Argument<'_>` - --> $SRC_DIR/core/src/fmt/rt.rs:LL:COL - = note: required because it appears within the type `[core::fmt::rt::Argument<'_>]` - = note: required because it appears within the type `&[core::fmt::rt::Argument<'_>]` -note: required because it appears within the type `Arguments<'_>` - --> $SRC_DIR/core/src/fmt/mod.rs:LL:COL + = help: the trait `Sync` is not implemented for `Arguments<'_>` note: required by a bound in `sync` --> $DIR/send-sync.rs:2:12 | From c6b25234fe92f7b1098017bd3b23eb0c58b7d485 Mon Sep 17 00:00:00 2001 From: Ben Kimock Date: Tue, 25 Jun 2024 18:00:44 -0400 Subject: [PATCH 315/892] 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 11a1c43bae9a2..e5e9f0bbdaf16 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version @@ -1 +1 @@ -d49994b060684af423339b55769439b2f444a7b9 +c290e9de32e8ba6a673ef125fde40eadd395d170 From 23d1cc4b84ad6d966f5a686ac6a93daf0239c455 Mon Sep 17 00:00:00 2001 From: joboet Date: Wed, 26 Jun 2024 00:06:16 +0200 Subject: [PATCH 316/892] core: avoid `extern` types in formatting infrastructure --- library/core/src/fmt/rt.rs | 46 +++++++++++++++++++++----------------- 1 file changed, 25 insertions(+), 21 deletions(-) diff --git a/library/core/src/fmt/rt.rs b/library/core/src/fmt/rt.rs index 92626feabf3d7..5836ce59ec1dc 100644 --- a/library/core/src/fmt/rt.rs +++ b/library/core/src/fmt/rt.rs @@ -5,6 +5,7 @@ use super::*; use crate::hint::unreachable_unchecked; +use crate::ptr::NonNull; #[lang = "format_placeholder"] #[derive(Copy, Clone)] @@ -66,7 +67,13 @@ pub(super) enum Flag { #[derive(Copy, Clone)] enum ArgumentType<'a> { - Placeholder { value: &'a Opaque, formatter: fn(&Opaque, &mut Formatter<'_>) -> Result }, + Placeholder { + // INVARIANT: if `formatter` had type `fn(&T, _) -> _` then `value` + // was derived from a `&T` with lifetime `'a`. + value: NonNull<()>, + formatter: unsafe fn(NonNull<()>, &mut Formatter<'_>) -> Result, + _lifetime: PhantomData<&'a ()>, + }, Count(usize), } @@ -90,21 +97,15 @@ pub struct Argument<'a> { impl<'a> Argument<'a> { #[inline(always)] fn new<'b, T>(x: &'b T, f: fn(&T, &mut Formatter<'_>) -> Result) -> Argument<'b> { - // SAFETY: `mem::transmute(x)` is safe because - // 1. `&'b T` keeps the lifetime it originated with `'b` - // (so as to not have an unbounded lifetime) - // 2. `&'b T` and `&'b Opaque` have the same memory layout - // (when `T` is `Sized`, as it is here) - // `mem::transmute(f)` is safe since `fn(&T, &mut Formatter<'_>) -> Result` - // and `fn(&Opaque, &mut Formatter<'_>) -> Result` have the same ABI - // (as long as `T` is `Sized`) - unsafe { - Argument { - ty: ArgumentType::Placeholder { - formatter: mem::transmute(f), - value: mem::transmute(x), - }, - } + Argument { + // INVARIANT: this creates an `ArgumentType<'b>` from a `&'b T` and + // a `fn(&T, ...)`, so the invariant is maintained. + ty: ArgumentType::Placeholder { + value: NonNull::from(x).cast(), + // SAFETY: function pointers always have the same layout. + formatter: unsafe { mem::transmute(f) }, + _lifetime: PhantomData, + }, } } @@ -162,7 +163,14 @@ impl<'a> Argument<'a> { #[inline(always)] pub(super) unsafe fn fmt(&self, f: &mut Formatter<'_>) -> Result { match self.ty { - ArgumentType::Placeholder { formatter, value } => formatter(value, f), + // SAFETY: + // Because of the invariant that if `formatter` had the type + // `fn(&T, _) -> _` then `value` has type `&'b T` where `'b` is + // the lifetime of the `ArgumentType`, and because references + // and `NonNull` are ABI-compatible, this is completely equivalent + // to calling the original function passed to `new` with the + // original reference, which is sound. + ArgumentType::Placeholder { formatter, value, .. } => unsafe { formatter(value, f) }, // SAFETY: the caller promised this. ArgumentType::Count(_) => unsafe { unreachable_unchecked() }, } @@ -208,7 +216,3 @@ impl UnsafeArg { Self { _private: () } } } - -extern "C" { - type Opaque; -} From 7526416ba6bcb3e0b51bfcdc93544a9552f9568e Mon Sep 17 00:00:00 2001 From: joboet Date: Wed, 26 Jun 2024 00:06:27 +0200 Subject: [PATCH 317/892] update coverage test --- tests/coverage/issue-83601.cov-map | 6 +++--- tests/coverage/issue-84561.cov-map | 14 +++++++------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/tests/coverage/issue-83601.cov-map b/tests/coverage/issue-83601.cov-map index ddb4407881aad..f2447e3c92c8a 100644 --- a/tests/coverage/issue-83601.cov-map +++ b/tests/coverage/issue-83601.cov-map @@ -1,12 +1,12 @@ Function name: issue_83601::main -Raw bytes (21): 0x[01, 01, 01, 05, 00, 03, 01, 06, 01, 02, 1c, 05, 03, 09, 01, 1c, 02, 02, 05, 03, 02] +Raw bytes (21): 0x[01, 01, 01, 05, 09, 03, 01, 06, 01, 02, 1c, 05, 03, 09, 01, 1c, 02, 02, 05, 03, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 1 -- expression 0 operands: lhs = Counter(1), rhs = Zero +- expression 0 operands: lhs = Counter(1), rhs = Counter(2) Number of file 0 mappings: 3 - Code(Counter(0)) at (prev + 6, 1) to (start + 2, 28) - Code(Counter(1)) at (prev + 3, 9) to (start + 1, 28) - Code(Expression(0, Sub)) at (prev + 2, 5) to (start + 3, 2) - = (c1 - Zero) + = (c1 - c2) diff --git a/tests/coverage/issue-84561.cov-map b/tests/coverage/issue-84561.cov-map index c4087d9369d87..d3c4671e0ba4c 100644 --- a/tests/coverage/issue-84561.cov-map +++ b/tests/coverage/issue-84561.cov-map @@ -54,15 +54,15 @@ Number of file 0 mappings: 1 - Code(Counter(0)) at (prev + 167, 9) to (start + 2, 10) Function name: issue_84561::test3 -Raw bytes (375): 0x[01, 01, 31, 05, 00, 0d, 00, 15, 00, 12, 00, 15, 00, 21, 00, 1e, 00, 21, 00, 31, 00, 3d, 00, 2e, 45, 3d, 00, 42, 49, 45, 00, 3f, 51, 42, 49, 45, 00, 7a, 55, 51, 00, 7a, 55, 51, 00, 77, 5d, 7a, 55, 51, 00, 77, 61, 7a, 55, 51, 00, 72, 65, 77, 61, 7a, 55, 51, 00, 75, be, 01, c2, 01, 79, 69, 6d, 69, 6d, 69, 6d, c2, 01, 00, 69, 6d, c2, 01, 79, 69, 6d, bb, 01, 7d, 75, be, 01, c2, 01, 79, 69, 6d, b6, 01, 00, bb, 01, 7d, 75, be, 01, c2, 01, 79, 69, 6d, 33, 01, 08, 01, 03, 1c, 05, 04, 09, 01, 1c, 02, 02, 05, 04, 1f, 0d, 05, 05, 00, 1f, 06, 01, 05, 00, 1f, 15, 01, 09, 01, 1c, 12, 02, 05, 00, 1f, 0e, 01, 05, 00, 0f, 00, 00, 20, 00, 30, 21, 01, 05, 03, 0f, 00, 03, 20, 00, 30, 00, 00, 33, 00, 41, 00, 00, 4b, 00, 5a, 1e, 01, 05, 00, 0f, 00, 05, 09, 03, 10, 00, 05, 0d, 00, 1b, 00, 02, 0d, 00, 1c, 1a, 04, 09, 05, 06, 31, 06, 05, 03, 06, 22, 04, 05, 03, 06, 3d, 04, 09, 04, 06, 2e, 05, 08, 00, 0f, 45, 01, 09, 03, 0a, 2a, 05, 09, 03, 0a, 3f, 05, 08, 00, 0f, 51, 01, 09, 00, 13, 00, 03, 0d, 00, 1d, 3a, 03, 09, 00, 13, 00, 03, 0d, 00, 1d, 77, 03, 05, 00, 0f, 77, 01, 0c, 00, 13, 5d, 01, 0d, 00, 13, 56, 02, 0d, 00, 13, 72, 04, 05, 02, 13, 65, 03, 0d, 00, 13, 6e, 02, 0d, 00, 13, bb, 01, 03, 05, 00, 0f, 69, 01, 0c, 00, 13, 6d, 01, 0d, 03, 0e, 75, 04, 0d, 00, 13, c2, 01, 02, 0d, 00, 17, c2, 01, 01, 14, 00, 1b, 00, 01, 15, 00, 1b, 92, 01, 02, 15, 00, 1b, be, 01, 04, 0d, 00, 13, 7d, 03, 09, 00, 19, b6, 01, 02, 05, 00, 0f, b2, 01, 03, 09, 00, 22, 00, 02, 05, 00, 0f, 00, 03, 09, 00, 2c, 00, 02, 01, 00, 02] +Raw bytes (375): 0x[01, 01, 31, 05, 09, 0d, 00, 15, 19, 12, 00, 15, 19, 21, 00, 1e, 00, 21, 00, 31, 00, 3d, 00, 2e, 45, 3d, 00, 42, 49, 45, 00, 3f, 51, 42, 49, 45, 00, 7a, 55, 51, 00, 7a, 55, 51, 00, 77, 5d, 7a, 55, 51, 00, 77, 61, 7a, 55, 51, 00, 72, 65, 77, 61, 7a, 55, 51, 00, 75, be, 01, c2, 01, 79, 69, 6d, 69, 6d, 69, 6d, c2, 01, 00, 69, 6d, c2, 01, 79, 69, 6d, bb, 01, 7d, 75, be, 01, c2, 01, 79, 69, 6d, b6, 01, 00, bb, 01, 7d, 75, be, 01, c2, 01, 79, 69, 6d, 33, 01, 08, 01, 03, 1c, 05, 04, 09, 01, 1c, 02, 02, 05, 04, 1f, 0d, 05, 05, 00, 1f, 06, 01, 05, 00, 1f, 15, 01, 09, 01, 1c, 12, 02, 05, 00, 1f, 0e, 01, 05, 00, 0f, 00, 00, 20, 00, 30, 21, 01, 05, 03, 0f, 00, 03, 20, 00, 30, 00, 00, 33, 00, 41, 00, 00, 4b, 00, 5a, 1e, 01, 05, 00, 0f, 00, 05, 09, 03, 10, 00, 05, 0d, 00, 1b, 00, 02, 0d, 00, 1c, 1a, 04, 09, 05, 06, 31, 06, 05, 03, 06, 22, 04, 05, 03, 06, 3d, 04, 09, 04, 06, 2e, 05, 08, 00, 0f, 45, 01, 09, 03, 0a, 2a, 05, 09, 03, 0a, 3f, 05, 08, 00, 0f, 51, 01, 09, 00, 13, 00, 03, 0d, 00, 1d, 3a, 03, 09, 00, 13, 00, 03, 0d, 00, 1d, 77, 03, 05, 00, 0f, 77, 01, 0c, 00, 13, 5d, 01, 0d, 00, 13, 56, 02, 0d, 00, 13, 72, 04, 05, 02, 13, 65, 03, 0d, 00, 13, 6e, 02, 0d, 00, 13, bb, 01, 03, 05, 00, 0f, 69, 01, 0c, 00, 13, 6d, 01, 0d, 03, 0e, 75, 04, 0d, 00, 13, c2, 01, 02, 0d, 00, 17, c2, 01, 01, 14, 00, 1b, 00, 01, 15, 00, 1b, 92, 01, 02, 15, 00, 1b, be, 01, 04, 0d, 00, 13, 7d, 03, 09, 00, 19, b6, 01, 02, 05, 00, 0f, b2, 01, 03, 09, 00, 22, 00, 02, 05, 00, 0f, 00, 03, 09, 00, 2c, 00, 02, 01, 00, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 49 -- expression 0 operands: lhs = Counter(1), rhs = Zero +- expression 0 operands: lhs = Counter(1), rhs = Counter(2) - expression 1 operands: lhs = Counter(3), rhs = Zero -- expression 2 operands: lhs = Counter(5), rhs = Zero +- expression 2 operands: lhs = Counter(5), rhs = Counter(6) - expression 3 operands: lhs = Expression(4, Sub), rhs = Zero -- expression 4 operands: lhs = Counter(5), rhs = Zero +- expression 4 operands: lhs = Counter(5), rhs = Counter(6) - expression 5 operands: lhs = Counter(8), rhs = Zero - expression 6 operands: lhs = Expression(7, Sub), rhs = Zero - expression 7 operands: lhs = Counter(8), rhs = Zero @@ -111,15 +111,15 @@ Number of file 0 mappings: 51 - Code(Counter(0)) at (prev + 8, 1) to (start + 3, 28) - Code(Counter(1)) at (prev + 4, 9) to (start + 1, 28) - Code(Expression(0, Sub)) at (prev + 2, 5) to (start + 4, 31) - = (c1 - Zero) + = (c1 - c2) - Code(Counter(3)) at (prev + 5, 5) to (start + 0, 31) - Code(Expression(1, Sub)) at (prev + 1, 5) to (start + 0, 31) = (c3 - Zero) - Code(Counter(5)) at (prev + 1, 9) to (start + 1, 28) - Code(Expression(4, Sub)) at (prev + 2, 5) to (start + 0, 31) - = (c5 - Zero) + = (c5 - c6) - Code(Expression(3, Sub)) at (prev + 1, 5) to (start + 0, 15) - = ((c5 - Zero) - Zero) + = ((c5 - c6) - Zero) - Code(Zero) at (prev + 0, 32) to (start + 0, 48) - Code(Counter(8)) at (prev + 1, 5) to (start + 3, 15) - Code(Zero) at (prev + 3, 32) to (start + 0, 48) From 476b7bdbe5fec58075b38b783bb463e6e4dd257f Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Wed, 26 Jun 2024 09:13:12 +0000 Subject: [PATCH 318/892] Rustup to rustc 1.81.0-nightly (fda509e81 2024-06-25) --- rust-toolchain | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-toolchain b/rust-toolchain index 36d98a869db1e..85d73cb414f17 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2024-06-18" +channel = "nightly-2024-06-26" components = ["rust-src", "rustc-dev", "llvm-tools"] From 94c2e7aad3ae5c8ac690ab9c173d68a1fe79d82c Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Wed, 26 Jun 2024 09:33:35 +0000 Subject: [PATCH 319/892] Fix rustc test suite --- scripts/test_rustc_tests.sh | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/scripts/test_rustc_tests.sh b/scripts/test_rustc_tests.sh index 283889e9471c3..c1b7e4b0e0768 100755 --- a/scripts/test_rustc_tests.sh +++ b/scripts/test_rustc_tests.sh @@ -59,7 +59,6 @@ rm tests/ui/asm/x86_64/goto.rs # inline asm labels not supported # requires LTO rm -r tests/run-make/cdylib -rm -r tests/run-make/issue-64153 rm -r tests/run-make/codegen-options-parsing rm -r tests/run-make/lto-* rm -r tests/run-make/reproducible-build-2 @@ -72,6 +71,9 @@ rm tests/ui/consts/precise-drop-with-coverage.rs rm tests/ui/issues/issue-85461.rs rm -r tests/ui/instrument-coverage/ +# missing f16/f128 support +rm tests/ui/half-open-range-patterns/half-open-range-pats-semantics.rs + # optimization tests # ================== rm tests/ui/codegen/issue-28950.rs # depends on stack size optimizations @@ -106,6 +108,7 @@ rm -r tests/run-make/compressed-debuginfo rm -r tests/run-make/symbols-include-type-name rm -r tests/run-make/notify-all-emit-artifacts rm -r tests/run-make/reset-codegen-1 +rm -r tests/run-make/inline-always-many-cgu # giving different but possibly correct results # ============================================= @@ -124,6 +127,7 @@ rm -r tests/run-make/compiler-builtins # Expects lib/rustlib/src/rust to contain # ============ rm -r tests/run-make/extern-fn-explicit-align # argument alignment not yet supported rm -r tests/run-make/panic-abort-eh_frame # .eh_frame emitted with panic=abort +rm tests/ui/deprecation/deprecated_inline_threshold.rs # missing deprecation warning for -Cinline-threshold # bugs in the test suite # ====================== From 2ffff791ce0d5d29a0e47d9c5519fcccdb696e9f Mon Sep 17 00:00:00 2001 From: Oneirical Date: Wed, 26 Jun 2024 10:39:45 -0400 Subject: [PATCH 320/892] rewrite pretty-print-with-dep-file to rmake --- .../tidy/src/allowed_run_make_makefiles.txt | 1 - .../pretty-print-with-dep-file/Makefile | 9 --------- .../pretty-print-with-dep-file/rmake.rs | 17 +++++++++++++++++ 3 files changed, 17 insertions(+), 10 deletions(-) delete mode 100644 tests/run-make/pretty-print-with-dep-file/Makefile create mode 100644 tests/run-make/pretty-print-with-dep-file/rmake.rs diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index cb68589d8a4c2..2f64b6004fd52 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -134,7 +134,6 @@ run-make/pgo-indirect-call-promotion/Makefile run-make/pgo-use/Makefile run-make/pointer-auth-link-with-c/Makefile run-make/pretty-print-to-file/Makefile -run-make/pretty-print-with-dep-file/Makefile run-make/print-calling-conventions/Makefile run-make/print-target-list/Makefile run-make/profile/Makefile diff --git a/tests/run-make/pretty-print-with-dep-file/Makefile b/tests/run-make/pretty-print-with-dep-file/Makefile deleted file mode 100644 index fa8089eb6a552..0000000000000 --- a/tests/run-make/pretty-print-with-dep-file/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -include ../tools.mk - -all: - $(RUSTC) --emit=dep-info -Zunpretty=expanded with-dep.rs - $(CGREP) "with-dep.rs" < $(TMPDIR)/with-dep.d - -rm $(TMPDIR)/with-dep.d - - $(RUSTC) --emit=dep-info -Zunpretty=normal with-dep.rs - ! test -f $(TMPDIR)/with-dep.d diff --git a/tests/run-make/pretty-print-with-dep-file/rmake.rs b/tests/run-make/pretty-print-with-dep-file/rmake.rs new file mode 100644 index 0000000000000..859a9781bb6e6 --- /dev/null +++ b/tests/run-make/pretty-print-with-dep-file/rmake.rs @@ -0,0 +1,17 @@ +// Passing --emit=dep-info to the Rust compiler should create a .d file... +// but it failed to do so in Rust 1.69.0 when combined with -Z unpretty=expanded +// due to a bug. This test checks that -Z unpretty=expanded does not prevent the +// generation of the dep-info file, and that its -Z unpretty=normal counterpart +// does not get an unexpected dep-info file. +// See https://github.com/rust-lang/rust/issues/112898 + +use run_make_support::{fs_wrapper, invalid_utf8_contains, rustc}; +use std::path::Path; + +fn main() { + rustc().emit("dep-info").arg("-Zunpretty=expanded").input("with-dep.rs").run(); + invalid_utf8_contains("with-dep.d", "with-dep.rs"); + fs_wrapper::remove_file("with-dep.d"); + rustc().emit("dep-info").arg("-Zunpretty=normal").input("with-dep.rs").run(); + assert!(!Path::new("with-dep.d").exists()); +} From 722ae2243ece024797c006d1812c6abd3158f720 Mon Sep 17 00:00:00 2001 From: Oneirical Date: Wed, 26 Jun 2024 11:44:11 -0400 Subject: [PATCH 321/892] rewrite pretty-print-to-file to rmake --- src/tools/tidy/src/allowed_run_make_makefiles.txt | 2 -- tests/run-make/pretty-print-to-file/Makefile | 5 ----- tests/run-make/pretty-print-to-file/rmake.rs | 12 ++++++++++++ 3 files changed, 12 insertions(+), 7 deletions(-) delete mode 100644 tests/run-make/pretty-print-to-file/Makefile create mode 100644 tests/run-make/pretty-print-to-file/rmake.rs diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index 2f64b6004fd52..fa754d2e6d543 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -84,7 +84,6 @@ run-make/jobserver-error/Makefile run-make/libs-through-symlinks/Makefile run-make/libtest-json/Makefile run-make/libtest-junit/Makefile -run-make/libtest-padding/Makefile run-make/libtest-thread-limit/Makefile run-make/link-cfg/Makefile run-make/link-framework/Makefile @@ -133,7 +132,6 @@ run-make/pgo-gen/Makefile run-make/pgo-indirect-call-promotion/Makefile run-make/pgo-use/Makefile run-make/pointer-auth-link-with-c/Makefile -run-make/pretty-print-to-file/Makefile run-make/print-calling-conventions/Makefile run-make/print-target-list/Makefile run-make/profile/Makefile diff --git a/tests/run-make/pretty-print-to-file/Makefile b/tests/run-make/pretty-print-to-file/Makefile deleted file mode 100644 index ca11b8c47f06f..0000000000000 --- a/tests/run-make/pretty-print-to-file/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -include ../tools.mk - -all: - $(RUSTC) -o $(TMPDIR)/input.out -Zunpretty=normal input.rs - diff -u $(TMPDIR)/input.out input.pp diff --git a/tests/run-make/pretty-print-to-file/rmake.rs b/tests/run-make/pretty-print-to-file/rmake.rs new file mode 100644 index 0000000000000..c23514ae84960 --- /dev/null +++ b/tests/run-make/pretty-print-to-file/rmake.rs @@ -0,0 +1,12 @@ +// The "pretty-printer" of rustc translates source code into other formats, +// which is useful for debugging. This test checks the "normal" version of +// -Zunpretty, which should format the poorly formatted input.rs into a one-line +// function identical to the one in input.pp. +// See https://github.com/rust-lang/rust/commit/da25539c1ab295ec40261109557dd4526923928c + +use run_make_support::{diff, rustc}; + +fn main() { + rustc().output("input.out").arg("-Zunpretty=normal").input("input.rs").run(); + diff().expected_file("input.out").actual_file("input.pp").run(); +} From 53109d5d6e284da313617be95e31ff4152d317f0 Mon Sep 17 00:00:00 2001 From: Oneirical Date: Wed, 26 Jun 2024 11:44:23 -0400 Subject: [PATCH 322/892] rewrite libtest-padding to rmake --- tests/run-make/libtest-padding/Makefile | 14 -------- tests/run-make/libtest-padding/rmake.rs | 46 +++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 14 deletions(-) delete mode 100644 tests/run-make/libtest-padding/Makefile create mode 100644 tests/run-make/libtest-padding/rmake.rs diff --git a/tests/run-make/libtest-padding/Makefile b/tests/run-make/libtest-padding/Makefile deleted file mode 100644 index c8e2fc01f677d..0000000000000 --- a/tests/run-make/libtest-padding/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -# ignore-cross-compile because we run the compiled code -# needs-unwind because #[bench] and -Cpanic=abort requires -Zpanic-abort-tests -include ../tools.mk - -NORMALIZE=sed 's%[0-9,\.]\{1,\} ns/iter (+/- [0-9,\.]\{1,\})%?? ns/iter (+/- ??)%' | sed 's%finished in [0-9\.]\{1,\}%finished in ??%' - -all: - $(RUSTC) --test tests.rs - - $(call RUN,tests) --test-threads=1 | $(NORMALIZE) > "$(TMPDIR)"/test.stdout - $(RUSTC_TEST_OP) "$(TMPDIR)"/test.stdout test.stdout - - $(call RUN,tests) --test-threads=1 --bench | $(NORMALIZE) > "$(TMPDIR)"/bench.stdout - $(RUSTC_TEST_OP) "$(TMPDIR)"/bench.stdout bench.stdout diff --git a/tests/run-make/libtest-padding/rmake.rs b/tests/run-make/libtest-padding/rmake.rs new file mode 100644 index 0000000000000..4b17ba19bf7da --- /dev/null +++ b/tests/run-make/libtest-padding/rmake.rs @@ -0,0 +1,46 @@ +// Benchmarks, when ran as tests, would cause strange indentations +// to appear in the output. This was because padding formatting was +// applied before the conversion from bench to test, and not afterwards. +// Now that this bug has been fixed in #118548, this test checks that it +// does not make a resurgence by comparing the output of --bench with an +// example stdout file. +// See https://github.com/rust-lang/rust/issues/104092 + +//@ ignore-cross-compile +// Reason: the compiled code is ran +//@ needs-unwind +// Reason: #[bench] requires -Z panic-abort-tests + +use run_make_support::{diff, run_with_args, rustc}; + +fn main() { + rustc().arg("--test").input("tests.rs").run(); + let out = run_with_args("tests", &["--test-threads=1"]).stdout_utf8(); + diff() + .expected_file("test.stdout") + .actual_text("actual-test-stdout", out) + .normalize( + // Replace all instances of (arbitrary numbers) + // [1.2345 ns/iter (+/- 0.1234)] + // with + // [?? ns/iter (+/- ??)] + r#"(\d+(?:[.,]\d+)*)\s*ns/iter\s*\(\+/-\s*(\d+(?:[.,]\d+)*)\)"#, + "?? ns/iter (+/- ??)", + ) + // Replace all instances of (arbitrary numbers) + // finished in 8.0000 s + // with + // finished in ?? + .normalize(r#"finished\s+in\s+(\d+(?:\.\d+)*)"#, "finished in ??") + .run(); + let out = run_with_args("tests", &["--test-threads=1", "--bench"]).stdout_utf8(); + diff() + .expected_file("bench.stdout") + .actual_text("actual-bench-stdout", out) + .normalize( + r#"(\d+(?:[.,]\d+)*)\s*ns/iter\s*\(\+/-\s*(\d+(?:[.,]\d+)*)\)"#, + "?? ns/iter (+/- ??)", + ) + .normalize(r#"finished\s+in\s+(\d+(?:\.\d+)*)"#, "finished in ??") + .run(); +} From 81695a147aa1f88c34ec4ae1f0bffe429981c442 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 25 Jun 2024 08:05:58 +0000 Subject: [PATCH 323/892] Split lifetimes on mir borrowck dataflow --- compiler/rustc_borrowck/src/dataflow.rs | 40 +++++++------- compiler/rustc_borrowck/src/lib.rs | 38 ++++++------- compiler/rustc_borrowck/src/nll.rs | 2 +- .../src/type_check/liveness/mod.rs | 2 +- .../src/type_check/liveness/trace.rs | 16 +++--- compiler/rustc_borrowck/src/type_check/mod.rs | 2 +- .../src/impls/initialized.rs | 54 +++++++++++-------- .../src/elaborate_drops.rs | 26 ++++----- 8 files changed, 94 insertions(+), 86 deletions(-) diff --git a/compiler/rustc_borrowck/src/dataflow.rs b/compiler/rustc_borrowck/src/dataflow.rs index f2b5ddcd7827c..00a30dc2240a6 100644 --- a/compiler/rustc_borrowck/src/dataflow.rs +++ b/compiler/rustc_borrowck/src/dataflow.rs @@ -15,24 +15,24 @@ use std::fmt; use crate::{places_conflict, BorrowSet, PlaceConflictBias, PlaceExt, RegionInferenceContext}; /// The results of the dataflow analyses used by the borrow checker. -pub struct BorrowckResults<'mir, 'tcx> { - pub(crate) borrows: Results<'tcx, Borrows<'mir, 'tcx>>, - pub(crate) uninits: Results<'tcx, MaybeUninitializedPlaces<'mir, 'tcx>>, - pub(crate) ever_inits: Results<'tcx, EverInitializedPlaces<'mir, 'tcx>>, +pub struct BorrowckResults<'a, 'mir, 'tcx> { + pub(crate) borrows: Results<'tcx, Borrows<'a, 'mir, 'tcx>>, + pub(crate) uninits: Results<'tcx, MaybeUninitializedPlaces<'a, 'mir, 'tcx>>, + pub(crate) ever_inits: Results<'tcx, EverInitializedPlaces<'a, 'mir, 'tcx>>, } /// The transient state of the dataflow analyses used by the borrow checker. #[derive(Debug)] -pub struct BorrowckFlowState<'mir, 'tcx> { - pub(crate) borrows: as AnalysisDomain<'tcx>>::Domain, - pub(crate) uninits: as AnalysisDomain<'tcx>>::Domain, - pub(crate) ever_inits: as AnalysisDomain<'tcx>>::Domain, +pub struct BorrowckFlowState<'a, 'mir, 'tcx> { + pub(crate) borrows: as AnalysisDomain<'tcx>>::Domain, + pub(crate) uninits: as AnalysisDomain<'tcx>>::Domain, + pub(crate) ever_inits: as AnalysisDomain<'tcx>>::Domain, } -impl<'mir, 'tcx> ResultsVisitable<'tcx> for BorrowckResults<'mir, 'tcx> { +impl<'a, 'mir, 'tcx> ResultsVisitable<'tcx> for BorrowckResults<'a, 'mir, 'tcx> { // All three analyses are forward, but we have to use just one here. - type Direction = as AnalysisDomain<'tcx>>::Direction; - type FlowState = BorrowckFlowState<'mir, 'tcx>; + type Direction = as AnalysisDomain<'tcx>>::Direction; + type FlowState = BorrowckFlowState<'a, 'mir, 'tcx>; fn new_flow_state(&self, body: &mir::Body<'tcx>) -> Self::FlowState { BorrowckFlowState { @@ -106,11 +106,11 @@ rustc_index::newtype_index! { /// `BorrowIndex`, and maps each such index to a `BorrowData` /// describing the borrow. These indexes are used for representing the /// borrows in compact bitvectors. -pub struct Borrows<'mir, 'tcx> { +pub struct Borrows<'a, 'mir, 'tcx> { tcx: TyCtxt<'tcx>, body: &'mir Body<'tcx>, - borrow_set: &'mir BorrowSet<'tcx>, + borrow_set: &'a BorrowSet<'tcx>, borrows_out_of_scope_at_location: FxIndexMap>, } @@ -389,12 +389,12 @@ impl<'tcx> PoloniusOutOfScopePrecomputer<'_, 'tcx> { } } -impl<'mir, 'tcx> Borrows<'mir, 'tcx> { +impl<'a, 'mir, 'tcx> Borrows<'a, 'mir, 'tcx> { pub fn new( tcx: TyCtxt<'tcx>, body: &'mir Body<'tcx>, - regioncx: &'mir RegionInferenceContext<'tcx>, - borrow_set: &'mir BorrowSet<'tcx>, + regioncx: &RegionInferenceContext<'tcx>, + borrow_set: &'a BorrowSet<'tcx>, ) -> Self { let mut borrows_out_of_scope_at_location = calculate_borrows_out_of_scope_at_location(body, regioncx, borrow_set); @@ -494,7 +494,7 @@ impl<'mir, 'tcx> Borrows<'mir, 'tcx> { } } -impl<'tcx> rustc_mir_dataflow::AnalysisDomain<'tcx> for Borrows<'_, 'tcx> { +impl<'tcx> rustc_mir_dataflow::AnalysisDomain<'tcx> for Borrows<'_, '_, 'tcx> { type Domain = BitSet; const NAME: &'static str = "borrows"; @@ -517,7 +517,7 @@ impl<'tcx> rustc_mir_dataflow::AnalysisDomain<'tcx> for Borrows<'_, 'tcx> { /// region stops containing the CFG points reachable from the issuing location. /// - we also kill loans of conflicting places when overwriting a shared path: e.g. borrows of /// `a.b.c` when `a` is overwritten. -impl<'tcx> rustc_mir_dataflow::GenKillAnalysis<'tcx> for Borrows<'_, 'tcx> { +impl<'tcx> rustc_mir_dataflow::GenKillAnalysis<'tcx> for Borrows<'_, '_, 'tcx> { type Idx = BorrowIndex; fn domain_size(&self, _: &mir::Body<'tcx>) -> usize { @@ -617,8 +617,8 @@ impl<'tcx> rustc_mir_dataflow::GenKillAnalysis<'tcx> for Borrows<'_, 'tcx> { } } -impl DebugWithContext> for BorrowIndex { - fn fmt_with(&self, ctxt: &Borrows<'_, '_>, f: &mut fmt::Formatter<'_>) -> fmt::Result { +impl DebugWithContext> for BorrowIndex { + fn fmt_with(&self, ctxt: &Borrows<'_, '_, '_>, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{:?}", ctxt.location(*self)) } } diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index 69efee2fbdc14..0bdae081b94f1 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -605,15 +605,15 @@ struct MirBorrowckCtxt<'a, 'mir, 'cx, 'tcx> { // 2. loans made in overlapping scopes do not conflict // 3. assignments do not affect things loaned out as immutable // 4. moves do not affect things loaned out in any way -impl<'mir, 'tcx, R> rustc_mir_dataflow::ResultsVisitor<'mir, 'tcx, R> - for MirBorrowckCtxt<'_, 'mir, '_, 'tcx> +impl<'a, 'mir, 'tcx, R> rustc_mir_dataflow::ResultsVisitor<'mir, 'tcx, R> + for MirBorrowckCtxt<'a, 'mir, '_, 'tcx> { - type FlowState = Flows<'mir, 'tcx>; + type FlowState = Flows<'a, 'mir, 'tcx>; fn visit_statement_before_primary_effect( &mut self, _results: &mut R, - flow_state: &Flows<'mir, 'tcx>, + flow_state: &Flows<'_, 'mir, 'tcx>, stmt: &'mir Statement<'tcx>, location: Location, ) { @@ -683,7 +683,7 @@ impl<'mir, 'tcx, R> rustc_mir_dataflow::ResultsVisitor<'mir, 'tcx, R> fn visit_terminator_before_primary_effect( &mut self, _results: &mut R, - flow_state: &Flows<'mir, 'tcx>, + flow_state: &Flows<'_, 'mir, 'tcx>, term: &'mir Terminator<'tcx>, loc: Location, ) { @@ -794,7 +794,7 @@ impl<'mir, 'tcx, R> rustc_mir_dataflow::ResultsVisitor<'mir, 'tcx, R> fn visit_terminator_after_primary_effect( &mut self, _results: &mut R, - flow_state: &Flows<'mir, 'tcx>, + flow_state: &Flows<'_, 'mir, 'tcx>, term: &'mir Terminator<'tcx>, loc: Location, ) { @@ -988,7 +988,7 @@ impl<'mir, 'tcx> MirBorrowckCtxt<'_, 'mir, '_, 'tcx> { place_span: (Place<'tcx>, Span), kind: (AccessDepth, ReadOrWrite), is_local_mutation_allowed: LocalMutationIsAllowed, - flow_state: &Flows<'mir, 'tcx>, + flow_state: &Flows<'_, 'mir, 'tcx>, ) { let (sd, rw) = kind; @@ -1038,7 +1038,7 @@ impl<'mir, 'tcx> MirBorrowckCtxt<'_, 'mir, '_, 'tcx> { place_span: (Place<'tcx>, Span), sd: AccessDepth, rw: ReadOrWrite, - flow_state: &Flows<'mir, 'tcx>, + flow_state: &Flows<'_, 'mir, 'tcx>, ) -> bool { let mut error_reported = false; let borrow_set = Rc::clone(&self.borrow_set); @@ -1179,7 +1179,7 @@ impl<'mir, 'tcx> MirBorrowckCtxt<'_, 'mir, '_, 'tcx> { location: Location, place_span: (Place<'tcx>, Span), kind: AccessDepth, - flow_state: &Flows<'mir, 'tcx>, + flow_state: &Flows<'_, 'mir, 'tcx>, ) { // Write of P[i] or *P requires P init'd. self.check_if_assigned_path_is_moved(location, place_span, flow_state); @@ -1197,7 +1197,7 @@ impl<'mir, 'tcx> MirBorrowckCtxt<'_, 'mir, '_, 'tcx> { &mut self, location: Location, (rvalue, span): (&'mir Rvalue<'tcx>, Span), - flow_state: &Flows<'mir, 'tcx>, + flow_state: &Flows<'_, 'mir, 'tcx>, ) { match rvalue { &Rvalue::Ref(_ /*rgn*/, bk, place) => { @@ -1455,7 +1455,7 @@ impl<'mir, 'tcx> MirBorrowckCtxt<'_, 'mir, '_, 'tcx> { &mut self, location: Location, (operand, span): (&'mir Operand<'tcx>, Span), - flow_state: &Flows<'mir, 'tcx>, + flow_state: &Flows<'_, 'mir, 'tcx>, ) { match *operand { Operand::Copy(place) => { @@ -1579,7 +1579,7 @@ impl<'mir, 'tcx> MirBorrowckCtxt<'_, 'mir, '_, 'tcx> { &mut self, location: Location, span: Span, - flow_state: &Flows<'mir, 'tcx>, + flow_state: &Flows<'_, 'mir, 'tcx>, ) { // Two-phase borrow support: For each activation that is newly // generated at this statement, check if it interferes with @@ -1743,7 +1743,7 @@ impl<'mir, 'tcx> MirBorrowckCtxt<'_, 'mir, '_, 'tcx> { location: Location, desired_action: InitializationRequiringAction, place_span: (PlaceRef<'tcx>, Span), - flow_state: &Flows<'mir, 'tcx>, + flow_state: &Flows<'_, 'mir, 'tcx>, ) { let maybe_uninits = &flow_state.uninits; @@ -1848,7 +1848,7 @@ impl<'mir, 'tcx> MirBorrowckCtxt<'_, 'mir, '_, 'tcx> { location: Location, desired_action: InitializationRequiringAction, place_span: (PlaceRef<'tcx>, Span), - flow_state: &Flows<'mir, 'tcx>, + flow_state: &Flows<'_, 'mir, 'tcx>, ) { let maybe_uninits = &flow_state.uninits; @@ -1947,7 +1947,7 @@ impl<'mir, 'tcx> MirBorrowckCtxt<'_, 'mir, '_, 'tcx> { &mut self, location: Location, (place, span): (Place<'tcx>, Span), - flow_state: &Flows<'mir, 'tcx>, + flow_state: &Flows<'_, 'mir, 'tcx>, ) { debug!("check_if_assigned_path_is_moved place: {:?}", place); @@ -2013,7 +2013,7 @@ impl<'mir, 'tcx> MirBorrowckCtxt<'_, 'mir, '_, 'tcx> { location: Location, base: PlaceRef<'tcx>, span: Span, - flow_state: &Flows<'mir, 'tcx>, + flow_state: &Flows<'_, 'mir, 'tcx>, ) { // rust-lang/rust#21232: Until Rust allows reads from the // initialized parts of partially initialized structs, we @@ -2104,7 +2104,7 @@ impl<'mir, 'tcx> MirBorrowckCtxt<'_, 'mir, '_, 'tcx> { (place, span): (Place<'tcx>, Span), kind: ReadOrWrite, is_local_mutation_allowed: LocalMutationIsAllowed, - flow_state: &Flows<'mir, 'tcx>, + flow_state: &Flows<'_, 'mir, 'tcx>, location: Location, ) -> bool { debug!( @@ -2220,7 +2220,7 @@ impl<'mir, 'tcx> MirBorrowckCtxt<'_, 'mir, '_, 'tcx> { fn is_local_ever_initialized( &self, local: Local, - flow_state: &Flows<'mir, 'tcx>, + flow_state: &Flows<'_, 'mir, 'tcx>, ) -> Option { let mpi = self.move_data.rev_lookup.find_local(local)?; let ii = &self.move_data.init_path_map[mpi]; @@ -2228,7 +2228,7 @@ impl<'mir, 'tcx> MirBorrowckCtxt<'_, 'mir, '_, 'tcx> { } /// Adds the place into the used mutable variables set - fn add_used_mut(&mut self, root_place: RootPlace<'tcx>, flow_state: &Flows<'mir, 'tcx>) { + fn add_used_mut(&mut self, root_place: RootPlace<'tcx>, flow_state: &Flows<'_, 'mir, 'tcx>) { match root_place { RootPlace { place_local: local, place_projection: [], is_local_mutation_allowed } => { // If the local may have been initialized, and it is now currently being diff --git a/compiler/rustc_borrowck/src/nll.rs b/compiler/rustc_borrowck/src/nll.rs index 923cf7e940573..4ab06d9c4d09e 100644 --- a/compiler/rustc_borrowck/src/nll.rs +++ b/compiler/rustc_borrowck/src/nll.rs @@ -81,7 +81,7 @@ pub(crate) fn compute_regions<'cx, 'tcx>( promoted: &IndexSlice>, location_table: &LocationTable, param_env: ty::ParamEnv<'tcx>, - flow_inits: &mut ResultsCursor<'cx, 'tcx, MaybeInitializedPlaces<'cx, 'tcx>>, + flow_inits: &mut ResultsCursor<'cx, 'tcx, MaybeInitializedPlaces<'_, 'cx, 'tcx>>, move_data: &MoveData<'tcx>, borrow_set: &BorrowSet<'tcx>, upvars: &[&ty::CapturedPlace<'tcx>], diff --git a/compiler/rustc_borrowck/src/type_check/liveness/mod.rs b/compiler/rustc_borrowck/src/type_check/liveness/mod.rs index b777e01f7a6c2..6d6425b5f19f0 100644 --- a/compiler/rustc_borrowck/src/type_check/liveness/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/liveness/mod.rs @@ -34,7 +34,7 @@ pub(super) fn generate<'mir, 'tcx>( typeck: &mut TypeChecker<'_, 'tcx>, body: &Body<'tcx>, elements: &Rc, - flow_inits: &mut ResultsCursor<'mir, 'tcx, MaybeInitializedPlaces<'mir, 'tcx>>, + flow_inits: &mut ResultsCursor<'mir, 'tcx, MaybeInitializedPlaces<'_, 'mir, 'tcx>>, move_data: &MoveData<'tcx>, ) { debug!("liveness::generate"); diff --git a/compiler/rustc_borrowck/src/type_check/liveness/trace.rs b/compiler/rustc_borrowck/src/type_check/liveness/trace.rs index 359c4ea0eb1e2..eb86c8d06f113 100644 --- a/compiler/rustc_borrowck/src/type_check/liveness/trace.rs +++ b/compiler/rustc_borrowck/src/type_check/liveness/trace.rs @@ -43,7 +43,7 @@ pub(super) fn trace<'mir, 'tcx>( typeck: &mut TypeChecker<'_, 'tcx>, body: &Body<'tcx>, elements: &Rc, - flow_inits: &mut ResultsCursor<'mir, 'tcx, MaybeInitializedPlaces<'mir, 'tcx>>, + flow_inits: &mut ResultsCursor<'mir, 'tcx, MaybeInitializedPlaces<'_, 'mir, 'tcx>>, move_data: &MoveData<'tcx>, relevant_live_locals: Vec, boring_locals: Vec, @@ -101,7 +101,7 @@ pub(super) fn trace<'mir, 'tcx>( } /// Contextual state for the type-liveness coroutine. -struct LivenessContext<'me, 'typeck, 'flow, 'tcx> { +struct LivenessContext<'a, 'me, 'typeck, 'flow, 'tcx> { /// Current type-checker, giving us our inference context etc. typeck: &'me mut TypeChecker<'typeck, 'tcx>, @@ -119,7 +119,7 @@ struct LivenessContext<'me, 'typeck, 'flow, 'tcx> { /// Results of dataflow tracking which variables (and paths) have been /// initialized. - flow_inits: &'me mut ResultsCursor<'flow, 'tcx, MaybeInitializedPlaces<'flow, 'tcx>>, + flow_inits: &'me mut ResultsCursor<'flow, 'tcx, MaybeInitializedPlaces<'a, 'flow, 'tcx>>, /// Index indicating where each variable is assigned, used, or /// dropped. @@ -131,8 +131,8 @@ struct DropData<'tcx> { region_constraint_data: Option<&'tcx QueryRegionConstraints<'tcx>>, } -struct LivenessResults<'me, 'typeck, 'flow, 'tcx> { - cx: LivenessContext<'me, 'typeck, 'flow, 'tcx>, +struct LivenessResults<'a, 'me, 'typeck, 'flow, 'tcx> { + cx: LivenessContext<'a, 'me, 'typeck, 'flow, 'tcx>, /// Set of points that define the current local. defs: BitSet, @@ -153,8 +153,8 @@ struct LivenessResults<'me, 'typeck, 'flow, 'tcx> { stack: Vec, } -impl<'me, 'typeck, 'flow, 'tcx> LivenessResults<'me, 'typeck, 'flow, 'tcx> { - fn new(cx: LivenessContext<'me, 'typeck, 'flow, 'tcx>) -> Self { +impl<'a, 'me, 'typeck, 'flow, 'tcx> LivenessResults<'a, 'me, 'typeck, 'flow, 'tcx> { + fn new(cx: LivenessContext<'a, 'me, 'typeck, 'flow, 'tcx>) -> Self { let num_points = cx.elements.num_points(); LivenessResults { cx, @@ -507,7 +507,7 @@ impl<'me, 'typeck, 'flow, 'tcx> LivenessResults<'me, 'typeck, 'flow, 'tcx> { } } -impl<'tcx> LivenessContext<'_, '_, '_, 'tcx> { +impl<'tcx> LivenessContext<'_, '_, '_, '_, 'tcx> { /// Returns `true` if the local variable (or some part of it) is initialized at the current /// cursor position. Callers should call one of the `seek` methods immediately before to point /// the cursor to the desired location. diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 81bde14a82f4e..aa25e3adf28af 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -129,7 +129,7 @@ pub(crate) fn type_check<'mir, 'tcx>( location_table: &LocationTable, borrow_set: &BorrowSet<'tcx>, all_facts: &mut Option, - flow_inits: &mut ResultsCursor<'mir, 'tcx, MaybeInitializedPlaces<'mir, 'tcx>>, + flow_inits: &mut ResultsCursor<'mir, 'tcx, MaybeInitializedPlaces<'_, 'mir, 'tcx>>, move_data: &MoveData<'tcx>, elements: &Rc, upvars: &[&ty::CapturedPlace<'tcx>], diff --git a/compiler/rustc_mir_dataflow/src/impls/initialized.rs b/compiler/rustc_mir_dataflow/src/impls/initialized.rs index f0b79dab0c974..ffcf630b653cd 100644 --- a/compiler/rustc_mir_dataflow/src/impls/initialized.rs +++ b/compiler/rustc_mir_dataflow/src/impls/initialized.rs @@ -50,15 +50,19 @@ use crate::{lattice, AnalysisDomain, GenKill, GenKillAnalysis, MaybeReachable}; /// Similarly, at a given `drop` statement, the set-intersection /// between this data and `MaybeUninitializedPlaces` yields the set of /// places that would require a dynamic drop-flag at that statement. -pub struct MaybeInitializedPlaces<'a, 'tcx> { +pub struct MaybeInitializedPlaces<'a, 'mir, 'tcx> { tcx: TyCtxt<'tcx>, - body: &'a Body<'tcx>, + body: &'mir Body<'tcx>, mdpe: &'a MoveDataParamEnv<'tcx>, skip_unreachable_unwind: bool, } -impl<'a, 'tcx> MaybeInitializedPlaces<'a, 'tcx> { - pub fn new(tcx: TyCtxt<'tcx>, body: &'a Body<'tcx>, mdpe: &'a MoveDataParamEnv<'tcx>) -> Self { +impl<'a, 'mir, 'tcx> MaybeInitializedPlaces<'a, 'mir, 'tcx> { + pub fn new( + tcx: TyCtxt<'tcx>, + body: &'mir Body<'tcx>, + mdpe: &'a MoveDataParamEnv<'tcx>, + ) -> Self { MaybeInitializedPlaces { tcx, body, mdpe, skip_unreachable_unwind: false } } @@ -84,7 +88,7 @@ impl<'a, 'tcx> MaybeInitializedPlaces<'a, 'tcx> { } } -impl<'a, 'tcx> HasMoveData<'tcx> for MaybeInitializedPlaces<'a, 'tcx> { +impl<'a, 'mir, 'tcx> HasMoveData<'tcx> for MaybeInitializedPlaces<'a, 'mir, 'tcx> { fn move_data(&self) -> &MoveData<'tcx> { &self.mdpe.move_data } @@ -125,17 +129,21 @@ impl<'a, 'tcx> HasMoveData<'tcx> for MaybeInitializedPlaces<'a, 'tcx> { /// Similarly, at a given `drop` statement, the set-intersection /// between this data and `MaybeInitializedPlaces` yields the set of /// places that would require a dynamic drop-flag at that statement. -pub struct MaybeUninitializedPlaces<'a, 'tcx> { +pub struct MaybeUninitializedPlaces<'a, 'mir, 'tcx> { tcx: TyCtxt<'tcx>, - body: &'a Body<'tcx>, + body: &'mir Body<'tcx>, mdpe: &'a MoveDataParamEnv<'tcx>, mark_inactive_variants_as_uninit: bool, skip_unreachable_unwind: BitSet, } -impl<'a, 'tcx> MaybeUninitializedPlaces<'a, 'tcx> { - pub fn new(tcx: TyCtxt<'tcx>, body: &'a Body<'tcx>, mdpe: &'a MoveDataParamEnv<'tcx>) -> Self { +impl<'a, 'mir, 'tcx> MaybeUninitializedPlaces<'a, 'mir, 'tcx> { + pub fn new( + tcx: TyCtxt<'tcx>, + body: &'mir Body<'tcx>, + mdpe: &'a MoveDataParamEnv<'tcx>, + ) -> Self { MaybeUninitializedPlaces { tcx, body, @@ -164,7 +172,7 @@ impl<'a, 'tcx> MaybeUninitializedPlaces<'a, 'tcx> { } } -impl<'a, 'tcx> HasMoveData<'tcx> for MaybeUninitializedPlaces<'a, 'tcx> { +impl<'a, 'tcx> HasMoveData<'tcx> for MaybeUninitializedPlaces<'a, '_, 'tcx> { fn move_data(&self) -> &MoveData<'tcx> { &self.mdpe.move_data } @@ -250,24 +258,24 @@ impl<'a, 'tcx> HasMoveData<'tcx> for DefinitelyInitializedPlaces<'a, 'tcx> { /// c = S; // {a, b, c, d } /// } /// ``` -pub struct EverInitializedPlaces<'a, 'tcx> { - body: &'a Body<'tcx>, +pub struct EverInitializedPlaces<'a, 'mir, 'tcx> { + body: &'mir Body<'tcx>, mdpe: &'a MoveDataParamEnv<'tcx>, } -impl<'a, 'tcx> EverInitializedPlaces<'a, 'tcx> { - pub fn new(body: &'a Body<'tcx>, mdpe: &'a MoveDataParamEnv<'tcx>) -> Self { +impl<'a, 'mir, 'tcx> EverInitializedPlaces<'a, 'mir, 'tcx> { + pub fn new(body: &'mir Body<'tcx>, mdpe: &'a MoveDataParamEnv<'tcx>) -> Self { EverInitializedPlaces { body, mdpe } } } -impl<'a, 'tcx> HasMoveData<'tcx> for EverInitializedPlaces<'a, 'tcx> { +impl<'a, 'tcx> HasMoveData<'tcx> for EverInitializedPlaces<'a, '_, 'tcx> { fn move_data(&self) -> &MoveData<'tcx> { &self.mdpe.move_data } } -impl<'a, 'tcx> MaybeInitializedPlaces<'a, 'tcx> { +impl<'a, 'mir, 'tcx> MaybeInitializedPlaces<'a, 'mir, 'tcx> { fn update_bits( trans: &mut impl GenKill, path: MovePathIndex, @@ -280,7 +288,7 @@ impl<'a, 'tcx> MaybeInitializedPlaces<'a, 'tcx> { } } -impl<'a, 'tcx> MaybeUninitializedPlaces<'a, 'tcx> { +impl<'a, 'tcx> MaybeUninitializedPlaces<'a, '_, 'tcx> { fn update_bits( trans: &mut impl GenKill, path: MovePathIndex, @@ -306,7 +314,7 @@ impl<'a, 'tcx> DefinitelyInitializedPlaces<'a, 'tcx> { } } -impl<'tcx> AnalysisDomain<'tcx> for MaybeInitializedPlaces<'_, 'tcx> { +impl<'tcx> AnalysisDomain<'tcx> for MaybeInitializedPlaces<'_, '_, 'tcx> { /// There can be many more `MovePathIndex` than there are locals in a MIR body. /// We use a chunked bitset to avoid paying too high a memory footprint. type Domain = MaybeReachable>; @@ -328,7 +336,7 @@ impl<'tcx> AnalysisDomain<'tcx> for MaybeInitializedPlaces<'_, 'tcx> { } } -impl<'tcx> GenKillAnalysis<'tcx> for MaybeInitializedPlaces<'_, 'tcx> { +impl<'tcx> GenKillAnalysis<'tcx> for MaybeInitializedPlaces<'_, '_, 'tcx> { type Idx = MovePathIndex; fn domain_size(&self, _: &Body<'tcx>) -> usize { @@ -441,7 +449,7 @@ impl<'tcx> GenKillAnalysis<'tcx> for MaybeInitializedPlaces<'_, 'tcx> { } } -impl<'tcx> AnalysisDomain<'tcx> for MaybeUninitializedPlaces<'_, 'tcx> { +impl<'tcx> AnalysisDomain<'tcx> for MaybeUninitializedPlaces<'_, '_, 'tcx> { /// There can be many more `MovePathIndex` than there are locals in a MIR body. /// We use a chunked bitset to avoid paying too high a memory footprint. type Domain = ChunkedBitSet; @@ -465,7 +473,7 @@ impl<'tcx> AnalysisDomain<'tcx> for MaybeUninitializedPlaces<'_, 'tcx> { } } -impl<'tcx> GenKillAnalysis<'tcx> for MaybeUninitializedPlaces<'_, 'tcx> { +impl<'tcx> GenKillAnalysis<'tcx> for MaybeUninitializedPlaces<'_, '_, 'tcx> { type Idx = MovePathIndex; fn domain_size(&self, _: &Body<'tcx>) -> usize { @@ -642,7 +650,7 @@ impl<'tcx> GenKillAnalysis<'tcx> for DefinitelyInitializedPlaces<'_, 'tcx> { } } -impl<'tcx> AnalysisDomain<'tcx> for EverInitializedPlaces<'_, 'tcx> { +impl<'tcx> AnalysisDomain<'tcx> for EverInitializedPlaces<'_, '_, 'tcx> { /// There can be many more `InitIndex` than there are locals in a MIR body. /// We use a chunked bitset to avoid paying too high a memory footprint. type Domain = ChunkedBitSet; @@ -661,7 +669,7 @@ impl<'tcx> AnalysisDomain<'tcx> for EverInitializedPlaces<'_, 'tcx> { } } -impl<'tcx> GenKillAnalysis<'tcx> for EverInitializedPlaces<'_, 'tcx> { +impl<'tcx> GenKillAnalysis<'tcx> for EverInitializedPlaces<'_, '_, 'tcx> { type Idx = InitIndex; fn domain_size(&self, _: &Body<'tcx>) -> usize { diff --git a/compiler/rustc_mir_transform/src/elaborate_drops.rs b/compiler/rustc_mir_transform/src/elaborate_drops.rs index 665b2260294a3..fbbb8c5e47245 100644 --- a/compiler/rustc_mir_transform/src/elaborate_drops.rs +++ b/compiler/rustc_mir_transform/src/elaborate_drops.rs @@ -97,7 +97,7 @@ impl<'tcx> MirPass<'tcx> for ElaborateDrops { #[instrument(level = "trace", skip(body, flow_inits), ret)] fn compute_dead_unwinds<'mir, 'tcx>( body: &'mir Body<'tcx>, - flow_inits: &mut ResultsCursor<'mir, 'tcx, MaybeInitializedPlaces<'mir, 'tcx>>, + flow_inits: &mut ResultsCursor<'mir, 'tcx, MaybeInitializedPlaces<'_, 'mir, 'tcx>>, ) -> BitSet { // We only need to do this pass once, because unwind edges can only // reach cleanup blocks, which can't have unwind edges themselves. @@ -118,12 +118,12 @@ fn compute_dead_unwinds<'mir, 'tcx>( dead_unwinds } -struct InitializationData<'mir, 'tcx> { - inits: ResultsCursor<'mir, 'tcx, MaybeInitializedPlaces<'mir, 'tcx>>, - uninits: ResultsCursor<'mir, 'tcx, MaybeUninitializedPlaces<'mir, 'tcx>>, +struct InitializationData<'a, 'mir, 'tcx> { + inits: ResultsCursor<'mir, 'tcx, MaybeInitializedPlaces<'a, 'mir, 'tcx>>, + uninits: ResultsCursor<'mir, 'tcx, MaybeUninitializedPlaces<'a, 'mir, 'tcx>>, } -impl InitializationData<'_, '_> { +impl InitializationData<'_, '_, '_> { fn seek_before(&mut self, loc: Location) { self.inits.seek_before_primary_effect(loc); self.uninits.seek_before_primary_effect(loc); @@ -134,17 +134,17 @@ impl InitializationData<'_, '_> { } } -struct Elaborator<'a, 'b, 'tcx> { - ctxt: &'a mut ElaborateDropsCtxt<'b, 'tcx>, +struct Elaborator<'a, 'b, 'mir, 'tcx> { + ctxt: &'a mut ElaborateDropsCtxt<'b, 'mir, 'tcx>, } -impl fmt::Debug for Elaborator<'_, '_, '_> { +impl fmt::Debug for Elaborator<'_, '_, '_, '_> { fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result { Ok(()) } } -impl<'a, 'tcx> DropElaborator<'a, 'tcx> for Elaborator<'a, '_, 'tcx> { +impl<'a, 'tcx> DropElaborator<'a, 'tcx> for Elaborator<'a, '_, '_, 'tcx> { type Path = MovePathIndex; fn patch(&mut self) -> &mut MirPatch<'tcx> { @@ -238,16 +238,16 @@ impl<'a, 'tcx> DropElaborator<'a, 'tcx> for Elaborator<'a, '_, 'tcx> { } } -struct ElaborateDropsCtxt<'a, 'tcx> { +struct ElaborateDropsCtxt<'a, 'mir, 'tcx> { tcx: TyCtxt<'tcx>, - body: &'a Body<'tcx>, + body: &'mir Body<'tcx>, env: &'a MoveDataParamEnv<'tcx>, - init_data: InitializationData<'a, 'tcx>, + init_data: InitializationData<'a, 'mir, 'tcx>, drop_flags: IndexVec>, patch: MirPatch<'tcx>, } -impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> { +impl<'b, 'mir, 'tcx> ElaborateDropsCtxt<'b, 'mir, 'tcx> { fn move_data(&self) -> &'b MoveData<'tcx> { &self.env.move_data } From ef559199efc3f9d411353140f46fdcec4f0bab04 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 25 Jun 2024 08:06:34 +0000 Subject: [PATCH 324/892] Restrict diagnostic context lifetime of mir borrowck to InferCtxt instead of TyCtxt --- .../rustc_borrowck/src/borrowck_errors.rs | 50 +++++++++---------- .../src/diagnostics/conflict_errors.rs | 24 ++++----- .../rustc_borrowck/src/diagnostics/mod.rs | 4 +- .../src/diagnostics/move_errors.rs | 6 +-- .../src/diagnostics/mutability_errors.rs | 10 ++-- .../src/diagnostics/region_errors.rs | 8 +-- compiler/rustc_borrowck/src/lib.rs | 38 +++++++------- compiler/rustc_borrowck/src/nll.rs | 10 ++-- 8 files changed, 75 insertions(+), 75 deletions(-) diff --git a/compiler/rustc_borrowck/src/borrowck_errors.rs b/compiler/rustc_borrowck/src/borrowck_errors.rs index f26f8711dd40b..604feeb47feaf 100644 --- a/compiler/rustc_borrowck/src/borrowck_errors.rs +++ b/compiler/rustc_borrowck/src/borrowck_errors.rs @@ -6,8 +6,8 @@ use rustc_middle::span_bug; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_span::Span; -impl<'tcx> crate::MirBorrowckCtxt<'_, '_, '_, 'tcx> { - pub fn dcx(&self) -> DiagCtxtHandle<'tcx> { +impl<'cx, 'tcx> crate::MirBorrowckCtxt<'_, '_, 'cx, 'tcx> { + pub fn dcx(&self) -> DiagCtxtHandle<'cx> { self.infcx.dcx() } @@ -18,7 +18,7 @@ impl<'tcx> crate::MirBorrowckCtxt<'_, '_, '_, 'tcx> { place: &str, borrow_place: &str, value_place: &str, - ) -> Diag<'tcx> { + ) -> Diag<'cx> { self.dcx().create_err(crate::session_diagnostics::MoveBorrow { place, span, @@ -34,7 +34,7 @@ impl<'tcx> crate::MirBorrowckCtxt<'_, '_, '_, 'tcx> { desc: &str, borrow_span: Span, borrow_desc: &str, - ) -> Diag<'tcx> { + ) -> Diag<'cx> { struct_span_code_err!( self.dcx(), span, @@ -54,7 +54,7 @@ impl<'tcx> crate::MirBorrowckCtxt<'_, '_, '_, 'tcx> { old_loan_span: Span, old_opt_via: &str, old_load_end_span: Option, - ) -> Diag<'tcx> { + ) -> Diag<'cx> { let via = |msg: &str| if msg.is_empty() { "".to_string() } else { format!(" (via {msg})") }; let mut err = struct_span_code_err!( self.dcx(), @@ -101,7 +101,7 @@ impl<'tcx> crate::MirBorrowckCtxt<'_, '_, '_, 'tcx> { desc: &str, old_loan_span: Span, old_load_end_span: Option, - ) -> Diag<'tcx> { + ) -> Diag<'cx> { let mut err = struct_span_code_err!( self.dcx(), new_loan_span, @@ -134,7 +134,7 @@ impl<'tcx> crate::MirBorrowckCtxt<'_, '_, '_, 'tcx> { noun_old: &str, old_opt_via: &str, previous_end_span: Option, - ) -> Diag<'tcx> { + ) -> Diag<'cx> { let mut err = struct_span_code_err!( self.dcx(), new_loan_span, @@ -166,7 +166,7 @@ impl<'tcx> crate::MirBorrowckCtxt<'_, '_, '_, 'tcx> { old_opt_via: &str, previous_end_span: Option, second_borrow_desc: &str, - ) -> Diag<'tcx> { + ) -> Diag<'cx> { let mut err = struct_span_code_err!( self.dcx(), new_loan_span, @@ -198,7 +198,7 @@ impl<'tcx> crate::MirBorrowckCtxt<'_, '_, '_, 'tcx> { kind_old: &str, msg_old: &str, old_load_end_span: Option, - ) -> Diag<'tcx> { + ) -> Diag<'cx> { let via = |msg: &str| if msg.is_empty() { "".to_string() } else { format!(" (via {msg})") }; let mut err = struct_span_code_err!( self.dcx(), @@ -239,7 +239,7 @@ impl<'tcx> crate::MirBorrowckCtxt<'_, '_, '_, 'tcx> { span: Span, borrow_span: Span, desc: &str, - ) -> Diag<'tcx> { + ) -> Diag<'cx> { struct_span_code_err!( self.dcx(), span, @@ -256,12 +256,12 @@ impl<'tcx> crate::MirBorrowckCtxt<'_, '_, '_, 'tcx> { span: Span, desc: &str, is_arg: bool, - ) -> Diag<'tcx> { + ) -> Diag<'cx> { let msg = if is_arg { "to immutable argument" } else { "twice to immutable variable" }; struct_span_code_err!(self.dcx(), span, E0384, "cannot assign {} {}", msg, desc) } - pub(crate) fn cannot_assign(&self, span: Span, desc: &str) -> Diag<'tcx> { + pub(crate) fn cannot_assign(&self, span: Span, desc: &str) -> Diag<'cx> { struct_span_code_err!(self.dcx(), span, E0594, "cannot assign to {}", desc) } @@ -269,7 +269,7 @@ impl<'tcx> crate::MirBorrowckCtxt<'_, '_, '_, 'tcx> { &self, move_from_span: Span, move_from_desc: &str, - ) -> Diag<'tcx> { + ) -> Diag<'cx> { struct_span_code_err!( self.dcx(), move_from_span, @@ -287,7 +287,7 @@ impl<'tcx> crate::MirBorrowckCtxt<'_, '_, '_, 'tcx> { move_from_span: Span, ty: Ty<'_>, is_index: Option, - ) -> Diag<'tcx> { + ) -> Diag<'cx> { let type_name = match (&ty.kind(), is_index) { (&ty::Array(_, _), Some(true)) | (&ty::Array(_, _), None) => "array", (&ty::Slice(_), _) => "slice", @@ -308,7 +308,7 @@ impl<'tcx> crate::MirBorrowckCtxt<'_, '_, '_, 'tcx> { &self, move_from_span: Span, container_ty: Ty<'_>, - ) -> Diag<'tcx> { + ) -> Diag<'cx> { struct_span_code_err!( self.dcx(), move_from_span, @@ -325,7 +325,7 @@ impl<'tcx> crate::MirBorrowckCtxt<'_, '_, '_, 'tcx> { verb: &str, optional_adverb_for_moved: &str, moved_path: Option, - ) -> Diag<'tcx> { + ) -> Diag<'cx> { let moved_path = moved_path.map(|mp| format!(": `{mp}`")).unwrap_or_default(); struct_span_code_err!( @@ -344,7 +344,7 @@ impl<'tcx> crate::MirBorrowckCtxt<'_, '_, '_, 'tcx> { span: Span, path: &str, reason: &str, - ) -> Diag<'tcx> { + ) -> Diag<'cx> { struct_span_code_err!( self.dcx(), span, @@ -362,7 +362,7 @@ impl<'tcx> crate::MirBorrowckCtxt<'_, '_, '_, 'tcx> { immutable_place: &str, immutable_section: &str, action: &str, - ) -> Diag<'tcx> { + ) -> Diag<'cx> { struct_span_code_err!( self.dcx(), mutate_span, @@ -380,7 +380,7 @@ impl<'tcx> crate::MirBorrowckCtxt<'_, '_, '_, 'tcx> { &self, span: Span, yield_span: Span, - ) -> Diag<'tcx> { + ) -> Diag<'cx> { let coroutine_kind = self.body.coroutine.as_ref().unwrap().coroutine_kind; struct_span_code_err!( self.dcx(), @@ -391,7 +391,7 @@ impl<'tcx> crate::MirBorrowckCtxt<'_, '_, '_, 'tcx> { .with_span_label(yield_span, "possible yield occurs here") } - pub(crate) fn cannot_borrow_across_destructor(&self, borrow_span: Span) -> Diag<'tcx> { + pub(crate) fn cannot_borrow_across_destructor(&self, borrow_span: Span) -> Diag<'cx> { struct_span_code_err!( self.dcx(), borrow_span, @@ -400,7 +400,7 @@ impl<'tcx> crate::MirBorrowckCtxt<'_, '_, '_, 'tcx> { ) } - pub(crate) fn path_does_not_live_long_enough(&self, span: Span, path: &str) -> Diag<'tcx> { + pub(crate) fn path_does_not_live_long_enough(&self, span: Span, path: &str) -> Diag<'cx> { struct_span_code_err!(self.dcx(), span, E0597, "{} does not live long enough", path,) } @@ -410,7 +410,7 @@ impl<'tcx> crate::MirBorrowckCtxt<'_, '_, '_, 'tcx> { return_kind: &str, reference_desc: &str, path_desc: &str, - ) -> Diag<'tcx> { + ) -> Diag<'cx> { struct_span_code_err!( self.dcx(), span, @@ -433,7 +433,7 @@ impl<'tcx> crate::MirBorrowckCtxt<'_, '_, '_, 'tcx> { borrowed_path: &str, capture_span: Span, scope: &str, - ) -> Diag<'tcx> { + ) -> Diag<'cx> { struct_span_code_err!( self.dcx(), closure_span, @@ -445,7 +445,7 @@ impl<'tcx> crate::MirBorrowckCtxt<'_, '_, '_, 'tcx> { .with_span_label(closure_span, format!("may outlive borrowed value {borrowed_path}")) } - pub(crate) fn thread_local_value_does_not_live_long_enough(&self, span: Span) -> Diag<'tcx> { + pub(crate) fn thread_local_value_does_not_live_long_enough(&self, span: Span) -> Diag<'cx> { struct_span_code_err!( self.dcx(), span, @@ -454,7 +454,7 @@ impl<'tcx> crate::MirBorrowckCtxt<'_, '_, '_, 'tcx> { ) } - pub(crate) fn temporary_value_borrowed_for_too_long(&self, span: Span) -> Diag<'tcx> { + pub(crate) fn temporary_value_borrowed_for_too_long(&self, span: Span) -> Diag<'cx> { struct_span_code_err!(self.dcx(), span, E0716, "temporary value dropped while borrowed",) } } diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index 1cc7fee718e87..74ebfc54182b6 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -73,7 +73,7 @@ enum StorageDeadOrDrop<'tcx> { Destructor(Ty<'tcx>), } -impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> { +impl<'cx, 'tcx> MirBorrowckCtxt<'_, '_, 'cx, 'tcx> { pub(crate) fn report_use_of_moved_or_uninitialized( &mut self, location: Location, @@ -341,7 +341,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> { fn suggest_ref_or_clone( &self, mpi: MovePathIndex, - err: &mut Diag<'tcx>, + err: &mut Diag<'cx>, in_pattern: &mut bool, move_spans: UseSpans<'tcx>, ) { @@ -517,7 +517,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> { desired_action: InitializationRequiringAction, span: Span, use_spans: UseSpans<'tcx>, - ) -> Diag<'tcx> { + ) -> Diag<'cx> { // We need all statements in the body where the binding was assigned to later find all // the branching code paths where the binding *wasn't* assigned to. let inits = &self.move_data.init_path_map[mpi]; @@ -1441,7 +1441,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> { location: Location, (place, _span): (Place<'tcx>, Span), borrow: &BorrowData<'tcx>, - ) -> Diag<'tcx> { + ) -> Diag<'cx> { let borrow_spans = self.retrieve_borrow_spans(borrow); let borrow_span = borrow_spans.args_or_use(); @@ -1491,7 +1491,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> { (place, span): (Place<'tcx>, Span), gen_borrow_kind: BorrowKind, issued_borrow: &BorrowData<'tcx>, - ) -> Diag<'tcx> { + ) -> Diag<'cx> { let issued_spans = self.retrieve_borrow_spans(issued_borrow); let issued_span = issued_spans.args_or_use(); @@ -1782,7 +1782,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> { err } - fn suggest_copy_for_type_in_cloned_ref(&self, err: &mut Diag<'tcx>, place: Place<'tcx>) { + fn suggest_copy_for_type_in_cloned_ref(&self, err: &mut Diag<'cx>, place: Place<'tcx>) { let tcx = self.infcx.tcx; let hir = tcx.hir(); let Some(body_id) = tcx.hir_node(self.mir_hir_id()).body_id() else { return }; @@ -2841,7 +2841,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> { drop_span: Span, borrow_spans: UseSpans<'tcx>, explanation: BorrowExplanation<'tcx>, - ) -> Diag<'tcx> { + ) -> Diag<'cx> { debug!( "report_local_value_does_not_live_long_enough(\ {:?}, {:?}, {:?}, {:?}, {:?}\ @@ -3016,7 +3016,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> { &self, drop_span: Span, borrow_span: Span, - ) -> Diag<'tcx> { + ) -> Diag<'cx> { debug!( "report_thread_local_value_does_not_live_long_enough(\ {:?}, {:?}\ @@ -3041,7 +3041,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> { borrow_spans: UseSpans<'tcx>, proper_span: Span, explanation: BorrowExplanation<'tcx>, - ) -> Diag<'tcx> { + ) -> Diag<'cx> { if let BorrowExplanation::MustBeValidFor { category, span, from_closure: false, .. } = explanation { @@ -3206,7 +3206,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> { return_span: Span, category: ConstraintCategory<'tcx>, opt_place_desc: Option<&String>, - ) -> Result<(), Diag<'tcx>> { + ) -> Result<(), Diag<'cx>> { let return_kind = match category { ConstraintCategory::Return(_) => "return", ConstraintCategory::Yield => "yield", @@ -3299,7 +3299,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> { constraint_span: Span, captured_var: &str, scope: &str, - ) -> Diag<'tcx> { + ) -> Diag<'cx> { let tcx = self.infcx.tcx; let args_span = use_span.args_or_use(); @@ -3411,7 +3411,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> { upvar_span: Span, upvar_name: Symbol, escape_span: Span, - ) -> Diag<'tcx> { + ) -> Diag<'cx> { let tcx = self.infcx.tcx; let escapes_from = tcx.def_descr(self.mir_def_id().to_def_id()); diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs index 842ed38f1e294..3bc7083976e44 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mod.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs @@ -69,7 +69,7 @@ pub(super) struct DescribePlaceOpt { pub(super) struct IncludingTupleField(pub(super) bool); -impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> { +impl<'cx, 'tcx> MirBorrowckCtxt<'_, '_, 'cx, 'tcx> { /// Adds a suggestion when a closure is invoked twice with a moved variable or when a closure /// is moved after being invoked. /// @@ -86,7 +86,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> { &self, location: Location, place: PlaceRef<'tcx>, - diag: &mut Diag<'_>, + diag: &mut Diag<'cx>, ) -> bool { debug!("add_moved_or_invoked_closure_note: location={:?} place={:?}", location, place); let mut target = place.local_or_deref_local(); diff --git a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs index 12fa4c4f5ee05..40a6a65649a35 100644 --- a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs @@ -93,7 +93,7 @@ enum GroupedMoveError<'tcx> { }, } -impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> { +impl<'cx, 'tcx> MirBorrowckCtxt<'_, '_, 'cx, 'tcx> { pub(crate) fn report_move_errors(&mut self) { let grouped_errors = self.group_move_errors(); for error in grouped_errors { @@ -291,7 +291,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> { self.buffer_error(err); } - fn report_cannot_move_from_static(&mut self, place: Place<'tcx>, span: Span) -> Diag<'tcx> { + fn report_cannot_move_from_static(&mut self, place: Place<'tcx>, span: Span) -> Diag<'cx> { let description = if place.projection.len() == 1 { format!("static item {}", self.describe_any_place(place.as_ref())) } else { @@ -428,7 +428,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> { deref_target_place: Place<'tcx>, span: Span, use_spans: Option>, - ) -> Diag<'tcx> { + ) -> Diag<'cx> { let tcx = self.infcx.tcx; // Inspect the type of the content behind the // borrow to provide feedback about why this diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs index 93fac3181ba4b..6d92f0cdd988a 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs @@ -30,7 +30,7 @@ pub(crate) enum AccessKind { Mutate, } -impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> { +impl<'cx, 'tcx> MirBorrowckCtxt<'_, '_, 'cx, 'tcx> { pub(crate) fn report_mutability_error( &mut self, access_place: Place<'tcx>, @@ -541,7 +541,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> { } /// Suggest `map[k] = v` => `map.insert(k, v)` and the like. - fn suggest_map_index_mut_alternatives(&self, ty: Ty<'tcx>, err: &mut Diag<'tcx>, span: Span) { + fn suggest_map_index_mut_alternatives(&self, ty: Ty<'tcx>, err: &mut Diag<'cx>, span: Span) { let Some(adt) = ty.ty_adt_def() else { return }; let did = adt.did(); if self.infcx.tcx.is_diagnostic_item(sym::HashMap, did) @@ -550,13 +550,13 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> { /// Walks through the HIR, looking for the corresponding span for this error. /// When it finds it, see if it corresponds to assignment operator whose LHS /// is an index expr. - struct SuggestIndexOperatorAlternativeVisitor<'a, 'tcx> { + struct SuggestIndexOperatorAlternativeVisitor<'a, 'cx, 'tcx> { assign_span: Span, - err: &'a mut Diag<'tcx>, + err: &'a mut Diag<'cx>, ty: Ty<'tcx>, suggested: bool, } - impl<'a, 'tcx> Visitor<'tcx> for SuggestIndexOperatorAlternativeVisitor<'a, 'tcx> { + impl<'a, 'cx, 'tcx> Visitor<'tcx> for SuggestIndexOperatorAlternativeVisitor<'a, 'cx, 'tcx> { fn visit_stmt(&mut self, stmt: &'tcx hir::Stmt<'tcx>) { hir::intravisit::walk_stmt(self, stmt); let expr = match stmt.kind { diff --git a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs index db78edc45b9de..bb3542287d5e0 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs @@ -160,7 +160,7 @@ pub struct ErrorConstraintInfo<'tcx> { pub(super) span: Span, } -impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> { +impl<'cx, 'tcx> MirBorrowckCtxt<'_, '_, 'cx, 'tcx> { /// Converts a region inference variable into a `ty::Region` that /// we can use for error reporting. If `r` is universally bound, /// then we use the name that we have on record for it. If `r` is @@ -589,7 +589,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> { &self, errci: &ErrorConstraintInfo<'tcx>, kind: ReturnConstraint, - ) -> Diag<'tcx> { + ) -> Diag<'cx> { let ErrorConstraintInfo { outlived_fr, span, .. } = errci; let mut output_ty = self.regioncx.universal_regions().unnormalized_output_ty; @@ -658,7 +658,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> { /// | ^^^^^^^^^^ `x` escapes the function body here /// ``` #[instrument(level = "debug", skip(self))] - fn report_escaping_data_error(&self, errci: &ErrorConstraintInfo<'tcx>) -> Diag<'tcx> { + fn report_escaping_data_error(&self, errci: &ErrorConstraintInfo<'tcx>) -> Diag<'cx> { let ErrorConstraintInfo { span, category, .. } = errci; let fr_name_and_span = self.regioncx.get_var_name_and_span_for_region( @@ -767,7 +767,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> { /// | is returning data with lifetime `'b` /// ``` #[allow(rustc::diagnostic_outside_of_impl)] // FIXME - fn report_general_error(&self, errci: &ErrorConstraintInfo<'tcx>) -> Diag<'tcx> { + fn report_general_error(&self, errci: &ErrorConstraintInfo<'tcx>) -> Diag<'cx> { let ErrorConstraintInfo { fr, fr_is_local, diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index 0bdae081b94f1..8aea8ae188898 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -596,7 +596,7 @@ struct MirBorrowckCtxt<'a, 'mir, 'cx, 'tcx> { /// Results of Polonius analysis. polonius_output: Option>, - diags: diags::BorrowckDiags<'tcx>, + diags: diags::BorrowckDiags<'cx, 'tcx>, move_errors: Vec>, } @@ -2428,12 +2428,12 @@ mod diags { use super::*; - enum BufferedDiag<'tcx> { - Error(Diag<'tcx>), - NonError(Diag<'tcx, ()>), + enum BufferedDiag<'cx> { + Error(Diag<'cx>), + NonError(Diag<'cx, ()>), } - impl<'tcx> BufferedDiag<'tcx> { + impl<'cx> BufferedDiag<'cx> { fn sort_span(&self) -> Span { match self { BufferedDiag::Error(diag) => diag.sort_span, @@ -2442,7 +2442,7 @@ mod diags { } } - pub struct BorrowckDiags<'tcx> { + pub struct BorrowckDiags<'cx, 'tcx> { /// This field keeps track of move errors that are to be reported for given move indices. /// /// There are situations where many errors can be reported for a single move out (see @@ -2457,15 +2457,15 @@ mod diags { /// `BTreeMap` is used to preserve the order of insertions when iterating. This is necessary /// when errors in the map are being re-added to the error buffer so that errors with the /// same primary span come out in a consistent order. - buffered_move_errors: BTreeMap, (PlaceRef<'tcx>, Diag<'tcx>)>, + buffered_move_errors: BTreeMap, (PlaceRef<'tcx>, Diag<'cx>)>, - buffered_mut_errors: FxIndexMap, usize)>, + buffered_mut_errors: FxIndexMap, usize)>, /// Buffer of diagnostics to be reported. A mixture of error and non-error diagnostics. - buffered_diags: Vec>, + buffered_diags: Vec>, } - impl<'tcx> BorrowckDiags<'tcx> { + impl<'cx, 'tcx> BorrowckDiags<'cx, 'tcx> { pub fn new() -> Self { BorrowckDiags { buffered_move_errors: BTreeMap::new(), @@ -2474,28 +2474,28 @@ mod diags { } } - pub fn buffer_error(&mut self, diag: Diag<'tcx>) { + pub fn buffer_error(&mut self, diag: Diag<'cx>) { self.buffered_diags.push(BufferedDiag::Error(diag)); } - pub fn buffer_non_error(&mut self, diag: Diag<'tcx, ()>) { + pub fn buffer_non_error(&mut self, diag: Diag<'cx, ()>) { self.buffered_diags.push(BufferedDiag::NonError(diag)); } } - impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> { - pub fn buffer_error(&mut self, diag: Diag<'tcx>) { + impl<'cx, 'tcx> MirBorrowckCtxt<'_, '_, 'cx, 'tcx> { + pub fn buffer_error(&mut self, diag: Diag<'cx>) { self.diags.buffer_error(diag); } - pub fn buffer_non_error(&mut self, diag: Diag<'tcx, ()>) { + pub fn buffer_non_error(&mut self, diag: Diag<'cx, ()>) { self.diags.buffer_non_error(diag); } pub fn buffer_move_error( &mut self, move_out_indices: Vec, - place_and_err: (PlaceRef<'tcx>, Diag<'tcx>), + place_and_err: (PlaceRef<'tcx>, Diag<'cx>), ) -> bool { if let Some((_, diag)) = self.diags.buffered_move_errors.insert(move_out_indices, place_and_err) @@ -2508,12 +2508,12 @@ mod diags { } } - pub fn get_buffered_mut_error(&mut self, span: Span) -> Option<(Diag<'tcx>, usize)> { + pub fn get_buffered_mut_error(&mut self, span: Span) -> Option<(Diag<'cx>, usize)> { // FIXME(#120456) - is `swap_remove` correct? self.diags.buffered_mut_errors.swap_remove(&span) } - pub fn buffer_mut_error(&mut self, span: Span, diag: Diag<'tcx>, count: usize) { + pub fn buffer_mut_error(&mut self, span: Span, diag: Diag<'cx>, count: usize) { self.diags.buffered_mut_errors.insert(span, (diag, count)); } @@ -2554,7 +2554,7 @@ mod diags { pub fn has_move_error( &self, move_out_indices: &[MoveOutIndex], - ) -> Option<&(PlaceRef<'tcx>, Diag<'tcx>)> { + ) -> Option<&(PlaceRef<'tcx>, Diag<'cx>)> { self.diags.buffered_move_errors.get(move_out_indices) } } diff --git a/compiler/rustc_borrowck/src/nll.rs b/compiler/rustc_borrowck/src/nll.rs index 4ab06d9c4d09e..2ffa9ba5b4d32 100644 --- a/compiler/rustc_borrowck/src/nll.rs +++ b/compiler/rustc_borrowck/src/nll.rs @@ -262,13 +262,13 @@ pub(super) fn dump_mir_results<'tcx>( #[allow(rustc::diagnostic_outside_of_impl)] #[allow(rustc::untranslatable_diagnostic)] -pub(super) fn dump_annotation<'tcx>( - infcx: &BorrowckInferCtxt<'tcx>, +pub(super) fn dump_annotation<'tcx, 'cx>( + infcx: &'cx BorrowckInferCtxt<'tcx>, body: &Body<'tcx>, regioncx: &RegionInferenceContext<'tcx>, closure_region_requirements: &Option>, opaque_type_values: &FxIndexMap>, - diags: &mut crate::diags::BorrowckDiags<'tcx>, + diags: &mut crate::diags::BorrowckDiags<'cx, 'tcx>, ) { let tcx = infcx.tcx; let base_def_id = tcx.typeck_root_def_id(body.source.def_id()); @@ -285,7 +285,7 @@ pub(super) fn dump_annotation<'tcx>( let def_span = tcx.def_span(body.source.def_id()); let mut err = if let Some(closure_region_requirements) = closure_region_requirements { - let mut err = tcx.dcx().struct_span_note(def_span, "external requirements"); + let mut err = infcx.dcx().struct_span_note(def_span, "external requirements"); regioncx.annotate(tcx, &mut err); @@ -304,7 +304,7 @@ pub(super) fn dump_annotation<'tcx>( err } else { - let mut err = tcx.dcx().struct_span_note(def_span, "no external requirements"); + let mut err = infcx.dcx().struct_span_note(def_span, "no external requirements"); regioncx.annotate(tcx, &mut err); err From f3d9523a2e0d9c2a60e713decd32a59c347e113f Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 25 Jun 2024 08:10:04 +0000 Subject: [PATCH 325/892] Restrict diagnostic context lifetime of FnCtxt to InferCtxt instead of TyCtxt --- compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs | 2 +- compiler/rustc_hir_typeck/src/pat.rs | 4 ++-- compiler/rustc_infer/src/infer/mod.rs | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs index c0d604779677b..ad8eb7c30826c 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs @@ -144,7 +144,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } - pub(crate) fn dcx(&self) -> DiagCtxtHandle<'tcx> { + pub(crate) fn dcx(&self) -> DiagCtxtHandle<'a> { self.infcx.dcx() } diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index aaf3d3ec34d01..208930208ed83 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -1881,7 +1881,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { &self, pat: &Pat<'_>, fields: &'tcx [hir::PatField<'tcx>], - ) -> Diag<'tcx> { + ) -> Diag<'a> { let mut err = self .dcx() .struct_span_err(pat.span, "pattern requires `..` due to inaccessible fields"); @@ -1973,7 +1973,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { unmentioned_fields: &[(&ty::FieldDef, Ident)], have_inaccessible_fields: bool, fields: &'tcx [hir::PatField<'tcx>], - ) -> Diag<'tcx> { + ) -> Diag<'a> { let inaccessible = if have_inaccessible_fields { " and inaccessible fields" } else { "" }; let field_names = if let [(_, field)] = unmentioned_fields { format!("field `{field}`{inaccessible}") diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index a3cf588da1c02..78d42942de47c 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -1607,7 +1607,7 @@ impl<'tcx> InferCtxt<'tcx> { } } -impl<'tcx> TypeErrCtxt<'_, 'tcx> { +impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { // [Note-Type-error-reporting] // An invariant is that anytime the expected or actual type is Error (the special // error type, meaning that an error occurred when typechecking this expression), @@ -1623,9 +1623,9 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { sp: Span, mk_diag: M, actual_ty: Ty<'tcx>, - ) -> Diag<'tcx> + ) -> Diag<'a> where - M: FnOnce(String) -> Diag<'tcx>, + M: FnOnce(String) -> Diag<'a>, { let actual_ty = self.resolve_vars_if_possible(actual_ty); debug!("type_error_struct_with_diag({:?}, {:?})", sp, actual_ty); From 79ac8982ca24e25b592b06ef636050f5a5a81bde Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 25 Jun 2024 08:14:35 +0000 Subject: [PATCH 326/892] Restrict diagnostic context lifetime of TypeErrCtxt to InferCtxt instead of TyCtxt --- .../src/infer/error_reporting/mod.rs | 2 +- .../infer/error_reporting/need_type_info.rs | 4 ++-- .../src/infer/error_reporting/note.rs | 6 +++--- .../src/traits/error_reporting/suggestions.rs | 10 +++++----- .../error_reporting/type_err_ctxt_ext.rs | 18 +++++++++--------- 5 files changed, 20 insertions(+), 20 deletions(-) diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index 227691d099434..503d3424e7481 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -139,7 +139,7 @@ pub struct TypeErrCtxt<'a, 'tcx> { } impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { - pub fn dcx(&self) -> DiagCtxtHandle<'tcx> { + pub fn dcx(&self) -> DiagCtxtHandle<'a> { self.infcx.dcx() } diff --git a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs index d7349abc44c24..ba5e3ae8a930c 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs @@ -436,7 +436,7 @@ impl<'tcx> InferCtxt<'tcx> { } } -impl<'tcx> TypeErrCtxt<'_, 'tcx> { +impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { #[instrument(level = "debug", skip(self, error_code))] pub fn emit_inference_failure_err( &self, @@ -445,7 +445,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { arg: GenericArg<'tcx>, error_code: TypeAnnotationNeeded, should_label_span: bool, - ) -> Diag<'tcx> { + ) -> Diag<'a> { let arg = self.resolve_vars_if_possible(arg); let arg_data = self.extract_inference_diagnostics_data(arg, None); diff --git a/compiler/rustc_infer/src/infer/error_reporting/note.rs b/compiler/rustc_infer/src/infer/error_reporting/note.rs index 8fd19563c3057..e37b0b83f4d00 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/note.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/note.rs @@ -14,7 +14,7 @@ use rustc_span::symbol::kw; use super::ObligationCauseAsDiagArg; -impl<'tcx> TypeErrCtxt<'_, 'tcx> { +impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { pub(super) fn note_region_origin(&self, err: &mut Diag<'_>, origin: &SubregionOrigin<'tcx>) { match *origin { infer::Subtype(ref trace) => RegionOriginNote::WithRequirement { @@ -79,7 +79,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { origin: SubregionOrigin<'tcx>, sub: Region<'tcx>, sup: Region<'tcx>, - ) -> Diag<'tcx> { + ) -> Diag<'a> { let mut err = match origin { infer::Subtype(box trace) => { let terr = TypeError::RegionsDoesNotOutlive(sup, sub); @@ -378,7 +378,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { placeholder_origin: SubregionOrigin<'tcx>, sub: Region<'tcx>, sup: Region<'tcx>, - ) -> Diag<'tcx> { + ) -> Diag<'a> { // I can't think how to do better than this right now. -nikomatsakis debug!(?placeholder_origin, ?sub, ?sup, "report_placeholder_failure"); match placeholder_origin { diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index f4a026c0367f4..5753ac91709a4 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -241,8 +241,8 @@ pub fn suggest_restriction<'tcx, G: EmissionGuarantee>( } } -#[extension(pub trait TypeErrCtxtExt<'tcx>)] -impl<'tcx> TypeErrCtxt<'_, 'tcx> { +#[extension(pub trait TypeErrCtxtExt<'a, 'tcx>)] +impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { fn suggest_restricting_param_bound( &self, err: &mut Diag<'_>, @@ -1845,7 +1845,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { fn point_at_returns_when_relevant( &self, - err: &mut Diag<'tcx>, + err: &mut Diag<'_>, obligation: &PredicateObligation<'tcx>, ) { match obligation.cause.code().peel_derives() { @@ -1884,7 +1884,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { cause: &ObligationCauseCode<'tcx>, found_node: Option>, param_env: ty::ParamEnv<'tcx>, - ) -> Diag<'tcx> { + ) -> Diag<'a> { pub(crate) fn build_fn_sig_ty<'tcx>( infcx: &InferCtxt<'tcx>, trait_ref: ty::TraitRef<'tcx>, @@ -2104,7 +2104,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { fn note_conflicting_closure_bounds( &self, cause: &ObligationCauseCode<'tcx>, - err: &mut Diag<'tcx>, + err: &mut Diag<'_>, ) { // First, look for an `WhereClauseInExpr`, which means we can get // the uninstantiated predicate list of the called function. And check diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs index d3096cf4b52ce..cccb78bec9d39 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs @@ -82,8 +82,8 @@ pub fn suggest_new_overflow_limit<'tcx, G: EmissionGuarantee>( )); } -#[extension(pub trait TypeErrCtxtExt<'tcx>)] -impl<'tcx> TypeErrCtxt<'_, 'tcx> { +#[extension(pub trait TypeErrCtxtExt<'a, 'tcx>)] +impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { fn report_fulfillment_errors( &self, mut errors: Vec>, @@ -228,7 +228,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { cause: OverflowCause<'tcx>, span: Span, suggest_increasing_limit: bool, - ) -> Diag<'tcx> { + ) -> Diag<'a> { fn with_short_path<'tcx, T>(tcx: TyCtxt<'tcx>, value: T) -> String where T: fmt::Display + Print<'tcx, FmtPrinter<'tcx, 'tcx>>, @@ -1351,7 +1351,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { &self, ty: Ty<'tcx>, obligation: &PredicateObligation<'tcx>, - ) -> Diag<'tcx> { + ) -> Diag<'a> { let span = obligation.cause.span; let mut diag = match ty.kind() { @@ -1445,8 +1445,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { } } -#[extension(pub(super) trait InferCtxtPrivExt<'tcx>)] -impl<'tcx> TypeErrCtxt<'_, 'tcx> { +#[extension(pub(super) trait InferCtxtPrivExt<'a, 'tcx>)] +impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { fn can_match_trait( &self, goal: ty::TraitPredicate<'tcx>, @@ -3379,7 +3379,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { found_kind: ty::ClosureKind, kind: ty::ClosureKind, trait_prefix: &'static str, - ) -> Diag<'tcx> { + ) -> Diag<'a> { let closure_span = self.tcx.def_span(closure_def_id); let mut err = ClosureKindMismatch { @@ -3473,7 +3473,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { span: Span, found_trait_ref: ty::TraitRef<'tcx>, expected_trait_ref: ty::TraitRef<'tcx>, - ) -> Result, ErrorGuaranteed> { + ) -> Result, ErrorGuaranteed> { let found_trait_ref = self.resolve_vars_if_possible(found_trait_ref); let expected_trait_ref = self.resolve_vars_if_possible(expected_trait_ref); @@ -3569,7 +3569,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { &self, obligation: &PredicateObligation<'tcx>, span: Span, - ) -> Result, ErrorGuaranteed> { + ) -> Result, ErrorGuaranteed> { if !self.tcx.features().generic_const_exprs { let guar = self .dcx() From 5988078aa20bf642bc1bbab15a45ac5cb74e77e2 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Wed, 26 Jun 2024 10:52:57 +0000 Subject: [PATCH 327/892] Restrict diagnostic context lifetime of InferCtxt to itself instead of TyCtxt --- .../src/diagnostics/bound_region_errors.rs | 69 ++++++++++++------- compiler/rustc_errors/src/diagnostic.rs | 5 ++ compiler/rustc_hir_typeck/src/coercion.rs | 6 +- compiler/rustc_hir_typeck/src/demand.rs | 20 +++--- .../rustc_hir_typeck/src/fn_ctxt/checks.rs | 2 +- compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs | 2 +- compiler/rustc_hir_typeck/src/pat.rs | 6 +- .../src/infer/error_reporting/mod.rs | 4 +- .../infer/error_reporting/need_type_info.rs | 6 +- compiler/rustc_infer/src/infer/mod.rs | 6 +- .../traits/error_reporting/infer_ctxt_ext.rs | 2 +- .../error_reporting/type_err_ctxt_ext.rs | 4 +- 12 files changed, 79 insertions(+), 53 deletions(-) diff --git a/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs index d46febffba862..c4275e1393509 100644 --- a/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs @@ -149,13 +149,13 @@ trait TypeOpInfo<'tcx> { fn base_universe(&self) -> ty::UniverseIndex; - fn nice_error( + fn nice_error<'cx>( &self, - mbcx: &mut MirBorrowckCtxt<'_, '_, '_, 'tcx>, + mbcx: &mut MirBorrowckCtxt<'_, '_, 'cx, 'tcx>, cause: ObligationCause<'tcx>, placeholder_region: ty::Region<'tcx>, error_region: Option>, - ) -> Option>; + ) -> Option>; #[instrument(level = "debug", skip(self, mbcx))] fn report_error( @@ -231,18 +231,25 @@ impl<'tcx> TypeOpInfo<'tcx> for PredicateQuery<'tcx> { self.base_universe } - fn nice_error( + fn nice_error<'cx>( &self, - mbcx: &mut MirBorrowckCtxt<'_, '_, '_, 'tcx>, + mbcx: &mut MirBorrowckCtxt<'_, '_, 'cx, 'tcx>, cause: ObligationCause<'tcx>, placeholder_region: ty::Region<'tcx>, error_region: Option>, - ) -> Option> { + ) -> Option> { let (infcx, key, _) = mbcx.infcx.tcx.infer_ctxt().build_with_canonical(cause.span, &self.canonical_query); let ocx = ObligationCtxt::new(&infcx); type_op_prove_predicate_with_cause(&ocx, key, cause); - try_extract_error_from_fulfill_cx(&ocx, mbcx.mir_def_id(), placeholder_region, error_region) + let diag = try_extract_error_from_fulfill_cx( + &ocx, + mbcx.mir_def_id(), + placeholder_region, + error_region, + )? + .with_dcx(mbcx.dcx()); + Some(diag) } } @@ -268,13 +275,13 @@ where self.base_universe } - fn nice_error( + fn nice_error<'cx>( &self, - mbcx: &mut MirBorrowckCtxt<'_, '_, '_, 'tcx>, + mbcx: &mut MirBorrowckCtxt<'_, '_, 'cx, 'tcx>, cause: ObligationCause<'tcx>, placeholder_region: ty::Region<'tcx>, error_region: Option>, - ) -> Option> { + ) -> Option> { let (infcx, key, _) = mbcx.infcx.tcx.infer_ctxt().build_with_canonical(cause.span, &self.canonical_query); let ocx = ObligationCtxt::new(&infcx); @@ -288,7 +295,14 @@ where let (param_env, value) = key.into_parts(); let _ = ocx.normalize(&cause, param_env, value.value); - try_extract_error_from_fulfill_cx(&ocx, mbcx.mir_def_id(), placeholder_region, error_region) + let diag = try_extract_error_from_fulfill_cx( + &ocx, + mbcx.mir_def_id(), + placeholder_region, + error_region, + )? + .with_dcx(mbcx.dcx()); + Some(diag) } } @@ -308,18 +322,25 @@ impl<'tcx> TypeOpInfo<'tcx> for AscribeUserTypeQuery<'tcx> { self.base_universe } - fn nice_error( + fn nice_error<'cx>( &self, - mbcx: &mut MirBorrowckCtxt<'_, '_, '_, 'tcx>, + mbcx: &mut MirBorrowckCtxt<'_, '_, 'cx, 'tcx>, cause: ObligationCause<'tcx>, placeholder_region: ty::Region<'tcx>, error_region: Option>, - ) -> Option> { + ) -> Option> { let (infcx, key, _) = mbcx.infcx.tcx.infer_ctxt().build_with_canonical(cause.span, &self.canonical_query); let ocx = ObligationCtxt::new(&infcx); type_op_ascribe_user_type_with_span(&ocx, key, Some(cause.span)).ok()?; - try_extract_error_from_fulfill_cx(&ocx, mbcx.mir_def_id(), placeholder_region, error_region) + let diag = try_extract_error_from_fulfill_cx( + &ocx, + mbcx.mir_def_id(), + placeholder_region, + error_region, + )? + .with_dcx(mbcx.dcx()); + Some(diag) } } @@ -334,13 +355,13 @@ impl<'tcx> TypeOpInfo<'tcx> for crate::type_check::InstantiateOpaqueType<'tcx> { self.base_universe.unwrap() } - fn nice_error( + fn nice_error<'cx>( &self, - mbcx: &mut MirBorrowckCtxt<'_, '_, '_, 'tcx>, + mbcx: &mut MirBorrowckCtxt<'_, '_, 'cx, 'tcx>, _cause: ObligationCause<'tcx>, placeholder_region: ty::Region<'tcx>, error_region: Option>, - ) -> Option> { + ) -> Option> { try_extract_error_from_region_constraints( mbcx.infcx, mbcx.mir_def_id(), @@ -358,12 +379,12 @@ impl<'tcx> TypeOpInfo<'tcx> for crate::type_check::InstantiateOpaqueType<'tcx> { } #[instrument(skip(ocx), level = "debug")] -fn try_extract_error_from_fulfill_cx<'tcx>( - ocx: &ObligationCtxt<'_, 'tcx>, +fn try_extract_error_from_fulfill_cx<'a, 'tcx>( + ocx: &ObligationCtxt<'a, 'tcx>, generic_param_scope: LocalDefId, placeholder_region: ty::Region<'tcx>, error_region: Option>, -) -> Option> { +) -> Option> { // We generally shouldn't have errors here because the query was // already run, but there's no point using `span_delayed_bug` // when we're going to emit an error here anyway. @@ -381,15 +402,15 @@ fn try_extract_error_from_fulfill_cx<'tcx>( } #[instrument(level = "debug", skip(infcx, region_var_origin, universe_of_region))] -fn try_extract_error_from_region_constraints<'tcx>( - infcx: &InferCtxt<'tcx>, +fn try_extract_error_from_region_constraints<'a, 'tcx>( + infcx: &'a InferCtxt<'tcx>, generic_param_scope: LocalDefId, placeholder_region: ty::Region<'tcx>, error_region: Option>, region_constraints: &RegionConstraintData<'tcx>, mut region_var_origin: impl FnMut(RegionVid) -> RegionVariableOrigin, mut universe_of_region: impl FnMut(RegionVid) -> UniverseIndex, -) -> Option> { +) -> Option> { let placeholder_universe = match placeholder_region.kind() { ty::RePlaceholder(p) => p.universe, ty::ReVar(vid) => universe_of_region(vid), diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs index e580910af7799..0231665b64cf5 100644 --- a/compiler/rustc_errors/src/diagnostic.rs +++ b/compiler/rustc_errors/src/diagnostic.rs @@ -582,6 +582,11 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> { Self::new_diagnostic(dcx, DiagInner::new(level, message)) } + /// Allow moving diagnostics between different error tainting contexts + pub fn with_dcx(mut self, dcx: DiagCtxtHandle<'_>) -> Diag<'_, G> { + Diag { dcx, diag: self.diag.take(), _marker: PhantomData } + } + /// Creates a new `Diag` with an already constructed diagnostic. #[track_caller] pub(crate) fn new_diagnostic(dcx: DiagCtxtHandle<'a>, diag: DiagInner) -> Self { diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs index 0551b9bc1f0b4..f055a77696180 100644 --- a/compiler/rustc_hir_typeck/src/coercion.rs +++ b/compiler/rustc_hir_typeck/src/coercion.rs @@ -1797,16 +1797,16 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { err.subdiagnostic(SuggestBoxingForReturnImplTrait::BoxReturnExpr { starts, ends }); } - fn report_return_mismatched_types<'a>( + fn report_return_mismatched_types<'cx>( &self, cause: &ObligationCause<'tcx>, expected: Ty<'tcx>, found: Ty<'tcx>, ty_err: TypeError<'tcx>, - fcx: &FnCtxt<'a, 'tcx>, + fcx: &'cx FnCtxt<'_, 'tcx>, block_or_return_id: hir::HirId, expression: Option<&'tcx hir::Expr<'tcx>>, - ) -> Diag<'a> { + ) -> Diag<'cx> { let mut err = fcx.err_ctxt().report_mismatched_types(cause, expected, found, ty_err); let due_to_block = matches!(fcx.tcx.hir_node(block_or_return_id), hir::Node::Block(..)); diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs index f9720c9c30795..ad9c1e2821172 100644 --- a/compiler/rustc_hir_typeck/src/demand.rs +++ b/compiler/rustc_hir_typeck/src/demand.rs @@ -172,21 +172,21 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } pub fn demand_suptype_diag( - &self, + &'a self, sp: Span, expected: Ty<'tcx>, actual: Ty<'tcx>, - ) -> Result<(), Diag<'tcx>> { + ) -> Result<(), Diag<'a>> { self.demand_suptype_with_origin(&self.misc(sp), expected, actual) } #[instrument(skip(self), level = "debug")] pub fn demand_suptype_with_origin( - &self, + &'a self, cause: &ObligationCause<'tcx>, expected: Ty<'tcx>, actual: Ty<'tcx>, - ) -> Result<(), Diag<'tcx>> { + ) -> Result<(), Diag<'a>> { self.at(cause, self.param_env) .sup(DefineOpaqueTypes::Yes, expected, actual) .map(|infer_ok| self.register_infer_ok_obligations(infer_ok)) @@ -200,20 +200,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } pub fn demand_eqtype_diag( - &self, + &'a self, sp: Span, expected: Ty<'tcx>, actual: Ty<'tcx>, - ) -> Result<(), Diag<'tcx>> { + ) -> Result<(), Diag<'a>> { self.demand_eqtype_with_origin(&self.misc(sp), expected, actual) } pub fn demand_eqtype_with_origin( - &self, + &'a self, cause: &ObligationCause<'tcx>, expected: Ty<'tcx>, actual: Ty<'tcx>, - ) -> Result<(), Diag<'tcx>> { + ) -> Result<(), Diag<'a>> { self.at(cause, self.param_env) .eq(DefineOpaqueTypes::Yes, expected, actual) .map(|infer_ok| self.register_infer_ok_obligations(infer_ok)) @@ -247,13 +247,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// will be permitted if the diverges flag is currently "always". #[instrument(level = "debug", skip(self, expr, expected_ty_expr, allow_two_phase))] pub fn demand_coerce_diag( - &self, + &'a self, mut expr: &'tcx hir::Expr<'tcx>, checked_ty: Ty<'tcx>, expected: Ty<'tcx>, mut expected_ty_expr: Option<&'tcx hir::Expr<'tcx>>, allow_two_phase: AllowTwoPhase, - ) -> Result, Diag<'tcx>> { + ) -> Result, Diag<'a>> { let expected = self.resolve_vars_with_obligations(expected); let e = match self.coerce(expr, checked_ty, expected, allow_two_phase, None) { diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index 1138642c56d61..75664824477e3 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -1424,7 +1424,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { expected_ty: Ty<'tcx>, provided_ty: Ty<'tcx>, arg: &hir::Expr<'tcx>, - err: &mut Diag<'tcx>, + err: &mut Diag<'_>, ) { if let ty::RawPtr(_, hir::Mutability::Mut) = expected_ty.kind() && let ty::RawPtr(_, hir::Mutability::Not) = provided_ty.kind() diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs index ad8eb7c30826c..f0131b3225cc9 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs @@ -145,7 +145,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } pub(crate) fn dcx(&self) -> DiagCtxtHandle<'a> { - self.infcx.dcx() + self.root_ctxt.infcx.dcx() } pub fn cause(&self, span: Span, code: ObligationCauseCode<'tcx>) -> ObligationCause<'tcx> { diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index 208930208ed83..8dde3032ca471 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -89,7 +89,7 @@ struct PatInfo<'tcx, 'a> { current_depth: u32, } -impl<'tcx> FnCtxt<'_, 'tcx> { +impl<'a, 'tcx> FnCtxt<'a, 'tcx> { fn pattern_cause(&self, ti: &TopInfo<'tcx>, cause_span: Span) -> ObligationCause<'tcx> { let code = ObligationCauseCode::Pattern { span: ti.span, @@ -100,12 +100,12 @@ impl<'tcx> FnCtxt<'_, 'tcx> { } fn demand_eqtype_pat_diag( - &self, + &'a self, cause_span: Span, expected: Ty<'tcx>, actual: Ty<'tcx>, ti: &TopInfo<'tcx>, - ) -> Result<(), Diag<'tcx>> { + ) -> Result<(), Diag<'a>> { self.demand_eqtype_with_origin(&self.pattern_cause(ti, cause_span), expected, actual) .map_err(|mut diag| { if let Some(expr) = ti.origin_expr { diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index 503d3424e7481..d321bc265bc93 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -436,7 +436,7 @@ impl<'tcx> InferCtxt<'tcx> { } } -impl<'tcx> TypeErrCtxt<'_, 'tcx> { +impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { pub fn report_region_errors( &self, generic_param_scope: LocalDefId, @@ -2206,7 +2206,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { &self, trace: TypeTrace<'tcx>, terr: TypeError<'tcx>, - ) -> Diag<'tcx> { + ) -> Diag<'a> { debug!("report_and_explain_type_error(trace={:?}, terr={:?})", trace, terr); let span = trace.cause.span(); diff --git a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs index ba5e3ae8a930c..084aebc296f86 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs @@ -391,7 +391,7 @@ impl<'tcx> InferCtxt<'tcx> { span: Span, arg_data: InferenceDiagnosticsData, error_code: TypeAnnotationNeeded, - ) -> Diag<'tcx> { + ) -> Diag<'_> { let source_kind = "other"; let source_name = ""; let failure_span = None; @@ -453,7 +453,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { // If we don't have any typeck results we're outside // of a body, so we won't be able to get better info // here. - return self.bad_inference_failure_err(failure_span, arg_data, error_code); + return self.infcx.bad_inference_failure_err(failure_span, arg_data, error_code); }; let mut local_visitor = FindInferSourceVisitor::new(self, typeck_results, arg); @@ -465,7 +465,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { } let Some(InferSource { span, kind }) = local_visitor.infer_source else { - return self.bad_inference_failure_err(failure_span, arg_data, error_code); + return self.infcx.bad_inference_failure_err(failure_span, arg_data, error_code); }; let (source_kind, name, path) = kind.ty_localized_msg(self); diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index 78d42942de47c..10471e8bbdd71 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -684,7 +684,7 @@ impl<'tcx> InferOk<'tcx, ()> { } impl<'tcx> InferCtxt<'tcx> { - pub fn dcx(&self) -> DiagCtxtHandle<'tcx> { + pub fn dcx(&self) -> DiagCtxtHandle<'_> { self.tcx.dcx() } @@ -1646,7 +1646,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { expected: Ty<'tcx>, actual: Ty<'tcx>, err: TypeError<'tcx>, - ) -> Diag<'tcx> { + ) -> Diag<'a> { self.report_and_explain_type_error(TypeTrace::types(cause, true, expected, actual), err) } @@ -1656,7 +1656,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { expected: ty::Const<'tcx>, actual: ty::Const<'tcx>, err: TypeError<'tcx>, - ) -> Diag<'tcx> { + ) -> Diag<'a> { self.report_and_explain_type_error(TypeTrace::consts(cause, true, expected, actual), err) } } diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/infer_ctxt_ext.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/infer_ctxt_ext.rs index 4b5b1d77b30da..34da8e576ce86 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/infer_ctxt_ext.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/infer_ctxt_ext.rs @@ -88,7 +88,7 @@ impl<'tcx> InferCtxt<'tcx> { found_args: Vec, is_closure: bool, closure_arg_span: Option, - ) -> Diag<'tcx> { + ) -> Diag<'_> { let kind = if is_closure { "closure" } else { "function" }; let args_str = |arguments: &[ArgKind], other: &[ArgKind]| { diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs index cccb78bec9d39..3ef3efc6252e9 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs @@ -3422,7 +3422,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { found_trait_ref: ty::TraitRef<'tcx>, expected_trait_ref: ty::TraitRef<'tcx>, terr: TypeError<'tcx>, - ) -> Diag<'tcx> { + ) -> Diag<'a> { let self_ty = found_trait_ref.self_ty(); let (cause, terr) = if let ty::Closure(def_id, _) = self_ty.kind() { ( @@ -3553,7 +3553,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { }) .unwrap_or((found_span, None, found)); - self.report_arg_count_mismatch( + self.infcx.report_arg_count_mismatch( span, closure_span, expected, From 86c8eae7745b47ada8305dcdac16b7f2dbdd68c9 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Wed, 26 Jun 2024 16:01:38 +0000 Subject: [PATCH 328/892] Automatically taint InferCtxt when errors are emitted --- .../src/diagnostics/region_errors.rs | 2 +- .../src/region_infer/opaque_types.rs | 13 +- compiler/rustc_errors/src/diagnostic.rs | 2 +- compiler/rustc_errors/src/lib.rs | 61 ++++++--- compiler/rustc_hir_typeck/src/cast.rs | 2 +- compiler/rustc_hir_typeck/src/expr.rs | 6 +- .../rustc_hir_typeck/src/expr_use_visitor.rs | 2 +- .../rustc_hir_typeck/src/fn_ctxt/_impl.rs | 6 +- .../rustc_hir_typeck/src/fn_ctxt/checks.rs | 14 +- compiler/rustc_hir_typeck/src/intrinsicck.rs | 6 +- .../rustc_hir_typeck/src/method/suggest.rs | 8 +- compiler/rustc_hir_typeck/src/pat.rs | 17 +-- .../src/infer/error_reporting/mod.rs | 21 +-- .../src/infer/error_reporting/note.rs | 2 +- compiler/rustc_infer/src/infer/mod.rs | 19 +-- .../rustc_infer/src/infer/opaque_types/mod.rs | 2 +- .../src/traits/error_reporting/mod.rs | 8 +- .../error_reporting/type_err_ctxt_ext.rs | 4 +- tests/ui/asm/x86_64/type-check-2.rs | 3 + tests/ui/asm/x86_64/type-check-2.stderr | 68 ++++++++-- .../associated-types-eq-expr-path.rs | 1 + .../associated-types-eq-expr-path.stderr | 20 ++- .../assoc_const_as_type_argument.rs | 1 + .../assoc_const_as_type_argument.stderr | 18 ++- .../const-arg-in-const-arg.min.stderr | 120 ++++++++++++------ .../const-generics/const-arg-in-const-arg.rs | 4 + .../generic_const_exprs/opaque_type.rs | 1 + .../generic_const_exprs/opaque_type.stderr | 14 +- .../issues/issue-62878.min.stderr | 30 ++++- tests/ui/const-generics/issues/issue-62878.rs | 2 + ...const-expression-suggest-missing-braces.rs | 1 + ...t-expression-suggest-missing-braces.stderr | 38 ++++-- .../min_const_generics/macro-fail.rs | 5 +- .../min_const_generics/macro-fail.stderr | 61 +++++++-- .../const-generics/suggest_const_for_array.rs | 10 +- .../suggest_const_for_array.stderr | 41 ++++-- .../generic-function-item-where-type.rs | 1 + .../generic-function-item-where-type.stderr | 11 +- .../impl-fn-predefined-lifetimes.rs | 1 + .../impl-fn-predefined-lifetimes.stderr | 14 +- .../impl-trait/transmute/in-defining-scope.rs | 1 + .../transmute/in-defining-scope.stderr | 14 +- tests/ui/infinite/infinite-struct.rs | 1 + tests/ui/infinite/infinite-struct.stderr | 17 ++- .../reference-of-mut-static-unsafe-fn.rs | 26 ---- .../reference-of-mut-static-unsafe-fn.stderr | 75 ----------- .../reference-of-mut-static.e2021.stderr | 91 ------------- .../reference-of-mut-static.e2024.stderr | 75 ----------- tests/ui/static/reference-of-mut-static.rs | 50 -------- .../reference-to-mut-static-safe.e2024.stderr | 13 +- .../ui/static/reference-to-mut-static-safe.rs | 2 +- .../reference-to-mut-static-unsafe-fn.rs | 28 ++-- .../reference-to-mut-static-unsafe-fn.stderr | 60 ++++----- .../hkl_forbidden4.stderr | 24 ++-- .../ui/type-alias-impl-trait/issue-53092-2.rs | 2 + .../issue-53092-2.stderr | 32 ++++- 56 files changed, 601 insertions(+), 570 deletions(-) delete mode 100644 tests/ui/static/reference-of-mut-static-unsafe-fn.rs delete mode 100644 tests/ui/static/reference-of-mut-static-unsafe-fn.stderr delete mode 100644 tests/ui/static/reference-of-mut-static.e2021.stderr delete mode 100644 tests/ui/static/reference-of-mut-static.e2024.stderr delete mode 100644 tests/ui/static/reference-of-mut-static.rs diff --git a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs index bb3542287d5e0..dd22f8d8440ee 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs @@ -360,7 +360,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'_, '_, 'cx, 'tcx> { let named_key = self.regioncx.name_regions(self.infcx.tcx, key); let named_region = self.regioncx.name_regions(self.infcx.tcx, member_region); let diag = unexpected_hidden_region_diagnostic( - self.infcx.tcx, + self.infcx, self.mir_def_id(), span, named_ty, diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs index 67e5c8352df0f..e195ceded1bf3 100644 --- a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs +++ b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs @@ -285,7 +285,7 @@ impl<'tcx> InferCtxt<'tcx> { } if let Err(guar) = - check_opaque_type_parameter_valid(self.tcx, opaque_type_key, instantiated_ty.span) + check_opaque_type_parameter_valid(self, opaque_type_key, instantiated_ty.span) { return Ty::new_error(self.tcx, guar); } @@ -294,6 +294,10 @@ impl<'tcx> InferCtxt<'tcx> { .remap_generic_params_to_declaration_params(opaque_type_key, self.tcx, false) .ty; + if let Err(e) = definition_ty.error_reported() { + return Ty::new_error(self.tcx, e); + } + // `definition_ty` does not live in of the current inference context, // so lets make sure that we don't accidentally misuse our current `infcx`. match check_opaque_type_well_formed( @@ -387,10 +391,11 @@ fn check_opaque_type_well_formed<'tcx>( /// [rustc-dev-guide chapter]: /// https://rustc-dev-guide.rust-lang.org/opaque-types-region-infer-restrictions.html fn check_opaque_type_parameter_valid<'tcx>( - tcx: TyCtxt<'tcx>, + infcx: &InferCtxt<'tcx>, opaque_type_key: OpaqueTypeKey<'tcx>, span: Span, ) -> Result<(), ErrorGuaranteed> { + let tcx = infcx.tcx; let opaque_generics = tcx.generics_of(opaque_type_key.def_id); let opaque_env = LazyOpaqueTyEnv::new(tcx, opaque_type_key.def_id); let mut seen_params: FxIndexMap<_, Vec<_>> = FxIndexMap::default(); @@ -420,7 +425,7 @@ fn check_opaque_type_parameter_valid<'tcx>( opaque_env.param_is_error(i)?; - return Err(tcx.dcx().emit_err(NonGenericOpaqueTypeParam { + return Err(infcx.dcx().emit_err(NonGenericOpaqueTypeParam { ty: arg, kind, span, @@ -438,7 +443,7 @@ fn check_opaque_type_parameter_valid<'tcx>( .collect(); #[allow(rustc::diagnostic_outside_of_impl)] #[allow(rustc::untranslatable_diagnostic)] - return Err(tcx + return Err(infcx .dcx() .struct_span_err(span, "non-defining opaque type use in defining scope") .with_span_note(spans, format!("{descr} used multiple times")) diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs index 0231665b64cf5..d500f6d88a01b 100644 --- a/compiler/rustc_errors/src/diagnostic.rs +++ b/compiler/rustc_errors/src/diagnostic.rs @@ -510,7 +510,7 @@ pub struct Diag<'a, G: EmissionGuarantee = ErrorGuaranteed> { // would be bad. impl !Clone for Diag<'_, G> {} -rustc_data_structures::static_assert_size!(Diag<'_, ()>, 2 * std::mem::size_of::()); +rustc_data_structures::static_assert_size!(Diag<'_, ()>, 3 * std::mem::size_of::()); impl Deref for Diag<'_, G> { type Target = DiagInner; diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index 91112a572770e..242684e63a082 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -63,6 +63,7 @@ use rustc_span::source_map::SourceMap; use rustc_span::{Loc, Span, DUMMY_SP}; use std::backtrace::{Backtrace, BacktraceStatus}; use std::borrow::Cow; +use std::cell::Cell; use std::error::Report; use std::fmt; use std::hash::Hash; @@ -98,9 +99,9 @@ rustc_fluent_macro::fluent_messages! { "../messages.ftl" } // `PResult` is used a lot. Make sure it doesn't unintentionally get bigger. #[cfg(target_pointer_width = "64")] -rustc_data_structures::static_assert_size!(PResult<'_, ()>, 16); +rustc_data_structures::static_assert_size!(PResult<'_, ()>, 24); #[cfg(target_pointer_width = "64")] -rustc_data_structures::static_assert_size!(PResult<'_, bool>, 16); +rustc_data_structures::static_assert_size!(PResult<'_, bool>, 24); #[derive(Debug, PartialEq, Eq, Clone, Copy, Hash, Encodable, Decodable)] pub enum SuggestionStyle { @@ -417,6 +418,7 @@ pub struct DiagCtxt { #[derive(Copy, Clone)] pub struct DiagCtxtHandle<'a> { dcx: &'a DiagCtxt, + tainted_with_errors: Option<&'a Cell>>, } impl<'a> std::ops::Deref for DiagCtxtHandle<'a> { @@ -752,7 +754,14 @@ impl DiagCtxt { } pub fn handle<'a>(&'a self) -> DiagCtxtHandle<'a> { - DiagCtxtHandle { dcx: self } + DiagCtxtHandle { dcx: self, tainted_with_errors: None } + } + + pub fn taintable_handle<'a>( + &'a self, + tainted_with_errors: &'a Cell>, + ) -> DiagCtxtHandle<'a> { + DiagCtxtHandle { dcx: self, tainted_with_errors: Some(tainted_with_errors) } } } @@ -795,7 +804,9 @@ impl<'a> DiagCtxtHandle<'a> { // can be used to create a backtrace at the stashing site insted of whenever the // diagnostic context is dropped and thus delayed bugs are emitted. Error => Some(self.span_delayed_bug(span, format!("stashing {key:?}"))), - DelayedBug => return self.inner.borrow_mut().emit_diagnostic(diag), + DelayedBug => { + return self.inner.borrow_mut().emit_diagnostic(diag, self.tainted_with_errors); + } ForceWarning(_) | Warning | Note | OnceNote | Help | OnceHelp | FailureNote | Allow | Expect(_) => None, }; @@ -947,16 +958,19 @@ impl<'a> DiagCtxtHandle<'a> { (0, _) => { // Use `ForceWarning` rather than `Warning` to guarantee emission, e.g. with a // configuration like `--cap-lints allow --force-warn bare_trait_objects`. - inner.emit_diagnostic(DiagInner::new( - ForceWarning(None), - DiagMessage::Str(warnings), - )); + inner.emit_diagnostic( + DiagInner::new(ForceWarning(None), DiagMessage::Str(warnings)), + None, + ); } (_, 0) => { - inner.emit_diagnostic(DiagInner::new(Error, errors)); + inner.emit_diagnostic(DiagInner::new(Error, errors), self.tainted_with_errors); } (_, _) => { - inner.emit_diagnostic(DiagInner::new(Error, format!("{errors}; {warnings}"))); + inner.emit_diagnostic( + DiagInner::new(Error, format!("{errors}; {warnings}")), + self.tainted_with_errors, + ); } } @@ -987,14 +1001,14 @@ impl<'a> DiagCtxtHandle<'a> { "For more information about an error, try `rustc --explain {}`.", &error_codes[0] ); - inner.emit_diagnostic(DiagInner::new(FailureNote, msg1)); - inner.emit_diagnostic(DiagInner::new(FailureNote, msg2)); + inner.emit_diagnostic(DiagInner::new(FailureNote, msg1), None); + inner.emit_diagnostic(DiagInner::new(FailureNote, msg2), None); } else { let msg = format!( "For more information about this error, try `rustc --explain {}`.", &error_codes[0] ); - inner.emit_diagnostic(DiagInner::new(FailureNote, msg)); + inner.emit_diagnostic(DiagInner::new(FailureNote, msg), None); } } } @@ -1020,7 +1034,7 @@ impl<'a> DiagCtxtHandle<'a> { } pub fn emit_diagnostic(&self, diagnostic: DiagInner) -> Option { - self.inner.borrow_mut().emit_diagnostic(diagnostic) + self.inner.borrow_mut().emit_diagnostic(diagnostic, self.tainted_with_errors) } pub fn emit_artifact_notification(&self, path: &Path, artifact_type: &str) { @@ -1080,7 +1094,7 @@ impl<'a> DiagCtxtHandle<'a> { // Here the diagnostic is given back to `emit_diagnostic` where it was first // intercepted. Now it should be processed as usual, since the unstable expectation // id is now stable. - inner.emit_diagnostic(diag); + inner.emit_diagnostic(diag, self.tainted_with_errors); } } @@ -1430,13 +1444,17 @@ impl DiagCtxtInner { continue; } } - guar = guar.or(self.emit_diagnostic(diag)); + guar = guar.or(self.emit_diagnostic(diag, None)); } guar } // Return value is only `Some` if the level is `Error` or `DelayedBug`. - fn emit_diagnostic(&mut self, mut diagnostic: DiagInner) -> Option { + fn emit_diagnostic( + &mut self, + mut diagnostic: DiagInner, + taint: Option<&Cell>>, + ) -> Option { match diagnostic.level { Expect(expect_id) | ForceWarning(Some(expect_id)) => { // The `LintExpectationId` can be stable or unstable depending on when it was @@ -1609,6 +1627,9 @@ impl DiagCtxtInner { if is_lint { self.lint_err_guars.push(guar); } else { + if let Some(taint) = taint { + taint.set(Some(guar)); + } self.err_guars.push(guar); } self.panic_if_treat_err_as_bug(); @@ -1718,8 +1739,8 @@ impl DiagCtxtInner { // `-Ztreat-err-as-bug`, which we don't want. let note1 = "no errors encountered even though delayed bugs were created"; let note2 = "those delayed bugs will now be shown as internal compiler errors"; - self.emit_diagnostic(DiagInner::new(Note, note1)); - self.emit_diagnostic(DiagInner::new(Note, note2)); + self.emit_diagnostic(DiagInner::new(Note, note1), None); + self.emit_diagnostic(DiagInner::new(Note, note2), None); for bug in bugs { if let Some(out) = &mut out { @@ -1752,7 +1773,7 @@ impl DiagCtxtInner { } bug.level = Bug; - self.emit_diagnostic(bug); + self.emit_diagnostic(bug, None); } // Panic with `DelayedBugPanic` to avoid "unexpected panic" messages. diff --git a/compiler/rustc_hir_typeck/src/cast.rs b/compiler/rustc_hir_typeck/src/cast.rs index 92f2d3254bb22..cb1a412d17eef 100644 --- a/compiler/rustc_hir_typeck/src/cast.rs +++ b/compiler/rustc_hir_typeck/src/cast.rs @@ -319,7 +319,7 @@ impl<'a, 'tcx> CastCheck<'tcx> { } else { errors::CannotCastToBoolHelp::Unsupported(self.span) }; - fcx.tcx.dcx().emit_err(errors::CannotCastToBool { span: self.span, expr_ty, help }); + fcx.dcx().emit_err(errors::CannotCastToBool { span: self.span, expr_ty, help }); } CastError::CastToChar => { let mut err = type_error_struct!( diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index f4e1e46195345..2fbc8a3f146a1 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -638,7 +638,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Set expectation to error in that case and set tainted // by error (#114529) let coerce_to = opt_coerce_to.unwrap_or_else(|| { - let guar = tcx.dcx().span_delayed_bug( + let guar = self.dcx().span_delayed_bug( expr.span, "illegal break with value found but no error reported", ); @@ -1716,7 +1716,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } else { error_happened = true; let guar = if let Some(prev_span) = seen_fields.get(&ident) { - tcx.dcx().emit_err(FieldMultiplySpecifiedInInitializer { + self.dcx().emit_err(FieldMultiplySpecifiedInInitializer { span: field.ident.span, prev_span: *prev_span, ident, @@ -1757,7 +1757,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if adt_kind == AdtKind::Union { if hir_fields.len() != 1 { struct_span_code_err!( - tcx.dcx(), + self.dcx(), span, E0784, "union expressions should have exactly one field", diff --git a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs index 0ba4bd090f5e2..9a353bfe49d0e 100644 --- a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs +++ b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs @@ -170,7 +170,7 @@ impl<'tcx> TypeInformationCtxt<'tcx> for &FnCtxt<'_, 'tcx> { } fn report_error(&self, span: Span, msg: impl ToString) -> Self::Error { - self.tcx.dcx().span_delayed_bug(span, msg.to_string()) + self.dcx().span_delayed_bug(span, msg.to_string()) } fn error_reported_in_ty(&self, ty: Ty<'tcx>) -> Result<(), Self::Error> { diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index 061afd0306230..21269d9c0982b 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -1182,7 +1182,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { name: self.tcx.item_name(def.did()).to_ident_string(), }); if ty.raw.has_param() { - let guar = self.tcx.dcx().emit_err(errors::SelfCtorFromOuterItem { + let guar = self.dcx().emit_err(errors::SelfCtorFromOuterItem { span: path_span, impl_span: tcx.def_span(impl_def_id), sugg, @@ -1207,7 +1207,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Check the visibility of the ctor. let vis = tcx.visibility(ctor_def_id); if !vis.is_accessible_from(tcx.parent_module(hir_id).to_def_id(), tcx) { - tcx.dcx() + self.dcx() .emit_err(CtorIsPrivate { span, def: tcx.def_path_str(adt_def.did()) }); } let new_res = Res::Def(DefKind::Ctor(CtorOf::Struct, ctor_kind), ctor_def_id); @@ -1216,7 +1216,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { (new_res, Some(user_args.args)) } _ => { - let mut err = tcx.dcx().struct_span_err( + let mut err = self.dcx().struct_span_err( span, "the `Self` constructor can only be used with tuple or unit structs", ); diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index 75664824477e3..430e12ff7b87b 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -238,7 +238,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Otherwise, there's a mismatch, so clear out what we're expecting, and set // our input types to err_args so we don't blow up the error messages let guar = struct_span_code_err!( - tcx.dcx(), + self.dcx(), call_span, E0059, "cannot use call notation; the first type parameter \ @@ -453,7 +453,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .map(|vars| self.resolve_vars_if_possible(vars)), ); - self.set_tainted_by_errors(self.report_arg_errors( + self.report_arg_errors( compatibility_diagonal, formal_and_expected_inputs, provided_args, @@ -462,7 +462,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { fn_def_id, call_span, call_expr, - )); + ); } } @@ -788,7 +788,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { format!("arguments to this {call_name} are incorrect"), ); } else { - err = tcx.dcx().struct_span_err( + err = self.dcx().struct_span_err( full_call_span, format!( "{call_name} takes {}{} but {} {} supplied", @@ -848,7 +848,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { span_bug!(error_span, "expected errors from argument matrix"); } else { let mut err = - tcx.dcx().create_err(errors::ArgMismatchIndeterminate { span: error_span }); + self.dcx().create_err(errors::ArgMismatchIndeterminate { span: error_span }); suggest_confusable(&mut err); return err.emit(); } @@ -953,14 +953,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let mut err = if formal_and_expected_inputs.len() == provided_args.len() { struct_span_code_err!( - tcx.dcx(), + self.dcx(), full_call_span, E0308, "arguments to this {} are incorrect", call_name, ) } else { - tcx.dcx() + self.dcx() .struct_span_err( full_call_span, format!( diff --git a/compiler/rustc_hir_typeck/src/intrinsicck.rs b/compiler/rustc_hir_typeck/src/intrinsicck.rs index 5eafc60a04eb8..0389c06c3123f 100644 --- a/compiler/rustc_hir_typeck/src/intrinsicck.rs +++ b/compiler/rustc_hir_typeck/src/intrinsicck.rs @@ -52,7 +52,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Note: this path is currently not reached in any test, so any // example that triggers this would be worth minimizing and // converting into a test. - tcx.dcx().span_bug(span, "argument to transmute has inference variables"); + self.dcx().span_bug(span, "argument to transmute has inference variables"); } // Transmutes that are only changing lifetimes are always ok. if from == to { @@ -76,7 +76,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if let (&ty::FnDef(..), SizeSkeleton::Known(size_to, _)) = (from.kind(), sk_to) && size_to == Pointer(dl.instruction_address_space).size(&tcx) { - struct_span_code_err!(tcx.dcx(), span, E0591, "can't transmute zero-sized type") + struct_span_code_err!(self.dcx(), span, E0591, "can't transmute zero-sized type") .with_note(format!("source type: {from}")) .with_note(format!("target type: {to}")) .with_help("cast with `as` to a pointer instead") @@ -116,7 +116,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }; let mut err = struct_span_code_err!( - tcx.dcx(), + self.dcx(), span, E0512, "cannot transmute between types of different sizes, \ diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index a385bc70e359b..e310730bf9e91 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -705,7 +705,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let mut err = if is_write && let SelfSource::MethodCall(rcvr_expr) = source { self.suggest_missing_writer(rcvr_ty, rcvr_expr) } else { - let mut err = tcx.dcx().create_err(NoAssociatedItem { + let mut err = self.dcx().create_err(NoAssociatedItem { span, item_kind, item_name, @@ -1194,7 +1194,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { span: item_span, .. })) => { - tcx.dcx().span_delayed_bug( + self.dcx().span_delayed_bug( *item_span, "auto trait is invoked with no method error, but no error reported?", ); @@ -2361,7 +2361,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ); if pick.is_ok() { let range_span = parent_expr.span.with_hi(expr.span.hi()); - return Err(tcx.dcx().emit_err(errors::MissingParenthesesInRange { + return Err(self.dcx().emit_err(errors::MissingParenthesesInRange { span, ty_str: ty_str.to_string(), method_name: item_name.as_str().to_string(), @@ -2420,7 +2420,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { && let SelfSource::MethodCall(expr) = source { let mut err = struct_span_code_err!( - tcx.dcx(), + self.dcx(), span, E0689, "can't call {} `{}` on ambiguous numeric type `{}`", diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index 8dde3032ca471..f932a27e9a287 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -698,7 +698,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { && let MutblCap::WeaklyNot(and_pat_span) = pat_info.max_ref_mutbl { let mut err = struct_span_code_err!( - self.tcx.dcx(), + self.dcx(), ident.span, E0596, "cannot borrow as mutable inside an `&` pattern" @@ -1010,7 +1010,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let (res, opt_ty, segments) = path_resolution; match res { Res::Err => { - let e = tcx.dcx().span_delayed_bug(qpath.span(), "`Res::Err` but no error emitted"); + let e = + self.dcx().span_delayed_bug(qpath.span(), "`Res::Err` but no error emitted"); self.set_tainted_by_errors(e); return Ty::new_error(tcx, e); } @@ -1191,7 +1192,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let (res, opt_ty, segments) = self.resolve_ty_and_res_fully_qualified_call(qpath, pat.hir_id, pat.span); if res == Res::Err { - let e = tcx.dcx().span_delayed_bug(pat.span, "`Res::Err` but no error emitted"); + let e = self.dcx().span_delayed_bug(pat.span, "`Res::Err` but no error emitted"); self.set_tainted_by_errors(e); on_error(e); return Ty::new_error(tcx, e); @@ -1207,7 +1208,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let variant = match res { Res::Err => { - tcx.dcx().span_bug(pat.span, "`Res::Err` but no error emitted"); + self.dcx().span_bug(pat.span, "`Res::Err` but no error emitted"); } Res::Def(DefKind::AssocConst | DefKind::AssocFn, _) => { let e = report_unexpected_res(res); @@ -1549,10 +1550,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Report an error if an incorrect number of fields was specified. if adt.is_union() { if fields.len() != 1 { - tcx.dcx().emit_err(errors::UnionPatMultipleFields { span: pat.span }); + self.dcx().emit_err(errors::UnionPatMultipleFields { span: pat.span }); } if has_rest_pat { - tcx.dcx().emit_err(errors::UnionPatDotDot { span: pat.span }); + self.dcx().emit_err(errors::UnionPatDotDot { span: pat.span }); } } else if !unmentioned_fields.is_empty() { let accessible_unmentioned_fields: Vec<_> = unmentioned_fields @@ -1690,7 +1691,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { pat: &'tcx Pat<'tcx>, variant: &ty::VariantDef, args: ty::GenericArgsRef<'tcx>, - ) -> Diag<'tcx> { + ) -> Diag<'a> { let tcx = self.tcx; let (field_names, t, plural) = if let [field] = inexistent_fields { (format!("a field named `{}`", field.ident), "this", "") @@ -1710,7 +1711,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }; let spans = inexistent_fields.iter().map(|field| field.ident.span).collect::>(); let mut err = struct_span_code_err!( - tcx.dcx(), + self.dcx(), spans, E0026, "{} `{}` does not have {}", diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index d321bc265bc93..a8fd3ca8c59bd 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -305,16 +305,17 @@ fn label_msg_span( } } -#[instrument(level = "trace", skip(tcx))] -pub fn unexpected_hidden_region_diagnostic<'tcx>( - tcx: TyCtxt<'tcx>, +#[instrument(level = "trace", skip(infcx))] +pub fn unexpected_hidden_region_diagnostic<'a, 'tcx>( + infcx: &'a InferCtxt<'tcx>, generic_param_scope: LocalDefId, span: Span, hidden_ty: Ty<'tcx>, hidden_region: ty::Region<'tcx>, opaque_ty_key: ty::OpaqueTypeKey<'tcx>, -) -> Diag<'tcx> { - let mut err = tcx.dcx().create_err(errors::OpaqueCapturesLifetime { +) -> Diag<'a> { + let tcx = infcx.tcx; + let mut err = infcx.dcx().create_err(errors::OpaqueCapturesLifetime { span, opaque_ty: Ty::new_opaque(tcx, opaque_ty_key.def_id.to_def_id(), opaque_ty_key.args), opaque_ty_span: tcx.def_span(opaque_ty_key.def_id), @@ -2215,7 +2216,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { span, self.type_error_additional_suggestions(&trace, terr), ); - let mut diag = self.tcx.dcx().create_err(failure_code); + let mut diag = self.dcx().create_err(failure_code); self.note_type_err(&mut diag, &trace.cause, None, Some(trace.values), terr, false, false); diag } @@ -2357,14 +2358,14 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { origin: Option>, bound_kind: GenericKind<'tcx>, sub: Region<'tcx>, - ) -> Diag<'tcx> { + ) -> Diag<'a> { if let Some(SubregionOrigin::CompareImplItemObligation { span, impl_item_def_id, trait_item_def_id, }) = origin { - return self.report_extra_impl_obligation( + return self.infcx.report_extra_impl_obligation( span, impl_item_def_id, trait_item_def_id, @@ -2790,7 +2791,7 @@ impl<'tcx> TypeRelation> for SameTypeModuloInfer<'_, 'tcx> { } impl<'tcx> InferCtxt<'tcx> { - fn report_inference_failure(&self, var_origin: RegionVariableOrigin) -> Diag<'tcx> { + fn report_inference_failure(&self, var_origin: RegionVariableOrigin) -> Diag<'_> { let br_string = |br: ty::BoundRegionKind| { let mut s = match br { ty::BrNamed(_, name) => name.to_string(), @@ -2829,7 +2830,7 @@ impl<'tcx> InferCtxt<'tcx> { }; struct_span_code_err!( - self.tcx.dcx(), + self.dcx(), var_origin.span(), E0495, "cannot infer an appropriate lifetime{} due to conflicting requirements", diff --git a/compiler/rustc_infer/src/infer/error_reporting/note.rs b/compiler/rustc_infer/src/infer/error_reporting/note.rs index e37b0b83f4d00..d1fc9c9f140b1 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/note.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/note.rs @@ -245,7 +245,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { }) } infer::CompareImplItemObligation { span, impl_item_def_id, trait_item_def_id } => { - let mut err = self.report_extra_impl_obligation( + let mut err = self.infcx.report_extra_impl_obligation( span, impl_item_def_id, trait_item_def_id, diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index 10471e8bbdd71..ff593d7ffb7df 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -685,7 +685,7 @@ impl<'tcx> InferOk<'tcx, ()> { impl<'tcx> InferCtxt<'tcx> { pub fn dcx(&self) -> DiagCtxtHandle<'_> { - self.tcx.dcx() + self.tcx.dcx().taintable_handle(&self.tainted_by_errors) } pub fn defining_opaque_types(&self) -> &'tcx ty::List { @@ -1089,19 +1089,7 @@ impl<'tcx> InferCtxt<'tcx> { /// inference variables, regionck errors). #[must_use = "this method does not have any side effects"] pub fn tainted_by_errors(&self) -> Option { - if let Some(guar) = self.tainted_by_errors.get() { - Some(guar) - } else if self.dcx().err_count_excluding_lint_errs() > self.err_count_on_creation { - // Errors reported since this infcx was made. Lint errors are - // excluded to avoid some being swallowed in the presence of - // non-lint errors. (It's arguable whether or not this exclusion is - // important.) - let guar = self.dcx().has_errors().unwrap(); - self.set_tainted_by_errors(guar); - Some(guar) - } else { - None - } + self.tainted_by_errors.get() } /// Set the "tainted by errors" flag to true. We call this when we @@ -1328,8 +1316,7 @@ impl<'tcx> InferCtxt<'tcx> { bug!("`{value:?}` is not fully resolved"); } if value.has_infer_regions() { - let guar = - self.tcx.dcx().delayed_bug(format!("`{value:?}` is not fully resolved")); + let guar = self.dcx().delayed_bug(format!("`{value:?}` is not fully resolved")); Ok(self.tcx.fold_regions(value, |re, _| { if re.is_var() { ty::Region::new_error(self.tcx, guar) } else { re } })) diff --git a/compiler/rustc_infer/src/infer/opaque_types/mod.rs b/compiler/rustc_infer/src/infer/opaque_types/mod.rs index b8dd501a721b5..7c764cccc4772 100644 --- a/compiler/rustc_infer/src/infer/opaque_types/mod.rs +++ b/compiler/rustc_infer/src/infer/opaque_types/mod.rs @@ -156,7 +156,7 @@ impl<'tcx> InferCtxt<'tcx> { if self.can_define_opaque_ty(b_def_id) && self.tcx.is_type_alias_impl_trait(b_def_id) { - self.tcx.dcx().emit_err(OpaqueHiddenTypeDiag { + self.dcx().emit_err(OpaqueHiddenTypeDiag { span, hidden_type: self.tcx.def_span(b_def_id), opaque_type: self.tcx.def_span(def_id), diff --git a/compiler/rustc_infer/src/traits/error_reporting/mod.rs b/compiler/rustc_infer/src/traits/error_reporting/mod.rs index 890e25368bc75..7730fe29e0933 100644 --- a/compiler/rustc_infer/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/traits/error_reporting/mod.rs @@ -12,15 +12,15 @@ use std::fmt; use std::iter; impl<'tcx> InferCtxt<'tcx> { - pub fn report_extra_impl_obligation( - &self, + pub fn report_extra_impl_obligation<'a>( + &'a self, error_span: Span, impl_item_def_id: LocalDefId, trait_item_def_id: DefId, requirement: &dyn fmt::Display, - ) -> Diag<'tcx> { + ) -> Diag<'a> { let mut err = struct_span_code_err!( - self.tcx.dcx(), + self.dcx(), error_span, E0276, "impl has stricter requirements than trait" diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs index 3ef3efc6252e9..adf1076a7c90e 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs @@ -1101,7 +1101,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { && let ty::FnPtr(sig) = by_ref_captures.kind() && !sig.skip_binder().output().is_unit() { - let mut err = self.tcx.dcx().create_err(AsyncClosureNotFn { + let mut err = self.dcx().create_err(AsyncClosureNotFn { span: self.tcx.def_span(closure_def_id), kind: expected_kind.as_str(), }); @@ -2884,7 +2884,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { self.suggest_unsized_bound_if_applicable(err, obligation); if let Some(span) = err.span.primary_span() && let Some(mut diag) = - self.tcx.dcx().steal_non_err(span, StashKey::AssociatedTypeSuggestion) + self.dcx().steal_non_err(span, StashKey::AssociatedTypeSuggestion) && let Ok(ref mut s1) = err.suggestions && let Ok(ref mut s2) = diag.suggestions { diff --git a/tests/ui/asm/x86_64/type-check-2.rs b/tests/ui/asm/x86_64/type-check-2.rs index c866f9fd8cc4d..4b5d59fdbc785 100644 --- a/tests/ui/asm/x86_64/type-check-2.rs +++ b/tests/ui/asm/x86_64/type-check-2.rs @@ -13,13 +13,16 @@ fn main() { let x: u64; asm!("{}", in(reg) x); + //~^ ERROR isn't initialized let mut y: u64; asm!("{}", inout(reg) y); + //~^ ERROR isn't initialized let _ = y; // Outputs require mutable places let v: Vec = vec![0, 1, 2]; + //~^ ERROR is not declared as mutable asm!("{}", in(reg) v[0]); asm!("{}", out(reg) v[0]); asm!("{}", inout(reg) v[0]); diff --git a/tests/ui/asm/x86_64/type-check-2.stderr b/tests/ui/asm/x86_64/type-check-2.stderr index 4f3d5100af056..6ae118b16e766 100644 --- a/tests/ui/asm/x86_64/type-check-2.stderr +++ b/tests/ui/asm/x86_64/type-check-2.stderr @@ -1,5 +1,5 @@ error: invalid `sym` operand - --> $DIR/type-check-2.rs:35:24 + --> $DIR/type-check-2.rs:38:24 | LL | asm!("{}", sym x); | ^ is a local variable @@ -7,7 +7,7 @@ LL | asm!("{}", sym x); = help: `sym` operands must refer to either a function or a static error: invalid `sym` operand - --> $DIR/type-check-2.rs:86:19 + --> $DIR/type-check-2.rs:89:19 | LL | global_asm!("{}", sym C); | ^^^^^ is an `i32` @@ -15,7 +15,7 @@ LL | global_asm!("{}", sym C); = help: `sym` operands must refer to either a function or a static error: invalid `sym` operand - --> $DIR/type-check-2.rs:33:20 + --> $DIR/type-check-2.rs:36:20 | LL | asm!("{}", sym C); | ^^^^^ is an `i32` @@ -23,15 +23,15 @@ LL | asm!("{}", sym C); = help: `sym` operands must refer to either a function or a static error: arguments for inline assembly must be copyable - --> $DIR/type-check-2.rs:40:32 + --> $DIR/type-check-2.rs:43:32 | LL | asm!("{}", in(xmm_reg) SimdNonCopy(0.0, 0.0, 0.0, 0.0)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: `SimdNonCopy` does not implement the Copy trait -error: cannot use value of type `{closure@$DIR/type-check-2.rs:52:28: 52:36}` for inline assembly - --> $DIR/type-check-2.rs:52:28 +error: cannot use value of type `{closure@$DIR/type-check-2.rs:55:28: 55:36}` for inline assembly + --> $DIR/type-check-2.rs:55:28 | LL | asm!("{}", in(reg) |x: i32| x); | ^^^^^^^^^^ @@ -39,7 +39,7 @@ LL | asm!("{}", in(reg) |x: i32| x); = note: only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly error: cannot use value of type `Vec` for inline assembly - --> $DIR/type-check-2.rs:54:28 + --> $DIR/type-check-2.rs:57:28 | LL | asm!("{}", in(reg) vec![0]); | ^^^^^^^ @@ -48,7 +48,7 @@ LL | asm!("{}", in(reg) vec![0]); = note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info) error: cannot use value of type `(i32, i32, i32)` for inline assembly - --> $DIR/type-check-2.rs:56:28 + --> $DIR/type-check-2.rs:59:28 | LL | asm!("{}", in(reg) (1, 2, 3)); | ^^^^^^^^^ @@ -56,7 +56,7 @@ LL | asm!("{}", in(reg) (1, 2, 3)); = note: only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly error: cannot use value of type `[i32; 3]` for inline assembly - --> $DIR/type-check-2.rs:58:28 + --> $DIR/type-check-2.rs:61:28 | LL | asm!("{}", in(reg) [1, 2, 3]); | ^^^^^^^^^ @@ -64,7 +64,7 @@ LL | asm!("{}", in(reg) [1, 2, 3]); = note: only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly error: cannot use value of type `fn() {main}` for inline assembly - --> $DIR/type-check-2.rs:66:31 + --> $DIR/type-check-2.rs:69:31 | LL | asm!("{}", inout(reg) f); | ^ @@ -72,12 +72,56 @@ LL | asm!("{}", inout(reg) f); = note: only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly error: cannot use value of type `&mut i32` for inline assembly - --> $DIR/type-check-2.rs:69:31 + --> $DIR/type-check-2.rs:72:31 | LL | asm!("{}", inout(reg) r); | ^ | = note: only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly -error: aborting due to 10 previous errors +error[E0381]: used binding `x` isn't initialized + --> $DIR/type-check-2.rs:15:28 + | +LL | let x: u64; + | - binding declared here but left uninitialized +LL | asm!("{}", in(reg) x); + | ^ `x` used here but it isn't initialized + | +help: consider assigning a value + | +LL | let x: u64 = 42; + | ++++ + +error[E0381]: used binding `y` isn't initialized + --> $DIR/type-check-2.rs:18:9 + | +LL | let mut y: u64; + | ----- binding declared here but left uninitialized +LL | asm!("{}", inout(reg) y); + | ^^^^^^^^^^^^^^^^^^^^^^^^ `y` used here but it isn't initialized + | +help: consider assigning a value + | +LL | let mut y: u64 = 42; + | ++++ + +error[E0596]: cannot borrow `v` as mutable, as it is not declared as mutable + --> $DIR/type-check-2.rs:24:13 + | +LL | let v: Vec = vec![0, 1, 2]; + | ^ not mutable +... +LL | asm!("{}", out(reg) v[0]); + | - cannot borrow as mutable +LL | asm!("{}", inout(reg) v[0]); + | - cannot borrow as mutable + | +help: consider changing this to be mutable + | +LL | let mut v: Vec = vec![0, 1, 2]; + | +++ + +error: aborting due to 13 previous errors +Some errors have detailed explanations: E0381, E0596. +For more information about an error, try `rustc --explain E0381`. diff --git a/tests/ui/associated-types/associated-types-eq-expr-path.rs b/tests/ui/associated-types/associated-types-eq-expr-path.rs index 4561e596c6658..67831f913039a 100644 --- a/tests/ui/associated-types/associated-types-eq-expr-path.rs +++ b/tests/ui/associated-types/associated-types-eq-expr-path.rs @@ -13,4 +13,5 @@ impl Foo for isize { pub fn main() { let x: isize = Foo::::bar(); //~^ ERROR associated item constraints are not allowed here + //~| ERROR cannot call } diff --git a/tests/ui/associated-types/associated-types-eq-expr-path.stderr b/tests/ui/associated-types/associated-types-eq-expr-path.stderr index 3d0e3e61eca90..4f28b3cb2de33 100644 --- a/tests/ui/associated-types/associated-types-eq-expr-path.stderr +++ b/tests/ui/associated-types/associated-types-eq-expr-path.stderr @@ -4,6 +4,22 @@ error[E0229]: associated item constraints are not allowed here LL | let x: isize = Foo::::bar(); | ^^^^^^^^^ associated item constraint not allowed here -error: aborting due to 1 previous error +error[E0790]: cannot call associated function on trait without specifying the corresponding `impl` type + --> $DIR/associated-types-eq-expr-path.rs:14:20 + | +LL | fn bar() -> isize; + | ------------------ `Foo::bar` defined here +... +LL | let x: isize = Foo::::bar(); + | ^^^^^^^^^^^^^^^^^^^^^^^ cannot call associated function of trait + | +help: use the fully-qualified path to the only available implementation + | +LL - let x: isize = Foo::::bar(); +LL + let x: isize = >::bar(); + | + +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0229`. +Some errors have detailed explanations: E0229, E0790. +For more information about an error, try `rustc --explain E0229`. diff --git a/tests/ui/const-generics/assoc_const_as_type_argument.rs b/tests/ui/const-generics/assoc_const_as_type_argument.rs index ffc7f116a94ef..bec6102417c5f 100644 --- a/tests/ui/const-generics/assoc_const_as_type_argument.rs +++ b/tests/ui/const-generics/assoc_const_as_type_argument.rs @@ -8,6 +8,7 @@ fn foo() { bar::<::ASSOC>(); //~^ ERROR: expected associated type, found associated constant `Trait::ASSOC` //~| ERROR: unresolved item provided when a constant was expected + //~| ERROR type annotations needed } fn main() {} diff --git a/tests/ui/const-generics/assoc_const_as_type_argument.stderr b/tests/ui/const-generics/assoc_const_as_type_argument.stderr index ac00954613506..53edc19b28ca2 100644 --- a/tests/ui/const-generics/assoc_const_as_type_argument.stderr +++ b/tests/ui/const-generics/assoc_const_as_type_argument.stderr @@ -15,7 +15,19 @@ help: if this generic argument was intended as a const parameter, surround it wi LL | bar::<{ ::ASSOC }>(); | + + -error: aborting due to 2 previous errors +error[E0284]: type annotations needed + --> $DIR/assoc_const_as_type_argument.rs:8:5 + | +LL | bar::<::ASSOC>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer the value of the const parameter `N` declared on the function `bar` + | +note: required by a const generic parameter in `bar` + --> $DIR/assoc_const_as_type_argument.rs:5:8 + | +LL | fn bar() {} + | ^^^^^^^^^^^^^^ required by this const generic parameter in `bar` + +error: aborting due to 3 previous errors -Some errors have detailed explanations: E0575, E0747. -For more information about an error, try `rustc --explain E0575`. +Some errors have detailed explanations: E0284, E0575, E0747. +For more information about an error, try `rustc --explain E0284`. diff --git a/tests/ui/const-generics/const-arg-in-const-arg.min.stderr b/tests/ui/const-generics/const-arg-in-const-arg.min.stderr index ce7fce2599360..2ea9d6b35b451 100644 --- a/tests/ui/const-generics/const-arg-in-const-arg.min.stderr +++ b/tests/ui/const-generics/const-arg-in-const-arg.min.stderr @@ -17,7 +17,7 @@ LL | let _: [u8; bar::()]; = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations - --> $DIR/const-arg-in-const-arg.rs:18:23 + --> $DIR/const-arg-in-const-arg.rs:19:23 | LL | let _: [u8; faz::<'a>(&())]; | ^^ cannot perform const operation using `'a` @@ -26,7 +26,7 @@ LL | let _: [u8; faz::<'a>(&())]; = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations - --> $DIR/const-arg-in-const-arg.rs:20:23 + --> $DIR/const-arg-in-const-arg.rs:21:23 | LL | let _: [u8; baz::<'a>(&())]; | ^^ cannot perform const operation using `'a` @@ -35,7 +35,7 @@ LL | let _: [u8; baz::<'a>(&())]; = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations - --> $DIR/const-arg-in-const-arg.rs:21:23 + --> $DIR/const-arg-in-const-arg.rs:22:23 | LL | let _: [u8; faz::<'b>(&())]; | ^^ cannot perform const operation using `'b` @@ -44,7 +44,7 @@ LL | let _: [u8; faz::<'b>(&())]; = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations - --> $DIR/const-arg-in-const-arg.rs:23:23 + --> $DIR/const-arg-in-const-arg.rs:24:23 | LL | let _: [u8; baz::<'b>(&())]; | ^^ cannot perform const operation using `'b` @@ -53,7 +53,7 @@ LL | let _: [u8; baz::<'b>(&())]; = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations - --> $DIR/const-arg-in-const-arg.rs:26:23 + --> $DIR/const-arg-in-const-arg.rs:27:23 | LL | let _ = [0; bar::()]; | ^ cannot perform const operation using `N` @@ -62,7 +62,7 @@ LL | let _ = [0; bar::()]; = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations - --> $DIR/const-arg-in-const-arg.rs:28:23 + --> $DIR/const-arg-in-const-arg.rs:30:23 | LL | let _ = [0; faz::<'a>(&())]; | ^^ cannot perform const operation using `'a` @@ -71,7 +71,7 @@ LL | let _ = [0; faz::<'a>(&())]; = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations - --> $DIR/const-arg-in-const-arg.rs:30:23 + --> $DIR/const-arg-in-const-arg.rs:32:23 | LL | let _ = [0; baz::<'a>(&())]; | ^^ cannot perform const operation using `'a` @@ -80,7 +80,7 @@ LL | let _ = [0; baz::<'a>(&())]; = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations - --> $DIR/const-arg-in-const-arg.rs:31:23 + --> $DIR/const-arg-in-const-arg.rs:33:23 | LL | let _ = [0; faz::<'b>(&())]; | ^^ cannot perform const operation using `'b` @@ -89,7 +89,7 @@ LL | let _ = [0; faz::<'b>(&())]; = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations - --> $DIR/const-arg-in-const-arg.rs:33:23 + --> $DIR/const-arg-in-const-arg.rs:35:23 | LL | let _ = [0; baz::<'b>(&())]; | ^^ cannot perform const operation using `'b` @@ -98,7 +98,7 @@ LL | let _ = [0; baz::<'b>(&())]; = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations - --> $DIR/const-arg-in-const-arg.rs:34:24 + --> $DIR/const-arg-in-const-arg.rs:36:24 | LL | let _: Foo<{ foo::() }>; | ^ cannot perform const operation using `T` @@ -107,7 +107,7 @@ LL | let _: Foo<{ foo::() }>; = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations - --> $DIR/const-arg-in-const-arg.rs:35:24 + --> $DIR/const-arg-in-const-arg.rs:37:24 | LL | let _: Foo<{ bar::() }>; | ^ cannot perform const operation using `N` @@ -116,7 +116,7 @@ LL | let _: Foo<{ bar::() }>; = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations - --> $DIR/const-arg-in-const-arg.rs:37:24 + --> $DIR/const-arg-in-const-arg.rs:40:24 | LL | let _: Foo<{ faz::<'a>(&()) }>; | ^^ cannot perform const operation using `'a` @@ -125,7 +125,7 @@ LL | let _: Foo<{ faz::<'a>(&()) }>; = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations - --> $DIR/const-arg-in-const-arg.rs:39:24 + --> $DIR/const-arg-in-const-arg.rs:42:24 | LL | let _: Foo<{ baz::<'a>(&()) }>; | ^^ cannot perform const operation using `'a` @@ -134,7 +134,7 @@ LL | let _: Foo<{ baz::<'a>(&()) }>; = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations - --> $DIR/const-arg-in-const-arg.rs:40:24 + --> $DIR/const-arg-in-const-arg.rs:43:24 | LL | let _: Foo<{ faz::<'b>(&()) }>; | ^^ cannot perform const operation using `'b` @@ -143,7 +143,7 @@ LL | let _: Foo<{ faz::<'b>(&()) }>; = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations - --> $DIR/const-arg-in-const-arg.rs:42:24 + --> $DIR/const-arg-in-const-arg.rs:45:24 | LL | let _: Foo<{ baz::<'b>(&()) }>; | ^^ cannot perform const operation using `'b` @@ -152,7 +152,7 @@ LL | let _: Foo<{ baz::<'b>(&()) }>; = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations - --> $DIR/const-arg-in-const-arg.rs:43:27 + --> $DIR/const-arg-in-const-arg.rs:46:27 | LL | let _ = Foo::<{ foo::() }>; | ^ cannot perform const operation using `T` @@ -161,7 +161,7 @@ LL | let _ = Foo::<{ foo::() }>; = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations - --> $DIR/const-arg-in-const-arg.rs:44:27 + --> $DIR/const-arg-in-const-arg.rs:47:27 | LL | let _ = Foo::<{ bar::() }>; | ^ cannot perform const operation using `N` @@ -170,7 +170,7 @@ LL | let _ = Foo::<{ bar::() }>; = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations - --> $DIR/const-arg-in-const-arg.rs:46:27 + --> $DIR/const-arg-in-const-arg.rs:50:27 | LL | let _ = Foo::<{ faz::<'a>(&()) }>; | ^^ cannot perform const operation using `'a` @@ -179,7 +179,7 @@ LL | let _ = Foo::<{ faz::<'a>(&()) }>; = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations - --> $DIR/const-arg-in-const-arg.rs:48:27 + --> $DIR/const-arg-in-const-arg.rs:52:27 | LL | let _ = Foo::<{ baz::<'a>(&()) }>; | ^^ cannot perform const operation using `'a` @@ -188,7 +188,7 @@ LL | let _ = Foo::<{ baz::<'a>(&()) }>; = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations - --> $DIR/const-arg-in-const-arg.rs:49:27 + --> $DIR/const-arg-in-const-arg.rs:53:27 | LL | let _ = Foo::<{ faz::<'b>(&()) }>; | ^^ cannot perform const operation using `'b` @@ -197,7 +197,7 @@ LL | let _ = Foo::<{ faz::<'b>(&()) }>; = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations - --> $DIR/const-arg-in-const-arg.rs:51:27 + --> $DIR/const-arg-in-const-arg.rs:55:27 | LL | let _ = Foo::<{ baz::<'b>(&()) }>; | ^^ cannot perform const operation using `'b` @@ -216,8 +216,20 @@ help: if this generic argument was intended as a const parameter, surround it wi LL | let _: [u8; bar::<{ N }>()]; | + + +error[E0284]: type annotations needed + --> $DIR/const-arg-in-const-arg.rs:16:17 + | +LL | let _: [u8; bar::()]; + | ^^^^^^^^ cannot infer the value of the const parameter `N` declared on the function `bar` + | +note: required by a const generic parameter in `bar` + --> $DIR/const-arg-in-const-arg.rs:9:14 + | +LL | const fn bar() -> usize { N } + | ^^^^^^^^^^^^^^ required by this const generic parameter in `bar` + error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present - --> $DIR/const-arg-in-const-arg.rs:18:23 + --> $DIR/const-arg-in-const-arg.rs:19:23 | LL | let _: [u8; faz::<'a>(&())]; | ^^ @@ -229,7 +241,7 @@ LL | const fn faz<'a>(_: &'a ()) -> usize { 13 } | ^^ error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present - --> $DIR/const-arg-in-const-arg.rs:21:23 + --> $DIR/const-arg-in-const-arg.rs:22:23 | LL | let _: [u8; faz::<'b>(&())]; | ^^ @@ -241,7 +253,7 @@ LL | const fn faz<'a>(_: &'a ()) -> usize { 13 } | ^^ error[E0747]: unresolved item provided when a constant was expected - --> $DIR/const-arg-in-const-arg.rs:35:24 + --> $DIR/const-arg-in-const-arg.rs:37:24 | LL | let _: Foo<{ bar::() }>; | ^ @@ -251,8 +263,20 @@ help: if this generic argument was intended as a const parameter, surround it wi LL | let _: Foo<{ bar::<{ N }>() }>; | + + +error[E0284]: type annotations needed + --> $DIR/const-arg-in-const-arg.rs:37:18 + | +LL | let _: Foo<{ bar::() }>; + | ^^^^^^^^ cannot infer the value of the const parameter `N` declared on the function `bar` + | +note: required by a const generic parameter in `bar` + --> $DIR/const-arg-in-const-arg.rs:9:14 + | +LL | const fn bar() -> usize { N } + | ^^^^^^^^^^^^^^ required by this const generic parameter in `bar` + error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present - --> $DIR/const-arg-in-const-arg.rs:37:24 + --> $DIR/const-arg-in-const-arg.rs:40:24 | LL | let _: Foo<{ faz::<'a>(&()) }>; | ^^ @@ -264,7 +288,7 @@ LL | const fn faz<'a>(_: &'a ()) -> usize { 13 } | ^^ error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present - --> $DIR/const-arg-in-const-arg.rs:40:24 + --> $DIR/const-arg-in-const-arg.rs:43:24 | LL | let _: Foo<{ faz::<'b>(&()) }>; | ^^ @@ -276,7 +300,7 @@ LL | const fn faz<'a>(_: &'a ()) -> usize { 13 } | ^^ error: constant expression depends on a generic parameter - --> $DIR/const-arg-in-const-arg.rs:25:17 + --> $DIR/const-arg-in-const-arg.rs:26:17 | LL | let _ = [0; foo::()]; | ^^^^^^^^^^ @@ -284,7 +308,7 @@ LL | let _ = [0; foo::()]; = note: this may fail depending on what value the parameter takes error[E0747]: unresolved item provided when a constant was expected - --> $DIR/const-arg-in-const-arg.rs:26:23 + --> $DIR/const-arg-in-const-arg.rs:27:23 | LL | let _ = [0; bar::()]; | ^ @@ -294,8 +318,20 @@ help: if this generic argument was intended as a const parameter, surround it wi LL | let _ = [0; bar::<{ N }>()]; | + + +error[E0284]: type annotations needed + --> $DIR/const-arg-in-const-arg.rs:27:17 + | +LL | let _ = [0; bar::()]; + | ^^^^^^^^ cannot infer the value of the const parameter `N` declared on the function `bar` + | +note: required by a const generic parameter in `bar` + --> $DIR/const-arg-in-const-arg.rs:9:14 + | +LL | const fn bar() -> usize { N } + | ^^^^^^^^^^^^^^ required by this const generic parameter in `bar` + error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present - --> $DIR/const-arg-in-const-arg.rs:28:23 + --> $DIR/const-arg-in-const-arg.rs:30:23 | LL | let _ = [0; faz::<'a>(&())]; | ^^ @@ -307,7 +343,7 @@ LL | const fn faz<'a>(_: &'a ()) -> usize { 13 } | ^^ error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present - --> $DIR/const-arg-in-const-arg.rs:31:23 + --> $DIR/const-arg-in-const-arg.rs:33:23 | LL | let _ = [0; faz::<'b>(&())]; | ^^ @@ -319,7 +355,7 @@ LL | const fn faz<'a>(_: &'a ()) -> usize { 13 } | ^^ error[E0747]: unresolved item provided when a constant was expected - --> $DIR/const-arg-in-const-arg.rs:44:27 + --> $DIR/const-arg-in-const-arg.rs:47:27 | LL | let _ = Foo::<{ bar::() }>; | ^ @@ -329,8 +365,20 @@ help: if this generic argument was intended as a const parameter, surround it wi LL | let _ = Foo::<{ bar::<{ N }>() }>; | + + +error[E0284]: type annotations needed + --> $DIR/const-arg-in-const-arg.rs:47:21 + | +LL | let _ = Foo::<{ bar::() }>; + | ^^^^^^^^ cannot infer the value of the const parameter `N` declared on the function `bar` + | +note: required by a const generic parameter in `bar` + --> $DIR/const-arg-in-const-arg.rs:9:14 + | +LL | const fn bar() -> usize { N } + | ^^^^^^^^^^^^^^ required by this const generic parameter in `bar` + error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present - --> $DIR/const-arg-in-const-arg.rs:46:27 + --> $DIR/const-arg-in-const-arg.rs:50:27 | LL | let _ = Foo::<{ faz::<'a>(&()) }>; | ^^ @@ -342,7 +390,7 @@ LL | const fn faz<'a>(_: &'a ()) -> usize { 13 } | ^^ error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present - --> $DIR/const-arg-in-const-arg.rs:49:27 + --> $DIR/const-arg-in-const-arg.rs:53:27 | LL | let _ = Foo::<{ faz::<'b>(&()) }>; | ^^ @@ -353,7 +401,7 @@ note: the late bound lifetime parameter is introduced here LL | const fn faz<'a>(_: &'a ()) -> usize { 13 } | ^^ -error: aborting due to 36 previous errors +error: aborting due to 40 previous errors -Some errors have detailed explanations: E0747, E0794. -For more information about an error, try `rustc --explain E0747`. +Some errors have detailed explanations: E0284, E0747, E0794. +For more information about an error, try `rustc --explain E0284`. diff --git a/tests/ui/const-generics/const-arg-in-const-arg.rs b/tests/ui/const-generics/const-arg-in-const-arg.rs index 27b74489fe8e0..b95c63309f782 100644 --- a/tests/ui/const-generics/const-arg-in-const-arg.rs +++ b/tests/ui/const-generics/const-arg-in-const-arg.rs @@ -15,6 +15,7 @@ fn test<'a, 'b, T, const N: usize>() where &'b (): Sized { let _: [u8; foo::()]; //[min]~ ERROR generic parameters may not let _: [u8; bar::()]; //[min]~ ERROR generic parameters may not //[min]~^ ERROR unresolved item provided when a constant was expected + //[min]~| ERROR type annotations needed let _: [u8; faz::<'a>(&())]; //[min]~ ERROR generic parameters may not //[min]~^ ERROR cannot specify lifetime arguments let _: [u8; baz::<'a>(&())]; //[min]~ ERROR generic parameters may not @@ -25,6 +26,7 @@ fn test<'a, 'b, T, const N: usize>() where &'b (): Sized { let _ = [0; foo::()]; //[min]~ ERROR constant expression depends on a generic parameter let _ = [0; bar::()]; //[min]~ ERROR generic parameters may not //[min]~^ ERROR unresolved item provided when a constant was expected + //[min]~| ERROR type annotations needed let _ = [0; faz::<'a>(&())]; //[min]~ ERROR generic parameters may not //[min]~^ ERROR cannot specify lifetime arguments let _ = [0; baz::<'a>(&())]; //[min]~ ERROR generic parameters may not @@ -34,6 +36,7 @@ fn test<'a, 'b, T, const N: usize>() where &'b (): Sized { let _: Foo<{ foo::() }>; //[min]~ ERROR generic parameters may not let _: Foo<{ bar::() }>; //[min]~ ERROR generic parameters may not //[min]~^ ERROR unresolved item provided when a constant was expected + //[min]~| ERROR type annotations needed let _: Foo<{ faz::<'a>(&()) }>; //[min]~ ERROR generic parameters may not //[min]~^ ERROR cannot specify lifetime arguments let _: Foo<{ baz::<'a>(&()) }>; //[min]~ ERROR generic parameters may not @@ -43,6 +46,7 @@ fn test<'a, 'b, T, const N: usize>() where &'b (): Sized { let _ = Foo::<{ foo::() }>; //[min]~ ERROR generic parameters may not let _ = Foo::<{ bar::() }>; //[min]~ ERROR generic parameters may not //[min]~^ ERROR unresolved item provided when a constant was expected + //[min]~| ERROR type annotations needed let _ = Foo::<{ faz::<'a>(&()) }>; //[min]~ ERROR generic parameters may not //[min]~^ ERROR cannot specify lifetime arguments let _ = Foo::<{ baz::<'a>(&()) }>; //[min]~ ERROR generic parameters may not diff --git a/tests/ui/const-generics/generic_const_exprs/opaque_type.rs b/tests/ui/const-generics/generic_const_exprs/opaque_type.rs index 56b8acbf88cde..7209290a36e0a 100644 --- a/tests/ui/const-generics/generic_const_exprs/opaque_type.rs +++ b/tests/ui/const-generics/generic_const_exprs/opaque_type.rs @@ -2,6 +2,7 @@ #![allow(incomplete_features)] type Foo = impl Sized; +//~^ ERROR: unconstrained opaque type fn with_bound() -> Foo where diff --git a/tests/ui/const-generics/generic_const_exprs/opaque_type.stderr b/tests/ui/const-generics/generic_const_exprs/opaque_type.stderr index e9fb8c0f403ae..c7a266205b4b5 100644 --- a/tests/ui/const-generics/generic_const_exprs/opaque_type.stderr +++ b/tests/ui/const-generics/generic_const_exprs/opaque_type.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/opaque_type.rs:10:17 + --> $DIR/opaque_type.rs:11:17 | LL | type Foo = impl Sized; | ---------- the found opaque type @@ -11,12 +11,20 @@ LL | let _: [u8; (N / 2) as Foo] = [0; (N / 2) as usize]; found opaque type `Foo` error[E0605]: non-primitive cast: `usize` as `Foo` - --> $DIR/opaque_type.rs:10:17 + --> $DIR/opaque_type.rs:11:17 | LL | let _: [u8; (N / 2) as Foo] = [0; (N / 2) as usize]; | ^^^^^^^^^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object -error: aborting due to 2 previous errors +error: unconstrained opaque type + --> $DIR/opaque_type.rs:4:12 + | +LL | type Foo = impl Sized; + | ^^^^^^^^^^ + | + = note: `Foo` must be used in combination with a concrete type within the same module + +error: aborting due to 3 previous errors Some errors have detailed explanations: E0308, E0605. For more information about an error, try `rustc --explain E0308`. diff --git a/tests/ui/const-generics/issues/issue-62878.min.stderr b/tests/ui/const-generics/issues/issue-62878.min.stderr index 5205726d73845..3fd50bbe29803 100644 --- a/tests/ui/const-generics/issues/issue-62878.min.stderr +++ b/tests/ui/const-generics/issues/issue-62878.min.stderr @@ -30,7 +30,31 @@ help: add `#![feature(generic_arg_infer)]` to the crate attributes to enable LL + #![feature(generic_arg_infer)] | -error: aborting due to 3 previous errors +error[E0284]: type annotations needed + --> $DIR/issue-62878.rs:10:5 + | +LL | foo::<_, { [1] }>(); + | ^^^^^^^^^^^^^^^^^ cannot infer the value of the const parameter `N` declared on the function `foo` + | +note: required by a const generic parameter in `foo` + --> $DIR/issue-62878.rs:5:8 + | +LL | fn foo() {} + | ^^^^^^^^^^^^^^ required by this const generic parameter in `foo` + +error[E0284]: type annotations needed + --> $DIR/issue-62878.rs:10:5 + | +LL | foo::<_, { [1] }>(); + | ^^^^^^^^^^^^^^^^^ cannot infer the value of the const parameter `A` declared on the function `foo` + | +note: required by a const generic parameter in `foo` + --> $DIR/issue-62878.rs:5:24 + | +LL | fn foo() {} + | ^^^^^^^^^^^^^^^^ required by this const generic parameter in `foo` + +error: aborting due to 5 previous errors -Some errors have detailed explanations: E0747, E0770. -For more information about an error, try `rustc --explain E0747`. +Some errors have detailed explanations: E0284, E0747, E0770. +For more information about an error, try `rustc --explain E0284`. diff --git a/tests/ui/const-generics/issues/issue-62878.rs b/tests/ui/const-generics/issues/issue-62878.rs index 0b5269df85ee1..c784e95edd824 100644 --- a/tests/ui/const-generics/issues/issue-62878.rs +++ b/tests/ui/const-generics/issues/issue-62878.rs @@ -9,4 +9,6 @@ fn foo() {} fn main() { foo::<_, { [1] }>(); //[min]~^ ERROR: type provided when a constant was expected + //[min]~| ERROR type annotations needed + //[min]~| ERROR type annotations needed } diff --git a/tests/ui/const-generics/min_const_generics/const-expression-suggest-missing-braces.rs b/tests/ui/const-generics/min_const_generics/const-expression-suggest-missing-braces.rs index e12e07a28e763..497c020bde43e 100644 --- a/tests/ui/const-generics/min_const_generics/const-expression-suggest-missing-braces.rs +++ b/tests/ui/const-generics/min_const_generics/const-expression-suggest-missing-braces.rs @@ -12,6 +12,7 @@ fn b() { //~^ ERROR expected trait, found constant `BAR` //~| ERROR expected trait, found constant `BAR` //~| ERROR type provided when a constant was expected + //~| ERROR type annotations needed } fn c() { foo::<3 + 3>(); //~ ERROR expressions must be enclosed in braces diff --git a/tests/ui/const-generics/min_const_generics/const-expression-suggest-missing-braces.stderr b/tests/ui/const-generics/min_const_generics/const-expression-suggest-missing-braces.stderr index d9bcc523b1fc4..c2ba517f60960 100644 --- a/tests/ui/const-generics/min_const_generics/const-expression-suggest-missing-braces.stderr +++ b/tests/ui/const-generics/min_const_generics/const-expression-suggest-missing-braces.stderr @@ -10,7 +10,7 @@ LL | foo::<{ BAR + 3 }>(); | + + error: expressions must be enclosed in braces to be used as const generic arguments - --> $DIR/const-expression-suggest-missing-braces.rs:17:11 + --> $DIR/const-expression-suggest-missing-braces.rs:18:11 | LL | foo::<3 + 3>(); | ^^^^^ @@ -21,7 +21,7 @@ LL | foo::<{ 3 + 3 }>(); | + + error: expected one of `,` or `>`, found `-` - --> $DIR/const-expression-suggest-missing-braces.rs:20:15 + --> $DIR/const-expression-suggest-missing-braces.rs:21:15 | LL | foo::(); | ^ expected one of `,` or `>` @@ -32,7 +32,7 @@ LL | foo::<{ BAR - 3 }>(); | + + error: expected one of `,` or `>`, found `-` - --> $DIR/const-expression-suggest-missing-braces.rs:23:15 + --> $DIR/const-expression-suggest-missing-braces.rs:24:15 | LL | foo::(); | ^ expected one of `,` or `>` @@ -43,7 +43,7 @@ LL | foo::<{ BAR - BAR }>(); | + + error: expressions must be enclosed in braces to be used as const generic arguments - --> $DIR/const-expression-suggest-missing-braces.rs:26:11 + --> $DIR/const-expression-suggest-missing-braces.rs:27:11 | LL | foo::<100 - BAR>(); | ^^^^^^^^^ @@ -54,7 +54,7 @@ LL | foo::<{ 100 - BAR }>(); | + + error: expected one of `,` or `>`, found `(` - --> $DIR/const-expression-suggest-missing-braces.rs:29:19 + --> $DIR/const-expression-suggest-missing-braces.rs:30:19 | LL | foo::()>(); | ^ expected one of `,` or `>` @@ -65,7 +65,7 @@ LL | foo::<{ bar() }>(); | + + error: expected one of `,` or `>`, found `(` - --> $DIR/const-expression-suggest-missing-braces.rs:32:21 + --> $DIR/const-expression-suggest-missing-braces.rs:33:21 | LL | foo::()>(); | ^ expected one of `,` or `>` @@ -76,7 +76,7 @@ LL | foo::<{ bar::() }>(); | + + error: expected one of `,` or `>`, found `(` - --> $DIR/const-expression-suggest-missing-braces.rs:35:21 + --> $DIR/const-expression-suggest-missing-braces.rs:36:21 | LL | foo::() + BAR>(); | ^ expected one of `,` or `>` @@ -87,7 +87,7 @@ LL | foo::<{ bar::() + BAR }>(); | + + error: expected one of `,` or `>`, found `(` - --> $DIR/const-expression-suggest-missing-braces.rs:38:21 + --> $DIR/const-expression-suggest-missing-braces.rs:39:21 | LL | foo::() - BAR>(); | ^ expected one of `,` or `>` @@ -98,7 +98,7 @@ LL | foo::<{ bar::() - BAR }>(); | + + error: expected one of `,` or `>`, found `-` - --> $DIR/const-expression-suggest-missing-braces.rs:41:15 + --> $DIR/const-expression-suggest-missing-braces.rs:42:15 | LL | foo::()>(); | ^ expected one of `,` or `>` @@ -109,7 +109,7 @@ LL | foo::<{ BAR - bar::() }>(); | + + error: expected one of `,` or `>`, found `-` - --> $DIR/const-expression-suggest-missing-braces.rs:44:15 + --> $DIR/const-expression-suggest-missing-braces.rs:45:15 | LL | foo::()>(); | ^ expected one of `,` or `>` @@ -137,7 +137,19 @@ error[E0747]: type provided when a constant was expected LL | foo::(); | ^^^^^^^^^ -error: aborting due to 14 previous errors +error[E0284]: type annotations needed + --> $DIR/const-expression-suggest-missing-braces.rs:11:5 + | +LL | foo::(); + | ^^^^^^^^^^^^^^^^ cannot infer the value of the const parameter `C` declared on the function `foo` + | +note: required by a const generic parameter in `foo` + --> $DIR/const-expression-suggest-missing-braces.rs:1:8 + | +LL | fn foo() {} + | ^^^^^^^^^^^^^^ required by this const generic parameter in `foo` + +error: aborting due to 15 previous errors -Some errors have detailed explanations: E0404, E0747. -For more information about an error, try `rustc --explain E0404`. +Some errors have detailed explanations: E0284, E0404, E0747. +For more information about an error, try `rustc --explain E0284`. diff --git a/tests/ui/const-generics/min_const_generics/macro-fail.rs b/tests/ui/const-generics/min_const_generics/macro-fail.rs index 2f101ecfb1f7a..25726490c2cca 100644 --- a/tests/ui/const-generics/min_const_generics/macro-fail.rs +++ b/tests/ui/const-generics/min_const_generics/macro-fail.rs @@ -16,6 +16,7 @@ fn make_marker() -> impl Marker { //~| ERROR: type provided when a constant was expected Example:: //~^ ERROR: type provided when a constant was expected + //~| ERROR type annotations needed } fn from_marker(_: impl Marker<{ @@ -35,9 +36,11 @@ fn main() { }>; let _fail = Example::; - //~^ ERROR: type provided when a constant was expected + //~^ ERROR: type provided when a constant + //~| ERROR type annotations needed let _fail = Example::; //~^ ERROR unexpected end of macro invocation //~| ERROR: type provided when a constant was expected + //~| ERROR type annotations needed } diff --git a/tests/ui/const-generics/min_const_generics/macro-fail.stderr b/tests/ui/const-generics/min_const_generics/macro-fail.stderr index 34764982bb046..4e183fe5b1c55 100644 --- a/tests/ui/const-generics/min_const_generics/macro-fail.stderr +++ b/tests/ui/const-generics/min_const_generics/macro-fail.stderr @@ -1,5 +1,5 @@ error: expected type, found `{` - --> $DIR/macro-fail.rs:30:27 + --> $DIR/macro-fail.rs:31:27 | LL | fn make_marker() -> impl Marker { | ---------------------- @@ -13,7 +13,7 @@ LL | ($rusty: ident) => {{ let $rusty = 3; *&$rusty }} = note: this error originates in the macro `gimme_a_const` (in Nightly builds, run with -Z macro-backtrace for more info) error: expected type, found `{` - --> $DIR/macro-fail.rs:30:27 + --> $DIR/macro-fail.rs:31:27 | LL | Example:: | ---------------------- @@ -41,7 +41,7 @@ LL | let _fail = Example::; = note: this error originates in the macro `external_macro` (in Nightly builds, run with -Z macro-backtrace for more info) error: unexpected end of macro invocation - --> $DIR/macro-fail.rs:40:25 + --> $DIR/macro-fail.rs:42:25 | LL | macro_rules! gimme_a_const { | -------------------------- when calling this macro @@ -50,7 +50,7 @@ LL | let _fail = Example::; | ^^^^^^^^^^^^^^^^ missing tokens in macro arguments | note: while trying to match meta-variable `$rusty:ident` - --> $DIR/macro-fail.rs:30:8 + --> $DIR/macro-fail.rs:31:8 | LL | ($rusty: ident) => {{ let $rusty = 3; *&$rusty }} | ^^^^^^^^^^^^^ @@ -75,18 +75,63 @@ error[E0747]: type provided when a constant was expected LL | Example:: | ^^^^^^^^^^^^^^^^^^^^^^ +error[E0284]: type annotations needed + --> $DIR/macro-fail.rs:17:3 + | +LL | Example:: + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer the value of the const parameter `N` declared on the struct `Example` + | +note: required by a const generic parameter in `Example` + --> $DIR/macro-fail.rs:1:16 + | +LL | struct Example; + | ^^^^^^^^^^^^^^ required by this const generic parameter in `Example` + error[E0747]: type provided when a constant was expected - --> $DIR/macro-fail.rs:37:25 + --> $DIR/macro-fail.rs:38:25 | LL | let _fail = Example::; | ^^^^^^^^^^^^^^^^^ error[E0747]: type provided when a constant was expected - --> $DIR/macro-fail.rs:40:25 + --> $DIR/macro-fail.rs:42:25 | LL | let _fail = Example::; | ^^^^^^^^^^^^^^^^ -error: aborting due to 9 previous errors +error[E0284]: type annotations needed for `Example<_>` + --> $DIR/macro-fail.rs:38:7 + | +LL | let _fail = Example::; + | ^^^^^ ---------------------------- type must be known at this point + | +note: required by a const generic parameter in `Example` + --> $DIR/macro-fail.rs:1:16 + | +LL | struct Example; + | ^^^^^^^^^^^^^^ required by this const generic parameter in `Example` +help: consider giving `_fail` an explicit type, where the value of const parameter `N` is specified + | +LL | let _fail: Example = Example::; + | ++++++++++++ + +error[E0284]: type annotations needed for `Example<_>` + --> $DIR/macro-fail.rs:42:7 + | +LL | let _fail = Example::; + | ^^^^^ --------------------------- type must be known at this point + | +note: required by a const generic parameter in `Example` + --> $DIR/macro-fail.rs:1:16 + | +LL | struct Example; + | ^^^^^^^^^^^^^^ required by this const generic parameter in `Example` +help: consider giving `_fail` an explicit type, where the value of const parameter `N` is specified + | +LL | let _fail: Example = Example::; + | ++++++++++++ + +error: aborting due to 12 previous errors -For more information about this error, try `rustc --explain E0747`. +Some errors have detailed explanations: E0284, E0747. +For more information about an error, try `rustc --explain E0284`. diff --git a/tests/ui/const-generics/suggest_const_for_array.rs b/tests/ui/const-generics/suggest_const_for_array.rs index f3e5a3186cdd6..4d29d0693759f 100644 --- a/tests/ui/const-generics/suggest_const_for_array.rs +++ b/tests/ui/const-generics/suggest_const_for_array.rs @@ -3,8 +3,10 @@ fn example() {} fn other() { - example::<[usize; 3]>(); - //~^ ERROR type provided when a const - example::<[usize; 4+5]>(); - //~^ ERROR type provided when a const + example::<[usize; 3]>(); + //~^ ERROR type provided when a const + //~| ERROR type annotations needed + example::<[usize; 4 + 5]>(); + //~^ ERROR type provided when a const + //~| ERROR type annotations needed } diff --git a/tests/ui/const-generics/suggest_const_for_array.stderr b/tests/ui/const-generics/suggest_const_for_array.stderr index a617bf2bb0d96..c867914070bb7 100644 --- a/tests/ui/const-generics/suggest_const_for_array.stderr +++ b/tests/ui/const-generics/suggest_const_for_array.stderr @@ -1,15 +1,40 @@ error[E0747]: type provided when a constant was expected - --> $DIR/suggest_const_for_array.rs:6:13 + --> $DIR/suggest_const_for_array.rs:6:15 | -LL | example::<[usize; 3]>(); - | ^^^^^^^^^^ help: array type provided where a `usize` was expected, try: `{ 3 }` +LL | example::<[usize; 3]>(); + | ^^^^^^^^^^ help: array type provided where a `usize` was expected, try: `{ 3 }` error[E0747]: type provided when a constant was expected - --> $DIR/suggest_const_for_array.rs:8:13 + --> $DIR/suggest_const_for_array.rs:9:15 | -LL | example::<[usize; 4+5]>(); - | ^^^^^^^^^^^^ help: array type provided where a `usize` was expected, try: `{ 4+5 }` +LL | example::<[usize; 4 + 5]>(); + | ^^^^^^^^^^^^^^ help: array type provided where a `usize` was expected, try: `{ 4 + 5 }` -error: aborting due to 2 previous errors +error[E0284]: type annotations needed + --> $DIR/suggest_const_for_array.rs:6:5 + | +LL | example::<[usize; 3]>(); + | ^^^^^^^^^^^^^^^^^^^^^ cannot infer the value of the const parameter `N` declared on the function `example` + | +note: required by a const generic parameter in `example` + --> $DIR/suggest_const_for_array.rs:3:12 + | +LL | fn example() {} + | ^^^^^^^^^^^^^^ required by this const generic parameter in `example` + +error[E0284]: type annotations needed + --> $DIR/suggest_const_for_array.rs:9:5 + | +LL | example::<[usize; 4 + 5]>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer the value of the const parameter `N` declared on the function `example` + | +note: required by a const generic parameter in `example` + --> $DIR/suggest_const_for_array.rs:3:12 + | +LL | fn example() {} + | ^^^^^^^^^^^^^^ required by this const generic parameter in `example` + +error: aborting due to 4 previous errors -For more information about this error, try `rustc --explain E0747`. +Some errors have detailed explanations: E0284, E0747. +For more information about an error, try `rustc --explain E0284`. diff --git a/tests/ui/generics/generic-function-item-where-type.rs b/tests/ui/generics/generic-function-item-where-type.rs index e1b0578cadbe9..0e36018389e96 100644 --- a/tests/ui/generics/generic-function-item-where-type.rs +++ b/tests/ui/generics/generic-function-item-where-type.rs @@ -3,4 +3,5 @@ fn foo() {} fn main() { foo::
() //~^ ERROR constant provided when a type was expected + //~| ERROR type annotations needed } diff --git a/tests/ui/generics/generic-function-item-where-type.stderr b/tests/ui/generics/generic-function-item-where-type.stderr index 00e62843cb4b6..5b0c9a8ee6df5 100644 --- a/tests/ui/generics/generic-function-item-where-type.stderr +++ b/tests/ui/generics/generic-function-item-where-type.stderr @@ -7,6 +7,13 @@ LL | foo::
() = help: `main` is a function item, not a type = help: function item types cannot be named directly -error: aborting due to 1 previous error +error[E0282]: type annotations needed + --> $DIR/generic-function-item-where-type.rs:4:5 + | +LL | foo::
() + | ^^^^^^^^^^^ cannot infer type of the type parameter `U` declared on the function `foo` + +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0747`. +Some errors have detailed explanations: E0282, E0747. +For more information about an error, try `rustc --explain E0282`. diff --git a/tests/ui/impl-trait/impl-fn-predefined-lifetimes.rs b/tests/ui/impl-trait/impl-fn-predefined-lifetimes.rs index 199cbbf4fcc9b..8aba3de530b8e 100644 --- a/tests/ui/impl-trait/impl-fn-predefined-lifetimes.rs +++ b/tests/ui/impl-trait/impl-fn-predefined-lifetimes.rs @@ -2,6 +2,7 @@ use std::fmt::Debug; fn a<'a>() -> impl Fn(&'a u8) -> (impl Debug + '_) { + //~^ ERROR cannot resolve opaque type |x| x //~^ ERROR expected generic lifetime parameter, found `'_` } diff --git a/tests/ui/impl-trait/impl-fn-predefined-lifetimes.stderr b/tests/ui/impl-trait/impl-fn-predefined-lifetimes.stderr index 6064b09ef0927..c2386e8c88be0 100644 --- a/tests/ui/impl-trait/impl-fn-predefined-lifetimes.stderr +++ b/tests/ui/impl-trait/impl-fn-predefined-lifetimes.stderr @@ -1,11 +1,19 @@ error[E0792]: expected generic lifetime parameter, found `'_` - --> $DIR/impl-fn-predefined-lifetimes.rs:5:9 + --> $DIR/impl-fn-predefined-lifetimes.rs:6:9 | LL | fn a<'a>() -> impl Fn(&'a u8) -> (impl Debug + '_) { | -- this generic parameter must be used with a generic lifetime parameter +LL | LL | |x| x | ^ -error: aborting due to 1 previous error +error[E0720]: cannot resolve opaque type + --> $DIR/impl-fn-predefined-lifetimes.rs:4:35 + | +LL | fn a<'a>() -> impl Fn(&'a u8) -> (impl Debug + '_) { + | ^^^^^^^^^^^^^^^ cannot resolve opaque type + +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0792`. +Some errors have detailed explanations: E0720, E0792. +For more information about an error, try `rustc --explain E0720`. diff --git a/tests/ui/impl-trait/transmute/in-defining-scope.rs b/tests/ui/impl-trait/transmute/in-defining-scope.rs index b0b77d60b245e..b9a9dbc10a5b4 100644 --- a/tests/ui/impl-trait/transmute/in-defining-scope.rs +++ b/tests/ui/impl-trait/transmute/in-defining-scope.rs @@ -5,6 +5,7 @@ use std::mem::transmute; fn foo() -> impl Sized { //~^ ERROR cycle detected when computing type of + //~| WARN function cannot return without recursing unsafe { transmute::<_, u8>(foo()); } diff --git a/tests/ui/impl-trait/transmute/in-defining-scope.stderr b/tests/ui/impl-trait/transmute/in-defining-scope.stderr index 69812f43072b0..7172bfdf0d7e2 100644 --- a/tests/ui/impl-trait/transmute/in-defining-scope.stderr +++ b/tests/ui/impl-trait/transmute/in-defining-scope.stderr @@ -24,6 +24,18 @@ LL | fn foo() -> impl Sized { | ^^^^^^^^^^ = 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 +warning: function cannot return without recursing + --> $DIR/in-defining-scope.rs:6:1 + | +LL | fn foo() -> impl Sized { + | ^^^^^^^^^^^^^^^^^^^^^^ cannot return without recursing +... +LL | transmute::<_, u8>(foo()); + | ----- recursive call site + | + = help: a `loop` may express intention better if this is on purpose + = note: `#[warn(unconditional_recursion)]` on by default + +error: aborting due to 1 previous error; 1 warning emitted For more information about this error, try `rustc --explain E0391`. diff --git a/tests/ui/infinite/infinite-struct.rs b/tests/ui/infinite/infinite-struct.rs index f08e10f6bdbc0..62f9702b9f411 100644 --- a/tests/ui/infinite/infinite-struct.rs +++ b/tests/ui/infinite/infinite-struct.rs @@ -1,5 +1,6 @@ struct Take(Take); //~^ ERROR has infinite size +//~| ERROR cycle // check that we don't hang trying to find the tail of a recursive struct (#79437) fn foo() -> Take { diff --git a/tests/ui/infinite/infinite-struct.stderr b/tests/ui/infinite/infinite-struct.stderr index 82d147b63cda0..5896aec399dc4 100644 --- a/tests/ui/infinite/infinite-struct.stderr +++ b/tests/ui/infinite/infinite-struct.stderr @@ -10,7 +10,7 @@ LL | struct Take(Box); | ++++ + error[E0072]: recursive type `Foo` has infinite size - --> $DIR/infinite-struct.rs:10:1 + --> $DIR/infinite-struct.rs:11:1 | LL | struct Foo { | ^^^^^^^^^^ @@ -26,6 +26,17 @@ error: reached the recursion limit finding the struct tail for `Take` | = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` -error: aborting due to 3 previous errors +error[E0391]: cycle detected when computing when `Take` needs drop + --> $DIR/infinite-struct.rs:1:1 + | +LL | struct Take(Take); + | ^^^^^^^^^^^ + | + = note: ...which immediately requires computing when `Take` needs drop again + = note: cycle used when computing whether `Take` needs drop + = 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 4 previous errors -For more information about this error, try `rustc --explain E0072`. +Some errors have detailed explanations: E0072, E0391. +For more information about an error, try `rustc --explain E0072`. diff --git a/tests/ui/static/reference-of-mut-static-unsafe-fn.rs b/tests/ui/static/reference-of-mut-static-unsafe-fn.rs deleted file mode 100644 index 5652703a27186..0000000000000 --- a/tests/ui/static/reference-of-mut-static-unsafe-fn.rs +++ /dev/null @@ -1,26 +0,0 @@ -//@ compile-flags: --edition 2024 -Z unstable-options - -fn main() {} - -unsafe fn _foo() { - static mut X: i32 = 1; - static mut Y: i32 = 1; - - let _y = &X; - //~^ ERROR creating a shared reference to a mutable static [E0796] - - let ref _a = X; - //~^ ERROR creating a shared reference to a mutable static [E0796] - - let ref mut _a = X; - //~^ ERROR creating a mutable reference to a mutable static [E0796] - - let (_b, _c) = (&X, &mut Y); - //~^ ERROR creating a shared reference to a mutable static [E0796] - //~^^ ERROR creating a mutable reference to a mutable static [E0796] - - foo(&X); - //~^ ERROR creating a shared reference to a mutable static [E0796] -} - -fn foo<'a>(_x: &'a i32) {} diff --git a/tests/ui/static/reference-of-mut-static-unsafe-fn.stderr b/tests/ui/static/reference-of-mut-static-unsafe-fn.stderr deleted file mode 100644 index 5675d313e0763..0000000000000 --- a/tests/ui/static/reference-of-mut-static-unsafe-fn.stderr +++ /dev/null @@ -1,75 +0,0 @@ -error[E0796]: creating a shared reference to a mutable static - --> $DIR/reference-of-mut-static-unsafe-fn.rs:9:14 - | -LL | let _y = &X; - | ^^ shared reference to mutable static - | - = note: this shared reference has lifetime `'static`, but if the static ever gets mutated, or a mutable reference is created, then any further use of this shared reference is Undefined Behavior -help: use `addr_of!` instead to create a raw pointer - | -LL | let _y = addr_of!(X); - | ~~~~~~~~~~~ - -error[E0796]: creating a shared reference to a mutable static - --> $DIR/reference-of-mut-static-unsafe-fn.rs:12:18 - | -LL | let ref _a = X; - | ^ shared reference to mutable static - | - = note: this shared reference has lifetime `'static`, but if the static ever gets mutated, or a mutable reference is created, then any further use of this shared reference is Undefined Behavior -help: use `addr_of!` instead to create a raw pointer - | -LL | let ref _a = addr_of!(X); - | ~~~~~~~~~~~ - -error[E0796]: creating a mutable reference to a mutable static - --> $DIR/reference-of-mut-static-unsafe-fn.rs:15:22 - | -LL | let ref mut _a = X; - | ^ mutable reference to mutable static - | - = note: this mutable reference has lifetime `'static`, but if the static gets accessed (read or written) by any other means, or any other reference is created, then any further use of this mutable reference is Undefined Behavior -help: use `addr_of_mut!` instead to create a raw pointer - | -LL | let ref mut _a = addr_of_mut!(X); - | ~~~~~~~~~~~~~~~ - -error[E0796]: creating a shared reference to a mutable static - --> $DIR/reference-of-mut-static-unsafe-fn.rs:18:21 - | -LL | let (_b, _c) = (&X, &mut Y); - | ^^ shared reference to mutable static - | - = note: this shared reference has lifetime `'static`, but if the static ever gets mutated, or a mutable reference is created, then any further use of this shared reference is Undefined Behavior -help: use `addr_of!` instead to create a raw pointer - | -LL | let (_b, _c) = (addr_of!(X), &mut Y); - | ~~~~~~~~~~~ - -error[E0796]: creating a mutable reference to a mutable static - --> $DIR/reference-of-mut-static-unsafe-fn.rs:18:25 - | -LL | let (_b, _c) = (&X, &mut Y); - | ^^^^^^ mutable reference to mutable static - | - = note: this mutable reference has lifetime `'static`, but if the static gets accessed (read or written) by any other means, or any other reference is created, then any further use of this mutable reference is Undefined Behavior -help: use `addr_of_mut!` instead to create a raw pointer - | -LL | let (_b, _c) = (&X, addr_of_mut!(Y)); - | ~~~~~~~~~~~~~~~ - -error[E0796]: creating a shared reference to a mutable static - --> $DIR/reference-of-mut-static-unsafe-fn.rs:22:9 - | -LL | foo(&X); - | ^^ shared reference to mutable static - | - = note: this shared reference has lifetime `'static`, but if the static ever gets mutated, or a mutable reference is created, then any further use of this shared reference is Undefined Behavior -help: use `addr_of!` instead to create a raw pointer - | -LL | foo(addr_of!(X)); - | ~~~~~~~~~~~ - -error: aborting due to 6 previous errors - -For more information about this error, try `rustc --explain E0796`. diff --git a/tests/ui/static/reference-of-mut-static.e2021.stderr b/tests/ui/static/reference-of-mut-static.e2021.stderr deleted file mode 100644 index f7ad51b615711..0000000000000 --- a/tests/ui/static/reference-of-mut-static.e2021.stderr +++ /dev/null @@ -1,91 +0,0 @@ -error: creating a shared reference to mutable static is discouraged - --> $DIR/reference-of-mut-static.rs:16:18 - | -LL | let _y = &X; - | ^^ shared reference to mutable static - | - = note: for more information, see issue #114447 - = note: this will be a hard error in the 2024 edition - = note: this shared reference has lifetime `'static`, but if the static ever gets mutated, or a mutable reference is created, then any further use of this shared reference is Undefined Behavior -note: the lint level is defined here - --> $DIR/reference-of-mut-static.rs:6:9 - | -LL | #![deny(static_mut_refs)] - | ^^^^^^^^^^^^^^^ -help: use `addr_of!` instead to create a raw pointer - | -LL | let _y = addr_of!(X); - | ~~~~~~~~~~~ - -error: creating a mutable reference to mutable static is discouraged - --> $DIR/reference-of-mut-static.rs:20:18 - | -LL | let _y = &mut X; - | ^^^^^^ mutable reference to mutable static - | - = note: for more information, see issue #114447 - = note: this will be a hard error in the 2024 edition - = note: this mutable reference has lifetime `'static`, but if the static gets accessed (read or written) by any other means, or any other reference is created, then any further use of this mutable reference is Undefined Behavior -help: use `addr_of_mut!` instead to create a raw pointer - | -LL | let _y = addr_of_mut!(X); - | ~~~~~~~~~~~~~~~ - -error: creating a shared reference to mutable static is discouraged - --> $DIR/reference-of-mut-static.rs:28:22 - | -LL | let ref _a = X; - | ^ shared reference to mutable static - | - = note: for more information, see issue #114447 - = note: this will be a hard error in the 2024 edition - = note: this shared reference has lifetime `'static`, but if the static ever gets mutated, or a mutable reference is created, then any further use of this shared reference is Undefined Behavior -help: use `addr_of!` instead to create a raw pointer - | -LL | let ref _a = addr_of!(X); - | ~~~~~~~~~~~ - -error: creating a shared reference to mutable static is discouraged - --> $DIR/reference-of-mut-static.rs:32:25 - | -LL | let (_b, _c) = (&X, &Y); - | ^^ shared reference to mutable static - | - = note: for more information, see issue #114447 - = note: this will be a hard error in the 2024 edition - = note: this shared reference has lifetime `'static`, but if the static ever gets mutated, or a mutable reference is created, then any further use of this shared reference is Undefined Behavior -help: use `addr_of!` instead to create a raw pointer - | -LL | let (_b, _c) = (addr_of!(X), &Y); - | ~~~~~~~~~~~ - -error: creating a shared reference to mutable static is discouraged - --> $DIR/reference-of-mut-static.rs:32:29 - | -LL | let (_b, _c) = (&X, &Y); - | ^^ shared reference to mutable static - | - = note: for more information, see issue #114447 - = note: this will be a hard error in the 2024 edition - = note: this shared reference has lifetime `'static`, but if the static ever gets mutated, or a mutable reference is created, then any further use of this shared reference is Undefined Behavior -help: use `addr_of!` instead to create a raw pointer - | -LL | let (_b, _c) = (&X, addr_of!(Y)); - | ~~~~~~~~~~~ - -error: creating a shared reference to mutable static is discouraged - --> $DIR/reference-of-mut-static.rs:38:13 - | -LL | foo(&X); - | ^^ shared reference to mutable static - | - = note: for more information, see issue #114447 - = note: this will be a hard error in the 2024 edition - = note: this shared reference has lifetime `'static`, but if the static ever gets mutated, or a mutable reference is created, then any further use of this shared reference is Undefined Behavior -help: use `addr_of!` instead to create a raw pointer - | -LL | foo(addr_of!(X)); - | ~~~~~~~~~~~ - -error: aborting due to 6 previous errors - diff --git a/tests/ui/static/reference-of-mut-static.e2024.stderr b/tests/ui/static/reference-of-mut-static.e2024.stderr deleted file mode 100644 index 6205c10ac416f..0000000000000 --- a/tests/ui/static/reference-of-mut-static.e2024.stderr +++ /dev/null @@ -1,75 +0,0 @@ -error[E0796]: creating a shared reference to a mutable static - --> $DIR/reference-of-mut-static.rs:16:18 - | -LL | let _y = &X; - | ^^ shared reference to mutable static - | - = note: this shared reference has lifetime `'static`, but if the static ever gets mutated, or a mutable reference is created, then any further use of this shared reference is Undefined Behavior -help: use `addr_of!` instead to create a raw pointer - | -LL | let _y = addr_of!(X); - | ~~~~~~~~~~~ - -error[E0796]: creating a mutable reference to a mutable static - --> $DIR/reference-of-mut-static.rs:20:18 - | -LL | let _y = &mut X; - | ^^^^^^ mutable reference to mutable static - | - = note: this mutable reference has lifetime `'static`, but if the static gets accessed (read or written) by any other means, or any other reference is created, then any further use of this mutable reference is Undefined Behavior -help: use `addr_of_mut!` instead to create a raw pointer - | -LL | let _y = addr_of_mut!(X); - | ~~~~~~~~~~~~~~~ - -error[E0796]: creating a shared reference to a mutable static - --> $DIR/reference-of-mut-static.rs:28:22 - | -LL | let ref _a = X; - | ^ shared reference to mutable static - | - = note: this shared reference has lifetime `'static`, but if the static ever gets mutated, or a mutable reference is created, then any further use of this shared reference is Undefined Behavior -help: use `addr_of!` instead to create a raw pointer - | -LL | let ref _a = addr_of!(X); - | ~~~~~~~~~~~ - -error[E0796]: creating a shared reference to a mutable static - --> $DIR/reference-of-mut-static.rs:32:25 - | -LL | let (_b, _c) = (&X, &Y); - | ^^ shared reference to mutable static - | - = note: this shared reference has lifetime `'static`, but if the static ever gets mutated, or a mutable reference is created, then any further use of this shared reference is Undefined Behavior -help: use `addr_of!` instead to create a raw pointer - | -LL | let (_b, _c) = (addr_of!(X), &Y); - | ~~~~~~~~~~~ - -error[E0796]: creating a shared reference to a mutable static - --> $DIR/reference-of-mut-static.rs:32:29 - | -LL | let (_b, _c) = (&X, &Y); - | ^^ shared reference to mutable static - | - = note: this shared reference has lifetime `'static`, but if the static ever gets mutated, or a mutable reference is created, then any further use of this shared reference is Undefined Behavior -help: use `addr_of!` instead to create a raw pointer - | -LL | let (_b, _c) = (&X, addr_of!(Y)); - | ~~~~~~~~~~~ - -error[E0796]: creating a shared reference to a mutable static - --> $DIR/reference-of-mut-static.rs:38:13 - | -LL | foo(&X); - | ^^ shared reference to mutable static - | - = note: this shared reference has lifetime `'static`, but if the static ever gets mutated, or a mutable reference is created, then any further use of this shared reference is Undefined Behavior -help: use `addr_of!` instead to create a raw pointer - | -LL | foo(addr_of!(X)); - | ~~~~~~~~~~~ - -error: aborting due to 6 previous errors - -For more information about this error, try `rustc --explain E0796`. diff --git a/tests/ui/static/reference-of-mut-static.rs b/tests/ui/static/reference-of-mut-static.rs deleted file mode 100644 index af2cab7dd8723..0000000000000 --- a/tests/ui/static/reference-of-mut-static.rs +++ /dev/null @@ -1,50 +0,0 @@ -//@ revisions: e2021 e2024 - -//@ [e2021] edition:2021 -//@ [e2024] compile-flags: --edition 2024 -Z unstable-options - -#![deny(static_mut_refs)] - -use std::ptr::{addr_of, addr_of_mut}; - -fn main() { - static mut X: i32 = 1; - - static mut Y: i32 = 1; - - unsafe { - let _y = &X; - //[e2024]~^ ERROR creating a shared reference to a mutable static [E0796] - //[e2021]~^^ ERROR shared reference to mutable static is discouraged [static_mut_refs] - - let _y = &mut X; - //[e2024]~^ ERROR creating a mutable reference to a mutable static [E0796] - //[e2021]~^^ ERROR mutable reference to mutable static is discouraged [static_mut_refs] - - let _z = addr_of_mut!(X); - - let _p = addr_of!(X); - - let ref _a = X; - //[e2024]~^ ERROR creating a shared reference to a mutable static [E0796] - //[e2021]~^^ ERROR shared reference to mutable static is discouraged [static_mut_refs] - - let (_b, _c) = (&X, &Y); - //[e2024]~^ ERROR creating a shared reference to a mutable static [E0796] - //[e2021]~^^ ERROR shared reference to mutable static is discouraged [static_mut_refs] - //[e2024]~^^^ ERROR creating a shared reference to a mutable static [E0796] - //[e2021]~^^^^ ERROR shared reference to mutable static is discouraged [static_mut_refs] - - foo(&X); - //[e2024]~^ ERROR creating a shared reference to a mutable static [E0796] - //[e2021]~^^ ERROR shared reference to mutable static is discouraged [static_mut_refs] - - static mut Z: &[i32; 3] = &[0, 1, 2]; - - let _ = Z.len(); - let _ = Z[0]; - let _ = format!("{:?}", Z); - } -} - -fn foo<'a>(_x: &'a i32) {} diff --git a/tests/ui/static/reference-to-mut-static-safe.e2024.stderr b/tests/ui/static/reference-to-mut-static-safe.e2024.stderr index 607c1bba1352a..c57b418d7b2e2 100644 --- a/tests/ui/static/reference-to-mut-static-safe.e2024.stderr +++ b/tests/ui/static/reference-to-mut-static-safe.e2024.stderr @@ -10,6 +10,15 @@ help: use `addr_of!` instead to create a raw pointer LL | let _x = addr_of!(X); | ~~~~~~~~~~~ -error: aborting due to 1 previous error +error[E0133]: use of mutable static is unsafe and requires unsafe block + --> $DIR/reference-to-mut-static-safe.rs:9:15 + | +LL | let _x = &X; + | ^ use of mutable static + | + = note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior + +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0796`. +Some errors have detailed explanations: E0133, E0796. +For more information about an error, try `rustc --explain E0133`. diff --git a/tests/ui/static/reference-to-mut-static-safe.rs b/tests/ui/static/reference-to-mut-static-safe.rs index de4f4be8f7621..98afdadf4d255 100644 --- a/tests/ui/static/reference-to-mut-static-safe.rs +++ b/tests/ui/static/reference-to-mut-static-safe.rs @@ -8,6 +8,6 @@ fn main() { let _x = &X; //[e2024]~^ creating a shared reference to a mutable static [E0796] - //[e2021]~^^ use of mutable static is unsafe and requires unsafe function or block [E0133] + //~^^ use of mutable static is unsafe and requires unsafe //[e2021]~^^^ shared reference to mutable static is discouraged [static_mut_refs] } diff --git a/tests/ui/static/reference-to-mut-static-unsafe-fn.rs b/tests/ui/static/reference-to-mut-static-unsafe-fn.rs index 5652703a27186..d63fd5460d840 100644 --- a/tests/ui/static/reference-to-mut-static-unsafe-fn.rs +++ b/tests/ui/static/reference-to-mut-static-unsafe-fn.rs @@ -3,24 +3,26 @@ fn main() {} unsafe fn _foo() { - static mut X: i32 = 1; - static mut Y: i32 = 1; + unsafe { + static mut X: i32 = 1; + static mut Y: i32 = 1; - let _y = &X; - //~^ ERROR creating a shared reference to a mutable static [E0796] + let _y = &X; + //~^ ERROR creating a shared reference to a mutable static [E0796] - let ref _a = X; - //~^ ERROR creating a shared reference to a mutable static [E0796] + let ref _a = X; + //~^ ERROR creating a shared reference to a mutable static [E0796] - let ref mut _a = X; - //~^ ERROR creating a mutable reference to a mutable static [E0796] + let ref mut _a = X; + //~^ ERROR creating a mutable reference to a mutable static [E0796] - let (_b, _c) = (&X, &mut Y); - //~^ ERROR creating a shared reference to a mutable static [E0796] - //~^^ ERROR creating a mutable reference to a mutable static [E0796] + let (_b, _c) = (&X, &mut Y); + //~^ ERROR creating a shared reference to a mutable static [E0796] + //~^^ ERROR creating a mutable reference to a mutable static [E0796] - foo(&X); - //~^ ERROR creating a shared reference to a mutable static [E0796] + foo(&X); + //~^ ERROR creating a shared reference to a mutable static [E0796] + } } fn foo<'a>(_x: &'a i32) {} diff --git a/tests/ui/static/reference-to-mut-static-unsafe-fn.stderr b/tests/ui/static/reference-to-mut-static-unsafe-fn.stderr index 77d2aa5d1aec6..b24943cf59363 100644 --- a/tests/ui/static/reference-to-mut-static-unsafe-fn.stderr +++ b/tests/ui/static/reference-to-mut-static-unsafe-fn.stderr @@ -1,74 +1,74 @@ error[E0796]: creating a shared reference to a mutable static - --> $DIR/reference-to-mut-static-unsafe-fn.rs:9:14 + --> $DIR/reference-to-mut-static-unsafe-fn.rs:10:18 | -LL | let _y = &X; - | ^^ shared reference to mutable static +LL | let _y = &X; + | ^^ shared reference to mutable static | = note: this shared reference has lifetime `'static`, but if the static ever gets mutated, or a mutable reference is created, then any further use of this shared reference is Undefined Behavior help: use `addr_of!` instead to create a raw pointer | -LL | let _y = addr_of!(X); - | ~~~~~~~~~~~ +LL | let _y = addr_of!(X); + | ~~~~~~~~~~~ error[E0796]: creating a shared reference to a mutable static - --> $DIR/reference-to-mut-static-unsafe-fn.rs:12:18 + --> $DIR/reference-to-mut-static-unsafe-fn.rs:13:22 | -LL | let ref _a = X; - | ^ shared reference to mutable static +LL | let ref _a = X; + | ^ shared reference to mutable static | = note: this shared reference has lifetime `'static`, but if the static ever gets mutated, or a mutable reference is created, then any further use of this shared reference is Undefined Behavior help: use `addr_of!` instead to create a raw pointer | -LL | let ref _a = addr_of!(X); - | ~~~~~~~~~~~ +LL | let ref _a = addr_of!(X); + | ~~~~~~~~~~~ error[E0796]: creating a mutable reference to a mutable static - --> $DIR/reference-to-mut-static-unsafe-fn.rs:15:22 + --> $DIR/reference-to-mut-static-unsafe-fn.rs:16:26 | -LL | let ref mut _a = X; - | ^ mutable reference to mutable static +LL | let ref mut _a = X; + | ^ mutable reference to mutable static | = note: this mutable reference has lifetime `'static`, but if the static gets accessed (read or written) by any other means, or any other reference is created, then any further use of this mutable reference is Undefined Behavior help: use `addr_of_mut!` instead to create a raw pointer | -LL | let ref mut _a = addr_of_mut!(X); - | ~~~~~~~~~~~~~~~ +LL | let ref mut _a = addr_of_mut!(X); + | ~~~~~~~~~~~~~~~ error[E0796]: creating a shared reference to a mutable static - --> $DIR/reference-to-mut-static-unsafe-fn.rs:18:21 + --> $DIR/reference-to-mut-static-unsafe-fn.rs:19:25 | -LL | let (_b, _c) = (&X, &mut Y); - | ^^ shared reference to mutable static +LL | let (_b, _c) = (&X, &mut Y); + | ^^ shared reference to mutable static | = note: this shared reference has lifetime `'static`, but if the static ever gets mutated, or a mutable reference is created, then any further use of this shared reference is Undefined Behavior help: use `addr_of!` instead to create a raw pointer | -LL | let (_b, _c) = (addr_of!(X), &mut Y); - | ~~~~~~~~~~~ +LL | let (_b, _c) = (addr_of!(X), &mut Y); + | ~~~~~~~~~~~ error[E0796]: creating a mutable reference to a mutable static - --> $DIR/reference-to-mut-static-unsafe-fn.rs:18:25 + --> $DIR/reference-to-mut-static-unsafe-fn.rs:19:29 | -LL | let (_b, _c) = (&X, &mut Y); - | ^^^^^^ mutable reference to mutable static +LL | let (_b, _c) = (&X, &mut Y); + | ^^^^^^ mutable reference to mutable static | = note: this mutable reference has lifetime `'static`, but if the static gets accessed (read or written) by any other means, or any other reference is created, then any further use of this mutable reference is Undefined Behavior help: use `addr_of_mut!` instead to create a raw pointer | -LL | let (_b, _c) = (&X, addr_of_mut!(Y)); - | ~~~~~~~~~~~~~~~ +LL | let (_b, _c) = (&X, addr_of_mut!(Y)); + | ~~~~~~~~~~~~~~~ error[E0796]: creating a shared reference to a mutable static - --> $DIR/reference-to-mut-static-unsafe-fn.rs:22:9 + --> $DIR/reference-to-mut-static-unsafe-fn.rs:23:13 | -LL | foo(&X); - | ^^ shared reference to mutable static +LL | foo(&X); + | ^^ shared reference to mutable static | = note: this shared reference has lifetime `'static`, but if the static ever gets mutated, or a mutable reference is created, then any further use of this shared reference is Undefined Behavior help: use `addr_of!` instead to create a raw pointer | -LL | foo(addr_of!(X)); - | ~~~~~~~~~~~ +LL | foo(addr_of!(X)); + | ~~~~~~~~~~~ error: aborting due to 6 previous errors diff --git a/tests/ui/type-alias-impl-trait/hkl_forbidden4.stderr b/tests/ui/type-alias-impl-trait/hkl_forbidden4.stderr index 7df1a08bc883d..0c2772683a918 100644 --- a/tests/ui/type-alias-impl-trait/hkl_forbidden4.stderr +++ b/tests/ui/type-alias-impl-trait/hkl_forbidden4.stderr @@ -44,18 +44,6 @@ LL | LL | call(operation).await | ^^^^^^^^^^^^^^^ -error[E0792]: expected generic lifetime parameter, found `'any` - --> $DIR/hkl_forbidden4.rs:23:1 - | -LL | type FutNothing<'a> = impl 'a + Future; - | -- this generic parameter must be used with a generic lifetime parameter -... -LL | / { -LL | | -LL | | -LL | | } - | |_^ - error: concrete type differs from previous defining opaque type use --> $DIR/hkl_forbidden4.rs:13:1 | @@ -68,6 +56,18 @@ note: previous use here LL | call(operation).await | ^^^^^^^^^^^^^^^ +error[E0792]: expected generic lifetime parameter, found `'any` + --> $DIR/hkl_forbidden4.rs:23:1 + | +LL | type FutNothing<'a> = impl 'a + Future; + | -- this generic parameter must be used with a generic lifetime parameter +... +LL | / { +LL | | +LL | | +LL | | } + | |_^ + error: aborting due to 6 previous errors For more information about this error, try `rustc --explain E0792`. diff --git a/tests/ui/type-alias-impl-trait/issue-53092-2.rs b/tests/ui/type-alias-impl-trait/issue-53092-2.rs index 61b23a3a93322..2adfad4fc5b80 100644 --- a/tests/ui/type-alias-impl-trait/issue-53092-2.rs +++ b/tests/ui/type-alias-impl-trait/issue-53092-2.rs @@ -5,6 +5,8 @@ type Bug = impl Fn(T) -> U + Copy; //~ ERROR cycle detected const CONST_BUG: Bug = unsafe { std::mem::transmute(|_: u8| ()) }; //~^ ERROR: non-defining opaque type use +//~| ERROR: item does not constrain +//~| ERROR: item does not constrain fn make_bug>() -> Bug { |x| x.into() //~ ERROR the trait bound `U: From` is not satisfied diff --git a/tests/ui/type-alias-impl-trait/issue-53092-2.stderr b/tests/ui/type-alias-impl-trait/issue-53092-2.stderr index c2da5fc265cc2..121f765e66726 100644 --- a/tests/ui/type-alias-impl-trait/issue-53092-2.stderr +++ b/tests/ui/type-alias-impl-trait/issue-53092-2.stderr @@ -36,14 +36,40 @@ LL | type Bug = impl Fn(T) -> U + Copy; | ^^^^^^^^^^^^^^^^^^^^^^ = 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: item does not constrain `Bug::{opaque#0}`, but has it in its signature + --> $DIR/issue-53092-2.rs:6:7 + | +LL | const CONST_BUG: Bug = unsafe { std::mem::transmute(|_: u8| ()) }; + | ^^^^^^^^^ + | + = note: consider moving the opaque type's declaration and defining uses into a separate module +note: this opaque type is in the signature + --> $DIR/issue-53092-2.rs:4:18 + | +LL | type Bug = impl Fn(T) -> U + Copy; + | ^^^^^^^^^^^^^^^^^^^^^^ + +error: item does not constrain `Bug::{opaque#0}`, but has it in its signature + --> $DIR/issue-53092-2.rs:6:61 + | +LL | const CONST_BUG: Bug = unsafe { std::mem::transmute(|_: u8| ()) }; + | ^^^^^^^ + | + = note: consider moving the opaque type's declaration and defining uses into a separate module +note: this opaque type is in the signature + --> $DIR/issue-53092-2.rs:4:18 + | +LL | type Bug = impl Fn(T) -> U + Copy; + | ^^^^^^^^^^^^^^^^^^^^^^ + error[E0277]: the trait bound `U: From` is not satisfied - --> $DIR/issue-53092-2.rs:10:5 + --> $DIR/issue-53092-2.rs:12:5 | LL | |x| x.into() | ^^^^^^^^^^^^ the trait `From` is not implemented for `U` | note: required by a bound in `make_bug` - --> $DIR/issue-53092-2.rs:9:19 + --> $DIR/issue-53092-2.rs:11:19 | LL | fn make_bug>() -> Bug { | ^^^^^^^ required by this bound in `make_bug` @@ -52,7 +78,7 @@ help: consider restricting type parameter `U` LL | type Bug> = impl Fn(T) -> U + Copy; | +++++++++++++++++++++++ -error: aborting due to 3 previous errors +error: aborting due to 5 previous errors Some errors have detailed explanations: E0277, E0391, E0792. For more information about an error, try `rustc --explain E0277`. From bfc8dc8e5fb937ccc1e163e5f23d2561f0bd66c9 Mon Sep 17 00:00:00 2001 From: Oneirical Date: Wed, 26 Jun 2024 12:04:35 -0400 Subject: [PATCH 329/892] rewrite use-suggestions-rust-2018 to rmake --- .../tidy/src/allowed_run_make_makefiles.txt | 1 - .../use-suggestions-rust-2018/Makefile | 7 ------- .../use-suggestions-rust-2018/rmake.rs | 18 ++++++++++++++++++ 3 files changed, 18 insertions(+), 8 deletions(-) delete mode 100644 tests/run-make/use-suggestions-rust-2018/Makefile create mode 100644 tests/run-make/use-suggestions-rust-2018/rmake.rs diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index cb68589d8a4c2..199d9fd53f391 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -193,7 +193,6 @@ run-make/translation/Makefile run-make/type-mismatch-same-crate-name/Makefile run-make/unknown-mod-stdin/Makefile run-make/unstable-flag-required/Makefile -run-make/use-suggestions-rust-2018/Makefile run-make/used-cdylib-macos/Makefile run-make/volatile-intrinsics/Makefile run-make/wasm-exceptions-nostd/Makefile diff --git a/tests/run-make/use-suggestions-rust-2018/Makefile b/tests/run-make/use-suggestions-rust-2018/Makefile deleted file mode 100644 index 37cd6283c0a6e..0000000000000 --- a/tests/run-make/use-suggestions-rust-2018/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -include ../tools.mk - -all: - $(RUSTC) ep-nested-lib.rs - - $(RUSTC) use-suggestions.rs --edition=2018 --extern ep_nested_lib=$(TMPDIR)/libep_nested_lib.rlib 2>&1 | $(CGREP) "use ep_nested_lib::foo::bar::Baz" - diff --git a/tests/run-make/use-suggestions-rust-2018/rmake.rs b/tests/run-make/use-suggestions-rust-2018/rmake.rs new file mode 100644 index 0000000000000..52c694da75e9a --- /dev/null +++ b/tests/run-make/use-suggestions-rust-2018/rmake.rs @@ -0,0 +1,18 @@ +// The compilation error caused by calling on an unimported crate +// should have a suggestion to write, say, crate::bar::Foo instead +// of just bar::Foo. However, this suggestion used to only appear for +// extern crate statements, not crate struct. After this was fixed in #51456, +// this test checks that the correct suggestion is printed no matter what. +// See https://github.com/rust-lang/rust/issues/51212 + +use run_make_support::{rust_lib_name, rustc}; + +fn main() { + rustc().input("ep-nested-lib.rs").run(); + rustc() + .input("use-suggestions.rs") + .edition("2018") + .extern_("ep_nested_lib", rust_lib_name("ep_nested_lib")) + .run_fail() + .assert_stderr_contains("use ep_nested_lib::foo::bar::Baz"); +} From a6bb92ada7864cbd3bdc3c2a2cb998c0ba512bca Mon Sep 17 00:00:00 2001 From: Oneirical Date: Wed, 26 Jun 2024 13:11:46 -0400 Subject: [PATCH 330/892] rewrite overwrite-input to rmake --- src/tools/tidy/src/allowed_run_make_makefiles.txt | 1 - tests/run-make/overwrite-input/Makefile | 7 ------- tests/run-make/overwrite-input/file.stderr | 4 +--- tests/run-make/overwrite-input/folder.stderr | 4 +--- tests/run-make/overwrite-input/main.stderr | 6 ------ tests/run-make/overwrite-input/rmake.rs | 13 +++++++++++++ 6 files changed, 15 insertions(+), 20 deletions(-) delete mode 100644 tests/run-make/overwrite-input/Makefile delete mode 100644 tests/run-make/overwrite-input/main.stderr create mode 100644 tests/run-make/overwrite-input/rmake.rs diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index 199d9fd53f391..9d3c08ec83299 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -119,7 +119,6 @@ run-make/optimization-remarks-dir-pgo/Makefile run-make/optimization-remarks-dir/Makefile run-make/output-type-permutations/Makefile run-make/override-aliased-flags/Makefile -run-make/overwrite-input/Makefile run-make/panic-abort-eh_frame/Makefile run-make/pass-linker-flags-flavor/Makefile run-make/pass-linker-flags-from-dep/Makefile diff --git a/tests/run-make/overwrite-input/Makefile b/tests/run-make/overwrite-input/Makefile deleted file mode 100644 index 721bf62b26b5d..0000000000000 --- a/tests/run-make/overwrite-input/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -include ../tools.mk - -all: - $(RUSTC) main.rs -o main.rs 2> $(TMPDIR)/file.stderr || echo "failed successfully" - $(RUSTC) main.rs -o . 2> $(TMPDIR)/folder.stderr || echo "failed successfully" - $(RUSTC_TEST_OP) "$(TMPDIR)"/file.stderr file.stderr - $(RUSTC_TEST_OP) "$(TMPDIR)"/folder.stderr folder.stderr diff --git a/tests/run-make/overwrite-input/file.stderr b/tests/run-make/overwrite-input/file.stderr index c13a270b067f4..3a741ae3852b8 100644 --- a/tests/run-make/overwrite-input/file.stderr +++ b/tests/run-make/overwrite-input/file.stderr @@ -1,6 +1,4 @@ -warning: ignoring --out-dir flag due to -o flag - error: the input file "main.rs" would be overwritten by the generated executable -error: aborting due to 1 previous error; 1 warning emitted +error: aborting due to 1 previous error diff --git a/tests/run-make/overwrite-input/folder.stderr b/tests/run-make/overwrite-input/folder.stderr index 6e51cb812ceb1..30db08428fd91 100644 --- a/tests/run-make/overwrite-input/folder.stderr +++ b/tests/run-make/overwrite-input/folder.stderr @@ -1,6 +1,4 @@ -warning: ignoring --out-dir flag due to -o flag - error: the generated executable for the input file "main.rs" conflicts with the existing directory "." -error: aborting due to 1 previous error; 1 warning emitted +error: aborting due to 1 previous error diff --git a/tests/run-make/overwrite-input/main.stderr b/tests/run-make/overwrite-input/main.stderr deleted file mode 100644 index c13a270b067f4..0000000000000 --- a/tests/run-make/overwrite-input/main.stderr +++ /dev/null @@ -1,6 +0,0 @@ -warning: ignoring --out-dir flag due to -o flag - -error: the input file "main.rs" would be overwritten by the generated executable - -error: aborting due to 1 previous error; 1 warning emitted - diff --git a/tests/run-make/overwrite-input/rmake.rs b/tests/run-make/overwrite-input/rmake.rs new file mode 100644 index 0000000000000..b87a7c7e0a851 --- /dev/null +++ b/tests/run-make/overwrite-input/rmake.rs @@ -0,0 +1,13 @@ +// An attempt to set the output `-o` into a directory or a file we cannot write into should indeed +// be an error; but not an ICE (Internal Compiler Error). This test attempts both and checks +// that the standard error matches what is expected. +// See https://github.com/rust-lang/rust/issues/66530 + +use run_make_support::{diff, rustc}; + +fn main() { + let file_out = rustc().input("main.rs").output("main.rs").run_fail().stderr_utf8(); + let folder_out = rustc().input("main.rs").output(".").run_fail().stderr_utf8(); + diff().expected_file("file.stderr").actual_text("actual-file-stderr", file_out).run(); + diff().expected_file("folder.stderr").actual_text("actual-folder-stderr", folder_out).run(); +} From c6bb35750265cc9e630fb49d96ab5721ceb57136 Mon Sep 17 00:00:00 2001 From: Oneirical Date: Wed, 26 Jun 2024 13:32:30 -0400 Subject: [PATCH 331/892] rewrite lto-dylib-dep to rmake --- src/tools/tidy/src/allowed_run_make_makefiles.txt | 1 - tests/run-make/lto-dylib-dep/Makefile | 11 ----------- tests/run-make/lto-dylib-dep/rmake.rs | 15 +++++++++++++++ 3 files changed, 15 insertions(+), 12 deletions(-) delete mode 100644 tests/run-make/lto-dylib-dep/Makefile create mode 100644 tests/run-make/lto-dylib-dep/rmake.rs diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index 9d3c08ec83299..9d44b61d5e168 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -94,7 +94,6 @@ run-make/llvm-ident/Makefile run-make/long-linker-command-lines-cmd-exe/Makefile run-make/long-linker-command-lines/Makefile run-make/longjmp-across-rust/Makefile -run-make/lto-dylib-dep/Makefile run-make/lto-linkage-used-attr/Makefile run-make/lto-no-link-whole-rlib/Makefile run-make/lto-smoke-c/Makefile diff --git a/tests/run-make/lto-dylib-dep/Makefile b/tests/run-make/lto-dylib-dep/Makefile deleted file mode 100644 index a9344597d081e..0000000000000 --- a/tests/run-make/lto-dylib-dep/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -# ignore-cross-compile -include ../tools.mk - -# Test that we don't run into an assertion when using a Rust dylib dependency -# while compiling with full LTO. -# See https://github.com/rust-lang/rust/issues/59137 - -all: - $(RUSTC) a_dylib.rs --crate-type=dylib -C prefer-dynamic - $(RUSTC) main.rs -C lto - $(call RUN,main) diff --git a/tests/run-make/lto-dylib-dep/rmake.rs b/tests/run-make/lto-dylib-dep/rmake.rs new file mode 100644 index 0000000000000..842fce467d40b --- /dev/null +++ b/tests/run-make/lto-dylib-dep/rmake.rs @@ -0,0 +1,15 @@ +// Compiling with link-time-optimizations (LTO) would previously run into an internal +// compiler error (ICE) if a dylib was passed as a required library. This was due to a +// misplaced assert! call in the compiler, which is now removed. This test checks that +// this bug does not make a resurgence and that dylib+lto compilation succeeds. +// See https://github.com/rust-lang/rust/issues/59137 + +//@ ignore-cross-compile + +use run_make_support::{run, rustc}; + +fn main() { + rustc().input("a_dylib.rs").crate_type("dylib").arg("-Cprefer-dynamic").run(); + rustc().input("main.rs").arg("-Clto").run(); + run("main"); +} From 315be7d483bd4bad3e5541376ebf1d926c21f4f2 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 27 Jun 2024 00:04:23 +0200 Subject: [PATCH 332/892] Update browser-ui-test version to `0.18.0` --- .../host-x86_64/x86_64-gnu-tools/browser-ui-test.version | 2 +- tests/rustdoc-gui/label-next-to-symbol.goml | 3 +++ tests/rustdoc-gui/sidebar-source-code-display.goml | 5 +++-- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version b/src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version index 50c2e5e29f0b8..47d04a528837e 100644 --- a/src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version +++ b/src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version @@ -1 +1 @@ -0.17.2 \ No newline at end of file +0.18.0 \ No newline at end of file diff --git a/tests/rustdoc-gui/label-next-to-symbol.goml b/tests/rustdoc-gui/label-next-to-symbol.goml index 9a7de60bf38e1..0582bd2cad36e 100644 --- a/tests/rustdoc-gui/label-next-to-symbol.goml +++ b/tests/rustdoc-gui/label-next-to-symbol.goml @@ -1,7 +1,10 @@ // These tests verify that labels like "UNIX" and "Deprecated" stay on the same line as their symbol. // It also verifies the staggered layout on mobile. +include: "utils.goml" go-to: "file://" + |DOC_PATH| + "/test_docs/index.html" +call-function: ("switch-theme", {"theme": "light"}) + // Desktop view set-window-size: (1080, 600) assert: (".stab.deprecated") diff --git a/tests/rustdoc-gui/sidebar-source-code-display.goml b/tests/rustdoc-gui/sidebar-source-code-display.goml index 7ce3be8a5b355..67152afbbaa33 100644 --- a/tests/rustdoc-gui/sidebar-source-code-display.goml +++ b/tests/rustdoc-gui/sidebar-source-code-display.goml @@ -141,14 +141,15 @@ click: "#sidebar-button" wait-for-css: (".src .sidebar > *", {"visibility": "hidden"}) // We scroll to line 117 to change the scroll position. scroll-to: '//*[@id="117"]' -assert-window-property: {"pageYOffset": "2516"} +store-value: (y_offset, "2493") +assert-window-property: {"pageYOffset": |y_offset|} // Expanding the sidebar... click: "#sidebar-button" wait-for-css: (".sidebar", {"left": "0px"}) click: "#sidebar-button" wait-for-css: (".sidebar", {"left": "-1000px"}) // The "scrollTop" property should be the same. -assert-window-property: {"pageYOffset": "2516"} +assert-window-property: {"pageYOffset": |y_offset|} // We now check that opening the sidebar and clicking a link will close it. // The behavior here on mobile is different than the behavior on desktop, From 80b25b4c82d1a7ffb77dfed48e3bcebfe3506f43 Mon Sep 17 00:00:00 2001 From: Reilly Tucker Siemens Date: Mon, 24 Jun 2024 22:04:38 -0700 Subject: [PATCH 333/892] Fix doc_markdown DevOps false positive --- book/src/lint_configuration.md | 2 +- clippy_config/src/conf.rs | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/book/src/lint_configuration.md b/book/src/lint_configuration.md index adb5b0a54909b..69a1b8b176e1e 100644 --- a/book/src/lint_configuration.md +++ b/book/src/lint_configuration.md @@ -454,7 +454,7 @@ default configuration of Clippy. By default, any configuration will replace the * `doc-valid-idents = ["ClipPy"]` would replace the default list with `["ClipPy"]`. * `doc-valid-idents = ["ClipPy", ".."]` would append `ClipPy` to the default list. -**Default Value:** `["KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "DirectX", "ECMAScript", "GPLv2", "GPLv3", "GitHub", "GitLab", "IPv4", "IPv6", "ClojureScript", "CoffeeScript", "JavaScript", "PureScript", "TypeScript", "WebAssembly", "NaN", "NaNs", "OAuth", "GraphQL", "OCaml", "OpenDNS", "OpenGL", "OpenMP", "OpenSSH", "OpenSSL", "OpenStreetMap", "OpenTelemetry", "WebGL", "WebGL2", "WebGPU", "TensorFlow", "TrueType", "iOS", "macOS", "FreeBSD", "TeX", "LaTeX", "BibTeX", "BibLaTeX", "MinGW", "CamelCase"]` +**Default Value:** `["KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "DevOps", "DirectX", "ECMAScript", "GPLv2", "GPLv3", "GitHub", "GitLab", "IPv4", "IPv6", "ClojureScript", "CoffeeScript", "JavaScript", "PureScript", "TypeScript", "WebAssembly", "NaN", "NaNs", "OAuth", "GraphQL", "OCaml", "OpenDNS", "OpenGL", "OpenMP", "OpenSSH", "OpenSSL", "OpenStreetMap", "OpenTelemetry", "WebGL", "WebGL2", "WebGPU", "TensorFlow", "TrueType", "iOS", "macOS", "FreeBSD", "TeX", "LaTeX", "BibTeX", "BibLaTeX", "MinGW", "CamelCase"]` --- **Affected lints:** diff --git a/clippy_config/src/conf.rs b/clippy_config/src/conf.rs index 93ca535a7a461..703b88f33b361 100644 --- a/clippy_config/src/conf.rs +++ b/clippy_config/src/conf.rs @@ -18,6 +18,7 @@ use std::{cmp, env, fmt, fs, io}; #[rustfmt::skip] const DEFAULT_DOC_VALID_IDENTS: &[&str] = &[ "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", + "DevOps", "DirectX", "ECMAScript", "GPLv2", "GPLv3", From c053e8939bae9c052ff53f58e692408a8099df5d Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 5 Jun 2024 18:06:09 +1000 Subject: [PATCH 334/892] Remove the `box_pointers` lint. As the comment says, this lint "is mostly historical, and not particularly useful". It's not worth keeping it around. --- compiler/rustc_lint/messages.ftl | 2 - compiler/rustc_lint/src/builtin.rs | 82 +------------------ compiler/rustc_lint/src/lib.rs | 5 +- compiler/rustc_lint/src/lints.rs | 6 -- .../crates/ide-db/src/generated/lints.rs | 1 - tests/ui/lint/lint-owned-heap-memory.rs | 12 --- tests/ui/lint/lint-owned-heap-memory.stderr | 20 ----- tests/ui/lint/reasons-erroneous.rs | 2 +- tests/ui/lint/reasons-erroneous.stderr | 6 +- 9 files changed, 11 insertions(+), 125 deletions(-) delete mode 100644 tests/ui/lint/lint-owned-heap-memory.rs delete mode 100644 tests/ui/lint/lint-owned-heap-memory.stderr diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl index 46cf87d1e3c17..3e952558d29d3 100644 --- a/compiler/rustc_lint/messages.ftl +++ b/compiler/rustc_lint/messages.ftl @@ -56,8 +56,6 @@ lint_builtin_asm_labels = avoid using named labels in inline assembly .help = only local labels of the form `:` should be used in inline asm .note = see the asm section of Rust By Example for more information -lint_builtin_box_pointers = type uses owned (Box type) pointers: {$ty} - lint_builtin_clashing_extern_diff_name = `{$this}` redeclares `{$orig}` with a different signature .previous_decl_label = `{$orig}` previously declared here .mismatch_label = this signature doesn't match the previous declaration diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index 98318cd14d9dc..79c8046f9b741 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -24,9 +24,9 @@ use crate::fluent_generated as fluent; use crate::{ errors::BuiltinEllipsisInclusiveRangePatterns, lints::{ - BuiltinAnonymousParams, BuiltinBoxPointers, BuiltinConstNoMangle, - BuiltinDeprecatedAttrLink, BuiltinDeprecatedAttrLinkSuggestion, BuiltinDeprecatedAttrUsed, - BuiltinDerefNullptr, BuiltinEllipsisInclusiveRangePatternsLint, BuiltinExplicitOutlives, + BuiltinAnonymousParams, BuiltinConstNoMangle, BuiltinDeprecatedAttrLink, + BuiltinDeprecatedAttrLinkSuggestion, BuiltinDeprecatedAttrUsed, BuiltinDerefNullptr, + BuiltinEllipsisInclusiveRangePatternsLint, BuiltinExplicitOutlives, BuiltinExplicitOutlivesSuggestion, BuiltinFeatureIssueNote, BuiltinIncompleteFeatures, BuiltinIncompleteFeaturesHelp, BuiltinInternalFeatures, BuiltinKeywordIdents, BuiltinMissingCopyImpl, BuiltinMissingDebugImpl, BuiltinMissingDoc, @@ -56,7 +56,6 @@ use rustc_middle::bug; use rustc_middle::lint::in_external_macro; use rustc_middle::ty::layout::LayoutOf; use rustc_middle::ty::print::with_no_trimmed_paths; -use rustc_middle::ty::GenericArgKind; use rustc_middle::ty::TypeVisitableExt; use rustc_middle::ty::Upcast; use rustc_middle::ty::{self, Ty, TyCtxt, VariantDef}; @@ -134,80 +133,6 @@ impl EarlyLintPass for WhileTrue { } } -declare_lint! { - /// The `box_pointers` lints use of the Box type. - /// - /// ### Example - /// - /// ```rust,compile_fail - /// #![deny(box_pointers)] - /// struct Foo { - /// x: Box, - /// } - /// ``` - /// - /// {{produces}} - /// - /// ### Explanation - /// - /// This lint is mostly historical, and not particularly useful. `Box` - /// used to be built into the language, and the only way to do heap - /// allocation. Today's Rust can call into other allocators, etc. - BOX_POINTERS, - Allow, - "use of owned (Box type) heap memory" -} - -declare_lint_pass!(BoxPointers => [BOX_POINTERS]); - -impl BoxPointers { - fn check_heap_type(&self, cx: &LateContext<'_>, span: Span, ty: Ty<'_>) { - for leaf in ty.walk() { - if let GenericArgKind::Type(leaf_ty) = leaf.unpack() - && leaf_ty.is_box() - { - cx.emit_span_lint(BOX_POINTERS, span, BuiltinBoxPointers { ty }); - } - } - } -} - -impl<'tcx> LateLintPass<'tcx> for BoxPointers { - fn check_item(&mut self, cx: &LateContext<'_>, it: &hir::Item<'_>) { - match it.kind { - hir::ItemKind::Fn(..) - | hir::ItemKind::TyAlias(..) - | hir::ItemKind::Enum(..) - | hir::ItemKind::Struct(..) - | hir::ItemKind::Union(..) => self.check_heap_type( - cx, - it.span, - cx.tcx.type_of(it.owner_id).instantiate_identity(), - ), - _ => (), - } - - // If it's a struct, we also have to check the fields' types - match it.kind { - hir::ItemKind::Struct(ref struct_def, _) | hir::ItemKind::Union(ref struct_def, _) => { - for field in struct_def.fields() { - self.check_heap_type( - cx, - field.span, - cx.tcx.type_of(field.def_id).instantiate_identity(), - ); - } - } - _ => (), - } - } - - fn check_expr(&mut self, cx: &LateContext<'_>, e: &hir::Expr<'_>) { - let ty = cx.typeck_results().node_type(e.hir_id); - self.check_heap_type(cx, e.span, ty); - } -} - declare_lint! { /// The `non_shorthand_field_patterns` lint detects using `Struct { x: x }` /// instead of `Struct { x }` in a pattern. @@ -1640,7 +1565,6 @@ declare_lint_pass!( /// which are used by other parts of the compiler. SoftLints => [ WHILE_TRUE, - BOX_POINTERS, NON_SHORTHAND_FIELD_PATTERNS, UNSAFE_CODE, MISSING_DOCS, diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index 7dae2de7bfb58..17f9d4421aef2 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -187,7 +187,6 @@ late_lint_methods!( ImproperCTypesDefinitions: ImproperCTypesDefinitions, InvalidFromUtf8: InvalidFromUtf8, VariantSizeDifferences: VariantSizeDifferences, - BoxPointers: BoxPointers, PathStatements: PathStatements, LetUnderscore: LetUnderscore, InvalidReferenceCasting: InvalidReferenceCasting, @@ -551,6 +550,10 @@ fn register_builtins(store: &mut LintStore) { "converted into hard error, see RFC #3535 \ for more information", ); + store.register_removed( + "box_pointers", + "it does not detect other kinds of allocations, and existed only for historical reasons", + ); } fn register_internals(store: &mut LintStore) { diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs index 14084405d0ee1..7c5640f5959a0 100644 --- a/compiler/rustc_lint/src/lints.rs +++ b/compiler/rustc_lint/src/lints.rs @@ -66,12 +66,6 @@ pub struct BuiltinWhileTrue { pub replace: String, } -#[derive(LintDiagnostic)] -#[diag(lint_builtin_box_pointers)] -pub struct BuiltinBoxPointers<'a> { - pub ty: Ty<'a>, -} - #[derive(LintDiagnostic)] #[diag(lint_builtin_non_shorthand_field_patterns)] pub struct BuiltinNonShorthandFieldPatterns { diff --git a/src/tools/rust-analyzer/crates/ide-db/src/generated/lints.rs b/src/tools/rust-analyzer/crates/ide-db/src/generated/lints.rs index c92d4e78ffa71..7755a9b9748be 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/generated/lints.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/generated/lints.rs @@ -49,7 +49,6 @@ pub const DEFAULT_LINTS: &[Lint] = &[ label: "bindings_with_variant_name", description: r##"detects pattern bindings with the same name as one of the matched variants"##, }, - Lint { label: "box_pointers", description: r##"use of owned (Box type) heap memory"## }, Lint { label: "break_with_label_and_loop", description: r##"`break` expression with label and unlabeled loop as value expression"##, diff --git a/tests/ui/lint/lint-owned-heap-memory.rs b/tests/ui/lint/lint-owned-heap-memory.rs deleted file mode 100644 index af47d5c072005..0000000000000 --- a/tests/ui/lint/lint-owned-heap-memory.rs +++ /dev/null @@ -1,12 +0,0 @@ -#![allow(dead_code)] -#![forbid(box_pointers)] - - -struct Foo { - x: Box //~ ERROR type uses owned -} - -fn main() { - let _x: Foo = Foo { x : Box::new(10) }; - //~^ ERROR type uses owned -} diff --git a/tests/ui/lint/lint-owned-heap-memory.stderr b/tests/ui/lint/lint-owned-heap-memory.stderr deleted file mode 100644 index 5ba3969707571..0000000000000 --- a/tests/ui/lint/lint-owned-heap-memory.stderr +++ /dev/null @@ -1,20 +0,0 @@ -error: type uses owned (Box type) pointers: Box - --> $DIR/lint-owned-heap-memory.rs:6:5 - | -LL | x: Box - | ^^^^^^^^^^^^^ - | -note: the lint level is defined here - --> $DIR/lint-owned-heap-memory.rs:2:11 - | -LL | #![forbid(box_pointers)] - | ^^^^^^^^^^^^ - -error: type uses owned (Box type) pointers: Box - --> $DIR/lint-owned-heap-memory.rs:10:29 - | -LL | let _x: Foo = Foo { x : Box::new(10) }; - | ^^^^^^^^^^^^ - -error: aborting due to 2 previous errors - diff --git a/tests/ui/lint/reasons-erroneous.rs b/tests/ui/lint/reasons-erroneous.rs index 244b376b60d88..0aa46953bf1ac 100644 --- a/tests/ui/lint/reasons-erroneous.rs +++ b/tests/ui/lint/reasons-erroneous.rs @@ -9,7 +9,7 @@ #![warn(bare_trait_objects, reasons = "leaders to no sure land, guides their bearings lost")] //~^ ERROR malformed lint attribute //~| NOTE bad attribute argument -#![warn(box_pointers, blerp = "or in league with robbers have reversed the signposts")] +#![warn(unsafe_code, blerp = "or in league with robbers have reversed the signposts")] //~^ ERROR malformed lint attribute //~| NOTE bad attribute argument #![warn(elided_lifetimes_in_paths, reason("disrespectful to ancestors", "irresponsible to heirs"))] diff --git a/tests/ui/lint/reasons-erroneous.stderr b/tests/ui/lint/reasons-erroneous.stderr index adc97174b99cd..fcff88d8e0fa7 100644 --- a/tests/ui/lint/reasons-erroneous.stderr +++ b/tests/ui/lint/reasons-erroneous.stderr @@ -17,10 +17,10 @@ LL | #![warn(bare_trait_objects, reasons = "leaders to no sure land, guides thei | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bad attribute argument error[E0452]: malformed lint attribute input - --> $DIR/reasons-erroneous.rs:12:23 + --> $DIR/reasons-erroneous.rs:12:22 | -LL | #![warn(box_pointers, blerp = "or in league with robbers have reversed the signposts")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bad attribute argument +LL | #![warn(unsafe_code, blerp = "or in league with robbers have reversed the signposts")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bad attribute argument error[E0452]: malformed lint attribute input --> $DIR/reasons-erroneous.rs:15:36 From 372847dd4447bcb5a8c3595f70fd88002a580cbd Mon Sep 17 00:00:00 2001 From: Jules Bertholet Date: Wed, 26 Jun 2024 17:01:04 -0400 Subject: [PATCH 335/892] Implement TC's match ergonomics 2024 proposal Under gate `ref_pat_eat_one_layer_2024_structural`. Enabling `ref_pat_eat_one_layer_2024` at the same time allows the union of what the individual gates allow. --- compiler/rustc_ast/src/ast.rs | 1 + compiler/rustc_feature/src/unstable.rs | 2 + compiler/rustc_hir_typeck/src/pat.rs | 84 ++++++--- compiler/rustc_span/src/symbol.rs | 1 + ...feature-gate-ref_pat_eat_one_layer_2024.rs | 1 + ...ure-gate-ref_pat_eat_one_layer_2024.stderr | 20 +-- .../ref_pat_eat_one_layer_2024.rs | 12 +- ...ef_pat_eat_one_layer_2024_fail.both.stderr | 156 ++++++++++++++++ ...at_eat_one_layer_2024_fail.classic.stderr} | 56 +++--- .../ref_pat_eat_one_layer_2024_fail.rs | 24 ++- ..._eat_one_layer_2024_fail.structural.stderr | 167 ++++++++++++++++++ 11 files changed, 451 insertions(+), 73 deletions(-) create mode 100644 tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.both.stderr rename tests/ui/match/ref_pat_eat_one_layer_2024/{ref_pat_eat_one_layer_2024_fail.stderr => ref_pat_eat_one_layer_2024_fail.classic.stderr} (76%) create mode 100644 tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.structural.stderr diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 4a3ce0e0c3066..9fcc0b25a2634 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -711,6 +711,7 @@ pub enum ByRef { } impl ByRef { + #[must_use] pub fn cap_ref_mutability(mut self, mutbl: Mutability) -> Self { if let ByRef::Yes(old_mutbl) = &mut self { *old_mutbl = cmp::min(*old_mutbl, mutbl); diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index f4e20328814d7..f100d3e4ca84e 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -573,6 +573,8 @@ declare_features! ( (unstable, raw_ref_op, "1.41.0", Some(64490)), /// Makes `&` and `&mut` patterns eat only one layer of references in Rust 2024. (incomplete, ref_pat_eat_one_layer_2024, "1.79.0", Some(123076)), + /// Makes `&` and `&mut` patterns eat only one layer of references in Rust 2024—structural variant + (incomplete, ref_pat_eat_one_layer_2024_structural, "1.79.0", Some(123076)), /// Allows using the `#[register_tool]` attribute. (unstable, register_tool, "1.41.0", Some(66079)), /// Allows the `#[repr(i128)]` attribute for enums. diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index aaf3d3ec34d01..8ce99e204e19f 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -328,8 +328,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { adjust_mode: AdjustMode, max_ref_mutbl: MutblCap, ) -> (Ty<'tcx>, ByRef, MutblCap) { - if let ByRef::Yes(Mutability::Mut) = def_br { - debug_assert!(max_ref_mutbl == MutblCap::Mut); + #[cfg(debug_assertions)] + if def_br == ByRef::Yes(Mutability::Mut) && max_ref_mutbl != MutblCap::Mut { + span_bug!(pat.span, "Pattern mutability cap violated!"); } match adjust_mode { AdjustMode::Pass => (expected, def_br, max_ref_mutbl), @@ -437,7 +438,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }); } - if self.tcx.features().ref_pat_eat_one_layer_2024 { + let features = self.tcx.features(); + if features.ref_pat_eat_one_layer_2024 || features.ref_pat_eat_one_layer_2024_structural { def_br = def_br.cap_ref_mutability(max_ref_mutbl.as_mutbl()); if def_br == ByRef::Yes(Mutability::Not) { max_ref_mutbl = MutblCap::Not; @@ -669,7 +671,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Determine the binding mode... let bm = match user_bind_annot { BindingMode(ByRef::No, Mutability::Mut) if matches!(def_br, ByRef::Yes(_)) => { - if pat.span.at_least_rust_2024() && self.tcx.features().ref_pat_eat_one_layer_2024 { + if pat.span.at_least_rust_2024() + && (self.tcx.features().ref_pat_eat_one_layer_2024 + || self.tcx.features().ref_pat_eat_one_layer_2024_structural) + { if !self.tcx.features().mut_ref { feature_err( &self.tcx.sess, @@ -2122,7 +2127,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { mut expected: Ty<'tcx>, mut pat_info: PatInfo<'tcx, '_>, ) -> Ty<'tcx> { - let no_ref_mut_behind_and = self.tcx.features().ref_pat_eat_one_layer_2024; + let tcx = self.tcx; + let features = tcx.features(); + let ref_pat_eat_one_layer_2024 = features.ref_pat_eat_one_layer_2024; + let ref_pat_eat_one_layer_2024_structural = features.ref_pat_eat_one_layer_2024_structural; + + let no_ref_mut_behind_and = + ref_pat_eat_one_layer_2024 || ref_pat_eat_one_layer_2024_structural; let new_match_ergonomics = pat.span.at_least_rust_2024() && no_ref_mut_behind_and; let pat_prefix_span = @@ -2137,32 +2148,49 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { pat_info.max_ref_mutbl = MutblCap::Mut; } + expected = self.try_structurally_resolve_type(pat.span, expected); if new_match_ergonomics { if let ByRef::Yes(inh_mut) = pat_info.binding_mode { - // ref pattern consumes inherited reference - - if pat_mutbl > inh_mut { - // Tried to match inherited `ref` with `&mut`, which is an error - let err_msg = "cannot match inherited `&` with `&mut` pattern"; - let err = if let Some(span) = pat_prefix_span { - let mut err = self.dcx().struct_span_err(span, err_msg); - err.span_suggestion_verbose( - span, - "replace this `&mut` pattern with `&`", - "&", - Applicability::MachineApplicable, - ); - err + if !ref_pat_eat_one_layer_2024 && let ty::Ref(_, _, r_mutbl) = *expected.kind() { + // Don't attempt to consume inherited reference + pat_info.binding_mode = pat_info.binding_mode.cap_ref_mutability(r_mutbl); + } else { + // ref pattern attempts to consume inherited reference + if pat_mutbl > inh_mut { + // Tried to match inherited `ref` with `&mut` + if !ref_pat_eat_one_layer_2024_structural { + let err_msg = "mismatched types"; + let err = if let Some(span) = pat_prefix_span { + let mut err = self.dcx().struct_span_err(span, err_msg); + err.code(E0308); + err.note("cannot match inherited `&` with `&mut` pattern"); + err.span_suggestion_verbose( + span, + "replace this `&mut` pattern with `&`", + "&", + Applicability::MachineApplicable, + ); + err + } else { + self.dcx().struct_span_err(pat.span, err_msg) + }; + err.emit(); + + pat_info.binding_mode = ByRef::No; + self.typeck_results + .borrow_mut() + .skipped_ref_pats_mut() + .insert(pat.hir_id); + self.check_pat(inner, expected, pat_info); + return expected; + } } else { - self.dcx().struct_span_err(pat.span, err_msg) - }; - err.emit(); + pat_info.binding_mode = ByRef::No; + self.typeck_results.borrow_mut().skipped_ref_pats_mut().insert(pat.hir_id); + self.check_pat(inner, expected, pat_info); + return expected; + } } - - pat_info.binding_mode = ByRef::No; - self.typeck_results.borrow_mut().skipped_ref_pats_mut().insert(pat.hir_id); - self.check_pat(inner, expected, pat_info); - return expected; } } else { // Reset binding mode on old editions @@ -2177,8 +2205,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } - let tcx = self.tcx; - expected = self.try_structurally_resolve_type(pat.span, expected); let (ref_ty, inner_ty) = match self.check_dereferenceable(pat.span, expected, inner) { Ok(()) => { // `demand::subtype` would be good enough, but using `eqtype` turns diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 6d4a8c29bc902..7cd5e4f7ce4c1 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1502,6 +1502,7 @@ symbols! { recursion_limit, reexport_test_harness_main, ref_pat_eat_one_layer_2024, + ref_pat_eat_one_layer_2024_structural, ref_pat_everywhere, ref_unwind_safe_trait, reference, diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/feature-gate-ref_pat_eat_one_layer_2024.rs b/tests/ui/match/ref_pat_eat_one_layer_2024/feature-gate-ref_pat_eat_one_layer_2024.rs index 83f1ee6a77e89..7cbe8e0943ae4 100644 --- a/tests/ui/match/ref_pat_eat_one_layer_2024/feature-gate-ref_pat_eat_one_layer_2024.rs +++ b/tests/ui/match/ref_pat_eat_one_layer_2024/feature-gate-ref_pat_eat_one_layer_2024.rs @@ -1,5 +1,6 @@ //@ edition: 2024 //@ compile-flags: -Zunstable-options +// gate-test-ref_pat_eat_one_layer_2024_structural pub fn main() { if let Some(Some(&x)) = &Some(&Some(0)) { diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/feature-gate-ref_pat_eat_one_layer_2024.stderr b/tests/ui/match/ref_pat_eat_one_layer_2024/feature-gate-ref_pat_eat_one_layer_2024.stderr index 132fe421a18d8..b3ea60252ac47 100644 --- a/tests/ui/match/ref_pat_eat_one_layer_2024/feature-gate-ref_pat_eat_one_layer_2024.stderr +++ b/tests/ui/match/ref_pat_eat_one_layer_2024/feature-gate-ref_pat_eat_one_layer_2024.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:5:22 + --> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:6:22 | LL | if let Some(Some(&x)) = &Some(&Some(0)) { | ^^ --------------- this expression has type `&Option<&Option<{integer}>>` @@ -14,7 +14,7 @@ LL | if let Some(Some(x)) = &Some(&Some(0)) { | ~ error[E0308]: mismatched types - --> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:10:23 + --> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:11:23 | LL | let _: &u32 = x; | ---- ^ expected `&u32`, found integer @@ -27,7 +27,7 @@ LL | let _: &u32 = &x; | + error[E0308]: mismatched types - --> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:13:23 + --> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:14:23 | LL | if let Some(Some(&&x)) = &Some(Some(&0)) { | ^^ --------------- this expression has type `&Option>` @@ -43,7 +43,7 @@ LL + if let Some(Some(&x)) = &Some(Some(&0)) { | error[E0308]: mismatched types - --> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:17:17 + --> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:18:17 | LL | if let Some(&Some(x)) = &Some(Some(0)) { | ^^^^^^^^ -------------- this expression has type `&Option>` @@ -54,7 +54,7 @@ LL | if let Some(&Some(x)) = &Some(Some(0)) { found reference `&_` error[E0308]: mismatched types - --> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:21:22 + --> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:22:22 | LL | if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) { | ^^^^^^ ----------------------- this expression has type `&mut Option<&mut Option<{integer}>>` @@ -64,7 +64,7 @@ LL | if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) { = note: expected type `{integer}` found mutable reference `&mut _` note: to declare a mutable binding use: `mut x` - --> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:21:22 + --> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:22:22 | LL | if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) { | ^^^^^^ @@ -74,7 +74,7 @@ LL | if let Some(Some(x)) = &mut Some(&mut Some(0)) { | ~ error[E0308]: mismatched types - --> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:25:22 + --> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:26:22 | LL | if let Some(Some(&x)) = &Some(&Some(0)) { | ^^ --------------- this expression has type `&Option<&Option<{integer}>>` @@ -89,7 +89,7 @@ LL | if let Some(Some(x)) = &Some(&Some(0)) { | ~ error[E0308]: mismatched types - --> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:29:27 + --> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:30:27 | LL | if let Some(&mut Some(&x)) = &Some(&mut Some(0)) { | ^^ ------------------- this expression has type `&Option<&mut Option<{integer}>>` @@ -104,7 +104,7 @@ LL | if let Some(&mut Some(x)) = &Some(&mut Some(0)) { | ~ error[E0308]: mismatched types - --> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:33:23 + --> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:34:23 | LL | if let Some(&Some(&mut x)) = &mut Some(&Some(0)) { | ^^^^^^ ------------------- this expression has type `&mut Option<&Option<{integer}>>` @@ -114,7 +114,7 @@ LL | if let Some(&Some(&mut x)) = &mut Some(&Some(0)) { = note: expected type `{integer}` found mutable reference `&mut _` note: to declare a mutable binding use: `mut x` - --> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:33:23 + --> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:34:23 | LL | if let Some(&Some(&mut x)) = &mut Some(&Some(0)) { | ^^^^^^ diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024.rs b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024.rs index 829b7f86e2621..0130189b874c6 100644 --- a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024.rs +++ b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024.rs @@ -1,8 +1,10 @@ //@ run-pass //@ edition: 2024 //@ compile-flags: -Zunstable-options +//@ revisions: classic structural both #![allow(incomplete_features)] -#![feature(ref_pat_eat_one_layer_2024)] +#![cfg_attr(any(classic, both), feature(ref_pat_eat_one_layer_2024))] +#![cfg_attr(any(structural, both), feature(ref_pat_eat_one_layer_2024_structural))] pub fn main() { if let Some(Some(&x)) = &Some(&Some(0)) { @@ -53,4 +55,12 @@ pub fn main() { if let Some(&Some(x)) = &mut Some(Some(0)) { let _: u32 = x; } + #[cfg(any(classic, both))] + if let Some(&mut x) = &mut Some(&0) { + let _: &u32 = x; + } + #[cfg(any(structural, both))] + if let Some(&mut x) = &Some(&mut 0) { + let _: &u32 = x; + } } diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.both.stderr b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.both.stderr new file mode 100644 index 0000000000000..f8931403774a3 --- /dev/null +++ b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.both.stderr @@ -0,0 +1,156 @@ +error[E0308]: mismatched types + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:9:17 + | +LL | if let Some(&mut Some(&_)) = &Some(&Some(0)) { + | ^^^^^^^^^^^^^ --------------- this expression has type `&Option<&Option<{integer}>>` + | | + | types differ in mutability + | + = note: expected reference `&Option<{integer}>` + found mutable reference `&mut _` + +error[E0308]: mismatched types + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:12:23 + | +LL | if let Some(&Some(&mut _)) = &Some(&mut Some(0)) { + | ^^^^^^ ------------------- this expression has type `&Option<&mut Option<{integer}>>` + | | + | expected integer, found `&mut _` + | + = note: expected type `{integer}` + found mutable reference `&mut _` + +error[E0308]: mismatched types + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:16:27 + | +LL | let _: &mut u32 = x; + | -------- ^ types differ in mutability + | | + | expected due to this + | + = note: expected mutable reference `&mut u32` + found reference `&{integer}` + +error[E0308]: mismatched types + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:19:23 + | +LL | if let Some(&Some(&mut _)) = &mut Some(&Some(0)) { + | ^^^^^^ ------------------- this expression has type `&mut Option<&Option<{integer}>>` + | | + | expected integer, found `&mut _` + | + = note: expected type `{integer}` + found mutable reference `&mut _` + +error[E0308]: mismatched types + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:22:29 + | +LL | if let Some(&Some(Some((&mut _)))) = &Some(Some(&mut Some(0))) { + | ^^^^^^ ------------------------- this expression has type `&Option>>` + | | + | expected integer, found `&mut _` + | + = note: expected type `{integer}` + found mutable reference `&mut _` + +error[E0308]: mismatched types + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:25:17 + | +LL | if let Some(&mut Some(x)) = &Some(Some(0)) { + | ^^^^^^^^^^^^ -------------- this expression has type `&Option>` + | | + | expected `Option<{integer}>`, found `&mut _` + | + = note: expected enum `Option<{integer}>` + found mutable reference `&mut _` + +error[E0308]: mismatched types + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:28:17 + | +LL | if let Some(&mut Some(x)) = &Some(Some(0)) { + | ^^^^^^^^^^^^ -------------- this expression has type `&Option>` + | | + | expected `Option<{integer}>`, found `&mut _` + | + = note: expected enum `Option<{integer}>` + found mutable reference `&mut _` + +error[E0308]: mismatched types + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:32:9 + | +LL | let &mut _ = &&0; + | ^^^^^^ --- this expression has type `&&{integer}` + | | + | types differ in mutability + | + = note: expected reference `&&{integer}` + found mutable reference `&mut _` + +error[E0308]: mismatched types + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:35:9 + | +LL | let &mut _ = &&&&&&&&&&&&&&&&&&&&&&&&&&&&0; + | ^^^^^^ ----------------------------- this expression has type `&&&&&&&&&&&&&&&&&&&&&&&&&&&&{integer}` + | | + | types differ in mutability + | + = note: expected reference `&&&&&&&&&&&&&&&&&&&&&&&&&&&&{integer}` + found mutable reference `&mut _` + +error[E0308]: mismatched types + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:46:9 + | +LL | let &mut _ = &&mut 0; + | ^^^^^^ ------- this expression has type `&&mut {integer}` + | | + | types differ in mutability + | + = note: expected reference `&&mut {integer}` + found mutable reference `&mut _` + +error[E0308]: mismatched types + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:49:9 + | +LL | let &mut _ = &&&&&&&&&&&&&&&&&&&&&&&&&&&&mut 0; + | ^^^^^^ --------------------------------- this expression has type `&&&&&&&&&&&&&&&&&&&&&&&&&&&&mut {integer}` + | | + | types differ in mutability + | + = note: expected reference `&&&&&&&&&&&&&&&&&&&&&&&&&&&&mut {integer}` + found mutable reference `&mut _` + +error[E0308]: mismatched types + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:52:14 + | +LL | let &mut &mut &mut &mut _ = &mut &&&&mut &&&mut &mut 0; + | ^^^^^^^^^^^^^^^^ -------------------------- this expression has type `&mut &&&&mut &&&mut &mut {integer}` + | | + | types differ in mutability + | + = note: expected reference `&&&&mut &&&mut &mut {integer}` + found mutable reference `&mut _` + +error[E0658]: binding cannot be both mutable and by-reference + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:61:13 + | +LL | let Foo(mut a) = &Foo(0); + | ^^^^ + | + = note: see issue #123076 for more information + = help: add `#![feature(mut_ref)]` 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]: binding cannot be both mutable and by-reference + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:65:13 + | +LL | let Foo(mut a) = &mut Foo(0); + | ^^^^ + | + = note: see issue #123076 for more information + = help: add `#![feature(mut_ref)]` 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 14 previous errors + +Some errors have detailed explanations: E0308, E0658. +For more information about an error, try `rustc --explain E0308`. diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.stderr b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.classic.stderr similarity index 76% rename from tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.stderr rename to tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.classic.stderr index 26317e43d023e..0010a612c30f1 100644 --- a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.stderr +++ b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.classic.stderr @@ -1,27 +1,29 @@ -error: cannot match inherited `&` with `&mut` pattern - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:7:17 +error[E0308]: mismatched types + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:9:17 | LL | if let Some(&mut Some(&_)) = &Some(&Some(0)) { | ^^^^^ | + = note: cannot match inherited `&` with `&mut` pattern help: replace this `&mut` pattern with `&` | LL | if let Some(&Some(&_)) = &Some(&Some(0)) { | ~ -error: cannot match inherited `&` with `&mut` pattern - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:10:23 +error[E0308]: mismatched types + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:12:23 | LL | if let Some(&Some(&mut _)) = &Some(&mut Some(0)) { | ^^^^^ | + = note: cannot match inherited `&` with `&mut` pattern help: replace this `&mut` pattern with `&` | LL | if let Some(&Some(&_)) = &Some(&mut Some(0)) { | ~ error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:14:27 + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:16:27 | LL | let _: &mut u32 = x; | -------- ^ types differ in mutability @@ -31,52 +33,56 @@ LL | let _: &mut u32 = x; = note: expected mutable reference `&mut u32` found reference `&{integer}` -error: cannot match inherited `&` with `&mut` pattern - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:17:23 +error[E0308]: mismatched types + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:19:23 | LL | if let Some(&Some(&mut _)) = &mut Some(&Some(0)) { | ^^^^^ | + = note: cannot match inherited `&` with `&mut` pattern help: replace this `&mut` pattern with `&` | LL | if let Some(&Some(&_)) = &mut Some(&Some(0)) { | ~ -error: cannot match inherited `&` with `&mut` pattern - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:20:29 +error[E0308]: mismatched types + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:22:29 | LL | if let Some(&Some(Some((&mut _)))) = &Some(Some(&mut Some(0))) { | ^^^^^ | + = note: cannot match inherited `&` with `&mut` pattern help: replace this `&mut` pattern with `&` | LL | if let Some(&Some(Some((&_)))) = &Some(Some(&mut Some(0))) { | ~ -error: cannot match inherited `&` with `&mut` pattern - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:23:17 +error[E0308]: mismatched types + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:25:17 | LL | if let Some(&mut Some(x)) = &Some(Some(0)) { | ^^^^^ | + = note: cannot match inherited `&` with `&mut` pattern help: replace this `&mut` pattern with `&` | LL | if let Some(&Some(x)) = &Some(Some(0)) { | ~ -error: cannot match inherited `&` with `&mut` pattern - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:26:17 +error[E0308]: mismatched types + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:28:17 | LL | if let Some(&mut Some(x)) = &Some(Some(0)) { | ^^^^^ | + = note: cannot match inherited `&` with `&mut` pattern help: replace this `&mut` pattern with `&` | LL | if let Some(&Some(x)) = &Some(Some(0)) { | ~ error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:30:9 + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:32:9 | LL | let &mut _ = &&0; | ^^^^^^ --- this expression has type `&&{integer}` @@ -87,7 +93,7 @@ LL | let &mut _ = &&0; found mutable reference `&mut _` error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:33:9 + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:35:9 | LL | let &mut _ = &&&&&&&&&&&&&&&&&&&&&&&&&&&&0; | ^^^^^^ ----------------------------- this expression has type `&&&&&&&&&&&&&&&&&&&&&&&&&&&&{integer}` @@ -97,30 +103,32 @@ LL | let &mut _ = &&&&&&&&&&&&&&&&&&&&&&&&&&&&0; = note: expected reference `&&&&&&&&&&&&&&&&&&&&&&&&&&&&{integer}` found mutable reference `&mut _` -error: cannot match inherited `&` with `&mut` pattern - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:36:17 +error[E0308]: mismatched types + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:38:17 | LL | if let Some(&mut Some(&_)) = &Some(&mut Some(0)) { | ^^^^^ | + = note: cannot match inherited `&` with `&mut` pattern help: replace this `&mut` pattern with `&` | LL | if let Some(&Some(&_)) = &Some(&mut Some(0)) { | ~ -error: cannot match inherited `&` with `&mut` pattern - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:40:22 +error[E0308]: mismatched types + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:42:22 | LL | if let Some(Some(&mut x)) = &Some(Some(&mut 0)) { | ^^^^^ | + = note: cannot match inherited `&` with `&mut` pattern help: replace this `&mut` pattern with `&` | LL | if let Some(Some(&x)) = &Some(Some(&mut 0)) { | ~ error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:44:9 + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:46:9 | LL | let &mut _ = &&mut 0; | ^^^^^^ ------- this expression has type `&&mut {integer}` @@ -131,7 +139,7 @@ LL | let &mut _ = &&mut 0; found mutable reference `&mut _` error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:47:9 + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:49:9 | LL | let &mut _ = &&&&&&&&&&&&&&&&&&&&&&&&&&&&mut 0; | ^^^^^^ --------------------------------- this expression has type `&&&&&&&&&&&&&&&&&&&&&&&&&&&&mut {integer}` @@ -142,7 +150,7 @@ LL | let &mut _ = &&&&&&&&&&&&&&&&&&&&&&&&&&&&mut 0; found mutable reference `&mut _` error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:50:14 + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:52:14 | LL | let &mut &mut &mut &mut _ = &mut &&&&mut &&&mut &mut 0; | ^^^^^^^^^^^^^^^^ -------------------------- this expression has type `&mut &&&&mut &&&mut &mut {integer}` @@ -153,7 +161,7 @@ LL | let &mut &mut &mut &mut _ = &mut &&&&mut &&&mut &mut 0; found mutable reference `&mut _` error[E0658]: binding cannot be both mutable and by-reference - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:55:13 + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:61:13 | LL | let Foo(mut a) = &Foo(0); | ^^^^ @@ -163,7 +171,7 @@ LL | let Foo(mut a) = &Foo(0); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: binding cannot be both mutable and by-reference - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:59:13 + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:65:13 | LL | let Foo(mut a) = &mut Foo(0); | ^^^^ diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.rs b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.rs index 40e8293e24111..4a40060b2ea40 100644 --- a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.rs +++ b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.rs @@ -1,30 +1,32 @@ //@ edition: 2024 //@ compile-flags: -Zunstable-options +//@ revisions: classic structural both #![allow(incomplete_features)] -#![feature(ref_pat_eat_one_layer_2024)] +#![cfg_attr(any(classic, both), feature(ref_pat_eat_one_layer_2024))] +#![cfg_attr(any(structural, both), feature(ref_pat_eat_one_layer_2024_structural))] pub fn main() { if let Some(&mut Some(&_)) = &Some(&Some(0)) { - //~^ ERROR: cannot match inherited `&` with `&mut` pattern + //~^ ERROR: mismatched types } if let Some(&Some(&mut _)) = &Some(&mut Some(0)) { - //~^ ERROR: cannot match inherited `&` with `&mut` pattern + //~^ ERROR: mismatched types } if let Some(&Some(x)) = &mut Some(&Some(0)) { let _: &mut u32 = x; //~^ ERROR: mismatched types } if let Some(&Some(&mut _)) = &mut Some(&Some(0)) { - //~^ ERROR: cannot match inherited `&` with `&mut` pattern + //~^ ERROR: mismatched types } if let Some(&Some(Some((&mut _)))) = &Some(Some(&mut Some(0))) { - //~^ ERROR: cannot match inherited `&` with `&mut` pattern + //~^ ERROR: mismatched types } if let Some(&mut Some(x)) = &Some(Some(0)) { - //~^ ERROR: cannot match inherited `&` with `&mut` pattern + //~^ ERROR: mismatched types } if let Some(&mut Some(x)) = &Some(Some(0)) { - //~^ ERROR: cannot match inherited `&` with `&mut` pattern + //~^ ERROR: mismatched types } let &mut _ = &&0; @@ -34,11 +36,11 @@ pub fn main() { //~^ ERROR: mismatched types if let Some(&mut Some(&_)) = &Some(&mut Some(0)) { - //~^ ERROR: cannot match inherited `&` with `&mut` pattern + //[classic]~^ ERROR: mismatched types } if let Some(Some(&mut x)) = &Some(Some(&mut 0)) { - //~^ ERROR: cannot match inherited `&` with `&mut` pattern + //[classic]~^ ERROR: mismatched types } let &mut _ = &&mut 0; @@ -50,6 +52,10 @@ pub fn main() { let &mut &mut &mut &mut _ = &mut &&&&mut &&&mut &mut 0; //~^ ERROR: mismatched types + if let Some(&mut _) = &mut Some(&0) { + //[structural]~^ ERROR + } + struct Foo(u8); let Foo(mut a) = &Foo(0); diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.structural.stderr b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.structural.stderr new file mode 100644 index 0000000000000..379bb6f4eaab3 --- /dev/null +++ b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.structural.stderr @@ -0,0 +1,167 @@ +error[E0308]: mismatched types + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:9:17 + | +LL | if let Some(&mut Some(&_)) = &Some(&Some(0)) { + | ^^^^^^^^^^^^^ --------------- this expression has type `&Option<&Option<{integer}>>` + | | + | types differ in mutability + | + = note: expected reference `&Option<{integer}>` + found mutable reference `&mut _` + +error[E0308]: mismatched types + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:12:23 + | +LL | if let Some(&Some(&mut _)) = &Some(&mut Some(0)) { + | ^^^^^^ ------------------- this expression has type `&Option<&mut Option<{integer}>>` + | | + | expected integer, found `&mut _` + | + = note: expected type `{integer}` + found mutable reference `&mut _` + +error[E0308]: mismatched types + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:16:27 + | +LL | let _: &mut u32 = x; + | -------- ^ types differ in mutability + | | + | expected due to this + | + = note: expected mutable reference `&mut u32` + found reference `&{integer}` + +error[E0308]: mismatched types + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:19:23 + | +LL | if let Some(&Some(&mut _)) = &mut Some(&Some(0)) { + | ^^^^^^ ------------------- this expression has type `&mut Option<&Option<{integer}>>` + | | + | expected integer, found `&mut _` + | + = note: expected type `{integer}` + found mutable reference `&mut _` + +error[E0308]: mismatched types + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:22:29 + | +LL | if let Some(&Some(Some((&mut _)))) = &Some(Some(&mut Some(0))) { + | ^^^^^^ ------------------------- this expression has type `&Option>>` + | | + | expected integer, found `&mut _` + | + = note: expected type `{integer}` + found mutable reference `&mut _` + +error[E0308]: mismatched types + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:25:17 + | +LL | if let Some(&mut Some(x)) = &Some(Some(0)) { + | ^^^^^^^^^^^^ -------------- this expression has type `&Option>` + | | + | expected `Option<{integer}>`, found `&mut _` + | + = note: expected enum `Option<{integer}>` + found mutable reference `&mut _` + +error[E0308]: mismatched types + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:28:17 + | +LL | if let Some(&mut Some(x)) = &Some(Some(0)) { + | ^^^^^^^^^^^^ -------------- this expression has type `&Option>` + | | + | expected `Option<{integer}>`, found `&mut _` + | + = note: expected enum `Option<{integer}>` + found mutable reference `&mut _` + +error[E0308]: mismatched types + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:32:9 + | +LL | let &mut _ = &&0; + | ^^^^^^ --- this expression has type `&&{integer}` + | | + | types differ in mutability + | + = note: expected reference `&&{integer}` + found mutable reference `&mut _` + +error[E0308]: mismatched types + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:35:9 + | +LL | let &mut _ = &&&&&&&&&&&&&&&&&&&&&&&&&&&&0; + | ^^^^^^ ----------------------------- this expression has type `&&&&&&&&&&&&&&&&&&&&&&&&&&&&{integer}` + | | + | types differ in mutability + | + = note: expected reference `&&&&&&&&&&&&&&&&&&&&&&&&&&&&{integer}` + found mutable reference `&mut _` + +error[E0308]: mismatched types + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:46:9 + | +LL | let &mut _ = &&mut 0; + | ^^^^^^ ------- this expression has type `&&mut {integer}` + | | + | types differ in mutability + | + = note: expected reference `&&mut {integer}` + found mutable reference `&mut _` + +error[E0308]: mismatched types + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:49:9 + | +LL | let &mut _ = &&&&&&&&&&&&&&&&&&&&&&&&&&&&mut 0; + | ^^^^^^ --------------------------------- this expression has type `&&&&&&&&&&&&&&&&&&&&&&&&&&&&mut {integer}` + | | + | types differ in mutability + | + = note: expected reference `&&&&&&&&&&&&&&&&&&&&&&&&&&&&mut {integer}` + found mutable reference `&mut _` + +error[E0308]: mismatched types + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:52:14 + | +LL | let &mut &mut &mut &mut _ = &mut &&&&mut &&&mut &mut 0; + | ^^^^^^^^^^^^^^^^ -------------------------- this expression has type `&mut &&&&mut &&&mut &mut {integer}` + | | + | types differ in mutability + | + = note: expected reference `&&&&mut &&&mut &mut {integer}` + found mutable reference `&mut _` + +error[E0308]: mismatched types + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:55:17 + | +LL | if let Some(&mut _) = &mut Some(&0) { + | ^^^^^^ ------------- this expression has type `&mut Option<&{integer}>` + | | + | types differ in mutability + | + = note: expected reference `&{integer}` + found mutable reference `&mut _` + +error[E0658]: binding cannot be both mutable and by-reference + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:61:13 + | +LL | let Foo(mut a) = &Foo(0); + | ^^^^ + | + = note: see issue #123076 for more information + = help: add `#![feature(mut_ref)]` 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]: binding cannot be both mutable and by-reference + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:65:13 + | +LL | let Foo(mut a) = &mut Foo(0); + | ^^^^ + | + = note: see issue #123076 for more information + = help: add `#![feature(mut_ref)]` 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 15 previous errors + +Some errors have detailed explanations: E0308, E0658. +For more information about an error, try `rustc --explain E0308`. From 35f6b7b97a7dd5fa21834a35faaa7470a071424a Mon Sep 17 00:00:00 2001 From: Jules Bertholet Date: Wed, 26 Jun 2024 17:29:16 -0400 Subject: [PATCH 336/892] Fix tidy --- src/tools/tidy/src/features.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/tools/tidy/src/features.rs b/src/tools/tidy/src/features.rs index 3e84bf3c34be5..e8dff2dc26163 100644 --- a/src/tools/tidy/src/features.rs +++ b/src/tools/tidy/src/features.rs @@ -112,7 +112,7 @@ pub fn check( let file = entry.path(); let filename = file.file_name().unwrap().to_string_lossy(); let filen_underscore = filename.replace('-', "_").replace(".rs", ""); - let filename_is_gate_test = test_filen_gate(&filen_underscore, &mut features); + let filename_gate = test_filen_gate(&filen_underscore, &mut features); for (i, line) in contents.lines().enumerate() { let mut err = |msg: &str| { @@ -128,7 +128,7 @@ pub fn check( }; match features.get_mut(feature_name) { Some(f) => { - if filename_is_gate_test { + if filename_gate == Some(feature_name) { err(&format!( "The file is already marked as gate test \ through its name, no need for a \ @@ -259,18 +259,18 @@ fn find_attr_val<'a>(line: &'a str, attr: &str) -> Option<&'a str> { r.captures(line).and_then(|c| c.get(1)).map(|m| m.as_str()) } -fn test_filen_gate(filen_underscore: &str, features: &mut Features) -> bool { +fn test_filen_gate<'f>(filen_underscore: &'f str, features: &mut Features) -> Option<&'f str> { let prefix = "feature_gate_"; - if filen_underscore.starts_with(prefix) { + if let Some(suffix) = filen_underscore.strip_prefix(prefix) { for (n, f) in features.iter_mut() { // Equivalent to filen_underscore == format!("feature_gate_{n}") - if &filen_underscore[prefix.len()..] == n { + if suffix == n { f.has_gate_test = true; - return true; + return Some(suffix); } } } - false + None } pub fn collect_lang_features(base_compiler_path: &Path, bad: &mut bool) -> Features { From c8a89b05533e7fcec0866e0a25424f94afed93a0 Mon Sep 17 00:00:00 2001 From: The Miri Cronjob Bot Date: Thu, 27 Jun 2024 04:54:26 +0000 Subject: [PATCH 337/892] 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 e5e9f0bbdaf16..989e9bc6d0242 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version @@ -1 +1 @@ -c290e9de32e8ba6a673ef125fde40eadd395d170 +7033f9b14a37f4a00766d6c01326600b31f3a716 From 0c0dfb88eeefbbaa4c10cfa4a7f0e16541e086eb Mon Sep 17 00:00:00 2001 From: Urgau Date: Thu, 27 Jun 2024 08:05:07 +0200 Subject: [PATCH 338/892] Switch back `non_local_definitions` lint to allow-by-default as request T-lang is requesting some major changes in the lint inner workings in #126768#issuecomment-2192634762 --- compiler/rustc_lint/src/non_local_def.rs | 2 +- tests/rustdoc-ui/doctest/non_local_defs.rs | 2 + .../rustdoc-ui/doctest/non_local_defs.stderr | 8 ++- .../rustdoc-ui/doctest/non_local_defs.stdout | 2 +- tests/ui/lint/non-local-defs/cargo-update.rs | 2 + .../lint/non-local-defs/cargo-update.stderr | 8 ++- tests/ui/lint/non-local-defs/consts.rs | 2 + tests/ui/lint/non-local-defs/consts.stderr | 22 ++++--- .../lint/non-local-defs/exhaustive-trait.rs | 2 + .../non-local-defs/exhaustive-trait.stderr | 18 +++--- tests/ui/lint/non-local-defs/exhaustive.rs | 2 + .../ui/lint/non-local-defs/exhaustive.stderr | 58 ++++++++++--------- .../non-local-defs/from-local-for-global.rs | 2 + .../from-local-for-global.stderr | 24 ++++---- tests/ui/lint/non-local-defs/generics.rs | 2 + tests/ui/lint/non-local-defs/generics.stderr | 36 +++++++----- .../lint/non-local-defs/inside-macro_rules.rs | 2 + .../non-local-defs/inside-macro_rules.stderr | 8 ++- tests/ui/lint/non-local-defs/local.rs | 2 + tests/ui/lint/non-local-defs/macro_rules.rs | 2 + .../ui/lint/non-local-defs/macro_rules.stderr | 14 +++-- .../non-local-defs/suggest-moving-inner.rs | 2 + .../suggest-moving-inner.stderr | 10 +++- .../trait-solver-overflow-123573.rs | 2 + .../trait-solver-overflow-123573.stderr | 10 +++- tests/ui/lint/non-local-defs/weird-exprs.rs | 2 + .../ui/lint/non-local-defs/weird-exprs.stderr | 18 +++--- 27 files changed, 169 insertions(+), 95 deletions(-) diff --git a/compiler/rustc_lint/src/non_local_def.rs b/compiler/rustc_lint/src/non_local_def.rs index 300dac442d564..17429ed061f25 100644 --- a/compiler/rustc_lint/src/non_local_def.rs +++ b/compiler/rustc_lint/src/non_local_def.rs @@ -50,7 +50,7 @@ declare_lint! { /// All nested bodies (functions, enum discriminant, array length, consts) (expect for /// `const _: Ty = { ... }` in top-level module, which is still undecided) are checked. pub NON_LOCAL_DEFINITIONS, - Warn, + Allow, "checks for non-local definitions", report_in_external_macro } diff --git a/tests/rustdoc-ui/doctest/non_local_defs.rs b/tests/rustdoc-ui/doctest/non_local_defs.rs index aa166c343b2b0..d8cfe5637ae02 100644 --- a/tests/rustdoc-ui/doctest/non_local_defs.rs +++ b/tests/rustdoc-ui/doctest/non_local_defs.rs @@ -4,6 +4,8 @@ //@ normalize-stderr-test: "tests/rustdoc-ui/doctest" -> "$$DIR" //@ normalize-stdout-test "finished in \d+\.\d+s" -> "finished in $$TIME" +#![doc(test(attr(warn(non_local_definitions))))] + //! ``` //! #[macro_export] //! macro_rules! a_macro { () => {} } diff --git a/tests/rustdoc-ui/doctest/non_local_defs.stderr b/tests/rustdoc-ui/doctest/non_local_defs.stderr index 2b47e6b5bc4d5..13cd2558793f8 100644 --- a/tests/rustdoc-ui/doctest/non_local_defs.stderr +++ b/tests/rustdoc-ui/doctest/non_local_defs.stderr @@ -1,5 +1,5 @@ warning: non-local `macro_rules!` definition, `#[macro_export]` macro should be written at top level module - --> $DIR/non_local_defs.rs:9:1 + --> $DIR/non_local_defs.rs:11:1 | LL | macro_rules! a_macro { () => {} } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -7,7 +7,11 @@ LL | macro_rules! a_macro { () => {} } = help: remove the `#[macro_export]` or make this doc-test a standalone test with its own `fn main() { ... }` = note: a `macro_rules!` definition is non-local if it is nested inside an item and has a `#[macro_export]` attribute = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue - = note: `#[warn(non_local_definitions)]` on by default +note: the lint level is defined here + --> $DIR/non_local_defs.rs:8:9 + | +LL | #![warn(non_local_definitions)] + | ^^^^^^^^^^^^^^^^^^^^^ warning: 1 warning emitted diff --git a/tests/rustdoc-ui/doctest/non_local_defs.stdout b/tests/rustdoc-ui/doctest/non_local_defs.stdout index bee195fcdd772..61b4074886e4b 100644 --- a/tests/rustdoc-ui/doctest/non_local_defs.stdout +++ b/tests/rustdoc-ui/doctest/non_local_defs.stdout @@ -1,6 +1,6 @@ running 1 test -test $DIR/non_local_defs.rs - (line 7) ... ok +test $DIR/non_local_defs.rs - (line 9) ... ok test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME diff --git a/tests/ui/lint/non-local-defs/cargo-update.rs b/tests/ui/lint/non-local-defs/cargo-update.rs index 8b8c15795d376..3c62a655a9f61 100644 --- a/tests/ui/lint/non-local-defs/cargo-update.rs +++ b/tests/ui/lint/non-local-defs/cargo-update.rs @@ -10,6 +10,8 @@ // of the `cargo update` suggestion we assert it here. //@ error-pattern: `cargo update -p non_local_macro` +#![warn(non_local_definitions)] + extern crate non_local_macro; struct LocalStruct; diff --git a/tests/ui/lint/non-local-defs/cargo-update.stderr b/tests/ui/lint/non-local-defs/cargo-update.stderr index bccf8622bac66..4dd41519455c6 100644 --- a/tests/ui/lint/non-local-defs/cargo-update.stderr +++ b/tests/ui/lint/non-local-defs/cargo-update.stderr @@ -1,5 +1,5 @@ warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/cargo-update.rs:17:1 + --> $DIR/cargo-update.rs:19:1 | LL | non_local_macro::non_local_impl!(LocalStruct); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -14,7 +14,11 @@ LL | non_local_macro::non_local_impl!(LocalStruct); = note: an `impl` is never scoped, even when it is nested inside an item, as it may impact type checking outside of that item, which can be the case if neither the trait or the self type are at the same nesting level as the `impl` = note: items in an anonymous const item (`const _: () = { ... }`) are treated as in the same scope as the anonymous const's declaration for the purpose of this lint = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue - = note: `#[warn(non_local_definitions)]` on by default +note: the lint level is defined here + --> $DIR/cargo-update.rs:13:9 + | +LL | #![warn(non_local_definitions)] + | ^^^^^^^^^^^^^^^^^^^^^ = note: this warning originates in the macro `non_local_macro::non_local_impl` (in Nightly builds, run with -Z macro-backtrace for more info) warning: 1 warning emitted diff --git a/tests/ui/lint/non-local-defs/consts.rs b/tests/ui/lint/non-local-defs/consts.rs index d8a497e43e502..e7ee611529b96 100644 --- a/tests/ui/lint/non-local-defs/consts.rs +++ b/tests/ui/lint/non-local-defs/consts.rs @@ -2,6 +2,8 @@ //@ edition:2021 //@ rustc-env:CARGO_CRATE_NAME=non_local_def +#![warn(non_local_definitions)] + struct Test; trait Uto {} diff --git a/tests/ui/lint/non-local-defs/consts.stderr b/tests/ui/lint/non-local-defs/consts.stderr index 9f70119e0f8c9..ed7bd56fe4a54 100644 --- a/tests/ui/lint/non-local-defs/consts.stderr +++ b/tests/ui/lint/non-local-defs/consts.stderr @@ -1,5 +1,5 @@ warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/consts.rs:13:5 + --> $DIR/consts.rs:15:5 | LL | const Z: () = { | ----------- @@ -17,10 +17,14 @@ LL | impl Uto for &Test {} = note: an `impl` is never scoped, even when it is nested inside an item, as it may impact type checking outside of that item, which can be the case if neither the trait or the self type are at the same nesting level as the `impl` = note: items in an anonymous const item (`const _: () = { ... }`) are treated as in the same scope as the anonymous const's declaration for the purpose of this lint = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue - = note: `#[warn(non_local_definitions)]` on by default +note: the lint level is defined here + --> $DIR/consts.rs:5:9 + | +LL | #![warn(non_local_definitions)] + | ^^^^^^^^^^^^^^^^^^^^^ warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/consts.rs:24:5 + --> $DIR/consts.rs:26:5 | LL | static A: u32 = { | ------------- move the `impl` block outside of this static `A` @@ -36,7 +40,7 @@ LL | impl Uto2 for Test {} = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/consts.rs:32:5 + --> $DIR/consts.rs:34:5 | LL | const B: u32 = { | ------------ move the `impl` block outside of this constant `B` @@ -52,7 +56,7 @@ LL | impl Uto3 for Test {} = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/consts.rs:43:5 + --> $DIR/consts.rs:45:5 | LL | fn main() { | --------- move the `impl` block outside of this function `main` @@ -65,7 +69,7 @@ LL | impl Test { = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/consts.rs:50:9 + --> $DIR/consts.rs:52:9 | LL | const { | ___________- @@ -84,7 +88,7 @@ LL | | }; = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/consts.rs:59:9 + --> $DIR/consts.rs:61:9 | LL | const _: u32 = { | ------------ move the `impl` block outside of this constant `_` and up 2 bodies @@ -98,7 +102,7 @@ LL | impl Test { = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/consts.rs:72:9 + --> $DIR/consts.rs:74:9 | LL | let _a = || { | -- move the `impl` block outside of this closure `` and up 2 bodies @@ -113,7 +117,7 @@ LL | impl Uto9 for Test {} = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/consts.rs:79:9 + --> $DIR/consts.rs:81:9 | LL | type A = [u32; { | ____________________- diff --git a/tests/ui/lint/non-local-defs/exhaustive-trait.rs b/tests/ui/lint/non-local-defs/exhaustive-trait.rs index 40d2314460f86..79f8cc4620b97 100644 --- a/tests/ui/lint/non-local-defs/exhaustive-trait.rs +++ b/tests/ui/lint/non-local-defs/exhaustive-trait.rs @@ -1,6 +1,8 @@ //@ check-pass //@ edition:2021 +#![warn(non_local_definitions)] + struct Dog; fn main() { diff --git a/tests/ui/lint/non-local-defs/exhaustive-trait.stderr b/tests/ui/lint/non-local-defs/exhaustive-trait.stderr index 67df0e31d5bdf..24c9a6b4f01e2 100644 --- a/tests/ui/lint/non-local-defs/exhaustive-trait.stderr +++ b/tests/ui/lint/non-local-defs/exhaustive-trait.stderr @@ -1,5 +1,5 @@ warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/exhaustive-trait.rs:7:5 + --> $DIR/exhaustive-trait.rs:9:5 | LL | fn main() { | --------- move the `impl` block outside of this function `main` @@ -12,10 +12,14 @@ LL | impl PartialEq<()> for Dog { = note: `impl` may be usable in bounds, etc. from outside the expression, which might e.g. make something constructible that previously wasn't, because it's still on a publicly-visible type = note: an `impl` is never scoped, even when it is nested inside an item, as it may impact type checking outside of that item, which can be the case if neither the trait or the self type are at the same nesting level as the `impl` = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue - = note: `#[warn(non_local_definitions)]` on by default +note: the lint level is defined here + --> $DIR/exhaustive-trait.rs:4:9 + | +LL | #![warn(non_local_definitions)] + | ^^^^^^^^^^^^^^^^^^^^^ warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/exhaustive-trait.rs:14:5 + --> $DIR/exhaustive-trait.rs:16:5 | LL | fn main() { | --------- move the `impl` block outside of this function `main` @@ -31,7 +35,7 @@ LL | impl PartialEq<()> for &Dog { = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/exhaustive-trait.rs:21:5 + --> $DIR/exhaustive-trait.rs:23:5 | LL | fn main() { | --------- move the `impl` block outside of this function `main` @@ -47,7 +51,7 @@ LL | impl PartialEq for () { = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/exhaustive-trait.rs:28:5 + --> $DIR/exhaustive-trait.rs:30:5 | LL | fn main() { | --------- move the `impl` block outside of this function `main` @@ -63,7 +67,7 @@ LL | impl PartialEq<&Dog> for () { = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/exhaustive-trait.rs:35:5 + --> $DIR/exhaustive-trait.rs:37:5 | LL | fn main() { | --------- move the `impl` block outside of this function `main` @@ -79,7 +83,7 @@ LL | impl PartialEq for &Dog { = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/exhaustive-trait.rs:42:5 + --> $DIR/exhaustive-trait.rs:44:5 | LL | fn main() { | --------- move the `impl` block outside of this function `main` diff --git a/tests/ui/lint/non-local-defs/exhaustive.rs b/tests/ui/lint/non-local-defs/exhaustive.rs index 2fb30f4344abb..f59a85c7ed94f 100644 --- a/tests/ui/lint/non-local-defs/exhaustive.rs +++ b/tests/ui/lint/non-local-defs/exhaustive.rs @@ -1,6 +1,8 @@ //@ check-pass //@ edition:2021 +#![warn(non_local_definitions)] + use std::fmt::Display; trait Trait {} diff --git a/tests/ui/lint/non-local-defs/exhaustive.stderr b/tests/ui/lint/non-local-defs/exhaustive.stderr index 1e0d5caec3830..6d8c2ec0bc7cf 100644 --- a/tests/ui/lint/non-local-defs/exhaustive.stderr +++ b/tests/ui/lint/non-local-defs/exhaustive.stderr @@ -1,5 +1,5 @@ warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/exhaustive.rs:10:5 + --> $DIR/exhaustive.rs:12:5 | LL | fn main() { | --------- move the `impl` block outside of this function `main` @@ -10,10 +10,14 @@ LL | impl Test { | = note: methods and associated constants are still usable outside the current expression, only `impl Local` and `impl dyn Local` can ever be private, and only if the type is nested in the same item as the `impl` = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue - = note: `#[warn(non_local_definitions)]` on by default +note: the lint level is defined here + --> $DIR/exhaustive.rs:4:9 + | +LL | #![warn(non_local_definitions)] + | ^^^^^^^^^^^^^^^^^^^^^ warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/exhaustive.rs:15:5 + --> $DIR/exhaustive.rs:17:5 | LL | fn main() { | --------- move the `impl` block outside of this function `main` @@ -29,7 +33,7 @@ LL | impl Display for Test { = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/exhaustive.rs:22:5 + --> $DIR/exhaustive.rs:24:5 | LL | fn main() { | --------- move the `impl` block outside of this function `main` @@ -43,7 +47,7 @@ LL | impl dyn Trait {} = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/exhaustive.rs:25:5 + --> $DIR/exhaustive.rs:27:5 | LL | fn main() { | --------- move the `impl` block outside of this function `main` @@ -59,7 +63,7 @@ LL | impl Trait for Vec { } = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/exhaustive.rs:28:5 + --> $DIR/exhaustive.rs:30:5 | LL | fn main() { | --------- move the `impl` block outside of this function `main` @@ -75,7 +79,7 @@ LL | impl Trait for &dyn Trait {} = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/exhaustive.rs:31:5 + --> $DIR/exhaustive.rs:33:5 | LL | fn main() { | --------- move the `impl` block outside of this function `main` @@ -91,7 +95,7 @@ LL | impl Trait for *mut Test {} = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/exhaustive.rs:34:5 + --> $DIR/exhaustive.rs:36:5 | LL | fn main() { | --------- move the `impl` block outside of this function `main` @@ -107,7 +111,7 @@ LL | impl Trait for *mut [Test] {} = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/exhaustive.rs:37:5 + --> $DIR/exhaustive.rs:39:5 | LL | fn main() { | --------- move the `impl` block outside of this function `main` @@ -123,7 +127,7 @@ LL | impl Trait for [Test; 8] {} = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/exhaustive.rs:40:5 + --> $DIR/exhaustive.rs:42:5 | LL | fn main() { | --------- move the `impl` block outside of this function `main` @@ -139,7 +143,7 @@ LL | impl Trait for (Test,) {} = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/exhaustive.rs:43:5 + --> $DIR/exhaustive.rs:45:5 | LL | fn main() { | --------- move the `impl` block outside of this function `main` @@ -155,7 +159,7 @@ LL | impl Trait for fn(Test) -> () {} = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/exhaustive.rs:46:5 + --> $DIR/exhaustive.rs:48:5 | LL | fn main() { | --------- move the `impl` block outside of this function `main` @@ -171,7 +175,7 @@ LL | impl Trait for fn() -> Test {} = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/exhaustive.rs:50:9 + --> $DIR/exhaustive.rs:52:9 | LL | let _a = || { | -- move the `impl` block outside of this closure `` and up 2 bodies @@ -186,7 +190,7 @@ LL | impl Trait for Test {} = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/exhaustive.rs:58:5 + --> $DIR/exhaustive.rs:60:5 | LL | impl Trait for *mut InsideMain {} | ^^^^^-----^^^^^--------------- @@ -198,7 +202,7 @@ LL | impl Trait for *mut InsideMain {} = note: `impl` may be usable in bounds, etc. from outside the expression, which might e.g. make something constructible that previously wasn't, because it's still on a publicly-visible type = note: an `impl` is never scoped, even when it is nested inside an item, as it may impact type checking outside of that item, which can be the case if neither the trait or the self type are at the same nesting level as the `impl` help: move the `impl` block outside of this function `main` - --> $DIR/exhaustive.rs:9:1 + --> $DIR/exhaustive.rs:11:1 | LL | fn main() { | ^^^^^^^^^ @@ -208,7 +212,7 @@ LL | struct InsideMain; = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/exhaustive.rs:60:5 + --> $DIR/exhaustive.rs:62:5 | LL | impl Trait for *mut [InsideMain] {} | ^^^^^-----^^^^^----------------- @@ -219,7 +223,7 @@ LL | impl Trait for *mut [InsideMain] {} = note: `impl` may be usable in bounds, etc. from outside the expression, which might e.g. make something constructible that previously wasn't, because it's still on a publicly-visible type = note: an `impl` is never scoped, even when it is nested inside an item, as it may impact type checking outside of that item, which can be the case if neither the trait or the self type are at the same nesting level as the `impl` help: move the `impl` block outside of this function `main` - --> $DIR/exhaustive.rs:9:1 + --> $DIR/exhaustive.rs:11:1 | LL | fn main() { | ^^^^^^^^^ @@ -229,7 +233,7 @@ LL | struct InsideMain; = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/exhaustive.rs:62:5 + --> $DIR/exhaustive.rs:64:5 | LL | impl Trait for [InsideMain; 8] {} | ^^^^^-----^^^^^--------------- @@ -240,7 +244,7 @@ LL | impl Trait for [InsideMain; 8] {} = note: `impl` may be usable in bounds, etc. from outside the expression, which might e.g. make something constructible that previously wasn't, because it's still on a publicly-visible type = note: an `impl` is never scoped, even when it is nested inside an item, as it may impact type checking outside of that item, which can be the case if neither the trait or the self type are at the same nesting level as the `impl` help: move the `impl` block outside of this function `main` - --> $DIR/exhaustive.rs:9:1 + --> $DIR/exhaustive.rs:11:1 | LL | fn main() { | ^^^^^^^^^ @@ -250,7 +254,7 @@ LL | struct InsideMain; = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/exhaustive.rs:64:5 + --> $DIR/exhaustive.rs:66:5 | LL | impl Trait for (InsideMain,) {} | ^^^^^-----^^^^^------------- @@ -261,7 +265,7 @@ LL | impl Trait for (InsideMain,) {} = note: `impl` may be usable in bounds, etc. from outside the expression, which might e.g. make something constructible that previously wasn't, because it's still on a publicly-visible type = note: an `impl` is never scoped, even when it is nested inside an item, as it may impact type checking outside of that item, which can be the case if neither the trait or the self type are at the same nesting level as the `impl` help: move the `impl` block outside of this function `main` - --> $DIR/exhaustive.rs:9:1 + --> $DIR/exhaustive.rs:11:1 | LL | fn main() { | ^^^^^^^^^ @@ -271,7 +275,7 @@ LL | struct InsideMain; = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/exhaustive.rs:66:5 + --> $DIR/exhaustive.rs:68:5 | LL | impl Trait for fn(InsideMain) -> () {} | ^^^^^-----^^^^^-------------------- @@ -282,7 +286,7 @@ LL | impl Trait for fn(InsideMain) -> () {} = note: `impl` may be usable in bounds, etc. from outside the expression, which might e.g. make something constructible that previously wasn't, because it's still on a publicly-visible type = note: an `impl` is never scoped, even when it is nested inside an item, as it may impact type checking outside of that item, which can be the case if neither the trait or the self type are at the same nesting level as the `impl` help: move the `impl` block outside of this function `main` - --> $DIR/exhaustive.rs:9:1 + --> $DIR/exhaustive.rs:11:1 | LL | fn main() { | ^^^^^^^^^ @@ -292,7 +296,7 @@ LL | struct InsideMain; = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/exhaustive.rs:68:5 + --> $DIR/exhaustive.rs:70:5 | LL | impl Trait for fn() -> InsideMain {} | ^^^^^-----^^^^^------------------ @@ -303,7 +307,7 @@ LL | impl Trait for fn() -> InsideMain {} = note: `impl` may be usable in bounds, etc. from outside the expression, which might e.g. make something constructible that previously wasn't, because it's still on a publicly-visible type = note: an `impl` is never scoped, even when it is nested inside an item, as it may impact type checking outside of that item, which can be the case if neither the trait or the self type are at the same nesting level as the `impl` help: move the `impl` block outside of this function `main` - --> $DIR/exhaustive.rs:9:1 + --> $DIR/exhaustive.rs:11:1 | LL | fn main() { | ^^^^^^^^^ @@ -313,7 +317,7 @@ LL | struct InsideMain; = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/exhaustive.rs:72:9 + --> $DIR/exhaustive.rs:74:9 | LL | fn inside_inside() { | ------------------ move the `impl` block outside of this function `inside_inside` and up 2 bodies @@ -328,7 +332,7 @@ LL | impl Display for InsideMain { = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/exhaustive.rs:79:9 + --> $DIR/exhaustive.rs:81:9 | LL | fn inside_inside() { | ------------------ move the `impl` block outside of this function `inside_inside` and up 2 bodies diff --git a/tests/ui/lint/non-local-defs/from-local-for-global.rs b/tests/ui/lint/non-local-defs/from-local-for-global.rs index fea9679d7375d..1d8f4845c2860 100644 --- a/tests/ui/lint/non-local-defs/from-local-for-global.rs +++ b/tests/ui/lint/non-local-defs/from-local-for-global.rs @@ -1,6 +1,8 @@ //@ check-pass //@ edition:2021 +#![warn(non_local_definitions)] + struct Cat; struct Wrap(T); diff --git a/tests/ui/lint/non-local-defs/from-local-for-global.stderr b/tests/ui/lint/non-local-defs/from-local-for-global.stderr index 67fd937d134cc..04eba8435fc04 100644 --- a/tests/ui/lint/non-local-defs/from-local-for-global.stderr +++ b/tests/ui/lint/non-local-defs/from-local-for-global.stderr @@ -1,5 +1,5 @@ warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/from-local-for-global.rs:8:5 + --> $DIR/from-local-for-global.rs:10:5 | LL | fn main() { | --------- move the `impl` block outside of this function `main` @@ -12,10 +12,14 @@ LL | impl From for () { = note: `impl` may be usable in bounds, etc. from outside the expression, which might e.g. make something constructible that previously wasn't, because it's still on a publicly-visible type = note: an `impl` is never scoped, even when it is nested inside an item, as it may impact type checking outside of that item, which can be the case if neither the trait or the self type are at the same nesting level as the `impl` = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue - = note: `#[warn(non_local_definitions)]` on by default +note: the lint level is defined here + --> $DIR/from-local-for-global.rs:4:9 + | +LL | #![warn(non_local_definitions)] + | ^^^^^^^^^^^^^^^^^^^^^ warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/from-local-for-global.rs:18:5 + --> $DIR/from-local-for-global.rs:20:5 | LL | impl From>> for () { | ^^^^^----^^^^^^^^^^^^^^^^^^^^^^^^^^^-- @@ -25,7 +29,7 @@ LL | impl From>> for () { = note: `impl` may be usable in bounds, etc. from outside the expression, which might e.g. make something constructible that previously wasn't, because it's still on a publicly-visible type = note: an `impl` is never scoped, even when it is nested inside an item, as it may impact type checking outside of that item, which can be the case if neither the trait or the self type are at the same nesting level as the `impl` help: move the `impl` block outside of this function `main` - --> $DIR/from-local-for-global.rs:7:1 + --> $DIR/from-local-for-global.rs:9:1 | LL | fn main() { | ^^^^^^^^^ @@ -35,7 +39,7 @@ LL | struct Elephant; = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/from-local-for-global.rs:32:5 + --> $DIR/from-local-for-global.rs:34:5 | LL | impl StillNonLocal for &Foo {} | ^^^^^-------------^^^^^---- @@ -47,7 +51,7 @@ LL | impl StillNonLocal for &Foo {} = note: `impl` may be usable in bounds, etc. from outside the expression, which might e.g. make something constructible that previously wasn't, because it's still on a publicly-visible type = note: an `impl` is never scoped, even when it is nested inside an item, as it may impact type checking outside of that item, which can be the case if neither the trait or the self type are at the same nesting level as the `impl` help: move the `impl` block outside of this function `only_global` - --> $DIR/from-local-for-global.rs:30:1 + --> $DIR/from-local-for-global.rs:32:1 | LL | fn only_global() { | ^^^^^^^^^^^^^^^^ @@ -56,7 +60,7 @@ LL | struct Foo; = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/from-local-for-global.rs:40:5 + --> $DIR/from-local-for-global.rs:42:5 | LL | impl From for GlobalSameFunction { | ^^^^^----^^^^^^^^^^^^^------------------ @@ -67,7 +71,7 @@ LL | impl From for GlobalSameFunction { = note: `impl` may be usable in bounds, etc. from outside the expression, which might e.g. make something constructible that previously wasn't, because it's still on a publicly-visible type = note: an `impl` is never scoped, even when it is nested inside an item, as it may impact type checking outside of that item, which can be the case if neither the trait or the self type are at the same nesting level as the `impl` help: move the `impl` block outside of this function `same_function` - --> $DIR/from-local-for-global.rs:38:1 + --> $DIR/from-local-for-global.rs:40:1 | LL | fn same_function() { | ^^^^^^^^^^^^^^^^^^ @@ -76,7 +80,7 @@ LL | struct Local1(GlobalSameFunction); = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/from-local-for-global.rs:48:5 + --> $DIR/from-local-for-global.rs:50:5 | LL | impl From for GlobalSameFunction { | ^^^^^----^^^^^^^^^^^^^------------------ @@ -87,7 +91,7 @@ LL | impl From for GlobalSameFunction { = note: `impl` may be usable in bounds, etc. from outside the expression, which might e.g. make something constructible that previously wasn't, because it's still on a publicly-visible type = note: an `impl` is never scoped, even when it is nested inside an item, as it may impact type checking outside of that item, which can be the case if neither the trait or the self type are at the same nesting level as the `impl` help: move the `impl` block outside of this function `same_function` - --> $DIR/from-local-for-global.rs:38:1 + --> $DIR/from-local-for-global.rs:40:1 | LL | fn same_function() { | ^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/lint/non-local-defs/generics.rs b/tests/ui/lint/non-local-defs/generics.rs index 0f526526dba21..13e392c510c64 100644 --- a/tests/ui/lint/non-local-defs/generics.rs +++ b/tests/ui/lint/non-local-defs/generics.rs @@ -1,6 +1,8 @@ //@ check-pass //@ edition:2021 +#![warn(non_local_definitions)] + trait Global {} fn main() { diff --git a/tests/ui/lint/non-local-defs/generics.stderr b/tests/ui/lint/non-local-defs/generics.stderr index ed2f87a4ed2d2..35366ed8ecf94 100644 --- a/tests/ui/lint/non-local-defs/generics.stderr +++ b/tests/ui/lint/non-local-defs/generics.stderr @@ -1,5 +1,5 @@ warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/generics.rs:9:5 + --> $DIR/generics.rs:11:5 | LL | impl Global for Vec { } | ^^^^^^^^^^^^^^^------^^^^^---^^^ @@ -10,17 +10,21 @@ LL | impl Global for Vec { } = note: `impl` may be usable in bounds, etc. from outside the expression, which might e.g. make something constructible that previously wasn't, because it's still on a publicly-visible type = note: an `impl` is never scoped, even when it is nested inside an item, as it may impact type checking outside of that item, which can be the case if neither the trait or the self type are at the same nesting level as the `impl` help: move the `impl` block outside of this function `main` - --> $DIR/generics.rs:6:1 + --> $DIR/generics.rs:8:1 | LL | fn main() { | ^^^^^^^^^ LL | trait Local {}; | ----------- may need to be moved as well = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue - = note: `#[warn(non_local_definitions)]` on by default +note: the lint level is defined here + --> $DIR/generics.rs:4:9 + | +LL | #![warn(non_local_definitions)] + | ^^^^^^^^^^^^^^^^^^^^^ warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/generics.rs:20:5 + --> $DIR/generics.rs:22:5 | LL | impl Uto7 for Test where Local: std::any::Any {} | ^^^^^----^^^^^---- @@ -31,7 +35,7 @@ LL | impl Uto7 for Test where Local: std::any::Any {} = note: `impl` may be usable in bounds, etc. from outside the expression, which might e.g. make something constructible that previously wasn't, because it's still on a publicly-visible type = note: an `impl` is never scoped, even when it is nested inside an item, as it may impact type checking outside of that item, which can be the case if neither the trait or the self type are at the same nesting level as the `impl` help: move the `impl` block outside of this function `bad` - --> $DIR/generics.rs:18:1 + --> $DIR/generics.rs:20:1 | LL | fn bad() { | ^^^^^^^^ @@ -40,7 +44,7 @@ LL | struct Local; = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/generics.rs:23:5 + --> $DIR/generics.rs:25:5 | LL | fn bad() { | -------- move the `impl` block outside of this function `bad` @@ -56,7 +60,7 @@ LL | impl Uto8 for T {} = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/generics.rs:32:5 + --> $DIR/generics.rs:34:5 | LL | impl Default for UwU { | ^^^^^-------^^^^^---^^^^^ @@ -67,7 +71,7 @@ LL | impl Default for UwU { = note: `impl` may be usable in bounds, etc. from outside the expression, which might e.g. make something constructible that previously wasn't, because it's still on a publicly-visible type = note: an `impl` is never scoped, even when it is nested inside an item, as it may impact type checking outside of that item, which can be the case if neither the trait or the self type are at the same nesting level as the `impl` help: move the `impl` block outside of this function `fun` - --> $DIR/generics.rs:29:1 + --> $DIR/generics.rs:31:1 | LL | fn fun() { | ^^^^^^^^ @@ -77,7 +81,7 @@ LL | struct OwO; = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/generics.rs:43:5 + --> $DIR/generics.rs:45:5 | LL | impl AsRef for () { | ^^^^^-----^^^^^^^^^^-- @@ -88,7 +92,7 @@ LL | impl AsRef for () { = note: `impl` may be usable in bounds, etc. from outside the expression, which might e.g. make something constructible that previously wasn't, because it's still on a publicly-visible type = note: an `impl` is never scoped, even when it is nested inside an item, as it may impact type checking outside of that item, which can be the case if neither the trait or the self type are at the same nesting level as the `impl` help: move the `impl` block outside of this function `meow` - --> $DIR/generics.rs:40:1 + --> $DIR/generics.rs:42:1 | LL | fn meow() { | ^^^^^^^^^ @@ -98,7 +102,7 @@ LL | struct Cat; = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/generics.rs:54:5 + --> $DIR/generics.rs:56:5 | LL | impl PartialEq for G { | ^^^^^---------^^^^^^^^- @@ -109,7 +113,7 @@ LL | impl PartialEq for G { = note: `impl` may be usable in bounds, etc. from outside the expression, which might e.g. make something constructible that previously wasn't, because it's still on a publicly-visible type = note: an `impl` is never scoped, even when it is nested inside an item, as it may impact type checking outside of that item, which can be the case if neither the trait or the self type are at the same nesting level as the `impl` help: move the `impl` block outside of this function `fun2` - --> $DIR/generics.rs:51:1 + --> $DIR/generics.rs:53:1 | LL | fn fun2() { | ^^^^^^^^^ @@ -119,7 +123,7 @@ LL | struct B; = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/generics.rs:69:5 + --> $DIR/generics.rs:71:5 | LL | impl From>> for () { | ^^^^^----^^^^^^^^^^^^^^^^^^^^^^^-- @@ -129,7 +133,7 @@ LL | impl From>> for () { = note: `impl` may be usable in bounds, etc. from outside the expression, which might e.g. make something constructible that previously wasn't, because it's still on a publicly-visible type = note: an `impl` is never scoped, even when it is nested inside an item, as it may impact type checking outside of that item, which can be the case if neither the trait or the self type are at the same nesting level as the `impl` help: move the `impl` block outside of this function `rawr` - --> $DIR/generics.rs:66:1 + --> $DIR/generics.rs:68:1 | LL | fn rawr() { | ^^^^^^^^^ @@ -138,7 +142,7 @@ LL | struct Lion; = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/generics.rs:76:5 + --> $DIR/generics.rs:78:5 | LL | impl From<()> for Wrap { | ^^^^^----^^^^^^^^^----^^^^^^ @@ -149,7 +153,7 @@ LL | impl From<()> for Wrap { = note: `impl` may be usable in bounds, etc. from outside the expression, which might e.g. make something constructible that previously wasn't, because it's still on a publicly-visible type = note: an `impl` is never scoped, even when it is nested inside an item, as it may impact type checking outside of that item, which can be the case if neither the trait or the self type are at the same nesting level as the `impl` help: move the `impl` block outside of this function `rawr` - --> $DIR/generics.rs:66:1 + --> $DIR/generics.rs:68:1 | LL | fn rawr() { | ^^^^^^^^^ diff --git a/tests/ui/lint/non-local-defs/inside-macro_rules.rs b/tests/ui/lint/non-local-defs/inside-macro_rules.rs index 9f21cc89852e2..744a1f7a6f1ab 100644 --- a/tests/ui/lint/non-local-defs/inside-macro_rules.rs +++ b/tests/ui/lint/non-local-defs/inside-macro_rules.rs @@ -1,6 +1,8 @@ //@ check-pass //@ edition:2021 +#![warn(non_local_definitions)] + macro_rules! m { () => { trait MacroTrait {} diff --git a/tests/ui/lint/non-local-defs/inside-macro_rules.stderr b/tests/ui/lint/non-local-defs/inside-macro_rules.stderr index fa9ba2cb785d9..89835372c8a53 100644 --- a/tests/ui/lint/non-local-defs/inside-macro_rules.stderr +++ b/tests/ui/lint/non-local-defs/inside-macro_rules.stderr @@ -1,5 +1,5 @@ warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/inside-macro_rules.rs:9:13 + --> $DIR/inside-macro_rules.rs:11:13 | LL | fn my_func() { | ------------ move the `impl` block outside of this function `my_func` @@ -16,7 +16,11 @@ LL | m!(); = note: `impl` may be usable in bounds, etc. from outside the expression, which might e.g. make something constructible that previously wasn't, because it's still on a publicly-visible type = note: an `impl` is never scoped, even when it is nested inside an item, as it may impact type checking outside of that item, which can be the case if neither the trait or the self type are at the same nesting level as the `impl` = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue - = note: `#[warn(non_local_definitions)]` on by default +note: the lint level is defined here + --> $DIR/inside-macro_rules.rs:4:9 + | +LL | #![warn(non_local_definitions)] + | ^^^^^^^^^^^^^^^^^^^^^ = note: this warning originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info) warning: 1 warning emitted diff --git a/tests/ui/lint/non-local-defs/local.rs b/tests/ui/lint/non-local-defs/local.rs index 166ee88c0210c..e9dbff1300f28 100644 --- a/tests/ui/lint/non-local-defs/local.rs +++ b/tests/ui/lint/non-local-defs/local.rs @@ -1,6 +1,8 @@ //@ check-pass //@ edition:2021 +#![warn(non_local_definitions)] + use std::fmt::Debug; trait GlobalTrait {} diff --git a/tests/ui/lint/non-local-defs/macro_rules.rs b/tests/ui/lint/non-local-defs/macro_rules.rs index ed30a24903d01..20672cf0a3225 100644 --- a/tests/ui/lint/non-local-defs/macro_rules.rs +++ b/tests/ui/lint/non-local-defs/macro_rules.rs @@ -3,6 +3,8 @@ //@ aux-build:non_local_macro.rs //@ rustc-env:CARGO_CRATE_NAME=non_local_def +#![warn(non_local_definitions)] + extern crate non_local_macro; const B: u32 = { diff --git a/tests/ui/lint/non-local-defs/macro_rules.stderr b/tests/ui/lint/non-local-defs/macro_rules.stderr index 4e86fc7b987e6..f9995bf82183c 100644 --- a/tests/ui/lint/non-local-defs/macro_rules.stderr +++ b/tests/ui/lint/non-local-defs/macro_rules.stderr @@ -1,5 +1,5 @@ warning: non-local `macro_rules!` definition, `#[macro_export]` macro should be written at top level module - --> $DIR/macro_rules.rs:10:5 + --> $DIR/macro_rules.rs:12:5 | LL | macro_rules! m0 { () => { } }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -7,10 +7,14 @@ LL | macro_rules! m0 { () => { } }; = help: remove the `#[macro_export]` or move this `macro_rules!` outside the of the current constant `B` = note: a `macro_rules!` definition is non-local if it is nested inside an item and has a `#[macro_export]` attribute = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue - = note: `#[warn(non_local_definitions)]` on by default +note: the lint level is defined here + --> $DIR/macro_rules.rs:6:9 + | +LL | #![warn(non_local_definitions)] + | ^^^^^^^^^^^^^^^^^^^^^ warning: non-local `macro_rules!` definition, `#[macro_export]` macro should be written at top level module - --> $DIR/macro_rules.rs:16:1 + --> $DIR/macro_rules.rs:18:1 | LL | non_local_macro::non_local_macro_rules!(my_macro); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -22,7 +26,7 @@ LL | non_local_macro::non_local_macro_rules!(my_macro); = note: this warning originates in the macro `non_local_macro::non_local_macro_rules` (in Nightly builds, run with -Z macro-backtrace for more info) warning: non-local `macro_rules!` definition, `#[macro_export]` macro should be written at top level module - --> $DIR/macro_rules.rs:21:5 + --> $DIR/macro_rules.rs:23:5 | LL | macro_rules! m { () => { } }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -32,7 +36,7 @@ LL | macro_rules! m { () => { } }; = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `macro_rules!` definition, `#[macro_export]` macro should be written at top level module - --> $DIR/macro_rules.rs:29:13 + --> $DIR/macro_rules.rs:31:13 | LL | macro_rules! m2 { () => { } }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/lint/non-local-defs/suggest-moving-inner.rs b/tests/ui/lint/non-local-defs/suggest-moving-inner.rs index 61b32e5bad9fe..9360ace4d805b 100644 --- a/tests/ui/lint/non-local-defs/suggest-moving-inner.rs +++ b/tests/ui/lint/non-local-defs/suggest-moving-inner.rs @@ -1,5 +1,7 @@ //@ check-pass +#![warn(non_local_definitions)] + trait Trait {} fn main() { diff --git a/tests/ui/lint/non-local-defs/suggest-moving-inner.stderr b/tests/ui/lint/non-local-defs/suggest-moving-inner.stderr index f0de0f72e74f6..a214415316f84 100644 --- a/tests/ui/lint/non-local-defs/suggest-moving-inner.stderr +++ b/tests/ui/lint/non-local-defs/suggest-moving-inner.stderr @@ -1,5 +1,5 @@ warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/suggest-moving-inner.rs:12:5 + --> $DIR/suggest-moving-inner.rs:14:5 | LL | impl Trait for &Vec> | ^^^^^^^^-----^^^^^^^^^^^^^^^^^---------------------------------- @@ -10,7 +10,7 @@ LL | impl Trait for &Vec> = note: `impl` may be usable in bounds, etc. from outside the expression, which might e.g. make something constructible that previously wasn't, because it's still on a publicly-visible type = note: an `impl` is never scoped, even when it is nested inside an item, as it may impact type checking outside of that item, which can be the case if neither the trait or the self type are at the same nesting level as the `impl` help: move the `impl` block outside of this function `main` - --> $DIR/suggest-moving-inner.rs:5:1 + --> $DIR/suggest-moving-inner.rs:7:1 | LL | fn main() { | ^^^^^^^^^ @@ -23,7 +23,11 @@ LL | struct InsideMain; LL | trait HasFoo {} | ------------ may need to be moved as well = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue - = note: `#[warn(non_local_definitions)]` on by default +note: the lint level is defined here + --> $DIR/suggest-moving-inner.rs:3:9 + | +LL | #![warn(non_local_definitions)] + | ^^^^^^^^^^^^^^^^^^^^^ warning: 1 warning emitted diff --git a/tests/ui/lint/non-local-defs/trait-solver-overflow-123573.rs b/tests/ui/lint/non-local-defs/trait-solver-overflow-123573.rs index 4291426e046a8..b726398bf9c9a 100644 --- a/tests/ui/lint/non-local-defs/trait-solver-overflow-123573.rs +++ b/tests/ui/lint/non-local-defs/trait-solver-overflow-123573.rs @@ -3,6 +3,8 @@ // https://github.com/rust-lang/rust/issues/123573#issue-2229428739 +#![warn(non_local_definitions)] + pub trait Test {} impl<'a, T: 'a> Test for &[T] where &'a T: Test {} diff --git a/tests/ui/lint/non-local-defs/trait-solver-overflow-123573.stderr b/tests/ui/lint/non-local-defs/trait-solver-overflow-123573.stderr index 80930ce1bcdf3..2eb71cecacaaf 100644 --- a/tests/ui/lint/non-local-defs/trait-solver-overflow-123573.stderr +++ b/tests/ui/lint/non-local-defs/trait-solver-overflow-123573.stderr @@ -1,5 +1,5 @@ warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/trait-solver-overflow-123573.rs:12:5 + --> $DIR/trait-solver-overflow-123573.rs:14:5 | LL | impl Test for &Local {} | ^^^^^----^^^^^------ @@ -11,14 +11,18 @@ LL | impl Test for &Local {} = note: `impl` may be usable in bounds, etc. from outside the expression, which might e.g. make something constructible that previously wasn't, because it's still on a publicly-visible type = note: an `impl` is never scoped, even when it is nested inside an item, as it may impact type checking outside of that item, which can be the case if neither the trait or the self type are at the same nesting level as the `impl` help: move the `impl` block outside of this function `main` - --> $DIR/trait-solver-overflow-123573.rs:10:1 + --> $DIR/trait-solver-overflow-123573.rs:12:1 | LL | fn main() { | ^^^^^^^^^ LL | struct Local {} | ------------ may need to be moved as well = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue - = note: `#[warn(non_local_definitions)]` on by default +note: the lint level is defined here + --> $DIR/trait-solver-overflow-123573.rs:6:9 + | +LL | #![warn(non_local_definitions)] + | ^^^^^^^^^^^^^^^^^^^^^ warning: 1 warning emitted diff --git a/tests/ui/lint/non-local-defs/weird-exprs.rs b/tests/ui/lint/non-local-defs/weird-exprs.rs index 1d9cecea0c971..fbf1fd941eecb 100644 --- a/tests/ui/lint/non-local-defs/weird-exprs.rs +++ b/tests/ui/lint/non-local-defs/weird-exprs.rs @@ -1,6 +1,8 @@ //@ check-pass //@ edition:2021 +#![warn(non_local_definitions)] + trait Uto {} struct Test; diff --git a/tests/ui/lint/non-local-defs/weird-exprs.stderr b/tests/ui/lint/non-local-defs/weird-exprs.stderr index cd414d636d34b..49aba904ebb0e 100644 --- a/tests/ui/lint/non-local-defs/weird-exprs.stderr +++ b/tests/ui/lint/non-local-defs/weird-exprs.stderr @@ -1,5 +1,5 @@ warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/weird-exprs.rs:8:5 + --> $DIR/weird-exprs.rs:10:5 | LL | type A = [u32; { | ________________- @@ -16,10 +16,14 @@ LL | | }]; = note: `impl` may be usable in bounds, etc. from outside the expression, which might e.g. make something constructible that previously wasn't, because it's still on a publicly-visible type = note: an `impl` is never scoped, even when it is nested inside an item, as it may impact type checking outside of that item, which can be the case if neither the trait or the self type are at the same nesting level as the `impl` = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue - = note: `#[warn(non_local_definitions)]` on by default +note: the lint level is defined here + --> $DIR/weird-exprs.rs:4:9 + | +LL | #![warn(non_local_definitions)] + | ^^^^^^^^^^^^^^^^^^^^^ warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/weird-exprs.rs:16:9 + --> $DIR/weird-exprs.rs:18:9 | LL | Discr = { | _____________- @@ -38,7 +42,7 @@ LL | | } = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/weird-exprs.rs:25:9 + --> $DIR/weird-exprs.rs:27:9 | LL | let _array = [0i32; { | _________________________- @@ -57,7 +61,7 @@ LL | | }]; = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/weird-exprs.rs:34:9 + --> $DIR/weird-exprs.rs:36:9 | LL | type A = [u32; { | ____________________- @@ -76,7 +80,7 @@ LL | | }]; = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/weird-exprs.rs:41:9 + --> $DIR/weird-exprs.rs:43:9 | LL | fn a(_: [u32; { | ___________________- @@ -95,7 +99,7 @@ LL | | }]) {} = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/weird-exprs.rs:48:9 + --> $DIR/weird-exprs.rs:50:9 | LL | fn b() -> [u32; { | _____________________- From 4cc16a53aeea6b82d05e665cb4bcbcddb1e2d7be Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Thu, 27 Jun 2024 09:53:59 +0200 Subject: [PATCH 339/892] tame unexpected_cfgs --- src/tools/miri/build.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/tools/miri/build.rs b/src/tools/miri/build.rs index 0977c0ba016bd..0918c9b13214d 100644 --- a/src/tools/miri/build.rs +++ b/src/tools/miri/build.rs @@ -1,8 +1,10 @@ fn main() { // Don't rebuild miri when nothing changed. println!("cargo:rerun-if-changed=build.rs"); - // Re-export the TARGET environment variable so it can - // be accessed by miri. + // Re-export the TARGET environment variable so it can be accessed by miri. Needed to know the + // "host" triple inside Miri. let target = std::env::var("TARGET").unwrap(); println!("cargo:rustc-env=TARGET={target}"); + // Allow some cfgs. + println!("cargo::rustc-check-cfg=cfg(bootstrap)"); } From 151986f493bce146db808db2bbb2b29fa6e0049c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Thu, 27 Jun 2024 10:22:03 +0200 Subject: [PATCH 340/892] Implement `x perf` as a separate tool --- Cargo.lock | 7 ++ Cargo.toml | 1 + src/bootstrap/src/core/build_steps/perf.rs | 32 ++--- src/bootstrap/src/core/build_steps/tool.rs | 1 + src/bootstrap/src/core/config/flags.rs | 4 +- src/etc/completions/x.py.fish | 2 +- src/etc/completions/x.py.ps1 | 2 +- src/etc/completions/x.py.zsh | 2 +- src/tools/rustc-perf-wrapper/Cargo.toml | 7 ++ src/tools/rustc-perf-wrapper/README.md | 3 + src/tools/rustc-perf-wrapper/src/config.rs | 45 +++++++ src/tools/rustc-perf-wrapper/src/main.rs | 130 +++++++++++++++++++++ 12 files changed, 211 insertions(+), 25 deletions(-) create mode 100644 src/tools/rustc-perf-wrapper/Cargo.toml create mode 100644 src/tools/rustc-perf-wrapper/README.md create mode 100644 src/tools/rustc-perf-wrapper/src/config.rs create mode 100644 src/tools/rustc-perf-wrapper/src/main.rs diff --git a/Cargo.lock b/Cargo.lock index 241a37588b409..b1b7020f29000 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3453,6 +3453,13 @@ dependencies = [ "stable_mir", ] +[[package]] +name = "rustc-perf-wrapper" +version = "0.1.0" +dependencies = [ + "clap", +] + [[package]] name = "rustc-rayon" version = "0.5.0" diff --git a/Cargo.toml b/Cargo.toml index c17ea99d03767..93c520b0d689d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -44,6 +44,7 @@ members = [ "src/tools/rustdoc-gui-test", "src/tools/opt-dist", "src/tools/coverage-dump", + "src/tools/rustc-perf-wrapper", ] exclude = [ diff --git a/src/bootstrap/src/core/build_steps/perf.rs b/src/bootstrap/src/core/build_steps/perf.rs index 9d70ca6bd71fd..f8170580722bf 100644 --- a/src/bootstrap/src/core/build_steps/perf.rs +++ b/src/bootstrap/src/core/build_steps/perf.rs @@ -1,7 +1,5 @@ -use std::process::Command; - use crate::core::build_steps::compile::{Std, Sysroot}; -use crate::core::build_steps::tool::RustcPerf; +use crate::core::build_steps::tool::{RustcPerf, Tool}; use crate::core::builder::Builder; use crate::core::config::DebuginfoLevel; @@ -22,24 +20,16 @@ Consider setting `rust.debuginfo-level = 1` in `config.toml`."#); let sysroot = builder.ensure(Sysroot::new(compiler)); let rustc = sysroot.join("bin/rustc"); - let results_dir = builder.build.tempdir().join("rustc-perf"); - - let mut cmd = Command::new(collector); - let cmd = cmd - .arg("profile_local") - .arg("eprintln") - .arg("--out-dir") - .arg(&results_dir) - .arg("--include") - .arg("helloworld") - .arg(&rustc); - - builder.info(&format!("Running `rustc-perf` using `{}`", rustc.display())); + let rustc_perf_dir = builder.build.tempdir().join("rustc-perf"); + let profile_results_dir = rustc_perf_dir.join("results"); - // We need to set the working directory to `src/tools/perf`, so that it can find the directory - // with compile-time benchmarks. - let cmd = cmd.current_dir(builder.src.join("src/tools/rustc-perf")); - builder.build.run(cmd); + // We need to take args passed after `--` and pass them to `rustc-perf-wrapper` + let args = std::env::args().skip_while(|a| a != "--").skip(1); - builder.info(&format!("You can find the results at `{}`", results_dir.display())); + let mut cmd = builder.tool_cmd(Tool::RustcPerfWrapper); + cmd.env("PERF_RUSTC", rustc) + .env("PERF_COLLECTOR", collector) + .env("PERF_RESULT_DIR", profile_results_dir) + .args(args); + builder.run(&mut cmd); } diff --git a/src/bootstrap/src/core/build_steps/tool.rs b/src/bootstrap/src/core/build_steps/tool.rs index 7411d0ba2befe..2ceca7305a621 100644 --- a/src/bootstrap/src/core/build_steps/tool.rs +++ b/src/bootstrap/src/core/build_steps/tool.rs @@ -336,6 +336,7 @@ bootstrap_tool!( GenerateWindowsSys, "src/tools/generate-windows-sys", "generate-windows-sys"; RustdocGUITest, "src/tools/rustdoc-gui-test", "rustdoc-gui-test", is_unstable_tool = true, allow_features = "test"; CoverageDump, "src/tools/coverage-dump", "coverage-dump"; + RustcPerfWrapper, "src/tools/rustc-perf-wrapper", "rustc-perf-wrapper"; ); #[derive(Debug, Clone, Hash, PartialEq, Eq)] diff --git a/src/bootstrap/src/core/config/flags.rs b/src/bootstrap/src/core/config/flags.rs index eb5152a38312b..aeb608a9ea26b 100644 --- a/src/bootstrap/src/core/config/flags.rs +++ b/src/bootstrap/src/core/config/flags.rs @@ -470,7 +470,9 @@ Arguments: versioned_dirs: bool, }, /// Perform profiling and benchmarking of the compiler using the - /// `rustc-perf` benchmark suite. + /// `rustc-perf-wrapper` tool. + /// + /// You need to pass arguments after `--`, e.g.`x perf -- cachegrind`. Perf {}, } diff --git a/src/etc/completions/x.py.fish b/src/etc/completions/x.py.fish index 2072f76a48181..805fc8aa8ccd0 100644 --- a/src/etc/completions/x.py.fish +++ b/src/etc/completions/x.py.fish @@ -48,7 +48,7 @@ complete -c x.py -n "__fish_use_subcommand" -f -a "run" -d 'Run tools contained complete -c x.py -n "__fish_use_subcommand" -f -a "setup" -d 'Set up the environment for development' complete -c x.py -n "__fish_use_subcommand" -f -a "suggest" -d 'Suggest a subset of tests to run, based on modified files' complete -c x.py -n "__fish_use_subcommand" -f -a "vendor" -d 'Vendor dependencies' -complete -c x.py -n "__fish_use_subcommand" -f -a "perf" -d 'Perform profiling and benchmarking of the compiler using the `rustc-perf` benchmark suite' +complete -c x.py -n "__fish_use_subcommand" -f -a "perf" -d 'Perform profiling and benchmarking of the compiler using the `rustc-perf-wrapper` tool' complete -c x.py -n "__fish_seen_subcommand_from build" -l config -d 'TOML configuration file for build' -r -F complete -c x.py -n "__fish_seen_subcommand_from build" -l build-dir -d 'Build directory, overrides `build.build-dir` in `config.toml`' -r -f -a "(__fish_complete_directories)" complete -c x.py -n "__fish_seen_subcommand_from build" -l build -d 'build target of the stage0 compiler' -r -f diff --git a/src/etc/completions/x.py.ps1 b/src/etc/completions/x.py.ps1 index 919382d441ffc..ce590d2fa4897 100644 --- a/src/etc/completions/x.py.ps1 +++ b/src/etc/completions/x.py.ps1 @@ -75,7 +75,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock { [CompletionResult]::new('setup', 'setup', [CompletionResultType]::ParameterValue, 'Set up the environment for development') [CompletionResult]::new('suggest', 'suggest', [CompletionResultType]::ParameterValue, 'Suggest a subset of tests to run, based on modified files') [CompletionResult]::new('vendor', 'vendor', [CompletionResultType]::ParameterValue, 'Vendor dependencies') - [CompletionResult]::new('perf', 'perf', [CompletionResultType]::ParameterValue, 'Perform profiling and benchmarking of the compiler using the `rustc-perf` benchmark suite') + [CompletionResult]::new('perf', 'perf', [CompletionResultType]::ParameterValue, 'Perform profiling and benchmarking of the compiler using the `rustc-perf-wrapper` tool') break } 'x.py;build' { diff --git a/src/etc/completions/x.py.zsh b/src/etc/completions/x.py.zsh index bbebf8b892d1f..fc8be4f788127 100644 --- a/src/etc/completions/x.py.zsh +++ b/src/etc/completions/x.py.zsh @@ -856,7 +856,7 @@ _x.py_commands() { 'setup:Set up the environment for development' \ 'suggest:Suggest a subset of tests to run, based on modified files' \ 'vendor:Vendor dependencies' \ -'perf:Perform profiling and benchmarking of the compiler using the \`rustc-perf\` benchmark suite' \ +'perf:Perform profiling and benchmarking of the compiler using the \`rustc-perf-wrapper\` tool' \ ) _describe -t commands 'x.py commands' commands "$@" } diff --git a/src/tools/rustc-perf-wrapper/Cargo.toml b/src/tools/rustc-perf-wrapper/Cargo.toml new file mode 100644 index 0000000000000..416bfef41d7fd --- /dev/null +++ b/src/tools/rustc-perf-wrapper/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "rustc-perf-wrapper" +version = "0.1.0" +edition = "2021" + +[dependencies] +clap = { version = "4.5.7", features = ["derive", "env"] } diff --git a/src/tools/rustc-perf-wrapper/README.md b/src/tools/rustc-perf-wrapper/README.md new file mode 100644 index 0000000000000..7c096e3081416 --- /dev/null +++ b/src/tools/rustc-perf-wrapper/README.md @@ -0,0 +1,3 @@ +# rustc-perf wrapper +Utility tool for invoking [`rustc-perf`](https://github.com/rust-lang/rustc-perf) for benchmarking/profiling +a stage1/2 compiler built by bootstrap using `x run perf`. diff --git a/src/tools/rustc-perf-wrapper/src/config.rs b/src/tools/rustc-perf-wrapper/src/config.rs new file mode 100644 index 0000000000000..a88abfe472377 --- /dev/null +++ b/src/tools/rustc-perf-wrapper/src/config.rs @@ -0,0 +1,45 @@ +use std::fmt::{Display, Formatter}; + +#[derive(Clone, Copy, Debug, clap::ValueEnum)] +#[value(rename_all = "PascalCase")] +pub enum Profile { + Check, + Debug, + Doc, + Opt, + Clippy, +} + +impl Display for Profile { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + let name = match self { + Profile::Check => "Check", + Profile::Debug => "Debug", + Profile::Doc => "Doc", + Profile::Opt => "Opt", + Profile::Clippy => "Clippy", + }; + f.write_str(name) + } +} + +#[derive(Clone, Copy, Debug, clap::ValueEnum)] +#[value(rename_all = "PascalCase")] +pub enum Scenario { + Full, + IncrFull, + IncrUnchanged, + IncrPatched, +} + +impl Display for Scenario { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + let name = match self { + Scenario::Full => "Full", + Scenario::IncrFull => "IncrFull", + Scenario::IncrUnchanged => "IncrUnchanged", + Scenario::IncrPatched => "IncrPatched", + }; + f.write_str(name) + } +} diff --git a/src/tools/rustc-perf-wrapper/src/main.rs b/src/tools/rustc-perf-wrapper/src/main.rs new file mode 100644 index 0000000000000..0974661f99787 --- /dev/null +++ b/src/tools/rustc-perf-wrapper/src/main.rs @@ -0,0 +1,130 @@ +use crate::config::{Profile, Scenario}; +use clap::Parser; +use std::path::PathBuf; +use std::process::Command; + +mod config; + +/// Performs profiling or benchmarking with [`rustc-perf`](https://github.com/rust-lang/rustc-perf) +/// using a locally built compiler. +#[derive(Debug, clap::Parser)] +// Hide arguments from BuildContext in the default usage string. +// Clap does not seem to have a way of disabling the usage of these arguments. +#[clap(override_usage = "rustc-perf-wrapper [OPTIONS] ")] +pub struct Args { + #[clap(subcommand)] + cmd: PerfCommand, + + #[clap(flatten)] + opts: SharedOpts, + + #[clap(flatten)] + ctx: BuildContext, +} + +#[derive(Debug, clap::Parser)] +enum PerfCommand { + /// Run `profile_local eprintln`. + /// This executes the compiler on the given benchmarks and stores its stderr output. + Eprintln, + /// Run `profile_local samply` + /// This executes the compiler on the given benchmarks and profiles it with `samply`. + /// You need to install `samply`, e.g. using `cargo install samply`. + Samply, + /// Run `profile_local cachegrind`. + /// This executes the compiler on the given benchmarks under `Cachegrind`. + Cachegrind, +} + +impl PerfCommand { + fn is_profiling(&self) -> bool { + match self { + PerfCommand::Eprintln | PerfCommand::Samply | PerfCommand::Cachegrind => true, + } + } +} + +#[derive(Debug, clap::Parser)] +struct SharedOpts { + /// Select the benchmarks that you want to run (separated by commas). + /// If unspecified, all benchmarks will be executed. + #[clap(long, global = true, value_delimiter = ',')] + include: Vec, + /// Select the scenarios that should be benchmarked. + #[clap( + long, + global = true, + value_delimiter = ',', + default_value = "Full,IncrFull,IncrUnchanged,IncrPatched" + )] + scenarios: Vec, + /// Select the profiles that should be benchmarked. + #[clap(long, global = true, value_delimiter = ',', default_value = "Check,Debug,Opt")] + profiles: Vec, +} + +/// These arguments are mostly designed to be passed from bootstrap, not by users +/// directly. +#[derive(Debug, clap::Parser)] +struct BuildContext { + /// Compiler binary that will be benchmarked/profiled. + #[clap(long, hide = true, env = "PERF_RUSTC")] + compiler: PathBuf, + /// rustc-perf collector binary that will be used for running benchmarks/profilers. + #[clap(long, hide = true, env = "PERF_COLLECTOR")] + collector: PathBuf, + /// Directory where to store results. + #[clap(long, hide = true, env = "PERF_RESULT_DIR")] + results_dir: PathBuf, +} + +fn main() { + let args = Args::parse(); + run(args); +} + +fn run(args: Args) { + let mut cmd = Command::new(args.ctx.collector); + match &args.cmd { + PerfCommand::Eprintln => { + cmd.arg("profile_local").arg("eprintln"); + } + PerfCommand::Samply => { + cmd.arg("profile_local").arg("samply"); + } + PerfCommand::Cachegrind => { + cmd.arg("profile_local").arg("cachegrind"); + } + } + if args.cmd.is_profiling() { + cmd.arg("--out-dir").arg(&args.ctx.results_dir); + } + + if !args.opts.include.is_empty() { + cmd.arg("--include").arg(args.opts.include.join(",")); + } + if !args.opts.profiles.is_empty() { + cmd.arg("--profiles") + .arg(args.opts.profiles.iter().map(|p| p.to_string()).collect::>().join(",")); + } + if !args.opts.scenarios.is_empty() { + cmd.arg("--scenarios") + .arg(args.opts.scenarios.iter().map(|p| p.to_string()).collect::>().join(",")); + } + cmd.arg(&args.ctx.compiler); + + println!("Running `rustc-perf` using `{}`", args.ctx.compiler.display()); + + const MANIFEST_DIR: &str = env!("CARGO_MANIFEST_DIR"); + + let rustc_perf_dir = PathBuf::from(MANIFEST_DIR).join("../rustc-perf"); + + // We need to set the working directory to `src/tools/perf`, so that it can find the directory + // with compile-time benchmarks. + let cmd = cmd.current_dir(rustc_perf_dir); + cmd.status().expect("error while running rustc-perf collector"); + + if args.cmd.is_profiling() { + println!("You can find the results at `{}`", args.ctx.results_dir.display()); + } +} From ba198af81f75ef01b7d603a7b1c001fafe8ad4a4 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Thu, 27 Jun 2024 09:07:57 +0000 Subject: [PATCH 341/892] Rename `'cx` to `'infcx` --- .../rustc_borrowck/src/borrowck_errors.rs | 50 +++++++++---------- .../src/diagnostics/bound_region_errors.rs | 30 +++++------ .../src/diagnostics/conflict_errors.rs | 24 ++++----- .../rustc_borrowck/src/diagnostics/mod.rs | 4 +- .../src/diagnostics/move_errors.rs | 6 +-- .../src/diagnostics/mutability_errors.rs | 8 +-- .../src/diagnostics/region_errors.rs | 8 +-- compiler/rustc_borrowck/src/lib.rs | 46 ++++++++--------- compiler/rustc_borrowck/src/used_muts.rs | 4 +- compiler/rustc_hir_typeck/src/coercion.rs | 6 +-- 10 files changed, 93 insertions(+), 93 deletions(-) diff --git a/compiler/rustc_borrowck/src/borrowck_errors.rs b/compiler/rustc_borrowck/src/borrowck_errors.rs index 604feeb47feaf..8eb44458137ff 100644 --- a/compiler/rustc_borrowck/src/borrowck_errors.rs +++ b/compiler/rustc_borrowck/src/borrowck_errors.rs @@ -6,8 +6,8 @@ use rustc_middle::span_bug; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_span::Span; -impl<'cx, 'tcx> crate::MirBorrowckCtxt<'_, '_, 'cx, 'tcx> { - pub fn dcx(&self) -> DiagCtxtHandle<'cx> { +impl<'infcx, 'tcx> crate::MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> { + pub fn dcx(&self) -> DiagCtxtHandle<'infcx> { self.infcx.dcx() } @@ -18,7 +18,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'_, '_, 'cx, 'tcx> { place: &str, borrow_place: &str, value_place: &str, - ) -> Diag<'cx> { + ) -> Diag<'infcx> { self.dcx().create_err(crate::session_diagnostics::MoveBorrow { place, span, @@ -34,7 +34,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'_, '_, 'cx, 'tcx> { desc: &str, borrow_span: Span, borrow_desc: &str, - ) -> Diag<'cx> { + ) -> Diag<'infcx> { struct_span_code_err!( self.dcx(), span, @@ -54,7 +54,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'_, '_, 'cx, 'tcx> { old_loan_span: Span, old_opt_via: &str, old_load_end_span: Option, - ) -> Diag<'cx> { + ) -> Diag<'infcx> { let via = |msg: &str| if msg.is_empty() { "".to_string() } else { format!(" (via {msg})") }; let mut err = struct_span_code_err!( self.dcx(), @@ -101,7 +101,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'_, '_, 'cx, 'tcx> { desc: &str, old_loan_span: Span, old_load_end_span: Option, - ) -> Diag<'cx> { + ) -> Diag<'infcx> { let mut err = struct_span_code_err!( self.dcx(), new_loan_span, @@ -134,7 +134,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'_, '_, 'cx, 'tcx> { noun_old: &str, old_opt_via: &str, previous_end_span: Option, - ) -> Diag<'cx> { + ) -> Diag<'infcx> { let mut err = struct_span_code_err!( self.dcx(), new_loan_span, @@ -166,7 +166,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'_, '_, 'cx, 'tcx> { old_opt_via: &str, previous_end_span: Option, second_borrow_desc: &str, - ) -> Diag<'cx> { + ) -> Diag<'infcx> { let mut err = struct_span_code_err!( self.dcx(), new_loan_span, @@ -198,7 +198,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'_, '_, 'cx, 'tcx> { kind_old: &str, msg_old: &str, old_load_end_span: Option, - ) -> Diag<'cx> { + ) -> Diag<'infcx> { let via = |msg: &str| if msg.is_empty() { "".to_string() } else { format!(" (via {msg})") }; let mut err = struct_span_code_err!( self.dcx(), @@ -239,7 +239,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'_, '_, 'cx, 'tcx> { span: Span, borrow_span: Span, desc: &str, - ) -> Diag<'cx> { + ) -> Diag<'infcx> { struct_span_code_err!( self.dcx(), span, @@ -256,12 +256,12 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'_, '_, 'cx, 'tcx> { span: Span, desc: &str, is_arg: bool, - ) -> Diag<'cx> { + ) -> Diag<'infcx> { let msg = if is_arg { "to immutable argument" } else { "twice to immutable variable" }; struct_span_code_err!(self.dcx(), span, E0384, "cannot assign {} {}", msg, desc) } - pub(crate) fn cannot_assign(&self, span: Span, desc: &str) -> Diag<'cx> { + pub(crate) fn cannot_assign(&self, span: Span, desc: &str) -> Diag<'infcx> { struct_span_code_err!(self.dcx(), span, E0594, "cannot assign to {}", desc) } @@ -269,7 +269,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'_, '_, 'cx, 'tcx> { &self, move_from_span: Span, move_from_desc: &str, - ) -> Diag<'cx> { + ) -> Diag<'infcx> { struct_span_code_err!( self.dcx(), move_from_span, @@ -287,7 +287,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'_, '_, 'cx, 'tcx> { move_from_span: Span, ty: Ty<'_>, is_index: Option, - ) -> Diag<'cx> { + ) -> Diag<'infcx> { let type_name = match (&ty.kind(), is_index) { (&ty::Array(_, _), Some(true)) | (&ty::Array(_, _), None) => "array", (&ty::Slice(_), _) => "slice", @@ -308,7 +308,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'_, '_, 'cx, 'tcx> { &self, move_from_span: Span, container_ty: Ty<'_>, - ) -> Diag<'cx> { + ) -> Diag<'infcx> { struct_span_code_err!( self.dcx(), move_from_span, @@ -325,7 +325,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'_, '_, 'cx, 'tcx> { verb: &str, optional_adverb_for_moved: &str, moved_path: Option, - ) -> Diag<'cx> { + ) -> Diag<'infcx> { let moved_path = moved_path.map(|mp| format!(": `{mp}`")).unwrap_or_default(); struct_span_code_err!( @@ -344,7 +344,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'_, '_, 'cx, 'tcx> { span: Span, path: &str, reason: &str, - ) -> Diag<'cx> { + ) -> Diag<'infcx> { struct_span_code_err!( self.dcx(), span, @@ -362,7 +362,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'_, '_, 'cx, 'tcx> { immutable_place: &str, immutable_section: &str, action: &str, - ) -> Diag<'cx> { + ) -> Diag<'infcx> { struct_span_code_err!( self.dcx(), mutate_span, @@ -380,7 +380,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'_, '_, 'cx, 'tcx> { &self, span: Span, yield_span: Span, - ) -> Diag<'cx> { + ) -> Diag<'infcx> { let coroutine_kind = self.body.coroutine.as_ref().unwrap().coroutine_kind; struct_span_code_err!( self.dcx(), @@ -391,7 +391,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'_, '_, 'cx, 'tcx> { .with_span_label(yield_span, "possible yield occurs here") } - pub(crate) fn cannot_borrow_across_destructor(&self, borrow_span: Span) -> Diag<'cx> { + pub(crate) fn cannot_borrow_across_destructor(&self, borrow_span: Span) -> Diag<'infcx> { struct_span_code_err!( self.dcx(), borrow_span, @@ -400,7 +400,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'_, '_, 'cx, 'tcx> { ) } - pub(crate) fn path_does_not_live_long_enough(&self, span: Span, path: &str) -> Diag<'cx> { + pub(crate) fn path_does_not_live_long_enough(&self, span: Span, path: &str) -> Diag<'infcx> { struct_span_code_err!(self.dcx(), span, E0597, "{} does not live long enough", path,) } @@ -410,7 +410,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'_, '_, 'cx, 'tcx> { return_kind: &str, reference_desc: &str, path_desc: &str, - ) -> Diag<'cx> { + ) -> Diag<'infcx> { struct_span_code_err!( self.dcx(), span, @@ -433,7 +433,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'_, '_, 'cx, 'tcx> { borrowed_path: &str, capture_span: Span, scope: &str, - ) -> Diag<'cx> { + ) -> Diag<'infcx> { struct_span_code_err!( self.dcx(), closure_span, @@ -445,7 +445,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'_, '_, 'cx, 'tcx> { .with_span_label(closure_span, format!("may outlive borrowed value {borrowed_path}")) } - pub(crate) fn thread_local_value_does_not_live_long_enough(&self, span: Span) -> Diag<'cx> { + pub(crate) fn thread_local_value_does_not_live_long_enough(&self, span: Span) -> Diag<'infcx> { struct_span_code_err!( self.dcx(), span, @@ -454,7 +454,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'_, '_, 'cx, 'tcx> { ) } - pub(crate) fn temporary_value_borrowed_for_too_long(&self, span: Span) -> Diag<'cx> { + pub(crate) fn temporary_value_borrowed_for_too_long(&self, span: Span) -> Diag<'infcx> { struct_span_code_err!(self.dcx(), span, E0716, "temporary value dropped while borrowed",) } } diff --git a/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs index c4275e1393509..8bf3e670ff228 100644 --- a/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs @@ -149,13 +149,13 @@ trait TypeOpInfo<'tcx> { fn base_universe(&self) -> ty::UniverseIndex; - fn nice_error<'cx>( + fn nice_error<'infcx>( &self, - mbcx: &mut MirBorrowckCtxt<'_, '_, 'cx, 'tcx>, + mbcx: &mut MirBorrowckCtxt<'_, '_, 'infcx, 'tcx>, cause: ObligationCause<'tcx>, placeholder_region: ty::Region<'tcx>, error_region: Option>, - ) -> Option>; + ) -> Option>; #[instrument(level = "debug", skip(self, mbcx))] fn report_error( @@ -231,13 +231,13 @@ impl<'tcx> TypeOpInfo<'tcx> for PredicateQuery<'tcx> { self.base_universe } - fn nice_error<'cx>( + fn nice_error<'infcx>( &self, - mbcx: &mut MirBorrowckCtxt<'_, '_, 'cx, 'tcx>, + mbcx: &mut MirBorrowckCtxt<'_, '_, 'infcx, 'tcx>, cause: ObligationCause<'tcx>, placeholder_region: ty::Region<'tcx>, error_region: Option>, - ) -> Option> { + ) -> Option> { let (infcx, key, _) = mbcx.infcx.tcx.infer_ctxt().build_with_canonical(cause.span, &self.canonical_query); let ocx = ObligationCtxt::new(&infcx); @@ -275,13 +275,13 @@ where self.base_universe } - fn nice_error<'cx>( + fn nice_error<'infcx>( &self, - mbcx: &mut MirBorrowckCtxt<'_, '_, 'cx, 'tcx>, + mbcx: &mut MirBorrowckCtxt<'_, '_, 'infcx, 'tcx>, cause: ObligationCause<'tcx>, placeholder_region: ty::Region<'tcx>, error_region: Option>, - ) -> Option> { + ) -> Option> { let (infcx, key, _) = mbcx.infcx.tcx.infer_ctxt().build_with_canonical(cause.span, &self.canonical_query); let ocx = ObligationCtxt::new(&infcx); @@ -322,13 +322,13 @@ impl<'tcx> TypeOpInfo<'tcx> for AscribeUserTypeQuery<'tcx> { self.base_universe } - fn nice_error<'cx>( + fn nice_error<'infcx>( &self, - mbcx: &mut MirBorrowckCtxt<'_, '_, 'cx, 'tcx>, + mbcx: &mut MirBorrowckCtxt<'_, '_, 'infcx, 'tcx>, cause: ObligationCause<'tcx>, placeholder_region: ty::Region<'tcx>, error_region: Option>, - ) -> Option> { + ) -> Option> { let (infcx, key, _) = mbcx.infcx.tcx.infer_ctxt().build_with_canonical(cause.span, &self.canonical_query); let ocx = ObligationCtxt::new(&infcx); @@ -355,13 +355,13 @@ impl<'tcx> TypeOpInfo<'tcx> for crate::type_check::InstantiateOpaqueType<'tcx> { self.base_universe.unwrap() } - fn nice_error<'cx>( + fn nice_error<'infcx>( &self, - mbcx: &mut MirBorrowckCtxt<'_, '_, 'cx, 'tcx>, + mbcx: &mut MirBorrowckCtxt<'_, '_, 'infcx, 'tcx>, _cause: ObligationCause<'tcx>, placeholder_region: ty::Region<'tcx>, error_region: Option>, - ) -> Option> { + ) -> Option> { try_extract_error_from_region_constraints( mbcx.infcx, mbcx.mir_def_id(), diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index 74ebfc54182b6..d72c5962929fc 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -73,7 +73,7 @@ enum StorageDeadOrDrop<'tcx> { Destructor(Ty<'tcx>), } -impl<'cx, 'tcx> MirBorrowckCtxt<'_, '_, 'cx, 'tcx> { +impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> { pub(crate) fn report_use_of_moved_or_uninitialized( &mut self, location: Location, @@ -341,7 +341,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'_, '_, 'cx, 'tcx> { fn suggest_ref_or_clone( &self, mpi: MovePathIndex, - err: &mut Diag<'cx>, + err: &mut Diag<'infcx>, in_pattern: &mut bool, move_spans: UseSpans<'tcx>, ) { @@ -517,7 +517,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'_, '_, 'cx, 'tcx> { desired_action: InitializationRequiringAction, span: Span, use_spans: UseSpans<'tcx>, - ) -> Diag<'cx> { + ) -> Diag<'infcx> { // We need all statements in the body where the binding was assigned to later find all // the branching code paths where the binding *wasn't* assigned to. let inits = &self.move_data.init_path_map[mpi]; @@ -1441,7 +1441,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'_, '_, 'cx, 'tcx> { location: Location, (place, _span): (Place<'tcx>, Span), borrow: &BorrowData<'tcx>, - ) -> Diag<'cx> { + ) -> Diag<'infcx> { let borrow_spans = self.retrieve_borrow_spans(borrow); let borrow_span = borrow_spans.args_or_use(); @@ -1491,7 +1491,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'_, '_, 'cx, 'tcx> { (place, span): (Place<'tcx>, Span), gen_borrow_kind: BorrowKind, issued_borrow: &BorrowData<'tcx>, - ) -> Diag<'cx> { + ) -> Diag<'infcx> { let issued_spans = self.retrieve_borrow_spans(issued_borrow); let issued_span = issued_spans.args_or_use(); @@ -1782,7 +1782,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'_, '_, 'cx, 'tcx> { err } - fn suggest_copy_for_type_in_cloned_ref(&self, err: &mut Diag<'cx>, place: Place<'tcx>) { + fn suggest_copy_for_type_in_cloned_ref(&self, err: &mut Diag<'infcx>, place: Place<'tcx>) { let tcx = self.infcx.tcx; let hir = tcx.hir(); let Some(body_id) = tcx.hir_node(self.mir_hir_id()).body_id() else { return }; @@ -2841,7 +2841,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'_, '_, 'cx, 'tcx> { drop_span: Span, borrow_spans: UseSpans<'tcx>, explanation: BorrowExplanation<'tcx>, - ) -> Diag<'cx> { + ) -> Diag<'infcx> { debug!( "report_local_value_does_not_live_long_enough(\ {:?}, {:?}, {:?}, {:?}, {:?}\ @@ -3016,7 +3016,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'_, '_, 'cx, 'tcx> { &self, drop_span: Span, borrow_span: Span, - ) -> Diag<'cx> { + ) -> Diag<'infcx> { debug!( "report_thread_local_value_does_not_live_long_enough(\ {:?}, {:?}\ @@ -3041,7 +3041,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'_, '_, 'cx, 'tcx> { borrow_spans: UseSpans<'tcx>, proper_span: Span, explanation: BorrowExplanation<'tcx>, - ) -> Diag<'cx> { + ) -> Diag<'infcx> { if let BorrowExplanation::MustBeValidFor { category, span, from_closure: false, .. } = explanation { @@ -3206,7 +3206,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'_, '_, 'cx, 'tcx> { return_span: Span, category: ConstraintCategory<'tcx>, opt_place_desc: Option<&String>, - ) -> Result<(), Diag<'cx>> { + ) -> Result<(), Diag<'infcx>> { let return_kind = match category { ConstraintCategory::Return(_) => "return", ConstraintCategory::Yield => "yield", @@ -3299,7 +3299,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'_, '_, 'cx, 'tcx> { constraint_span: Span, captured_var: &str, scope: &str, - ) -> Diag<'cx> { + ) -> Diag<'infcx> { let tcx = self.infcx.tcx; let args_span = use_span.args_or_use(); @@ -3411,7 +3411,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'_, '_, 'cx, 'tcx> { upvar_span: Span, upvar_name: Symbol, escape_span: Span, - ) -> Diag<'cx> { + ) -> Diag<'infcx> { let tcx = self.infcx.tcx; let escapes_from = tcx.def_descr(self.mir_def_id().to_def_id()); diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs index 3bc7083976e44..4567a014fe83d 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mod.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs @@ -69,7 +69,7 @@ pub(super) struct DescribePlaceOpt { pub(super) struct IncludingTupleField(pub(super) bool); -impl<'cx, 'tcx> MirBorrowckCtxt<'_, '_, 'cx, 'tcx> { +impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> { /// Adds a suggestion when a closure is invoked twice with a moved variable or when a closure /// is moved after being invoked. /// @@ -86,7 +86,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'_, '_, 'cx, 'tcx> { &self, location: Location, place: PlaceRef<'tcx>, - diag: &mut Diag<'cx>, + diag: &mut Diag<'infcx>, ) -> bool { debug!("add_moved_or_invoked_closure_note: location={:?} place={:?}", location, place); let mut target = place.local_or_deref_local(); diff --git a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs index 40a6a65649a35..b82ffe63266e4 100644 --- a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs @@ -93,7 +93,7 @@ enum GroupedMoveError<'tcx> { }, } -impl<'cx, 'tcx> MirBorrowckCtxt<'_, '_, 'cx, 'tcx> { +impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> { pub(crate) fn report_move_errors(&mut self) { let grouped_errors = self.group_move_errors(); for error in grouped_errors { @@ -291,7 +291,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'_, '_, 'cx, 'tcx> { self.buffer_error(err); } - fn report_cannot_move_from_static(&mut self, place: Place<'tcx>, span: Span) -> Diag<'cx> { + fn report_cannot_move_from_static(&mut self, place: Place<'tcx>, span: Span) -> Diag<'infcx> { let description = if place.projection.len() == 1 { format!("static item {}", self.describe_any_place(place.as_ref())) } else { @@ -428,7 +428,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'_, '_, 'cx, 'tcx> { deref_target_place: Place<'tcx>, span: Span, use_spans: Option>, - ) -> Diag<'cx> { + ) -> Diag<'infcx> { let tcx = self.infcx.tcx; // Inspect the type of the content behind the // borrow to provide feedback about why this diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs index 6d92f0cdd988a..19a4df0cd7b43 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs @@ -30,7 +30,7 @@ pub(crate) enum AccessKind { Mutate, } -impl<'cx, 'tcx> MirBorrowckCtxt<'_, '_, 'cx, 'tcx> { +impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> { pub(crate) fn report_mutability_error( &mut self, access_place: Place<'tcx>, @@ -541,7 +541,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'_, '_, 'cx, 'tcx> { } /// Suggest `map[k] = v` => `map.insert(k, v)` and the like. - fn suggest_map_index_mut_alternatives(&self, ty: Ty<'tcx>, err: &mut Diag<'cx>, span: Span) { + fn suggest_map_index_mut_alternatives(&self, ty: Ty<'tcx>, err: &mut Diag<'infcx>, span: Span) { let Some(adt) = ty.ty_adt_def() else { return }; let did = adt.did(); if self.infcx.tcx.is_diagnostic_item(sym::HashMap, did) @@ -550,9 +550,9 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'_, '_, 'cx, 'tcx> { /// Walks through the HIR, looking for the corresponding span for this error. /// When it finds it, see if it corresponds to assignment operator whose LHS /// is an index expr. - struct SuggestIndexOperatorAlternativeVisitor<'a, 'cx, 'tcx> { + struct SuggestIndexOperatorAlternativeVisitor<'a, 'infcx, 'tcx> { assign_span: Span, - err: &'a mut Diag<'cx>, + err: &'a mut Diag<'infcx>, ty: Ty<'tcx>, suggested: bool, } diff --git a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs index dd22f8d8440ee..fba18c381466b 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs @@ -160,7 +160,7 @@ pub struct ErrorConstraintInfo<'tcx> { pub(super) span: Span, } -impl<'cx, 'tcx> MirBorrowckCtxt<'_, '_, 'cx, 'tcx> { +impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> { /// Converts a region inference variable into a `ty::Region` that /// we can use for error reporting. If `r` is universally bound, /// then we use the name that we have on record for it. If `r` is @@ -589,7 +589,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'_, '_, 'cx, 'tcx> { &self, errci: &ErrorConstraintInfo<'tcx>, kind: ReturnConstraint, - ) -> Diag<'cx> { + ) -> Diag<'infcx> { let ErrorConstraintInfo { outlived_fr, span, .. } = errci; let mut output_ty = self.regioncx.universal_regions().unnormalized_output_ty; @@ -658,7 +658,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'_, '_, 'cx, 'tcx> { /// | ^^^^^^^^^^ `x` escapes the function body here /// ``` #[instrument(level = "debug", skip(self))] - fn report_escaping_data_error(&self, errci: &ErrorConstraintInfo<'tcx>) -> Diag<'cx> { + fn report_escaping_data_error(&self, errci: &ErrorConstraintInfo<'tcx>) -> Diag<'infcx> { let ErrorConstraintInfo { span, category, .. } = errci; let fr_name_and_span = self.regioncx.get_var_name_and_span_for_region( @@ -767,7 +767,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'_, '_, 'cx, 'tcx> { /// | is returning data with lifetime `'b` /// ``` #[allow(rustc::diagnostic_outside_of_impl)] // FIXME - fn report_general_error(&self, errci: &ErrorConstraintInfo<'tcx>) -> Diag<'cx> { + fn report_general_error(&self, errci: &ErrorConstraintInfo<'tcx>) -> Diag<'infcx> { let ErrorConstraintInfo { fr, fr_is_local, diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index 8aea8ae188898..e6f8ffd428d06 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -310,8 +310,8 @@ fn do_mir_borrowck<'tcx>( promoted_mbcx.report_move_errors(); diags = promoted_mbcx.diags; - struct MoveVisitor<'a, 'b, 'mir, 'cx, 'tcx> { - ctxt: &'a mut MirBorrowckCtxt<'b, 'mir, 'cx, 'tcx>, + struct MoveVisitor<'a, 'b, 'mir, 'infcx, 'tcx> { + ctxt: &'a mut MirBorrowckCtxt<'b, 'mir, 'infcx, 'tcx>, } impl<'tcx> Visitor<'tcx> for MoveVisitor<'_, '_, '_, '_, 'tcx> { @@ -528,8 +528,8 @@ impl<'tcx> Deref for BorrowckInferCtxt<'tcx> { } } -struct MirBorrowckCtxt<'a, 'mir, 'cx, 'tcx> { - infcx: &'cx BorrowckInferCtxt<'tcx>, +struct MirBorrowckCtxt<'a, 'mir, 'infcx, 'tcx> { + infcx: &'infcx BorrowckInferCtxt<'tcx>, param_env: ParamEnv<'tcx>, body: &'mir Body<'tcx>, move_data: &'a MoveData<'tcx>, @@ -596,7 +596,7 @@ struct MirBorrowckCtxt<'a, 'mir, 'cx, 'tcx> { /// Results of Polonius analysis. polonius_output: Option>, - diags: diags::BorrowckDiags<'cx, 'tcx>, + diags: diags::BorrowckDiags<'infcx, 'tcx>, move_errors: Vec>, } @@ -2428,12 +2428,12 @@ mod diags { use super::*; - enum BufferedDiag<'cx> { - Error(Diag<'cx>), - NonError(Diag<'cx, ()>), + enum BufferedDiag<'infcx> { + Error(Diag<'infcx>), + NonError(Diag<'infcx, ()>), } - impl<'cx> BufferedDiag<'cx> { + impl<'infcx> BufferedDiag<'infcx> { fn sort_span(&self) -> Span { match self { BufferedDiag::Error(diag) => diag.sort_span, @@ -2442,7 +2442,7 @@ mod diags { } } - pub struct BorrowckDiags<'cx, 'tcx> { + pub struct BorrowckDiags<'infcx, 'tcx> { /// This field keeps track of move errors that are to be reported for given move indices. /// /// There are situations where many errors can be reported for a single move out (see @@ -2457,15 +2457,15 @@ mod diags { /// `BTreeMap` is used to preserve the order of insertions when iterating. This is necessary /// when errors in the map are being re-added to the error buffer so that errors with the /// same primary span come out in a consistent order. - buffered_move_errors: BTreeMap, (PlaceRef<'tcx>, Diag<'cx>)>, + buffered_move_errors: BTreeMap, (PlaceRef<'tcx>, Diag<'infcx>)>, - buffered_mut_errors: FxIndexMap, usize)>, + buffered_mut_errors: FxIndexMap, usize)>, /// Buffer of diagnostics to be reported. A mixture of error and non-error diagnostics. - buffered_diags: Vec>, + buffered_diags: Vec>, } - impl<'cx, 'tcx> BorrowckDiags<'cx, 'tcx> { + impl<'infcx, 'tcx> BorrowckDiags<'infcx, 'tcx> { pub fn new() -> Self { BorrowckDiags { buffered_move_errors: BTreeMap::new(), @@ -2474,28 +2474,28 @@ mod diags { } } - pub fn buffer_error(&mut self, diag: Diag<'cx>) { + pub fn buffer_error(&mut self, diag: Diag<'infcx>) { self.buffered_diags.push(BufferedDiag::Error(diag)); } - pub fn buffer_non_error(&mut self, diag: Diag<'cx, ()>) { + pub fn buffer_non_error(&mut self, diag: Diag<'infcx, ()>) { self.buffered_diags.push(BufferedDiag::NonError(diag)); } } - impl<'cx, 'tcx> MirBorrowckCtxt<'_, '_, 'cx, 'tcx> { - pub fn buffer_error(&mut self, diag: Diag<'cx>) { + impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> { + pub fn buffer_error(&mut self, diag: Diag<'infcx>) { self.diags.buffer_error(diag); } - pub fn buffer_non_error(&mut self, diag: Diag<'cx, ()>) { + pub fn buffer_non_error(&mut self, diag: Diag<'infcx, ()>) { self.diags.buffer_non_error(diag); } pub fn buffer_move_error( &mut self, move_out_indices: Vec, - place_and_err: (PlaceRef<'tcx>, Diag<'cx>), + place_and_err: (PlaceRef<'tcx>, Diag<'infcx>), ) -> bool { if let Some((_, diag)) = self.diags.buffered_move_errors.insert(move_out_indices, place_and_err) @@ -2508,12 +2508,12 @@ mod diags { } } - pub fn get_buffered_mut_error(&mut self, span: Span) -> Option<(Diag<'cx>, usize)> { + pub fn get_buffered_mut_error(&mut self, span: Span) -> Option<(Diag<'infcx>, usize)> { // FIXME(#120456) - is `swap_remove` correct? self.diags.buffered_mut_errors.swap_remove(&span) } - pub fn buffer_mut_error(&mut self, span: Span, diag: Diag<'cx>, count: usize) { + pub fn buffer_mut_error(&mut self, span: Span, diag: Diag<'infcx>, count: usize) { self.diags.buffered_mut_errors.insert(span, (diag, count)); } @@ -2554,7 +2554,7 @@ mod diags { pub fn has_move_error( &self, move_out_indices: &[MoveOutIndex], - ) -> Option<&(PlaceRef<'tcx>, Diag<'cx>)> { + ) -> Option<&(PlaceRef<'tcx>, Diag<'infcx>)> { self.diags.buffered_move_errors.get(move_out_indices) } } diff --git a/compiler/rustc_borrowck/src/used_muts.rs b/compiler/rustc_borrowck/src/used_muts.rs index 25e1f6268e062..e2de6b8b4a929 100644 --- a/compiler/rustc_borrowck/src/used_muts.rs +++ b/compiler/rustc_borrowck/src/used_muts.rs @@ -45,10 +45,10 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> { /// MIR visitor for collecting used mutable variables. /// The 'visit lifetime represents the duration of the MIR walk. -struct GatherUsedMutsVisitor<'visit, 'a, 'mir, 'cx, 'tcx> { +struct GatherUsedMutsVisitor<'visit, 'a, 'mir, 'infcx, 'tcx> { temporary_used_locals: FxIndexSet, never_initialized_mut_locals: &'visit mut FxIndexSet, - mbcx: &'visit mut MirBorrowckCtxt<'a, 'mir, 'cx, 'tcx>, + mbcx: &'visit mut MirBorrowckCtxt<'a, 'mir, 'infcx, 'tcx>, } impl GatherUsedMutsVisitor<'_, '_, '_, '_, '_> { diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs index f055a77696180..f72e8a4afdef6 100644 --- a/compiler/rustc_hir_typeck/src/coercion.rs +++ b/compiler/rustc_hir_typeck/src/coercion.rs @@ -1797,16 +1797,16 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { err.subdiagnostic(SuggestBoxingForReturnImplTrait::BoxReturnExpr { starts, ends }); } - fn report_return_mismatched_types<'cx>( + fn report_return_mismatched_types<'infcx>( &self, cause: &ObligationCause<'tcx>, expected: Ty<'tcx>, found: Ty<'tcx>, ty_err: TypeError<'tcx>, - fcx: &'cx FnCtxt<'_, 'tcx>, + fcx: &'infcx FnCtxt<'_, 'tcx>, block_or_return_id: hir::HirId, expression: Option<&'tcx hir::Expr<'tcx>>, - ) -> Diag<'cx> { + ) -> Diag<'infcx> { let mut err = fcx.err_ctxt().report_mismatched_types(cause, expected, found, ty_err); let due_to_block = matches!(fcx.tcx.hir_node(block_or_return_id), hir::Node::Block(..)); From 5df6f720579d3dfc1060ff41e9218e8bc2593535 Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Thu, 27 Jun 2024 11:24:05 +0200 Subject: [PATCH 342/892] Add test --- .../simple_match.match_enum.built.after.mir | 62 +++++++++++++++++++ tests/mir-opt/building/match/simple_match.rs | 14 +++++ 2 files changed, 76 insertions(+) create mode 100644 tests/mir-opt/building/match/simple_match.match_enum.built.after.mir diff --git a/tests/mir-opt/building/match/simple_match.match_enum.built.after.mir b/tests/mir-opt/building/match/simple_match.match_enum.built.after.mir new file mode 100644 index 0000000000000..b233aa8b8e595 --- /dev/null +++ b/tests/mir-opt/building/match/simple_match.match_enum.built.after.mir @@ -0,0 +1,62 @@ +// MIR for `match_enum` after built + +fn match_enum(_1: E1) -> bool { + debug x => _1; + let mut _0: bool; + let mut _2: isize; + let mut _3: isize; + + bb0: { + PlaceMention(_1); + _2 = discriminant(_1); + switchInt(move _2) -> [0: bb3, 1: bb5, otherwise: bb2]; + } + + bb1: { + FakeRead(ForMatchedPlace(None), _1); + unreachable; + } + + bb2: { + _3 = discriminant(_1); + switchInt(move _3) -> [2: bb8, otherwise: bb1]; + } + + bb3: { + goto -> bb7; + } + + bb4: { + goto -> bb2; + } + + bb5: { + goto -> bb7; + } + + bb6: { + goto -> bb2; + } + + bb7: { + falseEdge -> [real: bb10, imaginary: bb2]; + } + + bb8: { + _0 = const false; + goto -> bb11; + } + + bb9: { + goto -> bb1; + } + + bb10: { + _0 = const true; + goto -> bb11; + } + + bb11: { + return; + } +} diff --git a/tests/mir-opt/building/match/simple_match.rs b/tests/mir-opt/building/match/simple_match.rs index 61c337822c859..c8b3d90748afb 100644 --- a/tests/mir-opt/building/match/simple_match.rs +++ b/tests/mir-opt/building/match/simple_match.rs @@ -9,4 +9,18 @@ fn match_bool(x: bool) -> usize { } } +pub enum E1 { + V1, + V2, + V3, +} + +// EMIT_MIR simple_match.match_enum.built.after.mir +pub fn match_enum(x: E1) -> bool { + match x { + E1::V1 | E1::V2 => true, + E1::V3 => false, + } +} + fn main() {} From 834f043a0878dda17118129e4ac8930d4d00fc6f Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Thu, 27 Jun 2024 11:26:22 +0200 Subject: [PATCH 343/892] Fix expansion of or-patterns --- .../rustc_mir_build/src/build/matches/mod.rs | 3 +++ .../simple_match.match_enum.built.after.mir | 18 ++++++++---------- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs index 932406fd1aaf2..5ba3e42d7b3dd 100644 --- a/compiler/rustc_mir_build/src/build/matches/mod.rs +++ b/compiler/rustc_mir_build/src/build/matches/mod.rs @@ -1411,6 +1411,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { break; } } + if expand_until != 0 { + expand_until = i + 1; + } } let (candidates_to_expand, remaining_candidates) = candidates.split_at_mut(expand_until); diff --git a/tests/mir-opt/building/match/simple_match.match_enum.built.after.mir b/tests/mir-opt/building/match/simple_match.match_enum.built.after.mir index b233aa8b8e595..905aa19da706a 100644 --- a/tests/mir-opt/building/match/simple_match.match_enum.built.after.mir +++ b/tests/mir-opt/building/match/simple_match.match_enum.built.after.mir @@ -4,12 +4,11 @@ fn match_enum(_1: E1) -> bool { debug x => _1; let mut _0: bool; let mut _2: isize; - let mut _3: isize; bb0: { PlaceMention(_1); _2 = discriminant(_1); - switchInt(move _2) -> [0: bb3, 1: bb5, otherwise: bb2]; + switchInt(move _2) -> [0: bb3, 1: bb5, 2: bb7, otherwise: bb2]; } bb1: { @@ -18,12 +17,11 @@ fn match_enum(_1: E1) -> bool { } bb2: { - _3 = discriminant(_1); - switchInt(move _3) -> [2: bb8, otherwise: bb1]; + goto -> bb1; } bb3: { - goto -> bb7; + goto -> bb9; } bb4: { @@ -31,7 +29,7 @@ fn match_enum(_1: E1) -> bool { } bb5: { - goto -> bb7; + goto -> bb9; } bb6: { @@ -39,16 +37,16 @@ fn match_enum(_1: E1) -> bool { } bb7: { - falseEdge -> [real: bb10, imaginary: bb2]; + _0 = const false; + goto -> bb11; } bb8: { - _0 = const false; - goto -> bb11; + goto -> bb2; } bb9: { - goto -> bb1; + falseEdge -> [real: bb10, imaginary: bb7]; } bb10: { From f026e0bfc16633d225dbc49e5b4da048bd419831 Mon Sep 17 00:00:00 2001 From: Urgau Date: Thu, 27 Jun 2024 11:04:16 +0200 Subject: [PATCH 344/892] Cleanup bootstrap check-cfg --- library/alloc/Cargo.toml | 2 -- library/core/Cargo.toml | 2 -- library/std/Cargo.toml | 2 -- src/bootstrap/src/lib.rs | 37 ++++--------------------------------- 4 files changed, 4 insertions(+), 39 deletions(-) diff --git a/library/alloc/Cargo.toml b/library/alloc/Cargo.toml index 024b92790e970..612452a960a37 100644 --- a/library/alloc/Cargo.toml +++ b/library/alloc/Cargo.toml @@ -47,8 +47,6 @@ optimize_for_size = ["core/optimize_for_size"] [lints.rust.unexpected_cfgs] level = "warn" -# x.py uses beta cargo, so `check-cfg` entries do not yet take effect -# for rust-lang/rust. But for users of `-Zbuild-std` it does. check-cfg = [ 'cfg(bootstrap)', 'cfg(no_global_oom_handling)', diff --git a/library/core/Cargo.toml b/library/core/Cargo.toml index cf9fddd269aa4..cace4582b489a 100644 --- a/library/core/Cargo.toml +++ b/library/core/Cargo.toml @@ -39,8 +39,6 @@ debug_refcell = [] [lints.rust.unexpected_cfgs] level = "warn" -# x.py uses beta cargo, so `check-cfg` entries do not yet take effect -# for rust-lang/rust. But for users of `-Zbuild-std` it does. check-cfg = [ 'cfg(bootstrap)', 'cfg(no_fp_fmt_parse)', diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml index 32479cd2836fa..358510b8f77d8 100644 --- a/library/std/Cargo.toml +++ b/library/std/Cargo.toml @@ -100,8 +100,6 @@ test = true [lints.rust.unexpected_cfgs] level = "warn" -# x.py uses beta cargo, so `check-cfg` entries do not yet take effect -# for rust-lang/rust. But for users of `-Zbuild-std` it does. check-cfg = [ 'cfg(bootstrap)', 'cfg(target_arch, values("xtensa"))', diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs index dfc30298c28d2..fac72e27f6293 100644 --- a/src/bootstrap/src/lib.rs +++ b/src/bootstrap/src/lib.rs @@ -74,7 +74,7 @@ const LLVM_TOOLS: &[&str] = &[ /// LLD file names for all flavors. const LLD_FILE_NAMES: &[&str] = &["ld.lld", "ld64.lld", "lld-link", "wasm-ld"]; -/// Extra --check-cfg to add when building +/// Extra `--check-cfg` to add when building the compiler or tools /// (Mode restriction, config name, config values (if any)) #[allow(clippy::type_complexity)] // It's fine for hard-coded list and type is explained above. const EXTRA_CHECK_CFGS: &[(Option, &str, Option<&[&'static str]>)] = &[ @@ -84,38 +84,9 @@ const EXTRA_CHECK_CFGS: &[(Option, &str, Option<&[&'static str]>)] = &[ (Some(Mode::ToolRustc), "rust_analyzer", None), (Some(Mode::ToolStd), "rust_analyzer", None), (Some(Mode::Codegen), "parallel_compiler", None), - // NOTE: consider updating `check-cfg` entries in `std/Cargo.toml` too. - // cfg(bootstrap) remove these once the bootstrap compiler supports - // `lints.rust.unexpected_cfgs.check-cfg` - (Some(Mode::Std), "stdarch_intel_sde", None), - (Some(Mode::Std), "no_fp_fmt_parse", None), - (Some(Mode::Std), "no_global_oom_handling", None), - (Some(Mode::Std), "no_rc", None), - (Some(Mode::Std), "no_sync", None), - /* Extra values not defined in the built-in targets yet, but used in std */ - (Some(Mode::Std), "target_env", Some(&["libnx", "p2"])), - (Some(Mode::Std), "target_os", Some(&["visionos"])), - (Some(Mode::Std), "target_arch", Some(&["arm64ec", "spirv", "nvptx", "xtensa"])), - (Some(Mode::ToolStd), "target_os", Some(&["visionos"])), - /* Extra names used by dependencies */ - // FIXME: Used by serde_json, but we should not be triggering on external dependencies. - (Some(Mode::Rustc), "no_btreemap_remove_entry", None), - (Some(Mode::ToolRustc), "no_btreemap_remove_entry", None), - // FIXME: Used by crossbeam-utils, but we should not be triggering on external dependencies. - (Some(Mode::Rustc), "crossbeam_loom", None), - (Some(Mode::ToolRustc), "crossbeam_loom", None), - // FIXME: Used by proc-macro2, but we should not be triggering on external dependencies. - (Some(Mode::Rustc), "span_locations", None), - (Some(Mode::ToolRustc), "span_locations", None), - // FIXME: Used by rustix, but we should not be triggering on external dependencies. - (Some(Mode::Rustc), "rustix_use_libc", None), - (Some(Mode::ToolRustc), "rustix_use_libc", None), - // FIXME: Used by filetime, but we should not be triggering on external dependencies. - (Some(Mode::Rustc), "emulate_second_only_system", None), - (Some(Mode::ToolRustc), "emulate_second_only_system", None), - // Needed to avoid the need to copy windows.lib into the sysroot. - (Some(Mode::Rustc), "windows_raw_dylib", None), - (Some(Mode::ToolRustc), "windows_raw_dylib", None), + // Any library specific cfgs like `target_os`, `target_arch` should be put in + // priority the `[lints.rust.unexpected_cfgs.check-cfg]` table + // in the appropriate `library/{std,alloc,core}/Cargo.toml` ]; /// A structure representing a Rust compiler. From 648cb1692050ecbcb5dfbb21623debbf5244ff15 Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Thu, 13 Jun 2024 08:11:16 -0500 Subject: [PATCH 345/892] Enable const casting for `f16` and `f128` --- .../rustc_const_eval/src/interpret/cast.rs | 27 ++++++++++++------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_const_eval/src/interpret/cast.rs b/compiler/rustc_const_eval/src/interpret/cast.rs index a13630ce084d5..83b61ab17492c 100644 --- a/compiler/rustc_const_eval/src/interpret/cast.rs +++ b/compiler/rustc_const_eval/src/interpret/cast.rs @@ -1,6 +1,6 @@ use std::assert_matches::assert_matches; -use rustc_apfloat::ieee::{Double, Single}; +use rustc_apfloat::ieee::{Double, Half, Quad, Single}; use rustc_apfloat::{Float, FloatConvert}; use rustc_middle::mir::interpret::{InterpResult, PointerArithmetic, Scalar}; use rustc_middle::mir::CastKind; @@ -187,10 +187,10 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { bug!("FloatToFloat/FloatToInt cast: source type {} is not a float type", src.layout.ty) }; let val = match fty { - FloatTy::F16 => unimplemented!("f16_f128"), + FloatTy::F16 => self.cast_from_float(src.to_scalar().to_f16()?, cast_to.ty), FloatTy::F32 => self.cast_from_float(src.to_scalar().to_f32()?, cast_to.ty), FloatTy::F64 => self.cast_from_float(src.to_scalar().to_f64()?, cast_to.ty), - FloatTy::F128 => unimplemented!("f16_f128"), + FloatTy::F128 => self.cast_from_float(src.to_scalar().to_f128()?, cast_to.ty), }; Ok(ImmTy::from_scalar(val, cast_to)) } @@ -296,18 +296,18 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { Float(fty) if signed => { let v = v as i128; match fty { - FloatTy::F16 => unimplemented!("f16_f128"), + FloatTy::F16 => Scalar::from_f16(Half::from_i128(v).value), FloatTy::F32 => Scalar::from_f32(Single::from_i128(v).value), FloatTy::F64 => Scalar::from_f64(Double::from_i128(v).value), - FloatTy::F128 => unimplemented!("f16_f128"), + FloatTy::F128 => Scalar::from_f128(Quad::from_i128(v).value), } } // unsigned int -> float Float(fty) => match fty { - FloatTy::F16 => unimplemented!("f16_f128"), + FloatTy::F16 => Scalar::from_f16(Half::from_u128(v).value), FloatTy::F32 => Scalar::from_f32(Single::from_u128(v).value), FloatTy::F64 => Scalar::from_f64(Double::from_u128(v).value), - FloatTy::F128 => unimplemented!("f16_f128"), + FloatTy::F128 => Scalar::from_f128(Quad::from_u128(v).value), }, // u8 -> char @@ -321,7 +321,12 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { /// Low-level cast helper function. Converts an apfloat `f` into int or float types. fn cast_from_float(&self, f: F, dest_ty: Ty<'tcx>) -> Scalar where - F: Float + Into> + FloatConvert + FloatConvert, + F: Float + + Into> + + FloatConvert + + FloatConvert + + FloatConvert + + FloatConvert, { use rustc_type_ir::TyKind::*; @@ -358,10 +363,12 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { } // float -> float Float(fty) => match fty { - FloatTy::F16 => unimplemented!("f16_f128"), + FloatTy::F16 => Scalar::from_f16(adjust_nan(self, f, f.convert(&mut false).value)), FloatTy::F32 => Scalar::from_f32(adjust_nan(self, f, f.convert(&mut false).value)), FloatTy::F64 => Scalar::from_f64(adjust_nan(self, f, f.convert(&mut false).value)), - FloatTy::F128 => unimplemented!("f16_f128"), + FloatTy::F128 => { + Scalar::from_f128(adjust_nan(self, f, f.convert(&mut false).value)) + } }, // That's it. _ => span_bug!(self.cur_span(), "invalid float to {} cast", dest_ty), From 4a11ab0b343239c38d7760c973f5be65dddeadc2 Mon Sep 17 00:00:00 2001 From: WANG Xuerui Date: Thu, 27 Jun 2024 16:45:56 +0800 Subject: [PATCH 346/892] Fix Markdown tables in platform-support.md These table entries have wrong number of columns so the "notes" field is missing from the rendered page. Fix by removing excess empty columns. --- src/doc/rustc/src/platform-support.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index 71dc8c4ca0f92..f5cd4bd217a32 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -168,12 +168,12 @@ target | std | notes `i686-unknown-freebsd` | ✓ | 32-bit FreeBSD [^x86_32-floats-return-ABI] `i686-unknown-linux-musl` | ✓ | 32-bit Linux with musl 1.2.3 [^x86_32-floats-return-ABI] [`i686-unknown-uefi`](platform-support/unknown-uefi.md) | ? | 32-bit UEFI -[`loongarch64-unknown-none`](platform-support/loongarch-none.md) | * | | LoongArch64 Bare-metal (LP64D ABI) -[`loongarch64-unknown-none-softfloat`](platform-support/loongarch-none.md) | * | | LoongArch64 Bare-metal (LP64S ABI) +[`loongarch64-unknown-none`](platform-support/loongarch-none.md) | * | LoongArch64 Bare-metal (LP64D ABI) +[`loongarch64-unknown-none-softfloat`](platform-support/loongarch-none.md) | * | LoongArch64 Bare-metal (LP64S ABI) [`nvptx64-nvidia-cuda`](platform-support/nvptx64-nvidia-cuda.md) | * | --emit=asm generates PTX code that [runs on NVIDIA GPUs] [`riscv32imac-unknown-none-elf`](platform-support/riscv32-unknown-none-elf.md) | * | Bare RISC-V (RV32IMAC ISA) [`riscv32i-unknown-none-elf`](platform-support/riscv32-unknown-none-elf.md) | * | Bare RISC-V (RV32I ISA) -[`riscv32im-unknown-none-elf`](platform-support/riscv32-unknown-none-elf.md) | * | | Bare RISC-V (RV32IM ISA) +[`riscv32im-unknown-none-elf`](platform-support/riscv32-unknown-none-elf.md) | * | Bare RISC-V (RV32IM ISA) [`riscv32imc-unknown-none-elf`](platform-support/riscv32-unknown-none-elf.md) | * | Bare RISC-V (RV32IMC ISA) [`riscv32imafc-unknown-none-elf`](platform-support/riscv32-unknown-none-elf.md) | * | Bare RISC-V (RV32IMAFC ISA) `riscv64gc-unknown-none-elf` | * | Bare RISC-V (RV64IMAFDC ISA) @@ -193,7 +193,7 @@ target | std | notes `wasm32-unknown-unknown` | ✓ | WebAssembly `wasm32-wasi` | ✓ | WebAssembly with WASI (undergoing a [rename to `wasm32-wasip1`][wasi-rename]) [`wasm32-wasip1`](platform-support/wasm32-wasip1.md) | ✓ | WebAssembly with WASI -[`wasm32-wasip1-threads`](platform-support/wasm32-wasip1-threads.md) | ✓ | | WebAssembly with WASI Preview 1 and threads +[`wasm32-wasip1-threads`](platform-support/wasm32-wasip1-threads.md) | ✓ | WebAssembly with WASI Preview 1 and threads [`x86_64-apple-ios`](platform-support/apple-ios.md) | ✓ | 64-bit x86 iOS [`x86_64-fortanix-unknown-sgx`](platform-support/x86_64-fortanix-unknown-sgx.md) | ✓ | [Fortanix ABI] for 64-bit Intel SGX `x86_64-fuchsia` | ✓ | Alias for `x86_64-unknown-fuchsia` From bd111f5c4bbf3726ef0c9daf78c16c453bf5cb3d Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Thu, 27 Jun 2024 09:45:26 +0000 Subject: [PATCH 347/892] Document new field and function --- compiler/rustc_errors/src/lib.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index 242684e63a082..2086d4030f905 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -418,6 +418,8 @@ pub struct DiagCtxt { #[derive(Copy, Clone)] pub struct DiagCtxtHandle<'a> { dcx: &'a DiagCtxt, + /// Some contexts create `DiagCtxtHandle` with this field set, and thus all + /// errors emitted with it will automatically taint when emitting errors. tainted_with_errors: Option<&'a Cell>>, } @@ -757,6 +759,9 @@ impl DiagCtxt { DiagCtxtHandle { dcx: self, tainted_with_errors: None } } + /// Link this to a taintable context so that emitting errors will automatically set + /// the `Option` instead of having to do that manually at every error + /// emission site. pub fn taintable_handle<'a>( &'a self, tainted_with_errors: &'a Cell>, From 7e7d0a959d9a0450ac3596e842dc49e8e6618bc6 Mon Sep 17 00:00:00 2001 From: joboet Date: Thu, 27 Jun 2024 12:16:46 +0200 Subject: [PATCH 348/892] core: improve comment Co-authored-by: Ralf Jung --- library/core/src/fmt/rt.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/core/src/fmt/rt.rs b/library/core/src/fmt/rt.rs index 5836ce59ec1dc..65a4d537cc74d 100644 --- a/library/core/src/fmt/rt.rs +++ b/library/core/src/fmt/rt.rs @@ -68,8 +68,8 @@ pub(super) enum Flag { #[derive(Copy, Clone)] enum ArgumentType<'a> { Placeholder { - // INVARIANT: if `formatter` had type `fn(&T, _) -> _` then `value` - // was derived from a `&T` with lifetime `'a`. + // INVARIANT: `formatter` has type `fn(&T, _) -> _` for some `T`, and `value` + // was derived from a `&'a T`. value: NonNull<()>, formatter: unsafe fn(NonNull<()>, &mut Formatter<'_>) -> Result, _lifetime: PhantomData<&'a ()>, From 3457ecc776e87550bc1b1bd4bb686bde8bd5c504 Mon Sep 17 00:00:00 2001 From: onur-ozkan Date: Thu, 27 Jun 2024 13:06:10 +0300 Subject: [PATCH 349/892] remove unnecessary packages from `metadata::workspace_members` Currently bootstrap doesn't use any inner paths from rust-analyzer and bootstrap with `ShouldRun::create_or_deps`. Signed-off-by: onur-ozkan --- src/bootstrap/src/core/metadata.rs | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/bootstrap/src/core/metadata.rs b/src/bootstrap/src/core/metadata.rs index 12867cb46b811..220eb5ba126e4 100644 --- a/src/bootstrap/src/core/metadata.rs +++ b/src/bootstrap/src/core/metadata.rs @@ -66,7 +66,10 @@ pub fn build(build: &mut Build) { } /// Invokes `cargo metadata` to get package metadata of each workspace member. -fn workspace_members(build: &Build) -> impl Iterator { +/// +/// This is used to resolve specific crate paths in `fn should_run` to compile +/// particular crate (e.g., `x build sysroot` to build library/sysroot). +fn workspace_members(build: &Build) -> Vec { let collect_metadata = |manifest_path| { let mut cargo = Command::new(&build.initial_cargo); cargo @@ -85,9 +88,5 @@ fn workspace_members(build: &Build) -> impl Iterator { }; // Collects `metadata.packages` from all workspaces. - let packages = collect_metadata("Cargo.toml"); - let ra_packages = collect_metadata("src/tools/rust-analyzer/Cargo.toml"); - let bootstrap_packages = collect_metadata("src/bootstrap/Cargo.toml"); - - packages.into_iter().chain(ra_packages).chain(bootstrap_packages) + collect_metadata("Cargo.toml") } From cf9bcb26a6582dcc9cceebb455acf330feda28f6 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Thu, 27 Jun 2024 11:09:20 +0000 Subject: [PATCH 350/892] Remove duplicate of tests/ui/impl-trait/nested-return-type2.rs --- tests/ui/type/subtyping-opaque-type.rs | 19 ------------------- 1 file changed, 19 deletions(-) delete mode 100644 tests/ui/type/subtyping-opaque-type.rs diff --git a/tests/ui/type/subtyping-opaque-type.rs b/tests/ui/type/subtyping-opaque-type.rs deleted file mode 100644 index e17114a364768..0000000000000 --- a/tests/ui/type/subtyping-opaque-type.rs +++ /dev/null @@ -1,19 +0,0 @@ -//@ check-pass -//@ compile-flags: -Zvalidate-mir -trait Duh {} - -impl Duh for i32 {} - -trait Trait { - type Assoc: Duh; -} - -impl R> Trait for F { - type Assoc = R; -} - -fn foo() -> impl Trait { - || 42 -} - -fn main() {} From 10a513bacc994ebffcd088b798caa52c55064332 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Thu, 27 Jun 2024 11:10:55 +0000 Subject: [PATCH 351/892] Remove duplicate of tests/ui/impl-trait/nested-return-type2-tait2.rs --- ...it-in-function-return-type-issue-101903.rs | 29 ------------------- ...n-function-return-type-issue-101903.stderr | 13 --------- 2 files changed, 42 deletions(-) delete mode 100644 tests/ui/type-alias-impl-trait/tait-in-function-return-type-issue-101903.rs delete mode 100644 tests/ui/type-alias-impl-trait/tait-in-function-return-type-issue-101903.stderr diff --git a/tests/ui/type-alias-impl-trait/tait-in-function-return-type-issue-101903.rs b/tests/ui/type-alias-impl-trait/tait-in-function-return-type-issue-101903.rs deleted file mode 100644 index 4f9d54737dc4c..0000000000000 --- a/tests/ui/type-alias-impl-trait/tait-in-function-return-type-issue-101903.rs +++ /dev/null @@ -1,29 +0,0 @@ -//@ check-pass - -// See https://doc.rust-lang.org/1.77.0/nightly-rustc/rustc_lint/opaque_hidden_inferred_bound/static.OPAQUE_HIDDEN_INFERRED_BOUND.html#example - -#![feature(type_alias_impl_trait)] -#![allow(dead_code)] - -trait Duh {} - -impl Duh for i32 {} - -trait Trait { - type Assoc: Duh; -} - -impl R> Trait for F { - type Assoc = R; -} - -type Sendable = impl Send; - -type Foo = impl Trait; - //~^ WARNING opaque type `Foo` does not satisfy its associated type bounds - -fn foo() -> Foo { - || 42 -} - -fn main() {} diff --git a/tests/ui/type-alias-impl-trait/tait-in-function-return-type-issue-101903.stderr b/tests/ui/type-alias-impl-trait/tait-in-function-return-type-issue-101903.stderr deleted file mode 100644 index 68def454c7fbd..0000000000000 --- a/tests/ui/type-alias-impl-trait/tait-in-function-return-type-issue-101903.stderr +++ /dev/null @@ -1,13 +0,0 @@ -warning: opaque type `Foo` does not satisfy its associated type bounds - --> $DIR/tait-in-function-return-type-issue-101903.rs:22:23 - | -LL | type Assoc: Duh; - | --- this associated type bound is unsatisfied for `Sendable` -... -LL | type Foo = impl Trait; - | ^^^^^^^^^^^^^^^^ - | - = note: `#[warn(opaque_hidden_inferred_bound)]` on by default - -warning: 1 warning emitted - From b94eae58772373c59d4a45ba02ce836aec59d1b0 Mon Sep 17 00:00:00 2001 From: Oneirical Date: Wed, 26 Jun 2024 14:02:05 -0400 Subject: [PATCH 352/892] rewrite many-crates-but-no-match to rmake --- .../tidy/src/allowed_run_make_makefiles.txt | 1 - .../many-crates-but-no-match/Makefile | 35 ------------------- .../many-crates-but-no-match/rmake.rs | 31 ++++++++++++++++ 3 files changed, 31 insertions(+), 36 deletions(-) delete mode 100644 tests/run-make/many-crates-but-no-match/Makefile create mode 100644 tests/run-make/many-crates-but-no-match/rmake.rs diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index 9d44b61d5e168..bdf9536f761d0 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -100,7 +100,6 @@ run-make/lto-smoke-c/Makefile run-make/macos-deployment-target/Makefile run-make/macos-fat-archive/Makefile run-make/manual-link/Makefile -run-make/many-crates-but-no-match/Makefile run-make/metadata-dep-info/Makefile run-make/min-global-align/Makefile run-make/mingw-export-call-convention/Makefile diff --git a/tests/run-make/many-crates-but-no-match/Makefile b/tests/run-make/many-crates-but-no-match/Makefile deleted file mode 100644 index ca0ab8e9e5f41..0000000000000 --- a/tests/run-make/many-crates-but-no-match/Makefile +++ /dev/null @@ -1,35 +0,0 @@ -include ../tools.mk - -# Modelled after ui/changing-crates.rs test, but this one puts -# more than one (mismatching) candidate crate into the search path, -# which did not appear directly expressible in UI testing infrastructure. -# -# Note that we move the built libraries into target direcrtories rather than -# use the `--out-dir` option because the `../tools.mk` file already bakes a -# use of `--out-dir` into the definition of $(RUSTC). - -A1=$(TMPDIR)/a1 -A2=$(TMPDIR)/a2 -A3=$(TMPDIR)/a3 - -# A hack to match distinct lines of output from a single run. -LOG=$(TMPDIR)/log.txt - -all: - mkdir -p $(A1) $(A2) $(A3) - $(RUSTC) --crate-type=rlib crateA1.rs - mv $(TMPDIR)/$(call RLIB_GLOB,crateA) $(A1) - $(RUSTC) --crate-type=rlib -L $(A1) crateB.rs - $(RUSTC) --crate-type=rlib crateA2.rs - mv $(TMPDIR)/$(call RLIB_GLOB,crateA) $(A2) - $(RUSTC) --crate-type=rlib crateA3.rs - mv $(TMPDIR)/$(call RLIB_GLOB,crateA) $(A3) - # Ensure crateC fails to compile since A1 is "missing" and A2/A3 hashes do not match - $(RUSTC) -L $(A2) -L $(A3) crateC.rs >$(LOG) 2>&1 || true - $(CGREP) \ - 'found possibly newer version of crate `crateA` which `crateB` depends on' \ - 'note: perhaps that crate needs to be recompiled?' \ - 'crate `crateA`:' \ - 'crate `crateB`:' \ - < $(LOG) - # the 'crate `crateA`' will match two entries. diff --git a/tests/run-make/many-crates-but-no-match/rmake.rs b/tests/run-make/many-crates-but-no-match/rmake.rs new file mode 100644 index 0000000000000..ea4f166b2bd99 --- /dev/null +++ b/tests/run-make/many-crates-but-no-match/rmake.rs @@ -0,0 +1,31 @@ +// An extended version of the ui/changing-crates.rs test, this test puts +// multiple mismatching crates into the search path of crateC (A2 and A3) +// and checks that the standard error contains helpful messages to indicate +// what should be done to fix the issue. +// See https://github.com/rust-lang/rust/issues/13266 + +use run_make_support::{fs_wrapper, rustc}; + +fn main() { + fs_wrapper::create_dir("a1"); + fs_wrapper::create_dir("a2"); + fs_wrapper::create_dir("a3"); + rustc().crate_type("rlib").out_dir("a1").input("crateA1.rs").run(); + rustc().crate_type("rlib").library_search_path("a1").input("crateB.rs").run(); + rustc().crate_type("rlib").out_dir("a2").input("crateA2.rs").run(); + rustc().crate_type("rlib").out_dir("a3").input("crateA3.rs").run(); + // Ensure crateC fails to compile since A1 is "missing" and A2/A3 hashes do not match + rustc() + .crate_type("rlib") + .library_search_path("a2") + .library_search_path("a3") + .input("crateC.rs") + .run_fail() + .assert_stderr_contains( + "found possibly newer version of crate `crateA` which `crateB` depends on", + ) + .assert_stderr_contains("note: perhaps that crate needs to be recompiled?") + .assert_stderr_contains("crate `crateA`:") + .assert_stderr_contains("crate `crateB`:"); + // the 'crate `crateA`' will match two entries. +} From 81c2c575192d8d6cc79e67187cd17cc2ed831b12 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 27 Jun 2024 12:01:49 -0400 Subject: [PATCH 353/892] Make queries more explicit --- compiler/rustc_hir_analysis/src/collect.rs | 14 ++++---- .../src/collect/predicates_of.rs | 12 +++---- .../src/collect/resolve_bound_vars.rs | 2 +- compiler/rustc_infer/src/traits/util.rs | 8 ++--- .../src/multiple_supertrait_upcastable.rs | 2 +- .../src/rmeta/decoder/cstore_impl.rs | 4 +-- compiler/rustc_metadata/src/rmeta/encoder.rs | 8 ++--- compiler/rustc_metadata/src/rmeta/mod.rs | 6 ++-- compiler/rustc_middle/src/query/mod.rs | 32 +++++++++++-------- compiler/rustc_middle/src/traits/util.rs | 2 +- compiler/rustc_middle/src/ty/context.rs | 9 ++++-- compiler/rustc_middle/src/ty/vtable.rs | 2 +- .../src/solve/assembly/structural_traits.rs | 5 +-- .../src/traits/object_safety.rs | 4 +-- .../src/traits/select/confirmation.rs | 2 +- .../rustc_trait_selection/src/traits/util.rs | 2 +- .../src/traits/vtable.rs | 2 +- compiler/rustc_type_ir/src/interner.rs | 3 +- src/librustdoc/clean/simplify.rs | 2 +- .../src/implied_bounds_in_impls.rs | 2 +- .../src/methods/type_id_on_box.rs | 2 +- .../clippy_lints/src/needless_maybe_sized.rs | 2 +- 22 files changed, 68 insertions(+), 59 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index e7892f1766067..18aff6a4d5a16 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -70,10 +70,10 @@ pub fn provide(providers: &mut Providers) { predicates_of: predicates_of::predicates_of, predicates_defined_on, explicit_predicates_of: predicates_of::explicit_predicates_of, - super_predicates_of: predicates_of::super_predicates_of, - implied_predicates_of: predicates_of::implied_predicates_of, - super_predicates_that_define_assoc_item: - predicates_of::super_predicates_that_define_assoc_item, + explicit_super_predicates_of: predicates_of::explicit_super_predicates_of, + explicit_implied_predicates_of: predicates_of::explicit_implied_predicates_of, + explicit_supertraits_containing_assoc_item: + predicates_of::explicit_supertraits_containing_assoc_item, trait_explicit_predicates_and_bounds: predicates_of::trait_explicit_predicates_and_bounds, type_param_predicates: predicates_of::type_param_predicates, trait_def, @@ -691,14 +691,14 @@ fn lower_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) { hir::ItemKind::Trait(..) => { tcx.ensure().generics_of(def_id); tcx.ensure().trait_def(def_id); - tcx.at(it.span).super_predicates_of(def_id); + tcx.at(it.span).explicit_super_predicates_of(def_id); tcx.ensure().predicates_of(def_id); tcx.ensure().associated_items(def_id); } hir::ItemKind::TraitAlias(..) => { tcx.ensure().generics_of(def_id); - tcx.at(it.span).implied_predicates_of(def_id); - tcx.at(it.span).super_predicates_of(def_id); + tcx.at(it.span).explicit_implied_predicates_of(def_id); + tcx.at(it.span).explicit_super_predicates_of(def_id); tcx.ensure().predicates_of(def_id); } hir::ItemKind::Struct(struct_def, _) | hir::ItemKind::Union(struct_def, _) => { diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs index 3421c8da4e9f3..8ba524e72eb3d 100644 --- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs @@ -519,21 +519,21 @@ pub(super) fn explicit_predicates_of<'tcx>( /// Ensures that the super-predicates of the trait with a `DefId` /// of `trait_def_id` are lowered and stored. This also ensures that /// the transitive super-predicates are lowered. -pub(super) fn super_predicates_of( +pub(super) fn explicit_super_predicates_of( tcx: TyCtxt<'_>, trait_def_id: LocalDefId, ) -> ty::GenericPredicates<'_> { implied_predicates_with_filter(tcx, trait_def_id.to_def_id(), PredicateFilter::SelfOnly) } -pub(super) fn super_predicates_that_define_assoc_item( +pub(super) fn explicit_supertraits_containing_assoc_item( tcx: TyCtxt<'_>, (trait_def_id, assoc_name): (DefId, Ident), ) -> ty::GenericPredicates<'_> { implied_predicates_with_filter(tcx, trait_def_id, PredicateFilter::SelfThatDefines(assoc_name)) } -pub(super) fn implied_predicates_of( +pub(super) fn explicit_implied_predicates_of( tcx: TyCtxt<'_>, trait_def_id: LocalDefId, ) -> ty::GenericPredicates<'_> { @@ -560,7 +560,7 @@ pub(super) fn implied_predicates_with_filter( // if `assoc_name` is None, then the query should've been redirected to an // external provider assert!(matches!(filter, PredicateFilter::SelfThatDefines(_))); - return tcx.super_predicates_of(trait_def_id); + return tcx.explicit_super_predicates_of(trait_def_id); }; let Node::Item(item) = tcx.hir_node_by_def_id(trait_def_id) else { @@ -601,7 +601,7 @@ pub(super) fn implied_predicates_with_filter( if let ty::ClauseKind::Trait(bound) = pred.kind().skip_binder() && bound.polarity == ty::PredicatePolarity::Positive { - tcx.at(span).super_predicates_of(bound.def_id()); + tcx.at(span).explicit_super_predicates_of(bound.def_id()); } } } @@ -611,7 +611,7 @@ pub(super) fn implied_predicates_with_filter( if let ty::ClauseKind::Trait(bound) = pred.kind().skip_binder() && bound.polarity == ty::PredicatePolarity::Positive { - tcx.at(span).implied_predicates_of(bound.def_id()); + tcx.at(span).explicit_implied_predicates_of(bound.def_id()); } } } 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 abc3bb838db3e..f953e32416298 100644 --- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs +++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs @@ -1760,7 +1760,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { if let Some(assoc_item) = trait_defines_associated_item_named(def_id) { break Some((bound_vars.into_iter().collect(), assoc_item)); } - let predicates = tcx.super_predicates_that_define_assoc_item((def_id, assoc_name)); + let predicates = tcx.explicit_supertraits_containing_assoc_item((def_id, assoc_name)); let obligations = predicates.predicates.iter().filter_map(|&(pred, _)| { let bound_predicate = pred.kind(); match bound_predicate.skip_binder() { diff --git a/compiler/rustc_infer/src/traits/util.rs b/compiler/rustc_infer/src/traits/util.rs index ab4148faaab63..24cf9f03fcdb3 100644 --- a/compiler/rustc_infer/src/traits/util.rs +++ b/compiler/rustc_infer/src/traits/util.rs @@ -275,10 +275,10 @@ impl<'tcx, O: Elaboratable<'tcx>> Elaborator<'tcx, O> { } // Get predicates implied by the trait, or only super predicates if we only care about self predicates. let predicates = match self.mode { - Filter::All => tcx.implied_predicates_of(data.def_id()), - Filter::OnlySelf => tcx.super_predicates_of(data.def_id()), + Filter::All => tcx.explicit_implied_predicates_of(data.def_id()), + Filter::OnlySelf => tcx.explicit_super_predicates_of(data.def_id()), Filter::OnlySelfThatDefines(ident) => { - tcx.super_predicates_that_define_assoc_item((data.def_id(), ident)) + tcx.explicit_supertraits_containing_assoc_item((data.def_id(), ident)) } }; @@ -420,7 +420,7 @@ pub fn transitive_bounds<'tcx>( /// A specialized variant of `elaborate` that only elaborates trait references that may /// define the given associated item with the name `assoc_name`. It uses the -/// `super_predicates_that_define_assoc_item` query to avoid enumerating super-predicates that +/// `explicit_supertraits_containing_assoc_item` query to avoid enumerating super-predicates that /// aren't related to `assoc_item`. This is used when resolving types like `Self::Item` or /// `T::Item` and helps to avoid cycle errors (see e.g. #35237). pub fn transitive_bounds_that_define_assoc_item<'tcx>( diff --git a/compiler/rustc_lint/src/multiple_supertrait_upcastable.rs b/compiler/rustc_lint/src/multiple_supertrait_upcastable.rs index aa1d94228ea22..445dcd41e5d52 100644 --- a/compiler/rustc_lint/src/multiple_supertrait_upcastable.rs +++ b/compiler/rustc_lint/src/multiple_supertrait_upcastable.rs @@ -45,7 +45,7 @@ impl<'tcx> LateLintPass<'tcx> for MultipleSupertraitUpcastable { { let direct_super_traits_iter = cx .tcx - .super_predicates_of(def_id) + .explicit_super_predicates_of(def_id) .predicates .into_iter() .filter_map(|(pred, _)| pred.as_trait_clause()); diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs index c9450142cd3be..743ceb1ee6cdf 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs @@ -211,8 +211,8 @@ provide! { tcx, def_id, other, cdata, explicit_predicates_of => { table } generics_of => { table } inferred_outlives_of => { table_defaulted_array } - super_predicates_of => { table } - implied_predicates_of => { table } + explicit_super_predicates_of => { table } + explicit_implied_predicates_of => { table } type_of => { table } type_alias_is_lazy => { cdata.root.tables.type_alias_is_lazy.get(cdata, def_id.index) } variances_of => { table } diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 4bd2ec09a6e6f..957e578a08e9d 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -1431,8 +1431,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { } if let DefKind::Trait = def_kind { record!(self.tables.trait_def[def_id] <- self.tcx.trait_def(def_id)); - record!(self.tables.super_predicates_of[def_id] <- self.tcx.super_predicates_of(def_id)); - record!(self.tables.implied_predicates_of[def_id] <- self.tcx.implied_predicates_of(def_id)); + record!(self.tables.explicit_super_predicates_of[def_id] <- self.tcx.explicit_super_predicates_of(def_id)); + record!(self.tables.explicit_implied_predicates_of[def_id] <- self.tcx.explicit_implied_predicates_of(def_id)); let module_children = self.tcx.module_children_local(local_id); record_array!(self.tables.module_children_non_reexports[def_id] <- @@ -1440,8 +1440,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { } if let DefKind::TraitAlias = def_kind { record!(self.tables.trait_def[def_id] <- self.tcx.trait_def(def_id)); - record!(self.tables.super_predicates_of[def_id] <- self.tcx.super_predicates_of(def_id)); - record!(self.tables.implied_predicates_of[def_id] <- self.tcx.implied_predicates_of(def_id)); + record!(self.tables.explicit_super_predicates_of[def_id] <- self.tcx.explicit_super_predicates_of(def_id)); + record!(self.tables.explicit_implied_predicates_of[def_id] <- self.tcx.explicit_implied_predicates_of(def_id)); } if let DefKind::Trait | DefKind::Impl { .. } = def_kind { let associated_item_def_ids = self.tcx.associated_item_def_ids(def_id); diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs index 87900c23d8daf..5f729fa8e3466 100644 --- a/compiler/rustc_metadata/src/rmeta/mod.rs +++ b/compiler/rustc_metadata/src/rmeta/mod.rs @@ -416,10 +416,10 @@ define_tables! { lookup_deprecation_entry: Table>, explicit_predicates_of: Table>>, generics_of: Table>, - super_predicates_of: Table>>, + explicit_super_predicates_of: Table>>, // As an optimization, we only store this for trait aliases, - // since it's identical to super_predicates_of for traits. - implied_predicates_of: Table>>, + // since it's identical to explicit_super_predicates_of for traits. + explicit_implied_predicates_of: Table>>, type_of: Table>>>, variances_of: Table>, fn_sig: Table>>>, diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 230a44bcf2452..86a415772de8a 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -646,6 +646,9 @@ rustc_queries! { } /// Returns the predicates written explicitly by the user. + /// + /// You should probably use `predicates_of` unless you're looking for + /// predicates with explicit spans for diagnostics purposes. query explicit_predicates_of(key: DefId) -> ty::GenericPredicates<'tcx> { desc { |tcx| "computing explicit predicates of `{}`", tcx.def_path_str(key) } cache_on_disk_if { key.is_local() } @@ -662,29 +665,32 @@ rustc_queries! { feedable } - /// Maps from the `DefId` of a trait to the list of - /// super-predicates. This is a subset of the full list of - /// predicates. We store these in a separate map because we must - /// evaluate them even during type conversion, often before the - /// full predicates are available (note that supertraits have - /// additional acyclicity requirements). - query super_predicates_of(key: DefId) -> ty::GenericPredicates<'tcx> { + /// Maps from the `DefId` of a trait to the list of super-predicates of the trait, + /// *before* elaboration (so it doesn't contain transitive super-predicates). This + /// is a subset of the full list of predicates. We store these in a separate map + /// because we must evaluate them even during type conversion, often before the full + /// predicates are available (note that super-predicates must not be cyclic). + query explicit_super_predicates_of(key: DefId) -> ty::GenericPredicates<'tcx> { desc { |tcx| "computing the super predicates of `{}`", tcx.def_path_str(key) } cache_on_disk_if { key.is_local() } separate_provide_extern } - query implied_predicates_of(key: DefId) -> ty::GenericPredicates<'tcx> { + /// The predicates of the trait that are implied during elaboration. This is a + /// superset of the super-predicates of the trait, but a subset of the predicates + /// of the trait. For regular traits, this includes all super-predicates and their + /// associated type bounds. For trait aliases, currently, this includes all of the + /// predicates of the trait alias. + query explicit_implied_predicates_of(key: DefId) -> ty::GenericPredicates<'tcx> { desc { |tcx| "computing the implied predicates of `{}`", tcx.def_path_str(key) } cache_on_disk_if { key.is_local() } separate_provide_extern } - /// The `Option` is the name of an associated type. If it is `None`, then this query - /// returns the full set of predicates. If `Some`, then the query returns only the - /// subset of super-predicates that reference traits that define the given associated type. - /// This is used to avoid cycles in resolving types like `T::Item`. - query super_predicates_that_define_assoc_item(key: (DefId, rustc_span::symbol::Ident)) -> ty::GenericPredicates<'tcx> { + /// The Ident is the name of an associated type.The query returns only the subset + /// of supertraits that define the given associated type. This is used to avoid + /// cycles in resolving type-dependent associated item paths like `T::Item`. + query explicit_supertraits_containing_assoc_item(key: (DefId, rustc_span::symbol::Ident)) -> ty::GenericPredicates<'tcx> { desc { |tcx| "computing the super traits of `{}` with associated type name `{}`", tcx.def_path_str(key.0), key.1 diff --git a/compiler/rustc_middle/src/traits/util.rs b/compiler/rustc_middle/src/traits/util.rs index adbb6cf2ddc94..7437be7a74c14 100644 --- a/compiler/rustc_middle/src/traits/util.rs +++ b/compiler/rustc_middle/src/traits/util.rs @@ -35,7 +35,7 @@ struct Elaborator<'tcx> { impl<'tcx> Elaborator<'tcx> { fn elaborate(&mut self, trait_ref: PolyTraitRef<'tcx>) { let super_predicates = - self.tcx.super_predicates_of(trait_ref.def_id()).predicates.iter().filter_map( + self.tcx.explicit_super_predicates_of(trait_ref.def_id()).predicates.iter().filter_map( |&(pred, _)| { let clause = pred.instantiate_supertrait(self.tcx, trait_ref); self.visited.insert(clause).then_some(clause) diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 4bac9396e59a9..4391e2516759b 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -342,12 +342,15 @@ impl<'tcx> Interner for TyCtxt<'tcx> { ) } - fn super_predicates_of( + fn explicit_super_predicates_of( self, def_id: DefId, ) -> ty::EarlyBinder<'tcx, impl IntoIterator>> { ty::EarlyBinder::bind( - self.super_predicates_of(def_id).instantiate_identity(self).predicates.into_iter(), + self.explicit_super_predicates_of(def_id) + .instantiate_identity(self) + .predicates + .into_iter(), ) } @@ -2473,7 +2476,7 @@ impl<'tcx> TyCtxt<'tcx> { iter::from_fn(move || -> Option { let trait_did = stack.pop()?; - let generic_predicates = self.super_predicates_of(trait_did); + let generic_predicates = self.explicit_super_predicates_of(trait_did); for (predicate, _) in generic_predicates.predicates { if let ty::ClauseKind::Trait(data) = predicate.kind().skip_binder() { diff --git a/compiler/rustc_middle/src/ty/vtable.rs b/compiler/rustc_middle/src/ty/vtable.rs index dc3c84f9e439a..38da279ec58a3 100644 --- a/compiler/rustc_middle/src/ty/vtable.rs +++ b/compiler/rustc_middle/src/ty/vtable.rs @@ -67,7 +67,7 @@ impl Iterator for SupertraitDefIds<'_> { fn next(&mut self) -> Option { let def_id = self.stack.pop()?; - let predicates = self.tcx.super_predicates_of(def_id); + let predicates = self.tcx.explicit_super_predicates_of(def_id); let visited = &mut self.visited; self.stack.extend( predicates diff --git a/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs b/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs index 0cef8d9f4bc34..3447b39fa5b40 100644 --- a/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs +++ b/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs @@ -668,8 +668,9 @@ where { let cx = ecx.cx(); let mut requirements = vec![]; - requirements - .extend(cx.super_predicates_of(trait_ref.def_id).iter_instantiated(cx, trait_ref.args)); + requirements.extend( + cx.explicit_super_predicates_of(trait_ref.def_id).iter_instantiated(cx, trait_ref.args), + ); // FIXME(associated_const_equality): Also add associated consts to // the requirements here. diff --git a/compiler/rustc_trait_selection/src/traits/object_safety.rs b/compiler/rustc_trait_selection/src/traits/object_safety.rs index 4d10d33fa6ef5..f1611bd049de9 100644 --- a/compiler/rustc_trait_selection/src/traits/object_safety.rs +++ b/compiler/rustc_trait_selection/src/traits/object_safety.rs @@ -187,7 +187,7 @@ fn predicates_reference_self( ) -> SmallVec<[Span; 1]> { let trait_ref = ty::Binder::dummy(ty::TraitRef::identity(tcx, trait_def_id)); let predicates = if supertraits_only { - tcx.super_predicates_of(trait_def_id) + tcx.explicit_super_predicates_of(trait_def_id) } else { tcx.predicates_of(trait_def_id) }; @@ -256,7 +256,7 @@ fn super_predicates_have_non_lifetime_binders( if !tcx.features().non_lifetime_binders { return SmallVec::new(); } - tcx.super_predicates_of(trait_def_id) + tcx.explicit_super_predicates_of(trait_def_id) .predicates .iter() .filter_map(|(pred, span)| pred.has_non_region_bound_vars().then_some(*span)) diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index 8c5dc88184cda..9508a3e8e1509 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -574,7 +574,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // Check supertraits hold. This is so that their associated type bounds // will be checked in the code below. for super_trait in tcx - .super_predicates_of(trait_predicate.def_id()) + .explicit_super_predicates_of(trait_predicate.def_id()) .instantiate(tcx, trait_predicate.trait_ref.args) .predicates .into_iter() diff --git a/compiler/rustc_trait_selection/src/traits/util.rs b/compiler/rustc_trait_selection/src/traits/util.rs index f132e36468ac2..951af4b0920cb 100644 --- a/compiler/rustc_trait_selection/src/traits/util.rs +++ b/compiler/rustc_trait_selection/src/traits/util.rs @@ -128,7 +128,7 @@ impl<'tcx> TraitAliasExpander<'tcx> { } // Get components of trait alias. - let predicates = tcx.super_predicates_of(trait_ref.def_id()); + let predicates = tcx.explicit_super_predicates_of(trait_ref.def_id()); debug!(?predicates); let items = predicates.predicates.iter().rev().filter_map(|(pred, span)| { diff --git a/compiler/rustc_trait_selection/src/traits/vtable.rs b/compiler/rustc_trait_selection/src/traits/vtable.rs index 017b0a45d1f41..e54ced85deeb7 100644 --- a/compiler/rustc_trait_selection/src/traits/vtable.rs +++ b/compiler/rustc_trait_selection/src/traits/vtable.rs @@ -117,7 +117,7 @@ fn prepare_vtable_segments_inner<'tcx, T>( let &(inner_most_trait_ref, _, _) = stack.last().unwrap(); let mut direct_super_traits_iter = tcx - .super_predicates_of(inner_most_trait_ref.def_id()) + .explicit_super_predicates_of(inner_most_trait_ref.def_id()) .predicates .into_iter() .filter_map(move |(pred, _)| { diff --git a/compiler/rustc_type_ir/src/interner.rs b/compiler/rustc_type_ir/src/interner.rs index b89ea30fc3435..6665158c7cd34 100644 --- a/compiler/rustc_type_ir/src/interner.rs +++ b/compiler/rustc_type_ir/src/interner.rs @@ -209,8 +209,7 @@ pub trait Interner: def_id: Self::DefId, ) -> ty::EarlyBinder>; - // FIXME: Rename this so it's obvious it's only *immediate* super predicates. - fn super_predicates_of( + fn explicit_super_predicates_of( self, def_id: Self::DefId, ) -> ty::EarlyBinder>; diff --git a/src/librustdoc/clean/simplify.rs b/src/librustdoc/clean/simplify.rs index af61eb6ae8de8..58eef36677b23 100644 --- a/src/librustdoc/clean/simplify.rs +++ b/src/librustdoc/clean/simplify.rs @@ -113,7 +113,7 @@ fn trait_is_same_or_supertrait(cx: &DocContext<'_>, child: DefId, trait_: DefId) if child == trait_ { return true; } - let predicates = cx.tcx.super_predicates_of(child); + let predicates = cx.tcx.explicit_super_predicates_of(child); debug_assert!(cx.tcx.generics_of(child).has_self); let self_ty = cx.tcx.types.self_param; predicates diff --git a/src/tools/clippy/clippy_lints/src/implied_bounds_in_impls.rs b/src/tools/clippy/clippy_lints/src/implied_bounds_in_impls.rs index 170ecf896b4e1..67b48878ca513 100644 --- a/src/tools/clippy/clippy_lints/src/implied_bounds_in_impls.rs +++ b/src/tools/clippy/clippy_lints/src/implied_bounds_in_impls.rs @@ -246,7 +246,7 @@ fn collect_supertrait_bounds<'tcx>(cx: &LateContext<'tcx>, bounds: GenericBounds && let [.., path] = poly_trait.trait_ref.path.segments && poly_trait.bound_generic_params.is_empty() && let Some(trait_def_id) = path.res.opt_def_id() - && let predicates = cx.tcx.super_predicates_of(trait_def_id).predicates + && let predicates = cx.tcx.explicit_super_predicates_of(trait_def_id).predicates // If the trait has no supertrait, there is no need to collect anything from that bound && !predicates.is_empty() { diff --git a/src/tools/clippy/clippy_lints/src/methods/type_id_on_box.rs b/src/tools/clippy/clippy_lints/src/methods/type_id_on_box.rs index 6f9b38fcf83cc..b62ecef0069af 100644 --- a/src/tools/clippy/clippy_lints/src/methods/type_id_on_box.rs +++ b/src/tools/clippy/clippy_lints/src/methods/type_id_on_box.rs @@ -24,7 +24,7 @@ fn is_subtrait_of_any(cx: &LateContext<'_>, ty: Ty<'_>) -> bool { cx.tcx.is_diagnostic_item(sym::Any, tr.def_id) || cx .tcx - .super_predicates_of(tr.def_id) + .explicit_super_predicates_of(tr.def_id) .predicates .iter() .any(|(clause, _)| { diff --git a/src/tools/clippy/clippy_lints/src/needless_maybe_sized.rs b/src/tools/clippy/clippy_lints/src/needless_maybe_sized.rs index 4922c87b206c0..a1d8ec3b32ec9 100644 --- a/src/tools/clippy/clippy_lints/src/needless_maybe_sized.rs +++ b/src/tools/clippy/clippy_lints/src/needless_maybe_sized.rs @@ -91,7 +91,7 @@ fn path_to_sized_bound(cx: &LateContext<'_>, trait_bound: &PolyTraitRef<'_>) -> return true; } - for &(predicate, _) in cx.tcx.super_predicates_of(trait_def_id).predicates { + for &(predicate, _) in cx.tcx.explicit_super_predicates_of(trait_def_id).predicates { if let ClauseKind::Trait(trait_predicate) = predicate.kind().skip_binder() && trait_predicate.polarity == PredicatePolarity::Positive && !path.contains(&trait_predicate.def_id()) From c9870cfa4bed1163be4e9fde814d79860f3caa57 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 27 Jun 2024 12:06:47 -0400 Subject: [PATCH 354/892] supertrait_def_ids --- compiler/rustc_middle/src/ty/context.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 4391e2516759b..d9fb10df103e1 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -2443,7 +2443,7 @@ impl<'tcx> TyCtxt<'tcx> { /// Given the def_id of a Trait `trait_def_id` and the name of an associated item `assoc_name` /// returns true if the `trait_def_id` defines an associated item of name `assoc_name`. pub fn trait_may_define_assoc_item(self, trait_def_id: DefId, assoc_name: Ident) -> bool { - self.super_traits_of(trait_def_id).any(|trait_did| { + self.supertrait_def_ids(trait_def_id).any(|trait_did| { self.associated_items(trait_did) .filter_by_name_unhygienic(assoc_name.name) .any(|item| self.hygienic_eq(assoc_name, item.ident(self), trait_did)) @@ -2467,8 +2467,7 @@ impl<'tcx> TyCtxt<'tcx> { /// Computes the def-ids of the transitive supertraits of `trait_def_id`. This (intentionally) /// does not compute the full elaborated super-predicates but just the set of def-ids. It is used /// to identify which traits may define a given associated type to help avoid cycle errors. - /// Returns a `DefId` iterator. - fn super_traits_of(self, trait_def_id: DefId) -> impl Iterator + 'tcx { + fn supertrait_def_ids(self, trait_def_id: DefId) -> impl Iterator + 'tcx { let mut set = FxHashSet::default(); let mut stack = vec![trait_def_id]; From 1160eecba5883ba2bf96bf2b774bca189b3829a1 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 27 Jun 2024 12:29:34 -0400 Subject: [PATCH 355/892] supertrait_def_ids was already implemented in middle --- compiler/rustc_middle/src/ty/context.rs | 5 ++-- compiler/rustc_middle/src/ty/vtable.rs | 35 ------------------------- 2 files changed, 3 insertions(+), 37 deletions(-) diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index d9fb10df103e1..ed1ec55bc8ed1 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -2466,8 +2466,9 @@ impl<'tcx> TyCtxt<'tcx> { /// Computes the def-ids of the transitive supertraits of `trait_def_id`. This (intentionally) /// does not compute the full elaborated super-predicates but just the set of def-ids. It is used - /// to identify which traits may define a given associated type to help avoid cycle errors. - fn supertrait_def_ids(self, trait_def_id: DefId) -> impl Iterator + 'tcx { + /// to identify which traits may define a given associated type to help avoid cycle errors, + /// and to make size estimates for vtable layout computation. + pub fn supertrait_def_ids(self, trait_def_id: DefId) -> impl Iterator + 'tcx { let mut set = FxHashSet::default(); let mut stack = vec![trait_def_id]; diff --git a/compiler/rustc_middle/src/ty/vtable.rs b/compiler/rustc_middle/src/ty/vtable.rs index 38da279ec58a3..466c3b93f8e5d 100644 --- a/compiler/rustc_middle/src/ty/vtable.rs +++ b/compiler/rustc_middle/src/ty/vtable.rs @@ -3,8 +3,6 @@ use std::fmt; use crate::mir::interpret::{alloc_range, AllocId, Allocation, Pointer, Scalar}; use crate::ty::{self, Instance, PolyTraitRef, Ty, TyCtxt}; use rustc_ast::Mutability; -use rustc_data_structures::fx::FxHashSet; -use rustc_hir::def_id::DefId; use rustc_macros::HashStable; #[derive(Clone, Copy, PartialEq, HashStable)] @@ -42,45 +40,12 @@ impl<'tcx> fmt::Debug for VtblEntry<'tcx> { impl<'tcx> TyCtxt<'tcx> { pub const COMMON_VTABLE_ENTRIES: &'tcx [VtblEntry<'tcx>] = &[VtblEntry::MetadataDropInPlace, VtblEntry::MetadataSize, VtblEntry::MetadataAlign]; - - pub fn supertrait_def_ids(self, trait_def_id: DefId) -> SupertraitDefIds<'tcx> { - SupertraitDefIds { - tcx: self, - stack: vec![trait_def_id], - visited: Some(trait_def_id).into_iter().collect(), - } - } } pub const COMMON_VTABLE_ENTRIES_DROPINPLACE: usize = 0; pub const COMMON_VTABLE_ENTRIES_SIZE: usize = 1; pub const COMMON_VTABLE_ENTRIES_ALIGN: usize = 2; -pub struct SupertraitDefIds<'tcx> { - tcx: TyCtxt<'tcx>, - stack: Vec, - visited: FxHashSet, -} - -impl Iterator for SupertraitDefIds<'_> { - type Item = DefId; - - fn next(&mut self) -> Option { - let def_id = self.stack.pop()?; - let predicates = self.tcx.explicit_super_predicates_of(def_id); - let visited = &mut self.visited; - self.stack.extend( - predicates - .predicates - .iter() - .filter_map(|(pred, _)| pred.as_trait_clause()) - .map(|trait_ref| trait_ref.def_id()) - .filter(|&super_def_id| visited.insert(super_def_id)), - ); - Some(def_id) - } -} - // Note that we don't have access to a self type here, this has to be purely based on the trait (and // supertrait) definitions. That means we can't call into the same vtable_entries code since that // returns a specific instantiation (e.g., with Vacant slots when bounds aren't satisfied). The goal From 585170ee60a302dbf072f3bfe76a3d01e93613a8 Mon Sep 17 00:00:00 2001 From: Philipp Krones Date: Thu, 27 Jun 2024 18:50:02 +0200 Subject: [PATCH 356/892] Bump nightly version -> 2024-06-27 --- rust-toolchain | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-toolchain b/rust-toolchain index 842c2f3de0d10..72b50d59f7e9a 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2024-06-13" +channel = "nightly-2024-06-27" components = ["cargo", "llvm-tools", "rust-src", "rust-std", "rustc", "rustc-dev", "rustfmt"] From 64be3a3ea756cea1397476e93968673d88770db0 Mon Sep 17 00:00:00 2001 From: WANG Xuerui Date: Fri, 28 Jun 2024 01:52:59 +0800 Subject: [PATCH 357/892] Update the LoongArch target documentation The docs for the LoongArch targets are a bit dated since their introduction, and the prose has some room for improvement as well. Streamline a bit, referring to the neighboring targets' docs, and provide up-to-date information as much as I can come up with. --- .../src/platform-support/loongarch-linux.md | 139 ++++++++++++------ .../src/platform-support/loongarch-none.md | 56 ++++--- 2 files changed, 125 insertions(+), 70 deletions(-) diff --git a/src/doc/rustc/src/platform-support/loongarch-linux.md b/src/doc/rustc/src/platform-support/loongarch-linux.md index e8f55b8bfce10..45eb0a81216d8 100644 --- a/src/doc/rustc/src/platform-support/loongarch-linux.md +++ b/src/doc/rustc/src/platform-support/loongarch-linux.md @@ -1,30 +1,24 @@ -# loongarch\*-unknown-linux-\* +# `loongarch*-unknown-linux-*` -**Tier: 2** +**Tier: 2 (with Host Tools)** -[LoongArch] is a new RISC ISA developed by Loongson Technology Corporation Limited. +[LoongArch][la-docs] Linux targets. +LoongArch is a RISC ISA developed by Loongson Technology Corporation Limited. -[LoongArch]: https://loongson.github.io/LoongArch-Documentation/README-EN.html +| Target | Description | +|--------|-------------| +| `loongarch64-unknown-linux-gnu` | LoongArch64 Linux, LP64D ABI (kernel 5.19, glibc 2.36) | +| `loongarch64-unknown-linux-musl` | LoongArch64 Linux, LP64D ABI (kernel 5.19, musl 1.2.5) | -The target name follow this format: `--`, where `` specifies the CPU family/model, `` specifies the vendor and `` the operating system name. -While the integer base ABI is implied by the machine field, the floating point base ABI type is encoded into the os field of the specifier using the string suffix ``. +These support both native and cross builds, and have full support for `std`. -| `` | `Description` | -|------------------------|--------------------------------------------------------------------| -| f64 | The base ABI use 64-bits FPRs for parameter passing. (lp64d)| -| f32 | The base ABI uses 32-bit FPRs for parameter passing. (lp64f)| -| sf | The base ABI uses no FPR for parameter passing. (lp64s) | +Reference material: -
+* [LoongArch ISA manuals][la-docs] +* [Application Binary Interface for the LoongArch™ Architecture][la-abi-specs] -|`ABI type(Base ABI/ABI extension)`| `C library` | `kernel` | `target tuple` | -|----------------------------------|-------------|----------|----------------------------------| -| lp64d/base | glibc | linux | loongarch64-unknown-linux-gnu | -| lp64f/base | glibc | linux | loongarch64-unknown-linux-gnuf32 | -| lp64s/base | glibc | linux | loongarch64-unknown-linux-gnusf | -| lp64d/base | musl libc | linux | loongarch64-unknown-linux-musl| -| lp64f/base | musl libc | linux | loongarch64-unknown-linux-muslf32| -| lp64s/base | musl libc | linux | loongarch64-unknown-linux-muslsf | +[la-abi-specs]: https://github.com/loongson/la-abi-specs +[la-docs]: https://loongson.github.io/LoongArch-Documentation/README-EN.html ## Target maintainers @@ -35,23 +29,57 @@ While the integer base ABI is implied by the machine field, the floating po ## Requirements -This target is cross-compiled. -A GNU toolchain for LoongArch target is required. It can be downloaded from https://github.com/loongson/build-tools/releases, or built from the source code of GCC (12.1.0 or later) and Binutils (2.40 or later). +### OS Version -## Building the target +The minimum supported Linux version is 5.19. -The target can be built by enabling it for a `rustc` build. +Some Linux distributions, mostly commercial ones, may provide forked Linux +kernels that has a version number less than 5.19 for their LoongArch ports. +Such kernels may still get patched to be compatible with the upstream Linux +5.19 UAPI, therefore supporting the targets described in this document, but +this is not always the case. The `rustup` installer contains a check for this, +and will abort if incompatibility is detected. + +### Host toolchain + +The targets require a reasonably up-to-date LoongArch toolchain on the host. +Currently the following components are used by the Rust CI to build the target, +and the versions can be seen as the minimum requirement: + +* GNU Binutils 2.40 +* GCC 13.x +* glibc 2.36 +* linux-headers 5.19 + +Of these, glibc and linux-headers are at their respective earliest versions with +mainline LoongArch support, so it is impossible to use older versions of these. +Older versions of Binutils and GCC will not work either, due to lack of support +for newer LoongArch ELF relocation types, among other features. + +Recent LLVM/Clang toolchains may be able to build the targets, but are not +currently being actively tested. + +## Building + +These targets are distributed through `rustup`, and otherwise require no +special configuration. + +If you need to build your own Rust for some reason though, the targets can be +simply enabled in `config.toml`. For example: ```toml [build] target = ["loongarch64-unknown-linux-gnu"] ``` -Make sure `loongarch64-unknown-linux-gnu-gcc` can be searched from the directories specified in`$PATH`. Alternatively, you can use GNU LoongArch Toolchain by adding the following to `config.toml`: +Make sure the LoongArch toolchain binaries are reachable from `$PATH`. +Alternatively, you can explicitly configure the paths in `config.toml`: ```toml [target.loongarch64-unknown-linux-gnu] -# ADJUST THIS PATH TO POINT AT YOUR TOOLCHAIN +# Adjust the paths to point at your toolchain +# Suppose the toolchain is placed at /TOOLCHAIN_PATH, and the cross prefix is +# "loongarch64-unknown-linux-gnu-": cc = "/TOOLCHAIN_PATH/bin/loongarch64-unknown-linux-gnu-gcc" cxx = "/TOOLCHAIN_PATH/bin/loongarch64-unknown-linux-gnu-g++" ar = "/TOOLCHAIN_PATH/bin/loongarch64-unknown-linux-gnu-ar" @@ -59,36 +87,51 @@ ranlib = "/TOOLCHAIN_PATH/bin/loongarch64-unknown-linux-gnu-ranlib" linker = "/TOOLCHAIN_PATH/bin/loongarch64-unknown-linux-gnu-gcc" ``` -## Cross-compilation +### Cross-compilation -This target can be cross-compiled on a `x86_64-unknown-linux-gnu` host. Cross-compilation on other hosts may work but is not tested. +This target can be cross-compiled on a `x86_64-unknown-linux-gnu` host. +Other hosts are also likely to work, but not actively tested. + +You can test the cross build directly on the host, thanks to QEMU linux-user emulation. +An example is given below: + +```sh +# Suppose the cross toolchain is placed at $TOOLCHAIN_PATH, with a cross prefix +# of "loongarch64-unknown-linux-gnu-". +export CC_loongarch64_unknown_linux_gnu="$TOOLCHAIN_PATH"/bin/loongarch64-unknown-linux-gnu-gcc +export CXX_loongarch64_unknown_linux_gnu="$TOOLCHAIN_PATH"/bin/loongarch64-unknown-linux-gnu-g++ +export AR_loongarch64_unknown_linux_gnu="$TOOLCHAIN_PATH"/bin/loongarch64-unknown-linux-gnu-gcc-ar +export CARGO_TARGET_LOONGARCH64_UNKNOWN_LINUX_GNU_LINKER="$TOOLCHAIN_PATH"/bin/loongarch64-unknown-linux-gnu-gcc + +# Point qemu-loongarch64 to the LoongArch sysroot. +# Suppose the sysroot is located at "sysroot" below the toolchain root: +export CARGO_TARGET_LOONGARCH64_UNKNOWN_LINUX_GNU_RUNNER="qemu-loongarch64 -L $TOOLCHAIN_PATH/sysroot" +# Or alternatively, if binfmt_misc is set up for running LoongArch binaries +# transparently: +export QEMU_LD_PREFIX="$TOOLCHAIN_PATH"/sysroot -## Testing -To test a cross-compiled binary on your build system, install the qemu binary that supports the LoongArch architecture and execute the following commands. -```text -CC_loongarch64_unknown_linux_gnu=/TOOLCHAIN_PATH/bin/loongarch64-unknown-linux-gnu-gcc \ -CXX_loongarch64_unknown_linux_gnu=/TOOLCHAIN_PATH/bin/loongarch64-unknown-linux-gnu-g++ \ -AR_loongarch64_unknown_linux_gnu=/TOOLCHAIN_PATH/bin/loongarch64-unknown-linux-gnu-gcc-ar \ -CARGO_TARGET_LOONGARCH64_UNKNOWN_LINUX_GNUN_LINKER=/TOOLCHAIN_PATH/bin/loongarch64-unknown-linux-gnu-gcc \ -# SET TARGET SYSTEM LIBRARY PATH -CARGO_TARGET_LOONGARCH64_UNKNOWN_LINUX_GNUN_RUNNER="qemu-loongarch64 -L /TOOLCHAIN_PATH/TARGET_LIBRARY_PATH" \ cargo run --target loongarch64-unknown-linux-gnu --release ``` -Tested on x86 architecture, other architectures not tested. -## Building Rust programs +## Testing + +There are no special requirements for testing and running the targets. +For testing cross builds on the host, please refer to the "Cross-compilation" +section above. -Rust does not yet ship pre-compiled artifacts for this target. To compile for this target, you will either need to build Rust with the target enabled (see "Building the target" above), or build your own copy of `std` by using `build-std` or similar. +## Building Rust programs -If `rustc` has support for that target and the library artifacts are available, then Rust static libraries can be built for that target: +As the targets are available through `rustup`, it is very easy to build Rust +programs for these targets: same as with other architectures. +Note that you will need a LoongArch C/C++ toolchain for linking, or if you want +to compile C code along with Rust (such as for Rust crates with C dependencies). -```shell -$ rustc --target loongarch64-unknown-linux-gnu your-code.rs --crate-type staticlib -$ ls libyour_code.a +```sh +rustup target add loongarch64-unknown-linux-gnu +cargo build --target loongarch64-unknown-linux-gnu ``` -On Rust Nightly it's possible to build without the target artifacts available: +Availability of pre-built artifacts through `rustup` are as follows: -```text -cargo build -Z build-std --target loongarch64-unknown-linux-gnu -``` +* `loongarch64-unknown-linux-gnu`: since Rust 1.71; +* `loongarch64-unknown-linux-musl`: since Rust 1.81. diff --git a/src/doc/rustc/src/platform-support/loongarch-none.md b/src/doc/rustc/src/platform-support/loongarch-none.md index 68d7c9d85e444..110a7cc3424d4 100644 --- a/src/doc/rustc/src/platform-support/loongarch-none.md +++ b/src/doc/rustc/src/platform-support/loongarch-none.md @@ -4,10 +4,10 @@ Freestanding/bare-metal LoongArch64 binaries in ELF format: firmware, kernels, etc. -| Target | Descriptions | -|------------------------------------|-------------------------------------------------------| -| loongarch64-unknown-none | LoongArch 64-bit, LP64D ABI (freestanding, hardfloat) | -| loongarch64-unknown-none-softfloat | LoongArch 64-bit, LP64S ABI (freestanding, softfloat) | +| Target | Description | +|--------|-------------| +| `loongarch64-unknown-none` | LoongArch 64-bit, LP64D ABI (freestanding, hard-float) | +| `loongarch64-unknown-none-softfloat` | LoongArch 64-bit, LP64S ABI (freestanding, soft-float) | ## Target maintainers @@ -19,6 +19,8 @@ Freestanding/bare-metal LoongArch64 binaries in ELF format: firmware, kernels, e This target is cross-compiled. There is no support for `std`. There is no default allocator, but it's possible to use `alloc` by supplying an allocator. +The `*-softfloat` target does not assume existence of FPU or any other LoongArch +ISA extension, and does not make use of any non-GPR register. This allows the generated code to run in environments, such as kernels, which may need to avoid the use of such registers or which may have special considerations about the use of such registers (e.g. saving and restoring them to avoid breaking @@ -26,54 +28,64 @@ userspace code using the same registers). You can change code generation to use additional CPU features via the `-C target-feature=` codegen options to rustc, or via the `#[target_feature]` mechanism within Rust code. -By default, code generated with this target should run on any `loongarch` -hardware; enabling additional target features may raise this baseline. +By default, code generated with the soft-float target should run on any +LoongArch64 hardware, with the hard-float target additionally requiring an FPU; +enabling additional target features may raise this baseline. -Code generated with this target will use the `small` code model by default. +Code generated with the targets will use the `small` code model by default. You can change this using the `-C code-model=` option to rustc. -On `loongarch64-unknown-none*`, `extern "C"` uses the [standard calling -convention](https://loongson.github.io/LoongArch-Documentation/LoongArch-ELF-ABI-EN.html). +On `loongarch64-unknown-none*`, `extern "C"` uses the [architecture's standard calling convention][lapcs]. -This target generates binaries in the ELF format. Any alternate formats or +[lapcs]: https://github.com/loongson/la-abi-specs/blob/release/lapcs.adoc + +The targets generate binaries in the ELF format. Any alternate formats or special considerations for binary layout will require linker options or linker scripts. ## Building the target -You can build Rust with support for the target by adding it to the `target` +You can build Rust with support for the targets by adding them to the `target` list in `config.toml`: ```toml [build] build-stage = 1 -target = ["loongarch64-unknown-none"] +target = [ + "loongarch64-unknown-none", + "loongarch64-unknown-none-softfloat", +] ``` +## Testing + +As the targets support a variety of different environments and do not support +`std`, they do not support running the Rust test suite. + ## Building Rust programs -```text +Starting with Rust 1.74, precompiled artifacts are provided via `rustup`: + +```sh +# install cross-compile toolchain +rustup target add loongarch64-unknown-none # target flag may be used with any cargo or rustc command cargo build --target loongarch64-unknown-none ``` -## Testing - -As `loongarch64-unknown-none*` supports a variety of different environments and does -not support `std`, this target does not support running the Rust test suite. - ## Cross-compilation toolchains and C code -If you want to compile C code along with Rust (such as for Rust crates with C -dependencies), you will need an appropriate `loongarch` toolchain. +For cross builds, you will need an appropriate LoongArch C/C++ toolchain for +linking, or if you want to compile C code along with Rust (such as for Rust +crates with C dependencies). Rust *may* be able to use an `loongarch64-unknown-linux-gnu-` toolchain with appropriate standalone flags to build for this toolchain (depending on the assumptions of that toolchain, see below), or you may wish to use a separate `loongarch64-unknown-none` toolchain. -On some `loongarch` hosts that use ELF binaries, you *may* be able to use the host +On some LoongArch hosts that use ELF binaries, you *may* be able to use the host C toolchain, if it does not introduce assumptions about the host environment that don't match the expectations of a standalone environment. Otherwise, you may need a separate toolchain for standalone/freestanding development, just as -when cross-compiling from a non-`loongarch` platform. +when cross-compiling from a non-LoongArch platform. From 448dd30ed4e28249895db1a231b336f3df573f68 Mon Sep 17 00:00:00 2001 From: Jake Goulding Date: Thu, 27 Jun 2024 14:16:27 -0400 Subject: [PATCH 358/892] Mark `Hasher::finish` as #[must_use] --- library/core/src/hash/mod.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/library/core/src/hash/mod.rs b/library/core/src/hash/mod.rs index 1c93a7b28fd35..da734466263ab 100644 --- a/library/core/src/hash/mod.rs +++ b/library/core/src/hash/mod.rs @@ -334,6 +334,7 @@ pub trait Hasher { /// /// [`write`]: Hasher::write #[stable(feature = "rust1", since = "1.0.0")] + #[must_use] fn finish(&self) -> u64; /// Writes some data into this `Hasher`. From 789ee88bd015fde4257464d0120ab57b0d744e0b Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 27 Jun 2024 14:56:57 -0400 Subject: [PATCH 359/892] Tighten spans for async blocks --- compiler/rustc_ast/src/ast.rs | 5 +- compiler/rustc_ast/src/mut_visit.rs | 3 +- compiler/rustc_ast/src/visit.rs | 2 +- compiler/rustc_ast_lowering/src/expr.rs | 7 ++- compiler/rustc_ast_lowering/src/item.rs | 16 +++--- .../rustc_ast_pretty/src/pprust/state/expr.rs | 2 +- .../src/assert/context.rs | 2 +- compiler/rustc_parse/src/parser/expr.rs | 5 +- compiler/rustc_resolve/src/def_collector.rs | 2 +- .../src/suspicious_operation_groupings.rs | 2 +- .../clippy/clippy_utils/src/ast_utils.rs | 2 +- src/tools/rustfmt/src/expr.rs | 2 +- ...block-control-flow-static-semantics.stderr | 26 +++++----- ...async-borrowck-escaping-block-error.stderr | 10 ++-- .../async-closures/wrong-fn-kind.stderr | 24 ++++----- .../ui/async-await/async-is-unwindsafe.stderr | 25 +++++----- tests/ui/async-await/coroutine-desc.stderr | 4 +- .../async-await/coroutine-not-future.stderr | 4 +- .../issue-67252-unnamed-future.stderr | 2 +- tests/ui/async-await/issue-68112.stderr | 15 ++---- .../issue-70935-complex-spans.stderr | 20 +++----- ...sue-74072-lifetime-name-annotations.stderr | 14 +++--- tests/ui/async-await/issue-86507.stderr | 2 +- .../issues/issue-78938-async-block.stderr | 10 ++-- .../async-closure-gate.afn.stderr | 4 +- .../async-closure-gate.nofeat.stderr | 4 +- .../async-await/try-on-option-in-async.stderr | 12 ++--- .../cloning-in-async-block-121547.stderr | 18 +++---- ...break-inside-coroutine-issue-124495.stderr | 50 ++++++++----------- tests/ui/coroutine/clone-impl-async.stderr | 24 ++++----- tests/ui/coroutine/gen_block_is_coro.stderr | 12 ++--- .../coroutine/gen_block_is_no_future.stderr | 6 +-- tests/ui/coroutine/gen_block_move.stderr | 13 ++--- .../issue-90014-tait.stderr | 2 +- tests/ui/impl-trait/issue-55872-3.stderr | 4 +- .../ui/impl-trait/issues/issue-78722-2.stderr | 4 +- tests/ui/impl-trait/issues/issue-78722.stderr | 2 +- .../ui/impl-trait/nested-return-type4.stderr | 2 +- .../mismatch-sugg-for-shorthand-field.stderr | 4 +- .../pattern/non-structural-match-types.stderr | 2 +- .../expected-boxed-future-isnt-pinned.stderr | 2 +- tests/ui/traits/next-solver/async.fail.stderr | 2 +- .../indirect-recursion-issue-112047.stderr | 4 +- 43 files changed, 173 insertions(+), 204 deletions(-) diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 4a3ce0e0c3066..f5e79c04d784f 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -1454,7 +1454,10 @@ pub enum ExprKind { Block(P, Option
{ | ^^^^^^^ -error: aborting due to 1 previous error +error[E0049]: method `to` has 1 const parameter but its trait declaration has 0 const parameters + --> $DIR/non-const-op-in-closure-in-const.rs:5:1 + | +LL | #[const_trait] + | ^^^^^^^^^^^^^^ found 1 const parameter +LL | trait Convert { +LL | fn to(self) -> T; + | - expected 0 const parameters + +error[E0015]: cannot call non-const fn `>::from` in constant functions + --> $DIR/non-const-op-in-closure-in-const.rs:12:9 + | +LL | B::from(self) + | ^^^^^^^^^^^^^ + | + = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants +help: add `#![feature(effects)]` to the crate attributes to enable + | +LL + #![feature(effects)] + | + +error: aborting due to 3 previous errors +Some errors have detailed explanations: E0015, E0049. +For more information about an error, try `rustc --explain E0015`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/specializing-constness.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/specializing-constness.rs index 3aabaf137d54c..4501a218ad723 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/specializing-constness.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/specializing-constness.rs @@ -22,6 +22,8 @@ impl const A for T { impl A for T { //~^ ERROR: cannot specialize +//~| ERROR: cannot specialize +//~| ERROR: cannot specialize //FIXME(effects) ~| ERROR: missing `~const` qualifier fn a() -> u32 { 3 diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/specializing-constness.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/specializing-constness.stderr index 226295bf949df..272cb26ff42e5 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/specializing-constness.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/specializing-constness.stderr @@ -13,5 +13,17 @@ error: cannot specialize on const impl with non-const impl LL | impl A for T { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 1 previous error; 1 warning emitted +error: cannot specialize on trait `Compat` + --> $DIR/specializing-constness.rs:23:16 + | +LL | impl A for T { + | ^^^ + +error: cannot specialize on trait `Compat` + --> $DIR/specializing-constness.rs:23:9 + | +LL | impl A for T { + | ^^^^ + +error: aborting due to 3 previous errors; 1 warning emitted diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.rs index 2f26eebbe32f9..ba20a79a4df74 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.rs @@ -15,7 +15,7 @@ trait Bar: ~const Foo {} const fn foo(x: &T) { x.a(); - //[yy,yn]~^ ERROR mismatched types + //[yy,yn]~^ ERROR the trait bound // FIXME(effects) diagnostic } diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.yn.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.yn.stderr index f96e6fb4ae468..a4f1c94bca0bc 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.yn.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.yn.stderr @@ -19,15 +19,25 @@ LL | #![feature(const_trait_impl, effects)] = note: see issue #102090 for more information = note: `#[warn(incomplete_features)]` on by default -error[E0308]: mismatched types - --> $DIR/super-traits-fail-2.rs:17:5 +error[E0277]: the trait bound `Foo::{synthetic#0}: ~const Compat` is not satisfied + --> $DIR/super-traits-fail-2.rs:17:7 | LL | x.a(); - | ^^^^^ expected `host`, found `true` + | ^ the trait `~const Compat` is not implemented for `Foo::{synthetic#0}` | - = note: expected constant `host` - found constant `true` +note: required by a bound in `Foo::a` + --> $DIR/super-traits-fail-2.rs:4:25 + | +LL | #[cfg_attr(any(yy, yn), const_trait)] + | ^^^^^^^^^^^ required by this bound in `Foo::a` +LL | trait Foo { +LL | fn a(&self); + | - required by a bound in this associated function +help: consider further restricting the associated type + | +LL | const fn foo(x: &T) where Foo::{synthetic#0}: ~const Compat { + | +++++++++++++++++++++++++++++++++++++++ error: aborting due to 2 previous errors; 1 warning emitted -For more information about this error, try `rustc --explain E0308`. +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.yy.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.yy.stderr index ffc259e590e80..4e27ebc5e9ec7 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.yy.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.yy.stderr @@ -7,15 +7,25 @@ LL | #![feature(const_trait_impl, effects)] = note: see issue #102090 for more information = note: `#[warn(incomplete_features)]` on by default -error[E0308]: mismatched types - --> $DIR/super-traits-fail-2.rs:17:5 +error[E0277]: the trait bound `Foo::{synthetic#0}: ~const Compat` is not satisfied + --> $DIR/super-traits-fail-2.rs:17:7 | LL | x.a(); - | ^^^^^ expected `host`, found `true` + | ^ the trait `~const Compat` is not implemented for `Foo::{synthetic#0}` | - = note: expected constant `host` - found constant `true` +note: required by a bound in `Foo::a` + --> $DIR/super-traits-fail-2.rs:4:25 + | +LL | #[cfg_attr(any(yy, yn), const_trait)] + | ^^^^^^^^^^^ required by this bound in `Foo::a` +LL | trait Foo { +LL | fn a(&self); + | - required by a bound in this associated function +help: consider further restricting the associated type + | +LL | const fn foo(x: &T) where Foo::{synthetic#0}: ~const Compat { + | +++++++++++++++++++++++++++++++++++++++ error: aborting due to 1 previous error; 1 warning emitted -For more information about this error, try `rustc --explain E0308`. +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.nn.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.nn.stderr index cde4b1ff77f35..a9bf2687cb88f 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.nn.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.nn.stderr @@ -1,32 +1,23 @@ error: `~const` is not allowed here - --> $DIR/super-traits-fail-3.rs:12:12 + --> $DIR/super-traits-fail-3.rs:13:12 | LL | trait Bar: ~const Foo {} | ^^^^^^ | note: this trait is not a `#[const_trait]`, so it cannot have `~const` trait bounds - --> $DIR/super-traits-fail-3.rs:12:1 + --> $DIR/super-traits-fail-3.rs:13:1 | LL | trait Bar: ~const Foo {} | ^^^^^^^^^^^^^^^^^^^^^^^^ -warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/super-traits-fail-3.rs:1:30 - | -LL | #![feature(const_trait_impl, effects)] - | ^^^^^^^ - | - = note: see issue #102090 for more information - = note: `#[warn(incomplete_features)]` on by default - error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/super-traits-fail-3.rs:12:19 + --> $DIR/super-traits-fail-3.rs:13:19 | LL | trait Bar: ~const Foo {} | ^^^ error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/super-traits-fail-3.rs:12:19 + --> $DIR/super-traits-fail-3.rs:13:19 | LL | trait Bar: ~const Foo {} | ^^^ @@ -34,7 +25,7 @@ LL | trait Bar: ~const Foo {} = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/super-traits-fail-3.rs:12:19 + --> $DIR/super-traits-fail-3.rs:13:19 | LL | trait Bar: ~const Foo {} | ^^^ @@ -42,10 +33,10 @@ LL | trait Bar: ~const Foo {} = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/super-traits-fail-3.rs:18:24 + --> $DIR/super-traits-fail-3.rs:19:24 | LL | const fn foo(x: &T) { | ^^^ -error: aborting due to 5 previous errors; 1 warning emitted +error: aborting due to 5 previous errors diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.ny.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.ny.stderr index 6f1840181481c..c3811623c1c86 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.ny.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.ny.stderr @@ -1,20 +1,11 @@ -warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/super-traits-fail-3.rs:1:30 - | -LL | #![feature(const_trait_impl, effects)] - | ^^^^^^^ - | - = note: see issue #102090 for more information - = note: `#[warn(incomplete_features)]` on by default - error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/super-traits-fail-3.rs:12:19 + --> $DIR/super-traits-fail-3.rs:13:19 | LL | trait Bar: ~const Foo {} | ^^^ error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/super-traits-fail-3.rs:12:19 + --> $DIR/super-traits-fail-3.rs:13:19 | LL | trait Bar: ~const Foo {} | ^^^ @@ -22,12 +13,12 @@ LL | trait Bar: ~const Foo {} = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/super-traits-fail-3.rs:12:19 + --> $DIR/super-traits-fail-3.rs:13:19 | LL | trait Bar: ~const Foo {} | ^^^ | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error: aborting due to 3 previous errors; 1 warning emitted +error: aborting due to 3 previous errors diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.rs index f7e85902a41b2..24661f078b017 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.rs @@ -1,7 +1,8 @@ -#![feature(const_trait_impl, effects)] //~ WARN the feature `effects` is incomplete +#![allow(incomplete_features)] +#![feature(const_trait_impl, effects)] //@ revisions: yy yn ny nn -//@[yy] check-pass +//@[yy] known-bug: #110395 #[cfg_attr(any(yy, yn), const_trait)] trait Foo { @@ -18,7 +19,7 @@ trait Bar: ~const Foo {} const fn foo(x: &T) { //[yn,nn]~^ ERROR: `~const` can only be applied to `#[const_trait]` x.a(); - //[yn]~^ ERROR: mismatched types + //[yn]~^ ERROR: the trait bound } fn main() {} diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.yn.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.yn.stderr index b0a3b39631dca..34a60329eb5e2 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.yn.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.yn.stderr @@ -1,39 +1,40 @@ error: `~const` is not allowed here - --> $DIR/super-traits-fail-3.rs:12:12 + --> $DIR/super-traits-fail-3.rs:13:12 | LL | trait Bar: ~const Foo {} | ^^^^^^ | note: this trait is not a `#[const_trait]`, so it cannot have `~const` trait bounds - --> $DIR/super-traits-fail-3.rs:12:1 + --> $DIR/super-traits-fail-3.rs:13:1 | LL | trait Bar: ~const Foo {} | ^^^^^^^^^^^^^^^^^^^^^^^^ -warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/super-traits-fail-3.rs:1:30 - | -LL | #![feature(const_trait_impl, effects)] - | ^^^^^^^ - | - = note: see issue #102090 for more information - = note: `#[warn(incomplete_features)]` on by default - error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/super-traits-fail-3.rs:18:24 + --> $DIR/super-traits-fail-3.rs:19:24 | LL | const fn foo(x: &T) { | ^^^ -error[E0308]: mismatched types - --> $DIR/super-traits-fail-3.rs:20:5 +error[E0277]: the trait bound `Foo::{synthetic#0}: ~const Compat` is not satisfied + --> $DIR/super-traits-fail-3.rs:21:7 | LL | x.a(); - | ^^^^^ expected `host`, found `true` + | ^ the trait `~const Compat` is not implemented for `Foo::{synthetic#0}` + | +note: required by a bound in `Foo::a` + --> $DIR/super-traits-fail-3.rs:7:25 + | +LL | #[cfg_attr(any(yy, yn), const_trait)] + | ^^^^^^^^^^^ required by this bound in `Foo::a` +LL | trait Foo { +LL | fn a(&self); + | - required by a bound in this associated function +help: consider further restricting the associated type | - = note: expected constant `host` - found constant `true` +LL | const fn foo(x: &T) where Foo::{synthetic#0}: ~const Compat { + | +++++++++++++++++++++++++++++++++++++++ -error: aborting due to 3 previous errors; 1 warning emitted +error: aborting due to 3 previous errors -For more information about this error, try `rustc --explain E0308`. +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.yy.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.yy.stderr index e354c66919ec6..8ac20b3e06852 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.yy.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.yy.stderr @@ -1,11 +1,22 @@ -warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/super-traits-fail-3.rs:1:30 +error[E0277]: the trait bound `Foo::{synthetic#0}: ~const Compat` is not satisfied + --> $DIR/super-traits-fail-3.rs:21:7 | -LL | #![feature(const_trait_impl, effects)] - | ^^^^^^^ +LL | x.a(); + | ^ the trait `~const Compat` is not implemented for `Foo::{synthetic#0}` | - = note: see issue #102090 for more information - = note: `#[warn(incomplete_features)]` on by default +note: required by a bound in `Foo::a` + --> $DIR/super-traits-fail-3.rs:7:25 + | +LL | #[cfg_attr(any(yy, yn), const_trait)] + | ^^^^^^^^^^^ required by this bound in `Foo::a` +LL | trait Foo { +LL | fn a(&self); + | - required by a bound in this associated function +help: consider further restricting the associated type + | +LL | const fn foo(x: &T) where Foo::{synthetic#0}: ~const Compat { + | +++++++++++++++++++++++++++++++++++++++ -warning: 1 warning emitted +error: aborting due to 1 previous error +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail.rs index 0bbf2dabffe57..bb8e06ab2f7a1 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail.rs @@ -1,7 +1,7 @@ //@ check-pass -//@ known-bug: #110395 -#![feature(const_trait_impl)] +#![allow(incomplete_features)] +#![feature(const_trait_impl, effects)] #[const_trait] trait Foo { diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits.rs index cfbb8e9f6be57..b32c8cab7ecbe 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits.rs @@ -1,5 +1,6 @@ -//@ check-pass -#![feature(const_trait_impl, effects)] //~ WARN the feature `effects` is incomplete +// FIXME(effects) check-pass +//@ known-bug: #110395 +#![feature(const_trait_impl, effects)] #[const_trait] trait Foo { diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits.stderr index 2ff1a880d84f0..a9cb68a247ccd 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits.stderr @@ -1,5 +1,5 @@ warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/super-traits.rs:2:30 + --> $DIR/super-traits.rs:3:30 | LL | #![feature(const_trait_impl, effects)] | ^^^^^^^ @@ -7,5 +7,25 @@ LL | #![feature(const_trait_impl, effects)] = note: see issue #102090 for more information = note: `#[warn(incomplete_features)]` on by default -warning: 1 warning emitted +error[E0277]: the trait bound `Foo::{synthetic#0}: ~const Compat` is not satisfied + --> $DIR/super-traits.rs:21:7 + | +LL | t.a(); + | ^ the trait `~const Compat` is not implemented for `Foo::{synthetic#0}` + | +note: required by a bound in `Foo::a` + --> $DIR/super-traits.rs:5:1 + | +LL | #[const_trait] + | ^^^^^^^^^^^^^^ required by this bound in `Foo::a` +LL | trait Foo { +LL | fn a(&self); + | - required by a bound in this associated function +help: consider further restricting the associated type + | +LL | const fn foo(t: &T) where Foo::{synthetic#0}: ~const Compat { + | +++++++++++++++++++++++++++++++++++++++ + +error: aborting due to 1 previous error; 1 warning emitted +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-invalid-places.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-invalid-places.stderr index 3b320f1c5424a..8151b9aaa23de 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-invalid-places.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-invalid-places.stderr @@ -282,21 +282,12 @@ help: wrap the field type in `ManuallyDrop<...>` LL | union Union { field: std::mem::ManuallyDrop } | +++++++++++++++++++++++ + -error[E0275]: overflow evaluating the requirement `Trait::{opaque#0} == _` +error[E0275]: overflow evaluating the requirement `(): Trait` --> $DIR/tilde-const-invalid-places.rs:34:34 | LL | type Type = (); | ^^ | -note: required for `()` to implement `Trait` - --> $DIR/tilde-const-invalid-places.rs:56:23 - | -LL | impl Trait for T {} - | ------------ ^^^^^ ^ - | | - | unsatisfied trait bound introduced here - = note: 1 redundant requirement hidden - = note: required for `()` to implement `Trait` note: required by a bound in `NonConstTrait::Type` --> $DIR/tilde-const-invalid-places.rs:25:33 | diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-default-body-stability.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-default-body-stability.stderr index adb1b01f08704..d0c2f88005d7a 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-default-body-stability.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-default-body-stability.stderr @@ -25,112 +25,5 @@ LL | impl const FromResidual for T { = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` = note: adding a non-const method body in the future would be a breaking change -error[E0207]: the const parameter `host` is not constrained by the impl trait, self type, or predicates - --> $DIR/trait-default-body-stability.rs:18:6 - | -LL | impl const Try for T { - | ^^^^^ unconstrained const parameter - | - = note: expressions using a const parameter must map each value to a distinct output value - = note: proving the result of expressions other than the parameter are unique is not supported - -error[E0207]: the const parameter `host` is not constrained by the impl trait, self type, or predicates - --> $DIR/trait-default-body-stability.rs:33:6 - | -LL | impl const FromResidual for T { - | ^^^^^ unconstrained const parameter - | - = note: expressions using a const parameter must map each value to a distinct output value - = note: proving the result of expressions other than the parameter are unique is not supported - -error[E0284]: type annotations needed - --> $DIR/trait-default-body-stability.rs:33:6 - | -LL | impl const FromResidual for T { - | ^^^^^ cannot infer the value of the constant `_` - | -note: required for `T` to implement `Try` - --> $DIR/trait-default-body-stability.rs:18:12 - | -LL | impl const Try for T { - | ----- ^^^ ^ - | | - | unsatisfied trait bound introduced here - -error[E0284]: type annotations needed - --> $DIR/trait-default-body-stability.rs:44:9 - | -LL | T? - | ^^ cannot infer the value of the constant `_` - | -note: required for `T` to implement `Try` - --> $DIR/trait-default-body-stability.rs:18:12 - | -LL | impl const Try for T { - | ----- ^^^ ^ - | | - | unsatisfied trait bound introduced here - -error[E0284]: type annotations needed - --> $DIR/trait-default-body-stability.rs:44:9 - | -LL | T? - | ^^ cannot infer the value of the constant `_` - | -note: required for `T` to implement `FromResidual` - --> $DIR/trait-default-body-stability.rs:33:12 - | -LL | impl const FromResidual for T { - | ----- ^^^^^^^^^^^^ ^ - | | - | unsatisfied trait bound introduced here - -error[E0284]: type annotations needed - --> $DIR/trait-default-body-stability.rs:44:9 - | -LL | T? - | ^^ cannot infer the value of the constant `_` - | -note: required for `T` to implement `Try` - --> $DIR/trait-default-body-stability.rs:18:12 - | -LL | impl const Try for T { - | ----- ^^^ ^ - | | - | unsatisfied trait bound introduced here - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error[E0284]: type annotations needed - --> $DIR/trait-default-body-stability.rs:44:9 - | -LL | T? - | ^^ cannot infer the value of the constant `_` - | -note: required for `T` to implement `FromResidual` - --> $DIR/trait-default-body-stability.rs:33:12 - | -LL | impl const FromResidual for T { - | ----- ^^^^^^^^^^^^ ^ - | | - | unsatisfied trait bound introduced here - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error[E0284]: type annotations needed - --> $DIR/trait-default-body-stability.rs:44:9 - | -LL | T? - | ^^ cannot infer the value of the constant `_` - | -note: required for `T` to implement `Try` - --> $DIR/trait-default-body-stability.rs:18:12 - | -LL | impl const Try for T { - | ----- ^^^ ^ - | | - | unsatisfied trait bound introduced here - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error: aborting due to 10 previous errors; 1 warning emitted +error: aborting due to 2 previous errors; 1 warning emitted -Some errors have detailed explanations: E0207, E0284. -For more information about an error, try `rustc --explain E0207`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-const.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-const.rs index 516451d881106..dd5de62aff529 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-const.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-const.rs @@ -2,7 +2,7 @@ // Checking the validity of traits' where clauses happen at a later stage. // (`rustc_const_eval` instead of `rustc_hir_analysis`) Therefore one file as a // test is not enough. -//@ known-bug: #110395 + #![feature(const_trait_impl, effects)] #![allow(incomplete_features)] @@ -20,8 +20,10 @@ const fn test1() { T::a(); T::b(); //~^ ERROR mismatched types + //~| ERROR the trait bound T::c::(); //~^ ERROR mismatched types + //~| ERROR the trait bound } const fn test2() { diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-const.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-const.stderr index 95c32b12241c9..877152472c16e 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-const.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-const.stderr @@ -1,44 +1,60 @@ -warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/trait-where-clause-const.rs:7:30 - | -LL | #![feature(const_trait_impl, effects)] - | ^^^^^^^ - | - = note: see issue #102090 for more information - = note: `#[warn(incomplete_features)]` on by default - -error[E0277]: the trait bound `T: ~const Bar` is not satisfied +error[E0277]: the trait bound `Foo::{synthetic#0}: Compat` is not satisfied --> $DIR/trait-where-clause-const.rs:21:5 | LL | T::b(); - | ^ the trait `~const Bar` is not implemented for `T` + | ^ the trait `Compat` is not implemented for `Foo::{synthetic#0}` | note: required by a bound in `Foo::b` - --> $DIR/trait-where-clause-const.rs:15:24 + --> $DIR/trait-where-clause-const.rs:12:1 | +LL | #[const_trait] + | ^^^^^^^^^^^^^^ required by this bound in `Foo::b` +... LL | fn b() where Self: ~const Bar; - | ^^^^^^^^^^ required by this bound in `Foo::b` -help: consider further restricting this bound + | - required by a bound in this associated function +help: consider further restricting the associated type + | +LL | const fn test1() where Foo::{synthetic#0}: Compat { + | ++++++++++++++++++++++++++++++++ + +error[E0308]: mismatched types + --> $DIR/trait-where-clause-const.rs:21:5 | -LL | const fn test1() { - | ++++++++++++ +LL | T::b(); + | ^^^^^^ expected `host`, found `true` + | + = note: expected constant `host` + found constant `true` -error[E0277]: the trait bound `T: ~const Bar` is not satisfied - --> $DIR/trait-where-clause-const.rs:23:12 +error[E0277]: the trait bound `Foo::{synthetic#0}: Compat` is not satisfied + --> $DIR/trait-where-clause-const.rs:24:5 | LL | T::c::(); - | ^ the trait `~const Bar` is not implemented for `T` + | ^ the trait `Compat` is not implemented for `Foo::{synthetic#0}` | note: required by a bound in `Foo::c` - --> $DIR/trait-where-clause-const.rs:16:13 + --> $DIR/trait-where-clause-const.rs:12:1 | +LL | #[const_trait] + | ^^^^^^^^^^^^^^ required by this bound in `Foo::c` +... LL | fn c(); - | ^^^^^^^^^^ required by this bound in `Foo::c` -help: consider further restricting this bound + | - required by a bound in this associated function +help: consider further restricting the associated type + | +LL | const fn test1() where Foo::{synthetic#0}: Compat { + | ++++++++++++++++++++++++++++++++ + +error[E0308]: mismatched types + --> $DIR/trait-where-clause-const.rs:24:5 + | +LL | T::c::(); + | ^^^^^^^^^^^ expected `host`, found `true` | -LL | const fn test1() { - | ++++++++++++ + = note: expected constant `host` + found constant `true` -error: aborting due to 2 previous errors; 1 warning emitted +error: aborting due to 4 previous errors -For more information about this error, try `rustc --explain E0277`. +Some errors have detailed explanations: E0277, E0308. +For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/unsatisfied-const-trait-bound.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/unsatisfied-const-trait-bound.rs index 3a8c6d5b1a4fa..c50c755f667fc 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/unsatisfied-const-trait-bound.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/unsatisfied-const-trait-bound.rs @@ -18,7 +18,8 @@ impl Trait for Ty { } fn main() { - require::(); //~ ERROR the trait bound `Ty: const Trait` is not satisfied + // FIXME(effects): improve diagnostics on this + require::(); //~ ERROR the trait bound `Trait::{synthetic#0}: const Compat` is not satisfied } struct Container; diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/unsatisfied-const-trait-bound.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/unsatisfied-const-trait-bound.stderr index 258f95b5c4a89..b9f6c9e883562 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/unsatisfied-const-trait-bound.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/unsatisfied-const-trait-bound.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/unsatisfied-const-trait-bound.rs:27:37 + --> $DIR/unsatisfied-const-trait-bound.rs:29:37 | LL | fn accept0(_: Container<{ T::make() }>) {} | ^^^^^^^^^ expected `false`, found `true` @@ -8,7 +8,7 @@ LL | fn accept0(_: Container<{ T::make() }>) {} found constant `true` error[E0308]: mismatched types - --> $DIR/unsatisfied-const-trait-bound.rs:32:50 + --> $DIR/unsatisfied-const-trait-bound.rs:34:50 | LL | const fn accept1(_: Container<{ T::make() }>) {} | ^^^^^^^^^ expected `false`, found `host` @@ -16,15 +16,14 @@ LL | const fn accept1(_: Container<{ T::make() }>) {} = note: expected constant `false` found constant `host` -error[E0277]: the trait bound `Ty: const Trait` is not satisfied - --> $DIR/unsatisfied-const-trait-bound.rs:20:15 +error[E0277]: the trait bound `Trait::{synthetic#0}: const Compat` is not satisfied + --> $DIR/unsatisfied-const-trait-bound.rs:22:15 | LL | require::(); - | ^^ the trait `const Trait` is not implemented for `Ty` + | ^^ the trait `const Compat` is not implemented for `Trait::{synthetic#0}` | - = help: the trait `Trait` is implemented for `Ty` note: required by a bound in `require` - --> $DIR/unsatisfied-const-trait-bound.rs:6:15 + --> $DIR/unsatisfied-const-trait-bound.rs:7:15 | LL | fn require() {} | ^^^^^^^^^^^ required by this bound in `require` From 0a2330630d223ac3601a7b53e65e0d5867b60c2c Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Tue, 25 Jun 2024 09:57:31 +0000 Subject: [PATCH 398/892] general fixups and turn `TODO`s into `FIXME`s --- compiler/rustc_hir_analysis/src/bounds.rs | 6 ++-- .../src/collect/item_bounds.rs | 9 +++-- .../src/collect/predicates_of.rs | 6 ++-- .../src/hir_ty_lowering/generics.rs | 2 +- compiler/rustc_hir_typeck/src/method/mod.rs | 2 +- .../src/solve/normalizes_to/mod.rs | 5 ++- .../src/solve/trait_goals.rs | 4 +-- compiler/rustc_ty_utils/src/assoc.rs | 4 +-- compiler/rustc_type_ir/src/effects.rs | 6 ++-- library/core/src/marker.rs | 4 ++- ...-type-const-bound-usage-0.qualified.stderr | 27 --------------- ...ype-const-bound-usage-0.unqualified.stderr | 11 ------- .../assoc-type-const-bound-usage-1.rs | 5 ++- ... => assoc-type-const-bound-usage-1.stderr} | 0 ...ype-const-bound-usage-1.unqualified.stderr | 33 ------------------- .../rfc-2632-const-trait-impl/assoc-type.rs | 3 +- 16 files changed, 31 insertions(+), 96 deletions(-) delete mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-0.qualified.stderr delete mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-0.unqualified.stderr rename tests/ui/rfcs/rfc-2632-const-trait-impl/{assoc-type-const-bound-usage-1.qualified.stderr => assoc-type-const-bound-usage-1.stderr} (100%) delete mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-1.unqualified.stderr diff --git a/compiler/rustc_hir_analysis/src/bounds.rs b/compiler/rustc_hir_analysis/src/bounds.rs index 0b03eeaced1be..61b7dd8bb8c34 100644 --- a/compiler/rustc_hir_analysis/src/bounds.rs +++ b/compiler/rustc_hir_analysis/src/bounds.rs @@ -72,7 +72,7 @@ impl<'tcx> Bounds<'tcx> { // For `T: ~const Tr` or `T: const Tr`, we need to add an additional bound on the // associated type of `` and make sure that the effect is compatible. if let Some(compat_val) = match (tcx.def_kind(defining_def_id), constness) { - // TODO: do we need `T: const Trait` anymore? + // FIXME(effects): revisit the correctness of this (_, ty::BoundConstness::Const) => Some(tcx.consts.false_), // body owners that can have trait bounds (DefKind::Const | DefKind::Fn | DefKind::AssocFn, ty::BoundConstness::ConstIfConst) => { @@ -120,7 +120,7 @@ impl<'tcx> Bounds<'tcx> { // FIXME(effects) this is equality for now, which wouldn't be helpful for a non-const implementor // that uses a `Bar` that implements `Trait` with `Maybe` effects. (DefKind::AssocTy, ty::BoundConstness::ConstIfConst) => { - // TODO write the actual impl + // FIXME(effects): implement this return; } // probably illegal in this position. @@ -169,7 +169,7 @@ impl<'tcx> Bounds<'tcx> { pub fn clauses( &self, - // TODO remove tcx + // FIXME(effects): remove tcx _tcx: TyCtxt<'tcx>, ) -> impl Iterator, Span)> + '_ { self.clauses.iter().cloned() diff --git a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs index c8c82c711de18..b32067ebd6aee 100644 --- a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs +++ b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs @@ -134,13 +134,16 @@ pub(super) fn explicit_item_bounds_with_filter( if let ty::AssocItemContainer::TraitContainer = tcx.associated_item(def_id).container { // for traits, emit `type Effects: TyCompat<<(T1::Effects, ..) as Min>::Output>` - // TODO do the same for impls let tup = Ty::new(tcx, ty::Tuple(preds.effects_min_tys)); - // TODO span + // FIXME(effects) span let span = tcx.def_span(def_id); let assoc = tcx.require_lang_item(hir::LangItem::EffectsMinOutput, Some(span)); let proj = Ty::new_projection(tcx, assoc, [tup]); - let self_proj = Ty::new_projection(tcx, def_id.to_def_id(), ty::GenericArgs::identity_for_item(tcx, def_id)); + let self_proj = Ty::new_projection( + tcx, + def_id.to_def_id(), + ty::GenericArgs::identity_for_item(tcx, def_id), + ); let trait_ = tcx.require_lang_item(hir::LangItem::EffectsTyCompat, Some(span)); let trait_ref = ty::TraitRef::new(tcx, trait_, [self_proj, proj]); predicates.push((ty::Binder::dummy(trait_ref).upcast(tcx), span)); diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs index cc3078f037a06..1c3c1a79cfbc3 100644 --- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs @@ -323,12 +323,14 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen let Some(assoc_def_id) = tcx.associated_type_for_effects(parent) else { bug!("associated_type_for_effects returned None when there is host effect in generics"); }; - let effects = Ty::new_projection(tcx, assoc_def_id, ty::GenericArgs::identity_for_item(tcx, parent)); + let effects = + Ty::new_projection(tcx, assoc_def_id, ty::GenericArgs::identity_for_item(tcx, parent)); let param = generics.param_at(host_effect_index, tcx); let span = tcx.def_span(param.def_id); let host = ty::Const::new_param(tcx, ty::ParamConst::for_def(param)); let compat = tcx.require_lang_item(LangItem::EffectsCompat, Some(span)); - let trait_ref = ty::TraitRef::new(tcx, compat, [ty::GenericArg::from(effects), host.into()]); + let trait_ref = + ty::TraitRef::new(tcx, compat, [ty::GenericArg::from(effects), host.into()]); predicates.push((ty::Binder::dummy(trait_ref).upcast(tcx), span)); } diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs index 67046b5ac0e40..e92c377f0ce2a 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs @@ -256,7 +256,7 @@ pub fn lower_generic_args<'tcx: 'a, 'a>( | GenericParamDefKind::Lifetime, _, ) => { - // TODO: this should be removed + // FIXME(effects): this should be removed // SPECIAL CASE FOR DESUGARED EFFECT PARAMS // This comes from the following example: // diff --git a/compiler/rustc_hir_typeck/src/method/mod.rs b/compiler/rustc_hir_typeck/src/method/mod.rs index dad909fc4e102..ff8899ae0368d 100644 --- a/compiler/rustc_hir_typeck/src/method/mod.rs +++ b/compiler/rustc_hir_typeck/src/method/mod.rs @@ -404,7 +404,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { debug!("lookup_in_trait_adjusted: method_item={:?}", method_item); let mut obligations = vec![]; - // TODO there is something wrong here because now methods for binops may get `const host: bool` + // FIXME(effects): revisit when binops get `#[const_trait]` // Instantiate late-bound regions and instantiate the trait // parameters into the method type to get the actual method type. diff --git a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs index f75c30eda9949..55c0440a53715 100644 --- a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs @@ -873,7 +873,6 @@ where return Err(NoSolution); }; - let cx = ecx.cx(); let mut first_non_maybe = None; @@ -907,11 +906,11 @@ where let Some(kind) = ty::EffectKind::try_from_ty(cx, ty) else { return Err(NoSolution); }; - + let Some(result) = ty::EffectKind::min(min, kind) else { return Err(NoSolution); }; - + min = result; } diff --git a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs index 8c6e5eb5a4d9d..73ae1c4b11359 100644 --- a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs +++ b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs @@ -731,11 +731,11 @@ where let Some(kind) = ty::EffectKind::try_from_ty(ecx.cx(), ty) else { return Err(NoSolution); }; - + let Some(result) = ty::EffectKind::min(min, kind) else { return Err(NoSolution); }; - + min = result; } } diff --git a/compiler/rustc_ty_utils/src/assoc.rs b/compiler/rustc_ty_utils/src/assoc.rs index 681f089e84fb7..6a55e83786cb8 100644 --- a/compiler/rustc_ty_utils/src/assoc.rs +++ b/compiler/rustc_ty_utils/src/assoc.rs @@ -255,7 +255,7 @@ fn associated_type_for_effects(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option, def_id: LocalDefId) -> Option None, } } -} \ No newline at end of file +} diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs index b71bedaa1948f..042acbf20b1a0 100644 --- a/library/core/src/marker.rs +++ b/library/core/src/marker.rs @@ -1028,6 +1028,9 @@ pub macro SmartPointer($item:item) { /* compiler built-in */ } +// Support traits and types for the desugaring of const traits and +// `~const` bounds. Not supposed to be used by anything other than +// the compiler. #[doc(hidden)] #[unstable( feature = "effect_types", @@ -1036,7 +1039,6 @@ pub macro SmartPointer($item:item) { )] #[allow(missing_debug_implementations)] // these unit structs don't need `Debug` impls. #[cfg(not(bootstrap))] -// TODO docs pub mod effects { #[lang = "EffectsNoRuntime"] pub struct NoRuntime; diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-0.qualified.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-0.qualified.stderr deleted file mode 100644 index 1af0f481943ab..0000000000000 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-0.qualified.stderr +++ /dev/null @@ -1,27 +0,0 @@ -warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/assoc-type-const-bound-usage-0.rs:6:30 - | -LL | #![feature(const_trait_impl, effects)] - | ^^^^^^^ - | - = note: see issue #102090 for more information - = note: `#[warn(incomplete_features)]` on by default - -error[E0277]: the trait bound `Trait::{synthetic#0}: Compat` is not satisfied - --> $DIR/assoc-type-const-bound-usage-0.rs:21:5 - | -LL | ::Assoc::func() - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Compat` is not implemented for `Trait::{synthetic#0}` - | -note: required by a bound in `Trait::func` - --> $DIR/assoc-type-const-bound-usage-0.rs:8:1 - | -LL | #[const_trait] - | ^^^^^^^^^^^^^^ required by this bound in `Trait::func` -... -LL | fn func() -> i32; - | ---- required by a bound in this associated function - -error: aborting due to 1 previous error; 1 warning emitted - -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-0.unqualified.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-0.unqualified.stderr deleted file mode 100644 index 3d592834600e0..0000000000000 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-0.unqualified.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/assoc-type-const-bound-usage-0.rs:6:30 - | -LL | #![feature(const_trait_impl, effects)] - | ^^^^^^^ - | - = note: see issue #102090 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-1.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-1.rs index 5394c3f2d070c..8a1bf75f87e1a 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-1.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-1.rs @@ -1,6 +1,5 @@ -// FIXME(effects): Collapse the revisions into one once we support `::Proj`. -//@ revisions: unqualified qualified -//@known-bug: unknown +//@ known-bug: unknown +// FIXME(effects) #![feature(const_trait_impl, effects, generic_const_exprs)] #![allow(incomplete_features)] diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-1.qualified.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-1.stderr similarity index 100% rename from tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-1.qualified.stderr rename to tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-1.stderr diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-1.unqualified.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-1.unqualified.stderr deleted file mode 100644 index f8bab2d4c27fa..0000000000000 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-1.unqualified.stderr +++ /dev/null @@ -1,33 +0,0 @@ -error[E0277]: the trait bound `Trait::{synthetic#0}: Compat` is not satisfied - --> $DIR/assoc-type-const-bound-usage-1.rs:16:44 - | -LL | fn unqualified() -> Type<{ T::Assoc::func() }> { - | ^^^^^^^^ the trait `Compat` is not implemented for `Trait::{synthetic#0}` - | -note: required by a bound in `Trait::func` - --> $DIR/assoc-type-const-bound-usage-1.rs:8:1 - | -LL | #[const_trait] - | ^^^^^^^^^^^^^^ required by this bound in `Trait::func` -... -LL | fn func() -> i32; - | ---- required by a bound in this associated function - -error[E0277]: the trait bound `Trait::{synthetic#0}: Compat` is not satisfied - --> $DIR/assoc-type-const-bound-usage-1.rs:20:42 - | -LL | fn qualified() -> Type<{ ::Assoc::func() }> { - | ^^^^^^^^^^^^^^^^^^^ the trait `Compat` is not implemented for `Trait::{synthetic#0}` - | -note: required by a bound in `Trait::func` - --> $DIR/assoc-type-const-bound-usage-1.rs:8:1 - | -LL | #[const_trait] - | ^^^^^^^^^^^^^^ required by this bound in `Trait::func` -... -LL | fn func() -> i32; - | ---- required by a bound in this associated function - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type.rs index b542ec4e5d0ae..348bf839b6995 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type.rs @@ -32,7 +32,8 @@ trait Foo { } impl const Foo for NonConstAdd { - type Bar = NonConstAdd; // FIXME(effects) ERROR the trait bound `NonConstAdd: ~const Add` is not satisfied + type Bar = NonConstAdd; + // FIXME(effects) ERROR the trait bound `NonConstAdd: ~const Add` is not satisfied } #[const_trait] From 8b2fac9612e3840f9736bed31502b3b91ba01a08 Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Tue, 25 Jun 2024 10:44:00 +0000 Subject: [PATCH 399/892] finishing touches, move fixed ICEs to ui tests --- .../src/solve/normalizes_to/mod.rs | 4 +- .../src/solve/trait_goals.rs | 4 +- .../ui/missing_const_for_fn/could_be_const.rs | 3 ++ .../could_be_const.stderr | 20 ++++++---- tests/crashes/119717.rs | 10 ----- tests/crashes/123664.rs | 4 -- tests/crashes/124857.rs | 11 ------ tests/crashes/126148.rs | 23 ----------- tests/rustdoc/rfc-2632-const-trait-impl.rs | 3 +- .../assoc-type-const-bound-usage-1.stderr | 8 ++-- .../assoc-type.stderr | 2 +- .../ice-119717-constant-lifetime.rs | 15 ++++++++ .../ice-119717-constant-lifetime.stderr | 33 ++++++++++++++++ .../ice-123664-unexpected-bound-var.rs | 7 ++++ .../ice-123664-unexpected-bound-var.stderr | 8 ++++ ...-124857-combine-effect-const-infer-vars.rs | 14 +++++++ ...857-combine-effect-const-infer-vars.stderr | 12 ++++++ .../ice-126148-failed-to-normalize.rs | 28 ++++++++++++++ .../ice-126148-failed-to-normalize.stderr | 38 +++++++++++++++++++ 19 files changed, 182 insertions(+), 65 deletions(-) delete mode 100644 tests/crashes/119717.rs delete mode 100644 tests/crashes/123664.rs delete mode 100644 tests/crashes/124857.rs delete mode 100644 tests/crashes/126148.rs create mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/ice-119717-constant-lifetime.rs create mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/ice-119717-constant-lifetime.stderr create mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/ice-123664-unexpected-bound-var.rs create mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/ice-123664-unexpected-bound-var.stderr create mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/ice-124857-combine-effect-const-infer-vars.rs create mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/ice-124857-combine-effect-const-infer-vars.stderr create mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/ice-126148-failed-to-normalize.rs create mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/ice-126148-failed-to-normalize.stderr diff --git a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs index 55c0440a53715..7a81c210c5d04 100644 --- a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs @@ -877,7 +877,7 @@ where let mut first_non_maybe = None; let mut non_maybe_count = 0; - for ty in types { + for ty in types.iter() { if !matches!(ty::EffectKind::try_from_ty(cx, ty), Some(ty::EffectKind::Maybe)) { first_non_maybe.get_or_insert(ty); non_maybe_count += 1; @@ -902,7 +902,7 @@ where _ => { let mut min = ty::EffectKind::Maybe; - for ty in types { + for ty in types.iter() { let Some(kind) = ty::EffectKind::try_from_ty(cx, ty) else { return Err(NoSolution); }; diff --git a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs index 73ae1c4b11359..08ed729b14405 100644 --- a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs +++ b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs @@ -717,7 +717,7 @@ where let cx = ecx.cx(); let maybe_count = types - .into_iter() + .iter() .filter_map(|ty| ty::EffectKind::try_from_ty(cx, ty)) .filter(|&ty| ty == ty::EffectKind::Maybe) .count(); @@ -727,7 +727,7 @@ where if types.len() - maybe_count > 1 { let mut min = ty::EffectKind::Maybe; - for ty in types { + for ty in types.iter() { let Some(kind) = ty::EffectKind::try_from_ty(ecx.cx(), ty) else { return Err(NoSolution); }; diff --git a/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.rs b/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.rs index 58e639cc7fd1f..5e4e2c58e5a4d 100644 --- a/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.rs +++ b/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.rs @@ -104,15 +104,18 @@ fn main() {} struct D; +/* FIXME(effects) impl const Drop for D { fn drop(&mut self) { todo!(); } } +*/ // Lint this, since it can be dropped in const contexts // FIXME(effects) fn d(this: D) {} +//~^ ERROR: this could be a `const fn` mod msrv { struct Foo(*const u8, &'static u8); diff --git a/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.stderr b/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.stderr index 8999af761e314..8ba42c0e5b673 100644 --- a/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.stderr +++ b/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.stderr @@ -157,7 +157,13 @@ LL | const fn msrv_1_46() -> i32 { | +++++ error: this could be a `const fn` - --> tests/ui/missing_const_for_fn/could_be_const.rs:122:9 + --> tests/ui/missing_const_for_fn/could_be_const.rs:117:1 + | +LL | fn d(this: D) {} + | ^^^^^^^^^^^^^^^^ + +error: this could be a `const fn` + --> tests/ui/missing_const_for_fn/could_be_const.rs:125:9 | LL | / fn deref_ptr_can_be_const(self) -> usize { LL | | @@ -171,7 +177,7 @@ LL | const fn deref_ptr_can_be_const(self) -> usize { | +++++ error: this could be a `const fn` - --> tests/ui/missing_const_for_fn/could_be_const.rs:127:9 + --> tests/ui/missing_const_for_fn/could_be_const.rs:130:9 | LL | / fn deref_copied_val(self) -> usize { LL | | @@ -185,7 +191,7 @@ LL | const fn deref_copied_val(self) -> usize { | +++++ error: this could be a `const fn` - --> tests/ui/missing_const_for_fn/could_be_const.rs:138:5 + --> tests/ui/missing_const_for_fn/could_be_const.rs:141:5 | LL | / fn union_access_can_be_const() { LL | | @@ -200,7 +206,7 @@ LL | const fn union_access_can_be_const() { | +++++ error: this could be a `const fn` - --> tests/ui/missing_const_for_fn/could_be_const.rs:152:9 + --> tests/ui/missing_const_for_fn/could_be_const.rs:155:9 | LL | / pub fn new(strings: Vec) -> Self { LL | | Self { strings } @@ -213,7 +219,7 @@ LL | pub const fn new(strings: Vec) -> Self { | +++++ error: this could be a `const fn` - --> tests/ui/missing_const_for_fn/could_be_const.rs:157:9 + --> tests/ui/missing_const_for_fn/could_be_const.rs:160:9 | LL | / pub fn empty() -> Self { LL | | Self { strings: Vec::new() } @@ -226,7 +232,7 @@ LL | pub const fn empty() -> Self { | +++++ error: this could be a `const fn` - --> tests/ui/missing_const_for_fn/could_be_const.rs:168:9 + --> tests/ui/missing_const_for_fn/could_be_const.rs:171:9 | LL | / pub fn new(text: String) -> Self { LL | | let vec = Vec::new(); @@ -239,5 +245,5 @@ help: make the function `const` LL | pub const fn new(text: String) -> Self { | +++++ -error: aborting due to 17 previous errors +error: aborting due to 18 previous errors diff --git a/tests/crashes/119717.rs b/tests/crashes/119717.rs deleted file mode 100644 index 22746548e02cb..0000000000000 --- a/tests/crashes/119717.rs +++ /dev/null @@ -1,10 +0,0 @@ -//@ known-bug: #119717 -#![feature(const_trait_impl, effects)] - -use std::ops::{FromResidual, Try}; - -impl const FromResidual for T { - fn from_residual(t: T) -> _ { - t - } -} diff --git a/tests/crashes/123664.rs b/tests/crashes/123664.rs deleted file mode 100644 index 80c415fe07bd7..0000000000000 --- a/tests/crashes/123664.rs +++ /dev/null @@ -1,4 +0,0 @@ -//@ known-bug: #123664 -#![feature(generic_const_exprs, effects)] -const fn with_positive() {} -pub fn main() {} diff --git a/tests/crashes/124857.rs b/tests/crashes/124857.rs deleted file mode 100644 index 4b952fd64ccfb..0000000000000 --- a/tests/crashes/124857.rs +++ /dev/null @@ -1,11 +0,0 @@ -//@ known-bug: rust-lang/rust#124857 -//@ compile-flags: -Znext-solver=coherence - -#![feature(effects)] - -#[const_trait] -trait Foo {} - -impl const Foo for i32 {} - -impl const Foo for T where T: ~const Foo {} diff --git a/tests/crashes/126148.rs b/tests/crashes/126148.rs deleted file mode 100644 index 79f8887b40154..0000000000000 --- a/tests/crashes/126148.rs +++ /dev/null @@ -1,23 +0,0 @@ -//@ known-bug: rust-lang/rust#126148 - -#![feature(effects)] -use std::ops::{FromResidual, Try}; - -struct TryMe; -struct Error; - -impl const FromResidual for TryMe {} - -impl const Try for TryMe { - type Output = (); - type Residual = Error; -} - -const fn t() -> TryMe { - TryMe?; - TryMe -} - -const _: () = { - t(); -}; diff --git a/tests/rustdoc/rfc-2632-const-trait-impl.rs b/tests/rustdoc/rfc-2632-const-trait-impl.rs index f6a5555dbadd0..eb3e00af3b0b5 100644 --- a/tests/rustdoc/rfc-2632-const-trait-impl.rs +++ b/tests/rustdoc/rfc-2632-const-trait-impl.rs @@ -8,7 +8,8 @@ // // FIXME(effects) add `const_trait` to `Fn` so we use `~const` // FIXME(effects) restore `const_trait` to `Destruct` -#![feature(const_trait_impl)] +#![allow(incomplete_features)] +#![feature(const_trait_impl, effects)] #![crate_name = "foo"] use std::marker::Destruct; diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-1.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-1.stderr index f8bab2d4c27fa..48855d64b58a1 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-1.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-1.stderr @@ -1,11 +1,11 @@ error[E0277]: the trait bound `Trait::{synthetic#0}: Compat` is not satisfied - --> $DIR/assoc-type-const-bound-usage-1.rs:16:44 + --> $DIR/assoc-type-const-bound-usage-1.rs:15:44 | LL | fn unqualified() -> Type<{ T::Assoc::func() }> { | ^^^^^^^^ the trait `Compat` is not implemented for `Trait::{synthetic#0}` | note: required by a bound in `Trait::func` - --> $DIR/assoc-type-const-bound-usage-1.rs:8:1 + --> $DIR/assoc-type-const-bound-usage-1.rs:7:1 | LL | #[const_trait] | ^^^^^^^^^^^^^^ required by this bound in `Trait::func` @@ -14,13 +14,13 @@ LL | fn func() -> i32; | ---- required by a bound in this associated function error[E0277]: the trait bound `Trait::{synthetic#0}: Compat` is not satisfied - --> $DIR/assoc-type-const-bound-usage-1.rs:20:42 + --> $DIR/assoc-type-const-bound-usage-1.rs:19:42 | LL | fn qualified() -> Type<{ ::Assoc::func() }> { | ^^^^^^^^^^^^^^^^^^^ the trait `Compat` is not implemented for `Trait::{synthetic#0}` | note: required by a bound in `Trait::func` - --> $DIR/assoc-type-const-bound-usage-1.rs:8:1 + --> $DIR/assoc-type-const-bound-usage-1.rs:7:1 | LL | #[const_trait] | ^^^^^^^^^^^^^^ required by this bound in `Trait::func` diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type.stderr index 333215adef217..1862339cddc5e 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type.stderr @@ -8,7 +8,7 @@ LL | #![feature(const_trait_impl, effects)] = note: `#[warn(incomplete_features)]` on by default error[E0277]: the trait bound `Add::{synthetic#0}: Compat` is not satisfied - --> $DIR/assoc-type.rs:40:15 + --> $DIR/assoc-type.rs:41:15 | LL | type Qux: Add; | ^^^ the trait `Compat` is not implemented for `Add::{synthetic#0}` diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-119717-constant-lifetime.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-119717-constant-lifetime.rs new file mode 100644 index 0000000000000..c2f452a9925c6 --- /dev/null +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-119717-constant-lifetime.rs @@ -0,0 +1,15 @@ +#![allow(incomplete_features)] +#![feature(const_trait_impl, effects, try_trait_v2)] + +use std::ops::FromResidual; + +impl const FromResidual for T { + //~^ ERROR const `impl` for trait `FromResidual` which is not marked with `#[const_trait]` + //~| type parameter `T` must be used as the type parameter for some local type + fn from_residual(t: T) -> _ { + //~^ the placeholder `_` is not allowed + t + } +} + +fn main() {} diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-119717-constant-lifetime.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-119717-constant-lifetime.stderr new file mode 100644 index 0000000000000..9e22422ad3b94 --- /dev/null +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-119717-constant-lifetime.stderr @@ -0,0 +1,33 @@ +error: const `impl` for trait `FromResidual` which is not marked with `#[const_trait]` + --> $DIR/ice-119717-constant-lifetime.rs:6:15 + | +LL | impl const FromResidual for T { + | ^^^^^^^^^^^^ + | + = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` + = note: adding a non-const method body in the future would be a breaking change + +error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct`) + --> $DIR/ice-119717-constant-lifetime.rs:6:6 + | +LL | impl const FromResidual for T { + | ^ type parameter `T` must be used as the type parameter for some local type + | + = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local + = note: only traits defined in the current crate can be implemented for a type parameter + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions + --> $DIR/ice-119717-constant-lifetime.rs:9:31 + | +LL | fn from_residual(t: T) -> _ { + | ^ not allowed in type signatures + | +help: try replacing `_` with the type in the corresponding trait method signature + | +LL | fn from_residual(t: T) -> T { + | ~ + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0121, E0210. +For more information about an error, try `rustc --explain E0121`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-123664-unexpected-bound-var.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-123664-unexpected-bound-var.rs new file mode 100644 index 0000000000000..64634e7b7ac30 --- /dev/null +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-123664-unexpected-bound-var.rs @@ -0,0 +1,7 @@ +#![allow(incomplete_features)] +#![feature(generic_const_exprs, const_trait_impl, effects)] + +const fn with_positive() {} +//~^ ERROR `~const` can only be applied to `#[const_trait]` traits + +pub fn main() {} diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-123664-unexpected-bound-var.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-123664-unexpected-bound-var.stderr new file mode 100644 index 0000000000000..19369e38964f4 --- /dev/null +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-123664-unexpected-bound-var.stderr @@ -0,0 +1,8 @@ +error: `~const` can only be applied to `#[const_trait]` traits + --> $DIR/ice-123664-unexpected-bound-var.rs:4:34 + | +LL | const fn with_positive() {} + | ^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-124857-combine-effect-const-infer-vars.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-124857-combine-effect-const-infer-vars.rs new file mode 100644 index 0000000000000..d4fcbfb1b83e6 --- /dev/null +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-124857-combine-effect-const-infer-vars.rs @@ -0,0 +1,14 @@ +//@ compile-flags: -Znext-solver=coherence + +#![allow(incomplete_features)] +#![feature(const_trait_impl, effects)] + +#[const_trait] +trait Foo {} + +impl const Foo for i32 {} + +impl const Foo for T where T: ~const Foo {} +//~^ ERROR conflicting implementations of trait `Foo` for type `i32` + +fn main() {} diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-124857-combine-effect-const-infer-vars.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-124857-combine-effect-const-infer-vars.stderr new file mode 100644 index 0000000000000..0b1f8b40898e3 --- /dev/null +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-124857-combine-effect-const-infer-vars.stderr @@ -0,0 +1,12 @@ +error[E0119]: conflicting implementations of trait `Foo` for type `i32` + --> $DIR/ice-124857-combine-effect-const-infer-vars.rs:11:1 + | +LL | impl const Foo for i32 {} + | ---------------------- first implementation here +LL | +LL | impl const Foo for T where T: ~const Foo {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `i32` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0119`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-126148-failed-to-normalize.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-126148-failed-to-normalize.rs new file mode 100644 index 0000000000000..717c0e7c08829 --- /dev/null +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-126148-failed-to-normalize.rs @@ -0,0 +1,28 @@ +#![allow(incomplete_features)] +#![feature(const_trait_impl, effects, try_trait_v2, const_try)] +use std::ops::{FromResidual, Try}; + +struct TryMe; +struct Error; + +impl const FromResidual for TryMe {} +//~^ ERROR const `impl` for trait `FromResidual` which is not marked with `#[const_trait]` +//~| ERROR not all trait items implemented + +impl const Try for TryMe { + //~^ ERROR const `impl` for trait `Try` which is not marked with `#[const_trait]` + //~| ERROR not all trait items implemented + type Output = (); + type Residual = Error; +} + +const fn t() -> TryMe { + TryMe?; + TryMe +} + +const _: () = { + t(); +}; + +fn main() {} diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-126148-failed-to-normalize.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-126148-failed-to-normalize.stderr new file mode 100644 index 0000000000000..e641b457ef9c8 --- /dev/null +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-126148-failed-to-normalize.stderr @@ -0,0 +1,38 @@ +error: const `impl` for trait `FromResidual` which is not marked with `#[const_trait]` + --> $DIR/ice-126148-failed-to-normalize.rs:8:12 + | +LL | impl const FromResidual for TryMe {} + | ^^^^^^^^^^^^^^^^^^^ + | + = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` + = note: adding a non-const method body in the future would be a breaking change + +error[E0046]: not all trait items implemented, missing: `from_residual` + --> $DIR/ice-126148-failed-to-normalize.rs:8:1 + | +LL | impl const FromResidual for TryMe {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `from_residual` in implementation + | + = help: implement the missing item: `fn from_residual(_: Error) -> Self { todo!() }` + +error: const `impl` for trait `Try` which is not marked with `#[const_trait]` + --> $DIR/ice-126148-failed-to-normalize.rs:12:12 + | +LL | impl const Try for TryMe { + | ^^^ + | + = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` + = note: adding a non-const method body in the future would be a breaking change + +error[E0046]: not all trait items implemented, missing: `from_output`, `branch` + --> $DIR/ice-126148-failed-to-normalize.rs:12:1 + | +LL | impl const Try for TryMe { + | ^^^^^^^^^^^^^^^^^^^^^^^^ missing `from_output`, `branch` in implementation + | + = help: implement the missing item: `fn from_output(_: ::Output) -> Self { todo!() }` + = help: implement the missing item: `fn branch(self) -> ControlFlow<::Residual, ::Output> { todo!() }` + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0046`. From cc05efe29e7184efa127d235d00be6ec2332d123 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 28 Jun 2024 11:50:15 +0000 Subject: [PATCH 400/892] Introduce UnwindModule wrapper around a Module and UnwindContext This way all UnwindContext::add_function calls can be done automatically in a single place. --- src/allocator.rs | 10 +--- src/base.rs | 3 -- src/common.rs | 2 - src/driver/aot.rs | 31 +++++------- src/driver/jit.rs | 50 ++++++------------- src/inline_asm.rs | 16 +----- src/lib.rs | 13 +---- src/main_shim.rs | 6 +-- src/unwind_module.rs | 115 +++++++++++++++++++++++++++++++++++++++++++ 9 files changed, 148 insertions(+), 98 deletions(-) create mode 100644 src/unwind_module.rs diff --git a/src/allocator.rs b/src/allocator.rs index e8af3e8c2555f..0d01cfd32395d 100644 --- a/src/allocator.rs +++ b/src/allocator.rs @@ -11,15 +11,10 @@ use rustc_session::config::OomStrategy; use crate::prelude::*; /// Returns whether an allocator shim was created -pub(crate) fn codegen( - tcx: TyCtxt<'_>, - module: &mut impl Module, - unwind_context: &mut UnwindContext, -) -> bool { +pub(crate) fn codegen(tcx: TyCtxt<'_>, module: &mut impl Module) -> bool { let Some(kind) = allocator_kind_for_codegen(tcx) else { return false }; codegen_inner( module, - unwind_context, kind, tcx.alloc_error_handler_kind(()).unwrap(), tcx.sess.opts.unstable_opts.oom, @@ -29,7 +24,6 @@ pub(crate) fn codegen( fn codegen_inner( module: &mut impl Module, - unwind_context: &mut UnwindContext, kind: AllocatorKind, alloc_error_handler_kind: AllocatorKind, oom_strategy: OomStrategy, @@ -67,7 +61,6 @@ fn codegen_inner( }; crate::common::create_wrapper_function( module, - unwind_context, sig, &global_fn_name(method.name), &default_fn_name(method.name), @@ -82,7 +75,6 @@ fn codegen_inner( }; crate::common::create_wrapper_function( module, - unwind_context, sig, "__rust_alloc_error_handler", &alloc_error_handler_name(alloc_error_handler_kind), diff --git a/src/base.rs b/src/base.rs index 6c7f75f41d5ff..c5b4277015a9e 100644 --- a/src/base.rs +++ b/src/base.rs @@ -249,9 +249,7 @@ pub(crate) fn compile_fn( } // Define debuginfo for function - let isa = module.isa(); let debug_context = &mut cx.debug_context; - let unwind_context = &mut cx.unwind_context; cx.profiler.generic_activity("generate debug info").run(|| { if let Some(debug_context) = debug_context { codegened_func.func_debug_cx.unwrap().finalize( @@ -260,7 +258,6 @@ pub(crate) fn compile_fn( context, ); } - unwind_context.add_function(codegened_func.func_id, &context, isa); }); } diff --git a/src/common.rs b/src/common.rs index 817498b195690..0931713993691 100644 --- a/src/common.rs +++ b/src/common.rs @@ -247,7 +247,6 @@ pub(crate) fn type_sign(ty: Ty<'_>) -> bool { pub(crate) fn create_wrapper_function( module: &mut dyn Module, - unwind_context: &mut UnwindContext, sig: Signature, wrapper_name: &str, callee_name: &str, @@ -280,7 +279,6 @@ pub(crate) fn create_wrapper_function( bcx.finalize(); } module.define_function(wrapper_func_id, &mut ctx).unwrap(); - unwind_context.add_function(wrapper_func_id, &ctx, module.isa()); } pub(crate) struct FunctionCx<'m, 'clif, 'tcx: 'm> { diff --git a/src/driver/aot.rs b/src/driver/aot.rs index dcafac21bc742..763d9a484077e 100644 --- a/src/driver/aot.rs +++ b/src/driver/aot.rs @@ -26,6 +26,7 @@ use rustc_session::Session; use crate::concurrency_limiter::{ConcurrencyLimiter, ConcurrencyLimiterToken}; use crate::debuginfo::TypeDebugContext; use crate::global_asm::GlobalAsmConfig; +use crate::unwind_module::UnwindModule; use crate::{prelude::*, BackendConfig}; struct ModuleCodegenResult { @@ -318,7 +319,11 @@ fn produce_final_output_artifacts( // These are used in linking steps and will be cleaned up afterward. } -fn make_module(sess: &Session, backend_config: &BackendConfig, name: String) -> ObjectModule { +fn make_module( + sess: &Session, + backend_config: &BackendConfig, + name: String, +) -> UnwindModule { let isa = crate::build_isa(sess, backend_config); let mut builder = @@ -327,16 +332,15 @@ fn make_module(sess: &Session, backend_config: &BackendConfig, name: String) -> // is important, while cg_clif cares more about compilation times. Enabling -Zfunction-sections // can easily double the amount of time necessary to perform linking. builder.per_function_section(sess.opts.unstable_opts.function_sections.unwrap_or(false)); - ObjectModule::new(builder) + UnwindModule::new(ObjectModule::new(builder), true) } fn emit_cgu( output_filenames: &OutputFilenames, prof: &SelfProfilerRef, name: String, - module: ObjectModule, + module: UnwindModule, debug: Option, - unwind_context: UnwindContext, global_asm_object_file: Option, producer: &str, ) -> Result { @@ -346,8 +350,6 @@ fn emit_cgu( debug.emit(&mut product); } - unwind_context.emit(&mut product); - let module_regular = emit_module( output_filenames, prof, @@ -494,7 +496,6 @@ fn module_codegen( let mut cx = crate::CodegenCx::new( tcx, - backend_config.clone(), module.isa(), tcx.sess.opts.debuginfo != DebugInfo::None, cgu_name, @@ -531,13 +532,7 @@ fn module_codegen( } } } - crate::main_shim::maybe_create_entry_wrapper( - tcx, - &mut module, - &mut cx.unwind_context, - false, - cgu.is_primary(), - ); + crate::main_shim::maybe_create_entry_wrapper(tcx, &mut module, false, cgu.is_primary()); let cgu_name = cgu.name().as_str().to_owned(); @@ -571,7 +566,6 @@ fn module_codegen( cgu_name, module, cx.debug_context, - cx.unwind_context, global_asm_object_file, &producer, ) @@ -665,13 +659,10 @@ pub(crate) fn run_aot( }); let mut allocator_module = make_module(tcx.sess, &backend_config, "allocator_shim".to_string()); - let mut allocator_unwind_context = UnwindContext::new(allocator_module.isa(), true); - let created_alloc_shim = - crate::allocator::codegen(tcx, &mut allocator_module, &mut allocator_unwind_context); + let created_alloc_shim = crate::allocator::codegen(tcx, &mut allocator_module); let allocator_module = if created_alloc_shim { - let mut product = allocator_module.finish(); - allocator_unwind_context.emit(&mut product); + let product = allocator_module.finish(); match emit_module( tcx.output_filenames(()), diff --git a/src/driver/jit.rs b/src/driver/jit.rs index ae0e45ae5312b..dfee8e714e64a 100644 --- a/src/driver/jit.rs +++ b/src/driver/jit.rs @@ -14,12 +14,12 @@ use rustc_session::Session; use rustc_span::Symbol; use crate::debuginfo::TypeDebugContext; +use crate::unwind_module::UnwindModule; use crate::{prelude::*, BackendConfig}; use crate::{CodegenCx, CodegenMode}; struct JitState { - backend_config: BackendConfig, - jit_module: JITModule, + jit_module: UnwindModule, } thread_local! { @@ -63,7 +63,7 @@ fn create_jit_module( tcx: TyCtxt<'_>, backend_config: &BackendConfig, hotswap: bool, -) -> (JITModule, CodegenCx) { +) -> (UnwindModule, CodegenCx) { let crate_info = CrateInfo::new(tcx, "dummy_target_cpu".to_string()); let isa = crate::build_isa(tcx.sess, backend_config); @@ -72,17 +72,11 @@ fn create_jit_module( crate::compiler_builtins::register_functions_for_jit(&mut jit_builder); jit_builder.symbol_lookup_fn(dep_symbol_lookup_fn(tcx.sess, crate_info)); jit_builder.symbol("__clif_jit_fn", clif_jit_fn as *const u8); - let mut jit_module = JITModule::new(jit_builder); + let mut jit_module = UnwindModule::new(JITModule::new(jit_builder), false); - let mut cx = crate::CodegenCx::new( - tcx, - backend_config.clone(), - jit_module.isa(), - false, - Symbol::intern("dummy_cgu_name"), - ); + let cx = crate::CodegenCx::new(tcx, jit_module.isa(), false, Symbol::intern("dummy_cgu_name")); - crate::allocator::codegen(tcx, &mut jit_module, &mut cx.unwind_context); + crate::allocator::codegen(tcx, &mut jit_module); (jit_module, cx) } @@ -128,7 +122,7 @@ pub(crate) fn run_jit(tcx: TyCtxt<'_>, backend_config: BackendConfig) -> ! { ); } CodegenMode::JitLazy => { - codegen_shim(tcx, &mut cx, &mut cached_context, &mut jit_module, inst) + codegen_shim(tcx, &mut cached_context, &mut jit_module, inst) } }, MonoItem::Static(def_id) => { @@ -146,18 +140,11 @@ pub(crate) fn run_jit(tcx: TyCtxt<'_>, backend_config: BackendConfig) -> ! { tcx.dcx().fatal("Inline asm is not supported in JIT mode"); } - crate::main_shim::maybe_create_entry_wrapper( - tcx, - &mut jit_module, - &mut cx.unwind_context, - true, - true, - ); + crate::main_shim::maybe_create_entry_wrapper(tcx, &mut jit_module, true, true); tcx.dcx().abort_if_errors(); - jit_module.finalize_definitions().unwrap(); - unsafe { cx.unwind_context.register_jit(&jit_module) }; + jit_module.finalize_definitions(); println!( "Rustc codegen cranelift will JIT run the executable, because -Cllvm-args=mode=jit was passed" @@ -177,12 +164,12 @@ pub(crate) fn run_jit(tcx: TyCtxt<'_>, backend_config: BackendConfig) -> ! { call_conv: jit_module.target_config().default_call_conv, }; let start_func_id = jit_module.declare_function("main", Linkage::Import, &start_sig).unwrap(); - let finalized_start: *const u8 = jit_module.get_finalized_function(start_func_id); + let finalized_start: *const u8 = jit_module.module.get_finalized_function(start_func_id); LAZY_JIT_STATE.with(|lazy_jit_state| { let mut lazy_jit_state = lazy_jit_state.borrow_mut(); assert!(lazy_jit_state.is_none()); - *lazy_jit_state = Some(JitState { backend_config, jit_module }); + *lazy_jit_state = Some(JitState { jit_module }); }); let f: extern "C" fn(c_int, *const *const c_char) -> c_int = @@ -268,7 +255,6 @@ fn jit_fn(instance_ptr: *const Instance<'static>, trampoline_ptr: *const u8) -> let mut lazy_jit_state = lazy_jit_state.borrow_mut(); let lazy_jit_state = lazy_jit_state.as_mut().unwrap(); let jit_module = &mut lazy_jit_state.jit_module; - let backend_config = lazy_jit_state.backend_config.clone(); let name = tcx.symbol_name(instance).name; let sig = crate::abi::get_function_sig( @@ -278,7 +264,7 @@ fn jit_fn(instance_ptr: *const Instance<'static>, trampoline_ptr: *const u8) -> ); let func_id = jit_module.declare_function(name, Linkage::Export, &sig).unwrap(); - let current_ptr = jit_module.read_got_entry(func_id); + let current_ptr = jit_module.module.read_got_entry(func_id); // If the function's GOT entry has already been updated to point at something other // than the shim trampoline, don't re-jit but just return the new pointer instead. @@ -288,11 +274,10 @@ fn jit_fn(instance_ptr: *const Instance<'static>, trampoline_ptr: *const u8) -> return current_ptr; } - jit_module.prepare_for_function_redefine(func_id).unwrap(); + jit_module.module.prepare_for_function_redefine(func_id).unwrap(); let mut cx = crate::CodegenCx::new( tcx, - backend_config, jit_module.isa(), false, Symbol::intern("dummy_cgu_name"), @@ -300,9 +285,8 @@ fn jit_fn(instance_ptr: *const Instance<'static>, trampoline_ptr: *const u8) -> codegen_and_compile_fn(tcx, &mut cx, &mut Context::new(), jit_module, instance); assert!(cx.global_asm.is_empty()); - jit_module.finalize_definitions().unwrap(); - unsafe { cx.unwind_context.register_jit(&jit_module) }; - jit_module.get_finalized_function(func_id) + jit_module.finalize_definitions(); + jit_module.module.get_finalized_function(func_id) }) }) } @@ -362,9 +346,8 @@ fn dep_symbol_lookup_fn( fn codegen_shim<'tcx>( tcx: TyCtxt<'tcx>, - cx: &mut CodegenCx, cached_context: &mut Context, - module: &mut JITModule, + module: &mut UnwindModule, inst: Instance<'tcx>, ) { let pointer_type = module.target_config().pointer_type(); @@ -413,5 +396,4 @@ fn codegen_shim<'tcx>( trampoline_builder.ins().return_(&ret_vals); module.define_function(func_id, context).unwrap(); - cx.unwind_context.add_function(func_id, context, module.isa()); } diff --git a/src/inline_asm.rs b/src/inline_asm.rs index c6b26dd873bdc..c88230c936056 100644 --- a/src/inline_asm.rs +++ b/src/inline_asm.rs @@ -113,13 +113,7 @@ pub(crate) fn codegen_inline_asm_terminator<'tcx>( ); let sig = get_function_sig(fx.tcx, fx.target_config.default_call_conv, instance); - create_wrapper_function( - fx.module, - &mut fx.cx.unwind_context, - sig, - &wrapper_name, - symbol.name, - ); + create_wrapper_function(fx.module, sig, &wrapper_name, symbol.name); CInlineAsmOperand::Symbol { symbol: wrapper_name } } else { @@ -283,13 +277,7 @@ pub(crate) fn codegen_naked_asm<'tcx>( ); let sig = get_function_sig(tcx, module.target_config().default_call_conv, instance); - create_wrapper_function( - module, - &mut cx.unwind_context, - sig, - &wrapper_name, - symbol.name, - ); + create_wrapper_function(module, sig, &wrapper_name, symbol.name); CInlineAsmOperand::Symbol { symbol: wrapper_name } } else { diff --git a/src/lib.rs b/src/lib.rs index 22c723e1a79b4..192e6c91ea38b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -79,6 +79,7 @@ mod pretty_clif; mod toolchain; mod trap; mod unsize; +mod unwind_module; mod value_and_place; mod vtable; @@ -130,22 +131,13 @@ struct CodegenCx { global_asm: String, inline_asm_index: Cell, debug_context: Option, - unwind_context: UnwindContext, cgu_name: Symbol, } impl CodegenCx { - fn new( - tcx: TyCtxt<'_>, - backend_config: BackendConfig, - isa: &dyn TargetIsa, - debug_info: bool, - cgu_name: Symbol, - ) -> Self { + fn new(tcx: TyCtxt<'_>, isa: &dyn TargetIsa, debug_info: bool, cgu_name: Symbol) -> Self { assert_eq!(pointer_ty(tcx), isa.pointer_type()); - let unwind_context = - UnwindContext::new(isa, matches!(backend_config.codegen_mode, CodegenMode::Aot)); let debug_context = if debug_info && !tcx.sess.target.options.is_like_windows { Some(DebugContext::new(tcx, isa, cgu_name.as_str())) } else { @@ -158,7 +150,6 @@ impl CodegenCx { global_asm: String::new(), inline_asm_index: Cell::new(0), debug_context, - unwind_context, cgu_name, } } diff --git a/src/main_shim.rs b/src/main_shim.rs index f9a729618a51a..3e85abde14ee5 100644 --- a/src/main_shim.rs +++ b/src/main_shim.rs @@ -12,7 +12,6 @@ use crate::prelude::*; pub(crate) fn maybe_create_entry_wrapper( tcx: TyCtxt<'_>, module: &mut impl Module, - unwind_context: &mut UnwindContext, is_jit: bool, is_primary_cgu: bool, ) { @@ -36,12 +35,11 @@ pub(crate) fn maybe_create_entry_wrapper( return; } - create_entry_fn(tcx, module, unwind_context, main_def_id, is_jit, is_main_fn, sigpipe); + create_entry_fn(tcx, module, main_def_id, is_jit, is_main_fn, sigpipe); fn create_entry_fn( tcx: TyCtxt<'_>, m: &mut impl Module, - unwind_context: &mut UnwindContext, rust_main_def_id: DefId, ignore_lang_start_wrapper: bool, is_main_fn: bool, @@ -170,7 +168,5 @@ pub(crate) fn maybe_create_entry_wrapper( if let Err(err) = m.define_function(cmain_func_id, &mut ctx) { tcx.dcx().fatal(format!("entry symbol `{entry_name}` defined multiple times: {err}")); } - - unwind_context.add_function(cmain_func_id, &ctx, m.isa()); } } diff --git a/src/unwind_module.rs b/src/unwind_module.rs new file mode 100644 index 0000000000000..b950aaa29ce04 --- /dev/null +++ b/src/unwind_module.rs @@ -0,0 +1,115 @@ +use cranelift_codegen::control::ControlPlane; +use cranelift_codegen::ir::{Function, Signature}; +use cranelift_codegen::isa::{TargetFrontendConfig, TargetIsa}; +use cranelift_codegen::{Context, FinalizedMachReloc}; +use cranelift_module::{ + DataDescription, DataId, FuncId, FuncOrDataId, Linkage, Module, ModuleDeclarations, + ModuleResult, +}; +use cranelift_object::{ObjectModule, ObjectProduct}; + +use crate::UnwindContext; + +/// A wrapper around a [Module] which adds any defined function to the [UnwindContext]. +pub(crate) struct UnwindModule { + pub(crate) module: T, + unwind_context: UnwindContext, +} + +impl UnwindModule { + pub(crate) fn new(module: T, pic_eh_frame: bool) -> Self { + let unwind_context = UnwindContext::new(module.isa(), pic_eh_frame); + UnwindModule { module, unwind_context } + } +} + +impl UnwindModule { + pub(crate) fn finish(self) -> ObjectProduct { + let mut product = self.module.finish(); + self.unwind_context.emit(&mut product); + product + } +} + +#[cfg(feature = "jit")] +impl UnwindModule { + pub(crate) fn finalize_definitions(&mut self) { + self.module.finalize_definitions().unwrap(); + let prev_unwind_context = std::mem::replace( + &mut self.unwind_context, + UnwindContext::new(self.module.isa(), false), + ); + unsafe { prev_unwind_context.register_jit(&self.module) }; + } +} + +impl Module for UnwindModule { + fn isa(&self) -> &dyn TargetIsa { + self.module.isa() + } + + fn declarations(&self) -> &ModuleDeclarations { + self.module.declarations() + } + + fn get_name(&self, name: &str) -> Option { + self.module.get_name(name) + } + + fn target_config(&self) -> TargetFrontendConfig { + self.module.target_config() + } + + fn declare_function( + &mut self, + name: &str, + linkage: Linkage, + signature: &Signature, + ) -> ModuleResult { + self.module.declare_function(name, linkage, signature) + } + + fn declare_anonymous_function(&mut self, signature: &Signature) -> ModuleResult { + self.module.declare_anonymous_function(signature) + } + + fn declare_data( + &mut self, + name: &str, + linkage: Linkage, + writable: bool, + tls: bool, + ) -> ModuleResult { + self.module.declare_data(name, linkage, writable, tls) + } + + fn declare_anonymous_data(&mut self, writable: bool, tls: bool) -> ModuleResult { + self.module.declare_anonymous_data(writable, tls) + } + + fn define_function_with_control_plane( + &mut self, + func: FuncId, + ctx: &mut Context, + ctrl_plane: &mut ControlPlane, + ) -> ModuleResult<()> { + self.module.define_function_with_control_plane(func, ctx, ctrl_plane)?; + self.unwind_context.add_function(func, ctx, self.module.isa()); + Ok(()) + } + + fn define_function_bytes( + &mut self, + _func_id: FuncId, + _func: &Function, + _alignment: u64, + _bytes: &[u8], + _relocs: &[FinalizedMachReloc], + ) -> ModuleResult<()> { + unimplemented!() + } + + fn define_data(&mut self, data_id: DataId, data: &DataDescription) -> ModuleResult<()> { + self.module.define_data(data_id, data) + } +} From e97cebb2b121038d5255257993b936c909f5cc05 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 28 Jun 2024 11:21:42 +0000 Subject: [PATCH 401/892] Use dyn Module instead of impl Module where possible --- src/allocator.rs | 4 ++-- src/main_shim.rs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/allocator.rs b/src/allocator.rs index 0d01cfd32395d..b4a3825e9965f 100644 --- a/src/allocator.rs +++ b/src/allocator.rs @@ -11,7 +11,7 @@ use rustc_session::config::OomStrategy; use crate::prelude::*; /// Returns whether an allocator shim was created -pub(crate) fn codegen(tcx: TyCtxt<'_>, module: &mut impl Module) -> bool { +pub(crate) fn codegen(tcx: TyCtxt<'_>, module: &mut dyn Module) -> bool { let Some(kind) = allocator_kind_for_codegen(tcx) else { return false }; codegen_inner( module, @@ -23,7 +23,7 @@ pub(crate) fn codegen(tcx: TyCtxt<'_>, module: &mut impl Module) -> bool { } fn codegen_inner( - module: &mut impl Module, + module: &mut dyn Module, kind: AllocatorKind, alloc_error_handler_kind: AllocatorKind, oom_strategy: OomStrategy, diff --git a/src/main_shim.rs b/src/main_shim.rs index 3e85abde14ee5..33d3f9b8a90a3 100644 --- a/src/main_shim.rs +++ b/src/main_shim.rs @@ -11,7 +11,7 @@ use crate::prelude::*; /// users main function. pub(crate) fn maybe_create_entry_wrapper( tcx: TyCtxt<'_>, - module: &mut impl Module, + module: &mut dyn Module, is_jit: bool, is_primary_cgu: bool, ) { @@ -39,7 +39,7 @@ pub(crate) fn maybe_create_entry_wrapper( fn create_entry_fn( tcx: TyCtxt<'_>, - m: &mut impl Module, + m: &mut dyn Module, rust_main_def_id: DefId, ignore_lang_start_wrapper: bool, is_main_fn: bool, From db243de8be050ce43e26de86018d5f45a101e863 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 28 Jun 2024 09:43:05 +0200 Subject: [PATCH 402/892] readme: tweak wording around soundness --- src/tools/miri/README.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/tools/miri/README.md b/src/tools/miri/README.md index 87b437a308034..b1be596c00679 100644 --- a/src/tools/miri/README.md +++ b/src/tools/miri/README.md @@ -72,11 +72,13 @@ Further caveats that Miri users should be aware of: when `SeqCst` fences are used that are not actually permitted by the Rust memory model, and it cannot produce all behaviors possibly observable on real hardware. -Moreover, Miri fundamentally cannot tell you whether your code is *sound*. [Soundness] is the property -of never causing undefined behavior when invoked from arbitrary safe code, even in combination with +Moreover, Miri fundamentally cannot ensure that your code is *sound*. [Soundness] is the property of +never causing undefined behavior when invoked from arbitrary safe code, even in combination with other sound code. In contrast, Miri can just tell you if *a particular way of interacting with your -code* (e.g., a test suite) causes any undefined behavior. It is up to you to ensure sufficient -coverage. +code* (e.g., a test suite) causes any undefined behavior *in a particular execution* (of which there +may be many, e.g. when concurrency or other forms of non-determinism are involved). When Miri finds +UB, your code is definitely unsound, but when Miri does not find UB, then you may just have to test +more inputs or more possible non-deterministic choices. [rust]: https://www.rust-lang.org/ [mir]: https://github.com/rust-lang/rfcs/blob/master/text/1211-mir.md From 90c2b238e6a38e3309a7ffc1162e6361db14ffdd Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 27 Jun 2024 19:54:28 -0400 Subject: [PATCH 403/892] Failing test for computing drop shim that has const param --- .../const-generics/polymorphic-drop-shim.rs | 21 ++ .../polymorphic-drop-shim.stderr | 257 ++++++++++++++++++ 2 files changed, 278 insertions(+) create mode 100644 tests/ui/const-generics/polymorphic-drop-shim.rs create mode 100644 tests/ui/const-generics/polymorphic-drop-shim.stderr diff --git a/tests/ui/const-generics/polymorphic-drop-shim.rs b/tests/ui/const-generics/polymorphic-drop-shim.rs new file mode 100644 index 0000000000000..97ade9fe69a30 --- /dev/null +++ b/tests/ui/const-generics/polymorphic-drop-shim.rs @@ -0,0 +1,21 @@ +//@ compile-flags: -Zinline-mir=yes --crate-type=lib + +//@ known-bug: unknown +//@ build-fail +//@ failure-status: 101 + +use std::mem::ManuallyDrop; + +pub struct Foo([T; N]); + +pub struct Dorp {} + +impl Drop for Dorp { + fn drop(&mut self) {} +} + +#[inline] +// SAFETY: call this with a valid allocation idk +pub unsafe fn drop(x: *mut Foo) { + std::ptr::drop_in_place(x); +} diff --git a/tests/ui/const-generics/polymorphic-drop-shim.stderr b/tests/ui/const-generics/polymorphic-drop-shim.stderr new file mode 100644 index 0000000000000..3a445a524097d --- /dev/null +++ b/tests/ui/const-generics/polymorphic-drop-shim.stderr @@ -0,0 +1,257 @@ +thread 'rustc' panicked at compiler/rustc_middle/src/ty/sty.rs:360:36: +called `Option::unwrap()` on a `None` value +stack backtrace: + 0: begin_panic_handler + at ./library/std/src/panicking.rs:661:5 + 1: panic_fmt + at ./library/core/src/panicking.rs:74:14 + 2: panic + at ./library/core/src/panicking.rs:148:5 + 3: core::option::unwrap_failed + at ./library/core/src/option.rs:2013:5 + 4: unwrap + at ./library/core/src/option.rs:963:21 + 5: find_ty_from_env + at ./compiler/rustc_middle/src/ty/sty.rs:360:18 + 6: {closure#0} + at ./compiler/rustc_trait_selection/src/traits/select/mod.rs:1016:29 + 7: maybe_grow, rustc_trait_selection::traits::select::{impl#1}::evaluate_predicate_recursively::{closure#0}::{closure_env#0}> + at /home/michael/.cargo/registry/src/index.crates.io-6f17d22bba15001f/stacker-0.1.15/src/lib.rs:55:9 + 8: ensure_sufficient_stack, rustc_trait_selection::traits::select::{impl#1}::evaluate_predicate_recursively::{closure#0}::{closure_env#0}> + at ./compiler/rustc_data_structures/src/stack.rs:17:5 + 9: {closure#0} + at ./compiler/rustc_trait_selection/src/traits/select/mod.rs:664:9 + 10: evaluate_predicate_recursively + at ./compiler/rustc_trait_selection/src/traits/select/mod.rs:643:5 + 11: evaluate_predicates_recursively, alloc::alloc::Global>> + at ./compiler/rustc_trait_selection/src/traits/select/mod.rs:631:24 + 12: {closure#0} + at ./compiler/rustc_trait_selection/src/traits/select/mod.rs:1317:21 + 13: {closure#0} + at ./compiler/rustc_trait_selection/src/traits/select/mod.rs:596:26 + 14: probe, rustc_trait_selection::traits::select::{impl#1}::evaluation_probe::{closure_env#0}> + at ./compiler/rustc_infer/src/infer/snapshot/mod.rs:85:17 + 15: ::evaluation_probe::<::evaluate_candidate::{closure#0}::{closure#0}> + at ./compiler/rustc_trait_selection/src/traits/select/mod.rs:594:9 + 16: {closure#0} + at ./compiler/rustc_trait_selection/src/traits/select/mod.rs:1298:26 + 17: evaluate_candidate + at ./compiler/rustc_trait_selection/src/traits/select/mod.rs:1286:5 + 18: evaluate_stack + at ./compiler/rustc_trait_selection/src/traits/select/mod.rs:1257:28 + 19: {closure#1} + at ./compiler/rustc_trait_selection/src/traits/select/mod.rs:1083:30 + 20: {closure#0}> + at ./compiler/rustc_trait_selection/src/traits/select/mod.rs:1445:88 + 21: with_anon_task>, core::result::Result> + at ./compiler/rustc_query_system/src/dep_graph/graph.rs:306:22 + 22: in_task> + at ./compiler/rustc_trait_selection/src/traits/select/mod.rs:1445:13 + 23: {closure#0} + at ./compiler/rustc_trait_selection/src/traits/select/mod.rs:1082:34 + 24: evaluate_trait_predicate_recursively + at ./compiler/rustc_trait_selection/src/traits/select/mod.rs:1037:5 + 25: {closure#0} + at ./compiler/rustc_trait_selection/src/traits/select/mod.rs:671:21 + 26: maybe_grow, rustc_trait_selection::traits::select::{impl#1}::evaluate_predicate_recursively::{closure#0}::{closure_env#0}> + at /home/michael/.cargo/registry/src/index.crates.io-6f17d22bba15001f/stacker-0.1.15/src/lib.rs:55:9 + 27: ensure_sufficient_stack, rustc_trait_selection::traits::select::{impl#1}::evaluate_predicate_recursively::{closure#0}::{closure_env#0}> + at ./compiler/rustc_data_structures/src/stack.rs:17:5 + 28: {closure#0} + at ./compiler/rustc_trait_selection/src/traits/select/mod.rs:664:9 + 29: evaluate_predicate_recursively + at ./compiler/rustc_trait_selection/src/traits/select/mod.rs:643:5 + 30: {closure#0} + at ./compiler/rustc_trait_selection/src/traits/select/mod.rs:572:30 + 31: {closure#0} + at ./compiler/rustc_trait_selection/src/traits/select/mod.rs:596:26 + 32: probe, rustc_trait_selection::traits::select::{impl#1}::evaluation_probe::{closure_env#0}> + at ./compiler/rustc_infer/src/infer/snapshot/mod.rs:85:17 + 33: evaluate_obligation + at ./compiler/rustc_traits/src/evaluate_obligation.rs:29:5 + 34: {closure#0} + at ./compiler/rustc_query_impl/src/plumbing.rs:281:9 + [... omitted 22 frames ...] + 35: query_get_at>, rustc_middle::query::erase::Erased<[u8; 2]>>> + at ./compiler/rustc_middle/src/query/plumbing.rs:145:17 + 36: evaluate_obligation + at ./compiler/rustc_middle/src/query/plumbing.rs:423:31 + 37: evaluate_obligation + at ./compiler/rustc_trait_selection/src/traits/query/evaluate_obligation.rs:93:13 + 38: evaluate_obligation_no_overflow + at ./compiler/rustc_trait_selection/src/traits/query/evaluate_obligation.rs:107:15 + 39: {closure#0}> + at ./compiler/rustc_trait_selection/src/traits/mod.rs:221:18 + 40: pred_known_to_hold_modulo_regions> + at ./compiler/rustc_trait_selection/src/traits/mod.rs:213:1 + 41: rustc_trait_selection::traits::type_known_to_meet_bound_modulo_regions + at ./compiler/rustc_trait_selection/src/traits/mod.rs:206:5 + 42: rustc_ty_utils::common_traits::is_item_raw + at ./compiler/rustc_ty_utils/src/common_traits.rs:33:5 + 43: {closure#0} + at ./compiler/rustc_query_impl/src/plumbing.rs:281:9 + [... omitted 22 frames ...] + 44: query_get_at, rustc_middle::query::erase::Erased<[u8; 1]>>> + at ./compiler/rustc_middle/src/query/plumbing.rs:145:17 + 45: is_copy_raw + at ./compiler/rustc_middle/src/query/plumbing.rs:423:31 + 46: is_copy_raw + at ./compiler/rustc_middle/src/query/plumbing.rs:414:17 + 47: is_copy_modulo_regions + at ./compiler/rustc_middle/src/ty/util.rs:1243:48 + 48: next, alloc::vec::into_iter::IntoIter> + at ./compiler/rustc_ty_utils/src/needs_drop.rs:184:26 + 49: try_fold>, (), core::iter::traits::iterator::Iterator::find::check::{closure_env#0}, &mut rustc_ty_utils::needs_drop::filter_array_elements::{closure_env#0}>, core::ops::control_flow::ControlFlow, ()>> + at ./library/core/src/iter/traits/iterator.rs:2409:29 + 50: find>, &mut rustc_ty_utils::needs_drop::filter_array_elements::{closure_env#0}> + at ./library/core/src/iter/traits/iterator.rs:2880:9 + 51: next>, rustc_ty_utils::needs_drop::filter_array_elements::{closure_env#0}> + at ./library/core/src/iter/adapters/filter.rs:96:9 + 52: needs_drop_raw + at ./compiler/rustc_ty_utils/src/needs_drop.rs:24:15 + 53: {closure#0} + at ./compiler/rustc_query_impl/src/plumbing.rs:281:9 + [... omitted 22 frames ...] + 54: query_get_at, rustc_middle::query::erase::Erased<[u8; 1]>>> + at ./compiler/rustc_middle/src/query/plumbing.rs:145:17 + 55: needs_drop_raw + at ./compiler/rustc_middle/src/query/plumbing.rs:423:31 + 56: needs_drop_raw + at ./compiler/rustc_middle/src/query/plumbing.rs:414:17 + 57: needs_drop + at ./compiler/rustc_middle/src/ty/util.rs:1433:17 + 58: {closure#0} + at ./compiler/rustc_mir_dataflow/src/elaborate_drops.rs:378:13 + 59: {closure#0}<(rustc_middle::mir::syntax::Place, core::option::Option<()>), alloc::alloc::Global, rustc_mir_dataflow::elaborate_drops::{impl#2}::drop_ladder::{closure_env#0}> + at ./library/alloc/src/vec/mod.rs:1683:32 + 60: process_loop), alloc::alloc::Global, rustc_mir_dataflow::elaborate_drops::{impl#2}::drop_ladder::{closure_env#0}>, (rustc_middle::mir::syntax::Place, core::option::Option<()>), alloc::alloc::Global, false> + at ./library/alloc/src/vec/mod.rs:1763:21 + 61: retain_mut<(rustc_middle::mir::syntax::Place, core::option::Option<()>), alloc::alloc::Global, alloc::vec::{impl#1}::retain::{closure_env#0}<(rustc_middle::mir::syntax::Place, core::option::Option<()>), alloc::alloc::Global, rustc_mir_dataflow::elaborate_drops::{impl#2}::drop_ladder::{closure_env#0}>> + at ./library/alloc/src/vec/mod.rs:1789:9 + 62: retain<(rustc_middle::mir::syntax::Place, core::option::Option<()>), alloc::alloc::Global, rustc_mir_dataflow::elaborate_drops::{impl#2}::drop_ladder::{closure_env#0}> + at ./library/alloc/src/vec/mod.rs:1683:9 + 63: drop_ladder + at ./compiler/rustc_mir_dataflow/src/elaborate_drops.rs:377:9 + 64: open_drop_for_adt_contents + at ./compiler/rustc_mir_dataflow/src/elaborate_drops.rs:488:13 + 65: {closure#0} + at ./compiler/rustc_mir_dataflow/src/elaborate_drops.rs:461:13 + 66: open_drop_for_adt + at ./compiler/rustc_mir_dataflow/src/elaborate_drops.rs:440:5 + 67: open_drop + at ./compiler/rustc_mir_dataflow/src/elaborate_drops.rs:869:35 + 68: elaborate_drop + at ./compiler/rustc_mir_dataflow/src/elaborate_drops.rs:253:31 + 69: rustc_mir_dataflow::elaborate_drops::elaborate_drop:: + at ./compiler/rustc_mir_dataflow/src/elaborate_drops.rs:192:5 + 70: build_drop_shim + at ./compiler/rustc_mir_transform/src/shim.rs:283:13 + 71: make_shim + at ./compiler/rustc_mir_transform/src/shim.rs:128:13 + 72: {closure#0} + at ./compiler/rustc_query_impl/src/plumbing.rs:281:9 + [... omitted 22 frames ...] + 73: query_get_at>> + at ./compiler/rustc_middle/src/query/plumbing.rs:145:17 + 74: mir_shims + at ./compiler/rustc_middle/src/query/plumbing.rs:423:31 + 75: mir_shims + at ./compiler/rustc_middle/src/query/plumbing.rs:414:17 + 76: instance_mir + at ./compiler/rustc_middle/src/ty/mod.rs:1738:62 + 77: try_instance_mir + at ./compiler/rustc_mir_transform/src/inline.rs:1082:8 + 78: try_inlining + at ./compiler/rustc_mir_transform/src/inline.rs:194:27 + 79: process_blocks + at ./compiler/rustc_mir_transform/src/inline.rs:139:19 + 80: inline + at ./compiler/rustc_mir_transform/src/inline.rs:97:5 + 81: run_pass + at ./compiler/rustc_mir_transform/src/inline.rs:62:12 + 82: run_passes_inner + at ./compiler/rustc_mir_transform/src/pass_manager.rs:144:17 + 83: rustc_mir_transform::pass_manager::run_passes + at ./compiler/rustc_mir_transform/src/pass_manager.rs:87:5 + 84: run_optimization_passes + at ./compiler/rustc_mir_transform/src/lib.rs:561:5 + 85: inner_optimized_mir + at ./compiler/rustc_mir_transform/src/lib.rs:667:5 + 86: optimized_mir + at ./compiler/rustc_mir_transform/src/lib.rs:630:21 + 87: {closure#0} + at ./compiler/rustc_query_impl/src/plumbing.rs:285:13 + [... omitted 22 frames ...] + 88: query_get_at>> + at ./compiler/rustc_middle/src/query/plumbing.rs:145:17 + 89: optimized_mir + at ./compiler/rustc_middle/src/query/plumbing.rs:423:31 + 90: optimized_mir + at ./compiler/rustc_middle/src/query/plumbing.rs:414:17 + 91: encode_mir + at ./compiler/rustc_metadata/src/rmeta/encoder.rs:1656:74 + 92: {closure#15} + at ./compiler/rustc_metadata/src/rmeta/encoder.rs:639:29 + 93: encode_crate_root + at ./compiler/rustc_metadata/src/rmeta/encoder.rs:600:27 + 94: encode_metadata + at ./compiler/rustc_metadata/src/rmeta/encoder.rs:2269:16 + 95: encode_and_write_metadata + at ./compiler/rustc_metadata/src/fs.rs:65:13 + 96: start_codegen + at ./compiler/rustc_interface/src/passes.rs:1024:44 + 97: {closure#0} + at ./compiler/rustc_interface/src/queries.rs:122:35 + 98: {closure#1}> + at ./compiler/rustc_middle/src/ty/context.rs:1288:37 + 99: {closure#0}>, core::result::Result> + at ./compiler/rustc_middle/src/ty/context/tls.rs:82:9 + 100: try_with, rustc_middle::ty::context::tls::enter_context::{closure_env#0}>, core::result::Result>, core::result::Result> + at ./library/std/src/thread/local.rs:283:12 + 101: with, rustc_middle::ty::context::tls::enter_context::{closure_env#0}>, core::result::Result>, core::result::Result> + at ./library/std/src/thread/local.rs:260:9 + 102: enter_context>, core::result::Result> + at ./compiler/rustc_middle/src/ty/context/tls.rs:79:5 + 103: enter> + at ./compiler/rustc_middle/src/ty/context.rs:1288:9 + 104: >::enter::, ::codegen_and_build_linker::{closure#0}> + at ./compiler/rustc_interface/src/queries.rs:64:9 + 105: codegen_and_build_linker + at ./compiler/rustc_interface/src/queries.rs:121:9 + 106: {closure#1} + at ./compiler/rustc_driver_impl/src/lib.rs:451:26 + 107: enter, rustc_span::ErrorGuaranteed>> + at ./compiler/rustc_interface/src/queries.rs:202:19 + 108: {closure#0} + at ./compiler/rustc_driver_impl/src/lib.rs:389:22 + 109: {closure#1}, rustc_driver_impl::run_compiler::{closure_env#0}> + at ./compiler/rustc_interface/src/interface.rs:502:27 + 110: {closure#0}, rustc_driver_impl::run_compiler::{closure_env#0}>, core::result::Result<(), rustc_span::ErrorGuaranteed>> + at ./compiler/rustc_interface/src/util.rs:154:13 + 111: {closure#0}, rustc_driver_impl::run_compiler::{closure_env#0}>, core::result::Result<(), rustc_span::ErrorGuaranteed>>, core::result::Result<(), rustc_span::ErrorGuaranteed>> + at ./compiler/rustc_interface/src/util.rs:106:21 + 112: set, rustc_driver_impl::run_compiler::{closure_env#0}>, core::result::Result<(), rustc_span::ErrorGuaranteed>>, core::result::Result<(), rustc_span::ErrorGuaranteed>>, core::result::Result<(), rustc_span::ErrorGuaranteed>> + at /home/michael/.cargo/registry/src/index.crates.io-6f17d22bba15001f/scoped-tls-1.0.1/src/lib.rs:137:9 + 113: create_session_globals_then, rustc_interface::util::run_in_thread_with_globals::{closure#0}::{closure#0}::{closure_env#0}, rustc_driver_impl::run_compiler::{closure_env#0}>, core::result::Result<(), rustc_span::ErrorGuaranteed>>, core::result::Result<(), rustc_span::ErrorGuaranteed>>> + at ./compiler/rustc_span/src/lib.rs:134:5 + 114: {closure#0}, rustc_driver_impl::run_compiler::{closure_env#0}>, core::result::Result<(), rustc_span::ErrorGuaranteed>>, core::result::Result<(), rustc_span::ErrorGuaranteed>> + at ./compiler/rustc_interface/src/util.rs:105:17 +note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace. + +error: the compiler unexpectedly panicked. this is a bug. + +note: we would appreciate a bug report: https://github.com/rust-lang/rust/issues/new?labels=C-bug%2C+I-ICE%2C+T-compiler&template=ice.md + +note: please make sure that you have updated to the latest nightly + +note: rustc 1.81.0-dev running on x86_64-unknown-linux-gnu + +note: compiler flags: -Z threads=1 -Z simulate-remapped-rust-src-base=/rustc/FAKE_PREFIX -Z translate-remapped-path-to-local-path=no -Z ignore-directory-in-diagnostics-source-blocks=/home/michael/.cargo -Z ignore-directory-in-diagnostics-source-blocks=/home/michael/programming/rust2/vendor -C codegen-units=1 -Z ui-testing -Z deduplicate-diagnostics=no -Z write-long-types-to-disk=no -C strip=debuginfo -C prefer-dynamic -C rpath -C debuginfo=0 -Z inline-mir=yes --crate-type lib + +query stack during panic: +#0 [evaluate_obligation] evaluating trait selection obligation `[Dorp; M]: core::marker::Copy` +#1 [is_copy_raw] computing whether `[Dorp; M]` is `Copy` +#2 [needs_drop_raw] computing whether `[Dorp; M]` needs drop +#3 [mir_shims] generating MIR shim for `core::ptr::drop_in_place` +#4 [optimized_mir] optimizing MIR for `drop` +end of query stack From f17b27b3014adea0c40df55b31bd2fbbd72e76c4 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 28 Jun 2024 10:18:13 -0400 Subject: [PATCH 404/892] Don't inline drop shims with unsubstituted generic consts in MIR inliner --- compiler/rustc_mir_transform/src/inline.rs | 12 +- .../const-generics/polymorphic-drop-shim.rs | 5 +- .../polymorphic-drop-shim.stderr | 257 ------------------ 3 files changed, 12 insertions(+), 262 deletions(-) delete mode 100644 tests/ui/const-generics/polymorphic-drop-shim.stderr diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs index 0a5fc697d0321..07482d0571a2f 100644 --- a/compiler/rustc_mir_transform/src/inline.rs +++ b/compiler/rustc_mir_transform/src/inline.rs @@ -11,7 +11,7 @@ use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs} use rustc_middle::mir::visit::*; use rustc_middle::mir::*; use rustc_middle::ty::TypeVisitableExt; -use rustc_middle::ty::{self, Instance, InstanceKind, ParamEnv, Ty, TyCtxt}; +use rustc_middle::ty::{self, Instance, InstanceKind, ParamEnv, Ty, TyCtxt, TypeFlags}; use rustc_session::config::{DebugInfo, OptLevel}; use rustc_span::source_map::Spanned; use rustc_span::sym; @@ -306,6 +306,16 @@ impl<'tcx> Inliner<'tcx> { InstanceKind::Intrinsic(_) | InstanceKind::Virtual(..) => { return Err("instance without MIR (intrinsic / virtual)"); } + + // FIXME(#127030): `ConstParamHasTy` has bad interactions with + // the drop shim builder, which does not evaluate predicates in + // the correct param-env for types being dropped. Stall resolving + // the MIR for this instance until all of its const params are + // substituted. + InstanceKind::DropGlue(_, Some(ty)) if ty.has_type_flags(TypeFlags::HAS_CT_PARAM) => { + return Err("still needs substitution"); + } + // This cannot result in an immediate cycle since the callee MIR is a shim, which does // not get any optimizations run on it. Any subsequent inlining may cause cycles, but we // do not need to catch this here, we can wait until the inliner decides to continue diff --git a/tests/ui/const-generics/polymorphic-drop-shim.rs b/tests/ui/const-generics/polymorphic-drop-shim.rs index 97ade9fe69a30..4ca2e86cff915 100644 --- a/tests/ui/const-generics/polymorphic-drop-shim.rs +++ b/tests/ui/const-generics/polymorphic-drop-shim.rs @@ -1,8 +1,5 @@ //@ compile-flags: -Zinline-mir=yes --crate-type=lib - -//@ known-bug: unknown -//@ build-fail -//@ failure-status: 101 +//@ build-pass use std::mem::ManuallyDrop; diff --git a/tests/ui/const-generics/polymorphic-drop-shim.stderr b/tests/ui/const-generics/polymorphic-drop-shim.stderr deleted file mode 100644 index 3a445a524097d..0000000000000 --- a/tests/ui/const-generics/polymorphic-drop-shim.stderr +++ /dev/null @@ -1,257 +0,0 @@ -thread 'rustc' panicked at compiler/rustc_middle/src/ty/sty.rs:360:36: -called `Option::unwrap()` on a `None` value -stack backtrace: - 0: begin_panic_handler - at ./library/std/src/panicking.rs:661:5 - 1: panic_fmt - at ./library/core/src/panicking.rs:74:14 - 2: panic - at ./library/core/src/panicking.rs:148:5 - 3: core::option::unwrap_failed - at ./library/core/src/option.rs:2013:5 - 4: unwrap - at ./library/core/src/option.rs:963:21 - 5: find_ty_from_env - at ./compiler/rustc_middle/src/ty/sty.rs:360:18 - 6: {closure#0} - at ./compiler/rustc_trait_selection/src/traits/select/mod.rs:1016:29 - 7: maybe_grow, rustc_trait_selection::traits::select::{impl#1}::evaluate_predicate_recursively::{closure#0}::{closure_env#0}> - at /home/michael/.cargo/registry/src/index.crates.io-6f17d22bba15001f/stacker-0.1.15/src/lib.rs:55:9 - 8: ensure_sufficient_stack, rustc_trait_selection::traits::select::{impl#1}::evaluate_predicate_recursively::{closure#0}::{closure_env#0}> - at ./compiler/rustc_data_structures/src/stack.rs:17:5 - 9: {closure#0} - at ./compiler/rustc_trait_selection/src/traits/select/mod.rs:664:9 - 10: evaluate_predicate_recursively - at ./compiler/rustc_trait_selection/src/traits/select/mod.rs:643:5 - 11: evaluate_predicates_recursively, alloc::alloc::Global>> - at ./compiler/rustc_trait_selection/src/traits/select/mod.rs:631:24 - 12: {closure#0} - at ./compiler/rustc_trait_selection/src/traits/select/mod.rs:1317:21 - 13: {closure#0} - at ./compiler/rustc_trait_selection/src/traits/select/mod.rs:596:26 - 14: probe, rustc_trait_selection::traits::select::{impl#1}::evaluation_probe::{closure_env#0}> - at ./compiler/rustc_infer/src/infer/snapshot/mod.rs:85:17 - 15: ::evaluation_probe::<::evaluate_candidate::{closure#0}::{closure#0}> - at ./compiler/rustc_trait_selection/src/traits/select/mod.rs:594:9 - 16: {closure#0} - at ./compiler/rustc_trait_selection/src/traits/select/mod.rs:1298:26 - 17: evaluate_candidate - at ./compiler/rustc_trait_selection/src/traits/select/mod.rs:1286:5 - 18: evaluate_stack - at ./compiler/rustc_trait_selection/src/traits/select/mod.rs:1257:28 - 19: {closure#1} - at ./compiler/rustc_trait_selection/src/traits/select/mod.rs:1083:30 - 20: {closure#0}> - at ./compiler/rustc_trait_selection/src/traits/select/mod.rs:1445:88 - 21: with_anon_task>, core::result::Result> - at ./compiler/rustc_query_system/src/dep_graph/graph.rs:306:22 - 22: in_task> - at ./compiler/rustc_trait_selection/src/traits/select/mod.rs:1445:13 - 23: {closure#0} - at ./compiler/rustc_trait_selection/src/traits/select/mod.rs:1082:34 - 24: evaluate_trait_predicate_recursively - at ./compiler/rustc_trait_selection/src/traits/select/mod.rs:1037:5 - 25: {closure#0} - at ./compiler/rustc_trait_selection/src/traits/select/mod.rs:671:21 - 26: maybe_grow, rustc_trait_selection::traits::select::{impl#1}::evaluate_predicate_recursively::{closure#0}::{closure_env#0}> - at /home/michael/.cargo/registry/src/index.crates.io-6f17d22bba15001f/stacker-0.1.15/src/lib.rs:55:9 - 27: ensure_sufficient_stack, rustc_trait_selection::traits::select::{impl#1}::evaluate_predicate_recursively::{closure#0}::{closure_env#0}> - at ./compiler/rustc_data_structures/src/stack.rs:17:5 - 28: {closure#0} - at ./compiler/rustc_trait_selection/src/traits/select/mod.rs:664:9 - 29: evaluate_predicate_recursively - at ./compiler/rustc_trait_selection/src/traits/select/mod.rs:643:5 - 30: {closure#0} - at ./compiler/rustc_trait_selection/src/traits/select/mod.rs:572:30 - 31: {closure#0} - at ./compiler/rustc_trait_selection/src/traits/select/mod.rs:596:26 - 32: probe, rustc_trait_selection::traits::select::{impl#1}::evaluation_probe::{closure_env#0}> - at ./compiler/rustc_infer/src/infer/snapshot/mod.rs:85:17 - 33: evaluate_obligation - at ./compiler/rustc_traits/src/evaluate_obligation.rs:29:5 - 34: {closure#0} - at ./compiler/rustc_query_impl/src/plumbing.rs:281:9 - [... omitted 22 frames ...] - 35: query_get_at>, rustc_middle::query::erase::Erased<[u8; 2]>>> - at ./compiler/rustc_middle/src/query/plumbing.rs:145:17 - 36: evaluate_obligation - at ./compiler/rustc_middle/src/query/plumbing.rs:423:31 - 37: evaluate_obligation - at ./compiler/rustc_trait_selection/src/traits/query/evaluate_obligation.rs:93:13 - 38: evaluate_obligation_no_overflow - at ./compiler/rustc_trait_selection/src/traits/query/evaluate_obligation.rs:107:15 - 39: {closure#0}> - at ./compiler/rustc_trait_selection/src/traits/mod.rs:221:18 - 40: pred_known_to_hold_modulo_regions> - at ./compiler/rustc_trait_selection/src/traits/mod.rs:213:1 - 41: rustc_trait_selection::traits::type_known_to_meet_bound_modulo_regions - at ./compiler/rustc_trait_selection/src/traits/mod.rs:206:5 - 42: rustc_ty_utils::common_traits::is_item_raw - at ./compiler/rustc_ty_utils/src/common_traits.rs:33:5 - 43: {closure#0} - at ./compiler/rustc_query_impl/src/plumbing.rs:281:9 - [... omitted 22 frames ...] - 44: query_get_at, rustc_middle::query::erase::Erased<[u8; 1]>>> - at ./compiler/rustc_middle/src/query/plumbing.rs:145:17 - 45: is_copy_raw - at ./compiler/rustc_middle/src/query/plumbing.rs:423:31 - 46: is_copy_raw - at ./compiler/rustc_middle/src/query/plumbing.rs:414:17 - 47: is_copy_modulo_regions - at ./compiler/rustc_middle/src/ty/util.rs:1243:48 - 48: next, alloc::vec::into_iter::IntoIter> - at ./compiler/rustc_ty_utils/src/needs_drop.rs:184:26 - 49: try_fold>, (), core::iter::traits::iterator::Iterator::find::check::{closure_env#0}, &mut rustc_ty_utils::needs_drop::filter_array_elements::{closure_env#0}>, core::ops::control_flow::ControlFlow, ()>> - at ./library/core/src/iter/traits/iterator.rs:2409:29 - 50: find>, &mut rustc_ty_utils::needs_drop::filter_array_elements::{closure_env#0}> - at ./library/core/src/iter/traits/iterator.rs:2880:9 - 51: next>, rustc_ty_utils::needs_drop::filter_array_elements::{closure_env#0}> - at ./library/core/src/iter/adapters/filter.rs:96:9 - 52: needs_drop_raw - at ./compiler/rustc_ty_utils/src/needs_drop.rs:24:15 - 53: {closure#0} - at ./compiler/rustc_query_impl/src/plumbing.rs:281:9 - [... omitted 22 frames ...] - 54: query_get_at, rustc_middle::query::erase::Erased<[u8; 1]>>> - at ./compiler/rustc_middle/src/query/plumbing.rs:145:17 - 55: needs_drop_raw - at ./compiler/rustc_middle/src/query/plumbing.rs:423:31 - 56: needs_drop_raw - at ./compiler/rustc_middle/src/query/plumbing.rs:414:17 - 57: needs_drop - at ./compiler/rustc_middle/src/ty/util.rs:1433:17 - 58: {closure#0} - at ./compiler/rustc_mir_dataflow/src/elaborate_drops.rs:378:13 - 59: {closure#0}<(rustc_middle::mir::syntax::Place, core::option::Option<()>), alloc::alloc::Global, rustc_mir_dataflow::elaborate_drops::{impl#2}::drop_ladder::{closure_env#0}> - at ./library/alloc/src/vec/mod.rs:1683:32 - 60: process_loop), alloc::alloc::Global, rustc_mir_dataflow::elaborate_drops::{impl#2}::drop_ladder::{closure_env#0}>, (rustc_middle::mir::syntax::Place, core::option::Option<()>), alloc::alloc::Global, false> - at ./library/alloc/src/vec/mod.rs:1763:21 - 61: retain_mut<(rustc_middle::mir::syntax::Place, core::option::Option<()>), alloc::alloc::Global, alloc::vec::{impl#1}::retain::{closure_env#0}<(rustc_middle::mir::syntax::Place, core::option::Option<()>), alloc::alloc::Global, rustc_mir_dataflow::elaborate_drops::{impl#2}::drop_ladder::{closure_env#0}>> - at ./library/alloc/src/vec/mod.rs:1789:9 - 62: retain<(rustc_middle::mir::syntax::Place, core::option::Option<()>), alloc::alloc::Global, rustc_mir_dataflow::elaborate_drops::{impl#2}::drop_ladder::{closure_env#0}> - at ./library/alloc/src/vec/mod.rs:1683:9 - 63: drop_ladder - at ./compiler/rustc_mir_dataflow/src/elaborate_drops.rs:377:9 - 64: open_drop_for_adt_contents - at ./compiler/rustc_mir_dataflow/src/elaborate_drops.rs:488:13 - 65: {closure#0} - at ./compiler/rustc_mir_dataflow/src/elaborate_drops.rs:461:13 - 66: open_drop_for_adt - at ./compiler/rustc_mir_dataflow/src/elaborate_drops.rs:440:5 - 67: open_drop - at ./compiler/rustc_mir_dataflow/src/elaborate_drops.rs:869:35 - 68: elaborate_drop - at ./compiler/rustc_mir_dataflow/src/elaborate_drops.rs:253:31 - 69: rustc_mir_dataflow::elaborate_drops::elaborate_drop:: - at ./compiler/rustc_mir_dataflow/src/elaborate_drops.rs:192:5 - 70: build_drop_shim - at ./compiler/rustc_mir_transform/src/shim.rs:283:13 - 71: make_shim - at ./compiler/rustc_mir_transform/src/shim.rs:128:13 - 72: {closure#0} - at ./compiler/rustc_query_impl/src/plumbing.rs:281:9 - [... omitted 22 frames ...] - 73: query_get_at>> - at ./compiler/rustc_middle/src/query/plumbing.rs:145:17 - 74: mir_shims - at ./compiler/rustc_middle/src/query/plumbing.rs:423:31 - 75: mir_shims - at ./compiler/rustc_middle/src/query/plumbing.rs:414:17 - 76: instance_mir - at ./compiler/rustc_middle/src/ty/mod.rs:1738:62 - 77: try_instance_mir - at ./compiler/rustc_mir_transform/src/inline.rs:1082:8 - 78: try_inlining - at ./compiler/rustc_mir_transform/src/inline.rs:194:27 - 79: process_blocks - at ./compiler/rustc_mir_transform/src/inline.rs:139:19 - 80: inline - at ./compiler/rustc_mir_transform/src/inline.rs:97:5 - 81: run_pass - at ./compiler/rustc_mir_transform/src/inline.rs:62:12 - 82: run_passes_inner - at ./compiler/rustc_mir_transform/src/pass_manager.rs:144:17 - 83: rustc_mir_transform::pass_manager::run_passes - at ./compiler/rustc_mir_transform/src/pass_manager.rs:87:5 - 84: run_optimization_passes - at ./compiler/rustc_mir_transform/src/lib.rs:561:5 - 85: inner_optimized_mir - at ./compiler/rustc_mir_transform/src/lib.rs:667:5 - 86: optimized_mir - at ./compiler/rustc_mir_transform/src/lib.rs:630:21 - 87: {closure#0} - at ./compiler/rustc_query_impl/src/plumbing.rs:285:13 - [... omitted 22 frames ...] - 88: query_get_at>> - at ./compiler/rustc_middle/src/query/plumbing.rs:145:17 - 89: optimized_mir - at ./compiler/rustc_middle/src/query/plumbing.rs:423:31 - 90: optimized_mir - at ./compiler/rustc_middle/src/query/plumbing.rs:414:17 - 91: encode_mir - at ./compiler/rustc_metadata/src/rmeta/encoder.rs:1656:74 - 92: {closure#15} - at ./compiler/rustc_metadata/src/rmeta/encoder.rs:639:29 - 93: encode_crate_root - at ./compiler/rustc_metadata/src/rmeta/encoder.rs:600:27 - 94: encode_metadata - at ./compiler/rustc_metadata/src/rmeta/encoder.rs:2269:16 - 95: encode_and_write_metadata - at ./compiler/rustc_metadata/src/fs.rs:65:13 - 96: start_codegen - at ./compiler/rustc_interface/src/passes.rs:1024:44 - 97: {closure#0} - at ./compiler/rustc_interface/src/queries.rs:122:35 - 98: {closure#1}> - at ./compiler/rustc_middle/src/ty/context.rs:1288:37 - 99: {closure#0}>, core::result::Result> - at ./compiler/rustc_middle/src/ty/context/tls.rs:82:9 - 100: try_with, rustc_middle::ty::context::tls::enter_context::{closure_env#0}>, core::result::Result>, core::result::Result> - at ./library/std/src/thread/local.rs:283:12 - 101: with, rustc_middle::ty::context::tls::enter_context::{closure_env#0}>, core::result::Result>, core::result::Result> - at ./library/std/src/thread/local.rs:260:9 - 102: enter_context>, core::result::Result> - at ./compiler/rustc_middle/src/ty/context/tls.rs:79:5 - 103: enter> - at ./compiler/rustc_middle/src/ty/context.rs:1288:9 - 104: >::enter::, ::codegen_and_build_linker::{closure#0}> - at ./compiler/rustc_interface/src/queries.rs:64:9 - 105: codegen_and_build_linker - at ./compiler/rustc_interface/src/queries.rs:121:9 - 106: {closure#1} - at ./compiler/rustc_driver_impl/src/lib.rs:451:26 - 107: enter, rustc_span::ErrorGuaranteed>> - at ./compiler/rustc_interface/src/queries.rs:202:19 - 108: {closure#0} - at ./compiler/rustc_driver_impl/src/lib.rs:389:22 - 109: {closure#1}, rustc_driver_impl::run_compiler::{closure_env#0}> - at ./compiler/rustc_interface/src/interface.rs:502:27 - 110: {closure#0}, rustc_driver_impl::run_compiler::{closure_env#0}>, core::result::Result<(), rustc_span::ErrorGuaranteed>> - at ./compiler/rustc_interface/src/util.rs:154:13 - 111: {closure#0}, rustc_driver_impl::run_compiler::{closure_env#0}>, core::result::Result<(), rustc_span::ErrorGuaranteed>>, core::result::Result<(), rustc_span::ErrorGuaranteed>> - at ./compiler/rustc_interface/src/util.rs:106:21 - 112: set, rustc_driver_impl::run_compiler::{closure_env#0}>, core::result::Result<(), rustc_span::ErrorGuaranteed>>, core::result::Result<(), rustc_span::ErrorGuaranteed>>, core::result::Result<(), rustc_span::ErrorGuaranteed>> - at /home/michael/.cargo/registry/src/index.crates.io-6f17d22bba15001f/scoped-tls-1.0.1/src/lib.rs:137:9 - 113: create_session_globals_then, rustc_interface::util::run_in_thread_with_globals::{closure#0}::{closure#0}::{closure_env#0}, rustc_driver_impl::run_compiler::{closure_env#0}>, core::result::Result<(), rustc_span::ErrorGuaranteed>>, core::result::Result<(), rustc_span::ErrorGuaranteed>>> - at ./compiler/rustc_span/src/lib.rs:134:5 - 114: {closure#0}, rustc_driver_impl::run_compiler::{closure_env#0}>, core::result::Result<(), rustc_span::ErrorGuaranteed>>, core::result::Result<(), rustc_span::ErrorGuaranteed>> - at ./compiler/rustc_interface/src/util.rs:105:17 -note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace. - -error: the compiler unexpectedly panicked. this is a bug. - -note: we would appreciate a bug report: https://github.com/rust-lang/rust/issues/new?labels=C-bug%2C+I-ICE%2C+T-compiler&template=ice.md - -note: please make sure that you have updated to the latest nightly - -note: rustc 1.81.0-dev running on x86_64-unknown-linux-gnu - -note: compiler flags: -Z threads=1 -Z simulate-remapped-rust-src-base=/rustc/FAKE_PREFIX -Z translate-remapped-path-to-local-path=no -Z ignore-directory-in-diagnostics-source-blocks=/home/michael/.cargo -Z ignore-directory-in-diagnostics-source-blocks=/home/michael/programming/rust2/vendor -C codegen-units=1 -Z ui-testing -Z deduplicate-diagnostics=no -Z write-long-types-to-disk=no -C strip=debuginfo -C prefer-dynamic -C rpath -C debuginfo=0 -Z inline-mir=yes --crate-type lib - -query stack during panic: -#0 [evaluate_obligation] evaluating trait selection obligation `[Dorp; M]: core::marker::Copy` -#1 [is_copy_raw] computing whether `[Dorp; M]` is `Copy` -#2 [needs_drop_raw] computing whether `[Dorp; M]` needs drop -#3 [mir_shims] generating MIR shim for `core::ptr::drop_in_place` -#4 [optimized_mir] optimizing MIR for `drop` -end of query stack From eb9292327612fda86d0e34528a5cf4045688d002 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sat, 20 Apr 2024 18:14:19 -0400 Subject: [PATCH 405/892] Bump elided_lifetimes_in_associated_constant --- compiler/rustc_lint_defs/src/builtin.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index 472e93d202d76..504707bb5a1a6 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -4617,7 +4617,7 @@ declare_lint! { /// [against]: https://github.com/rust-lang/rust/issues/38831 /// [future-incompatible]: ../index.md#future-incompatible-lints pub ELIDED_LIFETIMES_IN_ASSOCIATED_CONSTANT, - Warn, + Deny, "elided lifetimes cannot be used in associated constants in impls", @future_incompatible = FutureIncompatibleInfo { reason: FutureIncompatibilityReason::FutureReleaseErrorDontReportInDeps, From c7ac9bb30910227b95eb9fb7dc8d0a31b78bdbfe Mon Sep 17 00:00:00 2001 From: WANG Xuerui Date: Fri, 28 Jun 2024 15:57:14 +0800 Subject: [PATCH 406/892] Enable full tools and profiler for dist-loongarch64-{linux,musl} When the LoongArch targets were first introduced, the LLVM support was still immature and various tools were not supported on LoongArch. Nowadays most infra is in place, so it is time to enable them on LoongArch to provide a better experience for users of these targets. Plus, the profiler support is needed by Chromium, so better provide it in the official artifacts. --- .../docker/host-x86_64/dist-loongarch64-linux/Dockerfile | 7 ++++++- src/ci/docker/host-x86_64/dist-loongarch64-musl/Dockerfile | 3 ++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/ci/docker/host-x86_64/dist-loongarch64-linux/Dockerfile b/src/ci/docker/host-x86_64/dist-loongarch64-linux/Dockerfile index 55c737bd0aa31..7e35f781b6bb8 100644 --- a/src/ci/docker/host-x86_64/dist-loongarch64-linux/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-loongarch64-linux/Dockerfile @@ -25,5 +25,10 @@ ENV CC_loongarch64_unknown_linux_gnu=loongarch64-unknown-linux-gnu-gcc \ ENV HOSTS=loongarch64-unknown-linux-gnu -ENV RUST_CONFIGURE_ARGS --enable-extended --disable-docs +ENV RUST_CONFIGURE_ARGS \ + --enable-extended \ + --enable-full-tools \ + --enable-profiler \ + --disable-docs + ENV SCRIPT python3 ../x.py dist --host $HOSTS --target $HOSTS diff --git a/src/ci/docker/host-x86_64/dist-loongarch64-musl/Dockerfile b/src/ci/docker/host-x86_64/dist-loongarch64-musl/Dockerfile index 560adf971ba48..62dbfaaa67315 100644 --- a/src/ci/docker/host-x86_64/dist-loongarch64-musl/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-loongarch64-musl/Dockerfile @@ -27,7 +27,8 @@ ENV HOSTS=loongarch64-unknown-linux-musl ENV RUST_CONFIGURE_ARGS \ --enable-extended \ - --enable-lld \ + --enable-full-tools \ + --enable-profiler \ --disable-docs \ --set target.loongarch64-unknown-linux-musl.crt-static=false \ --musl-root-loongarch64=/x-tools/loongarch64-unknown-linux-musl/loongarch64-unknown-linux-musl/sysroot/usr From acb6078d9183c41e39495ff075cd01b3d68fe967 Mon Sep 17 00:00:00 2001 From: Oneirical Date: Thu, 20 Jun 2024 11:21:56 -0400 Subject: [PATCH 407/892] rewrite remap-path-prefix to rmake --- src/tools/run-make-support/src/rustc.rs | 11 +++++ tests/run-make/remap-path-prefix/Makefile | 30 ------------ tests/run-make/remap-path-prefix/rmake.rs | 58 +++++++++++++++++++++++ 3 files changed, 69 insertions(+), 30 deletions(-) delete mode 100644 tests/run-make/remap-path-prefix/Makefile create mode 100644 tests/run-make/remap-path-prefix/rmake.rs diff --git a/src/tools/run-make-support/src/rustc.rs b/src/tools/run-make-support/src/rustc.rs index 28ece1dff128d..df843d74fc927 100644 --- a/src/tools/run-make-support/src/rustc.rs +++ b/src/tools/run-make-support/src/rustc.rs @@ -106,6 +106,17 @@ impl Rustc { self } + /// Remap source path prefixes in all output. + pub fn remap_path_prefix>(&mut self, from: P, to: P) -> &mut Self { + let from = from.as_ref().to_string_lossy(); + let to = to.as_ref().to_string_lossy(); + + self.cmd.arg("--remap-path-prefix"); + self.cmd.arg(format!("{from}={to}")); + + self + } + /// Specify path to the input file. pub fn input>(&mut self, path: P) -> &mut Self { self.cmd.arg(path.as_ref()); diff --git a/tests/run-make/remap-path-prefix/Makefile b/tests/run-make/remap-path-prefix/Makefile deleted file mode 100644 index 02423dea7d26c..0000000000000 --- a/tests/run-make/remap-path-prefix/Makefile +++ /dev/null @@ -1,30 +0,0 @@ -include ../tools.mk - -# ignore-windows - -ifeq ($(UNAME),Darwin) - DEBUGINFOOPTS := -Csplit-debuginfo=off -else - DEBUGINFOOPTS := -endif - -all: remap remap-with-scope - -# Checks if remapping works if the remap-from string contains path to the working directory plus more -remap: - $(RUSTC) --remap-path-prefix $$PWD/auxiliary=/the/aux --crate-type=lib --emit=metadata auxiliary/lib.rs - grep "/the/aux/lib.rs" $(TMPDIR)/liblib.rmeta || exit 1 - ! grep "$$PWD/auxiliary" $(TMPDIR)/liblib.rmeta || exit 1 - -remap-with-scope: - $(RUSTC) --remap-path-prefix $$PWD/auxiliary=/the/aux -Zremap-path-scope=object $(DEBUGINFOOPTS) --crate-type=lib --emit=metadata auxiliary/lib.rs - grep "/the/aux/lib.rs" $(TMPDIR)/liblib.rmeta || exit 1 - ! grep "$$PWD/auxiliary" $(TMPDIR)/liblib.rmeta || exit 1 - - $(RUSTC) --remap-path-prefix $$PWD/auxiliary=/the/aux -Zremap-path-scope=macro $(DEBUGINFOOPTS) --crate-type=lib --emit=metadata auxiliary/lib.rs - grep "/the/aux/lib.rs" $(TMPDIR)/liblib.rmeta || exit 1 - ! grep "$$PWD/auxiliary" $(TMPDIR)/liblib.rmeta || exit 1 - - $(RUSTC) --remap-path-prefix $$PWD/auxiliary=/the/aux -Zremap-path-scope=diagnostics,object $(DEBUGINFOOPTS) --crate-type=lib --emit=metadata auxiliary/lib.rs - grep "/the/aux/lib.rs" $(TMPDIR)/liblib.rmeta || exit 1 - ! grep "$$PWD/auxiliary" $(TMPDIR)/liblib.rmeta || exit 1 diff --git a/tests/run-make/remap-path-prefix/rmake.rs b/tests/run-make/remap-path-prefix/rmake.rs new file mode 100644 index 0000000000000..4d98dcf6131cd --- /dev/null +++ b/tests/run-make/remap-path-prefix/rmake.rs @@ -0,0 +1,58 @@ +// Generating metadata alongside remap-path-prefix would fail to actually remap the path +// in the metadata. After this was fixed in #85344, this test checks that "auxiliary" is being +// successfully remapped to "/the/aux" in the rmeta files. +// See https://github.com/rust-lang/rust/pull/85344 + +// FIXME(Oneirical): check if works without ignore-windows + +use run_make_support::{invalid_utf8_contains, invalid_utf8_not_contains, is_darwin, rustc}; + +fn main() { + let mut out_simple = rustc(); + let mut out_object = rustc(); + let mut out_macro = rustc(); + let mut out_diagobj = rustc(); + out_simple + .remap_path_prefix("auxiliary", "/the/aux") + .crate_type("lib") + .emit("metadata") + .input("auxiliary/lib.rs"); + out_object + .remap_path_prefix("auxiliary", "/the/aux") + .crate_type("lib") + .emit("metadata") + .input("auxiliary/lib.rs"); + out_macro + .remap_path_prefix("auxiliary", "/the/aux") + .crate_type("lib") + .emit("metadata") + .input("auxiliary/lib.rs"); + out_diagobj + .remap_path_prefix("auxiliary", "/the/aux") + .crate_type("lib") + .emit("metadata") + .input("auxiliary/lib.rs"); + + out_simple.run(); + invalid_utf8_contains("liblib.rmeta", "/the/aux/lib.rs"); + invalid_utf8_not_contains("liblib.rmeta", "auxiliary"); + + out_object.arg("-Zremap-path-scope=object"); + out_macro.arg("-Zremap-path-scope=macro"); + out_diagobj.arg("-Zremap-path-scope=diagnostics,object"); + if is_darwin() { + out_object.arg("-Csplit-debuginfo=off"); + out_macro.arg("-Csplit-debuginfo=off"); + out_diagobj.arg("-Csplit-debuginfo=off"); + } + + out_object.run(); + invalid_utf8_contains("liblib.rmeta", "/the/aux/lib.rs"); + invalid_utf8_not_contains("liblib.rmeta", "auxiliary"); + out_macro.run(); + invalid_utf8_contains("liblib.rmeta", "/the/aux/lib.rs"); + invalid_utf8_not_contains("liblib.rmeta", "auxiliary"); + out_diagobj.run(); + invalid_utf8_contains("liblib.rmeta", "/the/aux/lib.rs"); + invalid_utf8_not_contains("liblib.rmeta", "auxiliary"); +} From cb1281b76d4d90fd66bd76507e583c69625e037d Mon Sep 17 00:00:00 2001 From: Oneirical Date: Fri, 21 Jun 2024 13:35:47 -0400 Subject: [PATCH 408/892] rewrite debug-assertions to rmake --- .../tidy/src/allowed_run_make_makefiles.txt | 1 - tests/run-make/debug-assertions/Makefile | 27 -------------- tests/run-make/debug-assertions/debug.rs | 9 ++--- tests/run-make/debug-assertions/rmake.rs | 37 +++++++++++++++++++ 4 files changed, 40 insertions(+), 34 deletions(-) delete mode 100644 tests/run-make/debug-assertions/Makefile create mode 100644 tests/run-make/debug-assertions/rmake.rs diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index 2bc3acc58cb22..6199dce7d9830 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -18,7 +18,6 @@ run-make/cross-lang-lto-clang/Makefile run-make/cross-lang-lto-pgo-smoketest/Makefile run-make/cross-lang-lto-upstream-rlibs/Makefile run-make/cross-lang-lto/Makefile -run-make/debug-assertions/Makefile run-make/dep-info-doesnt-run-much/Makefile run-make/dep-info-spaces/Makefile run-make/dep-info/Makefile diff --git a/tests/run-make/debug-assertions/Makefile b/tests/run-make/debug-assertions/Makefile deleted file mode 100644 index 4501459e9d1d8..0000000000000 --- a/tests/run-make/debug-assertions/Makefile +++ /dev/null @@ -1,27 +0,0 @@ -# ignore-cross-compile -# needs-unwind -include ../tools.mk - -all: - $(RUSTC) debug.rs -C debug-assertions=no - $(call RUN,debug) good - $(RUSTC) debug.rs -C opt-level=0 - $(call RUN,debug) bad - $(RUSTC) debug.rs -C opt-level=1 - $(call RUN,debug) good - $(RUSTC) debug.rs -C opt-level=2 - $(call RUN,debug) good - $(RUSTC) debug.rs -C opt-level=3 - $(call RUN,debug) good - $(RUSTC) debug.rs -C opt-level=s - $(call RUN,debug) good - $(RUSTC) debug.rs -C opt-level=z - $(call RUN,debug) good - $(RUSTC) debug.rs -O - $(call RUN,debug) good - $(RUSTC) debug.rs - $(call RUN,debug) bad - $(RUSTC) debug.rs -C debug-assertions=yes -O - $(call RUN,debug) bad - $(RUSTC) debug.rs -C debug-assertions=yes -C opt-level=1 - $(call RUN,debug) bad diff --git a/tests/run-make/debug-assertions/debug.rs b/tests/run-make/debug-assertions/debug.rs index 9eebf60ded09b..c6e4bddc34c75 100644 --- a/tests/run-make/debug-assertions/debug.rs +++ b/tests/run-make/debug-assertions/debug.rs @@ -1,15 +1,12 @@ #![feature(rustc_attrs)] #![deny(warnings)] -use std::env; use std::thread; fn main() { - let should_fail = env::args().nth(1) == Some("bad".to_string()); - - assert_eq!(thread::spawn(debug_assert_eq).join().is_err(), should_fail); - assert_eq!(thread::spawn(debug_assert).join().is_err(), should_fail); - assert_eq!(thread::spawn(overflow).join().is_err(), should_fail); + assert!(thread::spawn(debug_assert_eq).join().is_ok()); + assert!(thread::spawn(debug_assert).join().is_ok()); + assert!(thread::spawn(overflow).join().is_ok()); } fn debug_assert_eq() { diff --git a/tests/run-make/debug-assertions/rmake.rs b/tests/run-make/debug-assertions/rmake.rs new file mode 100644 index 0000000000000..ba8be9488a8d8 --- /dev/null +++ b/tests/run-make/debug-assertions/rmake.rs @@ -0,0 +1,37 @@ +// debug.rs contains some "debug assertion" statements which +// should only be enabled in either non-optimized builds or when +// `-C debug-assertions` is set to yes. These debug assertions +// are guaranteed to fail, so this test checks that the run command +// fails where debug assertions should be activated, and succeeds where +// debug assertions should be disabled. +// See https://github.com/rust-lang/rust/pull/22980 + +//@ ignore-cross-compile +//@ needs-unwind + +use run_make_support::{run, run_fail, rustc}; + +fn main() { + rustc().input("debug.rs").arg("-Cdebug-assertions=no").run(); + run("debug"); + rustc().input("debug.rs").opt_level("0").run(); + run_fail("debug"); + rustc().input("debug.rs").opt_level("1").run(); + run("debug"); + rustc().input("debug.rs").opt_level("2").run(); + run("debug"); + rustc().input("debug.rs").opt_level("3").run(); + run("debug"); + rustc().input("debug.rs").opt_level("s").run(); + run("debug"); + rustc().input("debug.rs").opt_level("z").run(); + run("debug"); + rustc().input("debug.rs").opt().run(); + run("debug"); + rustc().input("debug.rs").run(); + run_fail("debug"); + rustc().input("debug.rs").opt().arg("-Cdebug-assertions=yes").run(); + run_fail("debug"); + rustc().input("debug.rs").opt_level("1").arg("-Cdebug-assertions=yes").run(); + run_fail("debug"); +} From 133b47ab3837baf7d1a7f9f03a7166c137667797 Mon Sep 17 00:00:00 2001 From: Oneirical Date: Fri, 21 Jun 2024 15:05:54 -0400 Subject: [PATCH 409/892] rewrite emit-stack-sizes to rmake --- .../tidy/src/allowed_run_make_makefiles.txt | 2 -- tests/run-make/debug-assertions/debug.rs | 1 + tests/run-make/emit-stack-sizes/Makefile | 12 ---------- tests/run-make/emit-stack-sizes/rmake.rs | 23 +++++++++++++++++++ 4 files changed, 24 insertions(+), 14 deletions(-) delete mode 100644 tests/run-make/emit-stack-sizes/Makefile create mode 100644 tests/run-make/emit-stack-sizes/rmake.rs diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index 6199dce7d9830..f6c091ee4129e 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -26,7 +26,6 @@ run-make/dump-mono-stats/Makefile run-make/dylib-chain/Makefile run-make/emit-path-unhashed/Makefile run-make/emit-shared-files/Makefile -run-make/emit-stack-sizes/Makefile run-make/emit-to-stdout/Makefile run-make/env-dep-info/Makefile run-make/export-executable-symbols/Makefile @@ -147,7 +146,6 @@ run-make/raw-dylib-link-ordinal/Makefile run-make/raw-dylib-stdcall-ordinal/Makefile run-make/redundant-libs/Makefile run-make/remap-path-prefix-dwarf/Makefile -run-make/remap-path-prefix/Makefile run-make/reproducible-build-2/Makefile run-make/reproducible-build/Makefile run-make/return-non-c-like-enum-from-c/Makefile diff --git a/tests/run-make/debug-assertions/debug.rs b/tests/run-make/debug-assertions/debug.rs index c6e4bddc34c75..1f27c04a16d45 100644 --- a/tests/run-make/debug-assertions/debug.rs +++ b/tests/run-make/debug-assertions/debug.rs @@ -1,3 +1,4 @@ +#![allow(internal_features)] #![feature(rustc_attrs)] #![deny(warnings)] diff --git a/tests/run-make/emit-stack-sizes/Makefile b/tests/run-make/emit-stack-sizes/Makefile deleted file mode 100644 index b546fcba5121e..0000000000000 --- a/tests/run-make/emit-stack-sizes/Makefile +++ /dev/null @@ -1,12 +0,0 @@ -include ../tools.mk - -# ignore-windows -# ignore-apple -# -# This feature only works when the output object format is ELF so we ignore -# Apple and Windows - -# check that the .stack_sizes section is generated -all: - $(RUSTC) -C opt-level=3 -Z emit-stack-sizes --emit=obj foo.rs - size -A $(TMPDIR)/foo.o | $(CGREP) .stack_sizes diff --git a/tests/run-make/emit-stack-sizes/rmake.rs b/tests/run-make/emit-stack-sizes/rmake.rs new file mode 100644 index 0000000000000..53cc9ee5943f8 --- /dev/null +++ b/tests/run-make/emit-stack-sizes/rmake.rs @@ -0,0 +1,23 @@ +// Running rustc with the -Z emit-stack-sizes +// flag enables diagnostics to seek stack overflows +// at compile time. This test compiles a rust file +// with this flag, then checks that the output object +// file contains the section "stack_sizes", where +// this diagnostics information should be located. +// See https://github.com/rust-lang/rust/pull/51946 + +//@ ignore-windows +//@ ignore-apple +// Reason: this feature only works when the output object format is ELF. +// This won't be the case on Windows/OSX - for example, OSX produces a Mach-O binary. + +use run_make_support::{llvm_readobj, rustc}; + +fn main() { + rustc().opt_level("3").arg("-Zemit-stack-sizes").emit("obj").input("foo.rs").run(); + llvm_readobj() + .arg("--section-headers") + .input("foo.o") + .run() + .assert_stdout_contains(".stack_sizes"); +} From 65a0bee0b77bad05c1bf29bd2dd855e554a9eaf5 Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Wed, 26 Jun 2024 16:36:42 +0000 Subject: [PATCH 410/892] address review comments --- compiler/rustc_hir/src/lang_items.rs | 4 +- compiler/rustc_hir_analysis/src/bounds.rs | 52 +++++----- .../src/collect/item_bounds.rs | 2 +- compiler/rustc_middle/src/ty/context.rs | 4 +- .../src/solve/assembly/mod.rs | 6 +- .../src/solve/normalizes_to/mod.rs | 8 +- .../src/solve/trait_goals.rs | 4 +- compiler/rustc_span/src/symbol.rs | 4 +- compiler/rustc_ty_utils/src/assoc.rs | 99 +++++++------------ compiler/rustc_type_ir/src/effects.rs | 5 +- compiler/rustc_type_ir/src/lang_items.rs | 4 +- library/core/src/marker.rs | 11 ++- .../missing_const_for_fn/could_be_const.fixed | 5 +- .../could_be_const.stderr | 5 + .../const-fns-are-early-bound.rs | 6 +- .../super-traits-fail.rs | 1 + .../rfc-2632-const-trait-impl/super-traits.rs | 2 + .../super-traits.stderr | 15 +-- 18 files changed, 113 insertions(+), 124 deletions(-) diff --git a/compiler/rustc_hir/src/lang_items.rs b/compiler/rustc_hir/src/lang_items.rs index d49eb4ece99f8..3c44acb16577a 100644 --- a/compiler/rustc_hir/src/lang_items.rs +++ b/compiler/rustc_hir/src/lang_items.rs @@ -397,8 +397,8 @@ language_item_table! { EffectsRuntime, sym::EffectsRuntime, effects_runtime, Target::Struct, GenericRequirement::None; EffectsNoRuntime, sym::EffectsNoRuntime, effects_no_runtime, Target::Struct, GenericRequirement::None; EffectsMaybe, sym::EffectsMaybe, effects_maybe, Target::Struct, GenericRequirement::None; - EffectsMin, sym::EffectsMin, effects_min, Target::Trait, GenericRequirement::None; - EffectsMinOutput, sym::EffectsMinOutput, effects_min_output, Target::AssocTy, GenericRequirement::None; + EffectsIntersection, sym::EffectsIntersection, effects_intersection, Target::Trait, GenericRequirement::None; + EffectsIntersectionOutput, sym::EffectsIntersectionOutput, effects_intersection_output, Target::AssocTy, GenericRequirement::None; EffectsCompat, sym::EffectsCompat, effects_compat, Target::Trait, GenericRequirement::Exact(1); EffectsTyCompat, sym::EffectsTyCompat, effects_ty_compat, Target::Trait, GenericRequirement::Exact(1); } diff --git a/compiler/rustc_hir_analysis/src/bounds.rs b/compiler/rustc_hir_analysis/src/bounds.rs index 61b7dd8bb8c34..c7ee89e73c273 100644 --- a/compiler/rustc_hir_analysis/src/bounds.rs +++ b/compiler/rustc_hir_analysis/src/bounds.rs @@ -71,16 +71,19 @@ impl<'tcx> Bounds<'tcx> { } // For `T: ~const Tr` or `T: const Tr`, we need to add an additional bound on the // associated type of `` and make sure that the effect is compatible. - if let Some(compat_val) = match (tcx.def_kind(defining_def_id), constness) { + let compat_val = match (tcx.def_kind(defining_def_id), constness) { // FIXME(effects): revisit the correctness of this - (_, ty::BoundConstness::Const) => Some(tcx.consts.false_), + (_, ty::BoundConstness::Const) => tcx.consts.false_, // body owners that can have trait bounds (DefKind::Const | DefKind::Fn | DefKind::AssocFn, ty::BoundConstness::ConstIfConst) => { - Some(tcx.expected_host_effect_param_for_body(defining_def_id)) + tcx.expected_host_effect_param_for_body(defining_def_id) } (_, ty::BoundConstness::NotConst) => { - tcx.has_attr(bound_trait_ref.def_id(), sym::const_trait).then_some(tcx.consts.true_) + if !tcx.has_attr(bound_trait_ref.def_id(), sym::const_trait) { + return; + } + tcx.consts.true_ } ( @@ -97,8 +100,12 @@ impl<'tcx> Bounds<'tcx> { let ty = bound_trait_ref .map_bound(|trait_ref| Ty::new_projection(tcx, assoc, trait_ref.args)); - // Replace the binder with dummy types/lifetimes. This should work for any - // binder as long as they don't have any bounds e.g. `for`. + // When the user has written `for<'a, T> X<'a, T>: ~const Foo`, replace the + // binders to dummy ones i.e. `X<'static, ()>` so they can be referenced in + // the `Min` associated type properly (which doesn't allow using `for<>`) + // This should work for any bound variables as long as they don't have any + // bounds e.g. `for`. + // FIXME(effects) reconsider this approach to allow compatibility with `for` let ty = tcx.replace_bound_vars_uncached( ty, FnMutDelegate { @@ -128,24 +135,23 @@ impl<'tcx> Bounds<'tcx> { tcx.dcx().span_delayed_bug(span, "invalid `~const` encountered"); return; } - } { - // create a new projection type `::Effects` - let Some(assoc) = tcx.associated_type_for_effects(bound_trait_ref.def_id()) else { - tcx.dcx().span_delayed_bug( - span, - "`~const` trait bound has no effect assoc yet no errors encountered?", - ); - return; - }; - let self_ty = Ty::new_projection(tcx, assoc, bound_trait_ref.skip_binder().args); - // make `::Effects: Compat` - let new_trait_ref = ty::TraitRef::new( - tcx, - tcx.require_lang_item(LangItem::EffectsCompat, Some(span)), - [ty::GenericArg::from(self_ty), compat_val.into()], + }; + // create a new projection type `::Effects` + let Some(assoc) = tcx.associated_type_for_effects(bound_trait_ref.def_id()) else { + tcx.dcx().span_delayed_bug( + span, + "`~const` trait bound has no effect assoc yet no errors encountered?", ); - self.clauses.push((bound_trait_ref.rebind(new_trait_ref).upcast(tcx), span)); - } + return; + }; + let self_ty = Ty::new_projection(tcx, assoc, bound_trait_ref.skip_binder().args); + // make `::Effects: Compat` + let new_trait_ref = ty::TraitRef::new( + tcx, + tcx.require_lang_item(LangItem::EffectsCompat, Some(span)), + [ty::GenericArg::from(self_ty), compat_val.into()], + ); + self.clauses.push((bound_trait_ref.rebind(new_trait_ref).upcast(tcx), span)); } pub fn push_projection_bound( diff --git a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs index b32067ebd6aee..c03e074c80b7a 100644 --- a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs +++ b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs @@ -137,7 +137,7 @@ pub(super) fn explicit_item_bounds_with_filter( let tup = Ty::new(tcx, ty::Tuple(preds.effects_min_tys)); // FIXME(effects) span let span = tcx.def_span(def_id); - let assoc = tcx.require_lang_item(hir::LangItem::EffectsMinOutput, Some(span)); + let assoc = tcx.require_lang_item(hir::LangItem::EffectsIntersectionOutput, Some(span)); let proj = Ty::new_projection(tcx, assoc, [tup]); let self_proj = Ty::new_projection( tcx, diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index c0ebad9616df3..fabbec683506c 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -599,8 +599,8 @@ fn trait_lang_item_to_lang_item(lang_item: TraitSolverLangItem) -> LangItem { TraitSolverLangItem::DiscriminantKind => LangItem::DiscriminantKind, TraitSolverLangItem::DynMetadata => LangItem::DynMetadata, TraitSolverLangItem::EffectsMaybe => LangItem::EffectsMaybe, - TraitSolverLangItem::EffectsMin => LangItem::EffectsMin, - TraitSolverLangItem::EffectsMinOutput => LangItem::EffectsMinOutput, + TraitSolverLangItem::EffectsIntersection => LangItem::EffectsIntersection, + TraitSolverLangItem::EffectsIntersectionOutput => LangItem::EffectsIntersectionOutput, TraitSolverLangItem::EffectsNoRuntime => LangItem::EffectsNoRuntime, TraitSolverLangItem::EffectsRuntime => LangItem::EffectsRuntime, TraitSolverLangItem::FnPtrTrait => LangItem::FnPtrTrait, diff --git a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs index 8d57c3d9af004..6ee684605ac60 100644 --- a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs @@ -270,7 +270,7 @@ where goal: Goal, ) -> Vec>; - fn consider_builtin_effects_min_candidate( + fn consider_builtin_effects_intersection_candidate( ecx: &mut EvalCtxt<'_, D>, goal: Goal, ) -> Result, NoSolution>; @@ -425,8 +425,8 @@ where G::consider_builtin_destruct_candidate(self, goal) } else if cx.is_lang_item(trait_def_id, TraitSolverLangItem::TransmuteTrait) { G::consider_builtin_transmute_candidate(self, goal) - } else if tcx.is_lang_item(trait_def_id, TraitSolverLangItem::EffectsMin) { - G::consider_builtin_effects_min_candidate(self, goal) + } else if cx.is_lang_item(trait_def_id, TraitSolverLangItem::EffectsIntersection) { + G::consider_builtin_effects_intersection_candidate(self, goal) } else { Err(NoSolution) }; diff --git a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs index 7a81c210c5d04..9275bcc8e97c9 100644 --- a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs @@ -865,7 +865,7 @@ where panic!("`BikeshedIntrinsicFrom` does not have an associated type: {:?}", goal) } - fn consider_builtin_effects_min_candidate( + fn consider_builtin_effects_intersection_candidate( ecx: &mut EvalCtxt<'_, D>, goal: Goal, ) -> Result, NoSolution> { @@ -903,11 +903,15 @@ where let mut min = ty::EffectKind::Maybe; for ty in types.iter() { + // We can't find the intersection if the types used are generic. + // + // FIXME(effects) do we want to look at where clauses to get some + // clue for the case where generic types are being used? let Some(kind) = ty::EffectKind::try_from_ty(cx, ty) else { return Err(NoSolution); }; - let Some(result) = ty::EffectKind::min(min, kind) else { + let Some(result) = ty::EffectKind::intersection(min, kind) else { return Err(NoSolution); }; diff --git a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs index 08ed729b14405..f5832f7e5b4c9 100644 --- a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs +++ b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs @@ -703,7 +703,7 @@ where }) } - fn consider_builtin_effects_min_candidate( + fn consider_builtin_effects_intersection_candidate( ecx: &mut EvalCtxt<'_, D>, goal: Goal, ) -> Result, NoSolution> { @@ -732,7 +732,7 @@ where return Err(NoSolution); }; - let Some(result) = ty::EffectKind::min(min, kind) else { + let Some(result) = ty::EffectKind::intersection(min, kind) else { return Err(NoSolution); }; diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 4a26e8ae09734..8b7a63f5eb9b6 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -195,9 +195,9 @@ symbols! { DoubleEndedIterator, Duration, EffectsCompat, + EffectsIntersection, + EffectsIntersectionOutput, EffectsMaybe, - EffectsMin, - EffectsMinOutput, EffectsNoRuntime, EffectsRuntime, EffectsTyCompat, diff --git a/compiler/rustc_ty_utils/src/assoc.rs b/compiler/rustc_ty_utils/src/assoc.rs index 6a55e83786cb8..6726db8bb54df 100644 --- a/compiler/rustc_ty_utils/src/assoc.rs +++ b/compiler/rustc_ty_utils/src/assoc.rs @@ -184,12 +184,10 @@ fn associated_type_for_effects(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option { let trait_def_id = def_id; - let Some(attr) = tcx.get_attr(def_id, sym::const_trait) else { - return None; - }; + let attr = tcx.get_attr(def_id, sym::const_trait)?; let span = attr.span; let trait_assoc_ty = tcx.at(span).create_def(trait_def_id, kw::Empty, DefKind::AssocTy); @@ -197,8 +195,6 @@ fn associated_type_for_effects(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option, def_id: LocalDefId) -> Option { let impl_def_id = def_id; - let Some(trait_id) = tcx.trait_id_of_impl(def_id.to_def_id()) else { return None }; + let trait_id = tcx.trait_id_of_impl(def_id.to_def_id())?; // first get the DefId of the assoc type on the trait, if there is not, // then we don't need to generate it on the impl. - let Some(trait_assoc_id) = tcx.associated_type_for_effects(trait_id) else { - return None; - }; + let trait_assoc_id = tcx.associated_type_for_effects(trait_id)?; // FIXME(effects): span let span = tcx.def_ident_span(def_id).unwrap(); @@ -263,8 +232,6 @@ fn associated_type_for_effects(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option, def_id: LocalDefId) -> Option, def_id: LocalDefId) -> Option bug!( "associated_type_for_effects: {:?} should be Trait or Impl but is {:?}", def_id, def_kind ), - } + }; + + feed.feed_hir(); + + // visibility is public. + feed.visibility(ty::Visibility::Public); + + // Copy generics_of of the trait/impl, making the trait/impl as parent. + feed.generics_of({ + let parent_generics = tcx.generics_of(parent_did); + let parent_count = parent_generics.parent_count + parent_generics.own_params.len(); + + ty::Generics { + parent: Some(parent_did.to_def_id()), + parent_count, + own_params: vec![], + param_def_id_to_index: parent_generics.param_def_id_to_index.clone(), + has_self: false, + has_late_bound_regions: None, + host_effect_index: parent_generics.host_effect_index, + } + }); + feed.explicit_item_super_predicates(ty::EarlyBinder::bind(&[])); + + // There are no inferred outlives for the synthesized associated type. + feed.inferred_outlives_of(&[]); + + Some(feed.def_id().to_def_id()) } /// Given an `fn_def_id` of a trait or a trait implementation: diff --git a/compiler/rustc_type_ir/src/effects.rs b/compiler/rustc_type_ir/src/effects.rs index 39605936e3031..f7942f2f982f5 100644 --- a/compiler/rustc_type_ir/src/effects.rs +++ b/compiler/rustc_type_ir/src/effects.rs @@ -44,7 +44,10 @@ impl EffectKind { I::Ty::new_adt(tcx, tcx.adt_def(self.to_def_id(tcx)), Default::default()) } - pub fn min(a: Self, b: Self) -> Option { + /// Returns an intersection between two effect kinds. If one effect kind + /// is more permissive than the other (e.g. `Maybe` vs `Runtime`), this + /// returns the less permissive effect kind (`Runtime`). + pub fn intersection(a: Self, b: Self) -> Option { use EffectKind::*; match (a, b) { (Maybe, x) | (x, Maybe) => Some(x), diff --git a/compiler/rustc_type_ir/src/lang_items.rs b/compiler/rustc_type_ir/src/lang_items.rs index 55b9709b66876..cf00c37caa287 100644 --- a/compiler/rustc_type_ir/src/lang_items.rs +++ b/compiler/rustc_type_ir/src/lang_items.rs @@ -17,9 +17,9 @@ pub enum TraitSolverLangItem { Destruct, DiscriminantKind, DynMetadata, + EffectsIntersection, + EffectsIntersectionOutput, EffectsMaybe, - EffectsMin, - EffectsMinOutput, EffectsNoRuntime, EffectsRuntime, FnPtrTrait, diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs index 042acbf20b1a0..9f5818f675d86 100644 --- a/library/core/src/marker.rs +++ b/library/core/src/marker.rs @@ -1062,9 +1062,14 @@ pub mod effects { impl TyCompat for Maybe {} impl TyCompat for T {} - #[lang = "EffectsMin"] - pub trait Min { - #[lang = "EffectsMinOutput"] + #[lang = "EffectsIntersection"] + pub trait Intersection { + #[lang = "EffectsIntersectionOutput"] type Output: ?Sized; } + + // FIXME(effects): remove this after next trait solver lands + impl Intersection for () { + type Output = Maybe; + } } diff --git a/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.fixed b/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.fixed index 921dcf0b16261..f8fc935f3679d 100644 --- a/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.fixed +++ b/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.fixed @@ -104,15 +104,18 @@ fn main() {} struct D; +/* FIXME(effects) impl const Drop for D { fn drop(&mut self) { todo!(); } } +*/ // Lint this, since it can be dropped in const contexts // FIXME(effects) -fn d(this: D) {} +const fn d(this: D) {} +//~^ ERROR: this could be a `const fn` mod msrv { struct Foo(*const u8, &'static u8); diff --git a/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.stderr b/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.stderr index 8ba42c0e5b673..8302b074127e6 100644 --- a/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.stderr +++ b/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.stderr @@ -161,6 +161,11 @@ error: this could be a `const fn` | LL | fn d(this: D) {} | ^^^^^^^^^^^^^^^^ + | +help: make the function `const` + | +LL | const fn d(this: D) {} + | +++++ error: this could be a `const fn` --> tests/ui/missing_const_for_fn/could_be_const.rs:125:9 diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-fns-are-early-bound.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-fns-are-early-bound.rs index fdc53dbab1cbc..b3087349e4d3c 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-fns-are-early-bound.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-fns-are-early-bound.rs @@ -126,10 +126,10 @@ pub mod effects { #[stable(feature = "minicore", since = "1.0.0")] impl TyCompat for T {} - #[lang = "EffectsMin"] + #[lang = "EffectsIntersection"] #[stable(feature = "minicore", since = "1.0.0")] - pub trait Min { - #[lang = "EffectsMinOutput"] + pub trait Intersection { + #[lang = "EffectsIntersectionOutput"] #[stable(feature = "minicore", since = "1.0.0")] type Output: ?Sized; } diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail.rs index bb8e06ab2f7a1..637a24f53bc63 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail.rs @@ -1,4 +1,5 @@ //@ check-pass +//@ compile-flags: -Znext-solver #![allow(incomplete_features)] #![feature(const_trait_impl, effects)] diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits.rs index b32c8cab7ecbe..fbe89b00b974b 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits.rs @@ -1,5 +1,7 @@ // FIXME(effects) check-pass //@ known-bug: #110395 +//@ compile-flags: -Znext-solver +#![allow(incomplete_features)] #![feature(const_trait_impl, effects)] #[const_trait] diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits.stderr index a9cb68a247ccd..5b6b39ee05ef6 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits.stderr @@ -1,20 +1,11 @@ -warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/super-traits.rs:3:30 - | -LL | #![feature(const_trait_impl, effects)] - | ^^^^^^^ - | - = note: see issue #102090 for more information - = note: `#[warn(incomplete_features)]` on by default - error[E0277]: the trait bound `Foo::{synthetic#0}: ~const Compat` is not satisfied - --> $DIR/super-traits.rs:21:7 + --> $DIR/super-traits.rs:23:7 | LL | t.a(); | ^ the trait `~const Compat` is not implemented for `Foo::{synthetic#0}` | note: required by a bound in `Foo::a` - --> $DIR/super-traits.rs:5:1 + --> $DIR/super-traits.rs:7:1 | LL | #[const_trait] | ^^^^^^^^^^^^^^ required by this bound in `Foo::a` @@ -26,6 +17,6 @@ help: consider further restricting the associated type LL | const fn foo(t: &T) where Foo::{synthetic#0}: ~const Compat { | +++++++++++++++++++++++++++++++++++++++ -error: aborting due to 1 previous error; 1 warning emitted +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0277`. From 4061fd9e4e415f4c09b221895039c7c9d9d8eb9e Mon Sep 17 00:00:00 2001 From: Kornel Date: Fri, 28 Jun 2024 18:15:12 +0100 Subject: [PATCH 411/892] Reduce merge conflicts from rustfmt's wrapping --- compiler/rustc_interface/src/tests.rs | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index 02322c9b2828f..9bd67a1154b7d 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -2,14 +2,22 @@ use crate::interface::{initialize_checked_jobserver, parse_cfg}; use rustc_data_structures::profiling::TimePassesFormat; use rustc_errors::{emitter::HumanReadableErrorType, registry, ColorConfig}; +use rustc_session::config::{build_configuration, build_session_options, rustc_optgroups}; use rustc_session::config::{ - build_configuration, build_session_options, rustc_optgroups, BranchProtection, CFGuard, Cfg, - CollapseMacroDebuginfo, CoverageLevel, CoverageOptions, DebugInfo, DumpMonoStatsFormat, - ErrorOutputType, ExternEntry, ExternLocation, Externs, FunctionReturn, InliningThreshold, - Input, InstrumentCoverage, InstrumentXRay, LinkSelfContained, LinkerPluginLto, LocationDetail, - LtoCli, NextSolverConfig, OomStrategy, Options, OutFileName, OutputType, OutputTypes, PAuthKey, - PacRet, Passes, PatchableFunctionEntry, Polonius, ProcMacroExecutionStrategy, Strip, - SwitchWithOptPath, SymbolManglingVersion, WasiExecModel, + BranchProtection, CFGuard, Cfg, CollapseMacroDebuginfo, CoverageLevel, CoverageOptions, + DebugInfo, DumpMonoStatsFormat, ErrorOutputType, +}; +use rustc_session::config::{ + ExternEntry, ExternLocation, Externs, FunctionReturn, InliningThreshold, Input, + InstrumentCoverage, InstrumentXRay, LinkSelfContained, LinkerPluginLto, +}; +use rustc_session::config::{ + LocationDetail, LtoCli, NextSolverConfig, OomStrategy, Options, OutFileName, OutputType, + OutputTypes, PAuthKey, PacRet, Passes, PatchableFunctionEntry, +}; +use rustc_session::config::{ + Polonius, ProcMacroExecutionStrategy, Strip, SwitchWithOptPath, SymbolManglingVersion, + WasiExecModel, }; use rustc_session::lint::Level; use rustc_session::search_paths::SearchPath; From 71dfbeabc4abe992a42025a5b7341e1ceec22e0b Mon Sep 17 00:00:00 2001 From: Goldstein Date: Mon, 25 Mar 2024 20:44:58 +0300 Subject: [PATCH 412/892] Disable dead variant removal for `#[repr(C)]` enums. See https://github.com/rust-lang/unsafe-code-guidelines/issues/500. --- compiler/rustc_abi/src/layout.rs | 4 +- compiler/rustc_abi/src/lib.rs | 2 +- tests/ui/abi/compatibility.rs | 4 + ...-variants.aarch64-unknown-linux-gnu.stderr | 288 ++++++++++++++++++ ...-c-dead-variants.armebv7r-none-eabi.stderr | 288 ++++++++++++++++++ ...-dead-variants.i686-pc-windows-msvc.stderr | 288 ++++++++++++++++++ tests/ui/repr/repr-c-dead-variants.rs | 63 ++++ ...d-variants.x86_64-unknown-linux-gnu.stderr | 288 ++++++++++++++++++ tests/ui/repr/repr-c-int-dead-variants.rs | 38 +++ tests/ui/repr/repr-c-int-dead-variants.stderr | 288 ++++++++++++++++++ 10 files changed, 1548 insertions(+), 3 deletions(-) create mode 100644 tests/ui/repr/repr-c-dead-variants.aarch64-unknown-linux-gnu.stderr create mode 100644 tests/ui/repr/repr-c-dead-variants.armebv7r-none-eabi.stderr create mode 100644 tests/ui/repr/repr-c-dead-variants.i686-pc-windows-msvc.stderr create mode 100644 tests/ui/repr/repr-c-dead-variants.rs create mode 100644 tests/ui/repr/repr-c-dead-variants.x86_64-unknown-linux-gnu.stderr create mode 100644 tests/ui/repr/repr-c-int-dead-variants.rs create mode 100644 tests/ui/repr/repr-c-int-dead-variants.stderr diff --git a/compiler/rustc_abi/src/layout.rs b/compiler/rustc_abi/src/layout.rs index a95ef4c460f45..aff0d70bf90d9 100644 --- a/compiler/rustc_abi/src/layout.rs +++ b/compiler/rustc_abi/src/layout.rs @@ -186,7 +186,7 @@ pub trait LayoutCalculator { let (present_first, present_second) = { let mut present_variants = variants .iter_enumerated() - .filter_map(|(i, v)| if absent(v) { None } else { Some(i) }); + .filter_map(|(i, v)| if !repr.c() && absent(v) { None } else { Some(i) }); (present_variants.next(), present_variants.next()) }; let present_first = match present_first { @@ -621,7 +621,7 @@ where let discr_type = repr.discr_type(); let bits = Integer::from_attr(dl, discr_type).size().bits(); for (i, mut val) in discriminants { - if variants[i].iter().any(|f| f.abi.is_uninhabited()) { + if !repr.c() && variants[i].iter().any(|f| f.abi.is_uninhabited()) { continue; } if discr_type.is_signed() { diff --git a/compiler/rustc_abi/src/lib.rs b/compiler/rustc_abi/src/lib.rs index 5e3f64540e4aa..1e5e391d19b5d 100644 --- a/compiler/rustc_abi/src/lib.rs +++ b/compiler/rustc_abi/src/lib.rs @@ -1401,7 +1401,7 @@ pub enum Variants { /// Single enum variants, structs/tuples, unions, and all non-ADTs. Single { index: VariantIdx }, - /// Enum-likes with more than one inhabited variant: each variant comes with + /// Enum-likes with more than one variant: each variant comes with /// a *discriminant* (usually the same as the variant index but the user can /// assign explicit discriminant values). That discriminant is encoded /// as a *tag* on the machine. The layout of each variant is diff --git a/tests/ui/abi/compatibility.rs b/tests/ui/abi/compatibility.rs index 373d1cce1d73d..086177efb77b9 100644 --- a/tests/ui/abi/compatibility.rs +++ b/tests/ui/abi/compatibility.rs @@ -277,6 +277,10 @@ test_abi_compatible!(zst_unit, Zst, ()); test_abi_compatible!(zst_array, Zst, [u8; 0]); test_abi_compatible!(nonzero_int, NonZero, i32); +// `#[repr(C)]` enums should not change ABI based on individual variant inhabitedness. +enum Void {} +test_abi_compatible!(repr_c_enum_void, ReprCEnum, ReprCEnum>); + // `DispatchFromDyn` relies on ABI compatibility. // This is interesting since these types are not `repr(transparent)`. So this is not part of our // public ABI guarantees, but is relied on by the compiler. diff --git a/tests/ui/repr/repr-c-dead-variants.aarch64-unknown-linux-gnu.stderr b/tests/ui/repr/repr-c-dead-variants.aarch64-unknown-linux-gnu.stderr new file mode 100644 index 0000000000000..e2e57fe0e7311 --- /dev/null +++ b/tests/ui/repr/repr-c-dead-variants.aarch64-unknown-linux-gnu.stderr @@ -0,0 +1,288 @@ +error: layout_of(Univariant) = Layout { + size: Size(4 bytes), + align: AbiAndPrefAlign { + abi: Align(4 bytes), + pref: $SOME_ALIGN, + }, + abi: Uninhabited, + fields: Arbitrary { + offsets: [ + Size(0 bytes), + ], + memory_index: [ + 0, + ], + }, + largest_niche: Some( + Niche { + offset: Size(0 bytes), + value: Int( + I32, + false, + ), + valid_range: 0..=0, + }, + ), + variants: Multiple { + tag: Initialized { + value: Int( + I32, + false, + ), + valid_range: 0..=0, + }, + tag_encoding: Direct, + tag_field: 0, + variants: [ + Layout { + size: Size(4 bytes), + align: AbiAndPrefAlign { + abi: Align(4 bytes), + pref: $SOME_ALIGN, + }, + abi: Uninhabited, + fields: Arbitrary { + offsets: [ + Size(4 bytes), + ], + memory_index: [ + 0, + ], + }, + largest_niche: None, + variants: Single { + index: 0, + }, + max_repr_align: None, + unadjusted_abi_align: Align(4 bytes), + }, + ], + }, + max_repr_align: None, + unadjusted_abi_align: Align(4 bytes), + } + --> $DIR/repr-c-dead-variants.rs:38:1 + | +LL | enum Univariant { + | ^^^^^^^^^^^^^^^ + +error: layout_of(TwoVariants) = Layout { + size: Size(8 bytes), + align: AbiAndPrefAlign { + abi: Align(4 bytes), + pref: $SOME_ALIGN, + }, + abi: ScalarPair( + Initialized { + value: Int( + I32, + false, + ), + valid_range: 0..=1, + }, + Union { + value: Int( + I8, + false, + ), + }, + ), + fields: Arbitrary { + offsets: [ + Size(0 bytes), + ], + memory_index: [ + 0, + ], + }, + largest_niche: Some( + Niche { + offset: Size(0 bytes), + value: Int( + I32, + false, + ), + valid_range: 0..=1, + }, + ), + variants: Multiple { + tag: Initialized { + value: Int( + I32, + false, + ), + valid_range: 0..=1, + }, + tag_encoding: Direct, + tag_field: 0, + variants: [ + Layout { + size: Size(4 bytes), + align: AbiAndPrefAlign { + abi: Align(4 bytes), + pref: $SOME_ALIGN, + }, + abi: Uninhabited, + fields: Arbitrary { + offsets: [ + Size(4 bytes), + ], + memory_index: [ + 0, + ], + }, + largest_niche: None, + variants: Single { + index: 0, + }, + max_repr_align: None, + unadjusted_abi_align: Align(4 bytes), + }, + Layout { + size: Size(8 bytes), + align: AbiAndPrefAlign { + abi: Align(4 bytes), + pref: $SOME_ALIGN, + }, + abi: ScalarPair( + Initialized { + value: Int( + I32, + false, + ), + valid_range: 0..=1, + }, + Union { + value: Int( + I8, + false, + ), + }, + ), + fields: Arbitrary { + offsets: [ + Size(4 bytes), + ], + memory_index: [ + 0, + ], + }, + largest_niche: None, + variants: Single { + index: 1, + }, + max_repr_align: None, + unadjusted_abi_align: Align(4 bytes), + }, + ], + }, + max_repr_align: None, + unadjusted_abi_align: Align(4 bytes), + } + --> $DIR/repr-c-dead-variants.rs:45:1 + | +LL | enum TwoVariants { + | ^^^^^^^^^^^^^^^^ + +error: layout_of(DeadBranchHasOtherField) = Layout { + size: Size(16 bytes), + align: AbiAndPrefAlign { + abi: Align(8 bytes), + pref: $SOME_ALIGN, + }, + abi: Aggregate { + sized: true, + }, + fields: Arbitrary { + offsets: [ + Size(0 bytes), + ], + memory_index: [ + 0, + ], + }, + largest_niche: Some( + Niche { + offset: Size(0 bytes), + value: Int( + I32, + false, + ), + valid_range: 0..=1, + }, + ), + variants: Multiple { + tag: Initialized { + value: Int( + I32, + false, + ), + valid_range: 0..=1, + }, + tag_encoding: Direct, + tag_field: 0, + variants: [ + Layout { + size: Size(16 bytes), + align: AbiAndPrefAlign { + abi: Align(8 bytes), + pref: $SOME_ALIGN, + }, + abi: Uninhabited, + fields: Arbitrary { + offsets: [ + Size(8 bytes), + Size(8 bytes), + ], + memory_index: [ + 0, + 1, + ], + }, + largest_niche: None, + variants: Single { + index: 0, + }, + max_repr_align: Some( + Align(8 bytes), + ), + unadjusted_abi_align: Align(8 bytes), + }, + Layout { + size: Size(16 bytes), + align: AbiAndPrefAlign { + abi: Align(8 bytes), + pref: $SOME_ALIGN, + }, + abi: Aggregate { + sized: true, + }, + fields: Arbitrary { + offsets: [ + Size(8 bytes), + ], + memory_index: [ + 0, + ], + }, + largest_niche: None, + variants: Single { + index: 1, + }, + max_repr_align: None, + unadjusted_abi_align: Align(8 bytes), + }, + ], + }, + max_repr_align: Some( + Align(8 bytes), + ), + unadjusted_abi_align: Align(8 bytes), + } + --> $DIR/repr-c-dead-variants.rs:57:1 + | +LL | enum DeadBranchHasOtherField { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 3 previous errors + diff --git a/tests/ui/repr/repr-c-dead-variants.armebv7r-none-eabi.stderr b/tests/ui/repr/repr-c-dead-variants.armebv7r-none-eabi.stderr new file mode 100644 index 0000000000000..6ecdab1cc140c --- /dev/null +++ b/tests/ui/repr/repr-c-dead-variants.armebv7r-none-eabi.stderr @@ -0,0 +1,288 @@ +error: layout_of(Univariant) = Layout { + size: Size(1 bytes), + align: AbiAndPrefAlign { + abi: Align(1 bytes), + pref: $SOME_ALIGN, + }, + abi: Uninhabited, + fields: Arbitrary { + offsets: [ + Size(0 bytes), + ], + memory_index: [ + 0, + ], + }, + largest_niche: Some( + Niche { + offset: Size(0 bytes), + value: Int( + I8, + false, + ), + valid_range: 0..=0, + }, + ), + variants: Multiple { + tag: Initialized { + value: Int( + I8, + false, + ), + valid_range: 0..=0, + }, + tag_encoding: Direct, + tag_field: 0, + variants: [ + Layout { + size: Size(1 bytes), + align: AbiAndPrefAlign { + abi: Align(1 bytes), + pref: $SOME_ALIGN, + }, + abi: Uninhabited, + fields: Arbitrary { + offsets: [ + Size(1 bytes), + ], + memory_index: [ + 0, + ], + }, + largest_niche: None, + variants: Single { + index: 0, + }, + max_repr_align: None, + unadjusted_abi_align: Align(1 bytes), + }, + ], + }, + max_repr_align: None, + unadjusted_abi_align: Align(1 bytes), + } + --> $DIR/repr-c-dead-variants.rs:38:1 + | +LL | enum Univariant { + | ^^^^^^^^^^^^^^^ + +error: layout_of(TwoVariants) = Layout { + size: Size(2 bytes), + align: AbiAndPrefAlign { + abi: Align(1 bytes), + pref: $SOME_ALIGN, + }, + abi: ScalarPair( + Initialized { + value: Int( + I8, + false, + ), + valid_range: 0..=1, + }, + Union { + value: Int( + I8, + false, + ), + }, + ), + fields: Arbitrary { + offsets: [ + Size(0 bytes), + ], + memory_index: [ + 0, + ], + }, + largest_niche: Some( + Niche { + offset: Size(0 bytes), + value: Int( + I8, + false, + ), + valid_range: 0..=1, + }, + ), + variants: Multiple { + tag: Initialized { + value: Int( + I8, + false, + ), + valid_range: 0..=1, + }, + tag_encoding: Direct, + tag_field: 0, + variants: [ + Layout { + size: Size(1 bytes), + align: AbiAndPrefAlign { + abi: Align(1 bytes), + pref: $SOME_ALIGN, + }, + abi: Uninhabited, + fields: Arbitrary { + offsets: [ + Size(1 bytes), + ], + memory_index: [ + 0, + ], + }, + largest_niche: None, + variants: Single { + index: 0, + }, + max_repr_align: None, + unadjusted_abi_align: Align(1 bytes), + }, + Layout { + size: Size(2 bytes), + align: AbiAndPrefAlign { + abi: Align(1 bytes), + pref: $SOME_ALIGN, + }, + abi: ScalarPair( + Initialized { + value: Int( + I8, + false, + ), + valid_range: 0..=1, + }, + Union { + value: Int( + I8, + false, + ), + }, + ), + fields: Arbitrary { + offsets: [ + Size(1 bytes), + ], + memory_index: [ + 0, + ], + }, + largest_niche: None, + variants: Single { + index: 1, + }, + max_repr_align: None, + unadjusted_abi_align: Align(1 bytes), + }, + ], + }, + max_repr_align: None, + unadjusted_abi_align: Align(1 bytes), + } + --> $DIR/repr-c-dead-variants.rs:45:1 + | +LL | enum TwoVariants { + | ^^^^^^^^^^^^^^^^ + +error: layout_of(DeadBranchHasOtherField) = Layout { + size: Size(16 bytes), + align: AbiAndPrefAlign { + abi: Align(8 bytes), + pref: $SOME_ALIGN, + }, + abi: Aggregate { + sized: true, + }, + fields: Arbitrary { + offsets: [ + Size(0 bytes), + ], + memory_index: [ + 0, + ], + }, + largest_niche: Some( + Niche { + offset: Size(0 bytes), + value: Int( + I8, + false, + ), + valid_range: 0..=1, + }, + ), + variants: Multiple { + tag: Initialized { + value: Int( + I8, + false, + ), + valid_range: 0..=1, + }, + tag_encoding: Direct, + tag_field: 0, + variants: [ + Layout { + size: Size(16 bytes), + align: AbiAndPrefAlign { + abi: Align(8 bytes), + pref: $SOME_ALIGN, + }, + abi: Uninhabited, + fields: Arbitrary { + offsets: [ + Size(8 bytes), + Size(8 bytes), + ], + memory_index: [ + 0, + 1, + ], + }, + largest_niche: None, + variants: Single { + index: 0, + }, + max_repr_align: Some( + Align(8 bytes), + ), + unadjusted_abi_align: Align(8 bytes), + }, + Layout { + size: Size(16 bytes), + align: AbiAndPrefAlign { + abi: Align(8 bytes), + pref: $SOME_ALIGN, + }, + abi: Aggregate { + sized: true, + }, + fields: Arbitrary { + offsets: [ + Size(8 bytes), + ], + memory_index: [ + 0, + ], + }, + largest_niche: None, + variants: Single { + index: 1, + }, + max_repr_align: None, + unadjusted_abi_align: Align(8 bytes), + }, + ], + }, + max_repr_align: Some( + Align(8 bytes), + ), + unadjusted_abi_align: Align(8 bytes), + } + --> $DIR/repr-c-dead-variants.rs:57:1 + | +LL | enum DeadBranchHasOtherField { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 3 previous errors + diff --git a/tests/ui/repr/repr-c-dead-variants.i686-pc-windows-msvc.stderr b/tests/ui/repr/repr-c-dead-variants.i686-pc-windows-msvc.stderr new file mode 100644 index 0000000000000..e2e57fe0e7311 --- /dev/null +++ b/tests/ui/repr/repr-c-dead-variants.i686-pc-windows-msvc.stderr @@ -0,0 +1,288 @@ +error: layout_of(Univariant) = Layout { + size: Size(4 bytes), + align: AbiAndPrefAlign { + abi: Align(4 bytes), + pref: $SOME_ALIGN, + }, + abi: Uninhabited, + fields: Arbitrary { + offsets: [ + Size(0 bytes), + ], + memory_index: [ + 0, + ], + }, + largest_niche: Some( + Niche { + offset: Size(0 bytes), + value: Int( + I32, + false, + ), + valid_range: 0..=0, + }, + ), + variants: Multiple { + tag: Initialized { + value: Int( + I32, + false, + ), + valid_range: 0..=0, + }, + tag_encoding: Direct, + tag_field: 0, + variants: [ + Layout { + size: Size(4 bytes), + align: AbiAndPrefAlign { + abi: Align(4 bytes), + pref: $SOME_ALIGN, + }, + abi: Uninhabited, + fields: Arbitrary { + offsets: [ + Size(4 bytes), + ], + memory_index: [ + 0, + ], + }, + largest_niche: None, + variants: Single { + index: 0, + }, + max_repr_align: None, + unadjusted_abi_align: Align(4 bytes), + }, + ], + }, + max_repr_align: None, + unadjusted_abi_align: Align(4 bytes), + } + --> $DIR/repr-c-dead-variants.rs:38:1 + | +LL | enum Univariant { + | ^^^^^^^^^^^^^^^ + +error: layout_of(TwoVariants) = Layout { + size: Size(8 bytes), + align: AbiAndPrefAlign { + abi: Align(4 bytes), + pref: $SOME_ALIGN, + }, + abi: ScalarPair( + Initialized { + value: Int( + I32, + false, + ), + valid_range: 0..=1, + }, + Union { + value: Int( + I8, + false, + ), + }, + ), + fields: Arbitrary { + offsets: [ + Size(0 bytes), + ], + memory_index: [ + 0, + ], + }, + largest_niche: Some( + Niche { + offset: Size(0 bytes), + value: Int( + I32, + false, + ), + valid_range: 0..=1, + }, + ), + variants: Multiple { + tag: Initialized { + value: Int( + I32, + false, + ), + valid_range: 0..=1, + }, + tag_encoding: Direct, + tag_field: 0, + variants: [ + Layout { + size: Size(4 bytes), + align: AbiAndPrefAlign { + abi: Align(4 bytes), + pref: $SOME_ALIGN, + }, + abi: Uninhabited, + fields: Arbitrary { + offsets: [ + Size(4 bytes), + ], + memory_index: [ + 0, + ], + }, + largest_niche: None, + variants: Single { + index: 0, + }, + max_repr_align: None, + unadjusted_abi_align: Align(4 bytes), + }, + Layout { + size: Size(8 bytes), + align: AbiAndPrefAlign { + abi: Align(4 bytes), + pref: $SOME_ALIGN, + }, + abi: ScalarPair( + Initialized { + value: Int( + I32, + false, + ), + valid_range: 0..=1, + }, + Union { + value: Int( + I8, + false, + ), + }, + ), + fields: Arbitrary { + offsets: [ + Size(4 bytes), + ], + memory_index: [ + 0, + ], + }, + largest_niche: None, + variants: Single { + index: 1, + }, + max_repr_align: None, + unadjusted_abi_align: Align(4 bytes), + }, + ], + }, + max_repr_align: None, + unadjusted_abi_align: Align(4 bytes), + } + --> $DIR/repr-c-dead-variants.rs:45:1 + | +LL | enum TwoVariants { + | ^^^^^^^^^^^^^^^^ + +error: layout_of(DeadBranchHasOtherField) = Layout { + size: Size(16 bytes), + align: AbiAndPrefAlign { + abi: Align(8 bytes), + pref: $SOME_ALIGN, + }, + abi: Aggregate { + sized: true, + }, + fields: Arbitrary { + offsets: [ + Size(0 bytes), + ], + memory_index: [ + 0, + ], + }, + largest_niche: Some( + Niche { + offset: Size(0 bytes), + value: Int( + I32, + false, + ), + valid_range: 0..=1, + }, + ), + variants: Multiple { + tag: Initialized { + value: Int( + I32, + false, + ), + valid_range: 0..=1, + }, + tag_encoding: Direct, + tag_field: 0, + variants: [ + Layout { + size: Size(16 bytes), + align: AbiAndPrefAlign { + abi: Align(8 bytes), + pref: $SOME_ALIGN, + }, + abi: Uninhabited, + fields: Arbitrary { + offsets: [ + Size(8 bytes), + Size(8 bytes), + ], + memory_index: [ + 0, + 1, + ], + }, + largest_niche: None, + variants: Single { + index: 0, + }, + max_repr_align: Some( + Align(8 bytes), + ), + unadjusted_abi_align: Align(8 bytes), + }, + Layout { + size: Size(16 bytes), + align: AbiAndPrefAlign { + abi: Align(8 bytes), + pref: $SOME_ALIGN, + }, + abi: Aggregate { + sized: true, + }, + fields: Arbitrary { + offsets: [ + Size(8 bytes), + ], + memory_index: [ + 0, + ], + }, + largest_niche: None, + variants: Single { + index: 1, + }, + max_repr_align: None, + unadjusted_abi_align: Align(8 bytes), + }, + ], + }, + max_repr_align: Some( + Align(8 bytes), + ), + unadjusted_abi_align: Align(8 bytes), + } + --> $DIR/repr-c-dead-variants.rs:57:1 + | +LL | enum DeadBranchHasOtherField { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 3 previous errors + diff --git a/tests/ui/repr/repr-c-dead-variants.rs b/tests/ui/repr/repr-c-dead-variants.rs new file mode 100644 index 0000000000000..f113588e83fe9 --- /dev/null +++ b/tests/ui/repr/repr-c-dead-variants.rs @@ -0,0 +1,63 @@ +#![feature(no_core, rustc_attrs, lang_items)] +#![allow(dead_code)] +#![crate_type = "lib"] +#![no_std] +#![no_core] + +// See also: repr-c-int-dead-variants.rs + +//@ normalize-stderr-test "pref: Align\([1-8] bytes\)" -> "pref: $$SOME_ALIGN" + +// This test depends on the value of the `c_enum_min_bits` target option. +// As there's no way to actually check it from UI test, we only run this test on a subset of archs. +// Four archs specifically are chosen: one for major architectures (x86_64, i686, aarch64) +// and `armebv7r-none-eabi` that has `c_enum_min_bits` set to 8. + +//@ revisions: aarch64-unknown-linux-gnu +//@[aarch64-unknown-linux-gnu] compile-flags: --target aarch64-unknown-linux-gnu +//@[aarch64-unknown-linux-gnu] needs-llvm-components: aarch64 + +//@ revisions: i686-pc-windows-msvc +//@[i686-pc-windows-msvc] compile-flags: --target i686-pc-windows-gnu +//@[i686-pc-windows-msvc] needs-llvm-components: x86 + +//@ revisions: x86_64-unknown-linux-gnu +//@[x86_64-unknown-linux-gnu] compile-flags: --target x86_64-unknown-linux-gnu +//@[x86_64-unknown-linux-gnu] needs-llvm-components: x86 +// +//@ revisions: armebv7r-none-eabi +//@[armebv7r-none-eabi] compile-flags: --target armebv7r-none-eabi +//@[armebv7r-none-eabi] needs-llvm-components: arm + +// A simple uninhabited type. +enum Void {} + +// Compiler must not remove dead variants of `#[repr(C, int)]` ADTs. +#[repr(C)] +#[rustc_layout(debug)] +enum Univariant { //~ ERROR layout_of + Variant(Void), +} + +// ADTs with variants that have fields must have space allocated for those fields. +#[repr(C)] +#[rustc_layout(debug)] +enum TwoVariants { //~ ERROR layout_of + Variant1(Void), + Variant2(u8), +} + +// Some targets have 4-byte-aligned u64, make it always 8-byte-aligned. +#[repr(C, align(8))] +struct Align8U64(u64); + +// This one is 2 x u64: we reserve space for fields in a dead branch. +#[repr(C)] +#[rustc_layout(debug)] +enum DeadBranchHasOtherField { //~ ERROR layout_of + Variant1(Void, Align8U64), + Variant2(u8), +} + +#[lang = "sized"] +trait Sized {} diff --git a/tests/ui/repr/repr-c-dead-variants.x86_64-unknown-linux-gnu.stderr b/tests/ui/repr/repr-c-dead-variants.x86_64-unknown-linux-gnu.stderr new file mode 100644 index 0000000000000..e2e57fe0e7311 --- /dev/null +++ b/tests/ui/repr/repr-c-dead-variants.x86_64-unknown-linux-gnu.stderr @@ -0,0 +1,288 @@ +error: layout_of(Univariant) = Layout { + size: Size(4 bytes), + align: AbiAndPrefAlign { + abi: Align(4 bytes), + pref: $SOME_ALIGN, + }, + abi: Uninhabited, + fields: Arbitrary { + offsets: [ + Size(0 bytes), + ], + memory_index: [ + 0, + ], + }, + largest_niche: Some( + Niche { + offset: Size(0 bytes), + value: Int( + I32, + false, + ), + valid_range: 0..=0, + }, + ), + variants: Multiple { + tag: Initialized { + value: Int( + I32, + false, + ), + valid_range: 0..=0, + }, + tag_encoding: Direct, + tag_field: 0, + variants: [ + Layout { + size: Size(4 bytes), + align: AbiAndPrefAlign { + abi: Align(4 bytes), + pref: $SOME_ALIGN, + }, + abi: Uninhabited, + fields: Arbitrary { + offsets: [ + Size(4 bytes), + ], + memory_index: [ + 0, + ], + }, + largest_niche: None, + variants: Single { + index: 0, + }, + max_repr_align: None, + unadjusted_abi_align: Align(4 bytes), + }, + ], + }, + max_repr_align: None, + unadjusted_abi_align: Align(4 bytes), + } + --> $DIR/repr-c-dead-variants.rs:38:1 + | +LL | enum Univariant { + | ^^^^^^^^^^^^^^^ + +error: layout_of(TwoVariants) = Layout { + size: Size(8 bytes), + align: AbiAndPrefAlign { + abi: Align(4 bytes), + pref: $SOME_ALIGN, + }, + abi: ScalarPair( + Initialized { + value: Int( + I32, + false, + ), + valid_range: 0..=1, + }, + Union { + value: Int( + I8, + false, + ), + }, + ), + fields: Arbitrary { + offsets: [ + Size(0 bytes), + ], + memory_index: [ + 0, + ], + }, + largest_niche: Some( + Niche { + offset: Size(0 bytes), + value: Int( + I32, + false, + ), + valid_range: 0..=1, + }, + ), + variants: Multiple { + tag: Initialized { + value: Int( + I32, + false, + ), + valid_range: 0..=1, + }, + tag_encoding: Direct, + tag_field: 0, + variants: [ + Layout { + size: Size(4 bytes), + align: AbiAndPrefAlign { + abi: Align(4 bytes), + pref: $SOME_ALIGN, + }, + abi: Uninhabited, + fields: Arbitrary { + offsets: [ + Size(4 bytes), + ], + memory_index: [ + 0, + ], + }, + largest_niche: None, + variants: Single { + index: 0, + }, + max_repr_align: None, + unadjusted_abi_align: Align(4 bytes), + }, + Layout { + size: Size(8 bytes), + align: AbiAndPrefAlign { + abi: Align(4 bytes), + pref: $SOME_ALIGN, + }, + abi: ScalarPair( + Initialized { + value: Int( + I32, + false, + ), + valid_range: 0..=1, + }, + Union { + value: Int( + I8, + false, + ), + }, + ), + fields: Arbitrary { + offsets: [ + Size(4 bytes), + ], + memory_index: [ + 0, + ], + }, + largest_niche: None, + variants: Single { + index: 1, + }, + max_repr_align: None, + unadjusted_abi_align: Align(4 bytes), + }, + ], + }, + max_repr_align: None, + unadjusted_abi_align: Align(4 bytes), + } + --> $DIR/repr-c-dead-variants.rs:45:1 + | +LL | enum TwoVariants { + | ^^^^^^^^^^^^^^^^ + +error: layout_of(DeadBranchHasOtherField) = Layout { + size: Size(16 bytes), + align: AbiAndPrefAlign { + abi: Align(8 bytes), + pref: $SOME_ALIGN, + }, + abi: Aggregate { + sized: true, + }, + fields: Arbitrary { + offsets: [ + Size(0 bytes), + ], + memory_index: [ + 0, + ], + }, + largest_niche: Some( + Niche { + offset: Size(0 bytes), + value: Int( + I32, + false, + ), + valid_range: 0..=1, + }, + ), + variants: Multiple { + tag: Initialized { + value: Int( + I32, + false, + ), + valid_range: 0..=1, + }, + tag_encoding: Direct, + tag_field: 0, + variants: [ + Layout { + size: Size(16 bytes), + align: AbiAndPrefAlign { + abi: Align(8 bytes), + pref: $SOME_ALIGN, + }, + abi: Uninhabited, + fields: Arbitrary { + offsets: [ + Size(8 bytes), + Size(8 bytes), + ], + memory_index: [ + 0, + 1, + ], + }, + largest_niche: None, + variants: Single { + index: 0, + }, + max_repr_align: Some( + Align(8 bytes), + ), + unadjusted_abi_align: Align(8 bytes), + }, + Layout { + size: Size(16 bytes), + align: AbiAndPrefAlign { + abi: Align(8 bytes), + pref: $SOME_ALIGN, + }, + abi: Aggregate { + sized: true, + }, + fields: Arbitrary { + offsets: [ + Size(8 bytes), + ], + memory_index: [ + 0, + ], + }, + largest_niche: None, + variants: Single { + index: 1, + }, + max_repr_align: None, + unadjusted_abi_align: Align(8 bytes), + }, + ], + }, + max_repr_align: Some( + Align(8 bytes), + ), + unadjusted_abi_align: Align(8 bytes), + } + --> $DIR/repr-c-dead-variants.rs:57:1 + | +LL | enum DeadBranchHasOtherField { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 3 previous errors + diff --git a/tests/ui/repr/repr-c-int-dead-variants.rs b/tests/ui/repr/repr-c-int-dead-variants.rs new file mode 100644 index 0000000000000..8d2b39bd6486e --- /dev/null +++ b/tests/ui/repr/repr-c-int-dead-variants.rs @@ -0,0 +1,38 @@ +#![feature(rustc_attrs)] +#![allow(dead_code)] + +// See also: repr-c-dead-variants.rs + +//@ normalize-stderr-test "pref: Align\([1-8] bytes\)" -> "pref: $$SOME_ALIGN" + +// A simple uninhabited type. +enum Void {} + +// Compiler must not remove dead variants of `#[repr(C, int)]` ADTs. +#[repr(C, u8)] +#[rustc_layout(debug)] +enum UnivariantU8 { //~ ERROR layout_of + Variant(Void), +} + +// ADTs with variants that have fields must have space allocated for those fields. +#[repr(C, u8)] +#[rustc_layout(debug)] +enum TwoVariantsU8 { //~ ERROR layout_of + Variant1(Void), + Variant2(u8), +} + +// Some targets have 4-byte-aligned u64, make it always 8-byte-aligned. +#[repr(C, align(8))] +struct Align8U64(u64); + +// This one is 2 x u64: we reserve space for fields in a dead branch. +#[repr(C, u8)] +#[rustc_layout(debug)] +enum DeadBranchHasOtherFieldU8 { //~ ERROR layout_of + Variant1(Void, Align8U64), + Variant2(u8), +} + +fn main() {} diff --git a/tests/ui/repr/repr-c-int-dead-variants.stderr b/tests/ui/repr/repr-c-int-dead-variants.stderr new file mode 100644 index 0000000000000..f7df576df248b --- /dev/null +++ b/tests/ui/repr/repr-c-int-dead-variants.stderr @@ -0,0 +1,288 @@ +error: layout_of(UnivariantU8) = Layout { + size: Size(1 bytes), + align: AbiAndPrefAlign { + abi: Align(1 bytes), + pref: $SOME_ALIGN, + }, + abi: Uninhabited, + fields: Arbitrary { + offsets: [ + Size(0 bytes), + ], + memory_index: [ + 0, + ], + }, + largest_niche: Some( + Niche { + offset: Size(0 bytes), + value: Int( + I8, + false, + ), + valid_range: 0..=0, + }, + ), + variants: Multiple { + tag: Initialized { + value: Int( + I8, + false, + ), + valid_range: 0..=0, + }, + tag_encoding: Direct, + tag_field: 0, + variants: [ + Layout { + size: Size(1 bytes), + align: AbiAndPrefAlign { + abi: Align(1 bytes), + pref: $SOME_ALIGN, + }, + abi: Uninhabited, + fields: Arbitrary { + offsets: [ + Size(1 bytes), + ], + memory_index: [ + 0, + ], + }, + largest_niche: None, + variants: Single { + index: 0, + }, + max_repr_align: None, + unadjusted_abi_align: Align(1 bytes), + }, + ], + }, + max_repr_align: None, + unadjusted_abi_align: Align(1 bytes), + } + --> $DIR/repr-c-int-dead-variants.rs:14:1 + | +LL | enum UnivariantU8 { + | ^^^^^^^^^^^^^^^^^ + +error: layout_of(TwoVariantsU8) = Layout { + size: Size(2 bytes), + align: AbiAndPrefAlign { + abi: Align(1 bytes), + pref: $SOME_ALIGN, + }, + abi: ScalarPair( + Initialized { + value: Int( + I8, + false, + ), + valid_range: 0..=1, + }, + Union { + value: Int( + I8, + false, + ), + }, + ), + fields: Arbitrary { + offsets: [ + Size(0 bytes), + ], + memory_index: [ + 0, + ], + }, + largest_niche: Some( + Niche { + offset: Size(0 bytes), + value: Int( + I8, + false, + ), + valid_range: 0..=1, + }, + ), + variants: Multiple { + tag: Initialized { + value: Int( + I8, + false, + ), + valid_range: 0..=1, + }, + tag_encoding: Direct, + tag_field: 0, + variants: [ + Layout { + size: Size(1 bytes), + align: AbiAndPrefAlign { + abi: Align(1 bytes), + pref: $SOME_ALIGN, + }, + abi: Uninhabited, + fields: Arbitrary { + offsets: [ + Size(1 bytes), + ], + memory_index: [ + 0, + ], + }, + largest_niche: None, + variants: Single { + index: 0, + }, + max_repr_align: None, + unadjusted_abi_align: Align(1 bytes), + }, + Layout { + size: Size(2 bytes), + align: AbiAndPrefAlign { + abi: Align(1 bytes), + pref: $SOME_ALIGN, + }, + abi: ScalarPair( + Initialized { + value: Int( + I8, + false, + ), + valid_range: 0..=1, + }, + Union { + value: Int( + I8, + false, + ), + }, + ), + fields: Arbitrary { + offsets: [ + Size(1 bytes), + ], + memory_index: [ + 0, + ], + }, + largest_niche: None, + variants: Single { + index: 1, + }, + max_repr_align: None, + unadjusted_abi_align: Align(1 bytes), + }, + ], + }, + max_repr_align: None, + unadjusted_abi_align: Align(1 bytes), + } + --> $DIR/repr-c-int-dead-variants.rs:21:1 + | +LL | enum TwoVariantsU8 { + | ^^^^^^^^^^^^^^^^^^ + +error: layout_of(DeadBranchHasOtherFieldU8) = Layout { + size: Size(16 bytes), + align: AbiAndPrefAlign { + abi: Align(8 bytes), + pref: $SOME_ALIGN, + }, + abi: Aggregate { + sized: true, + }, + fields: Arbitrary { + offsets: [ + Size(0 bytes), + ], + memory_index: [ + 0, + ], + }, + largest_niche: Some( + Niche { + offset: Size(0 bytes), + value: Int( + I8, + false, + ), + valid_range: 0..=1, + }, + ), + variants: Multiple { + tag: Initialized { + value: Int( + I8, + false, + ), + valid_range: 0..=1, + }, + tag_encoding: Direct, + tag_field: 0, + variants: [ + Layout { + size: Size(16 bytes), + align: AbiAndPrefAlign { + abi: Align(8 bytes), + pref: $SOME_ALIGN, + }, + abi: Uninhabited, + fields: Arbitrary { + offsets: [ + Size(8 bytes), + Size(8 bytes), + ], + memory_index: [ + 0, + 1, + ], + }, + largest_niche: None, + variants: Single { + index: 0, + }, + max_repr_align: Some( + Align(8 bytes), + ), + unadjusted_abi_align: Align(8 bytes), + }, + Layout { + size: Size(16 bytes), + align: AbiAndPrefAlign { + abi: Align(8 bytes), + pref: $SOME_ALIGN, + }, + abi: Aggregate { + sized: true, + }, + fields: Arbitrary { + offsets: [ + Size(8 bytes), + ], + memory_index: [ + 0, + ], + }, + largest_niche: None, + variants: Single { + index: 1, + }, + max_repr_align: None, + unadjusted_abi_align: Align(8 bytes), + }, + ], + }, + max_repr_align: Some( + Align(8 bytes), + ), + unadjusted_abi_align: Align(8 bytes), + } + --> $DIR/repr-c-int-dead-variants.rs:33:1 + | +LL | enum DeadBranchHasOtherFieldU8 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 3 previous errors + From 8a3c07afbe94ff892b9fef982dea3ba1af7c7a5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Max=20=E2=80=9CGoldstein=E2=80=9D=20Siling?= Date: Sun, 5 May 2024 13:13:55 +0300 Subject: [PATCH 413/892] Clarify guarantees about ABI compatibility Co-authored-by: Ralf Jung --- tests/ui/abi/compatibility.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/ui/abi/compatibility.rs b/tests/ui/abi/compatibility.rs index 086177efb77b9..1bff3baaf7dca 100644 --- a/tests/ui/abi/compatibility.rs +++ b/tests/ui/abi/compatibility.rs @@ -278,6 +278,7 @@ test_abi_compatible!(zst_array, Zst, [u8; 0]); test_abi_compatible!(nonzero_int, NonZero, i32); // `#[repr(C)]` enums should not change ABI based on individual variant inhabitedness. +// (However, this is *not* a guarantee. We only guarantee same layout, not same ABI.) enum Void {} test_abi_compatible!(repr_c_enum_void, ReprCEnum, ReprCEnum>); From 17b843bc2cc2db2bf86f2c93ec3bade5f358ba57 Mon Sep 17 00:00:00 2001 From: onur-ozkan Date: Fri, 28 Jun 2024 20:32:31 +0300 Subject: [PATCH 414/892] update `run-make/windows-safeseh` compiletest header Signed-off-by: onur-ozkan --- tests/run-make/windows-safeseh/rmake.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/run-make/windows-safeseh/rmake.rs b/tests/run-make/windows-safeseh/rmake.rs index 10e6b38aa8df1..c7c6ef7339d25 100644 --- a/tests/run-make/windows-safeseh/rmake.rs +++ b/tests/run-make/windows-safeseh/rmake.rs @@ -1,4 +1,4 @@ -//@ only-windows +//@ only-x86_64-pc-windows-msvc //@ needs-rust-lld use run_make_support::rustc; From b1a0c0b1231a554d4ae699221a80a6e2f81bac4d Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 28 Jun 2024 11:49:16 -0400 Subject: [PATCH 415/892] Change RTN to use .. again --- compiler/rustc_ast/src/ast.rs | 5 +++- compiler/rustc_ast/src/mut_visit.rs | 1 + compiler/rustc_ast/src/util/classify.rs | 2 +- compiler/rustc_ast/src/visit.rs | 1 + compiler/rustc_ast_lowering/messages.ftl | 3 ++ compiler/rustc_ast_lowering/src/errors.rs | 6 ++++ compiler/rustc_ast_lowering/src/lib.rs | 25 +++++++---------- compiler/rustc_ast_lowering/src/path.rs | 3 ++ .../rustc_ast_passes/src/ast_validation.rs | 7 +++-- compiler/rustc_ast_passes/src/feature_gate.rs | 24 ++-------------- compiler/rustc_ast_pretty/src/pprust/state.rs | 5 ++++ compiler/rustc_hir/src/hir.rs | 2 +- compiler/rustc_parse/messages.ftl | 4 --- compiler/rustc_parse/src/errors.rs | 8 ------ compiler/rustc_parse/src/parser/path.rs | 27 ++++-------------- compiler/rustc_passes/src/hir_stats.rs | 2 +- compiler/rustc_resolve/src/late.rs | 1 + compiler/rustc_resolve/src/lib.rs | 1 + src/librustdoc/clean/types.rs | 2 +- tests/crashes/125249.rs | 2 +- .../bad-inputs-and-output.rs | 4 +-- .../bad-inputs-and-output.stderr | 12 ++++---- .../return-type-notation/basic.rs | 2 +- .../return-type-notation/equality.rs | 2 +- .../return-type-notation/equality.stderr | 4 +-- .../issue-120208-higher-ranked-const.rs | 2 +- .../issue-120208-higher-ranked-const.stderr | 4 +-- .../return-type-notation/missing.rs | 2 +- .../return-type-notation/missing.stderr | 2 +- .../return-type-notation/non-rpitit.rs | 2 +- .../return-type-notation/non-rpitit.stderr | 4 +-- .../issue-110963-early.rs | 2 +- .../return-type-notation/issue-110963-late.rs | 2 +- ...ormalizing-self-auto-trait-issue-109924.rs | 2 +- .../rtn-implied-in-supertrait.rs | 2 +- .../rtn-in-impl-signature.rs | 2 +- .../rtn-in-impl-signature.stderr | 12 ++++---- .../super-method-bound-ambig.rs | 2 +- .../super-method-bound-ambig.stderr | 4 +-- .../super-method-bound.rs | 2 +- .../return-type-notation/supertrait-bound.rs | 2 +- .../return-type-notation/ty-or-ct-params.rs | 2 +- .../ty-or-ct-params.stderr | 10 +++---- .../ui/borrowck/alias-liveness/rtn-static.rs | 4 +-- ...ature-gate-return_type_notation.cfg.stderr | 28 +++---------------- ...eature-gate-return_type_notation.no.stderr | 13 ++++----- .../feature-gate-return_type_notation.rs | 12 ++------ 47 files changed, 109 insertions(+), 163 deletions(-) diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index f5e79c04d784f..dbbc4980050de 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -176,6 +176,8 @@ pub enum GenericArgs { AngleBracketed(AngleBracketedArgs), /// The `(A, B)` and `C` in `Foo(A, B) -> C`. Parenthesized(ParenthesizedArgs), + /// `(..)` in return type notation + ParenthesizedElided(Span), } impl GenericArgs { @@ -187,6 +189,7 @@ impl GenericArgs { match self { AngleBracketed(data) => data.span, Parenthesized(data) => data.span, + ParenthesizedElided(span) => *span, } } } @@ -2051,7 +2054,7 @@ impl UintTy { /// * the `A: Bound` in `Trait` /// * the `RetTy` in `Trait(ArgTy, ArgTy) -> RetTy` /// * the `C = { Ct }` in `Trait` (feature `associated_const_equality`) -/// * the `f(): Bound` in `Trait` (feature `return_type_notation`) +/// * the `f(..): Bound` in `Trait` (feature `return_type_notation`) #[derive(Clone, Encodable, Decodable, Debug)] pub struct AssocItemConstraint { pub id: NodeId, diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index 27e781a5a6385..f816375b912d6 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -582,6 +582,7 @@ fn noop_visit_generic_args(generic_args: &mut GenericArgs, vis: & match generic_args { GenericArgs::AngleBracketed(data) => vis.visit_angle_bracketed_parameter_data(data), GenericArgs::Parenthesized(data) => vis.visit_parenthesized_parameter_data(data), + GenericArgs::ParenthesizedElided(span) => vis.visit_span(span), } } diff --git a/compiler/rustc_ast/src/util/classify.rs b/compiler/rustc_ast/src/util/classify.rs index 4b2544ac47ed8..ed64f44f726fc 100644 --- a/compiler/rustc_ast/src/util/classify.rs +++ b/compiler/rustc_ast/src/util/classify.rs @@ -234,6 +234,6 @@ fn path_return_type(path: &ast::Path) -> Option<&ast::Ty> { ast::FnRetTy::Default(_) => None, ast::FnRetTy::Ty(ret) => Some(ret), }, - ast::GenericArgs::AngleBracketed(_) => None, + ast::GenericArgs::AngleBracketed(_) | ast::GenericArgs::ParenthesizedElided(_) => None, } } diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index 26cb04d4d47fc..f6929057bed13 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -609,6 +609,7 @@ where walk_list!(visitor, visit_ty, inputs); try_visit!(visitor.visit_fn_ret_ty(output)); } + GenericArgs::ParenthesizedElided(_span) => {} } V::Result::output() } diff --git a/compiler/rustc_ast_lowering/messages.ftl b/compiler/rustc_ast_lowering/messages.ftl index 58f65f1257fc7..d6eb344fd1dbb 100644 --- a/compiler/rustc_ast_lowering/messages.ftl +++ b/compiler/rustc_ast_lowering/messages.ftl @@ -36,6 +36,9 @@ ast_lowering_bad_return_type_notation_inputs = argument types not allowed with return type notation .suggestion = remove the input types +ast_lowering_bad_return_type_notation_needs_dots = return type notation arguments must be elided with `..` + .suggestion = add `..` + ast_lowering_bad_return_type_notation_output = return type not allowed with return type notation .suggestion = remove the return type diff --git a/compiler/rustc_ast_lowering/src/errors.rs b/compiler/rustc_ast_lowering/src/errors.rs index 3d4b6a1f033fb..6699c6e75f5ea 100644 --- a/compiler/rustc_ast_lowering/src/errors.rs +++ b/compiler/rustc_ast_lowering/src/errors.rs @@ -393,6 +393,12 @@ pub enum BadReturnTypeNotation { #[suggestion(code = "", applicability = "maybe-incorrect")] span: Span, }, + #[diag(ast_lowering_bad_return_type_notation_needs_dots)] + NeedsDots { + #[primary_span] + #[suggestion(code = "(..)", applicability = "maybe-incorrect")] + span: Span, + }, } #[derive(Diagnostic)] diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 0a06304fcecfa..92fb5b3c2eb90 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -979,20 +979,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { self.lower_angle_bracketed_parameter_data(data, ParamMode::Explicit, itctx).0 } GenericArgs::Parenthesized(data) => { - if data.inputs.is_empty() && matches!(data.output, FnRetTy::Default(..)) { - let parenthesized = if self.tcx.features().return_type_notation { - hir::GenericArgsParentheses::ReturnTypeNotation - } else { - self.emit_bad_parenthesized_trait_in_assoc_ty(data); - hir::GenericArgsParentheses::No - }; - GenericArgsCtor { - args: Default::default(), - constraints: &[], - parenthesized, - span: data.inputs_span, - } - } else if let Some(first_char) = constraint.ident.as_str().chars().next() + if let Some(first_char) = constraint.ident.as_str().chars().next() && first_char.is_ascii_lowercase() { let mut err = if !data.inputs.is_empty() { @@ -1004,7 +991,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { span: data.inputs_span.shrink_to_hi().to(ty.span), }) } else { - unreachable!("inputs are empty and return type is not provided") + self.dcx().create_err(errors::BadReturnTypeNotation::NeedsDots { + span: data.inputs_span, + }) }; if !self.tcx.features().return_type_notation && self.tcx.sess.is_nightly_build() @@ -1034,6 +1023,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { .0 } } + GenericArgs::ParenthesizedElided(span) => GenericArgsCtor { + args: Default::default(), + constraints: &[], + parenthesized: hir::GenericArgsParentheses::ReturnTypeNotation, + span: *span, + }, }; gen_args_ctor.into_generic_args(self) } else { diff --git a/compiler/rustc_ast_lowering/src/path.rs b/compiler/rustc_ast_lowering/src/path.rs index 9d38e1e678471..1efa5bd3c4c6f 100644 --- a/compiler/rustc_ast_lowering/src/path.rs +++ b/compiler/rustc_ast_lowering/src/path.rs @@ -276,6 +276,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { ) } }, + GenericArgs::ParenthesizedElided(_span) => { + todo!() + } } } else { ( diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index ba4b6130b60c8..c0e8c4bf97789 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -1289,6 +1289,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { self.with_impl_trait(None, |this| this.visit_ty(ty)); } } + GenericArgs::ParenthesizedElided(_span) => {} } } @@ -1445,7 +1446,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { span: args.span, }); } - None => {} + Some(ast::GenericArgs::ParenthesizedElided(_)) | None => {} } } } @@ -1693,7 +1694,9 @@ fn deny_equality_constraints( // Add `` to `Foo`. match &mut assoc_path.segments[len].args { Some(args) => match args.deref_mut() { - GenericArgs::Parenthesized(_) => continue, + GenericArgs::Parenthesized(_) | GenericArgs::ParenthesizedElided(..) => { + continue; + } GenericArgs::AngleBracketed(args) => { args.args.push(arg); } diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs index e1c1a027a30a7..9cf3182daea59 100644 --- a/compiler/rustc_ast_passes/src/feature_gate.rs +++ b/compiler/rustc_ast_passes/src/feature_gate.rs @@ -1,6 +1,6 @@ use rustc_ast as ast; use rustc_ast::visit::{self, AssocCtxt, FnCtxt, FnKind, Visitor}; -use rustc_ast::{attr, AssocItemConstraint, AssocItemConstraintKind, NodeId}; +use rustc_ast::{attr, NodeId}; use rustc_ast::{token, PatKind}; use rustc_feature::{AttributeGate, BuiltinAttribute, Features, GateIssue, BUILTIN_ATTRIBUTE_MAP}; use rustc_session::parse::{feature_err, feature_err_issue, feature_warn}; @@ -445,23 +445,6 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { visit::walk_fn(self, fn_kind) } - fn visit_assoc_item_constraint(&mut self, constraint: &'a AssocItemConstraint) { - if let AssocItemConstraintKind::Bound { .. } = constraint.kind - && let Some(ast::GenericArgs::Parenthesized(args)) = constraint.gen_args.as_ref() - && args.inputs.is_empty() - && let ast::FnRetTy::Default(..) = args.output - { - gate!( - &self, - return_type_notation, - constraint.span, - "return type notation is experimental" - ); - } - - visit::walk_assoc_item_constraint(self, constraint) - } - fn visit_assoc_item(&mut self, i: &'a ast::AssocItem, ctxt: AssocCtxt) { let is_fn = match &i.kind { ast::AssocItemKind::Fn(_) => true, @@ -566,6 +549,7 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) { unsafe_extern_blocks, "`unsafe extern {}` blocks and `safe` keyword are experimental" ); + gate_all!(return_type_notation, "return type notation is experimental"); if !visitor.features.never_patterns { if let Some(spans) = spans.get(&sym::never_patterns) { @@ -611,10 +595,6 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) { gate_all_legacy_dont_use!(box_patterns, "box pattern syntax is experimental"); gate_all_legacy_dont_use!(trait_alias, "trait aliases are experimental"); - // Despite being a new feature, `where T: Trait`, which is RTN syntax now, - // used to be gated under associated_type_bounds, which are right above, so RTN needs to - // be too. - gate_all_legacy_dont_use!(return_type_notation, "return type notation is experimental"); gate_all_legacy_dont_use!(decl_macro, "`macro` is experimental"); gate_all_legacy_dont_use!(try_blocks, "`try` blocks are unstable"); gate_all_legacy_dont_use!(auto_traits, "`auto` traits are unstable"); diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs index 0225c95dca8e3..0568d368d8c4c 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state.rs @@ -1060,6 +1060,11 @@ impl<'a> PrintState<'a> for State<'a> { self.word(")"); self.print_fn_ret_ty(&data.output); } + ast::GenericArgs::ParenthesizedElided(_) => { + self.word("("); + self.word(".."); + self.word(")"); + } } } } diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 22a6c06bba323..5b126d37ed645 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -2413,7 +2413,7 @@ pub enum ImplItemKind<'hir> { /// * the `A: Bound` in `Trait` /// * the `RetTy` in `Trait(ArgTy, ArgTy) -> RetTy` /// * the `C = { Ct }` in `Trait` (feature `associated_const_equality`) -/// * the `f(): Bound` in `Trait` (feature `return_type_notation`) +/// * the `f(..): Bound` in `Trait` (feature `return_type_notation`) #[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct AssocItemConstraint<'hir> { pub hir_id: HirId, diff --git a/compiler/rustc_parse/messages.ftl b/compiler/rustc_parse/messages.ftl index f08efe60d96b8..e4c75ac11454a 100644 --- a/compiler/rustc_parse/messages.ftl +++ b/compiler/rustc_parse/messages.ftl @@ -45,10 +45,6 @@ parse_bad_assoc_type_bounds = bounds on associated types do not belong here parse_bad_item_kind = {$descr} is not supported in {$ctx} .help = consider moving the {$descr} out to a nearby module scope -parse_bad_return_type_notation_dotdot = - return type notation uses `()` instead of `(..)` for elided arguments - .suggestion = remove the `..` - parse_bad_return_type_notation_output = return type not allowed with return type notation .suggestion = remove the return type diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs index 8d49887f16441..6894f470d88fd 100644 --- a/compiler/rustc_parse/src/errors.rs +++ b/compiler/rustc_parse/src/errors.rs @@ -2567,14 +2567,6 @@ pub(crate) struct BadReturnTypeNotationOutput { pub span: Span, } -#[derive(Diagnostic)] -#[diag(parse_bad_return_type_notation_dotdot)] -pub(crate) struct BadReturnTypeNotationDotDot { - #[primary_span] - #[suggestion(code = "", applicability = "maybe-incorrect")] - pub span: Span, -} - #[derive(Diagnostic)] #[diag(parse_bad_assoc_type_bounds)] pub(crate) struct BadAssocTypeBounds { diff --git a/compiler/rustc_parse/src/parser/path.rs b/compiler/rustc_parse/src/parser/path.rs index da8d1194325b4..03c647dd5278e 100644 --- a/compiler/rustc_parse/src/parser/path.rs +++ b/compiler/rustc_parse/src/parser/path.rs @@ -353,18 +353,17 @@ impl<'a> Parser<'a> { })?; let span = lo.to(self.prev_token.span); AngleBracketedArgs { args, span }.into() - } else if self.may_recover() - && self.token.kind == token::OpenDelim(Delimiter::Parenthesis) + } else if self.token.kind == token::OpenDelim(Delimiter::Parenthesis) // FIXME(return_type_notation): Could also recover `...` here. && self.look_ahead(1, |tok| tok.kind == token::DotDot) { - self.bump(); - self.dcx() - .emit_err(errors::BadReturnTypeNotationDotDot { span: self.token.span }); - self.bump(); + self.bump(); // ( + self.bump(); // .. self.expect(&token::CloseDelim(Delimiter::Parenthesis))?; let span = lo.to(self.prev_token.span); + self.psess.gated_spans.gate(sym::return_type_notation, span); + if self.eat_noexpect(&token::RArrow) { let lo = self.prev_token.span; let ty = self.parse_ty()?; @@ -372,13 +371,7 @@ impl<'a> Parser<'a> { .emit_err(errors::BadReturnTypeNotationOutput { span: lo.to(ty.span) }); } - ParenthesizedArgs { - span, - inputs: ThinVec::new(), - inputs_span: span, - output: ast::FnRetTy::Default(self.prev_token.span.shrink_to_hi()), - } - .into() + P(ast::GenericArgs::ParenthesizedElided(span)) } else { // `(T, U) -> R` @@ -733,14 +726,6 @@ impl<'a> Parser<'a> { let span = lo.to(self.prev_token.span); - if let AssocItemConstraintKind::Bound { .. } = kind - && let Some(ast::GenericArgs::Parenthesized(args)) = &gen_args - && args.inputs.is_empty() - && let ast::FnRetTy::Default(..) = args.output - { - self.psess.gated_spans.gate(sym::return_type_notation, span); - } - let constraint = AssocItemConstraint { id: ast::DUMMY_NODE_ID, ident, gen_args, kind, span }; Ok(Some(AngleBracketedArg::Constraint(constraint))) diff --git a/compiler/rustc_passes/src/hir_stats.rs b/compiler/rustc_passes/src/hir_stats.rs index 0ba61f8e8b40f..0720efebf9721 100644 --- a/compiler/rustc_passes/src/hir_stats.rs +++ b/compiler/rustc_passes/src/hir_stats.rs @@ -695,7 +695,7 @@ impl<'v> ast_visit::Visitor<'v> for StatCollector<'v> { fn visit_generic_args(&mut self, g: &'v ast::GenericArgs) { record_variants!( (self, g, g, Id::None, ast, GenericArgs, GenericArgs), - [AngleBracketed, Parenthesized] + [AngleBracketed, Parenthesized, ParenthesizedElided] ); ast_visit::walk_generic_args(self, g) } diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 66a1c05289b7d..ad4e222f4deda 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -1221,6 +1221,7 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast, } } } + GenericArgs::ParenthesizedElided(_) => {} } } } diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 94cdce1025fe5..38963ef4ef092 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -350,6 +350,7 @@ impl<'a> From<&'a ast::PathSegment> for Segment { (args.span, found_lifetimes) } GenericArgs::Parenthesized(args) => (args.span, true), + GenericArgs::ParenthesizedElided(span) => (*span, true), } } else { (DUMMY_SP, false) diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index c4020f2a450bc..ddc3dd4270f7f 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -2557,7 +2557,7 @@ pub(crate) struct ProcMacro { /// * the `A: Bound` in `Trait` /// * the `RetTy` in `Trait(ArgTy, ArgTy) -> RetTy` /// * the `C = { Ct }` in `Trait` (feature `associated_const_equality`) -/// * the `f(): Bound` in `Trait` (feature `return_type_notation`) +/// * the `f(..): Bound` in `Trait` (feature `return_type_notation`) #[derive(Clone, PartialEq, Eq, Debug, Hash)] pub(crate) struct AssocItemConstraint { pub(crate) assoc: PathSegment, diff --git a/tests/crashes/125249.rs b/tests/crashes/125249.rs index 18196d7b34fe8..1cf6338a0d622 100644 --- a/tests/crashes/125249.rs +++ b/tests/crashes/125249.rs @@ -2,7 +2,7 @@ #![feature(return_position_impl_trait_in_trait, return_type_notation)] trait IntFactory { - fn stream(&self) -> impl IntFactory + Send>; + fn stream(&self) -> impl IntFactory + Send>; } pub fn main() {} diff --git a/tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.rs b/tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.rs index c23eff79ce2e5..a8c8a85c5aa68 100644 --- a/tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.rs +++ b/tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.rs @@ -13,7 +13,7 @@ fn foo>() {} fn bar (): Send>>() {} //~^ ERROR return type not allowed with return type notation -fn baz>() {} -//~^ ERROR return type notation uses `()` instead of `(..)` for elided arguments +fn baz>() {} +//~^ ERROR return type notation arguments must be elided with `..` fn main() {} diff --git a/tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.stderr b/tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.stderr index d95249efe4049..7e1695984f1c3 100644 --- a/tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.stderr +++ b/tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.stderr @@ -1,9 +1,3 @@ -error: return type notation uses `()` instead of `(..)` for elided arguments - --> $DIR/bad-inputs-and-output.rs:16:24 - | -LL | fn baz>() {} - | ^^ help: remove the `..` - warning: the feature `return_type_notation` is incomplete and may not be safe to use and/or cause compiler crashes --> $DIR/bad-inputs-and-output.rs:3:12 | @@ -25,5 +19,11 @@ error: return type not allowed with return type notation LL | fn bar (): Send>>() {} | ^^^^^^ help: remove the return type +error: return type notation arguments must be elided with `..` + --> $DIR/bad-inputs-and-output.rs:16:23 + | +LL | fn baz>() {} + | ^^ help: add `..`: `(..)` + error: aborting due to 3 previous errors; 1 warning emitted diff --git a/tests/ui/associated-type-bounds/return-type-notation/basic.rs b/tests/ui/associated-type-bounds/return-type-notation/basic.rs index 9755fd01c9764..be489a19a7ad2 100644 --- a/tests/ui/associated-type-bounds/return-type-notation/basic.rs +++ b/tests/ui/associated-type-bounds/return-type-notation/basic.rs @@ -17,7 +17,7 @@ async fn foo() -> Result<(), ()> { fn is_send(_: impl Send) {} fn test< - #[cfg(with)] T: Foo, + #[cfg(with)] T: Foo, #[cfg(without)] T: Foo, >() { is_send(foo::()); diff --git a/tests/ui/associated-type-bounds/return-type-notation/equality.rs b/tests/ui/associated-type-bounds/return-type-notation/equality.rs index ae38dce1818c9..95c16fa1e3f84 100644 --- a/tests/ui/associated-type-bounds/return-type-notation/equality.rs +++ b/tests/ui/associated-type-bounds/return-type-notation/equality.rs @@ -9,7 +9,7 @@ trait Trait { async fn method() {} } -fn test>>>() {} +fn test>>>() {} //~^ ERROR return type notation is not allowed to use type equality fn main() {} diff --git a/tests/ui/associated-type-bounds/return-type-notation/equality.stderr b/tests/ui/associated-type-bounds/return-type-notation/equality.stderr index d432e95773541..d76b1bd1c0510 100644 --- a/tests/ui/associated-type-bounds/return-type-notation/equality.stderr +++ b/tests/ui/associated-type-bounds/return-type-notation/equality.stderr @@ -10,8 +10,8 @@ LL | #![feature(return_type_notation)] error: return type notation is not allowed to use type equality --> $DIR/equality.rs:12:18 | -LL | fn test>>>() {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | fn test>>>() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 1 previous error; 1 warning emitted diff --git a/tests/ui/associated-type-bounds/return-type-notation/issue-120208-higher-ranked-const.rs b/tests/ui/associated-type-bounds/return-type-notation/issue-120208-higher-ranked-const.rs index 11728b879900e..4d026b7d1d859 100644 --- a/tests/ui/associated-type-bounds/return-type-notation/issue-120208-higher-ranked-const.rs +++ b/tests/ui/associated-type-bounds/return-type-notation/issue-120208-higher-ranked-const.rs @@ -9,7 +9,7 @@ trait HealthCheck { async fn do_health_check_par(hc: HC) where - HC: HealthCheck + Send + 'static, + HC: HealthCheck + Send + 'static, //~^ ERROR return type notation is not allowed for functions that have const parameters { } diff --git a/tests/ui/associated-type-bounds/return-type-notation/issue-120208-higher-ranked-const.stderr b/tests/ui/associated-type-bounds/return-type-notation/issue-120208-higher-ranked-const.stderr index 8a3f037d00321..12f32a75eda32 100644 --- a/tests/ui/associated-type-bounds/return-type-notation/issue-120208-higher-ranked-const.stderr +++ b/tests/ui/associated-type-bounds/return-type-notation/issue-120208-higher-ranked-const.stderr @@ -13,8 +13,8 @@ error: return type notation is not allowed for functions that have const paramet LL | async fn check() -> bool; | -------------- const parameter declared here ... -LL | HC: HealthCheck + Send + 'static, - | ^^^^^^^^^^^^^ +LL | HC: HealthCheck + Send + 'static, + | ^^^^^^^^^^^^^^^ error: aborting due to 1 previous error; 1 warning emitted diff --git a/tests/ui/associated-type-bounds/return-type-notation/missing.rs b/tests/ui/associated-type-bounds/return-type-notation/missing.rs index 9a8b77d00b714..3a04a56339ba5 100644 --- a/tests/ui/associated-type-bounds/return-type-notation/missing.rs +++ b/tests/ui/associated-type-bounds/return-type-notation/missing.rs @@ -7,7 +7,7 @@ trait Trait { async fn method() {} } -fn bar>() {} +fn bar>() {} //~^ ERROR associated function `methid` not found for `Trait` fn main() {} diff --git a/tests/ui/associated-type-bounds/return-type-notation/missing.stderr b/tests/ui/associated-type-bounds/return-type-notation/missing.stderr index db9cb9f49a305..5cb8e2642f51c 100644 --- a/tests/ui/associated-type-bounds/return-type-notation/missing.stderr +++ b/tests/ui/associated-type-bounds/return-type-notation/missing.stderr @@ -10,7 +10,7 @@ LL | #![feature(return_type_notation)] error[E0220]: associated function `methid` not found for `Trait` --> $DIR/missing.rs:10:17 | -LL | fn bar>() {} +LL | fn bar>() {} | ^^^^^^ help: there is an associated function with a similar name: `method` error: aborting due to 1 previous error; 1 warning emitted diff --git a/tests/ui/associated-type-bounds/return-type-notation/non-rpitit.rs b/tests/ui/associated-type-bounds/return-type-notation/non-rpitit.rs index db5f6fe389ea7..d283c6eab370d 100644 --- a/tests/ui/associated-type-bounds/return-type-notation/non-rpitit.rs +++ b/tests/ui/associated-type-bounds/return-type-notation/non-rpitit.rs @@ -5,7 +5,7 @@ trait Trait { fn method() {} } -fn test>() {} +fn test>() {} //~^ ERROR return type notation used on function that is not `async` and does not return `impl Trait` fn main() {} diff --git a/tests/ui/associated-type-bounds/return-type-notation/non-rpitit.stderr b/tests/ui/associated-type-bounds/return-type-notation/non-rpitit.stderr index 3e307c5f42ca4..79ced3c96ed5c 100644 --- a/tests/ui/associated-type-bounds/return-type-notation/non-rpitit.stderr +++ b/tests/ui/associated-type-bounds/return-type-notation/non-rpitit.stderr @@ -13,8 +13,8 @@ error: return type notation used on function that is not `async` and does not re LL | fn method() {} | ----------- this function must be `async` or return `impl Trait` ... -LL | fn test>() {} - | ^^^^^^^^^^^^^^ +LL | fn test>() {} + | ^^^^^^^^^^^^^^^^ | = note: function returns `()`, which is not compatible with associated type return bounds diff --git a/tests/ui/async-await/return-type-notation/issue-110963-early.rs b/tests/ui/async-await/return-type-notation/issue-110963-early.rs index 4090912f528c4..46b8fbf6f86e3 100644 --- a/tests/ui/async-await/return-type-notation/issue-110963-early.rs +++ b/tests/ui/async-await/return-type-notation/issue-110963-early.rs @@ -9,7 +9,7 @@ trait HealthCheck { async fn do_health_check_par(hc: HC) where - HC: HealthCheck + Send + 'static, + HC: HealthCheck + Send + 'static, { spawn(async move { let mut hc = hc; diff --git a/tests/ui/async-await/return-type-notation/issue-110963-late.rs b/tests/ui/async-await/return-type-notation/issue-110963-late.rs index e0e59b6c6adb2..cb9c0b97f1e99 100644 --- a/tests/ui/async-await/return-type-notation/issue-110963-late.rs +++ b/tests/ui/async-await/return-type-notation/issue-110963-late.rs @@ -10,7 +10,7 @@ trait HealthCheck { async fn do_health_check_par(hc: HC) where - HC: HealthCheck + Send + 'static, + HC: HealthCheck + Send + 'static, { spawn(async move { let mut hc = hc; diff --git a/tests/ui/async-await/return-type-notation/normalizing-self-auto-trait-issue-109924.rs b/tests/ui/async-await/return-type-notation/normalizing-self-auto-trait-issue-109924.rs index bee9ad2516ee2..24041ed080752 100644 --- a/tests/ui/async-await/return-type-notation/normalizing-self-auto-trait-issue-109924.rs +++ b/tests/ui/async-await/return-type-notation/normalizing-self-auto-trait-issue-109924.rs @@ -16,7 +16,7 @@ impl Foo for Bar { async fn bar(&self) {} } -fn build(_: T) where T: Foo {} +fn build(_: T) where T: Foo {} fn main() { build(Bar); diff --git a/tests/ui/async-await/return-type-notation/rtn-implied-in-supertrait.rs b/tests/ui/async-await/return-type-notation/rtn-implied-in-supertrait.rs index 365ca57400652..2f6e04c385384 100644 --- a/tests/ui/async-await/return-type-notation/rtn-implied-in-supertrait.rs +++ b/tests/ui/async-await/return-type-notation/rtn-implied-in-supertrait.rs @@ -16,7 +16,7 @@ trait Foo { async fn bar(&self) -> i32; } -trait SendFoo: Foo + Send {} +trait SendFoo: Foo + Send {} fn foobar(foo: impl SendFoo) -> JoinHandle { spawn(async move { diff --git a/tests/ui/async-await/return-type-notation/rtn-in-impl-signature.rs b/tests/ui/async-await/return-type-notation/rtn-in-impl-signature.rs index 637678692bd1f..1e971d0aea71d 100644 --- a/tests/ui/async-await/return-type-notation/rtn-in-impl-signature.rs +++ b/tests/ui/async-await/return-type-notation/rtn-in-impl-signature.rs @@ -7,7 +7,7 @@ trait Super1<'a> { fn bar<'b>() -> bool; } -impl Super1<'_, bar(): Send> for () {} +impl Super1<'_, bar(..): Send> for () {} //~^ ERROR associated item constraints are not allowed here //~| ERROR not all trait items implemented diff --git a/tests/ui/async-await/return-type-notation/rtn-in-impl-signature.stderr b/tests/ui/async-await/return-type-notation/rtn-in-impl-signature.stderr index 54960ae60bcca..b23dbc37a55cc 100644 --- a/tests/ui/async-await/return-type-notation/rtn-in-impl-signature.stderr +++ b/tests/ui/async-await/return-type-notation/rtn-in-impl-signature.stderr @@ -10,13 +10,13 @@ LL | #![feature(return_type_notation)] error[E0229]: associated item constraints are not allowed here --> $DIR/rtn-in-impl-signature.rs:10:17 | -LL | impl Super1<'_, bar(): Send> for () {} - | ^^^^^^^^^^^ associated item constraint not allowed here +LL | impl Super1<'_, bar(..): Send> for () {} + | ^^^^^^^^^^^^^ associated item constraint not allowed here | help: consider removing this associated item constraint | -LL | impl Super1<'_, bar(): Send> for () {} - | ~~~~~~~~~~~~~ +LL | impl Super1<'_, bar(..): Send> for () {} + | ~~~~~~~~~~~~~~~ error[E0046]: not all trait items implemented, missing: `bar` --> $DIR/rtn-in-impl-signature.rs:10:1 @@ -24,8 +24,8 @@ error[E0046]: not all trait items implemented, missing: `bar` LL | fn bar<'b>() -> bool; | --------------------- `bar` from trait ... -LL | impl Super1<'_, bar(): Send> for () {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `bar` in implementation +LL | impl Super1<'_, bar(..): Send> for () {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `bar` in implementation error: aborting due to 2 previous errors; 1 warning emitted diff --git a/tests/ui/async-await/return-type-notation/super-method-bound-ambig.rs b/tests/ui/async-await/return-type-notation/super-method-bound-ambig.rs index fa647ea0bc781..452568f3e4695 100644 --- a/tests/ui/async-await/return-type-notation/super-method-bound-ambig.rs +++ b/tests/ui/async-await/return-type-notation/super-method-bound-ambig.rs @@ -22,7 +22,7 @@ impl Foo for () {} fn test() where - T: Foo, + T: Foo, //~^ ERROR ambiguous associated function `test` in bounds of `Foo` { } diff --git a/tests/ui/async-await/return-type-notation/super-method-bound-ambig.stderr b/tests/ui/async-await/return-type-notation/super-method-bound-ambig.stderr index 4003aad6d03c3..9a6fdd7f2ac6b 100644 --- a/tests/ui/async-await/return-type-notation/super-method-bound-ambig.stderr +++ b/tests/ui/async-await/return-type-notation/super-method-bound-ambig.stderr @@ -16,8 +16,8 @@ LL | async fn test(); LL | async fn test(); | ---------------- ambiguous `test` from `Super2` ... -LL | T: Foo, - | ^^^^^^^^^^^^ ambiguous associated function `test` +LL | T: Foo, + | ^^^^^^^^^^^^^^ ambiguous associated function `test` error: aborting due to 1 previous error; 1 warning emitted diff --git a/tests/ui/async-await/return-type-notation/super-method-bound.rs b/tests/ui/async-await/return-type-notation/super-method-bound.rs index ad7ed5b283cf1..1aa8258a09b7d 100644 --- a/tests/ui/async-await/return-type-notation/super-method-bound.rs +++ b/tests/ui/async-await/return-type-notation/super-method-bound.rs @@ -16,7 +16,7 @@ impl Foo for () {} fn test() where - T: Foo, + T: Foo, { } diff --git a/tests/ui/async-await/return-type-notation/supertrait-bound.rs b/tests/ui/async-await/return-type-notation/supertrait-bound.rs index adb286a21d216..9c74c10b33319 100644 --- a/tests/ui/async-await/return-type-notation/supertrait-bound.rs +++ b/tests/ui/async-await/return-type-notation/supertrait-bound.rs @@ -6,6 +6,6 @@ trait IntFactory { fn stream(&self) -> impl Iterator; } -trait SendIntFactory: IntFactory + Send {} +trait SendIntFactory: IntFactory + Send {} fn main() {} diff --git a/tests/ui/async-await/return-type-notation/ty-or-ct-params.rs b/tests/ui/async-await/return-type-notation/ty-or-ct-params.rs index 328cd8d2ad02e..06a966df4451a 100644 --- a/tests/ui/async-await/return-type-notation/ty-or-ct-params.rs +++ b/tests/ui/async-await/return-type-notation/ty-or-ct-params.rs @@ -11,7 +11,7 @@ trait Foo { fn test() where - T: Foo, + T: Foo, //~^ ERROR return type notation is not allowed for functions that have const parameters //~| ERROR return type notation is not allowed for functions that have type parameters { diff --git a/tests/ui/async-await/return-type-notation/ty-or-ct-params.stderr b/tests/ui/async-await/return-type-notation/ty-or-ct-params.stderr index da94d9d1e6da4..1c000bc6c3318 100644 --- a/tests/ui/async-await/return-type-notation/ty-or-ct-params.stderr +++ b/tests/ui/async-await/return-type-notation/ty-or-ct-params.stderr @@ -13,17 +13,17 @@ error: return type notation is not allowed for functions that have type paramete LL | async fn bar() {} | - type parameter declared here ... -LL | T: Foo, - | ^^^^^^^^^^^ +LL | T: Foo, + | ^^^^^^^^^^^^^ error: return type notation is not allowed for functions that have const parameters - --> $DIR/ty-or-ct-params.rs:14:25 + --> $DIR/ty-or-ct-params.rs:14:27 | LL | async fn baz() {} | -------------- const parameter declared here ... -LL | T: Foo, - | ^^^^^^^^^^^ +LL | T: Foo, + | ^^^^^^^^^^^^^ error: aborting due to 2 previous errors; 1 warning emitted diff --git a/tests/ui/borrowck/alias-liveness/rtn-static.rs b/tests/ui/borrowck/alias-liveness/rtn-static.rs index 37f634a8e23cd..6aa5d8fc7a107 100644 --- a/tests/ui/borrowck/alias-liveness/rtn-static.rs +++ b/tests/ui/borrowck/alias-liveness/rtn-static.rs @@ -7,7 +7,7 @@ trait Foo { fn borrow(&mut self) -> impl Sized + '_; } -fn live_past_borrow>(mut t: T) { +fn live_past_borrow>(mut t: T) { let x = t.borrow(); drop(t); drop(x); @@ -15,7 +15,7 @@ fn live_past_borrow>(mut t: T) { // Test that the `'_` item bound in `borrow` does not cause us to // overlook the `'static` RTN bound. -fn overlapping_mut>(mut t: T) { +fn overlapping_mut>(mut t: T) { let x = t.borrow(); let x = t.borrow(); } diff --git a/tests/ui/feature-gates/feature-gate-return_type_notation.cfg.stderr b/tests/ui/feature-gates/feature-gate-return_type_notation.cfg.stderr index 41bd66b13e70d..18f46928fab54 100644 --- a/tests/ui/feature-gates/feature-gate-return_type_notation.cfg.stderr +++ b/tests/ui/feature-gates/feature-gate-return_type_notation.cfg.stderr @@ -1,33 +1,13 @@ error[E0658]: return type notation is experimental - --> $DIR/feature-gate-return_type_notation.rs:14:17 + --> $DIR/feature-gate-return_type_notation.rs:10:18 | -LL | fn foo>() {} - | ^^^^^^^^^ +LL | fn foo>() {} + | ^^^^ | = note: see issue #109417 for more information = help: add `#![feature(return_type_notation)]` 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: parenthesized generic arguments cannot be used in associated type constraints - --> $DIR/feature-gate-return_type_notation.rs:14:17 - | -LL | fn foo>() {} - | ^-- - | | - | help: remove these parentheses - -error: expected type, found function - --> $DIR/feature-gate-return_type_notation.rs:14:17 - | -LL | fn foo>() {} - | ^ unexpected function - | -note: the associated function is defined here - --> $DIR/feature-gate-return_type_notation.rs:10:5 - | -LL | async fn m(); - | ^^^^^^^^^^^^^ - -error: aborting due to 3 previous errors +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/feature-gates/feature-gate-return_type_notation.no.stderr b/tests/ui/feature-gates/feature-gate-return_type_notation.no.stderr index 79c626cef35dc..18f46928fab54 100644 --- a/tests/ui/feature-gates/feature-gate-return_type_notation.no.stderr +++ b/tests/ui/feature-gates/feature-gate-return_type_notation.no.stderr @@ -1,14 +1,13 @@ -warning: return type notation is experimental - --> $DIR/feature-gate-return_type_notation.rs:14:17 +error[E0658]: return type notation is experimental + --> $DIR/feature-gate-return_type_notation.rs:10:18 | -LL | fn foo>() {} - | ^^^^^^^^^ +LL | fn foo>() {} + | ^^^^ | = note: see issue #109417 for more information = help: add `#![feature(return_type_notation)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - = warning: unstable syntax can change at any point in the future, causing a hard error! - = note: for more information, see issue #65860 -warning: 1 warning emitted +error: aborting due to 1 previous error +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/feature-gates/feature-gate-return_type_notation.rs b/tests/ui/feature-gates/feature-gate-return_type_notation.rs index 7ae6cd0234be3..254b794e431e9 100644 --- a/tests/ui/feature-gates/feature-gate-return_type_notation.rs +++ b/tests/ui/feature-gates/feature-gate-return_type_notation.rs @@ -1,21 +1,13 @@ //@ edition: 2021 //@ revisions: cfg no -//@ [no] check-pass -// Since we're not adding new syntax, `cfg`'d out RTN must pass. - - trait Trait { #[allow(async_fn_in_trait)] async fn m(); } #[cfg(cfg)] -fn foo>() {} -//[cfg]~^ ERROR return type notation is experimental -//[cfg]~| ERROR parenthesized generic arguments cannot be used in associated type constraints -//[cfg]~| ERROR expected type, found function -//[no]~^^^^ WARN return type notation is experimental -//[no]~| WARN unstable syntax can change at any point in the future, causing a hard error! +fn foo>() {} +//~^ ERROR return type notation is experimental fn main() {} From 82b4af7511a430e53d2ed554771754552e5ecca8 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 28 Jun 2024 14:10:32 -0400 Subject: [PATCH 416/892] Make sure we deny unimplemented RTN on qpath segments --- compiler/rustc_ast_lowering/messages.ftl | 2 + compiler/rustc_ast_lowering/src/errors.rs | 5 ++ compiler/rustc_ast_lowering/src/path.rs | 16 ++++- .../return-type-notation/bare-path.rs | 26 ++++++++ .../return-type-notation/bare-path.stderr | 66 +++++++++++++++++++ 5 files changed, 112 insertions(+), 3 deletions(-) create mode 100644 tests/ui/associated-type-bounds/return-type-notation/bare-path.rs create mode 100644 tests/ui/associated-type-bounds/return-type-notation/bare-path.stderr diff --git a/compiler/rustc_ast_lowering/messages.ftl b/compiler/rustc_ast_lowering/messages.ftl index d6eb344fd1dbb..9ed93d481e773 100644 --- a/compiler/rustc_ast_lowering/messages.ftl +++ b/compiler/rustc_ast_lowering/messages.ftl @@ -43,6 +43,8 @@ ast_lowering_bad_return_type_notation_output = return type not allowed with return type notation .suggestion = remove the return type +ast_lowering_bad_return_type_notation_position = return type notation not allowed in this position yet + ast_lowering_base_expression_double_dot = base expression required after `..` .suggestion = add a base expression here diff --git a/compiler/rustc_ast_lowering/src/errors.rs b/compiler/rustc_ast_lowering/src/errors.rs index 6699c6e75f5ea..4c77892a6b753 100644 --- a/compiler/rustc_ast_lowering/src/errors.rs +++ b/compiler/rustc_ast_lowering/src/errors.rs @@ -399,6 +399,11 @@ pub enum BadReturnTypeNotation { #[suggestion(code = "(..)", applicability = "maybe-incorrect")] span: Span, }, + #[diag(ast_lowering_bad_return_type_notation_position)] + Position { + #[primary_span] + span: Span, + }, } #[derive(Diagnostic)] diff --git a/compiler/rustc_ast_lowering/src/path.rs b/compiler/rustc_ast_lowering/src/path.rs index 1efa5bd3c4c6f..c6c08649374dd 100644 --- a/compiler/rustc_ast_lowering/src/path.rs +++ b/compiler/rustc_ast_lowering/src/path.rs @@ -1,7 +1,8 @@ use crate::ImplTraitPosition; use super::errors::{ - AsyncBoundNotOnTrait, AsyncBoundOnlyForFnTraits, GenericTypeWithParentheses, UseAngleBrackets, + AsyncBoundNotOnTrait, AsyncBoundOnlyForFnTraits, BadReturnTypeNotation, + GenericTypeWithParentheses, UseAngleBrackets, }; use super::ResolverAstLoweringExt; use super::{GenericArgsCtor, LifetimeRes, ParenthesizedGenericArgs}; @@ -276,8 +277,17 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { ) } }, - GenericArgs::ParenthesizedElided(_span) => { - todo!() + GenericArgs::ParenthesizedElided(span) => { + self.dcx().emit_err(BadReturnTypeNotation::Position { span: *span }); + ( + GenericArgsCtor { + args: Default::default(), + constraints: &[], + parenthesized: hir::GenericArgsParentheses::ReturnTypeNotation, + span: *span, + }, + false, + ) } } } else { diff --git a/tests/ui/associated-type-bounds/return-type-notation/bare-path.rs b/tests/ui/associated-type-bounds/return-type-notation/bare-path.rs new file mode 100644 index 0000000000000..f507d82afec2f --- /dev/null +++ b/tests/ui/associated-type-bounds/return-type-notation/bare-path.rs @@ -0,0 +1,26 @@ +#![feature(return_type_notation)] +//~^ WARN the feature `return_type_notation` is incomplete + +trait Tr { + const CONST: usize; + + fn method() -> impl Sized; +} + +fn foo() +where + T::method(..): Send, + //~^ ERROR return type notation not allowed in this position yet + //~| ERROR expected type, found function + ::method(..): Send, + //~^ ERROR return type notation not allowed in this position yet + //~| ERROR expected associated type, found associated function `Tr::method` +{ + let _ = T::CONST::(..); + //~^ ERROR return type notation not allowed in this position yet + let _: T::method(..); + //~^ ERROR return type notation not allowed in this position yet + //~| ERROR expected type, found function +} + +fn main() {} diff --git a/tests/ui/associated-type-bounds/return-type-notation/bare-path.stderr b/tests/ui/associated-type-bounds/return-type-notation/bare-path.stderr new file mode 100644 index 0000000000000..cb45de59c7e23 --- /dev/null +++ b/tests/ui/associated-type-bounds/return-type-notation/bare-path.stderr @@ -0,0 +1,66 @@ +error[E0575]: expected associated type, found associated function `Tr::method` + --> $DIR/bare-path.rs:15:5 + | +LL | ::method(..): Send, + | ^^^^^^^^^^^^^^^^^^^^^ not a associated type + +warning: the feature `return_type_notation` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/bare-path.rs:1:12 + | +LL | #![feature(return_type_notation)] + | ^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #109417 for more information + = note: `#[warn(incomplete_features)]` on by default + +error: return type notation not allowed in this position yet + --> $DIR/bare-path.rs:19:23 + | +LL | let _ = T::CONST::(..); + | ^^^^ + +error: return type notation not allowed in this position yet + --> $DIR/bare-path.rs:21:21 + | +LL | let _: T::method(..); + | ^^^^ + +error: return type notation not allowed in this position yet + --> $DIR/bare-path.rs:12:14 + | +LL | T::method(..): Send, + | ^^^^ + +error: return type notation not allowed in this position yet + --> $DIR/bare-path.rs:15:22 + | +LL | ::method(..): Send, + | ^^^^ + +error: expected type, found function + --> $DIR/bare-path.rs:12:8 + | +LL | T::method(..): Send, + | ^^^^^^ unexpected function + | +note: the associated function is defined here + --> $DIR/bare-path.rs:7:5 + | +LL | fn method() -> impl Sized; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: expected type, found function + --> $DIR/bare-path.rs:21:15 + | +LL | let _: T::method(..); + | ^^^^^^ unexpected function + | +note: the associated function is defined here + --> $DIR/bare-path.rs:7:5 + | +LL | fn method() -> impl Sized; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 7 previous errors; 1 warning emitted + +For more information about this error, try `rustc --explain E0575`. From 99365a5a7ace1092852784c2fa71b7fd5ef25e5d Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 28 Jun 2024 14:18:36 -0400 Subject: [PATCH 417/892] Implement RTN support in rustfmt --- src/tools/rustfmt/src/types.rs | 34 +++++++++++-------- .../tests/target/return-type-notation.rs | 10 ++++++ 2 files changed, 29 insertions(+), 15 deletions(-) create mode 100644 src/tools/rustfmt/tests/target/return-type-notation.rs diff --git a/src/tools/rustfmt/src/types.rs b/src/tools/rustfmt/src/types.rs index c0bf9482b1143..c826547e9d001 100644 --- a/src/tools/rustfmt/src/types.rs +++ b/src/tools/rustfmt/src/types.rs @@ -484,21 +484,25 @@ fn rewrite_generic_args( span: Span, ) -> Option { match gen_args { - ast::GenericArgs::AngleBracketed(ref data) if !data.args.is_empty() => { - let args = data - .args - .iter() - .map(|x| match x { - ast::AngleBracketedArg::Arg(generic_arg) => { - SegmentParam::from_generic_arg(generic_arg) - } - ast::AngleBracketedArg::Constraint(constraint) => { - SegmentParam::Binding(constraint) - } - }) - .collect::>(); + ast::GenericArgs::AngleBracketed(ref data) => { + if data.args.is_empty() { + Some("".to_owned()) + } else { + let args = data + .args + .iter() + .map(|x| match x { + ast::AngleBracketedArg::Arg(generic_arg) => { + SegmentParam::from_generic_arg(generic_arg) + } + ast::AngleBracketedArg::Constraint(constraint) => { + SegmentParam::Binding(constraint) + } + }) + .collect::>(); - overflow::rewrite_with_angle_brackets(context, "", args.iter(), shape, span) + overflow::rewrite_with_angle_brackets(context, "", args.iter(), shape, span) + } } ast::GenericArgs::Parenthesized(ref data) => format_function_type( data.inputs.iter().map(|x| &**x), @@ -508,7 +512,7 @@ fn rewrite_generic_args( context, shape, ), - _ => Some("".to_owned()), + ast::GenericArgs::ParenthesizedElided(..) => Some("(..)".to_owned()), } } diff --git a/src/tools/rustfmt/tests/target/return-type-notation.rs b/src/tools/rustfmt/tests/target/return-type-notation.rs new file mode 100644 index 0000000000000..0f26e7e272b8b --- /dev/null +++ b/src/tools/rustfmt/tests/target/return-type-notation.rs @@ -0,0 +1,10 @@ +fn rtn() +where + T: Trait, + T::method(..): Send + 'static, +{ +} + +fn test() { + let x: T::method(..); +} From 18c248b6564ea750321cf9765f700def4265e490 Mon Sep 17 00:00:00 2001 From: Maybe Lapkin Date: Sun, 23 Jun 2024 23:53:28 +0200 Subject: [PATCH 418/892] Make `NEVER_TYPE_FALLBACK_FLOWING_INTO_UNSAFE` deny-by-default in e2024 --- compiler/rustc_lint_defs/src/builtin.rs | 1 + ...fallback-flowing-into-unsafe.e2015.stderr} | 20 +-- ...-fallback-flowing-into-unsafe.e2024.stderr | 116 ++++++++++++++++++ ...never-type-fallback-flowing-into-unsafe.rs | 46 +++++-- 4 files changed, 160 insertions(+), 23 deletions(-) rename tests/ui/never_type/{lint-never-type-fallback-flowing-into-unsafe.stderr => lint-never-type-fallback-flowing-into-unsafe.e2015.stderr} (86%) create mode 100644 tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.e2024.stderr diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index 1913b9d6a1c31..e270cbe610772 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -4197,6 +4197,7 @@ declare_lint! { reason: FutureIncompatibilityReason::FutureReleaseSemanticsChange, reference: "issue #123748 ", }; + @edition Edition2024 => Deny; report_in_external_macro } diff --git a/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.stderr b/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.e2015.stderr similarity index 86% rename from tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.stderr rename to tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.e2015.stderr index fbd92f8f662bb..a75039b8237a0 100644 --- a/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.stderr +++ b/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.e2015.stderr @@ -1,5 +1,5 @@ warning: never type fallback affects this call to an `unsafe` function - --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:8:18 + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:13:18 | LL | unsafe { mem::zeroed() } | ^^^^^^^^^^^^^ @@ -10,7 +10,7 @@ LL | unsafe { mem::zeroed() } = note: `#[warn(never_type_fallback_flowing_into_unsafe)]` on by default warning: never type fallback affects this call to an `unsafe` function - --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:23:13 + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:30:13 | LL | core::mem::transmute(Zst) | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -20,7 +20,7 @@ LL | core::mem::transmute(Zst) = help: specify the type explicitly warning: never type fallback affects this union access - --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:39:18 + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:47:18 | LL | unsafe { Union { a: () }.b } | ^^^^^^^^^^^^^^^^^ @@ -30,7 +30,7 @@ LL | unsafe { Union { a: () }.b } = help: specify the type explicitly warning: never type fallback affects this raw pointer dereference - --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:49:18 + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:58:18 | LL | unsafe { *ptr::from_ref(&()).cast() } | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -40,7 +40,7 @@ LL | unsafe { *ptr::from_ref(&()).cast() } = help: specify the type explicitly warning: never type fallback affects this call to an `unsafe` function - --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:67:18 + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:79:18 | LL | unsafe { internally_create(x) } | ^^^^^^^^^^^^^^^^^^^^ @@ -50,7 +50,7 @@ LL | unsafe { internally_create(x) } = help: specify the type explicitly warning: never type fallback affects this call to an `unsafe` function - --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:83:18 + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:97:18 | LL | unsafe { zeroed() } | ^^^^^^^^ @@ -60,7 +60,7 @@ LL | unsafe { zeroed() } = help: specify the type explicitly warning: never type fallback affects this `unsafe` function - --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:79:22 + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:92:22 | LL | let zeroed = mem::zeroed; | ^^^^^^^^^^^ @@ -70,7 +70,7 @@ LL | let zeroed = mem::zeroed; = help: specify the type explicitly warning: never type fallback affects this `unsafe` function - --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:98:17 + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:115:17 | LL | let f = internally_create; | ^^^^^^^^^^^^^^^^^ @@ -80,7 +80,7 @@ LL | let f = internally_create; = help: specify the type explicitly warning: never type fallback affects this call to an `unsafe` method - --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:122:13 + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:140:13 | LL | S(marker::PhantomData).create_out_of_thin_air() | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -90,7 +90,7 @@ LL | S(marker::PhantomData).create_out_of_thin_air() = help: specify the type explicitly warning: never type fallback affects this call to an `unsafe` function - --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:139:19 + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:158:19 | LL | match send_message::<_ /* ?0 */>() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.e2024.stderr b/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.e2024.stderr new file mode 100644 index 0000000000000..4138e9f8c8622 --- /dev/null +++ b/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.e2024.stderr @@ -0,0 +1,116 @@ +error: never type fallback affects this call to an `unsafe` function + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:13:18 + | +LL | unsafe { mem::zeroed() } + | ^^^^^^^^^^^^^ + | + = warning: this will change its meaning in a future release! + = note: for more information, see issue #123748 + = help: specify the type explicitly + = note: `#[deny(never_type_fallback_flowing_into_unsafe)]` on by default + +error: never type fallback affects this call to an `unsafe` function + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:30:13 + | +LL | core::mem::transmute(Zst) + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this will change its meaning in a future release! + = note: for more information, see issue #123748 + = help: specify the type explicitly + +error: never type fallback affects this union access + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:47:18 + | +LL | unsafe { Union { a: () }.b } + | ^^^^^^^^^^^^^^^^^ + | + = warning: this will change its meaning in a future release! + = note: for more information, see issue #123748 + = help: specify the type explicitly + +error: never type fallback affects this raw pointer dereference + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:58:18 + | +LL | unsafe { *ptr::from_ref(&()).cast() } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this will change its meaning in a future release! + = note: for more information, see issue #123748 + = help: specify the type explicitly + +error: never type fallback affects this call to an `unsafe` function + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:79:18 + | +LL | unsafe { internally_create(x) } + | ^^^^^^^^^^^^^^^^^^^^ + | + = warning: this will change its meaning in a future release! + = note: for more information, see issue #123748 + = help: specify the type explicitly + +error: never type fallback affects this call to an `unsafe` function + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:97:18 + | +LL | unsafe { zeroed() } + | ^^^^^^^^ + | + = warning: this will change its meaning in a future release! + = note: for more information, see issue #123748 + = help: specify the type explicitly + +error: never type fallback affects this `unsafe` function + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:92:22 + | +LL | let zeroed = mem::zeroed; + | ^^^^^^^^^^^ + | + = warning: this will change its meaning in a future release! + = note: for more information, see issue #123748 + = help: specify the type explicitly + +error: never type fallback affects this `unsafe` function + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:115:17 + | +LL | let f = internally_create; + | ^^^^^^^^^^^^^^^^^ + | + = warning: this will change its meaning in a future release! + = note: for more information, see issue #123748 + = help: specify the type explicitly + +error: never type fallback affects this call to an `unsafe` method + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:140:13 + | +LL | S(marker::PhantomData).create_out_of_thin_air() + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this will change its meaning in a future release! + = note: for more information, see issue #123748 + = help: specify the type explicitly + +error: never type fallback affects this call to an `unsafe` function + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:158:19 + | +LL | match send_message::<_ /* ?0 */>() { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | msg_send!(); + | ----------- in this macro invocation + | + = warning: this will change its meaning in a future release! + = note: for more information, see issue #123748 + = help: specify the type explicitly + = note: this error originates in the macro `msg_send` (in Nightly builds, run with -Z macro-backtrace for more info) + +warning: the type `!` does not permit zero-initialization + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:13:18 + | +LL | unsafe { mem::zeroed() } + | ^^^^^^^^^^^^^ this code causes undefined behavior when executed + | + = note: the `!` type has no valid value + = note: `#[warn(invalid_value)]` on by default + +error: aborting due to 10 previous errors; 1 warning emitted + diff --git a/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.rs b/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.rs index d65bfee843e3e..c96f4dda3f8ef 100644 --- a/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.rs +++ b/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.rs @@ -1,4 +1,9 @@ -//@ check-pass +//@ revisions: e2015 e2024 +//@[e2015] check-pass +//@[e2024] check-fail +//@[e2024] edition:2024 +//@[e2024] compile-flags: -Zunstable-options + use std::{marker, mem, ptr}; fn main() {} @@ -6,8 +11,10 @@ fn main() {} fn _zero() { if false { unsafe { mem::zeroed() } - //~^ warn: never type fallback affects this call to an `unsafe` function + //[e2015]~^ warn: never type fallback affects this call to an `unsafe` function + //[e2024]~^^ error: never type fallback affects this call to an `unsafe` function //~| warn: this will change its meaning in a future release! + //[e2024]~| warning: the type `!` does not permit zero-initialization } else { return; }; @@ -21,7 +28,8 @@ fn _trans() { unsafe { struct Zst; core::mem::transmute(Zst) - //~^ warn: never type fallback affects this call to an `unsafe` function + //[e2015]~^ warn: never type fallback affects this call to an `unsafe` function + //[e2024]~^^ error: never type fallback affects this call to an `unsafe` function //~| warn: this will change its meaning in a future release! } } else { @@ -37,7 +45,8 @@ fn _union() { } unsafe { Union { a: () }.b } - //~^ warn: never type fallback affects this union access + //[e2015]~^ warn: never type fallback affects this union access + //[e2024]~^^ error: never type fallback affects this union access //~| warn: this will change its meaning in a future release! } else { return; @@ -47,7 +56,8 @@ fn _union() { fn _deref() { if false { unsafe { *ptr::from_ref(&()).cast() } - //~^ warn: never type fallback affects this raw pointer dereference + //[e2015]~^ warn: never type fallback affects this raw pointer dereference + //[e2024]~^^ error: never type fallback affects this raw pointer dereference //~| warn: this will change its meaning in a future release! } else { return; @@ -57,7 +67,9 @@ fn _deref() { fn _only_generics() { if false { unsafe fn internally_create(_: Option) { - let _ = mem::zeroed::(); + unsafe { + let _ = mem::zeroed::(); + } } // We need the option (and unwrap later) to call a function in a way, @@ -65,7 +77,8 @@ fn _only_generics() { let x = None; unsafe { internally_create(x) } - //~^ warn: never type fallback affects this call to an `unsafe` function + //[e2015]~^ warn: never type fallback affects this call to an `unsafe` function + //[e2024]~^^ error: never type fallback affects this call to an `unsafe` function //~| warn: this will change its meaning in a future release! x.unwrap() @@ -77,11 +90,13 @@ fn _only_generics() { fn _stored_function() { if false { let zeroed = mem::zeroed; - //~^ warn: never type fallback affects this `unsafe` function + //[e2015]~^ warn: never type fallback affects this `unsafe` function + //[e2024]~^^ error: never type fallback affects this `unsafe` function //~| warn: this will change its meaning in a future release! unsafe { zeroed() } - //~^ warn: never type fallback affects this call to an `unsafe` function + //[e2015]~^ warn: never type fallback affects this call to an `unsafe` function + //[e2024]~^^ error: never type fallback affects this call to an `unsafe` function //~| warn: this will change its meaning in a future release! } else { return; @@ -91,12 +106,15 @@ fn _stored_function() { fn _only_generics_stored_function() { if false { unsafe fn internally_create(_: Option) { - let _ = mem::zeroed::(); + unsafe { + let _ = mem::zeroed::(); + } } let x = None; let f = internally_create; - //~^ warn: never type fallback affects this `unsafe` function + //[e2015]~^ warn: never type fallback affects this `unsafe` function + //[e2024]~^^ error: never type fallback affects this `unsafe` function //~| warn: this will change its meaning in a future release! unsafe { f(x) } @@ -120,7 +138,8 @@ fn _method() { if false { unsafe { S(marker::PhantomData).create_out_of_thin_air() - //~^ warn: never type fallback affects this call to an `unsafe` method + //[e2015]~^ warn: never type fallback affects this call to an `unsafe` method + //[e2024]~^^ error: never type fallback affects this call to an `unsafe` method //~| warn: this will change its meaning in a future release! } } else { @@ -137,7 +156,8 @@ fn _objc() { macro_rules! msg_send { () => { match send_message::<_ /* ?0 */>() { - //~^ warn: never type fallback affects this call to an `unsafe` function + //[e2015]~^ warn: never type fallback affects this call to an `unsafe` function + //[e2024]~^^ error: never type fallback affects this call to an `unsafe` function //~| warn: this will change its meaning in a future release! Ok(x) => x, Err(_) => loop {}, From 55b581689d5e75349c1b2a4e44d0b3177a4f945b Mon Sep 17 00:00:00 2001 From: Oneirical Date: Wed, 19 Jun 2024 10:45:45 -0400 Subject: [PATCH 419/892] rewrite unknown-mod-stdin to rmake --- .../tidy/src/allowed_run_make_makefiles.txt | 1 - tests/run-make/unknown-mod-stdin/Makefile | 8 ------ tests/run-make/unknown-mod-stdin/rmake.rs | 25 +++++++++++++++++++ 3 files changed, 25 insertions(+), 9 deletions(-) delete mode 100644 tests/run-make/unknown-mod-stdin/Makefile create mode 100644 tests/run-make/unknown-mod-stdin/rmake.rs diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index a29d57d160312..21e20d1026efa 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -187,7 +187,6 @@ run-make/track-path-dep-info/Makefile run-make/track-pgo-dep-info/Makefile run-make/translation/Makefile run-make/type-mismatch-same-crate-name/Makefile -run-make/unknown-mod-stdin/Makefile run-make/unstable-flag-required/Makefile run-make/used-cdylib-macos/Makefile run-make/volatile-intrinsics/Makefile diff --git a/tests/run-make/unknown-mod-stdin/Makefile b/tests/run-make/unknown-mod-stdin/Makefile deleted file mode 100644 index 313b0ba837e83..0000000000000 --- a/tests/run-make/unknown-mod-stdin/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -# ignore-windows - -include ../tools.mk - -all: - echo 'mod unknown;' | $(RUSTC) --crate-type rlib - >$(TMPDIR)/unknown-mod.stdout 2>$(TMPDIR)/unknown-mod.stderr || echo "failed successfully" - $(RUSTC_TEST_OP) "$(TMPDIR)"/unknown-mod.stdout unknown-mod.stdout - $(RUSTC_TEST_OP) "$(TMPDIR)"/unknown-mod.stderr unknown-mod.stderr diff --git a/tests/run-make/unknown-mod-stdin/rmake.rs b/tests/run-make/unknown-mod-stdin/rmake.rs new file mode 100644 index 0000000000000..0fe5c78ed0ff0 --- /dev/null +++ b/tests/run-make/unknown-mod-stdin/rmake.rs @@ -0,0 +1,25 @@ +// Rustc displays a compilation error when it finds a `mod` (module) +// statement referencing a file that does not exist. However, a bug from 2019 +// caused invalid `mod` statements to silently insert empty inline modules +// instead of showing an error if the invalid `mod` statement had been passed +// through standard input. This test checks that this bug does not make a resurgence. +// See https://github.com/rust-lang/rust/issues/65601 + +// NOTE: This is not a UI test, because the bug which this test +// is checking for is specifically tied to passing +// `mod unknown;` through standard input. + +use run_make_support::{diff, rustc}; + +fn main() { + let out = rustc().crate_type("rlib").stdin(b"mod unknown;").arg("-").run_fail(); + diff() + .actual_text("actual-stdout", out.stdout_utf8()) + .expected_file("unknown-mod.stdout") + .run(); + diff() + .actual_text("actual-stderr", out.stderr_utf8()) + .expected_file("unknown-mod.stderr") + .normalize(r#"\\"#, "/") + .run(); +} From a4f3e5f725c82b22eecf6576798f07a60b5ea7f5 Mon Sep 17 00:00:00 2001 From: Oneirical Date: Wed, 19 Jun 2024 11:09:05 -0400 Subject: [PATCH 420/892] rewrite and slightly rename issue-68794-textrel-on-minimal-lib --- .../tidy/src/allowed_run_make_makefiles.txt | 1 - .../Makefile | 18 ----------- .../bar.c | 0 .../foo.rs | 0 .../run-make/textrel-on-minimal-lib/rmake.rs | 30 +++++++++++++++++++ 5 files changed, 30 insertions(+), 19 deletions(-) delete mode 100644 tests/run-make/issue-68794-textrel-on-minimal-lib/Makefile rename tests/run-make/{issue-68794-textrel-on-minimal-lib => textrel-on-minimal-lib}/bar.c (100%) rename tests/run-make/{issue-68794-textrel-on-minimal-lib => textrel-on-minimal-lib}/foo.rs (100%) create mode 100644 tests/run-make/textrel-on-minimal-lib/rmake.rs diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index 21e20d1026efa..dfbd3773d46c4 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -70,7 +70,6 @@ run-make/issue-37839/Makefile run-make/issue-40535/Makefile run-make/issue-47384/Makefile run-make/issue-47551/Makefile -run-make/issue-68794-textrel-on-minimal-lib/Makefile run-make/issue-69368/Makefile run-make/issue-83045/Makefile run-make/issue-83112-incr-test-moved-file/Makefile diff --git a/tests/run-make/issue-68794-textrel-on-minimal-lib/Makefile b/tests/run-make/issue-68794-textrel-on-minimal-lib/Makefile deleted file mode 100644 index 6140b39c0e2aa..0000000000000 --- a/tests/run-make/issue-68794-textrel-on-minimal-lib/Makefile +++ /dev/null @@ -1,18 +0,0 @@ -# ignore-cross-compile -# Regression test for issue #68794 -# -# Verify that no text relocations are accidentally introduced by linking a -# minimal rust staticlib. -# -# The test links a rust static library into a shared library, and checks that -# the linker doesn't have to flag the resulting file as containing TEXTRELs. - -include ../tools.mk - -# only-linux - -all: - $(RUSTC) foo.rs - $(CC) bar.c $(call STATICLIB,foo) -fPIC -shared -o $(call DYLIB,bar) \ - $(EXTRACFLAGS) $(EXTRACXXFLAGS) - readelf -d $(call DYLIB,bar) | grep TEXTREL; test $$? -eq 1 diff --git a/tests/run-make/issue-68794-textrel-on-minimal-lib/bar.c b/tests/run-make/textrel-on-minimal-lib/bar.c similarity index 100% rename from tests/run-make/issue-68794-textrel-on-minimal-lib/bar.c rename to tests/run-make/textrel-on-minimal-lib/bar.c diff --git a/tests/run-make/issue-68794-textrel-on-minimal-lib/foo.rs b/tests/run-make/textrel-on-minimal-lib/foo.rs similarity index 100% rename from tests/run-make/issue-68794-textrel-on-minimal-lib/foo.rs rename to tests/run-make/textrel-on-minimal-lib/foo.rs diff --git a/tests/run-make/textrel-on-minimal-lib/rmake.rs b/tests/run-make/textrel-on-minimal-lib/rmake.rs new file mode 100644 index 0000000000000..4c27295591595 --- /dev/null +++ b/tests/run-make/textrel-on-minimal-lib/rmake.rs @@ -0,0 +1,30 @@ +// Verify that no text relocations are accidentally introduced by linking a +// minimal rust staticlib. +// The test links a rust static library into a shared library, and checks that +// the linker doesn't have to flag the resulting file as containing TEXTRELs. +// This bug otherwise breaks Android builds, which forbid TEXTRELs. +// See https://github.com/rust-lang/rust/issues/68794 + +//@ ignore-cross-compile +//FIXME(Oneirical): check that it works on more than just only-linux + +use run_make_support::{ + cc, dynamic_lib_name, extra_c_flags, extra_cxx_flags, llvm_readobj, rustc, static_lib_name, +}; + +fn main() { + rustc().input("foo.rs").run(); + cc().input("bar.c") + .input(static_lib_name("foo")) + .out_exe(&dynamic_lib_name("bar")) + .arg("-fPIC") + .arg("-shared") + .args(&extra_c_flags()) + .args(&extra_cxx_flags()) + .run(); + llvm_readobj() + .input(dynamic_lib_name("bar")) + .arg("--dynamic") + .run() + .assert_stdout_not_contains("TEXTREL"); +} From ec1ed26263b85fcc22eed85cb8836b14275e1e49 Mon Sep 17 00:00:00 2001 From: Oneirical Date: Wed, 19 Jun 2024 11:31:13 -0400 Subject: [PATCH 421/892] rewrite raw-dylib-cross-compilation to rmake --- .../tidy/src/allowed_run_make_makefiles.txt | 1 - .../raw-dylib-cross-compilation/Makefile | 20 --------- .../raw-dylib-cross-compilation/rmake.rs | 41 +++++++++++++++++++ 3 files changed, 41 insertions(+), 21 deletions(-) delete mode 100644 tests/run-make/raw-dylib-cross-compilation/Makefile create mode 100644 tests/run-make/raw-dylib-cross-compilation/rmake.rs diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index dfbd3773d46c4..336d894ac7501 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -136,7 +136,6 @@ run-make/profile/Makefile run-make/prune-link-args/Makefile run-make/raw-dylib-alt-calling-convention/Makefile run-make/raw-dylib-c/Makefile -run-make/raw-dylib-cross-compilation/Makefile run-make/raw-dylib-custom-dlltool/Makefile run-make/raw-dylib-import-name-type/Makefile run-make/raw-dylib-inline-cross-dylib/Makefile diff --git a/tests/run-make/raw-dylib-cross-compilation/Makefile b/tests/run-make/raw-dylib-cross-compilation/Makefile deleted file mode 100644 index 2524f8500e154..0000000000000 --- a/tests/run-make/raw-dylib-cross-compilation/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -# Tests that raw-dylib cross compilation works correctly - -# needs-dlltool - -# i686 dlltool.exe can't product x64 binaries. -# ignore-i686-pc-windows-gnu - -include ../tools.mk - -all: - # Build as x86 and make sure that we have x86 objects only. - $(RUSTC) --crate-type lib --crate-name i686_raw_dylib_test --target i686-pc-windows-gnu lib.rs - "$(LLVM_BIN_DIR)"/llvm-objdump -a $(TMPDIR)/libi686_raw_dylib_test.rlib > $(TMPDIR)/i686.objdump.txt - $(CGREP) "file format coff-i386" < $(TMPDIR)/i686.objdump.txt - $(CGREP) -v "file format coff-x86-64" < $(TMPDIR)/i686.objdump.txt - # Build as x64 and make sure that we have x64 objects only. - $(RUSTC) --crate-type lib --crate-name x64_raw_dylib_test --target x86_64-pc-windows-gnu lib.rs - "$(LLVM_BIN_DIR)"/llvm-objdump -a $(TMPDIR)/libx64_raw_dylib_test.rlib > $(TMPDIR)/x64.objdump.txt - $(CGREP) "file format coff-x86-64" < $(TMPDIR)/x64.objdump.txt - $(CGREP) -v "file format coff-i386" < $(TMPDIR)/x64.objdump.txt diff --git a/tests/run-make/raw-dylib-cross-compilation/rmake.rs b/tests/run-make/raw-dylib-cross-compilation/rmake.rs new file mode 100644 index 0000000000000..994345a197c40 --- /dev/null +++ b/tests/run-make/raw-dylib-cross-compilation/rmake.rs @@ -0,0 +1,41 @@ +// When cross-compiling using `raw-dylib`, rustc would try to fetch some +// very specific `dlltool` to complete the cross-compilation (such as `i686-w64-mingw32-dlltool`) +// when Windows only calls it `dlltool`. This test performs some cross-compilation in a +// way that previously failed due to this bug, and checks that it succeeds. +// See https://github.com/rust-lang/rust/pull/108355 + +//@ ignore-i686-pc-windows-msvc +// Reason: dlltool on this distribution is unable to produce x64 binaries +//@ needs-dlltool +// Reason: this is the utility being checked by this test + +use run_make_support::{llvm_objdump, rust_lib_name, rustc}; + +fn main() { + // Build as x86 and make sure that we have x86 objects only. + rustc() + .crate_type("lib") + .crate_name("i686_raw_dylib_test") + .target("i686-pc-windows-gnu") + .input("lib.rs") + .run(); + llvm_objdump() + .arg("-a") + .input(rust_lib_name("i686_raw_dylib_test")) + .run() + .assert_stdout_contains("file format coff-i386") + .assert_stdout_not_contains("file format coff-x86-64"); + // Build as x64 and make sure that we have x64 objects only. + rustc() + .crate_type("lib") + .crate_name("x64_raw_dylib_test") + .target("x86-64-pc-windows-gnu") + .input("lib.rs") + .run(); + llvm_objdump() + .arg("-a") + .input(rust_lib_name("i686_raw_dylib_test")) + .run() + .assert_stdout_not_contains("file format coff-i386") + .assert_stdout_contains("file format coff-x86-64"); +} From 4c9eeda36d24e1da8bdf74bd344cd98cb4b98c09 Mon Sep 17 00:00:00 2001 From: Oneirical Date: Wed, 19 Jun 2024 11:38:22 -0400 Subject: [PATCH 422/892] rewrite used-cdylib-macos to rmake --- src/tools/compiletest/src/command-list.rs | 2 ++ .../tidy/src/allowed_run_make_makefiles.txt | 1 - .../raw-dylib-cross-compilation/rmake.rs | 6 +++--- tests/run-make/textrel-on-minimal-lib/rmake.rs | 3 ++- tests/run-make/used-cdylib-macos/Makefile | 11 ----------- tests/run-make/used-cdylib-macos/rmake.rs | 16 ++++++++++++++++ 6 files changed, 23 insertions(+), 16 deletions(-) delete mode 100644 tests/run-make/used-cdylib-macos/Makefile create mode 100644 tests/run-make/used-cdylib-macos/rmake.rs diff --git a/src/tools/compiletest/src/command-list.rs b/src/tools/compiletest/src/command-list.rs index 6e1685a8a9456..6735e9faa7a67 100644 --- a/src/tools/compiletest/src/command-list.rs +++ b/src/tools/compiletest/src/command-list.rs @@ -53,6 +53,7 @@ const KNOWN_DIRECTIVE_NAMES: &[&str] = &[ "ignore-gnu", "ignore-haiku", "ignore-horizon", + "ignore-i686-pc-windows-gnu", "ignore-i686-pc-windows-msvc", "ignore-illumos", "ignore-ios", @@ -174,6 +175,7 @@ const KNOWN_DIRECTIVE_NAMES: &[&str] = &[ "only-bpf", "only-cdb", "only-gnu", + "only-i686-pc-windows-gnu", "only-i686-pc-windows-msvc", "only-ios", "only-linux", diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index 336d894ac7501..73ef7c5ba2579 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -186,7 +186,6 @@ run-make/track-pgo-dep-info/Makefile run-make/translation/Makefile run-make/type-mismatch-same-crate-name/Makefile run-make/unstable-flag-required/Makefile -run-make/used-cdylib-macos/Makefile run-make/volatile-intrinsics/Makefile run-make/wasm-exceptions-nostd/Makefile run-make/wasm-override-linker/Makefile diff --git a/tests/run-make/raw-dylib-cross-compilation/rmake.rs b/tests/run-make/raw-dylib-cross-compilation/rmake.rs index 994345a197c40..3eb55546314df 100644 --- a/tests/run-make/raw-dylib-cross-compilation/rmake.rs +++ b/tests/run-make/raw-dylib-cross-compilation/rmake.rs @@ -4,7 +4,7 @@ // way that previously failed due to this bug, and checks that it succeeds. // See https://github.com/rust-lang/rust/pull/108355 -//@ ignore-i686-pc-windows-msvc +//@ ignore-i686-pc-windows-gnu // Reason: dlltool on this distribution is unable to produce x64 binaries //@ needs-dlltool // Reason: this is the utility being checked by this test @@ -29,12 +29,12 @@ fn main() { rustc() .crate_type("lib") .crate_name("x64_raw_dylib_test") - .target("x86-64-pc-windows-gnu") + .target("x86_64-pc-windows-gnu") .input("lib.rs") .run(); llvm_objdump() .arg("-a") - .input(rust_lib_name("i686_raw_dylib_test")) + .input(rust_lib_name("x64_raw_dylib_test")) .run() .assert_stdout_not_contains("file format coff-i386") .assert_stdout_contains("file format coff-x86-64"); diff --git a/tests/run-make/textrel-on-minimal-lib/rmake.rs b/tests/run-make/textrel-on-minimal-lib/rmake.rs index 4c27295591595..eba664479f112 100644 --- a/tests/run-make/textrel-on-minimal-lib/rmake.rs +++ b/tests/run-make/textrel-on-minimal-lib/rmake.rs @@ -6,7 +6,8 @@ // See https://github.com/rust-lang/rust/issues/68794 //@ ignore-cross-compile -//FIXME(Oneirical): check that it works on more than just only-linux +//@ ignore-windows +// Reason: There is no `bar.dll` produced by CC to run readobj on use run_make_support::{ cc, dynamic_lib_name, extra_c_flags, extra_cxx_flags, llvm_readobj, rustc, static_lib_name, diff --git a/tests/run-make/used-cdylib-macos/Makefile b/tests/run-make/used-cdylib-macos/Makefile deleted file mode 100644 index bdf914a1ca950..0000000000000 --- a/tests/run-make/used-cdylib-macos/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -include ../tools.mk - -# only-apple -# -# This checks that `#[used]` passes through to the linker on -# Apple targets. This is subject to change in the future, see -# https://github.com/rust-lang/rust/pull/93718 for discussion - -all: - $(RUSTC) -Copt-level=3 dylib_used.rs - nm $(TMPDIR)/libdylib_used.dylib | $(CGREP) VERY_IMPORTANT_SYMBOL diff --git a/tests/run-make/used-cdylib-macos/rmake.rs b/tests/run-make/used-cdylib-macos/rmake.rs new file mode 100644 index 0000000000000..ad95ad640f0c1 --- /dev/null +++ b/tests/run-make/used-cdylib-macos/rmake.rs @@ -0,0 +1,16 @@ +// This checks that `#[used]` passes through to the linker on +// Apple targets. This is subject to change in the future. +// See https://github.com/rust-lang/rust/pull/93718 + +//@ only-apple + +use run_make_support::{dynamic_lib_name, llvm_readobj, rustc}; + +fn main() { + rustc().opt_level("3").input("dylib_used.rs").run(); + llvm_readobj() + .input(dynamic_lib_name("dylib_used")) + .arg("--all") + .run() + .assert_stdout_contains("VERY_IMPORTANT_SYMBOL"); +} From 17950828420fa2068214b906e9fea98a771e64e8 Mon Sep 17 00:00:00 2001 From: Oneirical Date: Thu, 27 Jun 2024 14:38:30 -0400 Subject: [PATCH 423/892] rmeta_contains functions for remap-path-prefix --- Cargo.lock | 1 + src/tools/run-make-support/Cargo.toml | 1 + src/tools/run-make-support/src/lib.rs | 1 + tests/run-make/remap-path-prefix/rmake.rs | 51 ++++++++++++++++++----- 4 files changed, 43 insertions(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0182eca05058d..f6293f9626e13 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3401,6 +3401,7 @@ name = "run_make_support" version = "0.2.0" dependencies = [ "ar", + "bstr", "gimli 0.28.1", "object 0.34.0", "regex", diff --git a/src/tools/run-make-support/Cargo.toml b/src/tools/run-make-support/Cargo.toml index e3837a2f8cc4e..ec3b8a96ef3b6 100644 --- a/src/tools/run-make-support/Cargo.toml +++ b/src/tools/run-make-support/Cargo.toml @@ -4,6 +4,7 @@ version = "0.2.0" edition = "2021" [dependencies] +bstr = "1.6.0" object = "0.34.0" similar = "2.5.0" wasmparser = "0.118.2" diff --git a/src/tools/run-make-support/src/lib.rs b/src/tools/run-make-support/src/lib.rs index 771cda630af6a..31b913810b665 100644 --- a/src/tools/run-make-support/src/lib.rs +++ b/src/tools/run-make-support/src/lib.rs @@ -21,6 +21,7 @@ use std::io; use std::panic; use std::path::{Path, PathBuf}; +pub use bstr; pub use gimli; pub use object; pub use regex; diff --git a/tests/run-make/remap-path-prefix/rmake.rs b/tests/run-make/remap-path-prefix/rmake.rs index 4d98dcf6131cd..62c0368e4b3a4 100644 --- a/tests/run-make/remap-path-prefix/rmake.rs +++ b/tests/run-make/remap-path-prefix/rmake.rs @@ -3,9 +3,8 @@ // successfully remapped to "/the/aux" in the rmeta files. // See https://github.com/rust-lang/rust/pull/85344 -// FIXME(Oneirical): check if works without ignore-windows - -use run_make_support::{invalid_utf8_contains, invalid_utf8_not_contains, is_darwin, rustc}; +use run_make_support::bstr::ByteSlice; +use run_make_support::{bstr, fs_wrapper, is_darwin, rustc}; fn main() { let mut out_simple = rustc(); @@ -34,8 +33,8 @@ fn main() { .input("auxiliary/lib.rs"); out_simple.run(); - invalid_utf8_contains("liblib.rmeta", "/the/aux/lib.rs"); - invalid_utf8_not_contains("liblib.rmeta", "auxiliary"); + rmeta_contains("/the/aux/lib.rs"); + rmeta_not_contains("auxiliary"); out_object.arg("-Zremap-path-scope=object"); out_macro.arg("-Zremap-path-scope=macro"); @@ -47,12 +46,42 @@ fn main() { } out_object.run(); - invalid_utf8_contains("liblib.rmeta", "/the/aux/lib.rs"); - invalid_utf8_not_contains("liblib.rmeta", "auxiliary"); + rmeta_contains("/the/aux/lib.rs"); + rmeta_not_contains("auxiliary"); out_macro.run(); - invalid_utf8_contains("liblib.rmeta", "/the/aux/lib.rs"); - invalid_utf8_not_contains("liblib.rmeta", "auxiliary"); + rmeta_contains("/the/aux/lib.rs"); + rmeta_not_contains("auxiliary"); out_diagobj.run(); - invalid_utf8_contains("liblib.rmeta", "/the/aux/lib.rs"); - invalid_utf8_not_contains("liblib.rmeta", "auxiliary"); + rmeta_contains("/the/aux/lib.rs"); + rmeta_not_contains("auxiliary"); +} + +//FIXME(Oneirical): These could be generalized into run_make_support +// helper functions. +fn rmeta_contains(expected: &str) { + // Normalize to account for path differences in Windows. + if !bstr::BString::from(fs_wrapper::read("liblib.rmeta")) + .replace(b"\\", b"/") + .contains_str(expected) + { + eprintln!("=== FILE CONTENTS (LOSSY) ==="); + eprintln!("{}", String::from_utf8_lossy(&fs_wrapper::read("liblib.rmeta"))); + eprintln!("=== SPECIFIED TEXT ==="); + eprintln!("{}", expected); + panic!("specified text was not found in file"); + } +} + +fn rmeta_not_contains(expected: &str) { + // Normalize to account for path differences in Windows. + if bstr::BString::from(fs_wrapper::read("liblib.rmeta")) + .replace(b"\\", b"/") + .contains_str(expected) + { + eprintln!("=== FILE CONTENTS (LOSSY) ==="); + eprintln!("{}", String::from_utf8_lossy(&fs_wrapper::read("liblib.rmeta"))); + eprintln!("=== SPECIFIED TEXT ==="); + eprintln!("{}", expected); + panic!("specified text was not found in file"); + } } From 16df91b97ad1df021ccd2203c974f416aae7e76b Mon Sep 17 00:00:00 2001 From: Oneirical Date: Wed, 26 Jun 2024 14:56:11 -0400 Subject: [PATCH 424/892] rewrite extern-flag-pathless to rmake --- .../tidy/src/allowed_run_make_makefiles.txt | 1 - tests/run-make/extern-flag-pathless/Makefile | 34 ---------------- tests/run-make/extern-flag-pathless/rmake.rs | 40 +++++++++++++++++++ 3 files changed, 40 insertions(+), 35 deletions(-) delete mode 100644 tests/run-make/extern-flag-pathless/Makefile create mode 100644 tests/run-make/extern-flag-pathless/rmake.rs diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index a29d57d160312..463edb461e824 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -33,7 +33,6 @@ run-make/env-dep-info/Makefile run-make/export-executable-symbols/Makefile run-make/extern-diff-internal-name/Makefile run-make/extern-flag-disambiguates/Makefile -run-make/extern-flag-pathless/Makefile run-make/extern-fn-explicit-align/Makefile run-make/extern-fn-generic/Makefile run-make/extern-fn-mangle/Makefile diff --git a/tests/run-make/extern-flag-pathless/Makefile b/tests/run-make/extern-flag-pathless/Makefile deleted file mode 100644 index 36b374e0d2e1d..0000000000000 --- a/tests/run-make/extern-flag-pathless/Makefile +++ /dev/null @@ -1,34 +0,0 @@ -# ignore-cross-compile -include ../tools.mk - -# Test mixing pathless --extern with paths. - -# Test for static linking by checking that the binary runs if the dylib -# is removed and test for dynamic linking by checking that the binary -# fails to run if the dylib is removed. - -all: - $(RUSTC) bar.rs --crate-type=rlib --crate-type=dylib -Cprefer-dynamic - - # rlib preferred over dylib - $(RUSTC) foo.rs --extern bar - mv $(call DYLIB,bar) $(TMPDIR)/bar.tmp - $(call RUN,foo) - mv $(TMPDIR)/bar.tmp $(call DYLIB,bar) - - $(RUSTC) foo.rs --extern bar=$(TMPDIR)/libbar.rlib --extern bar - mv $(call DYLIB,bar) $(TMPDIR)/bar.tmp - $(call RUN,foo) - mv $(TMPDIR)/bar.tmp $(call DYLIB,bar) - - # explicit --extern overrides pathless - $(RUSTC) foo.rs --extern bar=$(call DYLIB,bar) --extern bar - mv $(call DYLIB,bar) $(TMPDIR)/bar.tmp - $(call FAIL,foo) - mv $(TMPDIR)/bar.tmp $(call DYLIB,bar) - - # prefer-dynamic does what it says - $(RUSTC) foo.rs --extern bar -C prefer-dynamic - mv $(call DYLIB,bar) $(TMPDIR)/bar.tmp - $(call FAIL,foo) - mv $(TMPDIR)/bar.tmp $(call DYLIB,bar) diff --git a/tests/run-make/extern-flag-pathless/rmake.rs b/tests/run-make/extern-flag-pathless/rmake.rs new file mode 100644 index 0000000000000..2f151136c33c1 --- /dev/null +++ b/tests/run-make/extern-flag-pathless/rmake.rs @@ -0,0 +1,40 @@ +// It is possible, since #64882, to use the --extern flag without an explicit +// path. In the event of two --extern flags, the explicit one with a path will take +// priority, but otherwise, it is a more concise way of fetching specific libraries. +// This test checks that the default priority of explicit extern flags and rlibs is +// respected. +// See https://github.com/rust-lang/rust/pull/64882 + +use run_make_support::{dynamic_lib_name, fs_wrapper, run, run_fail, rust_lib_name, rustc}; + +fn main() { + rustc().input("bar.rs").crate_type("rlib").crate_type("dylib").arg("-Cprefer-dynamic").run(); + + // By default, the rlib has priority over the dylib. + rustc().input("foo.rs").arg("--extern").arg("bar").run(); + fs_wrapper::rename(dynamic_lib_name("bar"), "bar.tmp"); + run("foo"); + fs_wrapper::rename("bar.tmp", dynamic_lib_name("bar")); + + rustc().input("foo.rs").extern_("bar", rust_lib_name("bar")).arg("--extern").arg("bar").run(); + fs_wrapper::rename(dynamic_lib_name("bar"), "bar.tmp"); + run("foo"); + fs_wrapper::rename("bar.tmp", dynamic_lib_name("bar")); + + // The first explicit usage of extern overrides the second pathless --extern bar. + rustc() + .input("foo.rs") + .extern_("bar", dynamic_lib_name("bar")) + .arg("--extern") + .arg("bar") + .run(); + fs_wrapper::rename(dynamic_lib_name("bar"), "bar.tmp"); + run_fail("foo"); + fs_wrapper::rename("bar.tmp", dynamic_lib_name("bar")); + + // With prefer-dynamic, execution fails as it refuses to use the rlib. + rustc().input("foo.rs").arg("--extern").arg("bar").arg("-Cprefer-dynamic").run(); + fs_wrapper::rename(dynamic_lib_name("bar"), "bar.tmp"); + run_fail("foo"); + fs_wrapper::rename("bar.tmp", dynamic_lib_name("bar")); +} From 11ac258a5f5af5fe00cc68a598414a48661a28ce Mon Sep 17 00:00:00 2001 From: Oneirical Date: Wed, 26 Jun 2024 15:14:13 -0400 Subject: [PATCH 425/892] rewrite silly-file-names to rmake --- .../tidy/src/allowed_run_make_makefiles.txt | 1 - tests/run-make/silly-file-names/Makefile | 12 ---------- tests/run-make/silly-file-names/rmake.rs | 24 +++++++++++++++++++ 3 files changed, 24 insertions(+), 13 deletions(-) delete mode 100644 tests/run-make/silly-file-names/Makefile create mode 100644 tests/run-make/silly-file-names/rmake.rs diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index 463edb461e824..b23a6cb85c02c 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -162,7 +162,6 @@ run-make/sepcomp-cci-copies/Makefile run-make/sepcomp-inlining/Makefile run-make/sepcomp-separate/Makefile run-make/share-generics-dylib/Makefile -run-make/silly-file-names/Makefile run-make/simd-ffi/Makefile run-make/split-debuginfo/Makefile run-make/stable-symbol-names/Makefile diff --git a/tests/run-make/silly-file-names/Makefile b/tests/run-make/silly-file-names/Makefile deleted file mode 100644 index e51266c0880b0..0000000000000 --- a/tests/run-make/silly-file-names/Makefile +++ /dev/null @@ -1,12 +0,0 @@ -# ignore-cross-compile we need to execute the binary -# ignore-windows we create files with < and > in their names - -include ../tools.mk - -all: - echo '"comes from a file with a name that begins with <"' > "$(TMPDIR)/"' > "$(TMPDIR)/trailing-gt>" - cp silly-file-names.rs "$(TMPDIR)/silly-file-names.rs" - $(RUSTC) "$(TMPDIR)/silly-file-names.rs" -o "$(TMPDIR)/silly-file-names" - "$(TMPDIR)/silly-file-names" > "$(TMPDIR)/silly-file-names.run.stdout" - $(RUSTC_TEST_OP) "$(TMPDIR)/silly-file-names.run.stdout" silly-file-names.run.stdout diff --git a/tests/run-make/silly-file-names/rmake.rs b/tests/run-make/silly-file-names/rmake.rs new file mode 100644 index 0000000000000..9df116146fec3 --- /dev/null +++ b/tests/run-make/silly-file-names/rmake.rs @@ -0,0 +1,24 @@ +// There used to be assert! checks in the compiler to error on encountering +// files starting or ending with < or > respectively, as a preventive measure +// against "fake" files like . However, this was not truly required, +// as rustc has other checks to verify the veracity of a file. This test includes +// some files with < and > in their names and prints out their output to stdout, +// expecting no errors. +// See https://github.com/rust-lang/rust/issues/73419 + +//@ ignore-cross-compile +// Reason: the compiled binary is executed +//@ ignore-windows +// Reason: Windows refuses files with < and > in their names + +use run_make_support::{diff, fs_wrapper, run, rustc}; + +fn main() { + fs_wrapper::create_file(""); + fs_wrapper::write("trailing-gt>", r#""comes from a file with a name that ends with >""#); + rustc().input("silly-file-names.rs").output("silly-file-names").run(); + let out = run("silly-file-names").stdout_utf8(); + diff().expected_file("silly-file-names.run.stdout").actual_text("actual-stdout", out).run(); +} From db21af1a72926571427dd62b51bb1757e88ae64b Mon Sep 17 00:00:00 2001 From: Oneirical Date: Wed, 26 Jun 2024 15:33:27 -0400 Subject: [PATCH 426/892] rewrite metadata-dep-info to rmake --- .../tidy/src/allowed_run_make_makefiles.txt | 1 - tests/run-make/metadata-dep-info/Makefile | 7 ------- ...dash-separated_something-extra.expected.d} | 0 tests/run-make/metadata-dep-info/rmake.rs | 20 +++++++++++++++++++ 4 files changed, 20 insertions(+), 8 deletions(-) delete mode 100644 tests/run-make/metadata-dep-info/Makefile rename tests/run-make/metadata-dep-info/{dash-separated_something-extra.normalized.d => dash-separated_something-extra.expected.d} (100%) create mode 100644 tests/run-make/metadata-dep-info/rmake.rs diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index b23a6cb85c02c..e2ebdbca28188 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -98,7 +98,6 @@ run-make/lto-smoke-c/Makefile run-make/macos-deployment-target/Makefile run-make/macos-fat-archive/Makefile run-make/manual-link/Makefile -run-make/metadata-dep-info/Makefile run-make/min-global-align/Makefile run-make/mingw-export-call-convention/Makefile run-make/mismatching-target-triples/Makefile diff --git a/tests/run-make/metadata-dep-info/Makefile b/tests/run-make/metadata-dep-info/Makefile deleted file mode 100644 index d48cbe0f29505..0000000000000 --- a/tests/run-make/metadata-dep-info/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -include ../tools.mk - -all: - $(RUSTC) --emit=metadata,dep-info --crate-type lib dash-separated.rs -C extra-filename=_something-extra - # Strip TMPDIR since it is a machine specific absolute path - sed "s%.*[/\\]%%" "$(TMPDIR)"/dash-separated_something-extra.d > "$(TMPDIR)"/dash-separated_something-extra.normalized.d - $(RUSTC_TEST_OP) "$(TMPDIR)"/dash-separated_something-extra.normalized.d dash-separated_something-extra.normalized.d diff --git a/tests/run-make/metadata-dep-info/dash-separated_something-extra.normalized.d b/tests/run-make/metadata-dep-info/dash-separated_something-extra.expected.d similarity index 100% rename from tests/run-make/metadata-dep-info/dash-separated_something-extra.normalized.d rename to tests/run-make/metadata-dep-info/dash-separated_something-extra.expected.d diff --git a/tests/run-make/metadata-dep-info/rmake.rs b/tests/run-make/metadata-dep-info/rmake.rs new file mode 100644 index 0000000000000..f4bb3ea63fb16 --- /dev/null +++ b/tests/run-make/metadata-dep-info/rmake.rs @@ -0,0 +1,20 @@ +// Emitting dep-info alongside metadata would present subtle discrepancies +// in the output file, such as the filename transforming underscores_ into hyphens-. +// After the fix in #114750, this test checks that the emitted files are identical +// to the expected output. +// See https://github.com/rust-lang/rust/issues/68839 + +use run_make_support::{diff, rustc}; + +fn main() { + rustc() + .emit("metadata,dep-info") + .crate_type("lib") + .input("dash-separated.rs") + .extra_filename("_something-extra") + .run(); + diff() + .expected_file("dash-separated_something-extra.expected.d") + .actual_file("dash-separated_something-extra.d") + .run(); +} From 7c29298ea941247c13ef9de3f129802eb22f12b7 Mon Sep 17 00:00:00 2001 From: Oneirical Date: Wed, 26 Jun 2024 16:09:45 -0400 Subject: [PATCH 427/892] rewrite cdylib-fewer-symbols to rmake --- .../tidy/src/allowed_run_make_makefiles.txt | 1 - tests/run-make/cdylib-fewer-symbols/Makefile | 15 ------------ tests/run-make/cdylib-fewer-symbols/rmake.rs | 23 +++++++++++++++++++ 3 files changed, 23 insertions(+), 16 deletions(-) delete mode 100644 tests/run-make/cdylib-fewer-symbols/Makefile create mode 100644 tests/run-make/cdylib-fewer-symbols/rmake.rs diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index e2ebdbca28188..e9034c631af6f 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -9,7 +9,6 @@ run-make/c-unwind-abi-catch-lib-panic/Makefile run-make/c-unwind-abi-catch-panic/Makefile run-make/cat-and-grep-sanity-check/Makefile run-make/cdylib-dylib-linkage/Makefile -run-make/cdylib-fewer-symbols/Makefile run-make/compiler-lookup-paths-2/Makefile run-make/compiler-lookup-paths/Makefile run-make/compiler-rt-works-on-mingw/Makefile diff --git a/tests/run-make/cdylib-fewer-symbols/Makefile b/tests/run-make/cdylib-fewer-symbols/Makefile deleted file mode 100644 index d587cece5bec0..0000000000000 --- a/tests/run-make/cdylib-fewer-symbols/Makefile +++ /dev/null @@ -1,15 +0,0 @@ -# ignore-cross-compile - -# Test that allocator-related symbols don't show up as exported from a cdylib as -# they're internal to Rust and not part of the public ABI. -# See https://github.com/rust-lang/rust/commit/fbf98697021173a30b84d9145df0966a23a2f9d2 - -include ../tools.mk - -# ignore-windows -# FIXME: The __rdl_ and __rust_ symbol still remains, no matter using MSVC or GNU -# See https://github.com/rust-lang/rust/pull/46207#issuecomment-347561753 - -all: - $(RUSTC) foo.rs - nm -g "$(call DYLIB,foo)" | $(CGREP) -v __rdl_ __rde_ __rg_ __rust_ diff --git a/tests/run-make/cdylib-fewer-symbols/rmake.rs b/tests/run-make/cdylib-fewer-symbols/rmake.rs new file mode 100644 index 0000000000000..8a8d31e6e49e4 --- /dev/null +++ b/tests/run-make/cdylib-fewer-symbols/rmake.rs @@ -0,0 +1,23 @@ +// Symbols related to the allocator should be hidden and not exported from a cdylib, +// for they are internal to Rust +// and not part of the public ABI (application binary interface). This test checks that +// four such symbols are successfully hidden. +// See https://github.com/rust-lang/rust/pull/45710 + +//FIXME(Oneirical): try it on windows, restore ignore +// See https://github.com/rust-lang/rust/pull/46207#issuecomment-347561753 +//FIXME(Oneirical): I also removed cross-compile ignore since there is no binary execution + +use run_make_support::{dynamic_lib_name, llvm_readobj, rustc}; + +fn main() { + // Compile a cdylib + rustc().input("foo.rs").run(); + let out = llvm_readobj().arg("--symbols").input(dynamic_lib_name("foo")).run().stdout_utf8(); + let out = // All hidden symbols must be removed. + out.lines().filter(|&line| !line.trim().contains("HIDDEN")).collect::>().join("\n"); + assert!(!&out.contains("__rdl_")); + assert!(!&out.contains("__rde_")); + assert!(!&out.contains("__rg_")); + assert!(!&out.contains("__ruse_")); +} From 224cb3f638881525c00c46b012721f0aafc73263 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Fri, 28 Jun 2024 20:59:01 +0000 Subject: [PATCH 428/892] Revert "Rollup merge of #126938 - RalfJung:link_section, r=compiler-errors" This reverts commit 5c4ede88c61e746ed5c852d7a7e38ab1a824ae52, reversing changes made to 95332b89187bb6a0c910574cfeff1933b619565a. --- compiler/rustc_passes/src/reachable.rs | 12 ++++++++++-- .../miri/tests/pass/tls/win_tls_callback.rs | 16 ---------------- .../miri/tests/pass/tls/win_tls_callback.stderr | 1 - 3 files changed, 10 insertions(+), 19 deletions(-) delete mode 100644 src/tools/miri/tests/pass/tls/win_tls_callback.rs delete mode 100644 src/tools/miri/tests/pass/tls/win_tls_callback.stderr diff --git a/compiler/rustc_passes/src/reachable.rs b/compiler/rustc_passes/src/reachable.rs index da4435ebebe87..6dd8eaf7e6734 100644 --- a/compiler/rustc_passes/src/reachable.rs +++ b/compiler/rustc_passes/src/reachable.rs @@ -30,7 +30,7 @@ use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::Node; use rustc_middle::bug; -use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; +use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs}; use rustc_middle::middle::privacy::{self, Level}; use rustc_middle::mir::interpret::{ConstAllocation, ErrorHandled, GlobalAlloc}; use rustc_middle::query::Providers; @@ -178,7 +178,15 @@ impl<'tcx> ReachableContext<'tcx> { if !self.any_library { // If we are building an executable, only explicitly extern // types need to be exported. - if has_custom_linkage(self.tcx, search_item) { + let codegen_attrs = if self.tcx.def_kind(search_item).has_codegen_attrs() { + self.tcx.codegen_fn_attrs(search_item) + } else { + CodegenFnAttrs::EMPTY + }; + let is_extern = codegen_attrs.contains_extern_indicator(); + let std_internal = + codegen_attrs.flags.contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL); + if is_extern || std_internal { self.reachable_symbols.insert(search_item); } } else { diff --git a/src/tools/miri/tests/pass/tls/win_tls_callback.rs b/src/tools/miri/tests/pass/tls/win_tls_callback.rs deleted file mode 100644 index 99a8de29e9170..0000000000000 --- a/src/tools/miri/tests/pass/tls/win_tls_callback.rs +++ /dev/null @@ -1,16 +0,0 @@ -//! Ensure that we call Windows TLS callbacks in the local crate. -//@only-target-windows -// Calling eprintln in the callback seems to (re-)initialize some thread-local storage -// and then leak the memory allocated for that. Let's just ignore these leaks, -// that's not what this test is about. -//@compile-flags: -Zmiri-ignore-leaks - -#[link_section = ".CRT$XLB"] -#[used] // Miri only considers explicitly `#[used]` statics for `lookup_link_section` -pub static CALLBACK: unsafe extern "system" fn(*const (), u32, *const ()) = tls_callback; - -unsafe extern "system" fn tls_callback(_h: *const (), _dw_reason: u32, _pv: *const ()) { - eprintln!("in tls_callback"); -} - -fn main() {} diff --git a/src/tools/miri/tests/pass/tls/win_tls_callback.stderr b/src/tools/miri/tests/pass/tls/win_tls_callback.stderr deleted file mode 100644 index 8479558954456..0000000000000 --- a/src/tools/miri/tests/pass/tls/win_tls_callback.stderr +++ /dev/null @@ -1 +0,0 @@ -in tls_callback From 57931e50409f9365791f7923a68f9ae1ec301c4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Fri, 28 Jun 2024 20:59:33 +0000 Subject: [PATCH 429/892] add non-regression test for issue 127052 --- .../unreferenced-used-static-issue-127052.rs | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 tests/ui/linkage-attr/unreferenced-used-static-issue-127052.rs diff --git a/tests/ui/linkage-attr/unreferenced-used-static-issue-127052.rs b/tests/ui/linkage-attr/unreferenced-used-static-issue-127052.rs new file mode 100644 index 0000000000000..aa8236b74315c --- /dev/null +++ b/tests/ui/linkage-attr/unreferenced-used-static-issue-127052.rs @@ -0,0 +1,9 @@ +// This is a non-regression test for issue #127052 where unreferenced `#[used]` statics couldn't be +// removed by the MSVC linker, causing linking errors. + +//@ build-pass: needs linking +//@ only-msvc + +#[used] +static FOO: u32 = 0; +fn main() {} From 6f3ad0a40bf6bd80610008bfe48d3977e921d09d Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 27 Jun 2024 15:27:52 -0400 Subject: [PATCH 430/892] Only require symbol name for @feature_gate --- compiler/rustc_lint/src/impl_trait_overcaptures.rs | 6 +++--- .../src/multiple_supertrait_upcastable.rs | 3 +-- compiler/rustc_lint_defs/src/builtin.rs | 13 ++++++------- compiler/rustc_lint_defs/src/lib.rs | 12 ++++++------ src/librustdoc/lint.rs | 4 ++-- 5 files changed, 18 insertions(+), 20 deletions(-) diff --git a/compiler/rustc_lint/src/impl_trait_overcaptures.rs b/compiler/rustc_lint/src/impl_trait_overcaptures.rs index d4f6d388d9fe3..0860413190c3d 100644 --- a/compiler/rustc_lint/src/impl_trait_overcaptures.rs +++ b/compiler/rustc_lint/src/impl_trait_overcaptures.rs @@ -11,7 +11,7 @@ use rustc_middle::ty::{ self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, }; use rustc_session::{declare_lint, declare_lint_pass}; -use rustc_span::{sym, Span}; +use rustc_span::Span; use crate::fluent_generated as fluent; use crate::{LateContext, LateLintPass}; @@ -57,7 +57,7 @@ declare_lint! { pub IMPL_TRAIT_OVERCAPTURES, Allow, "`impl Trait` will capture more lifetimes than possibly intended in edition 2024", - @feature_gate = sym::precise_capturing; + @feature_gate = precise_capturing; //@future_incompatible = FutureIncompatibleInfo { // reason: FutureIncompatibilityReason::EditionSemanticsChange(Edition::Edition2024), // reference: "", @@ -91,7 +91,7 @@ declare_lint! { pub IMPL_TRAIT_REDUNDANT_CAPTURES, Warn, "redundant precise-capturing `use<...>` syntax on an `impl Trait`", - @feature_gate = sym::precise_capturing; + @feature_gate = precise_capturing; } declare_lint_pass!( diff --git a/compiler/rustc_lint/src/multiple_supertrait_upcastable.rs b/compiler/rustc_lint/src/multiple_supertrait_upcastable.rs index aa1d94228ea22..b9ed648b246fe 100644 --- a/compiler/rustc_lint/src/multiple_supertrait_upcastable.rs +++ b/compiler/rustc_lint/src/multiple_supertrait_upcastable.rs @@ -2,7 +2,6 @@ use crate::{LateContext, LateLintPass, LintContext}; use rustc_hir as hir; use rustc_session::{declare_lint, declare_lint_pass}; -use rustc_span::sym; declare_lint! { /// The `multiple_supertrait_upcastable` lint detects when an object-safe trait has multiple @@ -30,7 +29,7 @@ declare_lint! { pub MULTIPLE_SUPERTRAIT_UPCASTABLE, Allow, "detect when an object-safe trait has multiple supertraits", - @feature_gate = sym::multiple_supertrait_upcastable; + @feature_gate = multiple_supertrait_upcastable; } declare_lint_pass!(MultipleSupertraitUpcastable => [MULTIPLE_SUPERTRAIT_UPCASTABLE]); diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index 472e93d202d76..186be98332b36 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -9,7 +9,6 @@ use crate::{declare_lint, declare_lint_pass, FutureIncompatibilityReason}; use rustc_span::edition::Edition; -use rustc_span::symbol::sym; declare_lint_pass! { /// Does nothing as a lint pass, but registers some `Lint`s @@ -461,7 +460,7 @@ declare_lint! { pub MUST_NOT_SUSPEND, Allow, "use of a `#[must_not_suspend]` value across a yield point", - @feature_gate = rustc_span::symbol::sym::must_not_suspend; + @feature_gate = must_not_suspend; } declare_lint! { @@ -1645,7 +1644,7 @@ declare_lint! { pub RUST_2024_INCOMPATIBLE_PAT, Allow, "detects patterns whose meaning will change in Rust 2024", - @feature_gate = sym::ref_pat_eat_one_layer_2024; + @feature_gate = ref_pat_eat_one_layer_2024; // FIXME uncomment below upon stabilization /*@future_incompatible = FutureIncompatibleInfo { reason: FutureIncompatibilityReason::EditionSemanticsChange(Edition::Edition2024), @@ -2693,7 +2692,7 @@ declare_lint! { pub FUZZY_PROVENANCE_CASTS, Allow, "a fuzzy integer to pointer cast is used", - @feature_gate = sym::strict_provenance; + @feature_gate = strict_provenance; } declare_lint! { @@ -2739,7 +2738,7 @@ declare_lint! { pub LOSSY_PROVENANCE_CASTS, Allow, "a lossy pointer to integer cast is used", - @feature_gate = sym::strict_provenance; + @feature_gate = strict_provenance; } declare_lint! { @@ -3923,7 +3922,7 @@ declare_lint! { pub NON_EXHAUSTIVE_OMITTED_PATTERNS, Allow, "detect when patterns of types marked `non_exhaustive` are missed", - @feature_gate = sym::non_exhaustive_omitted_patterns_lint; + @feature_gate = non_exhaustive_omitted_patterns_lint; } declare_lint! { @@ -4043,7 +4042,7 @@ declare_lint! { pub TEST_UNSTABLE_LINT, Deny, "this unstable lint is only for testing", - @feature_gate = sym::test_unstable_lint; + @feature_gate = test_unstable_lint; } declare_lint! { diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs index b44eb25216770..f87f19e170005 100644 --- a/compiler/rustc_lint_defs/src/lib.rs +++ b/compiler/rustc_lint_defs/src/lib.rs @@ -865,7 +865,7 @@ macro_rules! declare_lint { ); ); ($(#[$attr:meta])* $vis: vis $NAME: ident, $Level: ident, $desc: expr, - $(@feature_gate = $gate:expr;)? + $(@feature_gate = $gate:ident;)? $(@future_incompatible = FutureIncompatibleInfo { reason: $reason:expr, $($field:ident : $val:expr),* $(,)* @@ -879,7 +879,7 @@ macro_rules! declare_lint { desc: $desc, is_externally_loaded: false, $($v: true,)* - $(feature_gate: Some($gate),)? + $(feature_gate: Some(rustc_span::symbol::sym::$gate),)? $(future_incompatible: Some($crate::FutureIncompatibleInfo { reason: $reason, $($field: $val,)* @@ -895,21 +895,21 @@ macro_rules! declare_lint { macro_rules! declare_tool_lint { ( $(#[$attr:meta])* $vis:vis $tool:ident ::$NAME:ident, $Level: ident, $desc: expr - $(, @feature_gate = $gate:expr;)? + $(, @feature_gate = $gate:ident;)? ) => ( $crate::declare_tool_lint!{$(#[$attr])* $vis $tool::$NAME, $Level, $desc, false $(, @feature_gate = $gate;)?} ); ( $(#[$attr:meta])* $vis:vis $tool:ident ::$NAME:ident, $Level:ident, $desc:expr, report_in_external_macro: $rep:expr - $(, @feature_gate = $gate:expr;)? + $(, @feature_gate = $gate:ident;)? ) => ( $crate::declare_tool_lint!{$(#[$attr])* $vis $tool::$NAME, $Level, $desc, $rep $(, @feature_gate = $gate;)?} ); ( $(#[$attr:meta])* $vis:vis $tool:ident ::$NAME:ident, $Level:ident, $desc:expr, $external:expr - $(, @feature_gate = $gate:expr;)? + $(, @feature_gate = $gate:ident;)? ) => ( $(#[$attr])* $vis static $NAME: &$crate::Lint = &$crate::Lint { @@ -920,7 +920,7 @@ macro_rules! declare_tool_lint { report_in_external_macro: $external, future_incompatible: None, is_externally_loaded: true, - $(feature_gate: Some($gate),)? + $(feature_gate: Some(rustc_span::symbol::sym::$gate),)? crate_level_only: false, ..$crate::Lint::default_fields_for_macro() }; diff --git a/src/librustdoc/lint.rs b/src/librustdoc/lint.rs index dd2bb47e5926b..b570b73bf08df 100644 --- a/src/librustdoc/lint.rs +++ b/src/librustdoc/lint.rs @@ -66,7 +66,7 @@ where macro_rules! declare_rustdoc_lint { ( $(#[$attr:meta])* $name: ident, $level: ident, $descr: literal $(,)? - $(@feature_gate = $gate:expr;)? + $(@feature_gate = $gate:ident;)? ) => { declare_tool_lint! { $(#[$attr])* pub rustdoc::$name, $level, $descr @@ -128,7 +128,7 @@ declare_rustdoc_lint! { MISSING_DOC_CODE_EXAMPLES, Allow, "detects publicly-exported items without code samples in their documentation", - @feature_gate = rustc_span::symbol::sym::rustdoc_missing_doc_code_examples; + @feature_gate = rustdoc_missing_doc_code_examples; } declare_rustdoc_lint! { From 1483815aa268b3a3dbfb3c4242772c88690a887e Mon Sep 17 00:00:00 2001 From: Tyler Mandry Date: Fri, 28 Jun 2024 15:44:33 -0700 Subject: [PATCH 431/892] Bump Fuchsia This includes the quality-of-life improvements for developers in https://fxrev.dev/1061894. --- .../docker/host-x86_64/x86_64-gnu-integration/build-fuchsia.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-integration/build-fuchsia.sh b/src/ci/docker/host-x86_64/x86_64-gnu-integration/build-fuchsia.sh index 2bb1d0a633871..e6d7eabf4e723 100755 --- a/src/ci/docker/host-x86_64/x86_64-gnu-integration/build-fuchsia.sh +++ b/src/ci/docker/host-x86_64/x86_64-gnu-integration/build-fuchsia.sh @@ -35,7 +35,7 @@ PICK_REFS=() # commit hash of fuchsia.git and some other repos in the "monorepo" checkout, in # addition to versions of prebuilts. It should be bumped regularly by the # Fuchsia team – we aim for every 1-2 months. -INTEGRATION_SHA=737ebdd83afa47b742ca8325fad0176952fcefbd +INTEGRATION_SHA=d1d2f20efe46e22be179953dd6726c96eced54ab checkout=fuchsia jiri=.jiri_root/bin/jiri From 45efd9ca8b60c792785741b91e8a19c983f958b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Sat, 29 Jun 2024 00:48:05 +0200 Subject: [PATCH 432/892] remove some amusing but redundant code --- compiler/rustc_mir_transform/src/dataflow_const_prop.rs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs index 0fd85eb345d0c..8b965f4d18e45 100644 --- a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs +++ b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs @@ -181,11 +181,6 @@ impl<'tcx> ValueAnalysis<'tcx> for ConstAnalysis<'_, 'tcx> { state.insert_value_idx(value_target, val, self.map()); } if let Some(overflow_target) = overflow_target { - let overflow = match overflow { - FlatSet::Top => FlatSet::Top, - FlatSet::Elem(overflow) => FlatSet::Elem(overflow), - FlatSet::Bottom => FlatSet::Bottom, - }; // We have flooded `target` earlier. state.insert_value_idx(overflow_target, overflow, self.map()); } From 1727e59ad2b2b8793bda3efac453ea556eb2cdcb Mon Sep 17 00:00:00 2001 From: Tyler Mandry Date: Fri, 28 Jun 2024 15:49:02 -0700 Subject: [PATCH 433/892] Remove wasm target This should no longer be required to build Fuchsia. --- src/ci/docker/host-x86_64/x86_64-gnu-integration/Dockerfile | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-integration/Dockerfile b/src/ci/docker/host-x86_64/x86_64-gnu-integration/Dockerfile index a944f370c6b30..a137808940716 100644 --- a/src/ci/docker/host-x86_64/x86_64-gnu-integration/Dockerfile +++ b/src/ci/docker/host-x86_64/x86_64-gnu-integration/Dockerfile @@ -24,7 +24,6 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ && rm -rf /var/lib/apt/lists/* # Duplicated in dist-various-2 Dockerfile. -# FIXME: Move to canonical triple ENV \ AR_x86_64_unknown_fuchsia=x86_64-unknown-fuchsia-ar \ CC_x86_64_unknown_fuchsia=x86_64-unknown-fuchsia-clang \ @@ -48,10 +47,6 @@ ENV CARGO_TARGET_X86_64_UNKNOWN_FUCHSIA_RUSTFLAGS \ ENV TARGETS=x86_64-unknown-fuchsia ENV TARGETS=$TARGETS,x86_64-unknown-linux-gnu -ENV TARGETS=$TARGETS,wasm32-unknown-unknown - -# Fuchsia clang does not have wasm target enabled, use system clang. -ENV CC_wasm32_unknown_unknown=clang-15 COPY scripts/sccache.sh /scripts/ RUN sh /scripts/sccache.sh From a8382023b4a4de1d9babe4ef2ce432fd8a3951f5 Mon Sep 17 00:00:00 2001 From: Tyler Mandry Date: Fri, 28 Jun 2024 15:51:32 -0700 Subject: [PATCH 434/892] Clarify docs --- src/ci/docker/host-x86_64/x86_64-gnu-integration/Dockerfile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-integration/Dockerfile b/src/ci/docker/host-x86_64/x86_64-gnu-integration/Dockerfile index a137808940716..be209a9de9f91 100644 --- a/src/ci/docker/host-x86_64/x86_64-gnu-integration/Dockerfile +++ b/src/ci/docker/host-x86_64/x86_64-gnu-integration/Dockerfile @@ -1,5 +1,6 @@ # This job builds a toolchain capable of building Fuchsia, and then builds -# Fuchsia. See the build-fuchsia.sh script in this directory for more details. +# Fuchsia as an integration test of the toolchain. See the build-fuchsia.sh +# script in this directory for more details. FROM ubuntu:22.04 From 078d9d8aa98fc1490734b51e6e151659c953bed7 Mon Sep 17 00:00:00 2001 From: Tyler Mandry Date: Fri, 28 Jun 2024 16:08:57 -0700 Subject: [PATCH 435/892] Rename x86_64-gnu-integration builder to x86_64-fuchsia This better reflects what the builder actually does. --- .../Dockerfile | 2 +- .../build-fuchsia.sh | 8 ++++---- src/ci/github-actions/jobs.yml | 14 +++++++------- 3 files changed, 12 insertions(+), 12 deletions(-) rename src/ci/docker/host-x86_64/{x86_64-gnu-integration => x86_64-fuchsia}/Dockerfile (97%) rename src/ci/docker/host-x86_64/{x86_64-gnu-integration => x86_64-fuchsia}/build-fuchsia.sh (91%) diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-integration/Dockerfile b/src/ci/docker/host-x86_64/x86_64-fuchsia/Dockerfile similarity index 97% rename from src/ci/docker/host-x86_64/x86_64-gnu-integration/Dockerfile rename to src/ci/docker/host-x86_64/x86_64-fuchsia/Dockerfile index be209a9de9f91..ba3e8bdb68754 100644 --- a/src/ci/docker/host-x86_64/x86_64-gnu-integration/Dockerfile +++ b/src/ci/docker/host-x86_64/x86_64-fuchsia/Dockerfile @@ -72,4 +72,4 @@ ENV RUST_CONFIGURE_ARGS \ --set target.x86_64-unknown-fuchsia.linker=/usr/local/bin/ld.lld ENV SCRIPT \ python3 ../x.py install --target $TARGETS compiler/rustc library/std clippy && \ - bash ../src/ci/docker/host-x86_64/x86_64-gnu-integration/build-fuchsia.sh + bash ../src/ci/docker/host-x86_64/x86_64-fuchsia/build-fuchsia.sh diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-integration/build-fuchsia.sh b/src/ci/docker/host-x86_64/x86_64-fuchsia/build-fuchsia.sh similarity index 91% rename from src/ci/docker/host-x86_64/x86_64-gnu-integration/build-fuchsia.sh rename to src/ci/docker/host-x86_64/x86_64-fuchsia/build-fuchsia.sh index e6d7eabf4e723..c806b886dae8f 100755 --- a/src/ci/docker/host-x86_64/x86_64-gnu-integration/build-fuchsia.sh +++ b/src/ci/docker/host-x86_64/x86_64-fuchsia/build-fuchsia.sh @@ -5,14 +5,14 @@ # # You may run this script locally using Docker with the following command: # -# $ src/ci/docker/run.sh x86_64-gnu-integration +# $ src/ci/docker/run.sh x86_64-fuchsia # # Alternatively, from within the container with --dev, assuming you have made it # as far as building the toolchain with the above command: # -# $ src/ci/docker/run.sh --dev x86_64-gnu-integration +# $ src/ci/docker/run.sh --dev x86_64-fuchsia # docker# git config --global --add safe.directory /checkout/obj/fuchsia -# docker# ../src/ci/docker/host-x86_64/x86_64-gnu-integration/build-fuchsia.sh +# docker# ../src/ci/docker/host-x86_64/x86_64-fuchsia/build-fuchsia.sh # # Also see the docs in the rustc-dev-guide for more info: # https://github.com/rust-lang/rustc-dev-guide/pull/1989 @@ -21,7 +21,7 @@ set -euf -o pipefail # Set this variable to 1 to disable updating the Fuchsia checkout. This is # useful for making local changes. You can find the Fuchsia checkout in -# `obj/x86_64-gnu-integration/fuchsia` in your local checkout after running this +# `obj/x86_64-fuchsia/fuchsia` in your local checkout after running this # job for the first time. KEEP_CHECKOUT= diff --git a/src/ci/github-actions/jobs.yml b/src/ci/github-actions/jobs.yml index e3903c3dd5a1f..cf750bbd0c568 100644 --- a/src/ci/github-actions/jobs.yml +++ b/src/ci/github-actions/jobs.yml @@ -208,6 +208,13 @@ auto: - image: test-various <<: *job-linux-4c + - image: x86_64-fuchsia + # Only run this job on the nightly channel. Fuchsia requires + # nightly features to compile, and this job would fail if + # executed on beta and stable. + only_on_channel: nightly + <<: *job-linux-8c + - image: x86_64-gnu <<: *job-linux-4c @@ -229,13 +236,6 @@ auto: - image: x86_64-gnu-aux <<: *job-linux-4c - - image: x86_64-gnu-integration - # Only run this job on the nightly channel. Fuchsia requires - # nightly features to compile, and this job would fail if - # executed on beta and stable. - only_on_channel: nightly - <<: *job-linux-8c - - image: x86_64-gnu-debug <<: *job-linux-4c From 3bc32472008387ab2adca98dcfd0bef6207357c1 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 28 Jun 2024 19:37:21 -0400 Subject: [PATCH 436/892] Move binder and polarity parsing into parse_generic_ty_bound --- compiler/rustc_parse/src/parser/expr.rs | 2 +- compiler/rustc_parse/src/parser/generics.rs | 2 +- compiler/rustc_parse/src/parser/ty.rs | 98 ++++++++++++------- .../higher-ranked/erroneous-lifetime-bound.rs | 5 + .../erroneous-lifetime-bound.stderr | 25 +++++ .../precise-capturing/bound-modifiers.rs | 25 +++++ .../precise-capturing/bound-modifiers.stderr | 87 ++++++++++++++++ 7 files changed, 204 insertions(+), 40 deletions(-) create mode 100644 tests/ui/higher-ranked/erroneous-lifetime-bound.rs create mode 100644 tests/ui/higher-ranked/erroneous-lifetime-bound.stderr create mode 100644 tests/ui/impl-trait/precise-capturing/bound-modifiers.rs create mode 100644 tests/ui/impl-trait/precise-capturing/bound-modifiers.stderr diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index e0c70884feea3..ac66edeb95e45 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -2327,7 +2327,7 @@ impl<'a> Parser<'a> { let before = self.prev_token.clone(); let binder = if self.check_keyword(kw::For) { let lo = self.token.span; - let lifetime_defs = self.parse_late_bound_lifetime_defs()?; + let (lifetime_defs, _) = self.parse_late_bound_lifetime_defs()?; let span = lo.to(self.prev_token.span); self.psess.gated_spans.gate(sym::closure_lifetime_binder, span); diff --git a/compiler/rustc_parse/src/parser/generics.rs b/compiler/rustc_parse/src/parser/generics.rs index fde16ac957dfe..10c7715c7dcd5 100644 --- a/compiler/rustc_parse/src/parser/generics.rs +++ b/compiler/rustc_parse/src/parser/generics.rs @@ -457,7 +457,7 @@ impl<'a> Parser<'a> { // * `for<'a> Trait1<'a>: Trait2<'a /* ok */>` // * `(for<'a> Trait1<'a>): Trait2<'a /* not ok */>` // * `for<'a> for<'b> Trait1<'a, 'b>: Trait2<'a /* ok */, 'b /* not ok */>` - let lifetime_defs = self.parse_late_bound_lifetime_defs()?; + let (lifetime_defs, _) = self.parse_late_bound_lifetime_defs()?; // Parse type with mandatory colon and (possibly empty) bounds, // or with mandatory equality sign and the second type. diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs index d2043c353fed9..1e5b227aaa9be 100644 --- a/compiler/rustc_parse/src/parser/ty.rs +++ b/compiler/rustc_parse/src/parser/ty.rs @@ -18,7 +18,7 @@ use rustc_ast::{ }; use rustc_errors::{Applicability, PResult}; use rustc_span::symbol::{kw, sym, Ident}; -use rustc_span::{Span, Symbol}; +use rustc_span::{ErrorGuaranteed, Span, Symbol}; use thin_vec::{thin_vec, ThinVec}; #[derive(Copy, Clone, PartialEq)] @@ -280,7 +280,7 @@ impl<'a> Parser<'a> { // Function pointer type or bound list (trait object type) starting with a poly-trait. // `for<'lt> [unsafe] [extern "ABI"] fn (&'lt S) -> T` // `for<'lt> Trait1<'lt> + Trait2 + 'a` - let lifetime_defs = self.parse_late_bound_lifetime_defs()?; + let (lifetime_defs, _) = self.parse_late_bound_lifetime_defs()?; if self.check_fn_front_matter(false, Case::Sensitive) { self.parse_ty_bare_fn( lo, @@ -833,12 +833,9 @@ impl<'a> Parser<'a> { let lo = self.token.span; let leading_token = self.prev_token.clone(); let has_parens = self.eat(&token::OpenDelim(Delimiter::Parenthesis)); - let inner_lo = self.token.span; - let modifiers = self.parse_trait_bound_modifiers()?; let bound = if self.token.is_lifetime() { - self.error_lt_bound_with_modifiers(modifiers); - self.parse_generic_lt_bound(lo, inner_lo, has_parens)? + self.parse_generic_lt_bound(lo, has_parens)? } else if self.eat_keyword(kw::Use) { // parse precise captures, if any. This is `use<'lt, 'lt, P, P>`; a list of // lifetimes and ident params (including SelfUpper). These are validated later @@ -848,7 +845,7 @@ impl<'a> Parser<'a> { let (args, args_span) = self.parse_precise_capturing_args()?; GenericBound::Use(args, use_span.to(args_span)) } else { - self.parse_generic_ty_bound(lo, has_parens, modifiers, &leading_token)? + self.parse_generic_ty_bound(lo, has_parens, &leading_token)? }; Ok(bound) @@ -858,50 +855,64 @@ impl<'a> Parser<'a> { /// ```ebnf /// LT_BOUND = LIFETIME /// ``` - fn parse_generic_lt_bound( - &mut self, - lo: Span, - inner_lo: Span, - has_parens: bool, - ) -> PResult<'a, GenericBound> { - let bound = GenericBound::Outlives(self.expect_lifetime()); + fn parse_generic_lt_bound(&mut self, lo: Span, has_parens: bool) -> PResult<'a, GenericBound> { + let lt = self.expect_lifetime(); + let bound = GenericBound::Outlives(lt); if has_parens { // FIXME(Centril): Consider not erroring here and accepting `('lt)` instead, // possibly introducing `GenericBound::Paren(P)`? - self.recover_paren_lifetime(lo, inner_lo)?; + self.recover_paren_lifetime(lo, lt.ident.span)?; } Ok(bound) } /// Emits an error if any trait bound modifiers were present. - fn error_lt_bound_with_modifiers(&self, modifiers: TraitBoundModifiers) { - match modifiers.constness { + fn error_lt_bound_with_modifiers( + &self, + modifiers: TraitBoundModifiers, + binder_span: Option, + ) -> ErrorGuaranteed { + let TraitBoundModifiers { constness, asyncness, polarity } = modifiers; + + match constness { BoundConstness::Never => {} BoundConstness::Always(span) | BoundConstness::Maybe(span) => { - self.dcx().emit_err(errors::ModifierLifetime { - span, - modifier: modifiers.constness.as_str(), - }); + return self + .dcx() + .emit_err(errors::ModifierLifetime { span, modifier: constness.as_str() }); } } - match modifiers.polarity { + match polarity { BoundPolarity::Positive => {} BoundPolarity::Negative(span) | BoundPolarity::Maybe(span) => { - self.dcx().emit_err(errors::ModifierLifetime { - span, - modifier: modifiers.polarity.as_str(), - }); + return self + .dcx() + .emit_err(errors::ModifierLifetime { span, modifier: polarity.as_str() }); + } + } + + match asyncness { + BoundAsyncness::Normal => {} + BoundAsyncness::Async(span) => { + return self + .dcx() + .emit_err(errors::ModifierLifetime { span, modifier: asyncness.as_str() }); } } + + if let Some(span) = binder_span { + return self.dcx().emit_err(errors::ModifierLifetime { span, modifier: "for<...>" }); + } + + unreachable!("lifetime bound intercepted in `parse_generic_ty_bound` but no modifiers?") } /// Recover on `('lifetime)` with `(` already eaten. - fn recover_paren_lifetime(&mut self, lo: Span, inner_lo: Span) -> PResult<'a, ()> { - let inner_span = inner_lo.to(self.prev_token.span); + fn recover_paren_lifetime(&mut self, lo: Span, lt_span: Span) -> PResult<'a, ()> { self.expect(&token::CloseDelim(Delimiter::Parenthesis))?; let span = lo.to(self.prev_token.span); - let (sugg, snippet) = if let Ok(snippet) = self.span_to_snippet(inner_span) { + let (sugg, snippet) = if let Ok(snippet) = self.span_to_snippet(lt_span) { (Some(span), snippet) } else { (None, String::new()) @@ -916,7 +927,7 @@ impl<'a> Parser<'a> { /// If no modifiers are present, this does not consume any tokens. /// /// ```ebnf - /// TRAIT_BOUND_MODIFIERS = [["~"] "const"] ["?" | "!"] + /// TRAIT_BOUND_MODIFIERS = [["~"] "const"] ["async"] ["?" | "!"] /// ``` fn parse_trait_bound_modifiers(&mut self) -> PResult<'a, TraitBoundModifiers> { let constness = if self.eat(&token::Tilde) { @@ -970,15 +981,23 @@ impl<'a> Parser<'a> { /// TY_BOUND_NOPAREN = [TRAIT_BOUND_MODIFIERS] [for] SIMPLE_PATH /// ``` /// - /// For example, this grammar accepts `~const ?for<'a: 'b> m::Trait<'a>`. + /// For example, this grammar accepts `for<'a: 'b> ~const ?m::Trait<'a>`. fn parse_generic_ty_bound( &mut self, lo: Span, has_parens: bool, - modifiers: TraitBoundModifiers, leading_token: &Token, ) -> PResult<'a, GenericBound> { - let mut lifetime_defs = self.parse_late_bound_lifetime_defs()?; + let modifiers = self.parse_trait_bound_modifiers()?; + let (mut lifetime_defs, binder_span) = self.parse_late_bound_lifetime_defs()?; + + // Recover erroneous lifetime bound with modifiers or binder. + // e.g. `T: for<'a> 'a` or `T: ~const 'a`. + if self.token.is_lifetime() { + let _: ErrorGuaranteed = self.error_lt_bound_with_modifiers(modifiers, binder_span); + return self.parse_generic_lt_bound(lo, has_parens); + } + let mut path = if self.token.is_keyword(kw::Fn) && self.look_ahead(1, |tok| tok.kind == TokenKind::OpenDelim(Delimiter::Parenthesis)) && let Some(path) = self.recover_path_from_fn() @@ -1094,16 +1113,19 @@ impl<'a> Parser<'a> { } /// Optionally parses `for<$generic_params>`. - pub(super) fn parse_late_bound_lifetime_defs(&mut self) -> PResult<'a, ThinVec> { + pub(super) fn parse_late_bound_lifetime_defs( + &mut self, + ) -> PResult<'a, (ThinVec, Option)> { if self.eat_keyword(kw::For) { + let lo = self.token.span; self.expect_lt()?; let params = self.parse_generic_params()?; self.expect_gt()?; - // We rely on AST validation to rule out invalid cases: There must not be type - // parameters, and the lifetime parameters must not have bounds. - Ok(params) + // We rely on AST validation to rule out invalid cases: There must not be + // type or const parameters, and parameters must not have bounds. + Ok((params, Some(lo.to(self.prev_token.span)))) } else { - Ok(ThinVec::new()) + Ok((ThinVec::new(), None)) } } diff --git a/tests/ui/higher-ranked/erroneous-lifetime-bound.rs b/tests/ui/higher-ranked/erroneous-lifetime-bound.rs new file mode 100644 index 0000000000000..b1720087b5f6d --- /dev/null +++ b/tests/ui/higher-ranked/erroneous-lifetime-bound.rs @@ -0,0 +1,5 @@ +fn foo() where T: for<'a> 'a {} +//~^ ERROR `for<...>` may only modify trait bounds, not lifetime bounds +//~| ERROR use of undeclared lifetime name `'a` [E0261] + +fn main() {} diff --git a/tests/ui/higher-ranked/erroneous-lifetime-bound.stderr b/tests/ui/higher-ranked/erroneous-lifetime-bound.stderr new file mode 100644 index 0000000000000..5b104f45d2361 --- /dev/null +++ b/tests/ui/higher-ranked/erroneous-lifetime-bound.stderr @@ -0,0 +1,25 @@ +error: `for<...>` may only modify trait bounds, not lifetime bounds + --> $DIR/erroneous-lifetime-bound.rs:1:25 + | +LL | fn foo() where T: for<'a> 'a {} + | ^^^^ + +error[E0261]: use of undeclared lifetime name `'a` + --> $DIR/erroneous-lifetime-bound.rs:1:30 + | +LL | fn foo() where T: for<'a> 'a {} + | ^^ undeclared lifetime + | + = note: for more information on higher-ranked polymorphism, visit https://doc.rust-lang.org/nomicon/hrtb.html +help: consider making the bound lifetime-generic with a new `'a` lifetime + | +LL | fn foo() where for<'a> T: for<'a> 'a {} + | +++++++ +help: consider introducing lifetime `'a` here + | +LL | fn foo<'a, T>() where T: for<'a> 'a {} + | +++ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0261`. diff --git a/tests/ui/impl-trait/precise-capturing/bound-modifiers.rs b/tests/ui/impl-trait/precise-capturing/bound-modifiers.rs new file mode 100644 index 0000000000000..15f2188262869 --- /dev/null +++ b/tests/ui/impl-trait/precise-capturing/bound-modifiers.rs @@ -0,0 +1,25 @@ +//@ edition: 2021 + +#![feature(precise_capturing)] + +fn polarity() -> impl Sized + ?use<> {} +//~^ ERROR expected identifier, found keyword `use` +//~| ERROR cannot find trait `r#use` in this scope +//~| WARN relaxing a default bound only does something for `?Sized` +//~| WARN relaxing a default bound only does something for `?Sized` + +fn asyncness() -> impl Sized + async use<> {} +//~^ ERROR expected identifier, found keyword `use` +//~| ERROR cannot find trait `r#use` in this scope +//~| ERROR async closures are unstable + +fn constness() -> impl Sized + const use<> {} +//~^ ERROR expected identifier, found keyword `use` +//~| ERROR cannot find trait `r#use` in this scope +//~| ERROR const trait impls are experimental + +fn binder() -> impl Sized + for<'a> use<> {} +//~^ ERROR expected identifier, found keyword `use` +//~| ERROR cannot find trait `r#use` in this scope + +fn main() {} diff --git a/tests/ui/impl-trait/precise-capturing/bound-modifiers.stderr b/tests/ui/impl-trait/precise-capturing/bound-modifiers.stderr new file mode 100644 index 0000000000000..4602225e7b922 --- /dev/null +++ b/tests/ui/impl-trait/precise-capturing/bound-modifiers.stderr @@ -0,0 +1,87 @@ +error: expected identifier, found keyword `use` + --> $DIR/bound-modifiers.rs:5:32 + | +LL | fn polarity() -> impl Sized + ?use<> {} + | ^^^ expected identifier, found keyword + +error: expected identifier, found keyword `use` + --> $DIR/bound-modifiers.rs:11:38 + | +LL | fn asyncness() -> impl Sized + async use<> {} + | ^^^ expected identifier, found keyword + +error: expected identifier, found keyword `use` + --> $DIR/bound-modifiers.rs:16:38 + | +LL | fn constness() -> impl Sized + const use<> {} + | ^^^ expected identifier, found keyword + +error: expected identifier, found keyword `use` + --> $DIR/bound-modifiers.rs:21:37 + | +LL | fn binder() -> impl Sized + for<'a> use<> {} + | ^^^ expected identifier, found keyword + +error[E0405]: cannot find trait `r#use` in this scope + --> $DIR/bound-modifiers.rs:5:32 + | +LL | fn polarity() -> impl Sized + ?use<> {} + | ^^^ not found in this scope + +error[E0405]: cannot find trait `r#use` in this scope + --> $DIR/bound-modifiers.rs:11:38 + | +LL | fn asyncness() -> impl Sized + async use<> {} + | ^^^ not found in this scope + +error[E0405]: cannot find trait `r#use` in this scope + --> $DIR/bound-modifiers.rs:16:38 + | +LL | fn constness() -> impl Sized + const use<> {} + | ^^^ not found in this scope + +error[E0405]: cannot find trait `r#use` in this scope + --> $DIR/bound-modifiers.rs:21:37 + | +LL | fn binder() -> impl Sized + for<'a> use<> {} + | ^^^ not found in this scope + +error[E0658]: async closures are unstable + --> $DIR/bound-modifiers.rs:11:32 + | +LL | fn asyncness() -> impl Sized + async use<> {} + | ^^^^^ + | + = note: see issue #62290 for more information + = help: add `#![feature(async_closure)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + = help: to use an async block, remove the `||`: `async {` + +error[E0658]: const trait impls are experimental + --> $DIR/bound-modifiers.rs:16:32 + | +LL | fn constness() -> impl Sized + const use<> {} + | ^^^^^ + | + = note: see issue #67792 for more information + = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +warning: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default + --> $DIR/bound-modifiers.rs:5:31 + | +LL | fn polarity() -> impl Sized + ?use<> {} + | ^^^^^^ + +warning: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default + --> $DIR/bound-modifiers.rs:5:31 + | +LL | fn polarity() -> impl Sized + ?use<> {} + | ^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: aborting due to 10 previous errors; 2 warnings emitted + +Some errors have detailed explanations: E0405, E0658. +For more information about an error, try `rustc --explain E0405`. From d526adad2580d20c6f01c4c285e699492dbd45f7 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 27 Jun 2024 15:32:29 -0400 Subject: [PATCH 437/892] Basic lint detecting closure-returning-async-block --- compiler/rustc_lint/messages.ftl | 3 + compiler/rustc_lint/src/async_closures.rs | 110 ++++++++++++++++++++++ compiler/rustc_lint/src/lib.rs | 3 + 3 files changed, 116 insertions(+) create mode 100644 compiler/rustc_lint/src/async_closures.rs diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl index 46cf87d1e3c17..8c4cfe9b87e60 100644 --- a/compiler/rustc_lint/messages.ftl +++ b/compiler/rustc_lint/messages.ftl @@ -187,6 +187,9 @@ lint_cfg_attr_no_attributes = lint_check_name_unknown_tool = unknown lint tool: `{$tool_name}` +lint_closure_returning_async_block = closure returning async block can be made into an async closure + .label = this async block can be removed, and the closure can be turned into an async closure + lint_command_line_source = `forbid` lint level was set on command line lint_confusable_identifier_pair = found both `{$existing_sym}` and `{$sym}` as identifiers, which look alike diff --git a/compiler/rustc_lint/src/async_closures.rs b/compiler/rustc_lint/src/async_closures.rs new file mode 100644 index 0000000000000..8a72b1d153b0b --- /dev/null +++ b/compiler/rustc_lint/src/async_closures.rs @@ -0,0 +1,110 @@ +use rustc_hir as hir; +use rustc_macros::LintDiagnostic; +use rustc_session::{declare_lint, declare_lint_pass}; +use rustc_span::Span; + +use crate::{LateContext, LateLintPass}; + +declare_lint! { + /// The `closure_returning_async_block` lint detects cases where users + /// write a closure that returns an async block. + /// + /// ### Example + /// + /// ```rust + /// #![warn(closure_returning_async_block)] + /// let c = |x: &str| async {}; + /// ``` + /// + /// {{produces}} + /// + /// ### Explanation + /// + /// Using an async closure is preferable over a closure that returns an + /// async block, since async closures are less restrictive in how its + /// captures are allowed to be used. + /// + /// For example, this code does not work with a closure returning an async + /// block: + /// + /// ```rust,compile_fail + /// async fn callback(x: &str) {} + /// + /// let captured_str = String::new(); + /// let c = move || async { + /// callback(&captured_str).await; + /// }; + /// ``` + /// + /// But it does work with async closures: + /// + /// ```rust + /// #![feature(async_closure)] + /// + /// async fn callback(x: &str) {} + /// + /// let captured_str = String::new(); + /// let c = async move || { + /// callback(&captured_str).await; + /// }; + /// ``` + pub CLOSURE_RETURNING_ASYNC_BLOCK, + Allow, + "closure that returns `async {}` could be rewritten as an async closure", + @feature_gate = async_closure; +} + +declare_lint_pass!( + /// Lint for potential usages of async closures and async fn trait bounds. + AsyncClosureUsage => [CLOSURE_RETURNING_ASYNC_BLOCK] +); + +impl<'tcx> LateLintPass<'tcx> for AsyncClosureUsage { + fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'tcx>) { + let hir::ExprKind::Closure(&hir::Closure { + body, + kind: hir::ClosureKind::Closure, + fn_decl_span, + .. + }) = expr.kind + else { + return; + }; + + let mut body = cx.tcx.hir().body(body).value; + + // Only peel blocks that have no expressions. + while let hir::ExprKind::Block(&hir::Block { stmts: [], expr: Some(tail), .. }, None) = + body.kind + { + body = tail; + } + + let hir::ExprKind::Closure(&hir::Closure { + kind: + hir::ClosureKind::Coroutine(hir::CoroutineKind::Desugared( + hir::CoroutineDesugaring::Async, + hir::CoroutineSource::Block, + )), + fn_decl_span: async_decl_span, + .. + }) = body.kind + else { + return; + }; + + cx.tcx.emit_node_span_lint( + CLOSURE_RETURNING_ASYNC_BLOCK, + expr.hir_id, + fn_decl_span, + ClosureReturningAsyncBlock { async_decl_span }, + ); + } +} + +#[derive(LintDiagnostic)] +#[diag(lint_closure_returning_async_block)] +struct ClosureReturningAsyncBlock { + #[label] + async_decl_span: Span, +} diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index 7dae2de7bfb58..43e6e6498b3a1 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -41,6 +41,7 @@ #![feature(trait_upcasting)] // tidy-alphabetical-end +mod async_closures; mod async_fn_in_trait; pub mod builtin; mod context; @@ -86,6 +87,7 @@ use rustc_hir::def_id::LocalModDefId; use rustc_middle::query::Providers; use rustc_middle::ty::TyCtxt; +use async_closures::AsyncClosureUsage; use async_fn_in_trait::AsyncFnInTrait; use builtin::*; use deref_into_dyn_supertrait::*; @@ -227,6 +229,7 @@ late_lint_methods!( MapUnitFn: MapUnitFn, MissingDebugImplementations: MissingDebugImplementations, MissingDoc: MissingDoc, + AsyncClosureUsage: AsyncClosureUsage, AsyncFnInTrait: AsyncFnInTrait, NonLocalDefinitions: NonLocalDefinitions::default(), ImplTraitOvercaptures: ImplTraitOvercaptures, From acc13e29d1f42805ea0701c05f59beb646978c1d Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 28 Jun 2024 15:56:06 -0400 Subject: [PATCH 438/892] Make it into a structured suggestion, maybe-incorrect --- compiler/rustc_lint/messages.ftl | 1 + compiler/rustc_lint/src/async_closures.rs | 23 ++++++- .../lint-closure-returning-async-block.rs | 21 ++++++ .../lint-closure-returning-async-block.stderr | 67 +++++++++++++++++++ 4 files changed, 110 insertions(+), 2 deletions(-) create mode 100644 tests/ui/async-await/async-closures/lint-closure-returning-async-block.rs create mode 100644 tests/ui/async-await/async-closures/lint-closure-returning-async-block.stderr diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl index 8c4cfe9b87e60..88f01c158b560 100644 --- a/compiler/rustc_lint/messages.ftl +++ b/compiler/rustc_lint/messages.ftl @@ -189,6 +189,7 @@ lint_check_name_unknown_tool = unknown lint tool: `{$tool_name}` lint_closure_returning_async_block = closure returning async block can be made into an async closure .label = this async block can be removed, and the closure can be turned into an async closure + .suggestion = turn this into an async closure lint_command_line_source = `forbid` lint level was set on command line diff --git a/compiler/rustc_lint/src/async_closures.rs b/compiler/rustc_lint/src/async_closures.rs index 8a72b1d153b0b..33cc5738262f6 100644 --- a/compiler/rustc_lint/src/async_closures.rs +++ b/compiler/rustc_lint/src/async_closures.rs @@ -1,5 +1,5 @@ use rustc_hir as hir; -use rustc_macros::LintDiagnostic; +use rustc_macros::{LintDiagnostic, Subdiagnostic}; use rustc_session::{declare_lint, declare_lint_pass}; use rustc_span::Span; @@ -93,11 +93,19 @@ impl<'tcx> LateLintPass<'tcx> for AsyncClosureUsage { return; }; + let deletion_span = cx.tcx.sess.source_map().span_extend_while_whitespace(async_decl_span); + cx.tcx.emit_node_span_lint( CLOSURE_RETURNING_ASYNC_BLOCK, expr.hir_id, fn_decl_span, - ClosureReturningAsyncBlock { async_decl_span }, + ClosureReturningAsyncBlock { + async_decl_span, + sugg: AsyncClosureSugg { + deletion_span, + insertion_span: fn_decl_span.shrink_to_lo(), + }, + }, ); } } @@ -107,4 +115,15 @@ impl<'tcx> LateLintPass<'tcx> for AsyncClosureUsage { struct ClosureReturningAsyncBlock { #[label] async_decl_span: Span, + #[subdiagnostic] + sugg: AsyncClosureSugg, +} + +#[derive(Subdiagnostic)] +#[multipart_suggestion(lint_suggestion, applicability = "maybe-incorrect")] +struct AsyncClosureSugg { + #[suggestion_part(code = "")] + deletion_span: Span, + #[suggestion_part(code = "async ")] + insertion_span: Span, } diff --git a/tests/ui/async-await/async-closures/lint-closure-returning-async-block.rs b/tests/ui/async-await/async-closures/lint-closure-returning-async-block.rs new file mode 100644 index 0000000000000..3e2ab8321a890 --- /dev/null +++ b/tests/ui/async-await/async-closures/lint-closure-returning-async-block.rs @@ -0,0 +1,21 @@ +//@ edition: 2021 + +#![feature(async_closure)] +#![deny(closure_returning_async_block)] + +fn main() { + let x = || async {}; + //~^ ERROR closure returning async block can be made into an async closure + + let x = || async move {}; + //~^ ERROR closure returning async block can be made into an async closure + + let x = move || async move {}; + //~^ ERROR closure returning async block can be made into an async closure + + let x = move || async {}; + //~^ ERROR closure returning async block can be made into an async closure + + let x = || {{ async {} }}; + //~^ ERROR closure returning async block can be made into an async closure +} diff --git a/tests/ui/async-await/async-closures/lint-closure-returning-async-block.stderr b/tests/ui/async-await/async-closures/lint-closure-returning-async-block.stderr new file mode 100644 index 0000000000000..4c0c4d797d8ef --- /dev/null +++ b/tests/ui/async-await/async-closures/lint-closure-returning-async-block.stderr @@ -0,0 +1,67 @@ +error: closure returning async block can be made into an async closure + --> $DIR/lint-closure-returning-async-block.rs:7:13 + | +LL | let x = || async {}; + | ^^ ----- this async block can be removed, and the closure can be turned into an async closure + | +note: the lint level is defined here + --> $DIR/lint-closure-returning-async-block.rs:4:9 + | +LL | #![deny(closure_returning_async_block)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: turn this into an async closure + | +LL - let x = || async {}; +LL + let x = async || {}; + | + +error: closure returning async block can be made into an async closure + --> $DIR/lint-closure-returning-async-block.rs:10:13 + | +LL | let x = || async move {}; + | ^^ ---------- this async block can be removed, and the closure can be turned into an async closure + | +help: turn this into an async closure + | +LL - let x = || async move {}; +LL + let x = async || {}; + | + +error: closure returning async block can be made into an async closure + --> $DIR/lint-closure-returning-async-block.rs:13:13 + | +LL | let x = move || async move {}; + | ^^^^^^^ ---------- this async block can be removed, and the closure can be turned into an async closure + | +help: turn this into an async closure + | +LL - let x = move || async move {}; +LL + let x = async move || {}; + | + +error: closure returning async block can be made into an async closure + --> $DIR/lint-closure-returning-async-block.rs:16:13 + | +LL | let x = move || async {}; + | ^^^^^^^ ----- this async block can be removed, and the closure can be turned into an async closure + | +help: turn this into an async closure + | +LL - let x = move || async {}; +LL + let x = async move || {}; + | + +error: closure returning async block can be made into an async closure + --> $DIR/lint-closure-returning-async-block.rs:19:13 + | +LL | let x = || {{ async {} }}; + | ^^ ----- this async block can be removed, and the closure can be turned into an async closure + | +help: turn this into an async closure + | +LL - let x = || {{ async {} }}; +LL + let x = async || {{ {} }}; + | + +error: aborting due to 5 previous errors + From c9f36f8cd7a6b0c76b5c99e12e888405fffdb829 Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Fri, 28 Jun 2024 19:05:01 -0700 Subject: [PATCH 439/892] Only update `Eq` operands in GVN if you can update both sides Otherwise the types might not match Fixes 127089 --- compiler/rustc_mir_transform/src/gvn.rs | 10 ++-- .../gvn_ptr_eq_with_constant.main.GVN.diff | 52 +++++++++++++++++++ tests/mir-opt/gvn_ptr_eq_with_constant.rs | 23 ++++++++ 3 files changed, 80 insertions(+), 5 deletions(-) create mode 100644 tests/mir-opt/gvn_ptr_eq_with_constant.main.GVN.diff create mode 100644 tests/mir-opt/gvn_ptr_eq_with_constant.rs diff --git a/compiler/rustc_mir_transform/src/gvn.rs b/compiler/rustc_mir_transform/src/gvn.rs index 936a7e2d9dedd..3dbdeb615cfe2 100644 --- a/compiler/rustc_mir_transform/src/gvn.rs +++ b/compiler/rustc_mir_transform/src/gvn.rs @@ -1074,11 +1074,11 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { { lhs = *lhs_value; rhs = *rhs_value; - if let Some(op) = self.try_as_operand(lhs, location) { - *lhs_operand = op; - } - if let Some(op) = self.try_as_operand(rhs, location) { - *rhs_operand = op; + if let Some(lhs_op) = self.try_as_operand(lhs, location) + && let Some(rhs_op) = self.try_as_operand(rhs, location) + { + *lhs_operand = lhs_op; + *rhs_operand = rhs_op; } } diff --git a/tests/mir-opt/gvn_ptr_eq_with_constant.main.GVN.diff b/tests/mir-opt/gvn_ptr_eq_with_constant.main.GVN.diff new file mode 100644 index 0000000000000..3af78d9b6ce98 --- /dev/null +++ b/tests/mir-opt/gvn_ptr_eq_with_constant.main.GVN.diff @@ -0,0 +1,52 @@ +- // MIR for `main` before GVN ++ // MIR for `main` after GVN + + fn main() -> () { + let mut _0: (); + let _1: bool; + let mut _2: *mut u8; + scope 1 (inlined dangling_mut::) { + let mut _3: usize; + scope 2 (inlined align_of::) { + } + scope 3 (inlined without_provenance_mut::) { + } + } + scope 4 (inlined Foo::::cmp_ptr) { + let mut _4: *const u8; + let mut _5: *mut u8; + let mut _6: *const u8; + scope 5 (inlined std::ptr::eq::) { + } + } + + bb0: { + StorageLive(_1); + StorageLive(_2); + StorageLive(_3); +- _3 = AlignOf(u8); +- _2 = _3 as *mut u8 (Transmute); ++ _3 = const 1_usize; ++ _2 = const {0x1 as *mut u8}; + StorageDead(_3); + StorageLive(_4); + StorageLive(_5); +- _5 = _2; +- _4 = _2 as *const u8 (PtrToPtr); ++ _5 = const {0x1 as *mut u8}; ++ _4 = const {0x1 as *const u8}; + StorageDead(_5); + StorageLive(_6); +- _6 = const Foo::::SENTINEL as *const u8 (PtrToPtr); +- _1 = Eq(_4, _6); ++ _6 = const {0x1 as *const u8}; ++ _1 = const true; + StorageDead(_6); + StorageDead(_4); + StorageDead(_2); + StorageDead(_1); + _0 = const (); + return; + } + } + diff --git a/tests/mir-opt/gvn_ptr_eq_with_constant.rs b/tests/mir-opt/gvn_ptr_eq_with_constant.rs new file mode 100644 index 0000000000000..d8025072ee3d3 --- /dev/null +++ b/tests/mir-opt/gvn_ptr_eq_with_constant.rs @@ -0,0 +1,23 @@ +// skip-filecheck +//@ test-mir-pass: GVN +//@ only-64bit +//@ compile-flags: -Z mir-enable-passes=+Inline + +// Regression for + +#![feature(strict_provenance)] + +struct Foo(std::marker::PhantomData); + +impl Foo { + const SENTINEL: *mut T = std::ptr::dangling_mut(); + + fn cmp_ptr(a: *mut T) -> bool { + std::ptr::eq(a, Self::SENTINEL) + } +} + +// EMIT_MIR gvn_ptr_eq_with_constant.main.GVN.diff +pub fn main() { + Foo::::cmp_ptr(std::ptr::dangling_mut()); +} From a62cbda57e23105d68d146cafce94b882882c0e1 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Fri, 28 Jun 2024 23:13:33 -0300 Subject: [PATCH 440/892] Add feature diagnostic for unsafe_extern_blocks --- compiler/rustc_ast_passes/src/ast_validation.rs | 10 +++++++++- .../feature-gate-unsafe-extern-blocks.stderr | 4 ++++ tests/ui/parser/unsafe-foreign-mod-2.stderr | 4 ++++ tests/ui/parser/unsafe-foreign-mod.stderr | 4 ++++ 4 files changed, 21 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index ba4b6130b60c8..d02b8510975fc 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -1088,7 +1088,15 @@ impl<'a> Visitor<'a> for AstValidator<'a> { } } } else if let &Safety::Unsafe(span) = safety { - this.dcx().emit_err(errors::UnsafeItem { span, kind: "extern block" }); + let mut diag = this + .dcx() + .create_err(errors::UnsafeItem { span, kind: "extern block" }); + rustc_session::parse::add_feature_diagnostics( + &mut diag, + self.session, + sym::unsafe_extern_blocks, + ); + diag.emit(); } if abi.is_none() { diff --git a/tests/ui/feature-gates/feature-gate-unsafe-extern-blocks.stderr b/tests/ui/feature-gates/feature-gate-unsafe-extern-blocks.stderr index 84f00827c6010..5653494630899 100644 --- a/tests/ui/feature-gates/feature-gate-unsafe-extern-blocks.stderr +++ b/tests/ui/feature-gates/feature-gate-unsafe-extern-blocks.stderr @@ -3,6 +3,10 @@ error: extern block cannot be declared unsafe | LL | unsafe extern "C" { | ^^^^^^ + | + = 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/feature-gate-unsafe-extern-blocks.rs:9:5 diff --git a/tests/ui/parser/unsafe-foreign-mod-2.stderr b/tests/ui/parser/unsafe-foreign-mod-2.stderr index 77a383d5efa26..07dbd5568d053 100644 --- a/tests/ui/parser/unsafe-foreign-mod-2.stderr +++ b/tests/ui/parser/unsafe-foreign-mod-2.stderr @@ -9,6 +9,10 @@ error: extern block cannot be declared unsafe | LL | extern "C" unsafe { | ^^^^^^ + | + = 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: items in unadorned `extern` blocks cannot have safety qualifiers --> $DIR/unsafe-foreign-mod-2.rs:4:5 diff --git a/tests/ui/parser/unsafe-foreign-mod.stderr b/tests/ui/parser/unsafe-foreign-mod.stderr index 77f6e93be10bb..60b918a89b34d 100644 --- a/tests/ui/parser/unsafe-foreign-mod.stderr +++ b/tests/ui/parser/unsafe-foreign-mod.stderr @@ -3,6 +3,10 @@ error: extern block cannot be declared unsafe | LL | unsafe extern "C" { | ^^^^^^ + | + = 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 1 previous error From 64c8366ca2a8c4e9cbf67f3eac6b4ab81e0d63bf Mon Sep 17 00:00:00 2001 From: The Miri Cronjob Bot Date: Sat, 29 Jun 2024 05:13:25 +0000 Subject: [PATCH 441/892] 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 a6096c0bf2cbe..fd59ad3b8f130 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version @@ -1 +1 @@ -9c3bc805dd9cb84019c124b9a50fdff1e62a7ec9 +9ed2ab3790ff41bf741dd690befd6a1c1e2b23ca From 0afc774e9dc3d000ecd3df05d14cfe0304908fbe Mon Sep 17 00:00:00 2001 From: onur-ozkan Date: Sat, 29 Jun 2024 08:05:53 +0300 Subject: [PATCH 442/892] unify `bin_helpers` and `dylib` utility modules Signed-off-by: onur-ozkan --- src/bootstrap/src/utils/dylib.rs | 40 ------------- src/bootstrap/src/utils/mod.rs | 2 +- .../{bin_helpers.rs => shared_helpers.rs} | 59 +++++++++++++++++-- 3 files changed, 54 insertions(+), 47 deletions(-) delete mode 100644 src/bootstrap/src/utils/dylib.rs rename src/bootstrap/src/utils/{bin_helpers.rs => shared_helpers.rs} (50%) diff --git a/src/bootstrap/src/utils/dylib.rs b/src/bootstrap/src/utils/dylib.rs deleted file mode 100644 index 90bcff59a647c..0000000000000 --- a/src/bootstrap/src/utils/dylib.rs +++ /dev/null @@ -1,40 +0,0 @@ -//! Various utilities for working with dylib paths. - -/// Returns the environment variable which the dynamic library lookup path -/// resides in for this platform. -pub fn dylib_path_var() -> &'static str { - if cfg!(target_os = "windows") { - "PATH" - } else if cfg!(target_vendor = "apple") { - "DYLD_LIBRARY_PATH" - } else if cfg!(target_os = "haiku") { - "LIBRARY_PATH" - } else if cfg!(target_os = "aix") { - "LIBPATH" - } else { - "LD_LIBRARY_PATH" - } -} - -/// Parses the `dylib_path_var()` environment variable, returning a list of -/// paths that are members of this lookup path. -pub fn dylib_path() -> Vec { - let var = match std::env::var_os(dylib_path_var()) { - Some(v) => v, - None => return vec![], - }; - std::env::split_paths(&var).collect() -} - -/// Given an executable called `name`, return the filename for the -/// executable for a particular target. -#[allow(dead_code)] -pub fn exe(name: &str, target: &str) -> String { - if target.contains("windows") { - format!("{name}.exe") - } else if target.contains("uefi") { - format!("{name}.efi") - } else { - name.to_string() - } -} diff --git a/src/bootstrap/src/utils/mod.rs b/src/bootstrap/src/utils/mod.rs index cb535f0e1632a..53b41f1578060 100644 --- a/src/bootstrap/src/utils/mod.rs +++ b/src/bootstrap/src/utils/mod.rs @@ -6,11 +6,11 @@ pub(crate) mod cache; pub(crate) mod cc_detect; pub(crate) mod change_tracker; pub(crate) mod channel; -pub(crate) mod dylib; pub(crate) mod exec; pub(crate) mod helpers; pub(crate) mod job; #[cfg(feature = "build-metrics")] pub(crate) mod metrics; pub(crate) mod render_tests; +pub(crate) mod shared_helpers; pub(crate) mod tarball; diff --git a/src/bootstrap/src/utils/bin_helpers.rs b/src/bootstrap/src/utils/shared_helpers.rs similarity index 50% rename from src/bootstrap/src/utils/bin_helpers.rs rename to src/bootstrap/src/utils/shared_helpers.rs index 5fbbe0bde0e28..8ec7116f6cab1 100644 --- a/src/bootstrap/src/utils/bin_helpers.rs +++ b/src/bootstrap/src/utils/shared_helpers.rs @@ -1,18 +1,65 @@ -//! This file is meant to be included directly from bootstrap shims to avoid a -//! dependency on the bootstrap library. This reduces the binary size and -//! improves compilation time by reducing the linking time. +//! This module serves two purposes: +//! 1. It is part of the `utils` module and used in other parts of bootstrap. +//! 2. It is embedded inside bootstrap shims to avoid a dependency on the bootstrap library. +//! Therefore, this module should never use any other bootstrap module. This reduces binary +//! size and improves compilation time by minimizing linking time. + +#![allow(dead_code)] use std::env; +use std::ffi::OsString; use std::fs::OpenOptions; use std::io::Write; use std::process::Command; use std::str::FromStr; +#[cfg(test)] +mod tests; + +/// Returns the environment variable which the dynamic library lookup path +/// resides in for this platform. +pub fn dylib_path_var() -> &'static str { + if cfg!(target_os = "windows") { + "PATH" + } else if cfg!(target_vendor = "apple") { + "DYLD_LIBRARY_PATH" + } else if cfg!(target_os = "haiku") { + "LIBRARY_PATH" + } else if cfg!(target_os = "aix") { + "LIBPATH" + } else { + "LD_LIBRARY_PATH" + } +} + +/// Parses the `dylib_path_var()` environment variable, returning a list of +/// paths that are members of this lookup path. +pub fn dylib_path() -> Vec { + let var = match std::env::var_os(dylib_path_var()) { + Some(v) => v, + None => return vec![], + }; + std::env::split_paths(&var).collect() +} + +/// Given an executable called `name`, return the filename for the +/// executable for a particular target. +#[allow(dead_code)] +pub fn exe(name: &str, target: &str) -> String { + if target.contains("windows") { + format!("{name}.exe") + } else if target.contains("uefi") { + format!("{name}.efi") + } else { + name.to_string() + } +} + /// Parses the value of the "RUSTC_VERBOSE" environment variable and returns it as a `usize`. /// If it was not defined, returns 0 by default. /// /// Panics if "RUSTC_VERBOSE" is defined with the value that is not an unsigned integer. -pub(crate) fn parse_rustc_verbose() -> usize { +pub fn parse_rustc_verbose() -> usize { match env::var("RUSTC_VERBOSE") { Ok(s) => usize::from_str(&s).expect("RUSTC_VERBOSE should be an integer"), Err(_) => 0, @@ -22,7 +69,7 @@ pub(crate) fn parse_rustc_verbose() -> usize { /// Parses the value of the "RUSTC_STAGE" environment variable and returns it as a `String`. /// /// If "RUSTC_STAGE" was not set, the program will be terminated with 101. -pub(crate) fn parse_rustc_stage() -> String { +pub fn parse_rustc_stage() -> String { env::var("RUSTC_STAGE").unwrap_or_else(|_| { // Don't panic here; it's reasonable to try and run these shims directly. Give a helpful error instead. eprintln!("rustc shim: FATAL: RUSTC_STAGE was not set"); @@ -35,7 +82,7 @@ pub(crate) fn parse_rustc_stage() -> String { /// /// Before writing it, replaces user-specific values to create generic dumps for cross-environment /// comparisons. -pub(crate) fn maybe_dump(dump_name: String, cmd: &Command) { +pub fn maybe_dump(dump_name: String, cmd: &Command) { if let Ok(dump_dir) = env::var("DUMP_BOOTSTRAP_SHIMS") { let dump_file = format!("{dump_dir}/{dump_name}"); From 50edb32939898fa6c22f3e2b2596317a031acaa7 Mon Sep 17 00:00:00 2001 From: surechen Date: Sat, 29 Jun 2024 14:23:33 +0800 Subject: [PATCH 443/892] Fix a error suggestion for E0121 when using placeholder _ as return types on function signature. Recommit after refactoring based on comment: https://github.com/rust-lang/rust/pull/126017#issuecomment-2189149361 But when changing return type's lifetime to `ReError` will affect the subsequent borrow check process and cause test11 in typeck_type_placeholder_item.rs to lost E0515 message. ```rust fn test11(x: &usize) -> &_ { //~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types &x //~ ERROR cannot return reference to function parameter(this E0515 msg will disappear) } ``` --- compiler/rustc_hir_analysis/src/collect.rs | 19 ++++++++- ...er-return-ty-for-fn-sig-issue-125488.fixed | 33 ++++++++++++++++ ...infer-return-ty-for-fn-sig-issue-125488.rs | 33 ++++++++++++++++ ...r-return-ty-for-fn-sig-issue-125488.stderr | 39 +++++++++++++++++++ .../ui/typeck/typeck_type_placeholder_item.rs | 2 +- .../typeck_type_placeholder_item.stderr | 12 ++---- 6 files changed, 127 insertions(+), 11 deletions(-) create mode 100644 tests/ui/return/infer-return-ty-for-fn-sig-issue-125488.fixed create mode 100644 tests/ui/return/infer-return-ty-for-fn-sig-issue-125488.rs create mode 100644 tests/ui/return/infer-return-ty-for-fn-sig-issue-125488.stderr diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index c6e8759327f03..36d0704b5b036 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -1459,8 +1459,25 @@ fn infer_return_ty_for_fn_sig<'tcx>( Some(ty) => { let fn_sig = tcx.typeck(def_id).liberated_fn_sigs()[hir_id]; // Typeck doesn't expect erased regions to be returned from `type_of`. + // This is a heuristic approach. If the scope has region paramters, + // we should change fn_sig's lifetime from `ReErased` to `ReError`, + // otherwise to `ReStatic`. + let has_region_params = generics.params.iter().any(|param| match param.kind { + GenericParamKind::Lifetime { .. } => true, + _ => false, + }); let fn_sig = tcx.fold_regions(fn_sig, |r, _| match *r { - ty::ReErased => tcx.lifetimes.re_static, + ty::ReErased => { + if has_region_params { + ty::Region::new_error_with_message( + tcx, + DUMMY_SP, + "erased region is not allowed here in return type", + ) + } else { + tcx.lifetimes.re_static + } + } _ => r, }); diff --git a/tests/ui/return/infer-return-ty-for-fn-sig-issue-125488.fixed b/tests/ui/return/infer-return-ty-for-fn-sig-issue-125488.fixed new file mode 100644 index 0000000000000..442ade6abf16d --- /dev/null +++ b/tests/ui/return/infer-return-ty-for-fn-sig-issue-125488.fixed @@ -0,0 +1,33 @@ +//@ run-rustfix + +#[allow(dead_code)] + +fn main() { + struct S<'a>(&'a ()); + + fn f1(s: S<'_>) -> S<'_> { + //~^ ERROR the placeholder `_` is not allowed + s + } + + fn f2(s: S<'_>) -> S<'_> { + //~^ ERROR the placeholder `_` is not allowed + let x = true; + if x { + s + } else { + s + } + } + + fn f3(s: S<'_>) -> S<'_> { + //~^ ERROR the placeholder `_` is not allowed + return s; + } + + fn f4(s: S<'_>) -> S<'_> { + //~^ ERROR the placeholder `_` is not allowed + let _x = 1; + return s; + } +} diff --git a/tests/ui/return/infer-return-ty-for-fn-sig-issue-125488.rs b/tests/ui/return/infer-return-ty-for-fn-sig-issue-125488.rs new file mode 100644 index 0000000000000..04ea3a28addfb --- /dev/null +++ b/tests/ui/return/infer-return-ty-for-fn-sig-issue-125488.rs @@ -0,0 +1,33 @@ +//@ run-rustfix + +#[allow(dead_code)] + +fn main() { + struct S<'a>(&'a ()); + + fn f1(s: S<'_>) -> _ { + //~^ ERROR the placeholder `_` is not allowed + s + } + + fn f2(s: S<'_>) -> _ { + //~^ ERROR the placeholder `_` is not allowed + let x = true; + if x { + s + } else { + s + } + } + + fn f3(s: S<'_>) -> _ { + //~^ ERROR the placeholder `_` is not allowed + return s; + } + + fn f4(s: S<'_>) -> _ { + //~^ ERROR the placeholder `_` is not allowed + let _x = 1; + return s; + } +} diff --git a/tests/ui/return/infer-return-ty-for-fn-sig-issue-125488.stderr b/tests/ui/return/infer-return-ty-for-fn-sig-issue-125488.stderr new file mode 100644 index 0000000000000..8b7c5e1681ad1 --- /dev/null +++ b/tests/ui/return/infer-return-ty-for-fn-sig-issue-125488.stderr @@ -0,0 +1,39 @@ +error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types + --> $DIR/infer-return-ty-for-fn-sig-issue-125488.rs:8:24 + | +LL | fn f1(s: S<'_>) -> _ { + | ^ + | | + | not allowed in type signatures + | help: replace with the correct return type: `S<'_>` + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types + --> $DIR/infer-return-ty-for-fn-sig-issue-125488.rs:13:24 + | +LL | fn f2(s: S<'_>) -> _ { + | ^ + | | + | not allowed in type signatures + | help: replace with the correct return type: `S<'_>` + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types + --> $DIR/infer-return-ty-for-fn-sig-issue-125488.rs:23:24 + | +LL | fn f3(s: S<'_>) -> _ { + | ^ + | | + | not allowed in type signatures + | help: replace with the correct return type: `S<'_>` + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types + --> $DIR/infer-return-ty-for-fn-sig-issue-125488.rs:28:24 + | +LL | fn f4(s: S<'_>) -> _ { + | ^ + | | + | not allowed in type signatures + | help: replace with the correct return type: `S<'_>` + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0121`. diff --git a/tests/ui/typeck/typeck_type_placeholder_item.rs b/tests/ui/typeck/typeck_type_placeholder_item.rs index a95b44e807c5d..29a21a1f45f56 100644 --- a/tests/ui/typeck/typeck_type_placeholder_item.rs +++ b/tests/ui/typeck/typeck_type_placeholder_item.rs @@ -47,7 +47,7 @@ impl Test9 { fn test11(x: &usize) -> &_ { //~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types - &x //~ ERROR cannot return reference to function parameter + &x } unsafe fn test12(x: *const usize) -> *const *const _ { diff --git a/tests/ui/typeck/typeck_type_placeholder_item.stderr b/tests/ui/typeck/typeck_type_placeholder_item.stderr index 7977504dae1d6..9d295f88da5aa 100644 --- a/tests/ui/typeck/typeck_type_placeholder_item.stderr +++ b/tests/ui/typeck/typeck_type_placeholder_item.stderr @@ -158,7 +158,7 @@ LL | fn test11(x: &usize) -> &_ { | -^ | || | |not allowed in type signatures - | help: replace with the correct return type: `&'static &'static usize` + | help: replace with the correct return type: `&&usize` error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types --> $DIR/typeck_type_placeholder_item.rs:53:52 @@ -687,13 +687,7 @@ help: add `#![feature(const_trait_impl)]` to the crate attributes to enable LL + #![feature(const_trait_impl)] | -error[E0515]: cannot return reference to function parameter `x` - --> $DIR/typeck_type_placeholder_item.rs:50:5 - | -LL | &x - | ^^ returns a reference to data owned by the current function - -error: aborting due to 75 previous errors +error: aborting due to 74 previous errors -Some errors have detailed explanations: E0015, E0046, E0121, E0282, E0403, E0515. +Some errors have detailed explanations: E0015, E0046, E0121, E0282, E0403. For more information about an error, try `rustc --explain E0015`. From 9098474dadaa7a6034652313bd4914ddbcf764c5 Mon Sep 17 00:00:00 2001 From: onur-ozkan Date: Sat, 29 Jun 2024 08:06:26 +0300 Subject: [PATCH 444/892] create `shared_helpers::parse_value_from_args` Signed-off-by: onur-ozkan --- src/bootstrap/src/bin/rustc.rs | 27 +++++++++--------- src/bootstrap/src/bin/rustdoc.rs | 20 ++++++------- src/bootstrap/src/utils/helpers.rs | 4 +-- src/bootstrap/src/utils/shared_helpers.rs | 17 ++++++++++- .../src/utils/shared_helpers/tests.rs | 28 +++++++++++++++++++ 5 files changed, 69 insertions(+), 27 deletions(-) create mode 100644 src/bootstrap/src/utils/shared_helpers/tests.rs diff --git a/src/bootstrap/src/bin/rustc.rs b/src/bootstrap/src/bin/rustc.rs index d227419917767..009e62469b4d1 100644 --- a/src/bootstrap/src/bin/rustc.rs +++ b/src/bootstrap/src/bin/rustc.rs @@ -20,26 +20,24 @@ use std::path::{Path, PathBuf}; use std::process::{Child, Command}; use std::time::Instant; -use dylib_util::{dylib_path, dylib_path_var, exe}; +use shared_helpers::{ + dylib_path, dylib_path_var, exe, maybe_dump, parse_rustc_stage, parse_rustc_verbose, + parse_value_from_args, +}; -#[path = "../utils/bin_helpers.rs"] -mod bin_helpers; - -#[path = "../utils/dylib.rs"] -mod dylib_util; +#[path = "../utils/shared_helpers.rs"] +mod shared_helpers; fn main() { let orig_args = env::args_os().skip(1).collect::>(); let mut args = orig_args.clone(); - let arg = - |name| orig_args.windows(2).find(|args| args[0] == name).and_then(|args| args[1].to_str()); - let stage = bin_helpers::parse_rustc_stage(); - let verbose = bin_helpers::parse_rustc_verbose(); + let stage = parse_rustc_stage(); + let verbose = parse_rustc_verbose(); // Detect whether or not we're a build script depending on whether --target // is passed (a bit janky...) - let target = arg("--target"); + let target = parse_value_from_args(&orig_args, "--target"); let version = args.iter().find(|w| &**w == "-vV"); // Use a different compiler for build scripts, since there may not yet be a @@ -102,7 +100,7 @@ fn main() { cmd.args(&args).env(dylib_path_var(), env::join_paths(&dylib_path).unwrap()); // Get the name of the crate we're compiling, if any. - let crate_name = arg("--crate-name"); + let crate_name = parse_value_from_args(&orig_args, "--crate-name"); if let Some(crate_name) = crate_name { if let Some(target) = env::var_os("RUSTC_TIME") { @@ -143,10 +141,11 @@ fn main() { cmd.arg("-C").arg("panic=abort"); } + let crate_type = parse_value_from_args(&orig_args, "--crate-type"); // `-Ztls-model=initial-exec` must not be applied to proc-macros, see // issue https://github.com/rust-lang/rust/issues/100530 if env::var("RUSTC_TLS_MODEL_INITIAL_EXEC").is_ok() - && arg("--crate-type") != Some("proc-macro") + && crate_type != Some("proc-macro") && !matches!(crate_name, Some("proc_macro2" | "quote" | "syn" | "synstructure")) { cmd.arg("-Ztls-model=initial-exec"); @@ -251,7 +250,7 @@ fn main() { eprintln!("{prefix} libdir: {libdir:?}"); } - bin_helpers::maybe_dump(format!("stage{stage}-rustc"), &cmd); + maybe_dump(format!("stage{stage}-rustc"), &cmd); let start = Instant::now(); let (child, status) = { diff --git a/src/bootstrap/src/bin/rustdoc.rs b/src/bootstrap/src/bin/rustdoc.rs index b4d1415189cfa..ba6b0c2dbdad7 100644 --- a/src/bootstrap/src/bin/rustdoc.rs +++ b/src/bootstrap/src/bin/rustdoc.rs @@ -6,19 +6,19 @@ use std::env; use std::path::PathBuf; use std::process::Command; -use dylib_util::{dylib_path, dylib_path_var}; +use shared_helpers::{ + dylib_path, dylib_path_var, maybe_dump, parse_rustc_stage, parse_rustc_verbose, + parse_value_from_args, +}; -#[path = "../utils/bin_helpers.rs"] -mod bin_helpers; - -#[path = "../utils/dylib.rs"] -mod dylib_util; +#[path = "../utils/shared_helpers.rs"] +mod shared_helpers; fn main() { let args = env::args_os().skip(1).collect::>(); - let stage = bin_helpers::parse_rustc_stage(); - let verbose = bin_helpers::parse_rustc_verbose(); + let stage = parse_rustc_stage(); + let verbose = parse_rustc_verbose(); let rustdoc = env::var_os("RUSTDOC_REAL").expect("RUSTDOC_REAL was not set"); let libdir = env::var_os("RUSTDOC_LIBDIR").expect("RUSTDOC_LIBDIR was not set"); @@ -26,7 +26,7 @@ fn main() { // Detect whether or not we're a build script depending on whether --target // is passed (a bit janky...) - let target = args.windows(2).find(|w| &*w[0] == "--target").and_then(|w| w[1].to_str()); + let target = parse_value_from_args(&args, "--target"); let mut dylib_path = dylib_path(); dylib_path.insert(0, PathBuf::from(libdir.clone())); @@ -62,7 +62,7 @@ fn main() { cmd.arg("-Zunstable-options"); cmd.arg("--check-cfg=cfg(bootstrap)"); - bin_helpers::maybe_dump(format!("stage{stage}-rustdoc"), &cmd); + maybe_dump(format!("stage{stage}-rustdoc"), &cmd); if verbose > 1 { eprintln!( diff --git a/src/bootstrap/src/utils/helpers.rs b/src/bootstrap/src/utils/helpers.rs index 59b29eedb7971..9fed7de681458 100644 --- a/src/bootstrap/src/utils/helpers.rs +++ b/src/bootstrap/src/utils/helpers.rs @@ -18,7 +18,7 @@ use crate::core::builder::Builder; use crate::core::config::{Config, TargetSelection}; use crate::LldMode; -pub use crate::utils::dylib::{dylib_path, dylib_path_var}; +pub use crate::utils::shared_helpers::{dylib_path, dylib_path_var}; #[cfg(test)] mod tests; @@ -50,7 +50,7 @@ macro_rules! t { pub use t; pub fn exe(name: &str, target: TargetSelection) -> String { - crate::utils::dylib::exe(name, &target.triple) + crate::utils::shared_helpers::exe(name, &target.triple) } /// Returns `true` if the file name given looks like a dynamic library. diff --git a/src/bootstrap/src/utils/shared_helpers.rs b/src/bootstrap/src/utils/shared_helpers.rs index 8ec7116f6cab1..7150c84313c55 100644 --- a/src/bootstrap/src/utils/shared_helpers.rs +++ b/src/bootstrap/src/utils/shared_helpers.rs @@ -44,7 +44,6 @@ pub fn dylib_path() -> Vec { /// Given an executable called `name`, return the filename for the /// executable for a particular target. -#[allow(dead_code)] pub fn exe(name: &str, target: &str) -> String { if target.contains("windows") { format!("{name}.exe") @@ -95,3 +94,19 @@ pub fn maybe_dump(dump_name: String, cmd: &Command) { file.write_all(cmd_dump.as_bytes()).expect("Unable to write file"); } } + +/// Finds `key` and returns its value from the given list of arguments `args`. +pub fn parse_value_from_args<'a>(args: &'a [OsString], key: &str) -> Option<&'a str> { + let mut args = args.iter(); + while let Some(arg) = args.next() { + let arg = arg.to_str().unwrap(); + + if let Some(value) = arg.strip_prefix(&format!("{key}=")) { + return Some(value); + } else if arg == key { + return args.next().map(|v| v.to_str().unwrap()); + } + } + + None +} diff --git a/src/bootstrap/src/utils/shared_helpers/tests.rs b/src/bootstrap/src/utils/shared_helpers/tests.rs new file mode 100644 index 0000000000000..da7924276f7c8 --- /dev/null +++ b/src/bootstrap/src/utils/shared_helpers/tests.rs @@ -0,0 +1,28 @@ +use super::parse_value_from_args; + +#[test] +fn test_parse_value_from_args() { + let args = vec![ + "--stage".into(), + "1".into(), + "--version".into(), + "2".into(), + "--target".into(), + "x86_64-unknown-linux".into(), + ]; + + assert_eq!(parse_value_from_args(args.as_slice(), "--stage").unwrap(), "1"); + assert_eq!(parse_value_from_args(args.as_slice(), "--version").unwrap(), "2"); + assert_eq!(parse_value_from_args(args.as_slice(), "--target").unwrap(), "x86_64-unknown-linux"); + assert!(parse_value_from_args(args.as_slice(), "random-key").is_none()); + + let args = vec![ + "app-name".into(), + "--key".into(), + "value".into(), + "random-value".into(), + "--sysroot=/x/y/z".into(), + ]; + assert_eq!(parse_value_from_args(args.as_slice(), "--key").unwrap(), "value"); + assert_eq!(parse_value_from_args(args.as_slice(), "--sysroot").unwrap(), "/x/y/z"); +} From fa12064d6de52baeb3ca4f5fdc26828facb6c11c Mon Sep 17 00:00:00 2001 From: Chris Denton Date: Sat, 29 Jun 2024 07:27:25 +0000 Subject: [PATCH 445/892] Don't get output if `lldb --version` errors --- src/bootstrap/src/core/build_steps/test.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index 1ef5af7cc2daf..55010f09049eb 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -7,6 +7,7 @@ use std::env; use std::ffi::OsStr; use std::ffi::OsString; use std::fs; +use std::io::ErrorKind; use std::iter; use std::path::{Path, PathBuf}; use std::process::{Command, Stdio}; @@ -1830,6 +1831,9 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the let lldb_version = Command::new(&lldb_exe) .arg("--version") .output() + .and_then(|output| { + if output.status.success() { Ok(output) } else { Err(ErrorKind::Other.into()) } + }) .map(|output| String::from_utf8_lossy(&output.stdout).to_string()) .ok(); if let Some(ref vers) = lldb_version { From c59e7fd95b985cb3622cdbf46cf31b7b250a0342 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Sun, 23 Jun 2024 18:14:44 +0200 Subject: [PATCH 446/892] crashes: add more tests --- tests/crashes/126646.rs | 18 ++++++++++++++++++ tests/crashes/126648.rs | 8 ++++++++ tests/crashes/126666.rs | 18 ++++++++++++++++++ tests/crashes/126667.rs | 14 ++++++++++++++ tests/crashes/126680.rs | 21 +++++++++++++++++++++ tests/crashes/126696.rs | 24 ++++++++++++++++++++++++ tests/crashes/126725.rs | 20 ++++++++++++++++++++ tests/crashes/126744.rs | 8 ++++++++ tests/crashes/126850.rs | 11 +++++++++++ 9 files changed, 142 insertions(+) create mode 100644 tests/crashes/126646.rs create mode 100644 tests/crashes/126648.rs create mode 100644 tests/crashes/126666.rs create mode 100644 tests/crashes/126667.rs create mode 100644 tests/crashes/126680.rs create mode 100644 tests/crashes/126696.rs create mode 100644 tests/crashes/126725.rs create mode 100644 tests/crashes/126744.rs create mode 100644 tests/crashes/126850.rs diff --git a/tests/crashes/126646.rs b/tests/crashes/126646.rs new file mode 100644 index 0000000000000..24e3530320a89 --- /dev/null +++ b/tests/crashes/126646.rs @@ -0,0 +1,18 @@ +//@ known-bug: rust-lang/rust#126646 +mod foo { + pub trait Callable { + type Output; + fn call() -> Self::Output; + } + + impl<'a, V: ?Sized> Callable for &'a () { + type Output = (); + } +} +use foo::*; + +fn test<'a>() -> impl Sized { + <&'a () as Callable>::call() +} + +fn main() {} diff --git a/tests/crashes/126648.rs b/tests/crashes/126648.rs new file mode 100644 index 0000000000000..1cf3e44bba9bc --- /dev/null +++ b/tests/crashes/126648.rs @@ -0,0 +1,8 @@ +//@ known-bug: rust-lang/rust#126648 +struct Outest(*const &'a ()); + +fn make() -> Outest {} + +fn main() { + if let Outest("foo") = make() {} +} diff --git a/tests/crashes/126666.rs b/tests/crashes/126666.rs new file mode 100644 index 0000000000000..58526707c9ab4 --- /dev/null +++ b/tests/crashes/126666.rs @@ -0,0 +1,18 @@ +//@ known-bug: rust-lang/rust#126666 +#![feature(const_mut_refs)] +#![feature(const_refs_to_static)] +#![feature(object_safe_for_dispatch)] + +struct Meh { + x: &'static dyn UnsafeCell, +} + +const MUH: Meh = Meh { + x: &mut *(&READONLY as *const _ as *mut _), +}; + +static READONLY: i32 = 0; + +trait UnsafeCell<'a> {} + +pub fn main() {} diff --git a/tests/crashes/126667.rs b/tests/crashes/126667.rs new file mode 100644 index 0000000000000..27b170d6da5fc --- /dev/null +++ b/tests/crashes/126667.rs @@ -0,0 +1,14 @@ +//@ known-bug: rust-lang/rust#126667 +#![warn(rust_2021_compatibility)] + +trait Static<'a> {} + +struct Foo((u32, u32)); + +fn main() { + type T = impl Static; + let foo: T = Foo((1u32, 2u32)); + let x = move || { + let Foo((a, b)) = foo; + }; +} diff --git a/tests/crashes/126680.rs b/tests/crashes/126680.rs new file mode 100644 index 0000000000000..b1566d5e6beed --- /dev/null +++ b/tests/crashes/126680.rs @@ -0,0 +1,21 @@ +//@ known-bug: rust-lang/rust#126680 +//@ compile-flags: -Zvalidate-mir +#![feature(type_alias_impl_trait)] +type Bar = impl std::fmt::Display; + +use std::path::Path; + +struct A { + pub func: fn(check: Bar, b: Option<&Path>), +} +const MY_A: A = A { + func: |check, b| { + if check { + () + } else if let Some(_) = b.and_then(|p| p.parent()) { + () + } + }, +}; + +fn main() {} diff --git a/tests/crashes/126696.rs b/tests/crashes/126696.rs new file mode 100644 index 0000000000000..51dcf6cf29405 --- /dev/null +++ b/tests/crashes/126696.rs @@ -0,0 +1,24 @@ +//@ known-bug: rust-lang/rust#126696 +#![feature(generic_const_exprs)] +#![allow(incomplete_features)] + +fn can_double(x: [(); N]) +where + [(); N * 2]:, +{ + x[0]; + unimplemented!() +} + +fn foo() +where + [(); (N + 1) * 2]:, +{ + can_double([(); { N + 1 }]); + // Adding an explicit constant generic causes the ICE to go away + // can_double::<{N + 1}>([(); { N + 1 }]); +} + +fn main() { + foo::<1>(); +} diff --git a/tests/crashes/126725.rs b/tests/crashes/126725.rs new file mode 100644 index 0000000000000..d7a7d21ae4244 --- /dev/null +++ b/tests/crashes/126725.rs @@ -0,0 +1,20 @@ +//@ known-bug: rust-lang/rust#126725 +trait Foo { + fn foo<'a>(&'a self) -> <&'a impl Sized as Bar>::Output; +} + +trait Bar { + type Output; +} + +struct X(i32); + +impl<'a> Bar for &'a X { + type Output = &'a i32; +} + +impl Foo for X { + fn foo<'a>(&'a self) -> <&'a Self as Bar>::Output { + &self.0 + } +} diff --git a/tests/crashes/126744.rs b/tests/crashes/126744.rs new file mode 100644 index 0000000000000..ed562c86e61b2 --- /dev/null +++ b/tests/crashes/126744.rs @@ -0,0 +1,8 @@ +//@ known-bug: rust-lang/rust#126744 +struct X {,} + +fn main() { + || { + if let X { x: 1,} = (X {}) {} + }; +} diff --git a/tests/crashes/126850.rs b/tests/crashes/126850.rs new file mode 100644 index 0000000000000..0ddc24c8bb151 --- /dev/null +++ b/tests/crashes/126850.rs @@ -0,0 +1,11 @@ +//@ known-bug: rust-lang/rust#126850 +fn bug() -> impl Iterator< + Item = [(); { + |found: &String| Some(false); + 4 + }], +> { + std::iter::empty() +} + +fn main() {} From a6ef91e41425ba315cb11ee20a99f3fdc714c6cf Mon Sep 17 00:00:00 2001 From: Chris Denton Date: Sat, 29 Jun 2024 07:57:58 +0000 Subject: [PATCH 447/892] Update test.rs --- src/bootstrap/src/core/build_steps/test.rs | 28 ++++++++++------------ 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index 55010f09049eb..7ac39227d3f17 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -7,7 +7,6 @@ use std::env; use std::ffi::OsStr; use std::ffi::OsString; use std::fs; -use std::io::ErrorKind; use std::iter; use std::path::{Path, PathBuf}; use std::process::{Command, Stdio}; @@ -1817,26 +1816,25 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the cmd.arg("--gdb").arg(gdb); } - let run = |cmd: &mut Command| { - cmd.output().map(|output| { - String::from_utf8_lossy(&output.stdout) - .lines() - .next() - .unwrap_or_else(|| panic!("{:?} failed {:?}", cmd, output)) - .to_string() - }) - }; - let lldb_exe = builder.config.lldb.clone().unwrap_or_else(|| PathBuf::from("lldb")); let lldb_version = Command::new(&lldb_exe) .arg("--version") .output() - .and_then(|output| { - if output.status.success() { Ok(output) } else { Err(ErrorKind::Other.into()) } + .map(|output| { + (String::from_utf8_lossy(&output.stdout).to_string(), output.status.success()) }) - .map(|output| String::from_utf8_lossy(&output.stdout).to_string()) - .ok(); + .ok() + .and_then(|(output, success)| if success { Some(output) } else { None }); if let Some(ref vers) = lldb_version { + let run = |cmd: &mut Command| { + cmd.output().map(|output| { + String::from_utf8_lossy(&output.stdout) + .lines() + .next() + .unwrap_or_else(|| panic!("{:?} failed {:?}", cmd, output)) + .to_string() + }) + }; cmd.arg("--lldb-version").arg(vers); let lldb_python_dir = run(Command::new(&lldb_exe).arg("-P")).ok(); if let Some(ref dir) = lldb_python_dir { From 4442fd7a0985ad3ac219b4f9ce8f26a27500acac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Fri, 28 Jun 2024 12:18:32 +0200 Subject: [PATCH 448/892] Add a run-make test that LLD is not being used by default on the x64 beta/stable channel --- .../rust-lld-by-default-beta-stable/main.rs | 1 + .../rust-lld-by-default-beta-stable/rmake.rs | 29 +++++++++++++++++++ .../main.rs | 0 .../rmake.rs | 4 +-- 4 files changed, 32 insertions(+), 2 deletions(-) create mode 100644 tests/run-make/rust-lld-by-default-beta-stable/main.rs create mode 100644 tests/run-make/rust-lld-by-default-beta-stable/rmake.rs rename tests/run-make/{rust-lld-by-default => rust-lld-by-default-nightly}/main.rs (100%) rename tests/run-make/{rust-lld-by-default => rust-lld-by-default-nightly}/rmake.rs (93%) diff --git a/tests/run-make/rust-lld-by-default-beta-stable/main.rs b/tests/run-make/rust-lld-by-default-beta-stable/main.rs new file mode 100644 index 0000000000000..f328e4d9d04c3 --- /dev/null +++ b/tests/run-make/rust-lld-by-default-beta-stable/main.rs @@ -0,0 +1 @@ +fn main() {} 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 new file mode 100644 index 0000000000000..fc3dffdbaf42a --- /dev/null +++ b/tests/run-make/rust-lld-by-default-beta-stable/rmake.rs @@ -0,0 +1,29 @@ +// Ensure that rust-lld is *not* used as the default linker on `x86_64-unknown-linux-gnu` on stable +// or beta. + +//@ ignore-nightly +//@ only-x86_64-unknown-linux-gnu + +use run_make_support::regex::Regex; +use run_make_support::rustc; +use std::process::Output; + +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() + .env("RUSTC_LOG", "rustc_codegen_ssa::back::link=info") + .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{}", + output.stderr_utf8() + ); +} + +fn find_lld_version_in_logs(stderr: String) -> bool { + let lld_version_re = Regex::new(r"^LLD [0-9]+\.[0-9]+\.[0-9]+").unwrap(); + stderr.lines().any(|line| lld_version_re.is_match(line.trim())) +} diff --git a/tests/run-make/rust-lld-by-default/main.rs b/tests/run-make/rust-lld-by-default-nightly/main.rs similarity index 100% rename from tests/run-make/rust-lld-by-default/main.rs rename to tests/run-make/rust-lld-by-default-nightly/main.rs diff --git a/tests/run-make/rust-lld-by-default/rmake.rs b/tests/run-make/rust-lld-by-default-nightly/rmake.rs similarity index 93% rename from tests/run-make/rust-lld-by-default/rmake.rs rename to tests/run-make/rust-lld-by-default-nightly/rmake.rs index 94857a57dfb7c..f3ce9ada15709 100644 --- a/tests/run-make/rust-lld-by-default/rmake.rs +++ b/tests/run-make/rust-lld-by-default-nightly/rmake.rs @@ -1,5 +1,5 @@ -// Ensure that rust-lld is used as the default linker on `x86_64-unknown-linux-gnu`, and that it can -// also be turned off with a CLI flag. +// Ensure that rust-lld is used as the default linker on `x86_64-unknown-linux-gnu` on the nightly +// channel, and that it can also be turned off with a CLI flag. //@ needs-rust-lld //@ ignore-beta From 4ee077aa63cbcf0e4f398988939fdb6bb020c322 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 27 Jun 2024 16:15:08 +0200 Subject: [PATCH 449/892] Migrate `run-make/override-aliased-flags` to `rmake.rs` --- .../tidy/src/allowed_run_make_makefiles.txt | 1 - .../run-make/override-aliased-flags/Makefile | 23 ------------------ .../run-make/override-aliased-flags/rmake.rs | 24 +++++++++++++++++++ 3 files changed, 24 insertions(+), 24 deletions(-) delete mode 100644 tests/run-make/override-aliased-flags/Makefile create mode 100644 tests/run-make/override-aliased-flags/rmake.rs diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index 73ef7c5ba2579..f601151294eb9 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -114,7 +114,6 @@ run-make/obey-crate-type-flag/Makefile run-make/optimization-remarks-dir-pgo/Makefile run-make/optimization-remarks-dir/Makefile run-make/output-type-permutations/Makefile -run-make/override-aliased-flags/Makefile run-make/panic-abort-eh_frame/Makefile run-make/pass-linker-flags-flavor/Makefile run-make/pass-linker-flags-from-dep/Makefile diff --git a/tests/run-make/override-aliased-flags/Makefile b/tests/run-make/override-aliased-flags/Makefile deleted file mode 100644 index db1ff1ff98161..0000000000000 --- a/tests/run-make/override-aliased-flags/Makefile +++ /dev/null @@ -1,23 +0,0 @@ -# ignore-cross-compile -include ../tools.mk - -# FIXME: it would be good to check that it's actually the rightmost flags -# that are used when multiple flags are specified, but I can't think of a -# reliable way to check this. - -all: - # Test that `-O` and `-C opt-level` can be specified multiple times. - # The rightmost flag will be used over any previous flags. - $(RUSTC) -O -O main.rs - $(RUSTC) -O -C opt-level=0 main.rs - $(RUSTC) -C opt-level=0 -O main.rs - $(RUSTC) -C opt-level=0 -C opt-level=2 main.rs - $(RUSTC) -C opt-level=2 -C opt-level=0 main.rs - - # Test that `-g` and `-C debuginfo` can be specified multiple times. - # The rightmost flag will be used over any previous flags. - $(RUSTC) -g -g main.rs - $(RUSTC) -g -C debuginfo=0 main.rs - $(RUSTC) -C debuginfo=0 -g main.rs - $(RUSTC) -C debuginfo=0 -C debuginfo=2 main.rs - $(RUSTC) -C debuginfo=2 -C debuginfo=0 main.rs diff --git a/tests/run-make/override-aliased-flags/rmake.rs b/tests/run-make/override-aliased-flags/rmake.rs new file mode 100644 index 0000000000000..e610c04651e95 --- /dev/null +++ b/tests/run-make/override-aliased-flags/rmake.rs @@ -0,0 +1,24 @@ +//@ ignore-cross-compile + +use run_make_support::rustc; + +// FIXME: it would be good to check that it's actually the rightmost flags +// that are used when multiple flags are specified, but I can't think of a +// reliable way to check this. +fn main() { + // Test that `-O` and `-C opt-level` can be specified multiple times. + // The rightmost flag will be used over any previous flags. + rustc().arg("-O").arg("-O").input("main.rs").run(); + rustc().arg("-O").arg("-C").arg("opt-level=0").input("main.rs").run(); + rustc().arg("-C").arg("opt-level=0").arg("-O").input("main.rs").run(); + rustc().arg("-C").arg("opt-level=0").arg("-C").arg("opt-level=2").input("main.rs").run(); + rustc().arg("-C").arg("opt-level=2").arg("-C").arg("opt-level=0").input("main.rs").run(); + + // Test that `-g` and `-C debuginfo` can be specified multiple times. + // The rightmost flag will be used over any previous flags. + rustc().arg("-g").arg("-g").input("main.rs").run(); + rustc().arg("-g").arg("-C").arg("debuginfo=0").input("main.rs").run(); + rustc().arg("-C").arg("debuginfo=0").arg("-g").input("main.rs").run(); + rustc().arg("-C").arg("debuginfo=0").arg("-C").arg("debuginfo=2").input("main.rs").run(); + rustc().arg("-C").arg("debuginfo=2").arg("-C").arg("debuginfo=0").input("main.rs").run(); +} From b1d1e663892f43ca8ea9efe999e25e83f9b6dded Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 28 Jun 2024 13:40:17 +0200 Subject: [PATCH 450/892] Add back `help-page.goml` rustdoc GUI test --- tests/rustdoc-gui/help-page.goml | 69 ++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 tests/rustdoc-gui/help-page.goml diff --git a/tests/rustdoc-gui/help-page.goml b/tests/rustdoc-gui/help-page.goml new file mode 100644 index 0000000000000..09d33af139cdd --- /dev/null +++ b/tests/rustdoc-gui/help-page.goml @@ -0,0 +1,69 @@ +// This test ensures that opening the help page in its own tab works. +include: "utils.goml" +go-to: "file://" + |DOC_PATH| + "/help.html" +set-window-size: (1000, 1000) // Try desktop size first. +wait-for: "#help" +assert-css: ("#help", {"display": "block"}) +assert-css: ("#help dd", {"font-size": "16px"}) +click: "#help-button > a" +assert-css: ("#help", {"display": "block"}) +compare-elements-property: (".sub", "#help", ["offsetWidth"]) +compare-elements-position: (".sub", "#help", ["x"]) +set-window-size: (500, 1000) // Try mobile next. +assert-css: ("#help", {"display": "block"}) +compare-elements-property: (".sub", "#help", ["offsetWidth"]) +compare-elements-position: (".sub", "#help", ["x"]) + +// Checking the color of the elements of the help menu. +show-text: true +define-function: ( + "check-colors", + [theme, color, background, box_shadow], + block { + call-function: ("switch-theme", {"theme": |theme|}) + assert-css: ("#help kbd", { + "color": |color|, + "background-color": |background|, + "box-shadow": |box_shadow| + " 0px -1px 0px 0px inset", + }, ALL) + }, +) + +call-function: ("check-colors", { + "theme": "ayu", + "color": "#c5c5c5", + "background": "#314559", + "box_shadow": "#5c6773", +}) +call-function: ("check-colors", { + "theme": "dark", + "color": "#000", + "background": "#fafbfc", + "box_shadow": "#c6cbd1", +}) +call-function: ("check-colors", { + "theme": "light", + "color": "#000", + "background": "#fafbfc", + "box_shadow": "#c6cbd1", +}) + +// This test ensures that opening the help popover without switching pages works. +go-to: "file://" + |DOC_PATH| + "/test_docs/index.html" +set-window-size: (1000, 1000) // Only supported on desktop. +assert-false: "#help" +click: "#help-button > a" +assert-css: ("#help", {"display": "block"}) +assert-css: ("#help dd", {"font-size": "16px"}) +click: "#help-button > a" +assert-css: ("#help", {"display": "none"}) +compare-elements-property-false: (".sub", "#help", ["offsetWidth"]) +compare-elements-position-false: (".sub", "#help", ["x"]) + +// This test ensures that the "the rustdoc book" anchor link within the help popover works. +go-to: "file://" + |DOC_PATH| + "/test_docs/index.html" +set-window-size: (1000, 1000) // Popover only appears when the screen width is >700px. +assert-false: "#help" +click: "#help-button > a" +click: "//*[@id='help']//a[text()='the rustdoc book']" +wait-for-document-property: ({"URL": "https://doc.rust-lang.org/"}, STARTS_WITH) From c8bbeef12ff7499aa163aef79447677b47499006 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 28 Jun 2024 14:24:41 +0200 Subject: [PATCH 451/892] Don't call `switch-theme` function --- tests/rustdoc-gui/help-page.goml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/rustdoc-gui/help-page.goml b/tests/rustdoc-gui/help-page.goml index 09d33af139cdd..f1a2675128ce4 100644 --- a/tests/rustdoc-gui/help-page.goml +++ b/tests/rustdoc-gui/help-page.goml @@ -1,5 +1,4 @@ // This test ensures that opening the help page in its own tab works. -include: "utils.goml" go-to: "file://" + |DOC_PATH| + "/help.html" set-window-size: (1000, 1000) // Try desktop size first. wait-for: "#help" @@ -20,7 +19,9 @@ define-function: ( "check-colors", [theme, color, background, box_shadow], block { - call-function: ("switch-theme", {"theme": |theme|}) + // FIXME: no clue why we can't call the `switch-theme` function here... + set-local-storage: {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"} + reload: assert-css: ("#help kbd", { "color": |color|, "background-color": |background|, From 66a885b25dbaf01232834a4c81344422750a5c6b Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 29 Jun 2024 12:17:10 +0200 Subject: [PATCH 452/892] iter_exported_symbols: also walk used statics in local crate --- src/tools/miri/src/helpers.rs | 34 ++++++++++++++----- .../miri/tests/pass/tls/win_tls_callback.rs | 16 +++++++++ .../tests/pass/tls/win_tls_callback.stderr | 1 + 3 files changed, 43 insertions(+), 8 deletions(-) create mode 100644 src/tools/miri/tests/pass/tls/win_tls_callback.rs create mode 100644 src/tools/miri/tests/pass/tls/win_tls_callback.stderr diff --git a/src/tools/miri/src/helpers.rs b/src/tools/miri/src/helpers.rs index 3d2b102b279a7..a7a6f8cfd8729 100644 --- a/src/tools/miri/src/helpers.rs +++ b/src/tools/miri/src/helpers.rs @@ -14,6 +14,7 @@ use rustc_hir::{ def_id::{CrateNum, DefId, CRATE_DEF_INDEX, LOCAL_CRATE}, }; use rustc_index::IndexVec; +use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; use rustc_middle::middle::dependency_format::Linkage; use rustc_middle::middle::exported_symbols::ExportedSymbol; use rustc_middle::mir; @@ -163,22 +164,39 @@ pub fn iter_exported_symbols<'tcx>( tcx: TyCtxt<'tcx>, mut f: impl FnMut(CrateNum, DefId) -> InterpResult<'tcx>, ) -> InterpResult<'tcx> { + // First, the symbols in the local crate. We can't use `exported_symbols` here as that + // skips `#[used]` statics (since `reachable_set` skips them in binary crates). + // So we walk all HIR items ourselves instead. + let crate_items = tcx.hir_crate_items(()); + for def_id in crate_items.definitions() { + let exported = tcx.def_kind(def_id).has_codegen_attrs() && { + let codegen_attrs = tcx.codegen_fn_attrs(def_id); + codegen_attrs.contains_extern_indicator() + || codegen_attrs.flags.contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL) + || codegen_attrs.flags.contains(CodegenFnAttrFlags::USED) + || codegen_attrs.flags.contains(CodegenFnAttrFlags::USED_LINKER) + }; + if exported { + f(LOCAL_CRATE, def_id.into())?; + } + } + + // Next, all our dependencies. // `dependency_formats` includes all the transitive informations needed to link a crate, // which is what we need here since we need to dig out `exported_symbols` from all transitive // dependencies. let dependency_formats = tcx.dependency_formats(()); + // Find the dependencies of the executable we are running. let dependency_format = dependency_formats .iter() .find(|(crate_type, _)| *crate_type == CrateType::Executable) .expect("interpreting a non-executable crate"); - for cnum in iter::once(LOCAL_CRATE).chain(dependency_format.1.iter().enumerate().filter_map( - |(num, &linkage)| { - // We add 1 to the number because that's what rustc also does everywhere it - // calls `CrateNum::new`... - #[allow(clippy::arithmetic_side_effects)] - (linkage != Linkage::NotLinked).then_some(CrateNum::new(num + 1)) - }, - )) { + for cnum in dependency_format.1.iter().enumerate().filter_map(|(num, &linkage)| { + // We add 1 to the number because that's what rustc also does everywhere it + // calls `CrateNum::new`... + #[allow(clippy::arithmetic_side_effects)] + (linkage != Linkage::NotLinked).then_some(CrateNum::new(num + 1)) + }) { // We can ignore `_export_info` here: we are a Rust crate, and everything is exported // from a Rust crate. for &(symbol, _export_info) in tcx.exported_symbols(cnum) { diff --git a/src/tools/miri/tests/pass/tls/win_tls_callback.rs b/src/tools/miri/tests/pass/tls/win_tls_callback.rs new file mode 100644 index 0000000000000..99a8de29e9170 --- /dev/null +++ b/src/tools/miri/tests/pass/tls/win_tls_callback.rs @@ -0,0 +1,16 @@ +//! Ensure that we call Windows TLS callbacks in the local crate. +//@only-target-windows +// Calling eprintln in the callback seems to (re-)initialize some thread-local storage +// and then leak the memory allocated for that. Let's just ignore these leaks, +// that's not what this test is about. +//@compile-flags: -Zmiri-ignore-leaks + +#[link_section = ".CRT$XLB"] +#[used] // Miri only considers explicitly `#[used]` statics for `lookup_link_section` +pub static CALLBACK: unsafe extern "system" fn(*const (), u32, *const ()) = tls_callback; + +unsafe extern "system" fn tls_callback(_h: *const (), _dw_reason: u32, _pv: *const ()) { + eprintln!("in tls_callback"); +} + +fn main() {} diff --git a/src/tools/miri/tests/pass/tls/win_tls_callback.stderr b/src/tools/miri/tests/pass/tls/win_tls_callback.stderr new file mode 100644 index 0000000000000..8479558954456 --- /dev/null +++ b/src/tools/miri/tests/pass/tls/win_tls_callback.stderr @@ -0,0 +1 @@ +in tls_callback From 8cbeedac8de7bbf7676129f07f338d106a162036 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 29 Jun 2024 12:18:26 +0200 Subject: [PATCH 453/892] Migrate `run-make/return-non-c-like-enum` to `rmake.rs` --- .../tidy/src/allowed_run_make_makefiles.txt | 1 - tests/run-make/return-non-c-like-enum/Makefile | 8 -------- tests/run-make/return-non-c-like-enum/rmake.rs | 18 ++++++++++++++++++ 3 files changed, 18 insertions(+), 9 deletions(-) delete mode 100644 tests/run-make/return-non-c-like-enum/Makefile create mode 100644 tests/run-make/return-non-c-like-enum/rmake.rs diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index 73ef7c5ba2579..8c59112f595f4 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -147,7 +147,6 @@ run-make/remap-path-prefix/Makefile run-make/reproducible-build-2/Makefile run-make/reproducible-build/Makefile run-make/return-non-c-like-enum-from-c/Makefile -run-make/return-non-c-like-enum/Makefile run-make/rlib-chain/Makefile run-make/rlib-format-packed-bundled-libs-2/Makefile run-make/rlib-format-packed-bundled-libs-3/Makefile diff --git a/tests/run-make/return-non-c-like-enum/Makefile b/tests/run-make/return-non-c-like-enum/Makefile deleted file mode 100644 index 0c8d8bf3acc60..0000000000000 --- a/tests/run-make/return-non-c-like-enum/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -# ignore-cross-compile -include ../tools.mk - -all: - $(RUSTC) --crate-type=staticlib nonclike.rs - $(CC) test.c $(call STATICLIB,nonclike) $(call OUT_EXE,test) \ - $(EXTRACFLAGS) $(EXTRACXXFLAGS) - $(call RUN,test) diff --git a/tests/run-make/return-non-c-like-enum/rmake.rs b/tests/run-make/return-non-c-like-enum/rmake.rs new file mode 100644 index 0000000000000..e698790b43c06 --- /dev/null +++ b/tests/run-make/return-non-c-like-enum/rmake.rs @@ -0,0 +1,18 @@ +// Check that we treat enum variants like union members in call ABIs. +// Added in #68443. +// Original issue: #68190. + +//@ ignore-cross-compile + +use run_make_support::{cc, extra_c_flags, extra_cxx_flags, run, rustc, static_lib_name}; + +fn main() { + rustc().crate_type("staticlib").input("nonclike.rs").run(); + cc().input("test.c") + .arg(&static_lib_name("nonclike")) + .out_exe("test") + .args(&extra_c_flags()) + .args(&extra_cxx_flags()) + .run(); + run("test"); +} From 61ede075bfbb1bcbe09595565381ab9c5ef5deec Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Wed, 26 Jun 2024 14:21:13 +0000 Subject: [PATCH 454/892] Stop ICEing on impossible predicates. --- compiler/rustc_mir_dataflow/src/value_analysis.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_mir_dataflow/src/value_analysis.rs b/compiler/rustc_mir_dataflow/src/value_analysis.rs index 5e2d88f94ca28..bfbfff7e25944 100644 --- a/compiler/rustc_mir_dataflow/src/value_analysis.rs +++ b/compiler/rustc_mir_dataflow/src/value_analysis.rs @@ -846,9 +846,10 @@ impl Map { if let ty::Ref(_, ref_ty, _) | ty::RawPtr(ref_ty, _) = ty.kind() && let ty::Slice(..) = ref_ty.kind() + // The user may have written a predicate like `[T]: Sized` in their where clauses, + // which makes slices scalars. + && self.places[place].value_index.is_none() { - assert!(self.places[place].value_index.is_none(), "slices are not scalars"); - // Prepend new child to the linked list. let len = self.places.push(PlaceInfo::new(Some(TrackElem::DerefLen))); self.places[len].next_sibling = self.places[place].first_child; From a175817ea6b554a3baa2debc4bcfdea88e467eeb Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Wed, 26 Jun 2024 22:25:03 +0000 Subject: [PATCH 455/892] Avoid cloning state when possible. --- compiler/rustc_mir_transform/src/jump_threading.rs | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_mir_transform/src/jump_threading.rs b/compiler/rustc_mir_transform/src/jump_threading.rs index 23cc0c46e7397..0dad003ee5f42 100644 --- a/compiler/rustc_mir_transform/src/jump_threading.rs +++ b/compiler/rustc_mir_transform/src/jump_threading.rs @@ -270,12 +270,13 @@ impl<'tcx, 'a> TOFinder<'tcx, 'a> { self.process_switch_int(discr, targets, bb, &mut state); self.find_opportunity(pred, state, cost, depth + 1); } - _ => self.recurse_through_terminator(pred, &state, &cost, depth), + _ => self.recurse_through_terminator(pred, || state, &cost, depth), } - } else { + } else if let &[ref predecessors @ .., last_pred] = &predecessors[..] { for &pred in predecessors { - self.recurse_through_terminator(pred, &state, &cost, depth); + self.recurse_through_terminator(pred, || state.clone(), &cost, depth); } + self.recurse_through_terminator(last_pred, || state, &cost, depth); } let new_tos = &mut self.opportunities[last_non_rec..]; @@ -566,11 +567,12 @@ impl<'tcx, 'a> TOFinder<'tcx, 'a> { None } - #[instrument(level = "trace", skip(self, cost))] + #[instrument(level = "trace", skip(self, state, cost))] fn recurse_through_terminator( &mut self, bb: BasicBlock, - state: &State>, + // Pass a closure that may clone the state, as we don't want to do it each time. + state: impl FnOnce() -> State>, cost: &CostChecker<'_, 'tcx>, depth: usize, ) { @@ -600,7 +602,7 @@ impl<'tcx, 'a> TOFinder<'tcx, 'a> { }; // We can recurse through this terminator. - let mut state = state.clone(); + let mut state = state(); if let Some(place_to_flood) = place_to_flood { state.flood_with(place_to_flood.as_ref(), self.map, ConditionSet::default()); } From dec4e985221cfa0a45828903f998ce4631c511d5 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Wed, 26 Jun 2024 16:18:03 +0000 Subject: [PATCH 456/892] Move entry point to a method. --- .../rustc_mir_transform/src/jump_threading.rs | 79 ++++++++++--------- 1 file changed, 42 insertions(+), 37 deletions(-) diff --git a/compiler/rustc_mir_transform/src/jump_threading.rs b/compiler/rustc_mir_transform/src/jump_threading.rs index 0dad003ee5f42..27e506a920bce 100644 --- a/compiler/rustc_mir_transform/src/jump_threading.rs +++ b/compiler/rustc_mir_transform/src/jump_threading.rs @@ -91,43 +91,8 @@ impl<'tcx> MirPass<'tcx> for JumpThreading { opportunities: Vec::new(), }; - for (bb, bbdata) in body.basic_blocks.iter_enumerated() { - debug!(?bb, term = ?bbdata.terminator()); - if bbdata.is_cleanup || loop_headers.contains(bb) { - continue; - } - let Some((discr, targets)) = bbdata.terminator().kind.as_switch() else { continue }; - let Some(discr) = discr.place() else { continue }; - debug!(?discr, ?bb); - - let discr_ty = discr.ty(body, tcx).ty; - let Ok(discr_layout) = finder.ecx.layout_of(discr_ty) else { continue }; - - let Some(discr) = finder.map.find(discr.as_ref()) else { continue }; - debug!(?discr); - - let cost = CostChecker::new(tcx, param_env, None, body); - - let mut state = State::new(ConditionSet::default(), finder.map); - - let conds = if let Some((value, then, else_)) = targets.as_static_if() { - let Some(value) = ScalarInt::try_from_uint(value, discr_layout.size) else { - continue; - }; - arena.alloc_from_iter([ - Condition { value, polarity: Polarity::Eq, target: then }, - Condition { value, polarity: Polarity::Ne, target: else_ }, - ]) - } else { - arena.alloc_from_iter(targets.iter().filter_map(|(value, target)| { - let value = ScalarInt::try_from_uint(value, discr_layout.size)?; - Some(Condition { value, polarity: Polarity::Eq, target }) - })) - }; - let conds = ConditionSet(conds); - state.insert_value_idx(discr, conds, finder.map); - - finder.find_opportunity(bb, state, cost, 0); + for bb in body.basic_blocks.indices() { + finder.start_from_switch(bb); } let opportunities = finder.opportunities; @@ -216,6 +181,46 @@ impl<'tcx, 'a> TOFinder<'tcx, 'a> { } /// Recursion entry point to find threading opportunities. + #[instrument(level = "trace", skip(self))] + fn start_from_switch(&mut self, bb: BasicBlock) -> Option { + let bbdata = &self.body[bb]; + if bbdata.is_cleanup || self.loop_headers.contains(bb) { + return None; + } + let (discr, targets) = bbdata.terminator().kind.as_switch()?; + let discr = discr.place()?; + debug!(?discr, ?bb); + + let discr_ty = discr.ty(self.body, self.tcx).ty; + let discr_layout = self.ecx.layout_of(discr_ty).ok()?; + + let discr = self.map.find(discr.as_ref())?; + debug!(?discr); + + let cost = CostChecker::new(self.tcx, self.param_env, None, self.body); + let mut state = State::new(ConditionSet::default(), self.map); + + let conds = if let Some((value, then, else_)) = targets.as_static_if() { + let value = ScalarInt::try_from_uint(value, discr_layout.size)?; + self.arena.alloc_from_iter([ + Condition { value, polarity: Polarity::Eq, target: then }, + Condition { value, polarity: Polarity::Ne, target: else_ }, + ]) + } else { + self.arena.alloc_from_iter(targets.iter().filter_map(|(value, target)| { + let value = ScalarInt::try_from_uint(value, discr_layout.size)?; + Some(Condition { value, polarity: Polarity::Eq, target }) + })) + }; + let conds = ConditionSet(conds); + state.insert_value_idx(discr, conds, self.map); + + self.find_opportunity(bb, state, cost, 0); + None + } + + /// Recursively walk statements backwards from this bb's terminator to find threading + /// opportunities. #[instrument(level = "trace", skip(self, cost), ret)] fn find_opportunity( &mut self, From c81481fdb91cca96635017e7275139b0f2cd8fe6 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Thu, 27 Jun 2024 09:39:37 +0000 Subject: [PATCH 457/892] Move crash test. --- .../116721.rs => ui/mir/sized-slice-predicate-116721.rs} | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) rename tests/{crashes/116721.rs => ui/mir/sized-slice-predicate-116721.rs} (82%) diff --git a/tests/crashes/116721.rs b/tests/ui/mir/sized-slice-predicate-116721.rs similarity index 82% rename from tests/crashes/116721.rs rename to tests/ui/mir/sized-slice-predicate-116721.rs index fc1a6530bc82b..c6a0aca2da80d 100644 --- a/tests/crashes/116721.rs +++ b/tests/ui/mir/sized-slice-predicate-116721.rs @@ -1,5 +1,6 @@ -//@ known-bug: #116721 +//@ build-pass //@ compile-flags: -Zmir-opt-level=3 --emit=mir + fn hey(it: &[T]) where [T]: Clone, From cf6f6ca441e2efd3e196f45f36da253c49cec4c0 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 29 Jun 2024 12:02:44 +0200 Subject: [PATCH 458/892] unreferenced-used-static: run test everywhere --- .../linkage-attr/unreferenced-used-static-issue-127052.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/tests/ui/linkage-attr/unreferenced-used-static-issue-127052.rs b/tests/ui/linkage-attr/unreferenced-used-static-issue-127052.rs index aa8236b74315c..0d34bf988efe6 100644 --- a/tests/ui/linkage-attr/unreferenced-used-static-issue-127052.rs +++ b/tests/ui/linkage-attr/unreferenced-used-static-issue-127052.rs @@ -1,9 +1,10 @@ -// This is a non-regression test for issue #127052 where unreferenced `#[used]` statics couldn't be -// removed by the MSVC linker, causing linking errors. +// This is a non-regression test for issue #127052 where unreferenced `#[used]` statics in the +// binary crate would be marked as "exported", but not be present in the binary, causing linking +// errors with the MSVC linker. //@ build-pass: needs linking -//@ only-msvc #[used] static FOO: u32 = 0; + fn main() {} From 9c0ce05d246811a977b6564b7df2b6947bd6903b Mon Sep 17 00:00:00 2001 From: surechen Date: Sat, 29 Jun 2024 18:45:07 +0800 Subject: [PATCH 459/892] Show `used attribute`'s kind for user when find it isn't applied to a `static` variable. fixes #126789 --- compiler/rustc_passes/messages.ftl | 1 + compiler/rustc_passes/src/check_attr.rs | 10 +++++++--- compiler/rustc_passes/src/errors.rs | 3 +++ tests/ui/attributes/used-issue-126789.rs | 6 ++++++ tests/ui/attributes/used-issue-126789.stderr | 10 ++++++++++ tests/ui/used.stderr | 8 ++++++++ 6 files changed, 35 insertions(+), 3 deletions(-) create mode 100644 tests/ui/attributes/used-issue-126789.rs create mode 100644 tests/ui/attributes/used-issue-126789.stderr diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl index 07c82065a80d1..3cc909a9d6e45 100644 --- a/compiler/rustc_passes/messages.ftl +++ b/compiler/rustc_passes/messages.ftl @@ -786,6 +786,7 @@ passes_used_compiler_linker = passes_used_static = attribute must be applied to a `static` variable + .label = but this is a {$target} passes_useless_assignment = useless assignment of {$is_field_assign -> diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index a0b3470df6dba..238e40022c9cf 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -278,7 +278,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { } self.check_repr(attrs, span, target, item, hir_id); - self.check_used(attrs, target); + self.check_used(attrs, target, span); } fn inline_attr_str_error_with_macro_def(&self, hir_id: HirId, attr: &Attribute, sym: &str) { @@ -1978,12 +1978,16 @@ impl<'tcx> CheckAttrVisitor<'tcx> { } } - fn check_used(&self, attrs: &[Attribute], target: Target) { + fn check_used(&self, attrs: &[Attribute], target: Target, target_span: Span) { let mut used_linker_span = None; let mut used_compiler_span = None; for attr in attrs.iter().filter(|attr| attr.has_name(sym::used)) { if target != Target::Static { - self.dcx().emit_err(errors::UsedStatic { span: attr.span }); + self.dcx().emit_err(errors::UsedStatic { + attr_span: attr.span, + span: target_span, + target: target.name(), + }); } let inner = attr.meta_item_list(); match inner.as_deref() { diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs index 25df80d5a92ca..897a377ce3461 100644 --- a/compiler/rustc_passes/src/errors.rs +++ b/compiler/rustc_passes/src/errors.rs @@ -563,7 +563,10 @@ pub struct ReprConflictingLint; #[diag(passes_used_static)] pub struct UsedStatic { #[primary_span] + pub attr_span: Span, + #[label] pub span: Span, + pub target: &'static str, } #[derive(Diagnostic)] diff --git a/tests/ui/attributes/used-issue-126789.rs b/tests/ui/attributes/used-issue-126789.rs new file mode 100644 index 0000000000000..90a1aa8d5cc3d --- /dev/null +++ b/tests/ui/attributes/used-issue-126789.rs @@ -0,0 +1,6 @@ +extern "C" { + #[used] //~ ERROR attribute must be applied to a `static` variable + static FOO: i32; +} + +fn main() {} diff --git a/tests/ui/attributes/used-issue-126789.stderr b/tests/ui/attributes/used-issue-126789.stderr new file mode 100644 index 0000000000000..6014f7af95c55 --- /dev/null +++ b/tests/ui/attributes/used-issue-126789.stderr @@ -0,0 +1,10 @@ +error: attribute must be applied to a `static` variable + --> $DIR/used-issue-126789.rs:2:5 + | +LL | #[used] + | ^^^^^^^ +LL | static FOO: i32; + | ---------------- but this is a foreign static item + +error: aborting due to 1 previous error + diff --git a/tests/ui/used.stderr b/tests/ui/used.stderr index ea77f129d8ef0..c586dc722932f 100644 --- a/tests/ui/used.stderr +++ b/tests/ui/used.stderr @@ -3,24 +3,32 @@ error: attribute must be applied to a `static` variable | LL | #[used] | ^^^^^^^ +LL | fn foo() {} + | ----------- but this is a function error: attribute must be applied to a `static` variable --> $DIR/used.rs:7:1 | LL | #[used] | ^^^^^^^ +LL | struct Foo {} + | ------------- but this is a struct error: attribute must be applied to a `static` variable --> $DIR/used.rs:10:1 | LL | #[used] | ^^^^^^^ +LL | trait Bar {} + | ------------ but this is a trait error: attribute must be applied to a `static` variable --> $DIR/used.rs:13:1 | LL | #[used] | ^^^^^^^ +LL | impl Bar for Foo {} + | ------------------- but this is a implementation block error: aborting due to 4 previous errors From 64b3492c30eaa3a963ed87a3c306f2cb29baa5b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Sat, 29 Jun 2024 13:51:50 +0200 Subject: [PATCH 460/892] Rename Rust for Linux CI job to make its name clearer --- .../{rfl => x86_64-rust-for-linux}/Dockerfile | 0 src/ci/github-actions/jobs.yml | 10 +++++----- 2 files changed, 5 insertions(+), 5 deletions(-) rename src/ci/docker/host-x86_64/{rfl => x86_64-rust-for-linux}/Dockerfile (100%) diff --git a/src/ci/docker/host-x86_64/rfl/Dockerfile b/src/ci/docker/host-x86_64/x86_64-rust-for-linux/Dockerfile similarity index 100% rename from src/ci/docker/host-x86_64/rfl/Dockerfile rename to src/ci/docker/host-x86_64/x86_64-rust-for-linux/Dockerfile diff --git a/src/ci/github-actions/jobs.yml b/src/ci/github-actions/jobs.yml index cf750bbd0c568..a6e12c6ff954d 100644 --- a/src/ci/github-actions/jobs.yml +++ b/src/ci/github-actions/jobs.yml @@ -215,6 +215,11 @@ auto: only_on_channel: nightly <<: *job-linux-8c + # Tests integration with Rust for Linux. + # Builds stage 1 compiler and tries to compile a few RfL examples with it. + - image: x86_64-rust-for-linux + <<: *job-linux-8c + - image: x86_64-gnu <<: *job-linux-4c @@ -465,8 +470,3 @@ auto: RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-msvc --enable-extended --enable-profiler SCRIPT: python x.py dist bootstrap --include-default-paths <<: *job-windows-8c - - # Tests integration with Rust for Linux. - # Builds stage 1 compiler and tries to compile a few RfL examples with it. - - image: rfl - <<: *job-linux-8c From 8dc36c16470d60fa1bd7bc370c77ac63ef25bfe4 Mon Sep 17 00:00:00 2001 From: Lin Yihai Date: Sat, 29 Jun 2024 16:49:35 +0800 Subject: [PATCH 461/892] fix: prefer `(*p).clone` to `p.clone` if the `p` is a raw pointer --- .../src/diagnostics/conflict_errors.rs | 26 +++++++++++++++--- .../src/diagnostics/move_errors.rs | 27 ++++++++++++++----- .../borrowck-move-from-unsafe-ptr.stderr | 10 ++----- tests/ui/borrowck/issue-20801.stderr | 10 ------- .../move-from-union-field-issue-66500.stderr | 10 +++---- 5 files changed, 50 insertions(+), 33 deletions(-) diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index 1cc7fee718e87..c26bbb926eaa1 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -1288,7 +1288,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> { return false; } // Try to find predicates on *generic params* that would allow copying `ty` - let suggestion = + let mut suggestion = if let Some(symbol) = tcx.hir().maybe_get_struct_pattern_shorthand_field(expr) { format!(": {symbol}.clone()") } else { @@ -1296,6 +1296,8 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> { }; let mut sugg = Vec::with_capacity(2); let mut inner_expr = expr; + let mut is_raw_ptr = false; + let typeck_result = self.infcx.tcx.typeck(self.mir_def_id()); // Remove uses of `&` and `*` when suggesting `.clone()`. while let hir::ExprKind::AddrOf(.., inner) | hir::ExprKind::Unary(hir::UnOp::Deref, inner) = &inner_expr.kind @@ -1306,14 +1308,32 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> { return false; } inner_expr = inner; + if let Some(inner_type) = typeck_result.node_type_opt(inner.hir_id) { + if matches!(inner_type.kind(), ty::RawPtr(..)) { + is_raw_ptr = true; + break; + } + } } - if inner_expr.span.lo() != expr.span.lo() { + // Cloning the raw pointer doesn't make sense in some cases and would cause a type mismatch error. (see #126863) + if inner_expr.span.lo() != expr.span.lo() && !is_raw_ptr { + // Remove "(*" or "(&" sugg.push((expr.span.with_hi(inner_expr.span.lo()), String::new())); } + // Check whether `expr` is surrounded by parentheses or not. let span = if inner_expr.span.hi() != expr.span.hi() { // Account for `(*x)` to suggest `x.clone()`. - expr.span.with_lo(inner_expr.span.hi()) + if is_raw_ptr { + expr.span.shrink_to_hi() + } else { + // Remove the close parenthesis ")" + expr.span.with_lo(inner_expr.span.hi()) + } } else { + if is_raw_ptr { + sugg.push((expr.span.shrink_to_lo(), "(".to_string())); + suggestion = ").clone()".to_string(); + } expr.span.shrink_to_hi() }; sugg.push((span, suggestion)); diff --git a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs index 12fa4c4f5ee05..407b83d497793 100644 --- a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs @@ -639,12 +639,27 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> { fn add_borrow_suggestions(&self, err: &mut Diag<'_>, span: Span) { match self.infcx.tcx.sess.source_map().span_to_snippet(span) { Ok(snippet) if snippet.starts_with('*') => { - err.span_suggestion_verbose( - span.with_hi(span.lo() + BytePos(1)), - "consider removing the dereference here", - String::new(), - Applicability::MaybeIncorrect, - ); + let sp = span.with_lo(span.lo() + BytePos(1)); + let inner = self.find_expr(sp); + let mut is_raw_ptr = false; + if let Some(inner) = inner { + let typck_result = self.infcx.tcx.typeck(self.mir_def_id()); + if let Some(inner_type) = typck_result.node_type_opt(inner.hir_id) { + if matches!(inner_type.kind(), ty::RawPtr(..)) { + is_raw_ptr = true; + } + } + } + // If the `inner` is a raw pointer, do not suggest removing the "*", see #126863 + // FIXME: need to check whether the assigned object can be a raw pointer, see `tests/ui/borrowck/issue-20801.rs`. + if !is_raw_ptr { + err.span_suggestion_verbose( + span.with_hi(span.lo() + BytePos(1)), + "consider removing the dereference here", + String::new(), + Applicability::MaybeIncorrect, + ); + } } _ => { err.span_suggestion_verbose( diff --git a/tests/ui/borrowck/borrowck-move-from-unsafe-ptr.stderr b/tests/ui/borrowck/borrowck-move-from-unsafe-ptr.stderr index ebc3b6ebcacda..79f18624c618b 100644 --- a/tests/ui/borrowck/borrowck-move-from-unsafe-ptr.stderr +++ b/tests/ui/borrowck/borrowck-move-from-unsafe-ptr.stderr @@ -4,16 +4,10 @@ error[E0507]: cannot move out of `*x` which is behind a raw pointer LL | let y = *x; | ^^ move occurs because `*x` has type `Box`, which does not implement the `Copy` trait | -help: consider removing the dereference here - | -LL - let y = *x; -LL + let y = x; - | help: consider cloning the value if the performance cost is acceptable | -LL - let y = *x; -LL + let y = x.clone(); - | +LL | let y = (*x).clone(); + | + +++++++++ error: aborting due to 1 previous error diff --git a/tests/ui/borrowck/issue-20801.stderr b/tests/ui/borrowck/issue-20801.stderr index 20a4bd4e42378..c1d06ac3e2196 100644 --- a/tests/ui/borrowck/issue-20801.stderr +++ b/tests/ui/borrowck/issue-20801.stderr @@ -67,11 +67,6 @@ LL | struct T(u8); ... LL | let c = unsafe { *mut_ptr() }; | ---------- you could clone this value -help: consider removing the dereference here - | -LL - let c = unsafe { *mut_ptr() }; -LL + let c = unsafe { mut_ptr() }; - | error[E0507]: cannot move out of a raw pointer --> $DIR/issue-20801.rs:36:22 @@ -87,11 +82,6 @@ LL | struct T(u8); ... LL | let d = unsafe { *const_ptr() }; | ------------ you could clone this value -help: consider removing the dereference here - | -LL - let d = unsafe { *const_ptr() }; -LL + let d = unsafe { const_ptr() }; - | error: aborting due to 4 previous errors; 1 warning emitted diff --git a/tests/ui/borrowck/move-from-union-field-issue-66500.stderr b/tests/ui/borrowck/move-from-union-field-issue-66500.stderr index c951ce8e3cd8f..7f4593eefcaf6 100644 --- a/tests/ui/borrowck/move-from-union-field-issue-66500.stderr +++ b/tests/ui/borrowck/move-from-union-field-issue-66500.stderr @@ -30,9 +30,8 @@ LL | *u.c | help: consider cloning the value if the performance cost is acceptable | -LL - *u.c -LL + u.c.clone() - | +LL | (*u.c).clone() + | + +++++++++ error[E0507]: cannot move out of `*u.d` which is behind a raw pointer --> $DIR/move-from-union-field-issue-66500.rs:24:5 @@ -42,9 +41,8 @@ LL | *u.d | help: consider cloning the value if the performance cost is acceptable | -LL - *u.d -LL + u.d.clone() - | +LL | (*u.d).clone() + | + +++++++++ error: aborting due to 4 previous errors From 614e04226df82e04c8c3ce30abfda67f26a93bc2 Mon Sep 17 00:00:00 2001 From: Jerry Wang Date: Sun, 23 Jun 2024 16:13:55 -0400 Subject: [PATCH 462/892] Migrate `volatile-intrinsics` to `rmake` --- .../tidy/src/allowed_run_make_makefiles.txt | 1 - tests/run-make/volatile-intrinsics/Makefile | 10 ---------- tests/run-make/volatile-intrinsics/rmake.rs | 18 ++++++++++++++++++ 3 files changed, 18 insertions(+), 11 deletions(-) delete mode 100644 tests/run-make/volatile-intrinsics/Makefile create mode 100644 tests/run-make/volatile-intrinsics/rmake.rs diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index 73ef7c5ba2579..ad80ac8d7c951 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -186,7 +186,6 @@ run-make/track-pgo-dep-info/Makefile run-make/translation/Makefile run-make/type-mismatch-same-crate-name/Makefile run-make/unstable-flag-required/Makefile -run-make/volatile-intrinsics/Makefile run-make/wasm-exceptions-nostd/Makefile run-make/wasm-override-linker/Makefile run-make/weird-output-filenames/Makefile diff --git a/tests/run-make/volatile-intrinsics/Makefile b/tests/run-make/volatile-intrinsics/Makefile deleted file mode 100644 index 5672a045873dd..0000000000000 --- a/tests/run-make/volatile-intrinsics/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -# ignore-cross-compile -include ../tools.mk - -all: - # The tests must pass... - $(RUSTC) main.rs - $(call RUN,main) - # ... and the loads/stores must not be optimized out. - $(RUSTC) main.rs --emit=llvm-ir - $(CGREP) "load volatile" "store volatile" < $(TMPDIR)/main.ll diff --git a/tests/run-make/volatile-intrinsics/rmake.rs b/tests/run-make/volatile-intrinsics/rmake.rs new file mode 100644 index 0000000000000..fb9be4bb9ba23 --- /dev/null +++ b/tests/run-make/volatile-intrinsics/rmake.rs @@ -0,0 +1,18 @@ +//@ ignore-cross-compile + +use run_make_support::fs_wrapper::read; +use run_make_support::{assert_contains, run, rustc}; + +fn main() { + // The tests must pass... + rustc().input("main.rs").run(); + run("main"); + + // ... and the loads/stores must not be optimized out. + rustc().input("main.rs").emit("llvm-ir").run(); + + let raw_llvm_ir = read("main.ll"); + let llvm_ir = String::from_utf8_lossy(&raw_llvm_ir); + assert_contains(&llvm_ir, "load volatile"); + assert_contains(&llvm_ir, "store volatile"); +} From 56fe015d4a2dac7281f573d52aef61835cab3bf9 Mon Sep 17 00:00:00 2001 From: Jerry Wang Date: Sun, 23 Jun 2024 16:31:27 -0400 Subject: [PATCH 463/892] Migrate `weird-output-filenames` to `rmake` --- .../tidy/src/allowed_run_make_makefiles.txt | 1 - .../run-make/weird-output-filenames/Makefile | 15 --------------- .../run-make/weird-output-filenames/rmake.rs | 19 +++++++++++++++++++ 3 files changed, 19 insertions(+), 16 deletions(-) delete mode 100644 tests/run-make/weird-output-filenames/Makefile create mode 100644 tests/run-make/weird-output-filenames/rmake.rs diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index ad80ac8d7c951..f7e1aeb75276a 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -188,5 +188,4 @@ run-make/type-mismatch-same-crate-name/Makefile run-make/unstable-flag-required/Makefile run-make/wasm-exceptions-nostd/Makefile run-make/wasm-override-linker/Makefile -run-make/weird-output-filenames/Makefile run-make/x86_64-fortanix-unknown-sgx-lvi/Makefile diff --git a/tests/run-make/weird-output-filenames/Makefile b/tests/run-make/weird-output-filenames/Makefile deleted file mode 100644 index d3a34e3b46e89..0000000000000 --- a/tests/run-make/weird-output-filenames/Makefile +++ /dev/null @@ -1,15 +0,0 @@ -include ../tools.mk - -all: - cp foo.rs $(TMPDIR)/.foo.rs - $(RUSTC) $(TMPDIR)/.foo.rs 2>&1 \ - | $(CGREP) -e "invalid character.*in crate name:" - cp foo.rs $(TMPDIR)/.foo.bar - $(RUSTC) $(TMPDIR)/.foo.bar 2>&1 \ - | $(CGREP) -e "invalid character.*in crate name:" - cp foo.rs $(TMPDIR)/+foo+bar.rs - $(RUSTC) $(TMPDIR)/+foo+bar.rs 2>&1 \ - | $(CGREP) -e "invalid character.*in crate name:" - cp foo.rs $(TMPDIR)/-foo.rs - $(RUSTC) $(TMPDIR)/-foo.rs 2>&1 \ - | $(CGREP) 'crate names cannot start with a `-`' diff --git a/tests/run-make/weird-output-filenames/rmake.rs b/tests/run-make/weird-output-filenames/rmake.rs new file mode 100644 index 0000000000000..ed331a0b8d4ea --- /dev/null +++ b/tests/run-make/weird-output-filenames/rmake.rs @@ -0,0 +1,19 @@ +use run_make_support::fs_wrapper::copy; +use run_make_support::regex::Regex; +use run_make_support::{cwd, rustc}; + +fn main() { + let invalid_characters = [".foo.rs", ".foo.bar", "+foo+bar.rs"]; + let re = Regex::new(r"invalid character.*in crate name:").unwrap(); + for f in invalid_characters { + copy("foo.rs", f); + let stderr = rustc().input(f).run_fail().stderr_utf8(); + assert!(re.is_match(&stderr)); + } + + copy("foo.rs", "-foo.rs"); + rustc() + .input(cwd().join("-foo.rs")) + .run_fail() + .assert_stderr_contains("crate names cannot start with a `-`"); +} From 189232bc42b7c66d1f75a40a806680b3935f96ca Mon Sep 17 00:00:00 2001 From: Jerry Wang Date: Sun, 23 Jun 2024 16:41:36 -0400 Subject: [PATCH 464/892] Migrate `wasm-override-linker` to `rmake` --- .../tidy/src/allowed_run_make_makefiles.txt | 1 - tests/run-make/wasm-override-linker/Makefile | 16 ---------------- tests/run-make/wasm-override-linker/rmake.rs | 17 +++++++++++++++++ 3 files changed, 17 insertions(+), 17 deletions(-) delete mode 100644 tests/run-make/wasm-override-linker/Makefile create mode 100644 tests/run-make/wasm-override-linker/rmake.rs diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index f7e1aeb75276a..2ab97c3c43751 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -187,5 +187,4 @@ run-make/translation/Makefile run-make/type-mismatch-same-crate-name/Makefile run-make/unstable-flag-required/Makefile run-make/wasm-exceptions-nostd/Makefile -run-make/wasm-override-linker/Makefile run-make/x86_64-fortanix-unknown-sgx-lvi/Makefile diff --git a/tests/run-make/wasm-override-linker/Makefile b/tests/run-make/wasm-override-linker/Makefile deleted file mode 100644 index 1a01a574dee28..0000000000000 --- a/tests/run-make/wasm-override-linker/Makefile +++ /dev/null @@ -1,16 +0,0 @@ -# needs-force-clang-based-tests - -# FIXME(#126180): This test doesn't actually run anywhere, because the only -# CI job that sets RUSTBUILD_FORCE_CLANG_BASED_TESTS runs very few tests. - -include ../tools.mk - -ifeq ($(TARGET),wasm32-unknown-unknown) -all: - $(RUSTC) foo.rs --crate-type cdylib --target $(TARGET) -C linker=$(CLANG) -else ifeq ($(TARGET),wasm64-unknown-unknown) -all: - $(RUSTC) foo.rs --crate-type cdylib --target $(TARGET) -C linker=$(CLANG) -else -all: -endif diff --git a/tests/run-make/wasm-override-linker/rmake.rs b/tests/run-make/wasm-override-linker/rmake.rs new file mode 100644 index 0000000000000..01bc08e990159 --- /dev/null +++ b/tests/run-make/wasm-override-linker/rmake.rs @@ -0,0 +1,17 @@ +// How to run this +// $ RUSTBUILD_FORCE_CLANG_BASED_TESTS=1 ./x.py test tests/run-make/wasm-override-linker/ + +//@ needs-force-clang-based-tests + +use run_make_support::{env_var, rustc, target}; + +fn main() { + if matches!(target().as_str(), "wasm32-unknown-unknown" | "wasm64-unknown-unknown") { + rustc() + .input("foo.rs") + .crate_type("cdylib") + .target(&target()) + .linker(&env_var("CLANG")) + .run(); + } +} From 68b6bb27c1d34e6cd9fe5d6c2d8f954e0f2a0690 Mon Sep 17 00:00:00 2001 From: Jerry Wang Date: Sun, 23 Jun 2024 17:03:36 -0400 Subject: [PATCH 465/892] Migrate `wasm-exceptions-nostd` to `rmake` --- .../tidy/src/allowed_run_make_makefiles.txt | 1 - tests/run-make/wasm-exceptions-nostd/Makefile | 12 ------------ tests/run-make/wasm-exceptions-nostd/rmake.rs | 18 ++++++++++++++++++ .../wasm-exceptions-nostd/src/panicking.rs | 4 ++-- 4 files changed, 20 insertions(+), 15 deletions(-) delete mode 100644 tests/run-make/wasm-exceptions-nostd/Makefile create mode 100644 tests/run-make/wasm-exceptions-nostd/rmake.rs diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index 2ab97c3c43751..c78f9dc4c6ebf 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -186,5 +186,4 @@ run-make/track-pgo-dep-info/Makefile run-make/translation/Makefile run-make/type-mismatch-same-crate-name/Makefile run-make/unstable-flag-required/Makefile -run-make/wasm-exceptions-nostd/Makefile run-make/x86_64-fortanix-unknown-sgx-lvi/Makefile diff --git a/tests/run-make/wasm-exceptions-nostd/Makefile b/tests/run-make/wasm-exceptions-nostd/Makefile deleted file mode 100644 index 34755ec14b745..0000000000000 --- a/tests/run-make/wasm-exceptions-nostd/Makefile +++ /dev/null @@ -1,12 +0,0 @@ -include ../tools.mk - -# only-wasm32-bare - -# Add a few command line args to make exceptions work -RUSTC := $(RUSTC) -C llvm-args=-wasm-enable-eh -RUSTC := $(RUSTC) -C target-feature=+exception-handling -RUSTC := $(RUSTC) -C panic=unwind - -all: - $(RUSTC) src/lib.rs --target wasm32-unknown-unknown - $(NODE) verify.mjs $(TMPDIR)/lib.wasm diff --git a/tests/run-make/wasm-exceptions-nostd/rmake.rs b/tests/run-make/wasm-exceptions-nostd/rmake.rs new file mode 100644 index 0000000000000..720ee9909d2ab --- /dev/null +++ b/tests/run-make/wasm-exceptions-nostd/rmake.rs @@ -0,0 +1,18 @@ +//@ only-wasm32-bare + +use std::path::Path; + +use run_make_support::{cmd, env_var, rustc}; + +fn main() { + // Add a few command line args to make exceptions work + rustc() + .input(Path::new("src").join("lib.rs")) + .target("wasm32-unknown-unknown") + .panic("unwind") + .arg("-Cllvm-args=-wasm-enable-eh") + .arg("-Ctarget-feature=+exception-handling") + .run(); + + cmd(&env_var("NODE")).arg("verify.mjs").arg("lib.wasm").run(); +} diff --git a/tests/run-make/wasm-exceptions-nostd/src/panicking.rs b/tests/run-make/wasm-exceptions-nostd/src/panicking.rs index 52a32f3cd3034..414c9f6a1650b 100644 --- a/tests/run-make/wasm-exceptions-nostd/src/panicking.rs +++ b/tests/run-make/wasm-exceptions-nostd/src/panicking.rs @@ -17,8 +17,8 @@ fn panic_handler(info: &core::panic::PanicInfo<'_>) -> ! { use alloc::boxed::Box; use alloc::string::ToString; - let msg = info.message().map(|msg| msg.to_string()).unwrap_or("(no message)".to_string()); - let exception = Box::new(msg.to_string()); + let msg = info.message().to_string(); + let exception = Box::new(msg); unsafe { let exception_raw = Box::into_raw(exception); wasm_throw(exception_raw as *mut u8); From 0c1df370caf489a38e8d263bb9a72565fd3ab718 Mon Sep 17 00:00:00 2001 From: Jerry Wang Date: Sun, 23 Jun 2024 17:31:08 -0400 Subject: [PATCH 466/892] Refactor `wasm-abi` to use `cmd` --- tests/run-make/wasm-abi/rmake.rs | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/tests/run-make/wasm-abi/rmake.rs b/tests/run-make/wasm-abi/rmake.rs index 0fc326babd943..ff12bcd536e7f 100644 --- a/tests/run-make/wasm-abi/rmake.rs +++ b/tests/run-make/wasm-abi/rmake.rs @@ -1,9 +1,8 @@ //@ only-wasm32-wasip1 //@ needs-wasmtime -use run_make_support::rustc; +use run_make_support::{cmd, rustc}; use std::path::Path; -use std::process::Command; fn main() { rustc().input("foo.rs").target("wasm32-wasip1").run(); @@ -19,14 +18,12 @@ fn main() { } fn run(file: &Path, method: &str, expected_output: &str) { - let output = Command::new("wasmtime") + cmd("wasmtime") .arg("run") .arg("--preload=host=host.wat") .arg("--invoke") .arg(method) .arg(file) - .output() - .unwrap(); - assert!(output.status.success()); - assert_eq!(expected_output, String::from_utf8_lossy(&output.stdout)); + .run() + .assert_stdout_equals(expected_output); } From 2ef269953a99182db6d6ca9901c566eaab15d471 Mon Sep 17 00:00:00 2001 From: Jerry Wang Date: Sun, 23 Jun 2024 17:44:58 -0400 Subject: [PATCH 467/892] Refactor `compressed-debuginfo` to use `llvm_readobj` --- tests/run-make/compressed-debuginfo/rmake.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tests/run-make/compressed-debuginfo/rmake.rs b/tests/run-make/compressed-debuginfo/rmake.rs index 9c6d50ab243cd..37002c672d8c0 100644 --- a/tests/run-make/compressed-debuginfo/rmake.rs +++ b/tests/run-make/compressed-debuginfo/rmake.rs @@ -5,7 +5,7 @@ // FIXME: This test isn't comprehensive and isn't covering all possible combinations. -use run_make_support::{assert_contains, cmd, run_in_tmpdir, rustc}; +use run_make_support::{assert_contains, cmd, llvm_readobj, run_in_tmpdir, rustc}; fn check_compression(compression: &str, to_find: &str) { run_in_tmpdir(|| { @@ -19,8 +19,7 @@ fn check_compression(compression: &str, to_find: &str) { .run(); let stderr = out.stderr_utf8(); if stderr.is_empty() { - // FIXME: `readelf` might need to be replaced with `llvm-readelf`. - cmd("readelf").arg("-t").arg("foo.o").run().assert_stdout_contains(to_find); + llvm_readobj().arg("-t").arg("foo.o").run().assert_stdout_contains(to_find); } else { assert_contains( &stderr, From 28ba5e4124659107bd0ed08ba5c480d0e71c3aa1 Mon Sep 17 00:00:00 2001 From: Askar Safin Date: Wed, 19 Jun 2024 21:19:20 +0300 Subject: [PATCH 468/892] Updated docs on `#[panic_handler]` in `library/core/src/lib.rs` --- library/core/src/lib.rs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index ef28bc99c4fc8..4bc0e37800ed5 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -34,12 +34,9 @@ //! Rust user code is to call the functions provided by this library instead (such as //! `ptr::copy`). //! -//! * `rust_begin_panic` - This function takes four arguments, a -//! `fmt::Arguments`, a `&'static str`, and two `u32`'s. These four arguments -//! dictate the panic message, the file at which panic was invoked, and the -//! line and column inside the file. It is up to consumers of this core +//! * Panic handler - This function takes one argument, a `&panic::PanicInfo`. It is up to consumers of this core //! library to define this panic function; it is only required to never -//! return. This requires a `lang` attribute named `panic_impl`. +//! return. You should mark your implementation using `#[panic_handler]`. //! //! * `rust_eh_personality` - is used by the failure mechanisms of the //! compiler. This is often mapped to GCC's personality function, but crates From c54a2a53f83d9eb4fec161ecc304164d0303fbfc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Thu, 27 Jun 2024 19:03:47 +0200 Subject: [PATCH 469/892] Make mtime of reproducible tarball dependent on git commit --- src/bootstrap/src/utils/tarball.rs | 26 ++++++++++++++++++++++- src/tools/rust-installer/src/tarballer.rs | 18 ++++++++++++++-- 2 files changed, 41 insertions(+), 3 deletions(-) diff --git a/src/bootstrap/src/utils/tarball.rs b/src/bootstrap/src/utils/tarball.rs index 5cc319826dbf3..3c15bb296f39a 100644 --- a/src/bootstrap/src/utils/tarball.rs +++ b/src/bootstrap/src/utils/tarball.rs @@ -9,9 +9,9 @@ use std::path::{Path, PathBuf}; use crate::core::builder::Builder; use crate::core::{build_steps::dist::distdir, builder::Kind}; -use crate::utils::channel; use crate::utils::exec::BootstrapCommand; use crate::utils::helpers::{move_file, t}; +use crate::utils::{channel, helpers}; #[derive(Copy, Clone)] pub(crate) enum OverlayKind { @@ -351,6 +351,30 @@ impl<'a> Tarball<'a> { }; cmd.args(["--compression-profile", compression_profile]); + + // We want to use a pinned modification time for files in the archive + // to achieve better reproducibility. However, using the same mtime for all + // releases is not ideal, because it can break e.g. Cargo mtime checking + // (https://github.com/rust-lang/rust/issues/125578). + // Therefore, we set mtime to the date of the latest commit (if we're managed + // by git). In this way, the archive will still be always the same for a given commit + // (achieving reproducibility), but it will also change between different commits and + // Rust versions, so that it won't break mtime-based caches. + // + // Note that this only overrides the mtime of files, not directories, due to the + // limitations of the tarballer tool. Directories will have their mtime set to 2006. + + // Get the UTC timestamp of the last git commit, if we're under git. + // We need to use UTC, so that anyone who tries to rebuild from the same commit + // gets the same timestamp. + if self.builder.rust_info().is_managed_git_subrepository() { + // %ct means committer date + let timestamp = helpers::output( + helpers::git(Some(&self.builder.src)).arg("log").arg("-1").arg("--format=%ct"), + ); + cmd.args(["--override-file-mtime", timestamp.trim()]); + } + self.builder.run(cmd); // Ensure there are no symbolic links in the tarball. In particular, diff --git a/src/tools/rust-installer/src/tarballer.rs b/src/tools/rust-installer/src/tarballer.rs index 2f093e7ad17fd..b5e87a66ffc39 100644 --- a/src/tools/rust-installer/src/tarballer.rs +++ b/src/tools/rust-installer/src/tarballer.rs @@ -32,6 +32,12 @@ actor! { /// The formats used to compress the tarball. #[arg(value_name = "FORMAT", default_value_t)] compression_formats: CompressionFormats, + + /// Modification time that will be set for all files added to the archive. + /// The default is the date of the first Rust commit from 2006. + /// This serves for better reproducibility of the archives. + #[arg(value_name = "FILE_MTIME", default_value_t = 1153704088)] + override_file_mtime: u64, } } @@ -65,6 +71,8 @@ impl Tarballer { let buf = BufWriter::with_capacity(1024 * 1024, encoder); let mut builder = Builder::new(buf); // Make uid, gid and mtime deterministic to improve reproducibility + // The modification time of directories will be set to the date of the first Rust commit. + // The modification time of files will be set to `override_file_mtime` (see `append_path`). builder.mode(HeaderMode::Deterministic); let pool = rayon::ThreadPoolBuilder::new().num_threads(2).build().unwrap(); @@ -77,7 +85,7 @@ impl Tarballer { } for path in files { let src = Path::new(&self.work_dir).join(&path); - append_path(&mut builder, &src, &path) + append_path(&mut builder, &src, &path, self.override_file_mtime) .with_context(|| format!("failed to tar file '{}'", src.display()))?; } builder @@ -93,10 +101,16 @@ impl Tarballer { } } -fn append_path(builder: &mut Builder, src: &Path, path: &String) -> Result<()> { +fn append_path( + builder: &mut Builder, + src: &Path, + path: &String, + override_file_mtime: u64, +) -> Result<()> { let stat = symlink_metadata(src)?; let mut header = Header::new_gnu(); header.set_metadata_in_mode(&stat, HeaderMode::Deterministic); + header.set_mtime(override_file_mtime); if stat.file_type().is_symlink() { let link = read_link(src)?; From 5dece2b2bd97c56f9abe2599ec1b4957fd63be55 Mon Sep 17 00:00:00 2001 From: Tobias Decking Date: Sat, 29 Jun 2024 15:08:59 +0200 Subject: [PATCH 470/892] Remove uneccessary condition in `div_ceil` --- library/core/src/num/uint_macros.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/core/src/num/uint_macros.rs b/library/core/src/num/uint_macros.rs index cd74cece0d12e..ad72c29758bd7 100644 --- a/library/core/src/num/uint_macros.rs +++ b/library/core/src/num/uint_macros.rs @@ -2726,7 +2726,7 @@ macro_rules! uint_impl { pub const fn div_ceil(self, rhs: Self) -> Self { let d = self / rhs; let r = self % rhs; - if r > 0 && rhs > 0 { + if r > 0 { d + 1 } else { d From 3d54358b643fc258b19688f6c6f8cc3d8831855c Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sat, 29 Jun 2024 15:13:31 +0200 Subject: [PATCH 471/892] Update object to 0.36.1 This fixes a crash with macOS's ld-prime on arm64. Fixes rust-lang/rustc_codegen_cranelift#1501 --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e4959eed37a00..15c9e9d66fac2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -279,9 +279,9 @@ checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" [[package]] name = "object" -version = "0.36.0" +version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "576dfe1fc8f9df304abb159d767a29d0476f7750fbf8aa7ad07816004a207434" +checksum = "081b846d1d56ddfc18fdf1a922e4f6e07a11768ea1b92dec44e42b72712ccfce" dependencies = [ "crc32fast", "hashbrown 0.14.3", From f6f21a8f11a51336784e93d6ea712f4484d7caef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Sat, 29 Jun 2024 16:07:22 +0200 Subject: [PATCH 472/892] Review changes --- src/bootstrap/src/core/build_steps/perf.rs | 2 +- src/tools/rustc-perf-wrapper/README.md | 2 +- src/tools/rustc-perf-wrapper/src/main.rs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/perf.rs b/src/bootstrap/src/core/build_steps/perf.rs index f8170580722bf..f41b5fe10f1d9 100644 --- a/src/bootstrap/src/core/build_steps/perf.rs +++ b/src/bootstrap/src/core/build_steps/perf.rs @@ -27,7 +27,7 @@ Consider setting `rust.debuginfo-level = 1` in `config.toml`."#); let args = std::env::args().skip_while(|a| a != "--").skip(1); let mut cmd = builder.tool_cmd(Tool::RustcPerfWrapper); - cmd.env("PERF_RUSTC", rustc) + cmd.env("RUSTC_REAL", rustc) .env("PERF_COLLECTOR", collector) .env("PERF_RESULT_DIR", profile_results_dir) .args(args); diff --git a/src/tools/rustc-perf-wrapper/README.md b/src/tools/rustc-perf-wrapper/README.md index 7c096e3081416..d7655459a2fe1 100644 --- a/src/tools/rustc-perf-wrapper/README.md +++ b/src/tools/rustc-perf-wrapper/README.md @@ -1,3 +1,3 @@ # rustc-perf wrapper Utility tool for invoking [`rustc-perf`](https://github.com/rust-lang/rustc-perf) for benchmarking/profiling -a stage1/2 compiler built by bootstrap using `x run perf`. +a stage1/2 compiler built by bootstrap using `x perf -- `. diff --git a/src/tools/rustc-perf-wrapper/src/main.rs b/src/tools/rustc-perf-wrapper/src/main.rs index 0974661f99787..1c0d1745f3d98 100644 --- a/src/tools/rustc-perf-wrapper/src/main.rs +++ b/src/tools/rustc-perf-wrapper/src/main.rs @@ -68,7 +68,7 @@ struct SharedOpts { #[derive(Debug, clap::Parser)] struct BuildContext { /// Compiler binary that will be benchmarked/profiled. - #[clap(long, hide = true, env = "PERF_RUSTC")] + #[clap(long, hide = true, env = "RUSTC_REAL")] compiler: PathBuf, /// rustc-perf collector binary that will be used for running benchmarks/profilers. #[clap(long, hide = true, env = "PERF_COLLECTOR")] From 6a2638e6c49817de9c2b1d56261de37c6a352571 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Sat, 29 Jun 2024 16:07:39 +0200 Subject: [PATCH 473/892] Autolabel `rustc-perf-wrapper` changes with t-bootstrap label --- triagebot.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/triagebot.toml b/triagebot.toml index 62e0917efabed..8ae454d412a6f 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -331,6 +331,7 @@ trigger_files = [ "src/tools/tidy", "src/tools/rustdoc-gui-test", "src/tools/libcxx-version", + "src/tools/rustc-perf-wrapper", ] [autolabel."T-infra"] From 35f209361fcd0751b3d260d67962b0af2d455596 Mon Sep 17 00:00:00 2001 From: Sky Date: Thu, 27 Jun 2024 22:27:59 -0400 Subject: [PATCH 474/892] small correction to fmt::Pointer impl the `expose_provenance` method does not require `T: Sized` --- library/core/src/fmt/mod.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/library/core/src/fmt/mod.rs b/library/core/src/fmt/mod.rs index c25bc5a1b13c9..69ccc6ce3ca3d 100644 --- a/library/core/src/fmt/mod.rs +++ b/library/core/src/fmt/mod.rs @@ -2478,8 +2478,7 @@ impl Display for char { #[stable(feature = "rust1", since = "1.0.0")] impl Pointer for *const T { fn fmt(&self, f: &mut Formatter<'_>) -> Result { - // Cast is needed here because `.expose_provenance()` requires `T: Sized`. - pointer_fmt_inner((*self as *const ()).expose_provenance(), f) + pointer_fmt_inner(self.expose_provenance(), f) } } From 30be8bcb45d108158c6553eff63db0d9ffb9f88a Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sat, 29 Jun 2024 15:06:08 +0000 Subject: [PATCH 475/892] Remove --cfg no_unstable_features --- build_system/tests.rs | 36 ++++---------------------------- example/mini_core_hello_world.rs | 20 +++++------------- 2 files changed, 9 insertions(+), 47 deletions(-) diff --git a/build_system/tests.rs b/build_system/tests.rs index 278f334796a9b..790d9cbd9fc59 100644 --- a/build_system/tests.rs +++ b/build_system/tests.rs @@ -329,7 +329,6 @@ pub(crate) fn run_tests( struct TestRunner<'a> { is_native: bool, jit_supported: bool, - use_unstable_features: bool, skip_tests: &'a [&'a str], dirs: Dirs, target_compiler: Compiler, @@ -361,15 +360,7 @@ impl<'a> TestRunner<'a> { && target_compiler.triple.contains("x86_64") && !target_compiler.triple.contains("windows"); - Self { - is_native, - jit_supported, - use_unstable_features, - skip_tests, - dirs, - target_compiler, - stdlib_source, - } + Self { is_native, jit_supported, skip_tests, dirs, target_compiler, stdlib_source } } fn run_testsuite(&self, tests: &[TestCase]) { @@ -393,31 +384,13 @@ impl<'a> TestRunner<'a> { match *cmd { TestCaseCmd::Custom { func } => func(self), TestCaseCmd::BuildLib { source, crate_types } => { - if self.use_unstable_features { - self.run_rustc([source, "--crate-type", crate_types]); - } else { - self.run_rustc([ - source, - "--crate-type", - crate_types, - "--cfg", - "no_unstable_features", - ]); - } + self.run_rustc([source, "--crate-type", crate_types]); } TestCaseCmd::BuildBin { source } => { - if self.use_unstable_features { - self.run_rustc([source]); - } else { - self.run_rustc([source, "--cfg", "no_unstable_features"]); - } + self.run_rustc([source]); } TestCaseCmd::BuildBinAndRun { source, args } => { - if self.use_unstable_features { - self.run_rustc([source]); - } else { - self.run_rustc([source, "--cfg", "no_unstable_features"]); - } + self.run_rustc([source]); self.run_out_command( source.split('/').last().unwrap().split('.').next().unwrap(), args, @@ -472,7 +445,6 @@ impl<'a> TestRunner<'a> { cmd.arg(&self.target_compiler.triple); cmd.arg("-Cpanic=abort"); cmd.arg("-Zunstable-options"); - cmd.arg("--check-cfg=cfg(no_unstable_features)"); cmd.arg("--check-cfg=cfg(jit)"); cmd.args(args); cmd diff --git a/example/mini_core_hello_world.rs b/example/mini_core_hello_world.rs index aab20f672487b..7d361a9ab2bb6 100644 --- a/example/mini_core_hello_world.rs +++ b/example/mini_core_hello_world.rs @@ -333,12 +333,7 @@ fn main() { #[cfg(all(not(jit), not(all(windows, target_env = "gnu"))))] test_tls(); - #[cfg(all( - not(jit), - not(no_unstable_features), - target_arch = "x86_64", - any(target_os = "linux", target_os = "macos") - ))] + #[cfg(all(not(jit), target_arch = "x86_64", any(target_os = "linux", target_os = "macos")))] unsafe { global_asm_test(); naked_test(); @@ -367,17 +362,12 @@ fn stack_val_align() { assert_eq!(&a as *const Foo as usize % 8192, 0); } -#[cfg(all( - not(jit), - not(no_unstable_features), - target_arch = "x86_64", - any(target_os = "linux", target_os = "macos") -))] +#[cfg(all(not(jit), target_arch = "x86_64", any(target_os = "linux", target_os = "macos")))] extern "C" { fn global_asm_test(); } -#[cfg(all(not(jit), not(no_unstable_features), target_arch = "x86_64", target_os = "linux"))] +#[cfg(all(not(jit), target_arch = "x86_64", target_os = "linux"))] global_asm! { " .global global_asm_test @@ -387,7 +377,7 @@ global_asm! { " } -#[cfg(all(not(jit), not(no_unstable_features), target_arch = "x86_64", target_os = "macos"))] +#[cfg(all(not(jit), target_arch = "x86_64", target_os = "macos"))] global_asm! { " .global _global_asm_test @@ -397,7 +387,7 @@ global_asm! { " } -#[cfg(all(not(jit), not(no_unstable_features), target_arch = "x86_64"))] +#[cfg(all(not(jit), target_arch = "x86_64"))] #[naked] extern "C" fn naked_test() { unsafe { From 45600348c009303847e8cddcfa8483f1f3d56625 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sat, 29 Jun 2024 15:08:04 +0000 Subject: [PATCH 476/892] Stop pinning XCode 14 The linker issue with XCode 15 has been fixed. --- .github/workflows/abi-cafe.yml | 4 ---- .github/workflows/main.yml | 8 -------- 2 files changed, 12 deletions(-) diff --git a/.github/workflows/abi-cafe.yml b/.github/workflows/abi-cafe.yml index b7063f35a3e80..1ed6f8fc359db 100644 --- a/.github/workflows/abi-cafe.yml +++ b/.github/workflows/abi-cafe.yml @@ -55,10 +55,6 @@ jobs: if: matrix.os == 'macos-latest' && matrix.env.TARGET_TRIPLE == 'x86_64-apple-darwin' run: rustup set default-host x86_64-apple-darwin - - name: Select XCode version - if: matrix.os == 'macos-latest' - run: sudo xcode-select -s /Applications/Xcode_14.3.1.app - - name: Prepare dependencies run: ./y.sh prepare diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 1fc7087170065..a2ae3d63fb907 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -111,10 +111,6 @@ jobs: sudo apt-get update sudo apt-get install -y ${{ matrix.apt_deps }} - - name: Select XCode version - if: matrix.os == 'macos-latest' - run: sudo xcode-select -s /Applications/Xcode_14.3.1.app - - name: Prepare dependencies run: ./y.sh prepare @@ -254,10 +250,6 @@ jobs: sudo apt-get update sudo apt-get install -y gcc-mingw-w64-x86-64 - - name: Select XCode version - if: matrix.os == 'macos-latest' - run: sudo xcode-select -s /Applications/Xcode_14.3.1.app - - name: Prepare dependencies run: ./y.sh prepare From 15d5dac32ecd54745d6f61659628286bd2678e03 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Fri, 28 Jun 2024 23:14:09 -0300 Subject: [PATCH 477/892] Avoid suggesting to add unsafe when the extern block is already unsafe --- .../rustc_ast_passes/src/ast_validation.rs | 19 ++++++++++++------- compiler/rustc_ast_passes/src/errors.rs | 2 +- tests/ui/parser/unsafe-foreign-mod-2.stderr | 5 ----- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index d02b8510975fc..60690a7e2cd83 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -459,13 +459,18 @@ impl<'a> AstValidator<'a> { fn check_item_safety(&self, span: Span, safety: Safety) { match self.extern_mod_safety { Some(extern_safety) => { - if matches!(safety, Safety::Unsafe(_) | Safety::Safe(_)) - && (extern_safety == Safety::Default || !self.features.unsafe_extern_blocks) - { - self.dcx().emit_err(errors::InvalidSafetyOnExtern { - item_span: span, - block: self.current_extern_span().shrink_to_lo(), - }); + if matches!(safety, Safety::Unsafe(_) | Safety::Safe(_)) { + if extern_safety == Safety::Default { + self.dcx().emit_err(errors::InvalidSafetyOnExtern { + item_span: span, + block: Some(self.current_extern_span().shrink_to_lo()), + }); + } else if !self.features.unsafe_extern_blocks { + self.dcx().emit_err(errors::InvalidSafetyOnExtern { + item_span: span, + block: None, + }); + } } } None => { diff --git a/compiler/rustc_ast_passes/src/errors.rs b/compiler/rustc_ast_passes/src/errors.rs index 965d8fac712ae..bfb9047645011 100644 --- a/compiler/rustc_ast_passes/src/errors.rs +++ b/compiler/rustc_ast_passes/src/errors.rs @@ -222,7 +222,7 @@ pub struct InvalidSafetyOnExtern { #[primary_span] pub item_span: Span, #[suggestion(code = "unsafe ", applicability = "machine-applicable", style = "verbose")] - pub block: Span, + pub block: Option, } #[derive(Diagnostic)] diff --git a/tests/ui/parser/unsafe-foreign-mod-2.stderr b/tests/ui/parser/unsafe-foreign-mod-2.stderr index 07dbd5568d053..8bd592b5d4311 100644 --- a/tests/ui/parser/unsafe-foreign-mod-2.stderr +++ b/tests/ui/parser/unsafe-foreign-mod-2.stderr @@ -19,11 +19,6 @@ error: items in unadorned `extern` blocks cannot have safety qualifiers | LL | unsafe fn foo(); | ^^^^^^^^^^^^^^^^ - | -help: add unsafe to this `extern` block - | -LL | unsafe extern "C" unsafe { - | ++++++ error: aborting due to 3 previous errors From 7f383d098a0c3ed0c1360aad5cb6825a2981866f Mon Sep 17 00:00:00 2001 From: Ole Bertram Date: Sat, 29 Jun 2024 20:39:13 +0200 Subject: [PATCH 478/892] Stabilize `duration_abs_diff` --- library/core/src/time.rs | 5 +++-- library/core/tests/lib.rs | 1 - 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/library/core/src/time.rs b/library/core/src/time.rs index 73c556249bedf..d66f558078ea8 100644 --- a/library/core/src/time.rs +++ b/library/core/src/time.rs @@ -620,13 +620,14 @@ impl Duration { /// Basic usage: /// /// ``` - /// #![feature(duration_abs_diff)] /// use std::time::Duration; /// /// assert_eq!(Duration::new(100, 0).abs_diff(Duration::new(80, 0)), Duration::new(20, 0)); /// assert_eq!(Duration::new(100, 400_000_000).abs_diff(Duration::new(110, 0)), Duration::new(9, 600_000_000)); /// ``` - #[unstable(feature = "duration_abs_diff", issue = "117618")] + #[stable(feature = "duration_abs_diff", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "duration_abs_diff", since = "CURRENT_RUSTC_VERSION")] + #[rustc_allow_const_fn_unstable(const_option)] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs index 57127df51ebdd..83a615fcd8be3 100644 --- a/library/core/tests/lib.rs +++ b/library/core/tests/lib.rs @@ -30,7 +30,6 @@ #![feature(core_private_bignum)] #![feature(core_private_diy_float)] #![feature(dec2flt)] -#![feature(duration_abs_diff)] #![feature(duration_consts_float)] #![feature(duration_constants)] #![feature(duration_constructors)] From e52d95bc823fc27d7f69f7aab980b278a6772a0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Sat, 29 Jun 2024 22:09:58 +0200 Subject: [PATCH 479/892] Remove unused compiler dependencies --- Cargo.lock | 4 ---- compiler/rustc_trait_selection/Cargo.toml | 4 ---- 2 files changed, 8 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0182eca05058d..16ed81bcd3897 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4752,8 +4752,6 @@ checksum = "8ba09476327c4b70ccefb6180f046ef588c26a24cf5d269a9feba316eb4f029f" name = "rustc_trait_selection" version = "0.0.0" dependencies = [ - "bitflags 2.5.0", - "derivative", "itertools", "rustc_ast", "rustc_ast_ir", @@ -4762,7 +4760,6 @@ dependencies = [ "rustc_errors", "rustc_fluent_macro", "rustc_hir", - "rustc_index", "rustc_infer", "rustc_macros", "rustc_middle", @@ -4775,7 +4772,6 @@ dependencies = [ "rustc_target", "rustc_transmute", "rustc_type_ir", - "rustc_type_ir_macros", "smallvec", "tracing", ] diff --git a/compiler/rustc_trait_selection/Cargo.toml b/compiler/rustc_trait_selection/Cargo.toml index 1f4fb57d996cc..f023a0eb53aeb 100644 --- a/compiler/rustc_trait_selection/Cargo.toml +++ b/compiler/rustc_trait_selection/Cargo.toml @@ -5,8 +5,6 @@ edition = "2021" [dependencies] # tidy-alphabetical-start -bitflags = "2.4.1" -derivative = "2.2.0" itertools = "0.12" rustc_ast = { path = "../rustc_ast" } rustc_ast_ir = { path = "../rustc_ast_ir" } @@ -15,7 +13,6 @@ rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_hir = { path = "../rustc_hir" } -rustc_index = { path = "../rustc_index" } rustc_infer = { path = "../rustc_infer" } rustc_macros = { path = "../rustc_macros" } rustc_middle = { path = "../rustc_middle" } @@ -28,7 +25,6 @@ rustc_span = { path = "../rustc_span" } rustc_target = { path = "../rustc_target" } rustc_transmute = { path = "../rustc_transmute", features = ["rustc"] } rustc_type_ir = { path = "../rustc_type_ir" } -rustc_type_ir_macros = { path = "../rustc_type_ir_macros" } smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } tracing = "0.1" # tidy-alphabetical-end From 682e7c1174161c6e4e48a50e188e09f2dec80712 Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Sat, 29 Jun 2024 16:14:34 -0400 Subject: [PATCH 480/892] Print `TypeId` as a `u128` for `Debug` Since , `TypeId` is represented as a `(u64, u64)`. This also made the debug implementation a lot larger, which is especially apparent with pretty formatting. Make this less noisy by converting the inner value back to a `u128` then printing as a tuple struct. Current: TypeId { t: (1403077013027291752, 4518903163082958039) } TypeId { t: ( 1403077013027291752, 4518903163082958039, ), } New: TypeId(25882202575019293479932656973818029271) TypeId( 25882202575019293479932656973818029271, ) --- library/core/src/any.rs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/library/core/src/any.rs b/library/core/src/any.rs index 37cb8e7d303af..eab11ae288a95 100644 --- a/library/core/src/any.rs +++ b/library/core/src/any.rs @@ -602,7 +602,7 @@ impl dyn Any + Send + Sync { /// While `TypeId` implements `Hash`, `PartialOrd`, and `Ord`, it is worth /// noting that the hashes and ordering will vary between Rust releases. Beware /// of relying on them inside of your code! -#[derive(Clone, Copy, Debug, Eq, PartialOrd, Ord)] +#[derive(Clone, Copy, Eq, PartialOrd, Ord)] #[stable(feature = "rust1", since = "1.0.0")] pub struct TypeId { // We avoid using `u128` because that imposes higher alignment requirements on many platforms. @@ -644,6 +644,10 @@ impl TypeId { let t2 = t as u64; TypeId { t: (t1, t2) } } + + fn as_u128(self) -> u128 { + u128::from(self.t.0) << 64 | u128::from(self.t.1) + } } #[stable(feature = "rust1", since = "1.0.0")] @@ -666,6 +670,13 @@ impl hash::Hash for TypeId { } } +#[stable(feature = "rust1", since = "1.0.0")] +impl fmt::Debug for TypeId { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { + f.debug_tuple("TypeId").field(&self.as_u128()).finish() + } +} + /// Returns the name of a type as a string slice. /// /// # Note From e1999f9a0815c891d71588045b96a76e8e2c45a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Sat, 29 Jun 2024 23:30:57 +0200 Subject: [PATCH 481/892] Add support for mtime override to `generate` and `combine` rust-installer commands --- src/tools/rust-installer/src/combiner.rs | 9 ++++++++- src/tools/rust-installer/src/generator.rs | 9 ++++++++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/tools/rust-installer/src/combiner.rs b/src/tools/rust-installer/src/combiner.rs index 565d19d863f64..c211b34850a07 100644 --- a/src/tools/rust-installer/src/combiner.rs +++ b/src/tools/rust-installer/src/combiner.rs @@ -55,6 +55,12 @@ actor! { /// The formats used to compress the tarball #[arg(value_name = "FORMAT", default_value_t)] compression_formats: CompressionFormats, + + /// Modification time that will be set for all files added to the archive. + /// The default is the date of the first Rust commit from 2006. + /// This serves for better reproducibility of the archives. + #[arg(value_name = "FILE_MTIME", default_value_t = 1153704088)] + override_file_mtime: u64, } } @@ -145,7 +151,8 @@ impl Combiner { .input(self.package_name) .output(path_to_str(&output)?.into()) .compression_profile(self.compression_profile) - .compression_formats(self.compression_formats); + .compression_formats(self.compression_formats) + .override_file_mtime(self.override_file_mtime); tarballer.run()?; Ok(()) diff --git a/src/tools/rust-installer/src/generator.rs b/src/tools/rust-installer/src/generator.rs index b101e67d8df7f..035a394deebe6 100644 --- a/src/tools/rust-installer/src/generator.rs +++ b/src/tools/rust-installer/src/generator.rs @@ -61,6 +61,12 @@ actor! { /// The formats used to compress the tarball #[arg(value_name = "FORMAT", default_value_t)] compression_formats: CompressionFormats, + + /// Modification time that will be set for all files added to the archive. + /// The default is the date of the first Rust commit from 2006. + /// This serves for better reproducibility of the archives. + #[arg(value_name = "FILE_MTIME", default_value_t = 1153704088)] + override_file_mtime: u64, } } @@ -114,7 +120,8 @@ impl Generator { .input(self.package_name) .output(path_to_str(&output)?.into()) .compression_profile(self.compression_profile) - .compression_formats(self.compression_formats); + .compression_formats(self.compression_formats) + .override_file_mtime(self.override_file_mtime); tarballer.run()?; Ok(()) From 294436d27371d77967c77d93e31a34362f7c3cd0 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sat, 29 Jun 2024 15:25:14 -0400 Subject: [PATCH 482/892] Make all tests in async dir build-pass, adjust implements-fnmut test to begin ICEing during codegen --- .../async-closures/constrained-but-no-upvars-yet.rs | 2 +- .../force-move-due-to-actually-fnonce.rs | 2 +- .../async-closures/force-move-due-to-inferred-kind.rs | 2 +- .../ui/async-await/async-closures/implements-fnmut.rs | 10 +++++++--- .../async-await/async-closures/signature-deduction.rs | 2 +- 5 files changed, 11 insertions(+), 7 deletions(-) diff --git a/tests/ui/async-await/async-closures/constrained-but-no-upvars-yet.rs b/tests/ui/async-await/async-closures/constrained-but-no-upvars-yet.rs index a43906d01e538..3b222d00baeaf 100644 --- a/tests/ui/async-await/async-closures/constrained-but-no-upvars-yet.rs +++ b/tests/ui/async-await/async-closures/constrained-but-no-upvars-yet.rs @@ -1,5 +1,5 @@ //@ edition: 2021 -//@ check-pass +//@ build-pass //@ revisions: current next //@ ignore-compare-mode-next-solver (explicit revisions) //@[next] compile-flags: -Znext-solver diff --git a/tests/ui/async-await/async-closures/force-move-due-to-actually-fnonce.rs b/tests/ui/async-await/async-closures/force-move-due-to-actually-fnonce.rs index ce49f55e3e304..7244a29673b98 100644 --- a/tests/ui/async-await/async-closures/force-move-due-to-actually-fnonce.rs +++ b/tests/ui/async-await/async-closures/force-move-due-to-actually-fnonce.rs @@ -1,6 +1,6 @@ //@ aux-build:block-on.rs //@ edition:2021 -//@ check-pass +//@ build-pass #![feature(async_closure)] diff --git a/tests/ui/async-await/async-closures/force-move-due-to-inferred-kind.rs b/tests/ui/async-await/async-closures/force-move-due-to-inferred-kind.rs index 803c990ef93f1..7ce210a33c3e5 100644 --- a/tests/ui/async-await/async-closures/force-move-due-to-inferred-kind.rs +++ b/tests/ui/async-await/async-closures/force-move-due-to-inferred-kind.rs @@ -1,6 +1,6 @@ //@ aux-build:block-on.rs //@ edition:2021 -//@ check-pass +//@ build-pass #![feature(async_closure)] diff --git a/tests/ui/async-await/async-closures/implements-fnmut.rs b/tests/ui/async-await/async-closures/implements-fnmut.rs index 1ed326cd0618b..8e780ce9889ab 100644 --- a/tests/ui/async-await/async-closures/implements-fnmut.rs +++ b/tests/ui/async-await/async-closures/implements-fnmut.rs @@ -1,4 +1,4 @@ -//@ check-pass +//@ build-pass //@ edition: 2021 // Demonstrates that an async closure may implement `FnMut` (not just `async FnMut`!) @@ -9,9 +9,13 @@ #![feature(async_closure)] -fn main() {} +fn main() { + hello(&Ty); +} -fn needs_fn_mut(x: impl FnMut() -> T) {} +fn needs_fn_mut(mut x: impl FnMut() -> T) { + x(); +} fn hello(x: &Ty) { needs_fn_mut(async || { x.hello(); }); diff --git a/tests/ui/async-await/async-closures/signature-deduction.rs b/tests/ui/async-await/async-closures/signature-deduction.rs index 031dab1029658..856f3963ee6a9 100644 --- a/tests/ui/async-await/async-closures/signature-deduction.rs +++ b/tests/ui/async-await/async-closures/signature-deduction.rs @@ -1,4 +1,4 @@ -//@ check-pass +//@ build-pass //@ edition: 2021 #![feature(async_closure)] From 90143b0be814ea70303906a81d8329b5b655c437 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sat, 29 Jun 2024 17:25:44 -0400 Subject: [PATCH 483/892] Fix FnMut/Fn shim for coroutine-closures that capture references --- compiler/rustc_codegen_ssa/src/mir/locals.rs | 2 +- compiler/rustc_mir_transform/src/shim.rs | 49 ++++++++++++------- compiler/rustc_symbol_mangling/src/legacy.rs | 10 ++-- compiler/rustc_symbol_mangling/src/v0.rs | 11 ++++- compiler/rustc_ty_utils/src/abi.rs | 4 +- src/tools/miri/tests/pass/async-closure.rs | 21 +++++--- .../miri/tests/pass/async-closure.stdout | 6 ++- ...ure#0}.coroutine_by_move.0.panic-abort.mir | 2 +- ...re#0}.coroutine_by_move.0.panic-unwind.mir | 2 +- ...oroutine_closure_by_move.0.panic-abort.mir | 6 +-- ...routine_closure_by_move.0.panic-unwind.mir | 6 +-- ...ure#0}.coroutine_by_move.0.panic-abort.mir | 47 ++++++++++++++++++ ...re#0}.coroutine_by_move.0.panic-unwind.mir | 47 ++++++++++++++++++ ...oroutine_closure_by_move.0.panic-abort.mir | 10 ++++ ...routine_closure_by_move.0.panic-unwind.mir | 10 ++++ ...coroutine_closure_by_ref.0.panic-abort.mir | 6 +-- ...oroutine_closure_by_ref.0.panic-unwind.mir | 6 +-- tests/mir-opt/async_closure_shims.rs | 20 +++++++- 18 files changed, 214 insertions(+), 51 deletions(-) create mode 100644 tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}-{closure#0}.coroutine_by_move.0.panic-abort.mir create mode 100644 tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}-{closure#0}.coroutine_by_move.0.panic-unwind.mir create mode 100644 tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}.coroutine_closure_by_move.0.panic-abort.mir create mode 100644 tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}.coroutine_closure_by_move.0.panic-unwind.mir diff --git a/compiler/rustc_codegen_ssa/src/mir/locals.rs b/compiler/rustc_codegen_ssa/src/mir/locals.rs index a6c873e195eb1..5190021c005b4 100644 --- a/compiler/rustc_codegen_ssa/src/mir/locals.rs +++ b/compiler/rustc_codegen_ssa/src/mir/locals.rs @@ -47,7 +47,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let expected_ty = self.monomorphize(self.mir.local_decls[local].ty); if expected_ty != op.layout.ty { warn!( - "Unexpected initial operand type: expected {expected_ty:?}, found {:?}.\ + "Unexpected initial operand type:\nexpected {expected_ty:?},\nfound {:?}.\n\ See .", op.layout.ty ); diff --git a/compiler/rustc_mir_transform/src/shim.rs b/compiler/rustc_mir_transform/src/shim.rs index 25577e88e2831..6835a39cf3624 100644 --- a/compiler/rustc_mir_transform/src/shim.rs +++ b/compiler/rustc_mir_transform/src/shim.rs @@ -1,18 +1,17 @@ use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_hir::lang_items::LangItem; +use rustc_index::{Idx, IndexVec}; use rustc_middle::mir::*; use rustc_middle::query::Providers; use rustc_middle::ty::GenericArgs; use rustc_middle::ty::{self, CoroutineArgs, CoroutineArgsExt, EarlyBinder, Ty, TyCtxt}; use rustc_middle::{bug, span_bug}; -use rustc_target::abi::{FieldIdx, VariantIdx, FIRST_VARIANT}; - -use rustc_index::{Idx, IndexVec}; - use rustc_span::{source_map::Spanned, Span, DUMMY_SP}; +use rustc_target::abi::{FieldIdx, VariantIdx, FIRST_VARIANT}; use rustc_target::spec::abi::Abi; +use std::assert_matches::assert_matches; use std::fmt; use std::iter; @@ -1020,21 +1019,19 @@ fn build_construct_coroutine_by_move_shim<'tcx>( receiver_by_ref: bool, ) -> Body<'tcx> { let mut self_ty = tcx.type_of(coroutine_closure_def_id).instantiate_identity(); + let mut self_local: Place<'tcx> = Local::from_usize(1).into(); let ty::CoroutineClosure(_, args) = *self_ty.kind() else { bug!(); }; - // We use `&mut Self` here because we only need to emit an ABI-compatible shim body, - // rather than match the signature exactly (which might take `&self` instead). + // We use `&Self` here because we only need to emit an ABI-compatible shim body, + // rather than match the signature exactly (which might take `&mut self` instead). // - // The self type here is a coroutine-closure, not a coroutine, and we never read from - // it because it never has any captures, because this is only true in the Fn/FnMut - // implementation, not the AsyncFn/AsyncFnMut implementation, which is implemented only - // if the coroutine-closure has no captures. + // We adjust the `self_local` to be a deref since we want to copy fields out of + // a reference to the closure. if receiver_by_ref { - // Triple-check that there's no captures here. - assert_eq!(args.as_coroutine_closure().tupled_upvars_ty(), tcx.types.unit); - self_ty = Ty::new_mut_ref(tcx, tcx.lifetimes.re_erased, self_ty); + self_local = tcx.mk_place_deref(self_local); + self_ty = Ty::new_imm_ref(tcx, tcx.lifetimes.re_erased, self_ty); } let poly_sig = args.as_coroutine_closure().coroutine_closure_sig().map_bound(|sig| { @@ -1067,11 +1064,27 @@ fn build_construct_coroutine_by_move_shim<'tcx>( fields.push(Operand::Move(Local::from_usize(idx + 1).into())); } for (idx, ty) in args.as_coroutine_closure().upvar_tys().iter().enumerate() { - fields.push(Operand::Move(tcx.mk_place_field( - Local::from_usize(1).into(), - FieldIdx::from_usize(idx), - ty, - ))); + if receiver_by_ref { + // The only situation where it's possible is when we capture immuatable references, + // since those don't need to be reborrowed with the closure's env lifetime. Since + // references are always `Copy`, just emit a copy. + assert_matches!( + ty.kind(), + ty::Ref(_, _, hir::Mutability::Not), + "field should be captured by immutable ref if we have an `Fn` instance" + ); + fields.push(Operand::Copy(tcx.mk_place_field( + self_local, + FieldIdx::from_usize(idx), + ty, + ))); + } else { + fields.push(Operand::Move(tcx.mk_place_field( + self_local, + FieldIdx::from_usize(idx), + ty, + ))); + } } let source_info = SourceInfo::outermost(span); diff --git a/compiler/rustc_symbol_mangling/src/legacy.rs b/compiler/rustc_symbol_mangling/src/legacy.rs index 9edd2ff9b1a53..5aa46cc0deae0 100644 --- a/compiler/rustc_symbol_mangling/src/legacy.rs +++ b/compiler/rustc_symbol_mangling/src/legacy.rs @@ -85,9 +85,13 @@ pub(super) fn mangle<'tcx>( } // FIXME(async_closures): This shouldn't be needed when we fix // `Instance::ty`/`Instance::def_id`. - ty::InstanceKind::ConstructCoroutineInClosureShim { .. } - | ty::InstanceKind::CoroutineKindShim { .. } => { - printer.write_str("{{fn-once-shim}}").unwrap(); + ty::InstanceKind::ConstructCoroutineInClosureShim { receiver_by_ref, .. } => { + printer + .write_str(if receiver_by_ref { "{{by-move-shim}}" } else { "{{by-ref-shim}}" }) + .unwrap(); + } + ty::InstanceKind::CoroutineKindShim { .. } => { + printer.write_str("{{by-move-body-shim}}").unwrap(); } _ => {} } diff --git a/compiler/rustc_symbol_mangling/src/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs index 42c4fa83d1bf0..5f8029af02044 100644 --- a/compiler/rustc_symbol_mangling/src/v0.rs +++ b/compiler/rustc_symbol_mangling/src/v0.rs @@ -49,8 +49,15 @@ pub(super) fn mangle<'tcx>( ty::InstanceKind::ReifyShim(_, Some(ReifyReason::FnPtr)) => Some("reify_fnptr"), ty::InstanceKind::ReifyShim(_, Some(ReifyReason::Vtable)) => Some("reify_vtable"), - ty::InstanceKind::ConstructCoroutineInClosureShim { .. } - | ty::InstanceKind::CoroutineKindShim { .. } => Some("fn_once"), + // FIXME(async_closures): This shouldn't be needed when we fix + // `Instance::ty`/`Instance::def_id`. + ty::InstanceKind::ConstructCoroutineInClosureShim { receiver_by_ref: true, .. } => { + Some("by_move") + } + ty::InstanceKind::ConstructCoroutineInClosureShim { receiver_by_ref: false, .. } => { + Some("by_ref") + } + ty::InstanceKind::CoroutineKindShim { .. } => Some("by_move_body"), _ => None, }; diff --git a/compiler/rustc_ty_utils/src/abi.rs b/compiler/rustc_ty_utils/src/abi.rs index f1dd94839fe1e..f078cfe1b2505 100644 --- a/compiler/rustc_ty_utils/src/abi.rs +++ b/compiler/rustc_ty_utils/src/abi.rs @@ -127,9 +127,9 @@ fn fn_sig_for_fn_abi<'tcx>( coroutine_kind = ty::ClosureKind::FnOnce; // Implementations of `FnMut` and `Fn` for coroutine-closures - // still take their receiver by (mut) ref. + // still take their receiver by ref. if receiver_by_ref { - Ty::new_mut_ref(tcx, tcx.lifetimes.re_erased, coroutine_ty) + Ty::new_imm_ref(tcx, tcx.lifetimes.re_erased, coroutine_ty) } else { coroutine_ty } diff --git a/src/tools/miri/tests/pass/async-closure.rs b/src/tools/miri/tests/pass/async-closure.rs index 2f7ec2b9e6f86..721af57888384 100644 --- a/src/tools/miri/tests/pass/async-closure.rs +++ b/src/tools/miri/tests/pass/async-closure.rs @@ -1,7 +1,8 @@ #![feature(async_closure, noop_waker, async_fn_traits)] +#![allow(unused)] use std::future::Future; -use std::ops::{AsyncFnMut, AsyncFnOnce}; +use std::ops::{AsyncFn, AsyncFnMut, AsyncFnOnce}; use std::pin::pin; use std::task::*; @@ -17,6 +18,10 @@ pub fn block_on(fut: impl Future) -> T { } } +async fn call(f: &mut impl AsyncFn(i32)) { + f(0).await; +} + async fn call_mut(f: &mut impl AsyncFnMut(i32)) { f(0).await; } @@ -26,10 +31,10 @@ async fn call_once(f: impl AsyncFnOnce(i32)) { } async fn call_normal>(f: &impl Fn(i32) -> F) { - f(0).await; + f(1).await; } -async fn call_normal_once>(f: impl FnOnce(i32) -> F) { +async fn call_normal_mut>(f: &mut impl FnMut(i32) -> F) { f(1).await; } @@ -39,14 +44,16 @@ pub fn main() { let mut async_closure = async move |a: i32| { println!("{a} {b}"); }; + call(&mut async_closure).await; call_mut(&mut async_closure).await; call_once(async_closure).await; - // No-capture closures implement `Fn`. - let async_closure = async move |a: i32| { - println!("{a}"); + let b = 2i32; + let mut async_closure = async |a: i32| { + println!("{a} {b}"); }; call_normal(&async_closure).await; - call_normal_once(async_closure).await; + call_normal_mut(&mut async_closure).await; + call_once(async_closure).await; }); } diff --git a/src/tools/miri/tests/pass/async-closure.stdout b/src/tools/miri/tests/pass/async-closure.stdout index 7baae1aa94f8d..217944c84a2d3 100644 --- a/src/tools/miri/tests/pass/async-closure.stdout +++ b/src/tools/miri/tests/pass/async-closure.stdout @@ -1,4 +1,6 @@ 0 2 +0 2 +1 2 +1 2 +1 2 1 2 -0 -1 diff --git a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}-{closure#0}.coroutine_by_move.0.panic-abort.mir b/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}-{closure#0}.coroutine_by_move.0.panic-abort.mir index 06028487d0178..1c34955a8d9da 100644 --- a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}-{closure#0}.coroutine_by_move.0.panic-abort.mir +++ b/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}-{closure#0}.coroutine_by_move.0.panic-abort.mir @@ -1,6 +1,6 @@ // MIR for `main::{closure#0}::{closure#0}::{closure#0}` 0 coroutine_by_move -fn main::{closure#0}::{closure#0}::{closure#0}(_1: {async closure body@$DIR/async_closure_shims.rs:42:53: 45:10}, _2: ResumeTy) -> () +fn main::{closure#0}::{closure#0}::{closure#0}(_1: {async closure body@$DIR/async_closure_shims.rs:53:53: 56:10}, _2: ResumeTy) -> () yields () { debug _task_context => _2; diff --git a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}-{closure#0}.coroutine_by_move.0.panic-unwind.mir b/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}-{closure#0}.coroutine_by_move.0.panic-unwind.mir index 06028487d0178..1c34955a8d9da 100644 --- a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}-{closure#0}.coroutine_by_move.0.panic-unwind.mir +++ b/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}-{closure#0}.coroutine_by_move.0.panic-unwind.mir @@ -1,6 +1,6 @@ // MIR for `main::{closure#0}::{closure#0}::{closure#0}` 0 coroutine_by_move -fn main::{closure#0}::{closure#0}::{closure#0}(_1: {async closure body@$DIR/async_closure_shims.rs:42:53: 45:10}, _2: ResumeTy) -> () +fn main::{closure#0}::{closure#0}::{closure#0}(_1: {async closure body@$DIR/async_closure_shims.rs:53:53: 56:10}, _2: ResumeTy) -> () yields () { debug _task_context => _2; diff --git a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}.coroutine_closure_by_move.0.panic-abort.mir b/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}.coroutine_closure_by_move.0.panic-abort.mir index 93447b1388dea..a984845fd2c11 100644 --- a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}.coroutine_closure_by_move.0.panic-abort.mir +++ b/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}.coroutine_closure_by_move.0.panic-abort.mir @@ -1,10 +1,10 @@ // MIR for `main::{closure#0}::{closure#0}` 0 coroutine_closure_by_move -fn main::{closure#0}::{closure#0}(_1: {async closure@$DIR/async_closure_shims.rs:42:33: 42:52}, _2: i32) -> {async closure body@$DIR/async_closure_shims.rs:42:53: 45:10} { - let mut _0: {async closure body@$DIR/async_closure_shims.rs:42:53: 45:10}; +fn main::{closure#0}::{closure#0}(_1: {async closure@$DIR/async_closure_shims.rs:53:33: 53:52}, _2: i32) -> {async closure body@$DIR/async_closure_shims.rs:53:53: 56:10} { + let mut _0: {async closure body@$DIR/async_closure_shims.rs:53:53: 56:10}; bb0: { - _0 = {coroutine@$DIR/async_closure_shims.rs:42:53: 45:10 (#0)} { a: move _2, b: move (_1.0: i32) }; + _0 = {coroutine@$DIR/async_closure_shims.rs:53:53: 56:10 (#0)} { a: move _2, b: move (_1.0: i32) }; return; } } diff --git a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}.coroutine_closure_by_move.0.panic-unwind.mir b/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}.coroutine_closure_by_move.0.panic-unwind.mir index 93447b1388dea..a984845fd2c11 100644 --- a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}.coroutine_closure_by_move.0.panic-unwind.mir +++ b/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#0}.coroutine_closure_by_move.0.panic-unwind.mir @@ -1,10 +1,10 @@ // MIR for `main::{closure#0}::{closure#0}` 0 coroutine_closure_by_move -fn main::{closure#0}::{closure#0}(_1: {async closure@$DIR/async_closure_shims.rs:42:33: 42:52}, _2: i32) -> {async closure body@$DIR/async_closure_shims.rs:42:53: 45:10} { - let mut _0: {async closure body@$DIR/async_closure_shims.rs:42:53: 45:10}; +fn main::{closure#0}::{closure#0}(_1: {async closure@$DIR/async_closure_shims.rs:53:33: 53:52}, _2: i32) -> {async closure body@$DIR/async_closure_shims.rs:53:53: 56:10} { + let mut _0: {async closure body@$DIR/async_closure_shims.rs:53:53: 56:10}; bb0: { - _0 = {coroutine@$DIR/async_closure_shims.rs:42:53: 45:10 (#0)} { a: move _2, b: move (_1.0: i32) }; + _0 = {coroutine@$DIR/async_closure_shims.rs:53:53: 56:10 (#0)} { a: move _2, b: move (_1.0: i32) }; return; } } diff --git a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}-{closure#0}.coroutine_by_move.0.panic-abort.mir b/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}-{closure#0}.coroutine_by_move.0.panic-abort.mir new file mode 100644 index 0000000000000..516908144a641 --- /dev/null +++ b/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}-{closure#0}.coroutine_by_move.0.panic-abort.mir @@ -0,0 +1,47 @@ +// MIR for `main::{closure#0}::{closure#1}::{closure#0}` 0 coroutine_by_move + +fn main::{closure#0}::{closure#1}::{closure#0}(_1: {async closure body@$DIR/async_closure_shims.rs:62:48: 65:10}, _2: ResumeTy) -> () +yields () + { + debug _task_context => _2; + debug a => (_1.0: i32); + debug b => (*(_1.1: &i32)); + let mut _0: (); + let _3: i32; + scope 1 { + debug a => _3; + let _4: &i32; + scope 2 { + debug a => _4; + let _5: &i32; + scope 3 { + debug b => _5; + } + } + } + + bb0: { + StorageLive(_3); + _3 = (_1.0: i32); + FakeRead(ForLet(None), _3); + StorageLive(_4); + _4 = &_3; + FakeRead(ForLet(None), _4); + StorageLive(_5); + _5 = &(*(_1.1: &i32)); + FakeRead(ForLet(None), _5); + _0 = const (); + StorageDead(_5); + StorageDead(_4); + StorageDead(_3); + drop(_1) -> [return: bb1, unwind: bb2]; + } + + bb1: { + return; + } + + bb2 (cleanup): { + resume; + } +} diff --git a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}-{closure#0}.coroutine_by_move.0.panic-unwind.mir b/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}-{closure#0}.coroutine_by_move.0.panic-unwind.mir new file mode 100644 index 0000000000000..516908144a641 --- /dev/null +++ b/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}-{closure#0}.coroutine_by_move.0.panic-unwind.mir @@ -0,0 +1,47 @@ +// MIR for `main::{closure#0}::{closure#1}::{closure#0}` 0 coroutine_by_move + +fn main::{closure#0}::{closure#1}::{closure#0}(_1: {async closure body@$DIR/async_closure_shims.rs:62:48: 65:10}, _2: ResumeTy) -> () +yields () + { + debug _task_context => _2; + debug a => (_1.0: i32); + debug b => (*(_1.1: &i32)); + let mut _0: (); + let _3: i32; + scope 1 { + debug a => _3; + let _4: &i32; + scope 2 { + debug a => _4; + let _5: &i32; + scope 3 { + debug b => _5; + } + } + } + + bb0: { + StorageLive(_3); + _3 = (_1.0: i32); + FakeRead(ForLet(None), _3); + StorageLive(_4); + _4 = &_3; + FakeRead(ForLet(None), _4); + StorageLive(_5); + _5 = &(*(_1.1: &i32)); + FakeRead(ForLet(None), _5); + _0 = const (); + StorageDead(_5); + StorageDead(_4); + StorageDead(_3); + drop(_1) -> [return: bb1, unwind: bb2]; + } + + bb1: { + return; + } + + bb2 (cleanup): { + resume; + } +} diff --git a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}.coroutine_closure_by_move.0.panic-abort.mir b/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}.coroutine_closure_by_move.0.panic-abort.mir new file mode 100644 index 0000000000000..aab9f7b03b9ab --- /dev/null +++ b/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}.coroutine_closure_by_move.0.panic-abort.mir @@ -0,0 +1,10 @@ +// MIR for `main::{closure#0}::{closure#1}` 0 coroutine_closure_by_move + +fn main::{closure#0}::{closure#1}(_1: {async closure@$DIR/async_closure_shims.rs:62:33: 62:47}, _2: i32) -> {async closure body@$DIR/async_closure_shims.rs:62:48: 65:10} { + let mut _0: {async closure body@$DIR/async_closure_shims.rs:62:48: 65:10}; + + bb0: { + _0 = {coroutine@$DIR/async_closure_shims.rs:62:48: 65:10 (#0)} { a: move _2, b: move (_1.0: &i32) }; + return; + } +} diff --git a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}.coroutine_closure_by_move.0.panic-unwind.mir b/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}.coroutine_closure_by_move.0.panic-unwind.mir new file mode 100644 index 0000000000000..aab9f7b03b9ab --- /dev/null +++ b/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}.coroutine_closure_by_move.0.panic-unwind.mir @@ -0,0 +1,10 @@ +// MIR for `main::{closure#0}::{closure#1}` 0 coroutine_closure_by_move + +fn main::{closure#0}::{closure#1}(_1: {async closure@$DIR/async_closure_shims.rs:62:33: 62:47}, _2: i32) -> {async closure body@$DIR/async_closure_shims.rs:62:48: 65:10} { + let mut _0: {async closure body@$DIR/async_closure_shims.rs:62:48: 65:10}; + + bb0: { + _0 = {coroutine@$DIR/async_closure_shims.rs:62:48: 65:10 (#0)} { a: move _2, b: move (_1.0: &i32) }; + return; + } +} diff --git a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}.coroutine_closure_by_ref.0.panic-abort.mir b/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}.coroutine_closure_by_ref.0.panic-abort.mir index cab7bdb7e3cbf..ba20c28cd0147 100644 --- a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}.coroutine_closure_by_ref.0.panic-abort.mir +++ b/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}.coroutine_closure_by_ref.0.panic-abort.mir @@ -1,10 +1,10 @@ // MIR for `main::{closure#0}::{closure#1}` 0 coroutine_closure_by_ref -fn main::{closure#0}::{closure#1}(_1: &mut {async closure@$DIR/async_closure_shims.rs:49:29: 49:48}, _2: i32) -> {async closure body@$DIR/async_closure_shims.rs:49:49: 51:10} { - let mut _0: {async closure body@$DIR/async_closure_shims.rs:49:49: 51:10}; +fn main::{closure#0}::{closure#1}(_1: &{async closure@$DIR/async_closure_shims.rs:62:33: 62:47}, _2: i32) -> {async closure body@$DIR/async_closure_shims.rs:62:48: 65:10} { + let mut _0: {async closure body@$DIR/async_closure_shims.rs:62:48: 65:10}; bb0: { - _0 = {coroutine@$DIR/async_closure_shims.rs:49:49: 51:10 (#0)} { a: move _2 }; + _0 = {coroutine@$DIR/async_closure_shims.rs:62:48: 65:10 (#0)} { a: move _2, b: ((*_1).0: &i32) }; return; } } diff --git a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}.coroutine_closure_by_ref.0.panic-unwind.mir b/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}.coroutine_closure_by_ref.0.panic-unwind.mir index cab7bdb7e3cbf..ba20c28cd0147 100644 --- a/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}.coroutine_closure_by_ref.0.panic-unwind.mir +++ b/tests/mir-opt/async_closure_shims.main-{closure#0}-{closure#1}.coroutine_closure_by_ref.0.panic-unwind.mir @@ -1,10 +1,10 @@ // MIR for `main::{closure#0}::{closure#1}` 0 coroutine_closure_by_ref -fn main::{closure#0}::{closure#1}(_1: &mut {async closure@$DIR/async_closure_shims.rs:49:29: 49:48}, _2: i32) -> {async closure body@$DIR/async_closure_shims.rs:49:49: 51:10} { - let mut _0: {async closure body@$DIR/async_closure_shims.rs:49:49: 51:10}; +fn main::{closure#0}::{closure#1}(_1: &{async closure@$DIR/async_closure_shims.rs:62:33: 62:47}, _2: i32) -> {async closure body@$DIR/async_closure_shims.rs:62:48: 65:10} { + let mut _0: {async closure body@$DIR/async_closure_shims.rs:62:48: 65:10}; bb0: { - _0 = {coroutine@$DIR/async_closure_shims.rs:49:49: 51:10 (#0)} { a: move _2 }; + _0 = {coroutine@$DIR/async_closure_shims.rs:62:48: 65:10 (#0)} { a: move _2, b: ((*_1).0: &i32) }; return; } } diff --git a/tests/mir-opt/async_closure_shims.rs b/tests/mir-opt/async_closure_shims.rs index 7d226df686654..57c55ef055cd7 100644 --- a/tests/mir-opt/async_closure_shims.rs +++ b/tests/mir-opt/async_closure_shims.rs @@ -3,9 +3,10 @@ // EMIT_MIR_FOR_EACH_PANIC_STRATEGY #![feature(async_closure, noop_waker, async_fn_traits)] +#![allow(unused)] use std::future::Future; -use std::ops::{AsyncFnMut, AsyncFnOnce}; +use std::ops::{AsyncFn, AsyncFnMut, AsyncFnOnce}; use std::pin::pin; use std::task::*; @@ -21,6 +22,10 @@ pub fn block_on(fut: impl Future) -> T { } } +async fn call(f: &mut impl AsyncFn(i32)) { + f(0).await; +} + async fn call_mut(f: &mut impl AsyncFnMut(i32)) { f(0).await; } @@ -33,9 +38,15 @@ async fn call_normal>(f: &impl Fn(i32) -> F) { f(1).await; } +async fn call_normal_mut>(f: &mut impl FnMut(i32) -> F) { + f(1).await; +} + // EMIT_MIR async_closure_shims.main-{closure#0}-{closure#0}.coroutine_closure_by_move.0.mir // EMIT_MIR async_closure_shims.main-{closure#0}-{closure#0}-{closure#0}.coroutine_by_move.0.mir // EMIT_MIR async_closure_shims.main-{closure#0}-{closure#1}.coroutine_closure_by_ref.0.mir +// EMIT_MIR async_closure_shims.main-{closure#0}-{closure#1}.coroutine_closure_by_move.0.mir +// EMIT_MIR async_closure_shims.main-{closure#0}-{closure#1}-{closure#0}.coroutine_by_move.0.mir pub fn main() { block_on(async { let b = 2i32; @@ -43,12 +54,17 @@ pub fn main() { let a = &a; let b = &b; }; + call(&mut async_closure).await; call_mut(&mut async_closure).await; call_once(async_closure).await; - let async_closure = async move |a: i32| { + let b = 2i32; + let mut async_closure = async |a: i32| { let a = &a; + let b = &b; }; call_normal(&async_closure).await; + call_normal_mut(&mut async_closure).await; + call_once(async_closure).await; }); } From 53db64168f7556bc57355a635b19e6b005e87876 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sat, 29 Jun 2024 22:35:17 -0400 Subject: [PATCH 484/892] Uplift fast rejection to new solver --- .../rustc_hir_typeck/src/method/suggest.rs | 2 +- compiler/rustc_middle/src/ty/context.rs | 11 - compiler/rustc_middle/src/ty/fast_reject.rs | 368 +--------------- compiler/rustc_middle/src/ty/impls_ty.rs | 13 - .../src/solve/normalizes_to/mod.rs | 3 +- .../src/solve/trait_goals.rs | 4 +- .../src/traits/coherence.rs | 2 +- .../src/traits/select/candidate_assembly.rs | 2 +- compiler/rustc_type_ir/src/fast_reject.rs | 397 ++++++++++++++++++ compiler/rustc_type_ir/src/inherent.rs | 8 + compiler/rustc_type_ir/src/interner.rs | 7 - compiler/rustc_type_ir/src/lib.rs | 1 + src/librustdoc/html/render/write_shared.rs | 3 +- 13 files changed, 419 insertions(+), 402 deletions(-) create mode 100644 compiler/rustc_type_ir/src/fast_reject.rs diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index a385bc70e359b..57f0da195c71d 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -2129,7 +2129,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let target_ty = self .autoderef(sugg_span, rcvr_ty) .find(|(rcvr_ty, _)| { - DeepRejectCtxt { treat_obligation_params: TreatParams::AsCandidateKey } + DeepRejectCtxt::new(self.tcx, TreatParams::ForLookup) .types_may_unify(*rcvr_ty, impl_ty) }) .map_or(impl_ty, |(ty, _)| ty) diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index ed1ec55bc8ed1..7fd2f4c9105cc 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -373,17 +373,6 @@ impl<'tcx> Interner for TyCtxt<'tcx> { .map(|assoc_item| assoc_item.def_id) } - fn args_may_unify_deep( - self, - obligation_args: ty::GenericArgsRef<'tcx>, - impl_args: ty::GenericArgsRef<'tcx>, - ) -> bool { - ty::fast_reject::DeepRejectCtxt { - treat_obligation_params: ty::fast_reject::TreatParams::ForLookup, - } - .args_may_unify(obligation_args, impl_args) - } - // This implementation is a bit different from `TyCtxt::for_each_relevant_impl`, // since we want to skip over blanket impls for non-rigid aliases, and also we // only want to consider types that *actually* unify with float/int vars. diff --git a/compiler/rustc_middle/src/ty/fast_reject.rs b/compiler/rustc_middle/src/ty/fast_reject.rs index 923667e609be4..0413cfa5a63c5 100644 --- a/compiler/rustc_middle/src/ty/fast_reject.rs +++ b/compiler/rustc_middle/src/ty/fast_reject.rs @@ -1,369 +1,9 @@ -use crate::mir::Mutability; -use crate::ty::GenericArgKind; -use crate::ty::{self, GenericArgsRef, Ty, TyCtxt, TypeVisitableExt}; use rustc_hir::def_id::DefId; -use rustc_macros::{HashStable, TyDecodable, TyEncodable}; -use std::fmt::Debug; -use std::hash::Hash; -use std::iter; -/// See `simplify_type`. -#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, TyEncodable, TyDecodable, HashStable)] -pub enum SimplifiedType { - Bool, - Char, - Int(ty::IntTy), - Uint(ty::UintTy), - Float(ty::FloatTy), - Adt(DefId), - Foreign(DefId), - Str, - Array, - Slice, - Ref(Mutability), - Ptr(Mutability), - Never, - Tuple(usize), - /// A trait object, all of whose components are markers - /// (e.g., `dyn Send + Sync`). - MarkerTraitObject, - Trait(DefId), - Closure(DefId), - Coroutine(DefId), - CoroutineWitness(DefId), - Function(usize), - Placeholder, - Error, -} +use super::TyCtxt; -/// Generic parameters are pretty much just bound variables, e.g. -/// the type of `fn foo<'a, T>(x: &'a T) -> u32 { ... }` can be thought of as -/// `for<'a, T> fn(&'a T) -> u32`. -/// -/// Typecheck of `foo` has to succeed for all possible generic arguments, so -/// during typeck, we have to treat its generic parameters as if they -/// were placeholders. -/// -/// But when calling `foo` we only have to provide a specific generic argument. -/// In that case the generic parameters are instantiated with inference variables. -/// As we use `simplify_type` before that instantiation happens, we just treat -/// generic parameters as if they were inference variables in that case. -#[derive(PartialEq, Eq, Debug, Clone, Copy)] -pub enum TreatParams { - /// Treat parameters as infer vars. This is the correct mode for caching - /// an impl's type for lookup. - AsCandidateKey, - /// Treat parameters as placeholders in the given environment. This is the - /// correct mode for *lookup*, as during candidate selection. - /// - /// This also treats projections with inference variables as infer vars - /// since they could be further normalized. - ForLookup, -} +pub use rustc_type_ir::fast_reject::*; -/// Tries to simplify a type by only returning the outermost injective¹ layer, if one exists. -/// -/// **This function should only be used if you need to store or retrieve the type from some -/// hashmap. If you want to quickly decide whether two types may unify, use the [DeepRejectCtxt] -/// instead.** -/// -/// The idea is to get something simple that we can use to quickly decide if two types could unify, -/// for example during method lookup. If this function returns `Some(x)` it can only unify with -/// types for which this method returns either `Some(x)` as well or `None`. -/// -/// A special case here are parameters and projections, which are only injective -/// if they are treated as placeholders. -/// -/// For example when storing impls based on their simplified self type, we treat -/// generic parameters as if they were inference variables. We must not simplify them here, -/// as they can unify with any other type. -/// -/// With projections we have to be even more careful, as treating them as placeholders -/// is only correct if they are fully normalized. -/// -/// ¹ meaning that if the outermost layers are different, then the whole types are also different. -pub fn simplify_type<'tcx>( - tcx: TyCtxt<'tcx>, - ty: Ty<'tcx>, - treat_params: TreatParams, -) -> Option { - match *ty.kind() { - ty::Bool => Some(SimplifiedType::Bool), - ty::Char => Some(SimplifiedType::Char), - ty::Int(int_type) => Some(SimplifiedType::Int(int_type)), - ty::Uint(uint_type) => Some(SimplifiedType::Uint(uint_type)), - ty::Float(float_type) => Some(SimplifiedType::Float(float_type)), - ty::Adt(def, _) => Some(SimplifiedType::Adt(def.did())), - ty::Str => Some(SimplifiedType::Str), - ty::Array(..) => Some(SimplifiedType::Array), - ty::Slice(..) => Some(SimplifiedType::Slice), - ty::Pat(ty, ..) => simplify_type(tcx, ty, treat_params), - ty::RawPtr(_, mutbl) => Some(SimplifiedType::Ptr(mutbl)), - ty::Dynamic(trait_info, ..) => match trait_info.principal_def_id() { - Some(principal_def_id) if !tcx.trait_is_auto(principal_def_id) => { - Some(SimplifiedType::Trait(principal_def_id)) - } - _ => Some(SimplifiedType::MarkerTraitObject), - }, - ty::Ref(_, _, mutbl) => Some(SimplifiedType::Ref(mutbl)), - ty::FnDef(def_id, _) | ty::Closure(def_id, _) | ty::CoroutineClosure(def_id, _) => { - Some(SimplifiedType::Closure(def_id)) - } - ty::Coroutine(def_id, _) => Some(SimplifiedType::Coroutine(def_id)), - ty::CoroutineWitness(def_id, _) => Some(SimplifiedType::CoroutineWitness(def_id)), - ty::Never => Some(SimplifiedType::Never), - ty::Tuple(tys) => Some(SimplifiedType::Tuple(tys.len())), - ty::FnPtr(f) => Some(SimplifiedType::Function(f.skip_binder().inputs().len())), - ty::Placeholder(..) => Some(SimplifiedType::Placeholder), - ty::Param(_) => match treat_params { - TreatParams::ForLookup => Some(SimplifiedType::Placeholder), - TreatParams::AsCandidateKey => None, - }, - ty::Alias(..) => match treat_params { - // When treating `ty::Param` as a placeholder, projections also - // don't unify with anything else as long as they are fully normalized. - // FIXME(-Znext-solver): Can remove this `if` and always simplify to `Placeholder` - // when the new solver is enabled by default. - TreatParams::ForLookup if !ty.has_non_region_infer() => { - Some(SimplifiedType::Placeholder) - } - TreatParams::ForLookup | TreatParams::AsCandidateKey => None, - }, - ty::Foreign(def_id) => Some(SimplifiedType::Foreign(def_id)), - ty::Error(_) => Some(SimplifiedType::Error), - ty::Bound(..) | ty::Infer(_) => None, - } -} +pub type DeepRejectCtxt<'tcx> = rustc_type_ir::fast_reject::DeepRejectCtxt>; -impl SimplifiedType { - pub fn def(self) -> Option { - match self { - SimplifiedType::Adt(d) - | SimplifiedType::Foreign(d) - | SimplifiedType::Trait(d) - | SimplifiedType::Closure(d) - | SimplifiedType::Coroutine(d) - | SimplifiedType::CoroutineWitness(d) => Some(d), - _ => None, - } - } -} - -/// Given generic arguments from an obligation and an impl, -/// could these two be unified after replacing parameters in the -/// the impl with inference variables. -/// -/// For obligations, parameters won't be replaced by inference -/// variables and only unify with themselves. We treat them -/// the same way we treat placeholders. -/// -/// We also use this function during coherence. For coherence the -/// impls only have to overlap for some value, so we treat parameters -/// on both sides like inference variables. This behavior is toggled -/// using the `treat_obligation_params` field. -#[derive(Debug, Clone, Copy)] -pub struct DeepRejectCtxt { - pub treat_obligation_params: TreatParams, -} - -impl DeepRejectCtxt { - pub fn args_may_unify<'tcx>( - self, - obligation_args: GenericArgsRef<'tcx>, - impl_args: GenericArgsRef<'tcx>, - ) -> bool { - iter::zip(obligation_args, impl_args).all(|(obl, imp)| { - match (obl.unpack(), imp.unpack()) { - // We don't fast reject based on regions. - (GenericArgKind::Lifetime(_), GenericArgKind::Lifetime(_)) => true, - (GenericArgKind::Type(obl), GenericArgKind::Type(imp)) => { - self.types_may_unify(obl, imp) - } - (GenericArgKind::Const(obl), GenericArgKind::Const(imp)) => { - self.consts_may_unify(obl, imp) - } - _ => bug!("kind mismatch: {obl} {imp}"), - } - }) - } - - pub fn types_may_unify<'tcx>(self, obligation_ty: Ty<'tcx>, impl_ty: Ty<'tcx>) -> bool { - match impl_ty.kind() { - // Start by checking whether the type in the impl may unify with - // pretty much everything. Just return `true` in that case. - ty::Param(_) | ty::Error(_) | ty::Alias(..) => return true, - // These types only unify with inference variables or their own - // variant. - ty::Bool - | ty::Char - | ty::Int(_) - | ty::Uint(_) - | ty::Float(_) - | ty::Adt(..) - | ty::Str - | ty::Array(..) - | ty::Slice(..) - | ty::RawPtr(..) - | ty::Dynamic(..) - | ty::Pat(..) - | ty::Ref(..) - | ty::Never - | ty::Tuple(..) - | ty::FnPtr(..) - | ty::Foreign(..) => debug_assert!(impl_ty.is_known_rigid()), - ty::FnDef(..) - | ty::Closure(..) - | ty::CoroutineClosure(..) - | ty::Coroutine(..) - | ty::CoroutineWitness(..) - | ty::Placeholder(..) - | ty::Bound(..) - | ty::Infer(_) => bug!("unexpected impl_ty: {impl_ty}"), - } - - let k = impl_ty.kind(); - match *obligation_ty.kind() { - // Purely rigid types, use structural equivalence. - ty::Bool - | ty::Char - | ty::Int(_) - | ty::Uint(_) - | ty::Float(_) - | ty::Str - | ty::Never - | ty::Foreign(_) => obligation_ty == impl_ty, - ty::Ref(_, obl_ty, obl_mutbl) => match k { - &ty::Ref(_, impl_ty, impl_mutbl) => { - obl_mutbl == impl_mutbl && self.types_may_unify(obl_ty, impl_ty) - } - _ => false, - }, - ty::Adt(obl_def, obl_args) => match k { - &ty::Adt(impl_def, impl_args) => { - obl_def == impl_def && self.args_may_unify(obl_args, impl_args) - } - _ => false, - }, - ty::Pat(obl_ty, _) => { - // FIXME(pattern_types): take pattern into account - matches!(k, &ty::Pat(impl_ty, _) if self.types_may_unify(obl_ty, impl_ty)) - } - ty::Slice(obl_ty) => { - matches!(k, &ty::Slice(impl_ty) if self.types_may_unify(obl_ty, impl_ty)) - } - ty::Array(obl_ty, obl_len) => match k { - &ty::Array(impl_ty, impl_len) => { - self.types_may_unify(obl_ty, impl_ty) - && self.consts_may_unify(obl_len, impl_len) - } - _ => false, - }, - ty::Tuple(obl) => match k { - &ty::Tuple(imp) => { - obl.len() == imp.len() - && iter::zip(obl, imp).all(|(obl, imp)| self.types_may_unify(obl, imp)) - } - _ => false, - }, - ty::RawPtr(obl_ty, obl_mutbl) => match *k { - ty::RawPtr(imp_ty, imp_mutbl) => { - obl_mutbl == imp_mutbl && self.types_may_unify(obl_ty, imp_ty) - } - _ => false, - }, - ty::Dynamic(obl_preds, ..) => { - // Ideally we would walk the existential predicates here or at least - // compare their length. But considering that the relevant `Relate` impl - // actually sorts and deduplicates these, that doesn't work. - matches!(k, ty::Dynamic(impl_preds, ..) if - obl_preds.principal_def_id() == impl_preds.principal_def_id() - ) - } - ty::FnPtr(obl_sig) => match k { - ty::FnPtr(impl_sig) => { - let ty::FnSig { inputs_and_output, c_variadic, safety, abi } = - obl_sig.skip_binder(); - let impl_sig = impl_sig.skip_binder(); - - abi == impl_sig.abi - && c_variadic == impl_sig.c_variadic - && safety == impl_sig.safety - && inputs_and_output.len() == impl_sig.inputs_and_output.len() - && iter::zip(inputs_and_output, impl_sig.inputs_and_output) - .all(|(obl, imp)| self.types_may_unify(obl, imp)) - } - _ => false, - }, - - // Impls cannot contain these types as these cannot be named directly. - ty::FnDef(..) | ty::Closure(..) | ty::CoroutineClosure(..) | ty::Coroutine(..) => false, - - // Placeholder types don't unify with anything on their own - ty::Placeholder(..) | ty::Bound(..) => false, - - // Depending on the value of `treat_obligation_params`, we either - // treat generic parameters like placeholders or like inference variables. - ty::Param(_) => match self.treat_obligation_params { - TreatParams::ForLookup => false, - TreatParams::AsCandidateKey => true, - }, - - ty::Infer(ty::IntVar(_)) => impl_ty.is_integral(), - - ty::Infer(ty::FloatVar(_)) => impl_ty.is_floating_point(), - - ty::Infer(_) => true, - - // As we're walking the whole type, it may encounter projections - // inside of binders and what not, so we're just going to assume that - // projections can unify with other stuff. - // - // Looking forward to lazy normalization this is the safer strategy anyways. - ty::Alias(..) => true, - - ty::Error(_) => true, - - ty::CoroutineWitness(..) => { - bug!("unexpected obligation type: {:?}", obligation_ty) - } - } - } - - pub fn consts_may_unify(self, obligation_ct: ty::Const<'_>, impl_ct: ty::Const<'_>) -> bool { - let impl_val = match impl_ct.kind() { - ty::ConstKind::Expr(_) - | ty::ConstKind::Param(_) - | ty::ConstKind::Unevaluated(_) - | ty::ConstKind::Error(_) => { - return true; - } - ty::ConstKind::Value(_, impl_val) => impl_val, - ty::ConstKind::Infer(_) | ty::ConstKind::Bound(..) | ty::ConstKind::Placeholder(_) => { - bug!("unexpected impl arg: {:?}", impl_ct) - } - }; - - match obligation_ct.kind() { - ty::ConstKind::Param(_) => match self.treat_obligation_params { - TreatParams::ForLookup => false, - TreatParams::AsCandidateKey => true, - }, - - // Placeholder consts don't unify with anything on their own - ty::ConstKind::Placeholder(_) => false, - - // As we don't necessarily eagerly evaluate constants, - // they might unify with any value. - ty::ConstKind::Expr(_) | ty::ConstKind::Unevaluated(_) | ty::ConstKind::Error(_) => { - true - } - ty::ConstKind::Value(_, obl_val) => obl_val == impl_val, - - ty::ConstKind::Infer(_) => true, - - ty::ConstKind::Bound(..) => { - bug!("unexpected obl const: {:?}", obligation_ct) - } - } - } -} +pub type SimplifiedType = rustc_type_ir::fast_reject::SimplifiedType; diff --git a/compiler/rustc_middle/src/ty/impls_ty.rs b/compiler/rustc_middle/src/ty/impls_ty.rs index efcf428c2136f..9be7370a1c21c 100644 --- a/compiler/rustc_middle/src/ty/impls_ty.rs +++ b/compiler/rustc_middle/src/ty/impls_ty.rs @@ -4,7 +4,6 @@ use crate::middle::region; use crate::mir; use crate::ty; -use crate::ty::fast_reject::SimplifiedType; use rustc_data_structures::fingerprint::Fingerprint; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::stable_hasher::HashingControls; @@ -57,18 +56,6 @@ where } } -impl<'a> ToStableHashKey> for SimplifiedType { - type KeyType = Fingerprint; - - #[inline] - fn to_stable_hash_key(&self, hcx: &StableHashingContext<'a>) -> Fingerprint { - let mut hasher = StableHasher::new(); - let mut hcx: StableHashingContext<'a> = hcx.clone(); - self.hash_stable(&mut hcx, &mut hasher); - hasher.finish() - } -} - impl<'a, 'tcx> HashStable> for ty::GenericArg<'tcx> { fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { self.unpack().hash_stable(hcx, hasher); diff --git a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs index 4e8cb4384f462..69219c06e5775 100644 --- a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs @@ -3,6 +3,7 @@ mod inherent; mod opaque_types; mod weak_types; +use rustc_type_ir::fast_reject::{DeepRejectCtxt, TreatParams}; use rustc_type_ir::inherent::*; use rustc_type_ir::lang_items::TraitSolverLangItem; use rustc_type_ir::Upcast as _; @@ -144,7 +145,7 @@ where let goal_trait_ref = goal.predicate.alias.trait_ref(cx); let impl_trait_ref = cx.impl_trait_ref(impl_def_id); - if !ecx.cx().args_may_unify_deep( + if !DeepRejectCtxt::new(ecx.cx(), TreatParams::ForLookup).args_may_unify( goal.predicate.alias.trait_ref(cx).args, impl_trait_ref.skip_binder().args, ) { diff --git a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs index 2bc9d35c2b020..33050e5c01936 100644 --- a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs +++ b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs @@ -2,6 +2,7 @@ use rustc_ast_ir::Movability; use rustc_type_ir::data_structures::IndexSet; +use rustc_type_ir::fast_reject::{DeepRejectCtxt, TreatParams}; use rustc_type_ir::inherent::*; use rustc_type_ir::lang_items::TraitSolverLangItem; use rustc_type_ir::visit::TypeVisitableExt as _; @@ -46,7 +47,8 @@ where let cx = ecx.cx(); let impl_trait_ref = cx.impl_trait_ref(impl_def_id); - if !cx.args_may_unify_deep(goal.predicate.trait_ref.args, impl_trait_ref.skip_binder().args) + if !DeepRejectCtxt::new(ecx.cx(), TreatParams::ForLookup) + .args_may_unify(goal.predicate.trait_ref.args, impl_trait_ref.skip_binder().args) { return Err(NoSolution); } diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs index a4177d8a93f47..9f0d84e7d4526 100644 --- a/compiler/rustc_trait_selection/src/traits/coherence.rs +++ b/compiler/rustc_trait_selection/src/traits/coherence.rs @@ -121,7 +121,7 @@ pub fn overlapping_impls( // Before doing expensive operations like entering an inference context, do // a quick check via fast_reject to tell if the impl headers could possibly // unify. - let drcx = DeepRejectCtxt { treat_obligation_params: TreatParams::AsCandidateKey }; + let drcx = DeepRejectCtxt::new(tcx, TreatParams::AsCandidateKey); let impl1_ref = tcx.impl_trait_ref(impl1_def_id); let impl2_ref = tcx.impl_trait_ref(impl2_def_id); let may_overlap = match (impl1_ref, impl2_ref) { diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs index e36a9ca8bd1c2..4c3d833b0f90f 100644 --- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs +++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs @@ -571,7 +571,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { return; } - let drcx = DeepRejectCtxt { treat_obligation_params: TreatParams::ForLookup }; + let drcx = DeepRejectCtxt::new(self.tcx(), TreatParams::ForLookup); let obligation_args = obligation.predicate.skip_binder().trait_ref.args; self.tcx().for_each_relevant_impl( obligation.predicate.def_id(), diff --git a/compiler/rustc_type_ir/src/fast_reject.rs b/compiler/rustc_type_ir/src/fast_reject.rs new file mode 100644 index 0000000000000..0810fa5c55832 --- /dev/null +++ b/compiler/rustc_type_ir/src/fast_reject.rs @@ -0,0 +1,397 @@ +use std::fmt::Debug; +use std::hash::Hash; +use std::iter; +use std::marker::PhantomData; + +use rustc_ast_ir::Mutability; +#[cfg(feature = "nightly")] +use rustc_data_structures::fingerprint::Fingerprint; +#[cfg(feature = "nightly")] +use rustc_data_structures::stable_hasher::{HashStable, StableHasher, ToStableHashKey}; +#[cfg(feature = "nightly")] +use rustc_macros::{HashStable_NoContext, TyDecodable, TyEncodable}; + +use crate::inherent::*; +use crate::visit::TypeVisitableExt as _; +use crate::{self as ty, Interner}; + +/// See `simplify_type`. +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] +#[cfg_attr(feature = "nightly", derive(TyEncodable, TyDecodable, HashStable_NoContext))] +pub enum SimplifiedType { + Bool, + Char, + Int(ty::IntTy), + Uint(ty::UintTy), + Float(ty::FloatTy), + Adt(DefId), + Foreign(DefId), + Str, + Array, + Slice, + Ref(Mutability), + Ptr(Mutability), + Never, + Tuple(usize), + /// A trait object, all of whose components are markers + /// (e.g., `dyn Send + Sync`). + MarkerTraitObject, + Trait(DefId), + Closure(DefId), + Coroutine(DefId), + CoroutineWitness(DefId), + Function(usize), + Placeholder, + Error, +} + +#[cfg(feature = "nightly")] +impl> ToStableHashKey for SimplifiedType { + type KeyType = Fingerprint; + + #[inline] + fn to_stable_hash_key(&self, hcx: &HCX) -> Fingerprint { + let mut hasher = StableHasher::new(); + let mut hcx: HCX = hcx.clone(); + self.hash_stable(&mut hcx, &mut hasher); + hasher.finish() + } +} + +/// Generic parameters are pretty much just bound variables, e.g. +/// the type of `fn foo<'a, T>(x: &'a T) -> u32 { ... }` can be thought of as +/// `for<'a, T> fn(&'a T) -> u32`. +/// +/// Typecheck of `foo` has to succeed for all possible generic arguments, so +/// during typeck, we have to treat its generic parameters as if they +/// were placeholders. +/// +/// But when calling `foo` we only have to provide a specific generic argument. +/// In that case the generic parameters are instantiated with inference variables. +/// As we use `simplify_type` before that instantiation happens, we just treat +/// generic parameters as if they were inference variables in that case. +#[derive(PartialEq, Eq, Debug, Clone, Copy)] +pub enum TreatParams { + /// Treat parameters as infer vars. This is the correct mode for caching + /// an impl's type for lookup. + AsCandidateKey, + /// Treat parameters as placeholders in the given environment. This is the + /// correct mode for *lookup*, as during candidate selection. + /// + /// This also treats projections with inference variables as infer vars + /// since they could be further normalized. + ForLookup, +} + +/// Tries to simplify a type by only returning the outermost injective¹ layer, if one exists. +/// +/// **This function should only be used if you need to store or retrieve the type from some +/// hashmap. If you want to quickly decide whether two types may unify, use the [DeepRejectCtxt] +/// instead.** +/// +/// The idea is to get something simple that we can use to quickly decide if two types could unify, +/// for example during method lookup. If this function returns `Some(x)` it can only unify with +/// types for which this method returns either `Some(x)` as well or `None`. +/// +/// A special case here are parameters and projections, which are only injective +/// if they are treated as placeholders. +/// +/// For example when storing impls based on their simplified self type, we treat +/// generic parameters as if they were inference variables. We must not simplify them here, +/// as they can unify with any other type. +/// +/// With projections we have to be even more careful, as treating them as placeholders +/// is only correct if they are fully normalized. +/// +/// ¹ meaning that if the outermost layers are different, then the whole types are also different. +pub fn simplify_type( + tcx: I, + ty: I::Ty, + treat_params: TreatParams, +) -> Option> { + match ty.kind() { + ty::Bool => Some(SimplifiedType::Bool), + ty::Char => Some(SimplifiedType::Char), + ty::Int(int_type) => Some(SimplifiedType::Int(int_type)), + ty::Uint(uint_type) => Some(SimplifiedType::Uint(uint_type)), + ty::Float(float_type) => Some(SimplifiedType::Float(float_type)), + ty::Adt(def, _) => Some(SimplifiedType::Adt(def.def_id())), + ty::Str => Some(SimplifiedType::Str), + ty::Array(..) => Some(SimplifiedType::Array), + ty::Slice(..) => Some(SimplifiedType::Slice), + ty::Pat(ty, ..) => simplify_type(tcx, ty, treat_params), + ty::RawPtr(_, mutbl) => Some(SimplifiedType::Ptr(mutbl)), + ty::Dynamic(trait_info, ..) => match trait_info.principal_def_id() { + Some(principal_def_id) if !tcx.trait_is_auto(principal_def_id) => { + Some(SimplifiedType::Trait(principal_def_id)) + } + _ => Some(SimplifiedType::MarkerTraitObject), + }, + ty::Ref(_, _, mutbl) => Some(SimplifiedType::Ref(mutbl)), + ty::FnDef(def_id, _) | ty::Closure(def_id, _) | ty::CoroutineClosure(def_id, _) => { + Some(SimplifiedType::Closure(def_id)) + } + ty::Coroutine(def_id, _) => Some(SimplifiedType::Coroutine(def_id)), + ty::CoroutineWitness(def_id, _) => Some(SimplifiedType::CoroutineWitness(def_id)), + ty::Never => Some(SimplifiedType::Never), + ty::Tuple(tys) => Some(SimplifiedType::Tuple(tys.len())), + ty::FnPtr(f) => Some(SimplifiedType::Function(f.skip_binder().inputs().len())), + ty::Placeholder(..) => Some(SimplifiedType::Placeholder), + ty::Param(_) => match treat_params { + TreatParams::ForLookup => Some(SimplifiedType::Placeholder), + TreatParams::AsCandidateKey => None, + }, + ty::Alias(..) => match treat_params { + // When treating `ty::Param` as a placeholder, projections also + // don't unify with anything else as long as they are fully normalized. + // FIXME(-Znext-solver): Can remove this `if` and always simplify to `Placeholder` + // when the new solver is enabled by default. + TreatParams::ForLookup if !ty.has_non_region_infer() => { + Some(SimplifiedType::Placeholder) + } + TreatParams::ForLookup | TreatParams::AsCandidateKey => None, + }, + ty::Foreign(def_id) => Some(SimplifiedType::Foreign(def_id)), + ty::Error(_) => Some(SimplifiedType::Error), + ty::Bound(..) | ty::Infer(_) => None, + } +} + +impl SimplifiedType { + pub fn def(self) -> Option { + match self { + SimplifiedType::Adt(d) + | SimplifiedType::Foreign(d) + | SimplifiedType::Trait(d) + | SimplifiedType::Closure(d) + | SimplifiedType::Coroutine(d) + | SimplifiedType::CoroutineWitness(d) => Some(d), + _ => None, + } + } +} + +/// Given generic arguments from an obligation and an impl, +/// could these two be unified after replacing parameters in the +/// the impl with inference variables. +/// +/// For obligations, parameters won't be replaced by inference +/// variables and only unify with themselves. We treat them +/// the same way we treat placeholders. +/// +/// We also use this function during coherence. For coherence the +/// impls only have to overlap for some value, so we treat parameters +/// on both sides like inference variables. This behavior is toggled +/// using the `treat_obligation_params` field. +#[derive(Debug, Clone, Copy)] +pub struct DeepRejectCtxt { + treat_obligation_params: TreatParams, + _interner: PhantomData, +} + +impl DeepRejectCtxt { + pub fn new(_interner: I, treat_obligation_params: TreatParams) -> Self { + DeepRejectCtxt { treat_obligation_params, _interner: PhantomData } + } + + pub fn args_may_unify( + self, + obligation_args: I::GenericArgs, + impl_args: I::GenericArgs, + ) -> bool { + iter::zip(obligation_args.iter(), impl_args.iter()).all(|(obl, imp)| { + match (obl.kind(), imp.kind()) { + // We don't fast reject based on regions. + (ty::GenericArgKind::Lifetime(_), ty::GenericArgKind::Lifetime(_)) => true, + (ty::GenericArgKind::Type(obl), ty::GenericArgKind::Type(imp)) => { + self.types_may_unify(obl, imp) + } + (ty::GenericArgKind::Const(obl), ty::GenericArgKind::Const(imp)) => { + self.consts_may_unify(obl, imp) + } + _ => panic!("kind mismatch: {obl:?} {imp:?}"), + } + }) + } + + pub fn types_may_unify(self, obligation_ty: I::Ty, impl_ty: I::Ty) -> bool { + match impl_ty.kind() { + // Start by checking whether the type in the impl may unify with + // pretty much everything. Just return `true` in that case. + ty::Param(_) | ty::Error(_) | ty::Alias(..) => return true, + // These types only unify with inference variables or their own + // variant. + ty::Bool + | ty::Char + | ty::Int(_) + | ty::Uint(_) + | ty::Float(_) + | ty::Adt(..) + | ty::Str + | ty::Array(..) + | ty::Slice(..) + | ty::RawPtr(..) + | ty::Dynamic(..) + | ty::Pat(..) + | ty::Ref(..) + | ty::Never + | ty::Tuple(..) + | ty::FnPtr(..) + | ty::Foreign(..) => debug_assert!(impl_ty.is_known_rigid()), + ty::FnDef(..) + | ty::Closure(..) + | ty::CoroutineClosure(..) + | ty::Coroutine(..) + | ty::CoroutineWitness(..) + | ty::Placeholder(..) + | ty::Bound(..) + | ty::Infer(_) => panic!("unexpected impl_ty: {impl_ty:?}"), + } + + let k = impl_ty.kind(); + match obligation_ty.kind() { + // Purely rigid types, use structural equivalence. + ty::Bool + | ty::Char + | ty::Int(_) + | ty::Uint(_) + | ty::Float(_) + | ty::Str + | ty::Never + | ty::Foreign(_) => obligation_ty == impl_ty, + ty::Ref(_, obl_ty, obl_mutbl) => match k { + ty::Ref(_, impl_ty, impl_mutbl) => { + obl_mutbl == impl_mutbl && self.types_may_unify(obl_ty, impl_ty) + } + _ => false, + }, + ty::Adt(obl_def, obl_args) => match k { + ty::Adt(impl_def, impl_args) => { + obl_def == impl_def && self.args_may_unify(obl_args, impl_args) + } + _ => false, + }, + ty::Pat(obl_ty, _) => { + // FIXME(pattern_types): take pattern into account + matches!(k, ty::Pat(impl_ty, _) if self.types_may_unify(obl_ty, impl_ty)) + } + ty::Slice(obl_ty) => { + matches!(k, ty::Slice(impl_ty) if self.types_may_unify(obl_ty, impl_ty)) + } + ty::Array(obl_ty, obl_len) => match k { + ty::Array(impl_ty, impl_len) => { + self.types_may_unify(obl_ty, impl_ty) + && self.consts_may_unify(obl_len, impl_len) + } + _ => false, + }, + ty::Tuple(obl) => match k { + ty::Tuple(imp) => { + obl.len() == imp.len() + && iter::zip(obl.iter(), imp.iter()) + .all(|(obl, imp)| self.types_may_unify(obl, imp)) + } + _ => false, + }, + ty::RawPtr(obl_ty, obl_mutbl) => match k { + ty::RawPtr(imp_ty, imp_mutbl) => { + obl_mutbl == imp_mutbl && self.types_may_unify(obl_ty, imp_ty) + } + _ => false, + }, + ty::Dynamic(obl_preds, ..) => { + // Ideally we would walk the existential predicates here or at least + // compare their length. But considering that the relevant `Relate` impl + // actually sorts and deduplicates these, that doesn't work. + matches!(k, ty::Dynamic(impl_preds, ..) if + obl_preds.principal_def_id() == impl_preds.principal_def_id() + ) + } + ty::FnPtr(obl_sig) => match k { + ty::FnPtr(impl_sig) => { + let ty::FnSig { inputs_and_output, c_variadic, safety, abi } = + obl_sig.skip_binder(); + let impl_sig = impl_sig.skip_binder(); + + abi == impl_sig.abi + && c_variadic == impl_sig.c_variadic + && safety == impl_sig.safety + && inputs_and_output.len() == impl_sig.inputs_and_output.len() + && iter::zip(inputs_and_output.iter(), impl_sig.inputs_and_output.iter()) + .all(|(obl, imp)| self.types_may_unify(obl, imp)) + } + _ => false, + }, + + // Impls cannot contain these types as these cannot be named directly. + ty::FnDef(..) | ty::Closure(..) | ty::CoroutineClosure(..) | ty::Coroutine(..) => false, + + // Placeholder types don't unify with anything on their own + ty::Placeholder(..) | ty::Bound(..) => false, + + // Depending on the value of `treat_obligation_params`, we either + // treat generic parameters like placeholders or like inference variables. + ty::Param(_) => match self.treat_obligation_params { + TreatParams::ForLookup => false, + TreatParams::AsCandidateKey => true, + }, + + ty::Infer(ty::IntVar(_)) => impl_ty.is_integral(), + + ty::Infer(ty::FloatVar(_)) => impl_ty.is_floating_point(), + + ty::Infer(_) => true, + + // As we're walking the whole type, it may encounter projections + // inside of binders and what not, so we're just going to assume that + // projections can unify with other stuff. + // + // Looking forward to lazy normalization this is the safer strategy anyways. + ty::Alias(..) => true, + + ty::Error(_) => true, + + ty::CoroutineWitness(..) => { + panic!("unexpected obligation type: {:?}", obligation_ty) + } + } + } + + pub fn consts_may_unify(self, obligation_ct: I::Const, impl_ct: I::Const) -> bool { + let impl_val = match impl_ct.kind() { + ty::ConstKind::Expr(_) + | ty::ConstKind::Param(_) + | ty::ConstKind::Unevaluated(_) + | ty::ConstKind::Error(_) => { + return true; + } + ty::ConstKind::Value(_, impl_val) => impl_val, + ty::ConstKind::Infer(_) | ty::ConstKind::Bound(..) | ty::ConstKind::Placeholder(_) => { + panic!("unexpected impl arg: {:?}", impl_ct) + } + }; + + match obligation_ct.kind() { + ty::ConstKind::Param(_) => match self.treat_obligation_params { + TreatParams::ForLookup => false, + TreatParams::AsCandidateKey => true, + }, + + // Placeholder consts don't unify with anything on their own + ty::ConstKind::Placeholder(_) => false, + + // As we don't necessarily eagerly evaluate constants, + // they might unify with any value. + ty::ConstKind::Expr(_) | ty::ConstKind::Unevaluated(_) | ty::ConstKind::Error(_) => { + true + } + ty::ConstKind::Value(_, obl_val) => obl_val == impl_val, + + ty::ConstKind::Infer(_) => true, + + ty::ConstKind::Bound(..) => { + panic!("unexpected obl const: {:?}", obligation_ct) + } + } + } +} diff --git a/compiler/rustc_type_ir/src/inherent.rs b/compiler/rustc_type_ir/src/inherent.rs index a4e1a97d50587..ffe16964ae515 100644 --- a/compiler/rustc_type_ir/src/inherent.rs +++ b/compiler/rustc_type_ir/src/inherent.rs @@ -120,6 +120,14 @@ pub trait Ty>: matches!(self.kind(), ty::Infer(ty::TyVar(_))) } + fn is_floating_point(self) -> bool { + matches!(self.kind(), ty::Float(_) | ty::Infer(ty::FloatVar(_))) + } + + fn is_integral(self) -> bool { + matches!(self.kind(), ty::Infer(ty::IntVar(_)) | ty::Int(_) | ty::Uint(_)) + } + fn is_fn_ptr(self) -> bool { matches!(self.kind(), ty::FnPtr(_)) } diff --git a/compiler/rustc_type_ir/src/interner.rs b/compiler/rustc_type_ir/src/interner.rs index 6665158c7cd34..eaa3ab7ce4383 100644 --- a/compiler/rustc_type_ir/src/interner.rs +++ b/compiler/rustc_type_ir/src/interner.rs @@ -222,13 +222,6 @@ pub trait Interner: fn associated_type_def_ids(self, def_id: Self::DefId) -> impl IntoIterator; - // FIXME: move `fast_reject` into `rustc_type_ir`. - fn args_may_unify_deep( - self, - obligation_args: Self::GenericArgs, - impl_args: Self::GenericArgs, - ) -> bool; - fn for_each_relevant_impl( self, trait_def_id: Self::DefId, diff --git a/compiler/rustc_type_ir/src/lib.rs b/compiler/rustc_type_ir/src/lib.rs index 9b8ca5efdda82..960ebf78cfe9d 100644 --- a/compiler/rustc_type_ir/src/lib.rs +++ b/compiler/rustc_type_ir/src/lib.rs @@ -21,6 +21,7 @@ pub mod visit; pub mod codec; pub mod data_structures; pub mod error; +pub mod fast_reject; pub mod fold; pub mod inherent; pub mod ir_print; diff --git a/src/librustdoc/html/render/write_shared.rs b/src/librustdoc/html/render/write_shared.rs index c806bf1cc66f3..8fd56eae37ffc 100644 --- a/src/librustdoc/html/render/write_shared.rs +++ b/src/librustdoc/html/render/write_shared.rs @@ -507,8 +507,7 @@ else if (window.initSearch) window.initSearch(searchIndex); // Be aware of `tests/rustdoc/type-alias/deeply-nested-112515.rs` which might regress. let Some(impl_did) = impl_item_id.as_def_id() else { continue }; let for_ty = self.cx.tcx().type_of(impl_did).skip_binder(); - let reject_cx = - DeepRejectCtxt { treat_obligation_params: TreatParams::AsCandidateKey }; + let reject_cx = DeepRejectCtxt::new(self.cx.tcx(), TreatParams::AsCandidateKey); if !reject_cx.types_may_unify(aliased_ty, for_ty) { continue; } From 03fce3648db08c8fdc726408930c276fec5af124 Mon Sep 17 00:00:00 2001 From: WANG Xuerui Date: Sun, 30 Jun 2024 14:55:36 +0800 Subject: [PATCH 485/892] Fix x86_64 code being produced for bare-metal LoongArch targets' `compiler_builtins` Formerly the `loongarch*-*-none*` targets were added to the `dist-various-2` CI job, but no corresponding toolchain was added along with them. This meant the `compiler_builtins` for the targets were built with the host toolchain. As the other `dist-various` toolchains are mostly pre-built so far, to avoid burdening them with crosstool-ng builds, simply move the two bare-metal LoongArch targets to the `dist-loongarch64-linux` job which has a ready-to-use LoongArch toolchain. With the proper CFLAGS applied it is possible to build artifacts suitable for bare-metal. I verified that the `compiler_builtins` objects are now correctly produced regarding architecture and ABI, with the changes here applied. Fixes #125908. cc @heiher try-job: dist-loongarch64-linux try-job: dist-various-2 --- .../dist-loongarch64-linux/Dockerfile | 20 ++++++++++++++++++- .../host-x86_64/dist-various-2/Dockerfile | 2 -- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/src/ci/docker/host-x86_64/dist-loongarch64-linux/Dockerfile b/src/ci/docker/host-x86_64/dist-loongarch64-linux/Dockerfile index 7e35f781b6bb8..d395665166365 100644 --- a/src/ci/docker/host-x86_64/dist-loongarch64-linux/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-loongarch64-linux/Dockerfile @@ -23,7 +23,25 @@ ENV CC_loongarch64_unknown_linux_gnu=loongarch64-unknown-linux-gnu-gcc \ AR_loongarch64_unknown_linux_gnu=loongarch64-unknown-linux-gnu-ar \ CXX_loongarch64_unknown_linux_gnu=loongarch64-unknown-linux-gnu-g++ +# We re-use the Linux toolchain for bare-metal, because upstream bare-metal +# target support for LoongArch is only available from GCC 14+. +# +# See: https://github.com/gcc-mirror/gcc/commit/976f4f9e4770 +ENV CC_loongarch64_unknown_none=loongarch64-unknown-linux-gnu-gcc \ + AR_loongarch64_unknown_none=loongarch64-unknown-linux-gnu-ar \ + CXX_loongarch64_unknown_none=loongarch64-unknown-linux-gnu-g++ \ + CFLAGS_loongarch64_unknown_none="-ffreestanding -mabi=lp64d" \ + CXXFLAGS_loongarch64_unknown_none="-ffreestanding -mabi=lp64d" \ + CC_loongarch64_unknown_none_softfloat=loongarch64-unknown-linux-gnu-gcc \ + AR_loongarch64_unknown_none_softfloat=loongarch64-unknown-linux-gnu-ar \ + CXX_loongarch64_unknown_none_softfloat=loongarch64-unknown-linux-gnu-g++ \ + CFLAGS_loongarch64_unknown_none_softfloat="-ffreestanding -mabi=lp64s -mfpu=none" \ + CXXFLAGS_loongarch64_unknown_none_softfloat="-ffreestanding -mabi=lp64s -mfpu=none" + ENV HOSTS=loongarch64-unknown-linux-gnu +ENV TARGETS=$HOSTS +ENV TARGETS=$TARGETS,loongarch64-unknown-none +ENV TARGETS=$TARGETS,loongarch64-unknown-none-softfloat ENV RUST_CONFIGURE_ARGS \ --enable-extended \ @@ -31,4 +49,4 @@ ENV RUST_CONFIGURE_ARGS \ --enable-profiler \ --disable-docs -ENV SCRIPT python3 ../x.py dist --host $HOSTS --target $HOSTS +ENV SCRIPT python3 ../x.py dist --host $HOSTS --target $TARGETS diff --git a/src/ci/docker/host-x86_64/dist-various-2/Dockerfile b/src/ci/docker/host-x86_64/dist-various-2/Dockerfile index bb6254942cbab..e3cb396b78297 100644 --- a/src/ci/docker/host-x86_64/dist-various-2/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-various-2/Dockerfile @@ -121,8 +121,6 @@ ENV TARGETS=$TARGETS,armv7-unknown-linux-gnueabi ENV TARGETS=$TARGETS,armv7-unknown-linux-musleabi ENV TARGETS=$TARGETS,i686-unknown-freebsd ENV TARGETS=$TARGETS,x86_64-unknown-none -ENV TARGETS=$TARGETS,loongarch64-unknown-none -ENV TARGETS=$TARGETS,loongarch64-unknown-none-softfloat ENV TARGETS=$TARGETS,aarch64-unknown-uefi ENV TARGETS=$TARGETS,i686-unknown-uefi ENV TARGETS=$TARGETS,x86_64-unknown-uefi From 617de8cfb59252a501fc7e0ab7c2510dd8a8a7f4 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Sun, 30 Jun 2024 17:36:16 +1000 Subject: [PATCH 486/892] coverage: Move span unexpansion into its own submodule --- .../src/coverage/mappings.rs | 5 +- .../rustc_mir_transform/src/coverage/mod.rs | 1 + .../rustc_mir_transform/src/coverage/spans.rs | 5 -- .../src/coverage/spans/from_mir.rs | 56 +------------------ .../src/coverage/unexpand.rs | 54 ++++++++++++++++++ 5 files changed, 59 insertions(+), 62 deletions(-) create mode 100644 compiler/rustc_mir_transform/src/coverage/unexpand.rs diff --git a/compiler/rustc_mir_transform/src/coverage/mappings.rs b/compiler/rustc_mir_transform/src/coverage/mappings.rs index 759bb7c1f9d96..e003de4e1fd71 100644 --- a/compiler/rustc_mir_transform/src/coverage/mappings.rs +++ b/compiler/rustc_mir_transform/src/coverage/mappings.rs @@ -9,9 +9,8 @@ use rustc_middle::ty::TyCtxt; use rustc_span::Span; use crate::coverage::graph::{BasicCoverageBlock, CoverageGraph, START_BCB}; -use crate::coverage::spans::{ - extract_refined_covspans, unexpand_into_body_span_with_visible_macro, -}; +use crate::coverage::spans::extract_refined_covspans; +use crate::coverage::unexpand::unexpand_into_body_span_with_visible_macro; use crate::coverage::ExtractedHirInfo; /// Associates an ordinary executable code span with its corresponding BCB. diff --git a/compiler/rustc_mir_transform/src/coverage/mod.rs b/compiler/rustc_mir_transform/src/coverage/mod.rs index 4a64d21f3d17b..d55bde311c17e 100644 --- a/compiler/rustc_mir_transform/src/coverage/mod.rs +++ b/compiler/rustc_mir_transform/src/coverage/mod.rs @@ -6,6 +6,7 @@ mod mappings; mod spans; #[cfg(test)] mod tests; +mod unexpand; use rustc_middle::mir::coverage::{ CodeRegion, CoverageKind, DecisionInfo, FunctionCoverageInfo, Mapping, MappingKind, diff --git a/compiler/rustc_mir_transform/src/coverage/spans.rs b/compiler/rustc_mir_transform/src/coverage/spans.rs index 84a70d1f02d75..7612c01c52ec4 100644 --- a/compiler/rustc_mir_transform/src/coverage/spans.rs +++ b/compiler/rustc_mir_transform/src/coverage/spans.rs @@ -14,11 +14,6 @@ use crate::coverage::ExtractedHirInfo; mod from_mir; -// FIXME(#124545) It's awkward that we have to re-export this, because it's an -// internal detail of `from_mir` that is also needed when handling branch and -// MC/DC spans. Ideally we would find a more natural home for it. -pub(super) use from_mir::unexpand_into_body_span_with_visible_macro; - pub(super) fn extract_refined_covspans( mir_body: &mir::Body<'_>, hir_info: &ExtractedHirInfo, diff --git a/compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs b/compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs index 09deb7534bfde..2ca166929eec8 100644 --- a/compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs +++ b/compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs @@ -4,12 +4,13 @@ use rustc_middle::mir::{ self, AggregateKind, FakeReadCause, Rvalue, Statement, StatementKind, Terminator, TerminatorKind, }; -use rustc_span::{ExpnKind, MacroKind, Span, Symbol}; +use rustc_span::{Span, Symbol}; use crate::coverage::graph::{ BasicCoverageBlock, BasicCoverageBlockData, CoverageGraph, START_BCB, }; use crate::coverage::spans::Covspan; +use crate::coverage::unexpand::unexpand_into_body_span_with_visible_macro; use crate::coverage::ExtractedHirInfo; pub(crate) struct ExtractedCovspans { @@ -215,59 +216,6 @@ fn filtered_terminator_span(terminator: &Terminator<'_>) -> Option { } } -/// Returns an extrapolated span (pre-expansion[^1]) corresponding to a range -/// within the function's body source. This span is guaranteed to be contained -/// within, or equal to, the `body_span`. If the extrapolated span is not -/// contained within the `body_span`, `None` is returned. -/// -/// [^1]Expansions result from Rust syntax including macros, syntactic sugar, -/// etc.). -pub(crate) fn unexpand_into_body_span_with_visible_macro( - original_span: Span, - body_span: Span, -) -> Option<(Span, Option)> { - let (span, prev) = unexpand_into_body_span_with_prev(original_span, body_span)?; - - let visible_macro = prev - .map(|prev| match prev.ctxt().outer_expn_data().kind { - ExpnKind::Macro(MacroKind::Bang, name) => Some(name), - _ => None, - }) - .flatten(); - - Some((span, visible_macro)) -} - -/// Walks through the expansion ancestors of `original_span` to find a span that -/// is contained in `body_span` and has the same [`SyntaxContext`] as `body_span`. -/// The ancestor that was traversed just before the matching span (if any) is -/// also returned. -/// -/// For example, a return value of `Some((ancestor, Some(prev))` means that: -/// - `ancestor == original_span.find_ancestor_inside_same_ctxt(body_span)` -/// - `ancestor == prev.parent_callsite()` -/// -/// [`SyntaxContext`]: rustc_span::SyntaxContext -fn unexpand_into_body_span_with_prev( - original_span: Span, - body_span: Span, -) -> Option<(Span, Option)> { - let mut prev = None; - let mut curr = original_span; - - while !body_span.contains(curr) || !curr.eq_ctxt(body_span) { - prev = Some(curr); - curr = curr.parent_callsite()?; - } - - debug_assert_eq!(Some(curr), original_span.find_ancestor_in_same_ctxt(body_span)); - if let Some(prev) = prev { - debug_assert_eq!(Some(curr), prev.parent_callsite()); - } - - Some((curr, prev)) -} - #[derive(Debug)] pub(crate) struct Hole { pub(crate) span: Span, diff --git a/compiler/rustc_mir_transform/src/coverage/unexpand.rs b/compiler/rustc_mir_transform/src/coverage/unexpand.rs new file mode 100644 index 0000000000000..18532b8ee4581 --- /dev/null +++ b/compiler/rustc_mir_transform/src/coverage/unexpand.rs @@ -0,0 +1,54 @@ +use rustc_span::{ExpnKind, MacroKind, Span, Symbol}; + +/// Returns an extrapolated span (pre-expansion[^1]) corresponding to a range +/// within the function's body source. This span is guaranteed to be contained +/// within, or equal to, the `body_span`. If the extrapolated span is not +/// contained within the `body_span`, `None` is returned. +/// +/// [^1]Expansions result from Rust syntax including macros, syntactic sugar, +/// etc.). +pub(crate) fn unexpand_into_body_span_with_visible_macro( + original_span: Span, + body_span: Span, +) -> Option<(Span, Option)> { + let (span, prev) = unexpand_into_body_span_with_prev(original_span, body_span)?; + + let visible_macro = prev + .map(|prev| match prev.ctxt().outer_expn_data().kind { + ExpnKind::Macro(MacroKind::Bang, name) => Some(name), + _ => None, + }) + .flatten(); + + Some((span, visible_macro)) +} + +/// Walks through the expansion ancestors of `original_span` to find a span that +/// is contained in `body_span` and has the same [`SyntaxContext`] as `body_span`. +/// The ancestor that was traversed just before the matching span (if any) is +/// also returned. +/// +/// For example, a return value of `Some((ancestor, Some(prev))` means that: +/// - `ancestor == original_span.find_ancestor_inside_same_ctxt(body_span)` +/// - `ancestor == prev.parent_callsite()` +/// +/// [`SyntaxContext`]: rustc_span::SyntaxContext +fn unexpand_into_body_span_with_prev( + original_span: Span, + body_span: Span, +) -> Option<(Span, Option)> { + let mut prev = None; + let mut curr = original_span; + + while !body_span.contains(curr) || !curr.eq_ctxt(body_span) { + prev = Some(curr); + curr = curr.parent_callsite()?; + } + + debug_assert_eq!(Some(curr), original_span.find_ancestor_in_same_ctxt(body_span)); + if let Some(prev) = prev { + debug_assert_eq!(Some(curr), prev.parent_callsite()); + } + + Some((curr, prev)) +} From 3d6cc605356f0919ae0bd024aba6cec5a9981ea7 Mon Sep 17 00:00:00 2001 From: Chris Denton Date: Sun, 30 Jun 2024 08:21:20 +0000 Subject: [PATCH 487/892] Try renaming the file if removing fails --- src/bootstrap/src/lib.rs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs index 730d0ae5f3d7c..6d00ff9982d96 100644 --- a/src/bootstrap/src/lib.rs +++ b/src/bootstrap/src/lib.rs @@ -26,6 +26,7 @@ use std::path::{Path, PathBuf}; use std::process::{Command, Stdio}; use std::str; use std::sync::OnceLock; +use std::time::SystemTime; use build_helper::ci::{gha, CiEnv}; use build_helper::exit; @@ -1676,7 +1677,14 @@ impl Build { if src == dst { return; } - let _ = fs::remove_file(dst); + if let Err(e) = fs::remove_file(dst) { + if e.kind() != io::ErrorKind::NotFound { + // workaround for https://github.com/rust-lang/rust/issues/127126 + // if removing the file fails, attempt to rename it instead. + let now = t!(SystemTime::now().duration_since(SystemTime::UNIX_EPOCH)); + let _ = fs::rename(dst, format!("{}-{}", dst.display(), now.as_nanos())); + } + } let metadata = t!(src.symlink_metadata(), format!("src = {}", src.display())); let mut src = src.to_path_buf(); if metadata.file_type().is_symlink() { From ad575b093bee669258b1d4914bccf56c5b9d1e82 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Wed, 26 Jun 2024 11:34:31 +1000 Subject: [PATCH 488/892] Replace a magic boolean with enum `DeclareLetBindings` The new enum `DeclareLetBindings` has three variants: - `Yes`: Declare `let` bindings as normal, for `if` conditions. - `No`: Don't declare bindings, for match guards and let-else. - `LetNotPermitted`: Assert that `let` expressions should not occur. --- compiler/rustc_mir_build/src/build/block.rs | 3 +- .../rustc_mir_build/src/build/expr/into.rs | 5 +- .../rustc_mir_build/src/build/matches/mod.rs | 73 +++++++++++++++---- 3 files changed, 64 insertions(+), 17 deletions(-) diff --git a/compiler/rustc_mir_build/src/build/block.rs b/compiler/rustc_mir_build/src/build/block.rs index 476969a1bd7ad..4616018c3c690 100644 --- a/compiler/rustc_mir_build/src/build/block.rs +++ b/compiler/rustc_mir_build/src/build/block.rs @@ -1,3 +1,4 @@ +use crate::build::matches::DeclareLetBindings; use crate::build::ForGuard::OutsideGuard; use crate::build::{BlockAnd, BlockAndExtension, BlockFrame, Builder}; use rustc_middle::middle::region::Scope; @@ -213,7 +214,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { pattern, None, initializer_span, - false, + DeclareLetBindings::No, true, ) }); diff --git a/compiler/rustc_mir_build/src/build/expr/into.rs b/compiler/rustc_mir_build/src/build/expr/into.rs index 76bdc26a501a6..942c69b5c0a75 100644 --- a/compiler/rustc_mir_build/src/build/expr/into.rs +++ b/compiler/rustc_mir_build/src/build/expr/into.rs @@ -1,6 +1,7 @@ //! See docs in build/expr/mod.rs use crate::build::expr::category::{Category, RvalueFunc}; +use crate::build::matches::DeclareLetBindings; use crate::build::{BlockAnd, BlockAndExtension, BlockFrame, Builder, NeedsTemporary}; use rustc_ast::InlineAsmOptions; use rustc_data_structures::fx::FxHashMap; @@ -86,7 +87,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { cond, Some(condition_scope), // Temp scope source_info, - true, // Declare `let` bindings normally + DeclareLetBindings::Yes, // Declare `let` bindings normally )); // Lower the `then` arm into its block. @@ -163,7 +164,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { source_info, // This flag controls how inner `let` expressions are lowered, // but either way there shouldn't be any of those in here. - true, + DeclareLetBindings::LetNotPermitted, ) }); let (short_circuit, continuation, constant) = match op { diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs index 6d52c30823769..71c065b3574c7 100644 --- a/compiler/rustc_mir_build/src/build/matches/mod.rs +++ b/compiler/rustc_mir_build/src/build/matches/mod.rs @@ -39,9 +39,27 @@ struct ThenElseArgs { /// `self.local_scope()` is used. temp_scope_override: Option, variable_source_info: SourceInfo, + /// Determines how bindings should be handled when lowering `let` expressions. + /// /// Forwarded to [`Builder::lower_let_expr`] when lowering [`ExprKind::Let`]. - /// When false (for match guards), `let` bindings won't be declared. - declare_let_bindings: bool, + declare_let_bindings: DeclareLetBindings, +} + +/// Should lowering a `let` expression also declare its bindings? +/// +/// Used by [`Builder::lower_let_expr`] when lowering [`ExprKind::Let`]. +#[derive(Clone, Copy)] +pub(crate) enum DeclareLetBindings { + /// Yes, declare `let` bindings as normal for `if` conditions. + Yes, + /// No, don't declare `let` bindings, because the caller declares them + /// separately due to special requirements. + /// + /// Used for match guards and let-else. + No, + /// Let expressions are not permitted in this context, so it is a bug to + /// try to lower one (e.g inside lazy-boolean-or or boolean-not). + LetNotPermitted, } impl<'a, 'tcx> Builder<'a, 'tcx> { @@ -57,7 +75,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { expr_id: ExprId, temp_scope_override: Option, variable_source_info: SourceInfo, - declare_let_bindings: bool, + declare_let_bindings: DeclareLetBindings, ) -> BlockAnd<()> { self.then_else_break_inner( block, @@ -91,13 +109,19 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { this.then_else_break_inner( block, lhs, - ThenElseArgs { declare_let_bindings: true, ..args }, + ThenElseArgs { + declare_let_bindings: DeclareLetBindings::LetNotPermitted, + ..args + }, ) }); let rhs_success_block = unpack!(this.then_else_break_inner( failure_block, rhs, - ThenElseArgs { declare_let_bindings: true, ..args }, + ThenElseArgs { + declare_let_bindings: DeclareLetBindings::LetNotPermitted, + ..args + }, )); // Make the LHS and RHS success arms converge to a common block. @@ -127,7 +151,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { this.then_else_break_inner( block, arg, - ThenElseArgs { declare_let_bindings: true, ..args }, + ThenElseArgs { + declare_let_bindings: DeclareLetBindings::LetNotPermitted, + ..args + }, ) }); this.break_for_else(success_block, args.variable_source_info); @@ -1991,8 +2018,14 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // Pat binding - used for `let` and function parameters as well. impl<'a, 'tcx> Builder<'a, 'tcx> { - /// If the bindings have already been declared, set `declare_bindings` to - /// `false` to avoid duplicated bindings declaration; used for if-let guards. + /// Lowers a `let` expression that appears in a suitable context + /// (e.g. an `if` condition or match guard). + /// + /// Also used for lowering let-else statements, since they have similar + /// needs despite not actually using `let` expressions. + /// + /// Use [`DeclareLetBindings`] to control whether the `let` bindings are + /// declared or not. pub(crate) fn lower_let_expr( &mut self, mut block: BasicBlock, @@ -2000,7 +2033,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { pat: &Pat<'tcx>, source_scope: Option, scope_span: Span, - declare_bindings: bool, + declare_let_bindings: DeclareLetBindings, storages_alive: bool, ) -> BlockAnd<()> { let expr_span = self.thir[expr_id].span; @@ -2017,10 +2050,22 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { self.break_for_else(otherwise_block, self.source_info(expr_span)); - if declare_bindings { - let expr_place = scrutinee.try_to_place(self); - let opt_expr_place = expr_place.as_ref().map(|place| (Some(place), expr_span)); - self.declare_bindings(source_scope, pat.span.to(scope_span), pat, None, opt_expr_place); + match declare_let_bindings { + DeclareLetBindings::Yes => { + let expr_place = scrutinee.try_to_place(self); + let opt_expr_place = expr_place.as_ref().map(|place| (Some(place), expr_span)); + self.declare_bindings( + source_scope, + pat.span.to(scope_span), + pat, + None, + opt_expr_place, + ); + } + DeclareLetBindings::No => {} // Caller is responsible for bindings. + DeclareLetBindings::LetNotPermitted => { + self.tcx.dcx().span_bug(expr_span, "let expression not expected in this context") + } } let success = self.bind_pattern( @@ -2203,7 +2248,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { guard, None, // Use `self.local_scope()` as the temp scope this.source_info(arm.span), - false, // For guards, `let` bindings are declared separately + DeclareLetBindings::No, // For guards, `let` bindings are declared separately ) }); From 3b22589cfa0015535ae08082b2cecf77ac1b5c33 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Wed, 26 Jun 2024 12:40:47 +1000 Subject: [PATCH 489/892] Replace a magic boolean with enum `EmitStorageLive` The previous boolean used `true` to indicate that storage-live should _not_ be emitted, so all occurrences of `Yes` and `No` should be the logical opposite of the previous value. --- compiler/rustc_mir_build/src/build/block.rs | 4 +- .../rustc_mir_build/src/build/matches/mod.rs | 47 ++++++++++++------- 2 files changed, 32 insertions(+), 19 deletions(-) diff --git a/compiler/rustc_mir_build/src/build/block.rs b/compiler/rustc_mir_build/src/build/block.rs index 4616018c3c690..80db30f0ae600 100644 --- a/compiler/rustc_mir_build/src/build/block.rs +++ b/compiler/rustc_mir_build/src/build/block.rs @@ -1,4 +1,4 @@ -use crate::build::matches::DeclareLetBindings; +use crate::build::matches::{DeclareLetBindings, EmitStorageLive}; use crate::build::ForGuard::OutsideGuard; use crate::build::{BlockAnd, BlockAndExtension, BlockFrame, Builder}; use rustc_middle::middle::region::Scope; @@ -215,7 +215,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { None, initializer_span, DeclareLetBindings::No, - true, + EmitStorageLive::No, ) }); matching.and(failure) diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs index 71c065b3574c7..4827d2dbfa85c 100644 --- a/compiler/rustc_mir_build/src/build/matches/mod.rs +++ b/compiler/rustc_mir_build/src/build/matches/mod.rs @@ -62,6 +62,18 @@ pub(crate) enum DeclareLetBindings { LetNotPermitted, } +/// Used by [`Builder::bind_matched_candidate_for_arm_body`] to determine +/// whether or not to call [`Builder::storage_live_binding`] to emit +/// [`StatementKind::StorageLive`]. +#[derive(Clone, Copy)] +pub(crate) enum EmitStorageLive { + /// Yes, emit `StorageLive` as normal. + Yes, + /// No, don't emit `StorageLive`. The caller has taken responsibility for + /// emitting `StorageLive` as appropriate. + No, +} + impl<'a, 'tcx> Builder<'a, 'tcx> { /// Lowers a condition in a way that ensures that variables bound in any let /// expressions are definitely initialized in the if body. @@ -174,7 +186,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { Some(args.variable_source_info.scope), args.variable_source_info.span, args.declare_let_bindings, - false, + EmitStorageLive::Yes, ), _ => { let mut block = block; @@ -467,7 +479,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { &fake_borrow_temps, scrutinee_span, Some((arm, match_scope)), - false, + EmitStorageLive::Yes, ); this.fixed_temps_scope = old_dedup_scope; @@ -512,7 +524,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { fake_borrow_temps: &[(Place<'tcx>, Local, FakeBorrowKind)], scrutinee_span: Span, arm_match_scope: Option<(&Arm<'tcx>, region::Scope)>, - storages_alive: bool, + emit_storage_live: EmitStorageLive, ) -> BasicBlock { if candidate.subcandidates.is_empty() { // Avoid generating another `BasicBlock` when we only have one @@ -524,7 +536,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { scrutinee_span, arm_match_scope, true, - storages_alive, + emit_storage_live, ) } else { // It's helpful to avoid scheduling drops multiple times to save @@ -561,7 +573,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { scrutinee_span, arm_match_scope, schedule_drops, - storages_alive, + emit_storage_live, ); if arm.is_none() { schedule_drops = false; @@ -731,7 +743,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { &[], irrefutable_pat.span, None, - false, + EmitStorageLive::Yes, ) .unit() } @@ -807,6 +819,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } } + /// Emits a [`StatementKind::StorageLive`] for the given var, and also + /// schedules a drop if requested (and possible). pub(crate) fn storage_live_binding( &mut self, block: BasicBlock, @@ -2034,7 +2048,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { source_scope: Option, scope_span: Span, declare_let_bindings: DeclareLetBindings, - storages_alive: bool, + emit_storage_live: EmitStorageLive, ) -> BlockAnd<()> { let expr_span = self.thir[expr_id].span; let scrutinee = unpack!(block = self.lower_scrutinee(block, expr_id, expr_span)); @@ -2074,7 +2088,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { &[], expr_span, None, - storages_alive, + emit_storage_live, ); // If branch coverage is enabled, record this branch. @@ -2099,7 +2113,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { scrutinee_span: Span, arm_match_scope: Option<(&Arm<'tcx>, region::Scope)>, schedule_drops: bool, - storages_alive: bool, + emit_storage_live: EmitStorageLive, ) -> BasicBlock { debug!("bind_and_guard_matched_candidate(candidate={:?})", candidate); @@ -2314,7 +2328,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { post_guard_block, true, by_value_bindings, - storages_alive, + emit_storage_live, ); post_guard_block @@ -2326,7 +2340,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { block, schedule_drops, bindings, - storages_alive, + emit_storage_live, ); block } @@ -2417,7 +2431,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { block: BasicBlock, schedule_drops: bool, bindings: impl IntoIterator>, - storages_alive: bool, + emit_storage_live: EmitStorageLive, ) where 'tcx: 'b, { @@ -2427,19 +2441,18 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // Assign each of the bindings. This may trigger moves out of the candidate. for binding in bindings { let source_info = self.source_info(binding.span); - let local = if storages_alive { + let local = match emit_storage_live { // Here storages are already alive, probably because this is a binding // from let-else. // We just need to schedule drop for the value. - self.var_local_id(binding.var_id, OutsideGuard).into() - } else { - self.storage_live_binding( + EmitStorageLive::No => self.var_local_id(binding.var_id, OutsideGuard).into(), + EmitStorageLive::Yes => self.storage_live_binding( block, binding.var_id, binding.span, OutsideGuard, schedule_drops, - ) + ), }; if schedule_drops { self.schedule_drop_for_binding(binding.var_id, binding.span, OutsideGuard); From ed07712e96506ca827ced41d748550b99318d47f Mon Sep 17 00:00:00 2001 From: Zalathar Date: Wed, 26 Jun 2024 13:44:25 +1000 Subject: [PATCH 490/892] Replace a magic boolean with enum `ScheduleDrops` --- compiler/rustc_mir_build/src/build/block.rs | 18 +++++- .../rustc_mir_build/src/build/matches/mod.rs | 56 ++++++++++++++----- 2 files changed, 56 insertions(+), 18 deletions(-) diff --git a/compiler/rustc_mir_build/src/build/block.rs b/compiler/rustc_mir_build/src/build/block.rs index 80db30f0ae600..5ccbd7c59cfba 100644 --- a/compiler/rustc_mir_build/src/build/block.rs +++ b/compiler/rustc_mir_build/src/build/block.rs @@ -1,4 +1,4 @@ -use crate::build::matches::{DeclareLetBindings, EmitStorageLive}; +use crate::build::matches::{DeclareLetBindings, EmitStorageLive, ScheduleDrops}; use crate::build::ForGuard::OutsideGuard; use crate::build::{BlockAnd, BlockAndExtension, BlockFrame, Builder}; use rustc_middle::middle::region::Scope; @@ -202,7 +202,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { pattern, UserTypeProjections::none(), &mut |this, _, _, node, span, _, _| { - this.storage_live_binding(block, node, span, OutsideGuard, true); + this.storage_live_binding( + block, + node, + span, + OutsideGuard, + ScheduleDrops::Yes, + ); }, ); let else_block_span = this.thir[*else_block].span; @@ -292,7 +298,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { pattern, UserTypeProjections::none(), &mut |this, _, _, node, span, _, _| { - this.storage_live_binding(block, node, span, OutsideGuard, true); + this.storage_live_binding( + block, + node, + span, + OutsideGuard, + ScheduleDrops::Yes, + ); this.schedule_drop_for_binding(node, span, OutsideGuard); }, ) diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs index 4827d2dbfa85c..efed52231e3fa 100644 --- a/compiler/rustc_mir_build/src/build/matches/mod.rs +++ b/compiler/rustc_mir_build/src/build/matches/mod.rs @@ -28,6 +28,7 @@ mod simplify; mod test; mod util; +use std::assert_matches::assert_matches; use std::borrow::Borrow; use std::mem; @@ -74,6 +75,17 @@ pub(crate) enum EmitStorageLive { No, } +/// Used by [`Builder::storage_live_binding`] and [`Builder::bind_matched_candidate_for_arm_body`] +/// to decide whether to schedule drops. +#[derive(Clone, Copy, Debug)] +pub(crate) enum ScheduleDrops { + /// Yes, the relevant functions should also schedule drops as appropriate. + Yes, + /// No, don't schedule drops. The caller has taken responsibility for any + /// appropriate drops. + No, +} + impl<'a, 'tcx> Builder<'a, 'tcx> { /// Lowers a condition in a way that ensures that variables bound in any let /// expressions are definitely initialized in the if body. @@ -535,7 +547,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { fake_borrow_temps, scrutinee_span, arm_match_scope, - true, + ScheduleDrops::Yes, emit_storage_live, ) } else { @@ -554,7 +566,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // To handle this we instead unschedule it's drop after each time // we lower the guard. let target_block = self.cfg.start_new_block(); - let mut schedule_drops = true; + let mut schedule_drops = ScheduleDrops::Yes; let arm = arm_match_scope.unzip().0; // We keep a stack of all of the bindings and type ascriptions // from the parent candidates that we visit, that also need to @@ -576,7 +588,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { emit_storage_live, ); if arm.is_none() { - schedule_drops = false; + schedule_drops = ScheduleDrops::No; } self.cfg.goto(binding_end, outer_source_info, target_block); }, @@ -602,8 +614,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { match irrefutable_pat.kind { // Optimize the case of `let x = ...` to write directly into `x` PatKind::Binding { mode: BindingMode(ByRef::No, _), var, subpattern: None, .. } => { - let place = - self.storage_live_binding(block, var, irrefutable_pat.span, OutsideGuard, true); + let place = self.storage_live_binding( + block, + var, + irrefutable_pat.span, + OutsideGuard, + ScheduleDrops::Yes, + ); unpack!(block = self.expr_into_dest(place, block, initializer_id)); // Inject a fake read, see comments on `FakeReadCause::ForLet`. @@ -636,8 +653,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { }, ascription: thir::Ascription { ref annotation, variance: _ }, } => { - let place = - self.storage_live_binding(block, var, irrefutable_pat.span, OutsideGuard, true); + let place = self.storage_live_binding( + block, + var, + irrefutable_pat.span, + OutsideGuard, + ScheduleDrops::Yes, + ); unpack!(block = self.expr_into_dest(place, block, initializer_id)); // Inject a fake read, see comments on `FakeReadCause::ForLet`. @@ -827,7 +849,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { var: LocalVarId, span: Span, for_guard: ForGuard, - schedule_drop: bool, + schedule_drop: ScheduleDrops, ) -> Place<'tcx> { let local_id = self.var_local_id(var, for_guard); let source_info = self.source_info(span); @@ -835,7 +857,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // Although there is almost always scope for given variable in corner cases // like #92893 we might get variable with no scope. if let Some(region_scope) = self.region_scope_tree.var_scope(var.0.local_id) - && schedule_drop + && matches!(schedule_drop, ScheduleDrops::Yes) { self.schedule_drop(span, region_scope, local_id, DropKind::Storage); } @@ -2112,7 +2134,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { fake_borrows: &[(Place<'tcx>, Local, FakeBorrowKind)], scrutinee_span: Span, arm_match_scope: Option<(&Arm<'tcx>, region::Scope)>, - schedule_drops: bool, + schedule_drops: ScheduleDrops, emit_storage_live: EmitStorageLive, ) -> BasicBlock { debug!("bind_and_guard_matched_candidate(candidate={:?})", candidate); @@ -2323,10 +2345,14 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let cause = FakeReadCause::ForGuardBinding; self.cfg.push_fake_read(post_guard_block, guard_end, cause, Place::from(local_id)); } - assert!(schedule_drops, "patterns with guards must schedule drops"); + assert_matches!( + schedule_drops, + ScheduleDrops::Yes, + "patterns with guards must schedule drops" + ); self.bind_matched_candidate_for_arm_body( post_guard_block, - true, + ScheduleDrops::Yes, by_value_bindings, emit_storage_live, ); @@ -2376,7 +2402,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { fn bind_matched_candidate_for_guard<'b>( &mut self, block: BasicBlock, - schedule_drops: bool, + schedule_drops: ScheduleDrops, bindings: impl IntoIterator>, ) where 'tcx: 'b, @@ -2429,7 +2455,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { fn bind_matched_candidate_for_arm_body<'b>( &mut self, block: BasicBlock, - schedule_drops: bool, + schedule_drops: ScheduleDrops, bindings: impl IntoIterator>, emit_storage_live: EmitStorageLive, ) where @@ -2454,7 +2480,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { schedule_drops, ), }; - if schedule_drops { + if matches!(schedule_drops, ScheduleDrops::Yes) { self.schedule_drop_for_binding(binding.var_id, binding.span, OutsideGuard); } let rvalue = match binding.binding_mode.0 { From 6c3314905574651fa2e004173187bd5d202f0df1 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Sun, 30 Jun 2024 18:20:45 +1000 Subject: [PATCH 491/892] coverage: Avoid getting extra unexpansion info when we don't need it These particular callers don't actually use the returned macro information, so they can use a simpler span-unexpansion function that doesn't return it. --- .../src/coverage/mappings.rs | 9 +++--- .../src/coverage/unexpand.rs | 28 +++++++++++-------- 2 files changed, 21 insertions(+), 16 deletions(-) diff --git a/compiler/rustc_mir_transform/src/coverage/mappings.rs b/compiler/rustc_mir_transform/src/coverage/mappings.rs index e003de4e1fd71..235992ac5470d 100644 --- a/compiler/rustc_mir_transform/src/coverage/mappings.rs +++ b/compiler/rustc_mir_transform/src/coverage/mappings.rs @@ -10,7 +10,7 @@ use rustc_span::Span; use crate::coverage::graph::{BasicCoverageBlock, CoverageGraph, START_BCB}; use crate::coverage::spans::extract_refined_covspans; -use crate::coverage::unexpand::unexpand_into_body_span_with_visible_macro; +use crate::coverage::unexpand::unexpand_into_body_span; use crate::coverage::ExtractedHirInfo; /// Associates an ordinary executable code span with its corresponding BCB. @@ -201,8 +201,7 @@ pub(super) fn extract_branch_pairs( if !raw_span.ctxt().outer_expn_data().is_root() { return None; } - let (span, _) = - unexpand_into_body_span_with_visible_macro(raw_span, hir_info.body_span)?; + let span = unexpand_into_body_span(raw_span, hir_info.body_span)?; let bcb_from_marker = |marker: BlockMarkerId| basic_coverage_blocks.bcb_from_bb(block_markers[marker]?); @@ -237,7 +236,7 @@ pub(super) fn extract_mcdc_mappings( if !raw_span.ctxt().outer_expn_data().is_root() { return None; } - let (span, _) = unexpand_into_body_span_with_visible_macro(raw_span, body_span)?; + let span = unexpand_into_body_span(raw_span, body_span)?; let true_bcb = bcb_from_marker(true_marker)?; let false_bcb = bcb_from_marker(false_marker)?; @@ -260,7 +259,7 @@ pub(super) fn extract_mcdc_mappings( mcdc_decisions.extend(branch_info.mcdc_decision_spans.iter().filter_map( |decision: &mir::coverage::MCDCDecisionSpan| { - let (span, _) = unexpand_into_body_span_with_visible_macro(decision.span, body_span)?; + let span = unexpand_into_body_span(decision.span, body_span)?; let end_bcbs = decision .end_markers diff --git a/compiler/rustc_mir_transform/src/coverage/unexpand.rs b/compiler/rustc_mir_transform/src/coverage/unexpand.rs index 18532b8ee4581..8cde291b9073e 100644 --- a/compiler/rustc_mir_transform/src/coverage/unexpand.rs +++ b/compiler/rustc_mir_transform/src/coverage/unexpand.rs @@ -1,12 +1,18 @@ use rustc_span::{ExpnKind, MacroKind, Span, Symbol}; -/// Returns an extrapolated span (pre-expansion[^1]) corresponding to a range -/// within the function's body source. This span is guaranteed to be contained -/// within, or equal to, the `body_span`. If the extrapolated span is not -/// contained within the `body_span`, `None` is returned. +/// Walks through the expansion ancestors of `original_span` to find a span that +/// is contained in `body_span` and has the same [syntax context] as `body_span`. +pub(crate) fn unexpand_into_body_span(original_span: Span, body_span: Span) -> Option { + // Because we don't need to return any extra ancestor information, + // we can just delegate directly to `find_ancestor_inside_same_ctxt`. + original_span.find_ancestor_inside_same_ctxt(body_span) +} + +/// Walks through the expansion ancestors of `original_span` to find a span that +/// is contained in `body_span` and has the same [syntax context] as `body_span`. /// -/// [^1]Expansions result from Rust syntax including macros, syntactic sugar, -/// etc.). +/// If the returned span represents a bang-macro invocation (e.g. `foo!(..)`), +/// the returned symbol will be the name of that macro (e.g. `foo`). pub(crate) fn unexpand_into_body_span_with_visible_macro( original_span: Span, body_span: Span, @@ -24,15 +30,15 @@ pub(crate) fn unexpand_into_body_span_with_visible_macro( } /// Walks through the expansion ancestors of `original_span` to find a span that -/// is contained in `body_span` and has the same [`SyntaxContext`] as `body_span`. +/// is contained in `body_span` and has the same [syntax context] as `body_span`. /// The ancestor that was traversed just before the matching span (if any) is /// also returned. /// -/// For example, a return value of `Some((ancestor, Some(prev))` means that: +/// For example, a return value of `Some((ancestor, Some(prev)))` means that: /// - `ancestor == original_span.find_ancestor_inside_same_ctxt(body_span)` -/// - `ancestor == prev.parent_callsite()` +/// - `prev.parent_callsite() == ancestor` /// -/// [`SyntaxContext`]: rustc_span::SyntaxContext +/// [syntax context]: rustc_span::SyntaxContext fn unexpand_into_body_span_with_prev( original_span: Span, body_span: Span, @@ -45,7 +51,7 @@ fn unexpand_into_body_span_with_prev( curr = curr.parent_callsite()?; } - debug_assert_eq!(Some(curr), original_span.find_ancestor_in_same_ctxt(body_span)); + debug_assert_eq!(Some(curr), original_span.find_ancestor_inside_same_ctxt(body_span)); if let Some(prev) = prev { debug_assert_eq!(Some(curr), prev.parent_callsite()); } From 4b516f599b15c81a5ab26c0044b9fdf84cf5e3c3 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sun, 30 Jun 2024 12:40:24 +0200 Subject: [PATCH 492/892] Improve `run-make-support` library `args` API --- src/tools/run-make-support/src/lib.rs | 5 +++-- tests/run-make/arguments-non-c-like-enum/rmake.rs | 4 ++-- tests/run-make/c-link-to-rust-staticlib/rmake.rs | 2 +- tests/run-make/c-link-to-rust-va-list-fn/rmake.rs | 2 +- tests/run-make/glibc-staticlib-args/rmake.rs | 4 ++-- tests/run-make/print-check-cfg/rmake.rs | 8 ++------ tests/run-make/return-non-c-like-enum/rmake.rs | 4 ++-- tests/run-make/textrel-on-minimal-lib/rmake.rs | 4 ++-- 8 files changed, 15 insertions(+), 18 deletions(-) diff --git a/src/tools/run-make-support/src/lib.rs b/src/tools/run-make-support/src/lib.rs index 31b913810b665..df417722e024f 100644 --- a/src/tools/run-make-support/src/lib.rs +++ b/src/tools/run-make-support/src/lib.rs @@ -525,11 +525,12 @@ macro_rules! impl_common_helpers { /// Generic command arguments provider. Prefer specific helper methods if possible. /// Note that for some executables, arguments might be platform specific. For C/C++ /// compilers, arguments might be platform *and* compiler specific. - pub fn args(&mut self, args: &[S]) -> &mut Self + pub fn args(&mut self, args: V) -> &mut Self where + V: AsRef<[S]>, S: AsRef<::std::ffi::OsStr>, { - self.cmd.args(args); + self.cmd.args(args.as_ref()); self } diff --git a/tests/run-make/arguments-non-c-like-enum/rmake.rs b/tests/run-make/arguments-non-c-like-enum/rmake.rs index 88f4d664aa626..036691e850931 100644 --- a/tests/run-make/arguments-non-c-like-enum/rmake.rs +++ b/tests/run-make/arguments-non-c-like-enum/rmake.rs @@ -10,8 +10,8 @@ pub fn main() { cc().input("test.c") .input(static_lib_name("nonclike")) .out_exe("test") - .args(&extra_c_flags()) - .args(&extra_cxx_flags()) + .args(extra_c_flags()) + .args(extra_cxx_flags()) .inspect(|cmd| eprintln!("{cmd:?}")) .run(); run("test"); diff --git a/tests/run-make/c-link-to-rust-staticlib/rmake.rs b/tests/run-make/c-link-to-rust-staticlib/rmake.rs index 2edd36b9ec0b7..d60b37524f43c 100644 --- a/tests/run-make/c-link-to-rust-staticlib/rmake.rs +++ b/tests/run-make/c-link-to-rust-staticlib/rmake.rs @@ -9,7 +9,7 @@ use std::fs; fn main() { rustc().input("foo.rs").run(); - cc().input("bar.c").input(static_lib_name("foo")).out_exe("bar").args(&extra_c_flags()).run(); + cc().input("bar.c").input(static_lib_name("foo")).out_exe("bar").args(extra_c_flags()).run(); run("bar"); remove_file(static_lib_name("foo")); run("bar"); diff --git a/tests/run-make/c-link-to-rust-va-list-fn/rmake.rs b/tests/run-make/c-link-to-rust-va-list-fn/rmake.rs index a01e259bce010..63904bea6227b 100644 --- a/tests/run-make/c-link-to-rust-va-list-fn/rmake.rs +++ b/tests/run-make/c-link-to-rust-va-list-fn/rmake.rs @@ -12,7 +12,7 @@ fn main() { cc().input("test.c") .input(static_lib_name("checkrust")) .out_exe("test") - .args(&extra_c_flags()) + .args(extra_c_flags()) .run(); run("test"); } diff --git a/tests/run-make/glibc-staticlib-args/rmake.rs b/tests/run-make/glibc-staticlib-args/rmake.rs index 8ab10419ab9d3..fc13be538123b 100644 --- a/tests/run-make/glibc-staticlib-args/rmake.rs +++ b/tests/run-make/glibc-staticlib-args/rmake.rs @@ -11,8 +11,8 @@ fn main() { cc().input("program.c") .arg(static_lib_name("library")) .out_exe("program") - .args(&extra_c_flags()) - .args(&extra_cxx_flags()) + .args(extra_c_flags()) + .args(extra_cxx_flags()) .run(); run(&bin_name("program")); } diff --git a/tests/run-make/print-check-cfg/rmake.rs b/tests/run-make/print-check-cfg/rmake.rs index f4b02b5e265be..4a79910c8e05e 100644 --- a/tests/run-make/print-check-cfg/rmake.rs +++ b/tests/run-make/print-check-cfg/rmake.rs @@ -86,12 +86,8 @@ fn main() { } fn check(CheckCfg { args, contains }: CheckCfg) { - let output = rustc() - .input("lib.rs") - .arg("-Zunstable-options") - .arg("--print=check-cfg") - .args(&*args) - .run(); + let output = + rustc().input("lib.rs").arg("-Zunstable-options").arg("--print=check-cfg").args(args).run(); let stdout = output.stdout_utf8(); diff --git a/tests/run-make/return-non-c-like-enum/rmake.rs b/tests/run-make/return-non-c-like-enum/rmake.rs index e698790b43c06..ecdfbd8889941 100644 --- a/tests/run-make/return-non-c-like-enum/rmake.rs +++ b/tests/run-make/return-non-c-like-enum/rmake.rs @@ -11,8 +11,8 @@ fn main() { cc().input("test.c") .arg(&static_lib_name("nonclike")) .out_exe("test") - .args(&extra_c_flags()) - .args(&extra_cxx_flags()) + .args(extra_c_flags()) + .args(extra_cxx_flags()) .run(); run("test"); } diff --git a/tests/run-make/textrel-on-minimal-lib/rmake.rs b/tests/run-make/textrel-on-minimal-lib/rmake.rs index eba664479f112..625ded70ad624 100644 --- a/tests/run-make/textrel-on-minimal-lib/rmake.rs +++ b/tests/run-make/textrel-on-minimal-lib/rmake.rs @@ -20,8 +20,8 @@ fn main() { .out_exe(&dynamic_lib_name("bar")) .arg("-fPIC") .arg("-shared") - .args(&extra_c_flags()) - .args(&extra_cxx_flags()) + .args(extra_c_flags()) + .args(extra_cxx_flags()) .run(); llvm_readobj() .input(dynamic_lib_name("bar")) From 8a0e1ab565346491f932612508e57c225ddbb34c Mon Sep 17 00:00:00 2001 From: Michael Baikov Date: Sun, 30 Jun 2024 07:12:26 -0400 Subject: [PATCH 493/892] Add a regression test for #123630 compiler should not suggest nonsensical signatures, original suggestion was error[E0308]: mismatched types --> src/lib.rs:3:31 | 3 | fn select(filter: F) -> Select { | ------ ^^^^^^^^^^^^ expected `Select`, found `()` | | | implicitly returns `()` as its body has no tail or `return` expression | = note: expected struct `Select` found unit type `()` error[E0282]: type annotations needed for `Select<{closure@src/lib.rs:8:22: 8:25}, I>` --> src/lib.rs:8:9 | 8 | let lit = select(|x| match x { | ^^^ | help: consider giving `lit` an explicit type, where the type for type parameter `I` is specified | 8 | let lit: Select<{closure@src/lib.rs:8:22: 8:25}, I> = select(|x| match x { | ++++++++++++++++++++++++++++++++++++++++++++ Some errors have detailed explanations: E0282, E0308. For more information about an error, try `rustc --explain E0282`. --- .../types/dont-suggest-path-names.rs | 17 ++++++++++++ .../types/dont-suggest-path-names.stderr | 26 +++++++++++++++++++ 2 files changed, 43 insertions(+) create mode 100644 tests/ui/suggestions/types/dont-suggest-path-names.rs create mode 100644 tests/ui/suggestions/types/dont-suggest-path-names.stderr diff --git a/tests/ui/suggestions/types/dont-suggest-path-names.rs b/tests/ui/suggestions/types/dont-suggest-path-names.rs new file mode 100644 index 0000000000000..d160e49cd0358 --- /dev/null +++ b/tests/ui/suggestions/types/dont-suggest-path-names.rs @@ -0,0 +1,17 @@ +// This is a regression test for #123630 +// +// Prior to #123703 this was resulting in compiler suggesting add a type signature +// for `lit` containing path to a file containing `Select` - something obviously invalid. + +struct Select(F, I); +fn select(filter: F) -> Select {} +//~^ 7:31: 7:43: mismatched types [E0308] + +fn parser1() { + let lit = select(|x| match x { + //~^ 11:23: 11:24: type annotations needed [E0282] + _ => (), + }); +} + +fn main() {} diff --git a/tests/ui/suggestions/types/dont-suggest-path-names.stderr b/tests/ui/suggestions/types/dont-suggest-path-names.stderr new file mode 100644 index 0000000000000..5c71e350f81a3 --- /dev/null +++ b/tests/ui/suggestions/types/dont-suggest-path-names.stderr @@ -0,0 +1,26 @@ +error[E0308]: mismatched types + --> $DIR/dont-suggest-path-names.rs:7:31 + | +LL | fn select(filter: F) -> Select {} + | ------ ^^^^^^^^^^^^ expected `Select`, found `()` + | | + | implicitly returns `()` as its body has no tail or `return` expression + | + = note: expected struct `Select` + found unit type `()` + +error[E0282]: type annotations needed + --> $DIR/dont-suggest-path-names.rs:11:23 + | +LL | let lit = select(|x| match x { + | ^ - type must be known at this point + | +help: consider giving this closure parameter an explicit type + | +LL | let lit = select(|x: /* Type */| match x { + | ++++++++++++ + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0282, E0308. +For more information about an error, try `rustc --explain E0282`. From 49cd5dd454d0115cfbe9e39102a8b3ba4616aa40 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sun, 30 Jun 2024 11:20:49 +0000 Subject: [PATCH 494/892] Rustup to rustc 1.81.0-nightly (ba1d7f4a0 2024-06-29) --- rust-toolchain | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-toolchain b/rust-toolchain index 85d73cb414f17..cfa91744a0e8d 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2024-06-26" +channel = "nightly-2024-06-30" components = ["rust-src", "rustc-dev", "llvm-tools"] From e09815f0efdf6a91f96974284b9e5129029da45f Mon Sep 17 00:00:00 2001 From: Guillaume Boisseau Date: Sun, 30 Jun 2024 14:26:28 +0200 Subject: [PATCH 495/892] New features gates mustn't specify a version by hand --- compiler/rustc_feature/src/unstable.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index f100d3e4ca84e..8c30006e292b9 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -574,7 +574,7 @@ declare_features! ( /// Makes `&` and `&mut` patterns eat only one layer of references in Rust 2024. (incomplete, ref_pat_eat_one_layer_2024, "1.79.0", Some(123076)), /// Makes `&` and `&mut` patterns eat only one layer of references in Rust 2024—structural variant - (incomplete, ref_pat_eat_one_layer_2024_structural, "1.79.0", Some(123076)), + (incomplete, ref_pat_eat_one_layer_2024_structural, "CURRENT_RUSTC_VERSION", Some(123076)), /// Allows using the `#[register_tool]` attribute. (unstable, register_tool, "1.41.0", Some(66079)), /// Allows the `#[repr(i128)]` attribute for enums. From f79bf19a7a9dc9bbdab3d1c274bd267b0e86a66e Mon Sep 17 00:00:00 2001 From: Boxy Date: Sun, 30 Jun 2024 15:15:05 +0100 Subject: [PATCH 496/892] Update test comment --- .../repeat_expr_hack_gives_right_generics.rs | 22 +++++++++++-------- ...peat_expr_hack_gives_right_generics.stderr | 2 +- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/tests/ui/const-generics/repeat_expr_hack_gives_right_generics.rs b/tests/ui/const-generics/repeat_expr_hack_gives_right_generics.rs index 899db191ae7d7..e7ae2ea1d5a6a 100644 --- a/tests/ui/const-generics/repeat_expr_hack_gives_right_generics.rs +++ b/tests/ui/const-generics/repeat_expr_hack_gives_right_generics.rs @@ -1,14 +1,18 @@ -// Given an anon const `a`: `{ N }` and some anon const `b` which references the -// first anon const: `{ [1; a] }`. `b` should not have any generics as it is not -// a simple `N` argument nor is it a repeat expr count. +// Given a const argument `a`: `{ N }` and some const argument `b` which references the +// first anon const like so: `{ [1; a] }`. The `b` anon const should not be allowed to use +// any generic parameters as: +// - The anon const is not a simple bare parameter, e.g. `N` +// - The anon const is not the *length* of an array repeat expression, e.g. the `N` in `[1; N]`. // -// On the other hand `b` *is* a repeat expr count and so it should inherit its -// parents generics as part of the `const_evaluatable_unchecked` fcw (#76200). +// On the other hand `a` *is* a const argument for the length of a repeat expression and +// so it *should* inherit the generics declared on its parent definition. (This hack is +// introduced for backwards compatibility and is tracked in #76200) // -// In this specific case however `b`'s parent should be `a` and so it should wind -// up not having any generics after all. If `a` were to inherit its generics from -// the enclosing item then the reference to `a` from `b` would contain generic -// parameters not usable by `b` which would cause us to ICE. +// In this specific case `a`'s parent should be `b` which does not have any generics. +// This means that even though `a` inherits generics from `b`, it still winds up not having +// access to any generic parameters. If `a` were to inherit its generics from the surrounding +// function `foo` then the reference to `a` from `b` would contain generic parameters not usable +// by `b` which would cause us to ICE. fn bar() {} diff --git a/tests/ui/const-generics/repeat_expr_hack_gives_right_generics.stderr b/tests/ui/const-generics/repeat_expr_hack_gives_right_generics.stderr index 64548cc5a301e..72a6e6977f583 100644 --- a/tests/ui/const-generics/repeat_expr_hack_gives_right_generics.stderr +++ b/tests/ui/const-generics/repeat_expr_hack_gives_right_generics.stderr @@ -1,5 +1,5 @@ error: generic parameters may not be used in const operations - --> $DIR/repeat_expr_hack_gives_right_generics.rs:16:17 + --> $DIR/repeat_expr_hack_gives_right_generics.rs:20:17 | LL | bar::<{ [1; N] }>(); | ^ cannot perform const operation using `N` From f23c1fdaeba6a1c8237996ae2efecaf938ba9ef8 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sun, 31 Dec 2023 18:35:49 +0000 Subject: [PATCH 497/892] Remove usage of specialization from newtype_index! --- compiler/rustc_index/src/lib.rs | 5 +---- compiler/rustc_index_macros/src/lib.rs | 5 +---- compiler/rustc_index_macros/src/newtype.rs | 4 ---- compiler/rustc_type_ir/src/lib.rs | 2 +- 4 files changed, 3 insertions(+), 13 deletions(-) diff --git a/compiler/rustc_index/src/lib.rs b/compiler/rustc_index/src/lib.rs index db6b250467e56..b775ae1f5e944 100644 --- a/compiler/rustc_index/src/lib.rs +++ b/compiler/rustc_index/src/lib.rs @@ -1,10 +1,7 @@ // tidy-alphabetical-start #![cfg_attr(all(feature = "nightly", test), feature(stmt_expr_attributes))] -#![cfg_attr( - feature = "nightly", - feature(extend_one, min_specialization, new_uninit, step_trait, test) -)] #![cfg_attr(feature = "nightly", allow(internal_features))] +#![cfg_attr(feature = "nightly", feature(extend_one, new_uninit, step_trait, test))] // tidy-alphabetical-end pub mod bit_set; diff --git a/compiler/rustc_index_macros/src/lib.rs b/compiler/rustc_index_macros/src/lib.rs index 3e55dd82a6e80..2b444932f8548 100644 --- a/compiler/rustc_index_macros/src/lib.rs +++ b/compiler/rustc_index_macros/src/lib.rs @@ -34,10 +34,7 @@ mod newtype; /// optimizations. The default max value is 0xFFFF_FF00. /// - `#[gate_rustc_only]`: makes parts of the generated code nightly-only. #[proc_macro] -#[cfg_attr( - feature = "nightly", - allow_internal_unstable(step_trait, rustc_attrs, trusted_step, min_specialization) -)] +#[cfg_attr(feature = "nightly", allow_internal_unstable(step_trait, rustc_attrs, trusted_step))] pub fn newtype_index(input: TokenStream) -> TokenStream { newtype::newtype(input) } diff --git a/compiler/rustc_index_macros/src/newtype.rs b/compiler/rustc_index_macros/src/newtype.rs index 41863f7b15f98..1ac2c44e9dca1 100644 --- a/compiler/rustc_index_macros/src/newtype.rs +++ b/compiler/rustc_index_macros/src/newtype.rs @@ -139,10 +139,6 @@ impl Parse for Newtype { Self::index(start).checked_sub(u).map(Self::from_usize) } } - - // Safety: The implementation of `Step` upholds all invariants. - #gate_rustc_only - unsafe impl ::std::iter::TrustedStep for #name {} } } else { quote! {} diff --git a/compiler/rustc_type_ir/src/lib.rs b/compiler/rustc_type_ir/src/lib.rs index d7442e7c89c4a..3913d996a6b96 100644 --- a/compiler/rustc_type_ir/src/lib.rs +++ b/compiler/rustc_type_ir/src/lib.rs @@ -2,7 +2,7 @@ #![allow(rustc::usage_of_ty_tykind)] #![cfg_attr( feature = "nightly", - feature(associated_type_defaults, min_specialization, never_type, rustc_attrs, negative_impls) + feature(associated_type_defaults, never_type, rustc_attrs, negative_impls) )] #![cfg_attr(feature = "nightly", allow(internal_features))] // tidy-alphabetical-end From 449581d89bd8361d6eaa2d0e91c2197831658b1a Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sun, 30 Jun 2024 15:10:34 +0000 Subject: [PATCH 498/892] Remove usage of specialization from rustc_borrowck --- compiler/rustc_borrowck/src/facts.rs | 28 ++++++++++++++++++++++++++-- compiler/rustc_borrowck/src/lib.rs | 1 - 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_borrowck/src/facts.rs b/compiler/rustc_borrowck/src/facts.rs index 51ea59e2092a5..af96f11538503 100644 --- a/compiler/rustc_borrowck/src/facts.rs +++ b/compiler/rustc_borrowck/src/facts.rs @@ -213,8 +213,32 @@ trait FactCell { fn to_string(&self, location_table: &LocationTable) -> String; } -impl FactCell for A { - default fn to_string(&self, _location_table: &LocationTable) -> String { +impl FactCell for BorrowIndex { + fn to_string(&self, _location_table: &LocationTable) -> String { + format!("{self:?}") + } +} + +impl FactCell for Local { + fn to_string(&self, _location_table: &LocationTable) -> String { + format!("{self:?}") + } +} + +impl FactCell for MovePathIndex { + fn to_string(&self, _location_table: &LocationTable) -> String { + format!("{self:?}") + } +} + +impl FactCell for PoloniusRegionVid { + fn to_string(&self, _location_table: &LocationTable) -> String { + format!("{self:?}") + } +} + +impl FactCell for RegionVid { + fn to_string(&self, _location_table: &LocationTable) -> String { format!("{self:?}") } } diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index 69efee2fbdc14..91c0a39073863 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -7,7 +7,6 @@ #![feature(box_patterns)] #![feature(control_flow_enum)] #![feature(let_chains)] -#![feature(min_specialization)] #![feature(never_type)] #![feature(rustc_attrs)] #![feature(rustdoc_internals)] From 34ae56de35d4c8b61f51758113debea2ec7c21e7 Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Sun, 30 Jun 2024 17:08:10 +0000 Subject: [PATCH 499/892] Make `feature(effects)` require `-Znext-solver` --- compiler/rustc_hir_analysis/messages.ftl | 4 ++++ compiler/rustc_hir_analysis/src/errors.rs | 6 ++++++ compiler/rustc_hir_analysis/src/lib.rs | 6 ++++++ .../effects/with-without-next-solver.coherence.stderr | 7 +++++++ .../effects/with-without-next-solver.rs | 10 ++++++++++ .../effects/with-without-next-solver.stock.stderr | 7 +++++++ 6 files changed, 40 insertions(+) create mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/effects/with-without-next-solver.coherence.stderr create mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/effects/with-without-next-solver.rs create mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/effects/with-without-next-solver.stock.stderr diff --git a/compiler/rustc_hir_analysis/messages.ftl b/compiler/rustc_hir_analysis/messages.ftl index 7ed32fb9d9f37..064d9c077b0a6 100644 --- a/compiler/rustc_hir_analysis/messages.ftl +++ b/compiler/rustc_hir_analysis/messages.ftl @@ -120,6 +120,10 @@ hir_analysis_drop_impl_reservation = reservation `Drop` impls are not supported hir_analysis_duplicate_precise_capture = cannot capture parameter `{$name}` twice .label = parameter captured again here +hir_analysis_effects_without_next_solver = using `#![feature(effects)]` without enabling next trait solver globally + .note = the next trait solver must be enabled globally for the effects feature to work correctly + .help = use `-Znext-solver` to enable + hir_analysis_empty_specialization = specialization impl does not specialize any associated items .note = impl is a specialization of this impl diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs index 44025c3cd61c1..3ffb51fa9926a 100644 --- a/compiler/rustc_hir_analysis/src/errors.rs +++ b/compiler/rustc_hir_analysis/src/errors.rs @@ -1699,3 +1699,9 @@ pub struct InvalidReceiverTy<'tcx> { pub span: Span, pub receiver_ty: Ty<'tcx>, } + +#[derive(Diagnostic)] +#[diag(hir_analysis_effects_without_next_solver)] +#[note] +#[help] +pub struct EffectsWithoutNextSolver; diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs index 0428abcdf24e8..cf41f51f74814 100644 --- a/compiler/rustc_hir_analysis/src/lib.rs +++ b/compiler/rustc_hir_analysis/src/lib.rs @@ -151,6 +151,12 @@ pub fn provide(providers: &mut Providers) { pub fn check_crate(tcx: TyCtxt<'_>) { let _prof_timer = tcx.sess.timer("type_check_crate"); + // FIXME(effects): remove once effects is implemented in old trait solver + // or if the next solver is stabilized. + if tcx.features().effects && !tcx.next_trait_solver_globally() { + tcx.dcx().emit_err(errors::EffectsWithoutNextSolver); + } + tcx.sess.time("coherence_checking", || { tcx.hir().par_for_each_module(|module| { let _ = tcx.ensure().check_mod_type_wf(module); diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/with-without-next-solver.coherence.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/with-without-next-solver.coherence.stderr new file mode 100644 index 0000000000000..20448f51de22c --- /dev/null +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/with-without-next-solver.coherence.stderr @@ -0,0 +1,7 @@ +error: using `#![feature(effects)]` without enabling next trait solver globally + | + = note: the next trait solver must be enabled globally for the effects feature to work correctly + = help: use `-Znext-solver` to enable + +error: aborting due to 1 previous error + diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/with-without-next-solver.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/with-without-next-solver.rs new file mode 100644 index 0000000000000..f022af05c50e7 --- /dev/null +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/with-without-next-solver.rs @@ -0,0 +1,10 @@ +// test that we error correctly when effects is used without the next-solver flag. +//@ revisions: stock coherence full +//@[coherence] compile-flags: -Znext-solver=coherence +//@[full] compile-flags: -Znext-solver +//@[full] check-pass + +#![feature(effects)] +#![allow(incomplete_features)] + +fn main() {} diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/with-without-next-solver.stock.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/with-without-next-solver.stock.stderr new file mode 100644 index 0000000000000..20448f51de22c --- /dev/null +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/with-without-next-solver.stock.stderr @@ -0,0 +1,7 @@ +error: using `#![feature(effects)]` without enabling next trait solver globally + | + = note: the next trait solver must be enabled globally for the effects feature to work correctly + = help: use `-Znext-solver` to enable + +error: aborting due to 1 previous error + From daff015314b9ffeb2f65fa45659a1c3008149534 Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Sun, 30 Jun 2024 17:08:45 +0000 Subject: [PATCH 500/892] Migrate tests to use `-Znext-solver` --- tests/crashes/119924-6.rs | 1 + .../auxiliary/const-effect-param.rs | 2 ++ .../unify-op-with-fn-call.rs | 2 +- .../unify-op-with-fn-call.stderr | 32 +++++++++++++------ tests/ui/const-generics/issues/issue-88119.rs | 4 +-- .../const-generics/issues/issue-88119.stderr | 27 ++++++++++++++++ .../auxiliary/closure-in-foreign-crate.rs | 4 ++- tests/ui/consts/const-float-classify.rs | 2 +- tests/ui/consts/const-try.stderr | 7 +++- tests/ui/consts/const_cmp_type_id.rs | 21 +++++++----- tests/ui/consts/const_cmp_type_id.stderr | 25 --------------- ...constifconst-call-in-const-position.stderr | 7 +++- tests/ui/consts/rustc-impl-const-stability.rs | 5 +-- .../consts/rustc-impl-const-stability.stderr | 13 ++------ .../generic-const-items/const-trait-impl.rs | 2 +- .../impls-nested-within-fns-semantic-1.rs | 4 ++- .../impls-nested-within-fns-semantic-1.stderr | 11 ------- .../assoc-type-const-bound-usage-0.stderr | 7 +++- .../assoc-type-const-bound-usage-1.stderr | 7 +++- .../assoc-type.stderr | 7 +++- .../auxiliary/cross-crate.rs | 1 + .../auxiliary/staged-api.rs | 4 ++- .../call-const-trait-method-fail.stderr | 7 +++- .../call-generic-method-chain.stderr | 7 +++- .../call-generic-method-dup-bound.stderr | 7 +++- .../call-generic-method-fail.rs | 5 +-- .../call-generic-method-fail.stderr | 11 ------- .../call-generic-method-nonconst.stderr | 7 +++- .../call-generic-method-pass.stderr | 7 +++- .../ui/rfcs/rfc-2632-const-trait-impl/call.rs | 2 +- ...st-bound-on-not-const-associated-fn.stderr | 7 +++- .../const-bounds-non-const-trait.stderr | 7 +++- .../const-check-fns-in-const-impl.stderr | 7 +++- .../const-default-method-bodies.stderr | 7 +++- .../const-impl-requires-const-trait.stderr | 7 +++- .../const-impl-trait.stderr | 7 +++- .../const-trait-bounds.rs | 5 +-- .../const-trait-bounds.stderr | 30 +++++++++++++++++ .../derive-const-non-const-type.stderr | 7 +++- .../const_derives/derive-const-use.stderr | 7 +++- .../derive-const-with-params.stderr | 7 +++- ...ross-crate-default-method-body-is-const.rs | 5 +-- ...-crate-default-method-body-is-const.stderr | 11 ------- .../cross-crate.gated.stderr | 11 ------- .../cross-crate.gatednc.stderr | 20 +++--------- .../rfc-2632-const-trait-impl/cross-crate.rs | 3 +- .../cross-crate.stock.stderr | 2 +- .../cross-crate.stocknc.stderr | 4 +-- ...-method-body-is-const-same-trait-ck.stderr | 7 +++- .../do-not-const-check-override.rs | 4 ++- .../do-not-const-check-override.stderr | 11 ------- .../effects/auxiliary/cross-crate.rs | 4 ++- ...nst_closure-const_trait_impl-ice-113381.rs | 1 + .../effects/effect-param-infer.rs | 5 +-- .../effects/effect-param-infer.stderr | 11 ------- .../effects/fallback.rs | 5 +-- .../effects/fallback.stderr | 11 ------- .../effects/helloworld.rs | 6 ++-- .../effects/helloworld.stderr | 11 ------- .../ice-112822-expected-type-for-param.stderr | 7 +++- ...ice-113375-index-out-of-bounds-generics.rs | 2 +- .../effects/infer-fallback.rs | 4 ++- .../effects/infer-fallback.stderr | 11 ------- ...o-explicit-const-params-cross-crate.stderr | 8 ++--- .../effects/no-explicit-const-params.stderr | 7 +++- .../effects/project.rs | 2 +- .../effects/span-bug-issue-121418.stderr | 7 +++- .../effects/spec-effectvar-ice.stderr | 7 +++- .../effects/trait-fn-const.stderr | 7 +++- .../hir-const-check.stderr | 7 +++- .../ice-119717-constant-lifetime.stderr | 7 +++- .../ice-120503-async-const-method.stderr | 7 +++- .../ice-121536-const-method.stderr | 7 +++- .../ice-123664-unexpected-bound-var.stderr | 7 +++- ...857-combine-effect-const-infer-vars.stderr | 7 +++- .../ice-126148-failed-to-normalize.stderr | 7 +++- .../impl-with-default-fn-fail.stderr | 7 +++- .../impl-with-default-fn-pass.rs | 1 + .../issue-100222.nn.stderr | 9 ++++++ .../issue-100222.ny.stderr | 9 ++++++ .../rfc-2632-const-trait-impl/issue-100222.rs | 3 +- .../issue-100222.yn.stderr | 9 ++++++ .../issue-100222.yy.stderr | 9 ++++++ .../rfc-2632-const-trait-impl/issue-79450.rs | 4 ++- .../issue-79450.stderr | 13 ++------ ...ult-impl-non-const-specialized-impl.stderr | 7 +++- .../specializing-constness.stderr | 7 +++- .../rfc-2632-const-trait-impl/staged-api.rs | 4 ++- .../staged-api.stable.stderr | 21 ++++-------- .../staged-api.unstable.stderr | 21 ++++-------- .../super-traits-fail-2.nn.stderr | 21 ++++-------- .../super-traits-fail-2.ny.stderr | 17 +++------- .../super-traits-fail-2.rs | 4 ++- .../super-traits-fail-2.yn.stderr | 19 +++-------- .../super-traits-fail-2.yy.stderr | 15 ++------- .../super-traits-fail-3.nn.stderr | 12 +++---- .../super-traits-fail-3.ny.stderr | 6 ++-- .../super-traits-fail-3.rs | 1 + .../super-traits-fail-3.yn.stderr | 10 +++--- .../super-traits-fail-3.yy.stderr | 4 +-- .../tilde-const-and-const-params.stderr | 7 +++- .../tilde-const-assoc-fn-in-trait-impl.rs | 5 +-- .../tilde-const-assoc-fn-in-trait-impl.stderr | 11 ------- .../tilde-const-inherent-assoc-const-fn.rs | 4 ++- ...tilde-const-inherent-assoc-const-fn.stderr | 11 ------- .../tilde-const-trait-assoc-tys.rs | 4 ++- .../tilde-const-trait-assoc-tys.stderr | 11 ------- .../trait-default-body-stability.rs | 3 +- .../trait-default-body-stability.stderr | 15 ++------- .../trait-where-clause-const.rs | 1 + .../trait-where-clause-const.stderr | 12 +++---- .../trait-where-clause-self-referential.rs | 5 +-- ...trait-where-clause-self-referential.stderr | 11 ------- .../missing-const-stability.rs | 1 + .../missing-const-stability.stderr | 8 ++--- 115 files changed, 503 insertions(+), 428 deletions(-) create mode 100644 tests/ui/const-generics/issues/issue-88119.stderr delete mode 100644 tests/ui/consts/const_cmp_type_id.stderr delete mode 100644 tests/ui/parser/impls-nested-within-fns-semantic-1.stderr delete mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-fail.stderr create mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/const-trait-bounds.stderr delete mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate-default-method-body-is-const.stderr delete mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate.gated.stderr delete mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/do-not-const-check-override.stderr delete mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/effects/effect-param-infer.stderr delete mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/effects/fallback.stderr delete mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/effects/helloworld.stderr delete mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/effects/infer-fallback.stderr create mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/issue-100222.nn.stderr create mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/issue-100222.ny.stderr create mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/issue-100222.yn.stderr create mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/issue-100222.yy.stderr delete mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-assoc-fn-in-trait-impl.stderr delete mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-inherent-assoc-const-fn.stderr delete mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-trait-assoc-tys.stderr delete mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-self-referential.stderr diff --git a/tests/crashes/119924-6.rs b/tests/crashes/119924-6.rs index 01c4f43e8fd43..f1cc9d2915915 100644 --- a/tests/crashes/119924-6.rs +++ b/tests/crashes/119924-6.rs @@ -1,4 +1,5 @@ //@ known-bug: #119924 +//@ compile-flags: -Znext-solver #![feature(const_trait_impl, effects)] struct S; diff --git a/tests/rustdoc/inline_cross/auxiliary/const-effect-param.rs b/tests/rustdoc/inline_cross/auxiliary/const-effect-param.rs index b0c21ffaeb997..161d0c9d54e11 100644 --- a/tests/rustdoc/inline_cross/auxiliary/const-effect-param.rs +++ b/tests/rustdoc/inline_cross/auxiliary/const-effect-param.rs @@ -1,4 +1,6 @@ +//@ compile-flags: -Znext-solver #![feature(effects, const_trait_impl)] +#![allow(incomplete_features)] #[const_trait] pub trait Resource {} diff --git a/tests/ui/const-generics/generic_const_exprs/unify-op-with-fn-call.rs b/tests/ui/const-generics/generic_const_exprs/unify-op-with-fn-call.rs index bd9c08e5ad895..818b5d6ca93ae 100644 --- a/tests/ui/const-generics/generic_const_exprs/unify-op-with-fn-call.rs +++ b/tests/ui/const-generics/generic_const_exprs/unify-op-with-fn-call.rs @@ -1,5 +1,5 @@ //@ known-bug: #110395 - +//@ compile-flags: -Znext-solver #![feature(generic_const_exprs, adt_const_params, const_trait_impl, effects)] #![allow(incomplete_features)] diff --git a/tests/ui/const-generics/generic_const_exprs/unify-op-with-fn-call.stderr b/tests/ui/const-generics/generic_const_exprs/unify-op-with-fn-call.stderr index cf03bb9ad7612..db93bcca60fb3 100644 --- a/tests/ui/const-generics/generic_const_exprs/unify-op-with-fn-call.stderr +++ b/tests/ui/const-generics/generic_const_exprs/unify-op-with-fn-call.stderr @@ -19,6 +19,12 @@ LL + #[derive(ConstParamTy)] LL | struct Foo(u8); | +error[E0284]: type annotations needed: cannot normalize `foo::{constant#0}` + --> $DIR/unify-op-with-fn-call.rs:20:25 + | +LL | fn foo(a: Evaluatable<{ N + N }>) { + | ^^^^^^^^^^^^^^^^^^^^^^ cannot normalize `foo::{constant#0}` + error[E0741]: `Foo` must implement `ConstParamTy` to be used as the type of a const generic parameter --> $DIR/unify-op-with-fn-call.rs:20:17 | @@ -43,17 +49,25 @@ LL + #[derive(ConstParamTy)] LL | struct Foo(u8); | -error: unconstrained generic constant - --> $DIR/unify-op-with-fn-call.rs:30:12 +error[E0284]: type annotations needed: cannot normalize `foo2::{constant#0}` + --> $DIR/unify-op-with-fn-call.rs:29:28 | -LL | bar2::<{ std::ops::Add::add(N, N) }>(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | fn foo2(a: Evaluatable2<{ N + N }>) { + | ^^^^^^^^^^^^^^^^^^^^^^^ cannot normalize `foo2::{constant#0}` + +error[E0284]: type annotations needed: cannot normalize `foo::{constant#0}` + --> $DIR/unify-op-with-fn-call.rs:21:11 | -help: try adding a `where` bound +LL | bar::<{ std::ops::Add::add(N, N) }>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot normalize `foo::{constant#0}` + +error[E0284]: type annotations needed: cannot normalize `foo2::{constant#0}` + --> $DIR/unify-op-with-fn-call.rs:30:12 | -LL | fn foo2(a: Evaluatable2<{ N + N }>) where [(); { std::ops::Add::add(N, N) }]: { - | +++++++++++++++++++++++++++++++++++++++++ +LL | bar2::<{ std::ops::Add::add(N, N) }>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot normalize `foo2::{constant#0}` -error: aborting due to 5 previous errors +error: aborting due to 8 previous errors -For more information about this error, try `rustc --explain E0741`. +Some errors have detailed explanations: E0284, E0741. +For more information about an error, try `rustc --explain E0284`. diff --git a/tests/ui/const-generics/issues/issue-88119.rs b/tests/ui/const-generics/issues/issue-88119.rs index 128e0b64a2bfa..12cb7ee7f55cc 100644 --- a/tests/ui/const-generics/issues/issue-88119.rs +++ b/tests/ui/const-generics/issues/issue-88119.rs @@ -1,5 +1,5 @@ -//@ check-pass - +//@ known-bug: #110395 +//@ compile-flags: -Znext-solver #![allow(incomplete_features)] #![feature(const_trait_impl, effects, generic_const_exprs)] diff --git a/tests/ui/const-generics/issues/issue-88119.stderr b/tests/ui/const-generics/issues/issue-88119.stderr new file mode 100644 index 0000000000000..c17a7d5d9fad0 --- /dev/null +++ b/tests/ui/const-generics/issues/issue-88119.stderr @@ -0,0 +1,27 @@ +error[E0284]: type annotations needed: cannot satisfy `the constant `name_len::()` can be evaluated` + --> $DIR/issue-88119.rs:21:5 + | +LL | [(); name_len::()]:, + | ^^^^^^^^^^^^^^^^^^^^^ cannot satisfy `the constant `name_len::()` can be evaluated` + | +note: required by a bound in `<&T as ConstName>` + --> $DIR/issue-88119.rs:21:10 + | +LL | [(); name_len::()]:, + | ^^^^^^^^^^^^^^^ required by this bound in `<&T as ConstName>` + +error[E0284]: type annotations needed: cannot satisfy `the constant `name_len::()` can be evaluated` + --> $DIR/issue-88119.rs:28:5 + | +LL | [(); name_len::()]:, + | ^^^^^^^^^^^^^^^^^^^^^ cannot satisfy `the constant `name_len::()` can be evaluated` + | +note: required by a bound in `<&mut T as ConstName>` + --> $DIR/issue-88119.rs:28:10 + | +LL | [(); name_len::()]:, + | ^^^^^^^^^^^^^^^ required by this bound in `<&mut T as ConstName>` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0284`. diff --git a/tests/ui/consts/auxiliary/closure-in-foreign-crate.rs b/tests/ui/consts/auxiliary/closure-in-foreign-crate.rs index eb58233d1b1f8..a4dd3ee2e7e96 100644 --- a/tests/ui/consts/auxiliary/closure-in-foreign-crate.rs +++ b/tests/ui/consts/auxiliary/closure-in-foreign-crate.rs @@ -1,5 +1,7 @@ +//@ compile-flags: -Znext-solver #![crate_type = "lib"] -#![feature(const_closures, const_trait_impl, effects)] //~ WARN the feature `effects` is incomplete +#![feature(const_closures, const_trait_impl, effects)] +#![allow(incomplete_features)] pub const fn test() { let cl = const || {}; diff --git a/tests/ui/consts/const-float-classify.rs b/tests/ui/consts/const-float-classify.rs index acc8d00f83e60..c64d31a5c60ae 100644 --- a/tests/ui/consts/const-float-classify.rs +++ b/tests/ui/consts/const-float-classify.rs @@ -1,4 +1,4 @@ -//@ compile-flags: -Zmir-opt-level=0 +//@ compile-flags: -Zmir-opt-level=0 -Znext-solver //@ known-bug: #110395 // FIXME(effects) run-pass diff --git a/tests/ui/consts/const-try.stderr b/tests/ui/consts/const-try.stderr index 27eb1252d7b7d..8afdd4e0d61bf 100644 --- a/tests/ui/consts/const-try.stderr +++ b/tests/ui/consts/const-try.stderr @@ -1,3 +1,8 @@ +error: using `#![feature(effects)]` without enabling next trait solver globally + | + = note: the next trait solver must be enabled globally for the effects feature to work correctly + = help: use `-Znext-solver` to enable + error: const `impl` for trait `FromResidual` which is not marked with `#[const_trait]` --> $DIR/const-try.rs:16:12 | @@ -16,5 +21,5 @@ LL | impl const Try for TryMe { = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` = note: adding a non-const method body in the future would be a breaking change -error: aborting due to 2 previous errors +error: aborting due to 3 previous errors diff --git a/tests/ui/consts/const_cmp_type_id.rs b/tests/ui/consts/const_cmp_type_id.rs index f27271423232c..77482007be48a 100644 --- a/tests/ui/consts/const_cmp_type_id.rs +++ b/tests/ui/consts/const_cmp_type_id.rs @@ -1,12 +1,17 @@ -//@ known-bug: #110395 -#![feature(const_type_id)] -#![feature(const_trait_impl, effects)] +//@ check-pass +//@ compile-flags: -Znext-solver +#![feature(const_type_id, const_trait_impl, effects)] +#![allow(incomplete_features)] use std::any::TypeId; -const fn main() { - assert!(TypeId::of::() == TypeId::of::()); - assert!(TypeId::of::<()>() != TypeId::of::()); - const _A: bool = TypeId::of::() < TypeId::of::(); - // can't assert `_A` because it is not deterministic +fn main() { + const { + // FIXME(effects) this isn't supposed to pass (right now) but it did. + // revisit binops typeck please. + assert!(TypeId::of::() == TypeId::of::()); + assert!(TypeId::of::<()>() != TypeId::of::()); + let _a = TypeId::of::() < TypeId::of::(); + // can't assert `_a` because it is not deterministic + } } diff --git a/tests/ui/consts/const_cmp_type_id.stderr b/tests/ui/consts/const_cmp_type_id.stderr deleted file mode 100644 index e0e673d5fbdcf..0000000000000 --- a/tests/ui/consts/const_cmp_type_id.stderr +++ /dev/null @@ -1,25 +0,0 @@ -warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/const_cmp_type_id.rs:3:30 - | -LL | #![feature(const_trait_impl, effects)] - | ^^^^^^^ - | - = note: see issue #102090 for more information - = note: `#[warn(incomplete_features)]` on by default - -error[E0131]: `main` function is not allowed to have generic parameters - --> $DIR/const_cmp_type_id.rs:7:14 - | -LL | const fn main() { - | ^ `main` cannot have generic parameters - -error[E0080]: evaluation of constant value failed - --> $DIR/const_cmp_type_id.rs:10:22 - | -LL | const _A: bool = TypeId::of::() < TypeId::of::(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ calling non-const function `::lt` - -error: aborting due to 2 previous errors; 1 warning emitted - -Some errors have detailed explanations: E0080, E0131. -For more information about an error, try `rustc --explain E0080`. diff --git a/tests/ui/consts/constifconst-call-in-const-position.stderr b/tests/ui/consts/constifconst-call-in-const-position.stderr index 9096bd7868272..7de10f0287b4b 100644 --- a/tests/ui/consts/constifconst-call-in-const-position.stderr +++ b/tests/ui/consts/constifconst-call-in-const-position.stderr @@ -1,3 +1,8 @@ +error: using `#![feature(effects)]` without enabling next trait solver globally + | + = note: the next trait solver must be enabled globally for the effects feature to work correctly + = help: use `-Znext-solver` to enable + error[E0308]: mismatched types --> $DIR/constifconst-call-in-const-position.rs:17:38 | @@ -16,6 +21,6 @@ LL | [0; T::a()] = note: expected constant `false` found constant `host` -error: aborting due to 2 previous errors +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/consts/rustc-impl-const-stability.rs b/tests/ui/consts/rustc-impl-const-stability.rs index 98c5c89713804..af3262ca57534 100644 --- a/tests/ui/consts/rustc-impl-const-stability.rs +++ b/tests/ui/consts/rustc-impl-const-stability.rs @@ -1,8 +1,9 @@ +//@ compile-flags: -Znext-solver //@ known-bug: #110395 #![crate_type = "lib"] -#![feature(staged_api)] -#![feature(const_trait_impl, effects)] +#![feature(staged_api, const_trait_impl, effects)] +#![allow(incomplete_features)] #![stable(feature = "foo", since = "1.0.0")] #[stable(feature = "potato", since = "1.27.0")] diff --git a/tests/ui/consts/rustc-impl-const-stability.stderr b/tests/ui/consts/rustc-impl-const-stability.stderr index 84bd375ea406e..4a534b3ca1410 100644 --- a/tests/ui/consts/rustc-impl-const-stability.stderr +++ b/tests/ui/consts/rustc-impl-const-stability.stderr @@ -1,14 +1,5 @@ -warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/rustc-impl-const-stability.rs:5:30 - | -LL | #![feature(const_trait_impl, effects)] - | ^^^^^^^ - | - = note: see issue #102090 for more information - = note: `#[warn(incomplete_features)]` on by default - error: const `impl` for trait `Default` which is not marked with `#[const_trait]` - --> $DIR/rustc-impl-const-stability.rs:15:12 + --> $DIR/rustc-impl-const-stability.rs:16:12 | LL | impl const Default for Data { | ^^^^^^^ @@ -16,5 +7,5 @@ LL | impl const Default for Data { = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` = note: adding a non-const method body in the future would be a breaking change -error: aborting due to 1 previous error; 1 warning emitted +error: aborting due to 1 previous error diff --git a/tests/ui/generic-const-items/const-trait-impl.rs b/tests/ui/generic-const-items/const-trait-impl.rs index 34be9fe601400..51209121bd915 100644 --- a/tests/ui/generic-const-items/const-trait-impl.rs +++ b/tests/ui/generic-const-items/const-trait-impl.rs @@ -1,5 +1,5 @@ //@ check-pass - +//@ compile-flags: -Znext-solver // Test that we can call methods from const trait impls inside of generic const items. #![feature(generic_const_items, const_trait_impl, effects)] diff --git a/tests/ui/parser/impls-nested-within-fns-semantic-1.rs b/tests/ui/parser/impls-nested-within-fns-semantic-1.rs index 0e95fc757f3e8..92823b05af840 100644 --- a/tests/ui/parser/impls-nested-within-fns-semantic-1.rs +++ b/tests/ui/parser/impls-nested-within-fns-semantic-1.rs @@ -1,7 +1,9 @@ // Regression test for part of issue #119924. //@ check-pass +//@ compile-flags: -Znext-solver -#![feature(const_trait_impl, effects)] //~ WARN the feature `effects` is incomplete +#![allow(incomplete_features)] +#![feature(const_trait_impl, effects)] #[const_trait] trait Trait { diff --git a/tests/ui/parser/impls-nested-within-fns-semantic-1.stderr b/tests/ui/parser/impls-nested-within-fns-semantic-1.stderr deleted file mode 100644 index 6670b3772db12..0000000000000 --- a/tests/ui/parser/impls-nested-within-fns-semantic-1.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/impls-nested-within-fns-semantic-1.rs:4:30 - | -LL | #![feature(const_trait_impl, effects)] - | ^^^^^^^ - | - = note: see issue #102090 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-0.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-0.stderr index 919b5b6cd913d..fb491453b379b 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-0.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-0.stderr @@ -1,3 +1,8 @@ +error: using `#![feature(effects)]` without enabling next trait solver globally + | + = note: the next trait solver must be enabled globally for the effects feature to work correctly + = help: use `-Znext-solver` to enable + error[E0277]: the trait bound `Trait::{synthetic#0}: Compat` is not satisfied --> $DIR/assoc-type-const-bound-usage-0.rs:13:5 | @@ -28,6 +33,6 @@ LL | #[const_trait] LL | fn func() -> i32; | ---- required by a bound in this associated function -error: aborting due to 2 previous errors +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-1.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-1.stderr index 48855d64b58a1..392b310a4c99e 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-1.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type-const-bound-usage-1.stderr @@ -1,3 +1,8 @@ +error: using `#![feature(effects)]` without enabling next trait solver globally + | + = note: the next trait solver must be enabled globally for the effects feature to work correctly + = help: use `-Znext-solver` to enable + error[E0277]: the trait bound `Trait::{synthetic#0}: Compat` is not satisfied --> $DIR/assoc-type-const-bound-usage-1.rs:15:44 | @@ -28,6 +33,6 @@ LL | #[const_trait] LL | fn func() -> i32; | ---- required by a bound in this associated function -error: aborting due to 2 previous errors +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type.stderr index 1862339cddc5e..405212b52c7c7 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/assoc-type.stderr @@ -7,6 +7,11 @@ LL | #![feature(const_trait_impl, effects)] = note: see issue #102090 for more information = note: `#[warn(incomplete_features)]` on by default +error: using `#![feature(effects)]` without enabling next trait solver globally + | + = note: the next trait solver must be enabled globally for the effects feature to work correctly + = help: use `-Znext-solver` to enable + error[E0277]: the trait bound `Add::{synthetic#0}: Compat` is not satisfied --> $DIR/assoc-type.rs:41:15 | @@ -18,6 +23,6 @@ help: consider further restricting the associated type LL | trait Baz where Add::{synthetic#0}: Compat { | ++++++++++++++++++++++++++++++++ -error: aborting due to 1 previous error; 1 warning emitted +error: aborting due to 2 previous errors; 1 warning emitted For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/auxiliary/cross-crate.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/auxiliary/cross-crate.rs index 78e41ca6b7519..8f63cd1d521ed 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/auxiliary/cross-crate.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/auxiliary/cross-crate.rs @@ -1,3 +1,4 @@ +//@ compile-flags: -Znext-solver #![allow(incomplete_features)] #![feature(const_trait_impl, effects)] diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/auxiliary/staged-api.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/auxiliary/staged-api.rs index fd4e1ff803da6..986165ef91e6c 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/auxiliary/staged-api.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/auxiliary/staged-api.rs @@ -1,4 +1,6 @@ -#![feature(const_trait_impl, effects)] //~ WARN the feature `effects` is incomplete +//@ compile-flags: -Znext-solver +#![allow(incomplete_features)] +#![feature(const_trait_impl, effects)] #![feature(staged_api)] #![stable(feature = "rust1", since = "1.0.0")] diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-fail.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-fail.stderr index 336ee01dc8d73..73ea1422bf9d7 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-fail.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-fail.stderr @@ -7,6 +7,11 @@ LL | #![feature(const_trait_impl, effects)] = note: see issue #102090 for more information = note: `#[warn(incomplete_features)]` on by default +error: using `#![feature(effects)]` without enabling next trait solver globally + | + = note: the next trait solver must be enabled globally for the effects feature to work correctly + = help: use `-Znext-solver` to enable + error[E0277]: the trait bound `Runtime: ~const Compat` is not satisfied --> $DIR/call-const-trait-method-fail.rs:25:5 | @@ -23,6 +28,6 @@ LL | pub trait Plus { LL | fn plus(self, rhs: Self) -> Self; | ---- required by a bound in this associated function -error: aborting due to 1 previous error; 1 warning emitted +error: aborting due to 2 previous errors; 1 warning emitted For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-chain.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-chain.stderr index 2e1feccd0f358..57d57dfd5b935 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-chain.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-chain.stderr @@ -7,6 +7,11 @@ LL | #![feature(const_trait_impl, effects)] = note: see issue #102090 for more information = note: `#[warn(incomplete_features)]` on by default +error: using `#![feature(effects)]` without enabling next trait solver globally + | + = note: the next trait solver must be enabled globally for the effects feature to work correctly + = help: use `-Znext-solver` to enable + error: const `impl` for trait `PartialEq` which is not marked with `#[const_trait]` --> $DIR/call-generic-method-chain.rs:10:12 | @@ -28,5 +33,5 @@ error: `~const` can only be applied to `#[const_trait]` traits LL | const fn equals_self_wrapper(t: &T) -> bool { | ^^^^^^^^^ -error: aborting due to 3 previous errors; 1 warning emitted +error: aborting due to 4 previous errors; 1 warning emitted diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-dup-bound.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-dup-bound.stderr index d3b009636865a..0088ed2eb13db 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-dup-bound.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-dup-bound.stderr @@ -7,6 +7,11 @@ LL | #![feature(const_trait_impl, effects)] = note: see issue #102090 for more information = note: `#[warn(incomplete_features)]` on by default +error: using `#![feature(effects)]` without enabling next trait solver globally + | + = note: the next trait solver must be enabled globally for the effects feature to work correctly + = help: use `-Znext-solver` to enable + error: const `impl` for trait `PartialEq` which is not marked with `#[const_trait]` --> $DIR/call-generic-method-dup-bound.rs:8:12 | @@ -28,5 +33,5 @@ error: `~const` can only be applied to `#[const_trait]` traits LL | const fn equals_self2(t: &T) -> bool { | ^^^^^^^^^ -error: aborting due to 3 previous errors; 1 warning emitted +error: aborting due to 4 previous errors; 1 warning emitted diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-fail.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-fail.rs index a9ed5a639d73a..86e0eae61c9ce 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-fail.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-fail.rs @@ -1,6 +1,7 @@ //@ check-pass - -#![feature(const_trait_impl, effects)] //~ WARN the feature `effects` is incomplete +//@ compile-flags: -Znext-solver +#![allow(incomplete_features)] +#![feature(const_trait_impl, effects)] pub const fn equals_self(t: &T) -> bool { *t == *t diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-fail.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-fail.stderr deleted file mode 100644 index 74b74052da079..0000000000000 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-fail.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/call-generic-method-fail.rs:3:30 - | -LL | #![feature(const_trait_impl, effects)] - | ^^^^^^^ - | - = note: see issue #102090 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-nonconst.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-nonconst.stderr index d48ee9c95f593..b2a98041c1cdf 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-nonconst.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-nonconst.stderr @@ -7,6 +7,11 @@ LL | #![feature(const_trait_impl, effects)] = note: see issue #102090 for more information = note: `#[warn(incomplete_features)]` on by default +error: using `#![feature(effects)]` without enabling next trait solver globally + | + = note: the next trait solver must be enabled globally for the effects feature to work correctly + = help: use `-Znext-solver` to enable + error[E0277]: the trait bound `Runtime: const Compat` is not satisfied --> $DIR/call-generic-method-nonconst.rs:23:34 | @@ -22,6 +27,6 @@ note: required by a bound in `equals_self` LL | const fn equals_self(t: &T) -> bool { | ^^^^^^^^^^ required by this bound in `equals_self` -error: aborting due to 1 previous error; 1 warning emitted +error: aborting due to 2 previous errors; 1 warning emitted For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-pass.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-pass.stderr index cab8d6d761195..4a6100c3c1aac 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-pass.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-pass.stderr @@ -7,6 +7,11 @@ LL | #![feature(const_trait_impl, effects)] = note: see issue #102090 for more information = note: `#[warn(incomplete_features)]` on by default +error: using `#![feature(effects)]` without enabling next trait solver globally + | + = note: the next trait solver must be enabled globally for the effects feature to work correctly + = help: use `-Znext-solver` to enable + error: const `impl` for trait `PartialEq` which is not marked with `#[const_trait]` --> $DIR/call-generic-method-pass.rs:10:12 | @@ -22,5 +27,5 @@ error: `~const` can only be applied to `#[const_trait]` traits LL | const fn equals_self(t: &T) -> bool { | ^^^^^^^^^ -error: aborting due to 2 previous errors; 1 warning emitted +error: aborting due to 3 previous errors; 1 warning emitted diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/call.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/call.rs index 1150d7e1059f1..af2f7caf88c75 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/call.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/call.rs @@ -1,5 +1,5 @@ //@ check-pass - +//@ compile-flags: -Znext-solver #![feature(const_closures, const_trait_impl, effects)] #![allow(incomplete_features)] diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-bound-on-not-const-associated-fn.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-bound-on-not-const-associated-fn.stderr index 42964b9774e29..b5d9b1fff8a1c 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-bound-on-not-const-associated-fn.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-bound-on-not-const-associated-fn.stderr @@ -22,5 +22,10 @@ note: this function is not `const`, so it cannot have `~const` trait bounds LL | pub fn foo(&self) where T: ~const MyTrait { | ^^^ -error: aborting due to 2 previous errors +error: using `#![feature(effects)]` without enabling next trait solver globally + | + = note: the next trait solver must be enabled globally for the effects feature to work correctly + = help: use `-Znext-solver` to enable + +error: aborting due to 3 previous errors diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-bounds-non-const-trait.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-bounds-non-const-trait.stderr index d04e5490b7639..e1a85fc54144b 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-bounds-non-const-trait.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-bounds-non-const-trait.stderr @@ -7,6 +7,11 @@ LL | #![feature(const_trait_impl, effects)] = note: see issue #102090 for more information = note: `#[warn(incomplete_features)]` on by default +error: using `#![feature(effects)]` without enabling next trait solver globally + | + = note: the next trait solver must be enabled globally for the effects feature to work correctly + = help: use `-Znext-solver` to enable + error: `~const` can only be applied to `#[const_trait]` traits --> $DIR/const-bounds-non-const-trait.rs:6:28 | @@ -19,5 +24,5 @@ error: `const` can only be applied to `#[const_trait]` traits LL | fn operate() {} | ^^^^^^^^ -error: aborting due to 2 previous errors; 1 warning emitted +error: aborting due to 3 previous errors; 1 warning emitted diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-check-fns-in-const-impl.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-check-fns-in-const-impl.stderr index d93327cea1b2c..49cd1725c8cf3 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-check-fns-in-const-impl.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-check-fns-in-const-impl.stderr @@ -7,6 +7,11 @@ LL | #![feature(const_trait_impl, effects)] = note: see issue #102090 for more information = note: `#[warn(incomplete_features)]` on by default +error: using `#![feature(effects)]` without enabling next trait solver globally + | + = note: the next trait solver must be enabled globally for the effects feature to work correctly + = help: use `-Znext-solver` to enable + error[E0015]: cannot call non-const fn `non_const` in constant functions --> $DIR/const-check-fns-in-const-impl.rs:12:16 | @@ -15,6 +20,6 @@ LL | fn foo() { non_const() } | = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants -error: aborting due to 1 previous error; 1 warning emitted +error: aborting due to 2 previous errors; 1 warning emitted For more information about this error, try `rustc --explain E0015`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-default-method-bodies.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-default-method-bodies.stderr index 32bc0093347c0..02f9dffba3239 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-default-method-bodies.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-default-method-bodies.stderr @@ -7,6 +7,11 @@ LL | #![feature(const_trait_impl, effects)] = note: see issue #102090 for more information = note: `#[warn(incomplete_features)]` on by default +error: using `#![feature(effects)]` without enabling next trait solver globally + | + = note: the next trait solver must be enabled globally for the effects feature to work correctly + = help: use `-Znext-solver` to enable + error[E0277]: the trait bound `Runtime: ~const Compat` is not satisfied --> $DIR/const-default-method-bodies.rs:24:18 | @@ -23,6 +28,6 @@ LL | #[const_trait] LL | fn a(self) { | - required by a bound in this associated function -error: aborting due to 1 previous error; 1 warning emitted +error: aborting due to 2 previous errors; 1 warning emitted For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-requires-const-trait.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-requires-const-trait.stderr index 7925cf53f42c4..2a030369093d6 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-requires-const-trait.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-requires-const-trait.stderr @@ -7,6 +7,11 @@ LL | #![feature(const_trait_impl, effects)] = note: see issue #102090 for more information = note: `#[warn(incomplete_features)]` on by default +error: using `#![feature(effects)]` without enabling next trait solver globally + | + = note: the next trait solver must be enabled globally for the effects feature to work correctly + = help: use `-Znext-solver` to enable + error: const `impl` for trait `A` which is not marked with `#[const_trait]` --> $DIR/const-impl-requires-const-trait.rs:8:12 | @@ -19,5 +24,5 @@ LL | impl const A for () {} = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` = note: adding a non-const method body in the future would be a breaking change -error: aborting due to 1 previous error; 1 warning emitted +error: aborting due to 2 previous errors; 1 warning emitted diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-trait.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-trait.stderr index af50a115c69f7..b59c6d1eed8da 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-trait.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-trait.stderr @@ -4,6 +4,11 @@ error[E0635]: unknown feature `const_cmp` LL | const_cmp, | ^^^^^^^^^ +error: using `#![feature(effects)]` without enabling next trait solver globally + | + = note: the next trait solver must be enabled globally for the effects feature to work correctly + = help: use `-Znext-solver` to enable + error: `~const` can only be applied to `#[const_trait]` traits --> $DIR/const-impl-trait.rs:13:30 | @@ -238,7 +243,7 @@ LL | const fn apit_assoc_bound(_: impl IntoIterator + ~const Des | | | the destructor for this type cannot be evaluated in constant functions -error: aborting due to 32 previous errors +error: aborting due to 33 previous errors Some errors have detailed explanations: E0493, E0635. For more information about an error, try `rustc --explain E0493`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-trait-bounds.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-trait-bounds.rs index cf452cf852687..3b4ba6a998f88 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-trait-bounds.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-trait-bounds.rs @@ -1,5 +1,6 @@ -//@ check-pass - +//@ known-bug: #110395 +//@ compile-flags: -Znext-solver +// FIXME(effects): check-pass #![feature(const_trait_impl, effects, generic_const_exprs)] #![allow(incomplete_features)] diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-trait-bounds.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-trait-bounds.stderr new file mode 100644 index 0000000000000..4d543f6a1559a --- /dev/null +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-trait-bounds.stderr @@ -0,0 +1,30 @@ +error[E0284]: type annotations needed: cannot normalize `process::{constant#0}` + --> $DIR/const-trait-bounds.rs:12:35 + | +LL | fn process(input: [(); T::make(2)]) -> [(); T::make(2)] { + | ^^^^^^^^^^^^^^^^ cannot normalize `process::{constant#0}` + +error[E0284]: type annotations needed: cannot satisfy `the constant `T::make(P)` can be evaluated` + --> $DIR/const-trait-bounds.rs:18:5 + | +LL | [u32; T::make(P)]:, + | ^^^^^^^^^^^^^^^^^ cannot satisfy `the constant `T::make(P)` can be evaluated` + | +note: required by a bound in `Struct` + --> $DIR/const-trait-bounds.rs:18:11 + | +LL | struct Struct + | ------ required by a bound in this struct +LL | where +LL | [u32; T::make(P)]:, + | ^^^^^^^^^^ required by this bound in `Struct` + +error[E0284]: type annotations needed: cannot normalize `process::{constant#1}` + --> $DIR/const-trait-bounds.rs:13:5 + | +LL | input + | ^^^^^ cannot normalize `process::{constant#1}` + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0284`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-non-const-type.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-non-const-type.stderr index 78e5b70d41c38..777b3313da6b2 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-non-const-type.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-non-const-type.stderr @@ -7,6 +7,11 @@ LL | #![feature(derive_const, effects)] = note: see issue #102090 for more information = note: `#[warn(incomplete_features)]` on by default +error: using `#![feature(effects)]` without enabling next trait solver globally + | + = note: the next trait solver must be enabled globally for the effects feature to work correctly + = help: use `-Znext-solver` to enable + error: const `impl` for trait `Default` which is not marked with `#[const_trait]` --> $DIR/derive-const-non-const-type.rs:10:16 | @@ -17,5 +22,5 @@ LL | #[derive_const(Default)] = note: adding a non-const method body in the future would be a breaking change = note: this error originates in the derive macro `Default` (in Nightly builds, run with -Z macro-backtrace for more info) -error: aborting due to 1 previous error; 1 warning emitted +error: aborting due to 2 previous errors; 1 warning emitted diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-use.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-use.stderr index da6b77f623cc1..ad727fc36cd76 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-use.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-use.stderr @@ -19,6 +19,11 @@ error[E0635]: unknown feature `const_default_impls` LL | #![feature(const_trait_impl, const_cmp, const_default_impls, derive_const, effects)] | ^^^^^^^^^^^^^^^^^^^ +error: using `#![feature(effects)]` without enabling next trait solver globally + | + = note: the next trait solver must be enabled globally for the effects feature to work correctly + = help: use `-Znext-solver` to enable + error: const `impl` for trait `Default` which is not marked with `#[const_trait]` --> $DIR/derive-const-use.rs:7:12 | @@ -79,7 +84,7 @@ LL | const _: () = assert!(S((), A) == S::default()); | ^^^^^^^^^^^^ = note: this error originates in the derive macro `Default` (in Nightly builds, run with -Z macro-backtrace for more info) -error: aborting due to 7 previous errors; 1 warning emitted +error: aborting due to 8 previous errors; 1 warning emitted Some errors have detailed explanations: E0080, E0635. For more information about an error, try `rustc --explain E0080`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-with-params.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-with-params.stderr index 102458450fbf7..addce8dcd6c75 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-with-params.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-with-params.stderr @@ -7,6 +7,11 @@ LL | #![feature(const_trait_impl, effects)] = note: see issue #102090 for more information = note: `#[warn(incomplete_features)]` on by default +error: using `#![feature(effects)]` without enabling next trait solver globally + | + = note: the next trait solver must be enabled globally for the effects feature to work correctly + = help: use `-Znext-solver` to enable + error: const `impl` for trait `PartialEq` which is not marked with `#[const_trait]` --> $DIR/derive-const-with-params.rs:7:16 | @@ -25,5 +30,5 @@ LL | #[derive_const(PartialEq)] | = note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info) -error: aborting due to 2 previous errors; 1 warning emitted +error: aborting due to 3 previous errors; 1 warning emitted diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate-default-method-body-is-const.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate-default-method-body-is-const.rs index d8be8b13d0822..9ee5254dbf8a8 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate-default-method-body-is-const.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate-default-method-body-is-const.rs @@ -2,8 +2,9 @@ // be called from a const context when used across crates. // //@ check-pass - -#![feature(const_trait_impl, effects)] //~ WARN the feature `effects` is incomplete +//@ compile-flags: -Znext-solver +#![allow(incomplete_features)] +#![feature(const_trait_impl, effects)] //@ aux-build: cross-crate.rs extern crate cross_crate; diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate-default-method-body-is-const.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate-default-method-body-is-const.stderr deleted file mode 100644 index 2f1e1e6b8d2b9..0000000000000 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate-default-method-body-is-const.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/cross-crate-default-method-body-is-const.rs:6:30 - | -LL | #![feature(const_trait_impl, effects)] - | ^^^^^^^ - | - = note: see issue #102090 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate.gated.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate.gated.stderr deleted file mode 100644 index 2ce29a74eaeb0..0000000000000 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate.gated.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/cross-crate.rs:3:60 - | -LL | #![cfg_attr(any(gated, gatednc), feature(const_trait_impl, effects))] - | ^^^^^^^ - | - = note: see issue #102090 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate.gatednc.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate.gatednc.stderr index af042ecff953b..b7209827c22c0 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate.gatednc.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate.gatednc.stderr @@ -1,21 +1,11 @@ -warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/cross-crate.rs:3:60 - | -LL | #![cfg_attr(any(gated, gatednc), feature(const_trait_impl, effects))] - | ^^^^^^^ - | - = note: see issue #102090 for more information - = note: `#[warn(incomplete_features)]` on by default - -error[E0277]: the trait bound `Runtime: ~const Compat` is not satisfied - --> $DIR/cross-crate.rs:18:14 +error[E0277]: the trait bound `cross_crate::MyTrait::{synthetic#0}: ~const Compat` is not satisfied + --> $DIR/cross-crate.rs:19:14 | LL | NonConst.func(); - | ^^^^ the trait `~const Compat` is not implemented for `Runtime` + | ^^^^ the trait `~const Compat` is not implemented for `cross_crate::MyTrait::{synthetic#0}` | - = help: the trait `Compat` is implemented for `Runtime` note: required by a bound in `func` - --> $DIR/auxiliary/cross-crate.rs:4:1 + --> $DIR/auxiliary/cross-crate.rs:5:1 | LL | #[const_trait] | ^^^^^^^^^^^^^^ required by this bound in `MyTrait::func` @@ -23,6 +13,6 @@ LL | #[const_trait] LL | fn func(self); | ---- required by a bound in this associated function -error: aborting due to 1 previous error; 1 warning emitted +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate.rs index 04c101d0fc5fb..cfcada9c828d4 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate.rs @@ -1,7 +1,8 @@ //@ revisions: stock gated stocknc gatednc //@ [gated] check-pass +//@ compile-flags: -Znext-solver #![cfg_attr(any(gated, gatednc), feature(const_trait_impl, effects))] -//[gated,gatednc]~^ WARN the feature `effects` is incomplete +#![allow(incomplete_features)] //@ aux-build: cross-crate.rs extern crate cross_crate; diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate.stock.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate.stock.stderr index 3df875057f2c8..b481bdc470ce3 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate.stock.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate.stock.stderr @@ -1,5 +1,5 @@ error[E0015]: cannot call non-const fn `::func` in constant functions - --> $DIR/cross-crate.rs:21:11 + --> $DIR/cross-crate.rs:22:11 | LL | Const.func(); | ^^^^^^ diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate.stocknc.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate.stocknc.stderr index e56a5e4165ce3..5c3e3b6ff4008 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate.stocknc.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate.stocknc.stderr @@ -1,5 +1,5 @@ error[E0015]: cannot call non-const fn `::func` in constant functions - --> $DIR/cross-crate.rs:18:14 + --> $DIR/cross-crate.rs:19:14 | LL | NonConst.func(); | ^^^^^^ @@ -11,7 +11,7 @@ LL + #![feature(const_trait_impl)] | error[E0015]: cannot call non-const fn `::func` in constant functions - --> $DIR/cross-crate.rs:21:11 + --> $DIR/cross-crate.rs:22:11 | LL | Const.func(); | ^^^^^^ diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/default-method-body-is-const-same-trait-ck.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/default-method-body-is-const-same-trait-ck.stderr index 8b422d62578a0..1b5aa9c91918c 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/default-method-body-is-const-same-trait-ck.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/default-method-body-is-const-same-trait-ck.stderr @@ -7,6 +7,11 @@ LL | #![feature(const_trait_impl, effects)] = note: see issue #102090 for more information = note: `#[warn(incomplete_features)]` on by default +error: using `#![feature(effects)]` without enabling next trait solver globally + | + = note: the next trait solver must be enabled globally for the effects feature to work correctly + = help: use `-Znext-solver` to enable + error[E0277]: the trait bound `Runtime: ~const Compat` is not satisfied --> $DIR/default-method-body-is-const-same-trait-ck.rs:8:12 | @@ -23,6 +28,6 @@ LL | pub trait Tr { LL | fn a(&self) {} | - required by a bound in this associated function -error: aborting due to 1 previous error; 1 warning emitted +error: aborting due to 2 previous errors; 1 warning emitted For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/do-not-const-check-override.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/do-not-const-check-override.rs index be5e66478dfaf..71e6375283fd8 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/do-not-const-check-override.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/do-not-const-check-override.rs @@ -1,5 +1,7 @@ //@ check-pass -#![feature(const_trait_impl, rustc_attrs, effects)] //~ WARN the feature `effects` is incomplete +//@ compile-flags: -Znext-solver +#![allow(incomplete_features)] +#![feature(const_trait_impl, rustc_attrs, effects)] #[const_trait] trait Foo { diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/do-not-const-check-override.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/do-not-const-check-override.stderr deleted file mode 100644 index 4be1160b58cb2..0000000000000 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/do-not-const-check-override.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/do-not-const-check-override.rs:2:43 - | -LL | #![feature(const_trait_impl, rustc_attrs, effects)] - | ^^^^^^^ - | - = note: see issue #102090 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/auxiliary/cross-crate.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/auxiliary/cross-crate.rs index 5c32eee8737e8..779527e22d4ab 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/auxiliary/cross-crate.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/auxiliary/cross-crate.rs @@ -1,4 +1,6 @@ -#![feature(const_trait_impl, effects)] //~ WARN the feature `effects` is incomplete +//@ compile-flags: -Znext-solver +#![allow(incomplete_features)] +#![feature(const_trait_impl, effects)] pub const fn foo() {} diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/const_closure-const_trait_impl-ice-113381.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/const_closure-const_trait_impl-ice-113381.rs index a1c0425b24e38..3debc22098afc 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/const_closure-const_trait_impl-ice-113381.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/const_closure-const_trait_impl-ice-113381.rs @@ -1,5 +1,6 @@ //@ check-pass // FIXME(effects) this shouldn't pass +//@ compile-flags: -Znext-solver #![feature(const_closures, const_trait_impl, effects)] #![allow(incomplete_features)] diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/effect-param-infer.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/effect-param-infer.rs index b354591e0070f..958b9ac6d5773 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/effect-param-infer.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/effect-param-infer.rs @@ -2,8 +2,9 @@ // at the end of generic args when the generics have defaulted params. // //@ check-pass - -#![feature(const_trait_impl, effects)] //~ WARN the feature `effects` is incomplete +//@ compile-flags: -Znext-solver +#![allow(incomplete_features)] +#![feature(const_trait_impl, effects)] #[const_trait] pub trait Foo { diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/effect-param-infer.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/effect-param-infer.stderr deleted file mode 100644 index 7ceb3669e5983..0000000000000 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/effect-param-infer.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/effect-param-infer.rs:6:30 - | -LL | #![feature(const_trait_impl, effects)] - | ^^^^^^^ - | - = note: see issue #102090 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/fallback.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/fallback.rs index d949e4b829fc4..4cfba00526b0b 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/fallback.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/fallback.rs @@ -1,6 +1,7 @@ //@ check-pass - -#![feature(effects)] //~ WARN the feature `effects` is incomplete +//@ compile-flags: -Znext-solver +#![allow(incomplete_features)] +#![feature(effects)] pub const fn owo() {} diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/fallback.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/fallback.stderr deleted file mode 100644 index f7d5de829b200..0000000000000 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/fallback.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/fallback.rs:3:12 - | -LL | #![feature(effects)] - | ^^^^^^^ - | - = note: see issue #102090 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/helloworld.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/helloworld.rs index eed8cdc447c55..54f362b4413b9 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/helloworld.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/helloworld.rs @@ -1,11 +1,11 @@ //@ check-pass - +//@ compile-flags: -Znext-solver // gate-test-effects // ^ effects doesn't have a gate so we will trick tidy into thinking this is a gate test - +#![allow(incomplete_features)] #![feature( const_trait_impl, - effects, //~ WARN the feature `effects` is incomplete + effects, core_intrinsics, const_eval_select )] diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/helloworld.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/helloworld.stderr deleted file mode 100644 index 8719c5cbcef0f..0000000000000 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/helloworld.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/helloworld.rs:8:5 - | -LL | effects, - | ^^^^^^^ - | - = note: see issue #102090 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/ice-112822-expected-type-for-param.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/ice-112822-expected-type-for-param.stderr index 3f0ed13d665f8..526746eec7346 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/ice-112822-expected-type-for-param.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/ice-112822-expected-type-for-param.stderr @@ -17,6 +17,11 @@ LL | #![feature(const_trait_impl, effects)] = note: see issue #102090 for more information = note: `#[warn(incomplete_features)]` on by default +error: using `#![feature(effects)]` without enabling next trait solver globally + | + = note: the next trait solver must be enabled globally for the effects feature to work correctly + = help: use `-Znext-solver` to enable + error: `~const` can only be applied to `#[const_trait]` traits --> $DIR/ice-112822-expected-type-for-param.rs:3:32 | @@ -40,7 +45,7 @@ LL | assert_eq!(first, &b'f'); = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants = note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info) -error: aborting due to 4 previous errors; 1 warning emitted +error: aborting due to 5 previous errors; 1 warning emitted Some errors have detailed explanations: E0015, E0658. For more information about an error, try `rustc --explain E0015`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/ice-113375-index-out-of-bounds-generics.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/ice-113375-index-out-of-bounds-generics.rs index 53f8e3c56d761..06e3377c5eec1 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/ice-113375-index-out-of-bounds-generics.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/ice-113375-index-out-of-bounds-generics.rs @@ -1,5 +1,5 @@ //@ check-pass - +//@ compile-flags: -Znext-solver // effects ice https://github.com/rust-lang/rust/issues/113375 index out of bounds #![allow(incomplete_features, unused)] diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/infer-fallback.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/infer-fallback.rs index ff3a27c3ee479..581c3949d3811 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/infer-fallback.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/infer-fallback.rs @@ -1,5 +1,7 @@ //@ check-pass -#![feature(const_trait_impl, effects)] //~ WARN the feature `effects` is incomplete +//@ compile-flags: -Znext-solver +#![allow(incomplete_features)] +#![feature(const_trait_impl, effects)] const fn a() {} diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/infer-fallback.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/infer-fallback.stderr deleted file mode 100644 index 49c7d3958466a..0000000000000 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/infer-fallback.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/infer-fallback.rs:2:30 - | -LL | #![feature(const_trait_impl, effects)] - | ^^^^^^^ - | - = note: see issue #102090 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/no-explicit-const-params-cross-crate.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/no-explicit-const-params-cross-crate.stderr index 34732ac4f2ef7..fa2e3da368bd8 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/no-explicit-const-params-cross-crate.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/no-explicit-const-params-cross-crate.stderr @@ -7,7 +7,7 @@ LL | foo::(); | expected 0 generic arguments | note: function defined here, with 0 generic parameters - --> $DIR/auxiliary/cross-crate.rs:3:14 + --> $DIR/auxiliary/cross-crate.rs:5:14 | LL | pub const fn foo() {} | ^^^ @@ -19,7 +19,7 @@ LL | <() as Bar>::bar(); | ^^^ expected 0 generic arguments | note: trait defined here, with 0 generic parameters - --> $DIR/auxiliary/cross-crate.rs:6:11 + --> $DIR/auxiliary/cross-crate.rs:8:11 | LL | pub trait Bar { | ^^^ @@ -37,7 +37,7 @@ LL | foo::(); | expected 0 generic arguments | note: function defined here, with 0 generic parameters - --> $DIR/auxiliary/cross-crate.rs:3:14 + --> $DIR/auxiliary/cross-crate.rs:5:14 | LL | pub const fn foo() {} | ^^^ @@ -49,7 +49,7 @@ LL | <() as Bar>::bar(); | ^^^ expected 0 generic arguments | note: trait defined here, with 0 generic parameters - --> $DIR/auxiliary/cross-crate.rs:6:11 + --> $DIR/auxiliary/cross-crate.rs:8:11 | LL | pub trait Bar { | ^^^ diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/no-explicit-const-params.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/no-explicit-const-params.stderr index c3ff30d2d797b..fbb96dfd85e1b 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/no-explicit-const-params.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/no-explicit-const-params.stderr @@ -7,6 +7,11 @@ LL | #![feature(const_trait_impl, effects)] = note: see issue #102090 for more information = note: `#[warn(incomplete_features)]` on by default +error: using `#![feature(effects)]` without enabling next trait solver globally + | + = note: the next trait solver must be enabled globally for the effects feature to work correctly + = help: use `-Znext-solver` to enable + error[E0107]: function takes 0 generic arguments but 1 generic argument was supplied --> $DIR/no-explicit-const-params.rs:22:5 | @@ -76,7 +81,7 @@ help: replace the generic bound with the associated type LL | <() as Bar< = true>>::bar(); | + -error: aborting due to 5 previous errors; 1 warning emitted +error: aborting due to 6 previous errors; 1 warning emitted Some errors have detailed explanations: E0107, E0308. For more information about an error, try `rustc --explain E0107`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/project.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/project.rs index 373a4393713c6..9f6ca1f294f01 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/project.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/project.rs @@ -1,5 +1,5 @@ //@ check-pass - +//@ compile-flags: -Znext-solver #![feature(const_trait_impl, effects)] #![allow(incomplete_features)] diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/span-bug-issue-121418.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/span-bug-issue-121418.stderr index 313ba4fc9565e..5ff1c6c5b9f15 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/span-bug-issue-121418.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/span-bug-issue-121418.stderr @@ -17,6 +17,11 @@ LL | #![feature(effects)] = note: see issue #102090 for more information = note: `#[warn(incomplete_features)]` on by default +error: using `#![feature(effects)]` without enabling next trait solver globally + | + = note: the next trait solver must be enabled globally for the effects feature to work correctly + = help: use `-Znext-solver` to enable + error[E0308]: mismatched types --> $DIR/span-bug-issue-121418.rs:9:27 | @@ -39,7 +44,7 @@ note: required because it appears within the type `Mutex<(dyn T + 'static)>` --> $SRC_DIR/std/src/sync/mutex.rs:LL:COL = note: the return type of a function must have a statically known size -error: aborting due to 3 previous errors; 1 warning emitted +error: aborting due to 4 previous errors; 1 warning emitted Some errors have detailed explanations: E0277, E0308. For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/spec-effectvar-ice.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/spec-effectvar-ice.stderr index 047549bca75a5..e97a9615ae1a0 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/spec-effectvar-ice.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/spec-effectvar-ice.stderr @@ -7,6 +7,11 @@ LL | #![feature(effects)] = note: see issue #102090 for more information = note: `#[warn(incomplete_features)]` on by default +error: using `#![feature(effects)]` without enabling next trait solver globally + | + = note: the next trait solver must be enabled globally for the effects feature to work correctly + = help: use `-Znext-solver` to enable + error: const `impl` for trait `Foo` which is not marked with `#[const_trait]` --> $DIR/spec-effectvar-ice.rs:12:15 | @@ -55,5 +60,5 @@ error: cannot specialize on trait `Specialize` LL | impl const Foo for T where T: const Specialize {} | ^^^^^^^^^^^^^^^^ -error: aborting due to 5 previous errors; 1 warning emitted +error: aborting due to 6 previous errors; 1 warning emitted diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/trait-fn-const.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/trait-fn-const.stderr index 33914cb306dc6..15cb84026e470 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/trait-fn-const.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/trait-fn-const.stderr @@ -63,6 +63,11 @@ LL | #![feature(const_trait_impl, effects)] = note: see issue #102090 for more information = note: `#[warn(incomplete_features)]` on by default -error: aborting due to 4 previous errors; 1 warning emitted +error: using `#![feature(effects)]` without enabling next trait solver globally + | + = note: the next trait solver must be enabled globally for the effects feature to work correctly + = help: use `-Znext-solver` to enable + +error: aborting due to 5 previous errors; 1 warning emitted For more information about this error, try `rustc --explain E0379`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/hir-const-check.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/hir-const-check.stderr index 416ba248a5f31..598129d8694e0 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/hir-const-check.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/hir-const-check.stderr @@ -17,6 +17,11 @@ LL | Some(())?; = help: add `#![feature(const_try)]` 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 1 previous error; 1 warning emitted +error: using `#![feature(effects)]` without enabling next trait solver globally + | + = note: the next trait solver must be enabled globally for the effects feature to work correctly + = help: use `-Znext-solver` to enable + +error: aborting due to 2 previous errors; 1 warning emitted For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-119717-constant-lifetime.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-119717-constant-lifetime.stderr index 9e22422ad3b94..50cdded8d5114 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-119717-constant-lifetime.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-119717-constant-lifetime.stderr @@ -1,3 +1,8 @@ +error: using `#![feature(effects)]` without enabling next trait solver globally + | + = note: the next trait solver must be enabled globally for the effects feature to work correctly + = help: use `-Znext-solver` to enable + error: const `impl` for trait `FromResidual` which is not marked with `#[const_trait]` --> $DIR/ice-119717-constant-lifetime.rs:6:15 | @@ -27,7 +32,7 @@ help: try replacing `_` with the type in the corresponding trait method signatur LL | fn from_residual(t: T) -> T { | ~ -error: aborting due to 3 previous errors +error: aborting due to 4 previous errors Some errors have detailed explanations: E0121, E0210. For more information about an error, try `rustc --explain E0121`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-120503-async-const-method.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-120503-async-const-method.stderr index 011232f30b8a6..1f309e1e85446 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-120503-async-const-method.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-120503-async-const-method.stderr @@ -55,6 +55,11 @@ LL | #![feature(effects)] = note: see issue #102090 for more information = note: `#[warn(incomplete_features)]` on by default +error: using `#![feature(effects)]` without enabling next trait solver globally + | + = note: the next trait solver must be enabled globally for the effects feature to work correctly + = help: use `-Znext-solver` to enable + error[E0425]: cannot find function `main8` in this scope --> $DIR/ice-120503-async-const-method.rs:13:9 | @@ -95,7 +100,7 @@ LL | async const fn bar(&self) { | ^^^^^^^^^^^^^^^^^^^^^^^^^ = 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 6 previous errors; 1 warning emitted +error: aborting due to 7 previous errors; 1 warning emitted Some errors have detailed explanations: E0379, E0391, E0407, E0425. For more information about an error, try `rustc --explain E0379`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-121536-const-method.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-121536-const-method.stderr index 4fe88f263c81b..29187654c3cc7 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-121536-const-method.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-121536-const-method.stderr @@ -23,6 +23,11 @@ LL | #![feature(const_trait_impl, effects)] = note: see issue #102090 for more information = note: `#[warn(incomplete_features)]` on by default -error: aborting due to 1 previous error; 1 warning emitted +error: using `#![feature(effects)]` without enabling next trait solver globally + | + = note: the next trait solver must be enabled globally for the effects feature to work correctly + = help: use `-Znext-solver` to enable + +error: aborting due to 2 previous errors; 1 warning emitted For more information about this error, try `rustc --explain E0379`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-123664-unexpected-bound-var.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-123664-unexpected-bound-var.stderr index 19369e38964f4..c937430a1ca19 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-123664-unexpected-bound-var.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-123664-unexpected-bound-var.stderr @@ -1,8 +1,13 @@ +error: using `#![feature(effects)]` without enabling next trait solver globally + | + = note: the next trait solver must be enabled globally for the effects feature to work correctly + = help: use `-Znext-solver` to enable + error: `~const` can only be applied to `#[const_trait]` traits --> $DIR/ice-123664-unexpected-bound-var.rs:4:34 | LL | const fn with_positive() {} | ^^^^ -error: aborting due to 1 previous error +error: aborting due to 2 previous errors diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-124857-combine-effect-const-infer-vars.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-124857-combine-effect-const-infer-vars.stderr index 0b1f8b40898e3..284757c1a8977 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-124857-combine-effect-const-infer-vars.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-124857-combine-effect-const-infer-vars.stderr @@ -1,3 +1,8 @@ +error: using `#![feature(effects)]` without enabling next trait solver globally + | + = note: the next trait solver must be enabled globally for the effects feature to work correctly + = help: use `-Znext-solver` to enable + error[E0119]: conflicting implementations of trait `Foo` for type `i32` --> $DIR/ice-124857-combine-effect-const-infer-vars.rs:11:1 | @@ -7,6 +12,6 @@ LL | LL | impl const Foo for T where T: ~const Foo {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `i32` -error: aborting due to 1 previous error +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0119`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-126148-failed-to-normalize.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-126148-failed-to-normalize.stderr index e641b457ef9c8..e49436c8f0f78 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-126148-failed-to-normalize.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-126148-failed-to-normalize.stderr @@ -1,3 +1,8 @@ +error: using `#![feature(effects)]` without enabling next trait solver globally + | + = note: the next trait solver must be enabled globally for the effects feature to work correctly + = help: use `-Znext-solver` to enable + error: const `impl` for trait `FromResidual` which is not marked with `#[const_trait]` --> $DIR/ice-126148-failed-to-normalize.rs:8:12 | @@ -33,6 +38,6 @@ LL | impl const Try for TryMe { = help: implement the missing item: `fn from_output(_: ::Output) -> Self { todo!() }` = help: implement the missing item: `fn branch(self) -> ControlFlow<::Residual, ::Output> { todo!() }` -error: aborting due to 4 previous errors +error: aborting due to 5 previous errors For more information about this error, try `rustc --explain E0046`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/impl-with-default-fn-fail.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/impl-with-default-fn-fail.stderr index 0135296526f96..2ea203627f435 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/impl-with-default-fn-fail.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/impl-with-default-fn-fail.stderr @@ -1,3 +1,8 @@ +error: using `#![feature(effects)]` without enabling next trait solver globally + | + = note: the next trait solver must be enabled globally for the effects feature to work correctly + = help: use `-Znext-solver` to enable + error[E0046]: not all trait items implemented, missing: `req` --> $DIR/impl-with-default-fn-fail.rs:13:1 | @@ -7,6 +12,6 @@ LL | fn req(&self); LL | impl const Tr for u16 { | ^^^^^^^^^^^^^^^^^^^^^ missing `req` in implementation -error: aborting due to 1 previous error +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0046`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/impl-with-default-fn-pass.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/impl-with-default-fn-pass.rs index 0a1d2355a75bc..2c375036941c0 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/impl-with-default-fn-pass.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/impl-with-default-fn-pass.rs @@ -1,4 +1,5 @@ //@ check-pass +//@ compile-flags: -Znext-solver #![allow(incomplete_features)] #![feature(const_trait_impl, effects)] diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-100222.nn.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-100222.nn.stderr new file mode 100644 index 0000000000000..4a949e90d8554 --- /dev/null +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-100222.nn.stderr @@ -0,0 +1,9 @@ +error[E0271]: type mismatch resolving `<() as Index>::Output == &mut <() as Index>::Output` + --> $DIR/issue-100222.rs:34:12 + | +LL | fn foo(&mut self, x: ::Output) -> ::Output + | ^^^^^^^^^ types differ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0271`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-100222.ny.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-100222.ny.stderr new file mode 100644 index 0000000000000..1bfce48d26a2d --- /dev/null +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-100222.ny.stderr @@ -0,0 +1,9 @@ +error[E0271]: type mismatch resolving `<() as Index>::Output == &mut <() as Index>::Output` + --> $DIR/issue-100222.rs:25:12 + | +LL | fn foo(&mut self, x: ::Output) -> ::Output + | ^^^^^^^^^ types differ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0271`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-100222.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-100222.rs index 10d7a3942e497..7949772a2b4e9 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-100222.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-100222.rs @@ -1,5 +1,6 @@ //@ revisions: nn ny yn yy -//@ check-pass +//@ known-bug: #110395 +//@ compile-flags: -Znext-solver #![allow(incomplete_features)] #![feature(const_trait_impl, effects, associated_type_defaults, const_mut_refs)] diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-100222.yn.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-100222.yn.stderr new file mode 100644 index 0000000000000..4a949e90d8554 --- /dev/null +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-100222.yn.stderr @@ -0,0 +1,9 @@ +error[E0271]: type mismatch resolving `<() as Index>::Output == &mut <() as Index>::Output` + --> $DIR/issue-100222.rs:34:12 + | +LL | fn foo(&mut self, x: ::Output) -> ::Output + | ^^^^^^^^^ types differ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0271`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-100222.yy.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-100222.yy.stderr new file mode 100644 index 0000000000000..1bfce48d26a2d --- /dev/null +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-100222.yy.stderr @@ -0,0 +1,9 @@ +error[E0271]: type mismatch resolving `<() as Index>::Output == &mut <() as Index>::Output` + --> $DIR/issue-100222.rs:25:12 + | +LL | fn foo(&mut self, x: ::Output) -> ::Output + | ^^^^^^^^^ types differ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0271`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-79450.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-79450.rs index 36c82dfe68485..b8b9e07b3bd60 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-79450.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-79450.rs @@ -1,5 +1,7 @@ +//@ compile-flags: -Znext-solver +#![allow(incomplete_features)] #![feature(const_fmt_arguments_new)] -#![feature(const_trait_impl, effects)] //~ WARN the feature `effects` is incomplete +#![feature(const_trait_impl, effects)] #[const_trait] trait Tr { diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-79450.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-79450.stderr index 9da31486faaff..9e6348d37ed5e 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-79450.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-79450.stderr @@ -1,14 +1,5 @@ -warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/issue-79450.rs:2:30 - | -LL | #![feature(const_trait_impl, effects)] - | ^^^^^^^ - | - = note: see issue #102090 for more information - = note: `#[warn(incomplete_features)]` on by default - error[E0015]: cannot call non-const fn `_print` in constant functions - --> $DIR/issue-79450.rs:9:9 + --> $DIR/issue-79450.rs:11:9 | LL | println!("lul"); | ^^^^^^^^^^^^^^^ @@ -16,6 +7,6 @@ LL | println!("lul"); = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants = note: this error originates in the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) -error: aborting due to 1 previous error; 1 warning emitted +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0015`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-impl-non-const-specialized-impl.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-impl-non-const-specialized-impl.stderr index 363fbee1f8bfb..c51d169dd3397 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-impl-non-const-specialized-impl.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-impl-non-const-specialized-impl.stderr @@ -7,11 +7,16 @@ LL | #![feature(const_trait_impl, effects)] = note: see issue #102090 for more information = note: `#[warn(incomplete_features)]` on by default +error: using `#![feature(effects)]` without enabling next trait solver globally + | + = note: the next trait solver must be enabled globally for the effects feature to work correctly + = help: use `-Znext-solver` to enable + error: cannot specialize on const impl with non-const impl --> $DIR/const-default-impl-non-const-specialized-impl.rs:19:1 | LL | impl Value for FortyTwo { | ^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 1 previous error; 1 warning emitted +error: aborting due to 2 previous errors; 1 warning emitted diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/specializing-constness.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/specializing-constness.stderr index 272cb26ff42e5..90721af8e5aab 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/specializing-constness.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/specializing-constness.stderr @@ -7,6 +7,11 @@ LL | #![feature(const_trait_impl, effects, min_specialization, rustc_attrs)] = note: see issue #102090 for more information = note: `#[warn(incomplete_features)]` on by default +error: using `#![feature(effects)]` without enabling next trait solver globally + | + = note: the next trait solver must be enabled globally for the effects feature to work correctly + = help: use `-Znext-solver` to enable + error: cannot specialize on const impl with non-const impl --> $DIR/specializing-constness.rs:23:1 | @@ -25,5 +30,5 @@ error: cannot specialize on trait `Compat` LL | impl A for T { | ^^^^ -error: aborting due to 3 previous errors; 1 warning emitted +error: aborting due to 4 previous errors; 1 warning emitted diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/staged-api.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/staged-api.rs index 460c2ef617438..f87e723472ad8 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/staged-api.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/staged-api.rs @@ -1,7 +1,9 @@ //@ revisions: stable unstable +//@ compile-flags: -Znext-solver #![cfg_attr(unstable, feature(unstable))] // The feature from the ./auxiliary/staged-api.rs file. -#![feature(const_trait_impl, effects)] //~ WARN the feature `effects` is incomplete +#![feature(const_trait_impl, effects)] +#![allow(incomplete_features)] #![feature(staged_api)] #![stable(feature = "rust1", since = "1.0.0")] diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/staged-api.stable.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/staged-api.stable.stderr index 0604b22ecbb3e..6c07a253f5b09 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/staged-api.stable.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/staged-api.stable.stderr @@ -1,14 +1,5 @@ -warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/staged-api.rs:4:30 - | -LL | #![feature(const_trait_impl, effects)] - | ^^^^^^^ - | - = note: see issue #102090 for more information - = note: `#[warn(incomplete_features)]` on by default - error: trait implementations cannot be const stable yet - --> $DIR/staged-api.rs:19:1 + --> $DIR/staged-api.rs:21:1 | LL | / impl const MyTrait for Foo { LL | | @@ -19,7 +10,7 @@ LL | | } = note: see issue #67792 for more information error: function has missing const stability attribute - --> $DIR/staged-api.rs:41:1 + --> $DIR/staged-api.rs:43:1 | LL | / pub const fn const_context_not_const_stable() { LL | | @@ -31,7 +22,7 @@ LL | | } | |_^ error: `::func` is not yet stable as a const fn - --> $DIR/staged-api.rs:32:5 + --> $DIR/staged-api.rs:34:5 | LL | Unstable::func(); | ^^^^^^^^^^^^^^^^ @@ -39,7 +30,7 @@ LL | Unstable::func(); = help: add `#![feature(unstable)]` to the crate attributes to enable error: `::func` is not yet stable as a const fn - --> $DIR/staged-api.rs:43:5 + --> $DIR/staged-api.rs:45:5 | LL | Unstable::func(); | ^^^^^^^^^^^^^^^^ @@ -47,12 +38,12 @@ LL | Unstable::func(); = help: add `#![feature(unstable)]` to the crate attributes to enable error: `::func` is not yet stable as a const fn - --> $DIR/staged-api.rs:53:5 + --> $DIR/staged-api.rs:55:5 | LL | Unstable::func(); | ^^^^^^^^^^^^^^^^ | = help: const-stable functions can only call other const-stable functions -error: aborting due to 5 previous errors; 1 warning emitted +error: aborting due to 5 previous errors diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/staged-api.unstable.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/staged-api.unstable.stderr index b53e7b6f6acec..1c772f13dd511 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/staged-api.unstable.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/staged-api.unstable.stderr @@ -1,14 +1,5 @@ -warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/staged-api.rs:4:30 - | -LL | #![feature(const_trait_impl, effects)] - | ^^^^^^^ - | - = note: see issue #102090 for more information - = note: `#[warn(incomplete_features)]` on by default - error: `::func` is not yet stable as a const fn - --> $DIR/staged-api.rs:34:5 + --> $DIR/staged-api.rs:36:5 | LL | Foo::func(); | ^^^^^^^^^^^ @@ -16,7 +7,7 @@ LL | Foo::func(); = help: add `#![feature(foo)]` to the crate attributes to enable error: `::func` is not yet stable as a const fn - --> $DIR/staged-api.rs:45:5 + --> $DIR/staged-api.rs:47:5 | LL | Foo::func(); | ^^^^^^^^^^^ @@ -24,7 +15,7 @@ LL | Foo::func(); = help: add `#![feature(foo)]` to the crate attributes to enable error: `::func` is not yet stable as a const fn - --> $DIR/staged-api.rs:53:5 + --> $DIR/staged-api.rs:55:5 | LL | Unstable::func(); | ^^^^^^^^^^^^^^^^ @@ -32,7 +23,7 @@ LL | Unstable::func(); = help: const-stable functions can only call other const-stable functions error: `::func` is not yet stable as a const fn - --> $DIR/staged-api.rs:55:5 + --> $DIR/staged-api.rs:57:5 | LL | Foo::func(); | ^^^^^^^^^^^ @@ -40,12 +31,12 @@ LL | Foo::func(); = help: const-stable functions can only call other const-stable functions error: `const_context_not_const_stable` is not yet stable as a const fn - --> $DIR/staged-api.rs:57:5 + --> $DIR/staged-api.rs:59:5 | LL | const_context_not_const_stable() | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: const-stable functions can only call other const-stable functions -error: aborting due to 5 previous errors; 1 warning emitted +error: aborting due to 5 previous errors diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.nn.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.nn.stderr index 3a36a5b750932..48bb1907be2eb 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.nn.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.nn.stderr @@ -1,32 +1,23 @@ error: `~const` is not allowed here - --> $DIR/super-traits-fail-2.rs:10:12 + --> $DIR/super-traits-fail-2.rs:12:12 | LL | trait Bar: ~const Foo {} | ^^^^^^ | note: this trait is not a `#[const_trait]`, so it cannot have `~const` trait bounds - --> $DIR/super-traits-fail-2.rs:10:1 + --> $DIR/super-traits-fail-2.rs:12:1 | LL | trait Bar: ~const Foo {} | ^^^^^^^^^^^^^^^^^^^^^^^^ -warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/super-traits-fail-2.rs:1:30 - | -LL | #![feature(const_trait_impl, effects)] - | ^^^^^^^ - | - = note: see issue #102090 for more information - = note: `#[warn(incomplete_features)]` on by default - error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/super-traits-fail-2.rs:10:19 + --> $DIR/super-traits-fail-2.rs:12:19 | LL | trait Bar: ~const Foo {} | ^^^ error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/super-traits-fail-2.rs:10:19 + --> $DIR/super-traits-fail-2.rs:12:19 | LL | trait Bar: ~const Foo {} | ^^^ @@ -34,12 +25,12 @@ LL | trait Bar: ~const Foo {} = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/super-traits-fail-2.rs:10:19 + --> $DIR/super-traits-fail-2.rs:12:19 | LL | trait Bar: ~const Foo {} | ^^^ | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error: aborting due to 4 previous errors; 1 warning emitted +error: aborting due to 4 previous errors diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.ny.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.ny.stderr index beb931570cb85..029c3b4bde3ec 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.ny.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.ny.stderr @@ -1,20 +1,11 @@ -warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/super-traits-fail-2.rs:1:30 - | -LL | #![feature(const_trait_impl, effects)] - | ^^^^^^^ - | - = note: see issue #102090 for more information - = note: `#[warn(incomplete_features)]` on by default - error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/super-traits-fail-2.rs:10:19 + --> $DIR/super-traits-fail-2.rs:12:19 | LL | trait Bar: ~const Foo {} | ^^^ error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/super-traits-fail-2.rs:10:19 + --> $DIR/super-traits-fail-2.rs:12:19 | LL | trait Bar: ~const Foo {} | ^^^ @@ -22,12 +13,12 @@ LL | trait Bar: ~const Foo {} = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/super-traits-fail-2.rs:10:19 + --> $DIR/super-traits-fail-2.rs:12:19 | LL | trait Bar: ~const Foo {} | ^^^ | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error: aborting due to 3 previous errors; 1 warning emitted +error: aborting due to 3 previous errors diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.rs index ba20a79a4df74..0d659744e700e 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.rs @@ -1,4 +1,6 @@ -#![feature(const_trait_impl, effects)] //~ WARN the feature `effects` is incomplete +//@ compile-flags: -Znext-solver +#![allow(incomplete_features)] +#![feature(const_trait_impl, effects)] //@ revisions: yy yn ny nn #[cfg_attr(any(yy, yn), const_trait)] diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.yn.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.yn.stderr index a4f1c94bca0bc..d4064e01ef10c 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.yn.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.yn.stderr @@ -1,32 +1,23 @@ error: `~const` is not allowed here - --> $DIR/super-traits-fail-2.rs:10:12 + --> $DIR/super-traits-fail-2.rs:12:12 | LL | trait Bar: ~const Foo {} | ^^^^^^ | note: this trait is not a `#[const_trait]`, so it cannot have `~const` trait bounds - --> $DIR/super-traits-fail-2.rs:10:1 + --> $DIR/super-traits-fail-2.rs:12:1 | LL | trait Bar: ~const Foo {} | ^^^^^^^^^^^^^^^^^^^^^^^^ -warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/super-traits-fail-2.rs:1:30 - | -LL | #![feature(const_trait_impl, effects)] - | ^^^^^^^ - | - = note: see issue #102090 for more information - = note: `#[warn(incomplete_features)]` on by default - error[E0277]: the trait bound `Foo::{synthetic#0}: ~const Compat` is not satisfied - --> $DIR/super-traits-fail-2.rs:17:7 + --> $DIR/super-traits-fail-2.rs:19:7 | LL | x.a(); | ^ the trait `~const Compat` is not implemented for `Foo::{synthetic#0}` | note: required by a bound in `Foo::a` - --> $DIR/super-traits-fail-2.rs:4:25 + --> $DIR/super-traits-fail-2.rs:6:25 | LL | #[cfg_attr(any(yy, yn), const_trait)] | ^^^^^^^^^^^ required by this bound in `Foo::a` @@ -38,6 +29,6 @@ help: consider further restricting the associated type LL | const fn foo(x: &T) where Foo::{synthetic#0}: ~const Compat { | +++++++++++++++++++++++++++++++++++++++ -error: aborting due to 2 previous errors; 1 warning emitted +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.yy.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.yy.stderr index 4e27ebc5e9ec7..9f9f96c6b486b 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.yy.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.yy.stderr @@ -1,20 +1,11 @@ -warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/super-traits-fail-2.rs:1:30 - | -LL | #![feature(const_trait_impl, effects)] - | ^^^^^^^ - | - = note: see issue #102090 for more information - = note: `#[warn(incomplete_features)]` on by default - error[E0277]: the trait bound `Foo::{synthetic#0}: ~const Compat` is not satisfied - --> $DIR/super-traits-fail-2.rs:17:7 + --> $DIR/super-traits-fail-2.rs:19:7 | LL | x.a(); | ^ the trait `~const Compat` is not implemented for `Foo::{synthetic#0}` | note: required by a bound in `Foo::a` - --> $DIR/super-traits-fail-2.rs:4:25 + --> $DIR/super-traits-fail-2.rs:6:25 | LL | #[cfg_attr(any(yy, yn), const_trait)] | ^^^^^^^^^^^ required by this bound in `Foo::a` @@ -26,6 +17,6 @@ help: consider further restricting the associated type LL | const fn foo(x: &T) where Foo::{synthetic#0}: ~const Compat { | +++++++++++++++++++++++++++++++++++++++ -error: aborting due to 1 previous error; 1 warning emitted +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.nn.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.nn.stderr index a9bf2687cb88f..f40583f0ca57f 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.nn.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.nn.stderr @@ -1,23 +1,23 @@ error: `~const` is not allowed here - --> $DIR/super-traits-fail-3.rs:13:12 + --> $DIR/super-traits-fail-3.rs:14:12 | LL | trait Bar: ~const Foo {} | ^^^^^^ | note: this trait is not a `#[const_trait]`, so it cannot have `~const` trait bounds - --> $DIR/super-traits-fail-3.rs:13:1 + --> $DIR/super-traits-fail-3.rs:14:1 | LL | trait Bar: ~const Foo {} | ^^^^^^^^^^^^^^^^^^^^^^^^ error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/super-traits-fail-3.rs:13:19 + --> $DIR/super-traits-fail-3.rs:14:19 | LL | trait Bar: ~const Foo {} | ^^^ error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/super-traits-fail-3.rs:13:19 + --> $DIR/super-traits-fail-3.rs:14:19 | LL | trait Bar: ~const Foo {} | ^^^ @@ -25,7 +25,7 @@ LL | trait Bar: ~const Foo {} = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/super-traits-fail-3.rs:13:19 + --> $DIR/super-traits-fail-3.rs:14:19 | LL | trait Bar: ~const Foo {} | ^^^ @@ -33,7 +33,7 @@ LL | trait Bar: ~const Foo {} = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/super-traits-fail-3.rs:19:24 + --> $DIR/super-traits-fail-3.rs:20:24 | LL | const fn foo(x: &T) { | ^^^ diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.ny.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.ny.stderr index c3811623c1c86..3f6dfa7b00896 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.ny.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.ny.stderr @@ -1,11 +1,11 @@ error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/super-traits-fail-3.rs:13:19 + --> $DIR/super-traits-fail-3.rs:14:19 | LL | trait Bar: ~const Foo {} | ^^^ error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/super-traits-fail-3.rs:13:19 + --> $DIR/super-traits-fail-3.rs:14:19 | LL | trait Bar: ~const Foo {} | ^^^ @@ -13,7 +13,7 @@ LL | trait Bar: ~const Foo {} = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/super-traits-fail-3.rs:13:19 + --> $DIR/super-traits-fail-3.rs:14:19 | LL | trait Bar: ~const Foo {} | ^^^ diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.rs index 24661f078b017..6694351265007 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.rs @@ -1,3 +1,4 @@ +//@ compile-flags: -Znext-solver #![allow(incomplete_features)] #![feature(const_trait_impl, effects)] diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.yn.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.yn.stderr index 34a60329eb5e2..0b48633a10e20 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.yn.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.yn.stderr @@ -1,29 +1,29 @@ error: `~const` is not allowed here - --> $DIR/super-traits-fail-3.rs:13:12 + --> $DIR/super-traits-fail-3.rs:14:12 | LL | trait Bar: ~const Foo {} | ^^^^^^ | note: this trait is not a `#[const_trait]`, so it cannot have `~const` trait bounds - --> $DIR/super-traits-fail-3.rs:13:1 + --> $DIR/super-traits-fail-3.rs:14:1 | LL | trait Bar: ~const Foo {} | ^^^^^^^^^^^^^^^^^^^^^^^^ error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/super-traits-fail-3.rs:19:24 + --> $DIR/super-traits-fail-3.rs:20:24 | LL | const fn foo(x: &T) { | ^^^ error[E0277]: the trait bound `Foo::{synthetic#0}: ~const Compat` is not satisfied - --> $DIR/super-traits-fail-3.rs:21:7 + --> $DIR/super-traits-fail-3.rs:22:7 | LL | x.a(); | ^ the trait `~const Compat` is not implemented for `Foo::{synthetic#0}` | note: required by a bound in `Foo::a` - --> $DIR/super-traits-fail-3.rs:7:25 + --> $DIR/super-traits-fail-3.rs:8:25 | LL | #[cfg_attr(any(yy, yn), const_trait)] | ^^^^^^^^^^^ required by this bound in `Foo::a` diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.yy.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.yy.stderr index 8ac20b3e06852..ea0e6c690b72b 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.yy.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.yy.stderr @@ -1,11 +1,11 @@ error[E0277]: the trait bound `Foo::{synthetic#0}: ~const Compat` is not satisfied - --> $DIR/super-traits-fail-3.rs:21:7 + --> $DIR/super-traits-fail-3.rs:22:7 | LL | x.a(); | ^ the trait `~const Compat` is not implemented for `Foo::{synthetic#0}` | note: required by a bound in `Foo::a` - --> $DIR/super-traits-fail-3.rs:7:25 + --> $DIR/super-traits-fail-3.rs:8:25 | LL | #[cfg_attr(any(yy, yn), const_trait)] | ^^^^^^^^^^^ required by this bound in `Foo::a` diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-and-const-params.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-and-const-params.stderr index b479793814cb9..73526a26e081e 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-and-const-params.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-and-const-params.stderr @@ -22,6 +22,11 @@ note: this function is not `const`, so it cannot have `~const` trait bounds LL | fn bar(_: Foo) -> Foo<{ A::add(N) }> { | ^^^ +error: using `#![feature(effects)]` without enabling next trait solver globally + | + = note: the next trait solver must be enabled globally for the effects feature to work correctly + = help: use `-Znext-solver` to enable + error[E0308]: mismatched types --> $DIR/tilde-const-and-const-params.rs:27:61 | @@ -40,6 +45,6 @@ LL | fn add(self) -> Foo<{ A::add(N) }> { = note: expected constant `false` found constant `true` -error: aborting due to 4 previous errors +error: aborting due to 5 previous errors For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-assoc-fn-in-trait-impl.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-assoc-fn-in-trait-impl.rs index 86a2bbe35ed7d..8e7202ecaa1ff 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-assoc-fn-in-trait-impl.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-assoc-fn-in-trait-impl.rs @@ -1,7 +1,8 @@ // Regression test for issue #119700. //@ check-pass - -#![feature(const_trait_impl, effects)] //~ WARN the feature `effects` is incomplete +//@ compile-flags: -Znext-solver +#![allow(incomplete_features)] +#![feature(const_trait_impl, effects)] #[const_trait] trait Main { diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-assoc-fn-in-trait-impl.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-assoc-fn-in-trait-impl.stderr deleted file mode 100644 index 70019ce57f29e..0000000000000 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-assoc-fn-in-trait-impl.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/tilde-const-assoc-fn-in-trait-impl.rs:4:30 - | -LL | #![feature(const_trait_impl, effects)] - | ^^^^^^^ - | - = note: see issue #102090 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-inherent-assoc-const-fn.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-inherent-assoc-const-fn.rs index 0f5729e3daf62..71c5d8366b2f4 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-inherent-assoc-const-fn.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-inherent-assoc-const-fn.rs @@ -1,5 +1,7 @@ //@ check-pass -#![feature(const_trait_impl, effects)] //~ WARN the feature `effects` is incomplete +//@ compile-flags: -Znext-solver +#![allow(incomplete_features)] +#![feature(const_trait_impl, effects)] #[const_trait] trait Foo { diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-inherent-assoc-const-fn.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-inherent-assoc-const-fn.stderr deleted file mode 100644 index 4ec8dac1f0d3a..0000000000000 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-inherent-assoc-const-fn.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/tilde-const-inherent-assoc-const-fn.rs:2:30 - | -LL | #![feature(const_trait_impl, effects)] - | ^^^^^^^ - | - = note: see issue #102090 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-trait-assoc-tys.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-trait-assoc-tys.rs index c2d3b2036c638..254cf2200d853 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-trait-assoc-tys.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-trait-assoc-tys.rs @@ -1,5 +1,7 @@ //@ check-pass -#![feature(const_trait_impl, effects)] //~ WARN the feature `effects` is incomplete +//@ compile-flags: -Znext-solver +#![allow(incomplete_features)] +#![feature(const_trait_impl, effects)] #[const_trait] trait Trait { diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-trait-assoc-tys.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-trait-assoc-tys.stderr deleted file mode 100644 index 1ead23d5c2c1d..0000000000000 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-trait-assoc-tys.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/tilde-const-trait-assoc-tys.rs:2:30 - | -LL | #![feature(const_trait_impl, effects)] - | ^^^^^^^ - | - = note: see issue #102090 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-default-body-stability.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-default-body-stability.rs index f41e70c99ff8a..b36e9535ca113 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-default-body-stability.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-default-body-stability.rs @@ -1,5 +1,6 @@ //@ known-bug: #110395 - +//@ compile-flags: -Znext-solver +#![allow(incomplete_features)] #![feature(staged_api)] #![feature(const_trait_impl, effects)] #![feature(const_t_try)] diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-default-body-stability.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-default-body-stability.stderr index d0c2f88005d7a..49fbef9aaa29f 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-default-body-stability.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-default-body-stability.stderr @@ -1,14 +1,5 @@ -warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/trait-default-body-stability.rs:4:30 - | -LL | #![feature(const_trait_impl, effects)] - | ^^^^^^^ - | - = note: see issue #102090 for more information - = note: `#[warn(incomplete_features)]` on by default - error: const `impl` for trait `Try` which is not marked with `#[const_trait]` - --> $DIR/trait-default-body-stability.rs:18:12 + --> $DIR/trait-default-body-stability.rs:19:12 | LL | impl const Try for T { | ^^^ @@ -17,7 +8,7 @@ LL | impl const Try for T { = note: adding a non-const method body in the future would be a breaking change error: const `impl` for trait `FromResidual` which is not marked with `#[const_trait]` - --> $DIR/trait-default-body-stability.rs:33:12 + --> $DIR/trait-default-body-stability.rs:34:12 | LL | impl const FromResidual for T { | ^^^^^^^^^^^^ @@ -25,5 +16,5 @@ LL | impl const FromResidual for T { = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` = note: adding a non-const method body in the future would be a breaking change -error: aborting due to 2 previous errors; 1 warning emitted +error: aborting due to 2 previous errors diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-const.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-const.rs index dd5de62aff529..8ca9b7cc7aa0a 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-const.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-const.rs @@ -1,3 +1,4 @@ +//@ compile-flags: -Znext-solver // Like trait-where-clause.rs, but we are calling from a const context. // Checking the validity of traits' where clauses happen at a later stage. // (`rustc_const_eval` instead of `rustc_hir_analysis`) Therefore one file as a diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-const.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-const.stderr index 877152472c16e..979f1e798e0a7 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-const.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-const.stderr @@ -1,11 +1,11 @@ error[E0277]: the trait bound `Foo::{synthetic#0}: Compat` is not satisfied - --> $DIR/trait-where-clause-const.rs:21:5 + --> $DIR/trait-where-clause-const.rs:22:5 | LL | T::b(); | ^ the trait `Compat` is not implemented for `Foo::{synthetic#0}` | note: required by a bound in `Foo::b` - --> $DIR/trait-where-clause-const.rs:12:1 + --> $DIR/trait-where-clause-const.rs:13:1 | LL | #[const_trait] | ^^^^^^^^^^^^^^ required by this bound in `Foo::b` @@ -18,7 +18,7 @@ LL | const fn test1() where Foo::{synthetic#0}: Compat { | ++++++++++++++++++++++++++++++++ error[E0308]: mismatched types - --> $DIR/trait-where-clause-const.rs:21:5 + --> $DIR/trait-where-clause-const.rs:22:5 | LL | T::b(); | ^^^^^^ expected `host`, found `true` @@ -27,13 +27,13 @@ LL | T::b(); found constant `true` error[E0277]: the trait bound `Foo::{synthetic#0}: Compat` is not satisfied - --> $DIR/trait-where-clause-const.rs:24:5 + --> $DIR/trait-where-clause-const.rs:25:5 | LL | T::c::(); | ^ the trait `Compat` is not implemented for `Foo::{synthetic#0}` | note: required by a bound in `Foo::c` - --> $DIR/trait-where-clause-const.rs:12:1 + --> $DIR/trait-where-clause-const.rs:13:1 | LL | #[const_trait] | ^^^^^^^^^^^^^^ required by this bound in `Foo::c` @@ -46,7 +46,7 @@ LL | const fn test1() where Foo::{synthetic#0}: Compat { | ++++++++++++++++++++++++++++++++ error[E0308]: mismatched types - --> $DIR/trait-where-clause-const.rs:24:5 + --> $DIR/trait-where-clause-const.rs:25:5 | LL | T::c::(); | ^^^^^^^^^^^ expected `host`, found `true` diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-self-referential.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-self-referential.rs index 59ddc2f748ede..cb5cc924bfd34 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-self-referential.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-self-referential.rs @@ -1,6 +1,7 @@ //@ check-pass - -#![feature(const_trait_impl, effects)] //~ WARN the feature `effects` is incomplete +//@ compile-flags: -Znext-solver +#![allow(incomplete_features)] +#![feature(const_trait_impl, effects)] #[const_trait] trait Foo { diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-self-referential.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-self-referential.stderr deleted file mode 100644 index 6e9e948e45cd3..0000000000000 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-self-referential.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/trait-where-clause-self-referential.rs:3:30 - | -LL | #![feature(const_trait_impl, effects)] - | ^^^^^^^ - | - = note: see issue #102090 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/stability-attribute/missing-const-stability.rs b/tests/ui/stability-attribute/missing-const-stability.rs index 62bb0239168e0..82da18cc9ac2c 100644 --- a/tests/ui/stability-attribute/missing-const-stability.rs +++ b/tests/ui/stability-attribute/missing-const-stability.rs @@ -1,3 +1,4 @@ +//@ compile-flags: -Znext-solver #![feature(staged_api)] #![feature(const_trait_impl, effects)] //~ WARN the feature `effects` is incomplete #![stable(feature = "stable", since = "1.0.0")] diff --git a/tests/ui/stability-attribute/missing-const-stability.stderr b/tests/ui/stability-attribute/missing-const-stability.stderr index 4e488124fe394..adf60c3861140 100644 --- a/tests/ui/stability-attribute/missing-const-stability.stderr +++ b/tests/ui/stability-attribute/missing-const-stability.stderr @@ -1,5 +1,5 @@ warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/missing-const-stability.rs:2:30 + --> $DIR/missing-const-stability.rs:3:30 | LL | #![feature(const_trait_impl, effects)] | ^^^^^^^ @@ -8,13 +8,13 @@ LL | #![feature(const_trait_impl, effects)] = note: `#[warn(incomplete_features)]` on by default error: function has missing const stability attribute - --> $DIR/missing-const-stability.rs:6:1 + --> $DIR/missing-const-stability.rs:7:1 | LL | pub const fn foo() {} | ^^^^^^^^^^^^^^^^^^^^^ error: implementation has missing const stability attribute - --> $DIR/missing-const-stability.rs:28:1 + --> $DIR/missing-const-stability.rs:29:1 | LL | / impl const Bar for Foo { LL | | @@ -23,7 +23,7 @@ LL | | } | |_^ error: associated function has missing const stability attribute - --> $DIR/missing-const-stability.rs:15:5 + --> $DIR/missing-const-stability.rs:16:5 | LL | pub const fn foo() {} | ^^^^^^^^^^^^^^^^^^^^^ From 69446e301cc271fca77b4d4f119540d6b82f1677 Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Sun, 30 Jun 2024 13:33:33 -0400 Subject: [PATCH 501/892] Print `TypeId` as hex for debugging In , the `Debug` impl for `TypeId` was changed to print a single integer rather than a tuple. Change this again to print as hex for more concise and consistent formatting, as was suggested. Result: TypeId(0x1378bb1c0a0202683eb65e7c11f2e4d7) --- library/core/src/any.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/core/src/any.rs b/library/core/src/any.rs index eab11ae288a95..59f3b6841d531 100644 --- a/library/core/src/any.rs +++ b/library/core/src/any.rs @@ -673,7 +673,7 @@ impl hash::Hash for TypeId { #[stable(feature = "rust1", since = "1.0.0")] impl fmt::Debug for TypeId { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { - f.debug_tuple("TypeId").field(&self.as_u128()).finish() + write!(f, "TypeId({:#034x})", self.as_u128()) } } From 8127461b0ed54dea8ca9cf430b1d231611e1b477 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sun, 30 Jun 2024 18:01:55 +0000 Subject: [PATCH 502/892] Move -Zprint-type-sizes and -Zprint-vtable-sizes into codegen_and_build_linker --- compiler/rustc_driver_impl/src/lib.rs | 17 +---------------- compiler/rustc_interface/src/queries.rs | 12 ++++++++++++ 2 files changed, 13 insertions(+), 16 deletions(-) diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index bbe9741bf444e..3780e575b9352 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -41,7 +41,6 @@ use rustc_session::getopts::{self, Matches}; use rustc_session::lint::{Lint, LintId}; use rustc_session::output::collect_crate_types; use rustc_session::{config, filesearch, EarlyDiagCtxt, Session}; -use rustc_span::def_id::LOCAL_CRATE; use rustc_span::source_map::FileLoader; use rustc_span::symbol::sym; use rustc_span::FileName; @@ -448,21 +447,7 @@ fn run_compiler( return early_exit(); } - let linker = queries.codegen_and_build_linker()?; - - // This must run after monomorphization so that all generic types - // have been instantiated. - if sess.opts.unstable_opts.print_type_sizes { - sess.code_stats.print_type_sizes(); - } - - if sess.opts.unstable_opts.print_vtable_sizes { - let crate_name = queries.global_ctxt()?.enter(|tcx| tcx.crate_name(LOCAL_CRATE)); - - sess.code_stats.print_vtable_sizes(crate_name); - } - - Ok(Some(linker)) + Ok(Some(queries.codegen_and_build_linker()?)) })?; // Linking is done outside the `compiler.enter()` so that the diff --git a/compiler/rustc_interface/src/queries.rs b/compiler/rustc_interface/src/queries.rs index cfd4304e89303..5f00d7a76b29b 100644 --- a/compiler/rustc_interface/src/queries.rs +++ b/compiler/rustc_interface/src/queries.rs @@ -121,6 +121,18 @@ impl<'tcx> Queries<'tcx> { self.global_ctxt()?.enter(|tcx| { let ongoing_codegen = passes::start_codegen(&*self.compiler.codegen_backend, tcx)?; + // This must run after monomorphization so that all generic types + // have been instantiated. + if tcx.sess.opts.unstable_opts.print_type_sizes { + tcx.sess.code_stats.print_type_sizes(); + } + + if tcx.sess.opts.unstable_opts.print_vtable_sizes { + let crate_name = tcx.crate_name(LOCAL_CRATE); + + tcx.sess.code_stats.print_vtable_sizes(crate_name); + } + Ok(Linker { dep_graph: tcx.dep_graph.clone(), output_filenames: tcx.output_filenames(()).clone(), From f6942112eb44cb292463d457c603016cc16f4bc6 Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Sun, 30 Jun 2024 11:30:22 -0700 Subject: [PATCH 503/892] Add a GVN test for 127089 that doesn't optimize to a constant --- ...ust_change_both_sides.GVN.panic-abort.diff | 16 +++++++++++++++ ...st_change_both_sides.GVN.panic-unwind.diff | 16 +++++++++++++++ tests/mir-opt/gvn.rs | 20 +++++++++++++++++++ 3 files changed, 52 insertions(+) create mode 100644 tests/mir-opt/gvn.remove_casts_must_change_both_sides.GVN.panic-abort.diff create mode 100644 tests/mir-opt/gvn.remove_casts_must_change_both_sides.GVN.panic-unwind.diff diff --git a/tests/mir-opt/gvn.remove_casts_must_change_both_sides.GVN.panic-abort.diff b/tests/mir-opt/gvn.remove_casts_must_change_both_sides.GVN.panic-abort.diff new file mode 100644 index 0000000000000..8b4bfb70401b3 --- /dev/null +++ b/tests/mir-opt/gvn.remove_casts_must_change_both_sides.GVN.panic-abort.diff @@ -0,0 +1,16 @@ +- // MIR for `remove_casts_must_change_both_sides` before GVN ++ // MIR for `remove_casts_must_change_both_sides` after GVN + + fn remove_casts_must_change_both_sides(_1: &*mut u8, _2: *mut u8) -> bool { + let mut _0: bool; + let mut _3: *const u8; + let mut _4: *const u8; + + bb0: { + _3 = (*_1) as *const u8 (PtrToPtr); + _4 = _2 as *const u8 (PtrToPtr); + _0 = Eq(_3, _4); + return; + } + } + diff --git a/tests/mir-opt/gvn.remove_casts_must_change_both_sides.GVN.panic-unwind.diff b/tests/mir-opt/gvn.remove_casts_must_change_both_sides.GVN.panic-unwind.diff new file mode 100644 index 0000000000000..8b4bfb70401b3 --- /dev/null +++ b/tests/mir-opt/gvn.remove_casts_must_change_both_sides.GVN.panic-unwind.diff @@ -0,0 +1,16 @@ +- // MIR for `remove_casts_must_change_both_sides` before GVN ++ // MIR for `remove_casts_must_change_both_sides` after GVN + + fn remove_casts_must_change_both_sides(_1: &*mut u8, _2: *mut u8) -> bool { + let mut _0: bool; + let mut _3: *const u8; + let mut _4: *const u8; + + bb0: { + _3 = (*_1) as *const u8 (PtrToPtr); + _4 = _2 as *const u8 (PtrToPtr); + _0 = Eq(_3, _4); + return; + } + } + diff --git a/tests/mir-opt/gvn.rs b/tests/mir-opt/gvn.rs index 86f42d23f3835..c7fae0bd08108 100644 --- a/tests/mir-opt/gvn.rs +++ b/tests/mir-opt/gvn.rs @@ -926,6 +926,25 @@ unsafe fn cast_pointer_then_transmute(thin: *mut u32, fat: *mut [u8]) { let fat_addr: usize = std::intrinsics::transmute(fat as *const ()); } +#[custom_mir(dialect = "analysis")] +fn remove_casts_must_change_both_sides(mut_a: &*mut u8, mut_b: *mut u8) -> bool { + // CHECK-LABEL: fn remove_casts_must_change_both_sides( + mir! { + // We'd like to remove these casts, but we can't change *both* of them + // to be locals, so make sure we don't change one without the other, as + // that would be a type error. + { + // CHECK: [[A:_.+]] = (*_1) as *const u8 (PtrToPtr); + let a = *mut_a as *const u8; + // CHECK: [[B:_.+]] = _2 as *const u8 (PtrToPtr); + let b = mut_b as *const u8; + // CHECK: _0 = Eq([[A]], [[B]]); + RET = a == b; + Return() + } + } +} + fn main() { subexpression_elimination(2, 4, 5); wrap_unwrap(5); @@ -995,3 +1014,4 @@ fn identity(x: T) -> T { // EMIT_MIR gvn.generic_cast_metadata.GVN.diff // EMIT_MIR gvn.cast_pointer_eq.GVN.diff // EMIT_MIR gvn.cast_pointer_then_transmute.GVN.diff +// EMIT_MIR gvn.remove_casts_must_change_both_sides.GVN.diff From 552794410a9237a26aded88990dbe8be26c72dfc Mon Sep 17 00:00:00 2001 From: Boxy Date: Sun, 30 Jun 2024 19:31:15 +0100 Subject: [PATCH 504/892] add `rustc_dump_def_parents` attribute --- compiler/rustc_feature/src/builtin_attrs.rs | 4 + .../rustc_hir_analysis/src/collect/dump.rs | 50 ++++++- compiler/rustc_hir_analysis/src/lib.rs | 1 + compiler/rustc_span/src/symbol.rs | 1 + tests/ui/attributes/dump_def_parents.rs | 34 +++++ tests/ui/attributes/dump_def_parents.stderr | 128 ++++++++++++++++++ 6 files changed, 217 insertions(+), 1 deletion(-) create mode 100644 tests/ui/attributes/dump_def_parents.rs create mode 100644 tests/ui/attributes/dump_def_parents.stderr diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index a4245f0908e33..910402d5499fd 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -1117,6 +1117,10 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ TEST, rustc_dump_predicates, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::No ), + rustc_attr!( + TEST, rustc_dump_def_parents, Normal, template!(Word), + WarnFollowing, EncodeCrossCrate::No + ), rustc_attr!( TEST, rustc_object_lifetime_default, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::No diff --git a/compiler/rustc_hir_analysis/src/collect/dump.rs b/compiler/rustc_hir_analysis/src/collect/dump.rs index 85e1c600d6da4..c73d3a5390d93 100644 --- a/compiler/rustc_hir_analysis/src/collect/dump.rs +++ b/compiler/rustc_hir_analysis/src/collect/dump.rs @@ -1,5 +1,7 @@ use rustc_hir::def::DefKind; -use rustc_hir::def_id::CRATE_DEF_ID; +use rustc_hir::def_id::{LocalDefId, CRATE_DEF_ID}; +use rustc_hir::intravisit; +use rustc_middle::hir::nested_filter::OnlyBodies; use rustc_middle::ty::TyCtxt; use rustc_span::sym; @@ -41,3 +43,49 @@ pub(crate) fn predicates_and_item_bounds(tcx: TyCtxt<'_>) { } } } + +pub(crate) fn def_parents(tcx: TyCtxt<'_>) { + for did in tcx.hir().body_owners() { + if tcx.has_attr(did, sym::rustc_dump_def_parents) { + struct AnonConstFinder<'tcx> { + tcx: TyCtxt<'tcx>, + anon_consts: Vec, + } + + impl<'tcx> intravisit::Visitor<'tcx> for AnonConstFinder<'tcx> { + type NestedFilter = OnlyBodies; + + fn nested_visit_map(&mut self) -> Self::Map { + self.tcx.hir() + } + + fn visit_anon_const(&mut self, c: &'tcx rustc_hir::AnonConst) { + self.anon_consts.push(c.def_id); + intravisit::walk_anon_const(self, c) + } + } + + // Look for any anon consts inside of this body owner as there is no way to apply + // the `rustc_dump_def_parents` attribute to the anon const so it would not be possible + // to see what its def parent is. + let mut anon_ct_finder = AnonConstFinder { tcx, anon_consts: vec![] }; + intravisit::walk_expr(&mut anon_ct_finder, tcx.hir().body_owned_by(did).value); + + for did in [did].into_iter().chain(anon_ct_finder.anon_consts) { + let span = tcx.def_span(did); + + let mut diag = tcx.dcx().struct_span_err( + span, + format!("{}: {did:?}", sym::rustc_dump_def_parents.as_str()), + ); + + let mut current_did = did.to_def_id(); + while let Some(parent_did) = tcx.opt_parent(current_did) { + current_did = parent_did; + diag.span_note(tcx.def_span(parent_did), format!("{parent_did:?}")); + } + diag.emit(); + } + } + } +} diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs index 0428abcdf24e8..dcf60edafe26e 100644 --- a/compiler/rustc_hir_analysis/src/lib.rs +++ b/compiler/rustc_hir_analysis/src/lib.rs @@ -169,6 +169,7 @@ pub fn check_crate(tcx: TyCtxt<'_>) { tcx.sess.time("variance_dumping", || variance::dump::variances(tcx)); collect::dump::opaque_hidden_types(tcx); collect::dump::predicates_and_item_bounds(tcx); + collect::dump::def_parents(tcx); } // Make sure we evaluate all static and (non-associated) const items, even if unused. diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 8b7a63f5eb9b6..7da9211bcbf74 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1614,6 +1614,7 @@ symbols! { rustc_do_not_const_check, rustc_doc_primitive, rustc_dummy, + rustc_dump_def_parents, rustc_dump_item_bounds, rustc_dump_predicates, rustc_dump_user_args, diff --git a/tests/ui/attributes/dump_def_parents.rs b/tests/ui/attributes/dump_def_parents.rs new file mode 100644 index 0000000000000..af1c210d2cd18 --- /dev/null +++ b/tests/ui/attributes/dump_def_parents.rs @@ -0,0 +1,34 @@ +//@ normalize-stderr-test "DefId\(.+?\)" -> "DefId(..)" +#![feature(rustc_attrs)] + +fn bar() { + fn foo() { + fn baz() { + #[rustc_dump_def_parents] + || { + //~^ ERROR: rustc_dump_def_parents: DefId + qux::< + { + //~^ ERROR: rustc_dump_def_parents: DefId + fn inhibits_dump() { + qux::< + { + "hi"; + 1 + }, + >(); + } + + qux::<{ 1 + 1 }>(); + //~^ ERROR: rustc_dump_def_parents: DefId + 1 + }, + >(); + }; + } + } +} + +const fn qux() {} + +fn main() {} diff --git a/tests/ui/attributes/dump_def_parents.stderr b/tests/ui/attributes/dump_def_parents.stderr new file mode 100644 index 0000000000000..b2cc32d09b07e --- /dev/null +++ b/tests/ui/attributes/dump_def_parents.stderr @@ -0,0 +1,128 @@ +error: rustc_dump_def_parents: DefId(..) + --> $DIR/dump_def_parents.rs:8:13 + | +LL | || { + | ^^ + | +note: DefId(..) + --> $DIR/dump_def_parents.rs:6:9 + | +LL | fn baz() { + | ^^^^^^^^ +note: DefId(..) + --> $DIR/dump_def_parents.rs:5:5 + | +LL | fn foo() { + | ^^^^^^^^ +note: DefId(..) + --> $DIR/dump_def_parents.rs:4:1 + | +LL | fn bar() { + | ^^^^^^^^ +note: DefId(..) + --> $DIR/dump_def_parents.rs:2:1 + | +LL | / #![feature(rustc_attrs)] +LL | | +LL | | fn bar() { +LL | | fn foo() { +... | +LL | | +LL | | fn main() {} + | |____________^ + +error: rustc_dump_def_parents: DefId(..) + --> $DIR/dump_def_parents.rs:11:21 + | +LL | / { +LL | | +LL | | fn inhibits_dump() { +LL | | qux::< +... | +LL | | 1 +LL | | }, + | |_____________________^ + | +note: DefId(..) + --> $DIR/dump_def_parents.rs:8:13 + | +LL | || { + | ^^ +note: DefId(..) + --> $DIR/dump_def_parents.rs:6:9 + | +LL | fn baz() { + | ^^^^^^^^ +note: DefId(..) + --> $DIR/dump_def_parents.rs:5:5 + | +LL | fn foo() { + | ^^^^^^^^ +note: DefId(..) + --> $DIR/dump_def_parents.rs:4:1 + | +LL | fn bar() { + | ^^^^^^^^ +note: DefId(..) + --> $DIR/dump_def_parents.rs:2:1 + | +LL | / #![feature(rustc_attrs)] +LL | | +LL | | fn bar() { +LL | | fn foo() { +... | +LL | | +LL | | fn main() {} + | |____________^ + +error: rustc_dump_def_parents: DefId(..) + --> $DIR/dump_def_parents.rs:22:31 + | +LL | qux::<{ 1 + 1 }>(); + | ^^^^^^^^^ + | +note: DefId(..) + --> $DIR/dump_def_parents.rs:11:21 + | +LL | / { +LL | | +LL | | fn inhibits_dump() { +LL | | qux::< +... | +LL | | 1 +LL | | }, + | |_____________________^ +note: DefId(..) + --> $DIR/dump_def_parents.rs:8:13 + | +LL | || { + | ^^ +note: DefId(..) + --> $DIR/dump_def_parents.rs:6:9 + | +LL | fn baz() { + | ^^^^^^^^ +note: DefId(..) + --> $DIR/dump_def_parents.rs:5:5 + | +LL | fn foo() { + | ^^^^^^^^ +note: DefId(..) + --> $DIR/dump_def_parents.rs:4:1 + | +LL | fn bar() { + | ^^^^^^^^ +note: DefId(..) + --> $DIR/dump_def_parents.rs:2:1 + | +LL | / #![feature(rustc_attrs)] +LL | | +LL | | fn bar() { +LL | | fn foo() { +... | +LL | | +LL | | fn main() {} + | |____________^ + +error: aborting due to 3 previous errors + From af3d7f869b7a10ee5ccd7b7f8c6ce184be480d5e Mon Sep 17 00:00:00 2001 From: Daniel Huang Date: Sun, 30 Jun 2024 14:54:05 -0400 Subject: [PATCH 505/892] Update ip_addr.rs --- library/core/src/net/ip_addr.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/core/src/net/ip_addr.rs b/library/core/src/net/ip_addr.rs index b578756e46a66..c11a508a135b3 100644 --- a/library/core/src/net/ip_addr.rs +++ b/library/core/src/net/ip_addr.rs @@ -406,7 +406,7 @@ impl IpAddr { matches!(self, IpAddr::V6(_)) } - /// Converts this address to an `IpAddr::V4` if it is an IPv4-mapped IPv6 addresses, otherwise it + /// Converts this address to an `IpAddr::V4` if it is an IPv4-mapped IPv6 address, otherwise it /// returns `self` as-is. /// /// # Examples @@ -1879,7 +1879,7 @@ impl Ipv6Addr { } } - /// Converts this address to an `IpAddr::V4` if it is an IPv4-mapped addresses, otherwise it + /// Converts this address to an `IpAddr::V4` if it is an IPv4-mapped address, otherwise it /// returns self wrapped in an `IpAddr::V6`. /// /// # Examples From 23e5468a09b7cfcb62f69dc18bb1f49c5e69b2b5 Mon Sep 17 00:00:00 2001 From: Pavel Grigorenko Date: Mon, 1 Jul 2024 00:08:42 +0300 Subject: [PATCH 506/892] LinkedList's Cursor: method to get a ref to the cursor's list --- library/alloc/src/collections/linked_list.rs | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/library/alloc/src/collections/linked_list.rs b/library/alloc/src/collections/linked_list.rs index 01510a6140512..077483a174b10 100644 --- a/library/alloc/src/collections/linked_list.rs +++ b/library/alloc/src/collections/linked_list.rs @@ -1495,6 +1495,14 @@ impl<'a, T, A: Allocator> Cursor<'a, T, A> { pub fn back(&self) -> Option<&'a T> { self.list.back() } + + /// Provides a reference to the cursor's parent list. + #[must_use] + #[inline(always)] + #[unstable(feature = "linked_list_cursors", issue = "58533")] + pub fn as_list(&self) -> &'a LinkedList { + self.list + } } impl<'a, T, A: Allocator> CursorMut<'a, T, A> { @@ -1605,6 +1613,18 @@ impl<'a, T, A: Allocator> CursorMut<'a, T, A> { pub fn as_cursor(&self) -> Cursor<'_, T, A> { Cursor { list: self.list, current: self.current, index: self.index } } + + /// Provides a read-only reference to the cursor's parent list. + /// + /// The lifetime of the returned reference is bound to that of the + /// `CursorMut`, which means it cannot outlive the `CursorMut` and that the + /// `CursorMut` is frozen for the lifetime of the reference. + #[must_use] + #[inline(always)] + #[unstable(feature = "linked_list_cursors", issue = "58533")] + pub fn as_list(&self) -> &LinkedList { + self.list + } } // Now the list editing operations From da81d0d940481827fb2bdd164ea0038832e3779e Mon Sep 17 00:00:00 2001 From: DianQK Date: Mon, 1 Jul 2024 06:03:08 +0800 Subject: [PATCH 507/892] Update LLVM submodule --- src/llvm-project | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/llvm-project b/src/llvm-project index 5a5152f653959..e6a6470d1eb4c 160000 --- a/src/llvm-project +++ b/src/llvm-project @@ -1 +1 @@ -Subproject commit 5a5152f653959d14d68613a3a8a033fb65eec021 +Subproject commit e6a6470d1eb4c88fee4b1ea98cd8e0ac4a181c16 From 4c919ac50b5fabe341b35d9440bc84dcc3388130 Mon Sep 17 00:00:00 2001 From: beetrees Date: Mon, 1 Jul 2024 00:24:56 +0100 Subject: [PATCH 508/892] Ensure `out_of_scope_macro_calls` lint is registered --- compiler/rustc_lint_defs/src/builtin.rs | 1 + tests/ui/macros/out-of-scope-macro-calls-lint-registered.rs | 6 ++++++ 2 files changed, 7 insertions(+) create mode 100644 tests/ui/macros/out-of-scope-macro-calls-lint-registered.rs diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index 472e93d202d76..2ade6964ca89e 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -74,6 +74,7 @@ declare_lint_pass! { NON_CONTIGUOUS_RANGE_ENDPOINTS, NON_EXHAUSTIVE_OMITTED_PATTERNS, ORDER_DEPENDENT_TRAIT_OBJECTS, + OUT_OF_SCOPE_MACRO_CALLS, OVERLAPPING_RANGE_ENDPOINTS, PATTERNS_IN_FNS_WITHOUT_BODY, PRIVATE_BOUNDS, diff --git a/tests/ui/macros/out-of-scope-macro-calls-lint-registered.rs b/tests/ui/macros/out-of-scope-macro-calls-lint-registered.rs new file mode 100644 index 0000000000000..0736c373d576e --- /dev/null +++ b/tests/ui/macros/out-of-scope-macro-calls-lint-registered.rs @@ -0,0 +1,6 @@ +//@ check-pass + +#![deny(unknown_lints)] +#![allow(out_of_scope_macro_calls)] + +fn main() {} From 15fbe618a14ddde520561c4cf1b85d4e4c9005f8 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Sat, 29 Jun 2024 09:34:52 -0700 Subject: [PATCH 509/892] rustdoc: update to pulldown-cmark 0.11 --- Cargo.lock | 21 ++-- compiler/rustc_resolve/Cargo.toml | 2 +- compiler/rustc_resolve/src/rustdoc.rs | 14 ++- src/librustdoc/html/markdown.rs | 111 +++++++++--------- src/librustdoc/passes/lint/bare_urls.rs | 4 +- src/librustdoc/passes/lint/html_tags.rs | 6 +- .../passes/lint/redundant_explicit_links.rs | 16 ++- src/tools/tidy/src/deps.rs | 1 + 8 files changed, 94 insertions(+), 81 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 94d70a020a4dc..3af90a252aea7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3123,25 +3123,26 @@ dependencies = [ [[package]] name = "pulldown-cmark" -version = "0.9.6" +version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57206b407293d2bcd3af849ce869d52068623f19e1b5ff8e8778e3309439682b" +checksum = "76979bea66e7875e7509c4ec5300112b316af87fa7a252ca91c448b32dfe3993" dependencies = [ "bitflags 2.5.0", + "getopts", "memchr", + "pulldown-cmark-escape 0.10.1", "unicase", ] [[package]] name = "pulldown-cmark" -version = "0.10.3" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76979bea66e7875e7509c4ec5300112b316af87fa7a252ca91c448b32dfe3993" +checksum = "8746739f11d39ce5ad5c2520a9b75285310dbfe78c541ccf832d38615765aec0" dependencies = [ "bitflags 2.5.0", - "getopts", "memchr", - "pulldown-cmark-escape", + "pulldown-cmark-escape 0.11.0", "unicase", ] @@ -3151,6 +3152,12 @@ version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bd348ff538bc9caeda7ee8cad2d1d48236a1f443c1fa3913c6a02fe0043b1dd3" +[[package]] +name = "pulldown-cmark-escape" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "007d8adb5ddab6f8e3f491ac63566a7d5002cc7ed73901f72057943fa71ae1ae" + [[package]] name = "pulldown-cmark-to-cmark" version = "13.0.0" @@ -4604,7 +4611,7 @@ name = "rustc_resolve" version = "0.0.0" dependencies = [ "bitflags 2.5.0", - "pulldown-cmark 0.9.6", + "pulldown-cmark 0.11.0", "rustc_arena", "rustc_ast", "rustc_ast_pretty", diff --git a/compiler/rustc_resolve/Cargo.toml b/compiler/rustc_resolve/Cargo.toml index b6ae54010c242..b71853b871dc5 100644 --- a/compiler/rustc_resolve/Cargo.toml +++ b/compiler/rustc_resolve/Cargo.toml @@ -6,7 +6,7 @@ edition = "2021" [dependencies] # tidy-alphabetical-start bitflags = "2.4.1" -pulldown-cmark = { version = "0.9.6", default-features = false } +pulldown-cmark = { version = "0.11", features = ["html"], default-features = false } rustc_arena = { path = "../rustc_arena" } rustc_ast = { path = "../rustc_ast" } rustc_ast_pretty = { path = "../rustc_ast_pretty" } diff --git a/compiler/rustc_resolve/src/rustdoc.rs b/compiler/rustc_resolve/src/rustdoc.rs index 66b4981eb55ba..594608153211d 100644 --- a/compiler/rustc_resolve/src/rustdoc.rs +++ b/compiler/rustc_resolve/src/rustdoc.rs @@ -1,4 +1,6 @@ -use pulldown_cmark::{BrokenLink, CowStr, Event, LinkType, Options, Parser, Tag}; +use pulldown_cmark::{ + BrokenLink, BrokenLinkCallback, CowStr, Event, LinkType, Options, Parser, Tag, +}; use rustc_ast as ast; use rustc_ast::util::comments::beautify_doc_string; use rustc_data_structures::fx::FxHashMap; @@ -427,7 +429,9 @@ fn parse_links<'md>(doc: &'md str) -> Vec> { while let Some(event) = event_iter.next() { match event { - Event::Start(Tag::Link(link_type, dest, _)) if may_be_doc_link(link_type) => { + Event::Start(Tag::Link { link_type, dest_url, title: _, id: _ }) + if may_be_doc_link(link_type) => + { if matches!( link_type, LinkType::Inline @@ -441,7 +445,7 @@ fn parse_links<'md>(doc: &'md str) -> Vec> { } } - links.push(preprocess_link(&dest)); + links.push(preprocess_link(&dest_url)); } _ => {} } @@ -451,8 +455,8 @@ fn parse_links<'md>(doc: &'md str) -> Vec> { } /// Collects additional data of link. -fn collect_link_data<'input, 'callback>( - event_iter: &mut Parser<'input, 'callback>, +fn collect_link_data<'input, F: BrokenLinkCallback<'input>>( + event_iter: &mut Parser<'input, F>, ) -> Option> { let mut display_text: Option = None; let mut append_text = |text: CowStr<'_>| { diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index bae929c64eab2..a7f0df5afa98f 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -54,7 +54,8 @@ use crate::html::render::small_url_encode; use crate::html::toc::TocBuilder; use pulldown_cmark::{ - html, BrokenLink, CodeBlockKind, CowStr, Event, LinkType, OffsetIter, Options, Parser, Tag, + html, BrokenLink, BrokenLinkCallback, CodeBlockKind, CowStr, Event, LinkType, OffsetIter, + Options, Parser, Tag, TagEnd, }; #[cfg(test)] @@ -230,7 +231,7 @@ impl<'a, I: Iterator>> Iterator for CodeBlocks<'_, 'a, I> { let mut original_text = String::new(); for event in &mut self.inner { match event { - Event::End(Tag::CodeBlock(..)) => break, + Event::End(TagEnd::CodeBlock) => break, Event::Text(ref s) => { original_text.push_str(s); } @@ -359,16 +360,17 @@ impl<'a, I: Iterator>> Iterator for LinkReplacer<'a, I> { match &mut event { // This is a shortcut link that was resolved by the broken_link_callback: `[fn@f]` // Remove any disambiguator. - Some(Event::Start(Tag::Link( + Some(Event::Start(Tag::Link { // [fn@f] or [fn@f][] - LinkType::ShortcutUnknown | LinkType::CollapsedUnknown, - dest, + link_type: LinkType::ShortcutUnknown | LinkType::CollapsedUnknown, + dest_url, title, - ))) => { - debug!("saw start of shortcut link to {dest} with title {title}"); + .. + })) => { + debug!("saw start of shortcut link to {dest_url} with title {title}"); // If this is a shortcut link, it was resolved by the broken_link_callback. // So the URL will already be updated properly. - let link = self.links.iter().find(|&link| *link.href == **dest); + let link = self.links.iter().find(|&link| *link.href == **dest_url); // Since this is an external iterator, we can't replace the inner text just yet. // Store that we saw a link so we know to replace it later. if let Some(link) = link { @@ -381,16 +383,9 @@ impl<'a, I: Iterator>> Iterator for LinkReplacer<'a, I> { } } // Now that we're done with the shortcut link, don't replace any more text. - Some(Event::End(Tag::Link( - LinkType::ShortcutUnknown | LinkType::CollapsedUnknown, - dest, - _, - ))) => { - debug!("saw end of shortcut link to {dest}"); - if self.links.iter().any(|link| *link.href == **dest) { - assert!(self.shortcut_link.is_some(), "saw closing link without opening tag"); - self.shortcut_link = None; - } + Some(Event::End(TagEnd::Link)) if self.shortcut_link.is_some() => { + debug!("saw end of shortcut link"); + self.shortcut_link = None; } // Handle backticks in inline code blocks, but only if we're in the middle of a shortcut link. // [`fn@f`] @@ -433,9 +428,11 @@ impl<'a, I: Iterator>> Iterator for LinkReplacer<'a, I> { } // If this is a link, but not a shortcut link, // replace the URL, since the broken_link_callback was not called. - Some(Event::Start(Tag::Link(_, dest, title))) => { - if let Some(link) = self.links.iter().find(|&link| *link.original_text == **dest) { - *dest = CowStr::Borrowed(link.href.as_ref()); + Some(Event::Start(Tag::Link { dest_url, title, .. })) => { + if let Some(link) = + self.links.iter().find(|&link| *link.original_text == **dest_url) + { + *dest_url = CowStr::Borrowed(link.href.as_ref()); if title.is_empty() && !link.tooltip.is_empty() { *title = CowStr::Borrowed(link.tooltip.as_ref()); } @@ -477,9 +474,9 @@ impl<'a, I: Iterator>> Iterator for TableWrapper<'a, I> { self.stored_events.push_back(Event::Start(Tag::Table(t))); Event::Html(CowStr::Borrowed("
")) } - Event::End(Tag::Table(t)) => { + Event::End(TagEnd::Table) => { self.stored_events.push_back(Event::Html(CowStr::Borrowed("
"))); - Event::End(Tag::Table(t)) + Event::End(TagEnd::Table) } e => e, }) @@ -519,11 +516,11 @@ impl<'a, 'b, 'ids, I: Iterator>> Iterator } let event = self.inner.next(); - if let Some((Event::Start(Tag::Heading(level, _, _)), _)) = event { + if let Some((Event::Start(Tag::Heading { level, .. }), _)) = event { let mut id = String::new(); for event in &mut self.inner { match &event.0 { - Event::End(Tag::Heading(..)) => break, + Event::End(TagEnd::Heading(_)) => break, Event::Text(text) | Event::Code(text) => { id.extend(text.chars().filter_map(slugify)); self.buf.push_back(event); @@ -566,27 +563,27 @@ impl<'a, I: Iterator>> SummaryLine<'a, I> { } } -fn check_if_allowed_tag(t: &Tag<'_>) -> bool { +fn check_if_allowed_tag(t: &TagEnd) -> bool { matches!( t, - Tag::Paragraph - | Tag::Emphasis - | Tag::Strong - | Tag::Strikethrough - | Tag::Link(..) - | Tag::BlockQuote + TagEnd::Paragraph + | TagEnd::Emphasis + | TagEnd::Strong + | TagEnd::Strikethrough + | TagEnd::Link + | TagEnd::BlockQuote ) } -fn is_forbidden_tag(t: &Tag<'_>) -> bool { +fn is_forbidden_tag(t: &TagEnd) -> bool { matches!( t, - Tag::CodeBlock(_) - | Tag::Table(_) - | Tag::TableHead - | Tag::TableRow - | Tag::TableCell - | Tag::FootnoteDefinition(_) + TagEnd::CodeBlock + | TagEnd::Table + | TagEnd::TableHead + | TagEnd::TableRow + | TagEnd::TableCell + | TagEnd::FootnoteDefinition ) } @@ -604,12 +601,12 @@ impl<'a, I: Iterator>> Iterator for SummaryLine<'a, I> { let mut is_start = true; let is_allowed_tag = match event { Event::Start(ref c) => { - if is_forbidden_tag(c) { + if is_forbidden_tag(&c.to_end()) { self.skipped_tags += 1; return None; } self.depth += 1; - check_if_allowed_tag(c) + check_if_allowed_tag(&c.to_end()) } Event::End(ref c) => { if is_forbidden_tag(c) { @@ -633,7 +630,7 @@ impl<'a, I: Iterator>> Iterator for SummaryLine<'a, I> { if is_start { Some(Event::Start(Tag::Paragraph)) } else { - Some(Event::End(Tag::Paragraph)) + Some(Event::End(TagEnd::Paragraph)) } } else { Some(event) @@ -679,7 +676,7 @@ impl<'a, I: Iterator>> Iterator for Footnotes<'a, I> { Some((Event::Start(Tag::FootnoteDefinition(def)), _)) => { let mut content = Vec::new(); for (event, _) in &mut self.inner { - if let Event::End(Tag::FootnoteDefinition(..)) = event { + if let Event::End(TagEnd::FootnoteDefinition) = event { break; } content.push(event); @@ -696,7 +693,7 @@ impl<'a, I: Iterator>> Iterator for Footnotes<'a, I> { for (mut content, id) in v { write!(ret, "
  • ").unwrap(); let mut is_paragraph = false; - if let Some(&Event::End(Tag::Paragraph)) = content.last() { + if let Some(&Event::End(TagEnd::Paragraph)) = content.last() { content.pop(); is_paragraph = true; } @@ -806,7 +803,7 @@ pub(crate) fn find_codes( tests.visit_test(text, block_info, line); prev_offset = offset.start; } - Event::Start(Tag::Heading(level, _, _)) => { + Event::Start(Tag::Heading { level, .. }) => { register_header = Some(level as u32); } Event::Text(ref s) if register_header.is_some() => { @@ -1432,7 +1429,7 @@ impl MarkdownItemInfo<'_> { // Treat inline HTML as plain text. let p = p.map(|event| match event.0 { - Event::Html(text) => (Event::Text(text), event.1), + Event::Html(text) | Event::InlineHtml(text) => (Event::Text(text), event.1), _ => event, }); @@ -1442,7 +1439,7 @@ impl MarkdownItemInfo<'_> { let p = Footnotes::new(p); let p = TableWrapper::new(p.map(|(ev, _)| ev)); let p = p.filter(|event| { - !matches!(event, Event::Start(Tag::Paragraph) | Event::End(Tag::Paragraph)) + !matches!(event, Event::Start(Tag::Paragraph) | Event::End(TagEnd::Paragraph)) }); html::push_html(&mut s, p); @@ -1472,7 +1469,7 @@ impl MarkdownSummaryLine<'_> { let mut s = String::new(); let without_paragraphs = LinkReplacer::new(&mut summary, links).filter(|event| { - !matches!(event, Event::Start(Tag::Paragraph) | Event::End(Tag::Paragraph)) + !matches!(event, Event::Start(Tag::Paragraph) | Event::End(TagEnd::Paragraph)) }); html::push_html(&mut s, without_paragraphs); @@ -1544,8 +1541,8 @@ fn markdown_summary_with_limit( _ => {} }, Event::End(tag) => match tag { - Tag::Emphasis | Tag::Strong => buf.close_tag(), - Tag::Paragraph | Tag::Heading(..) => return ControlFlow::Break(()), + TagEnd::Emphasis | TagEnd::Strong => buf.close_tag(), + TagEnd::Paragraph | TagEnd::Heading(_) => return ControlFlow::Break(()), _ => {} }, Event::HardBreak | Event::SoftBreak => buf.push(" ")?, @@ -1605,8 +1602,8 @@ pub(crate) fn plain_text_summary(md: &str, link_names: &[RenderedLink]) -> Strin } Event::HardBreak | Event::SoftBreak => s.push(' '), Event::Start(Tag::CodeBlock(..)) => break, - Event::End(Tag::Paragraph) => break, - Event::End(Tag::Heading(..)) => break, + Event::End(TagEnd::Paragraph) => break, + Event::End(TagEnd::Heading(..)) => break, _ => (), } } @@ -1765,7 +1762,7 @@ pub(crate) fn markdown_links<'md, R>( while let Some((event, span)) = event_iter.next() { match event { - Event::Start(Tag::Link(link_type, dest, _)) if may_be_doc_link(link_type) => { + Event::Start(Tag::Link { link_type, dest_url, .. }) if may_be_doc_link(link_type) => { let range = match link_type { // Link is pulled from the link itself. LinkType::ReferenceUnknown | LinkType::ShortcutUnknown => { @@ -1775,7 +1772,7 @@ pub(crate) fn markdown_links<'md, R>( LinkType::Inline => span_for_offset_backward(span, b'(', b')'), // Link is pulled from elsewhere in the document. LinkType::Reference | LinkType::Collapsed | LinkType::Shortcut => { - span_for_link(&dest, span) + span_for_link(&dest_url, span) } LinkType::Autolink | LinkType::Email => unreachable!(), }; @@ -1795,7 +1792,7 @@ pub(crate) fn markdown_links<'md, R>( if let Some(link) = preprocess_link(MarkdownLink { kind: link_type, - link: dest.into_string(), + link: dest_url.into_string(), display_text, range, }) { @@ -1810,8 +1807,8 @@ pub(crate) fn markdown_links<'md, R>( } /// Collects additional data of link. -fn collect_link_data<'input, 'callback>( - event_iter: &mut OffsetIter<'input, 'callback>, +fn collect_link_data<'input, F: BrokenLinkCallback<'input>>( + event_iter: &mut OffsetIter<'input, F>, ) -> Option { let mut display_text: Option = None; let mut append_text = |text: CowStr<'_>| { diff --git a/src/librustdoc/passes/lint/bare_urls.rs b/src/librustdoc/passes/lint/bare_urls.rs index 8f68f6ff4764a..4b2d3092837e1 100644 --- a/src/librustdoc/passes/lint/bare_urls.rs +++ b/src/librustdoc/passes/lint/bare_urls.rs @@ -42,11 +42,11 @@ pub(super) fn visit_item(cx: &DocContext<'_>, item: &Item) { match event { Event::Text(s) => find_raw_urls(cx, &s, range, &report_diag), // We don't want to check the text inside code blocks or links. - Event::Start(tag @ (Tag::CodeBlock(_) | Tag::Link(..))) => { + Event::Start(tag @ (Tag::CodeBlock(_) | Tag::Link { .. })) => { while let Some((event, _)) = p.next() { match event { Event::End(end) - if mem::discriminant(&end) == mem::discriminant(&tag) => + if mem::discriminant(&end) == mem::discriminant(&tag.to_end()) => { break; } diff --git a/src/librustdoc/passes/lint/html_tags.rs b/src/librustdoc/passes/lint/html_tags.rs index a0064a9011254..87dfa5d5389d7 100644 --- a/src/librustdoc/passes/lint/html_tags.rs +++ b/src/librustdoc/passes/lint/html_tags.rs @@ -4,7 +4,7 @@ use crate::clean::*; use crate::core::DocContext; use crate::html::markdown::main_body_opts; -use pulldown_cmark::{BrokenLink, Event, LinkType, Parser, Tag}; +use pulldown_cmark::{BrokenLink, Event, LinkType, Parser, Tag, TagEnd}; use rustc_resolve::rustdoc::source_span_for_markdown_range; use std::iter::Peekable; @@ -140,10 +140,10 @@ pub(crate) fn visit_item(cx: &DocContext<'_>, item: &Item) { for (event, range) in p { match event { Event::Start(Tag::CodeBlock(_)) => in_code_block = true, - Event::Html(text) if !in_code_block => { + Event::Html(text) | Event::InlineHtml(text) if !in_code_block => { extract_tags(&mut tags, &text, range, &mut is_in_comment, &report_diag) } - Event::End(Tag::CodeBlock(_)) => in_code_block = false, + Event::End(TagEnd::CodeBlock) => in_code_block = false, _ => {} } } diff --git a/src/librustdoc/passes/lint/redundant_explicit_links.rs b/src/librustdoc/passes/lint/redundant_explicit_links.rs index 7ab974046b9c7..b36b41c9f2d2e 100644 --- a/src/librustdoc/passes/lint/redundant_explicit_links.rs +++ b/src/librustdoc/passes/lint/redundant_explicit_links.rs @@ -1,6 +1,8 @@ use std::ops::Range; -use pulldown_cmark::{BrokenLink, CowStr, Event, LinkType, OffsetIter, Parser, Tag}; +use pulldown_cmark::{ + BrokenLink, BrokenLinkCallback, CowStr, Event, LinkType, OffsetIter, Parser, Tag, +}; use rustc_ast::NodeId; use rustc_errors::SuggestionStyle; use rustc_hir::def::{DefKind, DocLinkResMap, Namespace, Res}; @@ -95,7 +97,7 @@ fn check_redundant_explicit_link<'md>( while let Some((event, link_range)) = offset_iter.next() { match event { - Event::Start(Tag::Link(link_type, dest, _)) => { + Event::Start(Tag::Link { link_type, dest_url, .. }) => { let link_data = collect_link_data(&mut offset_iter); if let Some(resolvable_link) = link_data.resolvable_link.as_ref() { @@ -108,7 +110,7 @@ fn check_redundant_explicit_link<'md>( } } - let explicit_link = dest.to_string(); + let explicit_link = dest_url.to_string(); let display_link = link_data.resolvable_link.clone()?; if explicit_link.ends_with(&display_link) || display_link.ends_with(&explicit_link) @@ -122,7 +124,7 @@ fn check_redundant_explicit_link<'md>( doc, resolutions, link_range, - dest.to_string(), + dest_url.to_string(), link_data, if link_type == LinkType::Inline { (b'(', b')') @@ -139,7 +141,7 @@ fn check_redundant_explicit_link<'md>( doc, resolutions, link_range, - &dest, + &dest_url, link_data, ); } @@ -259,7 +261,9 @@ fn find_resolution(resolutions: &DocLinkResMap, path: &str) -> Option) -> LinkData { +fn collect_link_data<'input, F: BrokenLinkCallback<'input>>( + offset_iter: &mut OffsetIter<'input, F>, +) -> LinkData { let mut resolvable_link = None; let mut resolvable_link_range = None; let mut display_link = String::new(); diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs index aa119819aaa26..82fa43f581fde 100644 --- a/src/tools/tidy/src/deps.rs +++ b/src/tools/tidy/src/deps.rs @@ -335,6 +335,7 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[ "proc-macro2", "psm", "pulldown-cmark", + "pulldown-cmark-escape", "punycode", "quote", "r-efi", From 583b5fcad762d88dea0c1589e2aa6bff980848cd Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sat, 29 Jun 2024 14:49:27 -0400 Subject: [PATCH 510/892] Use full expr span for return suggestion on type error/ambiguity --- .../rustc_hir_typeck/src/fn_ctxt/checks.rs | 3 +- .../return/tail-expr-as-potential-return.rs | 36 ++++++++++++++----- .../tail-expr-as-potential-return.stderr | 33 +++++++++++++---- 3 files changed, 56 insertions(+), 16 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index 1138642c56d61..f4f3f24316716 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -2042,7 +2042,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } if block_num > 1 && found_semi { err.span_suggestion_verbose( - span.shrink_to_lo(), + // use the span of the *whole* expr + self.tcx.hir().span(binding_hir_id).shrink_to_lo(), "you might have meant to return this to infer its type parameters", "return ", Applicability::MaybeIncorrect, diff --git a/tests/ui/return/tail-expr-as-potential-return.rs b/tests/ui/return/tail-expr-as-potential-return.rs index 37dee1c19db8c..11ecddb049b57 100644 --- a/tests/ui/return/tail-expr-as-potential-return.rs +++ b/tests/ui/return/tail-expr-as-potential-return.rs @@ -1,3 +1,5 @@ +//@ edition:2018 + // > Suggest returning tail expressions that match return type // > // > Some newcomers are confused by the behavior of tail expressions, @@ -8,24 +10,24 @@ // // This test was amended to also serve as a regression test for #92308, where // this suggestion would not trigger with async functions. -// -//@ edition:2018 fn main() { } fn foo(x: bool) -> Result { if x { - Err(42) //~ ERROR mismatched types - //| HELP you might have meant to return this value + Err(42) + //~^ ERROR mismatched types + //~| HELP you might have meant to return this value } Ok(42.0) } async fn bar(x: bool) -> Result { if x { - Err(42) //~ ERROR mismatched types - //| HELP you might have meant to return this value + Err(42) + //~^ ERROR mismatched types + //~| HELP you might have meant to return this value } Ok(42.0) } @@ -40,8 +42,26 @@ impl Identity for T { async fn foo2() -> i32 { if true { - 1i32 //~ ERROR mismatched types - //| HELP you might have meant to return this value + 1i32 + //~^ ERROR mismatched types + //~| HELP you might have meant to return this value } 0 } + +struct Receiver; +impl Receiver { + fn generic(self) -> Option { + None + } +} +fn method() -> Option { + if true { + Receiver.generic(); + //~^ ERROR type annotations needed + //~| HELP consider specifying the generic argument + //~| HELP you might have meant to return this to infer its type parameters + } + + None +} diff --git a/tests/ui/return/tail-expr-as-potential-return.stderr b/tests/ui/return/tail-expr-as-potential-return.stderr index ccb208fc6c4ae..635a9e06633ff 100644 --- a/tests/ui/return/tail-expr-as-potential-return.stderr +++ b/tests/ui/return/tail-expr-as-potential-return.stderr @@ -1,10 +1,11 @@ error[E0308]: mismatched types - --> $DIR/tail-expr-as-potential-return.rs:27:9 + --> $DIR/tail-expr-as-potential-return.rs:28:9 | LL | / if x { LL | | Err(42) | | ^^^^^^^ expected `()`, found `Result<_, {integer}>` -LL | | //| HELP you might have meant to return this value +LL | | +LL | | LL | | } | |_____- expected this to be `()` | @@ -16,12 +17,13 @@ LL | return Err(42); | ++++++ + error[E0308]: mismatched types - --> $DIR/tail-expr-as-potential-return.rs:43:9 + --> $DIR/tail-expr-as-potential-return.rs:45:9 | LL | / if true { LL | | 1i32 | | ^^^^ expected `()`, found `i32` -LL | | //| HELP you might have meant to return this value +LL | | +LL | | LL | | } | |_____- expected this to be `()` | @@ -36,7 +38,8 @@ error[E0308]: mismatched types LL | / if x { LL | | Err(42) | | ^^^^^^^ expected `()`, found `Result<_, {integer}>` -LL | | //| HELP you might have meant to return this value +LL | | +LL | | LL | | } | |_____- expected this to be `()` | @@ -47,6 +50,22 @@ help: you might have meant to return this value LL | return Err(42); | ++++++ + -error: aborting due to 3 previous errors +error[E0282]: type annotations needed + --> $DIR/tail-expr-as-potential-return.rs:60:18 + | +LL | Receiver.generic(); + | ^^^^^^^ cannot infer type of the type parameter `T` declared on the method `generic` + | +help: consider specifying the generic argument + | +LL | Receiver.generic::(); + | +++++ +help: you might have meant to return this to infer its type parameters + | +LL | return Receiver.generic(); + | ++++++ + +error: aborting due to 4 previous errors -For more information about this error, try `rustc --explain E0308`. +Some errors have detailed explanations: E0282, E0308. +For more information about an error, try `rustc --explain E0282`. From 9732251e5f36772bb030ec4e3b8f6fc4f8371eec Mon Sep 17 00:00:00 2001 From: B I Mohammed Abbas Date: Mon, 1 Jul 2024 11:13:30 +0530 Subject: [PATCH 511/892] Remove unqualified import io:: Error for vxworks as all Error references are qualified in process_vxworks.rs --- library/std/src/sys/pal/unix/process/process_vxworks.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/std/src/sys/pal/unix/process/process_vxworks.rs b/library/std/src/sys/pal/unix/process/process_vxworks.rs index 76179e0910d9e..5007dbd34b4ab 100644 --- a/library/std/src/sys/pal/unix/process/process_vxworks.rs +++ b/library/std/src/sys/pal/unix/process/process_vxworks.rs @@ -1,5 +1,5 @@ use crate::fmt; -use crate::io::{self, Error, ErrorKind}; +use crate::io::{self, ErrorKind}; use crate::num::NonZero; use crate::sys; use crate::sys::cvt; From b3ef0e8487286b90e60261b9ac8d26dbb91b7e99 Mon Sep 17 00:00:00 2001 From: Amanda Stjerna Date: Thu, 13 Jun 2024 16:35:29 +0200 Subject: [PATCH 512/892] Handle universe leaks by rewriting the constraint graph This version is a squash-rebased version of a series of exiermental commits, since large parts of them were broken out into PR #125069. It explicitly handles universe violations in higher-kinded outlives constraints by adding extra outlives static constraints. --- .../rustc_borrowck/src/constraints/mod.rs | 84 +++++++++++++++++ .../src/diagnostics/region_errors.rs | 3 +- .../rustc_borrowck/src/region_infer/mod.rs | 89 +++++-------------- compiler/rustc_middle/src/mir/query.rs | 3 + 4 files changed, 111 insertions(+), 68 deletions(-) diff --git a/compiler/rustc_borrowck/src/constraints/mod.rs b/compiler/rustc_borrowck/src/constraints/mod.rs index b54e05b2b34a4..9a76539f57998 100644 --- a/compiler/rustc_borrowck/src/constraints/mod.rs +++ b/compiler/rustc_borrowck/src/constraints/mod.rs @@ -1,4 +1,6 @@ +use crate::region_infer::{ConstraintSccs, RegionDefinition, RegionTracker}; use crate::type_check::Locations; +use crate::universal_regions::UniversalRegions; use rustc_index::{IndexSlice, IndexVec}; use rustc_middle::mir::ConstraintCategory; use rustc_middle::ty::{RegionVid, TyCtxt, VarianceDiagInfo}; @@ -48,6 +50,88 @@ impl<'tcx> OutlivesConstraintSet<'tcx> { ) -> &IndexSlice> { &self.outlives } + + /// Computes cycles (SCCs) in the graph of regions. In particular, + /// find all regions R1, R2 such that R1: R2 and R2: R1 and group + /// them into an SCC, and find the relationships between SCCs. + pub(crate) fn compute_sccs( + &self, + static_region: RegionVid, + definitions: &IndexVec>, + ) -> ConstraintSccs { + let constraint_graph = self.graph(definitions.len()); + let region_graph = &constraint_graph.region_graph(self, static_region); + ConstraintSccs::new_with_annotation(®ion_graph, |r| { + RegionTracker::new(r, &definitions[r]) + }) + } + + /// This method handles universe errors by rewriting the constraint + /// graph. For each strongly connected component in the constraint + /// graph such that there is a series of constraints + /// A: B: C: ... : X where + /// A's universe is smaller than X's and A is a placeholder, + /// add A: 'static. + /// + /// For a more precise definition, see the documentation for + /// [`RegionTracker::has_incompatible_universes()`]. + /// + /// Every constraint added by this method is an + /// `IllegalUniverse` constraint. + #[instrument(skip(self, universal_regions, definitions))] + pub(crate) fn add_outlives_static( + &mut self, + universal_regions: &UniversalRegions<'tcx>, + definitions: &IndexVec>, + ) -> ConstraintSccs { + let fr_static = universal_regions.fr_static; + let sccs = self.compute_sccs(fr_static, definitions); + + // Changed to `true` if we added any constraints to `self` and need to + // recompute SCCs. + let mut added_constraints = false; + + for scc in sccs.all_sccs() { + // No point in adding 'static: 'static! + // This micro-optimisation makes somewhat sense + // because static outlives *everything*. + if scc == sccs.scc(fr_static) { + continue; + } + + let annotation = sccs.annotation(scc); + + // If this SCC participates in a universe violation, + // e.g. if it reaches a region with a universe smaller than + // the largest region reached, add a requirement that it must + // outlive `'static`. + if annotation.has_incompatible_universes() { + // Optimisation opportunity: this will add more constraints than + // needed for correctness, since an SCC upstream of another with + // a universe violation will "infect" its downstream SCCs to also + // outlive static. + added_constraints = true; + let scc_representative_outlives_static = OutlivesConstraint { + sup: annotation.representative, + sub: fr_static, + category: ConstraintCategory::IllegalUniverse, + locations: Locations::All(rustc_span::DUMMY_SP), + span: rustc_span::DUMMY_SP, + variance_info: VarianceDiagInfo::None, + from_closure: false, + }; + self.push(scc_representative_outlives_static); + } + } + + if added_constraints { + // We changed the constraint set and so must recompute SCCs. + self.compute_sccs(fr_static, definitions) + } else { + // If we didn't add any back-edges; no more work needs doing + sccs + } + } } impl<'tcx> Index for OutlivesConstraintSet<'tcx> { diff --git a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs index db78edc45b9de..61f107db784ad 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs @@ -66,7 +66,8 @@ impl<'tcx> ConstraintDescription for ConstraintCategory<'tcx> { ConstraintCategory::Predicate(_) | ConstraintCategory::Boring | ConstraintCategory::BoringNoLocation - | ConstraintCategory::Internal => "", + | ConstraintCategory::Internal + | ConstraintCategory::IllegalUniverse => "", } } } diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs index c56eaaff076ce..78e0b4783c3aa 100644 --- a/compiler/rustc_borrowck/src/region_infer/mod.rs +++ b/compiler/rustc_borrowck/src/region_infer/mod.rs @@ -62,7 +62,7 @@ pub struct RegionTracker { /// The representative Region Variable Id for this SCC. We prefer /// placeholders over existentially quantified variables, otherwise /// it's the one with the smallest Region Variable ID. - representative: RegionVid, + pub(crate) representative: RegionVid, /// Is the current representative a placeholder? representative_is_placeholder: bool, @@ -97,7 +97,7 @@ impl scc::Annotation for RegionTracker { } impl RegionTracker { - fn new(rvid: RegionVid, definition: &RegionDefinition<'_>) -> Self { + pub(crate) fn new(rvid: RegionVid, definition: &RegionDefinition<'_>) -> Self { let (representative_is_placeholder, representative_is_existential) = match definition.origin { rustc_infer::infer::NllRegionVariableOrigin::FreeRegion => (false, false), @@ -132,7 +132,7 @@ impl RegionTracker { /// Returns `true` if during the annotated SCC reaches a placeholder /// with a universe larger than the smallest reachable one, `false` otherwise. - pub fn has_incompatible_universes(&self) -> bool { + pub(crate) fn has_incompatible_universes(&self) -> bool { self.universe().cannot_name(self.max_placeholder_universe_reached) } } @@ -163,7 +163,7 @@ pub struct RegionInferenceContext<'tcx> { /// The SCC computed from `constraints` and the constraint /// graph. We have an edge from SCC A to SCC B if `A: B`. Used to /// compute the values of each region. - constraint_sccs: Rc, + constraint_sccs: ConstraintSccs, /// Reverse of the SCC constraint graph -- i.e., an edge `A -> B` exists if /// `B: A`. This is used to compute the universal regions that are required @@ -401,7 +401,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { universal_regions: Rc>, placeholder_indices: Rc, universal_region_relations: Frozen>, - outlives_constraints: OutlivesConstraintSet<'tcx>, + mut outlives_constraints: OutlivesConstraintSet<'tcx>, member_constraints_in: MemberConstraintSet<'tcx, RegionVid>, universe_causes: FxIndexMap>, type_tests: Vec>, @@ -419,17 +419,10 @@ impl<'tcx> RegionInferenceContext<'tcx> { .map(|info| RegionDefinition::new(info.universe, info.origin)) .collect(); - let fr_static = universal_regions.fr_static; + let constraint_sccs = + outlives_constraints.add_outlives_static(&universal_regions, &definitions); let constraints = Frozen::freeze(outlives_constraints); let constraint_graph = Frozen::freeze(constraints.graph(definitions.len())); - let constraint_sccs = { - let constraint_graph = constraints.graph(definitions.len()); - let region_graph = &constraint_graph.region_graph(&constraints, fr_static); - let sccs = ConstraintSccs::new_with_annotation(®ion_graph, |r| { - RegionTracker::new(r, &definitions[r]) - }); - Rc::new(sccs) - }; if cfg!(debug_assertions) { sccs_info(infcx, &constraint_sccs); @@ -548,21 +541,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { } NllRegionVariableOrigin::Placeholder(placeholder) => { - // Each placeholder region is only visible from - // its universe `ui` and its extensions. So we - // can't just add it into `scc` unless the - // universe of the scc can name this region. - let scc_universe = self.scc_universe(scc); - if scc_universe.can_name(placeholder.universe) { - self.scc_values.add_element(scc, placeholder); - } else { - debug!( - "init_free_and_bound_regions: placeholder {:?} is \ - not compatible with universe {:?} of its SCC {:?}", - placeholder, scc_universe, scc, - ); - self.add_incompatible_universe(scc); - } + self.scc_values.add_element(scc, placeholder); } NllRegionVariableOrigin::Existential { .. } => { @@ -744,23 +723,10 @@ impl<'tcx> RegionInferenceContext<'tcx> { /// (which is assured by iterating over SCCs in dependency order). #[instrument(skip(self), level = "debug")] fn compute_value_for_scc(&mut self, scc_a: ConstraintSccIndex) { - let constraint_sccs = self.constraint_sccs.clone(); - // Walk each SCC `B` such that `A: B`... - for &scc_b in constraint_sccs.successors(scc_a) { + for &scc_b in self.constraint_sccs.successors(scc_a) { debug!(?scc_b); - - // ...and add elements from `B` into `A`. One complication - // arises because of universes: If `B` contains something - // that `A` cannot name, then `A` can only contain `B` if - // it outlives static. - if self.universe_compatible(scc_b, scc_a) { - // `A` can name everything that is in `B`, so just - // merge the bits. - self.scc_values.add_region(scc_a, scc_b); - } else { - self.add_incompatible_universe(scc_a); - } + self.scc_values.add_region(scc_a, scc_b); } // Now take member constraints into account. @@ -886,35 +852,20 @@ impl<'tcx> RegionInferenceContext<'tcx> { /// in `scc_a`. Used during constraint propagation, and only once /// the value of `scc_b` has been computed. fn universe_compatible(&self, scc_b: ConstraintSccIndex, scc_a: ConstraintSccIndex) -> bool { - let universe_a = self.constraint_sccs().annotation(scc_a).universe(); - let universe_b = self.constraint_sccs().annotation(scc_b).universe(); + let a_annotation = self.constraint_sccs().annotation(scc_a); + let b_annotation = self.constraint_sccs().annotation(scc_b); + let a_universe = a_annotation.universe(); - // Quick check: if scc_b's declared universe is a subset of + // If scc_b's declared universe is a subset of // scc_a's declared universe (typically, both are ROOT), then // it cannot contain any problematic universe elements. - if universe_a.can_name(universe_b) { + if a_universe.can_name(b_annotation.universe()) { return true; } - // Otherwise, we have to iterate over the universe elements in - // B's value, and check whether all of them are nameable - // from universe_a - self.scc_values.placeholders_contained_in(scc_b).all(|p| universe_a.can_name(p.universe)) - } - - /// Extend `scc` so that it can outlive some placeholder region - /// from a universe it can't name; at present, the only way for - /// this to be true is if `scc` outlives `'static`. This is - /// actually stricter than necessary: ideally, we'd support bounds - /// like `for<'a: 'b>` that might then allow us to approximate - /// `'a` with `'b` and not `'static`. But it will have to do for - /// now. - fn add_incompatible_universe(&mut self, scc: ConstraintSccIndex) { - debug!("add_incompatible_universe(scc={:?})", scc); - - let fr_static = self.universal_regions.fr_static; - self.scc_values.add_all_points(scc); - self.scc_values.add_element(scc, fr_static); + // Otherwise, there can be no placeholder in `b` with a too high + // universe index to name from `a`. + a_universe.can_name(b_annotation.max_placeholder_universe_reached) } /// Once regions have been propagated, this method is used to see @@ -1896,6 +1847,10 @@ impl<'tcx> RegionInferenceContext<'tcx> { // This loop can be hot. for constraint in outgoing_edges_from_graph { + if matches!(constraint.category, ConstraintCategory::IllegalUniverse) { + debug!("Ignoring illegal universe constraint: {constraint:?}"); + continue; + } handle_constraint(constraint); } diff --git a/compiler/rustc_middle/src/mir/query.rs b/compiler/rustc_middle/src/mir/query.rs index 46b38e4a6a60c..cd8e28522ecfb 100644 --- a/compiler/rustc_middle/src/mir/query.rs +++ b/compiler/rustc_middle/src/mir/query.rs @@ -274,6 +274,9 @@ pub enum ConstraintCategory<'tcx> { /// A constraint that doesn't correspond to anything the user sees. Internal, + + /// An internal constraint derived from an illegal universe relation. + IllegalUniverse, } #[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Hash)] From b5b97dccaeb764c7dc0e7877941808acabb1cc8c Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 1 Jul 2024 10:45:55 +0200 Subject: [PATCH 513/892] Improve `run-make-support` API for `assert*` functions --- src/tools/run-make-support/src/command.rs | 8 ++++---- src/tools/run-make-support/src/lib.rs | 12 +++++++++--- tests/run-make/compressed-debuginfo/rmake.rs | 4 ++-- 3 files changed, 15 insertions(+), 9 deletions(-) diff --git a/src/tools/run-make-support/src/command.rs b/src/tools/run-make-support/src/command.rs index 0a1bd9b0b34f5..ee651704c6fd0 100644 --- a/src/tools/run-make-support/src/command.rs +++ b/src/tools/run-make-support/src/command.rs @@ -185,14 +185,14 @@ impl CompletedProcess { /// Checks that `stdout` does not contain `unexpected`. #[track_caller] pub fn assert_stdout_not_contains>(&self, unexpected: S) -> &Self { - assert_not_contains(&self.stdout_utf8(), unexpected.as_ref()); + assert_not_contains(&self.stdout_utf8(), unexpected); self } /// Checks that `stdout` contains `expected`. #[track_caller] pub fn assert_stdout_contains>(&self, expected: S) -> &Self { - assert_contains(&self.stdout_utf8(), expected.as_ref()); + assert_contains(&self.stdout_utf8(), expected); self } @@ -206,14 +206,14 @@ impl CompletedProcess { /// Checks that `stderr` contains `expected`. #[track_caller] pub fn assert_stderr_contains>(&self, expected: S) -> &Self { - assert_contains(&self.stderr_utf8(), expected.as_ref()); + assert_contains(&self.stderr_utf8(), expected); self } /// Checks that `stderr` does not contain `unexpected`. #[track_caller] pub fn assert_stderr_not_contains>(&self, unexpected: S) -> &Self { - assert_not_contains(&self.stdout_utf8(), unexpected.as_ref()); + assert_not_contains(&self.stdout_utf8(), unexpected); self } diff --git a/src/tools/run-make-support/src/lib.rs b/src/tools/run-make-support/src/lib.rs index df417722e024f..294dae109425f 100644 --- a/src/tools/run-make-support/src/lib.rs +++ b/src/tools/run-make-support/src/lib.rs @@ -409,7 +409,9 @@ pub fn read_dir(dir: impl AsRef, mut callback: F) { /// Check that `actual` is equal to `expected`. Panic otherwise. #[track_caller] -pub fn assert_equals(actual: &str, expected: &str) { +pub fn assert_equals, S2: AsRef>(actual: S1, expected: S2) { + let actual = actual.as_ref(); + let expected = expected.as_ref(); if actual != expected { eprintln!("=== ACTUAL TEXT ==="); eprintln!("{}", actual); @@ -421,7 +423,9 @@ pub fn assert_equals(actual: &str, expected: &str) { /// Check that `haystack` contains `needle`. Panic otherwise. #[track_caller] -pub fn assert_contains(haystack: &str, needle: &str) { +pub fn assert_contains, S2: AsRef>(haystack: S1, needle: S2) { + let haystack = haystack.as_ref(); + let needle = needle.as_ref(); if !haystack.contains(needle) { eprintln!("=== HAYSTACK ==="); eprintln!("{}", haystack); @@ -433,7 +437,9 @@ pub fn assert_contains(haystack: &str, needle: &str) { /// Check that `haystack` does not contain `needle`. Panic otherwise. #[track_caller] -pub fn assert_not_contains(haystack: &str, needle: &str) { +pub fn assert_not_contains, S2: AsRef>(haystack: S1, needle: S2) { + let haystack = haystack.as_ref(); + let needle = needle.as_ref(); if haystack.contains(needle) { eprintln!("=== HAYSTACK ==="); eprintln!("{}", haystack); diff --git a/tests/run-make/compressed-debuginfo/rmake.rs b/tests/run-make/compressed-debuginfo/rmake.rs index 9c6d50ab243cd..58eb2d6b1b39d 100644 --- a/tests/run-make/compressed-debuginfo/rmake.rs +++ b/tests/run-make/compressed-debuginfo/rmake.rs @@ -23,8 +23,8 @@ fn check_compression(compression: &str, to_find: &str) { cmd("readelf").arg("-t").arg("foo.o").run().assert_stdout_contains(to_find); } else { assert_contains( - &stderr, - &format!("unknown debuginfo compression algorithm {compression}"), + stderr, + format!("unknown debuginfo compression algorithm {compression}"), ); } }); From fcfac05657acf387392f853904c917ac06c082c5 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 1 Jul 2024 10:55:43 +0200 Subject: [PATCH 514/892] Improve `target` method API in `run-make-support` --- src/tools/run-make-support/src/rustc.rs | 3 ++- src/tools/run-make-support/src/rustdoc.rs | 3 ++- tests/run-make/comment-section/rmake.rs | 2 +- tests/run-make/inaccessible-temp-dir/rmake.rs | 2 +- tests/run-make/static-pie/rmake.rs | 2 +- 5 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/tools/run-make-support/src/rustc.rs b/src/tools/run-make-support/src/rustc.rs index df843d74fc927..3f23c1b8f9e76 100644 --- a/src/tools/run-make-support/src/rustc.rs +++ b/src/tools/run-make-support/src/rustc.rs @@ -201,7 +201,8 @@ impl Rustc { } /// Specify the target triple, or a path to a custom target json spec file. - pub fn target(&mut self, target: &str) -> &mut Self { + pub fn target>(&mut self, target: S) -> &mut Self { + let target = target.as_ref(); self.cmd.arg(format!("--target={target}")); self } diff --git a/src/tools/run-make-support/src/rustdoc.rs b/src/tools/run-make-support/src/rustdoc.rs index fb00427b1c199..2be962ad88828 100644 --- a/src/tools/run-make-support/src/rustdoc.rs +++ b/src/tools/run-make-support/src/rustdoc.rs @@ -104,7 +104,8 @@ impl Rustdoc { } /// Specify the target triple, or a path to a custom target json spec file. - pub fn target(&mut self, target: &str) -> &mut Self { + pub fn target>(&mut self, target: S) -> &mut Self { + let target = target.as_ref(); self.cmd.arg(format!("--target={target}")); self } diff --git a/tests/run-make/comment-section/rmake.rs b/tests/run-make/comment-section/rmake.rs index 41df04da7a578..188c6dcb25d2e 100644 --- a/tests/run-make/comment-section/rmake.rs +++ b/tests/run-make/comment-section/rmake.rs @@ -21,7 +21,7 @@ fn main() { .stdin("fn main() {}") .emit("link,obj") .arg("-Csave-temps") - .target(&target) + .target(target) .run(); // Check linked output has a `.comment` section with the expected content. diff --git a/tests/run-make/inaccessible-temp-dir/rmake.rs b/tests/run-make/inaccessible-temp-dir/rmake.rs index c6bfae4cc01db..6b3e9e0b29e38 100644 --- a/tests/run-make/inaccessible-temp-dir/rmake.rs +++ b/tests/run-make/inaccessible-temp-dir/rmake.rs @@ -28,7 +28,7 @@ fn main() { // Run rustc with `-Z temps-dir` set to a directory *inside* the inaccessible one, // so that it can't create `tmp`. rustc() - .target(&target()) + .target(target()) .input("program.rs") .arg("-Ztemps-dir=inaccessible/tmp") .run_fail() diff --git a/tests/run-make/static-pie/rmake.rs b/tests/run-make/static-pie/rmake.rs index 77c5e253bc03a..6a92f92328eec 100644 --- a/tests/run-make/static-pie/rmake.rs +++ b/tests/run-make/static-pie/rmake.rs @@ -51,7 +51,7 @@ fn test(compiler: &str) { rustc() .input("test-aslr.rs") - .target(&target()) + .target(target()) .linker(compiler) .arg("-Clinker-flavor=gcc") .arg("-Ctarget-feature=+crt-static") From eea5cf87b29c1ab4b2dc50a1a6dca87ec3628b19 Mon Sep 17 00:00:00 2001 From: Amanda Stjerna Date: Mon, 1 Jul 2024 11:32:45 +0200 Subject: [PATCH 515/892] Code review: rename the method `min_universe()` --- compiler/rustc_borrowck/src/region_infer/mod.rs | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs index 78e0b4783c3aa..44a84fb9d7f1a 100644 --- a/compiler/rustc_borrowck/src/region_infer/mod.rs +++ b/compiler/rustc_borrowck/src/region_infer/mod.rs @@ -116,7 +116,9 @@ impl RegionTracker { representative_is_existential, } } - fn universe(self) -> UniverseIndex { + + /// The smallest-indexed universe reachable from and/or in this SCC. + fn min_universe(self) -> UniverseIndex { self.min_reachable_universe } @@ -133,7 +135,7 @@ impl RegionTracker { /// Returns `true` if during the annotated SCC reaches a placeholder /// with a universe larger than the smallest reachable one, `false` otherwise. pub(crate) fn has_incompatible_universes(&self) -> bool { - self.universe().cannot_name(self.max_placeholder_universe_reached) + self.min_universe().cannot_name(self.max_placeholder_universe_reached) } } @@ -780,7 +782,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { // If the member region lives in a higher universe, we currently choose // the most conservative option by leaving it unchanged. - if !self.constraint_sccs().annotation(scc).universe().is_root() { + if !self.constraint_sccs().annotation(scc).min_universe().is_root() { return; } @@ -854,12 +856,12 @@ impl<'tcx> RegionInferenceContext<'tcx> { fn universe_compatible(&self, scc_b: ConstraintSccIndex, scc_a: ConstraintSccIndex) -> bool { let a_annotation = self.constraint_sccs().annotation(scc_a); let b_annotation = self.constraint_sccs().annotation(scc_b); - let a_universe = a_annotation.universe(); + let a_universe = a_annotation.min_universe(); // If scc_b's declared universe is a subset of // scc_a's declared universe (typically, both are ROOT), then // it cannot contain any problematic universe elements. - if a_universe.can_name(b_annotation.universe()) { + if a_universe.can_name(b_annotation.min_universe()) { return true; } @@ -973,7 +975,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { "lower_bound = {:?} r_scc={:?} universe={:?}", lower_bound, r_scc, - self.constraint_sccs.annotation(r_scc).universe() + self.constraint_sccs.annotation(r_scc).min_universe() ); // If the type test requires that `T: 'a` where `'a` is a @@ -1490,7 +1492,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { /// The minimum universe of any variable reachable from this /// SCC, inside or outside of it. fn scc_universe(&self, scc: ConstraintSccIndex) -> UniverseIndex { - self.constraint_sccs().annotation(scc).universe() + self.constraint_sccs().annotation(scc).min_universe() } /// Checks the final value for the free region `fr` to see if it /// grew too large. In particular, examine what `end(X)` points From 9be3a3d761060a047667226bd742346f8c25c6cf Mon Sep 17 00:00:00 2001 From: Amanda Stjerna Date: Mon, 1 Jul 2024 11:51:28 +0200 Subject: [PATCH 516/892] Add description for why this PR was made --- .../rustc_borrowck/src/constraints/mod.rs | 28 +++++++++++++++++-- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_borrowck/src/constraints/mod.rs b/compiler/rustc_borrowck/src/constraints/mod.rs index 9a76539f57998..bb2fc3b67e9d0 100644 --- a/compiler/rustc_borrowck/src/constraints/mod.rs +++ b/compiler/rustc_borrowck/src/constraints/mod.rs @@ -66,18 +66,40 @@ impl<'tcx> OutlivesConstraintSet<'tcx> { }) } - /// This method handles universe errors by rewriting the constraint + /// This method handles Universe errors by rewriting the constraint /// graph. For each strongly connected component in the constraint /// graph such that there is a series of constraints /// A: B: C: ... : X where /// A's universe is smaller than X's and A is a placeholder, - /// add A: 'static. + /// add a constraint that A: 'static. This is a safe upper bound + /// in the face of borrow checker/trait solver limitations that will + /// eventually go away. /// /// For a more precise definition, see the documentation for /// [`RegionTracker::has_incompatible_universes()`]. /// + /// This edge case used to be handled during constraint propagation + /// by iterating over the strongly connected components in the constraint + /// graph while maintaining a set of bookkeeping mappings similar + /// to what is stored in `RegionTracker` and manually adding 'sttaic as + /// needed. + /// + /// It was rewritten as part of the Polonius project with the goal of moving + /// higher-kindedness concerns out of the path of the borrow checker, + /// for two reasons: + /// + /// 1. Implementing Polonius is difficult enough without also + /// handling them. + /// 2. The long-term goal is to handle higher-kinded concerns + /// in the trait solver, where they belong. This avoids + /// logic duplication and allows future trait solvers + /// to compute better bounds than for example our + /// "must outlive 'static" here. + /// + /// This code is a stop-gap measure in preparation for the future trait solver. + /// /// Every constraint added by this method is an - /// `IllegalUniverse` constraint. + /// internal `IllegalUniverse` constraint. #[instrument(skip(self, universal_regions, definitions))] pub(crate) fn add_outlives_static( &mut self, From fe6f3fa107389f3b46235b97aa7330e54ad241e6 Mon Sep 17 00:00:00 2001 From: onur-ozkan Date: Sun, 30 Jun 2024 23:52:28 +0300 Subject: [PATCH 517/892] improve the way bootstrap handles rustlib components When CI rustc is enabled, bootstrap tries to symlink the rust source (project root) into target sysroot right before copying it from the CI rustc's sysroot. This becomes a problem in CI builders (which we currently don't see because they don't use CI rustc) because the copying part will fail as they run on read-only mode. This change fixes the problem by copying `rustc-src` from the CI rustc sysroot and only symlinking `rustc-src` from the rust source when download-rustc is not enabled. Signed-off-by: onur-ozkan --- src/bootstrap/src/core/build_steps/compile.rs | 52 +++++++++---------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs index a6172589dbb0f..6893ea883b11a 100644 --- a/src/bootstrap/src/core/build_steps/compile.rs +++ b/src/bootstrap/src/core/build_steps/compile.rs @@ -161,9 +161,10 @@ impl Step for Std { // This check is specific to testing std itself; see `test::Std` for more details. && !self.force_recompile { + let sysroot = builder.ensure(Sysroot { compiler, force_recompile: false }); cp_rustc_component_to_ci_sysroot( builder, - compiler, + &sysroot, builder.config.ci_rust_std_contents(), ); return; @@ -797,12 +798,7 @@ impl Step for StartupObjects { } } -fn cp_rustc_component_to_ci_sysroot( - builder: &Builder<'_>, - compiler: Compiler, - contents: Vec, -) { - let sysroot = builder.ensure(Sysroot { compiler, force_recompile: false }); +fn cp_rustc_component_to_ci_sysroot(builder: &Builder<'_>, sysroot: &Path, contents: Vec) { let ci_rustc_dir = builder.config.ci_rustc_dir(); for file in contents { @@ -881,13 +877,7 @@ impl Step for Rustc { // NOTE: the ABI of the beta compiler is different from the ABI of the downloaded compiler, // so its artifacts can't be reused. if builder.download_rustc() && compiler.stage != 0 { - // Copy the existing artifacts instead of rebuilding them. - // NOTE: this path is only taken for tools linking to rustc-dev (including ui-fulldeps tests). - cp_rustc_component_to_ci_sysroot( - builder, - compiler, - builder.config.ci_rustc_dev_contents(), - ); + builder.ensure(Sysroot { compiler, force_recompile: false }); return compiler.stage; } @@ -1646,19 +1636,29 @@ impl Step for Sysroot { ); } } - // Same for the rustc-src component. - let sysroot_lib_rustlib_rustcsrc = sysroot.join("lib/rustlib/rustc-src"); - t!(fs::create_dir_all(&sysroot_lib_rustlib_rustcsrc)); - let sysroot_lib_rustlib_rustcsrc_rust = sysroot_lib_rustlib_rustcsrc.join("rust"); - if let Err(e) = - symlink_dir(&builder.config, &builder.src, &sysroot_lib_rustlib_rustcsrc_rust) - { - eprintln!( - "WARNING: creating symbolic link `{}` to `{}` failed with {}", - sysroot_lib_rustlib_rustcsrc_rust.display(), - builder.src.display(), - e, + + // Unlike rust-src component, we have to handle rustc-src a bit differently. + // When using CI rustc, we copy rustc-src component from its sysroot, + // otherwise we handle it in a similar way what we do for rust-src above. + if builder.download_rustc() { + cp_rustc_component_to_ci_sysroot( + builder, + &sysroot, + builder.config.ci_rustc_dev_contents(), ); + } else { + let sysroot_lib_rustlib_rustcsrc = sysroot.join("lib/rustlib/rustc-src"); + t!(fs::create_dir_all(&sysroot_lib_rustlib_rustcsrc)); + let sysroot_lib_rustlib_rustcsrc_rust = sysroot_lib_rustlib_rustcsrc.join("rust"); + if let Err(e) = + symlink_dir(&builder.config, &builder.src, &sysroot_lib_rustlib_rustcsrc_rust) + { + eprintln!( + "WARNING: creating symbolic link `{}` to `{}` failed with {}", + sysroot_lib_rustlib_rustcsrc_rust.display(), + builder.src.display(), + e, + ); } sysroot From 61963fabdf2eaf9a68be970dfad7eb470a0fc0d5 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Mon, 1 Jul 2024 10:14:42 +0000 Subject: [PATCH 518/892] Avoid an ICE reachable through const eval shenanigans --- .../rustc_hir_typeck/src/method/confirm.rs | 9 ++-- .../arbitrary-self-from-method-substs-ice.rs | 29 ++++++++++++ ...bitrary-self-from-method-substs-ice.stderr | 46 +++++++++++++++++++ ...ary-self-from-method-substs.default.stderr | 1 - 4 files changed, 81 insertions(+), 4 deletions(-) create mode 100644 tests/ui/self/arbitrary-self-from-method-substs-ice.rs create mode 100644 tests/ui/self/arbitrary-self-from-method-substs-ice.stderr diff --git a/compiler/rustc_hir_typeck/src/method/confirm.rs b/compiler/rustc_hir_typeck/src/method/confirm.rs index 120e3239d1f1b..02844bcadac6e 100644 --- a/compiler/rustc_hir_typeck/src/method/confirm.rs +++ b/compiler/rustc_hir_typeck/src/method/confirm.rs @@ -510,9 +510,12 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> { .report_mismatched_types(&cause, method_self_ty, self_ty, terr) .emit(); } else { - error!("{self_ty} was a subtype of {method_self_ty} but now is not?"); - // This must already have errored elsewhere. - self.dcx().has_errors().unwrap(); + // This has/will have errored in wfcheck, which we cannot depend on from here, as typeck on functions + // may run before wfcheck if the function is used in const eval. + self.dcx().span_delayed_bug( + cause.span(), + format!("{self_ty} was a subtype of {method_self_ty} but now is not?"), + ); } } } diff --git a/tests/ui/self/arbitrary-self-from-method-substs-ice.rs b/tests/ui/self/arbitrary-self-from-method-substs-ice.rs new file mode 100644 index 0000000000000..8bf9f97e0b91d --- /dev/null +++ b/tests/ui/self/arbitrary-self-from-method-substs-ice.rs @@ -0,0 +1,29 @@ +//! The same as the non-ICE test, but const eval will run typeck of +//! `get` before running wfcheck (as that may in itself trigger const +//! eval again, and thus cause bogus cycles). This used to ICE because +//! we asserted that an error had already been emitted. + +use std::ops::Deref; + +struct Foo(u32); +impl Foo { + const fn get>(self: R) -> u32 { + //~^ ERROR: `R` cannot be used as the type of `self` + //~| ERROR destructor of `R` cannot be evaluated at compile-time + self.0 + //~^ ERROR cannot borrow here, since the borrowed element may contain interior mutability + //~| ERROR cannot call non-const fn `::deref` in constant function + } +} + +const FOO: () = { + let foo = Foo(1); + foo.get::<&Foo>(); +}; + +const BAR: [(); { + FOO; + 0 +}] = []; + +fn main() {} diff --git a/tests/ui/self/arbitrary-self-from-method-substs-ice.stderr b/tests/ui/self/arbitrary-self-from-method-substs-ice.stderr new file mode 100644 index 0000000000000..9e3851f9a6e72 --- /dev/null +++ b/tests/ui/self/arbitrary-self-from-method-substs-ice.stderr @@ -0,0 +1,46 @@ +error[E0658]: cannot borrow here, since the borrowed element may contain interior mutability + --> $DIR/arbitrary-self-from-method-substs-ice.rs:13:9 + | +LL | self.0 + | ^^^^ + | + = note: see issue #80384 for more information + = help: add `#![feature(const_refs_to_cell)]` 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[E0015]: cannot call non-const fn `::deref` in constant functions + --> $DIR/arbitrary-self-from-method-substs-ice.rs:13:9 + | +LL | self.0 + | ^^^^^^ + | + = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants +help: add `#![feature(const_trait_impl)]` to the crate attributes to enable + | +LL + #![feature(const_trait_impl)] + | + +error[E0493]: destructor of `R` cannot be evaluated at compile-time + --> $DIR/arbitrary-self-from-method-substs-ice.rs:10:43 + | +LL | const fn get>(self: R) -> u32 { + | ^^^^ the destructor for this type cannot be evaluated in constant functions +... +LL | } + | - value is dropped here + +error[E0658]: `R` cannot be used as the type of `self` without the `arbitrary_self_types` feature + --> $DIR/arbitrary-self-from-method-substs-ice.rs:10:49 + | +LL | const fn get>(self: R) -> u32 { + | ^ + | + = note: see issue #44874 for more information + = help: add `#![feature(arbitrary_self_types)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

    ` (where P is one of the previous types except `Self`) + +error: aborting due to 4 previous errors + +Some errors have detailed explanations: E0015, E0493, E0658. +For more information about an error, try `rustc --explain E0015`. diff --git a/tests/ui/self/arbitrary-self-from-method-substs.default.stderr b/tests/ui/self/arbitrary-self-from-method-substs.default.stderr index 6fff086a89c2e..4cc69666b8876 100644 --- a/tests/ui/self/arbitrary-self-from-method-substs.default.stderr +++ b/tests/ui/self/arbitrary-self-from-method-substs.default.stderr @@ -9,7 +9,6 @@ LL | fn get>(self: R) -> u32 { = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

    ` (where P is one of the previous types except `Self`) - ERROR rustc_hir_typeck::method::confirm Foo was a subtype of &Foo but now is not? error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0658`. From 97415ce6e792fecf5bfa5be20745c0f0f377dc51 Mon Sep 17 00:00:00 2001 From: onur-ozkan Date: Mon, 1 Jul 2024 11:47:32 +0300 Subject: [PATCH 519/892] fail on component linking errors Signed-off-by: onur-ozkan --- src/bootstrap/src/core/build_steps/compile.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs index 6893ea883b11a..de3b938e42731 100644 --- a/src/bootstrap/src/core/build_steps/compile.rs +++ b/src/bootstrap/src/core/build_steps/compile.rs @@ -1624,17 +1624,18 @@ impl Step for Sysroot { let sysroot_lib_rustlib_src_rust = sysroot_lib_rustlib_src.join("rust"); if let Err(e) = symlink_dir(&builder.config, &builder.src, &sysroot_lib_rustlib_src_rust) { eprintln!( - "WARNING: creating symbolic link `{}` to `{}` failed with {}", + "ERROR: creating symbolic link `{}` to `{}` failed with {}", sysroot_lib_rustlib_src_rust.display(), builder.src.display(), e, ); if builder.config.rust_remap_debuginfo { eprintln!( - "WARNING: some `tests/ui` tests will fail when lacking `{}`", + "ERROR: some `tests/ui` tests will fail when lacking `{}`", sysroot_lib_rustlib_src_rust.display(), ); } + build_helper::exit!(1); } // Unlike rust-src component, we have to handle rustc-src a bit differently. @@ -1654,11 +1655,13 @@ impl Step for Sysroot { symlink_dir(&builder.config, &builder.src, &sysroot_lib_rustlib_rustcsrc_rust) { eprintln!( - "WARNING: creating symbolic link `{}` to `{}` failed with {}", + "ERROR: creating symbolic link `{}` to `{}` failed with {}", sysroot_lib_rustlib_rustcsrc_rust.display(), builder.src.display(), e, ); + build_helper::exit!(1); + } } sysroot From 9d5da39b3a4d3155dca12db9eb7ea6be6234e8a6 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Mon, 1 Jul 2024 10:26:27 +0000 Subject: [PATCH 520/892] Revert some ICE avoiding logic that is not necessary anymore --- compiler/rustc_hir_typeck/src/writeback.rs | 25 +++------------------- 1 file changed, 3 insertions(+), 22 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/writeback.rs b/compiler/rustc_hir_typeck/src/writeback.rs index aea0114167eb9..ceb7480686d90 100644 --- a/compiler/rustc_hir_typeck/src/writeback.rs +++ b/compiler/rustc_hir_typeck/src/writeback.rs @@ -219,28 +219,9 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { fn fix_index_builtin_expr(&mut self, e: &hir::Expr<'_>) { if let hir::ExprKind::Index(ref base, ref index, _) = e.kind { // All valid indexing looks like this; might encounter non-valid indexes at this point. - let base_ty = self.typeck_results.expr_ty_adjusted_opt(base); - if base_ty.is_none() { - // When encountering `return [0][0]` outside of a `fn` body we can encounter a base - // that isn't in the type table. We assume more relevant errors have already been - // emitted. (#64638) - assert!(self.tcx().dcx().has_errors().is_some(), "bad base: `{base:?}`"); - } - if let Some(base_ty) = base_ty - && let ty::Ref(_, base_ty_inner, _) = *base_ty.kind() - { - let index_ty = - self.typeck_results.expr_ty_adjusted_opt(index).unwrap_or_else(|| { - // When encountering `return [0][0]` outside of a `fn` body we would attempt - // to access an nonexistent index. We assume that more relevant errors will - // already have been emitted, so we only gate on this with an ICE if no - // error has been emitted. (#64638) - Ty::new_error_with_message( - self.fcx.tcx, - e.span, - format!("bad index {index:?} for base: `{base:?}`"), - ) - }); + let base_ty = self.typeck_results.expr_ty_adjusted(base); + if let ty::Ref(_, base_ty_inner, _) = *base_ty.kind() { + let index_ty = self.typeck_results.expr_ty_adjusted(index); if self.is_builtin_index(e, base_ty_inner, index_ty) { // Remove the method call record self.typeck_results.type_dependent_defs_mut().remove(e.hir_id); From a5d37238a1171ddcf0bbf37f5900bcb442678ffd Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Mon, 1 Jul 2024 10:31:41 +0000 Subject: [PATCH 521/892] Prefer item-local tainting checks over global error count checks --- compiler/rustc_hir_typeck/src/expr.rs | 2 +- compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index 2fbc8a3f146a1..f3aece4e1d8aa 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -708,7 +708,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // else an error would have been flagged by the // `loops` pass for using break with an expression // where you are not supposed to. - assert!(expr_opt.is_none() || self.dcx().has_errors().is_some()); + assert!(expr_opt.is_none() || self.tainted_by_errors().is_some()); } // If we encountered a `break`, then (no surprise) it may be possible to break from the diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index 430e12ff7b87b..ba7719bbb4e6d 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -1652,7 +1652,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.warn_if_unreachable(stmt.hir_id, stmt.span, "statement"); - // Hide the outer diverging and `has_errors` flags. + // Hide the outer diverging flags. let old_diverges = self.diverges.replace(Diverges::Maybe); match stmt.kind { From 814bfe9335fd7c941169e0ef15ae2cffeacc78eb Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Mon, 1 Jul 2024 10:35:16 +0000 Subject: [PATCH 522/892] This check should now be unreachable --- compiler/rustc_hir_typeck/src/expr_use_visitor.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs index 9a353bfe49d0e..c8ab0429ffc70 100644 --- a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs +++ b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs @@ -734,9 +734,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx // struct; however, when EUV is run during typeck, it // may not. This will generate an error earlier in typeck, // so we can just ignore it. - if self.cx.tcx().dcx().has_errors().is_none() { - span_bug!(with_expr.span, "with expression doesn't evaluate to a struct"); - } + span_bug!(with_expr.span, "with expression doesn't evaluate to a struct"); } } From bd2ff518cefe1dc9e1dcd328319eead618eed67a Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sun, 30 Jun 2024 18:44:11 +0000 Subject: [PATCH 523/892] Move codegen_and_build_linker from Queries to Linker --- compiler/rustc_driver_impl/src/lib.rs | 6 ++- compiler/rustc_interface/src/lib.rs | 2 +- compiler/rustc_interface/src/queries.rs | 59 +++++++++++++------------ tests/ui-fulldeps/run-compiler-twice.rs | 7 ++- 4 files changed, 40 insertions(+), 34 deletions(-) diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index 3780e575b9352..ad2acb03b3f67 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -30,7 +30,7 @@ use rustc_errors::{ }; use rustc_feature::find_gated_cfg; use rustc_interface::util::{self, get_codegen_backend}; -use rustc_interface::{interface, passes, Queries}; +use rustc_interface::{interface, passes, Linker, Queries}; use rustc_lint::unerased_lint_store; use rustc_metadata::creader::MetadataLoader; use rustc_metadata::locator; @@ -447,7 +447,9 @@ fn run_compiler( return early_exit(); } - Ok(Some(queries.codegen_and_build_linker()?)) + queries.global_ctxt()?.enter(|tcx| { + Ok(Some(Linker::codegen_and_build_linker(tcx, &*compiler.codegen_backend)?)) + }) })?; // Linking is done outside the `compiler.enter()` so that the diff --git a/compiler/rustc_interface/src/lib.rs b/compiler/rustc_interface/src/lib.rs index 38f64ebb04e7b..e37b30749ab30 100644 --- a/compiler/rustc_interface/src/lib.rs +++ b/compiler/rustc_interface/src/lib.rs @@ -16,7 +16,7 @@ pub mod util; pub use callbacks::setup_callbacks; pub use interface::{run_compiler, Config}; pub use passes::DEFAULT_QUERY_PROVIDERS; -pub use queries::Queries; +pub use queries::{Linker, Queries}; #[cfg(test)] mod tests; diff --git a/compiler/rustc_interface/src/queries.rs b/compiler/rustc_interface/src/queries.rs index 5f00d7a76b29b..e78576c8e4301 100644 --- a/compiler/rustc_interface/src/queries.rs +++ b/compiler/rustc_interface/src/queries.rs @@ -116,35 +116,6 @@ impl<'tcx> Queries<'tcx> { ) }) } - - pub fn codegen_and_build_linker(&'tcx self) -> Result { - self.global_ctxt()?.enter(|tcx| { - let ongoing_codegen = passes::start_codegen(&*self.compiler.codegen_backend, tcx)?; - - // This must run after monomorphization so that all generic types - // have been instantiated. - if tcx.sess.opts.unstable_opts.print_type_sizes { - tcx.sess.code_stats.print_type_sizes(); - } - - if tcx.sess.opts.unstable_opts.print_vtable_sizes { - let crate_name = tcx.crate_name(LOCAL_CRATE); - - tcx.sess.code_stats.print_vtable_sizes(crate_name); - } - - Ok(Linker { - dep_graph: tcx.dep_graph.clone(), - output_filenames: tcx.output_filenames(()).clone(), - crate_hash: if tcx.needs_crate_hash() { - Some(tcx.crate_hash(LOCAL_CRATE)) - } else { - None - }, - ongoing_codegen, - }) - }) - } } pub struct Linker { @@ -156,6 +127,36 @@ pub struct Linker { } impl Linker { + pub fn codegen_and_build_linker( + tcx: TyCtxt<'_>, + codegen_backend: &dyn CodegenBackend, + ) -> Result { + let ongoing_codegen = passes::start_codegen(codegen_backend, tcx)?; + + // This must run after monomorphization so that all generic types + // have been instantiated. + if tcx.sess.opts.unstable_opts.print_type_sizes { + tcx.sess.code_stats.print_type_sizes(); + } + + if tcx.sess.opts.unstable_opts.print_vtable_sizes { + let crate_name = tcx.crate_name(LOCAL_CRATE); + + tcx.sess.code_stats.print_vtable_sizes(crate_name); + } + + Ok(Linker { + dep_graph: tcx.dep_graph.clone(), + output_filenames: tcx.output_filenames(()).clone(), + crate_hash: if tcx.needs_crate_hash() { + Some(tcx.crate_hash(LOCAL_CRATE)) + } else { + None + }, + ongoing_codegen, + }) + } + pub fn link(self, sess: &Session, codegen_backend: &dyn CodegenBackend) -> Result<()> { let (codegen_results, work_products) = codegen_backend.join_codegen(self.ongoing_codegen, sess, &self.output_filenames); diff --git a/tests/ui-fulldeps/run-compiler-twice.rs b/tests/ui-fulldeps/run-compiler-twice.rs index 02748626723d9..720fc42cc5700 100644 --- a/tests/ui-fulldeps/run-compiler-twice.rs +++ b/tests/ui-fulldeps/run-compiler-twice.rs @@ -17,6 +17,7 @@ extern crate rustc_span; use std::path::{Path, PathBuf}; +use rustc_interface::Linker; use rustc_interface::interface; use rustc_session::config::{Input, Options, OutFileName, OutputType, OutputTypes}; use rustc_span::FileName; @@ -78,8 +79,10 @@ fn compile(code: String, output: PathBuf, sysroot: PathBuf, linker: Option<&Path interface::run_compiler(config, |compiler| { let linker = compiler.enter(|queries| { - queries.global_ctxt()?.enter(|tcx| tcx.analysis(()))?; - queries.codegen_and_build_linker() + queries.global_ctxt()?.enter(|tcx| { + tcx.analysis(())?; + Linker::codegen_and_build_linker(tcx, &*compiler.codegen_backend) + }) }); linker.unwrap().link(&compiler.sess, &*compiler.codegen_backend).unwrap(); }); From ec2d1b0ed2f62d0d1da2ce1d5fbffc2eea4ff7b8 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sun, 30 Jun 2024 19:29:25 +0000 Subject: [PATCH 524/892] Minor change --- compiler/rustc_interface/src/queries.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_interface/src/queries.rs b/compiler/rustc_interface/src/queries.rs index e78576c8e4301..370c06c22a7de 100644 --- a/compiler/rustc_interface/src/queries.rs +++ b/compiler/rustc_interface/src/queries.rs @@ -210,7 +210,7 @@ impl Compiler { F: for<'tcx> FnOnce(&'tcx Queries<'tcx>) -> T, { // Must declare `_timer` first so that it is dropped after `queries`. - let mut _timer = None; + let _timer; let queries = Queries::new(self); let ret = f(&queries); @@ -233,7 +233,7 @@ impl Compiler { // The timer's lifetime spans the dropping of `queries`, which contains // the global context. - _timer = Some(self.sess.timer("free_global_ctxt")); + _timer = self.sess.timer("free_global_ctxt"); if let Err((path, error)) = queries.finish() { self.sess.dcx().emit_fatal(errors::FailedWritingFile { path: &path, error }); } From f27645927c15c8f643242101ced25492bacf0cce Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sun, 30 Jun 2024 19:40:54 +0000 Subject: [PATCH 525/892] Inline Query::default() --- compiler/rustc_interface/src/queries.rs | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_interface/src/queries.rs b/compiler/rustc_interface/src/queries.rs index 370c06c22a7de..821e8ee7ba589 100644 --- a/compiler/rustc_interface/src/queries.rs +++ b/compiler/rustc_interface/src/queries.rs @@ -65,12 +65,6 @@ impl<'a, 'tcx> QueryResult<'a, &'tcx GlobalCtxt<'tcx>> { } } -impl Default for Query { - fn default() -> Self { - Query { result: RefCell::new(None) } - } -} - pub struct Queries<'tcx> { compiler: &'tcx Compiler, gcx_cell: OnceLock>, @@ -90,8 +84,8 @@ impl<'tcx> Queries<'tcx> { gcx_cell: OnceLock::new(), arena: WorkerLocal::new(|_| Arena::default()), hir_arena: WorkerLocal::new(|_| rustc_hir::Arena::default()), - parse: Default::default(), - gcx: Default::default(), + parse: Query { result: RefCell::new(None) }, + gcx: Query { result: RefCell::new(None) }, } } From af31c338fc19c51d61b9dabe7b8e4bc854558907 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sat, 27 Jan 2024 19:35:55 +0300 Subject: [PATCH 526/892] linker: Refactor interface for passing arguments to linker --- compiler/rustc_codegen_ssa/src/back/link.rs | 70 +- compiler/rustc_codegen_ssa/src/back/linker.rs | 617 ++++++++---------- 2 files changed, 314 insertions(+), 373 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index d509e4ce56d5b..da7ffdc49116f 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -45,7 +45,7 @@ use tempfile::Builder as TempFileBuilder; use itertools::Itertools; use std::collections::BTreeSet; -use std::ffi::{OsStr, OsString}; +use std::ffi::OsString; use std::fs::{read, File, OpenOptions}; use std::io::{BufWriter, Write}; use std::ops::Deref; @@ -1306,12 +1306,12 @@ fn link_sanitizer_runtime( let filename = format!("rustc{channel}_rt.{name}"); let path = find_sanitizer_runtime(sess, &filename); let rpath = path.to_str().expect("non-utf8 component in path"); - linker.args(&["-Wl,-rpath", "-Xlinker", rpath]); + linker.cc_args(&["-Wl,-rpath", "-Xlinker", rpath]); linker.link_dylib_by_name(&filename, false, true); } else if sess.target.is_like_msvc && flavor == LinkerFlavor::Msvc(Lld::No) && name == "asan" { // MSVC provides the `/INFERASANLIBS` argument to automatically find the // compatible ASAN library. - linker.arg("/INFERASANLIBS"); + linker.link_arg("/INFERASANLIBS"); } else { let filename = format!("librustc{channel}_rt.{name}.a"); let path = find_sanitizer_runtime(sess, &filename).join(&filename); @@ -1888,9 +1888,9 @@ fn add_post_link_objects( /// FIXME: Determine where exactly these args need to be inserted. fn add_pre_link_args(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) { if let Some(args) = sess.target.pre_link_args.get(&flavor) { - cmd.args(args.iter().map(Deref::deref)); + cmd.verbatim_args(args.iter().map(Deref::deref)); } - cmd.args(&sess.opts.unstable_opts.pre_link_args); + cmd.verbatim_args(&sess.opts.unstable_opts.pre_link_args); } /// Add a link script embedded in the target, if applicable. @@ -1908,8 +1908,7 @@ fn add_link_script(cmd: &mut dyn Linker, sess: &Session, tmpdir: &Path, crate_ty sess.dcx().emit_fatal(errors::LinkScriptWriteFailure { path, error }); } - cmd.arg("--script"); - cmd.arg(path); + cmd.link_arg("--script").link_arg(path); } _ => {} } @@ -1918,7 +1917,7 @@ fn add_link_script(cmd: &mut dyn Linker, sess: &Session, tmpdir: &Path, crate_ty /// Add arbitrary "user defined" args defined from command line. /// FIXME: Determine where exactly these args need to be inserted. fn add_user_defined_link_args(cmd: &mut dyn Linker, sess: &Session) { - cmd.args(&sess.opts.cg.link_args); + cmd.verbatim_args(&sess.opts.cg.link_args); } /// Add arbitrary "late link" args defined by the target spec. @@ -1936,15 +1935,15 @@ fn add_late_link_args( }); if any_dynamic_crate { if let Some(args) = sess.target.late_link_args_dynamic.get(&flavor) { - cmd.args(args.iter().map(Deref::deref)); + cmd.verbatim_args(args.iter().map(Deref::deref)); } } else { if let Some(args) = sess.target.late_link_args_static.get(&flavor) { - cmd.args(args.iter().map(Deref::deref)); + cmd.verbatim_args(args.iter().map(Deref::deref)); } } if let Some(args) = sess.target.late_link_args.get(&flavor) { - cmd.args(args.iter().map(Deref::deref)); + cmd.verbatim_args(args.iter().map(Deref::deref)); } } @@ -1952,7 +1951,7 @@ fn add_late_link_args( /// FIXME: Determine where exactly these args need to be inserted. fn add_post_link_args(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) { if let Some(args) = sess.target.post_link_args.get(&flavor) { - cmd.args(args.iter().map(Deref::deref)); + cmd.verbatim_args(args.iter().map(Deref::deref)); } } @@ -2119,7 +2118,7 @@ fn add_rpath_args( is_like_osx: sess.target.is_like_osx, linker_is_gnu: sess.target.linker_flavor.is_gnu(), }; - cmd.args(&rpath::get_rpath_flags(&rpath_config)); + cmd.cc_args(&rpath::get_rpath_flags(&rpath_config)); } } @@ -2378,7 +2377,7 @@ fn add_order_independent_options( } else { "" }; - cmd.arg(format!("--dynamic-linker={prefix}ld.so.1")); + cmd.link_arg(format!("--dynamic-linker={prefix}ld.so.1")); } if sess.target.eh_frame_header { @@ -2393,8 +2392,7 @@ fn add_order_independent_options( } if sess.target.os == "emscripten" { - cmd.arg("-s"); - cmd.arg(if sess.panic_strategy() == PanicStrategy::Abort { + cmd.cc_arg("-s").cc_arg(if sess.panic_strategy() == PanicStrategy::Abort { "DISABLE_EXCEPTION_CATCHING=1" } else { "DISABLE_EXCEPTION_CATCHING=0" @@ -2402,22 +2400,21 @@ fn add_order_independent_options( } if flavor == LinkerFlavor::Llbc { - cmd.arg("--target"); - cmd.arg(sess.target.llvm_target.as_ref()); - cmd.arg("--target-cpu"); - cmd.arg(&codegen_results.crate_info.target_cpu); + cmd.link_args(&[ + "--target", + sess.target.llvm_target.as_ref(), + "--target-cpu", + &codegen_results.crate_info.target_cpu, + ]); } else if flavor == LinkerFlavor::Ptx { - cmd.arg("--fallback-arch"); - cmd.arg(&codegen_results.crate_info.target_cpu); + cmd.link_args(&["--fallback-arch", &codegen_results.crate_info.target_cpu]); } else if flavor == LinkerFlavor::Bpf { - cmd.arg("--cpu"); - cmd.arg(&codegen_results.crate_info.target_cpu); + cmd.link_args(&["--cpu", &codegen_results.crate_info.target_cpu]); if let Some(feat) = [sess.opts.cg.target_feature.as_str(), &sess.target.options.features] .into_iter() .find(|feat| !feat.is_empty()) { - cmd.arg("--cpu-features"); - cmd.arg(feat); + cmd.link_args(&["--cpu-features", feat]); } } @@ -2618,7 +2615,11 @@ fn add_native_libs_from_crate( NativeLibKind::WasmImportModule => {} NativeLibKind::LinkArg => { if link_static { - cmd.linker_arg(OsStr::new(name), verbatim); + if verbatim { + cmd.verbatim_arg(name); + } else { + cmd.link_arg(name); + } } } } @@ -3012,10 +3013,10 @@ fn add_apple_sdk(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) { // This is admittedly a bit strange, as on most targets // `-isysroot` only applies to include header files, but on Apple // targets this also applies to libraries and frameworks. - cmd.args(&["-isysroot", &sdk_root]); + cmd.cc_args(&["-isysroot", &sdk_root]); } LinkerFlavor::Darwin(Cc::No, _) => { - cmd.args(&["-syslibroot", &sdk_root]); + cmd.link_args(&["-syslibroot", &sdk_root]); } _ => unreachable!(), } @@ -3026,8 +3027,9 @@ fn add_apple_sdk(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) { // search path. // The flags are called `-L` and `-F` both in Clang, ld64 and ldd. - cmd.arg(format!("-L{sdk_root}/System/iOSSupport/usr/lib")); - cmd.arg(format!("-F{sdk_root}/System/iOSSupport/System/Library/Frameworks")); + let sdk_root = Path::new(&sdk_root); + cmd.include_path(&sdk_root.join("System/iOSSupport/usr/lib")); + cmd.framework_path(&sdk_root.join("System/iOSSupport/System/Library/Frameworks")); } } @@ -3142,7 +3144,7 @@ fn add_lld_args( for path in sess.get_tools_search_paths(false) { let linker_path = path.join("gcc-ld"); linker_path_exists |= linker_path.exists(); - cmd.arg({ + cmd.cc_arg({ let mut arg = OsString::from("-B"); arg.push(linker_path); arg @@ -3162,7 +3164,7 @@ fn add_lld_args( // is to use LLD but the `wasm32-wasip2` target relies on a wrapper around // this, `wasm-component-ld`, which is overridden if this option is passed. if !sess.target.is_like_wasm { - cmd.arg("-fuse-ld=lld"); + cmd.cc_arg("-fuse-ld=lld"); } if !flavor.is_gnu() { @@ -3186,7 +3188,7 @@ fn add_lld_args( // targeting a different linker flavor on macOS, and that's also always // the case when targeting WASM. if sess.target.linker_flavor != sess.host.linker_flavor { - cmd.arg(format!("--target={}", sess.target.llvm_target)); + cmd.cc_arg(format!("--target={}", sess.target.llvm_target)); } } } diff --git a/compiler/rustc_codegen_ssa/src/back/linker.rs b/compiler/rustc_codegen_ssa/src/back/linker.rs index a82478900b17f..0f75ece9729cd 100644 --- a/compiler/rustc_codegen_ssa/src/back/linker.rs +++ b/compiler/rustc_codegen_ssa/src/back/linker.rs @@ -8,7 +8,7 @@ use std::fs::{self, File}; use std::io::prelude::*; use std::io::{self, BufWriter}; use std::path::{Path, PathBuf}; -use std::{env, mem, str}; +use std::{env, iter, mem, str}; use rustc_hir::def_id::{CrateNum, LOCAL_CRATE}; use rustc_metadata::find_native_static_library; @@ -159,6 +159,102 @@ pub fn get_linker<'a>( } } +// Note: Ideally neither these helper function, nor the macro-generated inherent methods below +// would exist, and these functions would live in `trait Linker`. +// Unfortunately, adding these functions to `trait Linker` make it `dyn`-incompatible. +// If the methods are added to the trait with `where Self: Sized` bounds, then even a separate +// implementation of them for `dyn Linker {}` wouldn't work due to a conflict with those +// uncallable methods in the trait. + +/// Just pass the arguments to the linker as is. +/// It is assumed that they are correctly prepared in advance. +fn verbatim_args( + l: &mut L, + args: impl IntoIterator>, +) -> &mut L { + for arg in args { + l.cmd().arg(arg); + } + l +} +/// Arguments for the underlying linker. +/// Add options to pass them through cc wrapper if `Linker` is a cc wrapper. +fn link_args( + l: &mut L, + args: impl IntoIterator, IntoIter: ExactSizeIterator>, +) -> &mut L { + let args = args.into_iter(); + if !l.is_cc() { + verbatim_args(l, args); + } else if args.len() != 0 { + // FIXME: Support arguments with commas, see `rpaths_to_flags` for the example. + let mut combined_arg = OsString::from("-Wl"); + for arg in args { + combined_arg.push(","); + combined_arg.push(arg); + } + l.cmd().arg(combined_arg); + } + l +} +/// Arguments for the cc wrapper specifically. +/// Check that it's indeed a cc wrapper and pass verbatim. +fn cc_args(l: &mut L, args: impl IntoIterator>) -> &mut L { + assert!(l.is_cc()); + verbatim_args(l, args) +} +/// Arguments supported by both underlying linker and cc wrapper, pass verbatim. +fn link_or_cc_args( + l: &mut L, + args: impl IntoIterator>, +) -> &mut L { + verbatim_args(l, args) +} + +macro_rules! generate_arg_methods { + ($($ty:ty)*) => { $( + impl $ty { + pub fn verbatim_args(&mut self, args: impl IntoIterator>) -> &mut Self { + verbatim_args(self, args) + } + pub fn verbatim_arg(&mut self, arg: impl AsRef) -> &mut Self { + verbatim_args(self, iter::once(arg)) + } + pub fn link_args(&mut self, args: impl IntoIterator, IntoIter: ExactSizeIterator>) -> &mut Self { + link_args(self, args) + } + pub fn link_arg(&mut self, arg: impl AsRef) -> &mut Self { + link_args(self, iter::once(arg)) + } + pub fn cc_args(&mut self, args: impl IntoIterator>) -> &mut Self { + cc_args(self, args) + } + pub fn cc_arg(&mut self, arg: impl AsRef) -> &mut Self { + cc_args(self, iter::once(arg)) + } + pub fn link_or_cc_args(&mut self, args: impl IntoIterator>) -> &mut Self { + link_or_cc_args(self, args) + } + pub fn link_or_cc_arg(&mut self, arg: impl AsRef) -> &mut Self { + link_or_cc_args(self, iter::once(arg)) + } + } + )* } +} + +generate_arg_methods! { + GccLinker<'_> + MsvcLinker<'_> + EmLinker<'_> + WasmLd<'_> + L4Bender<'_> + AixLinker<'_> + LlbcLinker<'_> + PtxLinker<'_> + BpfLinker<'_> + dyn Linker + '_ +} + /// Linker abstraction used by `back::link` to build up the command to invoke a /// linker. /// @@ -168,6 +264,9 @@ pub fn get_linker<'a>( /// MSVC linker (e.g., `link.exe`) is being used. pub trait Linker { fn cmd(&mut self) -> &mut Command; + fn is_cc(&self) -> bool { + false + } fn set_output_kind(&mut self, output_kind: LinkOutputKind, out_filename: &Path); fn link_dylib_by_name(&mut self, name: &str, verbatim: bool, as_needed: bool); fn link_framework_by_name(&mut self, _name: &str, _verbatim: bool, _as_needed: bool) { @@ -175,10 +274,18 @@ pub trait Linker { } fn link_staticlib_by_name(&mut self, name: &str, verbatim: bool, whole_archive: bool); fn link_staticlib_by_path(&mut self, path: &Path, whole_archive: bool); - fn include_path(&mut self, path: &Path); - fn framework_path(&mut self, path: &Path); - fn output_filename(&mut self, path: &Path); - fn add_object(&mut self, path: &Path); + fn include_path(&mut self, path: &Path) { + link_or_cc_args(link_or_cc_args(self, &["-L"]), &[path]); + } + fn framework_path(&mut self, _path: &Path) { + bug!("framework path set with unsupported linker") + } + fn output_filename(&mut self, path: &Path) { + link_or_cc_args(link_or_cc_args(self, &["-o"]), &[path]); + } + fn add_object(&mut self, path: &Path) { + link_or_cc_args(self, &[path]); + } fn gc_sections(&mut self, keep_metadata: bool); fn no_gc_sections(&mut self); fn full_relro(&mut self); @@ -198,25 +305,9 @@ pub trait Linker { fn add_no_exec(&mut self) {} fn add_as_needed(&mut self) {} fn reset_per_library_state(&mut self) {} - fn linker_arg(&mut self, arg: &OsStr, verbatim: bool) { - self.linker_args(&[arg], verbatim); - } - fn linker_args(&mut self, args: &[&OsStr], _verbatim: bool) { - args.into_iter().for_each(|a| { - self.cmd().arg(a); - }); - } } impl dyn Linker + '_ { - pub fn arg(&mut self, arg: impl AsRef) { - self.cmd().arg(arg); - } - - pub fn args(&mut self, args: impl IntoIterator>) { - self.cmd().args(args); - } - pub fn take_cmd(&mut self) -> Command { mem::replace(self.cmd(), Command::new("")) } @@ -233,14 +324,6 @@ pub struct GccLinker<'a> { } impl<'a> GccLinker<'a> { - fn linker_arg(&mut self, arg: impl AsRef) { - Linker::linker_arg(self, arg.as_ref(), false); - } - fn linker_args(&mut self, args: &[impl AsRef]) { - let args_vec: Vec<&OsStr> = args.iter().map(|x| x.as_ref()).collect(); - Linker::linker_args(self, &args_vec, false); - } - fn takes_hints(&self) -> bool { // Really this function only returns true if the underlying linker // configured for a compiler is binutils `ld.bfd` and `ld.gold`. We @@ -262,7 +345,7 @@ impl<'a> GccLinker<'a> { return; } if self.hinted_static != Some(true) { - self.linker_arg("-Bstatic"); + self.link_arg("-Bstatic"); self.hinted_static = Some(true); } } @@ -272,7 +355,7 @@ impl<'a> GccLinker<'a> { return; } if self.hinted_static != Some(false) { - self.linker_arg("-Bdynamic"); + self.link_arg("-Bdynamic"); self.hinted_static = Some(false); } } @@ -281,7 +364,7 @@ impl<'a> GccLinker<'a> { if let Some(plugin_path) = plugin_path { let mut arg = OsString::from("-plugin="); arg.push(plugin_path); - self.linker_arg(&arg); + self.link_arg(&arg); } let opt_level = match self.sess.opts.optimize { @@ -292,9 +375,9 @@ impl<'a> GccLinker<'a> { }; if let Some(path) = &self.sess.opts.unstable_opts.profile_sample_use { - self.linker_arg(&format!("-plugin-opt=sample-profile={}", path.display())); + self.link_arg(&format!("-plugin-opt=sample-profile={}", path.display())); }; - self.linker_args(&[ + self.link_args(&[ &format!("-plugin-opt={opt_level}"), &format!("-plugin-opt=mcpu={}", self.target_cpu), ]); @@ -304,10 +387,10 @@ impl<'a> GccLinker<'a> { // On mac we need to tell the linker to let this library be rpathed if self.sess.target.is_like_osx { if !self.is_ld { - self.cmd.arg("-dynamiclib"); + self.cc_arg("-dynamiclib"); } - self.linker_arg("-dylib"); + self.link_arg("-dylib"); // Note that the `osx_rpath_install_name` option here is a hack // purely to support rustbuild right now, we should get a more @@ -316,10 +399,10 @@ impl<'a> GccLinker<'a> { if self.sess.opts.cg.rpath || self.sess.opts.unstable_opts.osx_rpath_install_name { let mut rpath = OsString::from("@rpath/"); rpath.push(out_filename.file_name().unwrap()); - self.linker_args(&[OsString::from("-install_name"), rpath]); + self.link_arg("-install_name").link_arg(rpath); } } else { - self.cmd.arg("-shared"); + self.link_or_cc_arg("-shared"); if self.sess.target.is_like_windows { // The output filename already contains `dll_suffix` so // the resulting import library will have a name in the @@ -336,7 +419,7 @@ impl<'a> GccLinker<'a> { if let Some(implib_name) = implib_name { let implib = out_filename.parent().map(|dir| dir.join(&implib_name)); if let Some(implib) = implib { - self.linker_arg(&format!("--out-implib={}", (*implib).to_str().unwrap())); + self.link_arg(&format!("--out-implib={}", (*implib).to_str().unwrap())); } } } @@ -345,76 +428,56 @@ impl<'a> GccLinker<'a> { } impl<'a> Linker for GccLinker<'a> { - /// Passes a series of arguments directly to the linker. - /// - /// When the linker is ld-like, the arguments are simply appended to the command. When the - /// linker is not ld-like such as when using a compiler as a linker, the arguments are joined by - /// commas to form an argument that is then prepended with `-Wl`. In this situation, only a - /// single argument is appended to the command to ensure that the order of the arguments is - /// preserved by the compiler. - fn linker_args(&mut self, args: &[&OsStr], verbatim: bool) { - if self.is_ld || verbatim { - args.into_iter().for_each(|a| { - self.cmd.arg(a); - }); - } else { - if !args.is_empty() { - let mut s = OsString::from("-Wl"); - for a in args { - s.push(","); - s.push(a); - } - self.cmd.arg(s); - } - } - } - fn cmd(&mut self) -> &mut Command { &mut self.cmd } + fn is_cc(&self) -> bool { + !self.is_ld + } + fn set_output_kind(&mut self, output_kind: LinkOutputKind, out_filename: &Path) { match output_kind { LinkOutputKind::DynamicNoPicExe => { if !self.is_ld && self.is_gnu { - self.cmd.arg("-no-pie"); + self.cc_arg("-no-pie"); } } LinkOutputKind::DynamicPicExe => { // noop on windows w/ gcc & ld, error w/ lld if !self.sess.target.is_like_windows { // `-pie` works for both gcc wrapper and ld. - self.cmd.arg("-pie"); + self.link_or_cc_arg("-pie"); } } LinkOutputKind::StaticNoPicExe => { // `-static` works for both gcc wrapper and ld. - self.cmd.arg("-static"); + self.link_or_cc_arg("-static"); if !self.is_ld && self.is_gnu { - self.cmd.arg("-no-pie"); + self.cc_arg("-no-pie"); } } LinkOutputKind::StaticPicExe => { if !self.is_ld { // Note that combination `-static -pie` doesn't work as expected // for the gcc wrapper, `-static` in that case suppresses `-pie`. - self.cmd.arg("-static-pie"); + self.cc_arg("-static-pie"); } else { // `--no-dynamic-linker` and `-z text` are not strictly necessary for producing // a static pie, but currently passed because gcc and clang pass them. // The former suppresses the `INTERP` ELF header specifying dynamic linker, // which is otherwise implicitly injected by ld (but not lld). // The latter doesn't change anything, only ensures that everything is pic. - self.cmd.args(&["-static", "-pie", "--no-dynamic-linker", "-z", "text"]); + self.link_args(&["-static", "-pie", "--no-dynamic-linker", "-z", "text"]); } } LinkOutputKind::DynamicDylib => self.build_dylib(out_filename), LinkOutputKind::StaticDylib => { - self.cmd.arg("-static"); + self.link_or_cc_arg("-static"); self.build_dylib(out_filename); } LinkOutputKind::WasiReactorExe => { - self.linker_args(&["--entry", "_initialize"]); + self.link_args(&["--entry", "_initialize"]); } } // VxWorks compiler driver introduced `--static-crt` flag specifically for rustc, @@ -430,7 +493,7 @@ impl<'a> Linker for GccLinker<'a> { | LinkOutputKind::StaticDylib ) { - self.cmd.arg("--static-crt"); + self.cc_arg("--static-crt"); } } @@ -450,18 +513,18 @@ impl<'a> Linker for GccLinker<'a> { // but we have no way to detect that here. self.sess.dcx().emit_warn(errors::Ld64UnimplementedModifier); } else if self.is_gnu && !self.sess.target.is_like_windows { - self.linker_arg("--no-as-needed"); + self.link_arg("--no-as-needed"); } else { self.sess.dcx().emit_warn(errors::LinkerUnsupportedModifier); } } self.hint_dynamic(); - self.cmd.arg(format!("-l{}{name}", if verbatim && self.is_gnu { ":" } else { "" },)); + self.link_or_cc_arg(format!("-l{}{name}", if verbatim && self.is_gnu { ":" } else { "" },)); if !as_needed { if self.sess.target.is_like_osx { // See above FIXME comment } else if self.is_gnu && !self.sess.target.is_like_windows { - self.linker_arg("--as-needed"); + self.link_arg("--as-needed"); } } } @@ -471,63 +534,51 @@ impl<'a> Linker for GccLinker<'a> { if !as_needed { // FIXME(81490): ld64 as of macOS 11 supports the -needed_framework // flag but we have no way to detect that here. - // self.cmd.arg("-needed_framework").arg(name); + // self.link_or_cc_arg("-needed_framework").link_or_cc_arg(name); self.sess.dcx().emit_warn(errors::Ld64UnimplementedModifier); } - self.cmd.arg("-framework").arg(name); + self.link_or_cc_args(&["-framework", name]); } fn link_staticlib_by_name(&mut self, name: &str, verbatim: bool, whole_archive: bool) { self.hint_static(); let colon = if verbatim && self.is_gnu { ":" } else { "" }; if !whole_archive { - self.cmd.arg(format!("-l{colon}{name}")); + self.link_or_cc_arg(format!("-l{colon}{name}")); } else if self.sess.target.is_like_osx { // -force_load is the macOS equivalent of --whole-archive, but it // involves passing the full path to the library to link. - self.linker_arg("-force_load"); - self.linker_arg(find_native_static_library(name, verbatim, self.sess)); + self.link_arg("-force_load"); + self.link_arg(find_native_static_library(name, verbatim, self.sess)); } else { - self.linker_arg("--whole-archive"); - self.cmd.arg(format!("-l{colon}{name}")); - self.linker_arg("--no-whole-archive"); + self.link_arg("--whole-archive") + .link_or_cc_arg(format!("-l{colon}{name}")) + .link_arg("--no-whole-archive"); } } fn link_staticlib_by_path(&mut self, path: &Path, whole_archive: bool) { self.hint_static(); if !whole_archive { - self.cmd.arg(path); + self.link_or_cc_arg(path); } else if self.sess.target.is_like_osx { - self.linker_arg("-force_load"); - self.linker_arg(path); + self.link_arg("-force_load").link_arg(path); } else { - self.linker_arg("--whole-archive"); - self.linker_arg(path); - self.linker_arg("--no-whole-archive"); + self.link_arg("--whole-archive").link_arg(path).link_arg("--no-whole-archive"); } } - fn include_path(&mut self, path: &Path) { - self.cmd.arg("-L").arg(path); - } fn framework_path(&mut self, path: &Path) { - self.cmd.arg("-F").arg(path); - } - fn output_filename(&mut self, path: &Path) { - self.cmd.arg("-o").arg(path); - } - fn add_object(&mut self, path: &Path) { - self.cmd.arg(path); + self.link_or_cc_arg("-F").link_or_cc_arg(path); } fn full_relro(&mut self) { - self.linker_args(&["-z", "relro", "-z", "now"]); + self.link_args(&["-z", "relro", "-z", "now"]); } fn partial_relro(&mut self) { - self.linker_args(&["-z", "relro"]); + self.link_args(&["-z", "relro"]); } fn no_relro(&mut self) { - self.linker_args(&["-z", "norelro"]); + self.link_args(&["-z", "norelro"]); } fn gc_sections(&mut self, keep_metadata: bool) { @@ -546,7 +597,7 @@ impl<'a> Linker for GccLinker<'a> { // for partial linking when using multiple codegen units (-r). So we // insert it here. if self.sess.target.is_like_osx { - self.linker_arg("-dead_strip"); + self.link_arg("-dead_strip"); // If we're building a dylib, we don't use --gc-sections because LLVM // has already done the best it can do, and we also don't want to @@ -554,13 +605,13 @@ impl<'a> Linker for GccLinker<'a> { // --gc-sections drops the size of hello world from 1.8MB to 597K, a 67% // reduction. } else if (self.is_gnu || self.sess.target.is_like_wasm) && !keep_metadata { - self.linker_arg("--gc-sections"); + self.link_arg("--gc-sections"); } } fn no_gc_sections(&mut self) { if self.is_gnu || self.sess.target.is_like_wasm { - self.linker_arg("--no-gc-sections"); + self.link_arg("--no-gc-sections"); } } @@ -574,7 +625,7 @@ impl<'a> Linker for GccLinker<'a> { if self.sess.opts.optimize == config::OptLevel::Default || self.sess.opts.optimize == config::OptLevel::Aggressive { - self.linker_arg("-O1"); + self.link_arg("-O1"); } } @@ -594,8 +645,7 @@ impl<'a> Linker for GccLinker<'a> { // // Though it may be worth to try to revert those changes upstream, since // the overhead of the initialization should be minor. - self.cmd.arg("-u"); - self.cmd.arg("__llvm_profile_runtime"); + self.link_or_cc_args(&["-u", "__llvm_profile_runtime"]); } fn control_flow_guard(&mut self) {} @@ -616,33 +666,33 @@ impl<'a> Linker for GccLinker<'a> { // The --strip-debug case is handled by running an external // `strip` utility as a separate step after linking. if !self.sess.target.is_like_solaris { - self.linker_arg("--strip-debug"); + self.link_arg("--strip-debug"); } } Strip::Symbols => { - self.linker_arg("--strip-all"); + self.link_arg("--strip-all"); } } match self.sess.opts.unstable_opts.debuginfo_compression { config::DebugInfoCompression::None => {} config::DebugInfoCompression::Zlib => { - self.linker_arg("--compress-debug-sections=zlib"); + self.link_arg("--compress-debug-sections=zlib"); } config::DebugInfoCompression::Zstd => { - self.linker_arg("--compress-debug-sections=zstd"); + self.link_arg("--compress-debug-sections=zstd"); } } } fn no_crt_objects(&mut self) { if !self.is_ld { - self.cmd.arg("-nostartfiles"); + self.cc_arg("-nostartfiles"); } } fn no_default_libraries(&mut self) { if !self.is_ld { - self.cmd.arg("-nodefaultlibs"); + self.cc_arg("-nodefaultlibs"); } } @@ -718,24 +768,22 @@ impl<'a> Linker for GccLinker<'a> { } if self.sess.target.is_like_osx { - self.linker_args(&[OsString::from("-exported_symbols_list"), path.into()]); + self.link_arg("-exported_symbols_list").link_arg(path); } else if self.sess.target.is_like_solaris { - self.linker_args(&[OsString::from("-M"), path.into()]); + self.link_arg("-M").link_arg(path); } else { if is_windows { - self.linker_arg(path); + self.link_arg(path); } else { let mut arg = OsString::from("--version-script="); arg.push(path); - self.linker_arg(arg); - self.linker_arg("--no-undefined-version"); + self.link_arg(arg).link_arg("--no-undefined-version"); } } } fn subsystem(&mut self, subsystem: &str) { - self.linker_arg("--subsystem"); - self.linker_arg(&subsystem); + self.link_args(&["--subsystem", subsystem]); } fn reset_per_library_state(&mut self) { @@ -760,23 +808,23 @@ impl<'a> Linker for GccLinker<'a> { // Some versions of `gcc` add it implicitly, some (e.g. `musl-gcc`) don't, // so we just always add it. fn add_eh_frame_header(&mut self) { - self.linker_arg("--eh-frame-hdr"); + self.link_arg("--eh-frame-hdr"); } fn add_no_exec(&mut self) { if self.sess.target.is_like_windows { - self.linker_arg("--nxcompat"); + self.link_arg("--nxcompat"); } else if self.is_gnu { - self.linker_args(&["-z", "noexecstack"]); + self.link_args(&["-z", "noexecstack"]); } } fn add_as_needed(&mut self) { if self.is_gnu && !self.sess.target.is_like_windows { - self.linker_arg("--as-needed"); + self.link_arg("--as-needed"); } else if self.sess.target.is_like_solaris { // -z ignore is the Solaris equivalent to the GNU ld --as-needed option - self.linker_args(&["-z", "ignore"]); + self.link_args(&["-z", "ignore"]); } } } @@ -798,10 +846,10 @@ impl<'a> Linker for MsvcLinker<'a> { | LinkOutputKind::StaticNoPicExe | LinkOutputKind::StaticPicExe => {} LinkOutputKind::DynamicDylib | LinkOutputKind::StaticDylib => { - self.cmd.arg("/DLL"); + self.link_arg("/DLL"); let mut arg: OsString = "/IMPLIB:".into(); arg.push(out_filename.with_extension("dll.lib")); - self.cmd.arg(arg); + self.link_arg(arg); } LinkOutputKind::WasiReactorExe => { panic!("can't link as reactor on non-wasi target"); @@ -810,44 +858,40 @@ impl<'a> Linker for MsvcLinker<'a> { } fn link_dylib_by_name(&mut self, name: &str, verbatim: bool, _as_needed: bool) { - self.cmd.arg(format!("{}{}", name, if verbatim { "" } else { ".lib" })); + self.link_arg(format!("{}{}", name, if verbatim { "" } else { ".lib" })); } fn link_staticlib_by_name(&mut self, name: &str, verbatim: bool, whole_archive: bool) { let prefix = if whole_archive { "/WHOLEARCHIVE:" } else { "" }; let suffix = if verbatim { "" } else { ".lib" }; - self.cmd.arg(format!("{prefix}{name}{suffix}")); + self.link_arg(format!("{prefix}{name}{suffix}")); } fn link_staticlib_by_path(&mut self, path: &Path, whole_archive: bool) { if !whole_archive { - self.cmd.arg(path); + self.link_arg(path); } else { let mut arg = OsString::from("/WHOLEARCHIVE:"); arg.push(path); - self.cmd.arg(arg); + self.link_arg(arg); } } - fn add_object(&mut self, path: &Path) { - self.cmd.arg(path); - } - fn gc_sections(&mut self, _keep_metadata: bool) { // MSVC's ICF (Identical COMDAT Folding) link optimization is // slow for Rust and thus we disable it by default when not in // optimization build. if self.sess.opts.optimize != config::OptLevel::No { - self.cmd.arg("/OPT:REF,ICF"); + self.link_arg("/OPT:REF,ICF"); } else { // It is necessary to specify NOICF here, because /OPT:REF // implies ICF by default. - self.cmd.arg("/OPT:REF,NOICF"); + self.link_arg("/OPT:REF,NOICF"); } } fn no_gc_sections(&mut self) { - self.cmd.arg("/OPT:NOREF,NOICF"); + self.link_arg("/OPT:NOREF,NOICF"); } fn full_relro(&mut self) { @@ -867,23 +911,19 @@ impl<'a> Linker for MsvcLinker<'a> { } fn no_default_libraries(&mut self) { - self.cmd.arg("/NODEFAULTLIB"); + self.link_arg("/NODEFAULTLIB"); } fn include_path(&mut self, path: &Path) { let mut arg = OsString::from("/LIBPATH:"); arg.push(path); - self.cmd.arg(&arg); + self.link_arg(&arg); } fn output_filename(&mut self, path: &Path) { let mut arg = OsString::from("/OUT:"); arg.push(path); - self.cmd.arg(&arg); - } - - fn framework_path(&mut self, _path: &Path) { - bug!("frameworks are not supported on windows") + self.link_arg(&arg); } fn optimize(&mut self) { @@ -895,19 +935,19 @@ impl<'a> Linker for MsvcLinker<'a> { } fn control_flow_guard(&mut self) { - self.cmd.arg("/guard:cf"); + self.link_arg("/guard:cf"); } fn ehcont_guard(&mut self) { if self.sess.target.pointer_width == 64 { - self.cmd.arg("/guard:ehcont"); + self.link_arg("/guard:ehcont"); } } fn debuginfo(&mut self, _strip: Strip, natvis_debugger_visualizers: &[PathBuf]) { // This will cause the Microsoft linker to generate a PDB file // from the CodeView line tables in the object files. - self.cmd.arg("/DEBUG"); + self.link_arg("/DEBUG"); // Default to emitting only the file name of the PDB file into // the binary instead of the full path. Emitting the full path @@ -916,7 +956,7 @@ impl<'a> Linker for MsvcLinker<'a> { // // This default behavior can be overridden by explicitly passing // `-Clink-arg=/PDBALTPATH:...` to rustc. - self.cmd.arg("/PDBALTPATH:%_PDB%"); + self.link_arg("/PDBALTPATH:%_PDB%"); // This will cause the Microsoft linker to embed .natvis info into the PDB file let natvis_dir_path = self.sess.sysroot.join("lib\\rustlib\\etc"); @@ -928,7 +968,7 @@ impl<'a> Linker for MsvcLinker<'a> { if path.extension() == Some("natvis".as_ref()) { let mut arg = OsString::from("/NATVIS:"); arg.push(path); - self.cmd.arg(arg); + self.link_arg(arg); } } Err(error) => { @@ -942,7 +982,7 @@ impl<'a> Linker for MsvcLinker<'a> { for path in natvis_debugger_visualizers { let mut arg = OsString::from("/NATVIS:"); arg.push(path); - self.cmd.arg(arg); + self.link_arg(arg); } } @@ -986,13 +1026,13 @@ impl<'a> Linker for MsvcLinker<'a> { } let mut arg = OsString::from("/DEF:"); arg.push(path); - self.cmd.arg(&arg); + self.link_arg(&arg); } fn subsystem(&mut self, subsystem: &str) { // Note that previous passes of the compiler validated this subsystem, // so we just blindly pass it to the linker. - self.cmd.arg(&format!("/SUBSYSTEM:{subsystem}")); + self.link_arg(&format!("/SUBSYSTEM:{subsystem}")); // Windows has two subsystems we're interested in right now, the console // and windows subsystems. These both implicitly have different entry @@ -1009,7 +1049,7 @@ impl<'a> Linker for MsvcLinker<'a> { // // For more information see RFC #1665 if subsystem == "windows" { - self.cmd.arg("/ENTRY:mainCRTStartup"); + self.link_arg("/ENTRY:mainCRTStartup"); } } @@ -1018,7 +1058,7 @@ impl<'a> Linker for MsvcLinker<'a> { } fn add_no_exec(&mut self) { - self.cmd.arg("/NXCOMPAT"); + self.link_arg("/NXCOMPAT"); } } @@ -1032,31 +1072,23 @@ impl<'a> Linker for EmLinker<'a> { &mut self.cmd } + fn is_cc(&self) -> bool { + true + } + fn set_output_kind(&mut self, _output_kind: LinkOutputKind, _out_filename: &Path) {} fn link_dylib_by_name(&mut self, name: &str, _verbatim: bool, _as_needed: bool) { // Emscripten always links statically - self.cmd.arg("-l").arg(name); + self.link_or_cc_args(&["-l", name]); } fn link_staticlib_by_name(&mut self, name: &str, _verbatim: bool, _whole_archive: bool) { - self.cmd.arg("-l").arg(name); + self.link_or_cc_args(&["-l", name]); } fn link_staticlib_by_path(&mut self, path: &Path, _whole_archive: bool) { - self.cmd.arg(path); - } - - fn include_path(&mut self, path: &Path) { - self.cmd.arg("-L").arg(path); - } - - fn output_filename(&mut self, path: &Path) { - self.cmd.arg("-o").arg(path); - } - - fn add_object(&mut self, path: &Path) { - self.cmd.arg(path); + self.link_or_cc_arg(path); } fn full_relro(&mut self) { @@ -1071,10 +1103,6 @@ impl<'a> Linker for EmLinker<'a> { // noop } - fn framework_path(&mut self, _path: &Path) { - bug!("frameworks are not supported on Emscripten") - } - fn gc_sections(&mut self, _keep_metadata: bool) { // noop } @@ -1085,7 +1113,7 @@ impl<'a> Linker for EmLinker<'a> { fn optimize(&mut self) { // Emscripten performs own optimizations - self.cmd.arg(match self.sess.opts.optimize { + self.cc_arg(match self.sess.opts.optimize { OptLevel::No => "-O0", OptLevel::Less => "-O1", OptLevel::Default => "-O2", @@ -1106,7 +1134,7 @@ impl<'a> Linker for EmLinker<'a> { fn debuginfo(&mut self, _strip: Strip, _: &[PathBuf]) { // Preserve names or generate source maps depending on debug info // For more information see https://emscripten.org/docs/tools_reference/emcc.html#emcc-g - self.cmd.arg(match self.sess.opts.debuginfo { + self.cc_arg(match self.sess.opts.debuginfo { DebugInfo::None => "-g0", DebugInfo::Limited | DebugInfo::LineTablesOnly | DebugInfo::LineDirectivesOnly => { "--profiling-funcs" @@ -1118,13 +1146,13 @@ impl<'a> Linker for EmLinker<'a> { fn no_crt_objects(&mut self) {} fn no_default_libraries(&mut self) { - self.cmd.arg("-nodefaultlibs"); + self.cc_arg("-nodefaultlibs"); } fn export_symbols(&mut self, _tmpdir: &Path, _crate_type: CrateType, symbols: &[String]) { debug!("EXPORTED SYMBOLS:"); - self.cmd.arg("-s"); + self.cc_arg("-s"); let mut arg = OsString::from("EXPORTED_FUNCTIONS="); let encoded = serde_json::to_string( @@ -1135,7 +1163,7 @@ impl<'a> Linker for EmLinker<'a> { arg.push(encoded); - self.cmd.arg(arg); + self.cc_arg(arg); } fn subsystem(&mut self, _subsystem: &str) { @@ -1153,7 +1181,7 @@ pub struct WasmLd<'a> { } impl<'a> WasmLd<'a> { - fn new(mut cmd: Command, sess: &'a Session) -> WasmLd<'a> { + fn new(cmd: Command, sess: &'a Session) -> WasmLd<'a> { // If the atomics feature is enabled for wasm then we need a whole bunch // of flags: // @@ -1172,18 +1200,19 @@ impl<'a> WasmLd<'a> { // On wasm32-unknown-unknown, we also export symbols for glue code to use: // * `--export=*tls*` - when `#[thread_local]` symbols are used these // symbols are how the TLS segments are initialized and configured. + let mut wasm_ld = WasmLd { cmd, sess }; if sess.target_features.contains(&sym::atomics) { - cmd.arg("--shared-memory"); - cmd.arg("--max-memory=1073741824"); - cmd.arg("--import-memory"); + wasm_ld.link_args(&["--shared-memory", "--max-memory=1073741824", "--import-memory"]); if sess.target.os == "unknown" { - cmd.arg("--export=__wasm_init_tls"); - cmd.arg("--export=__tls_size"); - cmd.arg("--export=__tls_align"); - cmd.arg("--export=__tls_base"); + wasm_ld.link_args(&[ + "--export=__wasm_init_tls", + "--export=__tls_size", + "--export=__tls_align", + "--export=__tls_base", + ]); } } - WasmLd { cmd, sess } + wasm_ld } } @@ -1199,51 +1228,36 @@ impl<'a> Linker for WasmLd<'a> { | LinkOutputKind::StaticNoPicExe | LinkOutputKind::StaticPicExe => {} LinkOutputKind::DynamicDylib | LinkOutputKind::StaticDylib => { - self.cmd.arg("--no-entry"); + self.link_arg("--no-entry"); } LinkOutputKind::WasiReactorExe => { - self.cmd.arg("--entry"); - self.cmd.arg("_initialize"); + self.link_args(&["--entry", "_initialize"]); } } } fn link_dylib_by_name(&mut self, name: &str, _verbatim: bool, _as_needed: bool) { - self.cmd.arg("-l").arg(name); + self.link_or_cc_args(&["-l", name]); } fn link_staticlib_by_name(&mut self, name: &str, _verbatim: bool, whole_archive: bool) { if !whole_archive { - self.cmd.arg("-l").arg(name); + self.link_or_cc_args(&["-l", name]); } else { - self.cmd.arg("--whole-archive").arg("-l").arg(name).arg("--no-whole-archive"); + self.link_arg("--whole-archive") + .link_or_cc_args(&["-l", name]) + .link_arg("--no-whole-archive"); } } fn link_staticlib_by_path(&mut self, path: &Path, whole_archive: bool) { if !whole_archive { - self.cmd.arg(path); + self.link_or_cc_arg(path); } else { - self.cmd.arg("--whole-archive").arg(path).arg("--no-whole-archive"); + self.link_arg("--whole-archive").link_or_cc_arg(path).link_arg("--no-whole-archive"); } } - fn include_path(&mut self, path: &Path) { - self.cmd.arg("-L").arg(path); - } - - fn framework_path(&mut self, _path: &Path) { - panic!("frameworks not supported") - } - - fn output_filename(&mut self, path: &Path) { - self.cmd.arg("-o").arg(path); - } - - fn add_object(&mut self, path: &Path) { - self.cmd.arg(path); - } - fn full_relro(&mut self) {} fn partial_relro(&mut self) {} @@ -1251,17 +1265,17 @@ impl<'a> Linker for WasmLd<'a> { fn no_relro(&mut self) {} fn gc_sections(&mut self, _keep_metadata: bool) { - self.cmd.arg("--gc-sections"); + self.link_arg("--gc-sections"); } fn no_gc_sections(&mut self) { - self.cmd.arg("--no-gc-sections"); + self.link_arg("--no-gc-sections"); } fn optimize(&mut self) { // The -O flag is, as of late 2023, only used for merging of strings and debuginfo, and // only differentiates -O0 and -O1. It does not apply to LTO. - self.cmd.arg(match self.sess.opts.optimize { + self.link_arg(match self.sess.opts.optimize { OptLevel::No => "-O0", OptLevel::Less => "-O1", OptLevel::Default => "-O2", @@ -1279,10 +1293,10 @@ impl<'a> Linker for WasmLd<'a> { match strip { Strip::None => {} Strip::Debuginfo => { - self.cmd.arg("--strip-debug"); + self.link_arg("--strip-debug"); } Strip::Symbols => { - self.cmd.arg("--strip-all"); + self.link_arg("--strip-all"); } } } @@ -1297,7 +1311,7 @@ impl<'a> Linker for WasmLd<'a> { fn export_symbols(&mut self, _tmpdir: &Path, _crate_type: CrateType, symbols: &[String]) { for sym in symbols { - self.cmd.arg("--export").arg(&sym); + self.link_args(&["--export", sym]); } // LLD will hide these otherwise-internal symbols since it only exports @@ -1305,8 +1319,7 @@ impl<'a> Linker for WasmLd<'a> { // others. Various bits and pieces of wasm32-unknown-unknown tooling use // this, so be sure these symbols make their way out of the linker as well. if self.sess.target.os == "unknown" { - self.cmd.arg("--export=__heap_base"); - self.cmd.arg("--export=__data_end"); + self.link_args(&["--export=__heap_base", "--export=__data_end"]); } } @@ -1337,7 +1350,7 @@ impl<'a> WasmLd<'a> { // wasm-ld only handles integer LTO opt levels. Use O2 config::OptLevel::Size | config::OptLevel::SizeMin => "O2", }; - self.cmd.arg(&format!("--lto-{opt_level}")); + self.link_arg(&format!("--lto-{opt_level}")); } } @@ -1362,56 +1375,43 @@ impl<'a> Linker for L4Bender<'a> { fn link_staticlib_by_name(&mut self, name: &str, _verbatim: bool, whole_archive: bool) { self.hint_static(); if !whole_archive { - self.cmd.arg(format!("-PC{name}")); + self.link_arg(format!("-PC{name}")); } else { - self.cmd.arg("--whole-archive").arg(format!("-l{name}")).arg("--no-whole-archive"); + self.link_arg("--whole-archive") + .link_or_cc_arg(format!("-l{name}")) + .link_arg("--no-whole-archive"); } } fn link_staticlib_by_path(&mut self, path: &Path, whole_archive: bool) { self.hint_static(); if !whole_archive { - self.cmd.arg(path); + self.link_or_cc_arg(path); } else { - self.cmd.arg("--whole-archive").arg(path).arg("--no-whole-archive"); + self.link_arg("--whole-archive").link_or_cc_arg(path).link_arg("--no-whole-archive"); } } - fn include_path(&mut self, path: &Path) { - self.cmd.arg("-L").arg(path); - } - fn framework_path(&mut self, _: &Path) { - bug!("frameworks are not supported on L4Re"); - } - fn output_filename(&mut self, path: &Path) { - self.cmd.arg("-o").arg(path); - } - - fn add_object(&mut self, path: &Path) { - self.cmd.arg(path); - } - fn full_relro(&mut self) { - self.cmd.arg("-z").arg("relro"); - self.cmd.arg("-z").arg("now"); + self.link_args(&["-z", "relro", "-z", "now"]); } fn partial_relro(&mut self) { - self.cmd.arg("-z").arg("relro"); + self.link_args(&["-z", "relro"]); } fn no_relro(&mut self) { - self.cmd.arg("-z").arg("norelro"); + self.link_args(&["-z", "norelro"]); } fn gc_sections(&mut self, keep_metadata: bool) { if !keep_metadata { - self.cmd.arg("--gc-sections"); + self.link_arg("--gc-sections"); } } fn no_gc_sections(&mut self) { - self.cmd.arg("--no-gc-sections"); + self.link_arg("--no-gc-sections"); } fn optimize(&mut self) { @@ -1420,7 +1420,7 @@ impl<'a> Linker for L4Bender<'a> { if self.sess.opts.optimize == config::OptLevel::Default || self.sess.opts.optimize == config::OptLevel::Aggressive { - self.cmd.arg("-O1"); + self.link_arg("-O1"); } } @@ -1430,16 +1430,16 @@ impl<'a> Linker for L4Bender<'a> { match strip { Strip::None => {} Strip::Debuginfo => { - self.cmd().arg("--strip-debug"); + self.link_arg("--strip-debug"); } Strip::Symbols => { - self.cmd().arg("--strip-all"); + self.link_arg("--strip-all"); } } } fn no_default_libraries(&mut self) { - self.cmd.arg("-nostdlib"); + self.cc_arg("-nostdlib"); } fn export_symbols(&mut self, _: &Path, _: CrateType, _: &[String]) { @@ -1449,7 +1449,7 @@ impl<'a> Linker for L4Bender<'a> { } fn subsystem(&mut self, subsystem: &str) { - self.cmd.arg(&format!("--subsystem {subsystem}")); + self.link_arg(&format!("--subsystem {subsystem}")); } fn reset_per_library_state(&mut self) { @@ -1467,12 +1467,12 @@ impl<'a> Linker for L4Bender<'a> { impl<'a> L4Bender<'a> { pub fn new(cmd: Command, sess: &'a Session) -> L4Bender<'a> { - L4Bender { cmd: cmd, sess: sess, hinted_static: false } + L4Bender { cmd, sess: sess, hinted_static: false } } fn hint_static(&mut self) { if !self.hinted_static { - self.cmd.arg("-static"); + self.link_or_cc_arg("-static"); self.hinted_static = true; } } @@ -1487,29 +1487,28 @@ pub struct AixLinker<'a> { impl<'a> AixLinker<'a> { pub fn new(cmd: Command, sess: &'a Session) -> AixLinker<'a> { - AixLinker { cmd: cmd, sess: sess, hinted_static: None } + AixLinker { cmd, sess: sess, hinted_static: None } } fn hint_static(&mut self) { if self.hinted_static != Some(true) { - self.cmd.arg("-bstatic"); + self.link_arg("-bstatic"); self.hinted_static = Some(true); } } fn hint_dynamic(&mut self) { if self.hinted_static != Some(false) { - self.cmd.arg("-bdynamic"); + self.link_arg("-bdynamic"); self.hinted_static = Some(false); } } fn build_dylib(&mut self, _out_filename: &Path) { - self.cmd.arg("-bM:SRE"); - self.cmd.arg("-bnoentry"); + self.link_args(&["-bM:SRE", "-bnoentry"]); // FIXME: Use CreateExportList utility to create export list // and remove -bexpfull. - self.cmd.arg("-bexpfull"); + self.link_arg("-bexpfull"); } } @@ -1534,47 +1533,31 @@ impl<'a> Linker for AixLinker<'a> { fn link_dylib_by_name(&mut self, name: &str, _verbatim: bool, _as_needed: bool) { self.hint_dynamic(); - self.cmd.arg(format!("-l{name}")); + self.link_or_cc_arg(format!("-l{name}")); } fn link_staticlib_by_name(&mut self, name: &str, verbatim: bool, whole_archive: bool) { self.hint_static(); if !whole_archive { - self.cmd.arg(format!("-l{name}")); + self.link_or_cc_arg(format!("-l{name}")); } else { let mut arg = OsString::from("-bkeepfile:"); arg.push(find_native_static_library(name, verbatim, self.sess)); - self.cmd.arg(arg); + self.link_or_cc_arg(arg); } } fn link_staticlib_by_path(&mut self, path: &Path, whole_archive: bool) { self.hint_static(); if !whole_archive { - self.cmd.arg(path); + self.link_or_cc_arg(path); } else { let mut arg = OsString::from("-bkeepfile:"); arg.push(path); - self.cmd.arg(arg); + self.link_arg(arg); } } - fn include_path(&mut self, path: &Path) { - self.cmd.arg("-L").arg(path); - } - - fn framework_path(&mut self, _: &Path) { - bug!("frameworks are not supported on AIX"); - } - - fn output_filename(&mut self, path: &Path) { - self.cmd.arg("-o").arg(path); - } - - fn add_object(&mut self, path: &Path) { - self.cmd.arg(path); - } - fn full_relro(&mut self) {} fn partial_relro(&mut self) {} @@ -1582,17 +1565,17 @@ impl<'a> Linker for AixLinker<'a> { fn no_relro(&mut self) {} fn gc_sections(&mut self, _keep_metadata: bool) { - self.cmd.arg("-bgc"); + self.link_arg("-bgc"); } fn no_gc_sections(&mut self) { - self.cmd.arg("-bnogc"); + self.link_arg("-bnogc"); } fn optimize(&mut self) {} fn pgo_gen(&mut self) { - self.cmd.arg("-bdbg:namedsects:ss"); + self.link_arg("-bdbg:namedsects:ss"); } fn control_flow_guard(&mut self) {} @@ -1618,7 +1601,7 @@ impl<'a> Linker for AixLinker<'a> { if let Err(e) = res { self.sess.dcx().fatal(format!("failed to write export file: {e}")); } - self.cmd.arg(format!("-bE:{}", path.to_str().unwrap())); + self.link_arg(format!("-bE:{}", path.to_str().unwrap())); } fn subsystem(&mut self, _subsystem: &str) {} @@ -1747,39 +1730,27 @@ impl<'a> Linker for PtxLinker<'a> { } fn link_staticlib_by_path(&mut self, path: &Path, _whole_archive: bool) { - self.cmd.arg("--rlib").arg(path); - } - - fn include_path(&mut self, path: &Path) { - self.cmd.arg("-L").arg(path); + self.link_arg("--rlib").link_arg(path); } fn debuginfo(&mut self, _strip: Strip, _: &[PathBuf]) { - self.cmd.arg("--debug"); + self.link_arg("--debug"); } fn add_object(&mut self, path: &Path) { - self.cmd.arg("--bitcode").arg(path); + self.link_arg("--bitcode").link_arg(path); } fn optimize(&mut self) { match self.sess.lto() { Lto::Thin | Lto::Fat | Lto::ThinLocal => { - self.cmd.arg("-Olto"); + self.link_arg("-Olto"); } Lto::No => {} } } - fn output_filename(&mut self, path: &Path) { - self.cmd.arg("-o").arg(path); - } - - fn framework_path(&mut self, _path: &Path) { - panic!("frameworks not supported") - } - fn full_relro(&mut self) {} fn partial_relro(&mut self) {} @@ -1829,19 +1800,11 @@ impl<'a> Linker for LlbcLinker<'a> { } fn link_staticlib_by_path(&mut self, path: &Path, _whole_archive: bool) { - self.cmd.arg(path); - } - - fn include_path(&mut self, path: &Path) { - self.cmd.arg("-L").arg(path); + self.link_or_cc_arg(path); } fn debuginfo(&mut self, _strip: Strip, _: &[PathBuf]) { - self.cmd.arg("--debug"); - } - - fn add_object(&mut self, path: &Path) { - self.cmd.arg(path); + self.link_arg("--debug"); } fn optimize(&mut self) { @@ -1855,14 +1818,6 @@ impl<'a> Linker for LlbcLinker<'a> { }; } - fn output_filename(&mut self, path: &Path) { - self.cmd.arg("-o").arg(path); - } - - fn framework_path(&mut self, _path: &Path) { - panic!("frameworks not supported") - } - fn full_relro(&mut self) {} fn partial_relro(&mut self) {} @@ -1887,7 +1842,7 @@ impl<'a> Linker for LlbcLinker<'a> { match _crate_type { CrateType::Cdylib => { for sym in symbols { - self.cmd.arg("--export-symbol").arg(sym); + self.link_args(&["--export-symbol", sym]); } } _ => (), @@ -1920,23 +1875,15 @@ impl<'a> Linker for BpfLinker<'a> { } fn link_staticlib_by_path(&mut self, path: &Path, _whole_archive: bool) { - self.cmd.arg(path); - } - - fn include_path(&mut self, path: &Path) { - self.cmd.arg("-L").arg(path); + self.link_or_cc_arg(path); } fn debuginfo(&mut self, _strip: Strip, _: &[PathBuf]) { - self.cmd.arg("--debug"); - } - - fn add_object(&mut self, path: &Path) { - self.cmd.arg(path); + self.link_arg("--debug"); } fn optimize(&mut self) { - self.cmd.arg(match self.sess.opts.optimize { + self.link_arg(match self.sess.opts.optimize { OptLevel::No => "-O0", OptLevel::Less => "-O1", OptLevel::Default => "-O2", @@ -1946,14 +1893,6 @@ impl<'a> Linker for BpfLinker<'a> { }); } - fn output_filename(&mut self, path: &Path) { - self.cmd.arg("-o").arg(path); - } - - fn framework_path(&mut self, _path: &Path) { - panic!("frameworks not supported") - } - fn full_relro(&mut self) {} fn partial_relro(&mut self) {} @@ -1985,7 +1924,7 @@ impl<'a> Linker for BpfLinker<'a> { if let Err(error) = res { self.sess.dcx().emit_fatal(errors::SymbolFileWriteFailure { error }); } else { - self.cmd.arg("--export-symbols").arg(&path); + self.link_arg("--export-symbols").link_arg(&path); } } From 5f9a0d3844e5a00f2c821c9b1e7d17679b758036 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Mon, 1 Jul 2024 13:06:20 +0300 Subject: [PATCH 527/892] linker: Bail out of rpath logic early if the target doesn't support rpath --- compiler/rustc_codegen_ssa/src/back/link.rs | 5 ++++- compiler/rustc_codegen_ssa/src/back/rpath.rs | 6 ------ compiler/rustc_codegen_ssa/src/back/rpath/tests.rs | 3 --- 3 files changed, 4 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index da7ffdc49116f..da4fa41e2aafc 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -2096,6 +2096,10 @@ fn add_rpath_args( codegen_results: &CodegenResults, out_filename: &Path, ) { + if !sess.target.has_rpath { + return; + } + // FIXME (#2397): At some point we want to rpath our guesses as to // where extern libraries might live, based on the // add_lib_search_paths @@ -2114,7 +2118,6 @@ fn add_rpath_args( let rpath_config = RPathConfig { libs: &*libs, out_filename: out_filename.to_path_buf(), - has_rpath: sess.target.has_rpath, is_like_osx: sess.target.is_like_osx, linker_is_gnu: sess.target.linker_flavor.is_gnu(), }; diff --git a/compiler/rustc_codegen_ssa/src/back/rpath.rs b/compiler/rustc_codegen_ssa/src/back/rpath.rs index f499bbcf85339..82070d4453b28 100644 --- a/compiler/rustc_codegen_ssa/src/back/rpath.rs +++ b/compiler/rustc_codegen_ssa/src/back/rpath.rs @@ -9,16 +9,10 @@ pub struct RPathConfig<'a> { pub libs: &'a [&'a Path], pub out_filename: PathBuf, pub is_like_osx: bool, - pub has_rpath: bool, pub linker_is_gnu: bool, } pub fn get_rpath_flags(config: &RPathConfig<'_>) -> Vec { - // No rpath on windows - if !config.has_rpath { - return Vec::new(); - } - debug!("preparing the RPATH!"); let rpaths = get_rpaths(config); diff --git a/compiler/rustc_codegen_ssa/src/back/rpath/tests.rs b/compiler/rustc_codegen_ssa/src/back/rpath/tests.rs index 0de90a1036ec5..c620e92db1f08 100644 --- a/compiler/rustc_codegen_ssa/src/back/rpath/tests.rs +++ b/compiler/rustc_codegen_ssa/src/back/rpath/tests.rs @@ -37,7 +37,6 @@ fn test_rpath_relative() { if cfg!(target_os = "macos") { let config = &mut RPathConfig { libs: &[], - has_rpath: true, is_like_osx: true, linker_is_gnu: false, out_filename: PathBuf::from("bin/rustc"), @@ -48,7 +47,6 @@ fn test_rpath_relative() { let config = &mut RPathConfig { libs: &[], out_filename: PathBuf::from("bin/rustc"), - has_rpath: true, is_like_osx: false, linker_is_gnu: true, }; @@ -62,7 +60,6 @@ fn test_rpath_relative_issue_119571() { let config = &mut RPathConfig { libs: &[], out_filename: PathBuf::from("rustc"), - has_rpath: true, is_like_osx: false, linker_is_gnu: true, }; From 8cc1ed81dfd9e6eeb50d3621e0c862e9d3b4fe92 Mon Sep 17 00:00:00 2001 From: yukang Date: Mon, 1 Jul 2024 13:05:23 +0800 Subject: [PATCH 528/892] Fix import suggestion error when failed not from starting --- compiler/rustc_resolve/src/diagnostics.rs | 12 +++++++++- .../ui/imports/suggest-import-issue-120074.rs | 11 +++++++++ .../suggest-import-issue-120074.stderr | 23 +++++++++++++++++++ 3 files changed, 45 insertions(+), 1 deletion(-) create mode 100644 tests/ui/imports/suggest-import-issue-120074.rs create mode 100644 tests/ui/imports/suggest-import-issue-120074.stderr diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index 263daa11ec316..50a4e03d233a7 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -1987,10 +1987,20 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { candidates .sort_by_cached_key(|c| (c.path.segments.len(), pprust::path_to_string(&c.path))); if let Some(candidate) = candidates.get(0) { + let path = { + // remove the possible common prefix of the path + let start_index = (0..failed_segment_idx) + .find(|&i| path[i].ident != candidate.path.segments[i].ident) + .unwrap_or_default(); + let segments = (start_index..=failed_segment_idx) + .map(|s| candidate.path.segments[s].clone()) + .collect(); + Path { segments, span: Span::default(), tokens: None } + }; ( String::from("unresolved import"), Some(( - vec![(ident.span, pprust::path_to_string(&candidate.path))], + vec![(ident.span, pprust::path_to_string(&path))], String::from("a similar path exists"), Applicability::MaybeIncorrect, )), diff --git a/tests/ui/imports/suggest-import-issue-120074.rs b/tests/ui/imports/suggest-import-issue-120074.rs new file mode 100644 index 0000000000000..a798e9eeeb809 --- /dev/null +++ b/tests/ui/imports/suggest-import-issue-120074.rs @@ -0,0 +1,11 @@ +pub mod foo { + pub mod bar { + pub fn do_the_thing() -> usize { + 42 + } + } +} + +fn main() { + println!("Hello, {}!", crate::bar::do_the_thing); //~ ERROR failed to resolve: unresolved import +} diff --git a/tests/ui/imports/suggest-import-issue-120074.stderr b/tests/ui/imports/suggest-import-issue-120074.stderr new file mode 100644 index 0000000000000..c1dff93bbdbff --- /dev/null +++ b/tests/ui/imports/suggest-import-issue-120074.stderr @@ -0,0 +1,23 @@ +error[E0433]: failed to resolve: unresolved import + --> $DIR/suggest-import-issue-120074.rs:10:35 + | +LL | println!("Hello, {}!", crate::bar::do_the_thing); + | ^^^ unresolved import + | +help: a similar path exists + | +LL | println!("Hello, {}!", crate::foo::bar::do_the_thing); + | ~~~~~~~~ +help: consider importing this module + | +LL + use foo::bar; + | +help: if you import `bar`, refer to it directly + | +LL - println!("Hello, {}!", crate::bar::do_the_thing); +LL + println!("Hello, {}!", bar::do_the_thing); + | + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0433`. From 860729ea39bc568aa57ce8cb152647138cfda995 Mon Sep 17 00:00:00 2001 From: dimi Date: Mon, 1 Jul 2024 14:14:22 +0200 Subject: [PATCH 529/892] Stabilize atomic_bool_fetch_not --- library/core/src/sync/atomic.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/library/core/src/sync/atomic.rs b/library/core/src/sync/atomic.rs index df108f5e0e4e5..efc07f38f68e0 100644 --- a/library/core/src/sync/atomic.rs +++ b/library/core/src/sync/atomic.rs @@ -1069,7 +1069,6 @@ impl AtomicBool { /// # Examples /// /// ``` - /// #![feature(atomic_bool_fetch_not)] /// use std::sync::atomic::{AtomicBool, Ordering}; /// /// let foo = AtomicBool::new(true); @@ -1081,7 +1080,7 @@ impl AtomicBool { /// assert_eq!(foo.load(Ordering::SeqCst), true); /// ``` #[inline] - #[unstable(feature = "atomic_bool_fetch_not", issue = "98485")] + #[stable(feature = "atomic_bool_fetch_not", since = "CURRENT_RUSTC_VERSION")] #[cfg(target_has_atomic = "8")] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub fn fetch_not(&self, order: Ordering) -> bool { From 23c8ed14c938ab28873e88321ac0ad75842fa2c1 Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Sat, 29 Jun 2024 00:48:23 -0700 Subject: [PATCH 530/892] Avoid MIR bloat in inlining In 126578 we ended up with more binary size increases than expected. This change attempts to avoid inlining large things into small things, to avoid that kind of increase, in cases when top-down inlining will still be able to do that inlining later. --- .../rustc_mir_transform/src/cost_checker.rs | 31 +++ compiler/rustc_mir_transform/src/inline.rs | 50 +++- compiler/rustc_session/src/options.rs | 2 + library/alloc/src/raw_vec.rs | 17 ++ library/alloc/src/vec/mod.rs | 1 + .../drop_in_place_intrinsic.rs | 1 + ...inline_direct.Inline.after.panic-abort.mir | 22 ++ ...nline_direct.Inline.after.panic-unwind.mir | 22 ++ ...line_indirect.Inline.after.panic-abort.mir | 27 ++ ...ine_indirect.Inline.after.panic-unwind.mir | 27 ++ ...ic_not_inline.Inline.after.panic-abort.mir | 34 +++ ...c_not_inline.Inline.after.panic-unwind.mir | 34 +++ .../inline/inline_more_in_non_inline.rs | 46 ++++ .../inline_shims.drop.Inline.panic-abort.diff | 58 +---- ...erse_loop.PreCodegen.after.panic-abort.mir | 231 +++-------------- ...rse_loop.PreCodegen.after.panic-unwind.mir | 237 +++--------------- ...next_back.PreCodegen.after.panic-abort.mir | 195 +------------- ...ext_back.PreCodegen.after.panic-unwind.mir | 195 +------------- 18 files changed, 385 insertions(+), 845 deletions(-) create mode 100644 tests/mir-opt/inline/inline_more_in_non_inline.marked_inline_direct.Inline.after.panic-abort.mir create mode 100644 tests/mir-opt/inline/inline_more_in_non_inline.marked_inline_direct.Inline.after.panic-unwind.mir create mode 100644 tests/mir-opt/inline/inline_more_in_non_inline.marked_inline_indirect.Inline.after.panic-abort.mir create mode 100644 tests/mir-opt/inline/inline_more_in_non_inline.marked_inline_indirect.Inline.after.panic-unwind.mir create mode 100644 tests/mir-opt/inline/inline_more_in_non_inline.monomorphic_not_inline.Inline.after.panic-abort.mir create mode 100644 tests/mir-opt/inline/inline_more_in_non_inline.monomorphic_not_inline.Inline.after.panic-unwind.mir create mode 100644 tests/mir-opt/inline/inline_more_in_non_inline.rs diff --git a/compiler/rustc_mir_transform/src/cost_checker.rs b/compiler/rustc_mir_transform/src/cost_checker.rs index 7e401b5482f3d..3333bebff3a6e 100644 --- a/compiler/rustc_mir_transform/src/cost_checker.rs +++ b/compiler/rustc_mir_transform/src/cost_checker.rs @@ -31,6 +31,37 @@ impl<'b, 'tcx> CostChecker<'b, 'tcx> { CostChecker { tcx, param_env, callee_body, instance, penalty: 0, bonus: 0 } } + /// Add function-level costs not well-represented by the block-level costs. + /// + /// Needed because the `CostChecker` is used sometimes for just blocks, + /// and even the full `Inline` doesn't call `visit_body`, so there's nowhere + /// to put this logic in the visitor. + pub fn add_function_level_costs(&mut self) { + fn is_call_like(bbd: &BasicBlockData<'_>) -> bool { + use TerminatorKind::*; + match bbd.terminator().kind { + Call { .. } | Drop { .. } | Assert { .. } | InlineAsm { .. } => true, + + Goto { .. } + | SwitchInt { .. } + | UnwindResume + | UnwindTerminate(_) + | Return + | Unreachable => false, + + Yield { .. } | CoroutineDrop | FalseEdge { .. } | FalseUnwind { .. } => { + unreachable!() + } + } + } + + // If the only has one Call (or similar), inlining isn't increasing the total + // number of calls, so give extra encouragement to inlining that. + if self.callee_body.basic_blocks.iter().filter(|bbd| is_call_like(bbd)).count() == 1 { + self.bonus += CALL_PENALTY; + } + } + pub fn cost(&self) -> usize { usize::saturating_sub(self.penalty, self.bonus) } diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs index 07482d0571a2f..6fa31c1174d0b 100644 --- a/compiler/rustc_mir_transform/src/inline.rs +++ b/compiler/rustc_mir_transform/src/inline.rs @@ -85,13 +85,18 @@ fn inline<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) -> bool { } let param_env = tcx.param_env_reveal_all_normalized(def_id); + let codegen_fn_attrs = tcx.codegen_fn_attrs(def_id); let mut this = Inliner { tcx, param_env, - codegen_fn_attrs: tcx.codegen_fn_attrs(def_id), + codegen_fn_attrs, history: Vec::new(), changed: false, + caller_is_inline_forwarder: matches!( + codegen_fn_attrs.inline, + InlineAttr::Hint | InlineAttr::Always + ) && body_is_forwarder(body), }; let blocks = START_BLOCK..body.basic_blocks.next_index(); this.process_blocks(body, blocks); @@ -111,6 +116,9 @@ struct Inliner<'tcx> { history: Vec, /// Indicates that the caller body has been modified. changed: bool, + /// Indicates that the caller is #[inline] and just calls another function, + /// and thus we can inline less into it as it'll be inlined itself. + caller_is_inline_forwarder: bool, } impl<'tcx> Inliner<'tcx> { @@ -485,7 +493,9 @@ impl<'tcx> Inliner<'tcx> { ) -> Result<(), &'static str> { let tcx = self.tcx; - let mut threshold = if cross_crate_inlinable { + let mut threshold = if self.caller_is_inline_forwarder { + self.tcx.sess.opts.unstable_opts.inline_mir_forwarder_threshold.unwrap_or(30) + } else if cross_crate_inlinable { self.tcx.sess.opts.unstable_opts.inline_mir_hint_threshold.unwrap_or(100) } else { self.tcx.sess.opts.unstable_opts.inline_mir_threshold.unwrap_or(50) @@ -504,6 +514,8 @@ impl<'tcx> Inliner<'tcx> { let mut checker = CostChecker::new(self.tcx, self.param_env, Some(callsite.callee), callee_body); + checker.add_function_level_costs(); + // Traverse the MIR manually so we can account for the effects of inlining on the CFG. let mut work_list = vec![START_BLOCK]; let mut visited = BitSet::new_empty(callee_body.basic_blocks.len()); @@ -1091,3 +1103,37 @@ fn try_instance_mir<'tcx>( } Ok(tcx.instance_mir(instance)) } + +fn body_is_forwarder(body: &Body<'_>) -> bool { + let TerminatorKind::Call { target, .. } = body.basic_blocks[START_BLOCK].terminator().kind + else { + return false; + }; + if let Some(target) = target { + let TerminatorKind::Return = body.basic_blocks[target].terminator().kind else { + return false; + }; + } + + let max_blocks = if !body.is_polymorphic { + 2 + } else if target.is_none() { + 3 + } else { + 4 + }; + if body.basic_blocks.len() > max_blocks { + return false; + } + + body.basic_blocks.iter_enumerated().all(|(bb, bb_data)| { + bb == START_BLOCK + || matches!( + bb_data.terminator().kind, + TerminatorKind::Return + | TerminatorKind::Drop { .. } + | TerminatorKind::UnwindResume + | TerminatorKind::UnwindTerminate(_) + ) + }) +} diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index 80f7ca544f3c5..2e4421d50e313 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -1766,6 +1766,8 @@ options! { "enable LLVM inlining (default: yes)"), inline_mir: Option = (None, parse_opt_bool, [TRACKED], "enable MIR inlining (default: no)"), + inline_mir_forwarder_threshold: Option = (None, parse_opt_number, [TRACKED], + "inlining threshold when the caller is a simple forwarding function (default: 30)"), inline_mir_hint_threshold: Option = (None, parse_opt_number, [TRACKED], "inlining threshold for functions with inline hint (default: 100)"), inline_mir_preserve_debug: Option = (None, parse_opt_bool, [TRACKED], diff --git a/library/alloc/src/raw_vec.rs b/library/alloc/src/raw_vec.rs index 1134c7f833e2b..7b7dae5a057f0 100644 --- a/library/alloc/src/raw_vec.rs +++ b/library/alloc/src/raw_vec.rs @@ -429,6 +429,7 @@ impl RawVec { /// /// Aborts on OOM. #[cfg(not(no_global_oom_handling))] + #[inline] pub fn shrink_to_fit(&mut self, cap: usize) { if let Err(err) = self.shrink(cap) { handle_error(err); @@ -511,9 +512,25 @@ impl RawVec { } #[cfg(not(no_global_oom_handling))] + #[inline] fn shrink(&mut self, cap: usize) -> Result<(), TryReserveError> { assert!(cap <= self.capacity(), "Tried to shrink to a larger capacity"); + // SAFETY: Just checked this isn't trying to grow + unsafe { self.shrink_unchecked(cap) } + } + /// `shrink`, but without the capacity check. + /// + /// This is split out so that `shrink` can inline the check, since it + /// optimizes out in things like `shrink_to_fit`, without needing to + /// also inline all this code, as doing that ends up failing the + /// `vec-shrink-panic` codegen test when `shrink_to_fit` ends up being too + /// big for LLVM to be willing to inline. + /// + /// # Safety + /// `cap <= self.capacity()` + #[cfg(not(no_global_oom_handling))] + unsafe fn shrink_unchecked(&mut self, cap: usize) -> Result<(), TryReserveError> { let (ptr, layout) = if let Some(mem) = self.current_memory() { mem } else { return Ok(()) }; // See current_memory() why this assert is here const { assert!(mem::size_of::() % mem::align_of::() == 0) }; diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index 743429d26dbfb..f1706e31bb80a 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -1101,6 +1101,7 @@ impl Vec { /// ``` #[cfg(not(no_global_oom_handling))] #[stable(feature = "rust1", since = "1.0.0")] + #[inline] pub fn shrink_to_fit(&mut self) { // The capacity is never less than the length, and there's nothing to do when // they are equal, so we can avoid the panic case in `RawVec::shrink_to_fit` diff --git a/tests/codegen-units/item-collection/drop_in_place_intrinsic.rs b/tests/codegen-units/item-collection/drop_in_place_intrinsic.rs index 947faa165a9cb..d87ad41e70d58 100644 --- a/tests/codegen-units/item-collection/drop_in_place_intrinsic.rs +++ b/tests/codegen-units/item-collection/drop_in_place_intrinsic.rs @@ -1,6 +1,7 @@ // //@ compile-flags:-Zprint-mono-items=eager //@ compile-flags:-Zinline-in-all-cgus +//@ compile-flags:-Zinline-mir=no #![feature(start)] diff --git a/tests/mir-opt/inline/inline_more_in_non_inline.marked_inline_direct.Inline.after.panic-abort.mir b/tests/mir-opt/inline/inline_more_in_non_inline.marked_inline_direct.Inline.after.panic-abort.mir new file mode 100644 index 0000000000000..522f772c6f48e --- /dev/null +++ b/tests/mir-opt/inline/inline_more_in_non_inline.marked_inline_direct.Inline.after.panic-abort.mir @@ -0,0 +1,22 @@ +// MIR for `marked_inline_direct` after Inline + +fn marked_inline_direct(_1: i32) -> () { + debug x => _1; + let mut _0: (); + let _2: (); + let mut _3: i32; + + bb0: { + StorageLive(_2); + StorageLive(_3); + _3 = _1; + _2 = call_twice(move _3) -> [return: bb1, unwind unreachable]; + } + + bb1: { + StorageDead(_3); + StorageDead(_2); + _0 = const (); + return; + } +} diff --git a/tests/mir-opt/inline/inline_more_in_non_inline.marked_inline_direct.Inline.after.panic-unwind.mir b/tests/mir-opt/inline/inline_more_in_non_inline.marked_inline_direct.Inline.after.panic-unwind.mir new file mode 100644 index 0000000000000..722b02eeba806 --- /dev/null +++ b/tests/mir-opt/inline/inline_more_in_non_inline.marked_inline_direct.Inline.after.panic-unwind.mir @@ -0,0 +1,22 @@ +// MIR for `marked_inline_direct` after Inline + +fn marked_inline_direct(_1: i32) -> () { + debug x => _1; + let mut _0: (); + let _2: (); + let mut _3: i32; + + bb0: { + StorageLive(_2); + StorageLive(_3); + _3 = _1; + _2 = call_twice(move _3) -> [return: bb1, unwind continue]; + } + + bb1: { + StorageDead(_3); + StorageDead(_2); + _0 = const (); + return; + } +} diff --git a/tests/mir-opt/inline/inline_more_in_non_inline.marked_inline_indirect.Inline.after.panic-abort.mir b/tests/mir-opt/inline/inline_more_in_non_inline.marked_inline_indirect.Inline.after.panic-abort.mir new file mode 100644 index 0000000000000..63b91cbce2d60 --- /dev/null +++ b/tests/mir-opt/inline/inline_more_in_non_inline.marked_inline_indirect.Inline.after.panic-abort.mir @@ -0,0 +1,27 @@ +// MIR for `marked_inline_indirect` after Inline + +fn marked_inline_indirect(_1: i32) -> () { + debug x => _1; + let mut _0: (); + let _2: (); + let mut _3: i32; + scope 1 (inlined marked_inline_direct) { + let _4: (); + } + + bb0: { + StorageLive(_2); + StorageLive(_3); + _3 = _1; + StorageLive(_4); + _4 = call_twice(move _3) -> [return: bb1, unwind unreachable]; + } + + bb1: { + StorageDead(_4); + StorageDead(_3); + StorageDead(_2); + _0 = const (); + return; + } +} diff --git a/tests/mir-opt/inline/inline_more_in_non_inline.marked_inline_indirect.Inline.after.panic-unwind.mir b/tests/mir-opt/inline/inline_more_in_non_inline.marked_inline_indirect.Inline.after.panic-unwind.mir new file mode 100644 index 0000000000000..7c84e98dd516c --- /dev/null +++ b/tests/mir-opt/inline/inline_more_in_non_inline.marked_inline_indirect.Inline.after.panic-unwind.mir @@ -0,0 +1,27 @@ +// MIR for `marked_inline_indirect` after Inline + +fn marked_inline_indirect(_1: i32) -> () { + debug x => _1; + let mut _0: (); + let _2: (); + let mut _3: i32; + scope 1 (inlined marked_inline_direct) { + let _4: (); + } + + bb0: { + StorageLive(_2); + StorageLive(_3); + _3 = _1; + StorageLive(_4); + _4 = call_twice(move _3) -> [return: bb1, unwind continue]; + } + + bb1: { + StorageDead(_4); + StorageDead(_3); + StorageDead(_2); + _0 = const (); + return; + } +} diff --git a/tests/mir-opt/inline/inline_more_in_non_inline.monomorphic_not_inline.Inline.after.panic-abort.mir b/tests/mir-opt/inline/inline_more_in_non_inline.monomorphic_not_inline.Inline.after.panic-abort.mir new file mode 100644 index 0000000000000..989014b8b476d --- /dev/null +++ b/tests/mir-opt/inline/inline_more_in_non_inline.monomorphic_not_inline.Inline.after.panic-abort.mir @@ -0,0 +1,34 @@ +// MIR for `monomorphic_not_inline` after Inline + +fn monomorphic_not_inline(_1: i32) -> () { + debug x => _1; + let mut _0: (); + let _2: (); + let mut _3: i32; + scope 1 (inlined call_twice) { + let _4: (); + let _5: (); + } + + bb0: { + StorageLive(_2); + StorageLive(_3); + _3 = _1; + StorageLive(_4); + StorageLive(_5); + _4 = other_thing(_3) -> [return: bb2, unwind unreachable]; + } + + bb1: { + StorageDead(_5); + StorageDead(_4); + StorageDead(_3); + StorageDead(_2); + _0 = const (); + return; + } + + bb2: { + _5 = other_thing(move _3) -> [return: bb1, unwind unreachable]; + } +} diff --git a/tests/mir-opt/inline/inline_more_in_non_inline.monomorphic_not_inline.Inline.after.panic-unwind.mir b/tests/mir-opt/inline/inline_more_in_non_inline.monomorphic_not_inline.Inline.after.panic-unwind.mir new file mode 100644 index 0000000000000..bd200719bbbe9 --- /dev/null +++ b/tests/mir-opt/inline/inline_more_in_non_inline.monomorphic_not_inline.Inline.after.panic-unwind.mir @@ -0,0 +1,34 @@ +// MIR for `monomorphic_not_inline` after Inline + +fn monomorphic_not_inline(_1: i32) -> () { + debug x => _1; + let mut _0: (); + let _2: (); + let mut _3: i32; + scope 1 (inlined call_twice) { + let _4: (); + let _5: (); + } + + bb0: { + StorageLive(_2); + StorageLive(_3); + _3 = _1; + StorageLive(_4); + StorageLive(_5); + _4 = other_thing(_3) -> [return: bb2, unwind continue]; + } + + bb1: { + StorageDead(_5); + StorageDead(_4); + StorageDead(_3); + StorageDead(_2); + _0 = const (); + return; + } + + bb2: { + _5 = other_thing(move _3) -> [return: bb1, unwind continue]; + } +} diff --git a/tests/mir-opt/inline/inline_more_in_non_inline.rs b/tests/mir-opt/inline/inline_more_in_non_inline.rs new file mode 100644 index 0000000000000..5968b97047096 --- /dev/null +++ b/tests/mir-opt/inline/inline_more_in_non_inline.rs @@ -0,0 +1,46 @@ +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY +//@ compile-flags: -O --crate-type lib + +// To avoid MIR blow-up, don't inline large callees into simple shim callers, +// but *do* inline other trivial things. + +extern "Rust" { + fn other_thing(x: i32); +} + +#[inline] +unsafe fn call_twice(x: i32) { + unsafe { + other_thing(x); + other_thing(x); + } +} + +// EMIT_MIR inline_more_in_non_inline.monomorphic_not_inline.Inline.after.mir +#[no_mangle] +pub unsafe fn monomorphic_not_inline(x: i32) { + // CHECK-LABEL: monomorphic_not_inline + // CHECK: other_thing + // CHECK: other_thing + unsafe { call_twice(x) }; +} + +// EMIT_MIR inline_more_in_non_inline.marked_inline_direct.Inline.after.mir +#[inline] +pub unsafe fn marked_inline_direct(x: i32) { + // CHECK-LABEL: marked_inline_direct + // CHECK-NOT: other_thing + // CHECK: call_twice + // CHECK-NOT: other_thing + unsafe { call_twice(x) }; +} + +// EMIT_MIR inline_more_in_non_inline.marked_inline_indirect.Inline.after.mir +#[inline] +pub unsafe fn marked_inline_indirect(x: i32) { + // CHECK-LABEL: marked_inline_indirect + // CHECK-NOT: other_thing + // CHECK: call_twice + // CHECK-NOT: other_thing + unsafe { marked_inline_direct(x) }; +} diff --git a/tests/mir-opt/inline/inline_shims.drop.Inline.panic-abort.diff b/tests/mir-opt/inline/inline_shims.drop.Inline.panic-abort.diff index 45ce933a55ad2..2a36ccaab110a 100644 --- a/tests/mir-opt/inline/inline_shims.drop.Inline.panic-abort.diff +++ b/tests/mir-opt/inline/inline_shims.drop.Inline.panic-abort.diff @@ -11,30 +11,10 @@ + scope 1 (inlined std::ptr::drop_in_place::> - shim(Some(Vec))) { + let mut _6: &mut std::vec::Vec; + let mut _7: (); -+ scope 2 (inlined as Drop>::drop) { -+ let mut _8: *mut [A]; -+ let mut _9: *mut A; -+ let mut _10: usize; -+ scope 3 (inlined Vec::::as_mut_ptr) { -+ let mut _11: &alloc::raw_vec::RawVec; -+ scope 4 (inlined alloc::raw_vec::RawVec::::ptr) { -+ let mut _13: std::ptr::NonNull; -+ scope 5 (inlined Unique::::as_ptr) { -+ scope 6 (inlined NonNull::::as_ptr) { -+ let mut _12: *const A; -+ } -+ } -+ } -+ } -+ scope 7 (inlined slice_from_raw_parts_mut::) { -+ scope 8 (inlined std::ptr::from_raw_parts_mut::<[A], A>) { -+ } -+ } -+ } + } -+ scope 9 (inlined std::ptr::drop_in_place::> - shim(Some(Option))) { -+ let mut _14: isize; -+ let mut _15: isize; ++ scope 2 (inlined std::ptr::drop_in_place::> - shim(Some(Option))) { ++ let mut _8: isize; ++ let mut _9: isize; + } bb0: { @@ -45,24 +25,7 @@ + StorageLive(_6); + StorageLive(_7); + _6 = &mut (*_4); -+ StorageLive(_8); -+ StorageLive(_9); -+ StorageLive(_11); -+ _11 = &((*_6).0: alloc::raw_vec::RawVec); -+ StorageLive(_13); -+ _13 = ((((*_6).0: alloc::raw_vec::RawVec).0: std::ptr::Unique).0: std::ptr::NonNull); -+ StorageLive(_12); -+ _12 = (_13.0: *const A); -+ _9 = move _12 as *mut A (PtrToPtr); -+ StorageDead(_12); -+ StorageDead(_13); -+ StorageDead(_11); -+ StorageLive(_10); -+ _10 = ((*_6).1: usize); -+ _8 = *mut [A] from (_9, _10); -+ StorageDead(_10); -+ StorageDead(_9); -+ _7 = std::ptr::drop_in_place::<[A]>(move _8) -> [return: bb2, unwind unreachable]; ++ _7 = as Drop>::drop(move _6) -> [return: bb2, unwind unreachable]; } bb1: { @@ -73,20 +36,19 @@ StorageLive(_5); _5 = _2; - _0 = std::ptr::drop_in_place::>(move _5) -> [return: bb2, unwind unreachable]; -+ StorageLive(_14); -+ StorageLive(_15); -+ _14 = discriminant((*_5)); -+ switchInt(move _14) -> [0: bb3, otherwise: bb4]; ++ StorageLive(_8); ++ StorageLive(_9); ++ _8 = discriminant((*_5)); ++ switchInt(move _8) -> [0: bb3, otherwise: bb4]; } bb2: { -+ StorageDead(_8); + drop(((*_4).0: alloc::raw_vec::RawVec)) -> [return: bb1, unwind unreachable]; + } + + bb3: { -+ StorageDead(_15); -+ StorageDead(_14); ++ StorageDead(_9); ++ StorageDead(_8); StorageDead(_5); return; + } diff --git a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-abort.mir index 79c5bcfe9cd5c..fbb887fe76a59 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-abort.mir @@ -7,90 +7,19 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () { let mut _11: std::slice::Iter<'_, T>; let mut _12: std::iter::Rev>; let mut _13: std::iter::Rev>; - let mut _37: std::option::Option<&T>; - let mut _39: &impl Fn(&T); - let mut _40: (&T,); - let _41: (); + let mut _15: std::option::Option<&T>; + let mut _16: isize; + let mut _18: &impl Fn(&T); + let mut _19: (&T,); + let _20: (); scope 1 { debug iter => _13; - let _38: &T; + let _17: &T; scope 2 { - debug x => _38; + debug x => _17; } scope 17 (inlined > as Iterator>::next) { - scope 18 (inlined as DoubleEndedIterator>::next_back) { - let mut _14: *const *const T; - let mut _15: *const std::ptr::NonNull; - let mut _20: bool; - let mut _21: *const T; - let _36: &T; - scope 19 { - let _16: std::ptr::NonNull; - let _22: usize; - scope 20 { - } - scope 21 { - scope 25 (inlined as PartialEq>::eq) { - let mut _17: std::ptr::NonNull; - scope 26 (inlined NonNull::::as_ptr) { - let mut _18: *const T; - } - scope 27 (inlined NonNull::::as_ptr) { - let mut _19: *const T; - } - } - } - scope 22 (inlined std::ptr::const_ptr::::addr) { - scope 23 (inlined std::ptr::const_ptr::::cast::<()>) { - } - } - scope 24 (inlined std::ptr::const_ptr::::cast::>) { - } - } - scope 28 (inlined std::slice::Iter::<'_, T>::next_back_unchecked) { - let _29: std::ptr::NonNull; - scope 29 (inlined std::slice::Iter::<'_, T>::pre_dec_end) { - let mut _23: *mut *const T; - let mut _24: *mut std::ptr::NonNull; - let mut _25: std::ptr::NonNull; - let mut _28: std::ptr::NonNull; - let mut _30: *mut *const T; - let mut _31: *mut usize; - let mut _32: usize; - let mut _33: usize; - scope 30 { - scope 31 { - } - scope 32 { - scope 35 (inlined NonNull::::sub) { - scope 36 (inlined core::num::::unchecked_neg) { - scope 37 (inlined core::ub_checks::check_language_ub) { - scope 38 (inlined core::ub_checks::check_language_ub::runtime) { - } - } - } - scope 39 (inlined NonNull::::offset) { - let mut _26: *const T; - let mut _27: *const T; - } - } - } - scope 33 (inlined std::ptr::mut_ptr::::cast::) { - } - scope 34 (inlined std::ptr::mut_ptr::::cast::>) { - } - } - } - scope 40 (inlined NonNull::::as_ref::<'_>) { - let mut _34: std::ptr::NonNull; - scope 41 (inlined NonNull::::as_ptr) { - let mut _35: *const T; - } - scope 42 (inlined std::ptr::mut_ptr::::cast_const) { - } - } - } - } + let mut _14: &mut std::slice::Iter<'_, T>; } } scope 3 (inlined core::slice::::iter) { @@ -178,147 +107,45 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () { } bb4: { - StorageLive(_37); - StorageLive(_22); - StorageLive(_21); - StorageLive(_16); - StorageLive(_36); - StorageLive(_20); - switchInt(const ::IS_ZST) -> [0: bb5, otherwise: bb6]; + StorageLive(_15); + StorageLive(_14); + _14 = &mut (_13.0: std::slice::Iter<'_, T>); + _15 = as DoubleEndedIterator>::next_back(move _14) -> [return: bb5, unwind unreachable]; } bb5: { - StorageLive(_15); - StorageLive(_14); - _14 = &raw const ((_13.0: std::slice::Iter<'_, T>).1: *const T); - _15 = _14 as *const std::ptr::NonNull (PtrToPtr); StorageDead(_14); - _16 = (*_15); - StorageDead(_15); - StorageLive(_18); - StorageLive(_19); - StorageLive(_17); - _17 = ((_13.0: std::slice::Iter<'_, T>).0: std::ptr::NonNull); - _18 = (_17.0: *const T); - StorageDead(_17); - _19 = (_16.0: *const T); - _20 = Eq(_18, _19); - StorageDead(_19); - StorageDead(_18); - goto -> bb7; + _16 = discriminant(_15); + switchInt(move _16) -> [0: bb6, 1: bb8, otherwise: bb10]; } bb6: { - _21 = ((_13.0: std::slice::Iter<'_, T>).1: *const T); - _22 = _21 as usize (Transmute); - _20 = Eq(_22, const 0_usize); - goto -> bb7; + StorageDead(_15); + StorageDead(_13); + drop(_2) -> [return: bb7, unwind unreachable]; } bb7: { - switchInt(move _20) -> [0: bb8, otherwise: bb16]; + return; } bb8: { - StorageLive(_35); - StorageLive(_29); - StorageLive(_31); - StorageLive(_24); - switchInt(const ::IS_ZST) -> [0: bb9, otherwise: bb13]; + _17 = ((_15 as Some).0: &T); + StorageLive(_18); + _18 = &_2; + StorageLive(_19); + _19 = (_17,); + _20 = >::call(move _18, move _19) -> [return: bb9, unwind unreachable]; } bb9: { - StorageLive(_23); - _23 = &raw mut ((_13.0: std::slice::Iter<'_, T>).1: *const T); - _24 = _23 as *mut std::ptr::NonNull (PtrToPtr); - StorageDead(_23); - StorageLive(_28); - _25 = (*_24); - switchInt(const ::IS_ZST) -> [0: bb10, otherwise: bb11]; - } - - bb10: { - StorageLive(_27); - StorageLive(_26); - _26 = (_25.0: *const T); - _27 = Offset(move _26, const -1_isize); - StorageDead(_26); - _28 = NonNull:: { pointer: move _27 }; - StorageDead(_27); - goto -> bb12; - } - - bb11: { - _28 = _25; - goto -> bb12; - } - - bb12: { - (*_24) = move _28; - StorageDead(_28); - _29 = (*_24); - goto -> bb14; - } - - bb13: { - StorageLive(_30); - _30 = &raw mut ((_13.0: std::slice::Iter<'_, T>).1: *const T); - _31 = _30 as *mut usize (PtrToPtr); - StorageDead(_30); - StorageLive(_33); - StorageLive(_32); - _32 = (*_31); - _33 = SubUnchecked(move _32, const 1_usize); - StorageDead(_32); - (*_31) = move _33; - StorageDead(_33); - _29 = ((_13.0: std::slice::Iter<'_, T>).0: std::ptr::NonNull); - goto -> bb14; - } - - bb14: { - StorageDead(_24); - StorageDead(_31); - StorageLive(_34); - _34 = _29; - _35 = (_34.0: *const T); - StorageDead(_34); - _36 = &(*_35); - StorageDead(_29); - StorageDead(_35); - _37 = Option::<&T>::Some(_36); - StorageDead(_20); - StorageDead(_36); - StorageDead(_16); - StorageDead(_21); - StorageDead(_22); - _38 = ((_37 as Some).0: &T); - StorageLive(_39); - _39 = &_2; - StorageLive(_40); - _40 = (_38,); - _41 = >::call(move _39, move _40) -> [return: bb15, unwind unreachable]; - } - - bb15: { - StorageDead(_40); - StorageDead(_39); - StorageDead(_37); + StorageDead(_19); + StorageDead(_18); + StorageDead(_15); goto -> bb4; } - bb16: { - StorageDead(_20); - StorageDead(_36); - StorageDead(_16); - StorageDead(_21); - StorageDead(_22); - StorageDead(_37); - StorageDead(_13); - drop(_2) -> [return: bb17, unwind unreachable]; - } - - bb17: { - return; + bb10: { + unreachable; } } diff --git a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir index 7c107a23f9e0b..db9409f72ab1a 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir @@ -7,90 +7,19 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () { let mut _11: std::slice::Iter<'_, T>; let mut _12: std::iter::Rev>; let mut _13: std::iter::Rev>; - let mut _37: std::option::Option<&T>; - let mut _39: &impl Fn(&T); - let mut _40: (&T,); - let _41: (); + let mut _15: std::option::Option<&T>; + let mut _16: isize; + let mut _18: &impl Fn(&T); + let mut _19: (&T,); + let _20: (); scope 1 { debug iter => _13; - let _38: &T; + let _17: &T; scope 2 { - debug x => _38; + debug x => _17; } scope 17 (inlined > as Iterator>::next) { - scope 18 (inlined as DoubleEndedIterator>::next_back) { - let mut _14: *const *const T; - let mut _15: *const std::ptr::NonNull; - let mut _20: bool; - let mut _21: *const T; - let _36: &T; - scope 19 { - let _16: std::ptr::NonNull; - let _22: usize; - scope 20 { - } - scope 21 { - scope 25 (inlined as PartialEq>::eq) { - let mut _17: std::ptr::NonNull; - scope 26 (inlined NonNull::::as_ptr) { - let mut _18: *const T; - } - scope 27 (inlined NonNull::::as_ptr) { - let mut _19: *const T; - } - } - } - scope 22 (inlined std::ptr::const_ptr::::addr) { - scope 23 (inlined std::ptr::const_ptr::::cast::<()>) { - } - } - scope 24 (inlined std::ptr::const_ptr::::cast::>) { - } - } - scope 28 (inlined std::slice::Iter::<'_, T>::next_back_unchecked) { - let _29: std::ptr::NonNull; - scope 29 (inlined std::slice::Iter::<'_, T>::pre_dec_end) { - let mut _23: *mut *const T; - let mut _24: *mut std::ptr::NonNull; - let mut _25: std::ptr::NonNull; - let mut _28: std::ptr::NonNull; - let mut _30: *mut *const T; - let mut _31: *mut usize; - let mut _32: usize; - let mut _33: usize; - scope 30 { - scope 31 { - } - scope 32 { - scope 35 (inlined NonNull::::sub) { - scope 36 (inlined core::num::::unchecked_neg) { - scope 37 (inlined core::ub_checks::check_language_ub) { - scope 38 (inlined core::ub_checks::check_language_ub::runtime) { - } - } - } - scope 39 (inlined NonNull::::offset) { - let mut _26: *const T; - let mut _27: *const T; - } - } - } - scope 33 (inlined std::ptr::mut_ptr::::cast::) { - } - scope 34 (inlined std::ptr::mut_ptr::::cast::>) { - } - } - } - scope 40 (inlined NonNull::::as_ref::<'_>) { - let mut _34: std::ptr::NonNull; - scope 41 (inlined NonNull::::as_ptr) { - let mut _35: *const T; - } - scope 42 (inlined std::ptr::mut_ptr::::cast_const) { - } - } - } - } + let mut _14: &mut std::slice::Iter<'_, T>; } } scope 3 (inlined core::slice::::iter) { @@ -178,155 +107,53 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () { } bb4: { - StorageLive(_37); - StorageLive(_22); - StorageLive(_21); - StorageLive(_16); - StorageLive(_36); - StorageLive(_20); - switchInt(const ::IS_ZST) -> [0: bb5, otherwise: bb6]; + StorageLive(_15); + StorageLive(_14); + _14 = &mut (_13.0: std::slice::Iter<'_, T>); + _15 = as DoubleEndedIterator>::next_back(move _14) -> [return: bb5, unwind: bb11]; } bb5: { - StorageLive(_15); - StorageLive(_14); - _14 = &raw const ((_13.0: std::slice::Iter<'_, T>).1: *const T); - _15 = _14 as *const std::ptr::NonNull (PtrToPtr); StorageDead(_14); - _16 = (*_15); - StorageDead(_15); - StorageLive(_18); - StorageLive(_19); - StorageLive(_17); - _17 = ((_13.0: std::slice::Iter<'_, T>).0: std::ptr::NonNull); - _18 = (_17.0: *const T); - StorageDead(_17); - _19 = (_16.0: *const T); - _20 = Eq(_18, _19); - StorageDead(_19); - StorageDead(_18); - goto -> bb7; + _16 = discriminant(_15); + switchInt(move _16) -> [0: bb6, 1: bb8, otherwise: bb10]; } bb6: { - _21 = ((_13.0: std::slice::Iter<'_, T>).1: *const T); - _22 = _21 as usize (Transmute); - _20 = Eq(_22, const 0_usize); - goto -> bb7; + StorageDead(_15); + StorageDead(_13); + drop(_2) -> [return: bb7, unwind continue]; } bb7: { - switchInt(move _20) -> [0: bb8, otherwise: bb18]; + return; } bb8: { - StorageLive(_35); - StorageLive(_29); - StorageLive(_31); - StorageLive(_24); - switchInt(const ::IS_ZST) -> [0: bb9, otherwise: bb13]; + _17 = ((_15 as Some).0: &T); + StorageLive(_18); + _18 = &_2; + StorageLive(_19); + _19 = (_17,); + _20 = >::call(move _18, move _19) -> [return: bb9, unwind: bb11]; } bb9: { - StorageLive(_23); - _23 = &raw mut ((_13.0: std::slice::Iter<'_, T>).1: *const T); - _24 = _23 as *mut std::ptr::NonNull (PtrToPtr); - StorageDead(_23); - StorageLive(_28); - _25 = (*_24); - switchInt(const ::IS_ZST) -> [0: bb10, otherwise: bb11]; + StorageDead(_19); + StorageDead(_18); + StorageDead(_15); + goto -> bb4; } bb10: { - StorageLive(_27); - StorageLive(_26); - _26 = (_25.0: *const T); - _27 = Offset(move _26, const -1_isize); - StorageDead(_26); - _28 = NonNull:: { pointer: move _27 }; - StorageDead(_27); - goto -> bb12; - } - - bb11: { - _28 = _25; - goto -> bb12; - } - - bb12: { - (*_24) = move _28; - StorageDead(_28); - _29 = (*_24); - goto -> bb14; - } - - bb13: { - StorageLive(_30); - _30 = &raw mut ((_13.0: std::slice::Iter<'_, T>).1: *const T); - _31 = _30 as *mut usize (PtrToPtr); - StorageDead(_30); - StorageLive(_33); - StorageLive(_32); - _32 = (*_31); - _33 = SubUnchecked(move _32, const 1_usize); - StorageDead(_32); - (*_31) = move _33; - StorageDead(_33); - _29 = ((_13.0: std::slice::Iter<'_, T>).0: std::ptr::NonNull); - goto -> bb14; + unreachable; } - bb14: { - StorageDead(_24); - StorageDead(_31); - StorageLive(_34); - _34 = _29; - _35 = (_34.0: *const T); - StorageDead(_34); - _36 = &(*_35); - StorageDead(_29); - StorageDead(_35); - _37 = Option::<&T>::Some(_36); - StorageDead(_20); - StorageDead(_36); - StorageDead(_16); - StorageDead(_21); - StorageDead(_22); - _38 = ((_37 as Some).0: &T); - StorageLive(_39); - _39 = &_2; - StorageLive(_40); - _40 = (_38,); - _41 = >::call(move _39, move _40) -> [return: bb15, unwind: bb16]; + bb11 (cleanup): { + drop(_2) -> [return: bb12, unwind terminate(cleanup)]; } - bb15: { - StorageDead(_40); - StorageDead(_39); - StorageDead(_37); - goto -> bb4; - } - - bb16 (cleanup): { - drop(_2) -> [return: bb17, unwind terminate(cleanup)]; - } - - bb17 (cleanup): { + bb12 (cleanup): { resume; } - - bb18: { - StorageDead(_20); - StorageDead(_36); - StorageDead(_16); - StorageDead(_21); - StorageDead(_22); - StorageDead(_37); - StorageDead(_13); - drop(_2) -> [return: bb19, unwind continue]; - } - - bb19: { - return; - } } diff --git a/tests/mir-opt/pre-codegen/slice_iter.slice_iter_mut_next_back.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_iter.slice_iter_mut_next_back.PreCodegen.after.panic-abort.mir index 2df346c081c8e..78f96bf419559 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.slice_iter_mut_next_back.PreCodegen.after.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.slice_iter_mut_next_back.PreCodegen.after.panic-abort.mir @@ -3,205 +3,12 @@ fn slice_iter_mut_next_back(_1: &mut std::slice::IterMut<'_, T>) -> Option<&mut T> { debug it => _1; let mut _0: std::option::Option<&mut T>; - scope 1 (inlined as DoubleEndedIterator>::next_back) { - let mut _2: *const *mut T; - let mut _3: *const std::ptr::NonNull; - let mut _8: bool; - let mut _9: *mut T; - let mut _25: &mut T; - scope 2 { - let _4: std::ptr::NonNull; - let _10: usize; - scope 3 { - } - scope 4 { - scope 8 (inlined as PartialEq>::eq) { - let mut _5: std::ptr::NonNull; - scope 9 (inlined NonNull::::as_ptr) { - let mut _6: *const T; - } - scope 10 (inlined NonNull::::as_ptr) { - let mut _7: *const T; - } - } - } - scope 5 (inlined std::ptr::mut_ptr::::addr) { - scope 6 (inlined std::ptr::mut_ptr::::cast::<()>) { - } - } - scope 7 (inlined std::ptr::const_ptr::::cast::>) { - } - } - scope 11 (inlined std::slice::IterMut::<'_, T>::next_back_unchecked) { - let mut _17: std::ptr::NonNull; - scope 12 (inlined std::slice::IterMut::<'_, T>::pre_dec_end) { - let mut _11: *mut *mut T; - let mut _12: *mut std::ptr::NonNull; - let mut _13: std::ptr::NonNull; - let mut _16: std::ptr::NonNull; - let mut _18: *mut *mut T; - let mut _19: *mut usize; - let mut _20: usize; - let mut _21: usize; - scope 13 { - scope 14 { - } - scope 15 { - scope 18 (inlined NonNull::::sub) { - scope 19 (inlined core::num::::unchecked_neg) { - scope 20 (inlined core::ub_checks::check_language_ub) { - scope 21 (inlined core::ub_checks::check_language_ub::runtime) { - } - } - } - scope 22 (inlined NonNull::::offset) { - let mut _14: *const T; - let mut _15: *const T; - } - } - } - scope 16 (inlined std::ptr::mut_ptr::::cast::) { - } - scope 17 (inlined std::ptr::mut_ptr::::cast::>) { - } - } - } - scope 23 (inlined NonNull::::as_mut::<'_>) { - let mut _22: std::ptr::NonNull; - let mut _24: *mut T; - scope 24 (inlined NonNull::::as_ptr) { - let mut _23: *const T; - } - } - } - } bb0: { - StorageLive(_10); - StorageLive(_9); - StorageLive(_4); - StorageLive(_25); - StorageLive(_8); - switchInt(const ::IS_ZST) -> [0: bb1, otherwise: bb2]; + _0 = as DoubleEndedIterator>::next_back(move _1) -> [return: bb1, unwind unreachable]; } bb1: { - StorageLive(_3); - StorageLive(_2); - _2 = &raw const ((*_1).1: *mut T); - _3 = _2 as *const std::ptr::NonNull (PtrToPtr); - StorageDead(_2); - _4 = (*_3); - StorageDead(_3); - StorageLive(_6); - StorageLive(_7); - StorageLive(_5); - _5 = ((*_1).0: std::ptr::NonNull); - _6 = (_5.0: *const T); - StorageDead(_5); - _7 = (_4.0: *const T); - _8 = Eq(_6, _7); - StorageDead(_7); - StorageDead(_6); - goto -> bb3; - } - - bb2: { - _9 = ((*_1).1: *mut T); - _10 = _9 as usize (Transmute); - _8 = Eq(_10, const 0_usize); - goto -> bb3; - } - - bb3: { - switchInt(move _8) -> [0: bb4, otherwise: bb11]; - } - - bb4: { - StorageLive(_24); - StorageLive(_17); - StorageLive(_19); - StorageLive(_12); - switchInt(const ::IS_ZST) -> [0: bb5, otherwise: bb9]; - } - - bb5: { - StorageLive(_11); - _11 = &raw mut ((*_1).1: *mut T); - _12 = _11 as *mut std::ptr::NonNull (PtrToPtr); - StorageDead(_11); - StorageLive(_16); - _13 = (*_12); - switchInt(const ::IS_ZST) -> [0: bb6, otherwise: bb7]; - } - - bb6: { - StorageLive(_15); - StorageLive(_14); - _14 = (_13.0: *const T); - _15 = Offset(move _14, const -1_isize); - StorageDead(_14); - _16 = NonNull:: { pointer: move _15 }; - StorageDead(_15); - goto -> bb8; - } - - bb7: { - _16 = _13; - goto -> bb8; - } - - bb8: { - (*_12) = move _16; - StorageDead(_16); - _17 = (*_12); - goto -> bb10; - } - - bb9: { - StorageLive(_18); - _18 = &raw mut ((*_1).1: *mut T); - _19 = _18 as *mut usize (PtrToPtr); - StorageDead(_18); - StorageLive(_21); - StorageLive(_20); - _20 = (*_19); - _21 = SubUnchecked(move _20, const 1_usize); - StorageDead(_20); - (*_19) = move _21; - StorageDead(_21); - _17 = ((*_1).0: std::ptr::NonNull); - goto -> bb10; - } - - bb10: { - StorageDead(_12); - StorageDead(_19); - StorageLive(_22); - _22 = _17; - StorageLive(_23); - _23 = (_22.0: *const T); - _24 = move _23 as *mut T (PtrToPtr); - StorageDead(_23); - StorageDead(_22); - _25 = &mut (*_24); - StorageDead(_17); - StorageDead(_24); - _0 = Option::<&mut T>::Some(_25); - goto -> bb12; - } - - bb11: { - _0 = const {transmute(0x0000000000000000): Option<&mut T>}; - goto -> bb12; - } - - bb12: { - StorageDead(_8); - StorageDead(_25); - StorageDead(_4); - StorageDead(_9); - StorageDead(_10); return; } } diff --git a/tests/mir-opt/pre-codegen/slice_iter.slice_iter_mut_next_back.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_iter.slice_iter_mut_next_back.PreCodegen.after.panic-unwind.mir index 2df346c081c8e..dfe5e206fadaf 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.slice_iter_mut_next_back.PreCodegen.after.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.slice_iter_mut_next_back.PreCodegen.after.panic-unwind.mir @@ -3,205 +3,12 @@ fn slice_iter_mut_next_back(_1: &mut std::slice::IterMut<'_, T>) -> Option<&mut T> { debug it => _1; let mut _0: std::option::Option<&mut T>; - scope 1 (inlined as DoubleEndedIterator>::next_back) { - let mut _2: *const *mut T; - let mut _3: *const std::ptr::NonNull; - let mut _8: bool; - let mut _9: *mut T; - let mut _25: &mut T; - scope 2 { - let _4: std::ptr::NonNull; - let _10: usize; - scope 3 { - } - scope 4 { - scope 8 (inlined as PartialEq>::eq) { - let mut _5: std::ptr::NonNull; - scope 9 (inlined NonNull::::as_ptr) { - let mut _6: *const T; - } - scope 10 (inlined NonNull::::as_ptr) { - let mut _7: *const T; - } - } - } - scope 5 (inlined std::ptr::mut_ptr::::addr) { - scope 6 (inlined std::ptr::mut_ptr::::cast::<()>) { - } - } - scope 7 (inlined std::ptr::const_ptr::::cast::>) { - } - } - scope 11 (inlined std::slice::IterMut::<'_, T>::next_back_unchecked) { - let mut _17: std::ptr::NonNull; - scope 12 (inlined std::slice::IterMut::<'_, T>::pre_dec_end) { - let mut _11: *mut *mut T; - let mut _12: *mut std::ptr::NonNull; - let mut _13: std::ptr::NonNull; - let mut _16: std::ptr::NonNull; - let mut _18: *mut *mut T; - let mut _19: *mut usize; - let mut _20: usize; - let mut _21: usize; - scope 13 { - scope 14 { - } - scope 15 { - scope 18 (inlined NonNull::::sub) { - scope 19 (inlined core::num::::unchecked_neg) { - scope 20 (inlined core::ub_checks::check_language_ub) { - scope 21 (inlined core::ub_checks::check_language_ub::runtime) { - } - } - } - scope 22 (inlined NonNull::::offset) { - let mut _14: *const T; - let mut _15: *const T; - } - } - } - scope 16 (inlined std::ptr::mut_ptr::::cast::) { - } - scope 17 (inlined std::ptr::mut_ptr::::cast::>) { - } - } - } - scope 23 (inlined NonNull::::as_mut::<'_>) { - let mut _22: std::ptr::NonNull; - let mut _24: *mut T; - scope 24 (inlined NonNull::::as_ptr) { - let mut _23: *const T; - } - } - } - } bb0: { - StorageLive(_10); - StorageLive(_9); - StorageLive(_4); - StorageLive(_25); - StorageLive(_8); - switchInt(const ::IS_ZST) -> [0: bb1, otherwise: bb2]; + _0 = as DoubleEndedIterator>::next_back(move _1) -> [return: bb1, unwind continue]; } bb1: { - StorageLive(_3); - StorageLive(_2); - _2 = &raw const ((*_1).1: *mut T); - _3 = _2 as *const std::ptr::NonNull (PtrToPtr); - StorageDead(_2); - _4 = (*_3); - StorageDead(_3); - StorageLive(_6); - StorageLive(_7); - StorageLive(_5); - _5 = ((*_1).0: std::ptr::NonNull); - _6 = (_5.0: *const T); - StorageDead(_5); - _7 = (_4.0: *const T); - _8 = Eq(_6, _7); - StorageDead(_7); - StorageDead(_6); - goto -> bb3; - } - - bb2: { - _9 = ((*_1).1: *mut T); - _10 = _9 as usize (Transmute); - _8 = Eq(_10, const 0_usize); - goto -> bb3; - } - - bb3: { - switchInt(move _8) -> [0: bb4, otherwise: bb11]; - } - - bb4: { - StorageLive(_24); - StorageLive(_17); - StorageLive(_19); - StorageLive(_12); - switchInt(const ::IS_ZST) -> [0: bb5, otherwise: bb9]; - } - - bb5: { - StorageLive(_11); - _11 = &raw mut ((*_1).1: *mut T); - _12 = _11 as *mut std::ptr::NonNull (PtrToPtr); - StorageDead(_11); - StorageLive(_16); - _13 = (*_12); - switchInt(const ::IS_ZST) -> [0: bb6, otherwise: bb7]; - } - - bb6: { - StorageLive(_15); - StorageLive(_14); - _14 = (_13.0: *const T); - _15 = Offset(move _14, const -1_isize); - StorageDead(_14); - _16 = NonNull:: { pointer: move _15 }; - StorageDead(_15); - goto -> bb8; - } - - bb7: { - _16 = _13; - goto -> bb8; - } - - bb8: { - (*_12) = move _16; - StorageDead(_16); - _17 = (*_12); - goto -> bb10; - } - - bb9: { - StorageLive(_18); - _18 = &raw mut ((*_1).1: *mut T); - _19 = _18 as *mut usize (PtrToPtr); - StorageDead(_18); - StorageLive(_21); - StorageLive(_20); - _20 = (*_19); - _21 = SubUnchecked(move _20, const 1_usize); - StorageDead(_20); - (*_19) = move _21; - StorageDead(_21); - _17 = ((*_1).0: std::ptr::NonNull); - goto -> bb10; - } - - bb10: { - StorageDead(_12); - StorageDead(_19); - StorageLive(_22); - _22 = _17; - StorageLive(_23); - _23 = (_22.0: *const T); - _24 = move _23 as *mut T (PtrToPtr); - StorageDead(_23); - StorageDead(_22); - _25 = &mut (*_24); - StorageDead(_17); - StorageDead(_24); - _0 = Option::<&mut T>::Some(_25); - goto -> bb12; - } - - bb11: { - _0 = const {transmute(0x0000000000000000): Option<&mut T>}; - goto -> bb12; - } - - bb12: { - StorageDead(_8); - StorageDead(_25); - StorageDead(_4); - StorageDead(_9); - StorageDead(_10); return; } } From fc8b6c6657962002af58f9a4cf5796031ebbf665 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 25 Jun 2024 12:39:04 +0200 Subject: [PATCH 531/892] Add `input_file` method on `LlvmFileCheck` --- src/tools/run-make-support/src/llvm.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/tools/run-make-support/src/llvm.rs b/src/tools/run-make-support/src/llvm.rs index 7f42223bf7f5a..4c9e9a5323025 100644 --- a/src/tools/run-make-support/src/llvm.rs +++ b/src/tools/run-make-support/src/llvm.rs @@ -180,6 +180,13 @@ impl LlvmFilecheck { self.cmd.arg(path.as_ref()); self } + + /// `--input-file` option. + pub fn input_file>(&mut self, input_file: P) -> &mut Self { + self.cmd.arg("--input-file"); + self.cmd.arg(input_file.as_ref()); + self + } } impl LlvmObjdump { From 7276499dc962a2fe5e6d7517ffdf1f866f046ed8 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 25 Jun 2024 12:39:19 +0200 Subject: [PATCH 532/892] Migrate `run-make/llvm-ident` to `rmake.rs` --- .../tidy/src/allowed_run_make_makefiles.txt | 1 - tests/run-make/llvm-ident/Makefile | 19 --------- tests/run-make/llvm-ident/rmake.rs | 41 +++++++++++++++++++ 3 files changed, 41 insertions(+), 20 deletions(-) delete mode 100644 tests/run-make/llvm-ident/Makefile create mode 100644 tests/run-make/llvm-ident/rmake.rs diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index 741bb46d1a713..5a8480e408d39 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -85,7 +85,6 @@ run-make/link-cfg/Makefile run-make/link-framework/Makefile run-make/link-path-order/Makefile run-make/linkage-attr-on-static/Makefile -run-make/llvm-ident/Makefile run-make/long-linker-command-lines-cmd-exe/Makefile run-make/long-linker-command-lines/Makefile run-make/longjmp-across-rust/Makefile diff --git a/tests/run-make/llvm-ident/Makefile b/tests/run-make/llvm-ident/Makefile deleted file mode 100644 index e583e6018e0bf..0000000000000 --- a/tests/run-make/llvm-ident/Makefile +++ /dev/null @@ -1,19 +0,0 @@ -include ../tools.mk - -# only-linux - -all: - # `-Ccodegen-units=16 -Copt-level=2` is used here to trigger thin LTO - # across codegen units to test deduplication of the named metadata - # (see `LLVMRustPrepareThinLTOImport` for details). - echo 'fn main(){}' | $(RUSTC) - --emit=link,obj -Csave-temps -Ccodegen-units=16 -Copt-level=2 --target=$(TARGET) - - # `llvm-dis` is used here since `--emit=llvm-ir` does not emit LLVM IR - # for temporary outputs. - "$(LLVM_BIN_DIR)"/llvm-dis $(TMPDIR)/*.bc - - # Check LLVM IR files (including temporary outputs) have `!llvm.ident` - # named metadata, reusing the related codegen test. - set -e; for f in $(TMPDIR)/*.ll; do \ - $(LLVM_FILECHECK) --input-file $$f ../../codegen/llvm-ident.rs; \ - done diff --git a/tests/run-make/llvm-ident/rmake.rs b/tests/run-make/llvm-ident/rmake.rs new file mode 100644 index 0000000000000..f460829288e8c --- /dev/null +++ b/tests/run-make/llvm-ident/rmake.rs @@ -0,0 +1,41 @@ +//@ only-linux +//@ ignore-cross-compile + +use run_make_support::llvm::llvm_bin_dir; +use run_make_support::{cmd, env_var, llvm_filecheck, read_dir, rustc, source_root}; + +use std::ffi::OsStr; + +fn main() { + // `-Ccodegen-units=16 -Copt-level=2` is used here to trigger thin LTO + // across codegen units to test deduplication of the named metadata + // (see `LLVMRustPrepareThinLTOImport` for details). + rustc() + .emit("link,obj") + .arg("-") + .arg("-Csave-temps") + .codegen_units(16) + .opt_level("2") + .target(&env_var("TARGET")) + .stdin("fn main(){}") + .run(); + + // `llvm-dis` is used here since `--emit=llvm-ir` does not emit LLVM IR + // for temporary outputs. + let mut files = Vec::new(); + read_dir(".", |path| { + if path.is_file() && path.extension().is_some_and(|ext| ext == OsStr::new("bc")) { + files.push(path.to_path_buf()); + } + }); + cmd(llvm_bin_dir().join("llvm-dis")).args(&files).run(); + + // Check LLVM IR files (including temporary outputs) have `!llvm.ident` + // named metadata, reusing the related codegen test. + let llvm_ident_path = source_root().join("tests/codegen/llvm-ident.rs"); + read_dir(".", |path| { + if path.is_file() && path.extension().is_some_and(|ext| ext == OsStr::new("ll")) { + llvm_filecheck().input_file(path).arg(&llvm_ident_path).run(); + } + }); +} From ccc50b21c149686e7620253b10936e79665404f1 Mon Sep 17 00:00:00 2001 From: Adwin White Date: Mon, 24 Jun 2024 14:40:04 +0800 Subject: [PATCH 533/892] add syscall `dup()` --- src/tools/miri/src/shims/unix/fd.rs | 28 +++++++++++++++++++ .../miri/src/shims/unix/foreign_items.rs | 13 +++++++++ src/tools/miri/tests/pass-dep/libc/libc-fs.rs | 26 +++++++++++++++++ 3 files changed, 67 insertions(+) diff --git a/src/tools/miri/src/shims/unix/fd.rs b/src/tools/miri/src/shims/unix/fd.rs index 599f78e712a2a..87e20954a70a1 100644 --- a/src/tools/miri/src/shims/unix/fd.rs +++ b/src/tools/miri/src/shims/unix/fd.rs @@ -273,6 +273,34 @@ impl FdTable { impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {} pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { + fn dup(&mut self, old_fd: i32) -> InterpResult<'tcx, i32> { + let this = self.eval_context_mut(); + + match this.machine.fds.dup(old_fd) { + Some(dup_fd) => Ok(this.machine.fds.insert_fd_with_min_fd(dup_fd, 0)), + None => this.fd_not_found(), + } + } + + fn dup2(&mut self, old_fd: i32, new_fd: i32) -> InterpResult<'tcx, i32> { + let this = self.eval_context_mut(); + + match this.machine.fds.dup(old_fd) { + Some(dup_fd) => { + if new_fd != old_fd { + // Close new_fd if it is previously opened. + // If old_fd and new_fd point to the same description, then `dup_fd` ensures we keep the underlying file description alive. + if let Some(file_descriptor) = this.machine.fds.fds.insert(new_fd, dup_fd) { + // Ignore close error (not interpreter's) according to dup2() doc. + file_descriptor.close(this.machine.communicate())?.ok(); + } + } + Ok(new_fd) + } + None => this.fd_not_found(), + } + } + fn fcntl(&mut self, args: &[OpTy<'tcx>]) -> InterpResult<'tcx, i32> { let this = self.eval_context_mut(); diff --git a/src/tools/miri/src/shims/unix/foreign_items.rs b/src/tools/miri/src/shims/unix/foreign_items.rs index 53ad40cfd2ccc..2421f9244f367 100644 --- a/src/tools/miri/src/shims/unix/foreign_items.rs +++ b/src/tools/miri/src/shims/unix/foreign_items.rs @@ -115,6 +115,19 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let result = this.fcntl(args)?; this.write_scalar(Scalar::from_i32(result), dest)?; } + "dup" => { + let [old_fd] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let old_fd = this.read_scalar(old_fd)?.to_i32()?; + let new_fd = this.dup(old_fd)?; + this.write_scalar(Scalar::from_i32(new_fd), dest)?; + } + "dup2" => { + let [old_fd, new_fd] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let old_fd = this.read_scalar(old_fd)?.to_i32()?; + let new_fd = this.read_scalar(new_fd)?.to_i32()?; + let result = this.dup2(old_fd, new_fd)?; + this.write_scalar(Scalar::from_i32(result), dest)?; + } // File and file system access "open" | "open64" => { diff --git a/src/tools/miri/tests/pass-dep/libc/libc-fs.rs b/src/tools/miri/tests/pass-dep/libc/libc-fs.rs index 80c9757e9c956..da685e5c6b7dc 100644 --- a/src/tools/miri/tests/pass-dep/libc/libc-fs.rs +++ b/src/tools/miri/tests/pass-dep/libc/libc-fs.rs @@ -15,6 +15,7 @@ use std::path::PathBuf; mod utils; fn main() { + test_dup(); test_dup_stdout_stderr(); test_canonicalize_too_long(); test_rename(); @@ -74,6 +75,31 @@ fn test_dup_stdout_stderr() { } } +fn test_dup() { + let bytes = b"dup and dup2"; + let path = utils::prepare_with_content("miri_test_libc_dup.txt", bytes); + + let mut name = path.into_os_string(); + name.push("\0"); + let name_ptr = name.as_bytes().as_ptr().cast::(); + unsafe { + let fd = libc::open(name_ptr, libc::O_RDONLY); + let mut first_buf = [0u8; 4]; + libc::read(fd, first_buf.as_mut_ptr() as *mut libc::c_void, 4); + assert_eq!(&first_buf, b"dup "); + + let new_fd = libc::dup(fd); + let mut second_buf = [0u8; 4]; + libc::read(new_fd, second_buf.as_mut_ptr() as *mut libc::c_void, 4); + assert_eq!(&second_buf, b"and "); + + let new_fd2 = libc::dup2(fd, 8); + let mut third_buf = [0u8; 4]; + libc::read(new_fd2, third_buf.as_mut_ptr() as *mut libc::c_void, 4); + assert_eq!(&third_buf, b"dup2"); + } +} + fn test_canonicalize_too_long() { // Make sure we get an error for long paths. let too_long = "x/".repeat(libc::PATH_MAX.try_into().unwrap()); From 294c3dda881ae65d528ee0380b7628deaf33ae96 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Sat, 29 Jun 2024 11:24:36 -0700 Subject: [PATCH 534/892] rustdoc: add usable lint for pulldown-cmark-0.11 parsing changes --- Cargo.lock | 12 ++ src/librustdoc/Cargo.toml | 1 + src/librustdoc/lint.rs | 9 ++ src/librustdoc/passes/lint.rs | 2 + .../passes/lint/unportable_markdown.rs | 152 ++++++++++++++++++ tests/rustdoc-ui/unportable-markdown.rs | 63 ++++++++ tests/rustdoc-ui/unportable-markdown.stderr | 39 +++++ 7 files changed, 278 insertions(+) create mode 100644 src/librustdoc/passes/lint/unportable_markdown.rs create mode 100644 tests/rustdoc-ui/unportable-markdown.rs create mode 100644 tests/rustdoc-ui/unportable-markdown.stderr diff --git a/Cargo.lock b/Cargo.lock index 3af90a252aea7..96cef9070842e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3121,6 +3121,17 @@ dependencies = [ "cc", ] +[[package]] +name = "pulldown-cmark" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57206b407293d2bcd3af849ce869d52068623f19e1b5ff8e8778e3309439682b" +dependencies = [ + "bitflags 2.5.0", + "memchr", + "unicase", +] + [[package]] name = "pulldown-cmark" version = "0.10.3" @@ -4890,6 +4901,7 @@ dependencies = [ "indexmap", "itertools", "minifier", + "pulldown-cmark 0.9.6", "regex", "rustdoc-json-types", "serde", diff --git a/src/librustdoc/Cargo.toml b/src/librustdoc/Cargo.toml index 31222f213d800..51fb126cb3407 100644 --- a/src/librustdoc/Cargo.toml +++ b/src/librustdoc/Cargo.toml @@ -13,6 +13,7 @@ base64 = "0.21.7" itertools = "0.12" indexmap = "2" minifier = "0.3.0" +pulldown-cmark-old = { version = "0.9.6", package = "pulldown-cmark", default-features = false } regex = "1" rustdoc-json-types = { path = "../rustdoc-json-types" } serde_json = "1.0" diff --git a/src/librustdoc/lint.rs b/src/librustdoc/lint.rs index dd2bb47e5926b..8eaca70eaff48 100644 --- a/src/librustdoc/lint.rs +++ b/src/librustdoc/lint.rs @@ -196,6 +196,14 @@ declare_rustdoc_lint! { "detects redundant explicit links in doc comments" } +declare_rustdoc_lint! { + /// This compatibility lint checks for Markdown syntax that works in the old engine but not + /// the new one. + UNPORTABLE_MARKDOWN, + Warn, + "detects markdown that is interpreted differently in different parser" +} + pub(crate) static RUSTDOC_LINTS: Lazy> = Lazy::new(|| { vec![ BROKEN_INTRA_DOC_LINKS, @@ -209,6 +217,7 @@ pub(crate) static RUSTDOC_LINTS: Lazy> = Lazy::new(|| { MISSING_CRATE_LEVEL_DOCS, UNESCAPED_BACKTICKS, REDUNDANT_EXPLICIT_LINKS, + UNPORTABLE_MARKDOWN, ] }); diff --git a/src/librustdoc/passes/lint.rs b/src/librustdoc/passes/lint.rs index c6d5b7bd346d4..bc804a340bf2c 100644 --- a/src/librustdoc/passes/lint.rs +++ b/src/librustdoc/passes/lint.rs @@ -6,6 +6,7 @@ mod check_code_block_syntax; mod html_tags; mod redundant_explicit_links; mod unescaped_backticks; +mod unportable_markdown; use super::Pass; use crate::clean::*; @@ -31,6 +32,7 @@ impl<'a, 'tcx> DocVisitor for Linter<'a, 'tcx> { html_tags::visit_item(self.cx, item); unescaped_backticks::visit_item(self.cx, item); redundant_explicit_links::visit_item(self.cx, item); + unportable_markdown::visit_item(self.cx, item); self.visit_item_recur(item) } diff --git a/src/librustdoc/passes/lint/unportable_markdown.rs b/src/librustdoc/passes/lint/unportable_markdown.rs new file mode 100644 index 0000000000000..5f18537763441 --- /dev/null +++ b/src/librustdoc/passes/lint/unportable_markdown.rs @@ -0,0 +1,152 @@ +//! Detects specific markdown syntax that's different between pulldown-cmark +//! 0.9 and 0.11. +//! +//! This is a mitigation for old parser bugs that affected some +//! real crates' docs. The old parser claimed to comply with CommonMark, +//! but it did not. These warnings will eventually be removed, +//! though some of them may become Clippy lints. +//! +//! +//! +//! + +use crate::clean::Item; +use crate::core::DocContext; +use pulldown_cmark as cmarkn; +use pulldown_cmark_old as cmarko; +use rustc_lint_defs::Applicability; +use rustc_resolve::rustdoc::source_span_for_markdown_range; +use std::collections::{BTreeMap, BTreeSet}; + +pub(crate) fn visit_item(cx: &DocContext<'_>, item: &Item) { + let tcx = cx.tcx; + let Some(hir_id) = DocContext::as_local_hir_id(tcx, item.item_id) else { + // If non-local, no need to check anything. + return; + }; + + let dox = item.doc_value(); + if dox.is_empty() { + return; + } + + // P1: unintended strikethrough was fixed by requiring single-tildes to flank + // the same way underscores do, so nothing is done here + + // P2: block quotes without following space parsed wrong + // + // This is the set of starting points for block quotes with no space after + // the `>`. It is populated by the new parser, and if the old parser fails to + // clear it out, it'll produce a warning. + let mut spaceless_block_quotes = BTreeSet::new(); + + // P3: missing footnote references + // + // This is populated by listening for FootnoteReference from + // the new parser and old parser. + let mut missing_footnote_references = BTreeMap::new(); + let mut found_footnote_references = BTreeSet::new(); + + // populate problem cases from new parser + { + pub fn main_body_opts_new() -> cmarkn::Options { + cmarkn::Options::ENABLE_TABLES + | cmarkn::Options::ENABLE_FOOTNOTES + | cmarkn::Options::ENABLE_STRIKETHROUGH + | cmarkn::Options::ENABLE_TASKLISTS + | cmarkn::Options::ENABLE_SMART_PUNCTUATION + } + let mut parser_new = cmarkn::Parser::new_ext(&dox, main_body_opts_new()).into_offset_iter(); + while let Some((event, span)) = parser_new.next() { + if let cmarkn::Event::Start(cmarkn::Tag::BlockQuote(_)) = event { + if !dox[span.clone()].starts_with("> ") { + spaceless_block_quotes.insert(span.start); + } + } + if let cmarkn::Event::FootnoteReference(_) = event { + found_footnote_references.insert(span.start + 1); + } + } + } + + // remove cases where they don't actually differ + { + pub fn main_body_opts_old() -> cmarko::Options { + cmarko::Options::ENABLE_TABLES + | cmarko::Options::ENABLE_FOOTNOTES + | cmarko::Options::ENABLE_STRIKETHROUGH + | cmarko::Options::ENABLE_TASKLISTS + | cmarko::Options::ENABLE_SMART_PUNCTUATION + } + let mut parser_old = cmarko::Parser::new_ext(&dox, main_body_opts_old()).into_offset_iter(); + while let Some((event, span)) = parser_old.next() { + if let cmarko::Event::Start(cmarko::Tag::BlockQuote) = event { + if !dox[span.clone()].starts_with("> ") { + spaceless_block_quotes.remove(&span.start); + } + } + if let cmarko::Event::FootnoteReference(_) = event { + if !found_footnote_references.contains(&(span.start + 1)) { + missing_footnote_references.insert(span.start + 1, span); + } + } + } + } + + for start in spaceless_block_quotes { + let (span, precise) = + source_span_for_markdown_range(tcx, &dox, &(start..start + 1), &item.attrs.doc_strings) + .map(|span| (span, true)) + .unwrap_or_else(|| (item.attr_span(tcx), false)); + + tcx.node_span_lint(crate::lint::UNPORTABLE_MARKDOWN, hir_id, span, |lint| { + lint.primary_message("unportable markdown"); + lint.help(format!("confusing block quote with no space after the `>` marker")); + if precise { + lint.span_suggestion( + span.shrink_to_hi(), + "if the quote is intended, add a space", + " ", + Applicability::MaybeIncorrect, + ); + lint.span_suggestion( + span.shrink_to_lo(), + "if it should not be a quote, escape it", + "\\", + Applicability::MaybeIncorrect, + ); + } + }); + } + for (_caret, span) in missing_footnote_references { + let (ref_span, precise) = + source_span_for_markdown_range(tcx, &dox, &span, &item.attrs.doc_strings) + .map(|span| (span, true)) + .unwrap_or_else(|| (item.attr_span(tcx), false)); + + tcx.node_span_lint(crate::lint::UNPORTABLE_MARKDOWN, hir_id, ref_span, |lint| { + lint.primary_message("unportable markdown"); + if precise { + lint.span_suggestion( + ref_span.shrink_to_lo(), + "if it should not be a footnote, escape it", + "\\", + Applicability::MaybeIncorrect, + ); + } + if dox.as_bytes().get(span.end) == Some(&b'[') { + lint.help("confusing footnote reference and link"); + if precise { + lint.span_suggestion( + ref_span.shrink_to_hi(), + "if the footnote is intended, add a space", + " ", + Applicability::MaybeIncorrect, + ); + } else { + lint.help("there should be a space between the link and the footnote"); + } + } + }); + } +} diff --git a/tests/rustdoc-ui/unportable-markdown.rs b/tests/rustdoc-ui/unportable-markdown.rs new file mode 100644 index 0000000000000..8035e680f3cf4 --- /dev/null +++ b/tests/rustdoc-ui/unportable-markdown.rs @@ -0,0 +1,63 @@ +// https://internals.rust-lang.org/t/proposal-migrate-the-syntax-of-rustdoc-markdown-footnotes-to-be-compatible-with-the-syntax-used-in-github/18929 +// +// A series of test cases for CommonMark corner cases that pulldown-cmark 0.11 fixes. +// +// This version of the lint is targeted at two especially-common cases where docs got broken. +// Other differences in parsing should not warn. +#![allow(rustdoc::broken_intra_doc_links)] +#![deny(rustdoc::unportable_markdown)] + +/// +/// +/// Test footnote [^foot]. +/// +/// [^foot]: This is nested within the footnote now, but didn't used to be. +/// +/// This is a multi-paragraph footnote. +pub struct GfmFootnotes; + +/// +/// +/// test [^foo][^bar] +//~^ ERROR unportable markdown +/// +/// [^foo]: test +/// [^bar]: test2 +pub struct FootnoteSmashedName; + +/// +/// +/// - _t +/// # test +/// t_ +pub struct NestingCornerCase; + +/// +/// +/// *~~__emphasis strike strong__~~* ~~*__strike emphasis strong__*~~ +pub struct Emphasis1; + +/// +/// +/// | +/// | +pub struct NotEnoughTable; + +/// +/// +/// foo +/// >bar +//~^ ERROR unportable markdown +pub struct BlockQuoteNoSpace; + +/// Negative test. +/// +/// foo +/// > bar +pub struct BlockQuoteSpace; + +/// Negative test. +/// +/// >bar +/// baz +pub struct BlockQuoteNoSpaceStart; diff --git a/tests/rustdoc-ui/unportable-markdown.stderr b/tests/rustdoc-ui/unportable-markdown.stderr new file mode 100644 index 0000000000000..b524aca25aef9 --- /dev/null +++ b/tests/rustdoc-ui/unportable-markdown.stderr @@ -0,0 +1,39 @@ +error: unportable markdown + --> $DIR/unportable-markdown.rs:21:10 + | +LL | /// test [^foo][^bar] + | ^^^^^^ + | + = help: confusing footnote reference and link +note: the lint level is defined here + --> $DIR/unportable-markdown.rs:8:9 + | +LL | #![deny(rustdoc::unportable_markdown)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: if it should not be a footnote, escape it + | +LL | /// test \[^foo][^bar] + | + +help: if the footnote is intended, add a space + | +LL | /// test [^foo] [^bar] + | + + +error: unportable markdown + --> $DIR/unportable-markdown.rs:49:5 + | +LL | /// >bar + | ^ + | + = help: confusing block quote with no space after the `>` marker +help: if the quote is intended, add a space + | +LL | /// > bar + | + +help: if it should not be a quote, escape it + | +LL | /// \>bar + | + + +error: aborting due to 2 previous errors + From cc1b3ee7f1601499ec96dcdfcf6ac1ee40657e6b Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Sat, 29 Jun 2024 11:25:12 -0700 Subject: [PATCH 535/892] clippy: update to pulldown-cmark 0.11 --- src/tools/clippy/clippy_lints/src/doc/mod.rs | 32 ++++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/tools/clippy/clippy_lints/src/doc/mod.rs b/src/tools/clippy/clippy_lints/src/doc/mod.rs index 3d875e7ac2d3f..3e210fd153bf5 100644 --- a/src/tools/clippy/clippy_lints/src/doc/mod.rs +++ b/src/tools/clippy/clippy_lints/src/doc/mod.rs @@ -6,10 +6,10 @@ use clippy_utils::ty::is_type_diagnostic_item; use clippy_utils::visitors::Visitable; use clippy_utils::{in_constant, is_entrypoint_fn, is_trait_impl_item, method_chain_args}; use pulldown_cmark::Event::{ - Code, End, FootnoteReference, HardBreak, Html, Rule, SoftBreak, Start, TaskListMarker, Text, + Code, DisplayMath, End, FootnoteReference, HardBreak, Html, InlineHtml, InlineMath, Rule, SoftBreak, Start, TaskListMarker, Text, }; use pulldown_cmark::Tag::{BlockQuote, CodeBlock, FootnoteDefinition, Heading, Item, Link, Paragraph}; -use pulldown_cmark::{BrokenLink, CodeBlockKind, CowStr, Options}; +use pulldown_cmark::{BrokenLink, CodeBlockKind, CowStr, Options, TagEnd}; use rustc_ast::ast::Attribute; use rustc_data_structures::fx::FxHashSet; use rustc_hir::intravisit::{self, Visitor}; @@ -659,7 +659,7 @@ fn check_doc<'a, Events: Iterator, Range { + Html(tag) | InlineHtml(tag) => { if tag.starts_with(", Range { + Start(BlockQuote(_)) => { blockquote_level += 1; containers.push(Container::Blockquote); }, - End(BlockQuote) => { + End(TagEnd::BlockQuote) => { blockquote_level -= 1; containers.pop(); }, @@ -699,15 +699,15 @@ fn check_doc<'a, Events: Iterator, Range { + End(TagEnd::CodeBlock) => { in_code = false; is_rust = false; ignore = false; }, - Start(Link(_, url, _)) => in_link = Some(url), - End(Link(..)) => in_link = None, - Start(Heading(_, _, _) | Paragraph | Item) => { - if let Start(Heading(_, _, _)) = event { + Start(Link { dest_url, .. }) => in_link = Some(dest_url), + End(TagEnd::Link) => in_link = None, + Start(Heading { .. } | Paragraph | Item) => { + if let Start(Heading { .. }) = event { in_heading = true; } if let Start(Item) = event { @@ -720,11 +720,11 @@ fn check_doc<'a, Events: Iterator, Range { - if let End(Heading(_, _, _)) = event { + End(TagEnd::Heading(_) | TagEnd::Paragraph | TagEnd::Item) => { + if let End(TagEnd::Heading(_)) = event { in_heading = false; } - if let End(Item) = event { + if let End(TagEnd::Item) = event { containers.pop(); } if ticks_unbalanced && let Some(span) = fragments.span(cx, paragraph_range.clone()) { @@ -746,8 +746,8 @@ fn check_doc<'a, Events: Iterator, Range in_footnote_definition = true, - End(FootnoteDefinition(..)) => in_footnote_definition = false, - Start(_tag) | End(_tag) => (), // We don't care about other tags + End(TagEnd::FootnoteDefinition) => in_footnote_definition = false, + Start(_) | End(_) => (), // We don't care about other tags SoftBreak | HardBreak => { if !containers.is_empty() && let Some((next_event, next_range)) = events.peek() @@ -765,7 +765,7 @@ fn check_doc<'a, Events: Iterator, Range (), + TaskListMarker(_) | Code(_) | Rule | InlineMath(..) | DisplayMath(..) => (), FootnoteReference(text) | Text(text) => { paragraph_range.end = range.end; ticks_unbalanced |= text.contains('`') && !in_code; From c8592da16a9e16535f3dfb9359066113f8656de0 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Sun, 30 Jun 2024 19:04:14 -0700 Subject: [PATCH 536/892] rustc_data_structures: fix wrong markdown syntax This didn't produce working footnote links. The unportable markdown lint warned about it. --- compiler/rustc_data_structures/src/sync.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_data_structures/src/sync.rs b/compiler/rustc_data_structures/src/sync.rs index 79ceb28abb518..058a675c40d7b 100644 --- a/compiler/rustc_data_structures/src/sync.rs +++ b/compiler/rustc_data_structures/src/sync.rs @@ -35,11 +35,11 @@ //! | | | | //! | `ParallelIterator` | `Iterator` | `rayon::iter::ParallelIterator` | //! -//! [^1] `MTLock` is similar to `Lock`, but the serial version avoids the cost +//! [^1]: `MTLock` is similar to `Lock`, but the serial version avoids the cost //! of a `RefCell`. This is appropriate when interior mutability is not //! required. //! -//! [^2] `MTRef`, `MTLockRef` are type aliases. +//! [^2]: `MTRef`, `MTLockRef` are type aliases. pub use crate::marker::*; use std::collections::HashMap; From e9dd39cda49c260213f73af4b0ba05cecb292b39 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 9 Jun 2024 10:29:11 +0200 Subject: [PATCH 537/892] fix simd_bitmask return type for non-power-of-two inputs, and add tests --- compiler/rustc_codegen_llvm/src/intrinsic.rs | 16 ++-- tests/ui/simd/simd-bitmask-notpow2.rs | 90 ++++++++++++++++++++ tests/ui/simd/simd-bitmask.rs | 45 +++++++--- 3 files changed, 131 insertions(+), 20 deletions(-) create mode 100644 tests/ui/simd/simd-bitmask-notpow2.rs diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index b5b0086f7405a..e02c61cd29654 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -1121,8 +1121,8 @@ fn generic_simd_intrinsic<'ll, 'tcx>( if name == sym::simd_select_bitmask { let (len, _) = require_simd!(arg_tys[1], SimdArgument); - let expected_int_bits = (len.max(8) - 1).next_power_of_two(); - let expected_bytes = len / 8 + ((len % 8 > 0) as u64); + let expected_int_bits = len.max(8).next_power_of_two(); + let expected_bytes = len.div_ceil(8); let mask_ty = arg_tys[0]; let mask = match mask_ty.kind() { @@ -1379,17 +1379,16 @@ fn generic_simd_intrinsic<'ll, 'tcx>( } if name == sym::simd_bitmask { - // The `fn simd_bitmask(vector) -> unsigned integer` intrinsic takes a - // vector mask and returns the most significant bit (MSB) of each lane in the form - // of either: + // The `fn simd_bitmask(vector) -> unsigned integer` intrinsic takes a vector mask and + // returns one bit for each lane (which must all be `0` or `!0`) in the form of either: // * an unsigned integer // * an array of `u8` // If the vector has less than 8 lanes, a u8 is returned with zeroed trailing bits. // // The bit order of the result depends on the byte endianness, LSB-first for little // endian and MSB-first for big endian. - let expected_int_bits = in_len.max(8); - let expected_bytes = expected_int_bits / 8 + ((expected_int_bits % 8 > 0) as u64); + let expected_int_bits = in_len.max(8).next_power_of_two(); + let expected_bytes = in_len.div_ceil(8); // Integer vector : let (i_xn, in_elem_bitwidth) = match in_elem.kind() { @@ -1409,7 +1408,8 @@ fn generic_simd_intrinsic<'ll, 'tcx>( }), }; - // Shift the MSB to the right by "in_elem_bitwidth - 1" into the first bit position. + // 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 _); diff --git a/tests/ui/simd/simd-bitmask-notpow2.rs b/tests/ui/simd/simd-bitmask-notpow2.rs new file mode 100644 index 0000000000000..ff43206a3fd6b --- /dev/null +++ b/tests/ui/simd/simd-bitmask-notpow2.rs @@ -0,0 +1,90 @@ +//@run-pass +// SEGFAULTS on LLVM 17. This should be merged into `simd-bitmask` once we require LLVM 18. +//@ min-llvm-version: 18 +// FIXME: broken codegen on big-endian (https://github.com/rust-lang/rust/issues/127205) +//@ ignore-endian-big +#![feature(repr_simd, intrinsics)] + +extern "rust-intrinsic" { + fn simd_bitmask(v: T) -> U; + fn simd_select_bitmask(m: T, a: U, b: U) -> U; +} + +fn main() { + // Non-power-of-2 multi-byte mask. + #[repr(simd, packed)] + #[allow(non_camel_case_types)] + #[derive(Copy, Clone, Debug, PartialEq)] + struct i32x10([i32; 10]); + impl i32x10 { + fn splat(x: i32) -> Self { + Self([x; 10]) + } + } + unsafe { + let mask = i32x10([!0, !0, 0, !0, 0, 0, !0, 0, !0, 0]); + let mask_bits = if cfg!(target_endian = "little") { 0b0101001011 } else { 0b1101001010 }; + let mask_bytes = + if cfg!(target_endian = "little") { [0b01001011, 0b01] } else { [0b11, 0b01001010] }; + + let bitmask1: u16 = simd_bitmask(mask); + let bitmask2: [u8; 2] = simd_bitmask(mask); + assert_eq!(bitmask1, mask_bits); + assert_eq!(bitmask2, mask_bytes); + + let selected1 = simd_select_bitmask::( + mask_bits, + i32x10::splat(!0), // yes + i32x10::splat(0), // no + ); + let selected2 = simd_select_bitmask::<[u8; 2], _>( + mask_bytes, + i32x10::splat(!0), // yes + i32x10::splat(0), // no + ); + assert_eq!(selected1, mask); + assert_eq!(selected2, mask); + } + + // Test for a mask where the next multiple of 8 is not a power of two. + #[repr(simd, packed)] + #[allow(non_camel_case_types)] + #[derive(Copy, Clone, Debug, PartialEq)] + struct i32x20([i32; 20]); + impl i32x20 { + fn splat(x: i32) -> Self { + Self([x; 20]) + } + } + unsafe { + let mask = i32x20([!0, !0, 0, !0, 0, 0, !0, 0, !0, 0, 0, 0, 0, !0, !0, !0, !0, !0, !0, !0]); + let mask_bits = if cfg!(target_endian = "little") { + 0b11111110000101001011 + } else { + 0b11010010100001111111 + }; + let mask_bytes = if cfg!(target_endian = "little") { + [0b01001011, 0b11100001, 0b1111] + } else { + [0b1101, 0b00101000, 0b01111111] + }; + + let bitmask1: u32 = simd_bitmask(mask); + let bitmask2: [u8; 3] = simd_bitmask(mask); + assert_eq!(bitmask1, mask_bits); + assert_eq!(bitmask2, mask_bytes); + + let selected1 = simd_select_bitmask::( + mask_bits, + i32x20::splat(!0), // yes + i32x20::splat(0), // no + ); + let selected2 = simd_select_bitmask::<[u8; 3], _>( + mask_bytes, + i32x20::splat(!0), // yes + i32x20::splat(0), // no + ); + assert_eq!(selected1, mask); + assert_eq!(selected2, mask); + } +} diff --git a/tests/ui/simd/simd-bitmask.rs b/tests/ui/simd/simd-bitmask.rs index 4a7c3bc77507c..82f73fca95124 100644 --- a/tests/ui/simd/simd-bitmask.rs +++ b/tests/ui/simd/simd-bitmask.rs @@ -1,5 +1,4 @@ //@run-pass -//@ignore-endian-big behavior of simd_select_bitmask is endian-specific #![feature(repr_simd, intrinsics)] extern "rust-intrinsic" { @@ -17,36 +16,58 @@ fn main() { let i: u8 = simd_bitmask(v); let a: [u8; 1] = simd_bitmask(v); - assert_eq!(i, 0b0101); - assert_eq!(a, [0b0101]); + if cfg!(target_endian = "little") { + assert_eq!(i, 0b0101); + assert_eq!(a, [0b0101]); + } else { + assert_eq!(i, 0b1010); + assert_eq!(a, [0b1010]); + } let v = Simd::([0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, -1, 0]); let i: u16 = simd_bitmask(v); let a: [u8; 2] = simd_bitmask(v); - assert_eq!(i, 0b0101000000001100); - assert_eq!(a, [0b1100, 0b01010000]); + if cfg!(target_endian = "little") { + assert_eq!(i, 0b0101000000001100); + assert_eq!(a, [0b00001100, 0b01010000]); + } else { + assert_eq!(i, 0b0011000000001010); + assert_eq!(a, [0b00110000, 0b00001010]); + } } unsafe { - let a = Simd::([0, 1, 2, 3, 4, 5, 6, 7]); - let b = Simd::([8, 9, 10, 11, 12, 13, 14, 15]); - let e = [0, 9, 2, 11, 12, 13, 14, 15]; + let a = Simd::([0, 1, 2, 3]); + let b = Simd::([8, 9, 10, 11]); + let e = [0, 9, 2, 11]; - let r = simd_select_bitmask(0b0101u8, a, b); + let mask = if cfg!(target_endian = "little") { 0b0101u8 } else { 0b1010u8 }; + let r = simd_select_bitmask(mask, a, b); assert_eq!(r.0, e); - let r = simd_select_bitmask([0b0101u8], a, b); + let mask = if cfg!(target_endian = "little") { [0b0101u8] } else { [0b1010u8] }; + let r = simd_select_bitmask(mask, a, b); assert_eq!(r.0, e); let a = Simd::([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]); let b = Simd::([16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31]); let e = [16, 17, 2, 3, 20, 21, 22, 23, 24, 25, 26, 27, 12, 29, 14, 31]; - let r = simd_select_bitmask(0b0101000000001100u16, a, b); + let mask = if cfg!(target_endian = "little") { + 0b0101000000001100u16 + } else { + 0b0011000000001010u16 + }; + let r = simd_select_bitmask(mask, a, b); assert_eq!(r.0, e); - let r = simd_select_bitmask([0b1100u8, 0b01010000u8], a, b); + let mask = if cfg!(target_endian = "little") { + [0b00001100u8, 0b01010000u8] + } else { + [0b00110000u8, 0b00001010u8] + }; + let r = simd_select_bitmask(mask, a, b); assert_eq!(r.0, e); } } From 1834f5a272d567a714f78c7f48c0d3ae4a6238bb Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Wed, 26 Jun 2024 19:13:38 +0000 Subject: [PATCH 538/892] Swap encapsulation of DCP state. --- .../rustc_mir_dataflow/src/value_analysis.rs | 149 ++++++++++-------- 1 file changed, 81 insertions(+), 68 deletions(-) diff --git a/compiler/rustc_mir_dataflow/src/value_analysis.rs b/compiler/rustc_mir_dataflow/src/value_analysis.rs index bfbfff7e25944..0364c23bfcbe4 100644 --- a/compiler/rustc_mir_dataflow/src/value_analysis.rs +++ b/compiler/rustc_mir_dataflow/src/value_analysis.rs @@ -39,7 +39,7 @@ use std::ops::Range; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_index::bit_set::BitSet; -use rustc_index::{IndexSlice, IndexVec}; +use rustc_index::IndexVec; use rustc_middle::bug; use rustc_middle::mir::visit::{MutatingUseContext, PlaceContext, Visitor}; use rustc_middle::mir::*; @@ -336,14 +336,14 @@ impl<'tcx, T: ValueAnalysis<'tcx>> AnalysisDomain<'tcx> for ValueAnalysisWrapper const NAME: &'static str = T::NAME; fn bottom_value(&self, _body: &Body<'tcx>) -> Self::Domain { - State(StateData::Unreachable) + State::Unreachable } fn initialize_start_block(&self, body: &Body<'tcx>, state: &mut Self::Domain) { // The initial state maps all tracked places of argument projections to ⊤ and the rest to ⊥. - assert!(matches!(state.0, StateData::Unreachable)); - let values = IndexVec::from_elem_n(T::Value::BOTTOM, self.0.map().value_count); - *state = State(StateData::Reachable(values)); + assert!(matches!(state, State::Unreachable)); + let values = StateData::from_elem_n(T::Value::BOTTOM, self.0.map().value_count); + *state = State::Reachable(values); for arg in body.args_iter() { state.flood(PlaceRef { local: arg, projection: &[] }, self.0.map()); } @@ -415,27 +415,30 @@ rustc_index::newtype_index!( /// See [`State`]. #[derive(PartialEq, Eq, Debug)] -enum StateData { - Reachable(IndexVec), - Unreachable, +struct StateData { + map: IndexVec, +} + +impl StateData { + fn from_elem_n(elem: V, n: usize) -> StateData { + StateData { map: IndexVec::from_elem_n(elem, n) } + } } impl Clone for StateData { fn clone(&self) -> Self { - match self { - Self::Reachable(x) => Self::Reachable(x.clone()), - Self::Unreachable => Self::Unreachable, - } + StateData { map: self.map.clone() } } fn clone_from(&mut self, source: &Self) { - match (&mut *self, source) { - (Self::Reachable(x), Self::Reachable(y)) => { - // We go through `raw` here, because `IndexVec` currently has a naive `clone_from`. - x.raw.clone_from(&y.raw); - } - _ => *self = source.clone(), - } + // We go through `raw` here, because `IndexVec` currently has a naive `clone_from`. + self.map.raw.clone_from(&source.map.raw) + } +} + +impl JoinSemiLattice for StateData { + fn join(&mut self, other: &Self) -> bool { + self.map.join(&other.map) } } @@ -450,33 +453,43 @@ impl Clone for StateData { /// /// Flooding means assigning a value (by default `⊤`) to all tracked projections of a given place. #[derive(PartialEq, Eq, Debug)] -pub struct State(StateData); +pub enum State { + Unreachable, + Reachable(StateData), +} impl Clone for State { fn clone(&self) -> Self { - Self(self.0.clone()) + match self { + Self::Reachable(x) => Self::Reachable(x.clone()), + Self::Unreachable => Self::Unreachable, + } } fn clone_from(&mut self, source: &Self) { - self.0.clone_from(&source.0); + match (&mut *self, source) { + (Self::Reachable(x), Self::Reachable(y)) => { + x.clone_from(&y); + } + _ => *self = source.clone(), + } } } impl State { pub fn new(init: V, map: &Map) -> State { - let values = IndexVec::from_elem_n(init, map.value_count); - State(StateData::Reachable(values)) + State::Reachable(StateData::from_elem_n(init, map.value_count)) } pub fn all(&self, f: impl Fn(&V) -> bool) -> bool { - match self.0 { - StateData::Unreachable => true, - StateData::Reachable(ref values) => values.iter().all(f), + match self { + State::Unreachable => true, + State::Reachable(ref values) => values.map.iter().all(f), } } fn is_reachable(&self) -> bool { - matches!(&self.0, StateData::Reachable(_)) + matches!(self, State::Reachable(_)) } /// Assign `value` to all places that are contained in `place` or may alias one. @@ -519,9 +532,9 @@ impl State { map: &Map, value: V, ) { - let StateData::Reachable(values) = &mut self.0 else { return }; + let State::Reachable(values) = self else { return }; map.for_each_aliasing_place(place, tail_elem, &mut |vi| { - values[vi] = value.clone(); + values.map[vi] = value.clone(); }); } @@ -541,9 +554,9 @@ impl State { /// /// The target place must have been flooded before calling this method. pub fn insert_value_idx(&mut self, target: PlaceIndex, value: V, map: &Map) { - let StateData::Reachable(values) = &mut self.0 else { return }; + let State::Reachable(values) = self else { return }; if let Some(value_index) = map.places[target].value_index { - values[value_index] = value; + values.map[value_index] = value; } } @@ -555,14 +568,14 @@ impl State { /// /// The target place must have been flooded before calling this method. pub fn insert_place_idx(&mut self, target: PlaceIndex, source: PlaceIndex, map: &Map) { - let StateData::Reachable(values) = &mut self.0 else { return }; + let State::Reachable(values) = self else { return }; // If both places are tracked, we copy the value to the target. // If the target is tracked, but the source is not, we do nothing, as invalidation has // already been performed. if let Some(target_value) = map.places[target].value_index { if let Some(source_value) = map.places[source].value_index { - values[target_value] = values[source_value].clone(); + values.map[target_value] = values.map[source_value].clone(); } } for target_child in map.children(target) { @@ -616,11 +629,11 @@ impl State { /// Retrieve the value stored for a place index, or `None` if it is not tracked. pub fn try_get_idx(&self, place: PlaceIndex, map: &Map) -> Option { - match &self.0 { - StateData::Reachable(values) => { - map.places[place].value_index.map(|v| values[v].clone()) + match self { + State::Reachable(values) => { + map.places[place].value_index.map(|v| values.map[v].clone()) } - StateData::Unreachable => None, + State::Unreachable => None, } } @@ -631,10 +644,10 @@ impl State { where V: HasBottom + HasTop, { - match &self.0 { - StateData::Reachable(_) => self.try_get(place, map).unwrap_or(V::TOP), + match self { + State::Reachable(_) => self.try_get(place, map).unwrap_or(V::TOP), // Because this is unreachable, we can return any value we want. - StateData::Unreachable => V::BOTTOM, + State::Unreachable => V::BOTTOM, } } @@ -645,10 +658,10 @@ impl State { where V: HasBottom + HasTop, { - match &self.0 { - StateData::Reachable(_) => self.try_get_discr(place, map).unwrap_or(V::TOP), + match self { + State::Reachable(_) => self.try_get_discr(place, map).unwrap_or(V::TOP), // Because this is unreachable, we can return any value we want. - StateData::Unreachable => V::BOTTOM, + State::Unreachable => V::BOTTOM, } } @@ -659,10 +672,10 @@ impl State { where V: HasBottom + HasTop, { - match &self.0 { - StateData::Reachable(_) => self.try_get_len(place, map).unwrap_or(V::TOP), + match self { + State::Reachable(_) => self.try_get_len(place, map).unwrap_or(V::TOP), // Because this is unreachable, we can return any value we want. - StateData::Unreachable => V::BOTTOM, + State::Unreachable => V::BOTTOM, } } @@ -673,11 +686,11 @@ impl State { where V: HasBottom + HasTop, { - match &self.0 { - StateData::Reachable(values) => { - map.places[place].value_index.map(|v| values[v].clone()).unwrap_or(V::TOP) + match self { + State::Reachable(values) => { + map.places[place].value_index.map(|v| values.map[v].clone()).unwrap_or(V::TOP) } - StateData::Unreachable => { + State::Unreachable => { // Because this is unreachable, we can return any value we want. V::BOTTOM } @@ -687,13 +700,13 @@ impl State { impl JoinSemiLattice for State { fn join(&mut self, other: &Self) -> bool { - match (&mut self.0, &other.0) { - (_, StateData::Unreachable) => false, - (StateData::Unreachable, _) => { + match (&mut *self, other) { + (_, State::Unreachable) => false, + (State::Unreachable, _) => { *self = other.clone(); true } - (StateData::Reachable(this), StateData::Reachable(other)) => this.join(other), + (State::Reachable(this), State::Reachable(ref other)) => this.join(other), } } } @@ -1194,9 +1207,9 @@ where T::Value: Debug, { fn fmt_with(&self, ctxt: &ValueAnalysisWrapper, f: &mut Formatter<'_>) -> std::fmt::Result { - match &self.0 { - StateData::Reachable(values) => debug_with_context(values, None, ctxt.0.map(), f), - StateData::Unreachable => write!(f, "unreachable"), + match self { + State::Reachable(values) => debug_with_context(values, None, ctxt.0.map(), f), + State::Unreachable => write!(f, "unreachable"), } } @@ -1206,8 +1219,8 @@ where ctxt: &ValueAnalysisWrapper, f: &mut Formatter<'_>, ) -> std::fmt::Result { - match (&self.0, &old.0) { - (StateData::Reachable(this), StateData::Reachable(old)) => { + match (self, old) { + (State::Reachable(this), State::Reachable(old)) => { debug_with_context(this, Some(old), ctxt.0.map(), f) } _ => Ok(()), // Consider printing something here. @@ -1218,18 +1231,18 @@ where fn debug_with_context_rec( place: PlaceIndex, place_str: &str, - new: &IndexSlice, - old: Option<&IndexSlice>, + new: &StateData, + old: Option<&StateData>, map: &Map, f: &mut Formatter<'_>, ) -> std::fmt::Result { if let Some(value) = map.places[place].value_index { match old { - None => writeln!(f, "{}: {:?}", place_str, new[value])?, + None => writeln!(f, "{}: {:?}", place_str, new.map[value])?, Some(old) => { - if new[value] != old[value] { - writeln!(f, "\u{001f}-{}: {:?}", place_str, old[value])?; - writeln!(f, "\u{001f}+{}: {:?}", place_str, new[value])?; + if new.map[value] != old.map[value] { + writeln!(f, "\u{001f}-{}: {:?}", place_str, old.map[value])?; + writeln!(f, "\u{001f}+{}: {:?}", place_str, new.map[value])?; } } } @@ -1262,8 +1275,8 @@ fn debug_with_context_rec( } fn debug_with_context( - new: &IndexSlice, - old: Option<&IndexSlice>, + new: &StateData, + old: Option<&StateData>, map: &Map, f: &mut Formatter<'_>, ) -> std::fmt::Result { From 76244d4dbc768e15e429c1f66ec021884f369f5f Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Wed, 26 Jun 2024 21:57:59 +0000 Subject: [PATCH 539/892] Make jump threading state sparse. --- .../src/framework/lattice.rs | 14 +++ .../rustc_mir_dataflow/src/value_analysis.rs | 91 ++++++++++++------- .../rustc_mir_transform/src/jump_threading.rs | 19 +++- 3 files changed, 86 insertions(+), 38 deletions(-) diff --git a/compiler/rustc_mir_dataflow/src/framework/lattice.rs b/compiler/rustc_mir_dataflow/src/framework/lattice.rs index 1c2b475a43c96..23738f7a4a538 100644 --- a/compiler/rustc_mir_dataflow/src/framework/lattice.rs +++ b/compiler/rustc_mir_dataflow/src/framework/lattice.rs @@ -76,6 +76,8 @@ pub trait MeetSemiLattice: Eq { /// A set that has a "bottom" element, which is less than or equal to any other element. pub trait HasBottom { const BOTTOM: Self; + + fn is_bottom(&self) -> bool; } /// A set that has a "top" element, which is greater than or equal to any other element. @@ -114,6 +116,10 @@ impl MeetSemiLattice for bool { impl HasBottom for bool { const BOTTOM: Self = false; + + fn is_bottom(&self) -> bool { + !self + } } impl HasTop for bool { @@ -267,6 +273,10 @@ impl MeetSemiLattice for FlatSet { impl HasBottom for FlatSet { const BOTTOM: Self = Self::Bottom; + + fn is_bottom(&self) -> bool { + matches!(self, Self::Bottom) + } } impl HasTop for FlatSet { @@ -291,6 +301,10 @@ impl MaybeReachable { impl HasBottom for MaybeReachable { const BOTTOM: Self = MaybeReachable::Unreachable; + + fn is_bottom(&self) -> bool { + matches!(self, Self::Unreachable) + } } impl HasTop for MaybeReachable { diff --git a/compiler/rustc_mir_dataflow/src/value_analysis.rs b/compiler/rustc_mir_dataflow/src/value_analysis.rs index 0364c23bfcbe4..7c1ff6fda53f7 100644 --- a/compiler/rustc_mir_dataflow/src/value_analysis.rs +++ b/compiler/rustc_mir_dataflow/src/value_analysis.rs @@ -36,7 +36,7 @@ use std::collections::VecDeque; use std::fmt::{Debug, Formatter}; use std::ops::Range; -use rustc_data_structures::fx::FxHashMap; +use rustc_data_structures::fx::{FxHashMap, StdEntry}; use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_index::bit_set::BitSet; use rustc_index::IndexVec; @@ -342,8 +342,7 @@ impl<'tcx, T: ValueAnalysis<'tcx>> AnalysisDomain<'tcx> for ValueAnalysisWrapper fn initialize_start_block(&self, body: &Body<'tcx>, state: &mut Self::Domain) { // The initial state maps all tracked places of argument projections to ⊤ and the rest to ⊥. assert!(matches!(state, State::Unreachable)); - let values = StateData::from_elem_n(T::Value::BOTTOM, self.0.map().value_count); - *state = State::Reachable(values); + *state = State::new_reachable(); for arg in body.args_iter() { state.flood(PlaceRef { local: arg, projection: &[] }, self.0.map()); } @@ -415,30 +414,54 @@ rustc_index::newtype_index!( /// See [`State`]. #[derive(PartialEq, Eq, Debug)] -struct StateData { - map: IndexVec, +pub struct StateData { + bottom: V, + /// This map only contains values that are not `⊥`. + map: FxHashMap, } -impl StateData { - fn from_elem_n(elem: V, n: usize) -> StateData { - StateData { map: IndexVec::from_elem_n(elem, n) } +impl StateData { + fn new() -> StateData { + StateData { bottom: V::BOTTOM, map: FxHashMap::default() } + } + + fn get(&self, idx: ValueIndex) -> &V { + self.map.get(&idx).unwrap_or(&self.bottom) + } + + fn insert(&mut self, idx: ValueIndex, elem: V) { + if elem.is_bottom() { + self.map.remove(&idx); + } else { + self.map.insert(idx, elem); + } } } impl Clone for StateData { fn clone(&self) -> Self { - StateData { map: self.map.clone() } + StateData { bottom: self.bottom.clone(), map: self.map.clone() } } fn clone_from(&mut self, source: &Self) { - // We go through `raw` here, because `IndexVec` currently has a naive `clone_from`. - self.map.raw.clone_from(&source.map.raw) + self.map.clone_from(&source.map) } } -impl JoinSemiLattice for StateData { +impl JoinSemiLattice for StateData { fn join(&mut self, other: &Self) -> bool { - self.map.join(&other.map) + let mut changed = false; + #[allow(rustc::potential_query_instability)] + for (i, v) in other.map.iter() { + match self.map.entry(*i) { + StdEntry::Vacant(e) => { + e.insert(v.clone()); + changed = true + } + StdEntry::Occupied(e) => changed |= e.into_mut().join(v), + } + } + changed } } @@ -476,15 +499,19 @@ impl Clone for State { } } -impl State { - pub fn new(init: V, map: &Map) -> State { - State::Reachable(StateData::from_elem_n(init, map.value_count)) +impl State { + pub fn new_reachable() -> State { + State::Reachable(StateData::new()) } - pub fn all(&self, f: impl Fn(&V) -> bool) -> bool { + pub fn all_bottom(&self) -> bool { match self { - State::Unreachable => true, - State::Reachable(ref values) => values.map.iter().all(f), + State::Unreachable => false, + State::Reachable(ref values) => + { + #[allow(rustc::potential_query_instability)] + values.map.values().all(V::is_bottom) + } } } @@ -533,9 +560,7 @@ impl State { value: V, ) { let State::Reachable(values) = self else { return }; - map.for_each_aliasing_place(place, tail_elem, &mut |vi| { - values.map[vi] = value.clone(); - }); + map.for_each_aliasing_place(place, tail_elem, &mut |vi| values.insert(vi, value.clone())); } /// Low-level method that assigns to a place. @@ -556,7 +581,7 @@ impl State { pub fn insert_value_idx(&mut self, target: PlaceIndex, value: V, map: &Map) { let State::Reachable(values) = self else { return }; if let Some(value_index) = map.places[target].value_index { - values.map[value_index] = value; + values.insert(value_index, value) } } @@ -575,7 +600,7 @@ impl State { // already been performed. if let Some(target_value) = map.places[target].value_index { if let Some(source_value) = map.places[source].value_index { - values.map[target_value] = values.map[source_value].clone(); + values.insert(target_value, values.get(source_value).clone()); } } for target_child in map.children(target) { @@ -631,7 +656,7 @@ impl State { pub fn try_get_idx(&self, place: PlaceIndex, map: &Map) -> Option { match self { State::Reachable(values) => { - map.places[place].value_index.map(|v| values.map[v].clone()) + map.places[place].value_index.map(|v| values.get(v).clone()) } State::Unreachable => None, } @@ -688,7 +713,7 @@ impl State { { match self { State::Reachable(values) => { - map.places[place].value_index.map(|v| values.map[v].clone()).unwrap_or(V::TOP) + map.places[place].value_index.map(|v| values.get(v).clone()).unwrap_or(V::TOP) } State::Unreachable => { // Because this is unreachable, we can return any value we want. @@ -698,7 +723,7 @@ impl State { } } -impl JoinSemiLattice for State { +impl JoinSemiLattice for State { fn join(&mut self, other: &Self) -> bool { match (&mut *self, other) { (_, State::Unreachable) => false, @@ -1228,7 +1253,7 @@ where } } -fn debug_with_context_rec( +fn debug_with_context_rec( place: PlaceIndex, place_str: &str, new: &StateData, @@ -1238,11 +1263,11 @@ fn debug_with_context_rec( ) -> std::fmt::Result { if let Some(value) = map.places[place].value_index { match old { - None => writeln!(f, "{}: {:?}", place_str, new.map[value])?, + None => writeln!(f, "{}: {:?}", place_str, new.get(value))?, Some(old) => { - if new.map[value] != old.map[value] { - writeln!(f, "\u{001f}-{}: {:?}", place_str, old.map[value])?; - writeln!(f, "\u{001f}+{}: {:?}", place_str, new.map[value])?; + if new.get(value) != old.get(value) { + writeln!(f, "\u{001f}-{}: {:?}", place_str, old.get(value))?; + writeln!(f, "\u{001f}+{}: {:?}", place_str, new.get(value))?; } } } @@ -1274,7 +1299,7 @@ fn debug_with_context_rec( Ok(()) } -fn debug_with_context( +fn debug_with_context( new: &StateData, old: Option<&StateData>, map: &Map, diff --git a/compiler/rustc_mir_transform/src/jump_threading.rs b/compiler/rustc_mir_transform/src/jump_threading.rs index 27e506a920bce..85a61f95ca36f 100644 --- a/compiler/rustc_mir_transform/src/jump_threading.rs +++ b/compiler/rustc_mir_transform/src/jump_threading.rs @@ -47,6 +47,7 @@ use rustc_middle::mir::visit::Visitor; use rustc_middle::mir::*; use rustc_middle::ty::layout::LayoutOf; use rustc_middle::ty::{self, ScalarInt, TyCtxt}; +use rustc_mir_dataflow::lattice::HasBottom; use rustc_mir_dataflow::value_analysis::{Map, PlaceIndex, State, TrackElem}; use rustc_span::DUMMY_SP; use rustc_target::abi::{TagEncoding, Variants}; @@ -158,9 +159,17 @@ impl Condition { } } -#[derive(Copy, Clone, Debug, Default)] +#[derive(Copy, Clone, Debug)] struct ConditionSet<'a>(&'a [Condition]); +impl HasBottom for ConditionSet<'_> { + const BOTTOM: Self = ConditionSet(&[]); + + fn is_bottom(&self) -> bool { + self.0.is_empty() + } +} + impl<'a> ConditionSet<'a> { fn iter(self) -> impl Iterator + 'a { self.0.iter().copied() @@ -177,7 +186,7 @@ impl<'a> ConditionSet<'a> { impl<'tcx, 'a> TOFinder<'tcx, 'a> { fn is_empty(&self, state: &State>) -> bool { - state.all(|cs| cs.0.is_empty()) + state.all_bottom() } /// Recursion entry point to find threading opportunities. @@ -198,7 +207,7 @@ impl<'tcx, 'a> TOFinder<'tcx, 'a> { debug!(?discr); let cost = CostChecker::new(self.tcx, self.param_env, None, self.body); - let mut state = State::new(ConditionSet::default(), self.map); + let mut state = State::new_reachable(); let conds = if let Some((value, then, else_)) = targets.as_static_if() { let value = ScalarInt::try_from_uint(value, discr_layout.size)?; @@ -255,7 +264,7 @@ impl<'tcx, 'a> TOFinder<'tcx, 'a> { // _1 = 5 // Whatever happens here, it won't change the result of a `SwitchInt`. // _1 = 6 if let Some((lhs, tail)) = self.mutated_statement(stmt) { - state.flood_with_tail_elem(lhs.as_ref(), tail, self.map, ConditionSet::default()); + state.flood_with_tail_elem(lhs.as_ref(), tail, self.map, ConditionSet::BOTTOM); } } @@ -609,7 +618,7 @@ impl<'tcx, 'a> TOFinder<'tcx, 'a> { // We can recurse through this terminator. let mut state = state(); if let Some(place_to_flood) = place_to_flood { - state.flood_with(place_to_flood.as_ref(), self.map, ConditionSet::default()); + state.flood_with(place_to_flood.as_ref(), self.map, ConditionSet::BOTTOM); } self.find_opportunity(bb, state, cost.clone(), depth + 1); } From 8d1065c803a70571538296bdf25101c70d39a100 Mon Sep 17 00:00:00 2001 From: rustbot <47979223+rustbot@users.noreply.github.com> Date: Mon, 1 Jul 2024 13:00:43 -0400 Subject: [PATCH 540/892] Update books --- src/doc/book | 2 +- src/doc/edition-guide | 2 +- src/doc/reference | 2 +- src/doc/rust-by-example | 2 +- src/doc/rustc-dev-guide | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/doc/book b/src/doc/book index 45c1a6d69edfd..f1e49bf7a8ea6 160000 --- a/src/doc/book +++ b/src/doc/book @@ -1 +1 @@ -Subproject commit 45c1a6d69edfd1fc91fb7504cb73958dbd09441e +Subproject commit f1e49bf7a8ea6c31ce016a52b8a4f6e1ffcfbc64 diff --git a/src/doc/edition-guide b/src/doc/edition-guide index cb58c430b4e80..941db8b3df45f 160000 --- a/src/doc/edition-guide +++ b/src/doc/edition-guide @@ -1 +1 @@ -Subproject commit cb58c430b4e8054c2cb81d2d4434092c482a93d8 +Subproject commit 941db8b3df45fd46cd87b50a5c86714b91dcde9c diff --git a/src/doc/reference b/src/doc/reference index 0b805c6580401..1ae3deebc3ac1 160000 --- a/src/doc/reference +++ b/src/doc/reference @@ -1 +1 @@ -Subproject commit 0b805c65804019b0ac8f2fe3117afad82a6069b8 +Subproject commit 1ae3deebc3ac16e276b6558e01420f8e605def08 diff --git a/src/doc/rust-by-example b/src/doc/rust-by-example index b1d97bd6113ab..658c6c27cb975 160000 --- a/src/doc/rust-by-example +++ b/src/doc/rust-by-example @@ -1 +1 @@ -Subproject commit b1d97bd6113aba732b2091ce093c76f2d05bb8a0 +Subproject commit 658c6c27cb975b92227936024816986c2d3716fb diff --git a/src/doc/rustc-dev-guide b/src/doc/rustc-dev-guide index aec82168dd312..d6e3a32a557db 160000 --- a/src/doc/rustc-dev-guide +++ b/src/doc/rustc-dev-guide @@ -1 +1 @@ -Subproject commit aec82168dd3121289a194b381f56076fc789a4d2 +Subproject commit d6e3a32a557db5902e714604def8015d6bb7e0f7 From 45b0f68e34c37e5e5f47a1474ad87ebdb099af4b Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Mon, 1 Jul 2024 18:02:40 +0000 Subject: [PATCH 541/892] Use the native unwind function in miri where possible --- library/panic_unwind/src/lib.rs | 34 +++++++++++++-------------------- 1 file changed, 13 insertions(+), 21 deletions(-) diff --git a/library/panic_unwind/src/lib.rs b/library/panic_unwind/src/lib.rs index 4dc3612060848..77abb9125f651 100644 --- a/library/panic_unwind/src/lib.rs +++ b/library/panic_unwind/src/lib.rs @@ -36,18 +36,14 @@ use core::panic::PanicPayload; cfg_if::cfg_if! { if #[cfg(target_os = "emscripten")] { #[path = "emcc.rs"] - mod real_imp; + mod imp; } else if #[cfg(target_os = "hermit")] { #[path = "hermit.rs"] - mod real_imp; + mod imp; } else if #[cfg(target_os = "l4re")] { // L4Re is unix family but does not yet support unwinding. #[path = "dummy.rs"] - mod real_imp; - } else if #[cfg(all(target_env = "msvc", not(target_arch = "arm")))] { - // LLVM does not support unwinding on 32 bit ARM msvc (thumbv7a-pc-windows-msvc) - #[path = "seh.rs"] - mod real_imp; + mod imp; } else if #[cfg(any( all(target_family = "windows", target_env = "gnu"), target_os = "psp", @@ -58,7 +54,16 @@ cfg_if::cfg_if! { target_family = "wasm", ))] { #[path = "gcc.rs"] - mod real_imp; + mod imp; + } else if #[cfg(miri)] { + // Use the Miri runtime on Windows as miri doesn't support funclet based unwinding, + // only landingpad based unwinding. Also use the Miri runtime on unsupported platforms. + #[path = "miri.rs"] + mod imp; + } else if #[cfg(all(target_env = "msvc", not(target_arch = "arm")))] { + // LLVM does not support unwinding on 32 bit ARM msvc (thumbv7a-pc-windows-msvc) + #[path = "seh.rs"] + mod imp; } else { // Targets that don't support unwinding. // - os=none ("bare metal" targets) @@ -67,20 +72,7 @@ cfg_if::cfg_if! { // - nvptx64-nvidia-cuda // - arch=avr #[path = "dummy.rs"] - mod real_imp; - } -} - -cfg_if::cfg_if! { - if #[cfg(miri)] { - // Use the Miri runtime. - // We still need to also load the normal runtime above, as rustc expects certain lang - // items from there to be defined. - #[path = "miri.rs"] mod imp; - } else { - // Use the real runtime. - use real_imp as imp; } } From 18049b73ec1c0b899d5ede199ba991f51fd652ed Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Mon, 1 Jul 2024 17:40:00 +0000 Subject: [PATCH 542/892] Use the symbol_name query instead of trying to infer from the link_name attribute This prevents the calculated name from going out of sync with exported_symbols. It also avoids having to special case the panic_impl lang item. --- src/tools/miri/src/helpers.rs | 10 +--------- src/tools/miri/src/machine.rs | 4 ++-- src/tools/miri/src/shims/foreign_items.rs | 15 --------------- 3 files changed, 3 insertions(+), 26 deletions(-) diff --git a/src/tools/miri/src/helpers.rs b/src/tools/miri/src/helpers.rs index a7a6f8cfd8729..590e8984e9908 100644 --- a/src/tools/miri/src/helpers.rs +++ b/src/tools/miri/src/helpers.rs @@ -24,7 +24,7 @@ use rustc_middle::ty::{ FloatTy, IntTy, Ty, TyCtxt, UintTy, }; use rustc_session::config::CrateType; -use rustc_span::{sym, Span, Symbol}; +use rustc_span::{Span, Symbol}; use rustc_target::abi::{Align, FieldIdx, FieldsShape, Size, Variants}; use rustc_target::spec::abi::Abi; @@ -1182,14 +1182,6 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.alloc_mark_immutable(provenance.get_alloc_id().unwrap()).unwrap(); } - fn item_link_name(&self, def_id: DefId) -> Symbol { - let tcx = self.eval_context_ref().tcx; - match tcx.get_attrs(def_id, sym::link_name).filter_map(|a| a.value_str()).next() { - Some(name) => name, - None => tcx.item_name(def_id), - } - } - /// Converts `src` from floating point to integer type `dest_ty` /// after rounding with mode `round`. /// Returns `None` if `f` is NaN or out of range. diff --git a/src/tools/miri/src/machine.rs b/src/tools/miri/src/machine.rs index 0d91279f9f4c4..e321237bb4a22 100644 --- a/src/tools/miri/src/machine.rs +++ b/src/tools/miri/src/machine.rs @@ -954,7 +954,7 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> { // foreign function // Any needed call to `goto_block` will be performed by `emulate_foreign_item`. let args = ecx.copy_fn_args(args); // FIXME: Should `InPlace` arguments be reset to uninit? - let link_name = ecx.item_link_name(instance.def_id()); + let link_name = Symbol::intern(ecx.tcx.symbol_name(instance).name); return ecx.emulate_foreign_item(link_name, abi, &args, dest, ret, unwind); } @@ -1050,7 +1050,7 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> { ecx: &MiriInterpCx<'tcx>, def_id: DefId, ) -> InterpResult<'tcx, StrictPointer> { - let link_name = ecx.item_link_name(def_id); + let link_name = Symbol::intern(ecx.tcx.symbol_name(Instance::mono(*ecx.tcx, def_id)).name); if let Some(&ptr) = ecx.machine.extern_statics.get(&link_name) { // Various parts of the engine rely on `get_alloc_info` for size and alignment // information. That uses the type information of this static. diff --git a/src/tools/miri/src/shims/foreign_items.rs b/src/tools/miri/src/shims/foreign_items.rs index f9ccc6ad4d2f6..9004f7efc8b5e 100644 --- a/src/tools/miri/src/shims/foreign_items.rs +++ b/src/tools/miri/src/shims/foreign_items.rs @@ -46,24 +46,9 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { unwind: mir::UnwindAction, ) -> InterpResult<'tcx, Option<(&'tcx mir::Body<'tcx>, ty::Instance<'tcx>)>> { let this = self.eval_context_mut(); - let tcx = this.tcx.tcx; // Some shims forward to other MIR bodies. match link_name.as_str() { - // This matches calls to the foreign item `panic_impl`. - // The implementation is provided by the function with the `#[panic_handler]` attribute. - "panic_impl" => { - // We don't use `check_shim` here because we are just forwarding to the lang - // item. Argument count checking will be performed when the returned `Body` is - // called. - this.check_abi_and_shim_symbol_clash(abi, Abi::Rust, link_name)?; - let panic_impl_id = tcx.lang_items().panic_impl().unwrap(); - let panic_impl_instance = ty::Instance::mono(tcx, panic_impl_id); - return Ok(Some(( - this.load_mir(panic_impl_instance.def, None)?, - panic_impl_instance, - ))); - } "__rust_alloc_error_handler" => { // Forward to the right symbol that implements this function. let Some(handler_kind) = this.tcx.alloc_error_handler_kind(()) else { From 9e12d919c3a247299e48d8b0fd71ca502288e443 Mon Sep 17 00:00:00 2001 From: Urgau Date: Mon, 1 Jul 2024 22:41:08 +0200 Subject: [PATCH 543/892] Improve well known value check-cfg diagnostic for the standard library --- .../src/context/diagnostics/check_cfg.rs | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_lint/src/context/diagnostics/check_cfg.rs b/compiler/rustc_lint/src/context/diagnostics/check_cfg.rs index c69e680cb64fa..da36f68fca970 100644 --- a/compiler/rustc_lint/src/context/diagnostics/check_cfg.rs +++ b/compiler/rustc_lint/src/context/diagnostics/check_cfg.rs @@ -261,10 +261,16 @@ pub(super) fn unexpected_cfg_value( lints::unexpected_cfg_value::CodeSuggestion::RemoveCondition { suggestion, name } }; - // We don't want to suggest adding values to well known names - // since those are defined by rustc it-self. Users can still - // do it if they want, but should not encourage them. - let is_cfg_a_well_know_name = sess.psess.check_config.well_known_names.contains(&name); + // We don't want to encourage people to add values to a well-known names, as these are + // defined by rustc/Rust itself. Users can still do this if they wish, but should not be + // encouraged to do so. + let can_suggest_adding_value = !sess.psess.check_config.well_known_names.contains(&name) + // Except when working on rustc or the standard library itself, in which case we want to + // suggest adding these cfgs to the "normal" place because of bootstraping reasons. As a + // basic heuristic, we use the "cheat" unstable feature enable method and the + // non-ui-testing enabled option. + || (matches!(sess.psess.unstable_features, rustc_feature::UnstableFeatures::Cheat) + && !sess.opts.unstable_opts.ui_testing); let inst = |escape_quotes| to_check_cfg_arg(name, value.map(|(v, _s)| v), escape_quotes); @@ -275,14 +281,14 @@ pub(super) fn unexpected_cfg_value( } else { Some(lints::unexpected_cfg_value::CargoHelp::DefineFeatures) } - } else if !is_cfg_a_well_know_name { + } else if can_suggest_adding_value { Some(lints::unexpected_cfg_value::CargoHelp::Other(cargo_help_sub(sess, &inst))) } else { None }; lints::unexpected_cfg_value::InvocationHelp::Cargo(help) } else { - let help = if !is_cfg_a_well_know_name { + let help = if can_suggest_adding_value { Some(lints::UnexpectedCfgRustcHelp::new(&inst(EscapeQuotes::No))) } else { None From bb4c427ce4f67d8a5b866eb3f40502c47cb2b671 Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Mon, 1 Jul 2024 18:18:10 -0400 Subject: [PATCH 544/892] Make `FloatTy` checks exhaustive in pretty print This should prevent the default fallback if we add more float types in the future. --- compiler/rustc_middle/src/ty/print/pretty.rs | 34 +++++++++++--------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 19700353f5944..d2f32cafb9d42 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -1710,22 +1710,24 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { ty::Bool if int == ScalarInt::FALSE => p!("false"), ty::Bool if int == ScalarInt::TRUE => p!("true"), // Float - ty::Float(ty::FloatTy::F16) => { - let val = Half::try_from(int).unwrap(); - p!(write("{}{}f16", val, if val.is_finite() { "" } else { "_" })) - } - ty::Float(ty::FloatTy::F32) => { - let val = Single::try_from(int).unwrap(); - p!(write("{}{}f32", val, if val.is_finite() { "" } else { "_" })) - } - ty::Float(ty::FloatTy::F64) => { - let val = Double::try_from(int).unwrap(); - p!(write("{}{}f64", val, if val.is_finite() { "" } else { "_" })) - } - ty::Float(ty::FloatTy::F128) => { - let val = Quad::try_from(int).unwrap(); - p!(write("{}{}f128", val, if val.is_finite() { "" } else { "_" })) - } + ty::Float(fty) => match fty { + ty::FloatTy::F16 => { + let val = Half::try_from(int).unwrap(); + p!(write("{}{}f16", val, if val.is_finite() { "" } else { "_" })) + } + ty::FloatTy::F32 => { + let val = Single::try_from(int).unwrap(); + p!(write("{}{}f32", val, if val.is_finite() { "" } else { "_" })) + } + ty::FloatTy::F64 => { + let val = Double::try_from(int).unwrap(); + p!(write("{}{}f64", val, if val.is_finite() { "" } else { "_" })) + } + ty::FloatTy::F128 => { + let val = Quad::try_from(int).unwrap(); + p!(write("{}{}f128", val, if val.is_finite() { "" } else { "_" })) + } + }, // Int ty::Uint(_) | ty::Int(_) => { let int = From 09e0abb0d19822455bfc40a8cf31f8fd5a675ba9 Mon Sep 17 00:00:00 2001 From: DianQK Date: Mon, 1 Jul 2024 20:54:47 +0800 Subject: [PATCH 545/892] Add the definition for `extern "C"` at `cast-target-abi.rs`. --- tests/codegen/cast-target-abi.rs | 382 +++++++++++++++++++++++++++++-- 1 file changed, 358 insertions(+), 24 deletions(-) diff --git a/tests/codegen/cast-target-abi.rs b/tests/codegen/cast-target-abi.rs index c6a8b7bbf3786..e5ff64699df95 100644 --- a/tests/codegen/cast-target-abi.rs +++ b/tests/codegen/cast-target-abi.rs @@ -1,6 +1,7 @@ // ignore-tidy-linelength -//@ revisions:aarch64 loongarch64 powerpc64 sparc64 -//@ compile-flags: -O -C no-prepopulate-passes +//@ revisions:aarch64 loongarch64 powerpc64 sparc64 x86_64 +// FIXME: Add `-Cllvm-args=--lint-abort-on-error` after LLVM 19 +//@ compile-flags: -O -C no-prepopulate-passes -C passes=lint //@[aarch64] compile-flags: --target aarch64-unknown-linux-gnu //@[aarch64] needs-llvm-components: arm @@ -10,6 +11,8 @@ //@[powerpc64] needs-llvm-components: powerpc //@[sparc64] compile-flags: --target sparc64-unknown-linux-gnu //@[sparc64] needs-llvm-components: sparc +//@[x86_64] compile-flags: --target x86_64-unknown-linux-gnu +//@[x86_64] needs-llvm-components: x86 // Tests that arguments with `PassMode::Cast` are handled correctly. @@ -60,30 +63,269 @@ pub struct DoubleFloat { g: f32, } -extern "C" { - fn receives_twou16s(x: TwoU16s); - fn returns_twou16s() -> TwoU16s; +// On x86_64, this struct will be passed as `{ i64, i32 }`. +// The load and store instructions will access 16 bytes, so we should allocate 16 bytes. +#[repr(C)] +pub struct Three32s { + a: u32, + b: u32, + c: u32, +} + +// CHECK-LABEL: @receives_twou16s +// aarch64-SAME: ([[ABI_TYPE:i64]] {{.*}}[[ABI_VALUE:%.+]]) +// loongarch64-SAME: ([[ABI_TYPE:i64]] {{.*}}[[ABI_VALUE:%.+]]) +// powerpc64-SAME: ([[ABI_TYPE:i32]] {{.*}}[[ABI_VALUE:%.+]]) +// sparc64-SAME: ([[ABI_TYPE:i64]] {{.*}}[[ABI_VALUE:%.+]]) +// x86_64-SAME: ([[ABI_TYPE:i32]] {{.*}}[[ABI_VALUE:%.+]]) +#[no_mangle] +#[inline(never)] +pub extern "C" fn receives_twou16s(x: TwoU16s) { + // aarch64: [[ABI_ALLOCA:%.+]] = alloca [8 x i8], align [[ABI_ALIGN:8]] + // loongarch64: [[ABI_ALLOCA:%.+]] = alloca [8 x i8], align [[ABI_ALIGN:8]] + // powerpc64: [[ABI_ALLOCA:%.+]] = alloca [4 x i8], align [[ABI_ALIGN:4]] + // sparc64: [[ABI_ALLOCA:%.+]] = alloca [8 x i8], align [[ABI_ALIGN:8]] + // x86_64: [[ABI_ALLOCA:%.+]] = alloca [4 x i8], align [[ABI_ALIGN:4]] - fn receives_fiveu16s(x: FiveU16s); - fn returns_fiveu16s() -> FiveU16s; + // CHECK: [[RUST_ALLOCA:%.+]] = alloca [4 x i8], align [[RUST_ALIGN:2]] - fn receives_doubledouble(x: DoubleDouble); - fn returns_doubledouble() -> DoubleDouble; + // CHECK: store [[ABI_TYPE]] [[ABI_VALUE]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] - // These functions cause an ICE in sparc64 ABI code (https://github.com/rust-lang/rust/issues/122620) - #[cfg(not(target_arch = "sparc64"))] - fn receives_doublefloat(x: DoubleFloat); - #[cfg(not(target_arch = "sparc64"))] - fn returns_doublefloat() -> DoubleFloat; + // CHECK: call void @llvm.memcpy.{{.+}}(ptr align [[RUST_ALIGN]] [[RUST_ALLOCA]], ptr align [[ABI_ALIGN]] [[ABI_ALLOCA]], i64 4, i1 false) +} + +// CHECK-LABEL: @returns_twou16s +// powerpc64-SAME: sret([4 x i8]) align [[RUST_ALIGN:2]] {{.*}}[[RET_PTR:%.*]]) +#[no_mangle] +#[inline(never)] +pub extern "C" fn returns_twou16s() -> TwoU16s { + // powerpc returns this struct via sret pointer, it doesn't use the cast ABI. + // The other targets copy the cast ABI type to an alloca. + + // aarch64: [[ABI_ALLOCA:%.+]] = alloca [4 x i8], align [[ABI_ALIGN:2]] + // loongarch64: [[ABI_ALLOCA:%.+]] = alloca [4 x i8], align [[ABI_ALIGN:2]] + // sparc64: [[ABI_ALLOCA:%.+]] = alloca [4 x i8], align [[ABI_ALIGN:2]] + // x86_64: [[ABI_ALLOCA:%.+]] = alloca [4 x i8], align [[ABI_ALIGN:2]] + + // aarch64: [[ABI_VALUE:%.+]] = load [[ABI_TYPE:i64]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] + // loongarch64: [[ABI_VALUE:%.+]] = load [[ABI_TYPE:i64]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] + // sparc64: [[ABI_VALUE:%.+]] = load [[ABI_TYPE:i64]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] + // x86_64: [[ABI_VALUE:%.+]] = load [[ABI_TYPE:i32]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] + + // aarch64: ret [[ABI_TYPE]] [[ABI_VALUE]] + // loongarch64: ret [[ABI_TYPE]] [[ABI_VALUE]] + // sparc64: ret [[ABI_TYPE]] [[ABI_VALUE]] + // x86_64: ret [[ABI_TYPE]] [[ABI_VALUE]] + TwoU16s { a: 0, b: 1 } +} + +// CHECK-LABEL: @receives_fiveu16s +// aarch64-SAME: ([[ABI_TYPE:\[2 x i64\]]] {{.*}}[[ABI_VALUE:%.+]]) +// loongarch64-SAME: ([[ABI_TYPE:\[2 x i64\]]] {{.*}}[[ABI_VALUE:%.+]]) +// powerpc64-SAME: ([[ABI_TYPE:\[2 x i64\]]] {{.*}}[[ABI_VALUE:%.+]]) +// sparc64-SAME: ([[ABI_TYPE:\[2 x i64\]]] {{.*}}[[ABI_VALUE:%.+]]) +// x86_64-SAME: ([[ABI_TYPE:{ i64, i16 }]] {{.*}}[[ABI_VALUE:%.+]]) +#[no_mangle] +#[inline(never)] +pub extern "C" fn receives_fiveu16s(x: FiveU16s) { + // aarch64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]] + // loongarch64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]] + // powerpc64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]] + // sparc64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]] + // x86_64: [[ABI_ALLOCA:%.+]] = alloca [10 x i8], align [[ABI_ALIGN:8]] + + // CHECK: [[RUST_ALLOCA:%.+]] = alloca [10 x i8], align [[RUST_ALIGN:2]] + + // CHECK: store [[ABI_TYPE]] [[ABI_VALUE]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] + + // CHECK: call void @llvm.memcpy.{{.+}}(ptr align [[RUST_ALIGN]] [[RUST_ALLOCA]], ptr align [[ABI_ALIGN]] [[ABI_ALLOCA]], i64 10, i1 false) +} + +// CHECK-LABEL: @returns_fiveu16s +// powerpc64-SAME: sret([10 x i8]) align [[RUST_ALIGN:2]] {{.*}}[[RET_PTR:%.*]]) +#[no_mangle] +#[inline(never)] +pub extern "C" fn returns_fiveu16s() -> FiveU16s { + // powerpc returns this struct via sret pointer, it doesn't use the cast ABI. + // The other targets copy the cast ABI type to an alloca. + + // aarch64: [[ABI_ALLOCA:%.+]] = alloca [10 x i8], align [[ABI_ALIGN:2]] + // loongarch64: [[ABI_ALLOCA:%.+]] = alloca [10 x i8], align [[ABI_ALIGN:2]] + // sparc64: [[ABI_ALLOCA:%.+]] = alloca [10 x i8], align [[ABI_ALIGN:2]] + // x86_64: [[ABI_ALLOCA:%.+]] = alloca [10 x i8], align [[ABI_ALIGN:2]] + + // aarch64: [[ABI_VALUE:%.+]] = load [[ABI_TYPE:\[2 x i64\]]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] + // loongarch64: [[ABI_VALUE:%.+]] = load [[ABI_TYPE:\[2 x i64\]]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] + // sparc64: [[ABI_VALUE:%.+]] = load [[ABI_TYPE:\[2 x i64\]]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] + // x86_64: [[ABI_VALUE:%.+]] = load [[ABI_TYPE:{ i64, i16 }]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] + + // aarch64: ret [[ABI_TYPE]] [[ABI_VALUE]] + // loongarch64: ret [[ABI_TYPE]] [[ABI_VALUE]] + // sparc64: ret [[ABI_TYPE]] [[ABI_VALUE]] + // x86_64: ret [[ABI_TYPE]] [[ABI_VALUE]] + FiveU16s { a: 0, b: 1, c: 2, d: 3, e: 4 } +} + +// CHECK-LABEL: @receives_doubledouble +// aarch64-SAME: ([[ABI_TYPE:\[2 x double\]]] {{.*}}[[ABI_VALUE:%.+]]) +// loongarch64-SAME: ([[ABI_TYPE:{ double, double }]] {{.*}}[[ABI_VALUE:%.+]]) +// powerpc64-SAME: ([[ABI_TYPE:\[2 x i64\]]] {{.*}}[[ABI_VALUE:%.+]]) +// sparc64-SAME: ([[ABI_TYPE:{ double, double }]] {{.*}}[[ABI_VALUE:%.+]]) +// x86_64-SAME: ([[ABI_TYPE:{ double, double }]] {{.*}}[[ABI_VALUE:%.+]]) +#[no_mangle] +#[inline(never)] +pub extern "C" fn receives_doubledouble(x: DoubleDouble) { + // CHECK: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]] + + // CHECK: [[RUST_ALLOCA:%.+]] = alloca [16 x i8], align [[RUST_ALIGN:8]] + + // CHECK: store [[ABI_TYPE]] [[ABI_VALUE]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] + + // CHECK: call void @llvm.memcpy.{{.+}}(ptr align [[RUST_ALIGN]] [[RUST_ALLOCA]], ptr align [[ABI_ALIGN]] [[ABI_ALLOCA]], i64 16, i1 false) +} + +// CHECK-LABEL: @returns_doubledouble +// powerpc64-SAME: sret([16 x i8]) align [[RUST_ALIGN:8]] {{.*}}[[RET_PTR:%.*]]) +#[no_mangle] +#[inline(never)] +pub extern "C" fn returns_doubledouble() -> DoubleDouble { + // powerpc returns this struct via sret pointer, it doesn't use the cast ABI. + // The other targets copy the cast ABI type to an alloca. + + // aarch64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]] + // loongarch64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]] + // sparc64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]] + // x86_64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]] + + // aarch64: [[ABI_VALUE:%.+]] = load [[ABI_TYPE:\[2 x double\]]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] + // loongarch64: [[ABI_VALUE:%.+]] = load [[ABI_TYPE:{ double, double }]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] + // sparc64: [[ABI_VALUE:%.+]] = load [[ABI_TYPE:{ double, double }]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] + // x86_64: [[ABI_VALUE:%.+]] = load [[ABI_TYPE:{ double, double }]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] + + // aarch64: ret [[ABI_TYPE]] [[ABI_VALUE]] + // loongarch64: ret [[ABI_TYPE]] [[ABI_VALUE]] + // sparc64: ret [[ABI_TYPE]] [[ABI_VALUE]] + // x86_64: ret [[ABI_TYPE]] [[ABI_VALUE]] + DoubleDouble { f: 0., g: 1. } +} + +// CHECK-LABEL: @receives_three32s +// aarch64-SAME: ([[ABI_TYPE:\[2 x i64\]]] {{.*}}[[ABI_VALUE:%.+]]) +// loongarch64-SAME: ([[ABI_TYPE:\[2 x i64\]]] {{.*}}[[ABI_VALUE:%.+]]) +// powerpc64-SAME: ([[ABI_TYPE:\[2 x i64\]]] {{.*}}[[ABI_VALUE:%.+]]) +// sparc64-SAME: ([[ABI_TYPE:\[2 x i64\]]] {{.*}}[[ABI_VALUE:%.+]]) +// x86_64-SAME: ([[ABI_TYPE:{ i64, i32 }]] {{.*}}[[ABI_VALUE:%.+]]) +#[no_mangle] +#[inline(never)] +pub extern "C" fn receives_three32s(x: Three32s) { + // aarch64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]] + // loongarch64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]] + // powerpc64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]] + // sparc64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]] + // x86_64: [[ABI_ALLOCA:%.+]] = alloca [12 x i8], align [[ABI_ALIGN:8]] + + // CHECK: [[RUST_ALLOCA:%.+]] = alloca [12 x i8], align [[RUST_ALIGN:4]] + + // CHECK: store [[ABI_TYPE]] [[ABI_VALUE]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] + + // CHECK: call void @llvm.memcpy.{{.+}}(ptr align [[RUST_ALIGN]] [[RUST_ALLOCA]], ptr align [[ABI_ALIGN]] [[ABI_ALLOCA]], i64 12, i1 false) +} + +// CHECK-LABEL: @returns_three32s +// powerpc64-SAME: sret([12 x i8]) align [[RUST_ALIGN:4]] {{.*}}[[RET_PTR:%.*]]) +#[no_mangle] +#[inline(never)] +pub extern "C" fn returns_three32s() -> Three32s { + // powerpc returns this struct via sret pointer, it doesn't use the cast ABI. + // The other targets copy the cast ABI type to an alloca. + + // aarch64: [[ABI_ALLOCA:%.+]] = alloca [12 x i8], align [[ABI_ALIGN:4]] + // loongarch64: [[ABI_ALLOCA:%.+]] = alloca [12 x i8], align [[ABI_ALIGN:4]] + // sparc64: [[ABI_ALLOCA:%.+]] = alloca [12 x i8], align [[ABI_ALIGN:4]] + // x86_64: [[ABI_ALLOCA:%.+]] = alloca [12 x i8], align [[ABI_ALIGN:4]] + + // aarch64: [[ABI_VALUE:%.+]] = load [[ABI_TYPE:\[2 x i64\]]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] + // loongarch64: [[ABI_VALUE:%.+]] = load [[ABI_TYPE:\[2 x i64\]]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] + // sparc64: [[ABI_VALUE:%.+]] = load [[ABI_TYPE:\[2 x i64\]]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] + // x86_64: [[ABI_VALUE:%.+]] = load [[ABI_TYPE:{ i64, i32 }]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] + + // aarch64: ret [[ABI_TYPE]] [[ABI_VALUE]] + // loongarch64: ret [[ABI_TYPE]] [[ABI_VALUE]] + // sparc64: ret [[ABI_TYPE]] [[ABI_VALUE]] + // x86_64: ret [[ABI_TYPE]] [[ABI_VALUE]] + Three32s { a: 0, b: 0, c: 0 } +} + +// These functions cause an ICE in sparc64 ABI code (https://github.com/rust-lang/rust/issues/122620) +#[cfg(not(target_arch = "sparc64"))] +// aarch64-LABEL: @receives_doublefloat +// loongarch64-LABEL: @receives_doublefloat +// powerpc64-LABEL: @receives_doublefloat +// x86_64-LABEL: @receives_doublefloat + +// aarch64-SAME: ([[ABI_TYPE:\[2 x i64\]]] {{.*}}[[ABI_VALUE:%.+]]) +// loongarch64-SAME: ([[ABI_TYPE:{ double, float }]] {{.*}}[[ABI_VALUE:%.+]]) +// powerpc64-SAME: ([[ABI_TYPE:\[2 x i64\]]] {{.*}}[[ABI_VALUE:%.+]]) +// x86_64-SAME: ([[ABI_TYPE:{ double, double }]] {{.*}}[[ABI_VALUE:%.+]]) +#[no_mangle] +#[inline(never)] +pub extern "C" fn receives_doublefloat(x: DoubleFloat) { + // aarch64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]] + // loongarch64: [[ABI_ALLOCA:%.+]] = alloca [12 x i8], align [[ABI_ALIGN:8]] + // powerpc64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]] + // x86_64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]] + + // aarch64: [[RUST_ALLOCA:%.+]] = alloca [16 x i8], align [[RUST_ALIGN:8]] + // loongarch64: [[RUST_ALLOCA:%.+]] = alloca [16 x i8], align [[RUST_ALIGN:8]] + // powerpc64: [[RUST_ALLOCA:%.+]] = alloca [16 x i8], align [[RUST_ALIGN:8]] + // x86_64: [[RUST_ALLOCA:%.+]] = alloca [16 x i8], align [[RUST_ALIGN:8]] + + // aarch64: store [[ABI_TYPE]] [[ABI_VALUE]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] + // loongarch64: store [[ABI_TYPE]] [[ABI_VALUE]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] + // powerpc64: store [[ABI_TYPE]] [[ABI_VALUE]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] + // x86_64: store [[ABI_TYPE]] [[ABI_VALUE]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] + + // aarch64: call void @llvm.memcpy.{{.+}}(ptr align [[RUST_ALIGN]] [[RUST_ALLOCA]], ptr align [[ABI_ALIGN]] [[ABI_ALLOCA]], i64 16, i1 false) + // loongarch64: call void @llvm.memcpy.{{.+}}(ptr align [[RUST_ALIGN]] [[RUST_ALLOCA]], ptr align [[ABI_ALIGN]] [[ABI_ALLOCA]], i64 12, i1 false) + // powerpc64: call void @llvm.memcpy.{{.+}}(ptr align [[RUST_ALIGN]] [[RUST_ALLOCA]], ptr align [[ABI_ALIGN]] [[ABI_ALLOCA]], i64 16, i1 false) + // x86_64: call void @llvm.memcpy.{{.+}}(ptr align [[RUST_ALIGN]] [[RUST_ALLOCA]], ptr align [[ABI_ALIGN]] [[ABI_ALLOCA]], i64 16, i1 false) +} + +#[cfg(not(target_arch = "sparc64"))] +// aarch64-LABEL: @returns_doublefloat +// loongarch64-LABEL: @returns_doublefloat +// powerpc64-LABEL: @returns_doublefloat +// x86_64-LABEL: @returns_doublefloat + +// powerpc64-SAME: sret([16 x i8]) align [[RUST_ALIGN:8]] {{.*}}[[RET_PTR:%.*]]) +#[no_mangle] +#[inline(never)] +pub extern "C" fn returns_doublefloat() -> DoubleFloat { + // powerpc returns this struct via sret pointer, it doesn't use the cast ABI. + // The other targets copy the cast ABI type to an alloca. + + // aarch64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]] + // loongarch64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]] + // x86_64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]] + + // aarch64: [[ABI_VALUE:%.+]] = load [[ABI_TYPE:\[2 x i64\]]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] + // loongarch64: [[ABI_VALUE:%.+]] = load [[ABI_TYPE:{ double, float }]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] + // x86_64: [[ABI_VALUE:%.+]] = load [[ABI_TYPE:{ double, double }]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] + + // aarch64: ret [[ABI_TYPE]] [[ABI_VALUE]] + // loongarch64: ret [[ABI_TYPE]] [[ABI_VALUE]] + // x86_64: ret [[ABI_TYPE]] [[ABI_VALUE]] + DoubleFloat { f: 0., g: 0. } } // CHECK-LABEL: @call_twou16s #[no_mangle] -pub unsafe fn call_twou16s() { +pub fn call_twou16s() { // aarch64: [[ABI_ALLOCA:%.+]] = alloca [8 x i8], align [[ABI_ALIGN:8]] // loongarch64: [[ABI_ALLOCA:%.+]] = alloca [8 x i8], align [[ABI_ALIGN:8]] // powerpc64: [[ABI_ALLOCA:%.+]] = alloca [4 x i8], align [[ABI_ALIGN:4]] // sparc64: [[ABI_ALLOCA:%.+]] = alloca [8 x i8], align [[ABI_ALIGN:8]] + // x86_64: [[ABI_ALLOCA:%.+]] = alloca [4 x i8], align [[ABI_ALIGN:4]] // CHECK: [[RUST_ALLOCA:%.+]] = alloca [4 x i8], align [[RUST_ALIGN:2]] @@ -93,6 +335,7 @@ pub unsafe fn call_twou16s() { // loongarch64: [[ABI_VALUE:%.+]] = load [[ABI_TYPE:i64]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] // powerpc64: [[ABI_VALUE:%.+]] = load [[ABI_TYPE:i32]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] // sparc64: [[ABI_VALUE:%.+]] = load [[ABI_TYPE:i64]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] + // x86_64: [[ABI_VALUE:%.+]] = load [[ABI_TYPE:i32]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] // CHECK: call void @receives_twou16s([[ABI_TYPE]] [[ABI_VALUE]]) let x = TwoU16s { a: 1, b: 2 }; @@ -101,7 +344,7 @@ pub unsafe fn call_twou16s() { // CHECK-LABEL: @return_twou16s #[no_mangle] -pub unsafe fn return_twou16s() -> TwoU16s { +pub fn return_twou16s() -> TwoU16s { // powerpc returns this struct via sret pointer, it doesn't use the cast ABI. // powerpc64: [[RETVAL:%.+]] = alloca [4 x i8], align 2 @@ -112,34 +355,49 @@ pub unsafe fn return_twou16s() -> TwoU16s { // aarch64: [[ABI_ALLOCA:%.+]] = alloca [8 x i8], align [[ABI_ALIGN:8]] // loongarch64: [[ABI_ALLOCA:%.+]] = alloca [8 x i8], align [[ABI_ALIGN:8]] // sparc64: [[ABI_ALLOCA:%.+]] = alloca [8 x i8], align [[ABI_ALIGN:8]] + // x86_64: [[ABI_ALLOCA:%.+]] = alloca [4 x i8], align [[ABI_ALIGN:4]] // aarch64: [[RUST_ALLOCA:%.+]] = alloca [4 x i8], align [[RUST_ALIGN:2]] // loongarch64: [[RUST_ALLOCA:%.+]] = alloca [4 x i8], align [[RUST_ALIGN:2]] // sparc64: [[RUST_ALLOCA:%.+]] = alloca [4 x i8], align [[RUST_ALIGN:2]] + // x86_64: [[RUST_ALLOCA:%.+]] = alloca [4 x i8], align [[RUST_ALIGN:2]] // aarch64: [[ABI_VALUE:%.+]] = call [[ABI_TYPE:i64]] @returns_twou16s() // loongarch64: [[ABI_VALUE:%.+]] = call [[ABI_TYPE:i64]] @returns_twou16s() // sparc64: [[ABI_VALUE:%.+]] = call [[ABI_TYPE:i64]] @returns_twou16s() + // x86_64: [[ABI_VALUE:%.+]] = call [[ABI_TYPE:i32]] @returns_twou16s() // aarch64: store [[ABI_TYPE]] [[ABI_VALUE]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] // loongarch64: store [[ABI_TYPE]] [[ABI_VALUE]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] // sparc64: store [[ABI_TYPE]] [[ABI_VALUE]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] + // x86_64: store [[ABI_TYPE]] [[ABI_VALUE]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] // aarch64: call void @llvm.memcpy.{{.+}}(ptr align [[RUST_ALIGN]] [[RUST_ALLOCA]], ptr align [[ABI_ALIGN]] [[ABI_ALLOCA]], i64 4, i1 false) // loongarch64: call void @llvm.memcpy.{{.+}}(ptr align [[RUST_ALIGN]] [[RUST_ALLOCA]], ptr align [[ABI_ALIGN]] [[ABI_ALLOCA]], i64 4, i1 false) // sparc64: call void @llvm.memcpy.{{.+}}(ptr align [[RUST_ALIGN]] [[RUST_ALLOCA]], ptr align [[ABI_ALIGN]] [[ABI_ALLOCA]], i64 4, i1 false) + // x86_64: call void @llvm.memcpy.{{.+}}(ptr align [[RUST_ALIGN]] [[RUST_ALLOCA]], ptr align [[ABI_ALIGN]] [[ABI_ALLOCA]], i64 4, i1 false) returns_twou16s() } // CHECK-LABEL: @call_fiveu16s #[no_mangle] -pub unsafe fn call_fiveu16s() { - // CHECK: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]] +pub fn call_fiveu16s() { + // aarch64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]] + // loongarch64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]] + // powerpc64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]] + // sparc64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]] + // x86_64: [[ABI_ALLOCA:%.+]] = alloca [10 x i8], align [[ABI_ALIGN:8]] // CHECK: [[RUST_ALLOCA:%.+]] = alloca [10 x i8], align 2 // CHECK: call void @llvm.memcpy.{{.+}}(ptr align [[ABI_ALIGN]] [[ABI_ALLOCA]], ptr align [[RUST_ALIGN]] [[RUST_ALLOCA]], i64 10, i1 false) - // CHECK: [[ABI_VALUE:%.+]] = load [[ABI_TYPE:\[2 x i64\]]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] + + // aarch64: [[ABI_VALUE:%.+]] = load [[ABI_TYPE:\[2 x i64\]]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] + // loongarch64: [[ABI_VALUE:%.+]] = load [[ABI_TYPE:\[2 x i64\]]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] + // powerpc64: [[ABI_VALUE:%.+]] = load [[ABI_TYPE:\[2 x i64\]]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] + // sparc64: [[ABI_VALUE:%.+]] = load [[ABI_TYPE:\[2 x i64\]]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] + // x86_64: [[ABI_VALUE:%.+]] = load [[ABI_TYPE:{ i64, i16 }]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] + // CHECK: call void @receives_fiveu16s([[ABI_TYPE]] [[ABI_VALUE]]) let x = FiveU16s { a: 1, b: 2, c: 3, d: 4, e: 5 }; receives_fiveu16s(x); @@ -148,7 +406,7 @@ pub unsafe fn call_fiveu16s() { // CHECK-LABEL: @return_fiveu16s // CHECK-SAME: (ptr {{.+}} sret([10 x i8]) align [[RUST_ALIGN:2]] dereferenceable(10) [[RET_PTR:%.+]]) #[no_mangle] -pub unsafe fn return_fiveu16s() -> FiveU16s { +pub fn return_fiveu16s() -> FiveU16s { // powerpc returns this struct via sret pointer, it doesn't use the cast ABI. // powerpc64: call void @returns_fiveu16s(ptr {{.+}} [[RET_PTR]]) @@ -158,24 +416,28 @@ pub unsafe fn return_fiveu16s() -> FiveU16s { // aarch64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]] // loongarch64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]] // sparc64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]] + // x86_64: [[ABI_ALLOCA:%.+]] = alloca [10 x i8], align [[ABI_ALIGN:8]] // aarch64: [[ABI_VALUE:%.+]] = call [[ABI_TYPE:\[2 x i64\]]] @returns_fiveu16s() // loongarch64: [[ABI_VALUE:%.+]] = call [[ABI_TYPE:\[2 x i64\]]] @returns_fiveu16s() // sparc64: [[ABI_VALUE:%.+]] = call [[ABI_TYPE:\[2 x i64\]]] @returns_fiveu16s() + // x86_64: [[ABI_VALUE:%.+]] = call [[ABI_TYPE:{ i64, i16 }]] @returns_fiveu16s() // aarch64: store [[ABI_TYPE]] [[ABI_VALUE]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] // loongarch64: store [[ABI_TYPE]] [[ABI_VALUE]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] // sparc64: store [[ABI_TYPE]] [[ABI_VALUE]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] + // x86_64: store [[ABI_TYPE]] [[ABI_VALUE]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] // aarch64: call void @llvm.memcpy.{{.+}}(ptr align [[RUST_ALIGN]] [[RET_PTR]], ptr align [[ABI_ALIGN]] [[ABI_ALLOCA]], i64 10, i1 false) // loongarch64: call void @llvm.memcpy.{{.+}}(ptr align [[RUST_ALIGN]] [[RET_PTR]], ptr align [[ABI_ALIGN]] [[ABI_ALLOCA]], i64 10, i1 false) // sparc64: call void @llvm.memcpy.{{.+}}(ptr align [[RUST_ALIGN]] [[RET_PTR]], ptr align [[ABI_ALIGN]] [[ABI_ALLOCA]], i64 10, i1 false) + // x86_64: call void @llvm.memcpy.{{.+}}(ptr align [[RUST_ALIGN]] [[RET_PTR]], ptr align [[ABI_ALIGN]] [[ABI_ALLOCA]], i64 10, i1 false) returns_fiveu16s() } // CHECK-LABEL: @call_doubledouble #[no_mangle] -pub unsafe fn call_doubledouble() { +pub fn call_doubledouble() { // CHECK: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]] // CHECK: [[RUST_ALLOCA:%.+]] = alloca [16 x i8], align [[RUST_ALIGN:8]] @@ -186,6 +448,7 @@ pub unsafe fn call_doubledouble() { // loongarch64: [[ABI_VALUE:%.+]] = load [[ABI_TYPE:{ double, double }]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] // powerpc64: [[ABI_VALUE:%.+]] = load [[ABI_TYPE:\[2 x i64\]]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] // sparc64: [[ABI_VALUE:%.+]] = load [[ABI_TYPE:{ double, double }]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] + // x86_64: [[ABI_VALUE:%.+]] = load [[ABI_TYPE:{ double, double }]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] // CHECK: call void @receives_doubledouble([[ABI_TYPE]] [[ABI_VALUE]]) let x = DoubleDouble { f: 1., g: 2. }; @@ -194,7 +457,7 @@ pub unsafe fn call_doubledouble() { // CHECK-LABEL: @return_doubledouble #[no_mangle] -pub unsafe fn return_doubledouble() -> DoubleDouble { +pub fn return_doubledouble() -> DoubleDouble { // powerpc returns this struct via sret pointer, it doesn't use the cast ABI. // powerpc64: [[RETVAL:%.+]] = alloca [16 x i8], align 8 @@ -205,22 +468,27 @@ pub unsafe fn return_doubledouble() -> DoubleDouble { // aarch64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]] // loongarch64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]] // sparc64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]] + // x86_64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]] // aarch64: [[RUST_ALLOCA:%.+]] = alloca [16 x i8], align [[RUST_ALIGN:8]] // loongarch64: [[RUST_ALLOCA:%.+]] = alloca [16 x i8], align [[RUST_ALIGN:8]] // sparc64: [[RUST_ALLOCA:%.+]] = alloca [16 x i8], align [[RUST_ALIGN:8]] + // x86_64: [[RUST_ALLOCA:%.+]] = alloca [16 x i8], align [[RUST_ALIGN:8]] // aarch64: [[ABI_VALUE:%.+]] = call [[ABI_TYPE:\[2 x double\]]] @returns_doubledouble() // loongarch64: [[ABI_VALUE:%.+]] = call [[ABI_TYPE:{ double, double }]] @returns_doubledouble() // sparc64: [[ABI_VALUE:%.+]] = call [[ABI_TYPE:{ double, double }]] @returns_doubledouble() + // x86_64: [[ABI_VALUE:%.+]] = call [[ABI_TYPE:{ double, double }]] @returns_doubledouble() // aarch64: store [[ABI_TYPE]] [[ABI_VALUE]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] // loongarch64: store [[ABI_TYPE]] [[ABI_VALUE]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] // sparc64: store [[ABI_TYPE]] [[ABI_VALUE]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] + // x86_64: store [[ABI_TYPE]] [[ABI_VALUE]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] // aarch64: call void @llvm.memcpy.{{.+}}(ptr align [[RUST_ALIGN]] [[RUST_ALLOCA]], ptr align [[ABI_ALIGN]] [[ABI_ALLOCA]], i64 16, i1 false) // loongarch64: call void @llvm.memcpy.{{.+}}(ptr align [[RUST_ALIGN]] [[RUST_ALLOCA]], ptr align [[ABI_ALIGN]] [[ABI_ALLOCA]], i64 16, i1 false) // sparc64: call void @llvm.memcpy.{{.+}}(ptr align [[RUST_ALIGN]] [[RUST_ALLOCA]], ptr align [[ABI_ALIGN]] [[ABI_ALLOCA]], i64 16, i1 false) + // x86_64: call void @llvm.memcpy.{{.+}}(ptr align [[RUST_ALIGN]] [[RUST_ALLOCA]], ptr align [[ABI_ALIGN]] [[ABI_ALLOCA]], i64 16, i1 false) returns_doubledouble() } @@ -229,27 +497,33 @@ pub unsafe fn return_doubledouble() -> DoubleDouble { // aarch64-LABEL: @call_doublefloat // loongarch64-LABEL: @call_doublefloat // powerpc64-LABEL: @call_doublefloat +// x86_64-LABEL: @call_doublefloat #[no_mangle] -pub unsafe fn call_doublefloat() { +pub fn call_doublefloat() { // aarch64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]] // loongarch64: [[ABI_ALLOCA:%.+]] = alloca [12 x i8], align [[ABI_ALIGN:8]] // powerpc64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]] + // x86_64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]] // aarch64: [[RUST_ALLOCA:%.+]] = alloca [16 x i8], align [[RUST_ALIGN:8]] // loongarch64: [[RUST_ALLOCA:%.+]] = alloca [16 x i8], align [[RUST_ALIGN:8]] // powerpc64: [[RUST_ALLOCA:%.+]] = alloca [16 x i8], align [[RUST_ALIGN:8]] + // x86_64: [[RUST_ALLOCA:%.+]] = alloca [16 x i8], align [[RUST_ALIGN:8]] // aarch64: call void @llvm.memcpy.{{.+}}(ptr align [[ABI_ALIGN]] [[ABI_ALLOCA]], ptr align [[RUST_ALIGN]] [[RUST_ALLOCA]], i64 16, i1 false) // loongarch64: call void @llvm.memcpy.{{.+}}(ptr align [[ABI_ALIGN]] [[ABI_ALLOCA]], ptr align [[RUST_ALIGN]] [[RUST_ALLOCA]], i64 12, i1 false) // powerpc64: call void @llvm.memcpy.{{.+}}(ptr align [[ABI_ALIGN]] [[ABI_ALLOCA]], ptr align [[RUST_ALIGN]] [[RUST_ALLOCA]], i64 16, i1 false) + // x86_64: call void @llvm.memcpy.{{.+}}(ptr align [[ABI_ALIGN]] [[ABI_ALLOCA]], ptr align [[RUST_ALIGN]] [[RUST_ALLOCA]], i64 16, i1 false) // aarch64: [[ABI_VALUE:%.+]] = load [[ABI_TYPE:\[2 x i64\]]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] // loongarch64: [[ABI_VALUE:%.+]] = load [[ABI_TYPE:{ double, float }]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] // powerpc64: [[ABI_VALUE:%.+]] = load [[ABI_TYPE:\[2 x i64\]]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] + // x86_64: [[ABI_VALUE:%.+]] = load [[ABI_TYPE:{ double, double }]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] // aarch64: call void @receives_doublefloat([[ABI_TYPE]] {{(inreg )?}}[[ABI_VALUE]]) // loongarch64: call void @receives_doublefloat([[ABI_TYPE]] {{(inreg )?}}[[ABI_VALUE]]) // powerpc64: call void @receives_doublefloat([[ABI_TYPE]] {{(inreg )?}}[[ABI_VALUE]]) + // x86_64: call void @receives_doublefloat([[ABI_TYPE]] {{(inreg )?}}[[ABI_VALUE]]) let x = DoubleFloat { f: 1., g: 2. }; receives_doublefloat(x); } @@ -259,8 +533,9 @@ pub unsafe fn call_doublefloat() { // aarch64-LABEL: @return_doublefloat // loongarch64-LABEL: @return_doublefloat // powerpc64-LABEL: @return_doublefloat +// x86_64-LABEL: @return_doublefloat #[no_mangle] -pub unsafe fn return_doublefloat() -> DoubleFloat { +pub fn return_doublefloat() -> DoubleFloat { // powerpc returns this struct via sret pointer, it doesn't use the cast ABI. // powerpc64: [[RETVAL:%.+]] = alloca [16 x i8], align 8 @@ -270,17 +545,76 @@ pub unsafe fn return_doublefloat() -> DoubleFloat { // aarch64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]] // loongarch64: [[ABI_ALLOCA:%.+]] = alloca [12 x i8], align [[ABI_ALIGN:8]] + // x86_64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]] // aarch64: [[RUST_ALLOCA:%.+]] = alloca [16 x i8], align [[RUST_ALIGN:8]] // loongarch64: [[RUST_ALLOCA:%.+]] = alloca [16 x i8], align [[RUST_ALIGN:8]] + // x86_64: [[RUST_ALLOCA:%.+]] = alloca [16 x i8], align [[RUST_ALIGN:8]] // aarch64: [[ABI_VALUE:%.+]] = call [[ABI_TYPE:\[2 x i64\]]] @returns_doublefloat() // loongarch64: [[ABI_VALUE:%.+]] = call [[ABI_TYPE:{ double, float }]] @returns_doublefloat() + // x86_64: [[ABI_VALUE:%.+]] = call [[ABI_TYPE:{ double, double }]] @returns_doublefloat() // aarch64: store [[ABI_TYPE]] [[ABI_VALUE]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] // loongarch64: store [[ABI_TYPE]] [[ABI_VALUE]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] + // x86_64: store [[ABI_TYPE]] [[ABI_VALUE]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] // aarch64: call void @llvm.memcpy.{{.+}}(ptr align [[RUST_ALIGN]] [[RUST_ALLOCA]], ptr align [[ABI_ALIGN]] [[ABI_ALLOCA]], i64 16, i1 false) // loongarch64: call void @llvm.memcpy.{{.+}}(ptr align [[RUST_ALIGN]] [[RUST_ALLOCA]], ptr align [[ABI_ALIGN]] [[ABI_ALLOCA]], i64 12, i1 false) + // x86_64: call void @llvm.memcpy.{{.+}}(ptr align [[RUST_ALIGN]] [[RUST_ALLOCA]], ptr align [[ABI_ALIGN]] [[ABI_ALLOCA]], i64 16, i1 false) returns_doublefloat() } + +// CHECK-LABEL: @call_three32s +#[no_mangle] +pub fn call_three32s() { + // aarch64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]] + // loongarch64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]] + // powerpc64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]] + // sparc64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]] + // x86_64: [[ABI_ALLOCA:%.+]] = alloca [12 x i8], align [[ABI_ALIGN:8]] + + // CHECK: [[RUST_ALLOCA:%.+]] = alloca [12 x i8], align [[RUST_ALIGN:4]] + // CHECK: call void @llvm.memcpy.{{.+}}(ptr align [[ABI_ALIGN]] [[ABI_ALLOCA]], ptr align [[RUST_ALIGN]] [[RUST_ALLOCA]], i64 12, i1 false) + + // aarch64: [[ABI_VALUE:%.+]] = load [[ABI_TYPE:\[2 x i64\]]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] + // loongarch64: [[ABI_VALUE:%.+]] = load [[ABI_TYPE:\[2 x i64\]]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] + // powerpc64: [[ABI_VALUE:%.+]] = load [[ABI_TYPE:\[2 x i64\]]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] + // sparc64: [[ABI_VALUE:%.+]] = load [[ABI_TYPE:\[2 x i64\]]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] + // x86_64: [[ABI_VALUE:%.+]] = load [[ABI_TYPE:{ i64, i32 }]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] + + // CHECK: call void @receives_three32s([[ABI_TYPE]] [[ABI_VALUE]]) + let x = Three32s { a: 1, b: 2, c: 3 }; + receives_three32s(x); +} + +// Regression test for #75839 +// CHECK-LABEL: @return_three32s( +// CHECK-SAME: sret([12 x i8]) align [[RUST_ALIGN:4]] {{.*}}[[RUST_RETVAL:%.*]]) +#[no_mangle] +pub fn return_three32s() -> Three32s { + // powerpc returns this struct via sret pointer, it doesn't use the cast ABI. + + // powerpc64: call void @returns_three32s(ptr {{.+}} [[RUST_RETVAL]]) + + // aarch64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]] + // loongarch64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]] + // sparc64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]] + // x86_64: [[ABI_ALLOCA:%.+]] = alloca [12 x i8], align [[ABI_ALIGN:8]] + + // aarch64: [[ABI_VALUE:%.+]] = call [[ABI_TYPE:\[2 x i64\]]] @returns_three32s() + // loongarch64: [[ABI_VALUE:%.+]] = call [[ABI_TYPE:\[2 x i64\]]] @returns_three32s() + // sparc64: [[ABI_VALUE:%.+]] = call [[ABI_TYPE:\[2 x i64\]]] @returns_three32s() + // x86_64: [[ABI_VALUE:%.+]] = call [[ABI_TYPE:{ i64, i32 }]] @returns_three32s() + + // aarch64: store [[ABI_TYPE]] [[ABI_VALUE]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] + // loongarch64: store [[ABI_TYPE]] [[ABI_VALUE]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] + // sparc64: store [[ABI_TYPE]] [[ABI_VALUE]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] + // x86_64: store [[ABI_TYPE]] [[ABI_VALUE]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] + + // aarch64: call void @llvm.memcpy.{{.+}}(ptr align [[RUST_ALIGN]] [[RUST_RETVAL]], ptr align [[ABI_ALIGN]] [[ABI_ALLOCA]], i64 12, i1 false) + // loongarch64: call void @llvm.memcpy.{{.+}}(ptr align [[RUST_ALIGN]] [[RUST_RETVAL]], ptr align [[ABI_ALIGN]] [[ABI_ALLOCA]], i64 12, i1 false) + // sparc64: call void @llvm.memcpy.{{.+}}(ptr align [[RUST_ALIGN]] [[RUST_RETVAL]], ptr align [[ABI_ALIGN]] [[ABI_ALLOCA]], i64 12, i1 false) + // x86_64: call void @llvm.memcpy.{{.+}}(ptr align [[RUST_ALIGN]] [[RUST_RETVAL]], ptr align [[ABI_ALIGN]] [[ABI_ALLOCA]], i64 12, i1 false) + returns_three32s() +} From c453dcd62abba536d0580ad9b880b86d46e911ce Mon Sep 17 00:00:00 2001 From: DianQK Date: Sun, 30 Jun 2024 21:33:46 +0800 Subject: [PATCH 546/892] Use the aligned size for alloca at args when the pass mode is cast. The `load` and `store` instructions in LLVM access the aligned size. --- compiler/rustc_codegen_llvm/src/abi.rs | 3 +- compiler/rustc_codegen_ssa/src/mir/block.rs | 2 +- compiler/rustc_target/src/abi/call/mod.rs | 8 ++++- tests/codegen/cast-target-abi.rs | 35 +++++-------------- tests/codegen/cffi/ffi-out-of-bounds-loads.rs | 4 +-- 5 files changed, 21 insertions(+), 31 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/abi.rs b/compiler/rustc_codegen_llvm/src/abi.rs index a6a3f0f964611..d034f9b525690 100644 --- a/compiler/rustc_codegen_llvm/src/abi.rs +++ b/compiler/rustc_codegen_llvm/src/abi.rs @@ -226,7 +226,8 @@ impl<'ll, 'tcx> ArgAbiExt<'ll, 'tcx> for ArgAbi<'tcx, Ty<'tcx>> { // when passed by value, making it smaller. // - On some ABIs, the Rust layout { u16, u16, u16 } may be padded up to 8 bytes // when passed by value, making it larger. - let copy_bytes = cmp::min(scratch_size.bytes(), self.layout.size.bytes()); + let copy_bytes = + cmp::min(cast.unaligned_size(bx).bytes(), self.layout.size.bytes()); // Allocate some scratch space... let llscratch = bx.alloca(scratch_size, scratch_align); bx.lifetime_start(llscratch, scratch_size); diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index 57138d3b9dbdb..d4da13068d267 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -1540,7 +1540,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { // when passed by value, making it smaller. // - On some ABIs, the Rust layout { u16, u16, u16 } may be padded up to 8 bytes // when passed by value, making it larger. - let copy_bytes = cmp::min(scratch_size.bytes(), arg.layout.size.bytes()); + let copy_bytes = cmp::min(cast.unaligned_size(bx).bytes(), arg.layout.size.bytes()); // Allocate some scratch space... let llscratch = bx.alloca(scratch_size, scratch_align); bx.lifetime_start(llscratch, scratch_size); diff --git a/compiler/rustc_target/src/abi/call/mod.rs b/compiler/rustc_target/src/abi/call/mod.rs index 5713542c17d63..8058130f44151 100644 --- a/compiler/rustc_target/src/abi/call/mod.rs +++ b/compiler/rustc_target/src/abi/call/mod.rs @@ -339,7 +339,9 @@ impl CastTarget { } } - pub fn size(&self, _cx: &C) -> Size { + /// When you only access the range containing valid data, you can use this unaligned size; + /// otherwise, use the safer `size` method. + pub fn unaligned_size(&self, _cx: &C) -> Size { // Prefix arguments are passed in specific designated registers let prefix_size = self .prefix @@ -353,6 +355,10 @@ impl CastTarget { prefix_size + rest_size } + pub fn size(&self, cx: &C) -> Size { + self.unaligned_size(cx).align_to(self.align(cx)) + } + pub fn align(&self, cx: &C) -> Align { self.prefix .iter() diff --git a/tests/codegen/cast-target-abi.rs b/tests/codegen/cast-target-abi.rs index e5ff64699df95..13b74d68f76e4 100644 --- a/tests/codegen/cast-target-abi.rs +++ b/tests/codegen/cast-target-abi.rs @@ -128,11 +128,7 @@ pub extern "C" fn returns_twou16s() -> TwoU16s { #[no_mangle] #[inline(never)] pub extern "C" fn receives_fiveu16s(x: FiveU16s) { - // aarch64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]] - // loongarch64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]] - // powerpc64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]] - // sparc64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]] - // x86_64: [[ABI_ALLOCA:%.+]] = alloca [10 x i8], align [[ABI_ALIGN:8]] + // CHECK: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]] // CHECK: [[RUST_ALLOCA:%.+]] = alloca [10 x i8], align [[RUST_ALIGN:2]] @@ -218,11 +214,7 @@ pub extern "C" fn returns_doubledouble() -> DoubleDouble { #[no_mangle] #[inline(never)] pub extern "C" fn receives_three32s(x: Three32s) { - // aarch64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]] - // loongarch64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]] - // powerpc64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]] - // sparc64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]] - // x86_64: [[ABI_ALLOCA:%.+]] = alloca [12 x i8], align [[ABI_ALIGN:8]] + // CHECK: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]] // CHECK: [[RUST_ALLOCA:%.+]] = alloca [12 x i8], align [[RUST_ALIGN:4]] @@ -271,7 +263,7 @@ pub extern "C" fn returns_three32s() -> Three32s { #[inline(never)] pub extern "C" fn receives_doublefloat(x: DoubleFloat) { // aarch64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]] - // loongarch64: [[ABI_ALLOCA:%.+]] = alloca [12 x i8], align [[ABI_ALIGN:8]] + // loongarch64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]] // powerpc64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]] // x86_64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]] @@ -382,11 +374,7 @@ pub fn return_twou16s() -> TwoU16s { // CHECK-LABEL: @call_fiveu16s #[no_mangle] pub fn call_fiveu16s() { - // aarch64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]] - // loongarch64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]] - // powerpc64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]] - // sparc64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]] - // x86_64: [[ABI_ALLOCA:%.+]] = alloca [10 x i8], align [[ABI_ALIGN:8]] + // CHECK: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]] // CHECK: [[RUST_ALLOCA:%.+]] = alloca [10 x i8], align 2 @@ -416,7 +404,7 @@ pub fn return_fiveu16s() -> FiveU16s { // aarch64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]] // loongarch64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]] // sparc64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]] - // x86_64: [[ABI_ALLOCA:%.+]] = alloca [10 x i8], align [[ABI_ALIGN:8]] + // x86_64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]] // aarch64: [[ABI_VALUE:%.+]] = call [[ABI_TYPE:\[2 x i64\]]] @returns_fiveu16s() // loongarch64: [[ABI_VALUE:%.+]] = call [[ABI_TYPE:\[2 x i64\]]] @returns_fiveu16s() @@ -501,7 +489,7 @@ pub fn return_doubledouble() -> DoubleDouble { #[no_mangle] pub fn call_doublefloat() { // aarch64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]] - // loongarch64: [[ABI_ALLOCA:%.+]] = alloca [12 x i8], align [[ABI_ALIGN:8]] + // loongarch64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]] // powerpc64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]] // x86_64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]] @@ -544,7 +532,7 @@ pub fn return_doublefloat() -> DoubleFloat { // The other targets copy the cast ABI type to an alloca. // aarch64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]] - // loongarch64: [[ABI_ALLOCA:%.+]] = alloca [12 x i8], align [[ABI_ALIGN:8]] + // loongarch64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]] // x86_64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]] // aarch64: [[RUST_ALLOCA:%.+]] = alloca [16 x i8], align [[RUST_ALIGN:8]] @@ -568,12 +556,7 @@ pub fn return_doublefloat() -> DoubleFloat { // CHECK-LABEL: @call_three32s #[no_mangle] pub fn call_three32s() { - // aarch64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]] - // loongarch64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]] - // powerpc64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]] - // sparc64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]] - // x86_64: [[ABI_ALLOCA:%.+]] = alloca [12 x i8], align [[ABI_ALIGN:8]] - + // CHECK: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]] // CHECK: [[RUST_ALLOCA:%.+]] = alloca [12 x i8], align [[RUST_ALIGN:4]] // CHECK: call void @llvm.memcpy.{{.+}}(ptr align [[ABI_ALIGN]] [[ABI_ALLOCA]], ptr align [[RUST_ALIGN]] [[RUST_ALLOCA]], i64 12, i1 false) @@ -600,7 +583,7 @@ pub fn return_three32s() -> Three32s { // aarch64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]] // loongarch64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]] // sparc64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]] - // x86_64: [[ABI_ALLOCA:%.+]] = alloca [12 x i8], align [[ABI_ALIGN:8]] + // x86_64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]] // aarch64: [[ABI_VALUE:%.+]] = call [[ABI_TYPE:\[2 x i64\]]] @returns_three32s() // loongarch64: [[ABI_VALUE:%.+]] = call [[ABI_TYPE:\[2 x i64\]]] @returns_three32s() diff --git a/tests/codegen/cffi/ffi-out-of-bounds-loads.rs b/tests/codegen/cffi/ffi-out-of-bounds-loads.rs index 614d5d94f6208..a4b7c0caa6d46 100644 --- a/tests/codegen/cffi/ffi-out-of-bounds-loads.rs +++ b/tests/codegen/cffi/ffi-out-of-bounds-loads.rs @@ -1,5 +1,5 @@ //@ revisions: linux apple -//@ compile-flags: -C opt-level=0 -C no-prepopulate-passes +//@ compile-flags: -C opt-level=0 -C no-prepopulate-passes -C passes=lint //@[linux] compile-flags: --target x86_64-unknown-linux-gnu //@[linux] needs-llvm-components: x86 @@ -36,7 +36,7 @@ extern "C" { pub fn test() { let s = S { f1: 1, f2: 2, f3: 3 }; unsafe { - // CHECK: [[ALLOCA:%.+]] = alloca [12 x i8], align 8 + // CHECK: [[ALLOCA:%.+]] = alloca [16 x i8], align 8 // CHECK: [[LOAD:%.+]] = load { i64, i32 }, ptr [[ALLOCA]], align 8 // CHECK: call void @foo({ i64, i32 } [[LOAD]]) foo(s); From 2ef82805d52a2f53368a56e8d3c9473f3cd89efc Mon Sep 17 00:00:00 2001 From: DianQK Date: Mon, 1 Jul 2024 13:15:40 +0800 Subject: [PATCH 547/892] Use the aligned size for alloca at ret when the pass mode is cast. --- compiler/rustc_codegen_ssa/src/mir/mod.rs | 18 +++++++++++++---- compiler/rustc_codegen_ssa/src/mir/place.rs | 10 +++++++++- tests/codegen/cast-target-abi.rs | 22 ++++++++++----------- 3 files changed, 34 insertions(+), 16 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/mir/mod.rs b/compiler/rustc_codegen_ssa/src/mir/mod.rs index e8da98428829e..61f57c9030a1a 100644 --- a/compiler/rustc_codegen_ssa/src/mir/mod.rs +++ b/compiler/rustc_codegen_ssa/src/mir/mod.rs @@ -230,10 +230,20 @@ pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( let layout = start_bx.layout_of(fx.monomorphize(decl.ty)); assert!(!layout.ty.has_erasable_regions()); - if local == mir::RETURN_PLACE && fx.fn_abi.ret.is_indirect() { - debug!("alloc: {:?} (return place) -> place", local); - let llretptr = start_bx.get_param(0); - return LocalRef::Place(PlaceRef::new_sized(llretptr, layout)); + if local == mir::RETURN_PLACE { + match fx.fn_abi.ret.mode { + PassMode::Indirect { .. } => { + debug!("alloc: {:?} (return place) -> place", local); + let llretptr = start_bx.get_param(0); + return LocalRef::Place(PlaceRef::new_sized(llretptr, layout)); + } + PassMode::Cast { ref cast, .. } => { + debug!("alloc: {:?} (return place) -> place", local); + let size = cast.size(&start_bx); + return LocalRef::Place(PlaceRef::alloca_size(&mut start_bx, size, layout)); + } + _ => {} + }; } if memory_locals.contains(local) { diff --git a/compiler/rustc_codegen_ssa/src/mir/place.rs b/compiler/rustc_codegen_ssa/src/mir/place.rs index 449fd9ae0db9c..97d5bb8312891 100644 --- a/compiler/rustc_codegen_ssa/src/mir/place.rs +++ b/compiler/rustc_codegen_ssa/src/mir/place.rs @@ -108,9 +108,17 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> { pub fn alloca>( bx: &mut Bx, layout: TyAndLayout<'tcx>, + ) -> Self { + Self::alloca_size(bx, layout.size, layout) + } + + pub fn alloca_size>( + bx: &mut Bx, + size: Size, + layout: TyAndLayout<'tcx>, ) -> Self { assert!(layout.is_sized(), "tried to statically allocate unsized place"); - PlaceValue::alloca(bx, layout.size, layout.align.abi).with_type(layout) + PlaceValue::alloca(bx, size, layout.align.abi).with_type(layout) } /// Returns a place for an indirect reference to an unsized place. diff --git a/tests/codegen/cast-target-abi.rs b/tests/codegen/cast-target-abi.rs index 13b74d68f76e4..34e52d38bbea9 100644 --- a/tests/codegen/cast-target-abi.rs +++ b/tests/codegen/cast-target-abi.rs @@ -102,9 +102,9 @@ pub extern "C" fn returns_twou16s() -> TwoU16s { // powerpc returns this struct via sret pointer, it doesn't use the cast ABI. // The other targets copy the cast ABI type to an alloca. - // aarch64: [[ABI_ALLOCA:%.+]] = alloca [4 x i8], align [[ABI_ALIGN:2]] - // loongarch64: [[ABI_ALLOCA:%.+]] = alloca [4 x i8], align [[ABI_ALIGN:2]] - // sparc64: [[ABI_ALLOCA:%.+]] = alloca [4 x i8], align [[ABI_ALIGN:2]] + // aarch64: [[ABI_ALLOCA:%.+]] = alloca [8 x i8], align [[ABI_ALIGN:2]] + // loongarch64: [[ABI_ALLOCA:%.+]] = alloca [8 x i8], align [[ABI_ALIGN:2]] + // sparc64: [[ABI_ALLOCA:%.+]] = alloca [8 x i8], align [[ABI_ALIGN:2]] // x86_64: [[ABI_ALLOCA:%.+]] = alloca [4 x i8], align [[ABI_ALIGN:2]] // aarch64: [[ABI_VALUE:%.+]] = load [[ABI_TYPE:i64]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] @@ -145,10 +145,10 @@ pub extern "C" fn returns_fiveu16s() -> FiveU16s { // powerpc returns this struct via sret pointer, it doesn't use the cast ABI. // The other targets copy the cast ABI type to an alloca. - // aarch64: [[ABI_ALLOCA:%.+]] = alloca [10 x i8], align [[ABI_ALIGN:2]] - // loongarch64: [[ABI_ALLOCA:%.+]] = alloca [10 x i8], align [[ABI_ALIGN:2]] - // sparc64: [[ABI_ALLOCA:%.+]] = alloca [10 x i8], align [[ABI_ALIGN:2]] - // x86_64: [[ABI_ALLOCA:%.+]] = alloca [10 x i8], align [[ABI_ALIGN:2]] + // aarch64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:2]] + // loongarch64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:2]] + // sparc64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:2]] + // x86_64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:2]] // aarch64: [[ABI_VALUE:%.+]] = load [[ABI_TYPE:\[2 x i64\]]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] // loongarch64: [[ABI_VALUE:%.+]] = load [[ABI_TYPE:\[2 x i64\]]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] @@ -231,10 +231,10 @@ pub extern "C" fn returns_three32s() -> Three32s { // powerpc returns this struct via sret pointer, it doesn't use the cast ABI. // The other targets copy the cast ABI type to an alloca. - // aarch64: [[ABI_ALLOCA:%.+]] = alloca [12 x i8], align [[ABI_ALIGN:4]] - // loongarch64: [[ABI_ALLOCA:%.+]] = alloca [12 x i8], align [[ABI_ALIGN:4]] - // sparc64: [[ABI_ALLOCA:%.+]] = alloca [12 x i8], align [[ABI_ALIGN:4]] - // x86_64: [[ABI_ALLOCA:%.+]] = alloca [12 x i8], align [[ABI_ALIGN:4]] + // aarch64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:4]] + // loongarch64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:4]] + // sparc64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:4]] + // x86_64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:4]] // aarch64: [[ABI_VALUE:%.+]] = load [[ABI_TYPE:\[2 x i64\]]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] // loongarch64: [[ABI_VALUE:%.+]] = load [[ABI_TYPE:\[2 x i64\]]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] From 16fc41cedc5f81a4ecba7bfaa9f408d41ca87f62 Mon Sep 17 00:00:00 2001 From: mat Date: Mon, 1 Jul 2024 22:36:40 +0000 Subject: [PATCH 548/892] Optimize SipHash by reordering compress instructions --- compiler/rustc_data_structures/src/sip128.rs | 11 ++++++----- library/core/src/hash/sip.rs | 11 ++++++----- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_data_structures/src/sip128.rs b/compiler/rustc_data_structures/src/sip128.rs index fed23df10dcf4..812ed410a94b6 100644 --- a/compiler/rustc_data_structures/src/sip128.rs +++ b/compiler/rustc_data_structures/src/sip128.rs @@ -70,18 +70,19 @@ macro_rules! compress { ($state:expr) => {{ compress!($state.v0, $state.v1, $state.v2, $state.v3) }}; ($v0:expr, $v1:expr, $v2:expr, $v3:expr) => {{ $v0 = $v0.wrapping_add($v1); + $v2 = $v2.wrapping_add($v3); $v1 = $v1.rotate_left(13); $v1 ^= $v0; - $v0 = $v0.rotate_left(32); - $v2 = $v2.wrapping_add($v3); $v3 = $v3.rotate_left(16); $v3 ^= $v2; - $v0 = $v0.wrapping_add($v3); - $v3 = $v3.rotate_left(21); - $v3 ^= $v0; + $v0 = $v0.rotate_left(32); + $v2 = $v2.wrapping_add($v1); + $v0 = $v0.wrapping_add($v3); $v1 = $v1.rotate_left(17); $v1 ^= $v2; + $v3 = $v3.rotate_left(21); + $v3 ^= $v0; $v2 = $v2.rotate_left(32); }}; } diff --git a/library/core/src/hash/sip.rs b/library/core/src/hash/sip.rs index 78a232faaf88c..0d1ac64aa56cf 100644 --- a/library/core/src/hash/sip.rs +++ b/library/core/src/hash/sip.rs @@ -76,18 +76,19 @@ macro_rules! compress { ($state:expr) => {{ compress!($state.v0, $state.v1, $state.v2, $state.v3) }}; ($v0:expr, $v1:expr, $v2:expr, $v3:expr) => {{ $v0 = $v0.wrapping_add($v1); + $v2 = $v2.wrapping_add($v3); $v1 = $v1.rotate_left(13); $v1 ^= $v0; - $v0 = $v0.rotate_left(32); - $v2 = $v2.wrapping_add($v3); $v3 = $v3.rotate_left(16); $v3 ^= $v2; - $v0 = $v0.wrapping_add($v3); - $v3 = $v3.rotate_left(21); - $v3 ^= $v0; + $v0 = $v0.rotate_left(32); + $v2 = $v2.wrapping_add($v1); + $v0 = $v0.wrapping_add($v3); $v1 = $v1.rotate_left(17); $v1 ^= $v2; + $v3 = $v3.rotate_left(21); + $v3 ^= $v0; $v2 = $v2.rotate_left(32); }}; } From 06982239a6210cfc7b0b370634c9a9160c9b9dc4 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Sun, 23 Jun 2024 16:58:15 -0700 Subject: [PATCH 549/892] Parenthesize break values containing leading label --- compiler/rustc_ast/src/util/classify.rs | 79 ++++++++++++++++++- .../rustc_ast_pretty/src/pprust/state/expr.rs | 8 +- .../ui/unpretty/expanded-interpolation.stdout | 4 +- 3 files changed, 86 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_ast/src/util/classify.rs b/compiler/rustc_ast/src/util/classify.rs index 4b2544ac47ed8..541b95ea97160 100644 --- a/compiler/rustc_ast/src/util/classify.rs +++ b/compiler/rustc_ast/src/util/classify.rs @@ -1,7 +1,8 @@ //! Routines the parser and pretty-printer use to classify AST nodes. use crate::ast::ExprKind::*; -use crate::{ast, token::Delimiter}; +use crate::ast::{self, MatchKind}; +use crate::token::Delimiter; /// This classification determines whether various syntactic positions break out /// of parsing the current expression (true) or continue parsing more of the @@ -81,6 +82,82 @@ pub fn expr_requires_semi_to_be_stmt(e: &ast::Expr) -> bool { } } +/// Returns whether the leftmost token of the given expression is the label of a +/// labeled loop or block, such as in `'inner: loop { break 'inner 1 } + 1`. +/// +/// Such expressions are not allowed as the value of an unlabeled break. +/// +/// ```ignore (illustrative) +/// 'outer: { +/// break 'inner: loop { break 'inner 1 } + 1; // invalid syntax +/// +/// break 'outer 'inner: loop { break 'inner 1 } + 1; // okay +/// +/// break ('inner: loop { break 'inner 1 } + 1); // okay +/// +/// break ('inner: loop { break 'inner 1 }) + 1; // okay +/// } +/// ``` +pub fn leading_labeled_expr(mut expr: &ast::Expr) -> bool { + loop { + match &expr.kind { + Block(_, label) | ForLoop { label, .. } | Loop(_, label, _) | While(_, _, label) => { + return label.is_some(); + } + + Assign(e, _, _) + | AssignOp(_, e, _) + | Await(e, _) + | Binary(_, e, _) + | Call(e, _) + | Cast(e, _) + | Field(e, _) + | Index(e, _, _) + | Match(e, _, MatchKind::Postfix) + | Range(Some(e), _, _) + | Try(e) => { + expr = e; + } + MethodCall(method_call) => { + expr = &method_call.receiver; + } + + AddrOf(..) + | Array(..) + | Become(..) + | Break(..) + | Closure(..) + | ConstBlock(..) + | Continue(..) + | FormatArgs(..) + | Gen(..) + | If(..) + | IncludedBytes(..) + | InlineAsm(..) + | Let(..) + | Lit(..) + | MacCall(..) + | Match(_, _, MatchKind::Prefix) + | OffsetOf(..) + | Paren(..) + | Path(..) + | Range(None, _, _) + | Repeat(..) + | Ret(..) + | Struct(..) + | TryBlock(..) + | Tup(..) + | Type(..) + | Unary(..) + | Underscore + | Yeet(..) + | Yield(..) + | Err(..) + | Dummy => return false, + } + } +} + pub enum TrailingBrace<'a> { /// Trailing brace in a macro call, like the one in `x as *const brace! {}`. /// We will suggest changing the macro call to a different delimiter. diff --git a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs index 1e117c46b6e29..86b6b0e219928 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs @@ -5,6 +5,7 @@ use ast::{ForLoopKind, MatchKind}; use itertools::{Itertools, Position}; use rustc_ast::ptr::P; use rustc_ast::token; +use rustc_ast::util::classify; use rustc_ast::util::literal::escape_byte_str_symbol; use rustc_ast::util::parser::{self, AssocOp, Fixity}; use rustc_ast::{self as ast, BlockCheckMode}; @@ -610,9 +611,12 @@ impl<'a> State<'a> { } if let Some(expr) = opt_expr { self.space(); - self.print_expr_maybe_paren( + self.print_expr_cond_paren( expr, - parser::PREC_JUMP, + // Parenthesize if required by precedence, or in the + // case of `break 'inner: loop { break 'inner 1 } + 1` + expr.precedence().order() < parser::PREC_JUMP + || (opt_label.is_none() && classify::leading_labeled_expr(expr)), fixup.subsequent_subexpression(), ); } diff --git a/tests/ui/unpretty/expanded-interpolation.stdout b/tests/ui/unpretty/expanded-interpolation.stdout index ed075c9114ce6..556e57dbd9210 100644 --- a/tests/ui/unpretty/expanded-interpolation.stdout +++ b/tests/ui/unpretty/expanded-interpolation.stdout @@ -25,12 +25,12 @@ fn break_labeled_loop() { 'outer: loop { break 'outer 'inner: loop { break 'inner 1; } + 1; }; let paren_around_break_value = - 'outer: loop { break 'inner: loop { break 'inner 1; } + 1; }; + 'outer: loop { break ('inner: loop { break 'inner 1; } + 1); }; macro_rules! breaking { ($value:expr) => { break $value }; } let paren_around_break_value = - loop { break 'inner: loop { break 'inner 1; } + 1; }; + loop { break ('inner: loop { break 'inner 1; } + 1); }; } fn if_let() { From 1680b791d57013ca2cf5839a279e3d4d826c336c Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 27 Jun 2024 10:33:46 +1000 Subject: [PATCH 550/892] Simplify `CfgEval`. It can contain an owned value instead of a reference. --- compiler/rustc_builtin_macros/src/cfg_eval.rs | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_builtin_macros/src/cfg_eval.rs b/compiler/rustc_builtin_macros/src/cfg_eval.rs index 03aff6f96330e..884cebf1939e4 100644 --- a/compiler/rustc_builtin_macros/src/cfg_eval.rs +++ b/compiler/rustc_builtin_macros/src/cfg_eval.rs @@ -38,16 +38,14 @@ pub(crate) fn cfg_eval( lint_node_id: NodeId, ) -> Annotatable { let features = Some(features); - CfgEval { cfg: &mut StripUnconfigured { sess, features, config_tokens: true, lint_node_id } } + CfgEval(StripUnconfigured { sess, features, config_tokens: true, lint_node_id }) .configure_annotatable(annotatable) // Since the item itself has already been configured by the `InvocationCollector`, // we know that fold result vector will contain exactly one element. .unwrap() } -struct CfgEval<'a, 'b> { - cfg: &'a mut StripUnconfigured<'b>, -} +struct CfgEval<'a>(StripUnconfigured<'a>); fn flat_map_annotatable( vis: &mut impl MutVisitor, @@ -125,9 +123,9 @@ fn has_cfg_or_cfg_attr(annotatable: &Annotatable) -> bool { res.is_break() } -impl CfgEval<'_, '_> { +impl CfgEval<'_> { fn configure(&mut self, node: T) -> Option { - self.cfg.configure(node) + self.0.configure(node) } fn configure_annotatable(&mut self, mut annotatable: Annotatable) -> Option { @@ -196,7 +194,7 @@ impl CfgEval<'_, '_> { // Re-parse the tokens, setting the `capture_cfg` flag to save extra information // to the captured `AttrTokenStream` (specifically, we capture // `AttrTokenTree::AttributesData` for all occurrences of `#[cfg]` and `#[cfg_attr]`) - let mut parser = Parser::new(&self.cfg.sess.psess, orig_tokens, None); + let mut parser = Parser::new(&self.0.sess.psess, orig_tokens, None); parser.capture_cfg = true; match parse_annotatable_with(&mut parser) { Ok(a) => annotatable = a, @@ -212,16 +210,16 @@ impl CfgEval<'_, '_> { } } -impl MutVisitor for CfgEval<'_, '_> { +impl MutVisitor for CfgEval<'_> { #[instrument(level = "trace", skip(self))] fn visit_expr(&mut self, expr: &mut P) { - self.cfg.configure_expr(expr, false); + self.0.configure_expr(expr, false); mut_visit::noop_visit_expr(expr, self); } #[instrument(level = "trace", skip(self))] fn visit_method_receiver_expr(&mut self, expr: &mut P) { - self.cfg.configure_expr(expr, true); + self.0.configure_expr(expr, true); mut_visit::noop_visit_expr(expr, self); } From d6c0b8117e4ccccd83c4a6e70eee8b12c51d1a18 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 27 Jun 2024 10:34:05 +1000 Subject: [PATCH 551/892] Fix a typo in a comment. --- compiler/rustc_parse/src/parser/attr_wrapper.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_parse/src/parser/attr_wrapper.rs b/compiler/rustc_parse/src/parser/attr_wrapper.rs index b5480b6b7d210..4b1531c5ff3e4 100644 --- a/compiler/rustc_parse/src/parser/attr_wrapper.rs +++ b/compiler/rustc_parse/src/parser/attr_wrapper.rs @@ -340,7 +340,7 @@ impl<'a> Parser<'a> { // If we support tokens at all if let Some(target_tokens) = ret.tokens_mut() { if target_tokens.is_none() { - // Store se our newly captured tokens into the AST node + // Store our newly captured tokens into the AST node. *target_tokens = Some(tokens.clone()); } } From f852568fa601171f20f924a50478c33fd2661fba Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 27 Jun 2024 10:42:46 +1000 Subject: [PATCH 552/892] Change `AttrTokenStream::to_tokenstream` to `to_token_trees`. I.e. change the return type from `TokenStream` to `Vec`. Most of the callsites require a `TokenStream`, but the recursive call used to create `target_tokens` requires a `Vec`. It's easy to convert a `Vec` to a `TokenStream` (just call `TokenStream::new`) but it's harder to convert a `TokenStream` to a `Vec` (either iterate/clone/collect, or use `Lrc::into_inner` if appropriate). So this commit changes the return value to simplify that `target_tokens` call site. --- compiler/rustc_ast/src/attr/mod.rs | 14 ++++++++------ compiler/rustc_ast/src/tokenstream.rs | 23 +++++++---------------- 2 files changed, 15 insertions(+), 22 deletions(-) diff --git a/compiler/rustc_ast/src/attr/mod.rs b/compiler/rustc_ast/src/attr/mod.rs index 593c78df3cdb8..65f1b5dbaf5b7 100644 --- a/compiler/rustc_ast/src/attr/mod.rs +++ b/compiler/rustc_ast/src/attr/mod.rs @@ -204,12 +204,14 @@ impl Attribute { pub fn tokens(&self) -> TokenStream { match &self.kind { - AttrKind::Normal(normal) => normal - .tokens - .as_ref() - .unwrap_or_else(|| panic!("attribute is missing tokens: {self:?}")) - .to_attr_token_stream() - .to_tokenstream(), + AttrKind::Normal(normal) => TokenStream::new( + normal + .tokens + .as_ref() + .unwrap_or_else(|| panic!("attribute is missing tokens: {self:?}")) + .to_attr_token_stream() + .to_token_trees(), + ), &AttrKind::DocComment(comment_kind, data) => TokenStream::token_alone( token::DocComment(comment_kind, self.style, data), self.span, diff --git a/compiler/rustc_ast/src/tokenstream.rs b/compiler/rustc_ast/src/tokenstream.rs index b4ddbe20689e2..5b2d673316a52 100644 --- a/compiler/rustc_ast/src/tokenstream.rs +++ b/compiler/rustc_ast/src/tokenstream.rs @@ -180,14 +180,13 @@ impl AttrTokenStream { AttrTokenStream(Lrc::new(tokens)) } - /// Converts this `AttrTokenStream` to a plain `TokenStream`. + /// Converts this `AttrTokenStream` to a plain `Vec`. /// During conversion, `AttrTokenTree::Attributes` get 'flattened' /// back to a `TokenStream` of the form `outer_attr attr_target`. /// If there are inner attributes, they are inserted into the proper /// place in the attribute target tokens. - pub fn to_tokenstream(&self) -> TokenStream { - let trees: Vec<_> = self - .0 + pub fn to_token_trees(&self) -> Vec { + self.0 .iter() .flat_map(|tree| match &tree { AttrTokenTree::Token(inner, spacing) => { @@ -198,7 +197,7 @@ impl AttrTokenStream { *span, *spacing, *delim, - stream.to_tokenstream() + TokenStream::new(stream.to_token_trees()) ),] .into_iter() } @@ -208,14 +207,7 @@ impl AttrTokenStream { .partition_point(|attr| matches!(attr.style, crate::AttrStyle::Outer)); let (outer_attrs, inner_attrs) = data.attrs.split_at(idx); - let mut target_tokens: Vec<_> = data - .tokens - .to_attr_token_stream() - .to_tokenstream() - .0 - .iter() - .cloned() - .collect(); + let mut target_tokens = data.tokens.to_attr_token_stream().to_token_trees(); if !inner_attrs.is_empty() { let mut found = false; // Check the last two trees (to account for a trailing semi) @@ -260,8 +252,7 @@ impl AttrTokenStream { flat.into_iter() } }) - .collect(); - TokenStream::new(trees) + .collect() } } @@ -461,7 +452,7 @@ impl TokenStream { AttributesData { attrs: attrs.iter().cloned().collect(), tokens: tokens.clone() }; AttrTokenStream::new(vec![AttrTokenTree::Attributes(attr_data)]) }; - attr_stream.to_tokenstream() + TokenStream::new(attr_stream.to_token_trees()) } pub fn from_nonterminal_ast(nt: &Nonterminal) -> TokenStream { From 0cfd2473be4a5555018cfbca089a7ed1bfd16c53 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 27 Jun 2024 10:49:12 +1000 Subject: [PATCH 553/892] Rename `TokenStream::new` argument. `tts` is a better name than `streams` for a `Vec`. --- compiler/rustc_ast/src/tokenstream.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_ast/src/tokenstream.rs b/compiler/rustc_ast/src/tokenstream.rs index 5b2d673316a52..cabf18fd1530a 100644 --- a/compiler/rustc_ast/src/tokenstream.rs +++ b/compiler/rustc_ast/src/tokenstream.rs @@ -400,8 +400,8 @@ impl PartialEq for TokenStream { } impl TokenStream { - pub fn new(streams: Vec) -> TokenStream { - TokenStream(Lrc::new(streams)) + pub fn new(tts: Vec) -> TokenStream { + TokenStream(Lrc::new(tts)) } pub fn is_empty(&self) -> bool { From 7416c20cfd781de5608494d67975be94e8689c24 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 27 Jun 2024 11:15:38 +1000 Subject: [PATCH 554/892] Just `push` in `AttrTokenStream::to_token_trees`. Currently it uses a mixture of functional style (`flat_map`) and imperative style (`push`), which is a bit hard to read. This commit converts it to fully imperative, which is more concise and avoids the need for `smallvec`. --- compiler/rustc_ast/src/tokenstream.rs | 28 ++++++++++++--------------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/compiler/rustc_ast/src/tokenstream.rs b/compiler/rustc_ast/src/tokenstream.rs index cabf18fd1530a..655c18e45597a 100644 --- a/compiler/rustc_ast/src/tokenstream.rs +++ b/compiler/rustc_ast/src/tokenstream.rs @@ -23,7 +23,6 @@ use rustc_data_structures::sync::{self, Lrc}; use rustc_macros::{Decodable, Encodable, HashStable_Generic}; use rustc_serialize::{Decodable, Encodable}; use rustc_span::{sym, Span, SpanDecoder, SpanEncoder, Symbol, DUMMY_SP}; -use smallvec::{smallvec, SmallVec}; use std::borrow::Cow; use std::{cmp, fmt, iter}; @@ -186,20 +185,19 @@ impl AttrTokenStream { /// If there are inner attributes, they are inserted into the proper /// place in the attribute target tokens. pub fn to_token_trees(&self) -> Vec { - self.0 - .iter() - .flat_map(|tree| match &tree { + let mut res = Vec::with_capacity(self.0.len()); + for tree in self.0.iter() { + match tree { AttrTokenTree::Token(inner, spacing) => { - smallvec![TokenTree::Token(inner.clone(), *spacing)].into_iter() + res.push(TokenTree::Token(inner.clone(), *spacing)); } AttrTokenTree::Delimited(span, spacing, delim, stream) => { - smallvec![TokenTree::Delimited( + res.push(TokenTree::Delimited( *span, *spacing, *delim, - TokenStream::new(stream.to_token_trees()) - ),] - .into_iter() + TokenStream::new(stream.to_token_trees()), + )) } AttrTokenTree::Attributes(data) => { let idx = data @@ -243,16 +241,14 @@ impl AttrTokenStream { "Failed to find trailing delimited group in: {target_tokens:?}" ); } - let mut flat: SmallVec<[_; 1]> = - SmallVec::with_capacity(target_tokens.len() + outer_attrs.len()); for attr in outer_attrs { - flat.extend(attr.tokens().0.iter().cloned()); + res.extend(attr.tokens().0.iter().cloned()); } - flat.extend(target_tokens); - flat.into_iter() + res.extend(target_tokens); } - }) - .collect() + } + } + res } } From 36c30a968b60a2926a0f600feb78eaba618d8d9a Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Mon, 1 Jul 2024 14:32:47 +1000 Subject: [PATCH 555/892] Fix comment. Both the indenting, and the missing `)`. --- compiler/rustc_parse/src/parser/attr_wrapper.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_parse/src/parser/attr_wrapper.rs b/compiler/rustc_parse/src/parser/attr_wrapper.rs index 4b1531c5ff3e4..a5aaa9f052208 100644 --- a/compiler/rustc_parse/src/parser/attr_wrapper.rs +++ b/compiler/rustc_parse/src/parser/attr_wrapper.rs @@ -233,9 +233,9 @@ impl<'a> Parser<'a> { // 1. Our target doesn't support tokens at all (e.g we're parsing an `NtIdent`) // so there's nothing for us to do. // 2. Our target already has tokens set (e.g. we've parsed something - // like `#[my_attr] $item`. The actual parsing code takes care of prepending - // any attributes to the nonterminal, so we don't need to modify the - // already captured tokens. + // like `#[my_attr] $item`). The actual parsing code takes care of + // prepending any attributes to the nonterminal, so we don't need to + // modify the already captured tokens. // Note that this check is independent of `force_collect`- if we already // have tokens, or can't even store them, then there's never a need to // force collection of new tokens. From 2342770f49dcc7e98069efb2db3620d4803c7698 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Mon, 1 Jul 2024 16:50:06 +1000 Subject: [PATCH 556/892] Flip an if/else in `AttrTokenStream::to_attr_token_stream`. To put the simple case first. --- compiler/rustc_parse/src/parser/attr_wrapper.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_parse/src/parser/attr_wrapper.rs b/compiler/rustc_parse/src/parser/attr_wrapper.rs index a5aaa9f052208..244a4f26fba85 100644 --- a/compiler/rustc_parse/src/parser/attr_wrapper.rs +++ b/compiler/rustc_parse/src/parser/attr_wrapper.rs @@ -112,7 +112,9 @@ impl ToAttrTokenStream for LazyAttrTokenStreamImpl { })) .take(self.num_calls); - if !self.replace_ranges.is_empty() { + if self.replace_ranges.is_empty() { + make_token_stream(tokens, self.break_last_token) + } else { let mut tokens: Vec<_> = tokens.collect(); let mut replace_ranges = self.replace_ranges.to_vec(); replace_ranges.sort_by_key(|(range, _)| range.start); @@ -165,8 +167,6 @@ impl ToAttrTokenStream for LazyAttrTokenStreamImpl { ); } make_token_stream(tokens.into_iter(), self.break_last_token) - } else { - make_token_stream(tokens, self.break_last_token) } } } From 8b5a7eb7f4840dcc27e1dcf4a0e102a417ad988f Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Mon, 1 Jul 2024 16:12:22 +1000 Subject: [PATCH 557/892] Move things around in `collect_tokens_trailing_token`. So that the `capturing` state is adjusted immediately before and after the call to `f`. --- compiler/rustc_parse/src/parser/attr_wrapper.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_parse/src/parser/attr_wrapper.rs b/compiler/rustc_parse/src/parser/attr_wrapper.rs index 244a4f26fba85..7c22cac350b02 100644 --- a/compiler/rustc_parse/src/parser/attr_wrapper.rs +++ b/compiler/rustc_parse/src/parser/attr_wrapper.rs @@ -218,16 +218,16 @@ impl<'a> Parser<'a> { let start_token = (self.token.clone(), self.token_spacing); let cursor_snapshot = self.token_cursor.clone(); let start_pos = self.num_bump_calls; - let has_outer_attrs = !attrs.attrs.is_empty(); - let prev_capturing = std::mem::replace(&mut self.capture_state.capturing, Capturing::Yes); let replace_ranges_start = self.capture_state.replace_ranges.len(); - let ret = f(self, attrs.attrs); - - self.capture_state.capturing = prev_capturing; - - let (mut ret, trailing) = ret?; + let (mut ret, trailing) = { + let prev_capturing = + std::mem::replace(&mut self.capture_state.capturing, Capturing::Yes); + let ret_and_trailing = f(self, attrs.attrs); + self.capture_state.capturing = prev_capturing; + ret_and_trailing? + }; // When we're not in `capture-cfg` mode, then bail out early if: // 1. Our target doesn't support tokens at all (e.g we're parsing an `NtIdent`) From f5b28968db07c96d1e2fe239d380fe5a418e85c5 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Mon, 1 Jul 2024 16:21:47 +1000 Subject: [PATCH 558/892] Move more things around in `collect_tokens_trailing_token`. To make things a little clearer, and to avoid some `mut` variables. --- .../rustc_parse/src/parser/attr_wrapper.rs | 41 ++++++++----------- 1 file changed, 18 insertions(+), 23 deletions(-) diff --git a/compiler/rustc_parse/src/parser/attr_wrapper.rs b/compiler/rustc_parse/src/parser/attr_wrapper.rs index 7c22cac350b02..10feccd21e286 100644 --- a/compiler/rustc_parse/src/parser/attr_wrapper.rs +++ b/compiler/rustc_parse/src/parser/attr_wrapper.rs @@ -276,37 +276,32 @@ impl<'a> Parser<'a> { let replace_ranges_end = self.capture_state.replace_ranges.len(); - let mut end_pos = self.num_bump_calls; - - let mut captured_trailing = false; - // Capture a trailing token if requested by the callback 'f' - match trailing { - TrailingToken::None => {} + let captured_trailing = match trailing { + TrailingToken::None => false, TrailingToken::Gt => { assert_eq!(self.token.kind, token::Gt); + false } TrailingToken::Semi => { assert_eq!(self.token.kind, token::Semi); - end_pos += 1; - captured_trailing = true; + true } - TrailingToken::MaybeComma => { - if self.token.kind == token::Comma { - end_pos += 1; - captured_trailing = true; - } - } - } + TrailingToken::MaybeComma => self.token.kind == token::Comma, + }; - // If we 'broke' the last token (e.g. breaking a '>>' token to two '>' tokens), - // then extend the range of captured tokens to include it, since the parser - // was not actually bumped past it. When the `LazyAttrTokenStream` gets converted - // into an `AttrTokenStream`, we will create the proper token. - if self.break_last_token { - assert!(!captured_trailing, "Cannot set break_last_token and have trailing token"); - end_pos += 1; - } + assert!( + !(self.break_last_token && captured_trailing), + "Cannot set break_last_token and have trailing token" + ); + + let end_pos = self.num_bump_calls + + captured_trailing as usize + // If we 'broke' the last token (e.g. breaking a '>>' token to two '>' tokens), then + // extend the range of captured tokens to include it, since the parser was not actually + // bumped past it. When the `LazyAttrTokenStream` gets converted into an + // `AttrTokenStream`, we will create the proper token. + + self.break_last_token as usize; let num_calls = end_pos - start_pos; From ada9fda7c38b1be39b4e8273ee6af150985df064 Mon Sep 17 00:00:00 2001 From: hattizai Date: Tue, 2 Jul 2024 11:25:31 +0800 Subject: [PATCH 559/892] chore: remove duplicate words --- compiler/rustc_codegen_ssa/src/mir/block.rs | 2 +- compiler/rustc_const_eval/src/interpret/discriminant.rs | 2 +- compiler/rustc_hir_typeck/src/method/suggest.rs | 4 ++-- compiler/rustc_middle/src/ty/closure.rs | 2 +- compiler/rustc_mir_build/src/build/expr/as_place.rs | 2 +- compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs | 2 +- compiler/rustc_mir_transform/src/gvn.rs | 2 +- compiler/rustc_mir_transform/src/lib.rs | 2 +- compiler/rustc_mir_transform/src/promote_consts.rs | 2 +- compiler/rustc_passes/src/dead.rs | 2 +- compiler/rustc_serialize/src/opaque.rs | 2 +- .../src/traits/error_reporting/suggestions.rs | 2 +- .../src/traits/error_reporting/type_err_ctxt_ext.rs | 2 +- library/core/src/clone.rs | 2 +- library/core/src/iter/adapters/mod.rs | 2 +- library/core/src/num/dec2flt/lemire.rs | 2 +- library/std/src/io/error/repr_bitpacked.rs | 2 +- library/std/src/sys/pal/unix/args.rs | 2 +- library/std/src/sys/pal/windows/alloc.rs | 2 +- src/tools/clippy/clippy_lints/src/empty_with_brackets.rs | 4 ++-- src/tools/clippy/clippy_lints/src/non_copy_const.rs | 2 +- .../2229_closure_analysis/migrations/precise_no_migrations.rs | 4 ++-- .../116464-invalid-assoc-type-suggestion-in-trait-impl.rs | 2 +- 23 files changed, 26 insertions(+), 26 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index b1c22faf1ae9d..a26359942a614 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -403,7 +403,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { // // Why only in unoptimized builds? // - In unoptimized builds LLVM uses FastISel which does not support switches, so it - // must fall back to the to the slower SelectionDAG isel. Therefore, using `br` gives + // must fall back to the slower SelectionDAG isel. Therefore, using `br` gives // significant compile time speedups for unoptimized builds. // - In optimized builds the above doesn't hold, and using `br` sometimes results in // worse generated code because LLVM can no longer tell that the value being switched diff --git a/compiler/rustc_const_eval/src/interpret/discriminant.rs b/compiler/rustc_const_eval/src/interpret/discriminant.rs index b3a139d553ade..181c71153866c 100644 --- a/compiler/rustc_const_eval/src/interpret/discriminant.rs +++ b/compiler/rustc_const_eval/src/interpret/discriminant.rs @@ -245,7 +245,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { // The tag of a `Single` enum is like the tag of the niched // variant: there's no tag as the discriminant is encoded // entirely implicitly. If `write_discriminant` ever hits this - // case, we do a "validation read" to ensure the the right + // case, we do a "validation read" to ensure the right // discriminant is encoded implicitly, so any attempt to write // the wrong discriminant for a `Single` enum will reliably // result in UB. diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index e310730bf9e91..72efe86b84170 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -499,7 +499,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } - // If the shadowed binding has an an itializer expression, + // If the shadowed binding has an itializer expression, // use the initializer expression'ty to try to find the method again. // For example like: `let mut x = Vec::new();`, // `Vec::new()` is the itializer expression. @@ -968,7 +968,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } // Make sure that, if any traits other than the found ones were involved, - // we don't don't report an unimplemented trait. + // we don't report an unimplemented trait. // We don't want to say that `iter::Cloned` is not an iterator, just // because of some non-Clone item being iterated over. for (predicate, _parent_pred, _cause) in unsatisfied_predicates { diff --git a/compiler/rustc_middle/src/ty/closure.rs b/compiler/rustc_middle/src/ty/closure.rs index bade0d564156f..bdd9a6bab2bee 100644 --- a/compiler/rustc_middle/src/ty/closure.rs +++ b/compiler/rustc_middle/src/ty/closure.rs @@ -237,7 +237,7 @@ impl<'tcx> TyCtxt<'tcx> { /// Eg: 1. `foo.x` which is represented using `projections=[Field(x)]` is an ancestor of /// `foo.x.y` which is represented using `projections=[Field(x), Field(y)]`. /// Note both `foo.x` and `foo.x.y` start off of the same root variable `foo`. -/// 2. Since we only look at the projections here function will return `bar.x` as an a valid +/// 2. Since we only look at the projections here function will return `bar.x` as a valid /// ancestor of `foo.x.y`. It's the caller's responsibility to ensure that both projections /// list are being applied to the same root variable. pub fn is_ancestor_or_same_capture( diff --git a/compiler/rustc_mir_build/src/build/expr/as_place.rs b/compiler/rustc_mir_build/src/build/expr/as_place.rs index 4b62afa61bbd5..91a3b53cc79c7 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_place.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_place.rs @@ -130,7 +130,7 @@ fn convert_to_hir_projections_and_truncate_for_capture( /// Eg: 1. `foo.x` which is represented using `projections=[Field(x)]` is an ancestor of /// `foo.x.y` which is represented using `projections=[Field(x), Field(y)]`. /// Note both `foo.x` and `foo.x.y` start off of the same root variable `foo`. -/// 2. Since we only look at the projections here function will return `bar.x` as an a valid +/// 2. Since we only look at the projections here function will return `bar.x` as a valid /// ancestor of `foo.x.y`. It's the caller's responsibility to ensure that both projections /// list are being applied to the same root variable. fn is_ancestor_or_same_capture( diff --git a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs index 8c6c9e10cdfdc..5745dc0969cce 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs @@ -138,7 +138,7 @@ impl<'tcx> ConstToPat<'tcx> { // lints, but no errors), double-check that all types in the const implement // `PartialEq`. Even if we have a valtree, we may have found something // in there with non-structural-equality, meaning we match using `PartialEq` - // and we hence have to check that that impl exists. + // and we hence have to check if that impl exists. // This is all messy but not worth cleaning up: at some point we'll emit // a hard error when we don't have a valtree or when we find something in // the valtree that is not structural; then this can all be made a lot simpler. diff --git a/compiler/rustc_mir_transform/src/gvn.rs b/compiler/rustc_mir_transform/src/gvn.rs index 3dbdeb615cfe2..2b7d9be6d350b 100644 --- a/compiler/rustc_mir_transform/src/gvn.rs +++ b/compiler/rustc_mir_transform/src/gvn.rs @@ -8,7 +8,7 @@ //! `Value` is interned as a `VnIndex`, which allows us to cheaply compute identical values. //! //! From those assignments, we construct a mapping `VnIndex -> Vec<(Local, Location)>` of available -//! values, the locals in which they are stored, and a the assignment location. +//! values, the locals in which they are stored, and the assignment location. //! //! In a second pass, we traverse all (non SSA) assignments `x = rvalue` and operands. For each //! one, we compute the `VnIndex` of the rvalue. If this `VnIndex` is associated to a constant, we diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index f7056702cb4ed..5d253d7384df4 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -519,7 +519,7 @@ fn run_runtime_lowering_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { &add_subtyping_projections::Subtyper, // calling this after reveal_all ensures that we don't deal with opaque types &elaborate_drops::ElaborateDrops, // This will remove extraneous landing pads which are no longer - // necessary as well as well as forcing any call in a non-unwinding + // necessary as well as forcing any call in a non-unwinding // function calling a possibly-unwinding function to abort the process. &abort_unwinding_calls::AbortUnwindingCalls, // AddMovesForPackedDrops needs to run after drop diff --git a/compiler/rustc_mir_transform/src/promote_consts.rs b/compiler/rustc_mir_transform/src/promote_consts.rs index 3f4d2b65ff240..736647fb64b12 100644 --- a/compiler/rustc_mir_transform/src/promote_consts.rs +++ b/compiler/rustc_mir_transform/src/promote_consts.rs @@ -816,7 +816,7 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> { mut func, mut args, call_source: desugar, fn_span, .. } => { // This promoted involves a function call, so it may fail to evaluate. - // Let's make sure it is added to `required_consts` so that that failure cannot get lost. + // Let's make sure it is added to `required_consts` so that failure cannot get lost. self.add_to_required = true; self.visit_operand(&mut func, loc); diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs index bbd586386dd27..6ea0ed339a66e 100644 --- a/compiler/rustc_passes/src/dead.rs +++ b/compiler/rustc_passes/src/dead.rs @@ -102,7 +102,7 @@ fn ty_ref_to_pub_struct(tcx: TyCtxt<'_>, ty: &hir::Ty<'_>) -> Publicness { Publicness::new(true, true) } -/// Determine if a work from the worklist is coming from the a `#[allow]` +/// Determine if a work from the worklist is coming from a `#[allow]` /// or a `#[expect]` of `dead_code` #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] enum ComesFromAllowExpect { diff --git a/compiler/rustc_serialize/src/opaque.rs b/compiler/rustc_serialize/src/opaque.rs index 1dcb69920d73e..d27dfd888245b 100644 --- a/compiler/rustc_serialize/src/opaque.rs +++ b/compiler/rustc_serialize/src/opaque.rs @@ -155,7 +155,7 @@ impl FileEncoder { if std::intrinsics::unlikely(self.buffered > flush_threshold) { self.flush(); } - // SAFETY: We checked above that that N < self.buffer_empty().len(), + // SAFETY: We checked above that N < self.buffer_empty().len(), // and if isn't, flush ensures that our empty buffer is now BUF_SIZE. // We produce a post-mono error if N > BUF_SIZE. let buf = unsafe { self.buffer_empty().first_chunk_mut::().unwrap_unchecked() }; diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index ccf86dbb1d0b6..a0a8e5963f109 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -4114,7 +4114,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { expr = binding_expr; } if let hir::Node::Param(param) = parent { - // ...and it is a an fn argument. + // ...and it is an fn argument. let prev_ty = self.resolve_vars_if_possible( typeck_results .node_type_opt(param.hir_id) diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs index adf1076a7c90e..3e316b7845439 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs @@ -1296,7 +1296,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { expr = binding_expr; } if let hir::Node::Param(_param) = parent { - // ...and it is a an fn argument. + // ...and it is an fn argument. break; } } diff --git a/library/core/src/clone.rs b/library/core/src/clone.rs index d7ce65f6c53a9..939b2be6dfaf1 100644 --- a/library/core/src/clone.rs +++ b/library/core/src/clone.rs @@ -230,7 +230,7 @@ pub struct AssertParamIsCopy { pub unsafe trait CloneToUninit { /// Performs copy-assignment from `self` to `dst`. /// - /// This is analogous to to `std::ptr::write(dst, self.clone())`, + /// This is analogous to `std::ptr::write(dst, self.clone())`, /// except that `self` may be a dynamically-sized type ([`!Sized`](Sized)). /// /// Before this function is called, `dst` may point to uninitialized memory. diff --git a/library/core/src/iter/adapters/mod.rs b/library/core/src/iter/adapters/mod.rs index 05a5f2689056b..1bde4488cc9de 100644 --- a/library/core/src/iter/adapters/mod.rs +++ b/library/core/src/iter/adapters/mod.rs @@ -159,7 +159,7 @@ pub(crate) struct GenericShunt<'a, I, R> { residual: &'a mut Option, } -/// Process the given iterator as if it yielded a the item's `Try::Output` +/// Process the given iterator as if it yielded the item's `Try::Output` /// type instead. Any `Try::Residual`s encountered will stop the inner iterator /// and be propagated back to the overall result. pub(crate) fn try_process(iter: I, mut f: F) -> ChangeOutputType diff --git a/library/core/src/num/dec2flt/lemire.rs b/library/core/src/num/dec2flt/lemire.rs index 3bc052df7a6c1..01642e1b1112a 100644 --- a/library/core/src/num/dec2flt/lemire.rs +++ b/library/core/src/num/dec2flt/lemire.rs @@ -157,7 +157,7 @@ fn compute_product_approx(q: i64, w: u64, precision: usize) -> (u64, u64) { // Need to do a second multiplication to get better precision // for the lower product. This will always be exact // where q is < 55, since 5^55 < 2^128. If this wraps, - // then we need to need to round up the hi product. + // then we need to round up the hi product. let (_, second_hi) = full_multiplication(w, hi5); first_lo = first_lo.wrapping_add(second_hi); if second_hi > first_lo { diff --git a/library/std/src/io/error/repr_bitpacked.rs b/library/std/src/io/error/repr_bitpacked.rs index c9d3934ad70ce..a5cefe2292be4 100644 --- a/library/std/src/io/error/repr_bitpacked.rs +++ b/library/std/src/io/error/repr_bitpacked.rs @@ -28,7 +28,7 @@ //! //! # Layout //! Tagged values are 64 bits, with the 2 least significant bits used for the -//! tag. This means there are there are 4 "variants": +//! tag. This means there are 4 "variants": //! //! - **Tag 0b00**: The first variant is equivalent to //! `ErrorData::SimpleMessage`, and holds a `&'static SimpleMessage` directly. diff --git a/library/std/src/sys/pal/unix/args.rs b/library/std/src/sys/pal/unix/args.rs index db2ec73148e38..e2ec838b740cb 100644 --- a/library/std/src/sys/pal/unix/args.rs +++ b/library/std/src/sys/pal/unix/args.rs @@ -183,7 +183,7 @@ mod imp { // Use `_NSGetArgc` and `_NSGetArgv` on Apple platforms. // // Even though these have underscores in their names, they've been available -// since since the first versions of both macOS and iOS, and are declared in +// since the first versions of both macOS and iOS, and are declared in // the header `crt_externs.h`. // // NOTE: This header was added to the iOS 13.0 SDK, which has been the source diff --git a/library/std/src/sys/pal/windows/alloc.rs b/library/std/src/sys/pal/windows/alloc.rs index 681d1a5efe932..24c237b5eb03d 100644 --- a/library/std/src/sys/pal/windows/alloc.rs +++ b/library/std/src/sys/pal/windows/alloc.rs @@ -190,7 +190,7 @@ unsafe fn allocate(layout: Layout, zeroed: bool) -> *mut u8 { // it, it is safe to write a header directly before it. unsafe { ptr::write((aligned as *mut Header).sub(1), Header(ptr)) }; - // SAFETY: The returned pointer does not point to the to the start of an allocated block, + // SAFETY: The returned pointer does not point to the start of an allocated block, // but there is a header readable directly before it containing the location of the start // of the block. aligned diff --git a/src/tools/clippy/clippy_lints/src/empty_with_brackets.rs b/src/tools/clippy/clippy_lints/src/empty_with_brackets.rs index 745599b0e57a2..743ec5b9ea7fb 100644 --- a/src/tools/clippy/clippy_lints/src/empty_with_brackets.rs +++ b/src/tools/clippy/clippy_lints/src/empty_with_brackets.rs @@ -16,7 +16,7 @@ declare_clippy_lint! { /// and it may be desirable to do so consistently for style. /// /// However, removing the brackets also introduces a public constant named after the struct, - /// so this is not just a syntactic simplification but an an API change, and adding them back + /// so this is not just a syntactic simplification but an API change, and adding them back /// is a *breaking* API change. /// /// ### Example @@ -44,7 +44,7 @@ declare_clippy_lint! { /// and it may be desirable to do so consistently for style. /// /// However, removing the brackets also introduces a public constant named after the variant, - /// so this is not just a syntactic simplification but an an API change, and adding them back + /// so this is not just a syntactic simplification but an API change, and adding them back /// is a *breaking* API change. /// /// ### Example diff --git a/src/tools/clippy/clippy_lints/src/non_copy_const.rs b/src/tools/clippy/clippy_lints/src/non_copy_const.rs index 5cb8e7bfab2a9..964d199bfcb69 100644 --- a/src/tools/clippy/clippy_lints/src/non_copy_const.rs +++ b/src/tools/clippy/clippy_lints/src/non_copy_const.rs @@ -258,7 +258,7 @@ impl<'tcx> NonCopyConst<'tcx> { // e.g. implementing `has_frozen_variant` described above, and not running this function // when the type doesn't have any frozen variants would be the 'correct' way for the 2nd // case (that actually removes another suboptimal behavior (I won't say 'false positive') where, - // similar to 2., but with the a frozen variant) (e.g. borrowing + // similar to 2., but with a frozen variant) (e.g. borrowing // `borrow_interior_mutable_const::enums::AssocConsts::TO_BE_FROZEN_VARIANT`). // I chose this way because unfrozen enums as assoc consts are rare (or, hopefully, none). matches!(err, ErrorHandled::TooGeneric(..)) diff --git a/tests/ui/closures/2229_closure_analysis/migrations/precise_no_migrations.rs b/tests/ui/closures/2229_closure_analysis/migrations/precise_no_migrations.rs index f46ec4b927aca..4da8703857740 100644 --- a/tests/ui/closures/2229_closure_analysis/migrations/precise_no_migrations.rs +++ b/tests/ui/closures/2229_closure_analysis/migrations/precise_no_migrations.rs @@ -48,7 +48,7 @@ impl Drop for ContainsAndImplsDrop { } // If a path isn't directly captured but requires Drop, then this tests that migrations aren't -// needed if the a parent to that path is captured. +// needed if the parent to that path is captured. fn test_precise_analysis_parent_captured_1() { let t = ConstainsDropField(Foo(10), Foo(20)); @@ -60,7 +60,7 @@ fn test_precise_analysis_parent_captured_1() { } // If a path isn't directly captured but requires Drop, then this tests that migrations aren't -// needed if the a parent to that path is captured. +// needed if the parent to that path is captured. fn test_precise_analysis_parent_captured_2() { let t = ContainsAndImplsDrop(Foo(10)); diff --git a/tests/ui/traits/associated_type_bound/116464-invalid-assoc-type-suggestion-in-trait-impl.rs b/tests/ui/traits/associated_type_bound/116464-invalid-assoc-type-suggestion-in-trait-impl.rs index 445ea2de610fd..52b488101a8b0 100644 --- a/tests/ui/traits/associated_type_bound/116464-invalid-assoc-type-suggestion-in-trait-impl.rs +++ b/tests/ui/traits/associated_type_bound/116464-invalid-assoc-type-suggestion-in-trait-impl.rs @@ -11,7 +11,7 @@ impl Trait for i32 { type Assoc = String; } -// Should not not trigger suggestion here... +// Should not trigger suggestion here... impl Trait for () {} //~^ ERROR trait takes 1 generic argument but 2 generic arguments were supplied From b998cff5582b819910cc8e0f092c15151b930d02 Mon Sep 17 00:00:00 2001 From: Chris Denton Date: Tue, 2 Jul 2024 06:04:23 +0000 Subject: [PATCH 560/892] Use `cfg!(windows)` --- src/bootstrap/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs index 6d00ff9982d96..f5941e31e251f 100644 --- a/src/bootstrap/src/lib.rs +++ b/src/bootstrap/src/lib.rs @@ -1678,7 +1678,7 @@ impl Build { return; } if let Err(e) = fs::remove_file(dst) { - if e.kind() != io::ErrorKind::NotFound { + if cfg!(windows) && e.kind() != io::ErrorKind::NotFound { // workaround for https://github.com/rust-lang/rust/issues/127126 // if removing the file fails, attempt to rename it instead. let now = t!(SystemTime::now().duration_since(SystemTime::UNIX_EPOCH)); From 3e44883606ad4df77018c157971ba7a47e540088 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 2 Jul 2024 08:21:44 +0200 Subject: [PATCH 561/892] 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 fd59ad3b8f130..912aa11ded053 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version @@ -1 +1 @@ -9ed2ab3790ff41bf741dd690befd6a1c1e2b23ca +7d97c59438e933e86f557ed999da3b8dfc6855a7 From 3d750e270279d2d8689aee3ee5cdbf60faec42bd Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 2 Jul 2024 16:31:24 +1000 Subject: [PATCH 562/892] Shrink parser positions from `usize` to `u32`. The number of source code bytes can't exceed a `u32`'s range, so a token position also can't. This reduces the size of `Parser` and `LazyAttrTokenStreamImpl` by eight bytes each. --- compiler/rustc_expand/src/mbe/diagnostics.rs | 12 +++++------ compiler/rustc_expand/src/mbe/macro_parser.rs | 2 +- compiler/rustc_expand/src/mbe/macro_rules.rs | 4 ++-- .../rustc_parse/src/parser/attr_wrapper.rs | 21 ++++++++----------- compiler/rustc_parse/src/parser/mod.rs | 6 +++--- 5 files changed, 21 insertions(+), 24 deletions(-) diff --git a/compiler/rustc_expand/src/mbe/diagnostics.rs b/compiler/rustc_expand/src/mbe/diagnostics.rs index bf475c1dc96ff..2df8b8f00f862 100644 --- a/compiler/rustc_expand/src/mbe/diagnostics.rs +++ b/compiler/rustc_expand/src/mbe/diagnostics.rs @@ -120,21 +120,21 @@ struct CollectTrackerAndEmitter<'a, 'cx, 'matcher> { struct BestFailure { token: Token, - position_in_tokenstream: usize, + position_in_tokenstream: u32, msg: &'static str, remaining_matcher: MatcherLoc, } impl BestFailure { - fn is_better_position(&self, position: usize) -> bool { + fn is_better_position(&self, position: u32) -> bool { position > self.position_in_tokenstream } } impl<'a, 'cx, 'matcher> Tracker<'matcher> for CollectTrackerAndEmitter<'a, 'cx, 'matcher> { - type Failure = (Token, usize, &'static str); + type Failure = (Token, u32, &'static str); - fn build_failure(tok: Token, position: usize, msg: &'static str) -> Self::Failure { + fn build_failure(tok: Token, position: u32, msg: &'static str) -> Self::Failure { (tok, position, msg) } @@ -211,9 +211,9 @@ impl<'matcher> FailureForwarder<'matcher> { } impl<'matcher> Tracker<'matcher> for FailureForwarder<'matcher> { - type Failure = (Token, usize, &'static str); + type Failure = (Token, u32, &'static str); - fn build_failure(tok: Token, position: usize, msg: &'static str) -> Self::Failure { + fn build_failure(tok: Token, position: u32, msg: &'static str) -> Self::Failure { (tok, position, msg) } diff --git a/compiler/rustc_expand/src/mbe/macro_parser.rs b/compiler/rustc_expand/src/mbe/macro_parser.rs index 2fbd09fd9ae20..99a9d4f8912cd 100644 --- a/compiler/rustc_expand/src/mbe/macro_parser.rs +++ b/compiler/rustc_expand/src/mbe/macro_parser.rs @@ -452,7 +452,7 @@ impl TtParser { &mut self, matcher: &'matcher [MatcherLoc], token: &Token, - approx_position: usize, + approx_position: u32, track: &mut T, ) -> Option> { // Matcher positions that would be valid if the macro invocation was over now. Only diff --git a/compiler/rustc_expand/src/mbe/macro_rules.rs b/compiler/rustc_expand/src/mbe/macro_rules.rs index e43ba7c3a5a8f..88ec3d8366429 100644 --- a/compiler/rustc_expand/src/mbe/macro_rules.rs +++ b/compiler/rustc_expand/src/mbe/macro_rules.rs @@ -153,7 +153,7 @@ pub(super) trait Tracker<'matcher> { /// Arm failed to match. If the token is `token::Eof`, it indicates an unexpected /// end of macro invocation. Otherwise, it indicates that no rules expected the given token. /// The usize is the approximate position of the token in the input token stream. - fn build_failure(tok: Token, position: usize, msg: &'static str) -> Self::Failure; + fn build_failure(tok: Token, position: u32, msg: &'static str) -> Self::Failure; /// This is called before trying to match next MatcherLoc on the current token. fn before_match_loc(&mut self, _parser: &TtParser, _matcher: &'matcher MatcherLoc) {} @@ -182,7 +182,7 @@ pub(super) struct NoopTracker; impl<'matcher> Tracker<'matcher> for NoopTracker { type Failure = (); - fn build_failure(_tok: Token, _position: usize, _msg: &'static str) -> Self::Failure {} + fn build_failure(_tok: Token, _position: u32, _msg: &'static str) -> Self::Failure {} fn description() -> &'static str { "none" diff --git a/compiler/rustc_parse/src/parser/attr_wrapper.rs b/compiler/rustc_parse/src/parser/attr_wrapper.rs index 10feccd21e286..d0d01cec816fb 100644 --- a/compiler/rustc_parse/src/parser/attr_wrapper.rs +++ b/compiler/rustc_parse/src/parser/attr_wrapper.rs @@ -29,15 +29,15 @@ pub struct AttrWrapper { // The start of the outer attributes in the token cursor. // This allows us to create a `ReplaceRange` for the entire attribute // target, including outer attributes. - start_pos: usize, + start_pos: u32, } impl AttrWrapper { - pub(super) fn new(attrs: AttrVec, start_pos: usize) -> AttrWrapper { + pub(super) fn new(attrs: AttrVec, start_pos: u32) -> AttrWrapper { AttrWrapper { attrs, start_pos } } pub fn empty() -> AttrWrapper { - AttrWrapper { attrs: AttrVec::new(), start_pos: usize::MAX } + AttrWrapper { attrs: AttrVec::new(), start_pos: u32::MAX } } pub(crate) fn take_for_recovery(self, psess: &ParseSess) -> AttrVec { @@ -91,7 +91,7 @@ fn has_cfg_or_cfg_attr(attrs: &[Attribute]) -> bool { struct LazyAttrTokenStreamImpl { start_token: (Token, Spacing), cursor_snapshot: TokenCursor, - num_calls: usize, + num_calls: u32, break_last_token: bool, replace_ranges: Box<[ReplaceRange]>, } @@ -110,7 +110,7 @@ impl ToAttrTokenStream for LazyAttrTokenStreamImpl { let token = cursor_snapshot.next(); (FlatToken::Token(token.0), token.1) })) - .take(self.num_calls); + .take(self.num_calls as usize); if self.replace_ranges.is_empty() { make_token_stream(tokens, self.break_last_token) @@ -296,12 +296,12 @@ impl<'a> Parser<'a> { ); let end_pos = self.num_bump_calls - + captured_trailing as usize + + captured_trailing as u32 // If we 'broke' the last token (e.g. breaking a '>>' token to two '>' tokens), then // extend the range of captured tokens to include it, since the parser was not actually // bumped past it. When the `LazyAttrTokenStream` gets converted into an // `AttrTokenStream`, we will create the proper token. - + self.break_last_token as usize; + + self.break_last_token as u32; let num_calls = end_pos - start_pos; @@ -313,14 +313,11 @@ impl<'a> Parser<'a> { // Grab any replace ranges that occur *inside* the current AST node. // We will perform the actual replacement when we convert the `LazyAttrTokenStream` // to an `AttrTokenStream`. - let start_calls: u32 = start_pos.try_into().unwrap(); self.capture_state.replace_ranges[replace_ranges_start..replace_ranges_end] .iter() .cloned() .chain(inner_attr_replace_ranges.iter().cloned()) - .map(|(range, tokens)| { - ((range.start - start_calls)..(range.end - start_calls), tokens) - }) + .map(|(range, tokens)| ((range.start - start_pos)..(range.end - start_pos), tokens)) .collect() }; @@ -459,6 +456,6 @@ mod size_asserts { use rustc_data_structures::static_assert_size; // tidy-alphabetical-start static_assert_size!(AttrWrapper, 16); - static_assert_size!(LazyAttrTokenStreamImpl, 104); + static_assert_size!(LazyAttrTokenStreamImpl, 96); // tidy-alphabetical-end } diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs index cfd0a72c056d5..5f16a3e1f3784 100644 --- a/compiler/rustc_parse/src/parser/mod.rs +++ b/compiler/rustc_parse/src/parser/mod.rs @@ -153,7 +153,7 @@ pub struct Parser<'a> { expected_tokens: Vec, token_cursor: TokenCursor, // The number of calls to `bump`, i.e. the position in the token stream. - num_bump_calls: usize, + num_bump_calls: u32, // During parsing we may sometimes need to 'unglue' a glued token into two // component tokens (e.g. '>>' into '>' and '>), so the parser can consume // them one at a time. This process bypasses the normal capturing mechanism @@ -192,7 +192,7 @@ pub struct Parser<'a> { // This type is used a lot, e.g. it's cloned when matching many declarative macro rules with nonterminals. Make sure // it doesn't unintentionally get bigger. #[cfg(target_pointer_width = "64")] -rustc_data_structures::static_assert_size!(Parser<'_>, 264); +rustc_data_structures::static_assert_size!(Parser<'_>, 256); /// Stores span information about a closure. #[derive(Clone, Debug)] @@ -1572,7 +1572,7 @@ impl<'a> Parser<'a> { self.expected_tokens.clear(); } - pub fn approx_token_stream_pos(&self) -> usize { + pub fn approx_token_stream_pos(&self) -> u32 { self.num_bump_calls } } From 6f6015679fb0153bd35d1b56df2456bb6146a9af Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 2 Jul 2024 17:38:43 +1000 Subject: [PATCH 563/892] Rename `make_token_stream`. And update the comment. Clearly the return type of this function was changed at some point in the past, but its name and comment weren't updated to match. --- compiler/rustc_parse/src/parser/attr_wrapper.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_parse/src/parser/attr_wrapper.rs b/compiler/rustc_parse/src/parser/attr_wrapper.rs index d0d01cec816fb..3afd178cc2b4e 100644 --- a/compiler/rustc_parse/src/parser/attr_wrapper.rs +++ b/compiler/rustc_parse/src/parser/attr_wrapper.rs @@ -113,7 +113,7 @@ impl ToAttrTokenStream for LazyAttrTokenStreamImpl { .take(self.num_calls as usize); if self.replace_ranges.is_empty() { - make_token_stream(tokens, self.break_last_token) + make_attr_token_stream(tokens, self.break_last_token) } else { let mut tokens: Vec<_> = tokens.collect(); let mut replace_ranges = self.replace_ranges.to_vec(); @@ -166,7 +166,7 @@ impl ToAttrTokenStream for LazyAttrTokenStreamImpl { new_tokens.into_iter().chain(filler), ); } - make_token_stream(tokens.into_iter(), self.break_last_token) + make_attr_token_stream(tokens.into_iter(), self.break_last_token) } } } @@ -374,10 +374,10 @@ impl<'a> Parser<'a> { } } -/// Converts a flattened iterator of tokens (including open and close delimiter tokens) -/// into a `TokenStream`, creating a `TokenTree::Delimited` for each matching pair -/// of open and close delims. -fn make_token_stream( +/// Converts a flattened iterator of tokens (including open and close delimiter tokens) into an +/// `AttrTokenStream`, creating an `AttrTokenTree::Delimited` for each matching pair of open and +/// close delims. +fn make_attr_token_stream( mut iter: impl Iterator, break_last_token: bool, ) -> AttrTokenStream { From 565ddfb48ca2a3b24236c2b393ec14eb86d64a7a Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Thu, 6 Jun 2024 19:57:36 +0300 Subject: [PATCH 564/892] linker: Link dylib crates by path --- compiler/rustc_codegen_ssa/src/back/link.rs | 42 ++---- compiler/rustc_codegen_ssa/src/back/linker.rs | 137 +++++++++++------- tests/run-make/dylib-soname/foo.rs | 1 + tests/run-make/dylib-soname/rmake.rs | 19 +++ 4 files changed, 114 insertions(+), 85 deletions(-) create mode 100644 tests/run-make/dylib-soname/foo.rs create mode 100644 tests/run-make/dylib-soname/rmake.rs diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index da4fa41e2aafc..1f627353d54e1 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -2817,6 +2817,15 @@ fn rehome_sysroot_lib_dir(sess: &Session, lib_dir: &Path) -> PathBuf { } } +fn rehome_lib_path(sess: &Session, path: &Path) -> PathBuf { + if let Some(dir) = path.parent() { + let file_name = path.file_name().expect("library path has no file name component"); + rehome_sysroot_lib_dir(sess, dir).join(file_name) + } else { + fix_windows_verbatim_for_gcc(path) + } +} + // Adds the static "rlib" versions of all crates to the command line. // There's a bit of magic which happens here specifically related to LTO, // namely that we remove upstream object files. @@ -2847,15 +2856,8 @@ fn add_static_crate( let src = &codegen_results.crate_info.used_crate_source[&cnum]; let cratepath = &src.rlib.as_ref().unwrap().0; - let mut link_upstream = |path: &Path| { - let rlib_path = if let Some(dir) = path.parent() { - let file_name = path.file_name().expect("rlib path has no file name path component"); - rehome_sysroot_lib_dir(sess, dir).join(file_name) - } else { - fix_windows_verbatim_for_gcc(path) - }; - cmd.link_staticlib_by_path(&rlib_path, false); - }; + let mut link_upstream = + |path: &Path| cmd.link_staticlib_by_path(&rehome_lib_path(sess, path), false); if !are_upstream_rust_objects_already_included(sess) || ignored_for_lto(sess, &codegen_results.crate_info, cnum) @@ -2919,27 +2921,7 @@ fn add_static_crate( // Same thing as above, but for dynamic crates instead of static crates. fn add_dynamic_crate(cmd: &mut dyn Linker, sess: &Session, cratepath: &Path) { - // Just need to tell the linker about where the library lives and - // what its name is - let parent = cratepath.parent(); - // When producing a dll, the MSVC linker may not actually emit a - // `foo.lib` file if the dll doesn't actually export any symbols, so we - // check to see if the file is there and just omit linking to it if it's - // not present. - if sess.target.is_like_msvc && !cratepath.with_extension("dll.lib").exists() { - return; - } - if let Some(dir) = parent { - cmd.include_path(&rehome_sysroot_lib_dir(sess, dir)); - } - // "

    /name.dll -> name.dll" on windows-msvc - // "/name.dll -> name" on windows-gnu - // "/libname. -> name" elsewhere - let stem = if sess.target.is_like_msvc { cratepath.file_name() } else { cratepath.file_stem() }; - let stem = stem.unwrap().to_str().unwrap(); - // Convert library file-stem into a cc -l argument. - let prefix = if stem.starts_with("lib") && !sess.target.is_like_windows { 3 } else { 0 }; - cmd.link_dylib_by_name(&stem[prefix..], false, true); + cmd.link_dylib_by_path(&rehome_lib_path(sess, cratepath), true); } fn relevant_lib(sess: &Session, lib: &NativeLib) -> bool { diff --git a/compiler/rustc_codegen_ssa/src/back/linker.rs b/compiler/rustc_codegen_ssa/src/back/linker.rs index 0f75ece9729cd..2bd5dfdce83ee 100644 --- a/compiler/rustc_codegen_ssa/src/back/linker.rs +++ b/compiler/rustc_codegen_ssa/src/back/linker.rs @@ -268,7 +268,12 @@ pub trait Linker { false } fn set_output_kind(&mut self, output_kind: LinkOutputKind, out_filename: &Path); - fn link_dylib_by_name(&mut self, name: &str, verbatim: bool, as_needed: bool); + fn link_dylib_by_name(&mut self, _name: &str, _verbatim: bool, _as_needed: bool) { + bug!("dylib linked with unsupported linker") + } + fn link_dylib_by_path(&mut self, _path: &Path, _as_needed: bool) { + bug!("dylib linked with unsupported linker") + } fn link_framework_by_name(&mut self, _name: &str, _verbatim: bool, _as_needed: bool) { bug!("framework linked with unsupported linker") } @@ -403,28 +408,53 @@ impl<'a> GccLinker<'a> { } } else { self.link_or_cc_arg("-shared"); - if self.sess.target.is_like_windows { - // The output filename already contains `dll_suffix` so - // the resulting import library will have a name in the - // form of libfoo.dll.a - let implib_name = - out_filename.file_name().and_then(|file| file.to_str()).map(|file| { - format!( - "{}{}{}", - self.sess.target.staticlib_prefix, - file, - self.sess.target.staticlib_suffix - ) - }); - if let Some(implib_name) = implib_name { - let implib = out_filename.parent().map(|dir| dir.join(&implib_name)); - if let Some(implib) = implib { - self.link_arg(&format!("--out-implib={}", (*implib).to_str().unwrap())); - } + if let Some(name) = out_filename.file_name() { + if self.sess.target.is_like_windows { + // The output filename already contains `dll_suffix` so + // the resulting import library will have a name in the + // form of libfoo.dll.a + let mut implib_name = OsString::from(&*self.sess.target.staticlib_prefix); + implib_name.push(name); + implib_name.push(&*self.sess.target.staticlib_suffix); + let mut out_implib = OsString::from("--out-implib="); + out_implib.push(out_filename.with_file_name(implib_name)); + self.link_arg(out_implib); + } else { + // When dylibs are linked by a full path this value will get into `DT_NEEDED` + // instead of the full path, so the library can be later found in some other + // location than that specific path. + let mut soname = OsString::from("-soname="); + soname.push(name); + self.link_arg(soname); } } } } + + fn with_as_needed(&mut self, as_needed: bool, f: impl FnOnce(&mut Self)) { + if !as_needed { + if self.sess.target.is_like_osx { + // FIXME(81490): ld64 doesn't support these flags but macOS 11 + // has -needed-l{} / -needed_library {} + // but we have no way to detect that here. + self.sess.dcx().emit_warn(errors::Ld64UnimplementedModifier); + } else if self.is_gnu && !self.sess.target.is_like_windows { + self.link_arg("--no-as-needed"); + } else { + self.sess.dcx().emit_warn(errors::LinkerUnsupportedModifier); + } + } + + f(self); + + if !as_needed { + if self.sess.target.is_like_osx { + // See above FIXME comment + } else if self.is_gnu && !self.sess.target.is_like_windows { + self.link_arg("--as-needed"); + } + } + } } impl<'a> Linker for GccLinker<'a> { @@ -506,27 +536,18 @@ impl<'a> Linker for GccLinker<'a> { // to the linker. return; } - if !as_needed { - if self.sess.target.is_like_osx { - // FIXME(81490): ld64 doesn't support these flags but macOS 11 - // has -needed-l{} / -needed_library {} - // but we have no way to detect that here. - self.sess.dcx().emit_warn(errors::Ld64UnimplementedModifier); - } else if self.is_gnu && !self.sess.target.is_like_windows { - self.link_arg("--no-as-needed"); - } else { - self.sess.dcx().emit_warn(errors::LinkerUnsupportedModifier); - } - } self.hint_dynamic(); - self.link_or_cc_arg(format!("-l{}{name}", if verbatim && self.is_gnu { ":" } else { "" },)); - if !as_needed { - if self.sess.target.is_like_osx { - // See above FIXME comment - } else if self.is_gnu && !self.sess.target.is_like_windows { - self.link_arg("--as-needed"); - } - } + self.with_as_needed(as_needed, |this| { + let colon = if verbatim && this.is_gnu { ":" } else { "" }; + this.link_or_cc_arg(format!("-l{colon}{name}")); + }); + } + + fn link_dylib_by_path(&mut self, path: &Path, as_needed: bool) { + self.hint_dynamic(); + self.with_as_needed(as_needed, |this| { + this.link_or_cc_arg(path); + }) } fn link_framework_by_name(&mut self, name: &str, _verbatim: bool, as_needed: bool) { @@ -861,6 +882,15 @@ impl<'a> Linker for MsvcLinker<'a> { self.link_arg(format!("{}{}", name, if verbatim { "" } else { ".lib" })); } + fn link_dylib_by_path(&mut self, path: &Path, _as_needed: bool) { + // When producing a dll, MSVC linker may not emit an implib file if the dll doesn't export + // any symbols, so we skip linking if the implib file is not present. + let implib_path = path.with_extension("dll.lib"); + if implib_path.exists() { + self.link_or_cc_arg(implib_path); + } + } + fn link_staticlib_by_name(&mut self, name: &str, verbatim: bool, whole_archive: bool) { let prefix = if whole_archive { "/WHOLEARCHIVE:" } else { "" }; let suffix = if verbatim { "" } else { ".lib" }; @@ -1083,6 +1113,10 @@ impl<'a> Linker for EmLinker<'a> { self.link_or_cc_args(&["-l", name]); } + fn link_dylib_by_path(&mut self, path: &Path, _as_needed: bool) { + self.link_or_cc_arg(path); + } + fn link_staticlib_by_name(&mut self, name: &str, _verbatim: bool, _whole_archive: bool) { self.link_or_cc_args(&["-l", name]); } @@ -1240,6 +1274,10 @@ impl<'a> Linker for WasmLd<'a> { self.link_or_cc_args(&["-l", name]); } + fn link_dylib_by_path(&mut self, path: &Path, _as_needed: bool) { + self.link_or_cc_arg(path); + } + fn link_staticlib_by_name(&mut self, name: &str, _verbatim: bool, whole_archive: bool) { if !whole_archive { self.link_or_cc_args(&["-l", name]); @@ -1368,10 +1406,6 @@ impl<'a> Linker for L4Bender<'a> { fn set_output_kind(&mut self, _output_kind: LinkOutputKind, _out_filename: &Path) {} - fn link_dylib_by_name(&mut self, _name: &str, _verbatim: bool, _as_needed: bool) { - bug!("dylibs are not supported on L4Re"); - } - fn link_staticlib_by_name(&mut self, name: &str, _verbatim: bool, whole_archive: bool) { self.hint_static(); if !whole_archive { @@ -1536,6 +1570,11 @@ impl<'a> Linker for AixLinker<'a> { self.link_or_cc_arg(format!("-l{name}")); } + fn link_dylib_by_path(&mut self, path: &Path, _as_needed: bool) { + self.hint_dynamic(); + self.link_or_cc_arg(path); + } + fn link_staticlib_by_name(&mut self, name: &str, verbatim: bool, whole_archive: bool) { self.hint_static(); if !whole_archive { @@ -1721,10 +1760,6 @@ impl<'a> Linker for PtxLinker<'a> { fn set_output_kind(&mut self, _output_kind: LinkOutputKind, _out_filename: &Path) {} - fn link_dylib_by_name(&mut self, _name: &str, _verbatim: bool, _as_needed: bool) { - panic!("external dylibs not supported") - } - fn link_staticlib_by_name(&mut self, _name: &str, _verbatim: bool, _whole_archive: bool) { panic!("staticlibs not supported") } @@ -1791,10 +1826,6 @@ impl<'a> Linker for LlbcLinker<'a> { fn set_output_kind(&mut self, _output_kind: LinkOutputKind, _out_filename: &Path) {} - fn link_dylib_by_name(&mut self, _name: &str, _verbatim: bool, _as_needed: bool) { - panic!("external dylibs not supported") - } - fn link_staticlib_by_name(&mut self, _name: &str, _verbatim: bool, _whole_archive: bool) { panic!("staticlibs not supported") } @@ -1866,10 +1897,6 @@ impl<'a> Linker for BpfLinker<'a> { fn set_output_kind(&mut self, _output_kind: LinkOutputKind, _out_filename: &Path) {} - fn link_dylib_by_name(&mut self, _name: &str, _verbatim: bool, _as_needed: bool) { - panic!("external dylibs not supported") - } - fn link_staticlib_by_name(&mut self, _name: &str, _verbatim: bool, _whole_archive: bool) { panic!("staticlibs not supported") } diff --git a/tests/run-make/dylib-soname/foo.rs b/tests/run-make/dylib-soname/foo.rs new file mode 100644 index 0000000000000..6833f39199943 --- /dev/null +++ b/tests/run-make/dylib-soname/foo.rs @@ -0,0 +1 @@ +pub fn something() {} diff --git a/tests/run-make/dylib-soname/rmake.rs b/tests/run-make/dylib-soname/rmake.rs new file mode 100644 index 0000000000000..a0215a6906e47 --- /dev/null +++ b/tests/run-make/dylib-soname/rmake.rs @@ -0,0 +1,19 @@ +// Checks that produced dylibs have a relative SONAME set, so they don't put "unmovable" full paths +// into DT_NEEDED when used by a full path. + +//@ only-linux +//@ ignore-cross-compile + +use run_make_support::regex::Regex; +use run_make_support::{cmd, run_in_tmpdir, rustc}; + +fn main() { + run_in_tmpdir(|| { + rustc().crate_name("foo").crate_type("dylib").input("foo.rs").run(); + cmd("readelf") + .arg("-d") + .arg("libfoo.so") + .run() + .assert_stdout_contains("Library soname: [libfoo.so]"); + }); +} From 42ac903f4fe4e9894f8c6e97538696bdbae848dc Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Tue, 2 Jul 2024 01:51:55 -0400 Subject: [PATCH 565/892] Change to the NetBSD archive URL rather than the CDN The CDN has been down for a few hours. Switch to an alternative for the time being so we can unblock CI. It appears that the CDN is quite a bit faster, so we will likely want to switch back when available. --- .../build-netbsd-toolchain.sh | 54 ++++++++++++++----- 1 file changed, 42 insertions(+), 12 deletions(-) diff --git a/src/ci/docker/host-x86_64/dist-x86_64-netbsd/build-netbsd-toolchain.sh b/src/ci/docker/host-x86_64/dist-x86_64-netbsd/build-netbsd-toolchain.sh index e0c008b76fa8b..4a42f5da29fcc 100755 --- a/src/ci/docker/host-x86_64/dist-x86_64-netbsd/build-netbsd-toolchain.sh +++ b/src/ci/docker/host-x86_64/dist-x86_64-netbsd/build-netbsd-toolchain.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash # ignore-tidy-linelength -set -ex +set -eux hide_output() { set +x @@ -20,6 +20,22 @@ exit 1 set -x } +# Download, verify SHA512, and remove the downloaded file +# Usage: +download() { + fname="$1" + shift + url="$1" + shift + sha="$1" + shift + + curl "$url" -o "$fname" + echo "$sha $fname" | shasum -a 512 --check || exit 1 + "$@" + rm "$fname" +} + mkdir netbsd cd netbsd @@ -27,17 +43,31 @@ mkdir -p /x-tools/x86_64-unknown-netbsd/sysroot # URL=https://ci-mirrors.rust-lang.org/rustc -SOURCE_URL=https://cdn.netbsd.org/pub/NetBSD/NetBSD-9.0/source/sets -curl $SOURCE_URL/src.tgz | tar xzf - -curl $SOURCE_URL/gnusrc.tgz | tar xzf - -curl $SOURCE_URL/sharesrc.tgz | tar xzf - -curl $SOURCE_URL/syssrc.tgz | tar xzf - - -BINARY_URL=https://cdn.netbsd.org/pub/NetBSD/NetBSD-9.0/amd64/binary/sets -curl $BINARY_URL/base.tar.xz | \ - tar xJf - -C /x-tools/x86_64-unknown-netbsd/sysroot ./usr/include ./usr/lib ./lib -curl $BINARY_URL/comp.tar.xz | \ - tar xJf - -C /x-tools/x86_64-unknown-netbsd/sysroot ./usr/include ./usr/lib +# Hashes come from https://cdn.netbsd.org/pub/NetBSD/security/hashes/NetBSD-9.0_hashes.asc +SRC_SHA=2c791ae009a6929c6fc893ec5df7e62910ee8207e0b2159d6937309c03efe175b6ae1e445829a13d041b6851334ad35c521f2fa03c97675d4a05f1fafe58ede0 +GNUSRC_SHA=3710085a73feecf6a843415271ec794c90146b03f6bbd30f07c9e0c79febf8995d557e40194f1e05db655e4f5ef2fae97563f8456fceaae65d4ea98857a83b1c +SHARESRC_SHA=f080776ed82c3ac5d6272dee39746f87897d8e6984996caf5bf6d87bf11d9c9e0c1ad5c437c21258bd278bb6fd76974946e878f548517885f71c556096231369 +SYSSRC_SHA=60b9ddf4cc6402256473e2e1eefeabd9001aa4e205208715ecc6d6fc3f5b400e469944580077271b8e80562a4c2f601249e69e07a504f46744e0c50335f1cbf1 +BASE_SHA=b5926b107cebf40c3c19b4f6cd039b610987dd7f819e7cdde3bd1e5230a856906e7930b15ab242d52ced9f0bda01d574be59488b8dbb95fa5df2987d0a70995f +COMP_SHA=38ea54f30d5fc2afea87e5096f06873e00182789e8ad9cec0cb3e9f7c538c1aa4779e63fd401a36ba02676158e83fa5c95e8e87898db59c1914fb206aecd82d2 + +# FIXME: the archive URL is being used temporarily while the CDN is down. +# We should serve this from our own CDN +# SOURCE_URL=https://cdn.netbsd.org/pub/NetBSD/NetBSD-9.0/source/sets +SOURCE_URL=http://archive.netbsd.org/pub/NetBSD-archive/NetBSD-9.0/source/sets +download src.tgz "$SOURCE_URL/src.tgz" "$SRC_SHA" tar xzf src.tgz +download gnusrc.tgz "$SOURCE_URL/gnusrc.tgz" "$GNUSRC_SHA" tar xzf gnusrc.tgz +download sharesrc.tgz "$SOURCE_URL/sharesrc.tgz" "$SHARESRC_SHA" tar xzf sharesrc.tgz +download syssrc.tgz "$SOURCE_URL/syssrc.tgz" "$SYSSRC_SHA" tar xzf syssrc.tgz + +# FIXME: the archive URL is being used temporarily while the CDN is down. +# We should serve this from our own CDN +# BINARY_URL=https://cdn.netbsd.org/pub/NetBSD/NetBSD-9.0/amd64/binary/sets +BINARY_URL=http://archive.netbsd.org/pub/NetBSD-archive/NetBSD-9.0/amd64/binary/sets +download base.tar.xz "$BINARY_URL/base.tar.xz" "$BASE_SHA" \ + tar xJf base.tar.xz -C /x-tools/x86_64-unknown-netbsd/sysroot ./usr/include ./usr/lib ./lib +download comp.tar.xz "$BINARY_URL/comp.tar.xz" "$COMP_SHA" \ + tar xJf comp.tar.xz -C /x-tools/x86_64-unknown-netbsd/sysroot ./usr/include ./usr/lib cd usr/src From ba1ebc266b253a2eb001f88b351e8862095c4a06 Mon Sep 17 00:00:00 2001 From: Xinzhao Xu Date: Tue, 2 Jul 2024 17:30:36 +0800 Subject: [PATCH 566/892] doc: update config file path in platform-support/wasm32-wasip1-threads.md --- src/doc/rustc/src/platform-support/wasm32-wasip1-threads.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/rustc/src/platform-support/wasm32-wasip1-threads.md b/src/doc/rustc/src/platform-support/wasm32-wasip1-threads.md index 2b3d15e93c8cb..c3eda26ca8ef9 100644 --- a/src/doc/rustc/src/platform-support/wasm32-wasip1-threads.md +++ b/src/doc/rustc/src/platform-support/wasm32-wasip1-threads.md @@ -107,7 +107,7 @@ flag, for example: Users need to install or built wasi-sdk since release 20.0 https://github.com/WebAssembly/wasi-sdk/releases/tag/wasi-sdk-20 -and specify path to *wasi-root* `.cargo/config.toml` +and specify path to *wasi-root* `config.toml` ```toml [target.wasm32-wasip1-threads] From e03c3b6f19df854fbc52dc57bf39dbe9ae4972e9 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Mon, 1 Jul 2024 19:09:25 +0000 Subject: [PATCH 567/892] Allow _Unwind_RaiseException with MinGW --- .../miri/src/shims/windows/foreign_items.rs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/tools/miri/src/shims/windows/foreign_items.rs b/src/tools/miri/src/shims/windows/foreign_items.rs index c9db798caad7f..71f6a2bc03333 100644 --- a/src/tools/miri/src/shims/windows/foreign_items.rs +++ b/src/tools/miri/src/shims/windows/foreign_items.rs @@ -758,6 +758,22 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_null(dest)?; } + "_Unwind_RaiseException" => { + // This is not formally part of POSIX, but it is very wide-spread on POSIX systems. + // It was originally specified as part of the Itanium C++ ABI: + // https://itanium-cxx-abi.github.io/cxx-abi/abi-eh.html#base-throw. + // MinGW implements _Unwind_RaiseException on top of SEH exceptions. + if this.tcx.sess.target.env != "gnu" { + throw_unsup_format!( + "`_Unwind_RaiseException` is not supported on non-MinGW Windows", + ); + } + // This function looks and behaves excatly like miri_start_unwind. + let [payload] = this.check_shim(abi, Abi::C { unwind: true }, link_name, args)?; + this.handle_miri_start_unwind(payload)?; + return Ok(EmulateItemResult::NeedsUnwind); + } + _ => return Ok(EmulateItemResult::NotSupported), } From edeebe675b39cbdca93ec5b4c79f9a0765678112 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 2 Jul 2024 20:29:01 +1000 Subject: [PATCH 568/892] Import `std::{iter,mem}`. --- .../rustc_parse/src/parser/attr_wrapper.rs | 21 +++++++++---------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/compiler/rustc_parse/src/parser/attr_wrapper.rs b/compiler/rustc_parse/src/parser/attr_wrapper.rs index 3afd178cc2b4e..13a647adfe3b5 100644 --- a/compiler/rustc_parse/src/parser/attr_wrapper.rs +++ b/compiler/rustc_parse/src/parser/attr_wrapper.rs @@ -9,6 +9,7 @@ use rustc_session::parse::ParseSess; use rustc_span::{sym, Span, DUMMY_SP}; use std::ops::Range; +use std::{iter, mem}; /// A wrapper type to ensure that the parser handles outer attributes correctly. /// When we parse outer attributes, we need to ensure that we capture tokens @@ -53,7 +54,7 @@ impl AttrWrapper { // FIXME: require passing an NT to prevent misuse of this method pub(crate) fn prepend_to_nt_inner(self, attrs: &mut AttrVec) { let mut self_attrs = self.attrs; - std::mem::swap(attrs, &mut self_attrs); + mem::swap(attrs, &mut self_attrs); attrs.extend(self_attrs); } @@ -104,13 +105,12 @@ impl ToAttrTokenStream for LazyAttrTokenStreamImpl { // produce an empty `TokenStream` if no calls were made, and omit the // final token otherwise. let mut cursor_snapshot = self.cursor_snapshot.clone(); - let tokens = - std::iter::once((FlatToken::Token(self.start_token.0.clone()), self.start_token.1)) - .chain(std::iter::repeat_with(|| { - let token = cursor_snapshot.next(); - (FlatToken::Token(token.0), token.1) - })) - .take(self.num_calls as usize); + let tokens = iter::once((FlatToken::Token(self.start_token.0.clone()), self.start_token.1)) + .chain(iter::repeat_with(|| { + let token = cursor_snapshot.next(); + (FlatToken::Token(token.0), token.1) + })) + .take(self.num_calls as usize); if self.replace_ranges.is_empty() { make_attr_token_stream(tokens, self.break_last_token) @@ -158,7 +158,7 @@ impl ToAttrTokenStream for LazyAttrTokenStreamImpl { // This keeps the total length of `tokens` constant throughout the // replacement process, allowing us to use all of the `ReplaceRanges` entries // without adjusting indices. - let filler = std::iter::repeat((FlatToken::Empty, Spacing::Alone)) + let filler = iter::repeat((FlatToken::Empty, Spacing::Alone)) .take(range.len() - new_tokens.len()); tokens.splice( @@ -222,8 +222,7 @@ impl<'a> Parser<'a> { let replace_ranges_start = self.capture_state.replace_ranges.len(); let (mut ret, trailing) = { - let prev_capturing = - std::mem::replace(&mut self.capture_state.capturing, Capturing::Yes); + let prev_capturing = mem::replace(&mut self.capture_state.capturing, Capturing::Yes); let ret_and_trailing = f(self, attrs.attrs); self.capture_state.capturing = prev_capturing; ret_and_trailing? From 8c353cbc4688b50a0c950d9afc4bba5b1718278d Mon Sep 17 00:00:00 2001 From: Ana Hobden Date: Mon, 24 Jun 2024 12:54:43 -0700 Subject: [PATCH 569/892] Disable rmake test inaccessible-temp-dir on riscv64 --- tests/run-make/inaccessible-temp-dir/rmake.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/tests/run-make/inaccessible-temp-dir/rmake.rs b/tests/run-make/inaccessible-temp-dir/rmake.rs index 6b3e9e0b29e38..b98e151e90696 100644 --- a/tests/run-make/inaccessible-temp-dir/rmake.rs +++ b/tests/run-make/inaccessible-temp-dir/rmake.rs @@ -13,13 +13,18 @@ // use a directory with non-existing parent like `/does-not-exist/output`. // See https://github.com/rust-lang/rust/issues/66530 +//@ ignore-riscv64 +// FIXME: The riscv build container runs as root, and can always write +// into `inaccessible/tmp`. Ideally, the riscv64-gnu docker container +// would use a non-root user, but this leads to issues with +// `mkfs.ext4 -d`, as well as mounting a loop device for the rootfs. //@ ignore-arm // Reason: linker error on `armhf-gnu` //@ ignore-windows // Reason: `set_readonly` has no effect on directories // and does not prevent modification. -use run_make_support::{fs_wrapper, rustc, target, test_while_readonly}; +use run_make_support::{fs_wrapper, rustc, test_while_readonly}; fn main() { // Create an inaccessible directory. @@ -28,7 +33,6 @@ fn main() { // Run rustc with `-Z temps-dir` set to a directory *inside* the inaccessible one, // so that it can't create `tmp`. rustc() - .target(target()) .input("program.rs") .arg("-Ztemps-dir=inaccessible/tmp") .run_fail() From 6c803ffefb8eba9c65afc9a122d94383f71ebfa2 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 2 Jul 2024 15:28:16 +0200 Subject: [PATCH 570/892] remove unnecessary ignore-endian-big from stack-overflow-trait-infer test --- tests/ui/sized/stack-overflow-trait-infer-98842.32bit.stderr | 4 ++-- tests/ui/sized/stack-overflow-trait-infer-98842.64bit.stderr | 4 ++-- tests/ui/sized/stack-overflow-trait-infer-98842.rs | 3 +-- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/tests/ui/sized/stack-overflow-trait-infer-98842.32bit.stderr b/tests/ui/sized/stack-overflow-trait-infer-98842.32bit.stderr index 6bbd81ae3e163..c01b2ccd1637c 100644 --- a/tests/ui/sized/stack-overflow-trait-infer-98842.32bit.stderr +++ b/tests/ui/sized/stack-overflow-trait-infer-98842.32bit.stderr @@ -3,14 +3,14 @@ error[E0391]: cycle detected when computing layout of `Foo` = note: ...which requires computing layout of `<&'static Foo as core::ops::deref::Deref>::Target`... = note: ...which again requires computing layout of `Foo`, completing the cycle note: cycle used when const-evaluating + checking `_` - --> $DIR/stack-overflow-trait-infer-98842.rs:15:1 + --> $DIR/stack-overflow-trait-infer-98842.rs:14:1 | LL | const _: *const Foo = 0 as _; | ^^^^^^^^^^^^^^^^^^^ = 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[E0080]: evaluation of constant value failed - --> $DIR/stack-overflow-trait-infer-98842.rs:15:1 + --> $DIR/stack-overflow-trait-infer-98842.rs:14:1 | LL | const _: *const Foo = 0 as _; | ^^^^^^^^^^^^^^^^^^^ a cycle occurred during layout computation diff --git a/tests/ui/sized/stack-overflow-trait-infer-98842.64bit.stderr b/tests/ui/sized/stack-overflow-trait-infer-98842.64bit.stderr index 6bbd81ae3e163..c01b2ccd1637c 100644 --- a/tests/ui/sized/stack-overflow-trait-infer-98842.64bit.stderr +++ b/tests/ui/sized/stack-overflow-trait-infer-98842.64bit.stderr @@ -3,14 +3,14 @@ error[E0391]: cycle detected when computing layout of `Foo` = note: ...which requires computing layout of `<&'static Foo as core::ops::deref::Deref>::Target`... = note: ...which again requires computing layout of `Foo`, completing the cycle note: cycle used when const-evaluating + checking `_` - --> $DIR/stack-overflow-trait-infer-98842.rs:15:1 + --> $DIR/stack-overflow-trait-infer-98842.rs:14:1 | LL | const _: *const Foo = 0 as _; | ^^^^^^^^^^^^^^^^^^^ = 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[E0080]: evaluation of constant value failed - --> $DIR/stack-overflow-trait-infer-98842.rs:15:1 + --> $DIR/stack-overflow-trait-infer-98842.rs:14:1 | LL | const _: *const Foo = 0 as _; | ^^^^^^^^^^^^^^^^^^^ a cycle occurred during layout computation diff --git a/tests/ui/sized/stack-overflow-trait-infer-98842.rs b/tests/ui/sized/stack-overflow-trait-infer-98842.rs index be4807b2e4aa7..8a958870b0e17 100644 --- a/tests/ui/sized/stack-overflow-trait-infer-98842.rs +++ b/tests/ui/sized/stack-overflow-trait-infer-98842.rs @@ -3,8 +3,7 @@ //@ check-fail //@ edition:2021 //@ stderr-per-bitwidth -//@ ignore-endian-big -//~^^^^^^ ERROR cycle detected when computing layout of `Foo` +//~^^^^^ ERROR cycle detected when computing layout of `Foo` // If the inner `Foo` is named through an associated type, // the "infinite size" error does not occur. From 1df876f4c0ab583ef8821739c38340c8062f2ed5 Mon Sep 17 00:00:00 2001 From: Boxy Date: Tue, 2 Jul 2024 16:28:01 +0100 Subject: [PATCH 571/892] Add test --- .../nested_bad_const_param_ty.rs | 18 +++++++ .../nested_bad_const_param_ty.stderr | 51 +++++++++++++++++++ 2 files changed, 69 insertions(+) create mode 100644 tests/ui/const-generics/adt_const_params/nested_bad_const_param_ty.rs create mode 100644 tests/ui/const-generics/adt_const_params/nested_bad_const_param_ty.stderr diff --git a/tests/ui/const-generics/adt_const_params/nested_bad_const_param_ty.rs b/tests/ui/const-generics/adt_const_params/nested_bad_const_param_ty.rs new file mode 100644 index 0000000000000..9f05c53eef0f6 --- /dev/null +++ b/tests/ui/const-generics/adt_const_params/nested_bad_const_param_ty.rs @@ -0,0 +1,18 @@ +#![feature(adt_const_params)] +#![allow(incomplete_features)] + +use std::marker::ConstParamTy; + +#[derive(ConstParamTy)] +//~^ the trait `ConstParamTy` cannot be implemented for this ty +struct Foo([*const u8; 1]); + +#[derive(ConstParamTy)] +//~^ the trait `ConstParamTy` cannot be implemented for this ty +struct Foo2([*mut u8; 1]); + +#[derive(ConstParamTy)] +//~^ the trait `ConstParamTy` cannot be implemented for this ty +struct Foo3([fn(); 1]); + +fn main() {} diff --git a/tests/ui/const-generics/adt_const_params/nested_bad_const_param_ty.stderr b/tests/ui/const-generics/adt_const_params/nested_bad_const_param_ty.stderr new file mode 100644 index 0000000000000..9e772e8d55df9 --- /dev/null +++ b/tests/ui/const-generics/adt_const_params/nested_bad_const_param_ty.stderr @@ -0,0 +1,51 @@ +error[E0204]: the trait `ConstParamTy` cannot be implemented for this type + --> $DIR/nested_bad_const_param_ty.rs:6:10 + | +LL | #[derive(ConstParamTy)] + | ^^^^^^^^^^^^ +LL | +LL | struct Foo([*const u8; 1]); + | -------------- this field does not implement `ConstParamTy` + | +note: the `ConstParamTy` impl for `[*const u8; 1]` requires that `*const u8: ConstParamTy` + --> $DIR/nested_bad_const_param_ty.rs:8:12 + | +LL | struct Foo([*const u8; 1]); + | ^^^^^^^^^^^^^^ + = note: this error originates in the derive macro `ConstParamTy` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0204]: the trait `ConstParamTy` cannot be implemented for this type + --> $DIR/nested_bad_const_param_ty.rs:10:10 + | +LL | #[derive(ConstParamTy)] + | ^^^^^^^^^^^^ +LL | +LL | struct Foo2([*mut u8; 1]); + | ------------ this field does not implement `ConstParamTy` + | +note: the `ConstParamTy` impl for `[*mut u8; 1]` requires that `*mut u8: ConstParamTy` + --> $DIR/nested_bad_const_param_ty.rs:12:13 + | +LL | struct Foo2([*mut u8; 1]); + | ^^^^^^^^^^^^ + = note: this error originates in the derive macro `ConstParamTy` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0204]: the trait `ConstParamTy` cannot be implemented for this type + --> $DIR/nested_bad_const_param_ty.rs:14:10 + | +LL | #[derive(ConstParamTy)] + | ^^^^^^^^^^^^ +LL | +LL | struct Foo3([fn(); 1]); + | --------- this field does not implement `ConstParamTy` + | +note: the `ConstParamTy` impl for `[fn(); 1]` requires that `fn(): ConstParamTy` + --> $DIR/nested_bad_const_param_ty.rs:16:13 + | +LL | struct Foo3([fn(); 1]); + | ^^^^^^^^^ + = note: this error originates in the derive macro `ConstParamTy` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0204`. From 371845b630a86f86233c4a031971f9737a2092ff Mon Sep 17 00:00:00 2001 From: Oneirical Date: Thu, 27 Jun 2024 10:14:24 -0400 Subject: [PATCH 572/892] rewrite dylib-chain to rmake --- .../tidy/src/allowed_run_make_makefiles.txt | 1 - tests/run-make/dylib-chain/Makefile | 13 ----------- tests/run-make/dylib-chain/rmake.rs | 22 +++++++++++++++++++ 3 files changed, 22 insertions(+), 14 deletions(-) delete mode 100644 tests/run-make/dylib-chain/Makefile create mode 100644 tests/run-make/dylib-chain/rmake.rs diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index 276d2d694cda0..cd01b8596bba1 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -23,7 +23,6 @@ run-make/dep-info-spaces/Makefile run-make/dep-info/Makefile run-make/dump-ice-to-disk/Makefile run-make/dump-mono-stats/Makefile -run-make/dylib-chain/Makefile run-make/emit-path-unhashed/Makefile run-make/emit-shared-files/Makefile run-make/emit-to-stdout/Makefile diff --git a/tests/run-make/dylib-chain/Makefile b/tests/run-make/dylib-chain/Makefile deleted file mode 100644 index f1fea99c5ee91..0000000000000 --- a/tests/run-make/dylib-chain/Makefile +++ /dev/null @@ -1,13 +0,0 @@ -# ignore-cross-compile -include ../tools.mk - -all: - $(RUSTC) m1.rs -C prefer-dynamic - $(RUSTC) m2.rs -C prefer-dynamic - $(RUSTC) m3.rs -C prefer-dynamic - $(RUSTC) m4.rs - $(call RUN,m4) - $(call REMOVE_DYLIBS,m1) - $(call REMOVE_DYLIBS,m2) - $(call REMOVE_DYLIBS,m3) - $(call FAIL,m4) diff --git a/tests/run-make/dylib-chain/rmake.rs b/tests/run-make/dylib-chain/rmake.rs new file mode 100644 index 0000000000000..1d27191806f8b --- /dev/null +++ b/tests/run-make/dylib-chain/rmake.rs @@ -0,0 +1,22 @@ +// In this test, m4 depends on m3, which depends on m2, which depends on m1. +// Even though dependencies are chained like this and there is no direct mention +// of m1 or m2 in m4.rs, compilation and execution should still succeed. Naturally, +// removing those dependencies should cause execution to fail. +// See https://github.com/rust-lang/rust/issues/10434 + +//@ ignore-cross-compile +// Reason: the compiled binary is executed + +use run_make_support::{dynamic_lib_name, fs_wrapper, run, run_fail, rustc}; + +fn main() { + rustc().input("m1.rs").arg("-Cprefer-dynamic").run(); + rustc().input("m2.rs").arg("-Cprefer-dynamic").run(); + rustc().input("m3.rs").arg("-Cprefer-dynamic").run(); + rustc().input("m4.rs").run(); + run("m4"); + fs_wrapper::remove_file(dynamic_lib_name("m1")); + fs_wrapper::remove_file(dynamic_lib_name("m2")); + fs_wrapper::remove_file(dynamic_lib_name("m3")); + run_fail("m4"); +} From 86bd3498b2c5a6a40f3db62c48a22f81d7713950 Mon Sep 17 00:00:00 2001 From: Oneirical Date: Thu, 27 Jun 2024 10:20:49 -0400 Subject: [PATCH 573/892] rewrite rlib-chain to rmake --- .../tidy/src/allowed_run_make_makefiles.txt | 1 - tests/run-make/dylib-chain/rmake.rs | 5 ++-- tests/run-make/rlib-chain/Makefile | 11 --------- tests/run-make/rlib-chain/rmake.rs | 23 +++++++++++++++++++ 4 files changed, 26 insertions(+), 14 deletions(-) delete mode 100644 tests/run-make/rlib-chain/Makefile create mode 100644 tests/run-make/rlib-chain/rmake.rs diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index cd01b8596bba1..1e213eabab580 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -135,7 +135,6 @@ run-make/remap-path-prefix-dwarf/Makefile run-make/reproducible-build-2/Makefile run-make/reproducible-build/Makefile run-make/return-non-c-like-enum-from-c/Makefile -run-make/rlib-chain/Makefile run-make/rlib-format-packed-bundled-libs-2/Makefile run-make/rlib-format-packed-bundled-libs-3/Makefile run-make/rlib-format-packed-bundled-libs/Makefile diff --git a/tests/run-make/dylib-chain/rmake.rs b/tests/run-make/dylib-chain/rmake.rs index 1d27191806f8b..a96cc3508750b 100644 --- a/tests/run-make/dylib-chain/rmake.rs +++ b/tests/run-make/dylib-chain/rmake.rs @@ -1,7 +1,8 @@ // In this test, m4 depends on m3, which depends on m2, which depends on m1. // Even though dependencies are chained like this and there is no direct mention -// of m1 or m2 in m4.rs, compilation and execution should still succeed. Naturally, -// removing those dependencies should cause execution to fail. +// of m1 or m2 in m4.rs, compilation and execution should still succeed. Unlike the +// rlib-chain test, dynamic libraries contain upstream dependencies, and breaking +// the chain by removing the dylibs causes execution to fail. // See https://github.com/rust-lang/rust/issues/10434 //@ ignore-cross-compile diff --git a/tests/run-make/rlib-chain/Makefile b/tests/run-make/rlib-chain/Makefile deleted file mode 100644 index 7a1f887fa5271..0000000000000 --- a/tests/run-make/rlib-chain/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -# ignore-cross-compile -include ../tools.mk - -all: - $(RUSTC) m1.rs - $(RUSTC) m2.rs - $(RUSTC) m3.rs - $(RUSTC) m4.rs - $(call RUN,m4) - rm $(TMPDIR)/*lib - $(call RUN,m4) diff --git a/tests/run-make/rlib-chain/rmake.rs b/tests/run-make/rlib-chain/rmake.rs new file mode 100644 index 0000000000000..0947262bf6200 --- /dev/null +++ b/tests/run-make/rlib-chain/rmake.rs @@ -0,0 +1,23 @@ +// In this test, m4 depends on m3, which depends on m2, which depends on m1. +// Even though dependencies are chained like this and there is no direct mention +// of m1 or m2 in m4.rs, compilation and execution should still succeed. Unlike +// the dylib-chain test, rlibs do not contain upstream dependencies, and removing +// the libraries still allows m4 to successfully execute. +// See https://github.com/rust-lang/rust/issues/10434 + +//@ ignore-cross-compile +// Reason: the compiled binary is executed + +use run_make_support::{fs_wrapper, run, rust_lib_name, rustc}; + +fn main() { + rustc().input("m1.rs").run(); + rustc().input("m2.rs").run(); + rustc().input("m3.rs").run(); + rustc().input("m4.rs").run(); + run("m4"); + fs_wrapper::remove_file(rust_lib_name("m1")); + fs_wrapper::remove_file(rust_lib_name("m2")); + fs_wrapper::remove_file(rust_lib_name("m3")); + run("m4"); +} From 3a656462ef59a5d5288e0eb9651060d640c975ed Mon Sep 17 00:00:00 2001 From: Oneirical Date: Thu, 27 Jun 2024 11:08:49 -0400 Subject: [PATCH 574/892] rewrite and rename issue-47384 to rmake --- .../tidy/src/allowed_run_make_makefiles.txt | 1 - .../lib.rs | 0 .../linker.ld | 0 .../main.rs | 0 .../include-all-symbols-linking/rmake.rs | 29 +++++++++++++++++++ tests/run-make/issue-47384/Makefile | 12 -------- 6 files changed, 29 insertions(+), 13 deletions(-) rename tests/run-make/{issue-47384 => include-all-symbols-linking}/lib.rs (100%) rename tests/run-make/{issue-47384 => include-all-symbols-linking}/linker.ld (100%) rename tests/run-make/{issue-47384 => include-all-symbols-linking}/main.rs (100%) create mode 100644 tests/run-make/include-all-symbols-linking/rmake.rs delete mode 100644 tests/run-make/issue-47384/Makefile diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index 1e213eabab580..6ef68509f1095 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -65,7 +65,6 @@ run-make/issue-35164/Makefile run-make/issue-36710/Makefile run-make/issue-37839/Makefile run-make/issue-40535/Makefile -run-make/issue-47384/Makefile run-make/issue-47551/Makefile run-make/issue-69368/Makefile run-make/issue-83045/Makefile diff --git a/tests/run-make/issue-47384/lib.rs b/tests/run-make/include-all-symbols-linking/lib.rs similarity index 100% rename from tests/run-make/issue-47384/lib.rs rename to tests/run-make/include-all-symbols-linking/lib.rs diff --git a/tests/run-make/issue-47384/linker.ld b/tests/run-make/include-all-symbols-linking/linker.ld similarity index 100% rename from tests/run-make/issue-47384/linker.ld rename to tests/run-make/include-all-symbols-linking/linker.ld diff --git a/tests/run-make/issue-47384/main.rs b/tests/run-make/include-all-symbols-linking/main.rs similarity index 100% rename from tests/run-make/issue-47384/main.rs rename to tests/run-make/include-all-symbols-linking/main.rs diff --git a/tests/run-make/include-all-symbols-linking/rmake.rs b/tests/run-make/include-all-symbols-linking/rmake.rs new file mode 100644 index 0000000000000..a443fc0a5c41b --- /dev/null +++ b/tests/run-make/include-all-symbols-linking/rmake.rs @@ -0,0 +1,29 @@ +// Linkers treat archives differently from object files: all object files participate in linking, +// while archives will only participate in linking if they can satisfy at least one undefined +// reference (version scripts doesn't count). This causes `#[no_mangle]` or `#[used]` items to +// be ignored by the linker, and since they never participate in the linking, using `KEEP` in the +// linker scripts can't keep them either. This causes #47384. After the fix in #95604, this test +// checks that these symbols and sections successfully appear in the output dynamic library. +// See https://github.com/rust-lang/rust/pull/95604 +// See https://github.com/rust-lang/rust/issues/47384 + +//FIXME(Oneirical): ignore flags: only linux and cross compile + +use run_make_support::{dynamic_lib_name, llvm_objdump, llvm_readobj, rustc}; + +fn main() { + rustc().crate_type("lib").input("lib.rs").run(); + rustc().crate_type("cdylib").link_args("-Tlinker.ld").input("main.rs").run(); + // Ensure `#[used]` and `KEEP`-ed section is there + llvm_objdump() + .arg("--full-contents") + .arg("--section=.static") + .input(dynamic_lib_name("main")) + .run(); + // Ensure `#[no_mangle]` symbol is there + llvm_readobj() + .arg("--symbols") + .input(dynamic_lib_name("main")) + .run() + .assert_stdout_contains("bar"); +} diff --git a/tests/run-make/issue-47384/Makefile b/tests/run-make/issue-47384/Makefile deleted file mode 100644 index afc77cb275aaa..0000000000000 --- a/tests/run-make/issue-47384/Makefile +++ /dev/null @@ -1,12 +0,0 @@ -include ../tools.mk - -# only-linux -# ignore-cross-compile - -all: main.rs - $(RUSTC) --crate-type lib lib.rs - $(RUSTC) --crate-type cdylib -Clink-args="-Tlinker.ld" main.rs - # Ensure `#[used]` and `KEEP`-ed section is there - objdump -s -j".static" $(TMPDIR)/libmain.so - # Ensure `#[no_mangle]` symbol is there - nm $(TMPDIR)/libmain.so | $(CGREP) bar From b75dd71ef0472a5ef2c7c1ec9f0a12b125905d02 Mon Sep 17 00:00:00 2001 From: Oneirical Date: Thu, 27 Jun 2024 11:28:50 -0400 Subject: [PATCH 575/892] rewrite msvc-opt-minsize to ui test --- tests/run-make/msvc-opt-minsize/Makefile | 6 ---- tests/run-make/msvc-opt-minsize/foo.rs | 19 ------------ .../{windows-subsystem => windows}/console.rs | 0 tests/ui/windows/msvc-opt-minsize.rs | 31 +++++++++++++++++++ .../windows-subsystem-invalid.rs | 0 .../windows-subsystem-invalid.stderr | 0 .../{windows-subsystem => windows}/windows.rs | 0 7 files changed, 31 insertions(+), 25 deletions(-) delete mode 100644 tests/run-make/msvc-opt-minsize/Makefile delete mode 100644 tests/run-make/msvc-opt-minsize/foo.rs rename tests/ui/{windows-subsystem => windows}/console.rs (100%) create mode 100644 tests/ui/windows/msvc-opt-minsize.rs rename tests/ui/{windows-subsystem => windows}/windows-subsystem-invalid.rs (100%) rename tests/ui/{windows-subsystem => windows}/windows-subsystem-invalid.stderr (100%) rename tests/ui/{windows-subsystem => windows}/windows.rs (100%) diff --git a/tests/run-make/msvc-opt-minsize/Makefile b/tests/run-make/msvc-opt-minsize/Makefile deleted file mode 100644 index 32e6e28018f7a..0000000000000 --- a/tests/run-make/msvc-opt-minsize/Makefile +++ /dev/null @@ -1,6 +0,0 @@ -# ignore-cross-compile -include ../tools.mk - -all: - $(RUSTC) foo.rs -Copt-level=z 2>&1 - $(call RUN,foo) diff --git a/tests/run-make/msvc-opt-minsize/foo.rs b/tests/run-make/msvc-opt-minsize/foo.rs deleted file mode 100644 index 3f5496c08ee25..0000000000000 --- a/tests/run-make/msvc-opt-minsize/foo.rs +++ /dev/null @@ -1,19 +0,0 @@ -#![feature(test)] -extern crate test; - -fn foo(x: i32, y: i32) -> i64 { - (x + y) as i64 -} - -#[inline(never)] -fn bar() { - let _f = Box::new(0); - // This call used to trigger an LLVM bug in opt-level z where the base - // pointer gets corrupted, see issue #45034 - let y: fn(i32, i32) -> i64 = test::black_box(foo); - test::black_box(y(1, 2)); -} - -fn main() { - bar(); -} diff --git a/tests/ui/windows-subsystem/console.rs b/tests/ui/windows/console.rs similarity index 100% rename from tests/ui/windows-subsystem/console.rs rename to tests/ui/windows/console.rs diff --git a/tests/ui/windows/msvc-opt-minsize.rs b/tests/ui/windows/msvc-opt-minsize.rs new file mode 100644 index 0000000000000..c1be168a05dde --- /dev/null +++ b/tests/ui/windows/msvc-opt-minsize.rs @@ -0,0 +1,31 @@ +// A previously outdated version of LLVM caused compilation failures on Windows +// specifically with optimization level `z`. After the update to a more recent LLVM +// version, this test checks that compilation and execution both succeed. +// See https://github.com/rust-lang/rust/issues/45034 + +//@ ignore-cross-compile +// Reason: the compiled binary is executed +//@ only-windows +// Reason: the observed bug only occurs on Windows +//@ run-pass +//@ compile-flags: -C opt-level=z + +#![feature(test)] +extern crate test; + +fn foo(x: i32, y: i32) -> i64 { + (x + y) as i64 +} + +#[inline(never)] +fn bar() { + let _f = Box::new(0); + // This call used to trigger an LLVM bug in opt-level z where the base + // pointer gets corrupted, see issue #45034 + let y: fn(i32, i32) -> i64 = test::black_box(foo); + test::black_box(y(1, 2)); +} + +fn main() { + bar(); +} diff --git a/tests/ui/windows-subsystem/windows-subsystem-invalid.rs b/tests/ui/windows/windows-subsystem-invalid.rs similarity index 100% rename from tests/ui/windows-subsystem/windows-subsystem-invalid.rs rename to tests/ui/windows/windows-subsystem-invalid.rs diff --git a/tests/ui/windows-subsystem/windows-subsystem-invalid.stderr b/tests/ui/windows/windows-subsystem-invalid.stderr similarity index 100% rename from tests/ui/windows-subsystem/windows-subsystem-invalid.stderr rename to tests/ui/windows/windows-subsystem-invalid.stderr diff --git a/tests/ui/windows-subsystem/windows.rs b/tests/ui/windows/windows.rs similarity index 100% rename from tests/ui/windows-subsystem/windows.rs rename to tests/ui/windows/windows.rs From 45313a6ca038995bc3a0cc952fac94102d00f60c Mon Sep 17 00:00:00 2001 From: Oneirical Date: Thu, 27 Jun 2024 11:44:47 -0400 Subject: [PATCH 576/892] rewrite test-harness to rmake --- .../tidy/src/allowed_run_make_makefiles.txt | 2 -- src/tools/tidy/src/ui_tests.rs | 2 +- .../include-all-symbols-linking/rmake.rs | 4 ++- tests/run-make/test-harness/Makefile | 9 ------- tests/run-make/test-harness/rmake.rs | 25 +++++++++++++++++++ tests/ui/{windows => }/msvc-opt-minsize.rs | 0 .../{windows => windows-subsystem}/console.rs | 0 .../windows-subsystem-invalid.rs | 0 .../windows-subsystem-invalid.stderr | 0 .../{windows => windows-subsystem}/windows.rs | 0 10 files changed, 29 insertions(+), 13 deletions(-) delete mode 100644 tests/run-make/test-harness/Makefile create mode 100644 tests/run-make/test-harness/rmake.rs rename tests/ui/{windows => }/msvc-opt-minsize.rs (100%) rename tests/ui/{windows => windows-subsystem}/console.rs (100%) rename tests/ui/{windows => windows-subsystem}/windows-subsystem-invalid.rs (100%) rename tests/ui/{windows => windows-subsystem}/windows-subsystem-invalid.stderr (100%) rename tests/ui/{windows => windows-subsystem}/windows.rs (100%) diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index 6ef68509f1095..2da4e476e9016 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -96,7 +96,6 @@ run-make/metadata-dep-info/Makefile run-make/min-global-align/Makefile run-make/missing-crate-dependency/Makefile run-make/mixing-libs/Makefile -run-make/msvc-opt-minsize/Makefile run-make/native-link-modifier-bundle/Makefile run-make/native-link-modifier-whole-archive/Makefile run-make/no-alloc-shim/Makefile @@ -163,7 +162,6 @@ run-make/target-cpu-native/Makefile run-make/target-specs/Makefile run-make/target-without-atomic-cas/Makefile run-make/test-benches/Makefile -run-make/test-harness/Makefile run-make/thumb-none-cortex-m/Makefile run-make/thumb-none-qemu/Makefile run-make/track-path-dep-info/Makefile diff --git a/src/tools/tidy/src/ui_tests.rs b/src/tools/tidy/src/ui_tests.rs index 95857502108da..5e6992038e395 100644 --- a/src/tools/tidy/src/ui_tests.rs +++ b/src/tools/tidy/src/ui_tests.rs @@ -13,7 +13,7 @@ use std::path::{Path, PathBuf}; // should all be 1000 or lower. Limits significantly smaller than 1000 are also // desirable, because large numbers of files are unwieldy in general. See issue // #73494. -const ENTRY_LIMIT: u32 = 900; +const ENTRY_LIMIT: u32 = 901; // FIXME: The following limits should be reduced eventually. const ISSUES_ENTRY_LIMIT: u32 = 1672; diff --git a/tests/run-make/include-all-symbols-linking/rmake.rs b/tests/run-make/include-all-symbols-linking/rmake.rs index a443fc0a5c41b..77fd71ab20d21 100644 --- a/tests/run-make/include-all-symbols-linking/rmake.rs +++ b/tests/run-make/include-all-symbols-linking/rmake.rs @@ -7,7 +7,9 @@ // See https://github.com/rust-lang/rust/pull/95604 // See https://github.com/rust-lang/rust/issues/47384 -//FIXME(Oneirical): ignore flags: only linux and cross compile +//@ only-linux +// Reason: differences in object file formats on OSX and Windows +// causes errors in the llvm_objdump step use run_make_support::{dynamic_lib_name, llvm_objdump, llvm_readobj, rustc}; diff --git a/tests/run-make/test-harness/Makefile b/tests/run-make/test-harness/Makefile deleted file mode 100644 index ee8c9294f91ab..0000000000000 --- a/tests/run-make/test-harness/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -# ignore-cross-compile -include ../tools.mk - -all: - # check that #[cfg_attr(..., ignore)] does the right thing. - $(RUSTC) --test test-ignore-cfg.rs --cfg ignorecfg - $(call RUN,test-ignore-cfg) | $(CGREP) 'shouldnotignore ... ok' 'shouldignore ... ignored' - $(call RUN,test-ignore-cfg --quiet) | $(CGREP) -e "^i\.$$" - $(call RUN,test-ignore-cfg --quiet) | $(CGREP) -v 'should' diff --git a/tests/run-make/test-harness/rmake.rs b/tests/run-make/test-harness/rmake.rs new file mode 100644 index 0000000000000..30b3d00f4d114 --- /dev/null +++ b/tests/run-make/test-harness/rmake.rs @@ -0,0 +1,25 @@ +// The way test suites run can be modified using configuration flags, +// ignoring certain tests while running others. This test contains two +// functions, one which must run and the other which must not. The standard +// output is checked to verify that the ignore configuration is doing its job, +// and that output is successfully minimized with the --quiet flag. +// See https://github.com/rust-lang/rust/commit/f7ebe23ae185991b0fee05b32fbb3e29b89a41bf + +//@ ignore-cross-compile +// Reason: the compiled binary is executed + +use run_make_support::{run, run_with_args, rustc}; + +fn main() { + rustc().arg("--test").input("test-ignore-cfg.rs").cfg("ignorecfg").run(); + // check that #[cfg_attr(..., ignore)] does the right thing. + run("test-ignore-cfg") + .assert_stdout_contains("shouldnotignore ... ok") + .assert_stdout_contains("shouldignore ... ignored"); + assert_eq!( + // One of the lines is exactly "i." + run_with_args("test-ignore-cfg", &["--quiet"]).stdout_utf8().lines().find(|&x| x == "i."), + Some("i.") + ); + run_with_args("test-ignore-cfg", &["--quiet"]).assert_stdout_not_contains("should"); +} diff --git a/tests/ui/windows/msvc-opt-minsize.rs b/tests/ui/msvc-opt-minsize.rs similarity index 100% rename from tests/ui/windows/msvc-opt-minsize.rs rename to tests/ui/msvc-opt-minsize.rs diff --git a/tests/ui/windows/console.rs b/tests/ui/windows-subsystem/console.rs similarity index 100% rename from tests/ui/windows/console.rs rename to tests/ui/windows-subsystem/console.rs diff --git a/tests/ui/windows/windows-subsystem-invalid.rs b/tests/ui/windows-subsystem/windows-subsystem-invalid.rs similarity index 100% rename from tests/ui/windows/windows-subsystem-invalid.rs rename to tests/ui/windows-subsystem/windows-subsystem-invalid.rs diff --git a/tests/ui/windows/windows-subsystem-invalid.stderr b/tests/ui/windows-subsystem/windows-subsystem-invalid.stderr similarity index 100% rename from tests/ui/windows/windows-subsystem-invalid.stderr rename to tests/ui/windows-subsystem/windows-subsystem-invalid.stderr diff --git a/tests/ui/windows/windows.rs b/tests/ui/windows-subsystem/windows.rs similarity index 100% rename from tests/ui/windows/windows.rs rename to tests/ui/windows-subsystem/windows.rs From 8ce8c62f1e908ffb7edec993cb5e6cbafe4d620c Mon Sep 17 00:00:00 2001 From: Boxy Date: Tue, 2 Jul 2024 17:07:21 +0100 Subject: [PATCH 577/892] add test --- .../generic_const_exprs/adt_wf_hang.rs | 14 ++++++++++++++ .../generic_const_exprs/adt_wf_hang.stderr | 18 ++++++++++++++++++ 2 files changed, 32 insertions(+) create mode 100644 tests/ui/const-generics/generic_const_exprs/adt_wf_hang.rs create mode 100644 tests/ui/const-generics/generic_const_exprs/adt_wf_hang.stderr diff --git a/tests/ui/const-generics/generic_const_exprs/adt_wf_hang.rs b/tests/ui/const-generics/generic_const_exprs/adt_wf_hang.rs new file mode 100644 index 0000000000000..5d538d2679dd8 --- /dev/null +++ b/tests/ui/const-generics/generic_const_exprs/adt_wf_hang.rs @@ -0,0 +1,14 @@ +#![feature(generic_const_exprs)] +#![feature(adt_const_params)] +#![allow(incomplete_features)] +#![allow(dead_code)] + +#[derive(PartialEq, Eq)] +struct U; + +struct S() +where + S<{ U }>:; +//~^ ERROR: overflow evaluating the requirement `S<{ U }> well-formed` + +fn main() {} diff --git a/tests/ui/const-generics/generic_const_exprs/adt_wf_hang.stderr b/tests/ui/const-generics/generic_const_exprs/adt_wf_hang.stderr new file mode 100644 index 0000000000000..b244acb37dde0 --- /dev/null +++ b/tests/ui/const-generics/generic_const_exprs/adt_wf_hang.stderr @@ -0,0 +1,18 @@ +error[E0275]: overflow evaluating the requirement `S<{ U }> well-formed` + --> $DIR/adt_wf_hang.rs:11:5 + | +LL | S<{ U }>:; + | ^^^^^^^^ + | +note: required by a bound in `S` + --> $DIR/adt_wf_hang.rs:11:5 + | +LL | struct S() + | - required by a bound in this struct +LL | where +LL | S<{ U }>:; + | ^^^^^^^^ required by this bound in `S` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0275`. From 8e819fbb5ccd520e39981f42ffd497831d34fecb Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 26 Mar 2024 14:35:54 +0100 Subject: [PATCH 578/892] Fix libcore patch --- patches/0022-core-Disable-not-compiling-tests.patch | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/patches/0022-core-Disable-not-compiling-tests.patch b/patches/0022-core-Disable-not-compiling-tests.patch index a7d523f940826..ea1a5a8d35535 100644 --- a/patches/0022-core-Disable-not-compiling-tests.patch +++ b/patches/0022-core-Disable-not-compiling-tests.patch @@ -39,4 +39,4 @@ index 42a26ae..5ac1042 100644 +#![cfg(test)] #![feature(alloc_layout_extra)] #![feature(array_chunks)] - #![feature(array_windows)] + #![feature(array_ptr_get)] From f848dbbda5e5666c3fe9eb805f9eababa6244d50 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 26 Mar 2024 14:44:01 +0100 Subject: [PATCH 579/892] Fix non-master build --- src/builder.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/builder.rs b/src/builder.rs index 4a3b6f678c444..84aa168bcca3c 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -630,8 +630,9 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { then: Block<'gcc>, catch: Block<'gcc>, _funclet: Option<&Funclet>, + instance: Option>, ) -> RValue<'gcc> { - let call_site = self.call(typ, fn_attrs, None, func, args, None); + let call_site = self.call(typ, fn_attrs, None, func, args, None, instance); let condition = self.context.new_rvalue_from_int(self.bool_type, 1); self.llbb().end_with_conditional(self.location, condition, then, catch); if let Some(_fn_abi) = fn_abi { From 580e5ba456a4993794f0c6cbcb67f4b78e8673e5 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 15 May 2024 19:18:38 +0200 Subject: [PATCH 580/892] Format code --- src/builder.rs | 8 ++------ src/context.rs | 8 ++++---- src/intrinsic/simd.rs | 4 +++- 3 files changed, 9 insertions(+), 11 deletions(-) diff --git a/src/builder.rs b/src/builder.rs index 84aa168bcca3c..41d85bdceb77c 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -25,7 +25,7 @@ use rustc_middle::ty::layout::{ FnAbiError, FnAbiOfHelpers, FnAbiRequest, HasParamEnv, HasTyCtxt, LayoutError, LayoutOfHelpers, TyAndLayout, }; -use rustc_middle::ty::{ParamEnv, Ty, TyCtxt, Instance}; +use rustc_middle::ty::{Instance, ParamEnv, Ty, TyCtxt}; use rustc_span::def_id::DefId; use rustc_span::Span; use rustc_target::abi::{ @@ -904,11 +904,7 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { // TODO(antoyo): It might be better to return a LValue, but fixing the rustc API is non-trivial. self.stack_var_count.set(self.stack_var_count.get() + 1); self.current_func() - .new_local( - self.location, - ty, - &format!("stack_var_{}", self.stack_var_count.get()), - ) + .new_local(self.location, ty, &format!("stack_var_{}", self.stack_var_count.get())) .get_address(self.location) } diff --git a/src/context.rs b/src/context.rs index 6231b09552cea..a082bc1b2fc27 100644 --- a/src/context.rs +++ b/src/context.rs @@ -110,7 +110,7 @@ pub struct CodegenCx<'gcc, 'tcx> { local_gen_sym_counter: Cell, eh_personality: Cell>>, - #[cfg(feature="master")] + #[cfg(feature = "master")] pub rust_try_fn: Cell, Function<'gcc>)>>, pub pointee_infos: RefCell, Size), Option>>, @@ -122,7 +122,7 @@ pub struct CodegenCx<'gcc, 'tcx> { /// FIXME(antoyo): fix the rustc API to avoid having this hack. pub structs_as_pointer: RefCell>>, - #[cfg(feature="master")] + #[cfg(feature = "master")] pub cleanup_blocks: RefCell>>, } @@ -324,11 +324,11 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { struct_types: Default::default(), local_gen_sym_counter: Cell::new(0), eh_personality: Cell::new(None), - #[cfg(feature="master")] + #[cfg(feature = "master")] rust_try_fn: Cell::new(None), pointee_infos: Default::default(), structs_as_pointer: Default::default(), - #[cfg(feature="master")] + #[cfg(feature = "master")] cleanup_blocks: Default::default(), }; // TODO(antoyo): instead of doing this, add SsizeT to libgccjit. diff --git a/src/intrinsic/simd.rs b/src/intrinsic/simd.rs index 1625e6ecdb701..9dfdff1fdcb42 100644 --- a/src/intrinsic/simd.rs +++ b/src/intrinsic/simd.rs @@ -816,7 +816,9 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( let (_, element_ty0) = arg_tys[0].simd_size_and_type(bx.tcx()); let (_, element_ty1) = arg_tys[1].simd_size_and_type(bx.tcx()); let (pointer_count, underlying_ty) = match *element_ty1.kind() { - ty::RawPtr(p_ty, _) if p_ty == in_elem => (ptr_count(element_ty1), non_ptr(element_ty1)), + ty::RawPtr(p_ty, _) if p_ty == in_elem => { + (ptr_count(element_ty1), non_ptr(element_ty1)) + } _ => { require!( false, From 263166894a90e907d541686488acf3f47fedf9d2 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 27 Mar 2024 10:18:57 +0100 Subject: [PATCH 581/892] Update libgccjit version --- libgccjit.version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libgccjit.version b/libgccjit.version index 41bec6df5d95c..77d9993d0fe6d 100644 --- a/libgccjit.version +++ b/libgccjit.version @@ -1 +1 @@ -b6f163f52 +2cf6ca7373dbaf81a5bbc5d286a98c72fff8c8ee From 9b1211db58243e15f363caabbd7f22a45abd3654 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 3 Apr 2024 17:37:00 +0200 Subject: [PATCH 582/892] Fix casts --- src/builder.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/builder.rs b/src/builder.rs index 41d85bdceb77c..d72082937a7da 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -153,7 +153,7 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { // NOTE: not sure why, but we have the wrong type here. let int_type = compare_exchange.get_param(2).to_rvalue().get_type(); - let src = self.context.new_cast(self.location, src, int_type); + let src = self.context.new_bitcast(self.location, src, int_type); self.context.new_call( self.location, compare_exchange, @@ -1617,7 +1617,7 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { let dst = self.context.new_cast(self.location, dst, volatile_void_ptr_type); // FIXME(antoyo): not sure why, but we have the wrong type here. let new_src_type = atomic_function.get_param(1).to_rvalue().get_type(); - let src = self.context.new_cast(self.location, src, new_src_type); + let src = self.context.new_bitcast(self.location, src, new_src_type); let res = self.context.new_call(self.location, atomic_function, &[dst, src, order]); self.context.new_cast(self.location, res, src.get_type()) } From 7615e04f8236897af5fe8876f6da1d83cb90e699 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 3 Apr 2024 17:54:20 +0200 Subject: [PATCH 583/892] Fix usage of `get_size` for gcc 12 --- src/builder.rs | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/src/builder.rs b/src/builder.rs index d72082937a7da..b4a01d3c065b2 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -68,7 +68,7 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { src: RValue<'gcc>, order: AtomicOrdering, ) -> RValue<'gcc> { - let size = src.get_type().get_size(); + let size = get_maybe_pointer_size(src); let func = self.current_func(); @@ -138,7 +138,7 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { failure_order: AtomicOrdering, weak: bool, ) -> RValue<'gcc> { - let size = src.get_type().get_size(); + let size = get_maybe_pointer_size(src); let compare_exchange = self.context.get_builtin_function(&format!("__atomic_compare_exchange_{}", size)); let order = self.context.new_rvalue_from_int(self.i32_type, order.to_gcc()); @@ -1586,7 +1586,7 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { src: RValue<'gcc>, order: AtomicOrdering, ) -> RValue<'gcc> { - let size = src.get_type().get_size(); + let size = get_maybe_pointer_size(src); let name = match op { AtomicRmwBinOp::AtomicXchg => format!("__atomic_exchange_{}", size), AtomicRmwBinOp::AtomicAdd => format!("__atomic_fetch_add_{}", size), @@ -2419,3 +2419,19 @@ impl ToGccOrdering for AtomicOrdering { ordering as i32 } } + +// Needed because gcc 12 `get_size()` doesn't work on pointers. +#[cfg(feature = "master")] +fn get_maybe_pointer_size(value: RValue<'_>) -> u32 { + value.get_type().get_size() +} + +#[cfg(not(feature = "master"))] +fn get_maybe_pointer_size(value: RValue<'_>) -> u32 { + let type_ = value.get_type(); + if type_.get_pointee().is_some() { + std::mem::size_of::<*const ()>() as _ + } else { + type_.get_size() + } +} From fd7979d46d3b19360e48fb54118761ecaed37c20 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 28 Mar 2024 00:48:07 +0100 Subject: [PATCH 584/892] Remove usage of `-Zno-parallel-llvm` --- tests/lang_tests_common.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/lang_tests_common.rs b/tests/lang_tests_common.rs index 09307836fd424..aecea37ab5a91 100644 --- a/tests/lang_tests_common.rs +++ b/tests/lang_tests_common.rs @@ -80,8 +80,7 @@ pub fn main_inner(profile: Profile) { compiler.args([ &format!("-Zcodegen-backend={}/target/debug/librustc_codegen_gcc.so", current_dir), "--sysroot", - &format!("{}/build_sysroot/sysroot/", current_dir), - "-Zno-parallel-llvm", + &format!("{}/build/build_sysroot/sysroot/", current_dir), "-C", "link-arg=-lc", "-o", From 621e948721abb85f9b075027180e3f15416efcfc Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 28 Mar 2024 00:55:45 +0100 Subject: [PATCH 585/892] Fix clippy lint --- src/builder.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/builder.rs b/src/builder.rs index b4a01d3c065b2..f85971d1657e8 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -190,8 +190,7 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { let casted_args: Vec<_> = param_types .into_iter() .zip(args.iter()) - .enumerate() - .map(|(_i, (expected_ty, &actual_val))| { + .map(|(expected_ty, &actual_val)| { let actual_ty = actual_val.get_type(); if expected_ty != actual_ty { self.bitcast(actual_val, expected_ty) From a89f17869c74f165c72dfe1cfbce5638b966b213 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 2 Apr 2024 12:24:15 +0200 Subject: [PATCH 586/892] Fix stdarch crate add patch --- patches/0001-Add-stdarch-Cargo.toml-for-testing.patch | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/patches/0001-Add-stdarch-Cargo.toml-for-testing.patch b/patches/0001-Add-stdarch-Cargo.toml-for-testing.patch index 2a55f2cb796f9..9cc377850b9b7 100644 --- a/patches/0001-Add-stdarch-Cargo.toml-for-testing.patch +++ b/patches/0001-Add-stdarch-Cargo.toml-for-testing.patch @@ -19,7 +19,7 @@ index 0000000..4c63700 +members = [ + "crates/core_arch", + "crates/std_detect", -+ "crates/stdarch-gen", ++ "crates/stdarch-gen-arm", + #"examples/" +] +exclude = [ From 068fe5d10a125c28ed4ae8f4b8e0f0e7f95eb64f Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 20 Apr 2024 01:17:46 +0200 Subject: [PATCH 587/892] If the type of a global is not the same, we remove the global and replace it with a new one --- src/consts.rs | 91 ++++++++++++++++++++++++++++++--------------------- 1 file changed, 54 insertions(+), 37 deletions(-) diff --git a/src/consts.rs b/src/consts.rs index 3d73a60b25504..be44ebe0698a8 100644 --- a/src/consts.rs +++ b/src/consts.rs @@ -1,7 +1,9 @@ #[cfg(feature = "master")] use gccjit::{FnAttribute, VarAttribute, Visibility}; -use gccjit::{Function, GlobalKind, LValue, RValue, ToRValue}; +use gccjit::{Function, GlobalKind, LValue, RValue, ToRValue, Type}; use rustc_codegen_ssa::traits::{BaseTypeMethods, ConstMethods, DerivedTypeMethods, StaticMethods}; +use rustc_hir::def::DefKind; +use rustc_middle::bug; use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs}; use rustc_middle::mir::interpret::{ self, read_target_uint, ConstAllocation, ErrorHandled, Scalar as InterpScalar, @@ -9,7 +11,7 @@ use rustc_middle::mir::interpret::{ use rustc_middle::mir::mono::MonoItem; use rustc_middle::span_bug; use rustc_middle::ty::layout::LayoutOf; -use rustc_middle::ty::{self, Instance, Ty}; +use rustc_middle::ty::{self, Instance}; use rustc_span::def_id::DefId; use rustc_target::abi::{self, Align, HasDataLayout, Primitive, Size, WrappingRange}; @@ -63,16 +65,15 @@ impl<'gcc, 'tcx> StaticMethods for CodegenCx<'gcc, 'tcx> { global_value } + #[cfg_attr(not(feature = "master"), allow(unused_mut))] fn codegen_static(&self, def_id: DefId) { let attrs = self.tcx.codegen_fn_attrs(def_id); - let value = match codegen_static_initializer(&self, def_id) { - Ok((value, _)) => value, + let Ok((value, alloc)) = codegen_static_initializer(self, def_id) else { // Error has already been reported - Err(_) => return, + return; }; - - let global = self.get_static(def_id); + let alloc = alloc.inner(); // boolean SSA values are i1, but they have to be stored in i8 slots, // otherwise some LLVM optimization passes don't work as expected @@ -81,23 +82,31 @@ impl<'gcc, 'tcx> StaticMethods for CodegenCx<'gcc, 'tcx> { unimplemented!(); }; - let instance = Instance::mono(self.tcx, def_id); - let ty = instance.ty(self.tcx, ty::ParamEnv::reveal_all()); - let gcc_type = self.layout_of(ty).gcc_type(self); + let is_thread_local = attrs.flags.contains(CodegenFnAttrFlags::THREAD_LOCAL); + let mut global = self.get_static_inner(def_id, val_llty); - set_global_alignment(self, global, self.align_of(ty)); + #[cfg(feature = "master")] + if global.to_rvalue().get_type() != val_llty { + let instance = Instance::mono(self.tcx, def_id); + self.instances.borrow_mut().remove(&instance); + + global.remove(); + let name = self.tcx.symbol_name(instance).name; + self.globals.borrow_mut().remove(name); + global = self.get_static_inner(def_id, val_llty); + } + set_global_alignment(self, global, alloc.align); - let value = self.bitcast_if_needed(value, gcc_type); global.global_set_initializer_rvalue(value); // As an optimization, all shared statics which do not have interior // mutability are placed into read-only memory. - if !self.tcx.static_mutability(def_id).unwrap().is_mut() && self.type_is_freeze(ty) { + if alloc.mutability.is_not() { #[cfg(feature = "master")] global.global_set_readonly(); } - if attrs.flags.contains(CodegenFnAttrFlags::THREAD_LOCAL) { + if is_thread_local { // Do not allow LLVM to change the alignment of a TLS on macOS. // // By default a global's alignment can be freely increased. @@ -205,39 +214,48 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { pub fn get_static(&self, def_id: DefId) -> LValue<'gcc> { let instance = Instance::mono(self.tcx, def_id); - let fn_attrs = self.tcx.codegen_fn_attrs(def_id); + let DefKind::Static { nested, .. } = self.tcx.def_kind(def_id) else { bug!() }; + // Nested statics do not have a type, so pick a random type and let `define_static` figure out + // the gcc type from the actual evaluated initializer. + let gcc_type = if nested { + self.type_i8() + } else { + let ty = instance.ty(self.tcx, ty::ParamEnv::reveal_all()); + self.layout_of(ty).gcc_type(self) + }; + + self.get_static_inner(def_id, gcc_type) + } + + pub(crate) fn get_static_inner(&self, def_id: DefId, gcc_type: Type<'gcc>) -> LValue<'gcc> { + let instance = Instance::mono(self.tcx, def_id); if let Some(&global) = self.instances.borrow().get(&instance) { + trace!("used cached value"); return global; } - let defined_in_current_codegen_unit = - self.codegen_unit.items().contains_key(&MonoItem::Static(def_id)); - assert!( - !defined_in_current_codegen_unit, - "consts::get_static() should always hit the cache for \ - statics defined in the same CGU, but did not for `{:?}`", - def_id - ); - - let ty = instance.ty(self.tcx, ty::ParamEnv::reveal_all()); + // FIXME: Once we stop removing globals in `codegen_static`, we can uncomment this code. + // let defined_in_current_codegen_unit = + // self.codegen_unit.items().contains_key(&MonoItem::Static(def_id)); + // assert!( + // !defined_in_current_codegen_unit, + // "consts::get_static() should always hit the cache for \ + // statics defined in the same CGU, but did not for `{:?}`", + // def_id + // ); let sym = self.tcx.symbol_name(instance).name; + let fn_attrs = self.tcx.codegen_fn_attrs(def_id); let global = if def_id.is_local() && !self.tcx.is_foreign_item(def_id) { - let llty = self.layout_of(ty).gcc_type(self); if let Some(global) = self.get_declared_value(sym) { - if self.val_ty(global) != self.type_ptr_to(llty) { + if self.val_ty(global) != self.type_ptr_to(gcc_type) { span_bug!(self.tcx.def_span(def_id), "Conflicting types for static"); } } let is_tls = fn_attrs.flags.contains(CodegenFnAttrFlags::THREAD_LOCAL); - let global = self.declare_global( - &sym, - llty, - GlobalKind::Exported, - is_tls, - fn_attrs.link_section, - ); + let global = + self.declare_global(sym, gcc_type, GlobalKind::Exported, is_tls, fn_attrs.link_section); if !self.tcx.is_reachable_non_generic(def_id) { #[cfg(feature = "master")] @@ -246,7 +264,7 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { global } else { - check_and_apply_linkage(&self, &fn_attrs, ty, sym) + check_and_apply_linkage(self, fn_attrs, gcc_type, sym) }; if !def_id.is_local() { @@ -360,11 +378,10 @@ fn codegen_static_initializer<'gcc, 'tcx>( fn check_and_apply_linkage<'gcc, 'tcx>( cx: &CodegenCx<'gcc, 'tcx>, attrs: &CodegenFnAttrs, - ty: Ty<'tcx>, + gcc_type: Type<'gcc>, sym: &str, ) -> LValue<'gcc> { let is_tls = attrs.flags.contains(CodegenFnAttrFlags::THREAD_LOCAL); - let gcc_type = cx.layout_of(ty).gcc_type(cx); if let Some(linkage) = attrs.import_linkage { // Declare a symbol `foo` with the desired linkage. let global1 = cx.declare_global_with_linkage( From 684a69b4e656c8d3c05fa0d56056371e3cef42c2 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 25 Apr 2024 14:26:50 +0200 Subject: [PATCH 588/892] Update gcc version to 272d0ccced960394fe6ff2b40b01610208cb4940 --- libgccjit.version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libgccjit.version b/libgccjit.version index 77d9993d0fe6d..71a61a4b8735f 100644 --- a/libgccjit.version +++ b/libgccjit.version @@ -1 +1 @@ -2cf6ca7373dbaf81a5bbc5d286a98c72fff8c8ee +272d0ccced960394fe6ff2b40b01610208cb4940 From 30ee7ba862f97bf32c1fc665590edd71901d12d1 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 21 May 2024 16:30:55 +0200 Subject: [PATCH 589/892] Add shl and shr missing casts --- src/context.rs | 2 +- src/int.rs | 24 ++++++++++++++++++++++-- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/src/context.rs b/src/context.rs index a082bc1b2fc27..0e3d790779926 100644 --- a/src/context.rs +++ b/src/context.rs @@ -613,7 +613,7 @@ impl<'b, 'tcx> CodegenCx<'b, 'tcx> { // user defined names let mut name = String::with_capacity(prefix.len() + 6); name.push_str(prefix); - name.push_str("."); + name.push('.'); name.push_str(&(idx as u64).to_base(ALPHANUMERIC_ONLY)); name } diff --git a/src/int.rs b/src/int.rs index 841bcf592e489..218198b9c5766 100644 --- a/src/int.rs +++ b/src/int.rs @@ -83,7 +83,17 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { let b = self.context.new_cast(self.location, b, a_type); a >> b } else { - a >> b + let a_size = a_type.get_size(); + let b_size = b_type.get_size(); + if a_size > b_size { + let b = self.context.new_cast(self.location, b, a_type); + a >> b + } else if a_size < b_size { + let a = self.context.new_cast(self.location, a, b_type); + a >> b + } else { + a >> b + } } } else if a_type.is_vector() && a_type.is_vector() { a >> b @@ -635,7 +645,17 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { let b = self.context.new_cast(self.location, b, a_type); a << b } else { - a << b + let a_size = a_type.get_size(); + let b_size = b_type.get_size(); + if a_size > b_size { + let b = self.context.new_cast(self.location, b, a_type); + a << b + } else if a_size < b_size { + let a = self.context.new_cast(self.location, a, b_type); + a << b + } else { + a << b + } } } else if a_type.is_vector() && a_type.is_vector() { a << b From ca654047fb130962943df137dabd6e58929319e8 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 21 May 2024 16:57:53 +0200 Subject: [PATCH 590/892] Add missing cast for function_ptr arguments --- src/builder.rs | 14 +++++++++++++- src/consts.rs | 9 +++++++-- src/lib.rs | 2 +- 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/src/builder.rs b/src/builder.rs index f85971d1657e8..c5819ff93d744 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -252,7 +252,19 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { { self.context.new_cast(self.location, actual_val, expected_ty) } else if on_stack_param_indices.contains(&index) { - actual_val.dereference(self.location).to_rvalue() + let ty = actual_val.get_type(); + if let Some(pointee_val) = ty.get_pointee() + && pointee_val != expected_ty + { + let new_val = self.context.new_cast( + self.location, + actual_val, + expected_ty.make_pointer(), + ); + new_val.dereference(self.location).to_rvalue() + } else { + actual_val.dereference(self.location).to_rvalue() + } } else { assert!( !((actual_ty.is_vector() && !expected_ty.is_vector()) diff --git a/src/consts.rs b/src/consts.rs index be44ebe0698a8..735793baf610d 100644 --- a/src/consts.rs +++ b/src/consts.rs @@ -254,8 +254,13 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { } let is_tls = fn_attrs.flags.contains(CodegenFnAttrFlags::THREAD_LOCAL); - let global = - self.declare_global(sym, gcc_type, GlobalKind::Exported, is_tls, fn_attrs.link_section); + let global = self.declare_global( + sym, + gcc_type, + GlobalKind::Exported, + is_tls, + fn_attrs.link_section, + ); if !self.tcx.is_reachable_non_generic(def_id) { #[cfg(feature = "master")] diff --git a/src/lib.rs b/src/lib.rs index 24856506c4644..d839385695511 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -16,7 +16,7 @@ #![allow(internal_features)] #![doc(rust_logo)] #![feature(rustdoc_internals)] -#![feature(rustc_private, decl_macro, never_type, trusted_len, hash_raw_entry)] +#![feature(rustc_private, decl_macro, never_type, trusted_len, hash_raw_entry, let_chains)] #![allow(broken_intra_doc_links)] #![recursion_limit = "256"] #![warn(rust_2018_idioms)] From 527c04958469c3d8701d3ab0dedb16fa396a7900 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 21 May 2024 23:09:34 +0200 Subject: [PATCH 591/892] Fix warnings --- src/consts.rs | 3 +-- src/type_of.rs | 8 +------- 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/src/consts.rs b/src/consts.rs index 735793baf610d..93c23440c57c1 100644 --- a/src/consts.rs +++ b/src/consts.rs @@ -1,14 +1,13 @@ #[cfg(feature = "master")] use gccjit::{FnAttribute, VarAttribute, Visibility}; use gccjit::{Function, GlobalKind, LValue, RValue, ToRValue, Type}; -use rustc_codegen_ssa::traits::{BaseTypeMethods, ConstMethods, DerivedTypeMethods, StaticMethods}; +use rustc_codegen_ssa::traits::{BaseTypeMethods, ConstMethods, StaticMethods}; use rustc_hir::def::DefKind; use rustc_middle::bug; use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs}; use rustc_middle::mir::interpret::{ self, read_target_uint, ConstAllocation, ErrorHandled, Scalar as InterpScalar, }; -use rustc_middle::mir::mono::MonoItem; use rustc_middle::span_bug; use rustc_middle::ty::layout::LayoutOf; use rustc_middle::ty::{self, Instance}; diff --git a/src/type_of.rs b/src/type_of.rs index a88d50cb43403..24eab8e9a1e83 100644 --- a/src/type_of.rs +++ b/src/type_of.rs @@ -8,7 +8,7 @@ use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::{self, CoroutineArgsExt, Ty, TypeVisitableExt}; use rustc_target::abi::call::{CastTarget, FnAbi, Reg}; use rustc_target::abi::{ - self, Abi, Align, FieldsShape, Float, Int, Integer, PointeeInfo, Pointer, Size, TyAbiInterface, + self, Abi, FieldsShape, Float, Int, Integer, PointeeInfo, Pointer, Size, TyAbiInterface, Variants, }; @@ -53,12 +53,6 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { } } -impl<'a, 'tcx> CodegenCx<'a, 'tcx> { - pub fn align_of(&self, ty: Ty<'tcx>) -> Align { - self.layout_of(ty).align.abi - } -} - fn uncached_gcc_type<'gcc, 'tcx>( cx: &CodegenCx<'gcc, 'tcx>, layout: TyAndLayout<'tcx>, From dd4a546de0af391759a901ac070e6ca66a6c7af1 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 22 May 2024 15:19:15 +0200 Subject: [PATCH 592/892] Add explanations for ptr func call argument cast --- src/builder.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/builder.rs b/src/builder.rs index c5819ff93d744..0d5ef42833d0a 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -253,6 +253,9 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { self.context.new_cast(self.location, actual_val, expected_ty) } else if on_stack_param_indices.contains(&index) { let ty = actual_val.get_type(); + // It's possible that the value behind the pointer is actually not exactly + // the expected type, so to go around that, we add a cast before + // dereferencing the value. if let Some(pointee_val) = ty.get_pointee() && pointee_val != expected_ty { From 0ffcbb0f6eda96ade2f1c3fbda4316998b8fbb90 Mon Sep 17 00:00:00 2001 From: Antoni Boucher Date: Wed, 12 Jun 2024 08:43:28 -0400 Subject: [PATCH 593/892] Remove the hack in zext TODO: make sure this doesn't break something else. --- src/builder.rs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/builder.rs b/src/builder.rs index 0d5ef42833d0a..91a019318a84f 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -1687,11 +1687,6 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { fn zext(&mut self, value: RValue<'gcc>, dest_typ: Type<'gcc>) -> RValue<'gcc> { // FIXME(antoyo): this does not zero-extend. - if value.get_type().is_bool() && dest_typ.is_i8(&self.cx) { - // FIXME(antoyo): hack because base::from_immediate converts i1 to i8. - // Fix the code in codegen_ssa::base::from_immediate. - return value; - } self.gcc_int_cast(value, dest_typ) } From e8e6663167618b7674165f894edf7acbf03980e1 Mon Sep 17 00:00:00 2001 From: Antoni Boucher Date: Tue, 18 Jun 2024 12:56:20 -0400 Subject: [PATCH 594/892] Fix provenance intrinsics --- Cargo.lock | 6 +- Cargo.toml | 3 +- rust-toolchain | 2 +- src/intrinsic/simd.rs | 135 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 140 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3ecb0ef6b4d29..ba6633bc2dcbd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -80,8 +80,7 @@ dependencies = [ [[package]] name = "gccjit" version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecaa4c3da2d74c1a991b4faff75d49ab1d0522d9a99d8e2614b3b04d226417ce" +source = "git+https://github.com/rust-lang/gccjit.rs#f1545d7c2c13e42d78eaac8032d49ab8f7d43b6e" dependencies = [ "gccjit_sys", ] @@ -89,8 +88,7 @@ dependencies = [ [[package]] name = "gccjit_sys" version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "406a66fba005f1a02661f2f9443e5693dd3a667b7c58e70aa4ccc4c8b50b4758" +source = "git+https://github.com/rust-lang/gccjit.rs#f1545d7c2c13e42d78eaac8032d49ab8f7d43b6e" dependencies = [ "libc", ] diff --git a/Cargo.toml b/Cargo.toml index c5aa2eed1e004..309746f04e014 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,7 +22,8 @@ master = ["gccjit/master"] default = ["master"] [dependencies] -gccjit = "2.0" +#gccjit = "2.0" +gccjit = { git = "https://github.com/rust-lang/gccjit.rs" } # Local copy. #gccjit = { path = "../gccjit.rs" } diff --git a/rust-toolchain b/rust-toolchain index a0ac82866609e..7a1806fe3c76f 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2024-03-05" +channel = "nightly-2024-06-18" components = ["rust-src", "rustc-dev", "llvm-tools-preview"] diff --git a/src/intrinsic/simd.rs b/src/intrinsic/simd.rs index 9dfdff1fdcb42..0c52bfd219230 100644 --- a/src/intrinsic/simd.rs +++ b/src/intrinsic/simd.rs @@ -436,6 +436,141 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( return Ok(bx.vector_select(args[0].immediate(), args[1].immediate(), args[2].immediate())); } + if name == sym::simd_cast_ptr { + require_simd!(ret_ty, InvalidMonomorphization::SimdReturn { span, name, ty: ret_ty }); + let (out_len, out_elem) = ret_ty.simd_size_and_type(bx.tcx()); + + require!( + in_len == out_len, + InvalidMonomorphization::ReturnLengthInputType { + span, + name, + in_len, + in_ty, + ret_ty, + out_len + } + ); + + match *in_elem.kind() { + ty::RawPtr(p_ty, _) => { + let metadata = p_ty.ptr_metadata_ty(bx.tcx, |ty| { + bx.tcx.normalize_erasing_regions(ty::ParamEnv::reveal_all(), ty) + }); + require!( + metadata.is_unit(), + InvalidMonomorphization::CastFatPointer { span, name, ty: in_elem } + ); + } + _ => { + return_error!(InvalidMonomorphization::ExpectedPointer { span, name, ty: in_elem }) + } + } + match *out_elem.kind() { + ty::RawPtr(p_ty, _) => { + let metadata = p_ty.ptr_metadata_ty(bx.tcx, |ty| { + bx.tcx.normalize_erasing_regions(ty::ParamEnv::reveal_all(), ty) + }); + require!( + metadata.is_unit(), + InvalidMonomorphization::CastFatPointer { span, name, ty: out_elem } + ); + } + _ => { + return_error!(InvalidMonomorphization::ExpectedPointer { span, name, ty: out_elem }) + } + } + + let arg = args[0].immediate(); + let elem_type = llret_ty.dyncast_vector().expect("vector return type").get_element_type(); + let values: Vec<_> = (0..in_len) + .map(|i| { + let idx = bx.gcc_int(bx.usize_type, i as _); + let value = bx.extract_element(arg, idx); + bx.pointercast(value, elem_type) + }) + .collect(); + return Ok(bx.context.new_rvalue_from_vector(bx.location, llret_ty, &values)); + } + + if name == sym::simd_expose_provenance { + require_simd!(ret_ty, InvalidMonomorphization::SimdReturn { span, name, ty: ret_ty }); + let (out_len, out_elem) = ret_ty.simd_size_and_type(bx.tcx()); + + require!( + in_len == out_len, + InvalidMonomorphization::ReturnLengthInputType { + span, + name, + in_len, + in_ty, + ret_ty, + out_len + } + ); + + match *in_elem.kind() { + ty::RawPtr(_, _) => {} + _ => { + return_error!(InvalidMonomorphization::ExpectedPointer { span, name, ty: in_elem }) + } + } + match *out_elem.kind() { + ty::Uint(ty::UintTy::Usize) => {} + _ => return_error!(InvalidMonomorphization::ExpectedUsize { span, name, ty: out_elem }), + } + + let arg = args[0].immediate(); + let elem_type = llret_ty.dyncast_vector().expect("vector return type").get_element_type(); + let values: Vec<_> = (0..in_len) + .map(|i| { + let idx = bx.gcc_int(bx.usize_type, i as _); + let value = bx.extract_element(arg, idx); + bx.ptrtoint(value, elem_type) + }) + .collect(); + return Ok(bx.context.new_rvalue_from_vector(bx.location, llret_ty, &values)); + } + + if name == sym::simd_with_exposed_provenance { + require_simd!(ret_ty, InvalidMonomorphization::SimdReturn { span, name, ty: ret_ty }); + let (out_len, out_elem) = ret_ty.simd_size_and_type(bx.tcx()); + + require!( + in_len == out_len, + InvalidMonomorphization::ReturnLengthInputType { + span, + name, + in_len, + in_ty, + ret_ty, + out_len + } + ); + + match *in_elem.kind() { + ty::Uint(ty::UintTy::Usize) => {} + _ => return_error!(InvalidMonomorphization::ExpectedUsize { span, name, ty: in_elem }), + } + match *out_elem.kind() { + ty::RawPtr(_, _) => {} + _ => { + return_error!(InvalidMonomorphization::ExpectedPointer { span, name, ty: out_elem }) + } + } + + let arg = args[0].immediate(); + let elem_type = llret_ty.dyncast_vector().expect("vector return type").get_element_type(); + let values: Vec<_> = (0..in_len) + .map(|i| { + let idx = bx.gcc_int(bx.usize_type, i as _); + let value = bx.extract_element(arg, idx); + bx.inttoptr(value, elem_type) + }) + .collect(); + return Ok(bx.context.new_rvalue_from_vector(bx.location, llret_ty, &values)); + } + #[cfg(feature = "master")] if name == sym::simd_cast || name == sym::simd_as { require_simd!(ret_ty, InvalidMonomorphization::SimdReturn { span, name, ty: ret_ty }); From 9ca76588177de76422cb54a416555b8b2fc234f9 Mon Sep 17 00:00:00 2001 From: Antoni Boucher Date: Tue, 18 Jun 2024 12:58:01 -0400 Subject: [PATCH 595/892] Fix tests --- ...0001-core-Disable-portable-simd-test.patch | 14 +++---- src/asm.rs | 5 +-- src/builder.rs | 4 +- src/context.rs | 2 +- src/int.rs | 36 +++++++++------- src/intrinsic/mod.rs | 14 +++++-- src/intrinsic/simd.rs | 1 + src/mono_item.rs | 2 +- tests/failing-run-make-tests.txt | 42 +++++++++++++++++++ tests/failing-ui-tests.txt | 1 - tests/run/array.rs | 11 +++++ tests/run/assign.rs | 6 +++ tests/run/closure.rs | 6 +++ tests/run/mut_ref.rs | 6 +++ tests/run/operations.rs | 18 ++++++++ 15 files changed, 133 insertions(+), 35 deletions(-) create mode 100644 tests/failing-run-make-tests.txt diff --git a/patches/libgccjit12/0001-core-Disable-portable-simd-test.patch b/patches/libgccjit12/0001-core-Disable-portable-simd-test.patch index 36d0789d2a23b..c060300f44f65 100644 --- a/patches/libgccjit12/0001-core-Disable-portable-simd-test.patch +++ b/patches/libgccjit12/0001-core-Disable-portable-simd-test.patch @@ -1,4 +1,4 @@ -From a5663265f797a43c502915c356fe7899c16cee92 Mon Sep 17 00:00:00 2001 +From 124a11ce086952a5794d5cfbaa45175809497b81 Mon Sep 17 00:00:00 2001 From: None Date: Sat, 18 Nov 2023 10:50:36 -0500 Subject: [PATCH] [core] Disable portable-simd test @@ -8,18 +8,18 @@ Subject: [PATCH] [core] Disable portable-simd test 1 file changed, 2 deletions(-) diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs -index d0a119c..76fdece 100644 +index b71786c..cf484d5 100644 --- a/library/core/tests/lib.rs +++ b/library/core/tests/lib.rs -@@ -89,7 +89,6 @@ +@@ -95,7 +95,6 @@ #![feature(never_type)] #![feature(unwrap_infallible)] #![feature(pointer_is_aligned_to)] -#![feature(portable_simd)] #![feature(ptr_metadata)] - #![feature(lazy_cell)] #![feature(unsized_tuple_coercion)] -@@ -155,7 +154,6 @@ mod pin; + #![feature(const_option)] +@@ -157,7 +156,6 @@ mod pin; mod pin_macro; mod ptr; mod result; @@ -27,6 +27,6 @@ index d0a119c..76fdece 100644 mod slice; mod str; mod str_lossy; --- -2.42.1 +-- +2.45.2 diff --git a/src/asm.rs b/src/asm.rs index 06b14a1f118a3..60e63efe57b79 100644 --- a/src/asm.rs +++ b/src/asm.rs @@ -538,9 +538,8 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> { } if dest.is_none() && options.contains(InlineAsmOptions::NORETURN) { let builtin_unreachable = self.context.get_builtin_function("__builtin_unreachable"); - let builtin_unreachable: RValue<'gcc> = unsafe { - std::mem::transmute(builtin_unreachable) - }; + let builtin_unreachable: RValue<'gcc> = + unsafe { std::mem::transmute(builtin_unreachable) }; self.call(self.type_void(), None, None, builtin_unreachable, &[], None, None); } diff --git a/src/builder.rs b/src/builder.rs index 91a019318a84f..4cbc8175aa078 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -1004,7 +1004,7 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { } } - let val = if let Some(_) = place.val.llextra { + let val = if place.val.llextra.is_some() { // FIXME: Merge with the `else` below? OperandValue::Ref(place.val) } else if place.layout.is_gcc_immediate() { @@ -1672,7 +1672,7 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { _instance: Option>, ) -> RValue<'gcc> { // FIXME(antoyo): remove when having a proper API. - let gcc_func = unsafe { std::mem::transmute(func) }; + let gcc_func = unsafe { std::mem::transmute::, Function<'gcc>>(func) }; let call = if self.functions.borrow().values().any(|value| *value == gcc_func) { self.function_call(func, args, funclet) } else { diff --git a/src/context.rs b/src/context.rs index 0e3d790779926..c5d5c6bc846db 100644 --- a/src/context.rs +++ b/src/context.rs @@ -495,7 +495,7 @@ impl<'gcc, 'tcx> MiscMethods<'tcx> for CodegenCx<'gcc, 'tcx> { "rust_eh_personality" }; let func = self.declare_func(name, self.type_i32(), &[], true); - unsafe { std::mem::transmute(func) } + unsafe { std::mem::transmute::, RValue<'gcc>>(func) } } }; // TODO(antoyo): apply target cpu attributes. diff --git a/src/int.rs b/src/int.rs index 218198b9c5766..a095dd3953968 100644 --- a/src/int.rs +++ b/src/int.rs @@ -85,14 +85,16 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { } else { let a_size = a_type.get_size(); let b_size = b_type.get_size(); - if a_size > b_size { - let b = self.context.new_cast(self.location, b, a_type); - a >> b - } else if a_size < b_size { - let a = self.context.new_cast(self.location, a, b_type); - a >> b - } else { - a >> b + match a_size.cmp(&b_size) { + std::cmp::Ordering::Less => { + let a = self.context.new_cast(self.location, a, b_type); + a >> b + } + std::cmp::Ordering::Equal => a >> b, + std::cmp::Ordering::Greater => { + let b = self.context.new_cast(self.location, b, a_type); + a >> b + } } } } else if a_type.is_vector() && a_type.is_vector() { @@ -647,14 +649,16 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { } else { let a_size = a_type.get_size(); let b_size = b_type.get_size(); - if a_size > b_size { - let b = self.context.new_cast(self.location, b, a_type); - a << b - } else if a_size < b_size { - let a = self.context.new_cast(self.location, a, b_type); - a << b - } else { - a << b + match a_size.cmp(&b_size) { + std::cmp::Ordering::Less => { + let a = self.context.new_cast(self.location, a, b_type); + a << b + } + std::cmp::Ordering::Equal => a << b, + std::cmp::Ordering::Greater => { + let b = self.context.new_cast(self.location, b, a_type); + a << b + } } } } else if a_type.is_vector() && a_type.is_vector() { diff --git a/src/intrinsic/mod.rs b/src/intrinsic/mod.rs index 43f12b514affa..1e09572e61286 100644 --- a/src/intrinsic/mod.rs +++ b/src/intrinsic/mod.rs @@ -125,7 +125,9 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'a, 'gcc, 'tcx> { let llval = match name { _ if simple.is_some() => { // FIXME(antoyo): remove this cast when the API supports function. - let func = unsafe { std::mem::transmute(simple.expect("simple")) }; + let func = unsafe { + std::mem::transmute::, RValue<'gcc>>(simple.expect("simple")) + }; self.call( self.type_void(), None, @@ -670,7 +672,11 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { let step3 = self.or(left, right); // Fourth step. - if width == 8 { step3 } else { self.gcc_bswap(step3, width) } + if width == 8 { + step3 + } else { + self.gcc_bswap(step3, width) + } } 128 => { // TODO(antoyo): find a more efficient implementation? @@ -1189,7 +1195,7 @@ fn codegen_gnu_try<'gcc>( bx.invoke(try_func_ty, None, None, try_func, &[data], then, catch, None, None); }); - let func = unsafe { std::mem::transmute(func) }; + let func = unsafe { std::mem::transmute::, RValue<'gcc>>(func) }; // Note that no invoke is used here because by definition this function // can't panic (that's what it's catching). @@ -1263,7 +1269,7 @@ fn gen_fn<'a, 'gcc, 'tcx>( // FIXME(eddyb) find a nicer way to do this. cx.linkage.set(FunctionType::Internal); let func = cx.declare_fn(name, fn_abi); - let func_val = unsafe { std::mem::transmute(func) }; + let func_val = unsafe { std::mem::transmute::, RValue<'gcc>>(func) }; cx.set_frame_pointer_type(func_val); cx.apply_target_cpu_attr(func_val); let block = Builder::append_block(cx, func_val, "entry-block"); diff --git a/src/intrinsic/simd.rs b/src/intrinsic/simd.rs index 0c52bfd219230..a54e7107a906e 100644 --- a/src/intrinsic/simd.rs +++ b/src/intrinsic/simd.rs @@ -13,6 +13,7 @@ use rustc_codegen_ssa::errors::InvalidMonomorphization; use rustc_codegen_ssa::mir::operand::OperandRef; use rustc_codegen_ssa::mir::place::PlaceRef; use rustc_codegen_ssa::traits::{BaseTypeMethods, BuilderMethods}; +#[cfg(feature = "master")] use rustc_hir as hir; use rustc_middle::mir::BinOp; use rustc_middle::span_bug; diff --git a/src/mono_item.rs b/src/mono_item.rs index 359d3c70b4cae..44657ad4f6e25 100644 --- a/src/mono_item.rs +++ b/src/mono_item.rs @@ -81,6 +81,6 @@ impl<'gcc, 'tcx> PreDefineMethods<'tcx> for CodegenCx<'gcc, 'tcx> { // TODO(antoyo): use inline attribute from there in linkage.set() above. self.functions.borrow_mut().insert(symbol_name.to_string(), decl); - self.function_instances.borrow_mut().insert(instance, unsafe { std::mem::transmute(decl) }); + self.function_instances.borrow_mut().insert(instance, decl); } } diff --git a/tests/failing-run-make-tests.txt b/tests/failing-run-make-tests.txt new file mode 100644 index 0000000000000..842533cd3c62c --- /dev/null +++ b/tests/failing-run-make-tests.txt @@ -0,0 +1,42 @@ +tests/run-make/a-b-a-linker-guard/ +tests/run-make/CURRENT_RUSTC_VERSION/ +tests/run-make/cross-lang-lto/ +tests/run-make/cross-lang-lto-upstream-rlibs/ +tests/run-make/doctests-keep-binaries/ +tests/run-make/doctests-runtool/ +tests/run-make/emit-shared-files/ +tests/run-make/exit-code/ +tests/run-make/issue-22131/ +tests/run-make/issue-64153/ +tests/run-make/llvm-ident/ +tests/run-make/native-link-modifier-bundle/ +tests/run-make/remap-path-prefix-dwarf/ +tests/run-make/repr128-dwarf/ +tests/run-make/rlib-format-packed-bundled-libs/ +tests/run-make/rlib-format-packed-bundled-libs-2/ +tests/run-make/rustdoc-determinism/ +tests/run-make/rustdoc-error-lines/ +tests/run-make/rustdoc-map-file/ +tests/run-make/rustdoc-output-path/ +tests/run-make/rustdoc-scrape-examples-invalid-expr/ +tests/run-make/rustdoc-scrape-examples-multiple/ +tests/run-make/rustdoc-scrape-examples-ordering/ +tests/run-make/rustdoc-scrape-examples-remap/ +tests/run-make/rustdoc-scrape-examples-test/ +tests/run-make/rustdoc-scrape-examples-whitespace/ +tests/run-make/rustdoc-scrape-examples-macros/ +tests/run-make/rustdoc-with-out-dir-option/ +tests/run-make/rustdoc-verify-output-files/ +tests/run-make/rustdoc-themes/ +tests/run-make/rustdoc-with-short-out-dir-option/ +tests/run-make/rustdoc-with-output-option/ +tests/run-make/arguments-non-c-like-enum/ +tests/run-make/c-link-to-rust-staticlib/ +tests/run-make/foreign-double-unwind/ +tests/run-make/foreign-exceptions/ +tests/run-make/glibc-staticlib-args/ +tests/run-make/issue-36710/ +tests/run-make/issue-68794-textrel-on-minimal-lib/ +tests/run-make/lto-smoke-c/ +tests/run-make/return-non-c-like-enum/ + diff --git a/tests/failing-ui-tests.txt b/tests/failing-ui-tests.txt index d13562f8bb01b..7cc3b0dee0f50 100644 --- a/tests/failing-ui-tests.txt +++ b/tests/failing-ui-tests.txt @@ -14,7 +14,6 @@ tests/ui/sepcomp/sepcomp-fns-backwards.rs tests/ui/sepcomp/sepcomp-fns.rs tests/ui/sepcomp/sepcomp-statics.rs tests/ui/asm/x86_64/may_unwind.rs -tests/ui/backtrace.rs tests/ui/catch-unwind-bang.rs tests/ui/cfg/cfg-panic-abort.rs tests/ui/drop/dynamic-drop-async.rs diff --git a/tests/run/array.rs b/tests/run/array.rs index afd0eed82004c..3fe8917c9a3c4 100644 --- a/tests/run/array.rs +++ b/tests/run/array.rs @@ -205,6 +205,17 @@ impl Sub for i16 { } } +#[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 diff --git a/tests/run/assign.rs b/tests/run/assign.rs index 5b0db2da294dd..e105d64a8ad8f 100644 --- a/tests/run/assign.rs +++ b/tests/run/assign.rs @@ -120,6 +120,12 @@ impl Add for isize { } } +#[track_caller] +#[lang = "panic_const_add_overflow"] +pub fn panic_const_add_overflow() -> ! { + panic("attempt to add with overflow"); +} + /* * Code */ diff --git a/tests/run/closure.rs b/tests/run/closure.rs index 4ce528f86800c..355f0acee7473 100644 --- a/tests/run/closure.rs +++ b/tests/run/closure.rs @@ -189,6 +189,12 @@ pub fn panic(_msg: &'static str) -> ! { } } +#[track_caller] +#[lang = "panic_const_add_overflow"] +pub fn panic_const_add_overflow() -> ! { + panic("attempt to add with overflow"); +} + /* * Code */ diff --git a/tests/run/mut_ref.rs b/tests/run/mut_ref.rs index 194e55a3deaeb..5a3f72b69047e 100644 --- a/tests/run/mut_ref.rs +++ b/tests/run/mut_ref.rs @@ -122,6 +122,12 @@ impl Add for isize { } } +#[track_caller] +#[lang = "panic_const_add_overflow"] +pub fn panic_const_add_overflow() -> ! { + panic("attempt to add with overflow"); +} + /* * Code */ diff --git a/tests/run/operations.rs b/tests/run/operations.rs index 2d781670873f0..d697bd921cd11 100644 --- a/tests/run/operations.rs +++ b/tests/run/operations.rs @@ -207,6 +207,24 @@ impl Mul for isize { } } +#[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"); +} + +#[track_caller] +#[lang = "panic_const_mul_overflow"] +pub fn panic_const_mul_overflow() -> ! { + panic("attempt to multiply with overflow"); +} + /* * Code */ From 21b1b11981b1c679c32e723cefcc1eb76b0b9a62 Mon Sep 17 00:00:00 2001 From: Antoni Boucher Date: Wed, 26 Jun 2024 08:54:49 -0400 Subject: [PATCH 596/892] WIP: Implement dummy ThinLTO FIXME: This seems very slow. ==> Not sure anymore: compare with the master branch. --- build_system/src/config.rs | 5 +- src/back/lto.rs | 404 ++++++++++++++++++++++++++++++++++++- src/back/write.rs | 17 +- src/base.rs | 7 +- src/lib.rs | 47 ++--- 5 files changed, 438 insertions(+), 42 deletions(-) diff --git a/build_system/src/config.rs b/build_system/src/config.rs index 34c92a3485ed6..88e1424a2841d 100644 --- a/build_system/src/config.rs +++ b/build_system/src/config.rs @@ -426,9 +426,10 @@ impl ConfigInfo { // Since we don't support ThinLTO, disable LTO completely when not trying to do LTO. // TODO(antoyo): remove when we can handle ThinLTO. - if !env.contains_key(&"FAT_LTO".to_string()) { + // TODO: remove: + /*if !env.contains_key(&"FAT_LTO".to_string()) { rustflags.push("-Clto=off".to_string()); - } + }*/ // FIXME(antoyo): remove once the atomic shim is gone if os_name == "Darwin" { rustflags.extend_from_slice(&[ diff --git a/src/back/lto.rs b/src/back/lto.rs index ec70fbdddb0ff..5b6eec8555030 100644 --- a/src/back/lto.rs +++ b/src/back/lto.rs @@ -16,13 +16,14 @@ // /usr/bin/ld: warning: type of symbol `_RNvNvNvNtCs5JWOrf9uCus_5rayon11thread_pool19WORKER_THREAD_STATE7___getit5___KEY' changed from 1 to 6 in /tmp/ccKeUSiR.ltrans0.ltrans.o // /usr/bin/ld: warning: type of symbol `_RNvNvNvNvNtNtNtCsAj5i4SGTR7_3std4sync4mpmc5waker17current_thread_id5DUMMY7___getit5___KEY' changed from 1 to 6 in /tmp/ccKeUSiR.ltrans0.ltrans.o // /usr/bin/ld: warning: incremental linking of LTO and non-LTO objects; using -flinker-output=nolto-rel which will bypass whole program optimization -use std::ffi::CString; +use std::ffi::{CStr, CString}; use std::fs::{self, File}; use std::path::{Path, PathBuf}; +use std::sync::Arc; -use gccjit::OutputKind; +use gccjit::{Context, OutputKind}; use object::read::archive::ArchiveFile; -use rustc_codegen_ssa::back::lto::{LtoModuleCodegen, SerializedModule}; +use rustc_codegen_ssa::back::lto::{LtoModuleCodegen, SerializedModule, ThinModule, ThinShared}; use rustc_codegen_ssa::back::symbol_export; use rustc_codegen_ssa::back::write::{CodegenContext, FatLtoInput}; use rustc_codegen_ssa::traits::*; @@ -30,6 +31,7 @@ use rustc_codegen_ssa::{looks_like_rust_object_file, ModuleCodegen, ModuleKind}; use rustc_data_structures::memmap::Mmap; use rustc_errors::{DiagCtxtHandle, FatalError}; use rustc_hir::def_id::LOCAL_CRATE; +use rustc_middle::bug; use rustc_middle::dep_graph::WorkProduct; use rustc_middle::middle::exported_symbols::{SymbolExportInfo, SymbolExportLevel}; use rustc_session::config::{CrateType, Lto}; @@ -349,6 +351,400 @@ impl ModuleBuffer { impl ModuleBufferMethods for ModuleBuffer { fn data(&self) -> &[u8] { - unimplemented!("data not needed for GCC codegen"); + &[] } } + +/// Performs thin LTO by performing necessary global analysis and returning two +/// lists, one of the modules that need optimization and another for modules that +/// can simply be copied over from the incr. comp. cache. +pub(crate) fn run_thin( + cgcx: &CodegenContext, + modules: Vec<(String, ThinBuffer)>, + cached_modules: Vec<(SerializedModule, WorkProduct)>, +) -> Result<(Vec>, Vec), FatalError> { + let dcx = cgcx.create_dcx(); + 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 \ + is deferred to the linker" + ); + } + thin_lto( + cgcx, + &dcx, + modules, + lto_data.upstream_modules, + lto_data.tmp_path, + cached_modules, /*, &symbols_below_threshold*/ + ) +} + +pub(crate) fn prepare_thin( + module: ModuleCodegen, + _emit_summary: bool, +) -> (String, ThinBuffer) { + let name = module.name; + //let buffer = ThinBuffer::new(module.module_llvm.context, true, emit_summary); + let buffer = ThinBuffer::new(&module.module_llvm.context); + (name, buffer) +} + +/// Prepare "thin" LTO to get run on these modules. +/// +/// The general structure of ThinLTO is quite different from the structure of +/// "fat" LTO above. With "fat" LTO all LLVM modules in question are merged into +/// one giant LLVM module, and then we run more optimization passes over this +/// big module after internalizing most symbols. Thin LTO, on the other hand, +/// avoid this large bottleneck through more targeted optimization. +/// +/// At a high level Thin LTO looks like: +/// +/// 1. Prepare a "summary" of each LLVM module in question which describes +/// the values inside, cost of the values, etc. +/// 2. Merge the summaries of all modules in question into one "index" +/// 3. Perform some global analysis on this index +/// 4. For each module, use the index and analysis calculated previously to +/// perform local transformations on the module, for example inlining +/// small functions from other modules. +/// 5. Run thin-specific optimization passes over each module, and then code +/// generate everything at the end. +/// +/// The summary for each module is intended to be quite cheap, and the global +/// index is relatively quite cheap to create as well. As a result, the goal of +/// ThinLTO is to reduce the bottleneck on LTO and enable LTO to be used in more +/// situations. For example one cheap optimization is that we can parallelize +/// all codegen modules, easily making use of all the cores on a machine. +/// +/// With all that in mind, the function here is designed at specifically just +/// calculating the *index* for ThinLTO. This index will then be shared amongst +/// all of the `LtoModuleCodegen` units returned below and destroyed once +/// they all go out of scope. +fn thin_lto( + cgcx: &CodegenContext, + _dcx: &DiagCtxt, + modules: Vec<(String, ThinBuffer)>, + serialized_modules: Vec<(SerializedModule, CString)>, + tmp_path: TempDir, + cached_modules: Vec<(SerializedModule, WorkProduct)>, + //symbols_below_threshold: &[*const libc::c_char], +) -> Result<(Vec>, Vec), FatalError> { + let _timer = cgcx.prof.generic_activity("LLVM_thin_lto_global_analysis"); + info!("going for that thin, thin LTO"); + + /*let green_modules: FxHashMap<_, _> = + cached_modules.iter().map(|(_, wp)| (wp.cgu_name.clone(), wp.clone())).collect();*/ + + let full_scope_len = modules.len() + serialized_modules.len() + cached_modules.len(); + let mut thin_buffers = Vec::with_capacity(modules.len()); + let mut module_names = Vec::with_capacity(full_scope_len); + //let mut thin_modules = Vec::with_capacity(full_scope_len); + + for (i, (name, buffer)) in modules.into_iter().enumerate() { + info!("local module: {} - {}", i, name); + let cname = CString::new(name.as_bytes()).unwrap(); + /*thin_modules.push(llvm::ThinLTOModule { + identifier: cname.as_ptr(), + data: buffer.data().as_ptr(), + len: buffer.data().len(), + });*/ + thin_buffers.push(buffer); + module_names.push(cname); + } + + // FIXME: All upstream crates are deserialized internally in the + // function below to extract their summary and modules. Note that + // unlike the loop above we *must* decode and/or read something + // here as these are all just serialized files on disk. An + // improvement, however, to make here would be to store the + // module summary separately from the actual module itself. Right + // now this is store in one large bitcode file, and the entire + // file is deflate-compressed. We could try to bypass some of the + // decompression by storing the index uncompressed and only + // lazily decompressing the bytecode if necessary. + // + // Note that truly taking advantage of this optimization will + // likely be further down the road. We'd have to implement + // incremental ThinLTO first where we could actually avoid + // looking at upstream modules entirely sometimes (the contents, + // we must always unconditionally look at the index). + let mut serialized = Vec::with_capacity(serialized_modules.len() + cached_modules.len()); + + let cached_modules = + cached_modules.into_iter().map(|(sm, wp)| (sm, CString::new(wp.cgu_name).unwrap())); + + for (module, name) in serialized_modules.into_iter().chain(cached_modules) { + info!("upstream or cached module {:?}", name); + /*thin_modules.push(llvm::ThinLTOModule { + identifier: name.as_ptr(), + data: module.data().as_ptr(), + len: module.data().len(), + });*/ + + match module { + SerializedModule::Local(ref module_buffer) => { + let path = module_buffer.0.to_str().expect("path"); + let my_path = PathBuf::from(path); + //let exists = my_path.exists(); + //println!("Path: {:?}: {}", path, exists); + /*module.module_llvm.should_combine_object_files = true; + module + .module_llvm + .context + .add_driver_option(module_buffer.0.to_str().expect("path"));*/ + } + SerializedModule::FromRlib(_) => unimplemented!("from rlib"), + SerializedModule::FromUncompressedFile(_) => { + unimplemented!("from uncompressed file") + } + } + + serialized.push(module); + module_names.push(name); + } + + // Sanity check + //assert_eq!(thin_modules.len(), module_names.len()); + + // Delegate to the C++ bindings to create some data here. Once this is a + // tried-and-true interface we may wish to try to upstream some of this + // to LLVM itself, right now we reimplement a lot of what they do + // upstream... + /*let data = llvm::LLVMRustCreateThinLTOData( + thin_modules.as_ptr(), + thin_modules.len() as u32, + symbols_below_threshold.as_ptr(), + symbols_below_threshold.len() as u32, + ) + .ok_or_else(|| write::llvm_err(dcx, LlvmError::PrepareThinLtoContext))?; + */ + + let data = ThinData; //(Arc::new(tmp_path))/*(data)*/; + + info!("thin LTO data created"); + + /*let (key_map_path, prev_key_map, curr_key_map) = + if let Some(ref incr_comp_session_dir) = cgcx.incr_comp_session_dir { + let path = incr_comp_session_dir.join(THIN_LTO_KEYS_INCR_COMP_FILE_NAME); + // If the previous file was deleted, or we get an IO error + // reading the file, then we'll just use `None` as the + // prev_key_map, which will force the code to be recompiled. + let prev = + if path.exists() { ThinLTOKeysMap::load_from_file(&path).ok() } else { None }; + let curr = ThinLTOKeysMap::from_thin_lto_modules(&data, &thin_modules, &module_names); + (Some(path), prev, curr) + } + else { + // If we don't compile incrementally, we don't need to load the + // import data from LLVM. + assert!(green_modules.is_empty()); + let curr = ThinLTOKeysMap::default(); + (None, None, curr) + }; + info!("thin LTO cache key map loaded"); + info!("prev_key_map: {:#?}", prev_key_map); + info!("curr_key_map: {:#?}", curr_key_map);*/ + + // Throw our data in an `Arc` as we'll be sharing it across threads. We + // also put all memory referenced by the C++ data (buffers, ids, etc) + // into the arc as well. After this we'll create a thin module + // codegen per module in this data. + let shared = + Arc::new(ThinShared { data, thin_buffers, serialized_modules: serialized, module_names }); + + let copy_jobs = vec![]; + let mut opt_jobs = vec![]; + + info!("checking which modules can be-reused and which have to be re-optimized."); + for (module_index, module_name) in shared.module_names.iter().enumerate() { + let module_name = module_name_to_str(module_name); + /*if let (Some(prev_key_map), true) = + (prev_key_map.as_ref(), green_modules.contains_key(module_name)) + { + assert!(cgcx.incr_comp_session_dir.is_some()); + + // If a module exists in both the current and the previous session, + // and has the same LTO cache key in both sessions, then we can re-use it + if prev_key_map.keys.get(module_name) == curr_key_map.keys.get(module_name) { + let work_product = green_modules[module_name].clone(); + copy_jobs.push(work_product); + info!(" - {}: re-used", module_name); + assert!(cgcx.incr_comp_session_dir.is_some()); + continue; + } + }*/ + + info!(" - {}: re-compiled", module_name); + opt_jobs + .push(LtoModuleCodegen::Thin(ThinModule { shared: shared.clone(), idx: module_index })); + } + + // Save the current ThinLTO import information for the next compilation + // session, overwriting the previous serialized data (if any). + /*if let Some(path) = key_map_path { + if let Err(err) = curr_key_map.save_to_file(&path) { + return Err(write::llvm_err(dcx, LlvmError::WriteThinLtoKey { err })); + } + }*/ + + // NOTE: save the temporary directory used by LTO so that it gets deleted after linking instead + // of now. + //module.module_llvm.temp_dir = Some(tmp_path); + // TODO: save the directory so that it gets deleted later. + std::mem::forget(tmp_path); + + Ok((opt_jobs, copy_jobs)) +} + +pub unsafe fn optimize_thin_module( + thin_module: ThinModule, + _cgcx: &CodegenContext, +) -> Result, FatalError> { + //let dcx = cgcx.create_dcx(); + + //let module_name = &thin_module.shared.module_names[thin_module.idx]; + /*let tm_factory_config = TargetMachineFactoryConfig::new(cgcx, module_name.to_str().unwrap()); + let tm = (cgcx.tm_factory)(tm_factory_config).map_err(|e| write::llvm_err(&dcx, e))?;*/ + + // Right now the implementation we've got only works over serialized + // modules, so we create a fresh new LLVM context and parse the module + // into that context. One day, however, we may do this for upstream + // crates but for locally codegened modules we may be able to reuse + // that LLVM Context and Module. + //let llcx = llvm::LLVMRustContextCreate(cgcx.fewer_names); + //let llmod_raw = parse_module(llcx, module_name, thin_module.data(), &dcx)? as *const _; + let mut should_combine_object_files = false; + let context = match thin_module.shared.thin_buffers.get(thin_module.idx) { + Some(thin_buffer) => Arc::clone(&thin_buffer.context), + None => { + let context = Context::default(); + let len = thin_module.shared.thin_buffers.len(); + let module = &thin_module.shared.serialized_modules[thin_module.idx - len]; + match *module { + SerializedModule::Local(ref module_buffer) => { + let path = module_buffer.0.to_str().expect("path"); + + //let my_path = PathBuf::from(path); + //let exists = my_path.exists(); + //println!("Path2: {:?}: {}", path, exists); + + context.add_driver_option(path); + should_combine_object_files = true; + /*module.module_llvm.should_combine_object_files = true; + module + .module_llvm + .context + .add_driver_option(module_buffer.0.to_str().expect("path"));*/ + } + SerializedModule::FromRlib(_) => unimplemented!("from rlib"), + SerializedModule::FromUncompressedFile(_) => { + unimplemented!("from uncompressed file") + } + } + Arc::new(context) + } + }; + let module = ModuleCodegen { + module_llvm: GccContext { context, should_combine_object_files, temp_dir: None }, + name: thin_module.name().to_string(), + kind: ModuleKind::Regular, + }; + /*{ + let target = &*module.module_llvm.tm; + let llmod = module.module_llvm.llmod(); + save_temp_bitcode(cgcx, &module, "thin-lto-input"); + + // Up next comes the per-module local analyses that we do for Thin LTO. + // Each of these functions is basically copied from the LLVM + // implementation and then tailored to suit this implementation. Ideally + // each of these would be supported by upstream LLVM but that's perhaps + // a patch for another day! + // + // You can find some more comments about these functions in the LLVM + // bindings we've got (currently `PassWrapper.cpp`) + { + let _timer = + cgcx.prof.generic_activity_with_arg("LLVM_thin_lto_rename", thin_module.name()); + if !llvm::LLVMRustPrepareThinLTORename(thin_module.shared.data.0, llmod, target) { + return Err(write::llvm_err(&dcx, LlvmError::PrepareThinLtoModule)); + } + save_temp_bitcode(cgcx, &module, "thin-lto-after-rename"); + } + + { + let _timer = cgcx + .prof + .generic_activity_with_arg("LLVM_thin_lto_resolve_weak", thin_module.name()); + if !llvm::LLVMRustPrepareThinLTOResolveWeak(thin_module.shared.data.0, llmod) { + return Err(write::llvm_err(&dcx, LlvmError::PrepareThinLtoModule)); + } + save_temp_bitcode(cgcx, &module, "thin-lto-after-resolve"); + } + + { + let _timer = cgcx + .prof + .generic_activity_with_arg("LLVM_thin_lto_internalize", thin_module.name()); + if !llvm::LLVMRustPrepareThinLTOInternalize(thin_module.shared.data.0, llmod) { + return Err(write::llvm_err(&dcx, LlvmError::PrepareThinLtoModule)); + } + save_temp_bitcode(cgcx, &module, "thin-lto-after-internalize"); + } + + { + let _timer = + cgcx.prof.generic_activity_with_arg("LLVM_thin_lto_import", thin_module.name()); + if !llvm::LLVMRustPrepareThinLTOImport(thin_module.shared.data.0, llmod, target) { + return Err(write::llvm_err(&dcx, LlvmError::PrepareThinLtoModule)); + } + save_temp_bitcode(cgcx, &module, "thin-lto-after-import"); + } + + // Alright now that we've done everything related to the ThinLTO + // analysis it's time to run some optimizations! Here we use the same + // `run_pass_manager` as the "fat" LTO above except that we tell it to + // populate a thin-specific pass manager, which presumably LLVM treats a + // little differently. + { + info!("running thin lto passes over {}", module.name); + run_pass_manager(cgcx, &dcx, &mut module, true)?; + save_temp_bitcode(cgcx, &module, "thin-lto-after-pm"); + } + }*/ + Ok(module) +} + +pub struct ThinBuffer { + context: Arc>, +} + +// TODO: check if this makes sense to make ThinBuffer Send and Sync. +unsafe impl Send for ThinBuffer {} +unsafe impl Sync for ThinBuffer {} + +impl ThinBuffer { + pub fn new(context: &Arc>) -> Self { + Self { context: Arc::clone(context) } + } +} + +impl ThinBufferMethods for ThinBuffer { + fn data(&self) -> &[u8] { + &[] + } + + fn thin_link_data(&self) -> &[u8] { + unimplemented!(); + } +} + +pub struct ThinData; //(Arc); + +fn module_name_to_str(c_str: &CStr) -> &str { + c_str.to_str().unwrap_or_else(|e| { + bug!("Encountered non-utf8 GCC module name `{}`: {}", c_str.to_string_lossy(), e) + }) +} diff --git a/src/back/write.rs b/src/back/write.rs index b9c7f72d0b727..09d7e692a4430 100644 --- a/src/back/write.rs +++ b/src/back/write.rs @@ -31,6 +31,7 @@ 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. let fat_lto = env::var("EMBED_LTO_BITCODE").as_deref() == Ok("1"); let bc_out = cgcx.output_filenames.temp_path(OutputType::Bitcode, module_name); @@ -113,17 +114,20 @@ pub(crate) unsafe fn codegen( context.set_debug_info(true); context.dump_to_file(path, true); } - if should_combine_object_files && fat_lto { - context.add_command_line_option("-flto=auto"); - context.add_command_line_option("-flto-partition=one"); + if should_combine_object_files { + if fat_lto { + context.add_command_line_option("-flto=auto"); + context.add_command_line_option("-flto-partition=one"); + + // NOTE: without -fuse-linker-plugin, we get the following error: + // lto1: internal compiler error: decompressed stream: Destination buffer is too small + context.add_driver_option("-fuse-linker-plugin"); + } context.add_driver_option("-Wl,-r"); // NOTE: we need -nostdlib, otherwise, we get the following error: // /usr/bin/ld: cannot find -lgcc_s: No such file or directory context.add_driver_option("-nostdlib"); - // NOTE: without -fuse-linker-plugin, we get the following error: - // lto1: internal compiler error: decompressed stream: Destination buffer is too small - context.add_driver_option("-fuse-linker-plugin"); // 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( @@ -131,6 +135,7 @@ pub(crate) unsafe fn codegen( obj_out.to_str().expect("path to str"), ); } else { + //println!("Combining to object file"); context.compile_to_file( OutputKind::ObjectFile, obj_out.to_str().expect("path to str"), diff --git a/src/base.rs b/src/base.rs index 2a2d5741d1318..b2cf6fe51df8d 100644 --- a/src/base.rs +++ b/src/base.rs @@ -1,5 +1,6 @@ use std::collections::HashSet; use std::env; +use std::sync::Arc; use std::time::Instant; use gccjit::{FunctionType, GlobalKind}; @@ -205,7 +206,11 @@ pub fn compile_codegen_unit( ModuleCodegen { name: cgu_name.to_string(), - module_llvm: GccContext { context, should_combine_object_files: false, temp_dir: None }, + module_llvm: GccContext { + context: Arc::new(context), + should_combine_object_files: false, + temp_dir: None, + }, kind: ModuleKind::Regular, } } diff --git a/src/lib.rs b/src/lib.rs index d839385695511..3df48f96e8c4b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -4,7 +4,7 @@ * TODO(antoyo): support LTO (gcc's equivalent to Full LTO is -flto -flto-partition=one — https://documentation.suse.com/sbp/all/html/SBP-GCC-10/index.html). * For Thin LTO, this might be helpful: * In gcc 4.6 -fwhopr was removed and became default with -flto. The non-whopr path can still be executed via -flto-partition=none. - * Or the new incremental LTO? + * Or the new incremental LTO (https://www.phoronix.com/news/GCC-Incremental-LTO-Patches)? * * Maybe some missing optizations enabled by rustc's LTO is in there: https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html * Like -fipa-icf (should be already enabled) and maybe -fdevirtualize-at-ltrans. @@ -80,6 +80,8 @@ use std::sync::atomic::Ordering; use std::sync::Arc; use std::sync::Mutex; +use back::lto::ThinBuffer; +use back::lto::ThinData; use errors::LTONotSupported; #[cfg(not(feature = "master"))] use gccjit::CType; @@ -92,9 +94,7 @@ use rustc_codegen_ssa::back::write::{ CodegenContext, FatLtoInput, ModuleConfig, TargetMachineFactoryFn, }; use rustc_codegen_ssa::base::codegen_crate; -use rustc_codegen_ssa::traits::{ - CodegenBackend, ExtraBackendMethods, ThinBufferMethods, WriteBackendMethods, -}; +use rustc_codegen_ssa::traits::{CodegenBackend, ExtraBackendMethods, WriteBackendMethods}; use rustc_codegen_ssa::{CodegenResults, CompiledModule, ModuleCodegen}; use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::sync::IntoDynSyncSend; @@ -188,6 +188,7 @@ 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 {}); } @@ -293,7 +294,7 @@ impl ExtraBackendMethods for GccCodegenBackend { alloc_error_handler_kind: AllocatorKind, ) -> Self::Module { let mut mods = GccContext { - context: new_context(tcx), + context: Arc::new(new_context(tcx)), should_combine_object_files: false, temp_dir: None, }; @@ -323,20 +324,8 @@ impl ExtraBackendMethods for GccCodegenBackend { } } -pub struct ThinBuffer; - -impl ThinBufferMethods for ThinBuffer { - fn data(&self) -> &[u8] { - unimplemented!(); - } - - fn thin_link_data(&self) -> &[u8] { - unimplemented!(); - } -} - pub struct GccContext { - context: Context<'static>, + context: Arc>, 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, @@ -351,7 +340,7 @@ impl WriteBackendMethods for GccCodegenBackend { type TargetMachine = (); type TargetMachineError = (); type ModuleBuffer = ModuleBuffer; - type ThinData = (); + type ThinData = ThinData; type ThinBuffer = ThinBuffer; fn run_fat_lto( @@ -363,11 +352,11 @@ impl WriteBackendMethods for GccCodegenBackend { } fn run_thin_lto( - _cgcx: &CodegenContext, - _modules: Vec<(String, Self::ThinBuffer)>, - _cached_modules: Vec<(SerializedModule, WorkProduct)>, + cgcx: &CodegenContext, + modules: Vec<(String, Self::ThinBuffer)>, + cached_modules: Vec<(SerializedModule, WorkProduct)>, ) -> Result<(Vec>, Vec), FatalError> { - unimplemented!(); + back::lto::run_thin(cgcx, modules, cached_modules) } fn print_pass_timings(&self) { @@ -397,10 +386,10 @@ impl WriteBackendMethods for GccCodegenBackend { } unsafe fn optimize_thin( - _cgcx: &CodegenContext, - _thin: ThinModule, + cgcx: &CodegenContext, + thin: ThinModule, ) -> Result, FatalError> { - unimplemented!(); + back::lto::optimize_thin_module(thin, cgcx) } unsafe fn codegen( @@ -413,10 +402,10 @@ impl WriteBackendMethods for GccCodegenBackend { } fn prepare_thin( - _module: ModuleCodegen, - _emit_summary: bool, + module: ModuleCodegen, + emit_summary: bool, ) -> (String, Self::ThinBuffer) { - unimplemented!(); + back::lto::prepare_thin(module, emit_summary) } fn serialize_module(_module: ModuleCodegen) -> (String, Self::ModuleBuffer) { From bbc765b49b7c0d57a30476c2550303d46c75ade3 Mon Sep 17 00:00:00 2001 From: Antoni Boucher Date: Fri, 28 Jun 2024 14:00:45 -0400 Subject: [PATCH 597/892] Fix clippy warnings --- src/back/lto.rs | 14 +++++++------- src/base.rs | 4 ++-- src/lib.rs | 30 +++++++++++++++++++++++++----- 3 files changed, 34 insertions(+), 14 deletions(-) diff --git a/src/back/lto.rs b/src/back/lto.rs index 5b6eec8555030..4b31bfac5dd79 100644 --- a/src/back/lto.rs +++ b/src/back/lto.rs @@ -39,7 +39,7 @@ use tempfile::{tempdir, TempDir}; use crate::back::write::save_temp_bitcode; use crate::errors::{DynamicLinkingWithLTO, LtoBitcodeFromRlib, LtoDisallowed, LtoDylib}; -use crate::{to_gcc_opt_level, GccCodegenBackend, GccContext}; +use crate::{to_gcc_opt_level, GccCodegenBackend, GccContext, SyncContext}; /// We keep track of the computed LTO cache keys from the previous /// session to determine which CGUs we can reuse. @@ -485,9 +485,9 @@ fn thin_lto( });*/ match module { - SerializedModule::Local(ref module_buffer) => { - let path = module_buffer.0.to_str().expect("path"); - let my_path = PathBuf::from(path); + SerializedModule::Local(_) => { + //let path = module_buffer.0.to_str().expect("path"); + //let my_path = PathBuf::from(path); //let exists = my_path.exists(); //println!("Path: {:?}: {}", path, exists); /*module.module_llvm.should_combine_object_files = true; @@ -644,7 +644,7 @@ pub unsafe fn optimize_thin_module( unimplemented!("from uncompressed file") } } - Arc::new(context) + Arc::new(SyncContext::new(context)) } }; let module = ModuleCodegen { @@ -718,7 +718,7 @@ pub unsafe fn optimize_thin_module( } pub struct ThinBuffer { - context: Arc>, + context: Arc, } // TODO: check if this makes sense to make ThinBuffer Send and Sync. @@ -726,7 +726,7 @@ unsafe impl Send for ThinBuffer {} unsafe impl Sync for ThinBuffer {} impl ThinBuffer { - pub fn new(context: &Arc>) -> Self { + pub(crate) fn new(context: &Arc) -> Self { Self { context: Arc::clone(context) } } } diff --git a/src/base.rs b/src/base.rs index b2cf6fe51df8d..488757c448493 100644 --- a/src/base.rs +++ b/src/base.rs @@ -19,8 +19,8 @@ use rustc_target::spec::PanicStrategy; use crate::builder::Builder; use crate::context::CodegenCx; -use crate::GccContext; use crate::{gcc_util, new_context, LockedTargetInfo}; +use crate::{GccContext, SyncContext}; #[cfg(feature = "master")] pub fn visibility_to_gcc(linkage: Visibility) -> gccjit::Visibility { @@ -207,7 +207,7 @@ pub fn compile_codegen_unit( ModuleCodegen { name: cgu_name.to_string(), module_llvm: GccContext { - context: Arc::new(context), + context: Arc::new(SyncContext::new(context)), should_combine_object_files: false, temp_dir: None, }, diff --git a/src/lib.rs b/src/lib.rs index 3df48f96e8c4b..ce781b3f3ff79 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -73,6 +73,7 @@ mod type_of; use std::any::Any; use std::fmt::Debug; +use std::ops::Deref; #[cfg(not(feature = "master"))] use std::sync::atomic::AtomicBool; #[cfg(not(feature = "master"))] @@ -294,7 +295,7 @@ impl ExtraBackendMethods for GccCodegenBackend { alloc_error_handler_kind: AllocatorKind, ) -> Self::Module { let mut mods = GccContext { - context: Arc::new(new_context(tcx)), + context: Arc::new(SyncContext::new(new_context(tcx))), should_combine_object_files: false, temp_dir: None, }; @@ -325,15 +326,34 @@ impl ExtraBackendMethods for GccCodegenBackend { } pub struct GccContext { - context: Arc>, + context: Arc, 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, } -unsafe impl Send for GccContext {} -// FIXME(antoyo): that shouldn't be Sync. Parallel compilation is currently disabled with "-Zno-parallel-llvm". Try to disable it here. -unsafe impl Sync for GccContext {} +struct SyncContext { + context: Context<'static>, +} + +impl SyncContext { + fn new(context: Context<'static>) -> Self { + Self { context } + } +} + +impl Deref for SyncContext { + type Target = Context<'static>; + + fn deref(&self) -> &Self::Target { + &self.context + } +} + +unsafe impl Send for SyncContext {} +// FIXME(antoyo): that shouldn't be Sync. Parallel compilation is currently disabled with "-Zno-parallel-llvm". +// TODO: disable it here by returing false in CodegenBackend::supports_parallel(). +unsafe impl Sync for SyncContext {} impl WriteBackendMethods for GccCodegenBackend { type Module = GccContext; From 2ecab996f82a85b5aae078ef24880276426914fa Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 28 Jun 2024 20:45:02 +0200 Subject: [PATCH 598/892] Fix build failure in cfg-if --- build_system/src/test.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/build_system/src/test.rs b/build_system/src/test.rs index 0895dc6bff700..d39036c26a188 100644 --- a/build_system/src/test.rs +++ b/build_system/src/test.rs @@ -703,12 +703,16 @@ fn test_projects(env: &Env, args: &TestArg) -> Result<(), String> { //"https://github.com/rust-lang/cargo", // TODO: very slow, only run on master? ]; + let mut env = env.clone(); + let rustflags = + format!("{} --cap-lints allow", env.get("RUSTFLAGS").cloned().unwrap_or_default()); + env.insert("RUSTFLAGS".to_string(), rustflags); let run_tests = |projects_path, iter: &mut dyn Iterator| -> Result<(), String> { for project in iter { let clone_result = git_clone_root_dir(project, projects_path, true)?; let repo_path = Path::new(&clone_result.repo_dir); - run_cargo_command(&[&"build", &"--release"], Some(repo_path), env, args)?; - run_cargo_command(&[&"test"], Some(repo_path), env, args)?; + run_cargo_command(&[&"build", &"--release"], Some(repo_path), &env, args)?; + run_cargo_command(&[&"test"], Some(repo_path), &env, args)?; } Ok(()) From 606196b0cf901d02a19bc67f0c14047991eaed2a Mon Sep 17 00:00:00 2001 From: Antoni Boucher Date: Sun, 30 Jun 2024 09:49:19 -0400 Subject: [PATCH 599/892] Comment libgccjit 12 CI --- .github/workflows/gcc12.yml | 38 +++++++++++++++++++------------------ 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/.github/workflows/gcc12.yml b/.github/workflows/gcc12.yml index f7bb156049233..5977ed33c56ec 100644 --- a/.github/workflows/gcc12.yml +++ b/.github/workflows/gcc12.yml @@ -68,21 +68,23 @@ jobs: run: | ./y.sh prepare --only-libcore --libgccjit12-patches ./y.sh build --no-default-features --sysroot-panic-abort - cargo test --no-default-features - ./y.sh clean all - - - name: Prepare dependencies - run: | - git config --global user.email "user@example.com" - git config --global user.name "User" - ./y.sh prepare --libgccjit12-patches - - - 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 + # Uncomment when we no longer need to remove global variables. + #./y.sh build --sysroot --no-default-features --sysroot-panic-abort + #cargo test --no-default-features + #./y.sh clean all + + #- name: Prepare dependencies + #run: | + #git config --global user.email "user@example.com" + #git config --global user.name "User" + #./y.sh prepare --libgccjit12-patches + + #- 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 From cd014cda8c09afd88f6a9b8d75043c1d95bee734 Mon Sep 17 00:00:00 2001 From: Antoni Boucher Date: Tue, 2 Jul 2024 09:54:01 -0400 Subject: [PATCH 600/892] Replace the type of global variables instead of replacing them --- Cargo.lock | 4 ++-- libgccjit.version | 2 +- src/consts.rs | 10 ++-------- 3 files changed, 5 insertions(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ba6633bc2dcbd..cd693835ded1d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -80,7 +80,7 @@ dependencies = [ [[package]] name = "gccjit" version = "2.0.0" -source = "git+https://github.com/rust-lang/gccjit.rs#f1545d7c2c13e42d78eaac8032d49ab8f7d43b6e" +source = "git+https://github.com/rust-lang/gccjit.rs#328cb1b414f67dfa15162ba7a55ed01931f1b219" dependencies = [ "gccjit_sys", ] @@ -88,7 +88,7 @@ dependencies = [ [[package]] name = "gccjit_sys" version = "0.1.0" -source = "git+https://github.com/rust-lang/gccjit.rs#f1545d7c2c13e42d78eaac8032d49ab8f7d43b6e" +source = "git+https://github.com/rust-lang/gccjit.rs#328cb1b414f67dfa15162ba7a55ed01931f1b219" dependencies = [ "libc", ] diff --git a/libgccjit.version b/libgccjit.version index 71a61a4b8735f..23ca7f022155e 100644 --- a/libgccjit.version +++ b/libgccjit.version @@ -1 +1 @@ -272d0ccced960394fe6ff2b40b01610208cb4940 +341be3b7d7ac6976cfed8ed59da3573c040d0776 diff --git a/src/consts.rs b/src/consts.rs index 93c23440c57c1..50f3a4e0402dd 100644 --- a/src/consts.rs +++ b/src/consts.rs @@ -82,17 +82,11 @@ impl<'gcc, 'tcx> StaticMethods for CodegenCx<'gcc, 'tcx> { }; let is_thread_local = attrs.flags.contains(CodegenFnAttrFlags::THREAD_LOCAL); - let mut global = self.get_static_inner(def_id, val_llty); + let global = self.get_static_inner(def_id, val_llty); #[cfg(feature = "master")] if global.to_rvalue().get_type() != val_llty { - let instance = Instance::mono(self.tcx, def_id); - self.instances.borrow_mut().remove(&instance); - - global.remove(); - let name = self.tcx.symbol_name(instance).name; - self.globals.borrow_mut().remove(name); - global = self.get_static_inner(def_id, val_llty); + global.to_rvalue().set_type(val_llty); } set_global_alignment(self, global, alloc.align); From 4d3d0d492f25eddeb837e16b2773783c95f8933b Mon Sep 17 00:00:00 2001 From: Antoni Boucher Date: Tue, 2 Jul 2024 10:43:26 -0400 Subject: [PATCH 601/892] Fix intrinsic/generic-arithmetic-pass.rs test --- src/intrinsic/simd.rs | 10 ++++++---- tests/failing-ui-tests.txt | 30 ++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 4 deletions(-) diff --git a/src/intrinsic/simd.rs b/src/intrinsic/simd.rs index a54e7107a906e..01f207368e898 100644 --- a/src/intrinsic/simd.rs +++ b/src/intrinsic/simd.rs @@ -343,11 +343,13 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( .map(|i| { let index = bx.context.new_rvalue_from_long(bx.i32_type, i as i64); let value = bx.extract_element(vector, index).to_rvalue(); - if name == sym::simd_ctlz { - bx.count_leading_zeroes(value.get_type().get_size() as u64 * 8, value) + let value_type = value.get_type(); + let element = if name == sym::simd_ctlz { + bx.count_leading_zeroes(value_type.get_size() as u64 * 8, value) } else { - bx.count_trailing_zeroes(value.get_type().get_size() as u64 * 8, value) - } + bx.count_trailing_zeroes(value_type.get_size() as u64 * 8, value) + }; + bx.context.new_cast(None, element, value_type) }) .collect(); return Ok(bx.context.new_rvalue_from_vector(None, vector.get_type(), &elements)); diff --git a/tests/failing-ui-tests.txt b/tests/failing-ui-tests.txt index 7cc3b0dee0f50..dcaf60d990393 100644 --- a/tests/failing-ui-tests.txt +++ b/tests/failing-ui-tests.txt @@ -73,3 +73,33 @@ tests/ui/simd/repr_packed.rs tests/ui/async-await/in-trait/dont-project-to-specializable-projection.rs tests/ui/consts/try-operator.rs tests/ui/coroutine/unwind-abort-mix.rs +tests/ui/type-alias-impl-trait/rpit_tait_equality_in_canonical_query.rs +tests/ui/impl-trait/equality-in-canonical-query.rs +tests/ui/consts/issue-miri-1910.rs +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/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/kcfi-mangling.rs +tests/ui/statics/const_generics.rs +tests/ui/backtrace/dylib-dep.rs +tests/ui/errors/pic-linker.rs +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/backtrace/backtrace.rs From ee41c1904a39d485b11672064f67ffe0236105fc Mon Sep 17 00:00:00 2001 From: Antoni Boucher Date: Tue, 2 Jul 2024 12:33:09 -0400 Subject: [PATCH 602/892] Update to nightly-2024-07-02 --- rust-toolchain | 2 +- src/back/lto.rs | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/rust-toolchain b/rust-toolchain index 7a1806fe3c76f..3c83f4b4608de 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2024-06-18" +channel = "nightly-2024-07-02" components = ["rust-src", "rustc-dev", "llvm-tools-preview"] diff --git a/src/back/lto.rs b/src/back/lto.rs index 4b31bfac5dd79..19964176bcbd0 100644 --- a/src/back/lto.rs +++ b/src/back/lto.rs @@ -364,7 +364,8 @@ pub(crate) fn run_thin( cached_modules: Vec<(SerializedModule, WorkProduct)>, ) -> Result<(Vec>, Vec), FatalError> { let dcx = cgcx.create_dcx(); - let lto_data = prepare_lto(cgcx, &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() { @@ -375,7 +376,7 @@ pub(crate) fn run_thin( } thin_lto( cgcx, - &dcx, + dcx, modules, lto_data.upstream_modules, lto_data.tmp_path, @@ -425,7 +426,7 @@ pub(crate) fn prepare_thin( /// they all go out of scope. fn thin_lto( cgcx: &CodegenContext, - _dcx: &DiagCtxt, + _dcx: DiagCtxtHandle<'_>, modules: Vec<(String, ThinBuffer)>, serialized_modules: Vec<(SerializedModule, CString)>, tmp_path: TempDir, From 6099d97bcbad92e04b8e34f3c1df706e0de86eb6 Mon Sep 17 00:00:00 2001 From: Antoni Boucher Date: Tue, 2 Jul 2024 12:40:45 -0400 Subject: [PATCH 603/892] Fix rebase --- Cargo.lock | 4 ++-- src/builder.rs | 8 -------- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2ce9eb081eecc..cd693835ded1d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -80,7 +80,7 @@ dependencies = [ [[package]] name = "gccjit" version = "2.0.0" -source = "git+https://github.com/antoyo/gccjit.rs#f1545d7c2c13e42d78eaac8032d49ab8f7d43b6e" +source = "git+https://github.com/rust-lang/gccjit.rs#328cb1b414f67dfa15162ba7a55ed01931f1b219" dependencies = [ "gccjit_sys", ] @@ -88,7 +88,7 @@ dependencies = [ [[package]] name = "gccjit_sys" version = "0.1.0" -source = "git+https://github.com/antoyo/gccjit.rs#f1545d7c2c13e42d78eaac8032d49ab8f7d43b6e" +source = "git+https://github.com/rust-lang/gccjit.rs#328cb1b414f67dfa15162ba7a55ed01931f1b219" dependencies = [ "libc", ] diff --git a/src/builder.rs b/src/builder.rs index 1a3509bfca501..307348f595dc9 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -1705,14 +1705,6 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { fn zext(&mut self, value: RValue<'gcc>, dest_typ: Type<'gcc>) -> RValue<'gcc> { // FIXME(antoyo): this does not zero-extend. -<<<<<<< HEAD -======= - if value.get_type().is_bool() && dest_typ.is_i8(self.cx) { - // FIXME(antoyo): hack because base::from_immediate converts i1 to i8. - // Fix the code in codegen_ssa::base::from_immediate. - return value; - } ->>>>>>> master self.gcc_int_cast(value, dest_typ) } From 63d308bd765553f03c2684f6ea8a5ef39029f54d Mon Sep 17 00:00:00 2001 From: Antoni Boucher Date: Tue, 2 Jul 2024 12:43:41 -0400 Subject: [PATCH 604/892] Fix broken libgccjit 12 CI --- .github/workflows/gcc12.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/gcc12.yml b/.github/workflows/gcc12.yml index 5a8686e1288fa..b0775646c5c95 100644 --- a/.github/workflows/gcc12.yml +++ b/.github/workflows/gcc12.yml @@ -67,9 +67,10 @@ jobs: - name: Build run: | ./y.sh prepare --only-libcore --libgccjit12-patches - ./y.sh build --sysroot --no-default-features --sysroot-panic-abort + ./y.sh build --no-default-features --sysroot-panic-abort # Uncomment when we no longer need to remove global variables. #./y.sh build --sysroot --no-default-features --sysroot-panic-abort + #./y.sh build --sysroot --no-default-features --sysroot-panic-abort #cargo test --no-default-features #./y.sh clean all From 59de4fa99191ba324e7aafc7666b10a125974bc5 Mon Sep 17 00:00:00 2001 From: Antoni Boucher Date: Fri, 28 Jun 2024 12:51:18 -0400 Subject: [PATCH 605/892] Fix type of intrinsics --- example/example.rs | 6 +++--- src/intrinsic/mod.rs | 31 +++++++++++++++---------------- 2 files changed, 18 insertions(+), 19 deletions(-) diff --git a/example/example.rs b/example/example.rs index 7c21b73b630e8..30e3c3c30c220 100644 --- a/example/example.rs +++ b/example/example.rs @@ -154,9 +154,9 @@ fn array_as_slice(arr: &[u8; 3]) -> &[u8] { } // FIXME: fix the intrinsic implementation to work with the new ->u32 signature -// unsafe fn use_ctlz_nonzero(a: u16) -> u32 { -// intrinsics::ctlz_nonzero(a) -// } +unsafe fn use_ctlz_nonzero(a: u16) -> u32 { + intrinsics::ctlz_nonzero(a) +} fn ptr_as_usize(ptr: *const u8) -> usize { ptr as usize diff --git a/src/intrinsic/mod.rs b/src/intrinsic/mod.rs index 864bc98a4b7b9..a739e6ff3fcba 100644 --- a/src/intrinsic/mod.rs +++ b/src/intrinsic/mod.rs @@ -220,12 +220,12 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'a, 'gcc, 'tcx> { let after_block = func.new_block("after"); let arg = args[0].immediate(); - let result = func.new_local(None, arg.get_type(), "zeros"); + let result = func.new_local(None, self.u32_type, "zeros"); let zero = self.cx.gcc_zero(arg.get_type()); let cond = self.gcc_icmp(IntPredicate::IntEQ, arg, zero); self.llbb().end_with_conditional(None, cond, then_block, else_block); - let zero_result = self.cx.gcc_uint(arg.get_type(), width); + let zero_result = self.cx.gcc_uint(self.u32_type, width); then_block.add_assignment(None, result, zero_result); then_block.end_with_jump(None, after_block); @@ -709,6 +709,7 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { fn count_leading_zeroes(&mut self, width: u64, arg: RValue<'gcc>) -> RValue<'gcc> { // TODO(antoyo): use width? let arg_type = arg.get_type(); + let result_type = self.u32_type; let count_leading_zeroes = // TODO(antoyo): write a new function Type::is_compatible_with(&Type) and use it here // instead of using is_uint(). @@ -766,7 +767,7 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { let res = self.context.new_array_access(self.location, result, index); - return self.gcc_int_cast(res.to_rvalue(), arg_type); + return self.gcc_int_cast(res.to_rvalue(), result_type); } else { let count_leading_zeroes = self.context.get_builtin_function("__builtin_clzll"); @@ -774,22 +775,22 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { let diff = self.ulonglong_type.get_size() as i64 - arg_type.get_size() as i64; let diff = self.context.new_rvalue_from_long(self.int_type, diff * 8); let res = self.context.new_call(self.location, count_leading_zeroes, &[arg]) - diff; - return self.context.new_cast(self.location, res, arg_type); + return self.context.new_cast(self.location, res, result_type); }; let count_leading_zeroes = self.context.get_builtin_function(count_leading_zeroes); let res = self.context.new_call(self.location, count_leading_zeroes, &[arg]); - self.context.new_cast(self.location, res, arg_type) + self.context.new_cast(self.location, res, result_type) } fn count_trailing_zeroes(&mut self, _width: u64, arg: RValue<'gcc>) -> RValue<'gcc> { - let result_type = arg.get_type(); - let arg = if result_type.is_signed(self.cx) { - let new_type = result_type.to_unsigned(self.cx); + let arg_type = arg.get_type(); + let result_type = self.u32_type; + let arg = if arg_type.is_signed(self.cx) { + let new_type = arg_type.to_unsigned(self.cx); self.gcc_int_cast(arg, new_type) } else { arg }; - let arg_type = arg.get_type(); let (count_trailing_zeroes, expected_type) = // TODO(antoyo): write a new function Type::is_compatible_with(&Type) and use it here // instead of using is_uint(). @@ -874,14 +875,12 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { fn pop_count(&mut self, value: RValue<'gcc>) -> RValue<'gcc> { // TODO(antoyo): use the optimized version with fewer operations. - let result_type = value.get_type(); - let value_type = result_type.to_unsigned(self.cx); + let result_type = self.u32_type; + let arg_type = value.get_type(); + let value_type = arg_type.to_unsigned(self.cx); - let value = if result_type.is_signed(self.cx) { - self.gcc_int_cast(value, value_type) - } else { - value - }; + let value = + if arg_type.is_signed(self.cx) { self.gcc_int_cast(value, value_type) } else { value }; // only break apart 128-bit ints if they're not natively supported // TODO(antoyo): remove this if/when native 128-bit integers land in libgccjit From 4b0b97f66ddf36525b844a9c0c775db9f980248f Mon Sep 17 00:00:00 2001 From: Ana Hobden Date: Tue, 2 Jul 2024 10:09:40 -0700 Subject: [PATCH 606/892] Give remote-test-client a longer timeout --- src/tools/remote-test-client/src/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/remote-test-client/src/main.rs b/src/tools/remote-test-client/src/main.rs index dd2c09c430b61..42de3caf5474d 100644 --- a/src/tools/remote-test-client/src/main.rs +++ b/src/tools/remote-test-client/src/main.rs @@ -71,7 +71,7 @@ fn spawn_emulator(target: &str, server: &Path, tmpdir: &Path, rootfs: Option Date: Tue, 2 Jul 2024 13:33:26 -0400 Subject: [PATCH 607/892] Ignore a stdarch test that will fail until the stdarch version in rustc is updated --- .github/workflows/stdarch.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/stdarch.yml b/.github/workflows/stdarch.yml index 20341ae53d7ee..e24b25b73690f 100644 --- a/.github/workflows/stdarch.yml +++ b/.github/workflows/stdarch.yml @@ -95,4 +95,5 @@ jobs: if: ${{ matrix.cargo_runner }} run: | # FIXME: these tests fail when the sysroot is compiled with LTO because of a missing symbol in proc-macro. - STDARCH_TEST_EVERYTHING=1 CHANNEL=release CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_RUNNER="${{ matrix.cargo_runner }}" TARGET=x86_64-unknown-linux-gnu CG_RUSTFLAGS="-Ainternal_features" ./y.sh cargo test --manifest-path build/build_sysroot/sysroot_src/library/stdarch/Cargo.toml -- --skip rtm --skip tbm --skip sse4a + # TODO: remove --skip test_mm512_stream_ps when stdarch is updated in rustc. + STDARCH_TEST_EVERYTHING=1 CHANNEL=release CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_RUNNER="${{ matrix.cargo_runner }}" TARGET=x86_64-unknown-linux-gnu CG_RUSTFLAGS="-Ainternal_features" ./y.sh cargo test --manifest-path build/build_sysroot/sysroot_src/library/stdarch/Cargo.toml -- --skip rtm --skip tbm --skip sse4a --skip test_mm512_stream_ps From fc2eee58d2ff933b6236e33ad60bc03f84966fad Mon Sep 17 00:00:00 2001 From: Antoni Boucher Date: Tue, 2 Jul 2024 13:37:34 -0400 Subject: [PATCH 608/892] Ignore more tests --- .github/workflows/failures.yml | 4 ++++ tests/failing-ui-tests.txt | 1 + 2 files changed, 5 insertions(+) diff --git a/.github/workflows/failures.yml b/.github/workflows/failures.yml index 66129f805d4c8..e5d94767fe7d7 100644 --- a/.github/workflows/failures.yml +++ b/.github/workflows/failures.yml @@ -94,12 +94,16 @@ jobs: 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 rg --text "test result" output_log >> $GITHUB_STEP_SUMMARY - name: Run failing ui pattern tests for ICE + # TODO: re-enable those tests for libgccjit 12. + 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 diff --git a/tests/failing-ui-tests.txt b/tests/failing-ui-tests.txt index 9672054cdad05..ce867be7390c9 100644 --- a/tests/failing-ui-tests.txt +++ b/tests/failing-ui-tests.txt @@ -93,3 +93,4 @@ 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/backtrace/backtrace.rs +tests/ui/lifetimes/tail-expr-lock-poisoning.rs From c96bec1860f6a95c045e76a3a456495d7c1dc21f Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 2 Jul 2024 21:03:13 +0200 Subject: [PATCH 609/892] use let-else to avoid rightwards drift --- src/tools/miri/src/shims/unix/fd.rs | 45 ++++++++++++++--------------- 1 file changed, 21 insertions(+), 24 deletions(-) diff --git a/src/tools/miri/src/shims/unix/fd.rs b/src/tools/miri/src/shims/unix/fd.rs index 87e20954a70a1..7f6a097810350 100644 --- a/src/tools/miri/src/shims/unix/fd.rs +++ b/src/tools/miri/src/shims/unix/fd.rs @@ -276,29 +276,27 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn dup(&mut self, old_fd: i32) -> InterpResult<'tcx, i32> { let this = self.eval_context_mut(); - match this.machine.fds.dup(old_fd) { - Some(dup_fd) => Ok(this.machine.fds.insert_fd_with_min_fd(dup_fd, 0)), - None => this.fd_not_found(), - } + let Some(dup_fd) = this.machine.fds.dup(old_fd) else { + return this.fd_not_found(); + }; + Ok(this.machine.fds.insert_fd_with_min_fd(dup_fd, 0)) } fn dup2(&mut self, old_fd: i32, new_fd: i32) -> InterpResult<'tcx, i32> { let this = self.eval_context_mut(); - match this.machine.fds.dup(old_fd) { - Some(dup_fd) => { - if new_fd != old_fd { - // Close new_fd if it is previously opened. - // If old_fd and new_fd point to the same description, then `dup_fd` ensures we keep the underlying file description alive. - if let Some(file_descriptor) = this.machine.fds.fds.insert(new_fd, dup_fd) { - // Ignore close error (not interpreter's) according to dup2() doc. - file_descriptor.close(this.machine.communicate())?.ok(); - } - } - Ok(new_fd) + let Some(dup_fd) = this.machine.fds.dup(old_fd) else { + return this.fd_not_found(); + }; + if new_fd != old_fd { + // Close new_fd if it is previously opened. + // If old_fd and new_fd point to the same description, then `dup_fd` ensures we keep the underlying file description alive. + if let Some(file_descriptor) = this.machine.fds.fds.insert(new_fd, dup_fd) { + // Ignore close error (not interpreter's) according to dup2() doc. + file_descriptor.close(this.machine.communicate())?.ok(); } - None => this.fd_not_found(), } + Ok(new_fd) } fn fcntl(&mut self, args: &[OpTy<'tcx>]) -> InterpResult<'tcx, i32> { @@ -362,14 +360,13 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let fd = this.read_scalar(fd_op)?.to_i32()?; - Ok(Scalar::from_i32(if let Some(file_descriptor) = this.machine.fds.remove(fd) { - let result = file_descriptor.close(this.machine.communicate())?; - // return `0` if close is successful - let result = result.map(|()| 0i32); - this.try_unwrap_io_result(result)? - } else { - this.fd_not_found()? - })) + let Some(file_descriptor) = this.machine.fds.remove(fd) else { + return Ok(Scalar::from_i32(this.fd_not_found()?)); + }; + let result = file_descriptor.close(this.machine.communicate())?; + // return `0` if close is successful + let result = result.map(|()| 0i32); + Ok(Scalar::from_i32(this.try_unwrap_io_result(result)?)) } /// Function used when a file descriptor does not exist. It returns `Ok(-1)`and sets From 41b98da42d0500e38b9dd85c82110ba177ac4de1 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 2 Jul 2024 21:05:22 +0200 Subject: [PATCH 610/892] Miri function identity hack: account for possible inlining --- .../rustc_codegen_cranelift/src/constant.rs | 8 +- compiler/rustc_codegen_gcc/src/common.rs | 2 +- compiler/rustc_codegen_llvm/src/common.rs | 4 +- .../rustc_const_eval/src/interpret/memory.rs | 14 ++-- .../src/interpret/validity.rs | 2 +- .../rustc_middle/src/mir/interpret/mod.rs | 73 +++++++++++++------ compiler/rustc_middle/src/mir/pretty.rs | 2 +- compiler/rustc_middle/src/ty/print/pretty.rs | 4 +- compiler/rustc_monomorphize/src/collector.rs | 8 +- compiler/rustc_passes/src/reachable.rs | 2 +- .../rustc_smir/src/rustc_smir/convert/mir.rs | 2 +- src/tools/miri/src/shims/backtrace.rs | 2 +- .../miri/tests/pass/function_pointers.rs | 3 +- .../miri/tests/pass/issues/issue-91636.rs | 1 + 14 files changed, 80 insertions(+), 47 deletions(-) diff --git a/compiler/rustc_codegen_cranelift/src/constant.rs b/compiler/rustc_codegen_cranelift/src/constant.rs index 87c5da3b7c3ed..9f7b95261d528 100644 --- a/compiler/rustc_codegen_cranelift/src/constant.rs +++ b/compiler/rustc_codegen_cranelift/src/constant.rs @@ -155,7 +155,7 @@ pub(crate) fn codegen_const_value<'tcx>( fx.bcx.ins().global_value(fx.pointer_type, local_data_id) } } - GlobalAlloc::Function(instance) => { + GlobalAlloc::Function { instance, .. } => { let func_id = crate::abi::import_function(fx.tcx, fx.module, instance); let local_func_id = fx.module.declare_func_in_func(func_id, &mut fx.bcx.func); @@ -351,7 +351,9 @@ fn define_all_allocs(tcx: TyCtxt<'_>, module: &mut dyn Module, cx: &mut Constant TodoItem::Alloc(alloc_id) => { let alloc = match tcx.global_alloc(alloc_id) { GlobalAlloc::Memory(alloc) => alloc, - GlobalAlloc::Function(_) | GlobalAlloc::Static(_) | GlobalAlloc::VTable(..) => { + GlobalAlloc::Function { .. } + | GlobalAlloc::Static(_) + | GlobalAlloc::VTable(..) => { unreachable!() } }; @@ -415,7 +417,7 @@ fn define_all_allocs(tcx: TyCtxt<'_>, module: &mut dyn Module, cx: &mut Constant let reloc_target_alloc = tcx.global_alloc(alloc_id); let data_id = match reloc_target_alloc { - GlobalAlloc::Function(instance) => { + GlobalAlloc::Function { instance, .. } => { assert_eq!(addend, 0); let func_id = crate::abi::import_function(tcx, module, instance.polymorphize(tcx)); diff --git a/compiler/rustc_codegen_gcc/src/common.rs b/compiler/rustc_codegen_gcc/src/common.rs index 230fe4f5871e8..fa8a1ec037c5c 100644 --- a/compiler/rustc_codegen_gcc/src/common.rs +++ b/compiler/rustc_codegen_gcc/src/common.rs @@ -220,7 +220,7 @@ impl<'gcc, 'tcx> ConstMethods<'tcx> for CodegenCx<'gcc, 'tcx> { } value } - GlobalAlloc::Function(fn_instance) => self.get_fn_addr(fn_instance), + GlobalAlloc::Function { instance, .. } => self.get_fn_addr(instance), GlobalAlloc::VTable(ty, trait_ref) => { let alloc = self .tcx diff --git a/compiler/rustc_codegen_llvm/src/common.rs b/compiler/rustc_codegen_llvm/src/common.rs index d42c6ed827aec..fe64649cf70fb 100644 --- a/compiler/rustc_codegen_llvm/src/common.rs +++ b/compiler/rustc_codegen_llvm/src/common.rs @@ -289,8 +289,8 @@ impl<'ll, 'tcx> ConstMethods<'tcx> for CodegenCx<'ll, 'tcx> { (value, AddressSpace::DATA) } } - GlobalAlloc::Function(fn_instance) => ( - self.get_fn_addr(fn_instance.polymorphize(self.tcx)), + GlobalAlloc::Function { instance, .. } => ( + self.get_fn_addr(instance.polymorphize(self.tcx)), self.data_layout().instruction_address_space, ), GlobalAlloc::VTable(ty, trait_ref) => { diff --git a/compiler/rustc_const_eval/src/interpret/memory.rs b/compiler/rustc_const_eval/src/interpret/memory.rs index 9d0c490822561..36fe8dfdd29b7 100644 --- a/compiler/rustc_const_eval/src/interpret/memory.rs +++ b/compiler/rustc_const_eval/src/interpret/memory.rs @@ -308,7 +308,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { let Some((alloc_kind, mut alloc)) = self.memory.alloc_map.remove(&alloc_id) else { // Deallocating global memory -- always an error return Err(match self.tcx.try_get_global_alloc(alloc_id) { - Some(GlobalAlloc::Function(..)) => { + Some(GlobalAlloc::Function { .. }) => { err_ub_custom!( fluent::const_eval_invalid_dealloc, alloc_id = alloc_id, @@ -555,7 +555,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { // Memory of a constant or promoted or anonymous memory referenced by a static. (mem, None) } - Some(GlobalAlloc::Function(..)) => throw_ub!(DerefFunctionPointer(id)), + Some(GlobalAlloc::Function { .. }) => throw_ub!(DerefFunctionPointer(id)), Some(GlobalAlloc::VTable(..)) => throw_ub!(DerefVTablePointer(id)), None => throw_ub!(PointerUseAfterFree(id, CheckInAllocMsg::MemoryAccessTest)), Some(GlobalAlloc::Static(def_id)) => { @@ -828,7 +828,9 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { let alloc = alloc.inner(); (alloc.size(), alloc.align, AllocKind::LiveData) } - Some(GlobalAlloc::Function(_)) => bug!("We already checked function pointers above"), + Some(GlobalAlloc::Function { .. }) => { + bug!("We already checked function pointers above") + } Some(GlobalAlloc::VTable(..)) => { // No data to be accessed here. But vtables are pointer-aligned. return (Size::ZERO, self.tcx.data_layout.pointer_align.abi, AllocKind::VTable); @@ -865,7 +867,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { Some(FnVal::Other(*extra)) } else { match self.tcx.try_get_global_alloc(id) { - Some(GlobalAlloc::Function(instance)) => Some(FnVal::Instance(instance)), + Some(GlobalAlloc::Function { instance, .. }) => Some(FnVal::Instance(instance)), _ => None, } } @@ -1056,8 +1058,8 @@ impl<'a, 'tcx, M: Machine<'tcx>> std::fmt::Debug for DumpAllocs<'a, 'tcx, M> { alloc.inner(), )?; } - Some(GlobalAlloc::Function(func)) => { - write!(fmt, " (fn: {func})")?; + Some(GlobalAlloc::Function { instance, .. }) => { + write!(fmt, " (fn: {instance})")?; } Some(GlobalAlloc::VTable(ty, Some(trait_ref))) => { write!(fmt, " (vtable: impl {trait_ref} for {ty})")?; diff --git a/compiler/rustc_const_eval/src/interpret/validity.rs b/compiler/rustc_const_eval/src/interpret/validity.rs index add48e1b186cb..7fea061766666 100644 --- a/compiler/rustc_const_eval/src/interpret/validity.rs +++ b/compiler/rustc_const_eval/src/interpret/validity.rs @@ -745,7 +745,7 @@ fn mutability<'tcx>(ecx: &InterpCx<'tcx, impl Machine<'tcx>>, alloc_id: AllocId) } } GlobalAlloc::Memory(alloc) => alloc.inner().mutability, - GlobalAlloc::Function(..) | GlobalAlloc::VTable(..) => { + GlobalAlloc::Function { .. } | GlobalAlloc::VTable(..) => { // These are immutable, we better don't allow mutable pointers here. Mutability::Not } diff --git a/compiler/rustc_middle/src/mir/interpret/mod.rs b/compiler/rustc_middle/src/mir/interpret/mod.rs index 16093cfca6add..4e95e600b5ab9 100644 --- a/compiler/rustc_middle/src/mir/interpret/mod.rs +++ b/compiler/rustc_middle/src/mir/interpret/mod.rs @@ -18,6 +18,7 @@ use smallvec::{smallvec, SmallVec}; use tracing::{debug, trace}; use rustc_ast::LitKind; +use rustc_attr::InlineAttr; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::sync::{HashMapExt, Lock}; use rustc_errors::ErrorGuaranteed; @@ -134,10 +135,11 @@ pub fn specialized_encode_alloc_id<'tcx, E: TyEncoder>>( AllocDiscriminant::Alloc.encode(encoder); alloc.encode(encoder); } - GlobalAlloc::Function(fn_instance) => { - trace!("encoding {:?} with {:#?}", alloc_id, fn_instance); + GlobalAlloc::Function { instance, unique } => { + trace!("encoding {:?} with {:#?}", alloc_id, instance); AllocDiscriminant::Fn.encode(encoder); - fn_instance.encode(encoder); + instance.encode(encoder); + unique.encode(encoder); } GlobalAlloc::VTable(ty, poly_trait_ref) => { trace!("encoding {:?} with {ty:#?}, {poly_trait_ref:#?}", alloc_id); @@ -285,7 +287,12 @@ impl<'s> AllocDecodingSession<'s> { trace!("creating fn alloc ID"); let instance = ty::Instance::decode(decoder); trace!("decoded fn alloc instance: {:?}", instance); - let alloc_id = decoder.interner().reserve_and_set_fn_alloc(instance); + let unique = bool::decode(decoder); + // Here we cannot call `reserve_and_set_fn_alloc` as that would use a query, which + // is not possible in this context. That's why the allocation stores + // whether it is unique or not. + let alloc_id = + decoder.interner().reserve_and_set_fn_alloc_internal(instance, unique); alloc_id } AllocDiscriminant::VTable => { @@ -323,7 +330,12 @@ impl<'s> AllocDecodingSession<'s> { #[derive(Debug, Clone, Eq, PartialEq, Hash, TyDecodable, TyEncodable, HashStable)] pub enum GlobalAlloc<'tcx> { /// The alloc ID is used as a function pointer. - Function(Instance<'tcx>), + Function { + instance: Instance<'tcx>, + /// Stores whether this instance is unique, i.e. all pointers to this function use the same + /// alloc ID. + unique: bool, + }, /// This alloc ID points to a symbolic (not-reified) vtable. VTable(Ty<'tcx>, Option>), /// The alloc ID points to a "lazy" static variable that did not get computed (yet). @@ -349,7 +361,7 @@ impl<'tcx> GlobalAlloc<'tcx> { #[inline] pub fn unwrap_fn(&self) -> Instance<'tcx> { match *self { - GlobalAlloc::Function(instance) => instance, + GlobalAlloc::Function { instance, .. } => instance, _ => bug!("expected function, got {:?}", self), } } @@ -368,7 +380,7 @@ impl<'tcx> GlobalAlloc<'tcx> { #[inline] pub fn address_space(&self, cx: &impl HasDataLayout) -> AddressSpace { match self { - GlobalAlloc::Function(..) => cx.data_layout().instruction_address_space, + GlobalAlloc::Function { .. } => cx.data_layout().instruction_address_space, GlobalAlloc::Static(..) | GlobalAlloc::Memory(..) | GlobalAlloc::VTable(..) => { AddressSpace::DATA } @@ -426,7 +438,7 @@ impl<'tcx> TyCtxt<'tcx> { fn reserve_and_set_dedup(self, alloc: GlobalAlloc<'tcx>) -> AllocId { let mut alloc_map = self.alloc_map.lock(); match alloc { - GlobalAlloc::Function(..) | GlobalAlloc::Static(..) | GlobalAlloc::VTable(..) => {} + GlobalAlloc::Function { .. } | GlobalAlloc::Static(..) | GlobalAlloc::VTable(..) => {} GlobalAlloc::Memory(..) => bug!("Trying to dedup-reserve memory with real data!"), } if let Some(&alloc_id) = alloc_map.dedup.get(&alloc) { @@ -445,30 +457,45 @@ impl<'tcx> TyCtxt<'tcx> { self.reserve_and_set_dedup(GlobalAlloc::Static(static_id)) } + /// Generates an `AllocId` for a function. The caller must already have decided whether this + /// function obtains a unique AllocId or gets de-duplicated via the cache. + fn reserve_and_set_fn_alloc_internal(self, instance: Instance<'tcx>, unique: bool) -> AllocId { + let alloc = GlobalAlloc::Function { instance, unique }; + if unique { + // Deduplicate. + self.reserve_and_set_dedup(alloc) + } else { + // Get a fresh ID. + let mut alloc_map = self.alloc_map.lock(); + let id = alloc_map.reserve(); + alloc_map.alloc_map.insert(id, alloc); + id + } + } + /// Generates an `AllocId` for a function. Depending on the function type, /// this might get deduplicated or assigned a new ID each time. pub fn reserve_and_set_fn_alloc(self, instance: Instance<'tcx>) -> AllocId { // Functions cannot be identified by pointers, as asm-equal functions can get deduplicated // by the linker (we set the "unnamed_addr" attribute for LLVM) and functions can be - // duplicated across crates. - // We thus generate a new `AllocId` for every mention of a function. This means that - // `main as fn() == main as fn()` is false, while `let x = main as fn(); x == x` is true. - // However, formatting code relies on function identity (see #58320), so we only do - // this for generic functions. Lifetime parameters are ignored. + // duplicated across crates. We thus generate a new `AllocId` for every mention of a + // function. This means that `main as fn() == main as fn()` is false, while `let x = main as + // fn(); x == x` is true. However, as a quality-of-life feature it can be useful to identify + // certain functions uniquely, e.g. for backtraces. So we identify whether codegen will + // actually emit duplicate functions. It does that when they have non-lifetime generics, or + // when they can be inlined. All other functions are given a unique address. + // This is not a stable guarantee! The `inline` attribute is a hint and cannot be relied + // upon for anything. But if we don't do this, backtraces look terrible. let is_generic = instance .args .into_iter() .any(|kind| !matches!(kind.unpack(), GenericArgKind::Lifetime(_))); - if is_generic { - // Get a fresh ID. - let mut alloc_map = self.alloc_map.lock(); - let id = alloc_map.reserve(); - alloc_map.alloc_map.insert(id, GlobalAlloc::Function(instance)); - id - } else { - // Deduplicate. - self.reserve_and_set_dedup(GlobalAlloc::Function(instance)) - } + let can_be_inlined = match self.codegen_fn_attrs(instance.def_id()).inline { + InlineAttr::Never => false, + _ => true, + }; + let unique = !is_generic && !can_be_inlined; + self.reserve_and_set_fn_alloc_internal(instance, unique) } /// Generates an `AllocId` for a (symbolic, not-reified) vtable. Will get deduplicated. diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs index 4657f4dcf8132..4453ce44b0371 100644 --- a/compiler/rustc_middle/src/mir/pretty.rs +++ b/compiler/rustc_middle/src/mir/pretty.rs @@ -1449,7 +1449,7 @@ pub fn write_allocations<'tcx>( // This can't really happen unless there are bugs, but it doesn't cost us anything to // gracefully handle it and allow buggy rustc to be debugged via allocation printing. None => write!(w, " (deallocated)")?, - Some(GlobalAlloc::Function(inst)) => write!(w, " (fn: {inst})")?, + Some(GlobalAlloc::Function { instance, .. }) => write!(w, " (fn: {instance})")?, Some(GlobalAlloc::VTable(ty, Some(trait_ref))) => { write!(w, " (vtable: impl {trait_ref} for {ty})")? } diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 19700353f5944..3f08ab33e1052 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -1667,7 +1667,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { Some(GlobalAlloc::Static(def_id)) => { p!(write("", def_id)) } - Some(GlobalAlloc::Function(_)) => p!(""), + Some(GlobalAlloc::Function { .. }) => p!(""), Some(GlobalAlloc::VTable(..)) => p!(""), None => p!(""), } @@ -1679,7 +1679,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { ty::FnPtr(_) => { // FIXME: We should probably have a helper method to share code with the "Byte strings" // printing above (which also has to handle pointers to all sorts of things). - if let Some(GlobalAlloc::Function(instance)) = + if let Some(GlobalAlloc::Function { instance, .. }) = self.tcx().try_get_global_alloc(prov.alloc_id()) { self.typed_value( diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index 235743fccc89e..ec16b716c109c 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -1223,10 +1223,10 @@ fn collect_alloc<'tcx>(tcx: TyCtxt<'tcx>, alloc_id: AllocId, output: &mut MonoIt }); } } - GlobalAlloc::Function(fn_instance) => { - if should_codegen_locally(tcx, fn_instance) { - trace!("collecting {:?} with {:#?}", alloc_id, fn_instance); - output.push(create_fn_mono_item(tcx, fn_instance, DUMMY_SP)); + GlobalAlloc::Function { instance, .. } => { + if should_codegen_locally(tcx, instance) { + trace!("collecting {:?} with {:#?}", alloc_id, instance); + output.push(create_fn_mono_item(tcx, instance, DUMMY_SP)); } } GlobalAlloc::VTable(ty, trait_ref) => { diff --git a/compiler/rustc_passes/src/reachable.rs b/compiler/rustc_passes/src/reachable.rs index 6dd8eaf7e6734..dee8ba7e87dfd 100644 --- a/compiler/rustc_passes/src/reachable.rs +++ b/compiler/rustc_passes/src/reachable.rs @@ -310,7 +310,7 @@ impl<'tcx> ReachableContext<'tcx> { GlobalAlloc::Static(def_id) => { self.propagate_item(Res::Def(self.tcx.def_kind(def_id), def_id)) } - GlobalAlloc::Function(instance) => { + GlobalAlloc::Function { instance, .. } => { // Manually visit to actually see the instance's `DefId`. Type visitors won't see it self.propagate_item(Res::Def( self.tcx.def_kind(instance.def_id()), diff --git a/compiler/rustc_smir/src/rustc_smir/convert/mir.rs b/compiler/rustc_smir/src/rustc_smir/convert/mir.rs index f15b82d0c031f..9d5a14b5145fb 100644 --- a/compiler/rustc_smir/src/rustc_smir/convert/mir.rs +++ b/compiler/rustc_smir/src/rustc_smir/convert/mir.rs @@ -709,7 +709,7 @@ impl<'tcx> Stable<'tcx> for mir::interpret::GlobalAlloc<'tcx> { fn stable(&self, tables: &mut Tables<'_>) -> Self::T { match self { - mir::interpret::GlobalAlloc::Function(instance) => { + mir::interpret::GlobalAlloc::Function { instance, .. } => { GlobalAlloc::Function(instance.stable(tables)) } mir::interpret::GlobalAlloc::VTable(ty, trait_ref) => { diff --git a/src/tools/miri/src/shims/backtrace.rs b/src/tools/miri/src/shims/backtrace.rs index 06be9c1e63e06..24a4b5f26a950 100644 --- a/src/tools/miri/src/shims/backtrace.rs +++ b/src/tools/miri/src/shims/backtrace.rs @@ -119,7 +119,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let (alloc_id, offset, _prov) = this.ptr_get_alloc_id(ptr)?; // This has to be an actual global fn ptr, not a dlsym function. - let fn_instance = if let Some(GlobalAlloc::Function(instance)) = + let fn_instance = if let Some(GlobalAlloc::Function { instance, .. }) = this.tcx.try_get_global_alloc(alloc_id) { instance diff --git a/src/tools/miri/tests/pass/function_pointers.rs b/src/tools/miri/tests/pass/function_pointers.rs index 36679b7180a64..2aa3ebf2dd0b4 100644 --- a/src/tools/miri/tests/pass/function_pointers.rs +++ b/src/tools/miri/tests/pass/function_pointers.rs @@ -23,6 +23,7 @@ fn h(i: i32, j: i32) -> i32 { j * i * 7 } +#[inline(never)] fn i() -> i32 { 73 } @@ -77,7 +78,7 @@ fn main() { assert_eq!(indirect_mut3(h), 210); assert_eq!(indirect_once3(h), 210); // Check that `i` always has the same address. This is not guaranteed - // but Miri currently uses a fixed address for monomorphic functions. + // but Miri currently uses a fixed address for non-inlineable monomorphic functions. assert!(return_fn_ptr(i) == i); assert!(return_fn_ptr(i) as unsafe fn() -> i32 == i as fn() -> i32 as unsafe fn() -> i32); // Miri gives different addresses to different reifications of a generic function. diff --git a/src/tools/miri/tests/pass/issues/issue-91636.rs b/src/tools/miri/tests/pass/issues/issue-91636.rs index 21000bb68d2bc..00370165812f5 100644 --- a/src/tools/miri/tests/pass/issues/issue-91636.rs +++ b/src/tools/miri/tests/pass/issues/issue-91636.rs @@ -10,6 +10,7 @@ impl Function { } } +#[inline(never)] fn dummy(_: &str) {} fn main() { From d3a742bde999add41c002513fccd0949859128f4 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 12 Jun 2024 12:53:03 -0400 Subject: [PATCH 611/892] Miscellaneous renaming --- .../src/interpret/terminator.rs | 5 +- compiler/rustc_middle/src/query/mod.rs | 4 +- compiler/rustc_middle/src/ty/instance.rs | 120 +++++++++--------- .../src/traits/vtable.rs | 6 +- compiler/rustc_ty_utils/src/instance.rs | 4 +- 5 files changed, 71 insertions(+), 68 deletions(-) diff --git a/compiler/rustc_const_eval/src/interpret/terminator.rs b/compiler/rustc_const_eval/src/interpret/terminator.rs index 74521d0f49345..f59293e7266ac 100644 --- a/compiler/rustc_const_eval/src/interpret/terminator.rs +++ b/compiler/rustc_const_eval/src/interpret/terminator.rs @@ -883,13 +883,12 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { ty::ExistentialTraitRef::erase_self_ty(tcx, virtual_trait_ref); let concrete_trait_ref = existential_trait_ref.with_self_ty(tcx, dyn_ty); - let concrete_method = Instance::resolve_for_vtable( + let concrete_method = Instance::expect_resolve_for_vtable( tcx, self.param_env, def_id, instance.args.rebase_onto(tcx, trait_def_id, concrete_trait_ref.args), - ) - .unwrap(); + ); assert_eq!(fn_inst, concrete_method); } diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index d40a783358959..33c27d41d8642 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -2197,8 +2197,8 @@ rustc_queries! { /// * `Err(ErrorGuaranteed)` when the `Instance` resolution process /// couldn't complete due to errors elsewhere - this is distinct /// from `Ok(None)` to avoid misleading diagnostics when an error - /// has already been/will be emitted, for the original cause - query resolve_instance( + /// has already been/will be emitted, for the original cause. + query resolve_instance_raw( key: ty::ParamEnvAnd<'tcx, (DefId, GenericArgsRef<'tcx>)> ) -> Result>, ErrorGuaranteed> { desc { "resolving instance `{}`", ty::Instance::new(key.value.0, key.value.1) } diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs index 1ba8820e0e11d..99ac503cd6800 100644 --- a/compiler/rustc_middle/src/ty/instance.rs +++ b/compiler/rustc_middle/src/ty/instance.rs @@ -505,7 +505,7 @@ impl<'tcx> Instance<'tcx> { // below is more likely to ignore the bounds in scope (e.g. if the only // generic parameters mentioned by `args` were lifetime ones). let args = tcx.erase_regions(args); - tcx.resolve_instance(tcx.erase_regions(param_env.and((def_id, args)))) + tcx.resolve_instance_raw(tcx.erase_regions(param_env.and((def_id, args)))) } pub fn expect_resolve( @@ -571,77 +571,81 @@ impl<'tcx> Instance<'tcx> { }) } - pub fn resolve_for_vtable( + pub fn expect_resolve_for_vtable( tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>, def_id: DefId, args: GenericArgsRef<'tcx>, - ) -> Option> { + ) -> Instance<'tcx> { debug!("resolve_for_vtable(def_id={:?}, args={:?})", def_id, args); let fn_sig = tcx.fn_sig(def_id).instantiate_identity(); let is_vtable_shim = !fn_sig.inputs().skip_binder().is_empty() && fn_sig.input(0).skip_binder().is_param(0) && tcx.generics_of(def_id).has_self; + if is_vtable_shim { debug!(" => associated item with unsizeable self: Self"); - Some(Instance { def: InstanceKind::VTableShim(def_id), args }) - } else { - let reason = tcx.sess.is_sanitizer_kcfi_enabled().then_some(ReifyReason::Vtable); - Instance::resolve(tcx, param_env, def_id, args).ok().flatten().map(|mut resolved| { - match resolved.def { - InstanceKind::Item(def) => { - // We need to generate a shim when we cannot guarantee that - // the caller of a trait object method will be aware of - // `#[track_caller]` - this ensures that the caller - // and callee ABI will always match. - // - // The shim is generated when all of these conditions are met: - // - // 1) The underlying method expects a caller location parameter - // in the ABI - if resolved.def.requires_caller_location(tcx) - // 2) The caller location parameter comes from having `#[track_caller]` - // on the implementation, and *not* on the trait method. - && !tcx.should_inherit_track_caller(def) - // If the method implementation comes from the trait definition itself - // (e.g. `trait Foo { #[track_caller] my_fn() { /* impl */ } }`), - // then we don't need to generate a shim. This check is needed because - // `should_inherit_track_caller` returns `false` if our method - // implementation comes from the trait block, and not an impl block - && !matches!( - tcx.opt_associated_item(def), - Some(ty::AssocItem { - container: ty::AssocItemContainer::TraitContainer, - .. - }) - ) - { - if tcx.is_closure_like(def) { - debug!(" => vtable fn pointer created for closure with #[track_caller]: {:?} for method {:?} {:?}", - def, def_id, args); - - // Create a shim for the `FnOnce/FnMut/Fn` method we are calling - // - unlike functions, invoking a closure always goes through a - // trait. - resolved = Instance { def: InstanceKind::ReifyShim(def_id, reason), args }; - } else { - debug!( - " => vtable fn pointer created for function with #[track_caller]: {:?}", def - ); - resolved.def = InstanceKind::ReifyShim(def, reason); - } - } - } - InstanceKind::Virtual(def_id, _) => { - debug!(" => vtable fn pointer created for virtual call"); - resolved.def = InstanceKind::ReifyShim(def_id, reason) + return Instance { def: InstanceKind::VTableShim(def_id), args }; + } + + let mut resolved = Instance::expect_resolve(tcx, param_env, def_id, args); + + let reason = tcx.sess.is_sanitizer_kcfi_enabled().then_some(ReifyReason::Vtable); + match resolved.def { + InstanceKind::Item(def) => { + // We need to generate a shim when we cannot guarantee that + // the caller of a trait object method will be aware of + // `#[track_caller]` - this ensures that the caller + // and callee ABI will always match. + // + // The shim is generated when all of these conditions are met: + // + // 1) The underlying method expects a caller location parameter + // in the ABI + if resolved.def.requires_caller_location(tcx) + // 2) The caller location parameter comes from having `#[track_caller]` + // on the implementation, and *not* on the trait method. + && !tcx.should_inherit_track_caller(def) + // If the method implementation comes from the trait definition itself + // (e.g. `trait Foo { #[track_caller] my_fn() { /* impl */ } }`), + // then we don't need to generate a shim. This check is needed because + // `should_inherit_track_caller` returns `false` if our method + // implementation comes from the trait block, and not an impl block + && !matches!( + tcx.opt_associated_item(def), + Some(ty::AssocItem { + container: ty::AssocItemContainer::TraitContainer, + .. + }) + ) + { + if tcx.is_closure_like(def) { + debug!( + " => vtable fn pointer created for closure with #[track_caller]: {:?} for method {:?} {:?}", + def, def_id, args + ); + + // Create a shim for the `FnOnce/FnMut/Fn` method we are calling + // - unlike functions, invoking a closure always goes through a + // trait. + resolved = Instance { def: InstanceKind::ReifyShim(def_id, reason), args }; + } else { + debug!( + " => vtable fn pointer created for function with #[track_caller]: {:?}", + def + ); + resolved.def = InstanceKind::ReifyShim(def, reason); } - _ => {} } - - resolved - }) + } + InstanceKind::Virtual(def_id, _) => { + debug!(" => vtable fn pointer created for virtual call"); + resolved.def = InstanceKind::ReifyShim(def_id, reason) + } + _ => {} } + + resolved } pub fn resolve_closure( diff --git a/compiler/rustc_trait_selection/src/traits/vtable.rs b/compiler/rustc_trait_selection/src/traits/vtable.rs index e54ced85deeb7..e710b17a10d6e 100644 --- a/compiler/rustc_trait_selection/src/traits/vtable.rs +++ b/compiler/rustc_trait_selection/src/traits/vtable.rs @@ -285,13 +285,13 @@ fn vtable_entries<'tcx>( return VtblEntry::Vacant; } - let instance = ty::Instance::resolve_for_vtable( + let instance = ty::Instance::expect_resolve_for_vtable( tcx, ty::ParamEnv::reveal_all(), def_id, args, - ) - .expect("resolution failed during building vtable representation"); + ); + VtblEntry::Method(instance) }); diff --git a/compiler/rustc_ty_utils/src/instance.rs b/compiler/rustc_ty_utils/src/instance.rs index c50a490a9dc0c..7b6d86d22a578 100644 --- a/compiler/rustc_ty_utils/src/instance.rs +++ b/compiler/rustc_ty_utils/src/instance.rs @@ -16,7 +16,7 @@ use traits::{translate_args, Reveal}; use crate::errors::UnexpectedFnPtrAssociatedItem; -fn resolve_instance<'tcx>( +fn resolve_instance_raw<'tcx>( tcx: TyCtxt<'tcx>, key: ty::ParamEnvAnd<'tcx, (DefId, GenericArgsRef<'tcx>)>, ) -> Result>, ErrorGuaranteed> { @@ -364,5 +364,5 @@ fn resolve_associated_item<'tcx>( } pub(crate) fn provide(providers: &mut Providers) { - *providers = Providers { resolve_instance, ..*providers }; + *providers = Providers { resolve_instance_raw, ..*providers }; } From 9dc129ae829f8f322421dc9fb2c64d58e11eb08a Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 12 Jun 2024 13:06:23 -0400 Subject: [PATCH 612/892] Give Instance::expect_resolve a span --- .../rustc_codegen_cranelift/src/abi/mod.rs | 11 +++++++--- .../rustc_codegen_cranelift/src/main_shim.rs | 2 ++ compiler/rustc_codegen_gcc/src/context.rs | 1 + compiler/rustc_codegen_llvm/src/context.rs | 1 + compiler/rustc_codegen_ssa/src/base.rs | 1 + compiler/rustc_codegen_ssa/src/mir/block.rs | 1 + .../src/const_eval/machine.rs | 1 + compiler/rustc_middle/src/ty/instance.rs | 12 ++++++----- compiler/rustc_monomorphize/src/collector.rs | 20 +++++++++++++++---- 9 files changed, 38 insertions(+), 12 deletions(-) diff --git a/compiler/rustc_codegen_cranelift/src/abi/mod.rs b/compiler/rustc_codegen_cranelift/src/abi/mod.rs index 0d7eee7afb41e..81dfde81e938c 100644 --- a/compiler/rustc_codegen_cranelift/src/abi/mod.rs +++ b/compiler/rustc_codegen_cranelift/src/abi/mod.rs @@ -371,9 +371,14 @@ pub(crate) fn codegen_terminator_call<'tcx>( // Handle special calls like intrinsics and empty drop glue. let instance = if let ty::FnDef(def_id, fn_args) = *func.layout().ty.kind() { - let instance = - ty::Instance::expect_resolve(fx.tcx, ty::ParamEnv::reveal_all(), def_id, fn_args) - .polymorphize(fx.tcx); + let instance = ty::Instance::expect_resolve( + fx.tcx, + ty::ParamEnv::reveal_all(), + def_id, + fn_args, + Some(source_info.span), + ) + .polymorphize(fx.tcx); if is_call_from_compiler_builtins_to_upstream_monomorphization(fx.tcx, instance) { if target.is_some() { diff --git a/compiler/rustc_codegen_cranelift/src/main_shim.rs b/compiler/rustc_codegen_cranelift/src/main_shim.rs index 33d3f9b8a90a3..d1dc147dba8f8 100644 --- a/compiler/rustc_codegen_cranelift/src/main_shim.rs +++ b/compiler/rustc_codegen_cranelift/src/main_shim.rs @@ -119,6 +119,7 @@ pub(crate) fn maybe_create_entry_wrapper( ParamEnv::reveal_all(), report.def_id, tcx.mk_args(&[GenericArg::from(main_ret_ty)]), + None, ) .polymorphize(tcx); @@ -144,6 +145,7 @@ pub(crate) fn maybe_create_entry_wrapper( ParamEnv::reveal_all(), start_def_id, tcx.mk_args(&[main_ret_ty.into()]), + None, ) .polymorphize(tcx); let start_func_id = import_function(tcx, m, start_instance); diff --git a/compiler/rustc_codegen_gcc/src/context.rs b/compiler/rustc_codegen_gcc/src/context.rs index 6231b09552cea..88ffcd7f4b502 100644 --- a/compiler/rustc_codegen_gcc/src/context.rs +++ b/compiler/rustc_codegen_gcc/src/context.rs @@ -479,6 +479,7 @@ impl<'gcc, 'tcx> MiscMethods<'tcx> for CodegenCx<'gcc, 'tcx> { ty::ParamEnv::reveal_all(), def_id, ty::List::empty(), + None, ); let symbol_name = tcx.symbol_name(instance).name; diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs index 1a8e8efdae507..a012c40ec0a6f 100644 --- a/compiler/rustc_codegen_llvm/src/context.rs +++ b/compiler/rustc_codegen_llvm/src/context.rs @@ -580,6 +580,7 @@ impl<'ll, 'tcx> MiscMethods<'tcx> for CodegenCx<'ll, 'tcx> { ty::ParamEnv::reveal_all(), def_id, ty::List::empty(), + None, )), _ => { let name = name.unwrap_or("rust_eh_personality"); diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs index c18816533a2fb..1be4cb186a7e9 100644 --- a/compiler/rustc_codegen_ssa/src/base.rs +++ b/compiler/rustc_codegen_ssa/src/base.rs @@ -467,6 +467,7 @@ pub fn maybe_create_entry_wrapper<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( ty::ParamEnv::reveal_all(), start_def_id, cx.tcx().mk_args(&[main_ret_ty.into()]), + None, ); let start_fn = cx.get_fn_addr(start_instance); diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index b1c22faf1ae9d..8b302b59e1312 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -842,6 +842,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { ty::ParamEnv::reveal_all(), def_id, args, + Some(fn_span), ) .polymorphize(bx.tcx()), ), diff --git a/compiler/rustc_const_eval/src/const_eval/machine.rs b/compiler/rustc_const_eval/src/const_eval/machine.rs index 99276bac03501..cb3288402c11b 100644 --- a/compiler/rustc_const_eval/src/const_eval/machine.rs +++ b/compiler/rustc_const_eval/src/const_eval/machine.rs @@ -253,6 +253,7 @@ impl<'tcx> CompileTimeInterpCx<'tcx> { ty::ParamEnv::reveal_all(), const_def_id, instance.args, + Some(self.find_closest_untracked_caller_location()), ); return Ok(Some(new_instance)); diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs index 99ac503cd6800..6d7c04fca4b94 100644 --- a/compiler/rustc_middle/src/ty/instance.rs +++ b/compiler/rustc_middle/src/ty/instance.rs @@ -13,7 +13,7 @@ use rustc_macros::{ }; use rustc_middle::ty::normalize_erasing_regions::NormalizationError; use rustc_span::def_id::LOCAL_CRATE; -use rustc_span::Symbol; +use rustc_span::{Span, Symbol}; use tracing::{debug, instrument}; use std::assert_matches::assert_matches; @@ -513,10 +513,12 @@ impl<'tcx> Instance<'tcx> { param_env: ty::ParamEnv<'tcx>, def_id: DefId, args: GenericArgsRef<'tcx>, + span: Option, ) -> Instance<'tcx> { match ty::Instance::resolve(tcx, param_env, def_id, args) { Ok(Some(instance)) => instance, - instance => bug!( + instance => span_bug!( + span.unwrap_or(tcx.def_span(def_id)), "failed to resolve instance for {}: {instance:#?}", tcx.def_path_str_with_args(def_id, args) ), @@ -588,7 +590,7 @@ impl<'tcx> Instance<'tcx> { return Instance { def: InstanceKind::VTableShim(def_id), args }; } - let mut resolved = Instance::expect_resolve(tcx, param_env, def_id, args); + let mut resolved = Instance::expect_resolve(tcx, param_env, def_id, args, None); let reason = tcx.sess.is_sanitizer_kcfi_enabled().then_some(ReifyReason::Vtable); match resolved.def { @@ -665,13 +667,13 @@ impl<'tcx> Instance<'tcx> { pub fn resolve_drop_in_place(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> ty::Instance<'tcx> { let def_id = tcx.require_lang_item(LangItem::DropInPlace, None); let args = tcx.mk_args(&[ty.into()]); - Instance::expect_resolve(tcx, ty::ParamEnv::reveal_all(), def_id, args) + Instance::expect_resolve(tcx, ty::ParamEnv::reveal_all(), def_id, args, None) } pub fn resolve_async_drop_in_place(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> ty::Instance<'tcx> { let def_id = tcx.require_lang_item(LangItem::AsyncDropInPlace, None); let args = tcx.mk_args(&[ty.into()]); - Instance::expect_resolve(tcx, ty::ParamEnv::reveal_all(), def_id, args) + Instance::expect_resolve(tcx, ty::ParamEnv::reveal_all(), def_id, args, None) } #[instrument(level = "debug", skip(tcx), ret)] diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index 235743fccc89e..8915876226572 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -916,7 +916,13 @@ fn visit_fn_use<'tcx>( ) { if let ty::FnDef(def_id, args) = *ty.kind() { let instance = if is_direct_call { - ty::Instance::expect_resolve(tcx, ty::ParamEnv::reveal_all(), def_id, args) + ty::Instance::expect_resolve( + tcx, + ty::ParamEnv::reveal_all(), + def_id, + args, + Some(source), + ) } else { match ty::Instance::resolve_for_fn_ptr(tcx, ty::ParamEnv::reveal_all(), def_id, args) { Some(instance) => instance, @@ -1318,8 +1324,13 @@ fn visit_mentioned_item<'tcx>( match *item { MentionedItem::Fn(ty) => { if let ty::FnDef(def_id, args) = *ty.kind() { - let instance = - Instance::expect_resolve(tcx, ty::ParamEnv::reveal_all(), def_id, args); + let instance = Instance::expect_resolve( + tcx, + ty::ParamEnv::reveal_all(), + def_id, + args, + Some(span), + ); // `visit_instance_use` was written for "used" item collection but works just as well // for "mentioned" item collection. // We can set `is_direct_call`; that just means we'll skip a bunch of shims that anyway @@ -1544,6 +1555,7 @@ impl<'v> RootCollector<'_, 'v> { ty::ParamEnv::reveal_all(), start_def_id, self.tcx.mk_args(&[main_ret_ty.into()]), + None, ); self.output.push(create_fn_mono_item(self.tcx, start_instance, DUMMY_SP)); @@ -1614,7 +1626,7 @@ fn create_mono_items_for_default_impls<'tcx>( // As mentioned above, the method is legal to eagerly instantiate if it // only has lifetime generic parameters. This is validated by let args = trait_ref.args.extend_to(tcx, method.def_id, only_region_params); - let instance = ty::Instance::expect_resolve(tcx, param_env, method.def_id, args); + let instance = ty::Instance::expect_resolve(tcx, param_env, method.def_id, args, None); let mono_item = create_fn_mono_item(tcx, instance, DUMMY_SP); if mono_item.node.is_instantiable(tcx) && should_codegen_locally(tcx, instance) { From 0f7f3f4045a3b34678584a4148ff452f8a072904 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 24 May 2024 14:09:40 -0400 Subject: [PATCH 613/892] Re-implement a type-size based limit --- compiler/rustc_middle/messages.ftl | 6 ++ compiler/rustc_middle/src/error.rs | 14 ++++ compiler/rustc_middle/src/middle/limits.rs | 2 +- compiler/rustc_middle/src/ty/instance.rs | 82 +++++++++++++++++-- compiler/rustc_middle/src/ty/print/mod.rs | 32 +++++++- compiler/rustc_monomorphize/messages.ftl | 5 -- compiler/rustc_monomorphize/src/collector.rs | 69 +--------------- compiler/rustc_monomorphize/src/errors.rs | 13 --- ...issue-72408-nested-closures-exponential.rs | 4 +- ...e-72408-nested-closures-exponential.stderr | 10 +++ tests/ui/codegen/overflow-during-mono.rs | 1 - tests/ui/codegen/overflow-during-mono.stderr | 11 +-- tests/ui/issues/issue-22638.rs | 5 +- tests/ui/issues/issue-22638.stderr | 17 ++-- .../issue-37311.rs | 4 +- .../issue-37311.stderr | 10 +-- .../issue-58952-filter-type-length.rs | 7 +- .../issue-58952-filter-type-length.stderr | 8 ++ .../ui/iterators/iter-map-fold-type-length.rs | 2 +- tests/ui/recursion/issue-83150.rs | 5 +- tests/ui/recursion/issue-83150.stderr | 16 ++-- .../traits/issue-91949-hangs-on-recursion.rs | 6 +- .../issue-91949-hangs-on-recursion.stderr | 20 ++--- tests/ui/type_length_limit.rs | 4 +- tests/ui/type_length_limit.stderr | 13 ++- 25 files changed, 206 insertions(+), 160 deletions(-) create mode 100644 tests/ui/closures/issue-72408-nested-closures-exponential.stderr create mode 100644 tests/ui/iterators/issue-58952-filter-type-length.stderr diff --git a/compiler/rustc_middle/messages.ftl b/compiler/rustc_middle/messages.ftl index f4d619329eb9c..2b9d9a07a98ef 100644 --- a/compiler/rustc_middle/messages.ftl +++ b/compiler/rustc_middle/messages.ftl @@ -41,6 +41,9 @@ middle_cannot_be_normalized = middle_conflict_types = this expression supplies two conflicting concrete types for the same opaque type +middle_consider_type_length_limit = + consider adding a `#![type_length_limit="{$type_length}"]` attribute to your crate + middle_const_eval_non_int = constant evaluation of enum discriminant resulted in non-integer @@ -94,8 +97,11 @@ 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_type_length_limit = reached the type-length limit while instantiating `{$shrunk}` + middle_unknown_layout = the type `{$ty}` has an unknown layout middle_values_too_big = values of the type `{$ty}` are too big for the current 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 6e622b0405f0a..711db4e0a6bdb 100644 --- a/compiler/rustc_middle/src/error.rs +++ b/compiler/rustc_middle/src/error.rs @@ -1,4 +1,5 @@ use std::fmt; +use std::path::PathBuf; use rustc_errors::{codes::*, DiagArgName, DiagArgValue, DiagMessage}; use rustc_macros::{Diagnostic, Subdiagnostic}; @@ -149,3 +150,16 @@ pub struct ErroneousConstant { /// Used by `rustc_const_eval` pub use crate::fluent_generated::middle_adjust_for_foreign_abi_error; + +#[derive(Diagnostic)] +#[diag(middle_type_length_limit)] +#[help(middle_consider_type_length_limit)] +pub struct TypeLengthLimit { + #[primary_span] + pub span: Span, + pub shrunk: String, + #[note(middle_written_to_path)] + pub was_written: Option<()>, + pub path: PathBuf, + pub type_length: usize, +} diff --git a/compiler/rustc_middle/src/middle/limits.rs b/compiler/rustc_middle/src/middle/limits.rs index 4d69801274956..d0b4f36a426fd 100644 --- a/compiler/rustc_middle/src/middle/limits.rs +++ b/compiler/rustc_middle/src/middle/limits.rs @@ -30,7 +30,7 @@ pub fn provide(providers: &mut Providers) { tcx.hir().krate_attrs(), tcx.sess, sym::type_length_limit, - 1048576, + 2usize.pow(24), ), } } diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs index 6d7c04fca4b94..65039d8b52c22 100644 --- a/compiler/rustc_middle/src/ty/instance.rs +++ b/compiler/rustc_middle/src/ty/instance.rs @@ -1,23 +1,25 @@ +use crate::error; use crate::middle::codegen_fn_attrs::CodegenFnAttrFlags; -use crate::ty::print::{FmtPrinter, Printer}; -use crate::ty::{self, Ty, TyCtxt, TypeFoldable, TypeSuperFoldable}; -use crate::ty::{EarlyBinder, GenericArgs, GenericArgsRef, TypeVisitableExt}; +use crate::ty::print::{shrunk_instance_name, FmtPrinter, Printer}; +use crate::ty::{ + self, EarlyBinder, GenericArgs, GenericArgsRef, Ty, TyCtxt, TypeFoldable, TypeSuperFoldable, + TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, +}; use rustc_errors::ErrorGuaranteed; use rustc_hir as hir; use rustc_hir::def::Namespace; use rustc_hir::def_id::{CrateNum, DefId}; use rustc_hir::lang_items::LangItem; use rustc_index::bit_set::FiniteBitSet; -use rustc_macros::{ - Decodable, Encodable, HashStable, Lift, TyDecodable, TyEncodable, TypeVisitable, -}; +use rustc_macros::{Decodable, Encodable, HashStable, Lift, TyDecodable, TyEncodable}; use rustc_middle::ty::normalize_erasing_regions::NormalizationError; use rustc_span::def_id::LOCAL_CRATE; -use rustc_span::{Span, Symbol}; +use rustc_span::{Span, Symbol, DUMMY_SP}; use tracing::{debug, instrument}; use std::assert_matches::assert_matches; use std::fmt; +use std::path::PathBuf; /// An `InstanceKind` along with the args that are needed to substitute the instance. /// @@ -385,7 +387,28 @@ impl<'tcx> InstanceKind<'tcx> { } } -fn fmt_instance( +fn type_length<'tcx>(item: impl TypeVisitable>) -> usize { + struct Visitor { + type_length: usize, + } + impl<'tcx> TypeVisitor> for Visitor { + fn visit_ty(&mut self, t: Ty<'tcx>) { + self.type_length += 1; + t.super_visit_with(self); + } + + fn visit_const(&mut self, ct: ty::Const<'tcx>) { + self.type_length += 1; + ct.super_visit_with(self); + } + } + let mut visitor = Visitor { type_length: 0 }; + item.visit_with(&mut visitor); + + visitor.type_length +} + +pub fn fmt_instance( f: &mut fmt::Formatter<'_>, instance: Instance<'_>, type_length: Option, @@ -485,7 +508,8 @@ impl<'tcx> Instance<'tcx> { /// /// Presuming that coherence and type-check have succeeded, if this method is invoked /// in a monomorphic context (i.e., like during codegen), then it is guaranteed to return - /// `Ok(Some(instance))`. + /// `Ok(Some(instance))`, **except** for when the instance's inputs hit the type size limit, + /// in which case it may bail out and return `Ok(None)`. /// /// Returns `Err(ErrorGuaranteed)` when the `Instance` resolution process /// couldn't complete due to errors elsewhere - this is distinct @@ -498,6 +522,16 @@ impl<'tcx> Instance<'tcx> { def_id: DefId, args: GenericArgsRef<'tcx>, ) -> Result>, ErrorGuaranteed> { + // Rust code can easily create exponentially-long types using only a + // polynomial recursion depth. Even with the default recursion + // depth, you can easily get cases that take >2^60 steps to run, + // which means that rustc basically hangs. + // + // Bail out in these cases to avoid that bad user experience. + if !tcx.type_length_limit().value_within_limit(type_length(args)) { + return Ok(None); + } + // All regions in the result of this query are erased, so it's // fine to erase all of the input regions. @@ -517,6 +551,36 @@ impl<'tcx> Instance<'tcx> { ) -> Instance<'tcx> { match ty::Instance::resolve(tcx, param_env, def_id, args) { Ok(Some(instance)) => instance, + Ok(None) => { + let type_length = type_length(args); + if !tcx.type_length_limit().value_within_limit(type_length) { + let (shrunk, written_to_path) = + shrunk_instance_name(tcx, Instance::new(def_id, args)); + let mut path = PathBuf::new(); + let was_written = if let Some(path2) = written_to_path { + path = path2; + Some(()) + } else { + None + }; + tcx.dcx().emit_fatal(error::TypeLengthLimit { + // We don't use `def_span(def_id)` so that diagnostics point + // to the crate root during mono instead of to foreign items. + // This is arguably better. + span: span.unwrap_or(DUMMY_SP), + shrunk, + was_written, + path, + type_length, + }); + } else { + span_bug!( + span.unwrap_or(tcx.def_span(def_id)), + "failed to resolve instance for {}", + tcx.def_path_str_with_args(def_id, args) + ) + } + } instance => span_bug!( span.unwrap_or(tcx.def_span(def_id)), "failed to resolve instance for {}: {instance:#?}", diff --git a/compiler/rustc_middle/src/ty/print/mod.rs b/compiler/rustc_middle/src/ty/print/mod.rs index 3c27df9529aa1..c165790548d75 100644 --- a/compiler/rustc_middle/src/ty/print/mod.rs +++ b/compiler/rustc_middle/src/ty/print/mod.rs @@ -1,5 +1,7 @@ +use std::path::PathBuf; + use crate::ty::GenericArg; -use crate::ty::{self, Ty, TyCtxt}; +use crate::ty::{self, ShortInstance, Ty, TyCtxt}; use hir::def::Namespace; use rustc_data_structures::fx::FxHashSet; @@ -356,3 +358,31 @@ where with_no_trimmed_paths!(Self::print(t, fmt)) } } + +/// Format instance name that is already known to be too long for rustc. +/// Show only the first 2 types if it is longer than 32 characters to avoid blasting +/// the user's terminal with thousands of lines of type-name. +/// +/// If the type name is longer than before+after, it will be written to a file. +pub fn shrunk_instance_name<'tcx>( + tcx: TyCtxt<'tcx>, + instance: ty::Instance<'tcx>, +) -> (String, Option) { + let s = instance.to_string(); + + // Only use the shrunk version if it's really shorter. + // This also avoids the case where before and after slices overlap. + if s.chars().nth(33).is_some() { + let shrunk = format!("{}", ShortInstance(instance, 4)); + if shrunk == s { + return (s, None); + } + + let path = tcx.output_filenames(()).temp_path_ext("long-type.txt", None); + let written_to_path = std::fs::write(&path, s).ok().map(|_| path); + + (shrunk, written_to_path) + } else { + (s, None) + } +} diff --git a/compiler/rustc_monomorphize/messages.ftl b/compiler/rustc_monomorphize/messages.ftl index 94b553a07a755..7210701d4828c 100644 --- a/compiler/rustc_monomorphize/messages.ftl +++ b/compiler/rustc_monomorphize/messages.ftl @@ -1,6 +1,3 @@ -monomorphize_consider_type_length_limit = - consider adding a `#![type_length_limit="{$type_length}"]` attribute to your crate - monomorphize_couldnt_dump_mono_stats = unexpected error occurred while dumping monomorphization stats: {$error} @@ -25,8 +22,6 @@ monomorphize_start_not_found = using `fn main` requires the standard library monomorphize_symbol_already_defined = symbol `{$symbol}` is already defined -monomorphize_type_length_limit = reached the type-length limit while instantiating `{$shrunk}` - monomorphize_unknown_cgu_collection_mode = unknown codegen-item collection mode '{$mode}', falling back to 'lazy' mode diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index 8915876226572..f98d4700528d5 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -222,12 +222,12 @@ use rustc_middle::mir::{self, Location, MentionedItem}; use rustc_middle::query::TyCtxtAt; use rustc_middle::ty::adjustment::{CustomCoerceUnsized, PointerCoercion}; use rustc_middle::ty::layout::ValidityRequirement; -use rustc_middle::ty::print::with_no_trimmed_paths; +use rustc_middle::ty::print::{shrunk_instance_name, with_no_trimmed_paths}; +use rustc_middle::ty::GenericArgs; use rustc_middle::ty::{ self, AssocKind, GenericParamDefKind, Instance, InstanceKind, Ty, TyCtxt, TypeFoldable, TypeVisitableExt, VtblEntry, }; -use rustc_middle::ty::{GenericArgKind, GenericArgs}; use rustc_middle::{bug, span_bug}; use rustc_session::config::EntryFnType; use rustc_session::Limit; @@ -238,9 +238,7 @@ use rustc_target::abi::Size; use std::path::PathBuf; use tracing::{debug, instrument, trace}; -use crate::errors::{ - self, EncounteredErrorWhileInstantiating, NoOptimizedMir, RecursionLimit, TypeLengthLimit, -}; +use crate::errors::{self, EncounteredErrorWhileInstantiating, NoOptimizedMir, RecursionLimit}; use move_check::MoveCheckState; #[derive(PartialEq)] @@ -443,7 +441,6 @@ fn collect_items_rec<'tcx>( recursion_depths, recursion_limit, )); - check_type_length_limit(tcx, instance); rustc_data_structures::stack::ensure_sufficient_stack(|| { collect_items_of_instance( @@ -554,34 +551,6 @@ fn collect_items_rec<'tcx>( } } -/// Format instance name that is already known to be too long for rustc. -/// Show only the first 2 types if it is longer than 32 characters to avoid blasting -/// the user's terminal with thousands of lines of type-name. -/// -/// If the type name is longer than before+after, it will be written to a file. -fn shrunk_instance_name<'tcx>( - tcx: TyCtxt<'tcx>, - instance: Instance<'tcx>, -) -> (String, Option) { - let s = instance.to_string(); - - // Only use the shrunk version if it's really shorter. - // This also avoids the case where before and after slices overlap. - if s.chars().nth(33).is_some() { - let shrunk = format!("{}", ty::ShortInstance(instance, 4)); - if shrunk == s { - return (s, None); - } - - let path = tcx.output_filenames(()).temp_path_ext("long-type.txt", None); - let written_to_path = std::fs::write(&path, s).ok().map(|_| path); - - (shrunk, written_to_path) - } else { - (s, None) - } -} - fn check_recursion_limit<'tcx>( tcx: TyCtxt<'tcx>, instance: Instance<'tcx>, @@ -630,38 +599,6 @@ fn check_recursion_limit<'tcx>( (def_id, recursion_depth) } -fn check_type_length_limit<'tcx>(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) { - let type_length = instance - .args - .iter() - .flat_map(|arg| arg.walk()) - .filter(|arg| match arg.unpack() { - GenericArgKind::Type(_) | GenericArgKind::Const(_) => true, - GenericArgKind::Lifetime(_) => false, - }) - .count(); - debug!(" => type length={}", type_length); - - // Rust code can easily create exponentially-long types using only a - // polynomial recursion depth. Even with the default recursion - // depth, you can easily get cases that take >2^60 steps to run, - // which means that rustc basically hangs. - // - // Bail out in these cases to avoid that bad user experience. - if !tcx.type_length_limit().value_within_limit(type_length) { - let (shrunk, written_to_path) = shrunk_instance_name(tcx, instance); - let span = tcx.def_span(instance.def_id()); - let mut path = PathBuf::new(); - let was_written = if let Some(path2) = written_to_path { - path = path2; - Some(()) - } else { - None - }; - tcx.dcx().emit_fatal(TypeLengthLimit { span, shrunk, was_written, path, type_length }); - } -} - struct MirUsedCollector<'a, 'tcx> { tcx: TyCtxt<'tcx>, body: &'a mir::Body<'tcx>, diff --git a/compiler/rustc_monomorphize/src/errors.rs b/compiler/rustc_monomorphize/src/errors.rs index c0d1efd96c5b7..9548c46e6fa04 100644 --- a/compiler/rustc_monomorphize/src/errors.rs +++ b/compiler/rustc_monomorphize/src/errors.rs @@ -19,19 +19,6 @@ pub struct RecursionLimit { pub path: PathBuf, } -#[derive(Diagnostic)] -#[diag(monomorphize_type_length_limit)] -#[help(monomorphize_consider_type_length_limit)] -pub struct TypeLengthLimit { - #[primary_span] - pub span: Span, - pub shrunk: String, - #[note(monomorphize_written_to_path)] - pub was_written: Option<()>, - pub path: PathBuf, - pub type_length: usize, -} - #[derive(Diagnostic)] #[diag(monomorphize_no_optimized_mir)] pub struct NoOptimizedMir { diff --git a/tests/ui/closures/issue-72408-nested-closures-exponential.rs b/tests/ui/closures/issue-72408-nested-closures-exponential.rs index 682508f928082..033e422433861 100644 --- a/tests/ui/closures/issue-72408-nested-closures-exponential.rs +++ b/tests/ui/closures/issue-72408-nested-closures-exponential.rs @@ -1,5 +1,4 @@ -//@ build-pass -//@ ignore-compare-mode-next-solver (hangs) +//@ build-fail // Closures include captured types twice in a type tree. // @@ -46,6 +45,7 @@ fn main() { let f = dup(f); let f = dup(f); + //~^ ERROR reached the type-length limit let f = dup(f); let f = dup(f); let f = dup(f); diff --git a/tests/ui/closures/issue-72408-nested-closures-exponential.stderr b/tests/ui/closures/issue-72408-nested-closures-exponential.stderr new file mode 100644 index 0000000000000..2120b45696392 --- /dev/null +++ b/tests/ui/closures/issue-72408-nested-closures-exponential.stderr @@ -0,0 +1,10 @@ +error: reached the type-length limit while instantiating `dup::<{closure@$DIR/issue-72408-nested-closures-exponential.rs:13:5: 13:13}>` + --> $DIR/issue-72408-nested-closures-exponential.rs:47:13 + | +LL | let f = dup(f); + | ^^^^^^ + | + = help: consider adding a `#![type_length_limit="29360121"]` attribute to your crate + +error: aborting due to 1 previous error + diff --git a/tests/ui/codegen/overflow-during-mono.rs b/tests/ui/codegen/overflow-during-mono.rs index 919f1a8120e0b..278298f27ff0e 100644 --- a/tests/ui/codegen/overflow-during-mono.rs +++ b/tests/ui/codegen/overflow-during-mono.rs @@ -1,5 +1,4 @@ //@ build-fail -//~^ ERROR overflow evaluating the requirement #![recursion_limit = "32"] diff --git a/tests/ui/codegen/overflow-during-mono.stderr b/tests/ui/codegen/overflow-during-mono.stderr index f7a3e2df3dbaa..9e463378004dc 100644 --- a/tests/ui/codegen/overflow-during-mono.stderr +++ b/tests/ui/codegen/overflow-during-mono.stderr @@ -1,11 +1,8 @@ -error[E0275]: overflow evaluating the requirement `{closure@$DIR/overflow-during-mono.rs:13:41: 13:44}: Sized` +error: reached the type-length limit while instantiating `, {closure@$DIR/overflow-during-mono.rs:12:41: 12:44}>, ...> as Iterator>::try_fold::<..., ..., ...>` + --> $SRC_DIR/core/src/iter/adapters/filter.rs:LL:COL | - = help: consider increasing the recursion limit by adding a `#![recursion_limit = "64"]` attribute to your crate (`overflow_during_mono`) - = note: required for `Filter, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>` to implement `Iterator` - = note: 31 redundant requirements hidden - = note: required for `Filter, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>` to implement `Iterator` - = note: required for `Filter, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>` to implement `IntoIterator` + = help: consider adding a `#![type_length_limit="20156994"]` attribute to your crate + = note: the full type name has been written to '$TEST_BUILD_DIR/codegen/overflow-during-mono/overflow-during-mono.long-type.txt' error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0275`. diff --git a/tests/ui/issues/issue-22638.rs b/tests/ui/issues/issue-22638.rs index 3e04eb41b98de..3e401e99fb48d 100644 --- a/tests/ui/issues/issue-22638.rs +++ b/tests/ui/issues/issue-22638.rs @@ -1,7 +1,4 @@ //@ build-fail -//@ normalize-stderr-test: "<\{closure@.+`" -> "$$CLOSURE`" -//@ normalize-stderr-test: ".nll/" -> "/" -//@ ignore-compare-mode-next-solver (hangs) #![allow(unused)] @@ -43,6 +40,7 @@ impl C { pub fn matches(&self, f: &F) { let &C(ref base) = self; base.matches(&|| { + //~^ ERROR reached the type-length limit C(base.clone()).matches(f) }) } @@ -55,7 +53,6 @@ impl D { pub fn matches(&self, f: &F) { let &D(ref a) = self; a.matches(f) - //~^ ERROR reached the recursion limit while instantiating `A::matches::<{closure } } diff --git a/tests/ui/issues/issue-22638.stderr b/tests/ui/issues/issue-22638.stderr index 45290f6afe9de..1344409c77040 100644 --- a/tests/ui/issues/issue-22638.stderr +++ b/tests/ui/issues/issue-22638.stderr @@ -1,14 +1,13 @@ -error: reached the recursion limit while instantiating `A::matches::$CLOSURE` - --> $DIR/issue-22638.rs:57:9 +error: reached the type-length limit while instantiating `D::matches::<{closure@$DIR/issue-22638.rs:42:23: 42:25}>` + --> $DIR/issue-22638.rs:42:9 | -LL | a.matches(f) - | ^^^^^^^^^^^^ +LL | / base.matches(&|| { +LL | | +LL | | C(base.clone()).matches(f) +LL | | }) + | |__________^ | -note: `A::matches` defined here - --> $DIR/issue-22638.rs:16:5 - | -LL | pub fn matches(&self, f: &F) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = help: consider adding a `#![type_length_limit="30408681"]` attribute to your crate error: aborting due to 1 previous error diff --git a/tests/ui/issues/issue-37311-type-length-limit/issue-37311.rs b/tests/ui/issues/issue-37311-type-length-limit/issue-37311.rs index 1646f16e1ecea..131c7535537f6 100644 --- a/tests/ui/issues/issue-37311-type-length-limit/issue-37311.rs +++ b/tests/ui/issues/issue-37311-type-length-limit/issue-37311.rs @@ -1,6 +1,5 @@ //@ build-fail //@ normalize-stderr-test: ".nll/" -> "/" -//@ ignore-compare-mode-next-solver (hangs) trait Mirror { type Image; @@ -15,7 +14,8 @@ trait Foo { impl Foo for T { #[allow(unconditional_recursion)] fn recurse(&self) { - (self, self).recurse(); //~ ERROR reached the recursion limit + (self, self).recurse(); + //~^ ERROR reached the type-length limit } } diff --git a/tests/ui/issues/issue-37311-type-length-limit/issue-37311.stderr b/tests/ui/issues/issue-37311-type-length-limit/issue-37311.stderr index ccee9ed4daadb..2978ced527949 100644 --- a/tests/ui/issues/issue-37311-type-length-limit/issue-37311.stderr +++ b/tests/ui/issues/issue-37311-type-length-limit/issue-37311.stderr @@ -1,14 +1,10 @@ -error: reached the recursion limit while instantiating `<(&(&(..., ...), ...), ...) as Foo>::recurse` - --> $DIR/issue-37311.rs:18:9 +error: reached the type-length limit while instantiating `<(&(&(..., ...), ...), ...) as Foo>::recurse` + --> $DIR/issue-37311.rs:17:9 | LL | (self, self).recurse(); | ^^^^^^^^^^^^^^^^^^^^^^ | -note: `::recurse` defined here - --> $DIR/issue-37311.rs:17:5 - | -LL | fn recurse(&self) { - | ^^^^^^^^^^^^^^^^^ + = help: consider adding a `#![type_length_limit="33554429"]` attribute to your crate = note: the full type name has been written to '$TEST_BUILD_DIR/issues/issue-37311-type-length-limit/issue-37311/issue-37311.long-type.txt' error: aborting due to 1 previous error diff --git a/tests/ui/iterators/issue-58952-filter-type-length.rs b/tests/ui/iterators/issue-58952-filter-type-length.rs index 9904eddb598ce..b2c208ae28f19 100644 --- a/tests/ui/iterators/issue-58952-filter-type-length.rs +++ b/tests/ui/iterators/issue-58952-filter-type-length.rs @@ -1,5 +1,4 @@ -//@ run-pass -//@ ignore-compare-mode-next-solver (hangs) +//@ build-fail //! This snippet causes the type length to blowup exponentially, //! so check that we don't accidentally exceed the type length limit. @@ -30,5 +29,9 @@ fn main() { .filter(|a| b.clone().any(|b| *b == *a)) .filter(|a| b.clone().any(|b| *b == *a)) .filter(|a| b.clone().any(|b| *b == *a)) + .filter(|a| b.clone().any(|b| *b == *a)) + .filter(|a| b.clone().any(|b| *b == *a)) + .filter(|a| b.clone().any(|b| *b == *a)) + .filter(|a| b.clone().any(|b| *b == *a)) .collect::>(); } diff --git a/tests/ui/iterators/issue-58952-filter-type-length.stderr b/tests/ui/iterators/issue-58952-filter-type-length.stderr new file mode 100644 index 0000000000000..975fcd4afffee --- /dev/null +++ b/tests/ui/iterators/issue-58952-filter-type-length.stderr @@ -0,0 +1,8 @@ +error: reached the type-length limit while instantiating ` as Iterator>::try_fold::, {closure@iter::adapters::filter::filter_try_fold<'_, ..., ..., ..., ..., ...>::{closure#0}}, ...>` + --> $SRC_DIR/core/src/iter/adapters/filter.rs:LL:COL + | + = help: consider adding a `#![type_length_limit="21233607"]` attribute to your crate + = note: the full type name has been written to '$TEST_BUILD_DIR/iterators/issue-58952-filter-type-length/issue-58952-filter-type-length.long-type.txt' + +error: aborting due to 1 previous error + diff --git a/tests/ui/iterators/iter-map-fold-type-length.rs b/tests/ui/iterators/iter-map-fold-type-length.rs index 6444fb9dada98..5f9567d68e819 100644 --- a/tests/ui/iterators/iter-map-fold-type-length.rs +++ b/tests/ui/iterators/iter-map-fold-type-length.rs @@ -3,7 +3,7 @@ //! //! The normal limit is a million, and this test used to exceed 1.5 million, but //! now we can survive an even tighter limit. Still seems excessive though... -#![type_length_limit = "256000"] +#![type_length_limit = "1327047"] // Custom wrapper so Iterator methods aren't specialized. struct Iter(I); diff --git a/tests/ui/recursion/issue-83150.rs b/tests/ui/recursion/issue-83150.rs index b74b2adfeab47..b3ddf88c4493f 100644 --- a/tests/ui/recursion/issue-83150.rs +++ b/tests/ui/recursion/issue-83150.rs @@ -1,7 +1,6 @@ //@ build-fail //@ compile-flags: -Copt-level=0 //@ normalize-stderr-test: "long-type-\d+" -> "long-type-hash" -//~^^^ ERROR overflow evaluating the requirement //@ ignore-compare-mode-next-solver (hangs) fn main() { @@ -9,6 +8,8 @@ fn main() { func(&mut iter) } -fn func>(iter: &mut T) { //~ WARN function cannot return without recursing +fn func>(iter: &mut T) { + //~^ WARN function cannot return without recursing func(&mut iter.map(|x| x + 1)) + //~^ ERROR reached the type-length limit } diff --git a/tests/ui/recursion/issue-83150.stderr b/tests/ui/recursion/issue-83150.stderr index 783f9cf763254..127de98ddc5b9 100644 --- a/tests/ui/recursion/issue-83150.stderr +++ b/tests/ui/recursion/issue-83150.stderr @@ -1,21 +1,23 @@ warning: function cannot return without recursing - --> $DIR/issue-83150.rs:12:1 + --> $DIR/issue-83150.rs:11:1 | LL | fn func>(iter: &mut T) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot return without recursing +LL | LL | func(&mut iter.map(|x| x + 1)) | ------------------------------ recursive call site | = help: a `loop` may express intention better if this is on purpose = note: `#[warn(unconditional_recursion)]` on by default -error[E0275]: overflow evaluating the requirement `Map<&mut std::ops::Range, {closure@$DIR/issue-83150.rs:13:24: 13:27}>: Iterator` +error: reached the type-length limit while instantiating `<&mut Map<&mut Map<&mut ..., ...>, ...> as Iterator>::map::<..., ...>` + --> $DIR/issue-83150.rs:13:15 | - = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_83150`) - = note: required for `&mut Map<&mut std::ops::Range, {closure@$DIR/issue-83150.rs:13:24: 13:27}>` to implement `Iterator` - = note: 65 redundant requirements hidden - = note: required for `&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut std::ops::Range, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>` to implement `Iterator` +LL | func(&mut iter.map(|x| x + 1)) + | ^^^^^^^^^^^^^^^^^^^ + | + = help: consider adding a `#![type_length_limit="23068663"]` attribute to your crate + = note: the full type name has been written to '$TEST_BUILD_DIR/recursion/issue-83150/issue-83150.long-type.txt' error: aborting due to 1 previous error; 1 warning emitted -For more information about this error, try `rustc --explain E0275`. diff --git a/tests/ui/traits/issue-91949-hangs-on-recursion.rs b/tests/ui/traits/issue-91949-hangs-on-recursion.rs index ddbbcdd052965..d9c422e6f7096 100644 --- a/tests/ui/traits/issue-91949-hangs-on-recursion.rs +++ b/tests/ui/traits/issue-91949-hangs-on-recursion.rs @@ -1,9 +1,5 @@ //@ build-fail //@ compile-flags: -Zinline-mir=no -//@ error-pattern: overflow evaluating the requirement ` as Iterator>::Item == ()` -//@ error-pattern: function cannot return without recursing -//@ normalize-stderr-test: "long-type-\d+" -> "long-type-hash" -//@ ignore-compare-mode-next-solver (hangs) // Regression test for #91949. // This hanged *forever* on 1.56, fixed by #90423. @@ -22,10 +18,12 @@ impl> Iterator for IteratorOfWrapped { } fn recurse(elements: T) -> Vec +//~^ WARN function cannot return without recursing where T: Iterator, { recurse(IteratorOfWrapped(elements).map(|t| t.0)) + //~^ ERROR reached the type-length limit } fn main() { diff --git a/tests/ui/traits/issue-91949-hangs-on-recursion.stderr b/tests/ui/traits/issue-91949-hangs-on-recursion.stderr index c4324f0f0a872..c46c78609d2c3 100644 --- a/tests/ui/traits/issue-91949-hangs-on-recursion.stderr +++ b/tests/ui/traits/issue-91949-hangs-on-recursion.stderr @@ -1,7 +1,8 @@ warning: function cannot return without recursing - --> $DIR/issue-91949-hangs-on-recursion.rs:24:1 + --> $DIR/issue-91949-hangs-on-recursion.rs:20:1 | LL | / fn recurse(elements: T) -> Vec +LL | | LL | | where LL | | T: Iterator, | |___________________________^ cannot return without recursing @@ -12,19 +13,14 @@ LL | recurse(IteratorOfWrapped(elements).map(|t| t.0)) = help: a `loop` may express intention better if this is on purpose = note: `#[warn(unconditional_recursion)]` on by default -error[E0275]: overflow evaluating the requirement ` as Iterator>::Item == ()` +error: reached the type-length limit while instantiating `, ...>> as Iterator>::map::<..., ...>` + --> $DIR/issue-91949-hangs-on-recursion.rs:25:13 | - = help: consider increasing the recursion limit by adding a `#![recursion_limit = "512"]` attribute to your crate (`issue_91949_hangs_on_recursion`) -note: required for `IteratorOfWrapped<(), std::iter::Empty<()>>` to implement `Iterator` - --> $DIR/issue-91949-hangs-on-recursion.rs:17:32 +LL | recurse(IteratorOfWrapped(elements).map(|t| t.0)) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | -LL | impl> Iterator for IteratorOfWrapped { - | -------- ^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^ - | | - | unsatisfied trait bound introduced here - = note: 256 redundant requirements hidden - = note: required for `IteratorOfWrapped<(), Map>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>, {closure@$DIR/issue-91949-hangs-on-recursion.rs:28:45: 28:48}>>` to implement `Iterator` + = help: consider adding a `#![type_length_limit="27262965"]` attribute to your crate + = note: the full type name has been written to '$TEST_BUILD_DIR/traits/issue-91949-hangs-on-recursion/issue-91949-hangs-on-recursion.long-type.txt' error: aborting due to 1 previous error; 1 warning emitted -For more information about this error, try `rustc --explain E0275`. diff --git a/tests/ui/type_length_limit.rs b/tests/ui/type_length_limit.rs index c60f1be06c671..d6937481a1551 100644 --- a/tests/ui/type_length_limit.rs +++ b/tests/ui/type_length_limit.rs @@ -1,7 +1,6 @@ //@ build-fail -//@ error-pattern: reached the type-length limit while instantiating //@ compile-flags: -Copt-level=0 -//@ normalize-stderr-test: ".nll/" -> "/" +//~^^ ERROR reached the type-length limit // Test that the type length limit can be changed. // The exact type depends on optimizations, so disable them. @@ -31,4 +30,5 @@ pub struct G(std::marker::PhantomData::<(T, K)>); fn main() { drop::>(None); + //~^ ERROR reached the type-length limit } diff --git a/tests/ui/type_length_limit.stderr b/tests/ui/type_length_limit.stderr index 32290a2f5bfc7..83353547d34db 100644 --- a/tests/ui/type_length_limit.stderr +++ b/tests/ui/type_length_limit.stderr @@ -1,8 +1,15 @@ error: reached the type-length limit while instantiating `std::mem::drop::>` - --> $SRC_DIR/core/src/mem/mod.rs:LL:COL + --> $DIR/type_length_limit.rs:32:5 | - = help: consider adding a `#![type_length_limit="10"]` attribute to your crate +LL | drop::>(None); + | ^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider adding a `#![type_length_limit="4010"]` attribute to your crate = note: the full type name has been written to '$TEST_BUILD_DIR/type_length_limit/type_length_limit.long-type.txt' -error: aborting due to 1 previous error +error: reached the type-length limit while instantiating `<{closure@rt::lang_start<()>::{closure#0}} as FnMut<()>>::call_mut` + | + = help: consider adding a `#![type_length_limit="10"]` attribute to your crate + +error: aborting due to 2 previous errors From 3273ccea4b2c1995a7ddd059657ded593eb859c9 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 1 Jul 2024 16:32:32 -0400 Subject: [PATCH 614/892] Fix spans --- .../rustc_codegen_cranelift/src/abi/mod.rs | 2 +- .../rustc_codegen_cranelift/src/main_shim.rs | 5 ++-- compiler/rustc_codegen_gcc/src/context.rs | 4 ++-- compiler/rustc_codegen_llvm/src/context.rs | 4 ++-- compiler/rustc_codegen_ssa/src/base.rs | 4 ++-- compiler/rustc_codegen_ssa/src/mir/block.rs | 2 +- .../src/const_eval/machine.rs | 2 +- .../src/interpret/terminator.rs | 1 + compiler/rustc_middle/src/ty/instance.rs | 21 ++++++++++------ compiler/rustc_monomorphize/src/collector.rs | 24 ++++++------------- .../src/traits/vtable.rs | 3 ++- 11 files changed, 36 insertions(+), 36 deletions(-) diff --git a/compiler/rustc_codegen_cranelift/src/abi/mod.rs b/compiler/rustc_codegen_cranelift/src/abi/mod.rs index 81dfde81e938c..9dc94ab33ea9e 100644 --- a/compiler/rustc_codegen_cranelift/src/abi/mod.rs +++ b/compiler/rustc_codegen_cranelift/src/abi/mod.rs @@ -376,7 +376,7 @@ pub(crate) fn codegen_terminator_call<'tcx>( ty::ParamEnv::reveal_all(), def_id, fn_args, - Some(source_info.span), + source_info.span, ) .polymorphize(fx.tcx); diff --git a/compiler/rustc_codegen_cranelift/src/main_shim.rs b/compiler/rustc_codegen_cranelift/src/main_shim.rs index d1dc147dba8f8..fe0a15514190c 100644 --- a/compiler/rustc_codegen_cranelift/src/main_shim.rs +++ b/compiler/rustc_codegen_cranelift/src/main_shim.rs @@ -4,6 +4,7 @@ use rustc_middle::ty::AssocKind; use rustc_middle::ty::GenericArg; use rustc_session::config::{sigpipe, EntryFnType}; use rustc_span::symbol::Ident; +use rustc_span::DUMMY_SP; use crate::prelude::*; @@ -119,7 +120,7 @@ pub(crate) fn maybe_create_entry_wrapper( ParamEnv::reveal_all(), report.def_id, tcx.mk_args(&[GenericArg::from(main_ret_ty)]), - None, + DUMMY_SP, ) .polymorphize(tcx); @@ -145,7 +146,7 @@ pub(crate) fn maybe_create_entry_wrapper( ParamEnv::reveal_all(), start_def_id, tcx.mk_args(&[main_ret_ty.into()]), - None, + DUMMY_SP, ) .polymorphize(tcx); let start_func_id = import_function(tcx, m, start_instance); diff --git a/compiler/rustc_codegen_gcc/src/context.rs b/compiler/rustc_codegen_gcc/src/context.rs index 88ffcd7f4b502..1d689c9ac0ef1 100644 --- a/compiler/rustc_codegen_gcc/src/context.rs +++ b/compiler/rustc_codegen_gcc/src/context.rs @@ -17,7 +17,7 @@ use rustc_middle::ty::layout::{ }; use rustc_middle::ty::{self, Instance, ParamEnv, PolyExistentialTraitRef, Ty, TyCtxt}; use rustc_session::Session; -use rustc_span::{source_map::respan, Span}; +use rustc_span::{source_map::respan, Span, DUMMY_SP}; use rustc_target::abi::{ call::FnAbi, HasDataLayout, PointeeInfo, Size, TargetDataLayout, VariantIdx, }; @@ -479,7 +479,7 @@ impl<'gcc, 'tcx> MiscMethods<'tcx> for CodegenCx<'gcc, 'tcx> { ty::ParamEnv::reveal_all(), def_id, ty::List::empty(), - None, + DUMMY_SP, ); let symbol_name = tcx.symbol_name(instance).name; diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs index a012c40ec0a6f..77beb9a6bb386 100644 --- a/compiler/rustc_codegen_llvm/src/context.rs +++ b/compiler/rustc_codegen_llvm/src/context.rs @@ -28,7 +28,7 @@ use rustc_session::config::{BranchProtection, CFGuard, CFProtection}; use rustc_session::config::{CrateType, DebugInfo, PAuthKey, PacRet}; use rustc_session::Session; use rustc_span::source_map::Spanned; -use rustc_span::Span; +use rustc_span::{Span, DUMMY_SP}; use rustc_target::abi::{call::FnAbi, HasDataLayout, TargetDataLayout, VariantIdx}; use rustc_target::spec::{HasTargetSpec, RelocModel, Target, TlsModel}; use smallvec::SmallVec; @@ -580,7 +580,7 @@ impl<'ll, 'tcx> MiscMethods<'tcx> for CodegenCx<'ll, 'tcx> { ty::ParamEnv::reveal_all(), def_id, ty::List::empty(), - None, + DUMMY_SP, )), _ => { let name = name.unwrap_or("rust_eh_personality"); diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs index 1be4cb186a7e9..137f14fe706cc 100644 --- a/compiler/rustc_codegen_ssa/src/base.rs +++ b/compiler/rustc_codegen_ssa/src/base.rs @@ -37,7 +37,7 @@ use rustc_middle::ty::{self, Instance, Ty, TyCtxt}; use rustc_session::config::{self, CrateType, EntryFnType, OptLevel, OutputType}; use rustc_session::Session; use rustc_span::symbol::sym; -use rustc_span::Symbol; +use rustc_span::{Symbol, DUMMY_SP}; use rustc_target::abi::FIRST_VARIANT; use std::cmp; @@ -467,7 +467,7 @@ pub fn maybe_create_entry_wrapper<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( ty::ParamEnv::reveal_all(), start_def_id, cx.tcx().mk_args(&[main_ret_ty.into()]), - None, + DUMMY_SP, ); let start_fn = cx.get_fn_addr(start_instance); diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index 8b302b59e1312..f5c7821fd7015 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -842,7 +842,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { ty::ParamEnv::reveal_all(), def_id, args, - Some(fn_span), + fn_span, ) .polymorphize(bx.tcx()), ), diff --git a/compiler/rustc_const_eval/src/const_eval/machine.rs b/compiler/rustc_const_eval/src/const_eval/machine.rs index cb3288402c11b..17e1d8566c26c 100644 --- a/compiler/rustc_const_eval/src/const_eval/machine.rs +++ b/compiler/rustc_const_eval/src/const_eval/machine.rs @@ -253,7 +253,7 @@ impl<'tcx> CompileTimeInterpCx<'tcx> { ty::ParamEnv::reveal_all(), const_def_id, instance.args, - Some(self.find_closest_untracked_caller_location()), + self.cur_span(), ); return Ok(Some(new_instance)); diff --git a/compiler/rustc_const_eval/src/interpret/terminator.rs b/compiler/rustc_const_eval/src/interpret/terminator.rs index f59293e7266ac..68acddf63d86e 100644 --- a/compiler/rustc_const_eval/src/interpret/terminator.rs +++ b/compiler/rustc_const_eval/src/interpret/terminator.rs @@ -888,6 +888,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { self.param_env, def_id, instance.args.rebase_onto(tcx, trait_def_id, concrete_trait_ref.args), + self.cur_span(), ); assert_eq!(fn_inst, concrete_method); } diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs index 65039d8b52c22..3f854ba74916f 100644 --- a/compiler/rustc_middle/src/ty/instance.rs +++ b/compiler/rustc_middle/src/ty/instance.rs @@ -547,8 +547,14 @@ impl<'tcx> Instance<'tcx> { param_env: ty::ParamEnv<'tcx>, def_id: DefId, args: GenericArgsRef<'tcx>, - span: Option, + span: Span, ) -> Instance<'tcx> { + // We compute the span lazily, to avoid unnecessary query calls. + // If `span` is a DUMMY_SP, and the def id is local, then use the + // def span of the def id. + let span_or_local_def_span = + || if span.is_dummy() && def_id.is_local() { tcx.def_span(def_id) } else { span }; + match ty::Instance::resolve(tcx, param_env, def_id, args) { Ok(Some(instance)) => instance, Ok(None) => { @@ -567,7 +573,7 @@ impl<'tcx> Instance<'tcx> { // We don't use `def_span(def_id)` so that diagnostics point // to the crate root during mono instead of to foreign items. // This is arguably better. - span: span.unwrap_or(DUMMY_SP), + span: span_or_local_def_span(), shrunk, was_written, path, @@ -575,14 +581,14 @@ impl<'tcx> Instance<'tcx> { }); } else { span_bug!( - span.unwrap_or(tcx.def_span(def_id)), + span_or_local_def_span(), "failed to resolve instance for {}", tcx.def_path_str_with_args(def_id, args) ) } } instance => span_bug!( - span.unwrap_or(tcx.def_span(def_id)), + span_or_local_def_span(), "failed to resolve instance for {}: {instance:#?}", tcx.def_path_str_with_args(def_id, args) ), @@ -642,6 +648,7 @@ impl<'tcx> Instance<'tcx> { param_env: ty::ParamEnv<'tcx>, def_id: DefId, args: GenericArgsRef<'tcx>, + span: Span, ) -> Instance<'tcx> { debug!("resolve_for_vtable(def_id={:?}, args={:?})", def_id, args); let fn_sig = tcx.fn_sig(def_id).instantiate_identity(); @@ -654,7 +661,7 @@ impl<'tcx> Instance<'tcx> { return Instance { def: InstanceKind::VTableShim(def_id), args }; } - let mut resolved = Instance::expect_resolve(tcx, param_env, def_id, args, None); + let mut resolved = Instance::expect_resolve(tcx, param_env, def_id, args, span); let reason = tcx.sess.is_sanitizer_kcfi_enabled().then_some(ReifyReason::Vtable); match resolved.def { @@ -731,13 +738,13 @@ impl<'tcx> Instance<'tcx> { pub fn resolve_drop_in_place(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> ty::Instance<'tcx> { let def_id = tcx.require_lang_item(LangItem::DropInPlace, None); let args = tcx.mk_args(&[ty.into()]); - Instance::expect_resolve(tcx, ty::ParamEnv::reveal_all(), def_id, args, None) + Instance::expect_resolve(tcx, ty::ParamEnv::reveal_all(), def_id, args, DUMMY_SP) } pub fn resolve_async_drop_in_place(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> ty::Instance<'tcx> { let def_id = tcx.require_lang_item(LangItem::AsyncDropInPlace, None); let args = tcx.mk_args(&[ty.into()]); - Instance::expect_resolve(tcx, ty::ParamEnv::reveal_all(), def_id, args, None) + Instance::expect_resolve(tcx, ty::ParamEnv::reveal_all(), def_id, args, DUMMY_SP) } #[instrument(level = "debug", skip(tcx), ret)] diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index f98d4700528d5..342c01ff69731 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -853,13 +853,7 @@ fn visit_fn_use<'tcx>( ) { if let ty::FnDef(def_id, args) = *ty.kind() { let instance = if is_direct_call { - ty::Instance::expect_resolve( - tcx, - ty::ParamEnv::reveal_all(), - def_id, - args, - Some(source), - ) + ty::Instance::expect_resolve(tcx, ty::ParamEnv::reveal_all(), def_id, args, source) } else { match ty::Instance::resolve_for_fn_ptr(tcx, ty::ParamEnv::reveal_all(), def_id, args) { Some(instance) => instance, @@ -1261,13 +1255,8 @@ fn visit_mentioned_item<'tcx>( match *item { MentionedItem::Fn(ty) => { if let ty::FnDef(def_id, args) = *ty.kind() { - let instance = Instance::expect_resolve( - tcx, - ty::ParamEnv::reveal_all(), - def_id, - args, - Some(span), - ); + let instance = + Instance::expect_resolve(tcx, ty::ParamEnv::reveal_all(), def_id, args, span); // `visit_instance_use` was written for "used" item collection but works just as well // for "mentioned" item collection. // We can set `is_direct_call`; that just means we'll skip a bunch of shims that anyway @@ -1492,7 +1481,7 @@ impl<'v> RootCollector<'_, 'v> { ty::ParamEnv::reveal_all(), start_def_id, self.tcx.mk_args(&[main_ret_ty.into()]), - None, + DUMMY_SP, ); self.output.push(create_fn_mono_item(self.tcx, start_instance, DUMMY_SP)); @@ -1561,9 +1550,10 @@ fn create_mono_items_for_default_impls<'tcx>( } // As mentioned above, the method is legal to eagerly instantiate if it - // only has lifetime generic parameters. This is validated by + // only has lifetime generic parameters. This is validated by calling + // `own_requires_monomorphization` on both the impl and method. let args = trait_ref.args.extend_to(tcx, method.def_id, only_region_params); - let instance = ty::Instance::expect_resolve(tcx, param_env, method.def_id, args, None); + let instance = ty::Instance::expect_resolve(tcx, param_env, method.def_id, args, DUMMY_SP); let mono_item = create_fn_mono_item(tcx, instance, DUMMY_SP); if mono_item.node.is_instantiable(tcx) && should_codegen_locally(tcx, instance) { diff --git a/compiler/rustc_trait_selection/src/traits/vtable.rs b/compiler/rustc_trait_selection/src/traits/vtable.rs index e710b17a10d6e..8f56f9c0f3eea 100644 --- a/compiler/rustc_trait_selection/src/traits/vtable.rs +++ b/compiler/rustc_trait_selection/src/traits/vtable.rs @@ -6,7 +6,7 @@ use rustc_middle::bug; use rustc_middle::query::Providers; use rustc_middle::ty::{self, GenericParamDefKind, Ty, TyCtxt, Upcast, VtblEntry}; use rustc_middle::ty::{GenericArgs, TypeVisitableExt}; -use rustc_span::{sym, Span}; +use rustc_span::{sym, Span, DUMMY_SP}; use smallvec::{smallvec, SmallVec}; use std::fmt::Debug; @@ -290,6 +290,7 @@ fn vtable_entries<'tcx>( ty::ParamEnv::reveal_all(), def_id, args, + DUMMY_SP, ); VtblEntry::Method(instance) From a21ba348964e6d72a3369daa4bc22af507eb7778 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sat, 29 Jun 2024 23:01:24 -0400 Subject: [PATCH 615/892] add TyCtxt::as_lang_item, use in new solver --- compiler/rustc_hir/src/lang_items.rs | 13 ++- .../rustc_middle/src/middle/lang_items.rs | 4 + compiler/rustc_middle/src/ty/context.rs | 95 +++++++++++-------- .../src/solve/assembly/mod.rs | 87 +++++++++-------- compiler/rustc_type_ir/src/interner.rs | 2 + 5 files changed, 126 insertions(+), 75 deletions(-) diff --git a/compiler/rustc_hir/src/lang_items.rs b/compiler/rustc_hir/src/lang_items.rs index 3c44acb16577a..30c0e40206aaf 100644 --- a/compiler/rustc_hir/src/lang_items.rs +++ b/compiler/rustc_hir/src/lang_items.rs @@ -11,6 +11,7 @@ use crate::def_id::DefId; use crate::{MethodKind, Target}; use rustc_ast as ast; +use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_macros::{Decodable, Encodable, HashStable_Generic}; use rustc_span::symbol::{kw, sym, Symbol}; @@ -23,6 +24,7 @@ pub struct LanguageItems { /// Mappings from lang items to their possibly found [`DefId`]s. /// The index corresponds to the order in [`LangItem`]. items: [Option; std::mem::variant_count::()], + reverse_items: FxIndexMap, /// Lang items that were not found during collection. pub missing: Vec, } @@ -30,7 +32,11 @@ pub struct LanguageItems { impl LanguageItems { /// Construct an empty collection of lang items and no missing ones. pub fn new() -> Self { - Self { items: [None; std::mem::variant_count::()], missing: Vec::new() } + Self { + items: [None; std::mem::variant_count::()], + reverse_items: FxIndexMap::default(), + missing: Vec::new(), + } } pub fn get(&self, item: LangItem) -> Option { @@ -39,6 +45,11 @@ impl LanguageItems { pub fn set(&mut self, item: LangItem, def_id: DefId) { self.items[item as usize] = Some(def_id); + self.reverse_items.insert(def_id, item); + } + + pub fn from_def_id(&self, def_id: DefId) -> Option { + self.reverse_items.get(&def_id).copied() } pub fn iter(&self) -> impl Iterator + '_ { diff --git a/compiler/rustc_middle/src/middle/lang_items.rs b/compiler/rustc_middle/src/middle/lang_items.rs index e76d7af6e4aba..a0c9af436e207 100644 --- a/compiler/rustc_middle/src/middle/lang_items.rs +++ b/compiler/rustc_middle/src/middle/lang_items.rs @@ -27,6 +27,10 @@ impl<'tcx> TyCtxt<'tcx> { self.lang_items().get(lang_item) == Some(def_id) } + pub fn as_lang_item(self, def_id: DefId) -> Option { + self.lang_items().from_def_id(def_id) + } + /// Given a [`DefId`] of one of the [`Fn`], [`FnMut`] or [`FnOnce`] traits, /// returns a corresponding [`ty::ClosureKind`]. /// For any other [`DefId`] return `None`. diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 9225ae6300fc6..155a76713cab6 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -366,6 +366,10 @@ impl<'tcx> Interner for TyCtxt<'tcx> { self.is_lang_item(def_id, trait_lang_item_to_lang_item(lang_item)) } + fn as_lang_item(self, def_id: DefId) -> Option { + lang_item_to_trait_lang_item(self.lang_items().from_def_id(def_id)?) + } + fn associated_type_def_ids(self, def_id: DefId) -> impl IntoIterator { self.associated_items(def_id) .in_definition_order() @@ -584,46 +588,63 @@ impl<'tcx> Interner for TyCtxt<'tcx> { } } -fn trait_lang_item_to_lang_item(lang_item: TraitSolverLangItem) -> LangItem { - match lang_item { - TraitSolverLangItem::AsyncDestruct => LangItem::AsyncDestruct, - TraitSolverLangItem::AsyncFnKindHelper => LangItem::AsyncFnKindHelper, - TraitSolverLangItem::AsyncFnKindUpvars => LangItem::AsyncFnKindUpvars, - TraitSolverLangItem::AsyncFnOnceOutput => LangItem::AsyncFnOnceOutput, - TraitSolverLangItem::AsyncIterator => LangItem::AsyncIterator, - TraitSolverLangItem::CallOnceFuture => LangItem::CallOnceFuture, - TraitSolverLangItem::CallRefFuture => LangItem::CallRefFuture, - TraitSolverLangItem::Clone => LangItem::Clone, - TraitSolverLangItem::Copy => LangItem::Copy, - TraitSolverLangItem::Coroutine => LangItem::Coroutine, - TraitSolverLangItem::CoroutineReturn => LangItem::CoroutineReturn, - TraitSolverLangItem::CoroutineYield => LangItem::CoroutineYield, - TraitSolverLangItem::Destruct => LangItem::Destruct, - TraitSolverLangItem::DiscriminantKind => LangItem::DiscriminantKind, - TraitSolverLangItem::DynMetadata => LangItem::DynMetadata, - TraitSolverLangItem::EffectsMaybe => LangItem::EffectsMaybe, - TraitSolverLangItem::EffectsIntersection => LangItem::EffectsIntersection, - TraitSolverLangItem::EffectsIntersectionOutput => LangItem::EffectsIntersectionOutput, - TraitSolverLangItem::EffectsNoRuntime => LangItem::EffectsNoRuntime, - TraitSolverLangItem::EffectsRuntime => LangItem::EffectsRuntime, - TraitSolverLangItem::FnPtrTrait => LangItem::FnPtrTrait, - TraitSolverLangItem::FusedIterator => LangItem::FusedIterator, - TraitSolverLangItem::Future => LangItem::Future, - TraitSolverLangItem::FutureOutput => LangItem::FutureOutput, - TraitSolverLangItem::Iterator => LangItem::Iterator, - TraitSolverLangItem::Metadata => LangItem::Metadata, - TraitSolverLangItem::Option => LangItem::Option, - TraitSolverLangItem::PointeeTrait => LangItem::PointeeTrait, - TraitSolverLangItem::PointerLike => LangItem::PointerLike, - TraitSolverLangItem::Poll => LangItem::Poll, - TraitSolverLangItem::Sized => LangItem::Sized, - TraitSolverLangItem::TransmuteTrait => LangItem::TransmuteTrait, - TraitSolverLangItem::Tuple => LangItem::Tuple, - TraitSolverLangItem::Unpin => LangItem::Unpin, - TraitSolverLangItem::Unsize => LangItem::Unsize, +macro_rules! bidirectional_lang_item_map { + ($($name:ident),+ $(,)?) => { + fn trait_lang_item_to_lang_item(lang_item: TraitSolverLangItem) -> LangItem { + match lang_item { + $(TraitSolverLangItem::$name => LangItem::$name,)+ + } + } + + fn lang_item_to_trait_lang_item(lang_item: LangItem) -> Option { + Some(match lang_item { + $(LangItem::$name => TraitSolverLangItem::$name,)+ + _ => return None, + }) + } } } +bidirectional_lang_item_map! { +// tidy-alphabetical-start + AsyncDestruct, + AsyncFnKindHelper, + AsyncFnKindUpvars, + AsyncFnOnceOutput, + AsyncIterator, + CallOnceFuture, + CallRefFuture, + Clone, + Copy, + Coroutine, + CoroutineReturn, + CoroutineYield, + Destruct, + DiscriminantKind, + DynMetadata, + EffectsMaybe, + EffectsIntersection, + EffectsIntersectionOutput, + EffectsNoRuntime, + EffectsRuntime, + FnPtrTrait, + FusedIterator, + Future, + FutureOutput, + Iterator, + Metadata, + Option, + PointeeTrait, + PointerLike, + Poll, + Sized, + TransmuteTrait, + Tuple, + Unpin, + Unsize, +// tidy-alphabetical-end +} + impl<'tcx> rustc_type_ir::inherent::DefId> for DefId { fn as_local(self) -> Option { self.as_local() diff --git a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs index 6ee684605ac60..20a0da16c7521 100644 --- a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs @@ -387,48 +387,61 @@ where G::consider_auto_trait_candidate(self, goal) } else if cx.trait_is_alias(trait_def_id) { G::consider_trait_alias_candidate(self, goal) - } else if cx.is_lang_item(trait_def_id, TraitSolverLangItem::Sized) { - G::consider_builtin_sized_candidate(self, goal) - } else if cx.is_lang_item(trait_def_id, TraitSolverLangItem::Copy) - || cx.is_lang_item(trait_def_id, TraitSolverLangItem::Clone) - { - G::consider_builtin_copy_clone_candidate(self, goal) - } else if cx.is_lang_item(trait_def_id, TraitSolverLangItem::PointerLike) { - G::consider_builtin_pointer_like_candidate(self, goal) - } else if cx.is_lang_item(trait_def_id, TraitSolverLangItem::FnPtrTrait) { - G::consider_builtin_fn_ptr_trait_candidate(self, goal) } else if let Some(kind) = self.cx().fn_trait_kind_from_def_id(trait_def_id) { G::consider_builtin_fn_trait_candidates(self, goal, kind) } else if let Some(kind) = self.cx().async_fn_trait_kind_from_def_id(trait_def_id) { G::consider_builtin_async_fn_trait_candidates(self, goal, kind) - } else if cx.is_lang_item(trait_def_id, TraitSolverLangItem::AsyncFnKindHelper) { - G::consider_builtin_async_fn_kind_helper_candidate(self, goal) - } else if cx.is_lang_item(trait_def_id, TraitSolverLangItem::Tuple) { - G::consider_builtin_tuple_candidate(self, goal) - } else if cx.is_lang_item(trait_def_id, TraitSolverLangItem::PointeeTrait) { - G::consider_builtin_pointee_candidate(self, goal) - } else if cx.is_lang_item(trait_def_id, TraitSolverLangItem::Future) { - G::consider_builtin_future_candidate(self, goal) - } else if cx.is_lang_item(trait_def_id, TraitSolverLangItem::Iterator) { - G::consider_builtin_iterator_candidate(self, goal) - } else if cx.is_lang_item(trait_def_id, TraitSolverLangItem::FusedIterator) { - G::consider_builtin_fused_iterator_candidate(self, goal) - } else if cx.is_lang_item(trait_def_id, TraitSolverLangItem::AsyncIterator) { - G::consider_builtin_async_iterator_candidate(self, goal) - } else if cx.is_lang_item(trait_def_id, TraitSolverLangItem::Coroutine) { - G::consider_builtin_coroutine_candidate(self, goal) - } else if cx.is_lang_item(trait_def_id, TraitSolverLangItem::DiscriminantKind) { - G::consider_builtin_discriminant_kind_candidate(self, goal) - } else if cx.is_lang_item(trait_def_id, TraitSolverLangItem::AsyncDestruct) { - G::consider_builtin_async_destruct_candidate(self, goal) - } else if cx.is_lang_item(trait_def_id, TraitSolverLangItem::Destruct) { - G::consider_builtin_destruct_candidate(self, goal) - } else if cx.is_lang_item(trait_def_id, TraitSolverLangItem::TransmuteTrait) { - G::consider_builtin_transmute_candidate(self, goal) - } else if cx.is_lang_item(trait_def_id, TraitSolverLangItem::EffectsIntersection) { - G::consider_builtin_effects_intersection_candidate(self, goal) } else { - Err(NoSolution) + match cx.as_lang_item(trait_def_id) { + Some(TraitSolverLangItem::Sized) => G::consider_builtin_sized_candidate(self, goal), + Some(TraitSolverLangItem::Copy | TraitSolverLangItem::Clone) => { + G::consider_builtin_copy_clone_candidate(self, goal) + } + Some(TraitSolverLangItem::PointerLike) => { + G::consider_builtin_pointer_like_candidate(self, goal) + } + Some(TraitSolverLangItem::FnPtrTrait) => { + G::consider_builtin_fn_ptr_trait_candidate(self, goal) + } + Some(TraitSolverLangItem::AsyncFnKindHelper) => { + G::consider_builtin_async_fn_kind_helper_candidate(self, goal) + } + Some(TraitSolverLangItem::Tuple) => G::consider_builtin_tuple_candidate(self, goal), + Some(TraitSolverLangItem::PointeeTrait) => { + G::consider_builtin_pointee_candidate(self, goal) + } + Some(TraitSolverLangItem::Future) => { + G::consider_builtin_future_candidate(self, goal) + } + Some(TraitSolverLangItem::Iterator) => { + G::consider_builtin_iterator_candidate(self, goal) + } + Some(TraitSolverLangItem::FusedIterator) => { + G::consider_builtin_fused_iterator_candidate(self, goal) + } + Some(TraitSolverLangItem::AsyncIterator) => { + G::consider_builtin_async_iterator_candidate(self, goal) + } + Some(TraitSolverLangItem::Coroutine) => { + G::consider_builtin_coroutine_candidate(self, goal) + } + Some(TraitSolverLangItem::DiscriminantKind) => { + G::consider_builtin_discriminant_kind_candidate(self, goal) + } + Some(TraitSolverLangItem::AsyncDestruct) => { + G::consider_builtin_async_destruct_candidate(self, goal) + } + Some(TraitSolverLangItem::Destruct) => { + G::consider_builtin_destruct_candidate(self, goal) + } + Some(TraitSolverLangItem::TransmuteTrait) => { + G::consider_builtin_transmute_candidate(self, goal) + } + Some(TraitSolverLangItem::EffectsIntersection) => { + G::consider_builtin_effects_intersection_candidate(self, goal) + } + _ => Err(NoSolution), + } }; candidates.extend(result); diff --git a/compiler/rustc_type_ir/src/interner.rs b/compiler/rustc_type_ir/src/interner.rs index 6665158c7cd34..84c7e6e8f2003 100644 --- a/compiler/rustc_type_ir/src/interner.rs +++ b/compiler/rustc_type_ir/src/interner.rs @@ -220,6 +220,8 @@ pub trait Interner: fn is_lang_item(self, def_id: Self::DefId, lang_item: TraitSolverLangItem) -> bool; + fn as_lang_item(self, def_id: Self::DefId) -> Option; + fn associated_type_def_ids(self, def_id: Self::DefId) -> impl IntoIterator; // FIXME: move `fast_reject` into `rustc_type_ir`. From 5a837515f28eed106dd031b0243d6476eba58dd9 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sat, 29 Jun 2024 23:05:35 -0400 Subject: [PATCH 616/892] Make fn traits into first-class TraitSolverLangItems to avoid needing fn_trait_kind_from_def_id --- compiler/rustc_middle/src/ty/context.rs | 16 +++++----- .../src/solve/assembly/mod.rs | 30 ++++++++++++++++--- compiler/rustc_type_ir/src/interner.rs | 4 --- compiler/rustc_type_ir/src/lang_items.rs | 6 ++++ 4 files changed, 39 insertions(+), 17 deletions(-) diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 155a76713cab6..7c3d2df72faa2 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -537,14 +537,6 @@ impl<'tcx> Interner for TyCtxt<'tcx> { self.trait_def(trait_def_id).implement_via_object } - fn fn_trait_kind_from_def_id(self, trait_def_id: DefId) -> Option { - self.fn_trait_kind_from_def_id(trait_def_id) - } - - fn async_fn_trait_kind_from_def_id(self, trait_def_id: DefId) -> Option { - self.async_fn_trait_kind_from_def_id(trait_def_id) - } - fn supertrait_def_ids(self, trait_def_id: DefId) -> impl IntoIterator { self.supertrait_def_ids(trait_def_id) } @@ -608,8 +600,11 @@ macro_rules! bidirectional_lang_item_map { bidirectional_lang_item_map! { // tidy-alphabetical-start AsyncDestruct, + AsyncFn, AsyncFnKindHelper, AsyncFnKindUpvars, + AsyncFnMut, + AsyncFnOnce, AsyncFnOnceOutput, AsyncIterator, CallOnceFuture, @@ -622,11 +617,14 @@ bidirectional_lang_item_map! { Destruct, DiscriminantKind, DynMetadata, - EffectsMaybe, EffectsIntersection, EffectsIntersectionOutput, + EffectsMaybe, EffectsNoRuntime, EffectsRuntime, + Fn, + FnMut, + FnOnce, FnPtrTrait, FusedIterator, Future, diff --git a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs index 20a0da16c7521..38a4f7dfe25cb 100644 --- a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs @@ -387,16 +387,38 @@ where G::consider_auto_trait_candidate(self, goal) } else if cx.trait_is_alias(trait_def_id) { G::consider_trait_alias_candidate(self, goal) - } else if let Some(kind) = self.cx().fn_trait_kind_from_def_id(trait_def_id) { - G::consider_builtin_fn_trait_candidates(self, goal, kind) - } else if let Some(kind) = self.cx().async_fn_trait_kind_from_def_id(trait_def_id) { - G::consider_builtin_async_fn_trait_candidates(self, goal, kind) } else { match cx.as_lang_item(trait_def_id) { Some(TraitSolverLangItem::Sized) => G::consider_builtin_sized_candidate(self, goal), Some(TraitSolverLangItem::Copy | TraitSolverLangItem::Clone) => { G::consider_builtin_copy_clone_candidate(self, goal) } + Some(TraitSolverLangItem::Fn) => { + G::consider_builtin_fn_trait_candidates(self, goal, ty::ClosureKind::Fn) + } + Some(TraitSolverLangItem::FnMut) => { + G::consider_builtin_fn_trait_candidates(self, goal, ty::ClosureKind::FnMut) + } + Some(TraitSolverLangItem::FnOnce) => { + G::consider_builtin_fn_trait_candidates(self, goal, ty::ClosureKind::FnOnce) + } + Some(TraitSolverLangItem::AsyncFn) => { + G::consider_builtin_async_fn_trait_candidates(self, goal, ty::ClosureKind::Fn) + } + Some(TraitSolverLangItem::AsyncFnMut) => { + G::consider_builtin_async_fn_trait_candidates( + self, + goal, + ty::ClosureKind::FnMut, + ) + } + Some(TraitSolverLangItem::AsyncFnOnce) => { + G::consider_builtin_async_fn_trait_candidates( + self, + goal, + ty::ClosureKind::FnOnce, + ) + } Some(TraitSolverLangItem::PointerLike) => { G::consider_builtin_pointer_like_candidate(self, goal) } diff --git a/compiler/rustc_type_ir/src/interner.rs b/compiler/rustc_type_ir/src/interner.rs index 84c7e6e8f2003..f76a2f55c482e 100644 --- a/compiler/rustc_type_ir/src/interner.rs +++ b/compiler/rustc_type_ir/src/interner.rs @@ -254,10 +254,6 @@ pub trait Interner: fn trait_may_be_implemented_via_object(self, trait_def_id: Self::DefId) -> bool; - fn fn_trait_kind_from_def_id(self, trait_def_id: Self::DefId) -> Option; - - fn async_fn_trait_kind_from_def_id(self, trait_def_id: Self::DefId) -> Option; - fn supertrait_def_ids(self, trait_def_id: Self::DefId) -> impl IntoIterator; diff --git a/compiler/rustc_type_ir/src/lang_items.rs b/compiler/rustc_type_ir/src/lang_items.rs index cf00c37caa287..265a411882735 100644 --- a/compiler/rustc_type_ir/src/lang_items.rs +++ b/compiler/rustc_type_ir/src/lang_items.rs @@ -3,8 +3,11 @@ pub enum TraitSolverLangItem { // tidy-alphabetical-start AsyncDestruct, + AsyncFn, AsyncFnKindHelper, AsyncFnKindUpvars, + AsyncFnMut, + AsyncFnOnce, AsyncFnOnceOutput, AsyncIterator, CallOnceFuture, @@ -22,6 +25,9 @@ pub enum TraitSolverLangItem { EffectsMaybe, EffectsNoRuntime, EffectsRuntime, + Fn, + FnMut, + FnOnce, FnPtrTrait, FusedIterator, Future, From ecdaff240da6938473d14f784f8ba9a8c5f3611b Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 12 Jun 2024 11:53:52 -0400 Subject: [PATCH 617/892] Actually report normalization-based type errors correctly for alias-relate obligations in new solver --- .../error_reporting/type_err_ctxt_ext.rs | 149 ++++++++++++------ .../as_expression.next.stderr | 5 +- .../issue-100222.nn.stderr | 5 +- .../issue-100222.ny.stderr | 5 +- .../issue-100222.yn.stderr | 5 +- .../issue-100222.yy.stderr | 5 +- tests/ui/traits/next-solver/async.fail.stderr | 6 +- tests/ui/traits/next-solver/async.rs | 2 +- .../next-solver/more-object-bound.stderr | 15 +- 9 files changed, 140 insertions(+), 57 deletions(-) diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs index adf1076a7c90e..ff263eaac34fb 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs @@ -1586,60 +1586,113 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { } self.probe(|_| { - let ocx = ObligationCtxt::new(self); - // try to find the mismatched types to report the error with. // // this can fail if the problem was higher-ranked, in which // cause I have no idea for a good error message. let bound_predicate = predicate.kind(); - let (values, err) = if let ty::PredicateKind::Clause(ty::ClauseKind::Projection(data)) = - bound_predicate.skip_binder() - { - let data = self.instantiate_binder_with_fresh_vars( - obligation.cause.span, - infer::BoundRegionConversionTime::HigherRankedType, - bound_predicate.rebind(data), - ); - let unnormalized_term = data.projection_term.to_term(self.tcx); - // FIXME(-Znext-solver): For diagnostic purposes, it would be nice - // to deeply normalize this type. - let normalized_term = - ocx.normalize(&obligation.cause, obligation.param_env, unnormalized_term); - - debug!(?obligation.cause, ?obligation.param_env); - - debug!(?normalized_term, data.ty = ?data.term); + let (values, err) = match bound_predicate.skip_binder() { + ty::PredicateKind::Clause(ty::ClauseKind::Projection(data)) => { + let ocx = ObligationCtxt::new(self); + + let data = self.instantiate_binder_with_fresh_vars( + obligation.cause.span, + infer::BoundRegionConversionTime::HigherRankedType, + bound_predicate.rebind(data), + ); + let unnormalized_term = data.projection_term.to_term(self.tcx); + // FIXME(-Znext-solver): For diagnostic purposes, it would be nice + // to deeply normalize this type. + let normalized_term = + ocx.normalize(&obligation.cause, obligation.param_env, unnormalized_term); + + let is_normalized_term_expected = !matches!( + obligation.cause.code().peel_derives(), + ObligationCauseCode::WhereClause(..) + | ObligationCauseCode::WhereClauseInExpr(..) + | ObligationCauseCode::Coercion { .. } + ); - let is_normalized_term_expected = !matches!( - obligation.cause.code().peel_derives(), - |ObligationCauseCode::WhereClause(..)| ObligationCauseCode::WhereClauseInExpr( - .. - ) | ObligationCauseCode::Coercion { .. } - ); + let (expected, actual) = if is_normalized_term_expected { + (normalized_term, data.term) + } else { + (data.term, normalized_term) + }; - let (expected, actual) = if is_normalized_term_expected { - (normalized_term, data.term) - } else { - (data.term, normalized_term) - }; + // constrain inference variables a bit more to nested obligations from normalize so + // we can have more helpful errors. + // + // we intentionally drop errors from normalization here, + // since the normalization is just done to improve the error message. + let _ = ocx.select_where_possible(); - // constrain inference variables a bit more to nested obligations from normalize so - // we can have more helpful errors. - // - // we intentionally drop errors from normalization here, - // since the normalization is just done to improve the error message. - let _ = ocx.select_where_possible(); + if let Err(new_err) = + ocx.eq(&obligation.cause, obligation.param_env, expected, actual) + { + ( + Some(( + data.projection_term, + is_normalized_term_expected, + self.resolve_vars_if_possible(normalized_term), + data.term, + )), + new_err, + ) + } else { + (None, error.err) + } + } + ty::PredicateKind::AliasRelate(lhs, rhs, _) => { + let derive_better_type_error = + |alias_term: ty::AliasTerm<'tcx>, expected_term: ty::Term<'tcx>| { + let ocx = ObligationCtxt::new(self); + let normalized_term = match expected_term.unpack() { + ty::TermKind::Ty(_) => self.next_ty_var(DUMMY_SP).into(), + ty::TermKind::Const(_) => self.next_const_var(DUMMY_SP).into(), + }; + ocx.register_obligation(Obligation::new( + self.tcx, + ObligationCause::dummy(), + obligation.param_env, + ty::PredicateKind::NormalizesTo(ty::NormalizesTo { + alias: alias_term, + term: normalized_term, + }), + )); + let _ = ocx.select_where_possible(); + if let Err(terr) = ocx.eq( + &ObligationCause::dummy(), + obligation.param_env, + expected_term, + normalized_term, + ) { + Some((terr, self.resolve_vars_if_possible(normalized_term))) + } else { + None + } + }; - if let Err(new_err) = - ocx.eq(&obligation.cause, obligation.param_env, expected, actual) - { - (Some((data, is_normalized_term_expected, normalized_term, data.term)), new_err) - } else { - (None, error.err) + if let Some(lhs) = lhs.to_alias_term() + && let Some((better_type_err, expected_term)) = + derive_better_type_error(lhs, rhs) + { + ( + Some((lhs, true, self.resolve_vars_if_possible(expected_term), rhs)), + better_type_err, + ) + } else if let Some(rhs) = rhs.to_alias_term() + && let Some((better_type_err, expected_term)) = + derive_better_type_error(rhs, lhs) + { + ( + Some((rhs, true, self.resolve_vars_if_possible(expected_term), lhs)), + better_type_err, + ) + } else { + (None, error.err) + } } - } else { - (None, error.err) + _ => (None, error.err), }; let msg = values @@ -1737,15 +1790,15 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { fn maybe_detailed_projection_msg( &self, - pred: ty::ProjectionPredicate<'tcx>, + projection_term: ty::AliasTerm<'tcx>, normalized_ty: ty::Term<'tcx>, expected_ty: ty::Term<'tcx>, ) -> Option { - let trait_def_id = pred.projection_term.trait_def_id(self.tcx); - let self_ty = pred.projection_term.self_ty(); + let trait_def_id = projection_term.trait_def_id(self.tcx); + let self_ty = projection_term.self_ty(); with_forced_trimmed_paths! { - if self.tcx.is_lang_item(pred.projection_term.def_id,LangItem::FnOnceOutput) { + if self.tcx.is_lang_item(projection_term.def_id, LangItem::FnOnceOutput) { let fn_kind = self_ty.prefix_string(self.tcx); let item = match self_ty.kind() { ty::FnDef(def, _) => self.tcx.item_name(*def).to_string(), diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/as_expression.next.stderr b/tests/ui/diagnostic_namespace/do_not_recommend/as_expression.next.stderr index d189d2dbdedc8..a686b913c55ef 100644 --- a/tests/ui/diagnostic_namespace/do_not_recommend/as_expression.next.stderr +++ b/tests/ui/diagnostic_namespace/do_not_recommend/as_expression.next.stderr @@ -29,7 +29,10 @@ error[E0271]: type mismatch resolving `::SqlType == Tex --> $DIR/as_expression.rs:57:5 | LL | SelectInt.check("bar"); - | ^^^^^^^^^^^^^^^^^^^^^^ types differ + | ^^^^^^^^^^^^^^^^^^^^^^ expected `Integer`, found `Text` + | + = note: expected struct `Integer` + found struct `Text` error: aborting due to 3 previous errors diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-100222.nn.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-100222.nn.stderr index 4a949e90d8554..03536dca1e848 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-100222.nn.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-100222.nn.stderr @@ -2,7 +2,10 @@ error[E0271]: type mismatch resolving `<() as Index>::Output == &mut <() as Inde --> $DIR/issue-100222.rs:34:12 | LL | fn foo(&mut self, x: ::Output) -> ::Output - | ^^^^^^^^^ types differ + | ^^^^^^^^^ expected `()`, found `&mut <() as Index>::Output` + | + = note: expected unit type `()` + found mutable reference `&mut <() as Index>::Output` error: aborting due to 1 previous error diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-100222.ny.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-100222.ny.stderr index 1bfce48d26a2d..6a70a50360619 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-100222.ny.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-100222.ny.stderr @@ -2,7 +2,10 @@ error[E0271]: type mismatch resolving `<() as Index>::Output == &mut <() as Inde --> $DIR/issue-100222.rs:25:12 | LL | fn foo(&mut self, x: ::Output) -> ::Output - | ^^^^^^^^^ types differ + | ^^^^^^^^^ expected `()`, found `&mut <() as Index>::Output` + | + = note: expected unit type `()` + found mutable reference `&mut <() as Index>::Output` error: aborting due to 1 previous error diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-100222.yn.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-100222.yn.stderr index 4a949e90d8554..03536dca1e848 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-100222.yn.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-100222.yn.stderr @@ -2,7 +2,10 @@ error[E0271]: type mismatch resolving `<() as Index>::Output == &mut <() as Inde --> $DIR/issue-100222.rs:34:12 | LL | fn foo(&mut self, x: ::Output) -> ::Output - | ^^^^^^^^^ types differ + | ^^^^^^^^^ expected `()`, found `&mut <() as Index>::Output` + | + = note: expected unit type `()` + found mutable reference `&mut <() as Index>::Output` error: aborting due to 1 previous error diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-100222.yy.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-100222.yy.stderr index 1bfce48d26a2d..6a70a50360619 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-100222.yy.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-100222.yy.stderr @@ -2,7 +2,10 @@ error[E0271]: type mismatch resolving `<() as Index>::Output == &mut <() as Inde --> $DIR/issue-100222.rs:25:12 | LL | fn foo(&mut self, x: ::Output) -> ::Output - | ^^^^^^^^^ types differ + | ^^^^^^^^^ expected `()`, found `&mut <() as Index>::Output` + | + = note: expected unit type `()` + found mutable reference `&mut <() as Index>::Output` error: aborting due to 1 previous error diff --git a/tests/ui/traits/next-solver/async.fail.stderr b/tests/ui/traits/next-solver/async.fail.stderr index 83d520341bcc3..e47da338736f4 100644 --- a/tests/ui/traits/next-solver/async.fail.stderr +++ b/tests/ui/traits/next-solver/async.fail.stderr @@ -1,11 +1,13 @@ -error[E0271]: type mismatch resolving `<{async block@$DIR/async.rs:12:17: 12:22} as Future>::Output == i32` +error[E0271]: expected `{async block@$DIR/async.rs:12:17: 12:22}` to be a future that resolves to `i32`, but it resolves to `()` --> $DIR/async.rs:12:17 | LL | needs_async(async {}); - | ----------- ^^^^^^^^ types differ + | ----------- ^^^^^^^^ expected `()`, found `i32` | | | required by a bound introduced by this call | + = note: expected unit type `()` + found type `i32` note: required by a bound in `needs_async` --> $DIR/async.rs:8:31 | diff --git a/tests/ui/traits/next-solver/async.rs b/tests/ui/traits/next-solver/async.rs index 129e4cfaa028b..fded774354759 100644 --- a/tests/ui/traits/next-solver/async.rs +++ b/tests/ui/traits/next-solver/async.rs @@ -10,7 +10,7 @@ fn needs_async(_: impl Future) {} #[cfg(fail)] fn main() { needs_async(async {}); - //[fail]~^ ERROR type mismatch + //[fail]~^ ERROR expected `{async block@$DIR/async.rs:12:17: 12:22}` to be a future that resolves to `i32`, but it resolves to `()` } #[cfg(pass)] diff --git a/tests/ui/traits/next-solver/more-object-bound.stderr b/tests/ui/traits/next-solver/more-object-bound.stderr index 8cc2a51ee2b6c..043cbdff9ab9d 100644 --- a/tests/ui/traits/next-solver/more-object-bound.stderr +++ b/tests/ui/traits/next-solver/more-object-bound.stderr @@ -1,9 +1,22 @@ error[E0271]: type mismatch resolving ` as SuperTrait>::A == B` --> $DIR/more-object-bound.rs:12:5 | +LL | fn transmute(x: A) -> B { + | - - + | | | + | | expected type parameter + | | found type parameter + | found type parameter + | expected type parameter LL | foo::>(x) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ types differ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected type parameter `A`, found type parameter `B` | + = note: expected type parameter `A` + found type parameter `B` + = note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound + = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters + = note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound + = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters = note: required because it appears within the type `dyn Trait` note: required by a bound in `foo` --> $DIR/more-object-bound.rs:18:8 From b1059ccda210e11c19b3c639a13ddd64de781daf Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 2 Jul 2024 15:55:17 -0400 Subject: [PATCH 618/892] Instance::resolve -> Instance::try_resolve, and other nits --- .../src/diagnostics/conflict_errors.rs | 2 +- .../src/diagnostics/region_errors.rs | 2 +- .../src/check_consts/check.rs | 2 +- .../src/interpret/eval_context.rs | 2 +- .../nice_region_error/static_impl_trait.rs | 2 +- compiler/rustc_lint/src/internal.rs | 4 ++-- compiler/rustc_lint/src/noop_method_call.rs | 4 +++- .../rustc_middle/src/mir/interpret/queries.rs | 4 ++-- compiler/rustc_middle/src/ty/instance.rs | 22 ++++++++++++++----- compiler/rustc_middle/src/util/call_kind.rs | 2 +- compiler/rustc_mir_build/src/lints.rs | 2 +- .../rustc_mir_build/src/thir/pattern/mod.rs | 3 ++- compiler/rustc_mir_transform/src/inline.rs | 2 +- .../rustc_mir_transform/src/inline/cycle.rs | 2 +- compiler/rustc_passes/src/abi_test.rs | 2 +- compiler/rustc_smir/src/rustc_smir/context.rs | 2 +- .../clippy_lints/src/assigning_clones.rs | 4 ++-- .../clippy/clippy_lints/src/non_copy_const.rs | 2 +- src/tools/miri/src/eval.rs | 2 +- tests/ui/codegen/overflow-during-mono.rs | 1 + tests/ui/codegen/overflow-during-mono.stderr | 2 +- .../issue-58952-filter-type-length.rs | 1 + 22 files changed, 44 insertions(+), 27 deletions(-) diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index 44ab762f66e0a..7ef53fa2078e4 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -3733,7 +3733,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> { if tcx.is_diagnostic_item(sym::deref_method, method_did) { let deref_target = tcx.get_diagnostic_item(sym::deref_target).and_then(|deref_target| { - Instance::resolve(tcx, self.param_env, deref_target, method_args) + Instance::try_resolve(tcx, self.param_env, deref_target, method_args) .transpose() }); if let Some(Ok(instance)) = deref_target { diff --git a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs index fba18c381466b..e1df5a8ec1655 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs @@ -948,7 +948,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> { return; } - if let Ok(Some(instance)) = ty::Instance::resolve( + if let Ok(Some(instance)) = ty::Instance::try_resolve( tcx, self.param_env, *fn_did, diff --git a/compiler/rustc_const_eval/src/check_consts/check.rs b/compiler/rustc_const_eval/src/check_consts/check.rs index ab60cc3792098..0d8a17775dd3d 100644 --- a/compiler/rustc_const_eval/src/check_consts/check.rs +++ b/compiler/rustc_const_eval/src/check_consts/check.rs @@ -768,7 +768,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { is_trait = true; if let Ok(Some(instance)) = - Instance::resolve(tcx, param_env, callee, fn_args) + Instance::try_resolve(tcx, param_env, callee, fn_args) && let InstanceKind::Item(def) = instance.def { // Resolve a trait method call to its concrete implementation, which may be in a diff --git a/compiler/rustc_const_eval/src/interpret/eval_context.rs b/compiler/rustc_const_eval/src/interpret/eval_context.rs index 67eeb1b3b8712..830c4bd3e26e0 100644 --- a/compiler/rustc_const_eval/src/interpret/eval_context.rs +++ b/compiler/rustc_const_eval/src/interpret/eval_context.rs @@ -618,7 +618,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { trace!("resolve: {:?}, {:#?}", def, args); trace!("param_env: {:#?}", self.param_env); trace!("args: {:#?}", args); - match ty::Instance::resolve(*self.tcx, self.param_env, def, args) { + match ty::Instance::try_resolve(*self.tcx, self.param_env, def, args) { Ok(Some(instance)) => Ok(instance), Ok(None) => throw_inval!(TooGeneric), diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs index 71a86683c2123..9973646aecd6a 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs @@ -534,7 +534,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { let tcx = self.tcx(); // Find the method being called. - let Ok(Some(instance)) = ty::Instance::resolve( + let Ok(Some(instance)) = ty::Instance::try_resolve( tcx, ctxt.param_env, ctxt.assoc_item.def_id, diff --git a/compiler/rustc_lint/src/internal.rs b/compiler/rustc_lint/src/internal.rs index 9110cccdc46f0..772cc2ff8b997 100644 --- a/compiler/rustc_lint/src/internal.rs +++ b/compiler/rustc_lint/src/internal.rs @@ -88,7 +88,7 @@ declare_lint_pass!(QueryStability => [POTENTIAL_QUERY_INSTABILITY]); impl LateLintPass<'_> for QueryStability { fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) { let Some((span, def_id, args)) = typeck_results_of_method_fn(cx, expr) else { return }; - if let Ok(Some(instance)) = ty::Instance::resolve(cx.tcx, cx.param_env, def_id, args) { + if let Ok(Some(instance)) = ty::Instance::try_resolve(cx.tcx, cx.param_env, def_id, args) { let def_id = instance.def_id(); if cx.tcx.has_attr(def_id, sym::rustc_lint_query_instability) { cx.emit_span_lint( @@ -393,7 +393,7 @@ impl LateLintPass<'_> for Diagnostics { }; // Is the callee marked with `#[rustc_lint_diagnostics]`? - let has_attr = ty::Instance::resolve(cx.tcx, cx.param_env, def_id, fn_gen_args) + let has_attr = ty::Instance::try_resolve(cx.tcx, cx.param_env, def_id, fn_gen_args) .ok() .flatten() .is_some_and(|inst| cx.tcx.has_attr(inst.def_id(), sym::rustc_lint_diagnostics)); diff --git a/compiler/rustc_lint/src/noop_method_call.rs b/compiler/rustc_lint/src/noop_method_call.rs index 91441248e70fd..307e4bebe9a1b 100644 --- a/compiler/rustc_lint/src/noop_method_call.rs +++ b/compiler/rustc_lint/src/noop_method_call.rs @@ -96,7 +96,9 @@ impl<'tcx> LateLintPass<'tcx> for NoopMethodCall { .tcx .normalize_erasing_regions(cx.param_env, cx.typeck_results().node_args(expr.hir_id)); // Resolve the trait method instance. - let Ok(Some(i)) = ty::Instance::resolve(cx.tcx, cx.param_env, did, args) else { return }; + let Ok(Some(i)) = ty::Instance::try_resolve(cx.tcx, cx.param_env, did, args) else { + return; + }; // (Re)check that it implements the noop diagnostic. let Some(name) = cx.tcx.get_diagnostic_name(i.def_id()) else { return }; if !matches!( diff --git a/compiler/rustc_middle/src/mir/interpret/queries.rs b/compiler/rustc_middle/src/mir/interpret/queries.rs index 95857e8579d9a..96613592bbcce 100644 --- a/compiler/rustc_middle/src/mir/interpret/queries.rs +++ b/compiler/rustc_middle/src/mir/interpret/queries.rs @@ -73,7 +73,7 @@ impl<'tcx> TyCtxt<'tcx> { bug!("did not expect inference variables here"); } - match ty::Instance::resolve( + match ty::Instance::try_resolve( self, param_env, // FIXME: maybe have a separate version for resolving mir::UnevaluatedConst? ct.def, ct.args, @@ -106,7 +106,7 @@ impl<'tcx> TyCtxt<'tcx> { bug!("did not expect inference variables here"); } - match ty::Instance::resolve(self, param_env, ct.def, ct.args) { + match ty::Instance::try_resolve(self, param_env, ct.def, ct.args) { Ok(Some(instance)) => { let cid = GlobalId { instance, promoted: None }; self.const_eval_global_id_for_typeck(param_env, cid, span).inspect(|_| { diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs index 3f854ba74916f..ae54411d788ab 100644 --- a/compiler/rustc_middle/src/ty/instance.rs +++ b/compiler/rustc_middle/src/ty/instance.rs @@ -516,7 +516,7 @@ impl<'tcx> Instance<'tcx> { /// from `Ok(None)` to avoid misleading diagnostics when an error /// has already been/will be emitted, for the original cause #[instrument(level = "debug", skip(tcx), ret)] - pub fn resolve( + pub fn try_resolve( tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>, def_id: DefId, @@ -555,7 +555,7 @@ impl<'tcx> Instance<'tcx> { let span_or_local_def_span = || if span.is_dummy() && def_id.is_local() { tcx.def_span(def_id) } else { span }; - match ty::Instance::resolve(tcx, param_env, def_id, args) { + match ty::Instance::try_resolve(tcx, param_env, def_id, args) { Ok(Some(instance)) => instance, Ok(None) => { let type_length = type_length(args); @@ -605,7 +605,7 @@ impl<'tcx> Instance<'tcx> { // Use either `resolve_closure` or `resolve_for_vtable` assert!(!tcx.is_closure_like(def_id), "Called `resolve_for_fn_ptr` on closure: {def_id:?}"); let reason = tcx.sess.is_sanitizer_kcfi_enabled().then_some(ReifyReason::FnPtr); - Instance::resolve(tcx, param_env, def_id, args).ok().flatten().map(|mut resolved| { + Instance::try_resolve(tcx, param_env, def_id, args).ok().flatten().map(|mut resolved| { match resolved.def { InstanceKind::Item(def) if resolved.def.requires_caller_location(tcx) => { debug!(" => fn pointer created for function with #[track_caller]"); @@ -738,13 +738,25 @@ impl<'tcx> Instance<'tcx> { pub fn resolve_drop_in_place(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> ty::Instance<'tcx> { let def_id = tcx.require_lang_item(LangItem::DropInPlace, None); let args = tcx.mk_args(&[ty.into()]); - Instance::expect_resolve(tcx, ty::ParamEnv::reveal_all(), def_id, args, DUMMY_SP) + Instance::expect_resolve( + tcx, + ty::ParamEnv::reveal_all(), + def_id, + args, + ty.ty_adt_def().and_then(|adt| tcx.hir().span_if_local(adt.did())).unwrap_or(DUMMY_SP), + ) } pub fn resolve_async_drop_in_place(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> ty::Instance<'tcx> { let def_id = tcx.require_lang_item(LangItem::AsyncDropInPlace, None); let args = tcx.mk_args(&[ty.into()]); - Instance::expect_resolve(tcx, ty::ParamEnv::reveal_all(), def_id, args, DUMMY_SP) + Instance::expect_resolve( + tcx, + ty::ParamEnv::reveal_all(), + def_id, + args, + ty.ty_adt_def().and_then(|adt| tcx.hir().span_if_local(adt.did())).unwrap_or(DUMMY_SP), + ) } #[instrument(level = "debug", skip(tcx), ret)] diff --git a/compiler/rustc_middle/src/util/call_kind.rs b/compiler/rustc_middle/src/util/call_kind.rs index dc1d73684f4f2..0815c291173de 100644 --- a/compiler/rustc_middle/src/util/call_kind.rs +++ b/compiler/rustc_middle/src/util/call_kind.rs @@ -98,7 +98,7 @@ pub fn call_kind<'tcx>( Some(CallKind::Operator { self_arg, trait_id, self_ty: method_args.type_at(0) }) } else if is_deref { let deref_target = tcx.get_diagnostic_item(sym::deref_target).and_then(|deref_target| { - Instance::resolve(tcx, param_env, deref_target, method_args).transpose() + Instance::try_resolve(tcx, param_env, deref_target, method_args).transpose() }); if let Some(Ok(instance)) = deref_target { let deref_target_ty = instance.ty(tcx, param_env); diff --git a/compiler/rustc_mir_build/src/lints.rs b/compiler/rustc_mir_build/src/lints.rs index 2c817d605af2a..1c7aa9f9ed095 100644 --- a/compiler/rustc_mir_build/src/lints.rs +++ b/compiler/rustc_mir_build/src/lints.rs @@ -141,7 +141,7 @@ impl<'tcx> TerminatorClassifier<'tcx> for CallRecursion<'tcx> { return false; }; let (callee, call_args) = if let Ok(Some(instance)) = - Instance::resolve(tcx, param_env, callee, normalized_args) + Instance::try_resolve(tcx, param_env, callee, normalized_args) { (instance.def_id(), instance.args) } else { diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs index 93db1f618533b..fd778ef78a3ee 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs @@ -558,7 +558,8 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { let args = self .tcx .normalize_erasing_regions(param_env_reveal_all, self.typeck_results.node_args(id)); - let instance = match ty::Instance::resolve(self.tcx, param_env_reveal_all, def_id, args) { + let instance = match ty::Instance::try_resolve(self.tcx, param_env_reveal_all, def_id, args) + { Ok(Some(i)) => i, Ok(None) => { // It should be assoc consts if there's no error but we cannot resolve it. diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs index 6fa31c1174d0b..5075e0727548f 100644 --- a/compiler/rustc_mir_transform/src/inline.rs +++ b/compiler/rustc_mir_transform/src/inline.rs @@ -389,7 +389,7 @@ impl<'tcx> Inliner<'tcx> { // To resolve an instance its args have to be fully normalized. let args = self.tcx.try_normalize_erasing_regions(self.param_env, args).ok()?; let callee = - Instance::resolve(self.tcx, self.param_env, def_id, args).ok().flatten()?; + Instance::try_resolve(self.tcx, self.param_env, def_id, args).ok().flatten()?; if let InstanceKind::Virtual(..) | InstanceKind::Intrinsic(_) = callee.def { return None; diff --git a/compiler/rustc_mir_transform/src/inline/cycle.rs b/compiler/rustc_mir_transform/src/inline/cycle.rs index 35bcd24ce95ba..d4477563e3adb 100644 --- a/compiler/rustc_mir_transform/src/inline/cycle.rs +++ b/compiler/rustc_mir_transform/src/inline/cycle.rs @@ -53,7 +53,7 @@ pub(crate) fn mir_callgraph_reachable<'tcx>( trace!(?caller, ?param_env, ?args, "cannot normalize, skipping"); continue; }; - let Ok(Some(callee)) = ty::Instance::resolve(tcx, param_env, callee, args) else { + let Ok(Some(callee)) = ty::Instance::try_resolve(tcx, param_env, callee, args) else { trace!(?callee, "cannot resolve, skipping"); continue; }; diff --git a/compiler/rustc_passes/src/abi_test.rs b/compiler/rustc_passes/src/abi_test.rs index 0c3dd649997ef..839b96fb3de84 100644 --- a/compiler/rustc_passes/src/abi_test.rs +++ b/compiler/rustc_passes/src/abi_test.rs @@ -61,7 +61,7 @@ fn unwrap_fn_abi<'tcx>( fn dump_abi_of_fn_item(tcx: TyCtxt<'_>, item_def_id: LocalDefId, attr: &Attribute) { let param_env = tcx.param_env(item_def_id); let args = GenericArgs::identity_for_item(tcx, item_def_id); - let instance = match Instance::resolve(tcx, param_env, item_def_id.into(), args) { + let instance = match Instance::try_resolve(tcx, param_env, item_def_id.into(), args) { Ok(Some(instance)) => instance, Ok(None) => { // Not sure what to do here, but `LayoutError::Unknown` seems reasonable? diff --git a/compiler/rustc_smir/src/rustc_smir/context.rs b/compiler/rustc_smir/src/rustc_smir/context.rs index 4eefd0eb17c40..b0ced8e920fe5 100644 --- a/compiler/rustc_smir/src/rustc_smir/context.rs +++ b/compiler/rustc_smir/src/rustc_smir/context.rs @@ -629,7 +629,7 @@ impl<'tcx> Context for TablesWrapper<'tcx> { let tcx = tables.tcx; let def_id = def.0.internal(&mut *tables, tcx); let args_ref = args.internal(&mut *tables, tcx); - match Instance::resolve(tables.tcx, ParamEnv::reveal_all(), def_id, args_ref) { + match Instance::try_resolve(tables.tcx, ParamEnv::reveal_all(), def_id, args_ref) { Ok(Some(instance)) => Some(instance.stable(&mut *tables)), Ok(None) | Err(_) => None, } diff --git a/src/tools/clippy/clippy_lints/src/assigning_clones.rs b/src/tools/clippy/clippy_lints/src/assigning_clones.rs index 05ea74b0d534f..406f38f411ecd 100644 --- a/src/tools/clippy/clippy_lints/src/assigning_clones.rs +++ b/src/tools/clippy/clippy_lints/src/assigning_clones.rs @@ -103,7 +103,7 @@ fn extract_call<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) -> Option< let args = cx.typeck_results().node_args(expr.hir_id); // If we could not resolve the method, don't apply the lint - let Ok(Some(resolved_method)) = Instance::resolve(cx.tcx, cx.param_env, fn_def_id, args) else { + let Ok(Some(resolved_method)) = Instance::try_resolve(cx.tcx, cx.param_env, fn_def_id, args) else { return None; }; if is_trait_method(cx, expr, sym::Clone) && path.ident.name == sym::clone { @@ -119,7 +119,7 @@ fn extract_call<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) -> Option< // If we could not resolve the method, don't apply the lint let Ok(Some(resolved_method)) = (match kind { - ty::FnDef(_, args) => Instance::resolve(cx.tcx, cx.param_env, fn_def_id, args), + ty::FnDef(_, args) => Instance::try_resolve(cx.tcx, cx.param_env, fn_def_id, args), _ => Ok(None), }) else { return None; diff --git a/src/tools/clippy/clippy_lints/src/non_copy_const.rs b/src/tools/clippy/clippy_lints/src/non_copy_const.rs index 5cb8e7bfab2a9..b71ebe35eb6a8 100644 --- a/src/tools/clippy/clippy_lints/src/non_copy_const.rs +++ b/src/tools/clippy/clippy_lints/src/non_copy_const.rs @@ -293,7 +293,7 @@ impl<'tcx> NonCopyConst<'tcx> { ct: ty::UnevaluatedConst<'tcx>, span: Span, ) -> EvalToValTreeResult<'tcx> { - match ty::Instance::resolve(tcx, param_env, ct.def, ct.args) { + match ty::Instance::try_resolve(tcx, param_env, ct.def, ct.args) { Ok(Some(instance)) => { let cid = GlobalId { instance, diff --git a/src/tools/miri/src/eval.rs b/src/tools/miri/src/eval.rs index c0827cce26301..9142b8b5fdbc0 100644 --- a/src/tools/miri/src/eval.rs +++ b/src/tools/miri/src/eval.rs @@ -375,7 +375,7 @@ pub fn create_ecx<'tcx>( }); let main_ret_ty = tcx.fn_sig(entry_id).no_bound_vars().unwrap().output(); let main_ret_ty = main_ret_ty.no_bound_vars().unwrap(); - let start_instance = ty::Instance::resolve( + let start_instance = ty::Instance::try_resolve( tcx, ty::ParamEnv::reveal_all(), start_id, diff --git a/tests/ui/codegen/overflow-during-mono.rs b/tests/ui/codegen/overflow-during-mono.rs index 278298f27ff0e..4d3f2c18dc837 100644 --- a/tests/ui/codegen/overflow-during-mono.rs +++ b/tests/ui/codegen/overflow-during-mono.rs @@ -1,4 +1,5 @@ //@ build-fail +//@ error-pattern: reached the type-length limit while instantiating #![recursion_limit = "32"] diff --git a/tests/ui/codegen/overflow-during-mono.stderr b/tests/ui/codegen/overflow-during-mono.stderr index 9e463378004dc..e06fcd289669f 100644 --- a/tests/ui/codegen/overflow-during-mono.stderr +++ b/tests/ui/codegen/overflow-during-mono.stderr @@ -1,4 +1,4 @@ -error: reached the type-length limit while instantiating `, {closure@$DIR/overflow-during-mono.rs:12:41: 12:44}>, ...> as Iterator>::try_fold::<..., ..., ...>` +error: reached the type-length limit while instantiating `, {closure@$DIR/overflow-during-mono.rs:13:41: 13:44}>, ...> as Iterator>::try_fold::<..., ..., ...>` --> $SRC_DIR/core/src/iter/adapters/filter.rs:LL:COL | = help: consider adding a `#![type_length_limit="20156994"]` attribute to your crate diff --git a/tests/ui/iterators/issue-58952-filter-type-length.rs b/tests/ui/iterators/issue-58952-filter-type-length.rs index b2c208ae28f19..4f3ddce69d822 100644 --- a/tests/ui/iterators/issue-58952-filter-type-length.rs +++ b/tests/ui/iterators/issue-58952-filter-type-length.rs @@ -1,4 +1,5 @@ //@ build-fail +//@ error-pattern: reached the type-length limit while instantiating //! This snippet causes the type length to blowup exponentially, //! so check that we don't accidentally exceed the type length limit. From 9f32459c988dec799458f304bbc49ed5dc6ef772 Mon Sep 17 00:00:00 2001 From: yukang Date: Wed, 3 Jul 2024 06:15:17 +0800 Subject: [PATCH 619/892] Fix incorrect suggestion for extra argument with a type error --- .../rustc_hir_typeck/src/fn_ctxt/checks.rs | 26 ++++ .../suggest-better-removing-issue-126246.rs | 21 +++ ...uggest-better-removing-issue-126246.stderr | 124 ++++++++++++++++++ 3 files changed, 171 insertions(+) create mode 100644 tests/ui/argument-suggestions/suggest-better-removing-issue-126246.rs create mode 100644 tests/ui/argument-suggestions/suggest-better-removing-issue-126246.stderr diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index 63148ab517c5d..c6d72700b3fce 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -951,6 +951,32 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return err.emit(); } + // Special case, we found an extra argument is provided, which is very common in practice. + // but there is a obviously better removing suggestion compared to the current one, + // try to find the argument with Error type, if we removed it all the types will become good, + // then we will replace the current suggestion. + if let [Error::Extra(provided_idx)] = &errors[..] { + let remove_idx_is_perfect = |idx: usize| -> bool { + let removed_arg_tys = provided_arg_tys + .iter() + .enumerate() + .filter_map(|(j, arg)| if idx == j { None } else { Some(arg) }) + .collect::>(); + std::iter::zip(formal_and_expected_inputs.iter(), removed_arg_tys.iter()).all( + |((expected_ty, _), (provided_ty, _))| { + !provided_ty.references_error() + && self.can_coerce(*provided_ty, *expected_ty) + }, + ) + }; + + if !remove_idx_is_perfect(provided_idx.as_usize()) { + if let Some(i) = (0..provided_args.len()).find(|&i| remove_idx_is_perfect(i)) { + errors = vec![Error::Extra(ProvidedIdx::from_usize(i))]; + } + } + } + let mut err = if formal_and_expected_inputs.len() == provided_args.len() { struct_span_code_err!( self.dcx(), diff --git a/tests/ui/argument-suggestions/suggest-better-removing-issue-126246.rs b/tests/ui/argument-suggestions/suggest-better-removing-issue-126246.rs new file mode 100644 index 0000000000000..fa1802283c39c --- /dev/null +++ b/tests/ui/argument-suggestions/suggest-better-removing-issue-126246.rs @@ -0,0 +1,21 @@ +fn add_one(x: i32) -> i32 { + x + 1 +} + +fn add_two(x: i32, y: i32) -> i32 { + x + y +} + +fn main() { + add_one(2, 2); //~ ERROR this function takes 1 argument but 2 arguments were supplied + add_one(no_such_local, 10); //~ ERROR cannot find value `no_such_local` in this scope + //~| ERROR this function takes 1 argument but 2 arguments were supplied + add_one(10, no_such_local); //~ ERROR cannot find value `no_such_local` in this scope + //~| ERROR this function takes 1 argument but 2 arguments were supplied + add_two(10, no_such_local, 10); //~ ERROR cannot find value `no_such_local` in this scope + //~| ERROR this function takes 2 arguments but 3 arguments were supplied + add_two(no_such_local, 10, 10); //~ ERROR cannot find value `no_such_local` in this scope + //~| ERROR this function takes 2 arguments but 3 arguments were supplied + add_two(10, 10, no_such_local); //~ ERROR cannot find value `no_such_local` in this scope + //~| ERROR this function takes 2 arguments but 3 arguments were supplied +} diff --git a/tests/ui/argument-suggestions/suggest-better-removing-issue-126246.stderr b/tests/ui/argument-suggestions/suggest-better-removing-issue-126246.stderr new file mode 100644 index 0000000000000..7c4daa3ffe95b --- /dev/null +++ b/tests/ui/argument-suggestions/suggest-better-removing-issue-126246.stderr @@ -0,0 +1,124 @@ +error[E0425]: cannot find value `no_such_local` in this scope + --> $DIR/suggest-better-removing-issue-126246.rs:11:13 + | +LL | add_one(no_such_local, 10); + | ^^^^^^^^^^^^^ not found in this scope + +error[E0425]: cannot find value `no_such_local` in this scope + --> $DIR/suggest-better-removing-issue-126246.rs:13:17 + | +LL | add_one(10, no_such_local); + | ^^^^^^^^^^^^^ not found in this scope + +error[E0425]: cannot find value `no_such_local` in this scope + --> $DIR/suggest-better-removing-issue-126246.rs:15:17 + | +LL | add_two(10, no_such_local, 10); + | ^^^^^^^^^^^^^ not found in this scope + +error[E0425]: cannot find value `no_such_local` in this scope + --> $DIR/suggest-better-removing-issue-126246.rs:17:13 + | +LL | add_two(no_such_local, 10, 10); + | ^^^^^^^^^^^^^ not found in this scope + +error[E0425]: cannot find value `no_such_local` in this scope + --> $DIR/suggest-better-removing-issue-126246.rs:19:21 + | +LL | add_two(10, 10, no_such_local); + | ^^^^^^^^^^^^^ not found in this scope + +error[E0061]: this function takes 1 argument but 2 arguments were supplied + --> $DIR/suggest-better-removing-issue-126246.rs:10:5 + | +LL | add_one(2, 2); + | ^^^^^^^ --- + | | | + | | unexpected argument of type `{integer}` + | help: remove the extra argument + | +note: function defined here + --> $DIR/suggest-better-removing-issue-126246.rs:1:4 + | +LL | fn add_one(x: i32) -> i32 { + | ^^^^^^^ ------ + +error[E0061]: this function takes 1 argument but 2 arguments were supplied + --> $DIR/suggest-better-removing-issue-126246.rs:11:5 + | +LL | add_one(no_such_local, 10); + | ^^^^^^^ --------------- + | | + | unexpected argument + | help: remove the extra argument + | +note: function defined here + --> $DIR/suggest-better-removing-issue-126246.rs:1:4 + | +LL | fn add_one(x: i32) -> i32 { + | ^^^^^^^ ------ + +error[E0061]: this function takes 1 argument but 2 arguments were supplied + --> $DIR/suggest-better-removing-issue-126246.rs:13:5 + | +LL | add_one(10, no_such_local); + | ^^^^^^^ --------------- + | | | + | | unexpected argument + | help: remove the extra argument + | +note: function defined here + --> $DIR/suggest-better-removing-issue-126246.rs:1:4 + | +LL | fn add_one(x: i32) -> i32 { + | ^^^^^^^ ------ + +error[E0061]: this function takes 2 arguments but 3 arguments were supplied + --> $DIR/suggest-better-removing-issue-126246.rs:15:5 + | +LL | add_two(10, no_such_local, 10); + | ^^^^^^^ --------------- + | | | + | | unexpected argument + | help: remove the extra argument + | +note: function defined here + --> $DIR/suggest-better-removing-issue-126246.rs:5:4 + | +LL | fn add_two(x: i32, y: i32) -> i32 { + | ^^^^^^^ ------ ------ + +error[E0061]: this function takes 2 arguments but 3 arguments were supplied + --> $DIR/suggest-better-removing-issue-126246.rs:17:5 + | +LL | add_two(no_such_local, 10, 10); + | ^^^^^^^ --------------- + | | + | unexpected argument + | help: remove the extra argument + | +note: function defined here + --> $DIR/suggest-better-removing-issue-126246.rs:5:4 + | +LL | fn add_two(x: i32, y: i32) -> i32 { + | ^^^^^^^ ------ ------ + +error[E0061]: this function takes 2 arguments but 3 arguments were supplied + --> $DIR/suggest-better-removing-issue-126246.rs:19:5 + | +LL | add_two(10, 10, no_such_local); + | ^^^^^^^ --------------- + | | | + | | unexpected argument + | help: remove the extra argument + | +note: function defined here + --> $DIR/suggest-better-removing-issue-126246.rs:5:4 + | +LL | fn add_two(x: i32, y: i32) -> i32 { + | ^^^^^^^ ------ ------ + +error: aborting due to 11 previous errors + +Some errors have detailed explanations: E0061, E0425. +For more information about an error, try `rustc --explain E0061`. From 64a3bd84d83a6138b6e7db82a53199246f292e53 Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Fri, 21 Jun 2024 14:01:15 -0500 Subject: [PATCH 620/892] Always preserve user-written comments in assembly --- compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp | 3 ++- tests/assembly/asm-comments.rs | 12 ++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 tests/assembly/asm-comments.rs diff --git a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp index c4cfc0b6dc6a1..a868c56c4e625 100644 --- a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp @@ -436,7 +436,8 @@ extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine( Options.FunctionSections = FunctionSections; Options.UniqueSectionNames = UniqueSectionNames; Options.MCOptions.AsmVerbose = AsmComments; - Options.MCOptions.PreserveAsmComments = AsmComments; + // Always preserve comments that were written by the user + Options.MCOptions.PreserveAsmComments = true; Options.MCOptions.ABIName = ABIStr; if (SplitDwarfFile) { Options.MCOptions.SplitDwarfFile = SplitDwarfFile; diff --git a/tests/assembly/asm-comments.rs b/tests/assembly/asm-comments.rs new file mode 100644 index 0000000000000..557009975ddc9 --- /dev/null +++ b/tests/assembly/asm-comments.rs @@ -0,0 +1,12 @@ +//@ assembly-output: emit-asm +//@ only-x86_64 +// Check that comments in assembly get passed + +#![crate_type = "lib"] + +// CHECK-LABEL: test_comments: +#[no_mangle] +pub fn test_comments() { + // CHECK: example comment + unsafe { core::arch::asm!("nop // example comment") }; +} From c15a698f567356cea22e79686c2883f3557bae0b Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Fri, 21 Jun 2024 14:08:49 -0500 Subject: [PATCH 621/892] Rename the `asm-comments` compiler flag to `verbose-asm` Since this codegen flag now only controls LLVM-generated comments rather than all assembly comments, make the name more accurate (and also match Clang). --- compiler/rustc_codegen_llvm/src/back/owned_target_machine.rs | 4 ++-- compiler/rustc_codegen_llvm/src/back/write.rs | 4 ++-- compiler/rustc_codegen_llvm/src/llvm/ffi.rs | 2 +- compiler/rustc_interface/src/tests.rs | 2 +- compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp | 4 ++-- compiler/rustc_session/src/options.rs | 4 ++-- 6 files changed, 10 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/back/owned_target_machine.rs b/compiler/rustc_codegen_llvm/src/back/owned_target_machine.rs index 28a88dd2efea0..b72636a62248e 100644 --- a/compiler/rustc_codegen_llvm/src/back/owned_target_machine.rs +++ b/compiler/rustc_codegen_llvm/src/back/owned_target_machine.rs @@ -32,7 +32,7 @@ impl OwnedTargetMachine { unique_section_names: bool, trap_unreachable: bool, singletree: bool, - asm_comments: bool, + verbose_asm: bool, emit_stack_size_section: bool, relax_elf_relocations: bool, use_init_array: bool, @@ -64,7 +64,7 @@ impl OwnedTargetMachine { unique_section_names, trap_unreachable, singletree, - asm_comments, + verbose_asm, emit_stack_size_section, relax_elf_relocations, use_init_array, diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs index 5e481eb98f55f..2fda19bf0c914 100644 --- a/compiler/rustc_codegen_llvm/src/back/write.rs +++ b/compiler/rustc_codegen_llvm/src/back/write.rs @@ -214,7 +214,7 @@ pub fn target_machine_factory( sess.opts.unstable_opts.trap_unreachable.unwrap_or(sess.target.trap_unreachable); let emit_stack_size_section = sess.opts.unstable_opts.emit_stack_sizes; - let asm_comments = sess.opts.unstable_opts.asm_comments; + let verbose_asm = sess.opts.unstable_opts.verbose_asm; let relax_elf_relocations = sess.opts.unstable_opts.relax_elf_relocations.unwrap_or(sess.target.relax_elf_relocations); @@ -289,7 +289,7 @@ pub fn target_machine_factory( funique_section_names, trap_unreachable, singlethread, - asm_comments, + verbose_asm, emit_stack_size_section, relax_elf_relocations, use_init_array, diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs index 132e1f9e8fd93..08e9e312827ce 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs @@ -2185,7 +2185,7 @@ extern "C" { UniqueSectionNames: bool, TrapUnreachable: bool, Singlethread: bool, - AsmComments: bool, + VerboseAsm: bool, EmitStackSizeSection: bool, RelaxELFRelocations: bool, UseInitArray: bool, diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index 9bd67a1154b7d..e2ba75dfd1902 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -757,7 +757,6 @@ fn test_unstable_options_tracking_hash() { // tidy-alphabetical-start tracked!(allow_features, Some(vec![String::from("lang_items")])); tracked!(always_encode_mir, true); - tracked!(asm_comments, true); tracked!(assume_incomplete_release, true); tracked!(binary_dep_depinfo, true); tracked!(box_noalias, false); @@ -862,6 +861,7 @@ fn test_unstable_options_tracking_hash() { tracked!(uninit_const_chunk_threshold, 123); tracked!(unleash_the_miri_inside_of_you, true); tracked!(use_ctors_section, Some(true)); + tracked!(verbose_asm, true); tracked!(verify_llvm_ir, true); tracked!(virtual_function_elimination, true); tracked!(wasi_exec_model, Some(WasiExecModel::Reactor)); diff --git a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp index a868c56c4e625..283c4fbbb7cf4 100644 --- a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp @@ -407,7 +407,7 @@ extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine( const char *ABIStr, LLVMRustCodeModel RustCM, LLVMRustRelocModel RustReloc, LLVMRustCodeGenOptLevel RustOptLevel, bool UseSoftFloat, bool FunctionSections, bool DataSections, bool UniqueSectionNames, - bool TrapUnreachable, bool Singlethread, bool AsmComments, + bool TrapUnreachable, bool Singlethread, bool VerboseAsm, bool EmitStackSizeSection, bool RelaxELFRelocations, bool UseInitArray, const char *SplitDwarfFile, const char *OutputObjFile, const char *DebugInfoCompression, bool UseEmulatedTls, @@ -435,7 +435,7 @@ extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine( Options.DataSections = DataSections; Options.FunctionSections = FunctionSections; Options.UniqueSectionNames = UniqueSectionNames; - Options.MCOptions.AsmVerbose = AsmComments; + Options.MCOptions.AsmVerbose = VerboseAsm; // Always preserve comments that were written by the user Options.MCOptions.PreserveAsmComments = true; Options.MCOptions.ABIName = ABIStr; diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index 2e4421d50e313..7421cae65e4f8 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -1630,8 +1630,6 @@ options! { "only allow the listed language features to be enabled in code (comma separated)"), always_encode_mir: bool = (false, parse_bool, [TRACKED], "encode MIR of all functions into the crate metadata (default: no)"), - asm_comments: bool = (false, parse_bool, [TRACKED], - "generate comments into the assembly (may change behavior) (default: no)"), assert_incr_state: Option = (None, parse_opt_string, [UNTRACKED], "assert that the incremental cache is in given state: \ either `loaded` or `not-loaded`."), @@ -2107,6 +2105,8 @@ written to standard error output)"), "Generate sync unwind tables instead of async unwind tables (default: no)"), validate_mir: bool = (false, parse_bool, [UNTRACKED], "validate MIR after each transformation"), + verbose_asm: bool = (false, parse_bool, [TRACKED], + "add descriptive comments from LLVM to the assembly (may change behavior) (default: no)"), #[rustc_lint_opt_deny_field_access("use `Session::verbose_internals` instead of this field")] verbose_internals: bool = (false, parse_bool, [TRACKED_NO_CRATE_HASH], "in general, enable more debug printouts (default: no)"), From 1a6893e14b7d08aee18acf82b9a08e1ba8534d7b Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Fri, 21 Jun 2024 14:17:47 -0500 Subject: [PATCH 622/892] Add documentation for -Zverbose-asm --- .../src/compiler-flags/verbose-asm.md | 70 +++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 src/doc/unstable-book/src/compiler-flags/verbose-asm.md diff --git a/src/doc/unstable-book/src/compiler-flags/verbose-asm.md b/src/doc/unstable-book/src/compiler-flags/verbose-asm.md new file mode 100644 index 0000000000000..84eb90a14cf53 --- /dev/null +++ b/src/doc/unstable-book/src/compiler-flags/verbose-asm.md @@ -0,0 +1,70 @@ +# `verbose-asm` + +The tracking issue for this feature is: [#126802](https://github.com/rust-lang/rust/issues/126802). + +------------------------ + +This enables passing `-Zverbose-asm` to get contextual comments added by LLVM. + +Sample code: + +```rust +#[no_mangle] +pub fn foo(a: i32, b: i32) -> i32 { + a + b +} +``` + +Default output: + +```asm +foo: + push rax + add edi, esi + mov dword ptr [rsp + 4], edi + seto al + jo .LBB0_2 + mov eax, dword ptr [rsp + 4] + pop rcx + ret +.LBB0_2: + lea rdi, [rip + .L__unnamed_1] + mov rax, qword ptr [rip + core::panicking::panic_const::panic_const_add_overflow::h9c85248fe0d735b2@GOTPCREL] + call rax + +.L__unnamed_2: + .ascii "/app/example.rs" + +.L__unnamed_1: + .quad .L__unnamed_2 + .asciz "\017\000\000\000\000\000\000\000\004\000\000\000\005\000\000" +``` + +With `-Zverbose-asm`: + +```asm +foo: # @foo +# %bb.0: + push rax + add edi, esi + mov dword ptr [rsp + 4], edi # 4-byte Spill + seto al + jo .LBB0_2 +# %bb.1: + mov eax, dword ptr [rsp + 4] # 4-byte Reload + pop rcx + ret +.LBB0_2: + lea rdi, [rip + .L__unnamed_1] + mov rax, qword ptr [rip + core::panicking::panic_const::panic_const_add_overflow::h9c85248fe0d735b2@GOTPCREL] + call rax + # -- End function +.L__unnamed_2: + .ascii "/app/example.rs" + +.L__unnamed_1: + .quad .L__unnamed_2 + .asciz "\017\000\000\000\000\000\000\000\004\000\000\000\005\000\000" + + # DW_AT_external +``` From 1ca7e24e3630e05dd1fbbe2a304a400f0aa521b8 Mon Sep 17 00:00:00 2001 From: Weihang Lo Date: Tue, 2 Jul 2024 23:34:50 -0400 Subject: [PATCH 623/892] Update cargo --- src/tools/cargo | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/cargo b/src/tools/cargo index 4ed7bee47f7dd..a515d463427b3 160000 --- a/src/tools/cargo +++ b/src/tools/cargo @@ -1 +1 @@ -Subproject commit 4ed7bee47f7dd4416b36fada1909e9a62c546246 +Subproject commit a515d463427b3912ec0365d106791f88c1c14e1b From a6c03ae6fe3dd93146be3a1f7fd65ccd58e3ab67 Mon Sep 17 00:00:00 2001 From: B I Mohammed Abbas Date: Mon, 1 Jul 2024 10:33:27 +0530 Subject: [PATCH 624/892] Fall back on remove dir implementation for vxworks --- library/std/src/sys/pal/unix/fs.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/library/std/src/sys/pal/unix/fs.rs b/library/std/src/sys/pal/unix/fs.rs index 92c76ec4303fe..f9d6b5fbc86a4 100644 --- a/library/std/src/sys/pal/unix/fs.rs +++ b/library/std/src/sys/pal/unix/fs.rs @@ -1976,13 +1976,14 @@ pub fn chroot(dir: &Path) -> io::Result<()> { pub use remove_dir_impl::remove_dir_all; -// Fallback for REDOX, ESP-ID, Horizon, Vita and Miri +// Fallback for REDOX, ESP-ID, Horizon, Vita, Vxworks and Miri #[cfg(any( target_os = "redox", target_os = "espidf", target_os = "horizon", target_os = "vita", target_os = "nto", + target_os = "vxworks", miri ))] mod remove_dir_impl { @@ -1996,6 +1997,7 @@ mod remove_dir_impl { target_os = "horizon", target_os = "vita", target_os = "nto", + target_os = "vxworks", miri )))] mod remove_dir_impl { From d982844b47c88c2d78cde42de88f27ce75586972 Mon Sep 17 00:00:00 2001 From: Tobias Decking Date: Mon, 1 Jul 2024 21:01:49 +0200 Subject: [PATCH 625/892] Implement the `_mm256_zeroupper` and `_mm256_zeroall` intrinsics --- src/tools/miri/src/shims/x86/avx.rs | 11 +++++++++++ .../miri/tests/pass/shims/x86/intrinsics-x86-avx.rs | 5 +++++ 2 files changed, 16 insertions(+) diff --git a/src/tools/miri/src/shims/x86/avx.rs b/src/tools/miri/src/shims/x86/avx.rs index 0d2977b7b6fe8..f36bb4826e487 100644 --- a/src/tools/miri/src/shims/x86/avx.rs +++ b/src/tools/miri/src/shims/x86/avx.rs @@ -338,6 +338,17 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_scalar(Scalar::from_i32(res.into()), dest)?; } + // Used to implement the `_mm256_zeroupper` and `_mm256_zeroall` functions. + // These function clear out the upper 128 bits of all avx registers or + // zero out all avx registers respectively. + "vzeroupper" | "vzeroall" => { + // These functions are purely a performance hint for the CPU. + // Any registers currently in use will be saved beforehand by the + // compiler, making these functions no-ops. + + // The only thing that needs to be ensured is the correct calling convention. + let [] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + } _ => return Ok(EmulateItemResult::NotSupported), } Ok(EmulateItemResult::NeedsReturn) diff --git a/src/tools/miri/tests/pass/shims/x86/intrinsics-x86-avx.rs b/src/tools/miri/tests/pass/shims/x86/intrinsics-x86-avx.rs index 7d43cc596aedb..728f57d48f17e 100644 --- a/src/tools/miri/tests/pass/shims/x86/intrinsics-x86-avx.rs +++ b/src/tools/miri/tests/pass/shims/x86/intrinsics-x86-avx.rs @@ -1342,6 +1342,11 @@ unsafe fn test_avx() { assert_eq!(r, 1); } test_mm_testnzc_ps(); + + // These intrinsics are functionally no-ops. The only thing + // that needs to be tested is that they can be executed. + _mm256_zeroupper(); + _mm256_zeroall(); } #[target_feature(enable = "sse2")] From 9e71c7b5a98fb1f18eade36c9188467616550ffc Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 3 Jul 2024 11:34:39 +0200 Subject: [PATCH 626/892] Small `run-make-support` API improvements --- src/tools/run-make-support/src/lib.rs | 6 ++++-- src/tools/run-make-support/src/rustc.rs | 3 ++- tests/run-make/emit-named-files/rmake.rs | 2 +- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/tools/run-make-support/src/lib.rs b/src/tools/run-make-support/src/lib.rs index 294dae109425f..9a180fe4ad19a 100644 --- a/src/tools/run-make-support/src/lib.rs +++ b/src/tools/run-make-support/src/lib.rs @@ -321,8 +321,9 @@ pub fn set_host_rpath(cmd: &mut Command) { /// Read the contents of a file that cannot simply be read by /// read_to_string, due to invalid utf8 data, then assert that it contains `expected`. #[track_caller] -pub fn invalid_utf8_contains>(path: P, expected: &str) { +pub fn invalid_utf8_contains, S: AsRef>(path: P, expected: S) { let buffer = fs_wrapper::read(path.as_ref()); + let expected = expected.as_ref(); if !String::from_utf8_lossy(&buffer).contains(expected) { eprintln!("=== FILE CONTENTS (LOSSY) ==="); eprintln!("{}", String::from_utf8_lossy(&buffer)); @@ -335,8 +336,9 @@ pub fn invalid_utf8_contains>(path: P, expected: &str) { /// Read the contents of a file that cannot simply be read by /// read_to_string, due to invalid utf8 data, then assert that it does not contain `expected`. #[track_caller] -pub fn invalid_utf8_not_contains>(path: P, expected: &str) { +pub fn invalid_utf8_not_contains, S: AsRef>(path: P, expected: S) { let buffer = fs_wrapper::read(path.as_ref()); + let expected = expected.as_ref(); if String::from_utf8_lossy(&buffer).contains(expected) { eprintln!("=== FILE CONTENTS (LOSSY) ==="); eprintln!("{}", String::from_utf8_lossy(&buffer)); diff --git a/src/tools/run-make-support/src/rustc.rs b/src/tools/run-make-support/src/rustc.rs index 3f23c1b8f9e76..054836e87cfbc 100644 --- a/src/tools/run-make-support/src/rustc.rs +++ b/src/tools/run-make-support/src/rustc.rs @@ -86,7 +86,8 @@ impl Rustc { } /// Specify type(s) of output files to generate. - pub fn emit(&mut self, kinds: &str) -> &mut Self { + pub fn emit>(&mut self, kinds: S) -> &mut Self { + let kinds = kinds.as_ref(); self.cmd.arg(format!("--emit={kinds}")); self } diff --git a/tests/run-make/emit-named-files/rmake.rs b/tests/run-make/emit-named-files/rmake.rs index 79c3ee90c9875..a02c97fec4cba 100644 --- a/tests/run-make/emit-named-files/rmake.rs +++ b/tests/run-make/emit-named-files/rmake.rs @@ -4,7 +4,7 @@ use run_make_support::{fs_wrapper, rustc}; fn emit_and_check(out_dir: &Path, out_file: &str, format: &str) { let out_file = out_dir.join(out_file); - rustc().input("foo.rs").emit(&format!("{format}={}", out_file.display())).run(); + rustc().input("foo.rs").emit(format!("{format}={}", out_file.display())).run(); assert!(out_file.is_file()); } From bcbcbfff4452ca34c4cee6a7737141df39591668 Mon Sep 17 00:00:00 2001 From: klensy Date: Wed, 3 Jul 2024 14:23:09 +0300 Subject: [PATCH 627/892] bootstrap: pass correct struct size to winapi --- src/bootstrap/src/bin/rustc.rs | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/src/bootstrap/src/bin/rustc.rs b/src/bootstrap/src/bin/rustc.rs index 009e62469b4d1..46e845f77ae1b 100644 --- a/src/bootstrap/src/bin/rustc.rs +++ b/src/bootstrap/src/bin/rustc.rs @@ -317,9 +317,7 @@ fn format_rusage_data(child: Child) -> Option { use windows::{ Win32::Foundation::HANDLE, - Win32::System::ProcessStatus::{ - K32GetProcessMemoryInfo, PROCESS_MEMORY_COUNTERS, PROCESS_MEMORY_COUNTERS_EX, - }, + Win32::System::ProcessStatus::{K32GetProcessMemoryInfo, PROCESS_MEMORY_COUNTERS}, Win32::System::Threading::GetProcessTimes, Win32::System::Time::FileTimeToSystemTime, }; @@ -331,6 +329,7 @@ fn format_rusage_data(child: Child) -> Option { let mut kernel_filetime = Default::default(); let mut kernel_time = Default::default(); let mut memory_counters = PROCESS_MEMORY_COUNTERS::default(); + let memory_counters_size = std::mem::size_of_val(&memory_counters); unsafe { GetProcessTimes( @@ -347,15 +346,9 @@ fn format_rusage_data(child: Child) -> Option { // Unlike on Linux with RUSAGE_CHILDREN, this will only return memory information for the process // with the given handle and none of that process's children. - unsafe { - K32GetProcessMemoryInfo( - handle, - &mut memory_counters, - std::mem::size_of::() as u32, - ) - } - .ok() - .ok()?; + unsafe { K32GetProcessMemoryInfo(handle, &mut memory_counters, memory_counters_size as u32) } + .ok() + .ok()?; // Guide on interpreting these numbers: // https://docs.microsoft.com/en-us/windows/win32/psapi/process-memory-usage-information From e8df637c619c749a52aead3fb6b8f73ed3ed17d6 Mon Sep 17 00:00:00 2001 From: Martin Nordholts Date: Wed, 3 Jul 2024 13:44:02 +0200 Subject: [PATCH 628/892] library/std/build.rs: "powerpc64le" is not a target_arch The target_arch of `powerpc64le` is `powerpc64`, so `powerpc64le` can be removed from a match arm in build.rs related to f16. You can check available `target_arch`:s with: $ rustc +nightly -Zunstable-options --print all-target-specs-json \ | grep powerpc | grep arch | sort | uniq "arch": "powerpc", "arch": "powerpc64", --- library/std/build.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/std/build.rs b/library/std/build.rs index 55388648a14b9..eaffad5b1313a 100644 --- a/library/std/build.rs +++ b/library/std/build.rs @@ -99,7 +99,7 @@ fn main() { // the compiler-builtins update. ("x86" | "x86_64", _) => false, // Missing `__gnu_h2f_ieee` and `__gnu_f2h_ieee` - ("powerpc" | "powerpc64" | "powerpc64le", _) => false, + ("powerpc" | "powerpc64", _) => false, // Missing `__extendhfsf` and `__truncsfhf` ("riscv32" | "riscv64", _) => false, // Most OSs are missing `__extendhfsf` and `__truncsfhf` From 310d4efca2a36363a236788077bbd1a7a06c4db1 Mon Sep 17 00:00:00 2001 From: Martin Nordholts Date: Mon, 1 Jul 2024 11:27:54 +0200 Subject: [PATCH 629/892] std: Set has_reliable_f16 to false for MIPS targets in build.rs To avoid this linker error: $ sudo apt install libc6-mips-cross gcc-mips-linux-gnu $ CC_mips_unknown_linux_gnu=mips-linux-gnu-gcc \ CARGO_TARGET_MIPS_UNKNOWN_LINUX_GNU_LINKER=mips-linux-gnu-gcc \ ./x test library/std --target mips-unknown-linux-gnu undefined reference to `__gnu_f2h_ieee' You get the same linker error also with mipsel, mips64 and mips64el toolchains. --- library/std/build.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/library/std/build.rs b/library/std/build.rs index eaffad5b1313a..c542ba81eedc1 100644 --- a/library/std/build.rs +++ b/library/std/build.rs @@ -100,6 +100,8 @@ fn main() { ("x86" | "x86_64", _) => false, // Missing `__gnu_h2f_ieee` and `__gnu_f2h_ieee` ("powerpc" | "powerpc64", _) => false, + // Missing `__gnu_h2f_ieee` and `__gnu_f2h_ieee` + ("mips" | "mips32r6" | "mips64" | "mips64r6", _) => false, // Missing `__extendhfsf` and `__truncsfhf` ("riscv32" | "riscv64", _) => false, // Most OSs are missing `__extendhfsf` and `__truncsfhf` From 6f9ec578cb5143b97d96a8399edf698398d3d2bb Mon Sep 17 00:00:00 2001 From: Martin Nordholts Date: Mon, 1 Jul 2024 17:37:00 +0200 Subject: [PATCH 630/892] core: Limit four f16 doctests to x86_64 linux These tests have link errors on many platforms, so limit them to only x86_64 linux for now. There are many other f16 non-doctests, so we don't need to run these particular ones widely. --- library/core/src/num/f16.rs | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/library/core/src/num/f16.rs b/library/core/src/num/f16.rs index 3c58b0af9c27e..e74300d6c2f33 100644 --- a/library/core/src/num/f16.rs +++ b/library/core/src/num/f16.rs @@ -507,8 +507,8 @@ impl f16 { /// /// ``` /// #![feature(f16)] - /// # // FIXME(f16_f128): remove when `extendhfsf2` and `truncsfhf2` are available - /// # #[cfg(target_os = "linux")] { + /// # // FIXME(f16_f128): extendhfsf2, truncsfhf2, __gnu_h2f_ieee, __gnu_f2h_ieee missing for many platforms + /// # #[cfg(all(target_arch = "x86_64", target_os = "linux"))] { /// /// let x = 2.0_f16; /// let abs_difference = (x.recip() - (1.0 / x)).abs(); @@ -528,8 +528,8 @@ impl f16 { /// /// ``` /// #![feature(f16)] - /// # // FIXME(f16_f128): remove when `extendhfsf2` and `truncsfhf2` are available - /// # #[cfg(target_os = "linux")] { + /// # // FIXME(f16_f128): extendhfsf2, truncsfhf2, __gnu_h2f_ieee, __gnu_f2h_ieee missing for many platforms + /// # #[cfg(all(target_arch = "x86_64", target_os = "linux"))] { /// /// let angle = std::f16::consts::PI; /// @@ -551,8 +551,8 @@ impl f16 { /// /// ``` /// #![feature(f16)] - /// # // FIXME(f16_f128): remove when `extendhfsf2` and `truncsfhf2` are available - /// # #[cfg(target_os = "linux")] { + /// # // FIXME(f16_f128): extendhfsf2, truncsfhf2, __gnu_h2f_ieee, __gnu_f2h_ieee missing for many platforms + /// # #[cfg(all(target_arch = "x86_64", target_os = "linux"))] { /// /// let angle = 180.0f16; /// @@ -870,6 +870,8 @@ impl f16 { /// /// ``` /// #![feature(f16)] + /// # // FIXME(f16_f128): extendhfsf2, truncsfhf2, __gnu_h2f_ieee, __gnu_f2h_ieee missing for many platforms + /// # #[cfg(all(target_arch = "x86_64", target_os = "linux"))] { /// /// struct GoodBoy { /// name: &'static str, @@ -897,6 +899,7 @@ impl f16 { /// .zip([-5.0, 0.1, 10.0, 99.0, f16::INFINITY, f16::NAN].iter()) /// .for_each(|(a, b)| assert_eq!(a.to_bits(), b.to_bits())) /// } + /// # } /// ``` #[inline] #[must_use] From 8b6435d5ce4efaecca51e530f0cb3c44d527f3c4 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Tue, 2 Jul 2024 17:35:49 -0300 Subject: [PATCH 631/892] Add parse fail test using safe trait/impl trait --- .../unsafe-extern-blocks/safe-impl-trait.gated.stderr | 8 ++++++++ .../ui/rust-2024/unsafe-extern-blocks/safe-impl-trait.rs | 8 ++++++++ .../unsafe-extern-blocks/safe-impl-trait.ungated.stderr | 8 ++++++++ .../unsafe-extern-blocks/safe-trait.gated.stderr | 8 ++++++++ tests/ui/rust-2024/unsafe-extern-blocks/safe-trait.rs | 7 +++++++ .../unsafe-extern-blocks/safe-trait.ungated.stderr | 8 ++++++++ 6 files changed, 47 insertions(+) create mode 100644 tests/ui/rust-2024/unsafe-extern-blocks/safe-impl-trait.gated.stderr create mode 100644 tests/ui/rust-2024/unsafe-extern-blocks/safe-impl-trait.rs create mode 100644 tests/ui/rust-2024/unsafe-extern-blocks/safe-impl-trait.ungated.stderr create mode 100644 tests/ui/rust-2024/unsafe-extern-blocks/safe-trait.gated.stderr create mode 100644 tests/ui/rust-2024/unsafe-extern-blocks/safe-trait.rs create mode 100644 tests/ui/rust-2024/unsafe-extern-blocks/safe-trait.ungated.stderr diff --git a/tests/ui/rust-2024/unsafe-extern-blocks/safe-impl-trait.gated.stderr b/tests/ui/rust-2024/unsafe-extern-blocks/safe-impl-trait.gated.stderr new file mode 100644 index 0000000000000..80e7a45f57e79 --- /dev/null +++ b/tests/ui/rust-2024/unsafe-extern-blocks/safe-impl-trait.gated.stderr @@ -0,0 +1,8 @@ +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-impl-trait.rs b/tests/ui/rust-2024/unsafe-extern-blocks/safe-impl-trait.rs new file mode 100644 index 0000000000000..57c03e4d896be --- /dev/null +++ b/tests/ui/rust-2024/unsafe-extern-blocks/safe-impl-trait.rs @@ -0,0 +1,8 @@ +//@ revisions: gated ungated +#![cfg_attr(gated, feature(unsafe_extern_blocks))] + +trait Bar {} +safe impl Bar for () { } +//~^ ERROR expected one of `!` or `::`, found keyword `impl` + +fn main() {} 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 new file mode 100644 index 0000000000000..80e7a45f57e79 --- /dev/null +++ b/tests/ui/rust-2024/unsafe-extern-blocks/safe-impl-trait.ungated.stderr @@ -0,0 +1,8 @@ +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 new file mode 100644 index 0000000000000..de84037f28c58 --- /dev/null +++ b/tests/ui/rust-2024/unsafe-extern-blocks/safe-trait.gated.stderr @@ -0,0 +1,8 @@ +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.rs b/tests/ui/rust-2024/unsafe-extern-blocks/safe-trait.rs new file mode 100644 index 0000000000000..e73cb45b18877 --- /dev/null +++ b/tests/ui/rust-2024/unsafe-extern-blocks/safe-trait.rs @@ -0,0 +1,7 @@ +//@ revisions: gated ungated +#![cfg_attr(gated, feature(unsafe_extern_blocks))] + +safe trait Foo {} +//~^ ERROR expected one of `!` or `::`, found keyword `trait` + +fn main() {} 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 new file mode 100644 index 0000000000000..de84037f28c58 --- /dev/null +++ b/tests/ui/rust-2024/unsafe-extern-blocks/safe-trait.ungated.stderr @@ -0,0 +1,8 @@ +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 + From 46af9870727abe142963c9873e960242188dbaab Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Mon, 1 Jul 2024 08:36:28 +0000 Subject: [PATCH 632/892] Add `constness` to `TraitDef` --- compiler/rustc_ast_lowering/src/item.rs | 9 +++++--- compiler/rustc_feature/src/builtin_attrs.rs | 2 +- compiler/rustc_hir_analysis/src/bounds.rs | 4 ++-- compiler/rustc_hir_analysis/src/collect.rs | 8 ++++++- .../src/hir_ty_lowering/mod.rs | 12 +++------- compiler/rustc_hir_typeck/src/method/mod.rs | 4 ++-- compiler/rustc_middle/src/ty/mod.rs | 7 +++++- compiler/rustc_middle/src/ty/trait_def.rs | 3 +++ .../rustc_must_implement_one_of_misuse.stderr | 22 +++++++++---------- 9 files changed, 41 insertions(+), 30 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index d59ac5766298d..0ad23b5356690 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -625,9 +625,12 @@ impl<'hir> LoweringContext<'_, 'hir> { _ => Const::No, } } else { - self.tcx - .get_attr(def_id, sym::const_trait) - .map_or(Const::No, |attr| Const::Yes(attr.span)) + if self.tcx.is_const_trait(def_id) { + // FIXME(effects) span + Const::Yes(self.tcx.def_ident_span(def_id).unwrap()) + } else { + Const::No + } } } else { Const::No diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index a4245f0908e33..0d990cbd66491 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -556,7 +556,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ ), // RFC 2632 gated!( - const_trait, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::Yes, const_trait_impl, + const_trait, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::No, const_trait_impl, "`const_trait` is a temporary placeholder for marking a trait that is suitable for `const` \ `impls` and all default bodies as `const`, which may be removed or renamed in the \ future." diff --git a/compiler/rustc_hir_analysis/src/bounds.rs b/compiler/rustc_hir_analysis/src/bounds.rs index c7ee89e73c273..c30a6f1eeb910 100644 --- a/compiler/rustc_hir_analysis/src/bounds.rs +++ b/compiler/rustc_hir_analysis/src/bounds.rs @@ -7,7 +7,7 @@ use rustc_hir::LangItem; use rustc_middle::ty::fold::FnMutDelegate; use rustc_middle::ty::{self, Ty, TyCtxt, Upcast}; use rustc_span::def_id::DefId; -use rustc_span::{sym, Span}; +use rustc_span::Span; /// Collects together a list of type bounds. These lists of bounds occur in many places /// in Rust's syntax: @@ -80,7 +80,7 @@ impl<'tcx> Bounds<'tcx> { } (_, ty::BoundConstness::NotConst) => { - if !tcx.has_attr(bound_trait_ref.def_id(), sym::const_trait) { + if !tcx.is_const_trait(bound_trait_ref.def_id()) { return; } tcx.consts.true_ diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index 41fbef489405c..01a1872f1cbc6 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -1194,6 +1194,11 @@ fn trait_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::TraitDef { _ => span_bug!(item.span, "trait_def_of_item invoked on non-trait"), }; + let constness = if tcx.has_attr(def_id, sym::const_trait) { + hir::Constness::Const + } else { + hir::Constness::NotConst + }; let paren_sugar = tcx.has_attr(def_id, sym::rustc_paren_sugar); if paren_sugar && !tcx.features().unboxed_closures { tcx.dcx().emit_err(errors::ParenSugarAttribute { span: item.span }); @@ -1348,6 +1353,7 @@ fn trait_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::TraitDef { ty::TraitDef { def_id: def_id.to_def_id(), safety, + constness, paren_sugar, has_auto_impl: is_auto, is_marker, @@ -1680,7 +1686,7 @@ fn check_impl_constness( } let trait_def_id = hir_trait_ref.trait_def_id()?; - if tcx.has_attr(trait_def_id, sym::const_trait) { + if tcx.is_const_trait(trait_def_id) { return None; } diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs index 2a68d3915bbbc..af7e49ce17dcd 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -47,7 +47,7 @@ use rustc_middle::{bug, span_bug}; use rustc_session::lint::builtin::AMBIGUOUS_ASSOCIATED_ITEMS; use rustc_span::edit_distance::find_best_match_for_name; use rustc_span::symbol::{kw, Ident, Symbol}; -use rustc_span::{sym, Span, DUMMY_SP}; +use rustc_span::{Span, DUMMY_SP}; use rustc_target::spec::abi; use rustc_trait_selection::traits::wf::object_region_bounds; use rustc_trait_selection::traits::{self, ObligationCtxt}; @@ -559,7 +559,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { } if let ty::BoundConstness::Const | ty::BoundConstness::ConstIfConst = constness && generics.has_self - && !tcx.has_attr(def_id, sym::const_trait) + && !tcx.is_const_trait(def_id) { let reported = tcx.dcx().emit_err(crate::errors::ConstBoundForNonConstTrait { span, @@ -1847,19 +1847,13 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { path.segments[..path.segments.len() - 2].iter(), GenericsArgsErrExtend::None, ); - // HACK: until we support ``, assume all of them are. - let constness = if tcx.has_attr(tcx.parent(def_id), sym::const_trait) { - ty::BoundConstness::ConstIfConst - } else { - ty::BoundConstness::NotConst - }; self.lower_qpath( span, opt_self_ty, def_id, &path.segments[path.segments.len() - 2], path.segments.last().unwrap(), - constness, + ty::BoundConstness::NotConst, ) } Res::PrimTy(prim_ty) => { diff --git a/compiler/rustc_hir_typeck/src/method/mod.rs b/compiler/rustc_hir_typeck/src/method/mod.rs index ff8899ae0368d..dc1b888374cf2 100644 --- a/compiler/rustc_hir_typeck/src/method/mod.rs +++ b/compiler/rustc_hir_typeck/src/method/mod.rs @@ -21,7 +21,7 @@ use rustc_middle::ty::{self, GenericParamDefKind, Ty, TypeVisitableExt}; use rustc_middle::ty::{GenericArgs, GenericArgsRef}; use rustc_middle::{bug, span_bug}; use rustc_span::symbol::Ident; -use rustc_span::{sym, Span}; +use rustc_span::Span; use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt; use rustc_trait_selection::traits::{self, NormalizeExt}; @@ -359,7 +359,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // FIXME(effects) find a better way to do this // Operators don't have generic methods, but making them `#[const_trait]` gives them // `const host: bool`. - let args = if self.tcx.has_attr(trait_def_id, sym::const_trait) { + let args = if self.tcx.is_const_trait(trait_def_id) { self.tcx.mk_args_from_iter( args.iter() .chain([self.tcx.expected_host_effect_param_for_body(self.body_id).into()]), diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 7d57d88f40f4a..9f8b46f8ab095 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -1966,9 +1966,14 @@ impl<'tcx> TyCtxt<'tcx> { ) && self.constness(def_id) == hir::Constness::Const } + #[inline] + pub fn is_const_trait(self, def_id: DefId) -> bool { + self.trait_def(def_id).constness == hir::Constness::Const + } + #[inline] pub fn is_const_default_method(self, def_id: DefId) -> bool { - matches!(self.trait_of_item(def_id), Some(trait_id) if self.has_attr(trait_id, sym::const_trait)) + matches!(self.trait_of_item(def_id), Some(trait_id) if self.is_const_trait(trait_id)) } pub fn impl_method_has_trait_impl_trait_tys(self, def_id: DefId) -> bool { diff --git a/compiler/rustc_middle/src/ty/trait_def.rs b/compiler/rustc_middle/src/ty/trait_def.rs index 4dba97c3b5b83..25cd10979eedc 100644 --- a/compiler/rustc_middle/src/ty/trait_def.rs +++ b/compiler/rustc_middle/src/ty/trait_def.rs @@ -18,6 +18,9 @@ pub struct TraitDef { pub safety: hir::Safety, + /// Whether this trait has been annotated with `#[const_trait]`. + pub constness: hir::Constness, + /// If `true`, then this trait had the `#[rustc_paren_sugar]` /// attribute, indicating that it should be used with `Foo()` /// sugar. This is a temporary thing -- eventually any trait will diff --git a/tests/ui/traits/default-method/rustc_must_implement_one_of_misuse.stderr b/tests/ui/traits/default-method/rustc_must_implement_one_of_misuse.stderr index 38e692521ca23..03a4017b3d7fc 100644 --- a/tests/ui/traits/default-method/rustc_must_implement_one_of_misuse.stderr +++ b/tests/ui/traits/default-method/rustc_must_implement_one_of_misuse.stderr @@ -23,29 +23,29 @@ LL | struct Struct {} | ---------------- not a trait error: function not found in this trait - --> $DIR/rustc_must_implement_one_of_misuse.rs:3:31 + --> $DIR/rustc_must_implement_one_of_misuse.rs:8:34 | LL | #[rustc_must_implement_one_of(a, b)] - | ^ + | ^ + +error: the `#[rustc_must_implement_one_of]` attribute must be used with at least 2 args + --> $DIR/rustc_must_implement_one_of_misuse.rs:14:1 + | +LL | #[rustc_must_implement_one_of(a)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: function not found in this trait - --> $DIR/rustc_must_implement_one_of_misuse.rs:3:34 + --> $DIR/rustc_must_implement_one_of_misuse.rs:3:31 | LL | #[rustc_must_implement_one_of(a, b)] - | ^ + | ^ error: function not found in this trait - --> $DIR/rustc_must_implement_one_of_misuse.rs:8:34 + --> $DIR/rustc_must_implement_one_of_misuse.rs:3:34 | LL | #[rustc_must_implement_one_of(a, b)] | ^ -error: the `#[rustc_must_implement_one_of]` attribute must be used with at least 2 args - --> $DIR/rustc_must_implement_one_of_misuse.rs:14:1 - | -LL | #[rustc_must_implement_one_of(a)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - error: not a function --> $DIR/rustc_must_implement_one_of_misuse.rs:26:5 | From 403e2e2bbd4c3ae3460ab0d922cdb0fae15725a7 Mon Sep 17 00:00:00 2001 From: Ana Hobden Date: Wed, 3 Jul 2024 10:12:39 -0700 Subject: [PATCH 633/892] Disable rmake test rustdoc-io-error on riscv64gc-gnu --- tests/run-make/inaccessible-temp-dir/rmake.rs | 2 +- tests/run-make/rustdoc-io-error/rmake.rs | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/tests/run-make/inaccessible-temp-dir/rmake.rs b/tests/run-make/inaccessible-temp-dir/rmake.rs index b98e151e90696..62b8479c32881 100644 --- a/tests/run-make/inaccessible-temp-dir/rmake.rs +++ b/tests/run-make/inaccessible-temp-dir/rmake.rs @@ -14,7 +14,7 @@ // See https://github.com/rust-lang/rust/issues/66530 //@ ignore-riscv64 -// FIXME: The riscv build container runs as root, and can always write +// FIXME: The riscv64gc-gnu build container runs as root, and can always write // into `inaccessible/tmp`. Ideally, the riscv64-gnu docker container // would use a non-root user, but this leads to issues with // `mkfs.ext4 -d`, as well as mounting a loop device for the rootfs. diff --git a/tests/run-make/rustdoc-io-error/rmake.rs b/tests/run-make/rustdoc-io-error/rmake.rs index d60e4438e6f27..69afea401622d 100644 --- a/tests/run-make/rustdoc-io-error/rmake.rs +++ b/tests/run-make/rustdoc-io-error/rmake.rs @@ -6,8 +6,13 @@ // permissions so that it is not writable. We have to take special care to set // the permissions back to normal so that it's able to be deleted later. +//@ ignore-riscv64 +//@ ignore-arm +// FIXME: The riscv64gc-gnu and armhf-gnu build containers run as root, +// and can always write into `inaccessible/tmp`. Ideally, these docker +// containers would use a non-root user, but this leads to issues with +// `mkfs.ext4 -d`, as well as mounting a loop device for the rootfs. //@ ignore-windows - the `set_readonly` functions doesn't work on folders. -//@ ignore-arm - weird file perms on armhf-gnu use run_make_support::{path, rustdoc}; use std::fs; From 9192479dc352c96927f3bfeda746d07c71a1a470 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Fri, 28 Jun 2024 10:46:52 +0200 Subject: [PATCH 634/892] Improve documentation --- src/bootstrap/src/utils/exec.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/bootstrap/src/utils/exec.rs b/src/bootstrap/src/utils/exec.rs index 8bcb2301f1ace..87a3a2b0b284e 100644 --- a/src/bootstrap/src/utils/exec.rs +++ b/src/bootstrap/src/utils/exec.rs @@ -34,7 +34,8 @@ pub enum OutputMode { /// By default, the command will print its stdout/stderr to stdout/stderr of bootstrap /// ([OutputMode::OnlyOutput]). If bootstrap uses verbose mode, then it will also print the /// command itself in case of failure ([OutputMode::All]). -/// If you want to handle the output programmatically, use `output_mode(OutputMode::OnlyOnFailure)`. +/// If you want to handle the output programmatically, use `output_mode(OutputMode::OnlyOnFailure)`, +/// which will print the output only if the command fails. /// /// [allow_failure]: BootstrapCommand::allow_failure /// [delay_failure]: BootstrapCommand::delay_failure @@ -113,7 +114,7 @@ impl BootstrapCommand { } } -/// This implementation is temporary, until all `Command` invocations are migrated to +/// FIXME: This implementation is temporary, until all `Command` invocations are migrated to /// `BootstrapCommand`. impl<'a> From<&'a mut Command> for BootstrapCommand { fn from(command: &'a mut Command) -> Self { @@ -138,7 +139,7 @@ impl<'a> From<&'a mut Command> for BootstrapCommand { } } -/// This implementation is temporary, until all `Command` invocations are migrated to +/// FIXME: This implementation is temporary, until all `Command` invocations are migrated to /// `BootstrapCommand`. impl<'a> From<&'a mut BootstrapCommand> for BootstrapCommand { fn from(command: &'a mut BootstrapCommand) -> Self { From a34d0a8d5f2abbbe4bf28d829bbf7490f23d5a9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Sat, 22 Jun 2024 17:21:33 +0200 Subject: [PATCH 635/892] Make `git` helper return `BootstrapCmd` --- src/bootstrap/src/core/build_steps/format.rs | 38 +++++++-------- src/bootstrap/src/core/build_steps/llvm.rs | 5 +- src/bootstrap/src/core/build_steps/perf.rs | 1 + src/bootstrap/src/core/build_steps/setup.rs | 1 + src/bootstrap/src/core/build_steps/test.rs | 2 +- .../src/core/build_steps/toolstate.rs | 19 ++++++-- src/bootstrap/src/core/config/config.rs | 26 +++++++---- src/bootstrap/src/lib.rs | 46 ++++++++++++------- src/bootstrap/src/utils/channel.rs | 14 +++--- src/bootstrap/src/utils/exec.rs | 36 ++++++++------- src/bootstrap/src/utils/helpers.rs | 4 +- 11 files changed, 112 insertions(+), 80 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/format.rs b/src/bootstrap/src/core/build_steps/format.rs index f5e346726868a..4583eb1c6cd85 100644 --- a/src/bootstrap/src/core/build_steps/format.rs +++ b/src/bootstrap/src/core/build_steps/format.rs @@ -7,7 +7,7 @@ use build_helper::git::get_git_modified_files; use ignore::WalkBuilder; use std::collections::VecDeque; use std::path::{Path, PathBuf}; -use std::process::{Command, Stdio}; +use std::process::Command; use std::sync::mpsc::SyncSender; use std::sync::Mutex; @@ -160,35 +160,29 @@ pub fn format(build: &Builder<'_>, check: bool, all: bool, paths: &[PathBuf]) { override_builder.add(&format!("!{ignore}")).expect(&ignore); } } - let git_available = match helpers::git(None) - .arg("--version") - .stdout(Stdio::null()) - .stderr(Stdio::null()) - .status() - { - Ok(status) => status.success(), - Err(_) => false, - }; + let git_available = build + .run(helpers::git(None).print_on_failure().allow_failure().arg("--version")) + .is_success(); let mut adjective = None; if git_available { - let in_working_tree = match helpers::git(Some(&build.src)) - .arg("rev-parse") - .arg("--is-inside-work-tree") - .stdout(Stdio::null()) - .stderr(Stdio::null()) - .status() - { - Ok(status) => status.success(), - Err(_) => false, - }; + let in_working_tree = build + .run( + helpers::git(Some(&build.src)) + .print_on_failure() + .allow_failure() + .arg("rev-parse") + .arg("--is-inside-work-tree"), + ) + .is_success(); if in_working_tree { let untracked_paths_output = output( - helpers::git(Some(&build.src)) + &mut helpers::git(Some(&build.src)) .arg("status") .arg("--porcelain") .arg("-z") - .arg("--untracked-files=normal"), + .arg("--untracked-files=normal") + .command, ); let untracked_paths: Vec<_> = untracked_paths_output .split_terminator('\0') diff --git a/src/bootstrap/src/core/build_steps/llvm.rs b/src/bootstrap/src/core/build_steps/llvm.rs index 8e6795b11bd21..ba21e2ad32d05 100644 --- a/src/bootstrap/src/core/build_steps/llvm.rs +++ b/src/bootstrap/src/core/build_steps/llvm.rs @@ -172,7 +172,7 @@ pub(crate) fn detect_llvm_sha(config: &Config, is_git: bool) -> String { // the LLVM shared object file is named `LLVM-12-rust-{version}-nightly` config.src.join("src/version"), ]); - output(&mut rev_list).trim().to_owned() + output(&mut rev_list.command).trim().to_owned() } else if let Some(info) = channel::read_commit_info_file(&config.src) { info.sha.trim().to_owned() } else { @@ -253,7 +253,8 @@ pub(crate) fn is_ci_llvm_modified(config: &Config) -> bool { // We assume we have access to git, so it's okay to unconditionally pass // `true` here. let llvm_sha = detect_llvm_sha(config, true); - let head_sha = output(helpers::git(Some(&config.src)).arg("rev-parse").arg("HEAD")); + let head_sha = + output(&mut helpers::git(Some(&config.src)).arg("rev-parse").arg("HEAD").command); let head_sha = head_sha.trim(); llvm_sha == head_sha } diff --git a/src/bootstrap/src/core/build_steps/perf.rs b/src/bootstrap/src/core/build_steps/perf.rs index f41b5fe10f1d9..20ab1836e0068 100644 --- a/src/bootstrap/src/core/build_steps/perf.rs +++ b/src/bootstrap/src/core/build_steps/perf.rs @@ -2,6 +2,7 @@ use crate::core::build_steps::compile::{Std, Sysroot}; use crate::core::build_steps::tool::{RustcPerf, Tool}; use crate::core::builder::Builder; use crate::core::config::DebuginfoLevel; +use crate::utils::exec::BootstrapCommand; /// Performs profiling using `rustc-perf` on a built version of the compiler. pub fn perf(builder: &Builder<'_>) { diff --git a/src/bootstrap/src/core/build_steps/setup.rs b/src/bootstrap/src/core/build_steps/setup.rs index 947c74f32c99e..e6a09e8cb8e8c 100644 --- a/src/bootstrap/src/core/build_steps/setup.rs +++ b/src/bootstrap/src/core/build_steps/setup.rs @@ -484,6 +484,7 @@ impl Step for Hook { fn install_git_hook_maybe(config: &Config) -> io::Result<()> { let git = helpers::git(Some(&config.src)) .args(["rev-parse", "--git-common-dir"]) + .command .output() .map(|output| { assert!(output.status.success(), "failed to run `git`"); diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index 1460a2290197b..918e4e2b90726 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -2349,7 +2349,7 @@ fn markdown_test(builder: &Builder<'_>, compiler: Compiler, markdown: &Path) -> cmd = cmd.delay_failure(); if !builder.config.verbose_tests { - cmd = cmd.quiet(); + cmd = cmd.print_on_failure(); } builder.run(cmd).is_success() } diff --git a/src/bootstrap/src/core/build_steps/toolstate.rs b/src/bootstrap/src/core/build_steps/toolstate.rs index 9e6d03349b5fb..e3e7931a5a2ab 100644 --- a/src/bootstrap/src/core/build_steps/toolstate.rs +++ b/src/bootstrap/src/core/build_steps/toolstate.rs @@ -101,8 +101,13 @@ fn print_error(tool: &str, submodule: &str) { fn check_changed_files(toolstates: &HashMap, ToolState>) { // Changed files - let output = - helpers::git(None).arg("diff").arg("--name-status").arg("HEAD").arg("HEAD^").output(); + let output = helpers::git(None) + .arg("diff") + .arg("--name-status") + .arg("HEAD") + .arg("HEAD^") + .command + .output(); let output = match output { Ok(o) => o, Err(e) => { @@ -324,6 +329,7 @@ fn checkout_toolstate_repo() { .arg("--depth=1") .arg(toolstate_repo()) .arg(TOOLSTATE_DIR) + .command .status(); let success = match status { Ok(s) => s.success(), @@ -337,7 +343,8 @@ fn checkout_toolstate_repo() { /// Sets up config and authentication for modifying the toolstate repo. fn prepare_toolstate_config(token: &str) { fn git_config(key: &str, value: &str) { - let status = helpers::git(None).arg("config").arg("--global").arg(key).arg(value).status(); + let status = + helpers::git(None).arg("config").arg("--global").arg(key).arg(value).command.status(); let success = match status { Ok(s) => s.success(), Err(_) => false, @@ -406,6 +413,7 @@ fn commit_toolstate_change(current_toolstate: &ToolstateData) { .arg("-a") .arg("-m") .arg(&message) + .command .status()); if !status.success() { success = true; @@ -416,6 +424,7 @@ fn commit_toolstate_change(current_toolstate: &ToolstateData) { .arg("push") .arg("origin") .arg("master") + .command .status()); // If we successfully push, exit. if status.success() { @@ -428,12 +437,14 @@ fn commit_toolstate_change(current_toolstate: &ToolstateData) { .arg("fetch") .arg("origin") .arg("master") + .command .status()); assert!(status.success()); let status = t!(helpers::git(Some(Path::new(TOOLSTATE_DIR))) .arg("reset") .arg("--hard") .arg("origin/master") + .command .status()); assert!(status.success()); } @@ -449,7 +460,7 @@ fn commit_toolstate_change(current_toolstate: &ToolstateData) { /// `publish_toolstate.py` script if the PR passes all tests and is merged to /// master. fn publish_test_results(current_toolstate: &ToolstateData) { - let commit = t!(helpers::git(None).arg("rev-parse").arg("HEAD").output()); + let commit = t!(helpers::git(None).arg("rev-parse").arg("HEAD").command.output()); let commit = t!(String::from_utf8(commit.stdout)); let toolstate_serialized = t!(serde_json::to_string(¤t_toolstate)); diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs index 948f97e746f42..10ac6c93e9a43 100644 --- a/src/bootstrap/src/core/config/config.rs +++ b/src/bootstrap/src/core/config/config.rs @@ -1259,6 +1259,7 @@ impl Config { cmd.arg("rev-parse").arg("--show-cdup"); // Discard stderr because we expect this to fail when building from a tarball. let output = cmd + .command .stderr(std::process::Stdio::null()) .output() .ok() @@ -2141,7 +2142,7 @@ impl Config { let mut git = helpers::git(Some(&self.src)); git.arg("show").arg(format!("{commit}:{}", file.to_str().unwrap())); - output(&mut git) + output(&mut git.command) } /// Bootstrap embeds a version number into the name of shared libraries it uploads in CI. @@ -2445,8 +2446,9 @@ impl Config { }; // Handle running from a directory other than the top level - let top_level = - output(helpers::git(Some(&self.src)).args(["rev-parse", "--show-toplevel"])); + let top_level = output( + &mut helpers::git(Some(&self.src)).args(["rev-parse", "--show-toplevel"]).command, + ); let top_level = top_level.trim_end(); let compiler = format!("{top_level}/compiler/"); let library = format!("{top_level}/library/"); @@ -2454,10 +2456,11 @@ impl Config { // Look for a version to compare to based on the current commit. // Only commits merged by bors will have CI artifacts. let merge_base = output( - helpers::git(Some(&self.src)) + &mut helpers::git(Some(&self.src)) .arg("rev-list") .arg(format!("--author={}", self.stage0_metadata.config.git_merge_commit_email)) - .args(["-n1", "--first-parent", "HEAD"]), + .args(["-n1", "--first-parent", "HEAD"]) + .command, ); let commit = merge_base.trim_end(); if commit.is_empty() { @@ -2471,6 +2474,7 @@ impl Config { // Warn if there were changes to the compiler or standard library since the ancestor commit. let has_changes = !t!(helpers::git(Some(&self.src)) .args(["diff-index", "--quiet", commit, "--", &compiler, &library]) + .command .status()) .success(); if has_changes { @@ -2542,17 +2546,19 @@ impl Config { if_unchanged: bool, ) -> Option { // Handle running from a directory other than the top level - let top_level = - output(helpers::git(Some(&self.src)).args(["rev-parse", "--show-toplevel"])); + let top_level = output( + &mut helpers::git(Some(&self.src)).args(["rev-parse", "--show-toplevel"]).command, + ); let top_level = top_level.trim_end(); // Look for a version to compare to based on the current commit. // Only commits merged by bors will have CI artifacts. let merge_base = output( - helpers::git(Some(&self.src)) + &mut helpers::git(Some(&self.src)) .arg("rev-list") .arg(format!("--author={}", self.stage0_metadata.config.git_merge_commit_email)) - .args(["-n1", "--first-parent", "HEAD"]), + .args(["-n1", "--first-parent", "HEAD"]) + .command, ); let commit = merge_base.trim_end(); if commit.is_empty() { @@ -2571,7 +2577,7 @@ impl Config { git.arg(format!("{top_level}/{path}")); } - let has_changes = !t!(git.status()).success(); + let has_changes = !t!(git.command.status()).success(); if has_changes { if if_unchanged { if self.verbose > 0 { diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs index c12449fdc4ae0..ae2982ea56f09 100644 --- a/src/bootstrap/src/lib.rs +++ b/src/bootstrap/src/lib.rs @@ -494,11 +494,12 @@ impl Build { let submodule_git = || helpers::git(Some(&absolute_path)); // Determine commit checked out in submodule. - let checked_out_hash = output(submodule_git().args(["rev-parse", "HEAD"])); + let checked_out_hash = output(&mut submodule_git().args(["rev-parse", "HEAD"]).command); let checked_out_hash = checked_out_hash.trim_end(); // Determine commit that the submodule *should* have. - let recorded = - output(helpers::git(Some(&self.src)).args(["ls-tree", "HEAD"]).arg(relative_path)); + let recorded = output( + &mut helpers::git(Some(&self.src)).args(["ls-tree", "HEAD"]).arg(relative_path).command, + ); let actual_hash = recorded .split_whitespace() .nth(2) @@ -521,6 +522,7 @@ impl Build { let current_branch = { let output = helpers::git(Some(&self.src)) .args(["symbolic-ref", "--short", "HEAD"]) + .command .stderr(Stdio::inherit()) .output(); let output = t!(output); @@ -546,7 +548,7 @@ impl Build { git }; // NOTE: doesn't use `try_run` because this shouldn't print an error if it fails. - if !update(true).status().map_or(false, |status| status.success()) { + if !update(true).command.status().map_or(false, |status| status.success()) { self.run(update(false)); } @@ -577,12 +579,15 @@ impl Build { if !self.config.submodules(self.rust_info()) { return; } - let output = output( - helpers::git(Some(&self.src)) - .args(["config", "--file"]) - .arg(self.config.src.join(".gitmodules")) - .args(["--get-regexp", "path"]), - ); + let output = self + .run( + helpers::git(Some(&self.src)) + .quiet() + .args(["config", "--file"]) + .arg(self.config.src.join(".gitmodules")) + .args(["--get-regexp", "path"]), + ) + .stdout(); for line in output.lines() { // Look for `submodule.$name.path = $path` // Sample output: `submodule.src/rust-installer.path src/tools/rust-installer` @@ -950,7 +955,10 @@ impl Build { command.command.status().map(|status| status.into()), matches!(mode, OutputMode::All), ), - OutputMode::OnlyOnFailure => (command.command.output().map(|o| o.into()), true), + mode @ (OutputMode::OnlyOnFailure | OutputMode::Quiet) => ( + command.command.output().map(|o| o.into()), + matches!(mode, OutputMode::OnlyOnFailure), + ), }; let output = match output { @@ -1480,14 +1488,18 @@ impl Build { // Figure out how many merge commits happened since we branched off master. // That's our beta number! // (Note that we use a `..` range, not the `...` symmetric difference.) - output( - helpers::git(Some(&self.src)).arg("rev-list").arg("--count").arg("--merges").arg( - format!( + self.run( + helpers::git(Some(&self.src)) + .quiet() + .arg("rev-list") + .arg("--count") + .arg("--merges") + .arg(format!( "refs/remotes/origin/{}..HEAD", self.config.stage0_metadata.config.nightly_branch - ), - ), + )), ) + .stdout() }); let n = count.trim().parse().unwrap(); self.prerelease_version.set(Some(n)); @@ -1914,6 +1926,7 @@ fn envify(s: &str) -> String { pub fn generate_smart_stamp_hash(dir: &Path, additional_input: &str) -> String { let diff = helpers::git(Some(dir)) .arg("diff") + .command .output() .map(|o| String::from_utf8(o.stdout).unwrap_or_default()) .unwrap_or_default(); @@ -1923,6 +1936,7 @@ pub fn generate_smart_stamp_hash(dir: &Path, additional_input: &str) -> String { .arg("--porcelain") .arg("-z") .arg("--untracked-files=normal") + .command .output() .map(|o| String::from_utf8(o.stdout).unwrap_or_default()) .unwrap_or_default(); diff --git a/src/bootstrap/src/utils/channel.rs b/src/bootstrap/src/utils/channel.rs index ce82c52f049e2..2ca86bdb0ed27 100644 --- a/src/bootstrap/src/utils/channel.rs +++ b/src/bootstrap/src/utils/channel.rs @@ -45,7 +45,7 @@ impl GitInfo { } // Make sure git commands work - match helpers::git(Some(dir)).arg("rev-parse").output() { + match helpers::git(Some(dir)).arg("rev-parse").command.output() { Ok(ref out) if out.status.success() => {} _ => return GitInfo::Absent, } @@ -58,15 +58,17 @@ impl GitInfo { // Ok, let's scrape some info let ver_date = output( - helpers::git(Some(dir)) + &mut helpers::git(Some(dir)) .arg("log") .arg("-1") .arg("--date=short") - .arg("--pretty=format:%cd"), + .arg("--pretty=format:%cd") + .command, + ); + let ver_hash = output(&mut helpers::git(Some(dir)).arg("rev-parse").arg("HEAD").command); + let short_ver_hash = output( + &mut helpers::git(Some(dir)).arg("rev-parse").arg("--short=9").arg("HEAD").command, ); - let ver_hash = output(helpers::git(Some(dir)).arg("rev-parse").arg("HEAD")); - let short_ver_hash = - output(helpers::git(Some(dir)).arg("rev-parse").arg("--short=9").arg("HEAD")); GitInfo::Present(Some(Info { commit_date: ver_date.trim().to_string(), sha: ver_hash.trim().to_string(), diff --git a/src/bootstrap/src/utils/exec.rs b/src/bootstrap/src/utils/exec.rs index 87a3a2b0b284e..dc30876601c6b 100644 --- a/src/bootstrap/src/utils/exec.rs +++ b/src/bootstrap/src/utils/exec.rs @@ -23,6 +23,8 @@ pub enum OutputMode { OnlyOutput, /// Suppress the output if the command succeeds, otherwise print the output. OnlyOnFailure, + /// Suppress the output of the command. + Quiet, } /// Wrapper around `std::process::Command`. @@ -105,10 +107,15 @@ impl BootstrapCommand { } /// Do not print the output of the command, unless it fails. - pub fn quiet(self) -> Self { + pub fn print_on_failure(self) -> Self { self.output_mode(OutputMode::OnlyOnFailure) } + /// Do not print the output of the command. + pub fn quiet(self) -> Self { + self.output_mode(OutputMode::Quiet) + } + pub fn output_mode(self, output_mode: OutputMode) -> Self { Self { output_mode: Some(output_mode), ..self } } @@ -116,15 +123,15 @@ impl BootstrapCommand { /// FIXME: This implementation is temporary, until all `Command` invocations are migrated to /// `BootstrapCommand`. -impl<'a> From<&'a mut Command> for BootstrapCommand { - fn from(command: &'a mut Command) -> Self { +impl<'a> From<&'a mut BootstrapCommand> for BootstrapCommand { + fn from(command: &'a mut BootstrapCommand) -> Self { // This is essentially a manual `Command::clone` - let mut cmd = Command::new(command.get_program()); - if let Some(dir) = command.get_current_dir() { + let mut cmd = Command::new(command.command.get_program()); + if let Some(dir) = command.command.get_current_dir() { cmd.current_dir(dir); } - cmd.args(command.get_args()); - for (key, value) in command.get_envs() { + cmd.args(command.command.get_args()); + for (key, value) in command.command.get_envs() { match value { Some(value) => { cmd.env(key, value); @@ -134,16 +141,11 @@ impl<'a> From<&'a mut Command> for BootstrapCommand { } } } - - cmd.into() - } -} - -/// FIXME: This implementation is temporary, until all `Command` invocations are migrated to -/// `BootstrapCommand`. -impl<'a> From<&'a mut BootstrapCommand> for BootstrapCommand { - fn from(command: &'a mut BootstrapCommand) -> Self { - BootstrapCommand::from(&mut command.command) + Self { + command: cmd, + output_mode: command.output_mode, + failure_behavior: command.failure_behavior, + } } } diff --git a/src/bootstrap/src/utils/helpers.rs b/src/bootstrap/src/utils/helpers.rs index adf18c0ace1b4..9c40065dfc4fa 100644 --- a/src/bootstrap/src/utils/helpers.rs +++ b/src/bootstrap/src/utils/helpers.rs @@ -498,8 +498,8 @@ pub fn check_cfg_arg(name: &str, values: Option<&[&str]>) -> String { /// manually building a git `Command`. This approach allows us to manage bootstrap-specific /// needs/hacks from a single source, rather than applying them on next to every `Command::new("git")`, /// which is painful to ensure that the required change is applied on each one of them correctly. -pub fn git(source_dir: Option<&Path>) -> Command { - let mut git = Command::new("git"); +pub fn git(source_dir: Option<&Path>) -> BootstrapCommand { + let mut git = BootstrapCommand::new("git"); if let Some(source_dir) = source_dir { git.current_dir(source_dir); From b14ff77c044652246809e197a3b0a0f23f0e1f74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Sat, 22 Jun 2024 12:32:55 +0200 Subject: [PATCH 636/892] Remove temporary `BootstrapCommand` trait impls --- src/bootstrap/src/core/build_steps/compile.rs | 2 +- src/bootstrap/src/core/build_steps/doc.rs | 6 +- src/bootstrap/src/core/build_steps/format.rs | 7 +- src/bootstrap/src/core/build_steps/run.rs | 2 +- src/bootstrap/src/core/build_steps/test.rs | 52 +++++------ src/bootstrap/src/core/build_steps/tool.rs | 4 +- src/bootstrap/src/core/builder.rs | 10 +- src/bootstrap/src/lib.rs | 81 ++++++++-------- src/bootstrap/src/utils/exec.rs | 93 +++++++------------ 9 files changed, 114 insertions(+), 143 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs index de3b938e42731..c267d3b0c0cf6 100644 --- a/src/bootstrap/src/core/build_steps/compile.rs +++ b/src/bootstrap/src/core/build_steps/compile.rs @@ -2080,7 +2080,7 @@ pub fn stream_cargo( tail_args: Vec, cb: &mut dyn FnMut(CargoMessage<'_>), ) -> bool { - let mut cargo = BootstrapCommand::from(cargo).command; + let mut cargo = cargo.into_cmd().command; // Instruct Cargo to give us json messages on stdout, critically leaving // stderr as piped so we can get those pretty colors. let mut message_format = if builder.config.json_output { diff --git a/src/bootstrap/src/core/build_steps/doc.rs b/src/bootstrap/src/core/build_steps/doc.rs index 4a5af25b3b2f8..823e842693e96 100644 --- a/src/bootstrap/src/core/build_steps/doc.rs +++ b/src/bootstrap/src/core/build_steps/doc.rs @@ -738,7 +738,7 @@ fn doc_std( format!("library{} in {} format", crate_description(requested_crates), format.as_str()); let _guard = builder.msg_doc(compiler, description, target); - builder.run(cargo); + builder.run(cargo.into_cmd()); builder.cp_link_r(&out_dir, out); } @@ -863,7 +863,7 @@ impl Step for Rustc { let proc_macro_out_dir = builder.stage_out(compiler, Mode::Rustc).join("doc"); symlink_dir_force(&builder.config, &out, &proc_macro_out_dir); - builder.run(cargo); + builder.run(cargo.into_cmd()); if !builder.config.dry_run() { // Sanity check on linked compiler crates @@ -996,7 +996,7 @@ macro_rules! tool_doc { symlink_dir_force(&builder.config, &out, &proc_macro_out_dir); let _guard = builder.msg_doc(compiler, stringify!($tool).to_lowercase(), target); - builder.run(cargo); + builder.run(cargo.into_cmd()); if !builder.config.dry_run() { // Sanity check on linked doc directories diff --git a/src/bootstrap/src/core/build_steps/format.rs b/src/bootstrap/src/core/build_steps/format.rs index 4583eb1c6cd85..0372360c3cb74 100644 --- a/src/bootstrap/src/core/build_steps/format.rs +++ b/src/bootstrap/src/core/build_steps/format.rs @@ -160,16 +160,15 @@ pub fn format(build: &Builder<'_>, check: bool, all: bool, paths: &[PathBuf]) { override_builder.add(&format!("!{ignore}")).expect(&ignore); } } - let git_available = build - .run(helpers::git(None).print_on_failure().allow_failure().arg("--version")) - .is_success(); + let git_available = + build.run(helpers::git(None).capture().allow_failure().arg("--version")).is_success(); let mut adjective = None; if git_available { let in_working_tree = build .run( helpers::git(Some(&build.src)) - .print_on_failure() + .capture() .allow_failure() .arg("rev-parse") .arg("--is-inside-work-tree"), diff --git a/src/bootstrap/src/core/build_steps/run.rs b/src/bootstrap/src/core/build_steps/run.rs index 22d5efa5d95dd..496fe446d724e 100644 --- a/src/bootstrap/src/core/build_steps/run.rs +++ b/src/bootstrap/src/core/build_steps/run.rs @@ -158,7 +158,7 @@ impl Step for Miri { // after another --, so this must be at the end. miri.args(builder.config.args()); - builder.run(miri); + builder.run(miri.into_cmd()); } } diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index 918e4e2b90726..9fc337dfd50db 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -26,7 +26,7 @@ use crate::core::builder::{Builder, Compiler, Kind, RunConfig, ShouldRun, Step}; use crate::core::config::flags::get_completion; use crate::core::config::flags::Subcommand; use crate::core::config::TargetSelection; -use crate::utils::exec::{BootstrapCommand, OutputMode}; +use crate::utils::exec::BootstrapCommand; use crate::utils::helpers::{ self, add_link_lib_path, add_rustdoc_cargo_linker_args, dylib_path, dylib_path_var, linker_args, linker_flags, output, t, target_supports_cranelift_backend, up_to_date, @@ -150,16 +150,13 @@ You can skip linkcheck with --skip src/tools/linkchecker" builder.default_doc(&[]); // Build the linkchecker before calling `msg`, since GHA doesn't support nested groups. - let mut linkchecker = builder.tool_cmd(Tool::Linkchecker); + let linkchecker = builder.tool_cmd(Tool::Linkchecker); // Run the linkchecker. let _guard = builder.msg(Kind::Test, compiler.stage, "Linkcheck", bootstrap_host, bootstrap_host); let _time = helpers::timeit(builder); - builder.run( - BootstrapCommand::from(linkchecker.arg(builder.out.join(host.triple).join("doc"))) - .delay_failure(), - ); + builder.run(linkchecker.delay_failure().arg(builder.out.join(host.triple).join("doc"))); } fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { @@ -217,10 +214,7 @@ impl Step for HtmlCheck { )); builder.run( - BootstrapCommand::from( - builder.tool_cmd(Tool::HtmlChecker).arg(builder.doc_out(self.target)), - ) - .delay_failure(), + builder.tool_cmd(Tool::HtmlChecker).delay_failure().arg(builder.doc_out(self.target)), ); } } @@ -260,14 +254,13 @@ impl Step for Cargotest { let _time = helpers::timeit(builder); let mut cmd = builder.tool_cmd(Tool::CargoTest); - let cmd = cmd - .arg(&cargo) + cmd.arg(&cargo) .arg(&out_dir) .args(builder.config.test_args()) .env("RUSTC", builder.rustc(compiler)) .env("RUSTDOC", builder.rustdoc(compiler)); - add_rustdoc_cargo_linker_args(cmd, builder, compiler.host, LldThreads::No); - builder.run(BootstrapCommand::from(cmd).delay_failure()); + add_rustdoc_cargo_linker_args(&mut cmd, builder, compiler.host, LldThreads::No); + builder.run(cmd.delay_failure()); } } @@ -763,12 +756,12 @@ impl Step for Clippy { cargo.env("HOST_LIBS", host_libs); cargo.add_rustc_lib_path(builder); - let mut cargo = prepare_cargo_test(cargo, &[], &[], "clippy", compiler, host, builder); + let cargo = prepare_cargo_test(cargo, &[], &[], "clippy", compiler, host, builder); let _guard = builder.msg_sysroot_tool(Kind::Test, compiler.stage, "clippy", host, host); // Clippy reports errors if it blessed the outputs - if builder.run(BootstrapCommand::from(&mut cargo).allow_failure()).is_success() { + if builder.run(cargo.allow_failure()).is_success() { // The tests succeeded; nothing to do. return; } @@ -821,7 +814,7 @@ impl Step for RustdocTheme { .env("RUSTC_BOOTSTRAP", "1"); cmd.args(linker_args(builder, self.compiler.host, LldThreads::No)); - builder.run(BootstrapCommand::from(&mut cmd).delay_failure()); + builder.run(cmd.delay_failure()); } } @@ -1099,7 +1092,7 @@ HELP: to skip test's attempt to check tidiness, pass `--skip src/tools/tidy` to } builder.info("tidy check"); - builder.run(BootstrapCommand::from(&mut cmd).delay_failure()); + builder.run(cmd.delay_failure()); builder.info("x.py completions check"); let [bash, zsh, fish, powershell] = ["x.py.sh", "x.py.zsh", "x.py.fish", "x.py.ps1"] @@ -1306,7 +1299,7 @@ impl Step for RunMakeSupport { &[], ); - builder.run(cargo); + builder.run(cargo.into_cmd()); let lib_name = "librun_make_support.rlib"; let lib = builder.tools_dir(self.compiler).join(lib_name); @@ -2187,7 +2180,7 @@ impl BookTest { compiler.host, ); let _time = helpers::timeit(builder); - let cmd = BootstrapCommand::from(&mut rustbook_cmd).delay_failure(); + let cmd = rustbook_cmd.delay_failure(); let toolstate = if builder.run(cmd).is_success() { ToolState::TestPass } else { ToolState::TestFail }; builder.save_toolstate(self.name, toolstate); @@ -2318,7 +2311,7 @@ impl Step for ErrorIndex { let guard = builder.msg(Kind::Test, compiler.stage, "error-index", compiler.host, compiler.host); let _time = helpers::timeit(builder); - builder.run(BootstrapCommand::from(&mut tool).output_mode(OutputMode::OnlyOnFailure)); + builder.run(tool.capture()); drop(guard); // The tests themselves need to link to std, so make sure it is // available. @@ -2349,7 +2342,7 @@ fn markdown_test(builder: &Builder<'_>, compiler: Compiler, markdown: &Path) -> cmd = cmd.delay_failure(); if !builder.config.verbose_tests { - cmd = cmd.print_on_failure(); + cmd = cmd.capture(); } builder.run(cmd).is_success() } @@ -2375,10 +2368,13 @@ impl Step for RustcGuide { builder.update_submodule(&relative_path); let src = builder.src.join(relative_path); - let mut rustbook_cmd = builder.tool_cmd(Tool::Rustbook); - let cmd = BootstrapCommand::from(rustbook_cmd.arg("linkcheck").arg(&src)).delay_failure(); - let toolstate = - if builder.run(cmd).is_success() { ToolState::TestPass } else { ToolState::TestFail }; + let mut rustbook_cmd = builder.tool_cmd(Tool::Rustbook).delay_failure(); + rustbook_cmd.arg("linkcheck").arg(&src); + let toolstate = if builder.run(rustbook_cmd).is_success() { + ToolState::TestPass + } else { + ToolState::TestFail + }; builder.save_toolstate("rustc-dev-guide", toolstate); } } @@ -3347,7 +3343,7 @@ impl Step for CodegenCranelift { .arg("testsuite.extended_sysroot"); cargo.args(builder.config.test_args()); - builder.run(cargo); + builder.run(cargo.into_cmd()); } } @@ -3472,6 +3468,6 @@ impl Step for CodegenGCC { .arg("--std-tests"); cargo.args(builder.config.test_args()); - builder.run(cargo); + builder.run(cargo.into_cmd()); } } diff --git a/src/bootstrap/src/core/build_steps/tool.rs b/src/bootstrap/src/core/build_steps/tool.rs index b34640439121a..20c7a30f1a823 100644 --- a/src/bootstrap/src/core/build_steps/tool.rs +++ b/src/bootstrap/src/core/build_steps/tool.rs @@ -603,7 +603,7 @@ impl Step for Rustdoc { &self.compiler.host, &target, ); - builder.run(cargo); + builder.run(cargo.into_cmd()); // Cargo adds a number of paths to the dylib search path on windows, which results in // the wrong rustdoc being executed. To avoid the conflicting rustdocs, we name the "tool" @@ -858,7 +858,7 @@ impl Step for LlvmBitcodeLinker { &self.extra_features, ); - builder.run(cargo); + builder.run(cargo.into_cmd()); let tool_out = builder .cargo_out(self.compiler, Mode::ToolRustc, self.target) diff --git a/src/bootstrap/src/core/builder.rs b/src/bootstrap/src/core/builder.rs index 58d6e7a58e308..35de91c41d4f1 100644 --- a/src/bootstrap/src/core/builder.rs +++ b/src/bootstrap/src/core/builder.rs @@ -2398,6 +2398,10 @@ impl Cargo { cargo } + pub fn into_cmd(self) -> BootstrapCommand { + self.into() + } + /// Same as `Cargo::new` except this one doesn't configure the linker with `Cargo::configure_linker` pub fn new_for_mir_opt_tests( builder: &Builder<'_>, @@ -2622,9 +2626,3 @@ impl From for BootstrapCommand { cargo.command } } - -impl From for Command { - fn from(cargo: Cargo) -> Command { - BootstrapCommand::from(cargo).command - } -} diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs index ae2982ea56f09..ae3d18e8774bc 100644 --- a/src/bootstrap/src/lib.rs +++ b/src/bootstrap/src/lib.rs @@ -555,10 +555,7 @@ impl Build { // Save any local changes, but avoid running `git stash pop` if there are none (since it will exit with an error). // diff-index reports the modifications through the exit status let has_local_modifications = self - .run( - BootstrapCommand::from(submodule_git().args(["diff-index", "--quiet", "HEAD"])) - .allow_failure(), - ) + .run(submodule_git().allow_failure().args(["diff-index", "--quiet", "HEAD"])) .is_failure(); if has_local_modifications { self.run(submodule_git().args(["stash", "push"])); @@ -582,7 +579,7 @@ impl Build { let output = self .run( helpers::git(Some(&self.src)) - .quiet() + .capture() .args(["config", "--file"]) .arg(self.config.src.join(".gitmodules")) .args(["--get-regexp", "path"]), @@ -937,69 +934,71 @@ impl Build { /// Execute a command and return its output. /// This method should be used for all command executions in bootstrap. - fn run>(&self, command: C) -> CommandOutput { + fn run>(&self, mut command: C) -> CommandOutput { if self.config.dry_run() { return CommandOutput::default(); } - let mut command = command.into(); + let command = command.as_mut(); self.verbose(|| println!("running: {command:?}")); - let output_mode = command.output_mode.unwrap_or_else(|| match self.is_verbose() { - true => OutputMode::All, - false => OutputMode::OnlyOutput, - }); - let (output, print_error): (io::Result, bool) = match output_mode { - mode @ (OutputMode::All | OutputMode::OnlyOutput) => ( - command.command.status().map(|status| status.into()), - matches!(mode, OutputMode::All), - ), - mode @ (OutputMode::OnlyOnFailure | OutputMode::Quiet) => ( - command.command.output().map(|o| o.into()), - matches!(mode, OutputMode::OnlyOnFailure), - ), + let output: io::Result = match command.output_mode { + OutputMode::Print => command.command.status().map(|status| status.into()), + OutputMode::CaptureAll => command.command.output().map(|o| o.into()), + OutputMode::CaptureStdout => { + command.command.stderr(Stdio::inherit()); + command.command.output().map(|o| o.into()) + } }; let output = match output { Ok(output) => output, - Err(e) => fail(&format!("failed to execute command: {:?}\nerror: {}", command, e)), + Err(e) => fail(&format!("failed to execute command: {command:?}\nerror: {e}")), }; if !output.is_success() { - if print_error { - println!( - "\n\nCommand did not execute successfully.\ - \nExpected success, got: {}", - output.status(), - ); + use std::fmt::Write; + + // Here we build an error message, and below we decide if it should be printed or not. + let mut message = String::new(); + writeln!( + message, + "\n\nCommand {command:?} did not execute successfully.\ + \nExpected success, got: {}", + output.status(), + ) + .unwrap(); - if !self.is_verbose() { - println!("Add `-v` to see more details.\n"); - } + // If the output mode is OutputMode::Print, the output has already been printed to + // stdout/stderr, and we thus don't have anything captured to print anyway. + if matches!(command.output_mode, OutputMode::CaptureAll | OutputMode::CaptureStdout) { + writeln!(message, "\nSTDOUT ----\n{}", output.stdout().trim()).unwrap(); - self.verbose(|| { - println!( - "\nSTDOUT ----\n{}\n\ - STDERR ----\n{}\n", - output.stdout(), - output.stderr(), - ) - }); + // Stderr is added to the message only if it was captured + if matches!(command.output_mode, OutputMode::CaptureAll) { + writeln!(message, "\nSTDERR ----\n{}", output.stderr().trim()).unwrap(); + } } match command.failure_behavior { BehaviorOnFailure::DelayFail => { if self.fail_fast { + println!("{message}"); exit!(1); } let mut failures = self.delayed_failures.borrow_mut(); - failures.push(format!("{command:?}")); + failures.push(message); } BehaviorOnFailure::Exit => { + println!("{message}"); exit!(1); } - BehaviorOnFailure::Ignore => {} + BehaviorOnFailure::Ignore => { + // If failures are allowed, either the error has been printed already + // (OutputMode::Print) or the user used a capture output mode and wants to + // handle the error output on their own. + } } } output @@ -1490,7 +1489,7 @@ impl Build { // (Note that we use a `..` range, not the `...` symmetric difference.) self.run( helpers::git(Some(&self.src)) - .quiet() + .capture() .arg("rev-list") .arg("--count") .arg("--merges") diff --git a/src/bootstrap/src/utils/exec.rs b/src/bootstrap/src/utils/exec.rs index dc30876601c6b..5f9e164816179 100644 --- a/src/bootstrap/src/utils/exec.rs +++ b/src/bootstrap/src/utils/exec.rs @@ -13,18 +13,19 @@ pub enum BehaviorOnFailure { Ignore, } -/// How should the output of the command be handled. +/// How should the output of the command be handled (whether it should be captured or printed). #[derive(Debug, Copy, Clone)] pub enum OutputMode { - /// Print both the output (by inheriting stdout/stderr) and also the command itself, if it - /// fails. - All, - /// Print the output (by inheriting stdout/stderr). - OnlyOutput, - /// Suppress the output if the command succeeds, otherwise print the output. - OnlyOnFailure, - /// Suppress the output of the command. - Quiet, + /// Prints the stdout/stderr of the command to stdout/stderr of bootstrap (by inheriting these + /// streams). + /// Corresponds to calling `cmd.status()`. + Print, + /// Captures the stdout and stderr of the command into memory. + /// Corresponds to calling `cmd.output()`. + CaptureAll, + /// Captures the stdout of the command into memory, inherits stderr. + /// Corresponds to calling `cmd.output()`. + CaptureStdout, } /// Wrapper around `std::process::Command`. @@ -34,10 +35,10 @@ pub enum OutputMode { /// If you want to delay failures until the end of bootstrap, use [delay_failure]. /// /// By default, the command will print its stdout/stderr to stdout/stderr of bootstrap -/// ([OutputMode::OnlyOutput]). If bootstrap uses verbose mode, then it will also print the -/// command itself in case of failure ([OutputMode::All]). -/// If you want to handle the output programmatically, use `output_mode(OutputMode::OnlyOnFailure)`, -/// which will print the output only if the command fails. +/// ([OutputMode::Print]). +/// If you want to handle the output programmatically, use [BootstrapCommand::capture]. +/// +/// Bootstrap will print a debug log to stdout if the command fails and failure is not allowed. /// /// [allow_failure]: BootstrapCommand::allow_failure /// [delay_failure]: BootstrapCommand::delay_failure @@ -45,12 +46,16 @@ pub enum OutputMode { pub struct BootstrapCommand { pub command: Command, pub failure_behavior: BehaviorOnFailure, - pub output_mode: Option, + pub output_mode: OutputMode, } impl BootstrapCommand { pub fn new>(program: S) -> Self { - Command::new(program).into() + Self { + command: Command::new(program), + failure_behavior: BehaviorOnFailure::Exit, + output_mode: OutputMode::Print, + } } pub fn arg>(&mut self, arg: S) -> &mut Self { @@ -106,52 +111,22 @@ impl BootstrapCommand { Self { failure_behavior: BehaviorOnFailure::Ignore, ..self } } - /// Do not print the output of the command, unless it fails. - pub fn print_on_failure(self) -> Self { - self.output_mode(OutputMode::OnlyOnFailure) - } - - /// Do not print the output of the command. - pub fn quiet(self) -> Self { - self.output_mode(OutputMode::Quiet) + /// Capture the output of the command, do not print it. + pub fn capture(self) -> Self { + Self { output_mode: OutputMode::CaptureAll, ..self } } - pub fn output_mode(self, output_mode: OutputMode) -> Self { - Self { output_mode: Some(output_mode), ..self } + /// Capture stdout of the command, do not print it. + pub fn capture_stdout(self) -> Self { + Self { output_mode: OutputMode::CaptureStdout, ..self } } } -/// FIXME: This implementation is temporary, until all `Command` invocations are migrated to -/// `BootstrapCommand`. -impl<'a> From<&'a mut BootstrapCommand> for BootstrapCommand { - fn from(command: &'a mut BootstrapCommand) -> Self { - // This is essentially a manual `Command::clone` - let mut cmd = Command::new(command.command.get_program()); - if let Some(dir) = command.command.get_current_dir() { - cmd.current_dir(dir); - } - cmd.args(command.command.get_args()); - for (key, value) in command.command.get_envs() { - match value { - Some(value) => { - cmd.env(key, value); - } - None => { - cmd.env_remove(key); - } - } - } - Self { - command: cmd, - output_mode: command.output_mode, - failure_behavior: command.failure_behavior, - } - } -} - -impl From for BootstrapCommand { - fn from(command: Command) -> Self { - Self { command, failure_behavior: BehaviorOnFailure::Exit, output_mode: None } +/// This implementation exists to make it possible to pass both [BootstrapCommand] and +/// `&mut BootstrapCommand` to `Build.run()`. +impl AsMut for BootstrapCommand { + fn as_mut(&mut self) -> &mut BootstrapCommand { + self } } @@ -176,6 +151,10 @@ impl CommandOutput { String::from_utf8(self.0.stdout.clone()).expect("Cannot parse process stdout as UTF-8") } + pub fn stdout_if_ok(&self) -> Option { + if self.is_success() { Some(self.stdout()) } else { None } + } + pub fn stderr(&self) -> String { String::from_utf8(self.0.stderr.clone()).expect("Cannot parse process stderr as UTF-8") } From 3ef77cc42cb1ea1f07c1bd8c2ac514d15291106b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Sat, 22 Jun 2024 17:47:11 +0200 Subject: [PATCH 637/892] Remove various usages of the `output` function --- src/bootstrap/src/core/build_steps/compile.rs | 13 ++-- src/bootstrap/src/core/build_steps/dist.rs | 19 ++--- src/bootstrap/src/core/build_steps/format.rs | 33 ++++----- src/bootstrap/src/core/build_steps/llvm.rs | 14 ++-- src/bootstrap/src/core/build_steps/run.rs | 6 +- src/bootstrap/src/core/build_steps/suggest.rs | 25 +++---- .../src/core/build_steps/synthetic_targets.rs | 14 ++-- src/bootstrap/src/core/build_steps/test.rs | 70 ++++++++----------- src/bootstrap/src/core/build_steps/tool.rs | 5 +- src/bootstrap/src/core/builder.rs | 7 +- src/bootstrap/src/core/metadata.rs | 8 +-- src/bootstrap/src/core/sanity.rs | 4 +- src/bootstrap/src/lib.rs | 6 +- src/bootstrap/src/utils/cc_detect.rs | 8 +-- src/bootstrap/src/utils/exec.rs | 12 ++-- src/bootstrap/src/utils/helpers.rs | 8 ++- 16 files changed, 120 insertions(+), 132 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs index c267d3b0c0cf6..01b25224de4cd 100644 --- a/src/bootstrap/src/core/build_steps/compile.rs +++ b/src/bootstrap/src/core/build_steps/compile.rs @@ -29,7 +29,7 @@ use crate::core::builder::{Builder, Kind, PathSet, RunConfig, ShouldRun, Step, T use crate::core::config::{DebuginfoLevel, LlvmLibunwind, RustcLto, TargetSelection}; use crate::utils::exec::BootstrapCommand; use crate::utils::helpers::{ - exe, get_clang_cl_resource_dir, is_debug_info, is_dylib, output, symlink_dir, t, up_to_date, + exe, get_clang_cl_resource_dir, is_debug_info, is_dylib, symlink_dir, t, up_to_date, }; use crate::LLVM_TOOLS; use crate::{CLang, Compiler, DependencyType, GitRepo, Mode}; @@ -1488,10 +1488,10 @@ pub fn compiler_file( if builder.config.dry_run() { return PathBuf::new(); } - let mut cmd = Command::new(compiler); + let mut cmd = BootstrapCommand::new(compiler); cmd.args(builder.cflags(target, GitRepo::Rustc, c)); cmd.arg(format!("-print-file-name={file}")); - let out = output(&mut cmd); + let out = builder.run(cmd.capture_stdout()).stdout(); PathBuf::from(out.trim()) } @@ -1836,7 +1836,9 @@ impl Step for Assemble { let llvm::LlvmResult { llvm_config, .. } = builder.ensure(llvm::Llvm { target: target_compiler.host }); if !builder.config.dry_run() && builder.config.llvm_tools_enabled { - let llvm_bin_dir = output(Command::new(llvm_config).arg("--bindir")); + let llvm_bin_dir = builder + .run(BootstrapCommand::new(llvm_config).capture_stdout().arg("--bindir")) + .stdout(); let llvm_bin_dir = Path::new(llvm_bin_dir.trim()); // Since we've already built the LLVM tools, install them to the sysroot. @@ -2161,8 +2163,7 @@ pub fn strip_debug(builder: &Builder<'_>, target: TargetSelection, path: &Path) } let previous_mtime = FileTime::from_last_modification_time(&path.metadata().unwrap()); - // NOTE: `output` will propagate any errors here. - output(Command::new("strip").arg("--strip-debug").arg(path)); + builder.run(BootstrapCommand::new("strip").capture().arg("--strip-debug").arg(path)); // After running `strip`, we have to set the file modification time to what it was before, // otherwise we risk Cargo invalidating its fingerprint and rebuilding the world next time diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs index 08795efe5bb4c..3dc871b1ca9dd 100644 --- a/src/bootstrap/src/core/build_steps/dist.rs +++ b/src/bootstrap/src/core/build_steps/dist.rs @@ -14,7 +14,6 @@ use std::ffi::OsStr; use std::fs; use std::io::Write; use std::path::{Path, PathBuf}; -use std::process::Command; use object::read::archive::ArchiveFile; use object::BinaryFormat; @@ -28,7 +27,7 @@ use crate::core::config::TargetSelection; use crate::utils::channel::{self, Info}; use crate::utils::exec::BootstrapCommand; use crate::utils::helpers::{ - exe, is_dylib, move_file, output, t, target_supports_cranelift_backend, timeit, + exe, is_dylib, move_file, t, target_supports_cranelift_backend, timeit, }; use crate::utils::tarball::{GeneratedTarball, OverlayKind, Tarball}; use crate::{Compiler, DependencyType, Mode, LLVM_TOOLS}; @@ -181,9 +180,9 @@ fn make_win_dist( } //Ask gcc where it keeps its stuff - let mut cmd = Command::new(builder.cc(target)); + let mut cmd = BootstrapCommand::new(builder.cc(target)); cmd.arg("-print-search-dirs"); - let gcc_out = output(&mut cmd); + let gcc_out = builder.run(cmd.capture_stdout()).stdout(); let mut bin_path: Vec<_> = env::split_paths(&env::var_os("PATH").unwrap_or_default()).collect(); let mut lib_path = Vec::new(); @@ -1024,7 +1023,7 @@ impl Step for PlainSourceTarball { } // Vendor all Cargo dependencies - let mut cmd = Command::new(&builder.initial_cargo); + let mut cmd = BootstrapCommand::new(&builder.initial_cargo); cmd.arg("vendor") .arg("--versioned-dirs") .arg("--sync") @@ -1062,7 +1061,7 @@ impl Step for PlainSourceTarball { } let config = if !builder.config.dry_run() { - t!(String::from_utf8(t!(cmd.output()).stdout)) + builder.run(cmd.capture()).stdout() } else { String::new() }; @@ -2079,10 +2078,14 @@ fn maybe_install_llvm( } else if let llvm::LlvmBuildStatus::AlreadyBuilt(llvm::LlvmResult { llvm_config, .. }) = llvm::prebuilt_llvm_config(builder, target) { - let mut cmd = Command::new(llvm_config); + let mut cmd = BootstrapCommand::new(llvm_config); cmd.arg("--libfiles"); builder.verbose(|| println!("running {cmd:?}")); - let files = if builder.config.dry_run() { "".into() } else { output(&mut cmd) }; + let files = if builder.config.dry_run() { + "".into() + } else { + builder.run(cmd.capture_stdout()).stdout() + }; let build_llvm_out = &builder.llvm_out(builder.config.build); let target_llvm_out = &builder.llvm_out(target); for file in files.trim_end().split(' ') { diff --git a/src/bootstrap/src/core/build_steps/format.rs b/src/bootstrap/src/core/build_steps/format.rs index 0372360c3cb74..66286a52813f4 100644 --- a/src/bootstrap/src/core/build_steps/format.rs +++ b/src/bootstrap/src/core/build_steps/format.rs @@ -1,7 +1,8 @@ //! Runs rustfmt on the repository. use crate::core::builder::Builder; -use crate::utils::helpers::{self, output, program_out_of_date, t}; +use crate::utils::exec::BootstrapCommand; +use crate::utils::helpers::{self, program_out_of_date, t}; use build_helper::ci::CiEnv; use build_helper::git::get_git_modified_files; use ignore::WalkBuilder; @@ -53,19 +54,17 @@ fn rustfmt(src: &Path, rustfmt: &Path, paths: &[PathBuf], check: bool) -> impl F fn get_rustfmt_version(build: &Builder<'_>) -> Option<(String, PathBuf)> { let stamp_file = build.out.join("rustfmt.stamp"); - let mut cmd = Command::new(match build.initial_rustfmt() { + let mut cmd = BootstrapCommand::new(match build.initial_rustfmt() { Some(p) => p, None => return None, }); cmd.arg("--version"); - let output = match cmd.output() { - Ok(status) => status, - Err(_) => return None, - }; - if !output.status.success() { + + let output = build.run(cmd.capture().allow_failure()); + if output.is_failure() { return None; } - Some((String::from_utf8(output.stdout).unwrap(), stamp_file)) + Some((output.stdout(), stamp_file)) } /// Return whether the format cache can be reused. @@ -175,14 +174,16 @@ pub fn format(build: &Builder<'_>, check: bool, all: bool, paths: &[PathBuf]) { ) .is_success(); if in_working_tree { - let untracked_paths_output = output( - &mut helpers::git(Some(&build.src)) - .arg("status") - .arg("--porcelain") - .arg("-z") - .arg("--untracked-files=normal") - .command, - ); + let untracked_paths_output = build + .run( + helpers::git(Some(&build.src)) + .capture_stdout() + .arg("status") + .arg("--porcelain") + .arg("-z") + .arg("--untracked-files=normal"), + ) + .stdout(); let untracked_paths: Vec<_> = untracked_paths_output .split_terminator('\0') .filter_map( diff --git a/src/bootstrap/src/core/build_steps/llvm.rs b/src/bootstrap/src/core/build_steps/llvm.rs index ba21e2ad32d05..4f1c1f87d1c6c 100644 --- a/src/bootstrap/src/core/build_steps/llvm.rs +++ b/src/bootstrap/src/core/build_steps/llvm.rs @@ -14,7 +14,6 @@ use std::ffi::{OsStr, OsString}; use std::fs::{self, File}; use std::io; use std::path::{Path, PathBuf}; -use std::process::Command; use std::sync::OnceLock; use crate::core::builder::{Builder, RunConfig, ShouldRun, Step}; @@ -25,6 +24,7 @@ use crate::utils::helpers::{ }; use crate::{generate_smart_stamp_hash, CLang, GitRepo, Kind}; +use crate::utils::exec::BootstrapCommand; use build_helper::ci::CiEnv; use build_helper::git::get_git_merge_base; @@ -478,7 +478,9 @@ impl Step for Llvm { let LlvmResult { llvm_config, .. } = builder.ensure(Llvm { target: builder.config.build }); if !builder.config.dry_run() { - let llvm_bindir = output(Command::new(&llvm_config).arg("--bindir")); + let llvm_bindir = builder + .run(BootstrapCommand::new(&llvm_config).capture_stdout().arg("--bindir")) + .stdout(); let host_bin = Path::new(llvm_bindir.trim()); cfg.define( "LLVM_TABLEGEN", @@ -528,8 +530,8 @@ impl Step for Llvm { // Helper to find the name of LLVM's shared library on darwin and linux. let find_llvm_lib_name = |extension| { - let mut cmd = Command::new(&res.llvm_config); - let version = output(cmd.arg("--version")); + let cmd = BootstrapCommand::new(&res.llvm_config); + let version = builder.run(cmd.capture_stdout().arg("--version")).stdout(); let major = version.split('.').next().unwrap(); match &llvm_version_suffix { @@ -585,8 +587,8 @@ fn check_llvm_version(builder: &Builder<'_>, llvm_config: &Path) { return; } - let mut cmd = Command::new(llvm_config); - let version = output(cmd.arg("--version")); + let cmd = BootstrapCommand::new(llvm_config); + let version = builder.run(cmd.capture_stdout().arg("--version")).stdout(); let mut parts = version.split('.').take(2).filter_map(|s| s.parse::().ok()); if let (Some(major), Some(_minor)) = (parts.next(), parts.next()) { if major >= 17 { diff --git a/src/bootstrap/src/core/build_steps/run.rs b/src/bootstrap/src/core/build_steps/run.rs index 496fe446d724e..316a03a2171b5 100644 --- a/src/bootstrap/src/core/build_steps/run.rs +++ b/src/bootstrap/src/core/build_steps/run.rs @@ -4,7 +4,6 @@ //! If it can be reached from `./x.py run` it can go here. use std::path::PathBuf; -use std::process::Command; use crate::core::build_steps::dist::distdir; use crate::core::build_steps::test; @@ -12,7 +11,7 @@ use crate::core::build_steps::tool::{self, SourceType, Tool}; use crate::core::builder::{Builder, RunConfig, ShouldRun, Step}; use crate::core::config::flags::get_completion; use crate::core::config::TargetSelection; -use crate::utils::helpers::output; +use crate::utils::exec::BootstrapCommand; use crate::Mode; #[derive(Debug, PartialOrd, Ord, Clone, Hash, PartialEq, Eq)] @@ -41,7 +40,8 @@ impl Step for BuildManifest { panic!("\n\nfailed to specify `dist.upload-addr` in `config.toml`\n\n") }); - let today = output(Command::new("date").arg("+%Y-%m-%d")); + let today = + builder.run(BootstrapCommand::new("date").capture_stdout().arg("+%Y-%m-%d")).stdout(); cmd.arg(sign); cmd.arg(distdir(builder)); diff --git a/src/bootstrap/src/core/build_steps/suggest.rs b/src/bootstrap/src/core/build_steps/suggest.rs index 7c5e0d4e13ebb..5412b3c807b62 100644 --- a/src/bootstrap/src/core/build_steps/suggest.rs +++ b/src/bootstrap/src/core/build_steps/suggest.rs @@ -13,24 +13,15 @@ use crate::core::builder::Builder; pub fn suggest(builder: &Builder<'_>, run: bool) { let git_config = builder.config.git_config(); let suggestions = builder - .tool_cmd(Tool::SuggestTests) - .env("SUGGEST_TESTS_GIT_REPOSITORY", git_config.git_repository) - .env("SUGGEST_TESTS_NIGHTLY_BRANCH", git_config.nightly_branch) - .command - .output() - .expect("failed to run `suggest-tests` tool"); + .run( + builder + .tool_cmd(Tool::SuggestTests) + .capture_stdout() + .env("SUGGEST_TESTS_GIT_REPOSITORY", git_config.git_repository) + .env("SUGGEST_TESTS_NIGHTLY_BRANCH", git_config.nightly_branch), + ) + .stdout(); - if !suggestions.status.success() { - println!("failed to run `suggest-tests` tool ({})", suggestions.status); - println!( - "`suggest_tests` stdout:\n{}`suggest_tests` stderr:\n{}", - String::from_utf8(suggestions.stdout).unwrap(), - String::from_utf8(suggestions.stderr).unwrap() - ); - panic!("failed to run `suggest-tests`"); - } - - let suggestions = String::from_utf8(suggestions.stdout).unwrap(); let suggestions = suggestions .lines() .map(|line| { diff --git a/src/bootstrap/src/core/build_steps/synthetic_targets.rs b/src/bootstrap/src/core/build_steps/synthetic_targets.rs index 281a9b093b90b..a115ba2d8b27a 100644 --- a/src/bootstrap/src/core/build_steps/synthetic_targets.rs +++ b/src/bootstrap/src/core/build_steps/synthetic_targets.rs @@ -9,8 +9,8 @@ use crate::core::builder::{Builder, ShouldRun, Step}; use crate::core::config::TargetSelection; +use crate::utils::exec::BootstrapCommand; use crate::Compiler; -use std::process::{Command, Stdio}; #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub(crate) struct MirOptPanicAbortSyntheticTarget { @@ -56,7 +56,7 @@ fn create_synthetic_target( return TargetSelection::create_synthetic(&name, path.to_str().unwrap()); } - let mut cmd = Command::new(builder.rustc(compiler)); + let mut cmd = BootstrapCommand::new(builder.rustc(compiler)); cmd.arg("--target").arg(base.rustc_target_arg()); cmd.args(["-Zunstable-options", "--print", "target-spec-json"]); @@ -64,14 +64,8 @@ fn create_synthetic_target( // we cannot use nightly features. So `RUSTC_BOOTSTRAP` is needed here. cmd.env("RUSTC_BOOTSTRAP", "1"); - cmd.stdout(Stdio::piped()); - - let output = cmd.spawn().unwrap().wait_with_output().unwrap(); - if !output.status.success() { - panic!("failed to gather the target spec for {base}"); - } - - let mut spec: serde_json::Value = serde_json::from_slice(&output.stdout).unwrap(); + let output = builder.run(cmd.capture()).stdout(); + let mut spec: serde_json::Value = serde_json::from_slice(output.as_bytes()).unwrap(); let spec_map = spec.as_object_mut().unwrap(); // The `is-builtin` attribute of a spec needs to be removed, otherwise rustc will complain. diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index 9fc337dfd50db..b063d0aaf4f16 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -29,8 +29,7 @@ use crate::core::config::TargetSelection; use crate::utils::exec::BootstrapCommand; use crate::utils::helpers::{ self, add_link_lib_path, add_rustdoc_cargo_linker_args, dylib_path, dylib_path_var, - linker_args, linker_flags, output, t, target_supports_cranelift_backend, up_to_date, - LldThreads, + linker_args, linker_flags, t, target_supports_cranelift_backend, up_to_date, LldThreads, }; use crate::utils::render_tests::{add_flags_and_try_run_tests, try_run_tests}; use crate::{envify, CLang, DocTests, GitRepo, Mode}; @@ -470,19 +469,12 @@ impl Miri { // We re-use the `cargo` from above. cargo.arg("--print-sysroot"); - // FIXME: Is there a way in which we can re-use the usual `run` helpers? if builder.config.dry_run() { String::new() } else { builder.verbose(|| println!("running: {cargo:?}")); - let out = cargo - .command - .output() - .expect("We already ran `cargo miri setup` before and that worked"); - assert!(out.status.success(), "`cargo miri setup` returned with non-0 exit code"); + let stdout = builder.run(cargo.capture_stdout()).stdout(); // Output is "\n". - let stdout = String::from_utf8(out.stdout) - .expect("`cargo miri setup` stdout is not valid UTF-8"); let sysroot = stdout.trim_end(); builder.verbose(|| println!("`cargo miri setup --print-sysroot` said: {sysroot:?}")); sysroot.to_owned() @@ -911,25 +903,26 @@ impl Step for RustdocJSNotStd { } } -fn get_browser_ui_test_version_inner(npm: &Path, global: bool) -> Option { - let mut command = Command::new(npm); +fn get_browser_ui_test_version_inner( + builder: &Builder<'_>, + npm: &Path, + global: bool, +) -> Option { + let mut command = BootstrapCommand::new(npm).capture(); command.arg("list").arg("--parseable").arg("--long").arg("--depth=0"); if global { command.arg("--global"); } - let lines = command - .output() - .map(|output| String::from_utf8_lossy(&output.stdout).into_owned()) - .unwrap_or_default(); + let lines = builder.run(command.allow_failure()).stdout(); lines .lines() .find_map(|l| l.split(':').nth(1)?.strip_prefix("browser-ui-test@")) .map(|v| v.to_owned()) } -fn get_browser_ui_test_version(npm: &Path) -> Option { - get_browser_ui_test_version_inner(npm, false) - .or_else(|| get_browser_ui_test_version_inner(npm, true)) +fn get_browser_ui_test_version(builder: &Builder<'_>, npm: &Path) -> Option { + get_browser_ui_test_version_inner(builder, npm, false) + .or_else(|| get_browser_ui_test_version_inner(builder, npm, true)) } #[derive(Debug, Clone, Hash, PartialEq, Eq)] @@ -953,7 +946,7 @@ impl Step for RustdocGUI { .config .npm .as_ref() - .map(|p| get_browser_ui_test_version(p).is_some()) + .map(|p| get_browser_ui_test_version(builder, p).is_some()) .unwrap_or(false) })) } @@ -1811,26 +1804,15 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the } let lldb_exe = builder.config.lldb.clone().unwrap_or_else(|| PathBuf::from("lldb")); - let lldb_version = Command::new(&lldb_exe) - .arg("--version") - .output() - .map(|output| { - (String::from_utf8_lossy(&output.stdout).to_string(), output.status.success()) - }) - .ok() - .and_then(|(output, success)| if success { Some(output) } else { None }); + let lldb_version = builder + .run(BootstrapCommand::new(&lldb_exe).capture().allow_failure().arg("--version")) + .stdout_if_ok(); if let Some(ref vers) = lldb_version { - let run = |cmd: &mut Command| { - cmd.output().map(|output| { - String::from_utf8_lossy(&output.stdout) - .lines() - .next() - .unwrap_or_else(|| panic!("{:?} failed {:?}", cmd, output)) - .to_string() - }) - }; cmd.arg("--lldb-version").arg(vers); - let lldb_python_dir = run(Command::new(&lldb_exe).arg("-P")).ok(); + let lldb_python_dir = builder + .run(BootstrapCommand::new(&lldb_exe).allow_failure().capture_stdout().arg("-P")) + .stdout_if_ok() + .map(|p| p.lines().next().expect("lldb Python dir not found").to_string()); if let Some(ref dir) = lldb_python_dir { cmd.arg("--lldb-python-dir").arg(dir); } @@ -1886,8 +1868,12 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the let llvm::LlvmResult { llvm_config, .. } = builder.ensure(llvm::Llvm { target: builder.config.build }); if !builder.config.dry_run() { - let llvm_version = output(Command::new(&llvm_config).arg("--version")); - let llvm_components = output(Command::new(&llvm_config).arg("--components")); + let llvm_version = builder + .run(BootstrapCommand::new(&llvm_config).capture_stdout().arg("--version")) + .stdout(); + let llvm_components = builder + .run(BootstrapCommand::new(&llvm_config).capture_stdout().arg("--components")) + .stdout(); // Remove trailing newline from llvm-config output. cmd.arg("--llvm-version") .arg(llvm_version.trim()) @@ -1906,7 +1892,9 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the // separate compilations. We can add LLVM's library path to the // platform-specific environment variable as a workaround. if !builder.config.dry_run() && suite.ends_with("fulldeps") { - let llvm_libdir = output(Command::new(&llvm_config).arg("--libdir")); + let llvm_libdir = builder + .run(BootstrapCommand::new(&llvm_config).capture_stdout().arg("--libdir")) + .stdout(); add_link_lib_path(vec![llvm_libdir.trim().into()], &mut cmd); } diff --git a/src/bootstrap/src/core/build_steps/tool.rs b/src/bootstrap/src/core/build_steps/tool.rs index 20c7a30f1a823..40184e016a634 100644 --- a/src/bootstrap/src/core/build_steps/tool.rs +++ b/src/bootstrap/src/core/build_steps/tool.rs @@ -1,7 +1,6 @@ use std::env; use std::fs; use std::path::{Path, PathBuf}; -use std::process::Command; use crate::core::build_steps::compile; use crate::core::build_steps::toolstate::ToolState; @@ -10,7 +9,6 @@ use crate::core::builder::{Builder, Cargo as CargoCommand, RunConfig, ShouldRun, use crate::core::config::TargetSelection; use crate::utils::channel::GitInfo; use crate::utils::exec::BootstrapCommand; -use crate::utils::helpers::output; use crate::utils::helpers::{add_dylib_path, exe, t}; use crate::Compiler; use crate::Mode; @@ -926,7 +924,8 @@ impl Step for LibcxxVersionTool { } } - let version_output = output(&mut Command::new(executable)); + let version_output = + builder.run(BootstrapCommand::new(executable).capture_stdout()).stdout(); let version_str = version_output.split_once("version:").unwrap().1; let version = version_str.trim().parse::().unwrap(); diff --git a/src/bootstrap/src/core/builder.rs b/src/bootstrap/src/core/builder.rs index 35de91c41d4f1..4da912994c3ee 100644 --- a/src/bootstrap/src/core/builder.rs +++ b/src/bootstrap/src/core/builder.rs @@ -8,7 +8,6 @@ use std::fs; use std::hash::Hash; use std::ops::Deref; use std::path::{Path, PathBuf}; -use std::process::Command; use std::time::{Duration, Instant}; use crate::core::build_steps::tool::{self, SourceType}; @@ -20,7 +19,7 @@ use crate::core::config::{DryRun, SplitDebuginfo, TargetSelection}; use crate::prepare_behaviour_dump_dir; use crate::utils::cache::Cache; use crate::utils::helpers::{self, add_dylib_path, add_link_lib_path, exe, linker_args}; -use crate::utils::helpers::{check_cfg_arg, libdir, linker_flags, output, t, LldThreads}; +use crate::utils::helpers::{check_cfg_arg, libdir, linker_flags, t, LldThreads}; use crate::EXTRA_CHECK_CFGS; use crate::{Build, CLang, Crate, DocTests, GitRepo, Mode}; @@ -1919,7 +1918,9 @@ impl<'a> Builder<'a> { // platform-specific environment variable as a workaround. if mode == Mode::ToolRustc || mode == Mode::Codegen { if let Some(llvm_config) = self.llvm_config(target) { - let llvm_libdir = output(Command::new(llvm_config).arg("--libdir")); + let llvm_libdir = self + .run(BootstrapCommand::new(llvm_config).capture_stdout().arg("--libdir")) + .stdout(); add_link_lib_path(vec![llvm_libdir.trim().into()], &mut cargo); } } diff --git a/src/bootstrap/src/core/metadata.rs b/src/bootstrap/src/core/metadata.rs index 220eb5ba126e4..da269959e7b43 100644 --- a/src/bootstrap/src/core/metadata.rs +++ b/src/bootstrap/src/core/metadata.rs @@ -1,9 +1,8 @@ use std::path::PathBuf; -use std::process::Command; use serde_derive::Deserialize; -use crate::utils::helpers::output; +use crate::utils::exec::BootstrapCommand; use crate::{t, Build, Crate}; /// For more information, see the output of @@ -71,7 +70,7 @@ pub fn build(build: &mut Build) { /// particular crate (e.g., `x build sysroot` to build library/sysroot). fn workspace_members(build: &Build) -> Vec { let collect_metadata = |manifest_path| { - let mut cargo = Command::new(&build.initial_cargo); + let mut cargo = BootstrapCommand::new(&build.initial_cargo); cargo // Will read the libstd Cargo.toml // which uses the unstable `public-dependency` feature. @@ -82,7 +81,8 @@ fn workspace_members(build: &Build) -> Vec { .arg("--no-deps") .arg("--manifest-path") .arg(build.src.join(manifest_path)); - let metadata_output = output(&mut cargo); + // FIXME: fix stderr + let metadata_output = build.run(cargo.capture()).stdout(); let Output { packages, .. } = t!(serde_json::from_str(&metadata_output)); packages }; diff --git a/src/bootstrap/src/core/sanity.rs b/src/bootstrap/src/core/sanity.rs index 5a0be2948a19e..d64923e69cbd0 100644 --- a/src/bootstrap/src/core/sanity.rs +++ b/src/bootstrap/src/core/sanity.rs @@ -24,6 +24,7 @@ use std::collections::HashSet; use crate::builder::Kind; use crate::core::config::Target; +use crate::utils::exec::BootstrapCommand; use crate::utils::helpers::output; use crate::Build; @@ -352,7 +353,8 @@ than building it. // There are three builds of cmake on windows: MSVC, MinGW, and // Cygwin. The Cygwin build does not have generators for Visual // Studio, so detect that here and error. - let out = output(Command::new("cmake").arg("--help")); + let out = + build.run(BootstrapCommand::new("cmake").capture_stdout().arg("--help")).stdout(); if !out.contains("Visual Studio") { panic!( " diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs index ae3d18e8774bc..dfaa1e5eb1294 100644 --- a/src/bootstrap/src/lib.rs +++ b/src/bootstrap/src/lib.rs @@ -861,14 +861,16 @@ impl Build { if let Some(s) = target_config.and_then(|c| c.llvm_filecheck.as_ref()) { s.to_path_buf() } else if let Some(s) = target_config.and_then(|c| c.llvm_config.as_ref()) { - let llvm_bindir = output(Command::new(s).arg("--bindir")); + let llvm_bindir = + self.run(BootstrapCommand::new(s).capture_stdout().arg("--bindir")).stdout(); let filecheck = Path::new(llvm_bindir.trim()).join(exe("FileCheck", target)); if filecheck.exists() { filecheck } else { // On Fedora the system LLVM installs FileCheck in the // llvm subdirectory of the libdir. - let llvm_libdir = output(Command::new(s).arg("--libdir")); + let llvm_libdir = + self.run(BootstrapCommand::new(s).capture_stdout().arg("--libdir")).stdout(); let lib_filecheck = Path::new(llvm_libdir.trim()).join("llvm").join(exe("FileCheck", target)); if lib_filecheck.exists() { diff --git a/src/bootstrap/src/utils/cc_detect.rs b/src/bootstrap/src/utils/cc_detect.rs index 540b8671333a9..b80df54520264 100644 --- a/src/bootstrap/src/utils/cc_detect.rs +++ b/src/bootstrap/src/utils/cc_detect.rs @@ -23,11 +23,10 @@ use std::collections::HashSet; use std::path::{Path, PathBuf}; -use std::process::Command; use std::{env, iter}; use crate::core::config::TargetSelection; -use crate::utils::helpers::output; +use crate::utils::exec::BootstrapCommand; use crate::{Build, CLang, GitRepo}; // The `cc` crate doesn't provide a way to obtain a path to the detected archiver, @@ -183,14 +182,15 @@ fn default_compiler( return None; } - let output = output(c.to_command().arg("--version")); + let cmd = BootstrapCommand::from(c.to_command()); + let output = build.run(cmd.capture_stdout().arg("--version")).stdout(); let i = output.find(" 4.")?; match output[i + 3..].chars().next().unwrap() { '0'..='6' => {} _ => return None, } let alternative = format!("e{gnu_compiler}"); - if Command::new(&alternative).output().is_ok() { + if build.run(BootstrapCommand::new(&alternative).capture()).is_success() { Some(PathBuf::from(alternative)) } else { None diff --git a/src/bootstrap/src/utils/exec.rs b/src/bootstrap/src/utils/exec.rs index 5f9e164816179..bda6e0bfbac02 100644 --- a/src/bootstrap/src/utils/exec.rs +++ b/src/bootstrap/src/utils/exec.rs @@ -51,11 +51,7 @@ pub struct BootstrapCommand { impl BootstrapCommand { pub fn new>(program: S) -> Self { - Self { - command: Command::new(program), - failure_behavior: BehaviorOnFailure::Exit, - output_mode: OutputMode::Print, - } + Command::new(program).into() } pub fn arg>(&mut self, arg: S) -> &mut Self { @@ -130,6 +126,12 @@ impl AsMut for BootstrapCommand { } } +impl From for BootstrapCommand { + fn from(command: Command) -> Self { + Self { command, failure_behavior: BehaviorOnFailure::Exit, output_mode: OutputMode::Print } + } +} + /// Represents the output of an executed process. #[allow(unused)] pub struct CommandOutput(Output); diff --git a/src/bootstrap/src/utils/helpers.rs b/src/bootstrap/src/utils/helpers.rs index 9c40065dfc4fa..bbd4185874f4f 100644 --- a/src/bootstrap/src/utils/helpers.rs +++ b/src/bootstrap/src/utils/helpers.rs @@ -360,7 +360,7 @@ pub fn get_clang_cl_resource_dir(clang_cl_path: &str) -> PathBuf { /// Returns a flag that configures LLD to use only a single thread. /// If we use an external LLD, we need to find out which version is it to know which flag should we /// pass to it (LLD older than version 10 had a different flag). -fn lld_flag_no_threads(lld_mode: LldMode, is_windows: bool) -> &'static str { +fn lld_flag_no_threads(builder: &Builder<'_>, lld_mode: LldMode, is_windows: bool) -> &'static str { static LLD_NO_THREADS: OnceLock<(&'static str, &'static str)> = OnceLock::new(); let new_flags = ("/threads:1", "--threads=1"); @@ -369,7 +369,9 @@ fn lld_flag_no_threads(lld_mode: LldMode, is_windows: bool) -> &'static str { let (windows_flag, other_flag) = LLD_NO_THREADS.get_or_init(|| { let newer_version = match lld_mode { LldMode::External => { - let out = output(Command::new("lld").arg("-flavor").arg("ld").arg("--version")); + let mut cmd = BootstrapCommand::new("lld").capture_stdout(); + cmd.arg("-flavor").arg("ld").arg("--version"); + let out = builder.run(cmd).stdout(); match (out.find(char::is_numeric), out.find('.')) { (Some(b), Some(e)) => out.as_str()[b..e].parse::().ok().unwrap_or(14) > 10, _ => true, @@ -431,7 +433,7 @@ pub fn linker_flags( if matches!(lld_threads, LldThreads::No) { args.push(format!( "-Clink-arg=-Wl,{}", - lld_flag_no_threads(builder.config.lld_mode, target.is_windows()) + lld_flag_no_threads(builder, builder.config.lld_mode, target.is_windows()) )); } } From e8c8860142a999d086efe579e8e17df8437a9730 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Sat, 22 Jun 2024 17:54:44 +0200 Subject: [PATCH 638/892] Allow unused `Tool` variants --- src/bootstrap/src/core/build_steps/tool.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/bootstrap/src/core/build_steps/tool.rs b/src/bootstrap/src/core/build_steps/tool.rs index 40184e016a634..5fb282db90a7c 100644 --- a/src/bootstrap/src/core/build_steps/tool.rs +++ b/src/bootstrap/src/core/build_steps/tool.rs @@ -244,6 +244,7 @@ macro_rules! bootstrap_tool { ; )+) => { #[derive(PartialEq, Eq, Clone)] + #[allow(dead_code)] pub enum Tool { $( $name, From 60c20bfe0c6e34d36d9a40d835ce6946a10f0238 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Sat, 29 Jun 2024 16:00:23 +0200 Subject: [PATCH 639/892] Refactor command outcome handling To handle the case of failing to start a `BootstrapCommand`. --- src/bootstrap/src/core/sanity.rs | 15 ++++--- src/bootstrap/src/lib.rs | 77 +++++++++++++++++++------------- src/bootstrap/src/utils/exec.rs | 52 +++++++++++++++------ 3 files changed, 93 insertions(+), 51 deletions(-) diff --git a/src/bootstrap/src/core/sanity.rs b/src/bootstrap/src/core/sanity.rs index d64923e69cbd0..78862ccb8cd68 100644 --- a/src/bootstrap/src/core/sanity.rs +++ b/src/bootstrap/src/core/sanity.rs @@ -13,7 +13,6 @@ use std::env; use std::ffi::{OsStr, OsString}; use std::fs; use std::path::PathBuf; -use std::process::Command; #[cfg(not(feature = "bootstrap-self-test"))] use crate::builder::Builder; @@ -25,7 +24,6 @@ use std::collections::HashSet; use crate::builder::Kind; use crate::core::config::Target; use crate::utils::exec::BootstrapCommand; -use crate::utils::helpers::output; use crate::Build; pub struct Finder { @@ -210,11 +208,14 @@ than building it. .or_else(|| cmd_finder.maybe_have("reuse")); #[cfg(not(feature = "bootstrap-self-test"))] - let stage0_supported_target_list: HashSet = - output(Command::new(&build.config.initial_rustc).args(["--print", "target-list"])) - .lines() - .map(|s| s.to_string()) - .collect(); + let stage0_supported_target_list: HashSet = crate::utils::helpers::output( + &mut BootstrapCommand::new(&build.config.initial_rustc) + .args(["--print", "target-list"]) + .command, + ) + .lines() + .map(|s| s.to_string()) + .collect(); // We're gonna build some custom C code here and there, host triples // also build some C++ shims for LLVM so we need a C++ compiler. diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs index dfaa1e5eb1294..309fec474a14b 100644 --- a/src/bootstrap/src/lib.rs +++ b/src/bootstrap/src/lib.rs @@ -23,14 +23,13 @@ use std::fmt::Display; use std::fs::{self, File}; use std::io; use std::path::{Path, PathBuf}; -use std::process::{Command, Stdio}; +use std::process::{Command, Output, Stdio}; use std::str; use std::sync::OnceLock; use std::time::SystemTime; use build_helper::ci::{gha, CiEnv}; use build_helper::exit; -use build_helper::util::fail; use filetime::FileTime; use sha2::digest::Digest; use termcolor::{ColorChoice, StandardStream, WriteColor}; @@ -945,43 +944,61 @@ impl Build { self.verbose(|| println!("running: {command:?}")); - let output: io::Result = match command.output_mode { - OutputMode::Print => command.command.status().map(|status| status.into()), - OutputMode::CaptureAll => command.command.output().map(|o| o.into()), + let output: io::Result = match command.output_mode { + OutputMode::Print => command.command.status().map(|status| Output { + status, + stdout: vec![], + stderr: vec![], + }), + OutputMode::CaptureAll => command.command.output(), OutputMode::CaptureStdout => { command.command.stderr(Stdio::inherit()); - command.command.output().map(|o| o.into()) + command.command.output() } }; - let output = match output { - Ok(output) => output, - Err(e) => fail(&format!("failed to execute command: {command:?}\nerror: {e}")), - }; - if !output.is_success() { - use std::fmt::Write; - - // Here we build an error message, and below we decide if it should be printed or not. - let mut message = String::new(); - writeln!( - message, - "\n\nCommand {command:?} did not execute successfully.\ + use std::fmt::Write; + + let mut message = String::new(); + let output: CommandOutput = match output { + // Command has succeeded + Ok(output) if output.status.success() => output.into(), + // Command has started, but then it failed + Ok(output) => { + writeln!( + message, + "\n\nCommand {command:?} did not execute successfully.\ \nExpected success, got: {}", - output.status(), - ) - .unwrap(); - - // If the output mode is OutputMode::Print, the output has already been printed to - // stdout/stderr, and we thus don't have anything captured to print anyway. - if matches!(command.output_mode, OutputMode::CaptureAll | OutputMode::CaptureStdout) { - writeln!(message, "\nSTDOUT ----\n{}", output.stdout().trim()).unwrap(); + output.status, + ) + .unwrap(); + + let output: CommandOutput = output.into(); + // If the output mode is OutputMode::Print, the output has already been printed to + // stdout/stderr, and we thus don't have anything captured to print anyway. + if matches!(command.output_mode, OutputMode::CaptureAll | OutputMode::CaptureStdout) + { + writeln!(message, "\nSTDOUT ----\n{}", output.stdout().trim()).unwrap(); - // Stderr is added to the message only if it was captured - if matches!(command.output_mode, OutputMode::CaptureAll) { - writeln!(message, "\nSTDERR ----\n{}", output.stderr().trim()).unwrap(); + // Stderr is added to the message only if it was captured + if matches!(command.output_mode, OutputMode::CaptureAll) { + writeln!(message, "\nSTDERR ----\n{}", output.stderr().trim()).unwrap(); + } } + output } - + // The command did not even start + Err(e) => { + writeln!( + message, + "\n\nCommand {command:?} did not execute successfully.\ + \nIt was not possible to execute the command: {e:?}" + ) + .unwrap(); + CommandOutput::did_not_start() + } + }; + if !output.is_success() { match command.failure_behavior { BehaviorOnFailure::DelayFail => { if self.fail_fast { diff --git a/src/bootstrap/src/utils/exec.rs b/src/bootstrap/src/utils/exec.rs index bda6e0bfbac02..78a3b917e459a 100644 --- a/src/bootstrap/src/utils/exec.rs +++ b/src/bootstrap/src/utils/exec.rs @@ -132,25 +132,47 @@ impl From for BootstrapCommand { } } +/// Represents the outcome of starting a command. +enum CommandOutcome { + /// The command has started and finished with some status. + Finished(ExitStatus), + /// It was not even possible to start the command. + DidNotStart, +} + /// Represents the output of an executed process. #[allow(unused)] -pub struct CommandOutput(Output); +pub struct CommandOutput { + outcome: CommandOutcome, + stdout: Vec, + stderr: Vec, +} impl CommandOutput { + pub fn did_not_start() -> Self { + Self { outcome: CommandOutcome::DidNotStart, stdout: vec![], stderr: vec![] } + } + pub fn is_success(&self) -> bool { - self.0.status.success() + match self.outcome { + CommandOutcome::Finished(status) => status.success(), + CommandOutcome::DidNotStart => false, + } } pub fn is_failure(&self) -> bool { !self.is_success() } - pub fn status(&self) -> ExitStatus { - self.0.status + pub fn status(&self) -> Option { + match self.outcome { + CommandOutcome::Finished(status) => Some(status), + CommandOutcome::DidNotStart => None, + } } pub fn stdout(&self) -> String { - String::from_utf8(self.0.stdout.clone()).expect("Cannot parse process stdout as UTF-8") + String::from_utf8(self.stdout.clone()).expect("Cannot parse process stdout as UTF-8") } pub fn stdout_if_ok(&self) -> Option { @@ -158,24 +180,26 @@ impl CommandOutput { } pub fn stderr(&self) -> String { - String::from_utf8(self.0.stderr.clone()).expect("Cannot parse process stderr as UTF-8") + String::from_utf8(self.stderr.clone()).expect("Cannot parse process stderr as UTF-8") } } impl Default for CommandOutput { fn default() -> Self { - Self(Output { status: Default::default(), stdout: vec![], stderr: vec![] }) + Self { + outcome: CommandOutcome::Finished(ExitStatus::default()), + stdout: vec![], + stderr: vec![], + } } } impl From for CommandOutput { fn from(output: Output) -> Self { - Self(output) - } -} - -impl From for CommandOutput { - fn from(status: ExitStatus) -> Self { - Self(Output { status, stdout: vec![], stderr: vec![] }) + Self { + outcome: CommandOutcome::Finished(output.status), + stdout: output.stdout, + stderr: output.stderr, + } } } From 70b6e044523b0a2bc89b748a389c04277b5b9da1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Sat, 29 Jun 2024 22:07:59 +0200 Subject: [PATCH 640/892] Handle execution of dry run commands --- src/bootstrap/src/core/build_steps/perf.rs | 1 - src/bootstrap/src/core/build_steps/test.rs | 8 +++++++- src/bootstrap/src/core/metadata.rs | 3 +-- src/bootstrap/src/lib.rs | 5 ++--- src/bootstrap/src/utils/exec.rs | 14 +++++++++++++- 5 files changed, 23 insertions(+), 8 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/perf.rs b/src/bootstrap/src/core/build_steps/perf.rs index 20ab1836e0068..f41b5fe10f1d9 100644 --- a/src/bootstrap/src/core/build_steps/perf.rs +++ b/src/bootstrap/src/core/build_steps/perf.rs @@ -2,7 +2,6 @@ use crate::core::build_steps::compile::{Std, Sysroot}; use crate::core::build_steps::tool::{RustcPerf, Tool}; use crate::core::builder::Builder; use crate::core::config::DebuginfoLevel; -use crate::utils::exec::BootstrapCommand; /// Performs profiling using `rustc-perf` on a built version of the compiler. pub fn perf(builder: &Builder<'_>) { diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index b063d0aaf4f16..998e45848a1c3 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -1805,7 +1805,13 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the let lldb_exe = builder.config.lldb.clone().unwrap_or_else(|| PathBuf::from("lldb")); let lldb_version = builder - .run(BootstrapCommand::new(&lldb_exe).capture().allow_failure().arg("--version")) + .run( + BootstrapCommand::new(&lldb_exe) + .capture() + .allow_failure() + .run_always() + .arg("--version"), + ) .stdout_if_ok(); if let Some(ref vers) = lldb_version { cmd.arg("--lldb-version").arg(vers); diff --git a/src/bootstrap/src/core/metadata.rs b/src/bootstrap/src/core/metadata.rs index da269959e7b43..49d17107125aa 100644 --- a/src/bootstrap/src/core/metadata.rs +++ b/src/bootstrap/src/core/metadata.rs @@ -81,8 +81,7 @@ fn workspace_members(build: &Build) -> Vec { .arg("--no-deps") .arg("--manifest-path") .arg(build.src.join(manifest_path)); - // FIXME: fix stderr - let metadata_output = build.run(cargo.capture()).stdout(); + let metadata_output = build.run(cargo.capture_stdout().run_always()).stdout(); let Output { packages, .. } = t!(serde_json::from_str(&metadata_output)); packages }; diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs index 309fec474a14b..ce139a0bc59df 100644 --- a/src/bootstrap/src/lib.rs +++ b/src/bootstrap/src/lib.rs @@ -936,12 +936,11 @@ impl Build { /// Execute a command and return its output. /// This method should be used for all command executions in bootstrap. fn run>(&self, mut command: C) -> CommandOutput { - if self.config.dry_run() { + let command = command.as_mut(); + if self.config.dry_run() && !command.run_always { return CommandOutput::default(); } - let command = command.as_mut(); - self.verbose(|| println!("running: {command:?}")); let output: io::Result = match command.output_mode { diff --git a/src/bootstrap/src/utils/exec.rs b/src/bootstrap/src/utils/exec.rs index 78a3b917e459a..98d194e64d3ab 100644 --- a/src/bootstrap/src/utils/exec.rs +++ b/src/bootstrap/src/utils/exec.rs @@ -47,6 +47,8 @@ pub struct BootstrapCommand { pub command: Command, pub failure_behavior: BehaviorOnFailure, pub output_mode: OutputMode, + // Run the command even during dry run + pub run_always: bool, } impl BootstrapCommand { @@ -107,6 +109,11 @@ impl BootstrapCommand { Self { failure_behavior: BehaviorOnFailure::Ignore, ..self } } + pub fn run_always(&mut self) -> &mut Self { + self.run_always = true; + self + } + /// Capture the output of the command, do not print it. pub fn capture(self) -> Self { Self { output_mode: OutputMode::CaptureAll, ..self } @@ -128,7 +135,12 @@ impl AsMut for BootstrapCommand { impl From for BootstrapCommand { fn from(command: Command) -> Self { - Self { command, failure_behavior: BehaviorOnFailure::Exit, output_mode: OutputMode::Print } + Self { + command, + failure_behavior: BehaviorOnFailure::Exit, + output_mode: OutputMode::Print, + run_always: false, + } } } From b90129dd21edb7492c7c4fc58883e849be8deff7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Wed, 3 Jul 2024 11:33:43 +0200 Subject: [PATCH 641/892] Review changes --- src/bootstrap/src/utils/exec.rs | 27 +++++++++++++-------------- src/bootstrap/src/utils/helpers.rs | 9 +++++---- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/bootstrap/src/utils/exec.rs b/src/bootstrap/src/utils/exec.rs index 98d194e64d3ab..74fb483773e3a 100644 --- a/src/bootstrap/src/utils/exec.rs +++ b/src/bootstrap/src/utils/exec.rs @@ -34,8 +34,7 @@ pub enum OutputMode { /// If you want to allow failures, use [allow_failure]. /// If you want to delay failures until the end of bootstrap, use [delay_failure]. /// -/// By default, the command will print its stdout/stderr to stdout/stderr of bootstrap -/// ([OutputMode::Print]). +/// By default, the command will print its stdout/stderr to stdout/stderr of bootstrap ([OutputMode::Print]). /// If you want to handle the output programmatically, use [BootstrapCommand::capture]. /// /// Bootstrap will print a debug log to stdout if the command fails and failure is not allowed. @@ -144,8 +143,8 @@ impl From for BootstrapCommand { } } -/// Represents the outcome of starting a command. -enum CommandOutcome { +/// Represents the current status of `BootstrapCommand`. +enum CommandStatus { /// The command has started and finished with some status. Finished(ExitStatus), /// It was not even possible to start the command. @@ -155,20 +154,20 @@ enum CommandOutcome { /// Represents the output of an executed process. #[allow(unused)] pub struct CommandOutput { - outcome: CommandOutcome, + status: CommandStatus, stdout: Vec, stderr: Vec, } impl CommandOutput { pub fn did_not_start() -> Self { - Self { outcome: CommandOutcome::DidNotStart, stdout: vec![], stderr: vec![] } + Self { status: CommandStatus::DidNotStart, stdout: vec![], stderr: vec![] } } pub fn is_success(&self) -> bool { - match self.outcome { - CommandOutcome::Finished(status) => status.success(), - CommandOutcome::DidNotStart => false, + match self.status { + CommandStatus::Finished(status) => status.success(), + CommandStatus::DidNotStart => false, } } @@ -177,9 +176,9 @@ impl CommandOutput { } pub fn status(&self) -> Option { - match self.outcome { - CommandOutcome::Finished(status) => Some(status), - CommandOutcome::DidNotStart => None, + match self.status { + CommandStatus::Finished(status) => Some(status), + CommandStatus::DidNotStart => None, } } @@ -199,7 +198,7 @@ impl CommandOutput { impl Default for CommandOutput { fn default() -> Self { Self { - outcome: CommandOutcome::Finished(ExitStatus::default()), + status: CommandStatus::Finished(ExitStatus::default()), stdout: vec![], stderr: vec![], } @@ -209,7 +208,7 @@ impl Default for CommandOutput { impl From for CommandOutput { fn from(output: Output) -> Self { Self { - outcome: CommandOutcome::Finished(output.status), + status: CommandStatus::Finished(output.status), stdout: output.stdout, stderr: output.stderr, } diff --git a/src/bootstrap/src/utils/helpers.rs b/src/bootstrap/src/utils/helpers.rs index bbd4185874f4f..2575b7939b44c 100644 --- a/src/bootstrap/src/utils/helpers.rs +++ b/src/bootstrap/src/utils/helpers.rs @@ -494,12 +494,13 @@ pub fn check_cfg_arg(name: &str, values: Option<&[&str]>) -> String { format!("--check-cfg=cfg({name}{next})") } -/// Prepares `Command` that runs git inside the source directory if given. +/// Prepares `BootstrapCommand` that runs git inside the source directory if given. /// /// Whenever a git invocation is needed, this function should be preferred over -/// manually building a git `Command`. This approach allows us to manage bootstrap-specific -/// needs/hacks from a single source, rather than applying them on next to every `Command::new("git")`, -/// which is painful to ensure that the required change is applied on each one of them correctly. +/// manually building a git `BootstrapCommand`. This approach allows us to manage +/// bootstrap-specific needs/hacks from a single source, rather than applying them on next to every +/// `BootstrapCommand::new("git")`, which is painful to ensure that the required change is applied +/// on each one of them correctly. pub fn git(source_dir: Option<&Path>) -> BootstrapCommand { let mut git = BootstrapCommand::new("git"); From b618fea358147080a27f3984a3be078f8b49e519 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Wed, 3 Jul 2024 21:04:02 +0200 Subject: [PATCH 642/892] Simplify and generalize implementation of output mode --- src/bootstrap/src/lib.rs | 35 ++++++++++--------------- src/bootstrap/src/utils/exec.rs | 45 +++++++++++++++++++++------------ 2 files changed, 42 insertions(+), 38 deletions(-) diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs index ce139a0bc59df..ffdd9bc885a62 100644 --- a/src/bootstrap/src/lib.rs +++ b/src/bootstrap/src/lib.rs @@ -23,7 +23,7 @@ use std::fmt::Display; use std::fs::{self, File}; use std::io; use std::path::{Path, PathBuf}; -use std::process::{Command, Output, Stdio}; +use std::process::{Command, Stdio}; use std::str; use std::sync::OnceLock; use std::time::SystemTime; @@ -41,7 +41,7 @@ use crate::core::builder::Kind; use crate::core::config::{flags, LldMode}; use crate::core::config::{DryRun, Target}; use crate::core::config::{LlvmLibunwind, TargetSelection}; -use crate::utils::exec::{BehaviorOnFailure, BootstrapCommand, CommandOutput, OutputMode}; +use crate::utils::exec::{BehaviorOnFailure, BootstrapCommand, CommandOutput}; use crate::utils::helpers::{self, dir_is_empty, exe, libdir, mtime, output, symlink_dir}; mod core; @@ -943,18 +943,10 @@ impl Build { self.verbose(|| println!("running: {command:?}")); - let output: io::Result = match command.output_mode { - OutputMode::Print => command.command.status().map(|status| Output { - status, - stdout: vec![], - stderr: vec![], - }), - OutputMode::CaptureAll => command.command.output(), - OutputMode::CaptureStdout => { - command.command.stderr(Stdio::inherit()); - command.command.output() - } - }; + command.command.stdout(command.stdout.stdio()); + command.command.stderr(command.stderr.stdio()); + + let output = command.command.output(); use std::fmt::Write; @@ -973,16 +965,15 @@ impl Build { .unwrap(); let output: CommandOutput = output.into(); - // If the output mode is OutputMode::Print, the output has already been printed to + + // If the output mode is OutputMode::Capture, we can now print the output. + // If it is OutputMode::Print, then the output has already been printed to // stdout/stderr, and we thus don't have anything captured to print anyway. - if matches!(command.output_mode, OutputMode::CaptureAll | OutputMode::CaptureStdout) - { + if command.stdout.captures() { writeln!(message, "\nSTDOUT ----\n{}", output.stdout().trim()).unwrap(); - - // Stderr is added to the message only if it was captured - if matches!(command.output_mode, OutputMode::CaptureAll) { - writeln!(message, "\nSTDERR ----\n{}", output.stderr().trim()).unwrap(); - } + } + if command.stderr.captures() { + writeln!(message, "\nSTDERR ----\n{}", output.stderr().trim()).unwrap(); } output } diff --git a/src/bootstrap/src/utils/exec.rs b/src/bootstrap/src/utils/exec.rs index 74fb483773e3a..086d10c63511a 100644 --- a/src/bootstrap/src/utils/exec.rs +++ b/src/bootstrap/src/utils/exec.rs @@ -1,6 +1,6 @@ use std::ffi::OsStr; use std::path::Path; -use std::process::{Command, CommandArgs, CommandEnvs, ExitStatus, Output}; +use std::process::{Command, CommandArgs, CommandEnvs, ExitStatus, Output, Stdio}; /// What should be done when the command fails. #[derive(Debug, Copy, Clone)] @@ -13,19 +13,30 @@ pub enum BehaviorOnFailure { Ignore, } -/// How should the output of the command be handled (whether it should be captured or printed). +/// How should the output of a specific stream of the command (stdout/stderr) be handled +/// (whether it should be captured or printed). #[derive(Debug, Copy, Clone)] pub enum OutputMode { - /// Prints the stdout/stderr of the command to stdout/stderr of bootstrap (by inheriting these - /// streams). - /// Corresponds to calling `cmd.status()`. + /// Prints the stream by inheriting it from the bootstrap process. Print, - /// Captures the stdout and stderr of the command into memory. - /// Corresponds to calling `cmd.output()`. - CaptureAll, - /// Captures the stdout of the command into memory, inherits stderr. - /// Corresponds to calling `cmd.output()`. - CaptureStdout, + /// Captures the stream into memory. + Capture, +} + +impl OutputMode { + pub fn captures(&self) -> bool { + match self { + OutputMode::Print => false, + OutputMode::Capture => true, + } + } + + pub fn stdio(&self) -> Stdio { + match self { + OutputMode::Print => Stdio::inherit(), + OutputMode::Capture => Stdio::piped(), + } + } } /// Wrapper around `std::process::Command`. @@ -45,7 +56,8 @@ pub enum OutputMode { pub struct BootstrapCommand { pub command: Command, pub failure_behavior: BehaviorOnFailure, - pub output_mode: OutputMode, + pub stdout: OutputMode, + pub stderr: OutputMode, // Run the command even during dry run pub run_always: bool, } @@ -113,14 +125,14 @@ impl BootstrapCommand { self } - /// Capture the output of the command, do not print it. + /// Capture all output of the command, do not print it. pub fn capture(self) -> Self { - Self { output_mode: OutputMode::CaptureAll, ..self } + Self { stdout: OutputMode::Capture, stderr: OutputMode::Capture, ..self } } /// Capture stdout of the command, do not print it. pub fn capture_stdout(self) -> Self { - Self { output_mode: OutputMode::CaptureStdout, ..self } + Self { stdout: OutputMode::Capture, ..self } } } @@ -137,7 +149,8 @@ impl From for BootstrapCommand { Self { command, failure_behavior: BehaviorOnFailure::Exit, - output_mode: OutputMode::Print, + stdout: OutputMode::Print, + stderr: OutputMode::Print, run_always: false, } } From 54952b444566956b12058162eae383c692da0147 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Wed, 3 Jul 2024 21:14:46 +0200 Subject: [PATCH 643/892] Rebase on master --- src/bootstrap/src/utils/tarball.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/bootstrap/src/utils/tarball.rs b/src/bootstrap/src/utils/tarball.rs index 3c15bb296f39a..1a35dc1fd3896 100644 --- a/src/bootstrap/src/utils/tarball.rs +++ b/src/bootstrap/src/utils/tarball.rs @@ -370,7 +370,11 @@ impl<'a> Tarball<'a> { if self.builder.rust_info().is_managed_git_subrepository() { // %ct means committer date let timestamp = helpers::output( - helpers::git(Some(&self.builder.src)).arg("log").arg("-1").arg("--format=%ct"), + &mut helpers::git(Some(&self.builder.src)) + .arg("log") + .arg("-1") + .arg("--format=%ct") + .command, ); cmd.args(["--override-file-mtime", timestamp.trim()]); } From ccc8baf08aa5a204a7df55e67022aa6c5254966c Mon Sep 17 00:00:00 2001 From: Alona Enraght-Moony Date: Wed, 3 Jul 2024 19:38:19 +0000 Subject: [PATCH 644/892] jsondocck: Use correct index for error message. If you misused a count command like `@count $some.selector '"T'"`, you would panic with OOB: ``` thread 'main' panicked at src/tools/jsondocck/src/main.rs:76:92: index out of bounds: the len is 2 but the index is 2 ``` Fixing this typo, we now get. ``` Invalid command: Second argument to @count must be a valid usize (got `"T"`) on line 20 ``` As some point I want to rewrite this code to avoid indexing in general, but this is a nice small fix. --- src/tools/jsondocck/src/main.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/tools/jsondocck/src/main.rs b/src/tools/jsondocck/src/main.rs index 688b403bf0e0a..429c6151796fe 100644 --- a/src/tools/jsondocck/src/main.rs +++ b/src/tools/jsondocck/src/main.rs @@ -56,6 +56,8 @@ pub enum CommandKind { impl CommandKind { fn validate(&self, args: &[String], lineno: usize) -> bool { + // FIXME(adotinthevoid): We should "parse, don't validate" here, so we avoid ad-hoc + // indexing in check_command. let count = match self { CommandKind::Has => (1..=2).contains(&args.len()), CommandKind::IsMany => args.len() >= 2, @@ -71,7 +73,7 @@ impl CommandKind { if let CommandKind::Count = self { if args[1].parse::().is_err() { print_err( - &format!("Second argument to @count must be a valid usize (got `{}`)", args[2]), + &format!("Second argument to @count must be a valid usize (got `{}`)", args[1]), lineno, ); return false; From 7e8aac553e756b0eb03fe98e1a65ffc47836ec51 Mon Sep 17 00:00:00 2001 From: Alona Enraght-Moony Date: Wed, 3 Jul 2024 19:57:15 +0000 Subject: [PATCH 645/892] rustdoc-json: Better representation of lifetime bounds in where clauses. As suggested [on zulip][1], there's no need to use `GenericBound` here, as the only bound a lifetime can have is that it outlives other lifetimes. While we're making breaking changes here, I also renamed it from using "region" to "lifetime", as this is more user-aligned. See [this comment][2] for details. [1]: https://rust-lang.zulipchat.com/#narrow/stream/266220-t-rustdoc/topic/.60ItemEnum.3A.3AOpaqueTy.60/near/448871430 [2]: https://github.com/rust-lang/rust/issues/100961#issuecomment-2206565556 --- src/librustdoc/clean/types.rs | 2 +- src/librustdoc/json/conversions.rs | 11 +++++++-- src/rustdoc-json-types/lib.rs | 6 ++--- src/tools/jsondoclint/src/validator.rs | 4 ++-- .../lifetime/outlives_in_param.rs | 8 +++++++ .../lifetime/outlives_in_where.rs | 24 +++++++++++++++++++ 6 files changed, 47 insertions(+), 8 deletions(-) create mode 100644 tests/rustdoc-json/lifetime/outlives_in_param.rs create mode 100644 tests/rustdoc-json/lifetime/outlives_in_where.rs diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 9050a1c12078b..6aa3da2719a80 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -1286,7 +1286,7 @@ impl GenericBound { } } -#[derive(Clone, PartialEq, Eq, Debug, Hash)] +#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)] pub(crate) struct Lifetime(pub Symbol); impl Lifetime { diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs index b965ab019cc4f..5111e363c522e 100644 --- a/src/librustdoc/json/conversions.rs +++ b/src/librustdoc/json/conversions.rs @@ -10,6 +10,7 @@ use rustc_ast::ast; use rustc_attr::DeprecatedSince; use rustc_hir::{def::CtorKind, def::DefKind, def_id::DefId}; use rustc_metadata::rendered_const; +use rustc_middle::bug; use rustc_middle::ty::{self, TyCtxt}; use rustc_span::symbol::sym; use rustc_span::{Pos, Symbol}; @@ -512,9 +513,15 @@ impl FromWithTcx for WherePredicate { }) .collect(), }, - RegionPredicate { lifetime, bounds } => WherePredicate::RegionPredicate { + RegionPredicate { lifetime, bounds } => WherePredicate::LifetimePredicate { lifetime: convert_lifetime(lifetime), - bounds: bounds.into_tcx(tcx), + outlives: bounds + .iter() + .map(|bound| match bound { + clean::GenericBound::Outlives(lt) => convert_lifetime(*lt), + _ => bug!("found non-outlives-bound on lifetime predicate"), + }) + .collect(), }, EqPredicate { lhs, rhs } => { WherePredicate::EqPredicate { lhs: lhs.into_tcx(tcx), rhs: rhs.into_tcx(tcx) } diff --git a/src/rustdoc-json-types/lib.rs b/src/rustdoc-json-types/lib.rs index 68030493e9cfd..89115d4d7d667 100644 --- a/src/rustdoc-json-types/lib.rs +++ b/src/rustdoc-json-types/lib.rs @@ -8,7 +8,7 @@ use serde::{Deserialize, Serialize}; use std::path::PathBuf; /// rustdoc format-version. -pub const FORMAT_VERSION: u32 = 30; +pub const FORMAT_VERSION: u32 = 31; /// A `Crate` is the root of the emitted JSON blob. It contains all type/documentation information /// about the language items in the local crate, as well as info about external items to allow @@ -511,9 +511,9 @@ pub enum WherePredicate { /// ``` generic_params: Vec, }, - RegionPredicate { + LifetimePredicate { lifetime: String, - bounds: Vec, + outlives: Vec, }, EqPredicate { lhs: Type, diff --git a/src/tools/jsondoclint/src/validator.rs b/src/tools/jsondoclint/src/validator.rs index 1713a4d812c4b..cd011dce7844e 100644 --- a/src/tools/jsondoclint/src/validator.rs +++ b/src/tools/jsondoclint/src/validator.rs @@ -374,8 +374,8 @@ impl<'a> Validator<'a> { bounds.iter().for_each(|b| self.check_generic_bound(b)); generic_params.iter().for_each(|gpd| self.check_generic_param_def(gpd)); } - WherePredicate::RegionPredicate { lifetime: _, bounds } => { - bounds.iter().for_each(|b| self.check_generic_bound(b)); + WherePredicate::LifetimePredicate { lifetime: _, outlives: _ } => { + // nop, all strings. } WherePredicate::EqPredicate { lhs, rhs } => { self.check_type(lhs); diff --git a/tests/rustdoc-json/lifetime/outlives_in_param.rs b/tests/rustdoc-json/lifetime/outlives_in_param.rs new file mode 100644 index 0000000000000..f6db93c918329 --- /dev/null +++ b/tests/rustdoc-json/lifetime/outlives_in_param.rs @@ -0,0 +1,8 @@ +// ignore-tidy-linelength + +// @count '$.index[*][?(@.name=="outlives")].inner.function.generics.params[*]' 2 +// @is '$.index[*][?(@.name=="outlives")].inner.function.generics.params[0].name' \"\'a\" +// @is '$.index[*][?(@.name=="outlives")].inner.function.generics.params[0].kind.lifetime.outlives' [] +// @is '$.index[*][?(@.name=="outlives")].inner.function.generics.params[1].name' '"T"' +// @is '$.index[*][?(@.name=="outlives")].inner.function.generics.params[1].kind.type.bounds' '[{"outlives": "'\''a"}]' +pub fn outlives<'a, T: 'a>() {} diff --git a/tests/rustdoc-json/lifetime/outlives_in_where.rs b/tests/rustdoc-json/lifetime/outlives_in_where.rs new file mode 100644 index 0000000000000..ca3e1a150ce8e --- /dev/null +++ b/tests/rustdoc-json/lifetime/outlives_in_where.rs @@ -0,0 +1,24 @@ +// ignore-tidy-linelength + +// @is '$.index[*][?(@.name=="on_lifetimes")].inner.function.generics.where_predicates' '[{"lifetime_predicate": {"lifetime": "'\''all", "outlives": ["'\''a", "'\''b", "'\''c"]}}]' +pub fn on_lifetimes<'a, 'b, 'c, 'all>() +where + 'all: 'a + 'b + 'c, +{ +} + +// @count '$.index[*][?(@.name=="on_trait")].inner.function.generics.params[*]' 2 +// @is '$.index[*][?(@.name=="on_trait")].inner.function.generics.params[0].name' \"\'a\" +// @is '$.index[*][?(@.name=="on_trait")].inner.function.generics.params[0].kind.lifetime.outlives' [] +// @is '$.index[*][?(@.name=="on_trait")].inner.function.generics.params[1].name' '"T"' +// @is '$.index[*][?(@.name=="on_trait")].inner.function.generics.params[1].kind.type.bounds' [] +// @is '$.index[*][?(@.name=="on_trait")].inner.function.generics.params[1].kind.type.bounds' [] +// @count '$.index[*][?(@.name=="on_trait")].inner.function.generics.where_predicates[*]' 1 +// @is '$.index[*][?(@.name=="on_trait")].inner.function.generics.where_predicates[0].bound_predicate.type.generic' '"T"' +// @count '$.index[*][?(@.name=="on_trait")].inner.function.generics.where_predicates[0].bound_predicate.bounds[*]' 1 +// @is '$.index[*][?(@.name=="on_trait")].inner.function.generics.where_predicates[0].bound_predicate.bounds[0].outlives' \"\'a\" +pub fn on_trait<'a, T>() +where + T: 'a, +{ +} From 529a3f4ce609f4bc98215185838351d9815fbdc1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Wed, 3 Jul 2024 19:36:14 +0000 Subject: [PATCH 646/892] cache type sizes in type-size limit visitor --- compiler/rustc_middle/src/ty/instance.rs | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs index ae54411d788ab..c50a98e88fd63 100644 --- a/compiler/rustc_middle/src/ty/instance.rs +++ b/compiler/rustc_middle/src/ty/instance.rs @@ -5,6 +5,7 @@ use crate::ty::{ self, EarlyBinder, GenericArgs, GenericArgsRef, Ty, TyCtxt, TypeFoldable, TypeSuperFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, }; +use rustc_data_structures::fx::FxHashMap; use rustc_errors::ErrorGuaranteed; use rustc_hir as hir; use rustc_hir::def::Namespace; @@ -388,13 +389,25 @@ impl<'tcx> InstanceKind<'tcx> { } fn type_length<'tcx>(item: impl TypeVisitable>) -> usize { - struct Visitor { + struct Visitor<'tcx> { type_length: usize, + cache: FxHashMap, usize>, } - impl<'tcx> TypeVisitor> for Visitor { + impl<'tcx> TypeVisitor> for Visitor<'tcx> { fn visit_ty(&mut self, t: Ty<'tcx>) { + if let Some(&value) = self.cache.get(&t) { + self.type_length += value; + return; + } + + let prev = self.type_length; self.type_length += 1; t.super_visit_with(self); + + // We don't try to use the cache if the type is fairly small. + if self.type_length > 16 { + self.cache.insert(t, self.type_length - prev); + } } fn visit_const(&mut self, ct: ty::Const<'tcx>) { @@ -402,7 +415,7 @@ fn type_length<'tcx>(item: impl TypeVisitable>) -> usize { ct.super_visit_with(self); } } - let mut visitor = Visitor { type_length: 0 }; + let mut visitor = Visitor { type_length: 0, cache: Default::default() }; item.visit_with(&mut visitor); visitor.type_length From a7372372f6c3b81804c2b83f2a0e9c0bc7d08e13 Mon Sep 17 00:00:00 2001 From: Zanie Blue Date: Tue, 2 Jul 2024 19:50:39 -0500 Subject: [PATCH 647/892] Add test case demonstrating equality of paths "foo/bar" and "foobar" --- library/std/src/path/tests.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/library/std/src/path/tests.rs b/library/std/src/path/tests.rs index 92702b395dfe1..53a65c60b580c 100644 --- a/library/std/src/path/tests.rs +++ b/library/std/src/path/tests.rs @@ -1566,6 +1566,13 @@ pub fn test_compare() { relative_from: Some("bar") ); + tc!("foo/bar", "foobar", + eq: false, + starts_with: false, + ends_with: false, + relative_from: None + ); + tc!("foo/bar/baz", "foo/bar", eq: false, starts_with: true, From dd509c7a6399f2784fa940d27a9f463da7e81d58 Mon Sep 17 00:00:00 2001 From: Zanie Blue Date: Tue, 2 Jul 2024 23:12:06 -0500 Subject: [PATCH 648/892] Add more test cases for path comparisons --- library/std/src/path/tests.rs | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/library/std/src/path/tests.rs b/library/std/src/path/tests.rs index 53a65c60b580c..87a06a9ea9153 100644 --- a/library/std/src/path/tests.rs +++ b/library/std/src/path/tests.rs @@ -1545,6 +1545,20 @@ pub fn test_compare() { relative_from: Some("") ); + tc!("foo//", "foo", + eq: true, + starts_with: true, + ends_with: true, + relative_from: Some("") + ); + + tc!("foo///", "foo", + eq: true, + starts_with: true, + ends_with: true, + relative_from: Some("") + ); + tc!("foo/.", "foo", eq: true, starts_with: true, @@ -1559,6 +1573,20 @@ pub fn test_compare() { relative_from: Some("") ); + tc!("foo/.//bar", "foo/bar", + eq: true, + starts_with: true, + ends_with: true, + relative_from: Some("") + ); + + tc!("foo//./bar", "foo/bar", + eq: true, + starts_with: true, + ends_with: true, + relative_from: Some("") + ); + tc!("foo/bar", "foo", eq: false, starts_with: true, From a9194f30eb5b80bd659f3f8e8357fd19b771063e Mon Sep 17 00:00:00 2001 From: Liu Dingming Date: Thu, 4 Jul 2024 04:52:01 +0800 Subject: [PATCH 649/892] Use `IndexVec` for coroutine local mapping --- compiler/rustc_index/src/vec.rs | 5 +++ compiler/rustc_mir_transform/src/coroutine.rs | 35 +++++++++---------- 2 files changed, 21 insertions(+), 19 deletions(-) diff --git a/compiler/rustc_index/src/vec.rs b/compiler/rustc_index/src/vec.rs index 88298150a79dc..b866c8b8433d9 100644 --- a/compiler/rustc_index/src/vec.rs +++ b/compiler/rustc_index/src/vec.rs @@ -208,6 +208,11 @@ impl IndexVec> { pub fn remove(&mut self, index: I) -> Option { self.get_mut(index)?.take() } + + #[inline] + pub fn contains(&self, index: I) -> bool { + self.get(index).and_then(Option::as_ref).is_some() + } } impl fmt::Debug for IndexVec { diff --git a/compiler/rustc_mir_transform/src/coroutine.rs b/compiler/rustc_mir_transform/src/coroutine.rs index 05674792426f1..41c9c55cef595 100644 --- a/compiler/rustc_mir_transform/src/coroutine.rs +++ b/compiler/rustc_mir_transform/src/coroutine.rs @@ -58,7 +58,7 @@ use crate::deref_separator::deref_finder; use crate::errors; use crate::pass_manager as pm; use crate::simplify; -use rustc_data_structures::fx::{FxHashMap, FxHashSet}; +use rustc_data_structures::fx::FxHashSet; use rustc_errors::pluralize; use rustc_hir as hir; use rustc_hir::lang_items::LangItem; @@ -236,8 +236,7 @@ struct TransformVisitor<'tcx> { discr_ty: Ty<'tcx>, // Mapping from Local to (type of local, coroutine struct index) - // FIXME(eddyb) This should use `IndexVec>`. - remap: FxHashMap, VariantIdx, FieldIdx)>, + remap: IndexVec, VariantIdx, FieldIdx)>>, // A map from a suspension point in a block to the locals which have live storage at that point storage_liveness: IndexVec>>, @@ -485,7 +484,7 @@ impl<'tcx> MutVisitor<'tcx> for TransformVisitor<'tcx> { } fn visit_local(&mut self, local: &mut Local, _: PlaceContext, _: Location) { - assert_eq!(self.remap.get(local), None); + assert!(!self.remap.contains(*local)); } fn visit_place( @@ -495,7 +494,7 @@ impl<'tcx> MutVisitor<'tcx> for TransformVisitor<'tcx> { _location: Location, ) { // Replace an Local in the remap with a coroutine struct access - if let Some(&(ty, variant_index, idx)) = self.remap.get(&place.local) { + if let Some(&Some((ty, variant_index, idx))) = self.remap.get(place.local) { replace_base(place, self.make_field(variant_index, idx, ty), self.tcx); } } @@ -504,7 +503,7 @@ impl<'tcx> MutVisitor<'tcx> for TransformVisitor<'tcx> { // Remove StorageLive and StorageDead statements for remapped locals data.retain_statements(|s| match s.kind { StatementKind::StorageLive(l) | StatementKind::StorageDead(l) => { - !self.remap.contains_key(&l) + !self.remap.contains(l) } _ => true, }); @@ -529,13 +528,9 @@ impl<'tcx> MutVisitor<'tcx> for TransformVisitor<'tcx> { // The resume arg target location might itself be remapped if its base local is // live across a yield. - let resume_arg = - if let Some(&(ty, variant, idx)) = self.remap.get(&resume_arg.local) { - replace_base(&mut resume_arg, self.make_field(variant, idx, ty), self.tcx); - resume_arg - } else { - resume_arg - }; + if let Some(&Some((ty, variant, idx))) = self.remap.get(resume_arg.local) { + replace_base(&mut resume_arg, self.make_field(variant, idx, ty), self.tcx); + } let storage_liveness: GrowableBitSet = self.storage_liveness[block].clone().unwrap().into(); @@ -543,7 +538,7 @@ impl<'tcx> MutVisitor<'tcx> for TransformVisitor<'tcx> { for i in 0..self.always_live_locals.domain_size() { let l = Local::new(i); let needs_storage_dead = storage_liveness.contains(l) - && !self.remap.contains_key(&l) + && !self.remap.contains(l) && !self.always_live_locals.contains(l); if needs_storage_dead { data.statements @@ -1037,7 +1032,7 @@ fn compute_layout<'tcx>( liveness: LivenessInfo, body: &Body<'tcx>, ) -> ( - FxHashMap, VariantIdx, FieldIdx)>, + IndexVec, VariantIdx, FieldIdx)>>, CoroutineLayout<'tcx>, IndexVec>>, ) { @@ -1098,7 +1093,7 @@ fn compute_layout<'tcx>( // Create a map from local indices to coroutine struct indices. let mut variant_fields: IndexVec> = iter::repeat(IndexVec::new()).take(RESERVED_VARIANTS).collect(); - let mut remap = FxHashMap::default(); + let mut remap = IndexVec::from_elem_n(None, saved_locals.domain_size()); for (suspension_point_idx, live_locals) in live_locals_at_suspension_points.iter().enumerate() { let variant_index = VariantIdx::from(RESERVED_VARIANTS + suspension_point_idx); let mut fields = IndexVec::new(); @@ -1109,7 +1104,7 @@ fn compute_layout<'tcx>( // around inside coroutines, so it doesn't matter which variant // index we access them by. let idx = FieldIdx::from_usize(idx); - remap.entry(locals[saved_local]).or_insert((tys[saved_local].ty, variant_index, idx)); + remap[locals[saved_local]] = Some((tys[saved_local].ty, variant_index, idx)); } variant_fields.push(fields); variant_source_info.push(source_info_at_suspension_points[suspension_point_idx]); @@ -1121,7 +1116,9 @@ fn compute_layout<'tcx>( for var in &body.var_debug_info { let VarDebugInfoContents::Place(place) = &var.value else { continue }; let Some(local) = place.as_local() else { continue }; - let Some(&(_, variant, field)) = remap.get(&local) else { continue }; + let Some(&Some((_, variant, field))) = remap.get(local) else { + continue; + }; let saved_local = variant_fields[variant][field]; field_names.get_or_insert_with(saved_local, || var.name); @@ -1524,7 +1521,7 @@ fn create_cases<'tcx>( for i in 0..(body.local_decls.len()) { let l = Local::new(i); let needs_storage_live = point.storage_liveness.contains(l) - && !transform.remap.contains_key(&l) + && !transform.remap.contains(l) && !transform.always_live_locals.contains(l); if needs_storage_live { statements From 493093796014201f8b519324d45f00c8b2e7f2b2 Mon Sep 17 00:00:00 2001 From: Liu Dingming Date: Thu, 4 Jul 2024 04:41:37 +0800 Subject: [PATCH 650/892] Less magic number for corountine --- compiler/rustc_middle/src/ty/sty.rs | 6 +++++- compiler/rustc_mir_transform/src/coroutine.rs | 7 ++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index ff40a726fbc38..52690ae678d6c 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -68,6 +68,10 @@ impl<'tcx> ty::CoroutineArgs> { const RETURNED: usize = 1; /// Coroutine has been poisoned. const POISONED: usize = 2; + /// Number of variants to reserve in coroutine state. Corresponds to + /// `UNRESUMED` (beginning of a coroutine) and `RETURNED`/`POISONED` + /// (end of a coroutine) states. + const RESERVED_VARIANTS: usize = 3; const UNRESUMED_NAME: &'static str = "Unresumed"; const RETURNED_NAME: &'static str = "Returned"; @@ -116,7 +120,7 @@ impl<'tcx> ty::CoroutineArgs> { Self::UNRESUMED => Cow::from(Self::UNRESUMED_NAME), Self::RETURNED => Cow::from(Self::RETURNED_NAME), Self::POISONED => Cow::from(Self::POISONED_NAME), - _ => Cow::from(format!("Suspend{}", v.as_usize() - 3)), + _ => Cow::from(format!("Suspend{}", v.as_usize() - Self::RESERVED_VARIANTS)), } } diff --git a/compiler/rustc_mir_transform/src/coroutine.rs b/compiler/rustc_mir_transform/src/coroutine.rs index 05674792426f1..4c00038365b73 100644 --- a/compiler/rustc_mir_transform/src/coroutine.rs +++ b/compiler/rustc_mir_transform/src/coroutine.rs @@ -208,11 +208,8 @@ const UNRESUMED: usize = CoroutineArgs::UNRESUMED; const RETURNED: usize = CoroutineArgs::RETURNED; /// Coroutine has panicked and is poisoned. const POISONED: usize = CoroutineArgs::POISONED; - -/// Number of variants to reserve in coroutine state. Corresponds to -/// `UNRESUMED` (beginning of a coroutine) and `RETURNED`/`POISONED` -/// (end of a coroutine) states. -const RESERVED_VARIANTS: usize = 3; +/// Number of reserved variants of coroutine state. +const RESERVED_VARIANTS: usize = CoroutineArgs::RESERVED_VARIANTS; /// A `yield` point in the coroutine. struct SuspensionPoint<'tcx> { From f21683432b72694b4558d779d6b5e5d49102ad7e Mon Sep 17 00:00:00 2001 From: The 8472 Date: Wed, 3 Jul 2024 22:54:15 +0200 Subject: [PATCH 651/892] stir the hash state a little to avoid prefix collisions --- library/std/src/path.rs | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/library/std/src/path.rs b/library/std/src/path.rs index caae8f924d2b1..e8f0b41f1f4c3 100644 --- a/library/std/src/path.rs +++ b/library/std/src/path.rs @@ -3098,15 +3098,19 @@ impl Hash for Path { let bytes = &bytes[prefix_len..]; let mut component_start = 0; - let mut bytes_hashed = 0; + // track some extra state to avoid prefix collisions. + // ["foo", "bar"] and ["foobar"], will have the same payload bytes + // but result in different chunk_bits + let mut chunk_bits: usize = 0; for i in 0..bytes.len() { let is_sep = if verbatim { is_verbatim_sep(bytes[i]) } else { is_sep_byte(bytes[i]) }; if is_sep { if i > component_start { let to_hash = &bytes[component_start..i]; + chunk_bits = chunk_bits.wrapping_add(to_hash.len()); + chunk_bits = chunk_bits.rotate_right(2); h.write(to_hash); - bytes_hashed += to_hash.len(); } // skip over separator and optionally a following CurDir item @@ -3127,11 +3131,12 @@ impl Hash for Path { if component_start < bytes.len() { let to_hash = &bytes[component_start..]; + chunk_bits = chunk_bits.wrapping_add(to_hash.len()); + chunk_bits = chunk_bits.rotate_right(2); h.write(to_hash); - bytes_hashed += to_hash.len(); } - h.write_usize(bytes_hashed); + h.write_usize(chunk_bits); } } From 140392b0418825c77ba68ab693dc18494ab27405 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 3 Jul 2024 20:00:04 +0000 Subject: [PATCH 652/892] Adjust rustdoc automatic link suggestion Use more accurate spans for multipart suggestion. --- src/librustdoc/passes/lint/bare_urls.rs | 36 +++---- tests/rustdoc-ui/diagnostic-width.stderr | 6 +- tests/rustdoc-ui/include-str-bare-urls.stderr | 6 +- tests/rustdoc-ui/lints/bare-urls.stderr | 102 +++++++++++++++--- .../lints/renamed-lint-still-applies.stderr | 6 +- 5 files changed, 117 insertions(+), 39 deletions(-) diff --git a/src/librustdoc/passes/lint/bare_urls.rs b/src/librustdoc/passes/lint/bare_urls.rs index 8f68f6ff4764a..a148f046f94b7 100644 --- a/src/librustdoc/passes/lint/bare_urls.rs +++ b/src/librustdoc/passes/lint/bare_urls.rs @@ -19,22 +19,22 @@ pub(super) fn visit_item(cx: &DocContext<'_>, item: &Item) { }; let dox = item.doc_value(); if !dox.is_empty() { - let report_diag = - |cx: &DocContext<'_>, msg: &'static str, url: &str, range: Range| { - let sp = - source_span_for_markdown_range(cx.tcx, &dox, &range, &item.attrs.doc_strings) - .unwrap_or_else(|| item.attr_span(cx.tcx)); - cx.tcx.node_span_lint(crate::lint::BARE_URLS, hir_id, sp, |lint| { - lint.primary_message(msg) - .note("bare URLs are not automatically turned into clickable links") - .span_suggestion( - sp, - "use an automatic link instead", - format!("<{url}>"), - Applicability::MachineApplicable, - ); - }); - }; + let report_diag = |cx: &DocContext<'_>, msg: &'static str, range: Range| { + let sp = source_span_for_markdown_range(cx.tcx, &dox, &range, &item.attrs.doc_strings) + .unwrap_or_else(|| item.attr_span(cx.tcx)); + cx.tcx.node_span_lint(crate::lint::BARE_URLS, hir_id, sp, |lint| { + lint.primary_message(msg) + .note("bare URLs are not automatically turned into clickable links") + .multipart_suggestion( + "use an automatic link instead", + vec![ + (sp.shrink_to_lo(), "<".to_string()), + (sp.shrink_to_hi(), ">".to_string()), + ], + Applicability::MachineApplicable, + ); + }); + }; let mut p = Parser::new_ext(&dox, main_body_opts()).into_offset_iter(); @@ -74,17 +74,15 @@ fn find_raw_urls( cx: &DocContext<'_>, text: &str, range: Range, - f: &impl Fn(&DocContext<'_>, &'static str, &str, Range), + f: &impl Fn(&DocContext<'_>, &'static str, Range), ) { trace!("looking for raw urls in {text}"); // For now, we only check "full" URLs (meaning, starting with "http://" or "https://"). for match_ in URL_REGEX.find_iter(text) { - let url = match_.as_str(); let url_range = match_.range(); f( cx, "this URL is not a hyperlink", - url, Range { start: range.start + url_range.start, end: range.start + url_range.end }, ); } diff --git a/tests/rustdoc-ui/diagnostic-width.stderr b/tests/rustdoc-ui/diagnostic-width.stderr index c1cc4898ac584..d8c4934a576cf 100644 --- a/tests/rustdoc-ui/diagnostic-width.stderr +++ b/tests/rustdoc-ui/diagnostic-width.stderr @@ -2,7 +2,7 @@ error: this URL is not a hyperlink --> $DIR/diagnostic-width.rs:4:41 | LL | ... a http://link.com - | ^^^^^^^^^^^^^^^ help: use an automatic link instead: `` + | ^^^^^^^^^^^^^^^ | = note: bare URLs are not automatically turned into clickable links note: the lint level is defined here @@ -10,6 +10,10 @@ note: the lint level is defined here | LL | ...ny(rustdoc::bare_url... | ^^^^^^^^^^^^^^^^^^ +help: use an automatic link instead + | +LL | /// This is a long line that contains a + | + + error: aborting due to 1 previous error diff --git a/tests/rustdoc-ui/include-str-bare-urls.stderr b/tests/rustdoc-ui/include-str-bare-urls.stderr index a4234196b2310..53da2411874a5 100644 --- a/tests/rustdoc-ui/include-str-bare-urls.stderr +++ b/tests/rustdoc-ui/include-str-bare-urls.stderr @@ -2,7 +2,7 @@ error: this URL is not a hyperlink --> $DIR/auxiliary/include-str-bare-urls.md:1:11 | LL | HEADS UP! https://example.com MUST SHOW UP IN THE STDERR FILE! - | ^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `` + | ^^^^^^^^^^^^^^^^^^^ | = note: bare URLs are not automatically turned into clickable links note: the lint level is defined here @@ -10,6 +10,10 @@ note: the lint level is defined here | LL | #![deny(rustdoc::bare_urls)] | ^^^^^^^^^^^^^^^^^^ +help: use an automatic link instead + | +LL | HEADS UP! MUST SHOW UP IN THE STDERR FILE! + | + + error: aborting due to 1 previous error diff --git a/tests/rustdoc-ui/lints/bare-urls.stderr b/tests/rustdoc-ui/lints/bare-urls.stderr index ccf52cd0b933f..ddfc387eaf66e 100644 --- a/tests/rustdoc-ui/lints/bare-urls.stderr +++ b/tests/rustdoc-ui/lints/bare-urls.stderr @@ -2,7 +2,7 @@ error: this URL is not a hyperlink --> $DIR/bare-urls.rs:5:5 | LL | /// https://somewhere.com - | ^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `` + | ^^^^^^^^^^^^^^^^^^^^^ | = note: bare URLs are not automatically turned into clickable links note: the lint level is defined here @@ -10,134 +10,202 @@ note: the lint level is defined here | LL | #![deny(rustdoc::bare_urls)] | ^^^^^^^^^^^^^^^^^^ +help: use an automatic link instead + | +LL | /// + | + + error: this URL is not a hyperlink --> $DIR/bare-urls.rs:7:5 | LL | /// https://somewhere.com/a - | ^^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `` + | ^^^^^^^^^^^^^^^^^^^^^^^ | = note: bare URLs are not automatically turned into clickable links +help: use an automatic link instead + | +LL | /// + | + + error: this URL is not a hyperlink --> $DIR/bare-urls.rs:9:5 | LL | /// https://www.somewhere.com - | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `` + | ^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: bare URLs are not automatically turned into clickable links +help: use an automatic link instead + | +LL | /// + | + + error: this URL is not a hyperlink --> $DIR/bare-urls.rs:11:5 | LL | /// https://www.somewhere.com/a - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: bare URLs are not automatically turned into clickable links +help: use an automatic link instead + | +LL | /// + | + + error: this URL is not a hyperlink --> $DIR/bare-urls.rs:13:5 | LL | /// https://subdomain.example.com - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: bare URLs are not automatically turned into clickable links +help: use an automatic link instead + | +LL | /// + | + + error: this URL is not a hyperlink --> $DIR/bare-urls.rs:15:5 | LL | /// https://somewhere.com? - | ^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `` + | ^^^^^^^^^^^^^^^^^^^^^^ | = note: bare URLs are not automatically turned into clickable links +help: use an automatic link instead + | +LL | /// + | + + error: this URL is not a hyperlink --> $DIR/bare-urls.rs:17:5 | LL | /// https://somewhere.com/a? - | ^^^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `` + | ^^^^^^^^^^^^^^^^^^^^^^^^ | = note: bare URLs are not automatically turned into clickable links +help: use an automatic link instead + | +LL | /// + | + + error: this URL is not a hyperlink --> $DIR/bare-urls.rs:19:5 | LL | /// https://somewhere.com?hello=12 - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: bare URLs are not automatically turned into clickable links +help: use an automatic link instead + | +LL | /// + | + + error: this URL is not a hyperlink --> $DIR/bare-urls.rs:21:5 | LL | /// https://somewhere.com/a?hello=12 - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: bare URLs are not automatically turned into clickable links +help: use an automatic link instead + | +LL | /// + | + + error: this URL is not a hyperlink --> $DIR/bare-urls.rs:23:5 | LL | /// https://example.com?hello=12#xyz - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: bare URLs are not automatically turned into clickable links +help: use an automatic link instead + | +LL | /// + | + + error: this URL is not a hyperlink --> $DIR/bare-urls.rs:25:5 | LL | /// https://example.com/a?hello=12#xyz - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: bare URLs are not automatically turned into clickable links +help: use an automatic link instead + | +LL | /// + | + + error: this URL is not a hyperlink --> $DIR/bare-urls.rs:27:5 | LL | /// https://example.com#xyz - | ^^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `` + | ^^^^^^^^^^^^^^^^^^^^^^^ | = note: bare URLs are not automatically turned into clickable links +help: use an automatic link instead + | +LL | /// + | + + error: this URL is not a hyperlink --> $DIR/bare-urls.rs:29:5 | LL | /// https://example.com/a#xyz - | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `` + | ^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: bare URLs are not automatically turned into clickable links +help: use an automatic link instead + | +LL | /// + | + + error: this URL is not a hyperlink --> $DIR/bare-urls.rs:31:5 | LL | /// https://somewhere.com?hello=12&bye=11 - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: bare URLs are not automatically turned into clickable links +help: use an automatic link instead + | +LL | /// + | + + error: this URL is not a hyperlink --> $DIR/bare-urls.rs:33:5 | LL | /// https://somewhere.com/a?hello=12&bye=11 - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: bare URLs are not automatically turned into clickable links +help: use an automatic link instead + | +LL | /// + | + + error: this URL is not a hyperlink --> $DIR/bare-urls.rs:35:5 | LL | /// https://somewhere.com?hello=12&bye=11#xyz - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: bare URLs are not automatically turned into clickable links +help: use an automatic link instead + | +LL | /// + | + + error: this URL is not a hyperlink --> $DIR/bare-urls.rs:37:10 | LL | /// hey! https://somewhere.com/a?hello=12&bye=11#xyz - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: bare URLs are not automatically turned into clickable links +help: use an automatic link instead + | +LL | /// hey! + | + + error: aborting due to 17 previous errors diff --git a/tests/rustdoc-ui/lints/renamed-lint-still-applies.stderr b/tests/rustdoc-ui/lints/renamed-lint-still-applies.stderr index ee9b67cb91be6..88807dfb495d0 100644 --- a/tests/rustdoc-ui/lints/renamed-lint-still-applies.stderr +++ b/tests/rustdoc-ui/lints/renamed-lint-still-applies.stderr @@ -29,7 +29,7 @@ error: this URL is not a hyperlink --> $DIR/renamed-lint-still-applies.rs:9:5 | LL | //! http://example.com - | ^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `` + | ^^^^^^^^^^^^^^^^^^ | = note: bare URLs are not automatically turned into clickable links note: the lint level is defined here @@ -37,6 +37,10 @@ note: the lint level is defined here | LL | #![deny(rustdoc::non_autolinks)] | ^^^^^^^^^^^^^^^^^^^^^^ +help: use an automatic link instead + | +LL | //! + | + + error: aborting due to 2 previous errors; 2 warnings emitted From 89ecae5d852a7346ee4e8240ae7a1130f1f6f458 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 3 Jul 2024 21:01:29 +0000 Subject: [PATCH 653/892] Better span for "make binding mutable" suggestion --- .../src/diagnostics/conflict_errors.rs | 25 +++++++-------- tests/ui/assign-imm-local-twice.rs | 2 +- tests/ui/assign-imm-local-twice.stderr | 8 +++-- tests/ui/async-await/issue-61452.stderr | 10 +++--- ...orrowck-match-binding-is-assignment.stderr | 20 ++++++------ tests/ui/borrowck/immutable-arg.stderr | 7 ++-- tests/ui/borrowck/issue-45199.rs | 6 ++-- tests/ui/borrowck/issue-45199.stderr | 26 +++++++++------ .../suggest-ref-mut-issue-118596.stderr | 8 ++--- tests/ui/borrowck/tainted-promoteds.stderr | 10 +++--- tests/ui/command-line-diagnostics.stderr | 10 +++--- ...3-both-anon-regions-one-is-struct-2.stderr | 7 ++-- .../liveness-assign-imm-local-notes.stderr | 32 ++++++++++++------- .../liveness-assign-imm-local-in-loop.rs | 2 +- .../liveness-assign-imm-local-in-loop.stderr | 8 +++-- .../liveness-assign-imm-local-in-op-eq.rs | 2 +- .../liveness-assign-imm-local-in-op-eq.stderr | 8 +++-- .../liveness-assign-imm-local-with-drop.rs | 2 +- ...liveness-assign-imm-local-with-drop.stderr | 10 +++--- .../liveness-assign-imm-local-with-init.rs | 2 +- ...liveness-assign-imm-local-with-init.stderr | 10 +++--- .../mut-pattern-internal-mutability.stderr | 4 +-- .../pat-at-same-name-both.stderr | 4 +-- .../borrowck-move-ref-pattern.stderr | 8 ++--- tests/ui/pattern/mut-ref-mut-2021.stderr | 4 +-- 25 files changed, 134 insertions(+), 101 deletions(-) diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index 7ef53fa2078e4..e291ebd9bb832 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -3757,13 +3757,11 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> { assigned_span: Span, err_place: Place<'tcx>, ) { - let (from_arg, local_decl, local_name) = match err_place.as_local() { - Some(local) => ( - self.body.local_kind(local) == LocalKind::Arg, - Some(&self.body.local_decls[local]), - self.local_names[local], - ), - None => (false, None, None), + let (from_arg, local_decl) = match err_place.as_local() { + Some(local) => { + (self.body.local_kind(local) == LocalKind::Arg, Some(&self.body.local_decls[local])) + } + None => (false, None), }; // If root local is initialized immediately (everything apart from let @@ -3795,13 +3793,12 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> { err.span_label(assigned_span, format!("first assignment to {place_description}")); } if let Some(decl) = local_decl - && let Some(name) = local_name && decl.can_be_made_mutable() { - err.span_suggestion( - decl.source_info.span, + err.span_suggestion_verbose( + decl.source_info.span.shrink_to_lo(), "consider making this binding mutable", - format!("mut {name}"), + "mut ".to_string(), Applicability::MachineApplicable, ); if !from_arg @@ -3813,10 +3810,10 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> { })) ) { - err.span_suggestion( - decl.source_info.span, + err.span_suggestion_verbose( + decl.source_info.span.shrink_to_lo(), "to modify the original value, take a borrow instead", - format!("ref mut {name}"), + "ref mut ".to_string(), Applicability::MaybeIncorrect, ); } diff --git a/tests/ui/assign-imm-local-twice.rs b/tests/ui/assign-imm-local-twice.rs index b50f6ab5deb15..b2dfeb564d9f9 100644 --- a/tests/ui/assign-imm-local-twice.rs +++ b/tests/ui/assign-imm-local-twice.rs @@ -1,7 +1,7 @@ fn test() { let v: isize; //~^ HELP consider making this binding mutable - //~| SUGGESTION mut v + //~| SUGGESTION mut v = 1; //~ NOTE first assignment println!("v={}", v); v = 2; //~ ERROR cannot assign twice to immutable variable diff --git a/tests/ui/assign-imm-local-twice.stderr b/tests/ui/assign-imm-local-twice.stderr index d92485de68fe7..fda3aa3de1b4b 100644 --- a/tests/ui/assign-imm-local-twice.stderr +++ b/tests/ui/assign-imm-local-twice.stderr @@ -1,14 +1,16 @@ error[E0384]: cannot assign twice to immutable variable `v` --> $DIR/assign-imm-local-twice.rs:7:5 | -LL | let v: isize; - | - help: consider making this binding mutable: `mut v` -... LL | v = 1; | ----- first assignment to `v` LL | println!("v={}", v); LL | v = 2; | ^^^^^ cannot assign twice to immutable variable + | +help: consider making this binding mutable + | +LL | let mut v: isize; + | +++ error: aborting due to 1 previous error diff --git a/tests/ui/async-await/issue-61452.stderr b/tests/ui/async-await/issue-61452.stderr index 3f623ba8ad274..b7b1e380c9e54 100644 --- a/tests/ui/async-await/issue-61452.stderr +++ b/tests/ui/async-await/issue-61452.stderr @@ -13,12 +13,14 @@ error[E0384]: cannot assign twice to immutable variable `x` --> $DIR/issue-61452.rs:9:5 | LL | pub async fn g(x: usize) { - | - - | | - | first assignment to `x` - | help: consider making this binding mutable: `mut x` + | - first assignment to `x` LL | x += 1; | ^^^^^^ cannot assign twice to immutable variable + | +help: consider making this binding mutable + | +LL | pub async fn g(mut x: usize) { + | +++ error: aborting due to 2 previous errors diff --git a/tests/ui/borrowck/borrowck-match-binding-is-assignment.stderr b/tests/ui/borrowck/borrowck-match-binding-is-assignment.stderr index 98ffa7f6ffa75..e164ea44aa4b8 100644 --- a/tests/ui/borrowck/borrowck-match-binding-is-assignment.stderr +++ b/tests/ui/borrowck/borrowck-match-binding-is-assignment.stderr @@ -9,11 +9,11 @@ LL | x += 1; help: consider making this binding mutable | LL | mut x => { - | ~~~~~ + | +++ help: to modify the original value, take a borrow instead | LL | ref mut x => { - | ~~~~~~~~~ + | +++++++ error[E0384]: cannot assign twice to immutable variable `x` --> $DIR/borrowck-match-binding-is-assignment.rs:20:13 @@ -26,11 +26,11 @@ LL | x += 1; help: consider making this binding mutable | LL | E::Foo(mut x) => { - | ~~~~~ + | +++ help: to modify the original value, take a borrow instead | LL | E::Foo(ref mut x) => { - | ~~~~~~~~~ + | +++++++ error[E0384]: cannot assign twice to immutable variable `x` --> $DIR/borrowck-match-binding-is-assignment.rs:26:13 @@ -43,11 +43,11 @@ LL | x += 1; help: consider making this binding mutable | LL | S { bar: mut x } => { - | ~~~~~ + | +++ help: to modify the original value, take a borrow instead | LL | S { bar: ref mut x } => { - | ~~~~~~~~~ + | +++++++ error[E0384]: cannot assign twice to immutable variable `x` --> $DIR/borrowck-match-binding-is-assignment.rs:32:13 @@ -60,11 +60,11 @@ LL | x += 1; help: consider making this binding mutable | LL | (mut x,) => { - | ~~~~~ + | +++ help: to modify the original value, take a borrow instead | LL | (ref mut x,) => { - | ~~~~~~~~~ + | +++++++ error[E0384]: cannot assign twice to immutable variable `x` --> $DIR/borrowck-match-binding-is-assignment.rs:38:13 @@ -77,11 +77,11 @@ LL | x += 1; help: consider making this binding mutable | LL | [mut x,_,_] => { - | ~~~~~ + | +++ help: to modify the original value, take a borrow instead | LL | [ref mut x,_,_] => { - | ~~~~~~~~~ + | +++++++ error: aborting due to 5 previous errors diff --git a/tests/ui/borrowck/immutable-arg.stderr b/tests/ui/borrowck/immutable-arg.stderr index 84a480f641071..fb75172532f54 100644 --- a/tests/ui/borrowck/immutable-arg.stderr +++ b/tests/ui/borrowck/immutable-arg.stderr @@ -1,10 +1,13 @@ error[E0384]: cannot assign to immutable argument `_x` --> $DIR/immutable-arg.rs:2:5 | -LL | fn foo(_x: u32) { - | -- help: consider making this binding mutable: `mut _x` LL | _x = 4; | ^^^^^^ cannot assign to immutable argument + | +help: consider making this binding mutable + | +LL | fn foo(mut _x: u32) { + | +++ error: aborting due to 1 previous error diff --git a/tests/ui/borrowck/issue-45199.rs b/tests/ui/borrowck/issue-45199.rs index ded46e56e3451..b38967524fa6f 100644 --- a/tests/ui/borrowck/issue-45199.rs +++ b/tests/ui/borrowck/issue-45199.rs @@ -1,7 +1,7 @@ fn test_drop_replace() { let b: Box; //~^ HELP consider making this binding mutable - //~| SUGGESTION mut b + //~| SUGGESTION mut b = Box::new(1); //~ NOTE first assignment b = Box::new(2); //~ ERROR cannot assign twice to immutable variable `b` //~| NOTE cannot assign twice to immutable @@ -10,13 +10,13 @@ fn test_drop_replace() { fn test_call() { let b = Box::new(1); //~ NOTE first assignment //~| HELP consider making this binding mutable - //~| SUGGESTION mut b + //~| SUGGESTION mut b = Box::new(2); //~ ERROR cannot assign twice to immutable variable `b` //~| NOTE cannot assign twice to immutable } fn test_args(b: Box) { //~ HELP consider making this binding mutable - //~| SUGGESTION mut b + //~| SUGGESTION mut b = Box::new(2); //~ ERROR cannot assign to immutable argument `b` //~| NOTE cannot assign to immutable argument } diff --git a/tests/ui/borrowck/issue-45199.stderr b/tests/ui/borrowck/issue-45199.stderr index 47aa30908270d..8886e618e18b6 100644 --- a/tests/ui/borrowck/issue-45199.stderr +++ b/tests/ui/borrowck/issue-45199.stderr @@ -1,34 +1,40 @@ error[E0384]: cannot assign twice to immutable variable `b` --> $DIR/issue-45199.rs:6:5 | -LL | let b: Box; - | - help: consider making this binding mutable: `mut b` -... LL | b = Box::new(1); | - first assignment to `b` LL | b = Box::new(2); | ^ cannot assign twice to immutable variable + | +help: consider making this binding mutable + | +LL | let mut b: Box; + | +++ error[E0384]: cannot assign twice to immutable variable `b` --> $DIR/issue-45199.rs:14:5 | LL | let b = Box::new(1); - | - - | | - | first assignment to `b` - | help: consider making this binding mutable: `mut b` + | - first assignment to `b` ... LL | b = Box::new(2); | ^ cannot assign twice to immutable variable + | +help: consider making this binding mutable + | +LL | let mut b = Box::new(1); + | +++ error[E0384]: cannot assign to immutable argument `b` --> $DIR/issue-45199.rs:20:5 | -LL | fn test_args(b: Box) { - | - help: consider making this binding mutable: `mut b` -LL | LL | b = Box::new(2); | ^ cannot assign to immutable argument + | +help: consider making this binding mutable + | +LL | fn test_args(mut b: Box) { + | +++ error: aborting due to 3 previous errors diff --git a/tests/ui/borrowck/suggest-ref-mut-issue-118596.stderr b/tests/ui/borrowck/suggest-ref-mut-issue-118596.stderr index fd2a775a099cb..aec3d66316085 100644 --- a/tests/ui/borrowck/suggest-ref-mut-issue-118596.stderr +++ b/tests/ui/borrowck/suggest-ref-mut-issue-118596.stderr @@ -9,11 +9,11 @@ LL | x = 2; help: consider making this binding mutable | LL | if let Some(mut x) = y { - | ~~~~~ + | +++ help: to modify the original value, take a borrow instead | LL | if let Some(ref mut x) = y { - | ~~~~~~~~~ + | +++++++ error[E0384]: cannot assign twice to immutable variable `x` --> $DIR/suggest-ref-mut-issue-118596.rs:9:5 @@ -26,11 +26,11 @@ LL | x = 0; help: consider making this binding mutable | LL | let [mut x, ref xs_hold @ ..] = arr; - | ~~~~~ + | +++ help: to modify the original value, take a borrow instead | LL | let [ref mut x, ref xs_hold @ ..] = arr; - | ~~~~~~~~~ + | +++++++ error: aborting due to 2 previous errors diff --git a/tests/ui/borrowck/tainted-promoteds.stderr b/tests/ui/borrowck/tainted-promoteds.stderr index a5c448fdcdbef..04669a290979b 100644 --- a/tests/ui/borrowck/tainted-promoteds.stderr +++ b/tests/ui/borrowck/tainted-promoteds.stderr @@ -2,12 +2,14 @@ error[E0384]: cannot assign twice to immutable variable `a` --> $DIR/tainted-promoteds.rs:7:5 | LL | let a = 0; - | - - | | - | first assignment to `a` - | help: consider making this binding mutable: `mut a` + | - first assignment to `a` LL | a = &0 * &1 * &2 * &3; | ^^^^^^^^^^^^^^^^^^^^^ cannot assign twice to immutable variable + | +help: consider making this binding mutable + | +LL | let mut a = 0; + | +++ error: aborting due to 1 previous error diff --git a/tests/ui/command-line-diagnostics.stderr b/tests/ui/command-line-diagnostics.stderr index b719a00ad5ddd..6d33fb4172f8d 100644 --- a/tests/ui/command-line-diagnostics.stderr +++ b/tests/ui/command-line-diagnostics.stderr @@ -2,12 +2,14 @@ error[E0384]: cannot assign twice to immutable variable `x` --> $DIR/command-line-diagnostics.rs:6:5 | LL | let x = 42; - | - - | | - | first assignment to `x` - | help: consider making this binding mutable: `mut x` + | - first assignment to `x` LL | x = 43; | ^^^^^^ cannot assign twice to immutable variable + | +help: consider making this binding mutable + | +LL | let mut x = 42; + | +++ error: aborting due to 1 previous error diff --git a/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct-2.stderr b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct-2.stderr index 0980de92d350e..29bf7e62985a3 100644 --- a/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct-2.stderr +++ b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct-2.stderr @@ -16,10 +16,13 @@ LL | fn foo<'a>(mut x: Ref<'a, 'a>, y: &'a u32) { error[E0384]: cannot assign to immutable argument `y` --> $DIR/ex3-both-anon-regions-one-is-struct-2.rs:4:5 | -LL | fn foo(mut x: Ref, y: &u32) { - | - help: consider making this binding mutable: `mut y` LL | y = x.b; | ^^^^^^^ cannot assign to immutable argument + | +help: consider making this binding mutable + | +LL | fn foo(mut x: Ref, mut y: &u32) { + | +++ error: aborting due to 2 previous errors diff --git a/tests/ui/lifetimes/lifetime-errors/liveness-assign-imm-local-notes.stderr b/tests/ui/lifetimes/lifetime-errors/liveness-assign-imm-local-notes.stderr index b47a47d631e5f..3fbd863467dcb 100644 --- a/tests/ui/lifetimes/lifetime-errors/liveness-assign-imm-local-notes.stderr +++ b/tests/ui/lifetimes/lifetime-errors/liveness-assign-imm-local-notes.stderr @@ -1,45 +1,53 @@ error[E0384]: cannot assign twice to immutable variable `x` --> $DIR/liveness-assign-imm-local-notes.rs:10:9 | -LL | let x; - | - help: consider making this binding mutable: `mut x` -... LL | x = 2; | ----- first assignment to `x` LL | x = 3; | ^^^^^ cannot assign twice to immutable variable + | +help: consider making this binding mutable + | +LL | let mut x; + | +++ error[E0384]: cannot assign twice to immutable variable `x` --> $DIR/liveness-assign-imm-local-notes.rs:21:13 | -LL | let x; - | - help: consider making this binding mutable: `mut x` -... LL | x = 2; | ----- first assignment to `x` LL | x = 3; | ^^^^^ cannot assign twice to immutable variable + | +help: consider making this binding mutable + | +LL | let mut x; + | +++ error[E0384]: cannot assign twice to immutable variable `x` --> $DIR/liveness-assign-imm-local-notes.rs:30:13 | -LL | let x; - | - help: consider making this binding mutable: `mut x` -... LL | x = 1; | ^^^^^ cannot assign twice to immutable variable + | +help: consider making this binding mutable + | +LL | let mut x; + | +++ error[E0384]: cannot assign twice to immutable variable `x` --> $DIR/liveness-assign-imm-local-notes.rs:32:13 | -LL | let x; - | - help: consider making this binding mutable: `mut x` -... LL | x = 1; | ----- first assignment to `x` LL | } else { LL | x = 2; | ^^^^^ cannot assign twice to immutable variable + | +help: consider making this binding mutable + | +LL | let mut x; + | +++ error: aborting due to 4 previous errors diff --git a/tests/ui/liveness/liveness-assign/liveness-assign-imm-local-in-loop.rs b/tests/ui/liveness/liveness-assign/liveness-assign-imm-local-in-loop.rs index 08911c5bde781..d2f32a47122c2 100644 --- a/tests/ui/liveness/liveness-assign/liveness-assign-imm-local-in-loop.rs +++ b/tests/ui/liveness/liveness-assign/liveness-assign-imm-local-in-loop.rs @@ -1,7 +1,7 @@ fn test() { let v: isize; //~^ HELP consider making this binding mutable - //~| SUGGESTION mut v + //~| SUGGESTION mut loop { v = 1; //~ ERROR cannot assign twice to immutable variable `v` //~| NOTE cannot assign twice to immutable variable diff --git a/tests/ui/liveness/liveness-assign/liveness-assign-imm-local-in-loop.stderr b/tests/ui/liveness/liveness-assign/liveness-assign-imm-local-in-loop.stderr index f0174560fd58c..e8c0721b903c9 100644 --- a/tests/ui/liveness/liveness-assign/liveness-assign-imm-local-in-loop.stderr +++ b/tests/ui/liveness/liveness-assign/liveness-assign-imm-local-in-loop.stderr @@ -1,11 +1,13 @@ error[E0384]: cannot assign twice to immutable variable `v` --> $DIR/liveness-assign-imm-local-in-loop.rs:6:9 | -LL | let v: isize; - | - help: consider making this binding mutable: `mut v` -... LL | v = 1; | ^^^^^ cannot assign twice to immutable variable + | +help: consider making this binding mutable + | +LL | let mut v: isize; + | +++ error: aborting due to 1 previous error diff --git a/tests/ui/liveness/liveness-assign/liveness-assign-imm-local-in-op-eq.rs b/tests/ui/liveness/liveness-assign/liveness-assign-imm-local-in-op-eq.rs index 1752d969086e8..fd6b4bcdf84c0 100644 --- a/tests/ui/liveness/liveness-assign/liveness-assign-imm-local-in-op-eq.rs +++ b/tests/ui/liveness/liveness-assign/liveness-assign-imm-local-in-op-eq.rs @@ -1,7 +1,7 @@ fn test() { let v: isize; //~^ HELP consider making this binding mutable - //~| SUGGESTION mut v + //~| SUGGESTION mut v = 2; //~ NOTE first assignment v += 1; //~ ERROR cannot assign twice to immutable variable `v` //~| NOTE cannot assign twice to immutable diff --git a/tests/ui/liveness/liveness-assign/liveness-assign-imm-local-in-op-eq.stderr b/tests/ui/liveness/liveness-assign/liveness-assign-imm-local-in-op-eq.stderr index 578a40e4070d0..b7373d7cf1d7e 100644 --- a/tests/ui/liveness/liveness-assign/liveness-assign-imm-local-in-op-eq.stderr +++ b/tests/ui/liveness/liveness-assign/liveness-assign-imm-local-in-op-eq.stderr @@ -1,13 +1,15 @@ error[E0384]: cannot assign twice to immutable variable `v` --> $DIR/liveness-assign-imm-local-in-op-eq.rs:6:5 | -LL | let v: isize; - | - help: consider making this binding mutable: `mut v` -... LL | v = 2; | ----- first assignment to `v` LL | v += 1; | ^^^^^^ cannot assign twice to immutable variable + | +help: consider making this binding mutable + | +LL | let mut v: isize; + | +++ error: aborting due to 1 previous error diff --git a/tests/ui/liveness/liveness-assign/liveness-assign-imm-local-with-drop.rs b/tests/ui/liveness/liveness-assign/liveness-assign-imm-local-with-drop.rs index c9b16e43910e8..b7050d69306d0 100644 --- a/tests/ui/liveness/liveness-assign/liveness-assign-imm-local-with-drop.rs +++ b/tests/ui/liveness/liveness-assign/liveness-assign-imm-local-with-drop.rs @@ -1,7 +1,7 @@ fn test() { let b = Box::new(1); //~ NOTE first assignment //~| HELP consider making this binding mutable - //~| SUGGESTION mut b + //~| SUGGESTION mut drop(b); b = Box::new(2); //~ ERROR cannot assign twice to immutable variable `b` //~| NOTE cannot assign twice to immutable diff --git a/tests/ui/liveness/liveness-assign/liveness-assign-imm-local-with-drop.stderr b/tests/ui/liveness/liveness-assign/liveness-assign-imm-local-with-drop.stderr index 2f55b50f0baf4..35b47bd6d91a5 100644 --- a/tests/ui/liveness/liveness-assign/liveness-assign-imm-local-with-drop.stderr +++ b/tests/ui/liveness/liveness-assign/liveness-assign-imm-local-with-drop.stderr @@ -2,13 +2,15 @@ error[E0384]: cannot assign twice to immutable variable `b` --> $DIR/liveness-assign-imm-local-with-drop.rs:6:5 | LL | let b = Box::new(1); - | - - | | - | first assignment to `b` - | help: consider making this binding mutable: `mut b` + | - first assignment to `b` ... LL | b = Box::new(2); | ^ cannot assign twice to immutable variable + | +help: consider making this binding mutable + | +LL | let mut b = Box::new(1); + | +++ error: aborting due to 1 previous error diff --git a/tests/ui/liveness/liveness-assign/liveness-assign-imm-local-with-init.rs b/tests/ui/liveness/liveness-assign/liveness-assign-imm-local-with-init.rs index 4bb2db27a1652..67c97e38546dc 100644 --- a/tests/ui/liveness/liveness-assign/liveness-assign-imm-local-with-init.rs +++ b/tests/ui/liveness/liveness-assign/liveness-assign-imm-local-with-init.rs @@ -1,7 +1,7 @@ fn test() { let v: isize = 1; //~ NOTE first assignment //~| HELP consider making this binding mutable - //~| SUGGESTION mut v + //~| SUGGESTION mut v.clone(); v = 2; //~ ERROR cannot assign twice to immutable variable `v` //~| NOTE cannot assign twice to immutable diff --git a/tests/ui/liveness/liveness-assign/liveness-assign-imm-local-with-init.stderr b/tests/ui/liveness/liveness-assign/liveness-assign-imm-local-with-init.stderr index 8eb71cd99bfc1..d1f9e1573e4b7 100644 --- a/tests/ui/liveness/liveness-assign/liveness-assign-imm-local-with-init.stderr +++ b/tests/ui/liveness/liveness-assign/liveness-assign-imm-local-with-init.stderr @@ -2,13 +2,15 @@ error[E0384]: cannot assign twice to immutable variable `v` --> $DIR/liveness-assign-imm-local-with-init.rs:6:5 | LL | let v: isize = 1; - | - - | | - | first assignment to `v` - | help: consider making this binding mutable: `mut v` + | - first assignment to `v` ... LL | v = 2; | ^^^^^ cannot assign twice to immutable variable + | +help: consider making this binding mutable + | +LL | let mut v: isize = 1; + | +++ error: aborting due to 1 previous error diff --git a/tests/ui/mut/mut-pattern-internal-mutability.stderr b/tests/ui/mut/mut-pattern-internal-mutability.stderr index ab80af17a085f..f3a8aa0126caf 100644 --- a/tests/ui/mut/mut-pattern-internal-mutability.stderr +++ b/tests/ui/mut/mut-pattern-internal-mutability.stderr @@ -9,11 +9,11 @@ LL | x += 1; help: consider making this binding mutable | LL | let &mut mut x = foo; - | ~~~~~ + | +++ help: to modify the original value, take a borrow instead | LL | let &mut ref mut x = foo; - | ~~~~~~~~~ + | +++++++ error[E0506]: cannot assign to `*foo` because it is borrowed --> $DIR/mut-pattern-internal-mutability.rs:13:5 diff --git a/tests/ui/pattern/bindings-after-at/pat-at-same-name-both.stderr b/tests/ui/pattern/bindings-after-at/pat-at-same-name-both.stderr index 41d1b79d97d1c..ed71a39ff7eed 100644 --- a/tests/ui/pattern/bindings-after-at/pat-at-same-name-both.stderr +++ b/tests/ui/pattern/bindings-after-at/pat-at-same-name-both.stderr @@ -78,11 +78,11 @@ LL | | Err(a @ b @ a) help: consider making this binding mutable | LL | Ok(a @ b @ mut a) - | ~~~~~ + | +++ help: to modify the original value, take a borrow instead | LL | Ok(a @ b @ ref mut a) - | ~~~~~~~~~ + | +++++++ error: aborting due to 12 previous errors diff --git a/tests/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern.stderr b/tests/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern.stderr index 1e7b990b67cf3..a1049701dc3b8 100644 --- a/tests/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern.stderr +++ b/tests/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern.stderr @@ -22,11 +22,11 @@ LL | _x1 = U; help: consider making this binding mutable | LL | let [ref _x0_hold, mut _x1, ref xs_hold @ ..] = arr; - | ~~~~~~~ + | +++ help: to modify the original value, take a borrow instead | LL | let [ref _x0_hold, ref mut _x1, ref xs_hold @ ..] = arr; - | ~~~~~~~~~~~ + | +++++++ error[E0505]: cannot move out of `arr[..]` because it is borrowed --> $DIR/borrowck-move-ref-pattern.rs:11:10 @@ -86,11 +86,11 @@ LL | _x1 = U; help: consider making this binding mutable | LL | let (ref _x0, mut _x1, ref _x2, ..) = tup; - | ~~~~~~~ + | +++ help: to modify the original value, take a borrow instead | LL | let (ref _x0, ref mut _x1, ref _x2, ..) = tup; - | ~~~~~~~~~~~ + | +++++++ error[E0502]: cannot borrow `tup.0` as mutable because it is also borrowed as immutable --> $DIR/borrowck-move-ref-pattern.rs:24:20 diff --git a/tests/ui/pattern/mut-ref-mut-2021.stderr b/tests/ui/pattern/mut-ref-mut-2021.stderr index ebf7979edb6ea..228afed2026ee 100644 --- a/tests/ui/pattern/mut-ref-mut-2021.stderr +++ b/tests/ui/pattern/mut-ref-mut-2021.stderr @@ -9,11 +9,11 @@ LL | a = 42; help: consider making this binding mutable | LL | let Foo(mut a) = Foo(0); - | ~~~~~ + | +++ help: to modify the original value, take a borrow instead | LL | let Foo(ref mut a) = Foo(0); - | ~~~~~~~~~ + | +++++++ error[E0384]: cannot assign twice to immutable variable `a` --> $DIR/mut-ref-mut-2021.rs:15:5 From f63d2bc657f2158bc37c747bb0835a9d02b864d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 3 Jul 2024 21:02:27 +0000 Subject: [PATCH 654/892] Better suggestion span for missing type parameter --- compiler/rustc_hir_analysis/src/errors.rs | 7 +++---- tests/ui/associated-types/issue-22560.stderr | 12 ++++++++++-- ...dy-to-be-a-closure-or-coroutine-ice-113776.stderr | 12 ++++++++++-- tests/ui/error-codes/E0393.stderr | 6 +++++- tests/ui/issues/issue-21950.stderr | 6 +++++- tests/ui/issues/issue-22370.stderr | 6 +++++- .../type-parameter-defaults-referencing-Self.stderr | 6 +++++- 7 files changed, 43 insertions(+), 12 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs index 3ffb51fa9926a..c2d86efd517aa 100644 --- a/compiler/rustc_hir_analysis/src/errors.rs +++ b/compiler/rustc_hir_analysis/src/errors.rs @@ -453,12 +453,11 @@ impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for MissingTypeParams { } else { // The user wrote `Iterator`, so we don't have a type we can suggest, but at // least we can clue them to the correct syntax `Iterator`. - err.span_suggestion( - self.span, + err.span_suggestion_verbose( + self.span.shrink_to_hi(), fluent::hir_analysis_suggestion, format!( - "{}<{}>", - snippet, + "<{}>", self.missing_type_params .iter() .map(|n| n.to_string()) diff --git a/tests/ui/associated-types/issue-22560.stderr b/tests/ui/associated-types/issue-22560.stderr index 46e6e3951a5bd..834040490f940 100644 --- a/tests/ui/associated-types/issue-22560.stderr +++ b/tests/ui/associated-types/issue-22560.stderr @@ -35,9 +35,13 @@ LL | trait Add { | ------------------- type parameter `Rhs` must be specified for this ... LL | type Test = dyn Add + Sub; - | ^^^ help: set the type parameter to the desired type: `Add` + | ^^^ | = note: because of the default `Self` reference, type parameters must be specified on object types +help: set the type parameter to the desired type + | +LL | type Test = dyn Add + Sub; + | +++++ error[E0393]: the type parameter `Rhs` must be explicitly specified --> $DIR/issue-22560.rs:9:23 @@ -46,9 +50,13 @@ LL | trait Sub { | ------------------- type parameter `Rhs` must be specified for this ... LL | type Test = dyn Add + Sub; - | ^^^ help: set the type parameter to the desired type: `Sub` + | ^^^ | = note: because of the default `Self` reference, type parameters must be specified on object types +help: set the type parameter to the desired type + | +LL | type Test = dyn Add + Sub; + | +++++ error: aborting due to 4 previous errors diff --git a/tests/ui/const-generics/generic_const_exprs/expected-type-of-closure-body-to-be-a-closure-or-coroutine-ice-113776.stderr b/tests/ui/const-generics/generic_const_exprs/expected-type-of-closure-body-to-be-a-closure-or-coroutine-ice-113776.stderr index be79450a3ce31..416a938112424 100644 --- a/tests/ui/const-generics/generic_const_exprs/expected-type-of-closure-body-to-be-a-closure-or-coroutine-ice-113776.stderr +++ b/tests/ui/const-generics/generic_const_exprs/expected-type-of-closure-body-to-be-a-closure-or-coroutine-ice-113776.stderr @@ -20,24 +20,32 @@ error[E0393]: the type parameter `Rhs` must be explicitly specified --> $DIR/expected-type-of-closure-body-to-be-a-closure-or-coroutine-ice-113776.rs:16:27 | LL | ) -> impl Iterator { - | ^^^^^^^^^ help: set the type parameter to the desired type: `SubAssign` + | ^^^^^^^^^ --> $SRC_DIR/core/src/ops/arith.rs:LL:COL | = note: type parameter `Rhs` must be specified for this | = note: because of the default `Self` reference, type parameters must be specified on object types +help: set the type parameter to the desired type + | +LL | ) -> impl Iterator> { + | +++++ error[E0393]: the type parameter `Rhs` must be explicitly specified --> $DIR/expected-type-of-closure-body-to-be-a-closure-or-coroutine-ice-113776.rs:16:27 | LL | ) -> impl Iterator { - | ^^^^^^^^^ help: set the type parameter to the desired type: `SubAssign` + | ^^^^^^^^^ --> $SRC_DIR/core/src/ops/arith.rs:LL:COL | = note: type parameter `Rhs` must be specified for this | = note: because of the default `Self` reference, type parameters must be specified on object types = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` +help: set the type parameter to the desired type + | +LL | ) -> impl Iterator> { + | +++++ error[E0277]: `()` is not an iterator --> $DIR/expected-type-of-closure-body-to-be-a-closure-or-coroutine-ice-113776.rs:16:6 diff --git a/tests/ui/error-codes/E0393.stderr b/tests/ui/error-codes/E0393.stderr index 4083fa23e87aa..489398b7be59e 100644 --- a/tests/ui/error-codes/E0393.stderr +++ b/tests/ui/error-codes/E0393.stderr @@ -5,9 +5,13 @@ LL | trait A {} | --------------- type parameter `T` must be specified for this LL | LL | fn together_we_will_rule_the_galaxy(son: &dyn A) {} - | ^ help: set the type parameter to the desired type: `A` + | ^ | = note: because of the default `Self` reference, type parameters must be specified on object types +help: set the type parameter to the desired type + | +LL | fn together_we_will_rule_the_galaxy(son: &dyn A) {} + | +++ error: aborting due to 1 previous error diff --git a/tests/ui/issues/issue-21950.stderr b/tests/ui/issues/issue-21950.stderr index e498565d4e653..584370c717827 100644 --- a/tests/ui/issues/issue-21950.stderr +++ b/tests/ui/issues/issue-21950.stderr @@ -14,9 +14,13 @@ LL | trait Add { | ------------------- type parameter `Rhs` must be specified for this ... LL | let x = &10 as &dyn Add; - | ^^^ help: set the type parameter to the desired type: `Add` + | ^^^ | = note: because of the default `Self` reference, type parameters must be specified on object types +help: set the type parameter to the desired type + | +LL | let x = &10 as &dyn Add; + | +++++ error: aborting due to 2 previous errors diff --git a/tests/ui/issues/issue-22370.stderr b/tests/ui/issues/issue-22370.stderr index 977cfe06bb8b9..3dc060963f920 100644 --- a/tests/ui/issues/issue-22370.stderr +++ b/tests/ui/issues/issue-22370.stderr @@ -5,9 +5,13 @@ LL | trait A {} | --------------- type parameter `T` must be specified for this LL | LL | fn f(a: &dyn A) {} - | ^ help: set the type parameter to the desired type: `A` + | ^ | = note: because of the default `Self` reference, type parameters must be specified on object types +help: set the type parameter to the desired type + | +LL | fn f(a: &dyn A) {} + | +++ error: aborting due to 1 previous error diff --git a/tests/ui/type/type-parameter-defaults-referencing-Self.stderr b/tests/ui/type/type-parameter-defaults-referencing-Self.stderr index 16d08b2672267..c81405f03f8fa 100644 --- a/tests/ui/type/type-parameter-defaults-referencing-Self.stderr +++ b/tests/ui/type/type-parameter-defaults-referencing-Self.stderr @@ -5,9 +5,13 @@ LL | trait Foo { | ----------------- type parameter `T` must be specified for this ... LL | fn foo(x: &dyn Foo) { } - | ^^^ help: set the type parameter to the desired type: `Foo` + | ^^^ | = note: because of the default `Self` reference, type parameters must be specified on object types +help: set the type parameter to the desired type + | +LL | fn foo(x: &dyn Foo) { } + | +++ error: aborting due to 1 previous error From 9344779f718e847283a1ada901bad1222bd5d55b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 3 Jul 2024 21:02:55 +0000 Subject: [PATCH 655/892] Fix `&mut` removal suggestion --- .../src/diagnostics/mutability_errors.rs | 4 ++-- tests/ui/borrowck/issue-33819.stderr | 11 +++++++---- tests/ui/did_you_mean/issue-34337.stderr | 11 +++++++---- tests/ui/did_you_mean/issue-37139.stderr | 11 +++++++---- 4 files changed, 23 insertions(+), 14 deletions(-) diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs index 19a4df0cd7b43..4174c75b2846f 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs @@ -449,8 +449,8 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> { .is_ok_and(|snippet| snippet.starts_with("&mut ")) => { err.span_label(span, format!("cannot {act}")); - err.span_suggestion( - span, + err.span_suggestion_verbose( + span.with_hi(span.lo() + BytePos(5)), "try removing `&mut` here", "", Applicability::MaybeIncorrect, diff --git a/tests/ui/borrowck/issue-33819.stderr b/tests/ui/borrowck/issue-33819.stderr index 41c9d6aac760b..e5f6df26bc190 100644 --- a/tests/ui/borrowck/issue-33819.stderr +++ b/tests/ui/borrowck/issue-33819.stderr @@ -2,10 +2,13 @@ error[E0596]: cannot borrow `v` as mutable, as it is not declared as mutable --> $DIR/issue-33819.rs:4:34 | LL | Some(ref v) => { let a = &mut v; }, - | ^^^^^^ - | | - | cannot borrow as mutable - | help: try removing `&mut` here + | ^^^^^^ cannot borrow as mutable + | +help: try removing `&mut` here + | +LL - Some(ref v) => { let a = &mut v; }, +LL + Some(ref v) => { let a = v; }, + | error: aborting due to 1 previous error diff --git a/tests/ui/did_you_mean/issue-34337.stderr b/tests/ui/did_you_mean/issue-34337.stderr index c727a565dbe34..7bb651c47d049 100644 --- a/tests/ui/did_you_mean/issue-34337.stderr +++ b/tests/ui/did_you_mean/issue-34337.stderr @@ -2,10 +2,13 @@ error[E0596]: cannot borrow `key` as mutable, as it is not declared as mutable --> $DIR/issue-34337.rs:6:9 | LL | get(&mut key); - | ^^^^^^^^ - | | - | cannot borrow as mutable - | help: try removing `&mut` here + | ^^^^^^^^ cannot borrow as mutable + | +help: try removing `&mut` here + | +LL - get(&mut key); +LL + get(key); + | error: aborting due to 1 previous error diff --git a/tests/ui/did_you_mean/issue-37139.stderr b/tests/ui/did_you_mean/issue-37139.stderr index a07d83b31db1d..dbaab70d8bc23 100644 --- a/tests/ui/did_you_mean/issue-37139.stderr +++ b/tests/ui/did_you_mean/issue-37139.stderr @@ -2,10 +2,13 @@ error[E0596]: cannot borrow `x` as mutable, as it is not declared as mutable --> $DIR/issue-37139.rs:12:18 | LL | test(&mut x); - | ^^^^^^ - | | - | cannot borrow as mutable - | help: try removing `&mut` here + | ^^^^^^ cannot borrow as mutable + | +help: try removing `&mut` here + | +LL - test(&mut x); +LL + test(x); + | error: aborting due to 1 previous error From 5c2946a4beb927d5c34519d5310b6507efb91724 Mon Sep 17 00:00:00 2001 From: The Miri Cronjob Bot Date: Thu, 4 Jul 2024 04:54:26 +0000 Subject: [PATCH 656/892] 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 912aa11ded053..5a35166769e89 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version @@ -1 +1 @@ -7d97c59438e933e86f557ed999da3b8dfc6855a7 +66b4f0021bfb11a8c20d084c99a40f4a78ce1d38 From a06a18a47fc36b6c2c7c317c7611fe0a2960765b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 3 Jul 2024 21:03:37 +0000 Subject: [PATCH 657/892] Properly handle removal suggestion rendering Do not leave a `+ ` line with only whitespace. In reality, the user will want to remove the entire line. --- compiler/rustc_errors/src/emitter.rs | 23 ++++++++++++++++--- .../tests/ui/dbg_macro/dbg_macro.stderr | 2 -- .../ui/dbg_macro/dbg_macro_unfixable.stderr | 1 - .../clippy/tests/ui/manual_split_once.stderr | 10 -------- .../ui/significant_drop_tightening.stderr | 2 -- 5 files changed, 20 insertions(+), 18 deletions(-) diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs index 45118bcc58abe..aa47ca166764b 100644 --- a/compiler/rustc_errors/src/emitter.rs +++ b/compiler/rustc_errors/src/emitter.rs @@ -2273,9 +2273,26 @@ impl HumanEmitter { &normalize_whitespace(last_line), Style::NoStyle, ); - buffer.puts(*row_num, 0, &self.maybe_anonymized(line_num), Style::LineNumber); - buffer.puts(*row_num, max_line_num_len + 1, "+ ", Style::Addition); - buffer.append(*row_num, &normalize_whitespace(line_to_add), Style::NoStyle); + if !line_to_add.trim().is_empty() { + // Check if after the removal, the line is left with only whitespace. If so, we + // will not show an "addition" line, as removing the whole line is what the user + // would really want. + // For example, for the following: + // | + // 2 - .await + // 2 + (note the left over whitepsace) + // | + // We really want + // | + // 2 - .await + // | + // *row_num -= 1; + buffer.puts(*row_num, 0, &self.maybe_anonymized(line_num), Style::LineNumber); + buffer.puts(*row_num, max_line_num_len + 1, "+ ", Style::Addition); + buffer.append(*row_num, &normalize_whitespace(line_to_add), Style::NoStyle); + } else { + *row_num -= 1; + } } else { *row_num -= 2; } diff --git a/src/tools/clippy/tests/ui/dbg_macro/dbg_macro.stderr b/src/tools/clippy/tests/ui/dbg_macro/dbg_macro.stderr index 86667701da0f3..7d3c3f7c918e8 100644 --- a/src/tools/clippy/tests/ui/dbg_macro/dbg_macro.stderr +++ b/src/tools/clippy/tests/ui/dbg_macro/dbg_macro.stderr @@ -86,7 +86,6 @@ LL | dbg!(); help: remove the invocation before committing it to a version control system | LL - dbg!(); -LL + | error: the `dbg!` macro is intended as a debugging tool @@ -146,7 +145,6 @@ LL | expand_to_dbg!(); help: remove the invocation before committing it to a version control system | LL - dbg!(); -LL + | error: the `dbg!` macro is intended as a debugging tool diff --git a/src/tools/clippy/tests/ui/dbg_macro/dbg_macro_unfixable.stderr b/src/tools/clippy/tests/ui/dbg_macro/dbg_macro_unfixable.stderr index d21595c2fcd42..16e51f4742e34 100644 --- a/src/tools/clippy/tests/ui/dbg_macro/dbg_macro_unfixable.stderr +++ b/src/tools/clippy/tests/ui/dbg_macro/dbg_macro_unfixable.stderr @@ -9,7 +9,6 @@ LL | dbg!(); help: remove the invocation before committing it to a version control system | LL - dbg!(); -LL + | error: the `dbg!` macro is intended as a debugging tool diff --git a/src/tools/clippy/tests/ui/manual_split_once.stderr b/src/tools/clippy/tests/ui/manual_split_once.stderr index b4e51f473cf4d..c5c9be3ac63df 100644 --- a/src/tools/clippy/tests/ui/manual_split_once.stderr +++ b/src/tools/clippy/tests/ui/manual_split_once.stderr @@ -96,12 +96,10 @@ LL | let (l, r) = "a.b.c".split_once('.').unwrap(); help: remove the `iter` usages | LL - let l = iter.next().unwrap(); -LL + | help: remove the `iter` usages | LL - let r = iter.next().unwrap(); -LL + | error: manual implementation of `split_once` @@ -121,12 +119,10 @@ LL | let (l, r) = "a.b.c".split_once('.')?; help: remove the `iter` usages | LL - let l = iter.next()?; -LL + | help: remove the `iter` usages | LL - let r = iter.next()?; -LL + | error: manual implementation of `rsplit_once` @@ -146,12 +142,10 @@ LL | let (l, r) = "a.b.c".rsplit_once('.').unwrap(); help: remove the `iter` usages | LL - let r = iter.next().unwrap(); -LL + | help: remove the `iter` usages | LL - let l = iter.next().unwrap(); -LL + | error: manual implementation of `rsplit_once` @@ -171,12 +165,10 @@ LL | let (l, r) = "a.b.c".rsplit_once('.')?; help: remove the `iter` usages | LL - let r = iter.next()?; -LL + | help: remove the `iter` usages | LL - let l = iter.next()?; -LL + | error: manual implementation of `split_once` @@ -202,12 +194,10 @@ LL | let (a, b) = "a.b.c".split_once('.').unwrap(); help: remove the `iter` usages | LL - let a = iter.next().unwrap(); -LL + | help: remove the `iter` usages | LL - let b = iter.next().unwrap(); -LL + | error: aborting due to 19 previous errors diff --git a/src/tools/clippy/tests/ui/significant_drop_tightening.stderr b/src/tools/clippy/tests/ui/significant_drop_tightening.stderr index f818a14cbe68b..5fc66279f00e7 100644 --- a/src/tools/clippy/tests/ui/significant_drop_tightening.stderr +++ b/src/tools/clippy/tests/ui/significant_drop_tightening.stderr @@ -64,7 +64,6 @@ LL + let rslt0 = mutex.lock().unwrap().abs(); help: remove separated single usage | LL - let rslt0 = lock.abs(); -LL + | error: temporary with significant `Drop` can be early dropped @@ -88,7 +87,6 @@ LL + mutex.lock().unwrap().clear(); help: remove separated single usage | LL - lock.clear(); -LL + | error: aborting due to 4 previous errors From 57e76d45960770e45e20a76019c96643b7ef0845 Mon Sep 17 00:00:00 2001 From: tison Date: Wed, 3 Jul 2024 22:12:55 -0700 Subject: [PATCH 658/892] impl PathBuf::add_extension and Path::with_added_extension Signed-off-by: tison --- library/std/src/path.rs | 97 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) diff --git a/library/std/src/path.rs b/library/std/src/path.rs index caae8f924d2b1..a6f6042eaefaf 100644 --- a/library/std/src/path.rs +++ b/library/std/src/path.rs @@ -1519,6 +1519,77 @@ impl PathBuf { true } + /// Append [`self.extension`] with `extension`. + /// + /// Returns `false` and does nothing if [`self.file_name`] is [`None`], + /// returns `true` and updates the extension otherwise. + /// + /// If [`self.extension`] is [`None`], the extension is added; otherwise + /// it is appended. + /// + /// # Caveats + /// + /// The appended `extension` may contain dots and will be used in its entirety, + /// but only the part after the final dot will be reflected in + /// [`self.extension`]. + /// + /// See the examples below. + /// + /// [`self.file_name`]: Path::file_name + /// [`self.extension`]: Path::extension + /// + /// # Examples + /// + /// ``` + /// #![feature(path_add_extension)] + /// + /// use std::path::{Path, PathBuf}; + /// + /// let mut p = PathBuf::from("/feel/the"); + /// + /// p.add_extension("formatted"); + /// assert_eq!(Path::new("/feel/the.formatted"), p.as_path()); + /// + /// p.add_extension("dark.side"); + /// assert_eq!(Path::new("/feel/the.formatted.dark.side"), p.as_path()); + /// + /// p.set_extension("cookie"); + /// assert_eq!(Path::new("/feel/the.formatted.dark.cookie"), p.as_path()); + /// + /// p.set_extension(""); + /// assert_eq!(Path::new("/feel/the.formatted.dark"), p.as_path()); + /// + /// p.add_extension(""); + /// assert_eq!(Path::new("/feel/the.formatted.dark"), p.as_path()); + /// ``` + #[unstable(feature = "path_add_extension", issue = "127292")] + pub fn add_extension>(&mut self, extension: S) -> bool { + self._add_extension(extension.as_ref()) + } + + fn _add_extension(&mut self, extension: &OsStr) -> bool { + let file_name = match self.file_name() { + None => return false, + Some(f) => f.as_encoded_bytes(), + }; + + let new = extension; + if !new.is_empty() { + // truncate until right after the file name + // this is necessary for trimming the trailing slash + let end_file_name = file_name[file_name.len()..].as_ptr().addr(); + let start = self.inner.as_encoded_bytes().as_ptr().addr(); + self.inner.truncate(end_file_name.wrapping_sub(start)); + + // append the new extension + self.inner.reserve_exact(new.len() + 1); + self.inner.push(OsStr::new(".")); + self.inner.push(new); + } + + true + } + /// Yields a mutable reference to the underlying [`OsString`] instance. /// /// # Examples @@ -2656,6 +2727,32 @@ impl Path { new_path } + /// Creates an owned [`PathBuf`] like `self` but with an extra extension. + /// + /// See [`PathBuf::add_extension`] for more details. + /// + /// # Examples + /// + /// ``` + /// #![feature(path_add_extension)] + /// + /// use std::path::{Path, PathBuf}; + /// + /// let path = Path::new("foo.rs"); + /// assert_eq!(path.with_added_extension("txt"), PathBuf::from("foo.rs.txt")); + /// + /// let path = Path::new("foo.tar.gz"); + /// assert_eq!(path.with_added_extension(""), PathBuf::from("foo.tar.gz")); + /// assert_eq!(path.with_added_extension("xz"), PathBuf::from("foo.tar.gz.xz")); + /// assert_eq!(path.with_added_extension("").with_added_extension("txt"), PathBuf::from("foo.tar.gz.txt")); + /// ``` + #[unstable(feature = "path_add_extension", issue = "127292")] + pub fn with_added_extension>(&self, extension: S) -> PathBuf { + let mut new_path = self.to_path_buf(); + new_path.add_extension(extension); + new_path + } + /// Produces an iterator over the [`Component`]s of the path. /// /// When parsing the path, there is a small amount of normalization: From 2699d8108cee47a86de22d8ac29344bcadfdbd45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 3 Jul 2024 23:23:38 +0000 Subject: [PATCH 659/892] Use shorter span for float literal suggestion --- .../infer/error_reporting/note_and_explain.rs | 6 +- tests/ui/consts/issue-39974.stderr | 10 ++- ...xpected-float-found-integer-literal.stderr | 33 +++++--- ...loat-literal-inference-restrictions.stderr | 11 ++- ...structure-constructor-type-mismatch.stderr | 80 +++++++++++-------- .../ui/try-block/try-block-type-error.stderr | 10 ++- 6 files changed, 91 insertions(+), 59 deletions(-) diff --git a/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs b/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs index bc59b5e033baa..fd50d1eb438aa 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs @@ -52,10 +52,10 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { ) = tcx.sess.source_map().span_to_snippet(sp) => { if snippet.chars().all(|c| c.is_digit(10) || c == '-' || c == '_') { - diag.span_suggestion( - sp, + diag.span_suggestion_verbose( + sp.shrink_to_hi(), "use a float literal", - format!("{snippet}.0"), + ".0", MachineApplicable, ); } diff --git a/tests/ui/consts/issue-39974.stderr b/tests/ui/consts/issue-39974.stderr index 114c4cfeaf7c0..a371ea5709e1b 100644 --- a/tests/ui/consts/issue-39974.stderr +++ b/tests/ui/consts/issue-39974.stderr @@ -2,10 +2,12 @@ error[E0308]: mismatched types --> $DIR/issue-39974.rs:1:21 | LL | const LENGTH: f64 = 2; - | ^ - | | - | expected `f64`, found integer - | help: use a float literal: `2.0` + | ^ expected `f64`, found integer + | +help: use a float literal + | +LL | const LENGTH: f64 = 2.0; + | ++ error[E0308]: mismatched types --> $DIR/issue-39974.rs:5:19 diff --git a/tests/ui/did_you_mean/issue-53280-expected-float-found-integer-literal.stderr b/tests/ui/did_you_mean/issue-53280-expected-float-found-integer-literal.stderr index 6f853ccab378a..6e32483aee49b 100644 --- a/tests/ui/did_you_mean/issue-53280-expected-float-found-integer-literal.stderr +++ b/tests/ui/did_you_mean/issue-53280-expected-float-found-integer-literal.stderr @@ -2,31 +2,40 @@ error[E0308]: mismatched types --> $DIR/issue-53280-expected-float-found-integer-literal.rs:2:24 | LL | let sixteen: f32 = 16; - | --- ^^ - | | | - | | expected `f32`, found integer - | | help: use a float literal: `16.0` + | --- ^^ expected `f32`, found integer + | | | expected due to this + | +help: use a float literal + | +LL | let sixteen: f32 = 16.0; + | ++ error[E0308]: mismatched types --> $DIR/issue-53280-expected-float-found-integer-literal.rs:5:38 | LL | let a_million_and_seventy: f64 = 1_000_070; - | --- ^^^^^^^^^ - | | | - | | expected `f64`, found integer - | | help: use a float literal: `1_000_070.0` + | --- ^^^^^^^^^ expected `f64`, found integer + | | | expected due to this + | +help: use a float literal + | +LL | let a_million_and_seventy: f64 = 1_000_070.0; + | ++ error[E0308]: mismatched types --> $DIR/issue-53280-expected-float-found-integer-literal.rs:8:30 | LL | let negative_nine: f32 = -9; - | --- ^^ - | | | - | | expected `f32`, found integer - | | help: use a float literal: `-9.0` + | --- ^^ expected `f32`, found integer + | | | expected due to this + | +help: use a float literal + | +LL | let negative_nine: f32 = -9.0; + | ++ error[E0308]: mismatched types --> $DIR/issue-53280-expected-float-found-integer-literal.rs:15:30 diff --git a/tests/ui/mismatched_types/float-literal-inference-restrictions.stderr b/tests/ui/mismatched_types/float-literal-inference-restrictions.stderr index 454373c322e9b..6b3e0cb505fe8 100644 --- a/tests/ui/mismatched_types/float-literal-inference-restrictions.stderr +++ b/tests/ui/mismatched_types/float-literal-inference-restrictions.stderr @@ -2,11 +2,14 @@ error[E0308]: mismatched types --> $DIR/float-literal-inference-restrictions.rs:2:18 | LL | let x: f32 = 1; - | --- ^ - | | | - | | expected `f32`, found integer - | | help: use a float literal: `1.0` + | --- ^ expected `f32`, found integer + | | | expected due to this + | +help: use a float literal + | +LL | let x: f32 = 1.0; + | ++ error[E0308]: mismatched types --> $DIR/float-literal-inference-restrictions.rs:3:18 diff --git a/tests/ui/structs/structure-constructor-type-mismatch.stderr b/tests/ui/structs/structure-constructor-type-mismatch.stderr index 63dda459396b8..cb9574873473f 100644 --- a/tests/ui/structs/structure-constructor-type-mismatch.stderr +++ b/tests/ui/structs/structure-constructor-type-mismatch.stderr @@ -2,55 +2,67 @@ error[E0308]: mismatched types --> $DIR/structure-constructor-type-mismatch.rs:17:12 | LL | x: 1, - | ^ - | | - | expected `f32`, found integer - | help: use a float literal: `1.0` + | ^ expected `f32`, found integer + | +help: use a float literal + | +LL | x: 1.0, + | ++ error[E0308]: mismatched types --> $DIR/structure-constructor-type-mismatch.rs:20:12 | LL | y: 2, - | ^ - | | - | expected `f32`, found integer - | help: use a float literal: `2.0` + | ^ expected `f32`, found integer + | +help: use a float literal + | +LL | y: 2.0, + | ++ error[E0308]: mismatched types --> $DIR/structure-constructor-type-mismatch.rs:26:12 | LL | x: 3, - | ^ - | | - | expected `f32`, found integer - | help: use a float literal: `3.0` + | ^ expected `f32`, found integer + | +help: use a float literal + | +LL | x: 3.0, + | ++ error[E0308]: mismatched types --> $DIR/structure-constructor-type-mismatch.rs:29:12 | LL | y: 4, - | ^ - | | - | expected `f32`, found integer - | help: use a float literal: `4.0` + | ^ expected `f32`, found integer + | +help: use a float literal + | +LL | y: 4.0, + | ++ error[E0308]: mismatched types --> $DIR/structure-constructor-type-mismatch.rs:35:12 | LL | x: 5, - | ^ - | | - | expected `f32`, found integer - | help: use a float literal: `5.0` + | ^ expected `f32`, found integer + | +help: use a float literal + | +LL | x: 5.0, + | ++ error[E0308]: mismatched types --> $DIR/structure-constructor-type-mismatch.rs:42:12 | LL | x: 7, - | ^ - | | - | expected `f32`, found integer - | help: use a float literal: `7.0` + | ^ expected `f32`, found integer + | +help: use a float literal + | +LL | x: 7.0, + | ++ error[E0107]: type alias takes 0 generic arguments but 1 generic argument was supplied --> $DIR/structure-constructor-type-mismatch.rs:48:15 @@ -70,19 +82,23 @@ error[E0308]: mismatched types --> $DIR/structure-constructor-type-mismatch.rs:49:12 | LL | x: 9, - | ^ - | | - | expected `f32`, found integer - | help: use a float literal: `9.0` + | ^ expected `f32`, found integer + | +help: use a float literal + | +LL | x: 9.0, + | ++ error[E0308]: mismatched types --> $DIR/structure-constructor-type-mismatch.rs:50:12 | LL | y: 10, - | ^^ - | | - | expected `f32`, found integer - | help: use a float literal: `10.0` + | ^^ expected `f32`, found integer + | +help: use a float literal + | +LL | y: 10.0, + | ++ error[E0107]: type alias takes 0 generic arguments but 1 generic argument was supplied --> $DIR/structure-constructor-type-mismatch.rs:54:9 diff --git a/tests/ui/try-block/try-block-type-error.stderr b/tests/ui/try-block/try-block-type-error.stderr index 3e9a584a5510a..2cdb5fdee79a1 100644 --- a/tests/ui/try-block/try-block-type-error.stderr +++ b/tests/ui/try-block/try-block-type-error.stderr @@ -2,10 +2,12 @@ error[E0271]: type mismatch resolving ` as Try>::Output == {integer} --> $DIR/try-block-type-error.rs:10:9 | LL | 42 - | ^^ - | | - | expected `f32`, found integer - | help: use a float literal: `42.0` + | ^^ expected `f32`, found integer + | +help: use a float literal + | +LL | 42.0 + | ++ error[E0271]: type mismatch resolving ` as Try>::Output == ()` --> $DIR/try-block-type-error.rs:16:5 From ff92ab09033d2b08689e8a1fafe607d51b01d8d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 3 Jul 2024 23:26:10 +0000 Subject: [PATCH 660/892] More accurate mutability suggestion --- .../src/diagnostics/mutability_errors.rs | 25 ++++---- .../borrow-raw-address-of-mutability.stderr | 8 ++- .../borrowck/borrowck-closures-unique.stderr | 7 +- tests/ui/borrowck/issue-111554.stderr | 7 +- ...5492-borrowck-migrate-scans-parents.stderr | 48 ++++++++------ tests/ui/borrowck/mutability-errors.stderr | 64 ++++++++++++------- .../cannot-mutate-captured-non-mut-var.stderr | 14 ++-- .../array_subslice.stderr | 8 ++- .../diagnostics/cant-mutate-imm.stderr | 16 +++-- .../closure-immutable-outer-variable.stderr | 7 +- tests/ui/fn/suggest-return-closure.stderr | 8 ++- tests/ui/nll/closure-captures.stderr | 48 ++++++++------ .../ui/nll/coroutine-upvar-mutability.stderr | 8 ++- tests/ui/nll/issue-46023.stderr | 8 ++- .../patkind-ref-binding-issue-114896.stderr | 7 +- .../patkind-ref-binding-issue-122415.stderr | 7 +- .../unboxed-closure-immutable-capture.stderr | 63 +++++++++++------- ...es-infer-fnmut-calling-fnmut-no-mut.stderr | 7 +- .../unboxed-closures-mutate-upvar.stderr | 24 ++++--- 19 files changed, 244 insertions(+), 140 deletions(-) diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs index 4174c75b2846f..677029f9d3f95 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs @@ -408,10 +408,10 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> { fn_decl.implicit_self, hir::ImplicitSelfKind::RefImm | hir::ImplicitSelfKind::RefMut ) { - err.span_suggestion( - upvar_ident.span, + err.span_suggestion_verbose( + upvar_ident.span.shrink_to_lo(), "consider changing this to be mutable", - format!("mut {}", upvar_ident.name), + "mut ", Applicability::MachineApplicable, ); break; @@ -419,10 +419,10 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> { } } } else { - err.span_suggestion( - upvar_ident.span, + err.span_suggestion_verbose( + upvar_ident.span.shrink_to_lo(), "consider changing this to be mutable", - format!("mut {}", upvar_ident.name), + "mut ", Applicability::MachineApplicable, ); } @@ -755,13 +755,16 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> { pat: hir::Pat { kind: hir::PatKind::Ref(_, _), .. }, .. }) = node - && let Ok(name) = - self.infcx.tcx.sess.source_map().span_to_snippet(local_decl.source_info.span) { - err.span_suggestion( - pat_span, + err.multipart_suggestion( "consider changing this to be mutable", - format!("&(mut {name})"), + vec![ + (pat_span.until(local_decl.source_info.span), "&(mut ".to_string()), + ( + local_decl.source_info.span.shrink_to_hi().with_hi(pat_span.hi()), + ")".to_string(), + ), + ], Applicability::MachineApplicable, ); return; diff --git a/tests/ui/borrowck/borrow-raw-address-of-mutability.stderr b/tests/ui/borrowck/borrow-raw-address-of-mutability.stderr index a774820918712..4b5b368287e16 100644 --- a/tests/ui/borrowck/borrow-raw-address-of-mutability.stderr +++ b/tests/ui/borrowck/borrow-raw-address-of-mutability.stderr @@ -12,11 +12,13 @@ LL | let mut x = 0; error[E0596]: cannot borrow `x` as mutable, as it is not declared as mutable --> $DIR/borrow-raw-address-of-mutability.rs:11:17 | -LL | let x = 0; - | - help: consider changing this to be mutable: `mut x` -LL | let mut f = || { LL | let y = &raw mut x; | ^^^^^^^^^^ cannot borrow as mutable + | +help: consider changing this to be mutable + | +LL | let mut x = 0; + | +++ error[E0596]: cannot borrow `f` as mutable, as it is not declared as mutable --> $DIR/borrow-raw-address-of-mutability.rs:21:5 diff --git a/tests/ui/borrowck/borrowck-closures-unique.stderr b/tests/ui/borrowck/borrowck-closures-unique.stderr index 23d3cc0e76ff7..613df9f2100c9 100644 --- a/tests/ui/borrowck/borrowck-closures-unique.stderr +++ b/tests/ui/borrowck/borrowck-closures-unique.stderr @@ -43,10 +43,13 @@ LL | c1; error[E0594]: cannot assign to `x`, as it is not declared as mutable --> $DIR/borrowck-closures-unique.rs:43:38 | -LL | fn e(x: &'static mut isize) { - | - help: consider changing this to be mutable: `mut x` LL | let c1 = |y: &'static mut isize| x = y; | ^^^^^ cannot assign + | +help: consider changing this to be mutable + | +LL | fn e(mut x: &'static mut isize) { + | +++ error: aborting due to 4 previous errors diff --git a/tests/ui/borrowck/issue-111554.stderr b/tests/ui/borrowck/issue-111554.stderr index 6b7a42e495999..b3e8caae34304 100644 --- a/tests/ui/borrowck/issue-111554.stderr +++ b/tests/ui/borrowck/issue-111554.stderr @@ -19,10 +19,13 @@ LL | || bar(&mut self); error[E0596]: cannot borrow `self` as mutable, as it is not declared as mutable --> $DIR/issue-111554.rs:21:16 | -LL | pub fn quux(self) { - | ---- help: consider changing this to be mutable: `mut self` LL | || bar(&mut self); | ^^^^^^^^^ cannot borrow as mutable + | +help: consider changing this to be mutable + | +LL | pub fn quux(mut self) { + | +++ error: aborting due to 4 previous errors diff --git a/tests/ui/borrowck/issue-55492-borrowck-migrate-scans-parents.stderr b/tests/ui/borrowck/issue-55492-borrowck-migrate-scans-parents.stderr index 098a2964e9fc7..ff5ec1db34634 100644 --- a/tests/ui/borrowck/issue-55492-borrowck-migrate-scans-parents.stderr +++ b/tests/ui/borrowck/issue-55492-borrowck-migrate-scans-parents.stderr @@ -44,56 +44,68 @@ LL | borrowck_closures_unique::e(addr_of_mut!(X)); error[E0594]: cannot assign to `x`, as it is not declared as mutable --> $DIR/issue-55492-borrowck-migrate-scans-parents.rs:9:46 | -LL | pub fn e(x: &'static mut isize) { - | - help: consider changing this to be mutable: `mut x` -LL | static mut Y: isize = 3; LL | let mut c1 = |y: &'static mut isize| x = y; | ^^^^^ cannot assign + | +help: consider changing this to be mutable + | +LL | pub fn e(mut x: &'static mut isize) { + | +++ error[E0594]: cannot assign to `x`, as it is not declared as mutable --> $DIR/issue-55492-borrowck-migrate-scans-parents.rs:22:50 | -LL | pub fn ee(x: &'static mut isize) { - | - help: consider changing this to be mutable: `mut x` -... LL | let mut c2 = |y: &'static mut isize| x = y; | ^^^^^ cannot assign + | +help: consider changing this to be mutable + | +LL | pub fn ee(mut x: &'static mut isize) { + | +++ error[E0594]: cannot assign to `x`, as it is not declared as mutable --> $DIR/issue-55492-borrowck-migrate-scans-parents.rs:37:13 | -LL | pub fn capture_assign_whole(x: (i32,)) { - | - help: consider changing this to be mutable: `mut x` -LL | || { LL | x = (1,); | ^^^^^^^^ cannot assign + | +help: consider changing this to be mutable + | +LL | pub fn capture_assign_whole(mut x: (i32,)) { + | +++ error[E0594]: cannot assign to `x.0`, as `x` is not declared as mutable --> $DIR/issue-55492-borrowck-migrate-scans-parents.rs:43:13 | -LL | pub fn capture_assign_part(x: (i32,)) { - | - help: consider changing this to be mutable: `mut x` -LL | || { LL | x.0 = 1; | ^^^^^^^ cannot assign + | +help: consider changing this to be mutable + | +LL | pub fn capture_assign_part(mut x: (i32,)) { + | +++ error[E0596]: cannot borrow `x` as mutable, as it is not declared as mutable --> $DIR/issue-55492-borrowck-migrate-scans-parents.rs:49:13 | -LL | pub fn capture_reborrow_whole(x: (i32,)) { - | - help: consider changing this to be mutable: `mut x` -LL | || { LL | &mut x; | ^^^^^^ cannot borrow as mutable + | +help: consider changing this to be mutable + | +LL | pub fn capture_reborrow_whole(mut x: (i32,)) { + | +++ error[E0596]: cannot borrow `x.0` as mutable, as `x` is not declared as mutable --> $DIR/issue-55492-borrowck-migrate-scans-parents.rs:55:13 | -LL | pub fn capture_reborrow_part(x: (i32,)) { - | - help: consider changing this to be mutable: `mut x` -LL | || { LL | &mut x.0; | ^^^^^^^^ cannot borrow as mutable + | +help: consider changing this to be mutable + | +LL | pub fn capture_reborrow_part(mut x: (i32,)) { + | +++ error: aborting due to 6 previous errors; 3 warnings emitted diff --git a/tests/ui/borrowck/mutability-errors.stderr b/tests/ui/borrowck/mutability-errors.stderr index b39e57d70ec65..3cab3ccb993c9 100644 --- a/tests/ui/borrowck/mutability-errors.stderr +++ b/tests/ui/borrowck/mutability-errors.stderr @@ -262,74 +262,90 @@ LL | fn imm_local(mut x: (i32,)) { error[E0594]: cannot assign to `x`, as it is not declared as mutable --> $DIR/mutability-errors.rs:60:9 | -LL | fn imm_capture(x: (i32,)) { - | - help: consider changing this to be mutable: `mut x` -LL | || { LL | x = (1,); | ^^^^^^^^ cannot assign + | +help: consider changing this to be mutable + | +LL | fn imm_capture(mut x: (i32,)) { + | +++ error[E0594]: cannot assign to `x.0`, as `x` is not declared as mutable --> $DIR/mutability-errors.rs:61:9 | -LL | fn imm_capture(x: (i32,)) { - | - help: consider changing this to be mutable: `mut x` -... LL | x.0 = 1; | ^^^^^^^ cannot assign + | +help: consider changing this to be mutable + | +LL | fn imm_capture(mut x: (i32,)) { + | +++ error[E0596]: cannot borrow `x` as mutable, as it is not declared as mutable --> $DIR/mutability-errors.rs:62:9 | -LL | fn imm_capture(x: (i32,)) { - | - help: consider changing this to be mutable: `mut x` -... LL | &mut x; | ^^^^^^ cannot borrow as mutable + | +help: consider changing this to be mutable + | +LL | fn imm_capture(mut x: (i32,)) { + | +++ error[E0596]: cannot borrow `x.0` as mutable, as `x` is not declared as mutable --> $DIR/mutability-errors.rs:63:9 | -LL | fn imm_capture(x: (i32,)) { - | - help: consider changing this to be mutable: `mut x` -... LL | &mut x.0; | ^^^^^^^^ cannot borrow as mutable + | +help: consider changing this to be mutable + | +LL | fn imm_capture(mut x: (i32,)) { + | +++ error[E0594]: cannot assign to `x`, as it is not declared as mutable --> $DIR/mutability-errors.rs:66:9 | -LL | fn imm_capture(x: (i32,)) { - | - help: consider changing this to be mutable: `mut x` -... LL | x = (1,); | ^^^^^^^^ cannot assign + | +help: consider changing this to be mutable + | +LL | fn imm_capture(mut x: (i32,)) { + | +++ error[E0594]: cannot assign to `x.0`, as `x` is not declared as mutable --> $DIR/mutability-errors.rs:67:9 | -LL | fn imm_capture(x: (i32,)) { - | - help: consider changing this to be mutable: `mut x` -... LL | x.0 = 1; | ^^^^^^^ cannot assign + | +help: consider changing this to be mutable + | +LL | fn imm_capture(mut x: (i32,)) { + | +++ error[E0596]: cannot borrow `x` as mutable, as it is not declared as mutable --> $DIR/mutability-errors.rs:68:9 | -LL | fn imm_capture(x: (i32,)) { - | - help: consider changing this to be mutable: `mut x` -... LL | &mut x; | ^^^^^^ cannot borrow as mutable + | +help: consider changing this to be mutable + | +LL | fn imm_capture(mut x: (i32,)) { + | +++ error[E0596]: cannot borrow `x.0` as mutable, as `x` is not declared as mutable --> $DIR/mutability-errors.rs:69:9 | -LL | fn imm_capture(x: (i32,)) { - | - help: consider changing this to be mutable: `mut x` -... LL | &mut x.0; | ^^^^^^^^ cannot borrow as mutable + | +help: consider changing this to be mutable + | +LL | fn imm_capture(mut x: (i32,)) { + | +++ error[E0594]: cannot assign to immutable static item `X` --> $DIR/mutability-errors.rs:76:5 diff --git a/tests/ui/cannot-mutate-captured-non-mut-var.stderr b/tests/ui/cannot-mutate-captured-non-mut-var.stderr index 2d6e83c9e82f9..8d794f8251f14 100644 --- a/tests/ui/cannot-mutate-captured-non-mut-var.stderr +++ b/tests/ui/cannot-mutate-captured-non-mut-var.stderr @@ -1,18 +1,24 @@ error[E0594]: cannot assign to `x`, as it is not declared as mutable --> $DIR/cannot-mutate-captured-non-mut-var.rs:9:25 | -LL | let x = 1; - | - help: consider changing this to be mutable: `mut x` LL | to_fn_once(move|| { x = 2; }); | ^^^^^ cannot assign + | +help: consider changing this to be mutable + | +LL | let mut x = 1; + | +++ error[E0596]: cannot borrow `s` as mutable, as it is not declared as mutable --> $DIR/cannot-mutate-captured-non-mut-var.rs:13:25 | -LL | let s = std::io::stdin(); - | - help: consider changing this to be mutable: `mut s` LL | to_fn_once(move|| { s.read_to_end(&mut Vec::new()); }); | ^ cannot borrow as mutable + | +help: consider changing this to be mutable + | +LL | let mut s = std::io::stdin(); + | +++ error: aborting due to 2 previous errors diff --git a/tests/ui/closures/2229_closure_analysis/array_subslice.stderr b/tests/ui/closures/2229_closure_analysis/array_subslice.stderr index 888c60d5e91fb..ee941caa77373 100644 --- a/tests/ui/closures/2229_closure_analysis/array_subslice.stderr +++ b/tests/ui/closures/2229_closure_analysis/array_subslice.stderr @@ -1,11 +1,13 @@ error[E0596]: cannot borrow `x[..]` as mutable, as `x` is not declared as mutable --> $DIR/array_subslice.rs:7:21 | -LL | pub fn subslice_array(x: [u8; 3]) { - | - help: consider changing this to be mutable: `mut x` -... LL | let [ref y, ref mut z @ ..] = x; | ^^^^^^^^^ cannot borrow as mutable + | +help: consider changing this to be mutable + | +LL | pub fn subslice_array(mut x: [u8; 3]) { + | +++ error[E0596]: cannot borrow `f` as mutable, as it is not declared as mutable --> $DIR/array_subslice.rs:10:5 diff --git a/tests/ui/closures/2229_closure_analysis/diagnostics/cant-mutate-imm.stderr b/tests/ui/closures/2229_closure_analysis/diagnostics/cant-mutate-imm.stderr index 98414fa8a3d5f..6f5043ef08de1 100644 --- a/tests/ui/closures/2229_closure_analysis/diagnostics/cant-mutate-imm.stderr +++ b/tests/ui/closures/2229_closure_analysis/diagnostics/cant-mutate-imm.stderr @@ -1,20 +1,24 @@ error[E0594]: cannot assign to `z.0.0.0`, as it is not declared as mutable --> $DIR/cant-mutate-imm.rs:12:9 | -LL | let z = (y, 10); - | - help: consider changing this to be mutable: `mut z` -... LL | z.0.0.0 = 20; | ^^^^^^^^^^^^ cannot assign + | +help: consider changing this to be mutable + | +LL | let mut z = (y, 10); + | +++ error[E0594]: cannot assign to `*bx.0`, as it is not declared as mutable --> $DIR/cant-mutate-imm.rs:24:9 | -LL | let bx = Box::new(x); - | -- help: consider changing this to be mutable: `mut bx` -... LL | bx.0 = 20; | ^^^^^^^^^ cannot assign + | +help: consider changing this to be mutable + | +LL | let mut bx = Box::new(x); + | +++ error: aborting due to 2 previous errors diff --git a/tests/ui/closures/closure-immutable-outer-variable.stderr b/tests/ui/closures/closure-immutable-outer-variable.stderr index 23bd0020db6b3..c4b0e5449579d 100644 --- a/tests/ui/closures/closure-immutable-outer-variable.stderr +++ b/tests/ui/closures/closure-immutable-outer-variable.stderr @@ -1,10 +1,13 @@ error[E0594]: cannot assign to `y`, as it is not declared as mutable --> $DIR/closure-immutable-outer-variable.rs:11:26 | -LL | let y = true; - | - help: consider changing this to be mutable: `mut y` LL | foo(Box::new(move || y = !y) as Box<_>); | ^^^^^^ cannot assign + | +help: consider changing this to be mutable + | +LL | let mut y = true; + | +++ error: aborting due to 1 previous error diff --git a/tests/ui/fn/suggest-return-closure.stderr b/tests/ui/fn/suggest-return-closure.stderr index d276ce8be2ba5..45c12b548e678 100644 --- a/tests/ui/fn/suggest-return-closure.stderr +++ b/tests/ui/fn/suggest-return-closure.stderr @@ -34,11 +34,13 @@ LL | fn fun() -> _ { error[E0596]: cannot borrow `x` as mutable, as it is not declared as mutable --> $DIR/suggest-return-closure.rs:23:9 | -LL | let x = String::new(); - | - help: consider changing this to be mutable: `mut x` -... LL | x.push(c); | ^ cannot borrow as mutable + | +help: consider changing this to be mutable + | +LL | let mut x = String::new(); + | +++ error[E0597]: `x` does not live long enough --> $DIR/suggest-return-closure.rs:23:9 diff --git a/tests/ui/nll/closure-captures.stderr b/tests/ui/nll/closure-captures.stderr index 5233f0b246261..828974c517e60 100644 --- a/tests/ui/nll/closure-captures.stderr +++ b/tests/ui/nll/closure-captures.stderr @@ -1,38 +1,46 @@ error[E0594]: cannot assign to `x`, as it is not declared as mutable --> $DIR/closure-captures.rs:7:5 | -LL | fn one_closure(x: i32) { - | - help: consider changing this to be mutable: `mut x` -LL | || LL | x = 1; | ^^^^^ cannot assign + | +help: consider changing this to be mutable + | +LL | fn one_closure(mut x: i32) { + | +++ error[E0594]: cannot assign to `x`, as it is not declared as mutable --> $DIR/closure-captures.rs:9:5 | -LL | fn one_closure(x: i32) { - | - help: consider changing this to be mutable: `mut x` -... LL | x = 1; | ^^^^^ cannot assign + | +help: consider changing this to be mutable + | +LL | fn one_closure(mut x: i32) { + | +++ error[E0594]: cannot assign to `x`, as it is not declared as mutable --> $DIR/closure-captures.rs:15:9 | -LL | fn two_closures(x: i32) { - | - help: consider changing this to be mutable: `mut x` -... LL | x = 1; | ^^^^^ cannot assign + | +help: consider changing this to be mutable + | +LL | fn two_closures(mut x: i32) { + | +++ error[E0594]: cannot assign to `x`, as it is not declared as mutable --> $DIR/closure-captures.rs:19:9 | -LL | fn two_closures(x: i32) { - | - help: consider changing this to be mutable: `mut x` -... LL | x = 1; | ^^^^^ cannot assign + | +help: consider changing this to be mutable + | +LL | fn two_closures(mut x: i32) { + | +++ error[E0596]: cannot borrow `x` as mutable, as it is a captured variable in a `Fn` closure --> $DIR/closure-captures.rs:27:9 @@ -67,11 +75,13 @@ LL | x = 1;}); error[E0594]: cannot assign to `x`, as it is not declared as mutable --> $DIR/closure-captures.rs:39:10 | -LL | fn two_closures_ref(x: i32) { - | - help: consider changing this to be mutable: `mut x` -... LL | x = 1;} | ^^^^^ cannot assign + | +help: consider changing this to be mutable + | +LL | fn two_closures_ref(mut x: i32) { + | +++ error[E0596]: cannot borrow `x` as mutable, as it is a captured variable in a `Fn` closure --> $DIR/closure-captures.rs:38:9 @@ -91,11 +101,13 @@ LL | x = 1;} error[E0594]: cannot assign to `x`, as it is not declared as mutable --> $DIR/closure-captures.rs:43:5 | -LL | fn two_closures_ref(x: i32) { - | - help: consider changing this to be mutable: `mut x` -... LL | x = 1;}); | ^^^^^ cannot assign + | +help: consider changing this to be mutable + | +LL | fn two_closures_ref(mut x: i32) { + | +++ error[E0596]: cannot borrow `x` as mutable, as it is a captured variable in a `Fn` closure --> $DIR/closure-captures.rs:42:9 diff --git a/tests/ui/nll/coroutine-upvar-mutability.stderr b/tests/ui/nll/coroutine-upvar-mutability.stderr index 8b9be877c8f39..02c011301761c 100644 --- a/tests/ui/nll/coroutine-upvar-mutability.stderr +++ b/tests/ui/nll/coroutine-upvar-mutability.stderr @@ -1,11 +1,13 @@ error[E0594]: cannot assign to `x`, as it is not declared as mutable --> $DIR/coroutine-upvar-mutability.rs:10:9 | -LL | let x = 0; - | - help: consider changing this to be mutable: `mut x` -... LL | x = 1; | ^^^^^ cannot assign + | +help: consider changing this to be mutable + | +LL | let mut x = 0; + | +++ error: aborting due to 1 previous error diff --git a/tests/ui/nll/issue-46023.stderr b/tests/ui/nll/issue-46023.stderr index 062e07407ce09..d071c29271c58 100644 --- a/tests/ui/nll/issue-46023.stderr +++ b/tests/ui/nll/issue-46023.stderr @@ -1,11 +1,13 @@ error[E0594]: cannot assign to `x`, as it is not declared as mutable --> $DIR/issue-46023.rs:5:9 | -LL | let x = 0; - | - help: consider changing this to be mutable: `mut x` -... LL | x = 1; | ^^^^^ cannot assign + | +help: consider changing this to be mutable + | +LL | let mut x = 0; + | +++ error: aborting due to 1 previous error diff --git a/tests/ui/pattern/patkind-ref-binding-issue-114896.stderr b/tests/ui/pattern/patkind-ref-binding-issue-114896.stderr index 68538255eddf0..e9c2fccaba284 100644 --- a/tests/ui/pattern/patkind-ref-binding-issue-114896.stderr +++ b/tests/ui/pattern/patkind-ref-binding-issue-114896.stderr @@ -1,10 +1,13 @@ error[E0596]: cannot borrow `b` as mutable, as it is not declared as mutable --> $DIR/patkind-ref-binding-issue-114896.rs:7:9 | -LL | let &b = a; - | -- help: consider changing this to be mutable: `&(mut b)` LL | b.make_ascii_uppercase(); | ^ cannot borrow as mutable + | +help: consider changing this to be mutable + | +LL | let &(mut b) = a; + | ~~~~~ + error: aborting due to 1 previous error diff --git a/tests/ui/pattern/patkind-ref-binding-issue-122415.stderr b/tests/ui/pattern/patkind-ref-binding-issue-122415.stderr index 39283133ac7c8..e93b8bbacccdd 100644 --- a/tests/ui/pattern/patkind-ref-binding-issue-122415.stderr +++ b/tests/ui/pattern/patkind-ref-binding-issue-122415.stderr @@ -1,10 +1,13 @@ error[E0596]: cannot borrow `x` as mutable, as it is not declared as mutable --> $DIR/patkind-ref-binding-issue-122415.rs:7:12 | -LL | fn foo(&x: &i32) { - | -- help: consider changing this to be mutable: `&(mut x)` LL | mutate(&mut x); | ^^^^^^ cannot borrow as mutable + | +help: consider changing this to be mutable + | +LL | fn foo(&(mut x): &i32) { + | ~~~~~ + error: aborting due to 1 previous error diff --git a/tests/ui/unboxed-closures/unboxed-closure-immutable-capture.stderr b/tests/ui/unboxed-closures/unboxed-closure-immutable-capture.stderr index ad5451ced55d0..04f9ab246b315 100644 --- a/tests/ui/unboxed-closures/unboxed-closure-immutable-capture.stderr +++ b/tests/ui/unboxed-closures/unboxed-closure-immutable-capture.stderr @@ -1,73 +1,90 @@ error[E0594]: cannot assign to `x`, as it is not declared as mutable --> $DIR/unboxed-closure-immutable-capture.rs:9:13 | -LL | let x = 0; - | - help: consider changing this to be mutable: `mut x` LL | move || x = 1; | ^^^^^ cannot assign + | +help: consider changing this to be mutable + | +LL | let mut x = 0; + | +++ error[E0596]: cannot borrow `x` as mutable, as it is not declared as mutable --> $DIR/unboxed-closure-immutable-capture.rs:10:17 | -LL | let x = 0; - | - help: consider changing this to be mutable: `mut x` -LL | move || x = 1; LL | move || set(&mut x); | ^^^^^^ cannot borrow as mutable + | +help: consider changing this to be mutable + | +LL | let mut x = 0; + | +++ error[E0594]: cannot assign to `x`, as it is not declared as mutable --> $DIR/unboxed-closure-immutable-capture.rs:11:13 | -LL | let x = 0; - | - help: consider changing this to be mutable: `mut x` -... LL | move || x = 1; | ^^^^^ cannot assign + | +help: consider changing this to be mutable + | +LL | let mut x = 0; + | +++ error[E0596]: cannot borrow `x` as mutable, as it is not declared as mutable --> $DIR/unboxed-closure-immutable-capture.rs:12:17 | -LL | let x = 0; - | - help: consider changing this to be mutable: `mut x` -... LL | move || set(&mut x); | ^^^^^^ cannot borrow as mutable + | +help: consider changing this to be mutable + | +LL | let mut x = 0; + | +++ error[E0594]: cannot assign to `x`, as it is not declared as mutable --> $DIR/unboxed-closure-immutable-capture.rs:13:8 | -LL | let x = 0; - | - help: consider changing this to be mutable: `mut x` -... LL | || x = 1; | ^^^^^ cannot assign + | +help: consider changing this to be mutable + | +LL | let mut x = 0; + | +++ error[E0596]: cannot borrow `x` as mutable, as it is not declared as mutable --> $DIR/unboxed-closure-immutable-capture.rs:14:12 | -LL | let x = 0; - | - help: consider changing this to be mutable: `mut x` -... LL | || set(&mut x); | ^^^^^^ cannot borrow as mutable + | +help: consider changing this to be mutable + | +LL | let mut x = 0; + | +++ error[E0594]: cannot assign to `x`, as it is not declared as mutable --> $DIR/unboxed-closure-immutable-capture.rs:15:8 | -LL | let x = 0; - | - help: consider changing this to be mutable: `mut x` -... LL | || x = 1; | ^^^^^ cannot assign + | +help: consider changing this to be mutable + | +LL | let mut x = 0; + | +++ error[E0596]: cannot borrow `x` as mutable, as it is not declared as mutable --> $DIR/unboxed-closure-immutable-capture.rs:16:12 | -LL | let x = 0; - | - help: consider changing this to be mutable: `mut x` -... LL | || set(&mut x); | ^^^^^^ cannot borrow as mutable + | +help: consider changing this to be mutable + | +LL | let mut x = 0; + | +++ error: aborting due to 8 previous errors diff --git a/tests/ui/unboxed-closures/unboxed-closures-infer-fnmut-calling-fnmut-no-mut.stderr b/tests/ui/unboxed-closures/unboxed-closures-infer-fnmut-calling-fnmut-no-mut.stderr index 5c93ed6d7f70f..07c66276eaf05 100644 --- a/tests/ui/unboxed-closures/unboxed-closures-infer-fnmut-calling-fnmut-no-mut.stderr +++ b/tests/ui/unboxed-closures/unboxed-closures-infer-fnmut-calling-fnmut-no-mut.stderr @@ -1,13 +1,16 @@ error[E0596]: cannot borrow `tick1` as mutable, as it is not declared as mutable --> $DIR/unboxed-closures-infer-fnmut-calling-fnmut-no-mut.rs:16:9 | -LL | let tick1 = || { - | ----- help: consider changing this to be mutable: `mut tick1` LL | counter += 1; | ------- calling `tick1` requires mutable binding due to mutable borrow of `counter` ... LL | tick1(); | ^^^^^ cannot borrow as mutable + | +help: consider changing this to be mutable + | +LL | let mut tick1 = || { + | +++ error[E0596]: cannot borrow `tick2` as mutable, as it is not declared as mutable --> $DIR/unboxed-closures-infer-fnmut-calling-fnmut-no-mut.rs:19:5 diff --git a/tests/ui/unboxed-closures/unboxed-closures-mutate-upvar.stderr b/tests/ui/unboxed-closures/unboxed-closures-mutate-upvar.stderr index 26f97b51913df..80caddb2a11e1 100644 --- a/tests/ui/unboxed-closures/unboxed-closures-mutate-upvar.stderr +++ b/tests/ui/unboxed-closures/unboxed-closures-mutate-upvar.stderr @@ -1,29 +1,35 @@ error[E0594]: cannot assign to `n`, as it is not declared as mutable --> $DIR/unboxed-closures-mutate-upvar.rs:15:9 | -LL | let n = 0; - | - help: consider changing this to be mutable: `mut n` -LL | let mut f = to_fn_mut(|| { LL | n += 1; | ^^^^^^ cannot assign + | +help: consider changing this to be mutable + | +LL | let mut n = 0; + | +++ error[E0594]: cannot assign to `n`, as it is not declared as mutable --> $DIR/unboxed-closures-mutate-upvar.rs:32:9 | -LL | let n = 0; - | - help: consider changing this to be mutable: `mut n` -... LL | n += 1; | ^^^^^^ cannot assign + | +help: consider changing this to be mutable + | +LL | let mut n = 0; + | +++ error[E0594]: cannot assign to `n`, as it is not declared as mutable --> $DIR/unboxed-closures-mutate-upvar.rs:46:9 | -LL | let n = 0; - | - help: consider changing this to be mutable: `mut n` -LL | let mut f = to_fn(move || { LL | n += 1; | ^^^^^^ cannot assign + | +help: consider changing this to be mutable + | +LL | let mut n = 0; + | +++ error[E0594]: cannot assign to `n`, as it is a captured variable in a `Fn` closure --> $DIR/unboxed-closures-mutate-upvar.rs:53:9 From 8ea1066fe6605d85969d403080b2c5d93376797e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 4 Jul 2024 00:22:26 +0000 Subject: [PATCH 661/892] Tweak slice and as_deref suggestion span Use multispan suggestion. --- compiler/rustc_hir_typeck/src/pat.rs | 13 +++--- .../ui/let-else/let-else-slicing-error.stderr | 9 ++-- tests/ui/suggestions/match-ergonomics.stderr | 14 ++++-- tests/ui/suggestions/pattern-slice-vec.stderr | 44 ++++++++++++------- ...press-consider-slicing-issue-120605.stderr | 9 ++-- tests/ui/typeck/issue-53712.rs | 2 +- tests/ui/typeck/issue-91328.stderr | 32 +++++++++----- 7 files changed, 78 insertions(+), 45 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index f932a27e9a287..478bbc0ed9855 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -2499,7 +2499,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .any(|(ty, _)| matches!(ty.kind(), ty::Slice(..) | ty::Array(..))) && let Some(span) = ti.span && let Some(_) = ti.origin_expr - && let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) { let resolved_ty = self.resolve_vars_if_possible(ti.expected); let (is_slice_or_array_or_vector, resolved_ty) = @@ -2510,10 +2509,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { || self.tcx.is_diagnostic_item(sym::Result, adt_def.did()) => { // Slicing won't work here, but `.as_deref()` might (issue #91328). - err.span_suggestion( - span, + err.span_suggestion_verbose( + span.shrink_to_hi(), "consider using `as_deref` here", - format!("{snippet}.as_deref()"), + ".as_deref()", Applicability::MaybeIncorrect, ); } @@ -2522,10 +2521,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let is_top_level = current_depth <= 1; if is_slice_or_array_or_vector && is_top_level { - err.span_suggestion( - span, + err.span_suggestion_verbose( + span.shrink_to_hi(), "consider slicing here", - format!("{snippet}[..]"), + "[..]", Applicability::MachineApplicable, ); } diff --git a/tests/ui/let-else/let-else-slicing-error.stderr b/tests/ui/let-else/let-else-slicing-error.stderr index 73c357dd5d462..4daae861965cd 100644 --- a/tests/ui/let-else/let-else-slicing-error.stderr +++ b/tests/ui/let-else/let-else-slicing-error.stderr @@ -2,9 +2,12 @@ error[E0529]: expected an array or slice, found `Vec<{integer}>` --> $DIR/let-else-slicing-error.rs:6:9 | LL | let [x, y] = nums else { - | ^^^^^^ ---- help: consider slicing here: `nums[..]` - | | - | pattern cannot match with input type `Vec<{integer}>` + | ^^^^^^ pattern cannot match with input type `Vec<{integer}>` + | +help: consider slicing here + | +LL | let [x, y] = nums[..] else { + | ++++ error: aborting due to 1 previous error diff --git a/tests/ui/suggestions/match-ergonomics.stderr b/tests/ui/suggestions/match-ergonomics.stderr index a3e059e8ac646..2cd43c26ca378 100644 --- a/tests/ui/suggestions/match-ergonomics.stderr +++ b/tests/ui/suggestions/match-ergonomics.stderr @@ -17,18 +17,24 @@ LL + [v] => {}, error[E0529]: expected an array or slice, found `Vec` --> $DIR/match-ergonomics.rs:8:9 | -LL | match x { - | - help: consider slicing here: `x[..]` LL | [&v] => {}, | ^^^^ pattern cannot match with input type `Vec` + | +help: consider slicing here + | +LL | match x[..] { + | ++++ error[E0529]: expected an array or slice, found `Vec` --> $DIR/match-ergonomics.rs:20:9 | -LL | match x { - | - help: consider slicing here: `x[..]` LL | [v] => {}, | ^^^ pattern cannot match with input type `Vec` + | +help: consider slicing here + | +LL | match x[..] { + | ++++ error[E0308]: mismatched types --> $DIR/match-ergonomics.rs:29:9 diff --git a/tests/ui/suggestions/pattern-slice-vec.stderr b/tests/ui/suggestions/pattern-slice-vec.stderr index f69e7de971a96..36a9df3f7505e 100644 --- a/tests/ui/suggestions/pattern-slice-vec.stderr +++ b/tests/ui/suggestions/pattern-slice-vec.stderr @@ -2,42 +2,56 @@ error[E0529]: expected an array or slice, found `Vec` --> $DIR/pattern-slice-vec.rs:8:12 | LL | if let [_, _, _] = foo() {} - | ^^^^^^^^^ ----- help: consider slicing here: `foo()[..]` - | | - | pattern cannot match with input type `Vec` + | ^^^^^^^^^ pattern cannot match with input type `Vec` + | +help: consider slicing here + | +LL | if let [_, _, _] = foo()[..] {} + | ++++ error[E0529]: expected an array or slice, found `Vec` --> $DIR/pattern-slice-vec.rs:12:12 | LL | if let [] = &foo() {} - | ^^ ------ help: consider slicing here: `&foo()[..]` - | | - | pattern cannot match with input type `Vec` + | ^^ pattern cannot match with input type `Vec` + | +help: consider slicing here + | +LL | if let [] = &foo()[..] {} + | ++++ error[E0529]: expected an array or slice, found `Vec` --> $DIR/pattern-slice-vec.rs:16:12 | LL | if let [] = foo() {} - | ^^ ----- help: consider slicing here: `foo()[..]` - | | - | pattern cannot match with input type `Vec` + | ^^ pattern cannot match with input type `Vec` + | +help: consider slicing here + | +LL | if let [] = foo()[..] {} + | ++++ error[E0529]: expected an array or slice, found `Vec<_>` --> $DIR/pattern-slice-vec.rs:23:9 | -LL | match &v { - | -- help: consider slicing here: `&v[..]` -LL | LL | [5] => {} | ^^^ pattern cannot match with input type `Vec<_>` + | +help: consider slicing here + | +LL | match &v[..] { + | ++++ error[E0529]: expected an array or slice, found `Vec<{integer}>` --> $DIR/pattern-slice-vec.rs:28:9 | LL | let [..] = vec![1, 2, 3]; - | ^^^^ ------------- help: consider slicing here: `vec![1, 2, 3][..]` - | | - | pattern cannot match with input type `Vec<{integer}>` + | ^^^^ pattern cannot match with input type `Vec<{integer}>` + | +help: consider slicing here + | +LL | let [..] = vec![1, 2, 3][..]; + | ++++ error: aborting due to 5 previous errors diff --git a/tests/ui/suggestions/suppress-consider-slicing-issue-120605.stderr b/tests/ui/suggestions/suppress-consider-slicing-issue-120605.stderr index c28d67604da9f..cab9bbb72df3b 100644 --- a/tests/ui/suggestions/suppress-consider-slicing-issue-120605.stderr +++ b/tests/ui/suggestions/suppress-consider-slicing-issue-120605.stderr @@ -2,9 +2,12 @@ error[E0529]: expected an array or slice, found `Vec` --> $DIR/suppress-consider-slicing-issue-120605.rs:7:16 | LL | if let [Struct { a: [] }] = &self.a { - | ^^^^^^^^^^^^^^^^^^ ------- help: consider slicing here: `&self.a[..]` - | | - | pattern cannot match with input type `Vec` + | ^^^^^^^^^^^^^^^^^^ pattern cannot match with input type `Vec` + | +help: consider slicing here + | +LL | if let [Struct { a: [] }] = &self.a[..] { + | ++++ error[E0529]: expected an array or slice, found `Vec` --> $DIR/suppress-consider-slicing-issue-120605.rs:7:29 diff --git a/tests/ui/typeck/issue-53712.rs b/tests/ui/typeck/issue-53712.rs index 2353904d79d75..49db4fa306a7c 100644 --- a/tests/ui/typeck/issue-53712.rs +++ b/tests/ui/typeck/issue-53712.rs @@ -5,5 +5,5 @@ fn main() { arr.0; //~^ ERROR no field `0` on type `[{integer}; 5]` [E0609] //~| HELP instead of using tuple indexing, use array indexing - //~| SUGGESTION arr[0] + //~| SUGGESTION [ } diff --git a/tests/ui/typeck/issue-91328.stderr b/tests/ui/typeck/issue-91328.stderr index f2f407bcafff2..f9016400fd7af 100644 --- a/tests/ui/typeck/issue-91328.stderr +++ b/tests/ui/typeck/issue-91328.stderr @@ -1,38 +1,46 @@ error[E0529]: expected an array or slice, found `Vec` --> $DIR/issue-91328.rs:10:12 | -LL | match r { - | - help: consider using `as_deref` here: `r.as_deref()` -LL | LL | Ok([a, b]) => a + b, | ^^^^^^ pattern cannot match with input type `Vec` + | +help: consider using `as_deref` here + | +LL | match r.as_deref() { + | +++++++++++ error[E0529]: expected an array or slice, found `Vec` --> $DIR/issue-91328.rs:20:14 | -LL | match o { - | - help: consider using `as_deref` here: `o.as_deref()` -LL | LL | Some([a, b]) => a + b, | ^^^^^^ pattern cannot match with input type `Vec` + | +help: consider using `as_deref` here + | +LL | match o.as_deref() { + | +++++++++++ error[E0529]: expected an array or slice, found `Vec` --> $DIR/issue-91328.rs:30:9 | -LL | match v { - | - help: consider slicing here: `v[..]` -LL | LL | [a, b] => a + b, | ^^^^^^ pattern cannot match with input type `Vec` + | +help: consider slicing here + | +LL | match v[..] { + | ++++ error[E0529]: expected an array or slice, found `Box<[i32; 2]>` --> $DIR/issue-91328.rs:40:14 | -LL | match a { - | - help: consider using `as_deref` here: `a.as_deref()` -LL | LL | Some([a, b]) => a + b, | ^^^^^^ pattern cannot match with input type `Box<[i32; 2]>` + | +help: consider using `as_deref` here + | +LL | match a.as_deref() { + | +++++++++++ error: aborting due to 4 previous errors From a5e7da0cf6cd7b03ad9d1079aab978b52007b221 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 4 Jul 2024 00:24:10 +0000 Subject: [PATCH 662/892] Tweak raw-pointer field access and array indexing suggestions --- compiler/rustc_hir_typeck/src/expr.rs | 44 +++++++++++-------- tests/ui/issues/issue-11004.stderr | 20 +++++---- .../parenthesized-deref-suggestion.stderr | 14 +++--- tests/ui/typeck/issue-53712.stderr | 10 +++-- tests/ui/unsafe/unsafe-fn-autoderef.stderr | 10 +++-- 5 files changed, 58 insertions(+), 40 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index f3aece4e1d8aa..bd5e5294983d2 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -2551,10 +2551,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { match *base_ty.peel_refs().kind() { ty::Array(_, len) => { - self.maybe_suggest_array_indexing(&mut err, expr, base, ident, len); + self.maybe_suggest_array_indexing(&mut err, base, ident, len); } ty::RawPtr(..) => { - self.suggest_first_deref_field(&mut err, expr, base, ident); + self.suggest_first_deref_field(&mut err, base, ident); } ty::Param(param_ty) => { err.span_label(ident.span, "unknown field"); @@ -2721,7 +2721,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { fn maybe_suggest_array_indexing( &self, err: &mut Diag<'_>, - expr: &hir::Expr<'_>, base: &hir::Expr<'_>, field: Ident, len: ty::Const<'tcx>, @@ -2729,32 +2728,41 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { err.span_label(field.span, "unknown field"); if let (Some(len), Ok(user_index)) = (len.try_eval_target_usize(self.tcx, self.param_env), field.as_str().parse::()) - && let Ok(base) = self.tcx.sess.source_map().span_to_snippet(base.span) { let help = "instead of using tuple indexing, use array indexing"; - let suggestion = format!("{base}[{field}]"); let applicability = if len < user_index { Applicability::MachineApplicable } else { Applicability::MaybeIncorrect }; - err.span_suggestion(expr.span, help, suggestion, applicability); + err.multipart_suggestion( + help, + vec![ + (base.span.between(field.span), "[".to_string()), + (field.span.shrink_to_hi(), "]".to_string()), + ], + applicability, + ); } } - fn suggest_first_deref_field( - &self, - err: &mut Diag<'_>, - expr: &hir::Expr<'_>, - base: &hir::Expr<'_>, - field: Ident, - ) { + fn suggest_first_deref_field(&self, err: &mut Diag<'_>, base: &hir::Expr<'_>, field: Ident) { err.span_label(field.span, "unknown field"); - if let Ok(base) = self.tcx.sess.source_map().span_to_snippet(base.span) { - let msg = format!("`{base}` is a raw pointer; try dereferencing it"); - let suggestion = format!("(*{base}).{field}"); - err.span_suggestion(expr.span, msg, suggestion, Applicability::MaybeIncorrect); - } + let val = if let Ok(base) = self.tcx.sess.source_map().span_to_snippet(base.span) + && base.len() < 20 + { + format!("`{base}`") + } else { + "the value".to_string() + }; + err.multipart_suggestion( + format!("{val} is a raw pointer; try dereferencing it"), + vec![ + (base.span.shrink_to_lo(), "(*".to_string()), + (base.span.shrink_to_hi(), ")".to_string()), + ], + Applicability::MaybeIncorrect, + ); } fn no_such_field_err(&self, field: Ident, expr_t: Ty<'tcx>, id: HirId) -> Diag<'_> { diff --git a/tests/ui/issues/issue-11004.stderr b/tests/ui/issues/issue-11004.stderr index ea141e61df8d3..6d157c9113024 100644 --- a/tests/ui/issues/issue-11004.stderr +++ b/tests/ui/issues/issue-11004.stderr @@ -2,19 +2,23 @@ error[E0609]: no field `x` on type `*mut A` --> $DIR/issue-11004.rs:7:21 | LL | let x : i32 = n.x; - | --^ - | | | - | | unknown field - | help: `n` is a raw pointer; try dereferencing it: `(*n).x` + | ^ unknown field + | +help: `n` is a raw pointer; try dereferencing it + | +LL | let x : i32 = (*n).x; + | ++ + error[E0609]: no field `y` on type `*mut A` --> $DIR/issue-11004.rs:8:21 | LL | let y : f64 = n.y; - | --^ - | | | - | | unknown field - | help: `n` is a raw pointer; try dereferencing it: `(*n).y` + | ^ unknown field + | +help: `n` is a raw pointer; try dereferencing it + | +LL | let y : f64 = (*n).y; + | ++ + error: aborting due to 2 previous errors diff --git a/tests/ui/suggestions/parenthesized-deref-suggestion.stderr b/tests/ui/suggestions/parenthesized-deref-suggestion.stderr index 9f185f5dd52b3..29e973b3a1730 100644 --- a/tests/ui/suggestions/parenthesized-deref-suggestion.stderr +++ b/tests/ui/suggestions/parenthesized-deref-suggestion.stderr @@ -4,19 +4,21 @@ error[E0609]: no field `opts` on type `*const Session` LL | (sess as *const Session).opts; | ^^^^ unknown field | -help: `(sess as *const Session)` is a raw pointer; try dereferencing it +help: the value is a raw pointer; try dereferencing it | LL | (*(sess as *const Session)).opts; - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + | ++ + error[E0609]: no field `0` on type `[u32; 1]` --> $DIR/parenthesized-deref-suggestion.rs:10:21 | LL | (x as [u32; 1]).0; - | ----------------^ - | | | - | | unknown field - | help: instead of using tuple indexing, use array indexing: `(x as [u32; 1])[0]` + | ^ unknown field + | +help: instead of using tuple indexing, use array indexing + | +LL | (x as [u32; 1])[0]; + | ~ + error: aborting due to 2 previous errors diff --git a/tests/ui/typeck/issue-53712.stderr b/tests/ui/typeck/issue-53712.stderr index ec31766324b26..ffaf5cde1d71e 100644 --- a/tests/ui/typeck/issue-53712.stderr +++ b/tests/ui/typeck/issue-53712.stderr @@ -2,10 +2,12 @@ error[E0609]: no field `0` on type `[{integer}; 5]` --> $DIR/issue-53712.rs:5:9 | LL | arr.0; - | ----^ - | | | - | | unknown field - | help: instead of using tuple indexing, use array indexing: `arr[0]` + | ^ unknown field + | +help: instead of using tuple indexing, use array indexing + | +LL | arr[0]; + | ~ + error: aborting due to 1 previous error diff --git a/tests/ui/unsafe/unsafe-fn-autoderef.stderr b/tests/ui/unsafe/unsafe-fn-autoderef.stderr index c3ab802022267..c19028ac8661b 100644 --- a/tests/ui/unsafe/unsafe-fn-autoderef.stderr +++ b/tests/ui/unsafe/unsafe-fn-autoderef.stderr @@ -2,10 +2,12 @@ error[E0609]: no field `f` on type `*const Rec` --> $DIR/unsafe-fn-autoderef.rs:19:14 | LL | return p.f; - | --^ - | | | - | | unknown field - | help: `p` is a raw pointer; try dereferencing it: `(*p).f` + | ^ unknown field + | +help: `p` is a raw pointer; try dereferencing it + | +LL | return (*p).f; + | ++ + error: aborting due to 1 previous error From b50e9155781d767c8edb487fe9d19e5b701961d5 Mon Sep 17 00:00:00 2001 From: cuishuang Date: Thu, 4 Jul 2024 14:56:08 +0800 Subject: [PATCH 663/892] chore: remove repeat words Signed-off-by: cuishuang --- library/core/src/hint.rs | 2 +- library/core/src/slice/sort/stable/drift.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/library/core/src/hint.rs b/library/core/src/hint.rs index 976a6c04ca6fa..b3e36e6fbc4ac 100644 --- a/library/core/src/hint.rs +++ b/library/core/src/hint.rs @@ -189,7 +189,7 @@ pub const unsafe fn unreachable_unchecked() -> ! { /// ``` /// /// This example is quite unlike anything that would be used in the real world: it is redundant -/// to put an an assertion right next to code that checks the same thing, and dereferencing a +/// to put an assertion right next to code that checks the same thing, and dereferencing a /// pointer already has the builtin assumption that it is nonnull. However, it illustrates the /// kind of changes the optimizer can make even when the behavior is less obviously related. #[track_caller] diff --git a/library/core/src/slice/sort/stable/drift.rs b/library/core/src/slice/sort/stable/drift.rs index 4008639095bde..2d9c4ac9fcf7c 100644 --- a/library/core/src/slice/sort/stable/drift.rs +++ b/library/core/src/slice/sort/stable/drift.rs @@ -200,7 +200,7 @@ fn logical_merge bool>( // If one or both of the runs are sorted do a physical merge, using // quicksort to sort the unsorted run if present. We also *need* to // physically merge if the combined runs would not fit in the scratch space - // anymore (as this would mean we are no longer able to to quicksort them). + // anymore (as this would mean we are no longer able to quicksort them). let len = v.len(); let can_fit_in_scratch = len <= scratch.len(); if !can_fit_in_scratch || left.sorted() || right.sorted() { From c198c0e6d0556cec74d10aec998f4e229137c701 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Thu, 4 Jul 2024 10:10:30 +0200 Subject: [PATCH 664/892] Do not consider LLDB version to be valid if it is empty When dry run is enabled, the command for finding LLDB version would succeed, but return an empty string. This was inadvertently enabling a code path that should only be executed when the LLDB is actually present and its version is valid. This commit makes sure that if the version is empty, LLDB will be considered not found. --- src/bootstrap/src/core/build_steps/test.rs | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index 998e45848a1c3..dc53bd3cfa785 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -1805,14 +1805,9 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the let lldb_exe = builder.config.lldb.clone().unwrap_or_else(|| PathBuf::from("lldb")); let lldb_version = builder - .run( - BootstrapCommand::new(&lldb_exe) - .capture() - .allow_failure() - .run_always() - .arg("--version"), - ) - .stdout_if_ok(); + .run(BootstrapCommand::new(&lldb_exe).capture().allow_failure().arg("--version")) + .stdout_if_ok() + .and_then(|v| if v.trim().is_empty() { None } else { Some(v) }); if let Some(ref vers) = lldb_version { cmd.arg("--lldb-version").arg(vers); let lldb_python_dir = builder From 0b4edb2487005d7db85a1261fcc77e26e1955553 Mon Sep 17 00:00:00 2001 From: Ding Xiang Fei Date: Thu, 4 Jul 2024 02:50:56 +0800 Subject: [PATCH 665/892] reject SmartPointer constructions not serving the purpose --- .../src/deriving/smart_ptr.rs | 39 +++++++++- .../ui/deriving/deriving-smart-pointer-neg.rs | 45 +++++++++++ .../deriving-smart-pointer-neg.stderr | 75 +++++++++++++++++++ tests/ui/deriving/deriving-smart-pointer.rs | 1 + .../feature-gate-derive-smart-pointer.rs | 1 + .../feature-gate-derive-smart-pointer.stderr | 2 +- 6 files changed, 159 insertions(+), 4 deletions(-) create mode 100644 tests/ui/deriving/deriving-smart-pointer-neg.rs create mode 100644 tests/ui/deriving/deriving-smart-pointer-neg.stderr diff --git a/compiler/rustc_builtin_macros/src/deriving/smart_ptr.rs b/compiler/rustc_builtin_macros/src/deriving/smart_ptr.rs index ea054a7e35526..bbc7cd3962720 100644 --- a/compiler/rustc_builtin_macros/src/deriving/smart_ptr.rs +++ b/compiler/rustc_builtin_macros/src/deriving/smart_ptr.rs @@ -3,8 +3,9 @@ use std::mem::swap; use ast::HasAttrs; use rustc_ast::{ self as ast, GenericArg, GenericBound, GenericParamKind, ItemKind, MetaItem, - TraitBoundModifiers, + TraitBoundModifiers, VariantData, }; +use rustc_attr as attr; use rustc_expand::base::{Annotatable, ExtCtxt}; use rustc_span::symbol::{sym, Ident}; use rustc_span::Span; @@ -24,11 +25,43 @@ pub fn expand_deriving_smart_ptr( _is_const: bool, ) { let (name_ident, generics) = if let Annotatable::Item(aitem) = item - && let ItemKind::Struct(_, g) = &aitem.kind + && let ItemKind::Struct(struct_data, g) = &aitem.kind { + let is_transparent = aitem.attrs.iter().any(|attr| { + attr::find_repr_attrs(cx.sess, attr) + .into_iter() + .any(|r| matches!(r, attr::ReprTransparent)) + }); + if !is_transparent { + cx.dcx() + .struct_span_err( + span, + "`SmartPointer` can only be derived on `struct`s with `#[repr(transparent)]`", + ) + .emit(); + return; + } + if !matches!( + struct_data, + VariantData::Struct { fields, recovered: _ } | VariantData::Tuple(fields, _) + if !fields.is_empty()) + { + cx.dcx() + .struct_span_err( + span, + "`SmartPointer` can only be derived on `struct`s with at least one field", + ) + .emit(); + return; + } (aitem.ident, g) } else { - cx.dcx().struct_span_err(span, "`SmartPointer` can only be derived on `struct`s").emit(); + cx.dcx() + .struct_span_err( + span, + "`SmartPointer` can only be derived on `struct`s with `#[repr(transparent)]`", + ) + .emit(); return; }; diff --git a/tests/ui/deriving/deriving-smart-pointer-neg.rs b/tests/ui/deriving/deriving-smart-pointer-neg.rs new file mode 100644 index 0000000000000..bfb4e86b39601 --- /dev/null +++ b/tests/ui/deriving/deriving-smart-pointer-neg.rs @@ -0,0 +1,45 @@ +#![feature(derive_smart_pointer, arbitrary_self_types)] + +use std::marker::SmartPointer; + +#[derive(SmartPointer)] +//~^ ERROR: `SmartPointer` can only be derived on `struct`s with `#[repr(transparent)]` +enum NotStruct<'a, T: ?Sized> { + Variant(&'a T), +} + +#[derive(SmartPointer)] +//~^ ERROR: At least one generic type should be designated as `#[pointee]` in order to derive `SmartPointer` traits +#[repr(transparent)] +struct NoPointee<'a, T: ?Sized> { + ptr: &'a T, +} + +#[derive(SmartPointer)] +//~^ ERROR: `SmartPointer` can only be derived on `struct`s with at least one field +#[repr(transparent)] +struct NoField<'a, #[pointee] T: ?Sized> {} +//~^ ERROR: lifetime parameter `'a` is never used +//~| ERROR: type parameter `T` is never used + +#[derive(SmartPointer)] +//~^ ERROR: `SmartPointer` can only be derived on `struct`s with at least one field +#[repr(transparent)] +struct NoFieldUnit<'a, #[pointee] T: ?Sized>(); +//~^ ERROR: lifetime parameter `'a` is never used +//~| ERROR: type parameter `T` is never used + +#[derive(SmartPointer)] +//~^ ERROR: `SmartPointer` can only be derived on `struct`s with `#[repr(transparent)]` +struct NotTransparent<'a, #[pointee] T: ?Sized> { + ptr: &'a T, +} + +// However, reordering attributes should work nevertheless. +#[repr(transparent)] +#[derive(SmartPointer)] +struct ThisIsAPossibleSmartPointer<'a, #[pointee] T: ?Sized> { + ptr: &'a T, +} + +fn main() {} diff --git a/tests/ui/deriving/deriving-smart-pointer-neg.stderr b/tests/ui/deriving/deriving-smart-pointer-neg.stderr new file mode 100644 index 0000000000000..d994a6ee376b0 --- /dev/null +++ b/tests/ui/deriving/deriving-smart-pointer-neg.stderr @@ -0,0 +1,75 @@ +error: `SmartPointer` can only be derived on `struct`s with `#[repr(transparent)]` + --> $DIR/deriving-smart-pointer-neg.rs:5:10 + | +LL | #[derive(SmartPointer)] + | ^^^^^^^^^^^^ + | + = note: this error originates in the derive macro `SmartPointer` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: At least one generic type should be designated as `#[pointee]` in order to derive `SmartPointer` traits + --> $DIR/deriving-smart-pointer-neg.rs:11:10 + | +LL | #[derive(SmartPointer)] + | ^^^^^^^^^^^^ + | + = note: this error originates in the derive macro `SmartPointer` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: `SmartPointer` can only be derived on `struct`s with at least one field + --> $DIR/deriving-smart-pointer-neg.rs:18:10 + | +LL | #[derive(SmartPointer)] + | ^^^^^^^^^^^^ + | + = note: this error originates in the derive macro `SmartPointer` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: `SmartPointer` can only be derived on `struct`s with at least one field + --> $DIR/deriving-smart-pointer-neg.rs:25:10 + | +LL | #[derive(SmartPointer)] + | ^^^^^^^^^^^^ + | + = note: this error originates in the derive macro `SmartPointer` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: `SmartPointer` can only be derived on `struct`s with `#[repr(transparent)]` + --> $DIR/deriving-smart-pointer-neg.rs:32:10 + | +LL | #[derive(SmartPointer)] + | ^^^^^^^^^^^^ + | + = note: this error originates in the derive macro `SmartPointer` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0392]: lifetime parameter `'a` is never used + --> $DIR/deriving-smart-pointer-neg.rs:21:16 + | +LL | struct NoField<'a, #[pointee] T: ?Sized> {} + | ^^ unused lifetime parameter + | + = help: consider removing `'a`, referring to it in a field, or using a marker such as `PhantomData` + +error[E0392]: type parameter `T` is never used + --> $DIR/deriving-smart-pointer-neg.rs:21:31 + | +LL | struct NoField<'a, #[pointee] T: ?Sized> {} + | ^ unused type parameter + | + = help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData` + +error[E0392]: lifetime parameter `'a` is never used + --> $DIR/deriving-smart-pointer-neg.rs:28:20 + | +LL | struct NoFieldUnit<'a, #[pointee] T: ?Sized>(); + | ^^ unused lifetime parameter + | + = help: consider removing `'a`, referring to it in a field, or using a marker such as `PhantomData` + +error[E0392]: type parameter `T` is never used + --> $DIR/deriving-smart-pointer-neg.rs:28:35 + | +LL | struct NoFieldUnit<'a, #[pointee] T: ?Sized>(); + | ^ unused type parameter + | + = help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData` + +error: aborting due to 9 previous errors + +For more information about this error, try `rustc --explain E0392`. diff --git a/tests/ui/deriving/deriving-smart-pointer.rs b/tests/ui/deriving/deriving-smart-pointer.rs index cfc3369850bd6..d34a502da684f 100644 --- a/tests/ui/deriving/deriving-smart-pointer.rs +++ b/tests/ui/deriving/deriving-smart-pointer.rs @@ -4,6 +4,7 @@ use std::marker::SmartPointer; #[derive(SmartPointer)] +#[repr(transparent)] struct MyPointer<'a, #[pointee] T: ?Sized> { ptr: &'a T, } diff --git a/tests/ui/feature-gates/feature-gate-derive-smart-pointer.rs b/tests/ui/feature-gates/feature-gate-derive-smart-pointer.rs index ae8005592cdb6..3257a9ca624ba 100644 --- a/tests/ui/feature-gates/feature-gate-derive-smart-pointer.rs +++ b/tests/ui/feature-gates/feature-gate-derive-smart-pointer.rs @@ -1,6 +1,7 @@ use std::marker::SmartPointer; //~ ERROR use of unstable library feature 'derive_smart_pointer' #[derive(SmartPointer)] //~ ERROR use of unstable library feature 'derive_smart_pointer' +#[repr(transparent)] struct MyPointer<'a, #[pointee] T: ?Sized> { //~^ ERROR the `#[pointee]` attribute is an experimental feature ptr: &'a T, diff --git a/tests/ui/feature-gates/feature-gate-derive-smart-pointer.stderr b/tests/ui/feature-gates/feature-gate-derive-smart-pointer.stderr index 0ffd82fb9e120..19501939dc5be 100644 --- a/tests/ui/feature-gates/feature-gate-derive-smart-pointer.stderr +++ b/tests/ui/feature-gates/feature-gate-derive-smart-pointer.stderr @@ -9,7 +9,7 @@ LL | #[derive(SmartPointer)] = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: the `#[pointee]` attribute is an experimental feature - --> $DIR/feature-gate-derive-smart-pointer.rs:4:22 + --> $DIR/feature-gate-derive-smart-pointer.rs:5:22 | LL | struct MyPointer<'a, #[pointee] T: ?Sized> { | ^^^^^^^^^^ From 1471532131984a8819401b02201982b5993ba996 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 4 Jul 2024 11:07:19 +0200 Subject: [PATCH 666/892] Allow to have different types for arguments of `Rustc::remap_path_prefix` --- src/tools/run-make-support/src/rustc.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/tools/run-make-support/src/rustc.rs b/src/tools/run-make-support/src/rustc.rs index 3f23c1b8f9e76..ffc18a5e48753 100644 --- a/src/tools/run-make-support/src/rustc.rs +++ b/src/tools/run-make-support/src/rustc.rs @@ -107,7 +107,11 @@ impl Rustc { } /// Remap source path prefixes in all output. - pub fn remap_path_prefix>(&mut self, from: P, to: P) -> &mut Self { + pub fn remap_path_prefix, P2: AsRef>( + &mut self, + from: P, + to: P2, + ) -> &mut Self { let from = from.as_ref().to_string_lossy(); let to = to.as_ref().to_string_lossy(); From 12f29e991a4eef962d315b45d24c784b4c5b987e Mon Sep 17 00:00:00 2001 From: schvv31n Date: Thu, 4 Jul 2024 10:18:57 +0100 Subject: [PATCH 667/892] added built-in var to jsondocck --- src/tools/jsondocck/src/cache.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/jsondocck/src/cache.rs b/src/tools/jsondocck/src/cache.rs index 50697d46b8c70..5f72bd171a17c 100644 --- a/src/tools/jsondocck/src/cache.rs +++ b/src/tools/jsondocck/src/cache.rs @@ -23,7 +23,7 @@ impl Cache { Cache { value: serde_json::from_str::(&content).expect("failed to convert from JSON"), - variables: HashMap::new(), + variables: HashMap::from([("FILE".to_owned(), config.template.clone().into())]), } } From 8ef2c6c6afd8f5b4d5c69278cc3dd986e37c574d Mon Sep 17 00:00:00 2001 From: Johannes Hostert Date: Wed, 3 Jul 2024 22:56:31 +0200 Subject: [PATCH 668/892] TB: Make FnEntry access on protected locations be a write under certain circumstances --- .../tree_borrows/diagnostics.rs | 7 ++-- .../src/borrow_tracker/tree_borrows/mod.rs | 19 ++------- .../src/borrow_tracker/tree_borrows/perms.rs | 4 ++ .../src/borrow_tracker/tree_borrows/tree.rs | 41 +++++++++++-------- 4 files changed, 35 insertions(+), 36 deletions(-) diff --git a/src/tools/miri/src/borrow_tracker/tree_borrows/diagnostics.rs b/src/tools/miri/src/borrow_tracker/tree_borrows/diagnostics.rs index 8abc8530f7c46..498b7dc3e420a 100644 --- a/src/tools/miri/src/borrow_tracker/tree_borrows/diagnostics.rs +++ b/src/tools/miri/src/borrow_tracker/tree_borrows/diagnostics.rs @@ -19,7 +19,7 @@ pub enum AccessCause { Explicit(AccessKind), Reborrow, Dealloc, - FnExit, + FnExit(AccessKind), } impl fmt::Display for AccessCause { @@ -28,7 +28,8 @@ impl fmt::Display for AccessCause { Self::Explicit(kind) => write!(f, "{kind}"), Self::Reborrow => write!(f, "reborrow"), Self::Dealloc => write!(f, "deallocation"), - Self::FnExit => write!(f, "protector release"), + Self::FnExit(AccessKind::Read) => write!(f, "protector release read"), + Self::FnExit(AccessKind::Write) => write!(f, "protector release write"), } } } @@ -40,7 +41,7 @@ impl AccessCause { Self::Explicit(kind) => format!("{rel} {kind}"), Self::Reborrow => format!("reborrow (acting as a {rel} read access)"), Self::Dealloc => format!("deallocation (acting as a {rel} write access)"), - Self::FnExit => format!("protector release (acting as a {rel} read access)"), + Self::FnExit(kind) => format!("protector release (acting as a {rel} {kind})"), } } } diff --git a/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs b/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs index 77e003ab8a789..86074384084d5 100644 --- a/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs +++ b/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs @@ -68,13 +68,11 @@ impl<'tcx> Tree { let global = machine.borrow_tracker.as_ref().unwrap(); let span = machine.current_span(); self.perform_access( - access_kind, tag, - Some(range), + Some((range, access_kind, diagnostics::AccessCause::Explicit(access_kind))), global, alloc_id, span, - diagnostics::AccessCause::Explicit(access_kind), ) } @@ -115,15 +113,8 @@ impl<'tcx> Tree { alloc_id: AllocId, // diagnostics ) -> InterpResult<'tcx> { let span = machine.current_span(); - self.perform_access( - AccessKind::Read, - tag, - None, // no specified range because it occurs on the entire allocation - global, - alloc_id, - span, - diagnostics::AccessCause::FnExit, - ) + // `None` makes it the magic on-protector-end operation + self.perform_access(tag, None, global, alloc_id, span) } } @@ -297,13 +288,11 @@ trait EvalContextPrivExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // All reborrows incur a (possibly zero-sized) read access to the parent tree_borrows.perform_access( - AccessKind::Read, orig_tag, - Some(range), + Some((range, AccessKind::Read, diagnostics::AccessCause::Reborrow)), this.machine.borrow_tracker.as_ref().unwrap(), alloc_id, this.machine.current_span(), - diagnostics::AccessCause::Reborrow, )?; // Record the parent-child pair in the tree. tree_borrows.new_child(orig_tag, new_tag, new_perm.initial_state, range, span)?; diff --git a/src/tools/miri/src/borrow_tracker/tree_borrows/perms.rs b/src/tools/miri/src/borrow_tracker/tree_borrows/perms.rs index fb3a4c8dad91c..7aa9c3e862bcc 100644 --- a/src/tools/miri/src/borrow_tracker/tree_borrows/perms.rs +++ b/src/tools/miri/src/borrow_tracker/tree_borrows/perms.rs @@ -186,6 +186,10 @@ impl Permission { pub fn is_disabled(&self) -> bool { self.inner == Disabled } + /// Check if `self` is the post-child-write state of a pointer (is `Active`). + pub fn is_active(&self) -> bool { + self.inner == Active + } /// Default initial permission of the root of a new tree at inbounds positions. /// Must *only* be used for the root, this is not in general an "initial" permission! diff --git a/src/tools/miri/src/borrow_tracker/tree_borrows/tree.rs b/src/tools/miri/src/borrow_tracker/tree_borrows/tree.rs index ff4589657aff2..90bd11032185c 100644 --- a/src/tools/miri/src/borrow_tracker/tree_borrows/tree.rs +++ b/src/tools/miri/src/borrow_tracker/tree_borrows/tree.rs @@ -530,13 +530,11 @@ impl<'tcx> Tree { span: Span, // diagnostics ) -> InterpResult<'tcx> { self.perform_access( - AccessKind::Write, tag, - Some(access_range), + Some((access_range, AccessKind::Write, diagnostics::AccessCause::Dealloc)), global, alloc_id, span, - diagnostics::AccessCause::Dealloc, )?; for (perms_range, perms) in self.rperms.iter_mut(access_range.start, access_range.size) { TreeVisitor { nodes: &mut self.nodes, tag_mapping: &self.tag_mapping, perms } @@ -570,12 +568,16 @@ impl<'tcx> Tree { } /// Map the per-node and per-location `LocationState::perform_access` - /// to each location of `access_range`, on every tag of the allocation. + /// to each location of the first component of `access_range_and_kind`, + /// on every tag of the allocation. /// - /// If `access_range` is `None`, this is interpreted as the special + /// If `access_range_and_kind` is `None`, this is interpreted as the special /// access that is applied on protector release: /// - the access will be applied only to initialized locations of the allocation, - /// - and it will not be visible to children. + /// - it will not be visible to children, + /// - it will be recorded as a `FnExit` diagnostic access + /// - and it will be a read except if the location is `Active`, i.e. has been written to, + /// in which case it will be a write. /// /// `LocationState::perform_access` will take care of raising transition /// errors and updating the `initialized` status of each location, @@ -585,13 +587,11 @@ impl<'tcx> Tree { /// - recording the history. pub fn perform_access( &mut self, - access_kind: AccessKind, tag: BorTag, - access_range: Option, + access_range_and_kind: Option<(AllocRange, AccessKind, diagnostics::AccessCause)>, global: &GlobalState, - alloc_id: AllocId, // diagnostics - span: Span, // diagnostics - access_cause: diagnostics::AccessCause, // diagnostics + alloc_id: AllocId, // diagnostics + span: Span, // diagnostics ) -> InterpResult<'tcx> { use std::ops::Range; // Performs the per-node work: @@ -605,6 +605,8 @@ impl<'tcx> Tree { // `perms_range` is only for diagnostics (it is the range of // the `RangeMap` on which we are currently working). let node_app = |perms_range: Range, + access_kind: AccessKind, + access_cause: diagnostics::AccessCause, args: NodeAppArgs<'_>| -> Result { let NodeAppArgs { node, mut perm, rel_pos } = args; @@ -618,14 +620,13 @@ impl<'tcx> Tree { let protected = global.borrow().protected_tags.contains_key(&node.tag); let transition = old_state.perform_access(access_kind, rel_pos, protected)?; - // Record the event as part of the history if !transition.is_noop() { node.debug_info.history.push(diagnostics::Event { transition, is_foreign: rel_pos.is_foreign(), access_cause, - access_range, + access_range: access_range_and_kind.map(|x| x.0), transition_range: perms_range, span, }); @@ -636,6 +637,7 @@ impl<'tcx> Tree { // Error handler in case `node_app` goes wrong. // Wraps the faulty transition in more context for diagnostics. let err_handler = |perms_range: Range, + access_cause: diagnostics::AccessCause, args: ErrHandlerArgs<'_, TransitionError>| -> InterpError<'tcx> { let ErrHandlerArgs { error_kind, conflicting_info, accessed_info } = args; @@ -650,7 +652,7 @@ impl<'tcx> Tree { .build() }; - if let Some(access_range) = access_range { + if let Some((access_range, access_kind, access_cause)) = access_range_and_kind { // Default branch: this is a "normal" access through a known range. // We iterate over affected locations and traverse the tree for each of them. for (perms_range, perms) in self.rperms.iter_mut(access_range.start, access_range.size) @@ -658,8 +660,8 @@ impl<'tcx> Tree { TreeVisitor { nodes: &mut self.nodes, tag_mapping: &self.tag_mapping, perms } .traverse_parents_this_children_others( tag, - |args| node_app(perms_range.clone(), args), - |args| err_handler(perms_range.clone(), args), + |args| node_app(perms_range.clone(), access_kind, access_cause, args), + |args| err_handler(perms_range.clone(), access_cause, args), )?; } } else { @@ -678,11 +680,14 @@ impl<'tcx> Tree { if let Some(p) = perms.get(idx) && p.initialized { + let access_kind = + if p.permission.is_active() { AccessKind::Write } else { AccessKind::Read }; + let access_cause = diagnostics::AccessCause::FnExit(access_kind); TreeVisitor { nodes: &mut self.nodes, tag_mapping: &self.tag_mapping, perms } .traverse_nonchildren( tag, - |args| node_app(perms_range.clone(), args), - |args| err_handler(perms_range.clone(), args), + |args| node_app(perms_range.clone(), access_kind, access_cause, args), + |args| err_handler(perms_range.clone(), access_cause, args), )?; } } From 0a86e7966442e12fa2080727d08047fdd2d3e619 Mon Sep 17 00:00:00 2001 From: Johannes Hostert Date: Thu, 4 Jul 2024 10:59:30 +0200 Subject: [PATCH 669/892] Add UI test for protector end write semantics --- .../fail/tree_borrows/protector-write-lazy.rs | 35 +++++++++++++++++++ .../tree_borrows/protector-write-lazy.stderr | 27 ++++++++++++++ 2 files changed, 62 insertions(+) create mode 100644 src/tools/miri/tests/fail/tree_borrows/protector-write-lazy.rs create mode 100644 src/tools/miri/tests/fail/tree_borrows/protector-write-lazy.stderr diff --git a/src/tools/miri/tests/fail/tree_borrows/protector-write-lazy.rs b/src/tools/miri/tests/fail/tree_borrows/protector-write-lazy.rs new file mode 100644 index 0000000000000..238f6dba9d3f7 --- /dev/null +++ b/src/tools/miri/tests/fail/tree_borrows/protector-write-lazy.rs @@ -0,0 +1,35 @@ +//@compile-flags: -Zmiri-tree-borrows +// This test tests that TB's protector end semantics correctly ensure +// that protected activated writes can be reordered. +fn the_other_function(ref_to_fst_elem: &mut i32, ptr_to_vec: *mut i32) -> *mut i32 { + // Activate the reference. Afterwards, we should be able to reorder arbitrary writes. + *ref_to_fst_elem = 0; + // Here is such an arbitrary write. + // It could be moved down after the retag, in which case the `funky_ref` would be invalidated. + // We need to ensure that the `funky_ptr` is unusable even if the write to `ref_to_fst_elem` + // happens before the retag. + *ref_to_fst_elem = 42; + // this creates a reference that is Reserved Lazy on the first element (offset 0). + // It does so by doing a proper retag on the second element (offset 1), which is fine + // since nothing else happens at that offset, but the lazy init mechanism means it's + // also reserved at offset 0, but not initialized. + let funky_ptr_lazy_on_fst_elem = + unsafe { (&mut *(ptr_to_vec.wrapping_add(1))) as *mut i32 }.wrapping_sub(1); + // If we write to `ref_to_fst_elem` here, then any further access to `funky_ptr_lazy_on_fst_elem` would + // definitely be UB. Since the compiler ought to be able to reorder the write of `42` above down to + // here, that means we want this program to also be UB. + return funky_ptr_lazy_on_fst_elem; +} + +fn main() { + let mut v = vec![0, 1]; + // get a pointer to the root of the allocation + // note that it's not important it's the actual root, what matters is that it's a parent + // of both references that will be created + let ptr_to_vec = v.as_mut_ptr(); + let ref_to_fst_elem = unsafe { &mut *ptr_to_vec }; + let funky_ptr_lazy_on_fst_elem = the_other_function(ref_to_fst_elem, ptr_to_vec); + // now we try to use the funky lazy pointer. + // It should be UB, since the write-on-protector-end should disable it. + unsafe { println!("Value of funky: {}", *funky_ptr_lazy_on_fst_elem) } //~ ERROR: /reborrow through .* is forbidden/ +} diff --git a/src/tools/miri/tests/fail/tree_borrows/protector-write-lazy.stderr b/src/tools/miri/tests/fail/tree_borrows/protector-write-lazy.stderr new file mode 100644 index 0000000000000..955abd144c7c3 --- /dev/null +++ b/src/tools/miri/tests/fail/tree_borrows/protector-write-lazy.stderr @@ -0,0 +1,27 @@ +error: Undefined Behavior: reborrow through at ALLOC[0x0] is forbidden + --> $DIR/protector-write-lazy.rs:LL:CC + | +LL | unsafe { println!("Value of funky: {}", *funky_ptr_lazy_on_fst_elem) } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ reborrow through at ALLOC[0x0] is forbidden + | + = help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental + = help: the accessed tag has state Disabled which forbids this reborrow (acting as a child read access) +help: the accessed tag was created here, in the initial state Reserved + --> $DIR/protector-write-lazy.rs:LL:CC + | +LL | unsafe { (&mut *(ptr_to_vec.wrapping_add(1))) as *mut i32 }.wrapping_sub(1); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: the accessed tag later transitioned to Disabled due to a protector release (acting as a foreign write access) on every location previously accessed by this tag + --> $DIR/protector-write-lazy.rs:LL:CC + | +LL | } + | ^ + = help: this transition corresponds to a loss of read and write permissions + = note: BACKTRACE (of the first span): + = note: inside `main` at $DIR/protector-write-lazy.rs:LL:CC + = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to 1 previous error + From 87b741549cff667ef59d92a36938f5d55d932bf6 Mon Sep 17 00:00:00 2001 From: yukang Date: Thu, 4 Jul 2024 10:07:22 +0000 Subject: [PATCH 670/892] trivial update on tidy bless note --- src/tools/tidy/src/run_make_tests.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/tidy/src/run_make_tests.rs b/src/tools/tidy/src/run_make_tests.rs index 2d9f8448a35bf..8d1767878378c 100644 --- a/src/tools/tidy/src/run_make_tests.rs +++ b/src/tools/tidy/src/run_make_tests.rs @@ -95,7 +95,7 @@ pub fn check(tests_path: &Path, src_path: &Path, bless: bool, bad: &mut bool) { tidy_error!( bad, "Makefile `{}` no longer exists and should be removed from the exclusions in \ - `src/tools/tidy/src/allowed_run_make_makefiles.txt`, you can run --bless to update \ + `src/tools/tidy/src/allowed_run_make_makefiles.txt`, you can run `x test tidy --bless` to update \ the allow list", p.display() ); From 02bec40930d7256d290c6a61b60df8284e460dda Mon Sep 17 00:00:00 2001 From: Johannes Hostert Date: Thu, 4 Jul 2024 12:01:49 +0200 Subject: [PATCH 671/892] TB: protector end semantics never causes immediate UB --- .../miri/src/borrow_tracker/tree_borrows/diagnostics.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/tools/miri/src/borrow_tracker/tree_borrows/diagnostics.rs b/src/tools/miri/src/borrow_tracker/tree_borrows/diagnostics.rs index 498b7dc3e420a..a753de28a041e 100644 --- a/src/tools/miri/src/borrow_tracker/tree_borrows/diagnostics.rs +++ b/src/tools/miri/src/borrow_tracker/tree_borrows/diagnostics.rs @@ -28,8 +28,11 @@ impl fmt::Display for AccessCause { Self::Explicit(kind) => write!(f, "{kind}"), Self::Reborrow => write!(f, "reborrow"), Self::Dealloc => write!(f, "deallocation"), - Self::FnExit(AccessKind::Read) => write!(f, "protector release read"), - Self::FnExit(AccessKind::Write) => write!(f, "protector release write"), + // This is dead code, since the protector release access itself can never + // cause UB (while the protector is active, if some other access invalidates + // further use of the protected tag, that is immediate UB). + // Describing the cause of UB is the only time this function is called. + Self::FnExit(_) => unreachable!("protector accesses can never be the source of UB"), } } } From 410f760ed530954a3f3da66b41207833207efdf2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Thu, 4 Jul 2024 12:34:07 +0200 Subject: [PATCH 672/892] Make CI more agnostic of the owning GitHub organization This should make it possible to switch running `auto` and `try` builds from `rust-lang-ci` to `rust-lang`. --- src/ci/docker/run.sh | 3 +-- src/ci/github-actions/calculate-job-matrix.py | 14 +++++--------- 2 files changed, 6 insertions(+), 11 deletions(-) diff --git a/src/ci/docker/run.sh b/src/ci/docker/run.sh index a4c59b3067ead..695b8b4c0d9e1 100755 --- a/src/ci/docker/run.sh +++ b/src/ci/docker/run.sh @@ -93,8 +93,7 @@ if [ -f "$docker_dir/$image/Dockerfile" ]; then docker --version REGISTRY=ghcr.io - # PR CI runs on rust-lang, but we want to use the cache from rust-lang-ci - REGISTRY_USERNAME=rust-lang-ci + REGISTRY_USERNAME=${GITHUB_REPOSITORY_OWNER} # Tag used to push the final Docker image, so that it can be pulled by e.g. rustup IMAGE_TAG=${REGISTRY}/${REGISTRY_USERNAME}/rust-ci:${cksum} # Tag used to cache the Docker build diff --git a/src/ci/github-actions/calculate-job-matrix.py b/src/ci/github-actions/calculate-job-matrix.py index 4f9bc39a628ce..d03bbda100807 100755 --- a/src/ci/github-actions/calculate-job-matrix.py +++ b/src/ci/github-actions/calculate-job-matrix.py @@ -91,21 +91,17 @@ def find_run_type(ctx: GitHubCtx) -> Optional[WorkflowRunType]: if ctx.event_name == "pull_request": return PRRunType() elif ctx.event_name == "push": - old_bors_try_build = ( - ctx.ref in ("refs/heads/try", "refs/heads/try-perf") and - ctx.repository == "rust-lang-ci/rust" + try_build = ctx.ref in ( + "refs/heads/try", + "refs/heads/try-perf", + "refs/heads/automation/bors/try" ) - new_bors_try_build = ( - ctx.ref == "refs/heads/automation/bors/try" and - ctx.repository == "rust-lang/rust" - ) - try_build = old_bors_try_build or new_bors_try_build if try_build: jobs = get_custom_jobs(ctx) return TryRunType(custom_jobs=jobs) - if ctx.ref == "refs/heads/auto" and ctx.repository == "rust-lang-ci/rust": + if ctx.ref == "refs/heads/auto": return AutoRunType() return None From 273d253ce6855381c9b7c36d3ea92581dd54becb Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Wed, 3 Jul 2024 16:04:37 +0200 Subject: [PATCH 673/892] offset_from: "the difference must fit in an isize" is a corollary also, isize::MIN is an impossible distance --- .../src/interpret/intrinsics.rs | 4 +-- library/core/src/ptr/const_ptr.rs | 27 +++----------- library/core/src/ptr/mut_ptr.rs | 27 +++----------- library/core/src/ptr/non_null.rs | 35 +++++-------------- tests/ui/consts/offset_from_ub.rs | 8 +++++ tests/ui/consts/offset_from_ub.stderr | 16 ++++++--- 6 files changed, 40 insertions(+), 77 deletions(-) diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs index 1d54da267eebf..d86f1a7a34f2a 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs @@ -301,9 +301,9 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { } // The signed form of the intrinsic allows this. If we interpret the // difference as isize, we'll get the proper signed difference. If that - // seems *positive*, they were more than isize::MAX apart. + // seems *positive* or equal to isize::MIN, they were more than isize::MAX apart. let dist = val.to_target_isize(self)?; - if dist >= 0 { + if dist >= 0 || i128::from(dist) == self.pointer_size().signed_int_min() { throw_ub_custom!( fluent::const_eval_offset_from_underflow, name = intrinsic_name, diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs index 5537d26669a23..039dc6d7a4981 100644 --- a/library/core/src/ptr/const_ptr.rs +++ b/library/core/src/ptr/const_ptr.rs @@ -611,8 +611,7 @@ impl *const T { /// /// # Safety /// - /// If any of the following conditions are violated, the result is Undefined - /// Behavior: + /// If any of the following conditions are violated, the result is Undefined Behavior: /// /// * `self` and `origin` must either /// @@ -623,26 +622,10 @@ impl *const T { /// * The distance between the pointers, in bytes, must be an exact multiple /// of the size of `T`. /// - /// * The distance between the pointers, **in bytes**, cannot overflow an `isize`. - /// - /// * The distance being in bounds cannot rely on "wrapping around" the address space. - /// - /// Rust types are never larger than `isize::MAX` and Rust allocations never wrap around the - /// address space, so two pointers within some value of any Rust type `T` will always satisfy - /// the last two conditions. The standard library also generally ensures that allocations - /// never reach a size where an offset is a concern. For instance, `Vec` and `Box` ensure they - /// never allocate more than `isize::MAX` bytes, so `ptr_into_vec.offset_from(vec.as_ptr())` - /// always satisfies the last two conditions. - /// - /// Most platforms fundamentally can't even construct such a large allocation. - /// For instance, no known 64-bit platform can ever serve a request - /// for 263 bytes due to page-table limitations or splitting the address space. - /// However, some 32-bit and 16-bit platforms may successfully serve a request for - /// more than `isize::MAX` bytes with things like Physical Address - /// Extension. As such, memory acquired directly from allocators or memory - /// mapped files *may* be too large to handle with this function. - /// (Note that [`offset`] and [`add`] also have a similar limitation and hence cannot be used on - /// such large allocations either.) + /// As a consequence, the absolute distance between the pointers, **in bytes**, computed on + /// mathematical integers (without "wrapping around"), cannot overflow an `isize`. This is + /// implied by the in-bounds requirement, and the fact that no allocated object can be larger + /// than `isize::MAX` bytes. /// /// The requirement for pointers to be derived from the same allocated object is primarily /// needed for `const`-compatibility: the distance between pointers into *different* allocated diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs index 30d5b2cfc5a8b..cbd3de1268a18 100644 --- a/library/core/src/ptr/mut_ptr.rs +++ b/library/core/src/ptr/mut_ptr.rs @@ -836,8 +836,7 @@ impl *mut T { /// /// # Safety /// - /// If any of the following conditions are violated, the result is Undefined - /// Behavior: + /// If any of the following conditions are violated, the result is Undefined Behavior: /// /// * `self` and `origin` must either /// @@ -848,26 +847,10 @@ impl *mut T { /// * The distance between the pointers, in bytes, must be an exact multiple /// of the size of `T`. /// - /// * The distance between the pointers, **in bytes**, cannot overflow an `isize`. - /// - /// * The distance being in bounds cannot rely on "wrapping around" the address space. - /// - /// Rust types are never larger than `isize::MAX` and Rust allocations never wrap around the - /// address space, so two pointers within some value of any Rust type `T` will always satisfy - /// the last two conditions. The standard library also generally ensures that allocations - /// never reach a size where an offset is a concern. For instance, `Vec` and `Box` ensure they - /// never allocate more than `isize::MAX` bytes, so `ptr_into_vec.offset_from(vec.as_ptr())` - /// always satisfies the last two conditions. - /// - /// Most platforms fundamentally can't even construct such a large allocation. - /// For instance, no known 64-bit platform can ever serve a request - /// for 263 bytes due to page-table limitations or splitting the address space. - /// However, some 32-bit and 16-bit platforms may successfully serve a request for - /// more than `isize::MAX` bytes with things like Physical Address - /// Extension. As such, memory acquired directly from allocators or memory - /// mapped files *may* be too large to handle with this function. - /// (Note that [`offset`] and [`add`] also have a similar limitation and hence cannot be used on - /// such large allocations either.) + /// As a consequence, the absolute distance between the pointers, in bytes, computed on + /// mathematical integers (without "wrapping around"), cannot overflow an `isize`. This is + /// implied by the in-bounds requirement, and the fact that no allocated object can be larger + /// than `isize::MAX` bytes. /// /// The requirement for pointers to be derived from the same allocated object is primarily /// needed for `const`-compatibility: the distance between pointers into *different* allocated diff --git a/library/core/src/ptr/non_null.rs b/library/core/src/ptr/non_null.rs index 0504a0fc32f4f..0b1bd5aeebb9c 100644 --- a/library/core/src/ptr/non_null.rs +++ b/library/core/src/ptr/non_null.rs @@ -761,38 +761,21 @@ impl NonNull { /// /// # Safety /// - /// If any of the following conditions are violated, the result is Undefined - /// Behavior: + /// If any of the following conditions are violated, the result is Undefined Behavior: /// - /// * Both `self` and `origin` must be either in bounds or one - /// byte past the end of the same [allocated object]. + /// * `self` and `origin` must either /// - /// * Both pointers must be *derived from* a pointer to the same object. - /// (See below for an example.) + /// * both be *derived from* a pointer to the same [allocated object], and the memory range between + /// the two pointers must be either empty or in bounds of that object. (See below for an example.) + /// * or both be derived from an integer literal/constant, and point to the same address. /// /// * The distance between the pointers, in bytes, must be an exact multiple /// of the size of `T`. /// - /// * The distance between the pointers, **in bytes**, cannot overflow an `isize`. - /// - /// * The distance being in bounds cannot rely on "wrapping around" the address space. - /// - /// Rust types are never larger than `isize::MAX` and Rust allocations never wrap around the - /// address space, so two pointers within some value of any Rust type `T` will always satisfy - /// the last two conditions. The standard library also generally ensures that allocations - /// never reach a size where an offset is a concern. For instance, `Vec` and `Box` ensure they - /// never allocate more than `isize::MAX` bytes, so `ptr_into_vec.offset_from(vec.as_ptr())` - /// always satisfies the last two conditions. - /// - /// Most platforms fundamentally can't even construct such a large allocation. - /// For instance, no known 64-bit platform can ever serve a request - /// for 263 bytes due to page-table limitations or splitting the address space. - /// However, some 32-bit and 16-bit platforms may successfully serve a request for - /// more than `isize::MAX` bytes with things like Physical Address - /// Extension. As such, memory acquired directly from allocators or memory - /// mapped files *may* be too large to handle with this function. - /// (Note that [`offset`] and [`add`] also have a similar limitation and hence cannot be used on - /// such large allocations either.) + /// As a consequence, the absolute distance between the pointers, in bytes, computed on + /// mathematical integers (without "wrapping around"), cannot overflow an `isize`. This is + /// implied by the in-bounds requirement, and the fact that no allocated object can be larger + /// than `isize::MAX` bytes. /// /// The requirement for pointers to be derived from the same allocated object is primarily /// needed for `const`-compatibility: the distance between pointers into *different* allocated diff --git a/tests/ui/consts/offset_from_ub.rs b/tests/ui/consts/offset_from_ub.rs index 57767e965962b..e71f88b8d5fab 100644 --- a/tests/ui/consts/offset_from_ub.rs +++ b/tests/ui/consts/offset_from_ub.rs @@ -92,6 +92,14 @@ pub const TOO_FAR_APART2: isize = { unsafe { ptr_offset_from(ptr1, ptr2) } //~ERROR evaluation of constant value failed //~| too far before }; +pub const TOO_FAR_APART3: isize = { + let ptr1 = &0u8 as *const u8; + let ptr2 = ptr1.wrapping_offset(isize::MIN); + // The result of this would be `isize::MIN`, which *does* fit in an `isize`, but its + // absolute value does not. (Also anyway there cannot be an allocation of that size.) + unsafe { ptr_offset_from(ptr1, ptr2) } //~ERROR evaluation of constant value failed + //~| too far before +}; const WRONG_ORDER_UNSIGNED: usize = { let a = ['a', 'b', 'c']; diff --git a/tests/ui/consts/offset_from_ub.stderr b/tests/ui/consts/offset_from_ub.stderr index 65f75a6e05875..7caf6247b9e9e 100644 --- a/tests/ui/consts/offset_from_ub.stderr +++ b/tests/ui/consts/offset_from_ub.stderr @@ -60,13 +60,19 @@ LL | unsafe { ptr_offset_from(ptr1, ptr2) } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `ptr_offset_from` called when first pointer is too far before second error[E0080]: evaluation of constant value failed - --> $DIR/offset_from_ub.rs:99:14 + --> $DIR/offset_from_ub.rs:100:14 + | +LL | unsafe { ptr_offset_from(ptr1, ptr2) } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `ptr_offset_from` called when first pointer is too far before second + +error[E0080]: evaluation of constant value failed + --> $DIR/offset_from_ub.rs:107:14 | LL | unsafe { ptr_offset_from_unsigned(p, p.add(2) ) } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `ptr_offset_from_unsigned` called when first pointer has smaller offset than second: 0 < 8 error[E0080]: evaluation of constant value failed - --> $DIR/offset_from_ub.rs:106:14 + --> $DIR/offset_from_ub.rs:114:14 | LL | unsafe { ptr_offset_from_unsigned(ptr2, ptr1) } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `ptr_offset_from_unsigned` called when first pointer is too far ahead of second @@ -79,7 +85,7 @@ error[E0080]: evaluation of constant value failed note: inside `std::ptr::const_ptr::::offset_from` --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL note: inside `OFFSET_VERY_FAR1` - --> $DIR/offset_from_ub.rs:115:14 + --> $DIR/offset_from_ub.rs:123:14 | LL | unsafe { ptr2.offset_from(ptr1) } | ^^^^^^^^^^^^^^^^^^^^^^ @@ -92,11 +98,11 @@ error[E0080]: evaluation of constant value failed note: inside `std::ptr::const_ptr::::offset_from` --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL note: inside `OFFSET_VERY_FAR2` - --> $DIR/offset_from_ub.rs:121:14 + --> $DIR/offset_from_ub.rs:129:14 | LL | unsafe { ptr1.offset_from(ptr2.wrapping_offset(1)) } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 13 previous errors +error: aborting due to 14 previous errors For more information about this error, try `rustc --explain E0080`. From 9ba492f2797250b2fcaa38d483ca5c23bf0bd8dd Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Wed, 3 Jul 2024 16:42:33 +0200 Subject: [PATCH 674/892] also remove redundant requirements from offset() --- library/core/src/ptr/const_ptr.rs | 101 ++++++++++-------------------- library/core/src/ptr/mut_ptr.rs | 99 ++++++++++------------------- library/core/src/ptr/non_null.rs | 96 ++++++++++------------------ 3 files changed, 100 insertions(+), 196 deletions(-) diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs index 039dc6d7a4981..68cf820343344 100644 --- a/library/core/src/ptr/const_ptr.rs +++ b/library/core/src/ptr/const_ptr.rs @@ -390,37 +390,26 @@ impl *const T { if self.is_null() { None } else { Some(unsafe { &*(self as *const MaybeUninit) }) } } - /// Calculates the offset from a pointer. + /// Adds an offset to a pointer. /// /// `count` is in units of T; e.g., a `count` of 3 represents a pointer /// offset of `3 * size_of::()` bytes. /// /// # Safety /// - /// If any of the following conditions are violated, the result is Undefined - /// Behavior: - /// - /// * If the computed offset, **in bytes**, is non-zero, then both the starting and resulting - /// pointer must be either in bounds or at the end of the same [allocated object]. - /// (If it is zero, then the function is always well-defined.) - /// - /// * The computed offset, **in bytes**, cannot overflow an `isize`. + /// If any of the following conditions are violated, the result is Undefined Behavior: /// - /// * The offset being in bounds cannot rely on "wrapping around" the address - /// space. That is, the infinite-precision sum, **in bytes** must fit in a usize. + /// * The computed offset, `count * size_of::()` bytes, must not overflow `isize`. /// - /// The compiler and standard library generally tries to ensure allocations - /// never reach a size where an offset is a concern. For instance, `Vec` - /// and `Box` ensure they never allocate more than `isize::MAX` bytes, so - /// `vec.as_ptr().add(vec.len())` is always safe. + /// * If the computed offset is non-zero, then `self` must be derived from a pointer to some + /// [allocated object], and the entire memory range between `self` and the result must be in + /// bounds of that allocated object. In particular, this range must not "wrap around" the edge + /// of the address space. /// - /// Most platforms fundamentally can't even construct such an allocation. - /// For instance, no known 64-bit platform can ever serve a request - /// for 263 bytes due to page-table limitations or splitting the address space. - /// However, some 32-bit and 16-bit platforms may successfully serve a request for - /// more than `isize::MAX` bytes with things like Physical Address - /// Extension. As such, memory acquired directly from allocators or memory - /// mapped files *may* be too large to handle with this function. + /// Allocated objects can never be larger than `isize::MAX` bytes, so if the computed offset + /// stays in bounds of the allocated object, it is guaranteed to satisfy the first requirement. + /// This implies, for instance, that `vec.as_ptr().add(vec.len())` (for `vec: Vec`) is always + /// safe. /// /// Consider using [`wrapping_offset`] instead if these constraints are /// difficult to satisfy. The only advantage of this method is that it @@ -622,7 +611,7 @@ impl *const T { /// * The distance between the pointers, in bytes, must be an exact multiple /// of the size of `T`. /// - /// As a consequence, the absolute distance between the pointers, **in bytes**, computed on + /// As a consequence, the absolute distance between the pointers, in bytes, computed on /// mathematical integers (without "wrapping around"), cannot overflow an `isize`. This is /// implied by the in-bounds requirement, and the fact that no allocated object can be larger /// than `isize::MAX` bytes. @@ -862,37 +851,26 @@ impl *const T { } } - /// Calculates the offset from a pointer (convenience for `.offset(count as isize)`). + /// Adds an offset to a pointer (convenience for `.offset(count as isize)`). /// /// `count` is in units of T; e.g., a `count` of 3 represents a pointer /// offset of `3 * size_of::()` bytes. /// /// # Safety /// - /// If any of the following conditions are violated, the result is Undefined - /// Behavior: - /// - /// * If the computed offset, **in bytes**, is non-zero, then both the starting and resulting - /// pointer must be either in bounds or at the end of the same [allocated object]. - /// (If it is zero, then the function is always well-defined.) - /// - /// * The computed offset, **in bytes**, cannot overflow an `isize`. + /// If any of the following conditions are violated, the result is Undefined Behavior: /// - /// * The offset being in bounds cannot rely on "wrapping around" the address - /// space. That is, the infinite-precision sum must fit in a `usize`. + /// * The computed offset, `count * size_of::()` bytes, must not overflow `isize`. /// - /// The compiler and standard library generally tries to ensure allocations - /// never reach a size where an offset is a concern. For instance, `Vec` - /// and `Box` ensure they never allocate more than `isize::MAX` bytes, so - /// `vec.as_ptr().add(vec.len())` is always safe. + /// * If the computed offset is non-zero, then `self` must be derived from a pointer to some + /// [allocated object], and the entire memory range between `self` and the result must be in + /// bounds of that allocated object. In particular, this range must not "wrap around" the edge + /// of the address space. /// - /// Most platforms fundamentally can't even construct such an allocation. - /// For instance, no known 64-bit platform can ever serve a request - /// for 263 bytes due to page-table limitations or splitting the address space. - /// However, some 32-bit and 16-bit platforms may successfully serve a request for - /// more than `isize::MAX` bytes with things like Physical Address - /// Extension. As such, memory acquired directly from allocators or memory - /// mapped files *may* be too large to handle with this function. + /// Allocated objects can never be larger than `isize::MAX` bytes, so if the computed offset + /// stays in bounds of the allocated object, it is guaranteed to satisfy the first requirement. + /// This implies, for instance, that `vec.as_ptr().add(vec.len())` (for `vec: Vec`) is always + /// safe. /// /// Consider using [`wrapping_add`] instead if these constraints are /// difficult to satisfy. The only advantage of this method is that it @@ -946,7 +924,7 @@ impl *const T { unsafe { self.cast::().add(count).with_metadata_of(self) } } - /// Calculates the offset from a pointer (convenience for + /// Subtracts an offset from a pointer (convenience for /// `.offset((count as isize).wrapping_neg())`). /// /// `count` is in units of T; e.g., a `count` of 3 represents a pointer @@ -954,30 +932,19 @@ impl *const T { /// /// # Safety /// - /// If any of the following conditions are violated, the result is Undefined - /// Behavior: - /// - /// * If the computed offset, **in bytes**, is non-zero, then both the starting and resulting - /// pointer must be either in bounds or at the end of the same [allocated object]. - /// (If it is zero, then the function is always well-defined.) - /// - /// * The computed offset cannot exceed `isize::MAX` **bytes**. + /// If any of the following conditions are violated, the result is Undefined Behavior: /// - /// * The offset being in bounds cannot rely on "wrapping around" the address - /// space. That is, the infinite-precision sum must fit in a usize. + /// * The computed offset, `count * size_of::()` bytes, must not overflow `isize`. /// - /// The compiler and standard library generally tries to ensure allocations - /// never reach a size where an offset is a concern. For instance, `Vec` - /// and `Box` ensure they never allocate more than `isize::MAX` bytes, so - /// `vec.as_ptr().add(vec.len()).sub(vec.len())` is always safe. + /// * If the computed offset is non-zero, then `self` must be derived from a pointer to some + /// [allocated object], and the entire memory range between `self` and the result must be in + /// bounds of that allocated object. In particular, this range must not "wrap around" the edge + /// of the address space. /// - /// Most platforms fundamentally can't even construct such an allocation. - /// For instance, no known 64-bit platform can ever serve a request - /// for 263 bytes due to page-table limitations or splitting the address space. - /// However, some 32-bit and 16-bit platforms may successfully serve a request for - /// more than `isize::MAX` bytes with things like Physical Address - /// Extension. As such, memory acquired directly from allocators or memory - /// mapped files *may* be too large to handle with this function. + /// Allocated objects can never be larger than `isize::MAX` bytes, so if the computed offset + /// stays in bounds of the allocated object, it is guaranteed to satisfy the first requirement. + /// This implies, for instance, that `vec.as_ptr().add(vec.len())` (for `vec: Vec`) is always + /// safe. /// /// Consider using [`wrapping_sub`] instead if these constraints are /// difficult to satisfy. The only advantage of this method is that it diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs index cbd3de1268a18..0dc910db5b9bd 100644 --- a/library/core/src/ptr/mut_ptr.rs +++ b/library/core/src/ptr/mut_ptr.rs @@ -404,37 +404,26 @@ impl *mut T { if self.is_null() { None } else { Some(unsafe { &*(self as *const MaybeUninit) }) } } - /// Calculates the offset from a pointer. + /// Adds an offset to a pointer. /// /// `count` is in units of T; e.g., a `count` of 3 represents a pointer /// offset of `3 * size_of::()` bytes. /// /// # Safety /// - /// If any of the following conditions are violated, the result is Undefined - /// Behavior: - /// - /// * If the computed offset, **in bytes**, is non-zero, then both the starting and resulting - /// pointer must be either in bounds or at the end of the same [allocated object]. - /// (If it is zero, then the function is always well-defined.) - /// - /// * The computed offset, **in bytes**, cannot overflow an `isize`. + /// If any of the following conditions are violated, the result is Undefined Behavior: /// - /// * The offset being in bounds cannot rely on "wrapping around" the address - /// space. That is, the infinite-precision sum, **in bytes** must fit in a usize. + /// * The computed offset, `count * size_of::()` bytes, must not overflow `isize`. /// - /// The compiler and standard library generally tries to ensure allocations - /// never reach a size where an offset is a concern. For instance, `Vec` - /// and `Box` ensure they never allocate more than `isize::MAX` bytes, so - /// `vec.as_ptr().add(vec.len())` is always safe. + /// * If the computed offset is non-zero, then `self` must be derived from a pointer to some + /// [allocated object], and the entire memory range between `self` and the result must be in + /// bounds of that allocated object. In particular, this range must not "wrap around" the edge + /// of the address space. /// - /// Most platforms fundamentally can't even construct such an allocation. - /// For instance, no known 64-bit platform can ever serve a request - /// for 263 bytes due to page-table limitations or splitting the address space. - /// However, some 32-bit and 16-bit platforms may successfully serve a request for - /// more than `isize::MAX` bytes with things like Physical Address - /// Extension. As such, memory acquired directly from allocators or memory - /// mapped files *may* be too large to handle with this function. + /// Allocated objects can never be larger than `isize::MAX` bytes, so if the computed offset + /// stays in bounds of the allocated object, it is guaranteed to satisfy the first requirement. + /// This implies, for instance, that `vec.as_ptr().add(vec.len())` (for `vec: Vec`) is always + /// safe. /// /// Consider using [`wrapping_offset`] instead if these constraints are /// difficult to satisfy. The only advantage of this method is that it @@ -1003,37 +992,26 @@ impl *mut T { unsafe { (self as *const T).sub_ptr(origin) } } - /// Calculates the offset from a pointer (convenience for `.offset(count as isize)`). + /// Adds an offset to a pointer (convenience for `.offset(count as isize)`). /// /// `count` is in units of T; e.g., a `count` of 3 represents a pointer /// offset of `3 * size_of::()` bytes. /// /// # Safety /// - /// If any of the following conditions are violated, the result is Undefined - /// Behavior: - /// - /// * If the computed offset, **in bytes**, is non-zero, then both the starting and resulting - /// pointer must be either in bounds or at the end of the same [allocated object]. - /// (If it is zero, then the function is always well-defined.) - /// - /// * The computed offset, **in bytes**, cannot overflow an `isize`. + /// If any of the following conditions are violated, the result is Undefined Behavior: /// - /// * The offset being in bounds cannot rely on "wrapping around" the address - /// space. That is, the infinite-precision sum must fit in a `usize`. + /// * The computed offset, `count * size_of::()` bytes, must not overflow `isize`. /// - /// The compiler and standard library generally tries to ensure allocations - /// never reach a size where an offset is a concern. For instance, `Vec` - /// and `Box` ensure they never allocate more than `isize::MAX` bytes, so - /// `vec.as_ptr().add(vec.len())` is always safe. + /// * If the computed offset is non-zero, then `self` must be derived from a pointer to some + /// [allocated object], and the entire memory range between `self` and the result must be in + /// bounds of that allocated object. In particular, this range must not "wrap around" the edge + /// of the address space. /// - /// Most platforms fundamentally can't even construct such an allocation. - /// For instance, no known 64-bit platform can ever serve a request - /// for 263 bytes due to page-table limitations or splitting the address space. - /// However, some 32-bit and 16-bit platforms may successfully serve a request for - /// more than `isize::MAX` bytes with things like Physical Address - /// Extension. As such, memory acquired directly from allocators or memory - /// mapped files *may* be too large to handle with this function. + /// Allocated objects can never be larger than `isize::MAX` bytes, so if the computed offset + /// stays in bounds of the allocated object, it is guaranteed to satisfy the first requirement. + /// This implies, for instance, that `vec.as_ptr().add(vec.len())` (for `vec: Vec`) is always + /// safe. /// /// Consider using [`wrapping_add`] instead if these constraints are /// difficult to satisfy. The only advantage of this method is that it @@ -1087,7 +1065,7 @@ impl *mut T { unsafe { self.cast::().add(count).with_metadata_of(self) } } - /// Calculates the offset from a pointer (convenience for + /// Subtracts an offset from a pointer (convenience for /// `.offset((count as isize).wrapping_neg())`). /// /// `count` is in units of T; e.g., a `count` of 3 represents a pointer @@ -1095,30 +1073,19 @@ impl *mut T { /// /// # Safety /// - /// If any of the following conditions are violated, the result is Undefined - /// Behavior: - /// - /// * If the computed offset, **in bytes**, is non-zero, then both the starting and resulting - /// pointer must be either in bounds or at the end of the same [allocated object]. - /// (If it is zero, then the function is always well-defined.) - /// - /// * The computed offset cannot exceed `isize::MAX` **bytes**. + /// If any of the following conditions are violated, the result is Undefined Behavior: /// - /// * The offset being in bounds cannot rely on "wrapping around" the address - /// space. That is, the infinite-precision sum must fit in a usize. + /// * The computed offset, `count * size_of::()` bytes, must not overflow `isize`. /// - /// The compiler and standard library generally tries to ensure allocations - /// never reach a size where an offset is a concern. For instance, `Vec` - /// and `Box` ensure they never allocate more than `isize::MAX` bytes, so - /// `vec.as_ptr().add(vec.len()).sub(vec.len())` is always safe. + /// * If the computed offset is non-zero, then `self` must be derived from a pointer to some + /// [allocated object], and the entire memory range between `self` and the result must be in + /// bounds of that allocated object. In particular, this range must not "wrap around" the edge + /// of the address space. /// - /// Most platforms fundamentally can't even construct such an allocation. - /// For instance, no known 64-bit platform can ever serve a request - /// for 263 bytes due to page-table limitations or splitting the address space. - /// However, some 32-bit and 16-bit platforms may successfully serve a request for - /// more than `isize::MAX` bytes with things like Physical Address - /// Extension. As such, memory acquired directly from allocators or memory - /// mapped files *may* be too large to handle with this function. + /// Allocated objects can never be larger than `isize::MAX` bytes, so if the computed offset + /// stays in bounds of the allocated object, it is guaranteed to satisfy the first requirement. + /// This implies, for instance, that `vec.as_ptr().add(vec.len())` (for `vec: Vec`) is always + /// safe. /// /// Consider using [`wrapping_sub`] instead if these constraints are /// difficult to satisfy. The only advantage of this method is that it diff --git a/library/core/src/ptr/non_null.rs b/library/core/src/ptr/non_null.rs index 0b1bd5aeebb9c..75a99e14fdadc 100644 --- a/library/core/src/ptr/non_null.rs +++ b/library/core/src/ptr/non_null.rs @@ -476,36 +476,26 @@ impl NonNull { unsafe { NonNull { pointer: self.as_ptr() as *mut U } } } - /// Calculates the offset from a pointer. + /// Adds an offset to a pointer. /// /// `count` is in units of T; e.g., a `count` of 3 represents a pointer /// offset of `3 * size_of::()` bytes. /// /// # Safety /// - /// If any of the following conditions are violated, the result is Undefined - /// Behavior: - /// - /// * Both the starting and resulting pointer must be either in bounds or one - /// byte past the end of the same [allocated object]. - /// - /// * The computed offset, **in bytes**, cannot overflow an `isize`. + /// If any of the following conditions are violated, the result is Undefined Behavior: /// - /// * The offset being in bounds cannot rely on "wrapping around" the address - /// space. That is, the infinite-precision sum, **in bytes** must fit in a usize. + /// * The computed offset, `count * size_of::()` bytes, must not overflow `isize`. /// - /// The compiler and standard library generally tries to ensure allocations - /// never reach a size where an offset is a concern. For instance, `Vec` - /// and `Box` ensure they never allocate more than `isize::MAX` bytes, so - /// `vec.as_ptr().add(vec.len())` is always safe. + /// * If the computed offset is non-zero, then `self` must be derived from a pointer to some + /// [allocated object], and the entire memory range between `self` and the result must be in + /// bounds of that allocated object. In particular, this range must not "wrap around" the edge + /// of the address space. /// - /// Most platforms fundamentally can't even construct such an allocation. - /// For instance, no known 64-bit platform can ever serve a request - /// for 263 bytes due to page-table limitations or splitting the address space. - /// However, some 32-bit and 16-bit platforms may successfully serve a request for - /// more than `isize::MAX` bytes with things like Physical Address - /// Extension. As such, memory acquired directly from allocators or memory - /// mapped files *may* be too large to handle with this function. + /// Allocated objects can never be larger than `isize::MAX` bytes, so if the computed offset + /// stays in bounds of the allocated object, it is guaranteed to satisfy the first requirement. + /// This implies, for instance, that `vec.as_ptr().add(vec.len())` (for `vec: Vec`) is always + /// safe. /// /// [allocated object]: crate::ptr#allocated-object /// @@ -562,36 +552,26 @@ impl NonNull { unsafe { NonNull { pointer: self.pointer.byte_offset(count) } } } - /// Calculates the offset from a pointer (convenience for `.offset(count as isize)`). + /// Adds an offset to a pointer (convenience for `.offset(count as isize)`). /// /// `count` is in units of T; e.g., a `count` of 3 represents a pointer /// offset of `3 * size_of::()` bytes. /// /// # Safety /// - /// If any of the following conditions are violated, the result is Undefined - /// Behavior: - /// - /// * Both the starting and resulting pointer must be either in bounds or one - /// byte past the end of the same [allocated object]. - /// - /// * The computed offset, **in bytes**, cannot overflow an `isize`. + /// If any of the following conditions are violated, the result is Undefined Behavior: /// - /// * The offset being in bounds cannot rely on "wrapping around" the address - /// space. That is, the infinite-precision sum must fit in a `usize`. + /// * The computed offset, `count * size_of::()` bytes, must not overflow `isize`. /// - /// The compiler and standard library generally tries to ensure allocations - /// never reach a size where an offset is a concern. For instance, `Vec` - /// and `Box` ensure they never allocate more than `isize::MAX` bytes, so - /// `vec.as_ptr().add(vec.len())` is always safe. + /// * If the computed offset is non-zero, then `self` must be derived from a pointer to some + /// [allocated object], and the entire memory range between `self` and the result must be in + /// bounds of that allocated object. In particular, this range must not "wrap around" the edge + /// of the address space. /// - /// Most platforms fundamentally can't even construct such an allocation. - /// For instance, no known 64-bit platform can ever serve a request - /// for 263 bytes due to page-table limitations or splitting the address space. - /// However, some 32-bit and 16-bit platforms may successfully serve a request for - /// more than `isize::MAX` bytes with things like Physical Address - /// Extension. As such, memory acquired directly from allocators or memory - /// mapped files *may* be too large to handle with this function. + /// Allocated objects can never be larger than `isize::MAX` bytes, so if the computed offset + /// stays in bounds of the allocated object, it is guaranteed to satisfy the first requirement. + /// This implies, for instance, that `vec.as_ptr().add(vec.len())` (for `vec: Vec`) is always + /// safe. /// /// [allocated object]: crate::ptr#allocated-object /// @@ -649,7 +629,7 @@ impl NonNull { unsafe { NonNull { pointer: self.pointer.byte_add(count) } } } - /// Calculates the offset from a pointer (convenience for + /// Subtracts an offset from a pointer (convenience for /// `.offset((count as isize).wrapping_neg())`). /// /// `count` is in units of T; e.g., a `count` of 3 represents a pointer @@ -657,29 +637,19 @@ impl NonNull { /// /// # Safety /// - /// If any of the following conditions are violated, the result is Undefined - /// Behavior: - /// - /// * Both the starting and resulting pointer must be either in bounds or one - /// byte past the end of the same [allocated object]. - /// - /// * The computed offset cannot exceed `isize::MAX` **bytes**. + /// If any of the following conditions are violated, the result is Undefined Behavior: /// - /// * The offset being in bounds cannot rely on "wrapping around" the address - /// space. That is, the infinite-precision sum must fit in a usize. + /// * The computed offset, `count * size_of::()` bytes, must not overflow `isize`. /// - /// The compiler and standard library generally tries to ensure allocations - /// never reach a size where an offset is a concern. For instance, `Vec` - /// and `Box` ensure they never allocate more than `isize::MAX` bytes, so - /// `vec.as_ptr().add(vec.len()).sub(vec.len())` is always safe. + /// * If the computed offset is non-zero, then `self` must be derived from a pointer to some + /// [allocated object], and the entire memory range between `self` and the result must be in + /// bounds of that allocated object. In particular, this range must not "wrap around" the edge + /// of the address space. /// - /// Most platforms fundamentally can't even construct such an allocation. - /// For instance, no known 64-bit platform can ever serve a request - /// for 263 bytes due to page-table limitations or splitting the address space. - /// However, some 32-bit and 16-bit platforms may successfully serve a request for - /// more than `isize::MAX` bytes with things like Physical Address - /// Extension. As such, memory acquired directly from allocators or memory - /// mapped files *may* be too large to handle with this function. + /// Allocated objects can never be larger than `isize::MAX` bytes, so if the computed offset + /// stays in bounds of the allocated object, it is guaranteed to satisfy the first requirement. + /// This implies, for instance, that `vec.as_ptr().add(vec.len())` (for `vec: Vec`) is always + /// safe. /// /// [allocated object]: crate::ptr#allocated-object /// From 34860a56f09baf9bc02cde287f4baff921b9a748 Mon Sep 17 00:00:00 2001 From: Chris Denton Date: Thu, 4 Jul 2024 12:09:25 +0000 Subject: [PATCH 675/892] Update windows-bindgen to 0.58.0 --- Cargo.lock | 8 +- library/std/src/sys/pal/windows/c.rs | 9 +- .../std/src/sys/pal/windows/c/bindings.txt | 2 +- .../std/src/sys/pal/windows/c/windows_sys.rs | 970 +++--------------- .../src/sys/pal/windows/c/windows_targets.rs | 15 + library/std/src/sys/pal/windows/stdio.rs | 8 +- src/tools/generate-windows-sys/Cargo.toml | 2 +- src/tools/generate-windows-sys/src/main.rs | 1 + 8 files changed, 159 insertions(+), 856 deletions(-) create mode 100644 library/std/src/sys/pal/windows/c/windows_targets.rs diff --git a/Cargo.lock b/Cargo.lock index 96cef9070842e..fbe1abf2a3317 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6356,9 +6356,9 @@ dependencies = [ [[package]] name = "windows-bindgen" -version = "0.57.0" +version = "0.58.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ccb96113d6277ba543c0f77e1c5494af8094bf9daf9b85acdc3f1b620e7c7b4" +checksum = "91cd28d93c692351f3a6e5615567c56756e330bee1c99c6bdd57bfc5ab15f589" dependencies = [ "proc-macro2", "rayon", @@ -6379,9 +6379,9 @@ dependencies = [ [[package]] name = "windows-metadata" -version = "0.57.0" +version = "0.58.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8308d076825b9d9e5abc64f8113e96d02b2aeeba869b20fdd65c7e70cda13dfc" +checksum = "2e837f3c3012cfe9e7086302a93f441a7999439be1ad4c530d55d2f6d2921809" [[package]] name = "windows-sys" diff --git a/library/std/src/sys/pal/windows/c.rs b/library/std/src/sys/pal/windows/c.rs index 6ec82693077dc..27aa35f69f1bf 100644 --- a/library/std/src/sys/pal/windows/c.rs +++ b/library/std/src/sys/pal/windows/c.rs @@ -13,6 +13,8 @@ use crate::os::raw::{c_char, c_long, c_longlong, c_uint, c_ulong, c_ushort, c_vo use crate::os::windows::io::{AsRawHandle, BorrowedHandle}; use crate::ptr; +mod windows_targets; + mod windows_sys; pub use windows_sys::*; @@ -504,11 +506,8 @@ if #[cfg(not(target_vendor = "uwp"))] { #[cfg(target_arch = "arm")] pub enum CONTEXT {} }} - -#[link(name = "ws2_32")] -extern "system" { - pub fn WSAStartup(wversionrequested: u16, lpwsadata: *mut WSADATA) -> i32; -} +// WSAStartup is only redefined here so that we can override WSADATA for Arm32 +windows_targets::link!("ws2_32.dll" "system" fn WSAStartup(wversionrequested: u16, lpwsadata: *mut WSADATA) -> i32); #[cfg(target_arch = "arm")] #[repr(C)] pub struct WSADATA { diff --git a/library/std/src/sys/pal/windows/c/bindings.txt b/library/std/src/sys/pal/windows/c/bindings.txt index 849e64ac59135..5ad4a3731d822 100644 --- a/library/std/src/sys/pal/windows/c/bindings.txt +++ b/library/std/src/sys/pal/windows/c/bindings.txt @@ -1,5 +1,5 @@ --out windows_sys.rs ---config flatten std +--config flatten sys --filter !Windows.Win32.Foundation.INVALID_HANDLE_VALUE Windows.Wdk.Storage.FileSystem.FILE_COMPLETE_IF_OPLOCKED diff --git a/library/std/src/sys/pal/windows/c/windows_sys.rs b/library/std/src/sys/pal/windows/c/windows_sys.rs index 19f013d3347e4..fea00fec9ae59 100644 --- a/library/std/src/sys/pal/windows/c/windows_sys.rs +++ b/library/std/src/sys/pal/windows/c/windows_sys.rs @@ -1,843 +1,136 @@ -// Bindings generated by `windows-bindgen` 0.57.0 +// Bindings generated by `windows-bindgen` 0.58.0 #![allow(non_snake_case, non_upper_case_globals, non_camel_case_types, dead_code, clippy::all)] -#[link(name = "advapi32")] -extern "system" { - pub fn OpenProcessToken( - processhandle: HANDLE, - desiredaccess: TOKEN_ACCESS_MASK, - tokenhandle: *mut HANDLE, - ) -> BOOL; -} -#[link(name = "advapi32")] -extern "system" { - #[link_name = "SystemFunction036"] - pub fn RtlGenRandom(randombuffer: *mut core::ffi::c_void, randombufferlength: u32) -> BOOLEAN; -} -#[link(name = "kernel32")] -extern "system" { - pub fn AcquireSRWLockExclusive(srwlock: *mut SRWLOCK); -} -#[link(name = "kernel32")] -extern "system" { - pub fn AcquireSRWLockShared(srwlock: *mut SRWLOCK); -} -#[link(name = "kernel32")] -extern "system" { - pub fn CancelIo(hfile: HANDLE) -> BOOL; -} -#[link(name = "kernel32")] -extern "system" { - pub fn CloseHandle(hobject: HANDLE) -> BOOL; -} -#[link(name = "kernel32")] -extern "system" { - pub fn CompareStringOrdinal( - lpstring1: PCWSTR, - cchcount1: i32, - lpstring2: PCWSTR, - cchcount2: i32, - bignorecase: BOOL, - ) -> COMPARESTRING_RESULT; -} -#[link(name = "kernel32")] -extern "system" { - pub fn CopyFileExW( - lpexistingfilename: PCWSTR, - lpnewfilename: PCWSTR, - lpprogressroutine: LPPROGRESS_ROUTINE, - lpdata: *const core::ffi::c_void, - pbcancel: *mut BOOL, - dwcopyflags: u32, - ) -> BOOL; -} -#[link(name = "kernel32")] -extern "system" { - pub fn CreateDirectoryW( - lppathname: PCWSTR, - lpsecurityattributes: *const SECURITY_ATTRIBUTES, - ) -> BOOL; -} -#[link(name = "kernel32")] -extern "system" { - pub fn CreateEventW( - lpeventattributes: *const SECURITY_ATTRIBUTES, - bmanualreset: BOOL, - binitialstate: BOOL, - lpname: PCWSTR, - ) -> HANDLE; -} -#[link(name = "kernel32")] -extern "system" { - pub fn CreateFileW( - lpfilename: PCWSTR, - dwdesiredaccess: u32, - dwsharemode: FILE_SHARE_MODE, - lpsecurityattributes: *const SECURITY_ATTRIBUTES, - dwcreationdisposition: FILE_CREATION_DISPOSITION, - dwflagsandattributes: FILE_FLAGS_AND_ATTRIBUTES, - htemplatefile: HANDLE, - ) -> HANDLE; -} -#[link(name = "kernel32")] -extern "system" { - pub fn CreateHardLinkW( - lpfilename: PCWSTR, - lpexistingfilename: PCWSTR, - lpsecurityattributes: *const SECURITY_ATTRIBUTES, - ) -> BOOL; -} -#[link(name = "kernel32")] -extern "system" { - pub fn CreateNamedPipeW( - lpname: PCWSTR, - dwopenmode: FILE_FLAGS_AND_ATTRIBUTES, - dwpipemode: NAMED_PIPE_MODE, - nmaxinstances: u32, - noutbuffersize: u32, - ninbuffersize: u32, - ndefaulttimeout: u32, - lpsecurityattributes: *const SECURITY_ATTRIBUTES, - ) -> HANDLE; -} -#[link(name = "kernel32")] -extern "system" { - pub fn CreateProcessW( - lpapplicationname: PCWSTR, - lpcommandline: PWSTR, - lpprocessattributes: *const SECURITY_ATTRIBUTES, - lpthreadattributes: *const SECURITY_ATTRIBUTES, - binherithandles: BOOL, - dwcreationflags: PROCESS_CREATION_FLAGS, - lpenvironment: *const core::ffi::c_void, - lpcurrentdirectory: PCWSTR, - lpstartupinfo: *const STARTUPINFOW, - lpprocessinformation: *mut PROCESS_INFORMATION, - ) -> BOOL; -} -#[link(name = "kernel32")] -extern "system" { - pub fn CreateSymbolicLinkW( - lpsymlinkfilename: PCWSTR, - lptargetfilename: PCWSTR, - dwflags: SYMBOLIC_LINK_FLAGS, - ) -> BOOLEAN; -} -#[link(name = "kernel32")] -extern "system" { - pub fn CreateThread( - lpthreadattributes: *const SECURITY_ATTRIBUTES, - dwstacksize: usize, - lpstartaddress: LPTHREAD_START_ROUTINE, - lpparameter: *const core::ffi::c_void, - dwcreationflags: THREAD_CREATION_FLAGS, - lpthreadid: *mut u32, - ) -> HANDLE; -} -#[link(name = "kernel32")] -extern "system" { - pub fn CreateWaitableTimerExW( - lptimerattributes: *const SECURITY_ATTRIBUTES, - lptimername: PCWSTR, - dwflags: u32, - dwdesiredaccess: u32, - ) -> HANDLE; -} -#[link(name = "kernel32")] -extern "system" { - pub fn DeleteFileW(lpfilename: PCWSTR) -> BOOL; -} -#[link(name = "kernel32")] -extern "system" { - pub fn DeleteProcThreadAttributeList(lpattributelist: LPPROC_THREAD_ATTRIBUTE_LIST); -} -#[link(name = "kernel32")] -extern "system" { - pub fn DeviceIoControl( - hdevice: HANDLE, - dwiocontrolcode: u32, - lpinbuffer: *const core::ffi::c_void, - ninbuffersize: u32, - lpoutbuffer: *mut core::ffi::c_void, - noutbuffersize: u32, - lpbytesreturned: *mut u32, - lpoverlapped: *mut OVERLAPPED, - ) -> BOOL; -} -#[link(name = "kernel32")] -extern "system" { - pub fn DuplicateHandle( - hsourceprocesshandle: HANDLE, - hsourcehandle: HANDLE, - htargetprocesshandle: HANDLE, - lptargethandle: *mut HANDLE, - dwdesiredaccess: u32, - binherithandle: BOOL, - dwoptions: DUPLICATE_HANDLE_OPTIONS, - ) -> BOOL; -} -#[link(name = "kernel32")] -extern "system" { - pub fn ExitProcess(uexitcode: u32) -> !; -} -#[link(name = "kernel32")] -extern "system" { - pub fn FindClose(hfindfile: HANDLE) -> BOOL; -} -#[link(name = "kernel32")] -extern "system" { - pub fn FindFirstFileW(lpfilename: PCWSTR, lpfindfiledata: *mut WIN32_FIND_DATAW) -> HANDLE; -} -#[link(name = "kernel32")] -extern "system" { - pub fn FindNextFileW(hfindfile: HANDLE, lpfindfiledata: *mut WIN32_FIND_DATAW) -> BOOL; -} -#[link(name = "kernel32")] -extern "system" { - pub fn FlushFileBuffers(hfile: HANDLE) -> BOOL; -} -#[link(name = "kernel32")] -extern "system" { - pub fn FormatMessageW( - dwflags: FORMAT_MESSAGE_OPTIONS, - lpsource: *const core::ffi::c_void, - dwmessageid: u32, - dwlanguageid: u32, - lpbuffer: PWSTR, - nsize: u32, - arguments: *const *const i8, - ) -> u32; -} -#[link(name = "kernel32")] -extern "system" { - pub fn FreeEnvironmentStringsW(penv: PCWSTR) -> BOOL; -} -#[link(name = "kernel32")] -extern "system" { - pub fn GetActiveProcessorCount(groupnumber: u16) -> u32; -} -#[link(name = "kernel32")] -extern "system" { - pub fn GetCommandLineW() -> PCWSTR; -} -#[link(name = "kernel32")] -extern "system" { - pub fn GetConsoleMode(hconsolehandle: HANDLE, lpmode: *mut CONSOLE_MODE) -> BOOL; -} -#[link(name = "kernel32")] -extern "system" { - pub fn GetCurrentDirectoryW(nbufferlength: u32, lpbuffer: PWSTR) -> u32; -} -#[link(name = "kernel32")] -extern "system" { - pub fn GetCurrentProcess() -> HANDLE; -} -#[link(name = "kernel32")] -extern "system" { - pub fn GetCurrentProcessId() -> u32; -} -#[link(name = "kernel32")] -extern "system" { - pub fn GetCurrentThread() -> HANDLE; -} -#[link(name = "kernel32")] -extern "system" { - pub fn GetEnvironmentStringsW() -> PWSTR; -} -#[link(name = "kernel32")] -extern "system" { - pub fn GetEnvironmentVariableW(lpname: PCWSTR, lpbuffer: PWSTR, nsize: u32) -> u32; -} -#[link(name = "kernel32")] -extern "system" { - pub fn GetExitCodeProcess(hprocess: HANDLE, lpexitcode: *mut u32) -> BOOL; -} -#[link(name = "kernel32")] -extern "system" { - pub fn GetFileAttributesW(lpfilename: PCWSTR) -> u32; -} -#[link(name = "kernel32")] -extern "system" { - pub fn GetFileInformationByHandle( - hfile: HANDLE, - lpfileinformation: *mut BY_HANDLE_FILE_INFORMATION, - ) -> BOOL; -} -#[link(name = "kernel32")] -extern "system" { - pub fn GetFileInformationByHandleEx( - hfile: HANDLE, - fileinformationclass: FILE_INFO_BY_HANDLE_CLASS, - lpfileinformation: *mut core::ffi::c_void, - dwbuffersize: u32, - ) -> BOOL; -} -#[link(name = "kernel32")] -extern "system" { - pub fn GetFileType(hfile: HANDLE) -> FILE_TYPE; -} -#[link(name = "kernel32")] -extern "system" { - pub fn GetFinalPathNameByHandleW( - hfile: HANDLE, - lpszfilepath: PWSTR, - cchfilepath: u32, - dwflags: GETFINALPATHNAMEBYHANDLE_FLAGS, - ) -> u32; -} -#[link(name = "kernel32")] -extern "system" { - pub fn GetFullPathNameW( - lpfilename: PCWSTR, - nbufferlength: u32, - lpbuffer: PWSTR, - lpfilepart: *mut PWSTR, - ) -> u32; -} -#[link(name = "kernel32")] -extern "system" { - pub fn GetLastError() -> WIN32_ERROR; -} -#[link(name = "kernel32")] -extern "system" { - pub fn GetModuleFileNameW(hmodule: HMODULE, lpfilename: PWSTR, nsize: u32) -> u32; -} -#[link(name = "kernel32")] -extern "system" { - pub fn GetModuleHandleA(lpmodulename: PCSTR) -> HMODULE; -} -#[link(name = "kernel32")] -extern "system" { - pub fn GetModuleHandleW(lpmodulename: PCWSTR) -> HMODULE; -} -#[link(name = "kernel32")] -extern "system" { - pub fn GetOverlappedResult( - hfile: HANDLE, - lpoverlapped: *const OVERLAPPED, - lpnumberofbytestransferred: *mut u32, - bwait: BOOL, - ) -> BOOL; -} -#[link(name = "kernel32")] -extern "system" { - pub fn GetProcAddress(hmodule: HMODULE, lpprocname: PCSTR) -> FARPROC; -} -#[link(name = "kernel32")] -extern "system" { - pub fn GetProcessId(process: HANDLE) -> u32; -} -#[link(name = "kernel32")] -extern "system" { - pub fn GetStdHandle(nstdhandle: STD_HANDLE) -> HANDLE; -} -#[link(name = "kernel32")] -extern "system" { - pub fn GetSystemDirectoryW(lpbuffer: PWSTR, usize: u32) -> u32; -} -#[link(name = "kernel32")] -extern "system" { - pub fn GetSystemInfo(lpsysteminfo: *mut SYSTEM_INFO); -} -#[link(name = "kernel32")] -extern "system" { - pub fn GetSystemTimeAsFileTime(lpsystemtimeasfiletime: *mut FILETIME); -} -#[link(name = "kernel32")] -extern "system" { - pub fn GetSystemTimePreciseAsFileTime(lpsystemtimeasfiletime: *mut FILETIME); -} -#[link(name = "kernel32")] -extern "system" { - pub fn GetTempPathW(nbufferlength: u32, lpbuffer: PWSTR) -> u32; -} -#[link(name = "kernel32")] -extern "system" { - pub fn GetWindowsDirectoryW(lpbuffer: PWSTR, usize: u32) -> u32; -} -#[link(name = "kernel32")] -extern "system" { - pub fn InitOnceBeginInitialize( - lpinitonce: *mut INIT_ONCE, - dwflags: u32, - fpending: *mut BOOL, - lpcontext: *mut *mut core::ffi::c_void, - ) -> BOOL; -} -#[link(name = "kernel32")] -extern "system" { - pub fn InitOnceComplete( - lpinitonce: *mut INIT_ONCE, - dwflags: u32, - lpcontext: *const core::ffi::c_void, - ) -> BOOL; -} -#[link(name = "kernel32")] -extern "system" { - pub fn InitializeProcThreadAttributeList( - lpattributelist: LPPROC_THREAD_ATTRIBUTE_LIST, - dwattributecount: u32, - dwflags: u32, - lpsize: *mut usize, - ) -> BOOL; -} -#[link(name = "kernel32")] -extern "system" { - pub fn LocalFree(hmem: HLOCAL) -> HLOCAL; -} -#[link(name = "kernel32")] -extern "system" { - pub fn MoveFileExW( - lpexistingfilename: PCWSTR, - lpnewfilename: PCWSTR, - dwflags: MOVE_FILE_FLAGS, - ) -> BOOL; -} -#[link(name = "kernel32")] -extern "system" { - pub fn MultiByteToWideChar( - codepage: u32, - dwflags: MULTI_BYTE_TO_WIDE_CHAR_FLAGS, - lpmultibytestr: PCSTR, - cbmultibyte: i32, - lpwidecharstr: PWSTR, - cchwidechar: i32, - ) -> i32; -} -#[link(name = "kernel32")] -extern "system" { - pub fn QueryPerformanceCounter(lpperformancecount: *mut i64) -> BOOL; -} -#[link(name = "kernel32")] -extern "system" { - pub fn QueryPerformanceFrequency(lpfrequency: *mut i64) -> BOOL; -} -#[link(name = "kernel32")] -extern "system" { - pub fn ReadConsoleW( - hconsoleinput: HANDLE, - lpbuffer: *mut core::ffi::c_void, - nnumberofcharstoread: u32, - lpnumberofcharsread: *mut u32, - pinputcontrol: *const CONSOLE_READCONSOLE_CONTROL, - ) -> BOOL; -} -#[link(name = "kernel32")] -extern "system" { - pub fn ReadFile( - hfile: HANDLE, - lpbuffer: *mut u8, - nnumberofbytestoread: u32, - lpnumberofbytesread: *mut u32, - lpoverlapped: *mut OVERLAPPED, - ) -> BOOL; -} -#[link(name = "kernel32")] -extern "system" { - pub fn ReadFileEx( - hfile: HANDLE, - lpbuffer: *mut u8, - nnumberofbytestoread: u32, - lpoverlapped: *mut OVERLAPPED, - lpcompletionroutine: LPOVERLAPPED_COMPLETION_ROUTINE, - ) -> BOOL; -} -#[link(name = "kernel32")] -extern "system" { - pub fn ReleaseSRWLockExclusive(srwlock: *mut SRWLOCK); -} -#[link(name = "kernel32")] -extern "system" { - pub fn ReleaseSRWLockShared(srwlock: *mut SRWLOCK); -} -#[link(name = "kernel32")] -extern "system" { - pub fn RemoveDirectoryW(lppathname: PCWSTR) -> BOOL; -} -#[link(name = "kernel32")] -extern "system" { - pub fn SetCurrentDirectoryW(lppathname: PCWSTR) -> BOOL; -} -#[link(name = "kernel32")] -extern "system" { - pub fn SetEnvironmentVariableW(lpname: PCWSTR, lpvalue: PCWSTR) -> BOOL; -} -#[link(name = "kernel32")] -extern "system" { - pub fn SetFileAttributesW( - lpfilename: PCWSTR, - dwfileattributes: FILE_FLAGS_AND_ATTRIBUTES, - ) -> BOOL; -} -#[link(name = "kernel32")] -extern "system" { - pub fn SetFileInformationByHandle( - hfile: HANDLE, - fileinformationclass: FILE_INFO_BY_HANDLE_CLASS, - lpfileinformation: *const core::ffi::c_void, - dwbuffersize: u32, - ) -> BOOL; -} -#[link(name = "kernel32")] -extern "system" { - pub fn SetFilePointerEx( - hfile: HANDLE, - lidistancetomove: i64, - lpnewfilepointer: *mut i64, - dwmovemethod: SET_FILE_POINTER_MOVE_METHOD, - ) -> BOOL; -} -#[link(name = "kernel32")] -extern "system" { - pub fn SetFileTime( - hfile: HANDLE, - lpcreationtime: *const FILETIME, - lplastaccesstime: *const FILETIME, - lplastwritetime: *const FILETIME, - ) -> BOOL; -} -#[link(name = "kernel32")] -extern "system" { - pub fn SetHandleInformation(hobject: HANDLE, dwmask: u32, dwflags: HANDLE_FLAGS) -> BOOL; -} -#[link(name = "kernel32")] -extern "system" { - pub fn SetLastError(dwerrcode: WIN32_ERROR); -} -#[link(name = "kernel32")] -extern "system" { - pub fn SetThreadStackGuarantee(stacksizeinbytes: *mut u32) -> BOOL; -} -#[link(name = "kernel32")] -extern "system" { - pub fn SetWaitableTimer( - htimer: HANDLE, - lpduetime: *const i64, - lperiod: i32, - pfncompletionroutine: PTIMERAPCROUTINE, - lpargtocompletionroutine: *const core::ffi::c_void, - fresume: BOOL, - ) -> BOOL; -} -#[link(name = "kernel32")] -extern "system" { - pub fn Sleep(dwmilliseconds: u32); -} -#[link(name = "kernel32")] -extern "system" { - pub fn SleepConditionVariableSRW( - conditionvariable: *mut CONDITION_VARIABLE, - srwlock: *mut SRWLOCK, - dwmilliseconds: u32, - flags: u32, - ) -> BOOL; -} -#[link(name = "kernel32")] -extern "system" { - pub fn SleepEx(dwmilliseconds: u32, balertable: BOOL) -> u32; -} -#[link(name = "kernel32")] -extern "system" { - pub fn SwitchToThread() -> BOOL; -} -#[link(name = "kernel32")] -extern "system" { - pub fn TerminateProcess(hprocess: HANDLE, uexitcode: u32) -> BOOL; -} -#[link(name = "kernel32")] -extern "system" { - pub fn TlsAlloc() -> u32; -} -#[link(name = "kernel32")] -extern "system" { - pub fn TlsFree(dwtlsindex: u32) -> BOOL; -} -#[link(name = "kernel32")] -extern "system" { - pub fn TlsGetValue(dwtlsindex: u32) -> *mut core::ffi::c_void; -} -#[link(name = "kernel32")] -extern "system" { - pub fn TlsSetValue(dwtlsindex: u32, lptlsvalue: *const core::ffi::c_void) -> BOOL; -} -#[link(name = "kernel32")] -extern "system" { - pub fn TryAcquireSRWLockExclusive(srwlock: *mut SRWLOCK) -> BOOLEAN; -} -#[link(name = "kernel32")] -extern "system" { - pub fn TryAcquireSRWLockShared(srwlock: *mut SRWLOCK) -> BOOLEAN; -} -#[link(name = "kernel32")] -extern "system" { - pub fn UpdateProcThreadAttribute( - lpattributelist: LPPROC_THREAD_ATTRIBUTE_LIST, - dwflags: u32, - attribute: usize, - lpvalue: *const core::ffi::c_void, - cbsize: usize, - lppreviousvalue: *mut core::ffi::c_void, - lpreturnsize: *const usize, - ) -> BOOL; -} -#[link(name = "kernel32")] -extern "system" { - pub fn WaitForMultipleObjects( - ncount: u32, - lphandles: *const HANDLE, - bwaitall: BOOL, - dwmilliseconds: u32, - ) -> WAIT_EVENT; -} -#[link(name = "kernel32")] -extern "system" { - pub fn WaitForSingleObject(hhandle: HANDLE, dwmilliseconds: u32) -> WAIT_EVENT; -} -#[link(name = "kernel32")] -extern "system" { - pub fn WakeAllConditionVariable(conditionvariable: *mut CONDITION_VARIABLE); -} -#[link(name = "kernel32")] -extern "system" { - pub fn WakeConditionVariable(conditionvariable: *mut CONDITION_VARIABLE); -} -#[link(name = "kernel32")] -extern "system" { - pub fn WideCharToMultiByte( - codepage: u32, - dwflags: u32, - lpwidecharstr: PCWSTR, - cchwidechar: i32, - lpmultibytestr: PSTR, - cbmultibyte: i32, - lpdefaultchar: PCSTR, - lpuseddefaultchar: *mut BOOL, - ) -> i32; -} -#[link(name = "kernel32")] -extern "system" { - pub fn WriteConsoleW( - hconsoleoutput: HANDLE, - lpbuffer: *const core::ffi::c_void, - nnumberofcharstowrite: u32, - lpnumberofcharswritten: *mut u32, - lpreserved: *const core::ffi::c_void, - ) -> BOOL; -} -#[link(name = "kernel32")] -extern "system" { - pub fn WriteFileEx( - hfile: HANDLE, - lpbuffer: *const u8, - nnumberofbytestowrite: u32, - lpoverlapped: *mut OVERLAPPED, - lpcompletionroutine: LPOVERLAPPED_COMPLETION_ROUTINE, - ) -> BOOL; -} -#[link(name = "ntdll")] -extern "system" { - pub fn NtCreateFile( - filehandle: *mut HANDLE, - desiredaccess: FILE_ACCESS_RIGHTS, - objectattributes: *const OBJECT_ATTRIBUTES, - iostatusblock: *mut IO_STATUS_BLOCK, - allocationsize: *const i64, - fileattributes: FILE_FLAGS_AND_ATTRIBUTES, - shareaccess: FILE_SHARE_MODE, - createdisposition: NTCREATEFILE_CREATE_DISPOSITION, - createoptions: NTCREATEFILE_CREATE_OPTIONS, - eabuffer: *const core::ffi::c_void, - ealength: u32, - ) -> NTSTATUS; -} -#[link(name = "ntdll")] -extern "system" { - pub fn NtReadFile( - filehandle: HANDLE, - event: HANDLE, - apcroutine: PIO_APC_ROUTINE, - apccontext: *const core::ffi::c_void, - iostatusblock: *mut IO_STATUS_BLOCK, - buffer: *mut core::ffi::c_void, - length: u32, - byteoffset: *const i64, - key: *const u32, - ) -> NTSTATUS; -} -#[link(name = "ntdll")] -extern "system" { - pub fn NtWriteFile( - filehandle: HANDLE, - event: HANDLE, - apcroutine: PIO_APC_ROUTINE, - apccontext: *const core::ffi::c_void, - iostatusblock: *mut IO_STATUS_BLOCK, - buffer: *const core::ffi::c_void, - length: u32, - byteoffset: *const i64, - key: *const u32, - ) -> NTSTATUS; -} -#[link(name = "ntdll")] -extern "system" { - pub fn RtlNtStatusToDosError(status: NTSTATUS) -> u32; -} -#[link(name = "userenv")] -extern "system" { - pub fn GetUserProfileDirectoryW( - htoken: HANDLE, - lpprofiledir: PWSTR, - lpcchsize: *mut u32, - ) -> BOOL; -} -#[link(name = "ws2_32")] -extern "system" { - pub fn WSACleanup() -> i32; -} -#[link(name = "ws2_32")] -extern "system" { - pub fn WSADuplicateSocketW( - s: SOCKET, - dwprocessid: u32, - lpprotocolinfo: *mut WSAPROTOCOL_INFOW, - ) -> i32; -} -#[link(name = "ws2_32")] -extern "system" { - pub fn WSAGetLastError() -> WSA_ERROR; -} -#[link(name = "ws2_32")] -extern "system" { - pub fn WSARecv( - s: SOCKET, - lpbuffers: *const WSABUF, - dwbuffercount: u32, - lpnumberofbytesrecvd: *mut u32, - lpflags: *mut u32, - lpoverlapped: *mut OVERLAPPED, - lpcompletionroutine: LPWSAOVERLAPPED_COMPLETION_ROUTINE, - ) -> i32; -} -#[link(name = "ws2_32")] -extern "system" { - pub fn WSASend( - s: SOCKET, - lpbuffers: *const WSABUF, - dwbuffercount: u32, - lpnumberofbytessent: *mut u32, - dwflags: u32, - lpoverlapped: *mut OVERLAPPED, - lpcompletionroutine: LPWSAOVERLAPPED_COMPLETION_ROUTINE, - ) -> i32; -} -#[link(name = "ws2_32")] -extern "system" { - pub fn WSASocketW( - af: i32, - r#type: i32, - protocol: i32, - lpprotocolinfo: *const WSAPROTOCOL_INFOW, - g: u32, - dwflags: u32, - ) -> SOCKET; -} -#[link(name = "ws2_32")] -extern "system" { - pub fn accept(s: SOCKET, addr: *mut SOCKADDR, addrlen: *mut i32) -> SOCKET; -} -#[link(name = "ws2_32")] -extern "system" { - pub fn bind(s: SOCKET, name: *const SOCKADDR, namelen: i32) -> i32; -} -#[link(name = "ws2_32")] -extern "system" { - pub fn closesocket(s: SOCKET) -> i32; -} -#[link(name = "ws2_32")] -extern "system" { - pub fn connect(s: SOCKET, name: *const SOCKADDR, namelen: i32) -> i32; -} -#[link(name = "ws2_32")] -extern "system" { - pub fn freeaddrinfo(paddrinfo: *const ADDRINFOA); -} -#[link(name = "ws2_32")] -extern "system" { - pub fn getaddrinfo( - pnodename: PCSTR, - pservicename: PCSTR, - phints: *const ADDRINFOA, - ppresult: *mut *mut ADDRINFOA, - ) -> i32; -} -#[link(name = "ws2_32")] -extern "system" { - pub fn getpeername(s: SOCKET, name: *mut SOCKADDR, namelen: *mut i32) -> i32; -} -#[link(name = "ws2_32")] -extern "system" { - pub fn getsockname(s: SOCKET, name: *mut SOCKADDR, namelen: *mut i32) -> i32; -} -#[link(name = "ws2_32")] -extern "system" { - pub fn getsockopt(s: SOCKET, level: i32, optname: i32, optval: PSTR, optlen: *mut i32) -> i32; -} -#[link(name = "ws2_32")] -extern "system" { - pub fn ioctlsocket(s: SOCKET, cmd: i32, argp: *mut u32) -> i32; -} -#[link(name = "ws2_32")] -extern "system" { - pub fn listen(s: SOCKET, backlog: i32) -> i32; -} -#[link(name = "ws2_32")] -extern "system" { - pub fn recv(s: SOCKET, buf: PSTR, len: i32, flags: SEND_RECV_FLAGS) -> i32; -} -#[link(name = "ws2_32")] -extern "system" { - pub fn recvfrom( - s: SOCKET, - buf: PSTR, - len: i32, - flags: i32, - from: *mut SOCKADDR, - fromlen: *mut i32, - ) -> i32; -} -#[link(name = "ws2_32")] -extern "system" { - pub fn select( - nfds: i32, - readfds: *mut FD_SET, - writefds: *mut FD_SET, - exceptfds: *mut FD_SET, - timeout: *const TIMEVAL, - ) -> i32; -} -#[link(name = "ws2_32")] -extern "system" { - pub fn send(s: SOCKET, buf: PCSTR, len: i32, flags: SEND_RECV_FLAGS) -> i32; -} -#[link(name = "ws2_32")] -extern "system" { - pub fn sendto( - s: SOCKET, - buf: PCSTR, - len: i32, - flags: i32, - to: *const SOCKADDR, - tolen: i32, - ) -> i32; -} -#[link(name = "ws2_32")] -extern "system" { - pub fn setsockopt(s: SOCKET, level: i32, optname: i32, optval: PCSTR, optlen: i32) -> i32; -} -#[link(name = "ws2_32")] -extern "system" { - pub fn shutdown(s: SOCKET, how: WINSOCK_SHUTDOWN_HOW) -> i32; -} +windows_targets::link!("advapi32.dll" "system" fn OpenProcessToken(processhandle : HANDLE, desiredaccess : TOKEN_ACCESS_MASK, tokenhandle : *mut HANDLE) -> BOOL); +windows_targets::link!("advapi32.dll" "system" "SystemFunction036" fn RtlGenRandom(randombuffer : *mut core::ffi::c_void, randombufferlength : u32) -> BOOLEAN); +windows_targets::link!("kernel32.dll" "system" fn AcquireSRWLockExclusive(srwlock : *mut SRWLOCK)); +windows_targets::link!("kernel32.dll" "system" fn AcquireSRWLockShared(srwlock : *mut SRWLOCK)); +windows_targets::link!("kernel32.dll" "system" fn CancelIo(hfile : HANDLE) -> BOOL); +windows_targets::link!("kernel32.dll" "system" fn CloseHandle(hobject : HANDLE) -> BOOL); +windows_targets::link!("kernel32.dll" "system" fn CompareStringOrdinal(lpstring1 : PCWSTR, cchcount1 : i32, lpstring2 : PCWSTR, cchcount2 : i32, bignorecase : BOOL) -> COMPARESTRING_RESULT); +windows_targets::link!("kernel32.dll" "system" fn CopyFileExW(lpexistingfilename : PCWSTR, lpnewfilename : PCWSTR, lpprogressroutine : LPPROGRESS_ROUTINE, lpdata : *const core::ffi::c_void, pbcancel : *mut BOOL, dwcopyflags : u32) -> BOOL); +windows_targets::link!("kernel32.dll" "system" fn CreateDirectoryW(lppathname : PCWSTR, lpsecurityattributes : *const SECURITY_ATTRIBUTES) -> BOOL); +windows_targets::link!("kernel32.dll" "system" fn CreateEventW(lpeventattributes : *const SECURITY_ATTRIBUTES, bmanualreset : BOOL, binitialstate : BOOL, lpname : PCWSTR) -> HANDLE); +windows_targets::link!("kernel32.dll" "system" fn CreateFileW(lpfilename : PCWSTR, dwdesiredaccess : u32, dwsharemode : FILE_SHARE_MODE, lpsecurityattributes : *const SECURITY_ATTRIBUTES, dwcreationdisposition : FILE_CREATION_DISPOSITION, dwflagsandattributes : FILE_FLAGS_AND_ATTRIBUTES, htemplatefile : HANDLE) -> HANDLE); +windows_targets::link!("kernel32.dll" "system" fn CreateHardLinkW(lpfilename : PCWSTR, lpexistingfilename : PCWSTR, lpsecurityattributes : *const SECURITY_ATTRIBUTES) -> BOOL); +windows_targets::link!("kernel32.dll" "system" fn CreateNamedPipeW(lpname : PCWSTR, dwopenmode : FILE_FLAGS_AND_ATTRIBUTES, dwpipemode : NAMED_PIPE_MODE, nmaxinstances : u32, noutbuffersize : u32, ninbuffersize : u32, ndefaulttimeout : u32, lpsecurityattributes : *const SECURITY_ATTRIBUTES) -> HANDLE); +windows_targets::link!("kernel32.dll" "system" fn CreateProcessW(lpapplicationname : PCWSTR, lpcommandline : PWSTR, lpprocessattributes : *const SECURITY_ATTRIBUTES, lpthreadattributes : *const SECURITY_ATTRIBUTES, binherithandles : BOOL, dwcreationflags : PROCESS_CREATION_FLAGS, lpenvironment : *const core::ffi::c_void, lpcurrentdirectory : PCWSTR, lpstartupinfo : *const STARTUPINFOW, lpprocessinformation : *mut PROCESS_INFORMATION) -> BOOL); +windows_targets::link!("kernel32.dll" "system" fn CreateSymbolicLinkW(lpsymlinkfilename : PCWSTR, lptargetfilename : PCWSTR, dwflags : SYMBOLIC_LINK_FLAGS) -> BOOLEAN); +windows_targets::link!("kernel32.dll" "system" fn CreateThread(lpthreadattributes : *const SECURITY_ATTRIBUTES, dwstacksize : usize, lpstartaddress : LPTHREAD_START_ROUTINE, lpparameter : *const core::ffi::c_void, dwcreationflags : THREAD_CREATION_FLAGS, lpthreadid : *mut u32) -> HANDLE); +windows_targets::link!("kernel32.dll" "system" fn CreateWaitableTimerExW(lptimerattributes : *const SECURITY_ATTRIBUTES, lptimername : PCWSTR, dwflags : u32, dwdesiredaccess : u32) -> HANDLE); +windows_targets::link!("kernel32.dll" "system" fn DeleteFileW(lpfilename : PCWSTR) -> BOOL); +windows_targets::link!("kernel32.dll" "system" fn DeleteProcThreadAttributeList(lpattributelist : LPPROC_THREAD_ATTRIBUTE_LIST)); +windows_targets::link!("kernel32.dll" "system" fn DeviceIoControl(hdevice : HANDLE, dwiocontrolcode : u32, lpinbuffer : *const core::ffi::c_void, ninbuffersize : u32, lpoutbuffer : *mut core::ffi::c_void, noutbuffersize : u32, lpbytesreturned : *mut u32, lpoverlapped : *mut OVERLAPPED) -> BOOL); +windows_targets::link!("kernel32.dll" "system" fn DuplicateHandle(hsourceprocesshandle : HANDLE, hsourcehandle : HANDLE, htargetprocesshandle : HANDLE, lptargethandle : *mut HANDLE, dwdesiredaccess : u32, binherithandle : BOOL, dwoptions : DUPLICATE_HANDLE_OPTIONS) -> BOOL); +windows_targets::link!("kernel32.dll" "system" fn ExitProcess(uexitcode : u32) -> !); +windows_targets::link!("kernel32.dll" "system" fn FindClose(hfindfile : HANDLE) -> BOOL); +windows_targets::link!("kernel32.dll" "system" fn FindFirstFileW(lpfilename : PCWSTR, lpfindfiledata : *mut WIN32_FIND_DATAW) -> HANDLE); +windows_targets::link!("kernel32.dll" "system" fn FindNextFileW(hfindfile : HANDLE, lpfindfiledata : *mut WIN32_FIND_DATAW) -> BOOL); +windows_targets::link!("kernel32.dll" "system" fn FlushFileBuffers(hfile : HANDLE) -> BOOL); +windows_targets::link!("kernel32.dll" "system" fn FormatMessageW(dwflags : FORMAT_MESSAGE_OPTIONS, lpsource : *const core::ffi::c_void, dwmessageid : u32, dwlanguageid : u32, lpbuffer : PWSTR, nsize : u32, arguments : *const *const i8) -> u32); +windows_targets::link!("kernel32.dll" "system" fn FreeEnvironmentStringsW(penv : PCWSTR) -> BOOL); +windows_targets::link!("kernel32.dll" "system" fn GetActiveProcessorCount(groupnumber : u16) -> u32); +windows_targets::link!("kernel32.dll" "system" fn GetCommandLineW() -> PCWSTR); +windows_targets::link!("kernel32.dll" "system" fn GetConsoleMode(hconsolehandle : HANDLE, lpmode : *mut CONSOLE_MODE) -> BOOL); +windows_targets::link!("kernel32.dll" "system" fn GetCurrentDirectoryW(nbufferlength : u32, lpbuffer : PWSTR) -> u32); +windows_targets::link!("kernel32.dll" "system" fn GetCurrentProcess() -> HANDLE); +windows_targets::link!("kernel32.dll" "system" fn GetCurrentProcessId() -> u32); +windows_targets::link!("kernel32.dll" "system" fn GetCurrentThread() -> HANDLE); +windows_targets::link!("kernel32.dll" "system" fn GetEnvironmentStringsW() -> PWSTR); +windows_targets::link!("kernel32.dll" "system" fn GetEnvironmentVariableW(lpname : PCWSTR, lpbuffer : PWSTR, nsize : u32) -> u32); +windows_targets::link!("kernel32.dll" "system" fn GetExitCodeProcess(hprocess : HANDLE, lpexitcode : *mut u32) -> BOOL); +windows_targets::link!("kernel32.dll" "system" fn GetFileAttributesW(lpfilename : PCWSTR) -> u32); +windows_targets::link!("kernel32.dll" "system" fn GetFileInformationByHandle(hfile : HANDLE, lpfileinformation : *mut BY_HANDLE_FILE_INFORMATION) -> BOOL); +windows_targets::link!("kernel32.dll" "system" fn GetFileInformationByHandleEx(hfile : HANDLE, fileinformationclass : FILE_INFO_BY_HANDLE_CLASS, lpfileinformation : *mut core::ffi::c_void, dwbuffersize : u32) -> BOOL); +windows_targets::link!("kernel32.dll" "system" fn GetFileType(hfile : HANDLE) -> FILE_TYPE); +windows_targets::link!("kernel32.dll" "system" fn GetFinalPathNameByHandleW(hfile : HANDLE, lpszfilepath : PWSTR, cchfilepath : u32, dwflags : GETFINALPATHNAMEBYHANDLE_FLAGS) -> u32); +windows_targets::link!("kernel32.dll" "system" fn GetFullPathNameW(lpfilename : PCWSTR, nbufferlength : u32, lpbuffer : PWSTR, lpfilepart : *mut PWSTR) -> u32); +windows_targets::link!("kernel32.dll" "system" fn GetLastError() -> WIN32_ERROR); +windows_targets::link!("kernel32.dll" "system" fn GetModuleFileNameW(hmodule : HMODULE, lpfilename : PWSTR, nsize : u32) -> u32); +windows_targets::link!("kernel32.dll" "system" fn GetModuleHandleA(lpmodulename : PCSTR) -> HMODULE); +windows_targets::link!("kernel32.dll" "system" fn GetModuleHandleW(lpmodulename : PCWSTR) -> HMODULE); +windows_targets::link!("kernel32.dll" "system" fn GetOverlappedResult(hfile : HANDLE, lpoverlapped : *const OVERLAPPED, lpnumberofbytestransferred : *mut u32, bwait : BOOL) -> BOOL); +windows_targets::link!("kernel32.dll" "system" fn GetProcAddress(hmodule : HMODULE, lpprocname : PCSTR) -> FARPROC); +windows_targets::link!("kernel32.dll" "system" fn GetProcessId(process : HANDLE) -> u32); +windows_targets::link!("kernel32.dll" "system" fn GetStdHandle(nstdhandle : STD_HANDLE) -> HANDLE); +windows_targets::link!("kernel32.dll" "system" fn GetSystemDirectoryW(lpbuffer : PWSTR, usize : u32) -> u32); +windows_targets::link!("kernel32.dll" "system" fn GetSystemInfo(lpsysteminfo : *mut SYSTEM_INFO)); +windows_targets::link!("kernel32.dll" "system" fn GetSystemTimeAsFileTime(lpsystemtimeasfiletime : *mut FILETIME)); +windows_targets::link!("kernel32.dll" "system" fn GetSystemTimePreciseAsFileTime(lpsystemtimeasfiletime : *mut FILETIME)); +windows_targets::link!("kernel32.dll" "system" fn GetTempPathW(nbufferlength : u32, lpbuffer : PWSTR) -> u32); +windows_targets::link!("kernel32.dll" "system" fn GetWindowsDirectoryW(lpbuffer : PWSTR, usize : u32) -> u32); +windows_targets::link!("kernel32.dll" "system" fn InitOnceBeginInitialize(lpinitonce : *mut INIT_ONCE, dwflags : u32, fpending : *mut BOOL, lpcontext : *mut *mut core::ffi::c_void) -> BOOL); +windows_targets::link!("kernel32.dll" "system" fn InitOnceComplete(lpinitonce : *mut INIT_ONCE, dwflags : u32, lpcontext : *const core::ffi::c_void) -> BOOL); +windows_targets::link!("kernel32.dll" "system" fn InitializeProcThreadAttributeList(lpattributelist : LPPROC_THREAD_ATTRIBUTE_LIST, dwattributecount : u32, dwflags : u32, lpsize : *mut usize) -> BOOL); +windows_targets::link!("kernel32.dll" "system" fn LocalFree(hmem : HLOCAL) -> HLOCAL); +windows_targets::link!("kernel32.dll" "system" fn MoveFileExW(lpexistingfilename : PCWSTR, lpnewfilename : PCWSTR, dwflags : MOVE_FILE_FLAGS) -> BOOL); +windows_targets::link!("kernel32.dll" "system" fn MultiByteToWideChar(codepage : u32, dwflags : MULTI_BYTE_TO_WIDE_CHAR_FLAGS, lpmultibytestr : PCSTR, cbmultibyte : i32, lpwidecharstr : PWSTR, cchwidechar : i32) -> i32); +windows_targets::link!("kernel32.dll" "system" fn QueryPerformanceCounter(lpperformancecount : *mut i64) -> BOOL); +windows_targets::link!("kernel32.dll" "system" fn QueryPerformanceFrequency(lpfrequency : *mut i64) -> BOOL); +windows_targets::link!("kernel32.dll" "system" fn ReadConsoleW(hconsoleinput : HANDLE, lpbuffer : *mut core::ffi::c_void, nnumberofcharstoread : u32, lpnumberofcharsread : *mut u32, pinputcontrol : *const CONSOLE_READCONSOLE_CONTROL) -> BOOL); +windows_targets::link!("kernel32.dll" "system" fn ReadFile(hfile : HANDLE, lpbuffer : *mut u8, nnumberofbytestoread : u32, lpnumberofbytesread : *mut u32, lpoverlapped : *mut OVERLAPPED) -> BOOL); +windows_targets::link!("kernel32.dll" "system" fn ReadFileEx(hfile : HANDLE, lpbuffer : *mut u8, nnumberofbytestoread : u32, lpoverlapped : *mut OVERLAPPED, lpcompletionroutine : LPOVERLAPPED_COMPLETION_ROUTINE) -> BOOL); +windows_targets::link!("kernel32.dll" "system" fn ReleaseSRWLockExclusive(srwlock : *mut SRWLOCK)); +windows_targets::link!("kernel32.dll" "system" fn ReleaseSRWLockShared(srwlock : *mut SRWLOCK)); +windows_targets::link!("kernel32.dll" "system" fn RemoveDirectoryW(lppathname : PCWSTR) -> BOOL); +windows_targets::link!("kernel32.dll" "system" fn SetCurrentDirectoryW(lppathname : PCWSTR) -> BOOL); +windows_targets::link!("kernel32.dll" "system" fn SetEnvironmentVariableW(lpname : PCWSTR, lpvalue : PCWSTR) -> BOOL); +windows_targets::link!("kernel32.dll" "system" fn SetFileAttributesW(lpfilename : PCWSTR, dwfileattributes : FILE_FLAGS_AND_ATTRIBUTES) -> BOOL); +windows_targets::link!("kernel32.dll" "system" fn SetFileInformationByHandle(hfile : HANDLE, fileinformationclass : FILE_INFO_BY_HANDLE_CLASS, lpfileinformation : *const core::ffi::c_void, dwbuffersize : u32) -> BOOL); +windows_targets::link!("kernel32.dll" "system" fn SetFilePointerEx(hfile : HANDLE, lidistancetomove : i64, lpnewfilepointer : *mut i64, dwmovemethod : SET_FILE_POINTER_MOVE_METHOD) -> BOOL); +windows_targets::link!("kernel32.dll" "system" fn SetFileTime(hfile : HANDLE, lpcreationtime : *const FILETIME, lplastaccesstime : *const FILETIME, lplastwritetime : *const FILETIME) -> BOOL); +windows_targets::link!("kernel32.dll" "system" fn SetHandleInformation(hobject : HANDLE, dwmask : u32, dwflags : HANDLE_FLAGS) -> BOOL); +windows_targets::link!("kernel32.dll" "system" fn SetLastError(dwerrcode : WIN32_ERROR)); +windows_targets::link!("kernel32.dll" "system" fn SetThreadStackGuarantee(stacksizeinbytes : *mut u32) -> BOOL); +windows_targets::link!("kernel32.dll" "system" fn SetWaitableTimer(htimer : HANDLE, lpduetime : *const i64, lperiod : i32, pfncompletionroutine : PTIMERAPCROUTINE, lpargtocompletionroutine : *const core::ffi::c_void, fresume : BOOL) -> BOOL); +windows_targets::link!("kernel32.dll" "system" fn Sleep(dwmilliseconds : u32)); +windows_targets::link!("kernel32.dll" "system" fn SleepConditionVariableSRW(conditionvariable : *mut CONDITION_VARIABLE, srwlock : *mut SRWLOCK, dwmilliseconds : u32, flags : u32) -> BOOL); +windows_targets::link!("kernel32.dll" "system" fn SleepEx(dwmilliseconds : u32, balertable : BOOL) -> u32); +windows_targets::link!("kernel32.dll" "system" fn SwitchToThread() -> BOOL); +windows_targets::link!("kernel32.dll" "system" fn TerminateProcess(hprocess : HANDLE, uexitcode : u32) -> BOOL); +windows_targets::link!("kernel32.dll" "system" fn TlsAlloc() -> u32); +windows_targets::link!("kernel32.dll" "system" fn TlsFree(dwtlsindex : u32) -> BOOL); +windows_targets::link!("kernel32.dll" "system" fn TlsGetValue(dwtlsindex : u32) -> *mut core::ffi::c_void); +windows_targets::link!("kernel32.dll" "system" fn TlsSetValue(dwtlsindex : u32, lptlsvalue : *const core::ffi::c_void) -> BOOL); +windows_targets::link!("kernel32.dll" "system" fn TryAcquireSRWLockExclusive(srwlock : *mut SRWLOCK) -> BOOLEAN); +windows_targets::link!("kernel32.dll" "system" fn TryAcquireSRWLockShared(srwlock : *mut SRWLOCK) -> BOOLEAN); +windows_targets::link!("kernel32.dll" "system" fn UpdateProcThreadAttribute(lpattributelist : LPPROC_THREAD_ATTRIBUTE_LIST, dwflags : u32, attribute : usize, lpvalue : *const core::ffi::c_void, cbsize : usize, lppreviousvalue : *mut core::ffi::c_void, lpreturnsize : *const usize) -> BOOL); +windows_targets::link!("kernel32.dll" "system" fn WaitForMultipleObjects(ncount : u32, lphandles : *const HANDLE, bwaitall : BOOL, dwmilliseconds : u32) -> WAIT_EVENT); +windows_targets::link!("kernel32.dll" "system" fn WaitForSingleObject(hhandle : HANDLE, dwmilliseconds : u32) -> WAIT_EVENT); +windows_targets::link!("kernel32.dll" "system" fn WakeAllConditionVariable(conditionvariable : *mut CONDITION_VARIABLE)); +windows_targets::link!("kernel32.dll" "system" fn WakeConditionVariable(conditionvariable : *mut CONDITION_VARIABLE)); +windows_targets::link!("kernel32.dll" "system" fn WideCharToMultiByte(codepage : u32, dwflags : u32, lpwidecharstr : PCWSTR, cchwidechar : i32, lpmultibytestr : PSTR, cbmultibyte : i32, lpdefaultchar : PCSTR, lpuseddefaultchar : *mut BOOL) -> i32); +windows_targets::link!("kernel32.dll" "system" fn WriteConsoleW(hconsoleoutput : HANDLE, lpbuffer : PCWSTR, nnumberofcharstowrite : u32, lpnumberofcharswritten : *mut u32, lpreserved : *const core::ffi::c_void) -> BOOL); +windows_targets::link!("kernel32.dll" "system" fn WriteFileEx(hfile : HANDLE, lpbuffer : *const u8, nnumberofbytestowrite : u32, lpoverlapped : *mut OVERLAPPED, lpcompletionroutine : LPOVERLAPPED_COMPLETION_ROUTINE) -> BOOL); +windows_targets::link!("ntdll.dll" "system" fn NtCreateFile(filehandle : *mut HANDLE, desiredaccess : FILE_ACCESS_RIGHTS, objectattributes : *const OBJECT_ATTRIBUTES, iostatusblock : *mut IO_STATUS_BLOCK, allocationsize : *const i64, fileattributes : FILE_FLAGS_AND_ATTRIBUTES, shareaccess : FILE_SHARE_MODE, createdisposition : NTCREATEFILE_CREATE_DISPOSITION, createoptions : NTCREATEFILE_CREATE_OPTIONS, eabuffer : *const core::ffi::c_void, ealength : u32) -> NTSTATUS); +windows_targets::link!("ntdll.dll" "system" fn NtReadFile(filehandle : HANDLE, event : HANDLE, apcroutine : PIO_APC_ROUTINE, apccontext : *const core::ffi::c_void, iostatusblock : *mut IO_STATUS_BLOCK, buffer : *mut core::ffi::c_void, length : u32, byteoffset : *const i64, key : *const u32) -> NTSTATUS); +windows_targets::link!("ntdll.dll" "system" fn NtWriteFile(filehandle : HANDLE, event : HANDLE, apcroutine : PIO_APC_ROUTINE, apccontext : *const core::ffi::c_void, iostatusblock : *mut IO_STATUS_BLOCK, buffer : *const core::ffi::c_void, length : u32, byteoffset : *const i64, key : *const u32) -> NTSTATUS); +windows_targets::link!("ntdll.dll" "system" fn RtlNtStatusToDosError(status : NTSTATUS) -> u32); +windows_targets::link!("userenv.dll" "system" fn GetUserProfileDirectoryW(htoken : HANDLE, lpprofiledir : PWSTR, lpcchsize : *mut u32) -> BOOL); +windows_targets::link!("ws2_32.dll" "system" fn WSACleanup() -> i32); +windows_targets::link!("ws2_32.dll" "system" fn WSADuplicateSocketW(s : SOCKET, dwprocessid : u32, lpprotocolinfo : *mut WSAPROTOCOL_INFOW) -> i32); +windows_targets::link!("ws2_32.dll" "system" fn WSAGetLastError() -> WSA_ERROR); +windows_targets::link!("ws2_32.dll" "system" fn WSARecv(s : SOCKET, lpbuffers : *const WSABUF, dwbuffercount : u32, lpnumberofbytesrecvd : *mut u32, lpflags : *mut u32, lpoverlapped : *mut OVERLAPPED, lpcompletionroutine : LPWSAOVERLAPPED_COMPLETION_ROUTINE) -> i32); +windows_targets::link!("ws2_32.dll" "system" fn WSASend(s : SOCKET, lpbuffers : *const WSABUF, dwbuffercount : u32, lpnumberofbytessent : *mut u32, dwflags : u32, lpoverlapped : *mut OVERLAPPED, lpcompletionroutine : LPWSAOVERLAPPED_COMPLETION_ROUTINE) -> i32); +windows_targets::link!("ws2_32.dll" "system" fn WSASocketW(af : i32, r#type : i32, protocol : i32, lpprotocolinfo : *const WSAPROTOCOL_INFOW, g : u32, dwflags : u32) -> SOCKET); +windows_targets::link!("ws2_32.dll" "system" fn accept(s : SOCKET, addr : *mut SOCKADDR, addrlen : *mut i32) -> SOCKET); +windows_targets::link!("ws2_32.dll" "system" fn bind(s : SOCKET, name : *const SOCKADDR, namelen : i32) -> i32); +windows_targets::link!("ws2_32.dll" "system" fn closesocket(s : SOCKET) -> i32); +windows_targets::link!("ws2_32.dll" "system" fn connect(s : SOCKET, name : *const SOCKADDR, namelen : i32) -> i32); +windows_targets::link!("ws2_32.dll" "system" fn freeaddrinfo(paddrinfo : *const ADDRINFOA)); +windows_targets::link!("ws2_32.dll" "system" fn getaddrinfo(pnodename : PCSTR, pservicename : PCSTR, phints : *const ADDRINFOA, ppresult : *mut *mut ADDRINFOA) -> i32); +windows_targets::link!("ws2_32.dll" "system" fn getpeername(s : SOCKET, name : *mut SOCKADDR, namelen : *mut i32) -> i32); +windows_targets::link!("ws2_32.dll" "system" fn getsockname(s : SOCKET, name : *mut SOCKADDR, namelen : *mut i32) -> i32); +windows_targets::link!("ws2_32.dll" "system" fn getsockopt(s : SOCKET, level : i32, optname : i32, optval : PSTR, optlen : *mut i32) -> i32); +windows_targets::link!("ws2_32.dll" "system" fn ioctlsocket(s : SOCKET, cmd : i32, argp : *mut u32) -> i32); +windows_targets::link!("ws2_32.dll" "system" fn listen(s : SOCKET, backlog : i32) -> i32); +windows_targets::link!("ws2_32.dll" "system" fn recv(s : SOCKET, buf : PSTR, len : i32, flags : SEND_RECV_FLAGS) -> i32); +windows_targets::link!("ws2_32.dll" "system" fn recvfrom(s : SOCKET, buf : PSTR, len : i32, flags : i32, from : *mut SOCKADDR, fromlen : *mut i32) -> i32); +windows_targets::link!("ws2_32.dll" "system" fn select(nfds : i32, readfds : *mut FD_SET, writefds : *mut FD_SET, exceptfds : *mut FD_SET, timeout : *const TIMEVAL) -> i32); +windows_targets::link!("ws2_32.dll" "system" fn send(s : SOCKET, buf : PCSTR, len : i32, flags : SEND_RECV_FLAGS) -> i32); +windows_targets::link!("ws2_32.dll" "system" fn sendto(s : SOCKET, buf : PCSTR, len : i32, flags : i32, to : *const SOCKADDR, tolen : i32) -> i32); +windows_targets::link!("ws2_32.dll" "system" fn setsockopt(s : SOCKET, level : i32, optname : i32, optval : PCSTR, optlen : i32) -> i32); +windows_targets::link!("ws2_32.dll" "system" fn shutdown(s : SOCKET, how : WINSOCK_SHUTDOWN_HOW) -> i32); pub const ABOVE_NORMAL_PRIORITY_CLASS: PROCESS_CREATION_FLAGS = 32768u32; pub type ADDRESS_FAMILY = u16; #[repr(C)] @@ -3991,3 +3284,4 @@ pub struct XSAVE_FORMAT { pub Reserved4: [u8; 224], } // ignore-tidy-filelength +use super::windows_targets; diff --git a/library/std/src/sys/pal/windows/c/windows_targets.rs b/library/std/src/sys/pal/windows/c/windows_targets.rs new file mode 100644 index 0000000000000..cc3cc6e861194 --- /dev/null +++ b/library/std/src/sys/pal/windows/c/windows_targets.rs @@ -0,0 +1,15 @@ +pub macro link { + ($library:literal $abi:literal $($link_name:literal)? $(#[$doc:meta])? fn $($function:tt)*) => ( + #[link(name = "kernel32")] + extern $abi { + $(#[link_name=$link_name])? + pub fn $($function)*; + } + ) +} + +#[link(name = "advapi32")] +#[link(name = "ntdll")] +#[link(name = "userenv")] +#[link(name = "ws2_32")] +extern "C" {} diff --git a/library/std/src/sys/pal/windows/stdio.rs b/library/std/src/sys/pal/windows/stdio.rs index 690b60d1decca..10aeeac07ea2e 100644 --- a/library/std/src/sys/pal/windows/stdio.rs +++ b/library/std/src/sys/pal/windows/stdio.rs @@ -232,13 +232,7 @@ fn write_u16s(handle: c::HANDLE, data: &[u16]) -> io::Result { debug_assert!(data.len() < u32::MAX as usize); let mut written = 0; cvt(unsafe { - c::WriteConsoleW( - handle, - data.as_ptr() as c::LPCVOID, - data.len() as u32, - &mut written, - ptr::null_mut(), - ) + c::WriteConsoleW(handle, data.as_ptr(), data.len() as u32, &mut written, ptr::null_mut()) })?; Ok(written as usize) } diff --git a/src/tools/generate-windows-sys/Cargo.toml b/src/tools/generate-windows-sys/Cargo.toml index ebf3082fb4f24..882d3d6352526 100644 --- a/src/tools/generate-windows-sys/Cargo.toml +++ b/src/tools/generate-windows-sys/Cargo.toml @@ -4,4 +4,4 @@ version = "0.1.0" edition = "2021" [dependencies.windows-bindgen] -version = "0.57.0" +version = "0.58.0" diff --git a/src/tools/generate-windows-sys/src/main.rs b/src/tools/generate-windows-sys/src/main.rs index c8913910bd6e7..fd21e7a86b002 100644 --- a/src/tools/generate-windows-sys/src/main.rs +++ b/src/tools/generate-windows-sys/src/main.rs @@ -17,6 +17,7 @@ fn main() -> Result<(), Box> { let mut f = std::fs::File::options().append(true).open("windows_sys.rs")?; writeln!(&mut f, "// ignore-tidy-filelength")?; + writeln!(&mut f, "use super::windows_targets;")?; Ok(()) } From 0d54fe0d02f24923cc82bbdae786471bfa79d70c Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Thu, 4 Jul 2024 12:20:51 +0000 Subject: [PATCH 676/892] Remove a use of `StructuredDiag`, which is incompatible with automatic error tainting and error translations --- compiler/rustc_hir_analysis/messages.ftl | 2 - compiler/rustc_hir_analysis/src/errors.rs | 9 --- .../src/structured_errors.rs | 5 +- .../structured_errors/sized_unsized_cast.rs | 56 ------------------- compiler/rustc_hir_typeck/messages.ftl | 15 +++++ compiler/rustc_hir_typeck/src/cast.rs | 10 +--- compiler/rustc_hir_typeck/src/errors.rs | 11 ++++ ...slice_elem_ty_mismatch_in_unsizing_cast.rs | 4 ++ ...e_elem_ty_mismatch_in_unsizing_cast.stderr | 9 +++ 9 files changed, 43 insertions(+), 78 deletions(-) delete mode 100644 compiler/rustc_hir_analysis/src/structured_errors/sized_unsized_cast.rs create mode 100644 tests/ui/consts/slice_elem_ty_mismatch_in_unsizing_cast.rs create mode 100644 tests/ui/consts/slice_elem_ty_mismatch_in_unsizing_cast.stderr diff --git a/compiler/rustc_hir_analysis/messages.ftl b/compiler/rustc_hir_analysis/messages.ftl index 064d9c077b0a6..91b1506d1e4e5 100644 --- a/compiler/rustc_hir_analysis/messages.ftl +++ b/compiler/rustc_hir_analysis/messages.ftl @@ -55,8 +55,6 @@ hir_analysis_cannot_capture_late_bound_ty = cannot capture late-bound type parameter in {$what} .label = parameter defined here -hir_analysis_cast_thin_pointer_to_fat_pointer = cannot cast thin pointer `{$expr_ty}` to fat pointer `{$cast_ty}` - hir_analysis_closure_implicit_hrtb = implicit types in closure signatures are forbidden when `for<...>` is present .label = `for<...>` is here diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs index 3ffb51fa9926a..79e948ae7d9e9 100644 --- a/compiler/rustc_hir_analysis/src/errors.rs +++ b/compiler/rustc_hir_analysis/src/errors.rs @@ -707,15 +707,6 @@ pub(crate) struct PassToVariadicFunction<'tcx, 'a> { pub help: Option<()>, } -#[derive(Diagnostic)] -#[diag(hir_analysis_cast_thin_pointer_to_fat_pointer, code = E0607)] -pub(crate) struct CastThinPointerToFatPointer<'tcx> { - #[primary_span] - pub span: Span, - pub expr_ty: Ty<'tcx>, - pub cast_ty: String, -} - #[derive(Diagnostic)] #[diag(hir_analysis_invalid_union_field, code = E0740)] pub(crate) struct InvalidUnionField { diff --git a/compiler/rustc_hir_analysis/src/structured_errors.rs b/compiler/rustc_hir_analysis/src/structured_errors.rs index 5abfd25dd95df..61a2400f9e434 100644 --- a/compiler/rustc_hir_analysis/src/structured_errors.rs +++ b/compiler/rustc_hir_analysis/src/structured_errors.rs @@ -1,10 +1,7 @@ mod missing_cast_for_variadic_arg; -mod sized_unsized_cast; mod wrong_number_of_generic_args; -pub use self::{ - missing_cast_for_variadic_arg::*, sized_unsized_cast::*, wrong_number_of_generic_args::*, -}; +pub use self::{missing_cast_for_variadic_arg::*, wrong_number_of_generic_args::*}; use rustc_errors::{Diag, ErrCode}; use rustc_session::Session; diff --git a/compiler/rustc_hir_analysis/src/structured_errors/sized_unsized_cast.rs b/compiler/rustc_hir_analysis/src/structured_errors/sized_unsized_cast.rs deleted file mode 100644 index 9e871ff9af01b..0000000000000 --- a/compiler/rustc_hir_analysis/src/structured_errors/sized_unsized_cast.rs +++ /dev/null @@ -1,56 +0,0 @@ -use crate::{errors, structured_errors::StructuredDiag}; -use rustc_errors::{codes::*, Diag}; -use rustc_middle::ty::{Ty, TypeVisitableExt}; -use rustc_session::Session; -use rustc_span::Span; - -pub struct SizedUnsizedCast<'tcx> { - pub sess: &'tcx Session, - pub span: Span, - pub expr_ty: Ty<'tcx>, - pub cast_ty: String, -} - -impl<'tcx> StructuredDiag<'tcx> for SizedUnsizedCast<'tcx> { - fn session(&self) -> &Session { - self.sess - } - - fn code(&self) -> ErrCode { - E0607 - } - - fn diagnostic_common(&self) -> Diag<'tcx> { - let mut err = self.sess.dcx().create_err(errors::CastThinPointerToFatPointer { - span: self.span, - expr_ty: self.expr_ty, - cast_ty: self.cast_ty.to_owned(), - }); - - if self.expr_ty.references_error() { - err.downgrade_to_delayed_bug(); - } - - err - } - - fn diagnostic_extended(&self, mut err: Diag<'tcx>) -> Diag<'tcx> { - err.help( - "Thin pointers are \"simple\" pointers: they are purely a reference to a -memory address. - -Fat pointers are pointers referencing \"Dynamically Sized Types\" (also -called DST). DST don't have a statically known size, therefore they can -only exist behind some kind of pointers that contain additional -information. Slices and trait objects are DSTs. In the case of slices, -the additional information the fat pointer holds is their size. - -To fix this error, don't try to cast directly between thin and fat -pointers. - -For more information about casts, take a look at The Book: -https://doc.rust-lang.org/reference/expressions/operator-expr.html#type-cast-expressions", - ); - err - } -} diff --git a/compiler/rustc_hir_typeck/messages.ftl b/compiler/rustc_hir_typeck/messages.ftl index d6f3f4d640bd5..3c5070bd00628 100644 --- a/compiler/rustc_hir_typeck/messages.ftl +++ b/compiler/rustc_hir_typeck/messages.ftl @@ -23,6 +23,21 @@ hir_typeck_cannot_cast_to_bool = cannot cast `{$expr_ty}` as `bool` hir_typeck_cast_enum_drop = cannot cast enum `{$expr_ty}` into integer `{$cast_ty}` because it implements `Drop` +hir_typeck_cast_thin_pointer_to_fat_pointer = cannot cast thin pointer `{$expr_ty}` to fat pointer `{$cast_ty}` + .teach_help = Thin pointers are "simple" pointers: they are purely a reference to a + memory address. + + Fat pointers are pointers referencing "Dynamically Sized Types" (also + called DST). DST don't have a statically known size, therefore they can + only exist behind some kind of pointers that contain additional + information. Slices and trait objects are DSTs. In the case of slices, + the additional information the fat pointer holds is their size. + + To fix this error, don't try to cast directly between thin and fat + pointers. + + For more information about casts, take a look at The Book: + https://doc.rust-lang.org/reference/expressions/operator-expr.html#type-cast-expressions", hir_typeck_cast_unknown_pointer = cannot cast {$to -> [true] to *[false] from diff --git a/compiler/rustc_hir_typeck/src/cast.rs b/compiler/rustc_hir_typeck/src/cast.rs index cb1a412d17eef..53e44d6bcaee8 100644 --- a/compiler/rustc_hir_typeck/src/cast.rs +++ b/compiler/rustc_hir_typeck/src/cast.rs @@ -500,16 +500,12 @@ impl<'a, 'tcx> CastCheck<'tcx> { err.emit(); } CastError::SizedUnsizedCast => { - use rustc_hir_analysis::structured_errors::{SizedUnsizedCast, StructuredDiag}; - - SizedUnsizedCast { - sess: fcx.tcx.sess, + fcx.dcx().emit_err(errors::CastThinPointerToFatPointer { span: self.span, expr_ty: self.expr_ty, cast_ty: fcx.ty_to_string(self.cast_ty), - } - .diagnostic() - .emit(); + teach: fcx.tcx.sess.teach(E0607).then_some(()), + }); } CastError::IntToFatCast(known_metadata) => { let expr_if_nightly = fcx.tcx.sess.is_nightly_build().then_some(self.expr_span); diff --git a/compiler/rustc_hir_typeck/src/errors.rs b/compiler/rustc_hir_typeck/src/errors.rs index 98add86252c52..e49b921e63cac 100644 --- a/compiler/rustc_hir_typeck/src/errors.rs +++ b/compiler/rustc_hir_typeck/src/errors.rs @@ -689,3 +689,14 @@ pub struct ReplaceWithName { pub span: Span, pub name: String, } + +#[derive(Diagnostic)] +#[diag(hir_typeck_cast_thin_pointer_to_fat_pointer, code = E0607)] +pub(crate) struct CastThinPointerToFatPointer<'tcx> { + #[primary_span] + pub span: Span, + pub expr_ty: Ty<'tcx>, + pub cast_ty: String, + #[note(hir_typeck_teach_help)] + pub(crate) teach: Option<()>, +} diff --git a/tests/ui/consts/slice_elem_ty_mismatch_in_unsizing_cast.rs b/tests/ui/consts/slice_elem_ty_mismatch_in_unsizing_cast.rs new file mode 100644 index 0000000000000..d821b6a0117e6 --- /dev/null +++ b/tests/ui/consts/slice_elem_ty_mismatch_in_unsizing_cast.rs @@ -0,0 +1,4 @@ +const FOO: &str = unsafe { &*(1_usize as *const [i64; 0] as *const [u8] as *const str) }; +//~^ ERROR: cannot cast + +fn main() {} diff --git a/tests/ui/consts/slice_elem_ty_mismatch_in_unsizing_cast.stderr b/tests/ui/consts/slice_elem_ty_mismatch_in_unsizing_cast.stderr new file mode 100644 index 0000000000000..3b861d784d8b8 --- /dev/null +++ b/tests/ui/consts/slice_elem_ty_mismatch_in_unsizing_cast.stderr @@ -0,0 +1,9 @@ +error[E0607]: cannot cast thin pointer `*const [i64; 0]` to fat pointer `*const [u8]` + --> $DIR/slice_elem_ty_mismatch_in_unsizing_cast.rs:1:31 + | +LL | const FOO: &str = unsafe { &*(1_usize as *const [i64; 0] as *const [u8] as *const str) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0607`. From 73660649cd9663e98d07458a62d967de1ad33fd6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Sat, 29 Jun 2024 15:01:11 +0200 Subject: [PATCH 677/892] Add `run` method to `BootstrapCommand` This makes it easier to use commands in a "Fluent-API" style, and also removes the need for the `AsMut` trait hack that was used before to allow passing both `BootstrapCommand` and `&mut BootstrapCommand` to `Builder::run`. The `Builder::run` method was still kept and can be used explicitly, if needed for some reason. --- src/bootstrap/src/core/build_steps/clean.rs | 2 +- src/bootstrap/src/core/build_steps/compile.rs | 25 +- src/bootstrap/src/core/build_steps/dist.rs | 241 +++++++++--------- src/bootstrap/src/core/build_steps/doc.rs | 38 +-- src/bootstrap/src/core/build_steps/format.rs | 34 ++- src/bootstrap/src/core/build_steps/install.rs | 2 +- src/bootstrap/src/core/build_steps/llvm.rs | 17 +- src/bootstrap/src/core/build_steps/perf.rs | 2 +- src/bootstrap/src/core/build_steps/run.rs | 16 +- src/bootstrap/src/core/build_steps/suggest.rs | 12 +- .../src/core/build_steps/synthetic_targets.rs | 2 +- src/bootstrap/src/core/build_steps/test.rs | 80 +++--- src/bootstrap/src/core/build_steps/tool.rs | 8 +- src/bootstrap/src/core/build_steps/vendor.rs | 2 +- src/bootstrap/src/core/builder.rs | 6 +- src/bootstrap/src/core/metadata.rs | 2 +- src/bootstrap/src/core/sanity.rs | 2 +- src/bootstrap/src/lib.rs | 67 +++-- src/bootstrap/src/utils/cc_detect.rs | 4 +- src/bootstrap/src/utils/exec.rs | 10 +- src/bootstrap/src/utils/helpers.rs | 2 +- src/bootstrap/src/utils/tarball.rs | 2 +- 22 files changed, 288 insertions(+), 288 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/clean.rs b/src/bootstrap/src/core/build_steps/clean.rs index 479af4af66665..a4be6bc56c50d 100644 --- a/src/bootstrap/src/core/build_steps/clean.rs +++ b/src/bootstrap/src/core/build_steps/clean.rs @@ -85,7 +85,7 @@ macro_rules! clean_crate_tree { // NOTE: doesn't use `run_cargo` because we don't want to save a stamp file, // and doesn't use `stream_cargo` to avoid passing `--message-format` which `clean` doesn't accept. - builder.run(cargo); + cargo.run(builder); } } )+ } diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs index 01b25224de4cd..4cabc77f2bea4 100644 --- a/src/bootstrap/src/core/build_steps/compile.rs +++ b/src/bootstrap/src/core/build_steps/compile.rs @@ -779,14 +779,13 @@ impl Step for StartupObjects { // a local_rebuild compiler already has stage1 features cmd.arg("--cfg").arg("bootstrap"); } - builder.run( - cmd.arg("--target") - .arg(target.rustc_target_arg()) - .arg("--emit=obj") - .arg("-o") - .arg(dst_file) - .arg(src_file), - ); + cmd.arg("--target") + .arg(target.rustc_target_arg()) + .arg("--emit=obj") + .arg("-o") + .arg(dst_file) + .arg(src_file) + .run(builder); } let target = sysroot_dir.join((*file).to_string() + ".o"); @@ -1491,7 +1490,7 @@ pub fn compiler_file( let mut cmd = BootstrapCommand::new(compiler); cmd.args(builder.cflags(target, GitRepo::Rustc, c)); cmd.arg(format!("-print-file-name={file}")); - let out = builder.run(cmd.capture_stdout()).stdout(); + let out = cmd.capture_stdout().run(builder).stdout(); PathBuf::from(out.trim()) } @@ -1836,8 +1835,10 @@ impl Step for Assemble { let llvm::LlvmResult { llvm_config, .. } = builder.ensure(llvm::Llvm { target: target_compiler.host }); if !builder.config.dry_run() && builder.config.llvm_tools_enabled { - let llvm_bin_dir = builder - .run(BootstrapCommand::new(llvm_config).capture_stdout().arg("--bindir")) + let llvm_bin_dir = BootstrapCommand::new(llvm_config) + .capture_stdout() + .arg("--bindir") + .run(builder) .stdout(); let llvm_bin_dir = Path::new(llvm_bin_dir.trim()); @@ -2163,7 +2164,7 @@ pub fn strip_debug(builder: &Builder<'_>, target: TargetSelection, path: &Path) } let previous_mtime = FileTime::from_last_modification_time(&path.metadata().unwrap()); - builder.run(BootstrapCommand::new("strip").capture().arg("--strip-debug").arg(path)); + BootstrapCommand::new("strip").capture().arg("--strip-debug").arg(path).run(builder); // After running `strip`, we have to set the file modification time to what it was before, // otherwise we risk Cargo invalidating its fingerprint and rebuilding the world next time diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs index 3dc871b1ca9dd..0a7f3ec6b79f1 100644 --- a/src/bootstrap/src/core/build_steps/dist.rs +++ b/src/bootstrap/src/core/build_steps/dist.rs @@ -182,7 +182,7 @@ fn make_win_dist( //Ask gcc where it keeps its stuff let mut cmd = BootstrapCommand::new(builder.cc(target)); cmd.arg("-print-search-dirs"); - let gcc_out = builder.run(cmd.capture_stdout()).stdout(); + let gcc_out = cmd.capture_stdout().run(builder).stdout(); let mut bin_path: Vec<_> = env::split_paths(&env::var_os("PATH").unwrap_or_default()).collect(); let mut lib_path = Vec::new(); @@ -1061,7 +1061,7 @@ impl Step for PlainSourceTarball { } let config = if !builder.config.dry_run() { - builder.run(cmd.capture()).stdout() + cmd.capture().run(builder).stdout() } else { String::new() }; @@ -1606,7 +1606,7 @@ impl Step for Extended { .arg(pkg.join(component)) .arg("--nopayload") .arg(pkg.join(component).with_extension("pkg")); - builder.run(cmd); + cmd.run(builder); }; let prepare = |name: &str| { @@ -1649,7 +1649,7 @@ impl Step for Extended { .arg("--package-path") .arg(&pkg); let _time = timeit(builder); - builder.run(cmd); + cmd.run(builder); } if target.is_windows() { @@ -1703,162 +1703,153 @@ impl Step for Extended { let light = wix.join("bin/light.exe"); let heat_flags = ["-nologo", "-gg", "-sfrag", "-srd", "-sreg"]; - builder.run( + BootstrapCommand::new(&heat) + .current_dir(&exe) + .arg("dir") + .arg("rustc") + .args(heat_flags) + .arg("-cg") + .arg("RustcGroup") + .arg("-dr") + .arg("Rustc") + .arg("-var") + .arg("var.RustcDir") + .arg("-out") + .arg(exe.join("RustcGroup.wxs")) + .run(builder); + if built_tools.contains("rust-docs") { BootstrapCommand::new(&heat) .current_dir(&exe) .arg("dir") - .arg("rustc") + .arg("rust-docs") .args(heat_flags) .arg("-cg") - .arg("RustcGroup") + .arg("DocsGroup") .arg("-dr") - .arg("Rustc") + .arg("Docs") .arg("-var") - .arg("var.RustcDir") + .arg("var.DocsDir") .arg("-out") - .arg(exe.join("RustcGroup.wxs")), - ); - if built_tools.contains("rust-docs") { - builder.run( - BootstrapCommand::new(&heat) - .current_dir(&exe) - .arg("dir") - .arg("rust-docs") - .args(heat_flags) - .arg("-cg") - .arg("DocsGroup") - .arg("-dr") - .arg("Docs") - .arg("-var") - .arg("var.DocsDir") - .arg("-out") - .arg(exe.join("DocsGroup.wxs")) - .arg("-t") - .arg(etc.join("msi/squash-components.xsl")), - ); + .arg(exe.join("DocsGroup.wxs")) + .arg("-t") + .arg(etc.join("msi/squash-components.xsl")) + .run(builder); } - builder.run( + BootstrapCommand::new(&heat) + .current_dir(&exe) + .arg("dir") + .arg("cargo") + .args(heat_flags) + .arg("-cg") + .arg("CargoGroup") + .arg("-dr") + .arg("Cargo") + .arg("-var") + .arg("var.CargoDir") + .arg("-out") + .arg(exe.join("CargoGroup.wxs")) + .arg("-t") + .arg(etc.join("msi/remove-duplicates.xsl")) + .run(builder); + BootstrapCommand::new(&heat) + .current_dir(&exe) + .arg("dir") + .arg("rust-std") + .args(heat_flags) + .arg("-cg") + .arg("StdGroup") + .arg("-dr") + .arg("Std") + .arg("-var") + .arg("var.StdDir") + .arg("-out") + .arg(exe.join("StdGroup.wxs")) + .run(builder); + if built_tools.contains("rust-analyzer") { BootstrapCommand::new(&heat) .current_dir(&exe) .arg("dir") - .arg("cargo") + .arg("rust-analyzer") .args(heat_flags) .arg("-cg") - .arg("CargoGroup") + .arg("RustAnalyzerGroup") .arg("-dr") - .arg("Cargo") + .arg("RustAnalyzer") .arg("-var") - .arg("var.CargoDir") + .arg("var.RustAnalyzerDir") .arg("-out") - .arg(exe.join("CargoGroup.wxs")) + .arg(exe.join("RustAnalyzerGroup.wxs")) .arg("-t") - .arg(etc.join("msi/remove-duplicates.xsl")), - ); - builder.run( + .arg(etc.join("msi/remove-duplicates.xsl")) + .run(builder); + } + if built_tools.contains("clippy") { BootstrapCommand::new(&heat) .current_dir(&exe) .arg("dir") - .arg("rust-std") + .arg("clippy") .args(heat_flags) .arg("-cg") - .arg("StdGroup") + .arg("ClippyGroup") .arg("-dr") - .arg("Std") + .arg("Clippy") .arg("-var") - .arg("var.StdDir") + .arg("var.ClippyDir") .arg("-out") - .arg(exe.join("StdGroup.wxs")), - ); - if built_tools.contains("rust-analyzer") { - builder.run( - BootstrapCommand::new(&heat) - .current_dir(&exe) - .arg("dir") - .arg("rust-analyzer") - .args(heat_flags) - .arg("-cg") - .arg("RustAnalyzerGroup") - .arg("-dr") - .arg("RustAnalyzer") - .arg("-var") - .arg("var.RustAnalyzerDir") - .arg("-out") - .arg(exe.join("RustAnalyzerGroup.wxs")) - .arg("-t") - .arg(etc.join("msi/remove-duplicates.xsl")), - ); - } - if built_tools.contains("clippy") { - builder.run( - BootstrapCommand::new(&heat) - .current_dir(&exe) - .arg("dir") - .arg("clippy") - .args(heat_flags) - .arg("-cg") - .arg("ClippyGroup") - .arg("-dr") - .arg("Clippy") - .arg("-var") - .arg("var.ClippyDir") - .arg("-out") - .arg(exe.join("ClippyGroup.wxs")) - .arg("-t") - .arg(etc.join("msi/remove-duplicates.xsl")), - ); + .arg(exe.join("ClippyGroup.wxs")) + .arg("-t") + .arg(etc.join("msi/remove-duplicates.xsl")) + .run(builder); } if built_tools.contains("miri") { - builder.run( - BootstrapCommand::new(&heat) - .current_dir(&exe) - .arg("dir") - .arg("miri") - .args(heat_flags) - .arg("-cg") - .arg("MiriGroup") - .arg("-dr") - .arg("Miri") - .arg("-var") - .arg("var.MiriDir") - .arg("-out") - .arg(exe.join("MiriGroup.wxs")) - .arg("-t") - .arg(etc.join("msi/remove-duplicates.xsl")), - ); - } - builder.run( BootstrapCommand::new(&heat) .current_dir(&exe) .arg("dir") - .arg("rust-analysis") + .arg("miri") .args(heat_flags) .arg("-cg") - .arg("AnalysisGroup") + .arg("MiriGroup") .arg("-dr") - .arg("Analysis") + .arg("Miri") .arg("-var") - .arg("var.AnalysisDir") + .arg("var.MiriDir") .arg("-out") - .arg(exe.join("AnalysisGroup.wxs")) + .arg(exe.join("MiriGroup.wxs")) .arg("-t") - .arg(etc.join("msi/remove-duplicates.xsl")), - ); + .arg(etc.join("msi/remove-duplicates.xsl")) + .run(builder); + } + BootstrapCommand::new(&heat) + .current_dir(&exe) + .arg("dir") + .arg("rust-analysis") + .args(heat_flags) + .arg("-cg") + .arg("AnalysisGroup") + .arg("-dr") + .arg("Analysis") + .arg("-var") + .arg("var.AnalysisDir") + .arg("-out") + .arg(exe.join("AnalysisGroup.wxs")) + .arg("-t") + .arg(etc.join("msi/remove-duplicates.xsl")) + .run(builder); if target.ends_with("windows-gnu") { - builder.run( - BootstrapCommand::new(&heat) - .current_dir(&exe) - .arg("dir") - .arg("rust-mingw") - .args(heat_flags) - .arg("-cg") - .arg("GccGroup") - .arg("-dr") - .arg("Gcc") - .arg("-var") - .arg("var.GccDir") - .arg("-out") - .arg(exe.join("GccGroup.wxs")), - ); + BootstrapCommand::new(&heat) + .current_dir(&exe) + .arg("dir") + .arg("rust-mingw") + .args(heat_flags) + .arg("-cg") + .arg("GccGroup") + .arg("-dr") + .arg("Gcc") + .arg("-var") + .arg("var.GccDir") + .arg("-out") + .arg(exe.join("GccGroup.wxs")) + .run(builder); } let candle = |input: &Path| { @@ -1893,7 +1884,7 @@ impl Step for Extended { if target.ends_with("windows-gnu") { cmd.arg("-dGccDir=rust-mingw"); } - builder.run(cmd); + cmd.run(builder); }; candle(&xform(&etc.join("msi/rust.wxs"))); candle(&etc.join("msi/ui.wxs")); @@ -1962,7 +1953,7 @@ impl Step for Extended { cmd.arg("-sice:ICE57"); let _time = timeit(builder); - builder.run(cmd); + cmd.run(builder); if !builder.config.dry_run() { t!(move_file(exe.join(&filename), distdir(builder).join(&filename))); @@ -2084,7 +2075,7 @@ fn maybe_install_llvm( let files = if builder.config.dry_run() { "".into() } else { - builder.run(cmd.capture_stdout()).stdout() + cmd.capture_stdout().run(builder).stdout() }; let build_llvm_out = &builder.llvm_out(builder.config.build); let target_llvm_out = &builder.llvm_out(target); diff --git a/src/bootstrap/src/core/build_steps/doc.rs b/src/bootstrap/src/core/build_steps/doc.rs index 823e842693e96..4b35d6c5d4c95 100644 --- a/src/bootstrap/src/core/build_steps/doc.rs +++ b/src/bootstrap/src/core/build_steps/doc.rs @@ -154,7 +154,7 @@ impl Step for RustbookSrc

    { builder.info(&format!("Rustbook ({target}) - {name}")); let _ = fs::remove_dir_all(&out); - builder.run(rustbook_cmd.arg("build").arg(&src).arg("-d").arg(&out)); + rustbook_cmd.arg("build").arg(&src).arg("-d").arg(&out).run(builder); for lang in &self.languages { let out = out.join(lang); @@ -162,10 +162,15 @@ impl Step for RustbookSrc

    { builder.info(&format!("Rustbook ({target}) - {name} - {lang}")); let _ = fs::remove_dir_all(&out); - let mut rustbook_cmd = builder.tool_cmd(Tool::Rustbook); - builder.run( - rustbook_cmd.arg("build").arg(&src).arg("-d").arg(&out).arg("-l").arg(lang), - ); + builder + .tool_cmd(Tool::Rustbook) + .arg("build") + .arg(&src) + .arg("-d") + .arg(&out) + .arg("-l") + .arg(lang) + .run(builder); } } @@ -301,7 +306,7 @@ fn invoke_rustdoc( cmd.arg("-Z").arg("unstable-options").arg("--disable-minification"); } - builder.run(cmd); + cmd.run(builder); } #[derive(Debug, Clone, Hash, PartialEq, Eq)] @@ -395,7 +400,7 @@ impl Step for Standalone { } else { cmd.arg("--markdown-css").arg("rust.css"); } - builder.run(cmd); + cmd.run(builder); } // We open doc/index.html as the default if invoked as `x.py doc --open` @@ -494,7 +499,7 @@ impl Step for Releases { cmd.arg("--disable-minification"); } - builder.run(cmd); + cmd.run(builder); } // We open doc/RELEASES.html as the default if invoked as `x.py doc --open RELEASES.md` @@ -738,7 +743,7 @@ fn doc_std( format!("library{} in {} format", crate_description(requested_crates), format.as_str()); let _guard = builder.msg_doc(compiler, description, target); - builder.run(cargo.into_cmd()); + cargo.into_cmd().run(builder); builder.cp_link_r(&out_dir, out); } @@ -863,7 +868,7 @@ impl Step for Rustc { let proc_macro_out_dir = builder.stage_out(compiler, Mode::Rustc).join("doc"); symlink_dir_force(&builder.config, &out, &proc_macro_out_dir); - builder.run(cargo.into_cmd()); + cargo.into_cmd().run(builder); if !builder.config.dry_run() { // Sanity check on linked compiler crates @@ -996,7 +1001,7 @@ macro_rules! tool_doc { symlink_dir_force(&builder.config, &out, &proc_macro_out_dir); let _guard = builder.msg_doc(compiler, stringify!($tool).to_lowercase(), target); - builder.run(cargo.into_cmd()); + cargo.into_cmd().run(builder); if !builder.config.dry_run() { // Sanity check on linked doc directories @@ -1075,12 +1080,7 @@ impl Step for ErrorIndex { builder.info(&format!("Documenting error index ({})", self.target)); let out = builder.doc_out(self.target); t!(fs::create_dir_all(&out)); - let mut index = tool::ErrorIndex::command(builder); - index.arg("html"); - index.arg(out); - index.arg(&builder.version); - - builder.run(index); + tool::ErrorIndex::command(builder).arg("html").arg(out).arg(&builder.version).run(builder); } } @@ -1116,7 +1116,7 @@ impl Step for UnstableBookGen { cmd.arg(builder.src.join("src")); cmd.arg(out); - builder.run(cmd); + cmd.run(builder); } } @@ -1211,7 +1211,7 @@ impl Step for RustcBook { self.compiler.host, self.target, ); - builder.run(cmd); + cmd.run(builder); drop(doc_generator_guard); // Run rustbook/mdbook to generate the HTML pages. diff --git a/src/bootstrap/src/core/build_steps/format.rs b/src/bootstrap/src/core/build_steps/format.rs index 66286a52813f4..04b3ec770d20d 100644 --- a/src/bootstrap/src/core/build_steps/format.rs +++ b/src/bootstrap/src/core/build_steps/format.rs @@ -60,7 +60,7 @@ fn get_rustfmt_version(build: &Builder<'_>) -> Option<(String, PathBuf)> { }); cmd.arg("--version"); - let output = build.run(cmd.capture().allow_failure()); + let output = cmd.capture().allow_failure().run(build); if output.is_failure() { return None; } @@ -160,29 +160,25 @@ pub fn format(build: &Builder<'_>, check: bool, all: bool, paths: &[PathBuf]) { } } let git_available = - build.run(helpers::git(None).capture().allow_failure().arg("--version")).is_success(); + helpers::git(None).capture().allow_failure().arg("--version").run(build).is_success(); let mut adjective = None; if git_available { - let in_working_tree = build - .run( - helpers::git(Some(&build.src)) - .capture() - .allow_failure() - .arg("rev-parse") - .arg("--is-inside-work-tree"), - ) + let in_working_tree = helpers::git(Some(&build.src)) + .capture() + .allow_failure() + .arg("rev-parse") + .arg("--is-inside-work-tree") + .run(build) .is_success(); if in_working_tree { - let untracked_paths_output = build - .run( - helpers::git(Some(&build.src)) - .capture_stdout() - .arg("status") - .arg("--porcelain") - .arg("-z") - .arg("--untracked-files=normal"), - ) + let untracked_paths_output = helpers::git(Some(&build.src)) + .capture_stdout() + .arg("status") + .arg("--porcelain") + .arg("-z") + .arg("--untracked-files=normal") + .run(build) .stdout(); let untracked_paths: Vec<_> = untracked_paths_output .split_terminator('\0') diff --git a/src/bootstrap/src/core/build_steps/install.rs b/src/bootstrap/src/core/build_steps/install.rs index 7ee1aca2abcd4..2cb745deff615 100644 --- a/src/bootstrap/src/core/build_steps/install.rs +++ b/src/bootstrap/src/core/build_steps/install.rs @@ -113,7 +113,7 @@ fn install_sh( .arg(format!("--libdir={}", prepare_dir(&destdir_env, libdir))) .arg(format!("--mandir={}", prepare_dir(&destdir_env, mandir))) .arg("--disable-ldconfig"); - builder.run(cmd); + cmd.run(builder); t!(fs::remove_dir_all(&empty_dir)); } diff --git a/src/bootstrap/src/core/build_steps/llvm.rs b/src/bootstrap/src/core/build_steps/llvm.rs index 4f1c1f87d1c6c..32414e4e3971e 100644 --- a/src/bootstrap/src/core/build_steps/llvm.rs +++ b/src/bootstrap/src/core/build_steps/llvm.rs @@ -478,8 +478,10 @@ impl Step for Llvm { let LlvmResult { llvm_config, .. } = builder.ensure(Llvm { target: builder.config.build }); if !builder.config.dry_run() { - let llvm_bindir = builder - .run(BootstrapCommand::new(&llvm_config).capture_stdout().arg("--bindir")) + let llvm_bindir = BootstrapCommand::new(&llvm_config) + .capture_stdout() + .arg("--bindir") + .run(builder) .stdout(); let host_bin = Path::new(llvm_bindir.trim()); cfg.define( @@ -530,8 +532,11 @@ impl Step for Llvm { // Helper to find the name of LLVM's shared library on darwin and linux. let find_llvm_lib_name = |extension| { - let cmd = BootstrapCommand::new(&res.llvm_config); - let version = builder.run(cmd.capture_stdout().arg("--version")).stdout(); + let version = BootstrapCommand::new(&res.llvm_config) + .capture_stdout() + .arg("--version") + .run(builder) + .stdout(); let major = version.split('.').next().unwrap(); match &llvm_version_suffix { @@ -587,8 +592,8 @@ fn check_llvm_version(builder: &Builder<'_>, llvm_config: &Path) { return; } - let cmd = BootstrapCommand::new(llvm_config); - let version = builder.run(cmd.capture_stdout().arg("--version")).stdout(); + let version = + BootstrapCommand::new(llvm_config).capture_stdout().arg("--version").run(builder).stdout(); let mut parts = version.split('.').take(2).filter_map(|s| s.parse::().ok()); if let (Some(major), Some(_minor)) = (parts.next(), parts.next()) { if major >= 17 { diff --git a/src/bootstrap/src/core/build_steps/perf.rs b/src/bootstrap/src/core/build_steps/perf.rs index f41b5fe10f1d9..5b83080a3260f 100644 --- a/src/bootstrap/src/core/build_steps/perf.rs +++ b/src/bootstrap/src/core/build_steps/perf.rs @@ -31,5 +31,5 @@ Consider setting `rust.debuginfo-level = 1` in `config.toml`."#); .env("PERF_COLLECTOR", collector) .env("PERF_RESULT_DIR", profile_results_dir) .args(args); - builder.run(&mut cmd); + cmd.run(builder); } diff --git a/src/bootstrap/src/core/build_steps/run.rs b/src/bootstrap/src/core/build_steps/run.rs index 316a03a2171b5..7088cd0d4c21d 100644 --- a/src/bootstrap/src/core/build_steps/run.rs +++ b/src/bootstrap/src/core/build_steps/run.rs @@ -41,7 +41,7 @@ impl Step for BuildManifest { }); let today = - builder.run(BootstrapCommand::new("date").capture_stdout().arg("+%Y-%m-%d")).stdout(); + BootstrapCommand::new("date").capture_stdout().arg("+%Y-%m-%d").run(builder).stdout(); cmd.arg(sign); cmd.arg(distdir(builder)); @@ -50,7 +50,7 @@ impl Step for BuildManifest { cmd.arg(&builder.config.channel); builder.create_dir(&distdir(builder)); - builder.run(cmd); + cmd.run(builder); } } @@ -72,7 +72,7 @@ impl Step for BumpStage0 { fn run(self, builder: &Builder<'_>) -> Self::Output { let mut cmd = builder.tool_cmd(Tool::BumpStage0); cmd.args(builder.config.args()); - builder.run(cmd); + cmd.run(builder); } } @@ -94,7 +94,7 @@ impl Step for ReplaceVersionPlaceholder { fn run(self, builder: &Builder<'_>) -> Self::Output { let mut cmd = builder.tool_cmd(Tool::ReplaceVersionPlaceholder); cmd.arg(&builder.src); - builder.run(cmd); + cmd.run(builder); } } @@ -158,7 +158,7 @@ impl Step for Miri { // after another --, so this must be at the end. miri.args(builder.config.args()); - builder.run(miri.into_cmd()); + miri.into_cmd().run(builder); } } @@ -188,7 +188,7 @@ impl Step for CollectLicenseMetadata { let mut cmd = builder.tool_cmd(Tool::CollectLicenseMetadata); cmd.env("REUSE_EXE", reuse); cmd.env("DEST", &dest); - builder.run(cmd); + cmd.run(builder); dest } @@ -218,7 +218,7 @@ impl Step for GenerateCopyright { let mut cmd = builder.tool_cmd(Tool::GenerateCopyright); cmd.env("LICENSE_METADATA", &license_metadata); cmd.env("DEST", &dest); - builder.run(cmd); + cmd.run(builder); dest } @@ -242,7 +242,7 @@ impl Step for GenerateWindowsSys { fn run(self, builder: &Builder<'_>) { let mut cmd = builder.tool_cmd(Tool::GenerateWindowsSys); cmd.arg(&builder.src); - builder.run(cmd); + cmd.run(builder); } } diff --git a/src/bootstrap/src/core/build_steps/suggest.rs b/src/bootstrap/src/core/build_steps/suggest.rs index 5412b3c807b62..2d4409d27c65f 100644 --- a/src/bootstrap/src/core/build_steps/suggest.rs +++ b/src/bootstrap/src/core/build_steps/suggest.rs @@ -13,13 +13,11 @@ use crate::core::builder::Builder; pub fn suggest(builder: &Builder<'_>, run: bool) { let git_config = builder.config.git_config(); let suggestions = builder - .run( - builder - .tool_cmd(Tool::SuggestTests) - .capture_stdout() - .env("SUGGEST_TESTS_GIT_REPOSITORY", git_config.git_repository) - .env("SUGGEST_TESTS_NIGHTLY_BRANCH", git_config.nightly_branch), - ) + .tool_cmd(Tool::SuggestTests) + .capture_stdout() + .env("SUGGEST_TESTS_GIT_REPOSITORY", git_config.git_repository) + .env("SUGGEST_TESTS_NIGHTLY_BRANCH", git_config.nightly_branch) + .run(builder) .stdout(); let suggestions = suggestions diff --git a/src/bootstrap/src/core/build_steps/synthetic_targets.rs b/src/bootstrap/src/core/build_steps/synthetic_targets.rs index a115ba2d8b27a..0f3963ac6639d 100644 --- a/src/bootstrap/src/core/build_steps/synthetic_targets.rs +++ b/src/bootstrap/src/core/build_steps/synthetic_targets.rs @@ -64,7 +64,7 @@ fn create_synthetic_target( // we cannot use nightly features. So `RUSTC_BOOTSTRAP` is needed here. cmd.env("RUSTC_BOOTSTRAP", "1"); - let output = builder.run(cmd.capture()).stdout(); + let output = cmd.capture().run(builder).stdout(); let mut spec: serde_json::Value = serde_json::from_slice(output.as_bytes()).unwrap(); let spec_map = spec.as_object_mut().unwrap(); diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index dc53bd3cfa785..e48ef58eb0c34 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -155,7 +155,7 @@ You can skip linkcheck with --skip src/tools/linkchecker" let _guard = builder.msg(Kind::Test, compiler.stage, "Linkcheck", bootstrap_host, bootstrap_host); let _time = helpers::timeit(builder); - builder.run(linkchecker.delay_failure().arg(builder.out.join(host.triple).join("doc"))); + linkchecker.delay_failure().arg(builder.out.join(host.triple).join("doc")).run(builder); } fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { @@ -212,9 +212,11 @@ impl Step for HtmlCheck { builder, )); - builder.run( - builder.tool_cmd(Tool::HtmlChecker).delay_failure().arg(builder.doc_out(self.target)), - ); + builder + .tool_cmd(Tool::HtmlChecker) + .delay_failure() + .arg(builder.doc_out(self.target)) + .run(builder); } } @@ -259,7 +261,7 @@ impl Step for Cargotest { .env("RUSTC", builder.rustc(compiler)) .env("RUSTDOC", builder.rustdoc(compiler)); add_rustdoc_cargo_linker_args(&mut cmd, builder, compiler.host, LldThreads::No); - builder.run(cmd.delay_failure()); + cmd.delay_failure().run(builder); } } @@ -460,7 +462,7 @@ impl Miri { let mut cargo = BootstrapCommand::from(cargo); let _guard = builder.msg(Kind::Build, compiler.stage, "miri sysroot", compiler.host, target); - builder.run(&mut cargo); + cargo.run(builder); // # Determine where Miri put its sysroot. // To this end, we run `cargo miri setup --print-sysroot` and capture the output. @@ -473,7 +475,7 @@ impl Miri { String::new() } else { builder.verbose(|| println!("running: {cargo:?}")); - let stdout = builder.run(cargo.capture_stdout()).stdout(); + let stdout = cargo.capture_stdout().run(builder).stdout(); // Output is "\n". let sysroot = stdout.trim_end(); builder.verbose(|| println!("`cargo miri setup --print-sysroot` said: {sysroot:?}")); @@ -561,7 +563,7 @@ impl Step for Miri { { let _guard = builder.msg_sysroot_tool(Kind::Test, stage, "miri", host, target); let _time = helpers::timeit(builder); - builder.run(&mut cargo); + cargo.run(builder); } // Run it again for mir-opt-level 4 to catch some miscompilations. @@ -583,7 +585,7 @@ impl Step for Miri { target, ); let _time = helpers::timeit(builder); - builder.run(cargo); + cargo.run(builder); } } } @@ -648,11 +650,11 @@ impl Step for CargoMiri { // Finally, pass test-args and run everything. cargo.arg("--").args(builder.config.test_args()); - let cargo = BootstrapCommand::from(cargo); + let mut cargo = BootstrapCommand::from(cargo); { let _guard = builder.msg_sysroot_tool(Kind::Test, stage, "cargo-miri", host, target); let _time = helpers::timeit(builder); - builder.run(cargo); + cargo.run(builder); } } } @@ -753,7 +755,7 @@ impl Step for Clippy { let _guard = builder.msg_sysroot_tool(Kind::Test, compiler.stage, "clippy", host, host); // Clippy reports errors if it blessed the outputs - if builder.run(cargo.allow_failure()).is_success() { + if cargo.allow_failure().run(builder).is_success() { // The tests succeeded; nothing to do. return; } @@ -806,7 +808,7 @@ impl Step for RustdocTheme { .env("RUSTC_BOOTSTRAP", "1"); cmd.args(linker_args(builder, self.compiler.host, LldThreads::No)); - builder.run(cmd.delay_failure()); + cmd.delay_failure().run(builder); } } @@ -866,7 +868,7 @@ impl Step for RustdocJSStd { builder.config.build, self.target, ); - builder.run(command); + command.run(builder); } } @@ -913,7 +915,7 @@ fn get_browser_ui_test_version_inner( if global { command.arg("--global"); } - let lines = builder.run(command.allow_failure()).stdout(); + let lines = command.allow_failure().run(builder).stdout(); lines .lines() .find_map(|l| l.split(':').nth(1)?.strip_prefix("browser-ui-test@")) @@ -1085,7 +1087,7 @@ HELP: to skip test's attempt to check tidiness, pass `--skip src/tools/tidy` to } builder.info("tidy check"); - builder.run(cmd.delay_failure()); + cmd.delay_failure().run(builder); builder.info("x.py completions check"); let [bash, zsh, fish, powershell] = ["x.py.sh", "x.py.zsh", "x.py.fish", "x.py.ps1"] @@ -1292,7 +1294,7 @@ impl Step for RunMakeSupport { &[], ); - builder.run(cargo.into_cmd()); + cargo.into_cmd().run(builder); let lib_name = "librun_make_support.rlib"; let lib = builder.tools_dir(self.compiler).join(lib_name); @@ -1804,14 +1806,20 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the } let lldb_exe = builder.config.lldb.clone().unwrap_or_else(|| PathBuf::from("lldb")); - let lldb_version = builder - .run(BootstrapCommand::new(&lldb_exe).capture().allow_failure().arg("--version")) + let lldb_version = BootstrapCommand::new(&lldb_exe) + .capture() + .allow_failure() + .arg("--version") + .run(builder) .stdout_if_ok() .and_then(|v| if v.trim().is_empty() { None } else { Some(v) }); if let Some(ref vers) = lldb_version { cmd.arg("--lldb-version").arg(vers); - let lldb_python_dir = builder - .run(BootstrapCommand::new(&lldb_exe).allow_failure().capture_stdout().arg("-P")) + let lldb_python_dir = BootstrapCommand::new(&lldb_exe) + .allow_failure() + .capture_stdout() + .arg("-P") + .run(builder) .stdout_if_ok() .map(|p| p.lines().next().expect("lldb Python dir not found").to_string()); if let Some(ref dir) = lldb_python_dir { @@ -2169,9 +2177,11 @@ impl BookTest { compiler.host, ); let _time = helpers::timeit(builder); - let cmd = rustbook_cmd.delay_failure(); - let toolstate = - if builder.run(cmd).is_success() { ToolState::TestPass } else { ToolState::TestFail }; + let toolstate = if rustbook_cmd.delay_failure().run(builder).is_success() { + ToolState::TestPass + } else { + ToolState::TestFail + }; builder.save_toolstate(self.name, toolstate); } @@ -2300,7 +2310,7 @@ impl Step for ErrorIndex { let guard = builder.msg(Kind::Test, compiler.stage, "error-index", compiler.host, compiler.host); let _time = helpers::timeit(builder); - builder.run(tool.capture()); + tool.capture().run(builder); drop(guard); // The tests themselves need to link to std, so make sure it is // available. @@ -2333,7 +2343,7 @@ fn markdown_test(builder: &Builder<'_>, compiler: Compiler, markdown: &Path) -> if !builder.config.verbose_tests { cmd = cmd.capture(); } - builder.run(cmd).is_success() + cmd.run(builder).is_success() } #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -2359,7 +2369,7 @@ impl Step for RustcGuide { let src = builder.src.join(relative_path); let mut rustbook_cmd = builder.tool_cmd(Tool::Rustbook).delay_failure(); rustbook_cmd.arg("linkcheck").arg(&src); - let toolstate = if builder.run(rustbook_cmd).is_success() { + let toolstate = if rustbook_cmd.run(builder).is_success() { ToolState::TestPass } else { ToolState::TestFail @@ -2868,7 +2878,7 @@ impl Step for RemoteCopyLibs { if let Some(rootfs) = builder.qemu_rootfs(target) { cmd.arg(rootfs); } - builder.run(cmd); + cmd.run(builder); // Push all our dylibs to the emulator for f in t!(builder.sysroot_libdir(compiler, target).read_dir()) { @@ -2911,7 +2921,7 @@ impl Step for Distcheck { .arg(builder.ensure(dist::PlainSourceTarball).tarball()) .arg("--strip-components=1") .current_dir(&dir); - builder.run(cmd); + cmd.run(builder); builder.run( BootstrapCommand::new("./configure") .args(&builder.config.configure_args) @@ -2935,7 +2945,7 @@ impl Step for Distcheck { .arg(builder.ensure(dist::Src).tarball()) .arg("--strip-components=1") .current_dir(&dir); - builder.run(cmd); + cmd.run(builder); let toml = dir.join("rust-src/lib/rustlib/src/rust/library/std/Cargo.toml"); builder.run( @@ -2976,7 +2986,7 @@ impl Step for Bootstrap { .current_dir(builder.src.join("src/bootstrap/")); // NOTE: we intentionally don't pass test_args here because the args for unittest and cargo test are mutually incompatible. // Use `python -m unittest` manually if you want to pass arguments. - builder.run(check_bootstrap.delay_failure()); + check_bootstrap.delay_failure().run(builder); let mut cmd = BootstrapCommand::new(&builder.initial_cargo); cmd.arg("test") @@ -3053,7 +3063,7 @@ impl Step for TierCheck { self.compiler.host, self.compiler.host, ); - builder.run(BootstrapCommand::from(cargo).delay_failure()); + BootstrapCommand::from(cargo).delay_failure().run(builder); } } @@ -3138,7 +3148,7 @@ impl Step for RustInstaller { cmd.env("CARGO", &builder.initial_cargo); cmd.env("RUSTC", &builder.initial_rustc); cmd.env("TMP_DIR", &tmpdir); - builder.run(cmd.delay_failure()); + cmd.delay_failure().run(builder); } fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { @@ -3332,7 +3342,7 @@ impl Step for CodegenCranelift { .arg("testsuite.extended_sysroot"); cargo.args(builder.config.test_args()); - builder.run(cargo.into_cmd()); + cargo.into_cmd().run(builder); } } @@ -3457,6 +3467,6 @@ impl Step for CodegenGCC { .arg("--std-tests"); cargo.args(builder.config.test_args()); - builder.run(cargo.into_cmd()); + cargo.into_cmd().run(builder); } } diff --git a/src/bootstrap/src/core/build_steps/tool.rs b/src/bootstrap/src/core/build_steps/tool.rs index 5fb282db90a7c..7b4b5ff5a8cc3 100644 --- a/src/bootstrap/src/core/build_steps/tool.rs +++ b/src/bootstrap/src/core/build_steps/tool.rs @@ -602,7 +602,7 @@ impl Step for Rustdoc { &self.compiler.host, &target, ); - builder.run(cargo.into_cmd()); + cargo.into_cmd().run(builder); // Cargo adds a number of paths to the dylib search path on windows, which results in // the wrong rustdoc being executed. To avoid the conflicting rustdocs, we name the "tool" @@ -857,7 +857,7 @@ impl Step for LlvmBitcodeLinker { &self.extra_features, ); - builder.run(cargo.into_cmd()); + cargo.into_cmd().run(builder); let tool_out = builder .cargo_out(self.compiler, Mode::ToolRustc, self.target) @@ -918,7 +918,7 @@ impl Step for LibcxxVersionTool { .arg(&executable) .arg(builder.src.join("src/tools/libcxx-version/main.cpp")); - builder.run(cmd); + cmd.run(builder); if !executable.exists() { panic!("Something went wrong. {} is not present", executable.display()); @@ -926,7 +926,7 @@ impl Step for LibcxxVersionTool { } let version_output = - builder.run(BootstrapCommand::new(executable).capture_stdout()).stdout(); + BootstrapCommand::new(executable).capture_stdout().run(builder).stdout(); let version_str = version_output.split_once("version:").unwrap().1; let version = version_str.trim().parse::().unwrap(); diff --git a/src/bootstrap/src/core/build_steps/vendor.rs b/src/bootstrap/src/core/build_steps/vendor.rs index 0b999a24a1fb9..82cd95489d022 100644 --- a/src/bootstrap/src/core/build_steps/vendor.rs +++ b/src/bootstrap/src/core/build_steps/vendor.rs @@ -59,6 +59,6 @@ impl Step for Vendor { cmd.current_dir(self.root_dir); - builder.run(cmd); + cmd.run(builder); } } diff --git a/src/bootstrap/src/core/builder.rs b/src/bootstrap/src/core/builder.rs index 4da912994c3ee..91dfffdaf7e47 100644 --- a/src/bootstrap/src/core/builder.rs +++ b/src/bootstrap/src/core/builder.rs @@ -1918,8 +1918,10 @@ impl<'a> Builder<'a> { // platform-specific environment variable as a workaround. if mode == Mode::ToolRustc || mode == Mode::Codegen { if let Some(llvm_config) = self.llvm_config(target) { - let llvm_libdir = self - .run(BootstrapCommand::new(llvm_config).capture_stdout().arg("--libdir")) + let llvm_libdir = BootstrapCommand::new(llvm_config) + .capture_stdout() + .arg("--libdir") + .run(self) .stdout(); add_link_lib_path(vec![llvm_libdir.trim().into()], &mut cargo); } diff --git a/src/bootstrap/src/core/metadata.rs b/src/bootstrap/src/core/metadata.rs index 49d17107125aa..83c22b0609994 100644 --- a/src/bootstrap/src/core/metadata.rs +++ b/src/bootstrap/src/core/metadata.rs @@ -81,7 +81,7 @@ fn workspace_members(build: &Build) -> Vec { .arg("--no-deps") .arg("--manifest-path") .arg(build.src.join(manifest_path)); - let metadata_output = build.run(cargo.capture_stdout().run_always()).stdout(); + let metadata_output = cargo.capture_stdout().run_always().run(build).stdout(); let Output { packages, .. } = t!(serde_json::from_str(&metadata_output)); packages }; diff --git a/src/bootstrap/src/core/sanity.rs b/src/bootstrap/src/core/sanity.rs index 78862ccb8cd68..e393d3df01f31 100644 --- a/src/bootstrap/src/core/sanity.rs +++ b/src/bootstrap/src/core/sanity.rs @@ -355,7 +355,7 @@ than building it. // Cygwin. The Cygwin build does not have generators for Visual // Studio, so detect that here and error. let out = - build.run(BootstrapCommand::new("cmake").capture_stdout().arg("--help")).stdout(); + BootstrapCommand::new("cmake").capture_stdout().arg("--help").run(build).stdout(); if !out.contains("Visual Studio") { panic!( " diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs index ffdd9bc885a62..6604b8efa1dee 100644 --- a/src/bootstrap/src/lib.rs +++ b/src/bootstrap/src/lib.rs @@ -510,9 +510,10 @@ impl Build { } println!("Updating submodule {}", relative_path.display()); - self.run( - helpers::git(Some(&self.src)).args(["submodule", "-q", "sync"]).arg(relative_path), - ); + helpers::git(Some(&self.src)) + .args(["submodule", "-q", "sync"]) + .arg(relative_path) + .run(self); // Try passing `--progress` to start, then run git again without if that fails. let update = |progress: bool| { @@ -548,23 +549,25 @@ impl Build { }; // NOTE: doesn't use `try_run` because this shouldn't print an error if it fails. if !update(true).command.status().map_or(false, |status| status.success()) { - self.run(update(false)); + update(false).run(self); } // Save any local changes, but avoid running `git stash pop` if there are none (since it will exit with an error). // diff-index reports the modifications through the exit status - let has_local_modifications = self - .run(submodule_git().allow_failure().args(["diff-index", "--quiet", "HEAD"])) + let has_local_modifications = submodule_git() + .allow_failure() + .args(["diff-index", "--quiet", "HEAD"]) + .run(self) .is_failure(); if has_local_modifications { - self.run(submodule_git().args(["stash", "push"])); + submodule_git().args(["stash", "push"]).run(self); } - self.run(submodule_git().args(["reset", "-q", "--hard"])); - self.run(submodule_git().args(["clean", "-qdfx"])); + submodule_git().args(["reset", "-q", "--hard"]).run(self); + submodule_git().args(["clean", "-qdfx"]).run(self); if has_local_modifications { - self.run(submodule_git().args(["stash", "pop"])); + submodule_git().args(["stash", "pop"]).run(self); } } @@ -575,14 +578,12 @@ impl Build { if !self.config.submodules(self.rust_info()) { return; } - let output = self - .run( - helpers::git(Some(&self.src)) - .capture() - .args(["config", "--file"]) - .arg(self.config.src.join(".gitmodules")) - .args(["--get-regexp", "path"]), - ) + let output = helpers::git(Some(&self.src)) + .capture() + .args(["config", "--file"]) + .arg(self.config.src.join(".gitmodules")) + .args(["--get-regexp", "path"]) + .run(self) .stdout(); for line in output.lines() { // Look for `submodule.$name.path = $path` @@ -861,7 +862,7 @@ impl Build { s.to_path_buf() } else if let Some(s) = target_config.and_then(|c| c.llvm_config.as_ref()) { let llvm_bindir = - self.run(BootstrapCommand::new(s).capture_stdout().arg("--bindir")).stdout(); + BootstrapCommand::new(s).capture_stdout().arg("--bindir").run(self).stdout(); let filecheck = Path::new(llvm_bindir.trim()).join(exe("FileCheck", target)); if filecheck.exists() { filecheck @@ -869,7 +870,7 @@ impl Build { // On Fedora the system LLVM installs FileCheck in the // llvm subdirectory of the libdir. let llvm_libdir = - self.run(BootstrapCommand::new(s).capture_stdout().arg("--libdir")).stdout(); + BootstrapCommand::new(s).capture_stdout().arg("--libdir").run(self).stdout(); let lib_filecheck = Path::new(llvm_libdir.trim()).join("llvm").join(exe("FileCheck", target)); if lib_filecheck.exists() { @@ -935,8 +936,7 @@ impl Build { /// Execute a command and return its output. /// This method should be used for all command executions in bootstrap. - fn run>(&self, mut command: C) -> CommandOutput { - let command = command.as_mut(); + fn run(&self, command: &mut BootstrapCommand) -> CommandOutput { if self.config.dry_run() && !command.run_always { return CommandOutput::default(); } @@ -1496,18 +1496,17 @@ impl Build { // Figure out how many merge commits happened since we branched off master. // That's our beta number! // (Note that we use a `..` range, not the `...` symmetric difference.) - self.run( - helpers::git(Some(&self.src)) - .capture() - .arg("rev-list") - .arg("--count") - .arg("--merges") - .arg(format!( - "refs/remotes/origin/{}..HEAD", - self.config.stage0_metadata.config.nightly_branch - )), - ) - .stdout() + helpers::git(Some(&self.src)) + .capture() + .arg("rev-list") + .arg("--count") + .arg("--merges") + .arg(format!( + "refs/remotes/origin/{}..HEAD", + self.config.stage0_metadata.config.nightly_branch + )) + .run(self) + .stdout() }); let n = count.trim().parse().unwrap(); self.prerelease_version.set(Some(n)); diff --git a/src/bootstrap/src/utils/cc_detect.rs b/src/bootstrap/src/utils/cc_detect.rs index b80df54520264..5d8a5223a2df2 100644 --- a/src/bootstrap/src/utils/cc_detect.rs +++ b/src/bootstrap/src/utils/cc_detect.rs @@ -183,14 +183,14 @@ fn default_compiler( } let cmd = BootstrapCommand::from(c.to_command()); - let output = build.run(cmd.capture_stdout().arg("--version")).stdout(); + let output = cmd.capture_stdout().arg("--version").run(build).stdout(); let i = output.find(" 4.")?; match output[i + 3..].chars().next().unwrap() { '0'..='6' => {} _ => return None, } let alternative = format!("e{gnu_compiler}"); - if build.run(BootstrapCommand::new(&alternative).capture()).is_success() { + if BootstrapCommand::new(&alternative).capture().run(build).is_success() { Some(PathBuf::from(alternative)) } else { None diff --git a/src/bootstrap/src/utils/exec.rs b/src/bootstrap/src/utils/exec.rs index 086d10c63511a..8940ea24385a3 100644 --- a/src/bootstrap/src/utils/exec.rs +++ b/src/bootstrap/src/utils/exec.rs @@ -1,3 +1,4 @@ +use crate::Build; use std::ffi::OsStr; use std::path::Path; use std::process::{Command, CommandArgs, CommandEnvs, ExitStatus, Output, Stdio}; @@ -134,13 +135,10 @@ impl BootstrapCommand { pub fn capture_stdout(self) -> Self { Self { stdout: OutputMode::Capture, ..self } } -} -/// This implementation exists to make it possible to pass both [BootstrapCommand] and -/// `&mut BootstrapCommand` to `Build.run()`. -impl AsMut for BootstrapCommand { - fn as_mut(&mut self) -> &mut BootstrapCommand { - self + /// Run the command, returning its output. + pub fn run(&mut self, builder: &Build) -> CommandOutput { + builder.run(self) } } diff --git a/src/bootstrap/src/utils/helpers.rs b/src/bootstrap/src/utils/helpers.rs index 2575b7939b44c..0a81db3cd8e22 100644 --- a/src/bootstrap/src/utils/helpers.rs +++ b/src/bootstrap/src/utils/helpers.rs @@ -371,7 +371,7 @@ fn lld_flag_no_threads(builder: &Builder<'_>, lld_mode: LldMode, is_windows: boo LldMode::External => { let mut cmd = BootstrapCommand::new("lld").capture_stdout(); cmd.arg("-flavor").arg("ld").arg("--version"); - let out = builder.run(cmd).stdout(); + let out = cmd.run(builder).stdout(); match (out.find(char::is_numeric), out.find('.')) { (Some(b), Some(e)) => out.as_str()[b..e].parse::().ok().unwrap_or(14) > 10, _ => true, diff --git a/src/bootstrap/src/utils/tarball.rs b/src/bootstrap/src/utils/tarball.rs index 1a35dc1fd3896..4f0104e4bbab6 100644 --- a/src/bootstrap/src/utils/tarball.rs +++ b/src/bootstrap/src/utils/tarball.rs @@ -379,7 +379,7 @@ impl<'a> Tarball<'a> { cmd.args(["--override-file-mtime", timestamp.trim()]); } - self.builder.run(cmd); + cmd.run(self.builder); // Ensure there are no symbolic links in the tarball. In particular, // rustup-toolchain-install-master and most versions of Windows can't handle symbolic links. From f933d789b7399f505525362b0527960966b62cdc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Sat, 29 Jun 2024 15:05:27 +0200 Subject: [PATCH 678/892] Add a shortcut helper function `command` for creating commands This is simply a quality-of-life improvement to make command creation in bootstrap a bit shorter and more discoverable. --- src/bootstrap/src/core/build_steps/compile.rs | 15 +++---- src/bootstrap/src/core/build_steps/dist.rs | 34 +++++++------- src/bootstrap/src/core/build_steps/format.rs | 4 +- src/bootstrap/src/core/build_steps/install.rs | 4 +- src/bootstrap/src/core/build_steps/llvm.rs | 19 +++----- src/bootstrap/src/core/build_steps/run.rs | 5 +-- .../src/core/build_steps/synthetic_targets.rs | 4 +- src/bootstrap/src/core/build_steps/test.rs | 44 +++++++++---------- src/bootstrap/src/core/build_steps/tool.rs | 11 +++-- src/bootstrap/src/core/build_steps/vendor.rs | 4 +- src/bootstrap/src/core/builder.rs | 19 ++++---- src/bootstrap/src/core/download.rs | 4 +- src/bootstrap/src/core/metadata.rs | 4 +- src/bootstrap/src/core/sanity.rs | 9 ++-- src/bootstrap/src/lib.rs | 8 ++-- src/bootstrap/src/utils/cc_detect.rs | 4 +- src/bootstrap/src/utils/exec.rs | 7 +++ src/bootstrap/src/utils/helpers.rs | 6 +-- 18 files changed, 94 insertions(+), 111 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs index 4cabc77f2bea4..11a7a40453516 100644 --- a/src/bootstrap/src/core/build_steps/compile.rs +++ b/src/bootstrap/src/core/build_steps/compile.rs @@ -27,7 +27,7 @@ use crate::core::builder::crate_description; use crate::core::builder::Cargo; use crate::core::builder::{Builder, Kind, PathSet, RunConfig, ShouldRun, Step, TaskPath}; use crate::core::config::{DebuginfoLevel, LlvmLibunwind, RustcLto, TargetSelection}; -use crate::utils::exec::BootstrapCommand; +use crate::utils::exec::command; use crate::utils::helpers::{ exe, get_clang_cl_resource_dir, is_debug_info, is_dylib, symlink_dir, t, up_to_date, }; @@ -773,7 +773,7 @@ impl Step for StartupObjects { let src_file = &src_dir.join(file.to_string() + ".rs"); let dst_file = &dst_dir.join(file.to_string() + ".o"); if !up_to_date(src_file, dst_file) { - let mut cmd = BootstrapCommand::new(&builder.initial_rustc); + let mut cmd = command(&builder.initial_rustc); cmd.env("RUSTC_BOOTSTRAP", "1"); if !builder.local_rebuild { // a local_rebuild compiler already has stage1 features @@ -1487,7 +1487,7 @@ pub fn compiler_file( if builder.config.dry_run() { return PathBuf::new(); } - let mut cmd = BootstrapCommand::new(compiler); + let mut cmd = command(compiler); cmd.args(builder.cflags(target, GitRepo::Rustc, c)); cmd.arg(format!("-print-file-name={file}")); let out = cmd.capture_stdout().run(builder).stdout(); @@ -1835,11 +1835,8 @@ impl Step for Assemble { let llvm::LlvmResult { llvm_config, .. } = builder.ensure(llvm::Llvm { target: target_compiler.host }); if !builder.config.dry_run() && builder.config.llvm_tools_enabled { - let llvm_bin_dir = BootstrapCommand::new(llvm_config) - .capture_stdout() - .arg("--bindir") - .run(builder) - .stdout(); + let llvm_bin_dir = + command(llvm_config).capture_stdout().arg("--bindir").run(builder).stdout(); let llvm_bin_dir = Path::new(llvm_bin_dir.trim()); // Since we've already built the LLVM tools, install them to the sysroot. @@ -2164,7 +2161,7 @@ pub fn strip_debug(builder: &Builder<'_>, target: TargetSelection, path: &Path) } let previous_mtime = FileTime::from_last_modification_time(&path.metadata().unwrap()); - BootstrapCommand::new("strip").capture().arg("--strip-debug").arg(path).run(builder); + command("strip").capture().arg("--strip-debug").arg(path).run(builder); // After running `strip`, we have to set the file modification time to what it was before, // otherwise we risk Cargo invalidating its fingerprint and rebuilding the world next time diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs index 0a7f3ec6b79f1..7bc5405e92f93 100644 --- a/src/bootstrap/src/core/build_steps/dist.rs +++ b/src/bootstrap/src/core/build_steps/dist.rs @@ -25,7 +25,7 @@ use crate::core::build_steps::tool::{self, Tool}; use crate::core::builder::{Builder, Kind, RunConfig, ShouldRun, Step}; use crate::core::config::TargetSelection; use crate::utils::channel::{self, Info}; -use crate::utils::exec::BootstrapCommand; +use crate::utils::exec::{command, BootstrapCommand}; use crate::utils::helpers::{ exe, is_dylib, move_file, t, target_supports_cranelift_backend, timeit, }; @@ -180,7 +180,7 @@ fn make_win_dist( } //Ask gcc where it keeps its stuff - let mut cmd = BootstrapCommand::new(builder.cc(target)); + let mut cmd = command(builder.cc(target)); cmd.arg("-print-search-dirs"); let gcc_out = cmd.capture_stdout().run(builder).stdout(); @@ -1023,7 +1023,7 @@ impl Step for PlainSourceTarball { } // Vendor all Cargo dependencies - let mut cmd = BootstrapCommand::new(&builder.initial_cargo); + let mut cmd = command(&builder.initial_cargo); cmd.arg("vendor") .arg("--versioned-dirs") .arg("--sync") @@ -1599,7 +1599,7 @@ impl Step for Extended { let _ = fs::remove_dir_all(&pkg); let pkgbuild = |component: &str| { - let mut cmd = BootstrapCommand::new("pkgbuild"); + let mut cmd = command("pkgbuild"); cmd.arg("--identifier") .arg(format!("org.rust-lang.{}", component)) .arg("--scripts") @@ -1636,7 +1636,7 @@ impl Step for Extended { builder.create_dir(&pkg.join("res")); builder.create(&pkg.join("res/LICENSE.txt"), &license); builder.install(&etc.join("gfx/rust-logo.png"), &pkg.join("res"), 0o644); - let mut cmd = BootstrapCommand::new("productbuild"); + let mut cmd = command("productbuild"); cmd.arg("--distribution") .arg(xform(&etc.join("pkg/Distribution.xml"))) .arg("--resources") @@ -1703,7 +1703,7 @@ impl Step for Extended { let light = wix.join("bin/light.exe"); let heat_flags = ["-nologo", "-gg", "-sfrag", "-srd", "-sreg"]; - BootstrapCommand::new(&heat) + command(&heat) .current_dir(&exe) .arg("dir") .arg("rustc") @@ -1718,7 +1718,7 @@ impl Step for Extended { .arg(exe.join("RustcGroup.wxs")) .run(builder); if built_tools.contains("rust-docs") { - BootstrapCommand::new(&heat) + command(&heat) .current_dir(&exe) .arg("dir") .arg("rust-docs") @@ -1735,7 +1735,7 @@ impl Step for Extended { .arg(etc.join("msi/squash-components.xsl")) .run(builder); } - BootstrapCommand::new(&heat) + command(&heat) .current_dir(&exe) .arg("dir") .arg("cargo") @@ -1751,7 +1751,7 @@ impl Step for Extended { .arg("-t") .arg(etc.join("msi/remove-duplicates.xsl")) .run(builder); - BootstrapCommand::new(&heat) + command(&heat) .current_dir(&exe) .arg("dir") .arg("rust-std") @@ -1766,7 +1766,7 @@ impl Step for Extended { .arg(exe.join("StdGroup.wxs")) .run(builder); if built_tools.contains("rust-analyzer") { - BootstrapCommand::new(&heat) + command(&heat) .current_dir(&exe) .arg("dir") .arg("rust-analyzer") @@ -1784,7 +1784,7 @@ impl Step for Extended { .run(builder); } if built_tools.contains("clippy") { - BootstrapCommand::new(&heat) + command(&heat) .current_dir(&exe) .arg("dir") .arg("clippy") @@ -1802,7 +1802,7 @@ impl Step for Extended { .run(builder); } if built_tools.contains("miri") { - BootstrapCommand::new(&heat) + command(&heat) .current_dir(&exe) .arg("dir") .arg("miri") @@ -1819,7 +1819,7 @@ impl Step for Extended { .arg(etc.join("msi/remove-duplicates.xsl")) .run(builder); } - BootstrapCommand::new(&heat) + command(&heat) .current_dir(&exe) .arg("dir") .arg("rust-analysis") @@ -1836,7 +1836,7 @@ impl Step for Extended { .arg(etc.join("msi/remove-duplicates.xsl")) .run(builder); if target.ends_with("windows-gnu") { - BootstrapCommand::new(&heat) + command(&heat) .current_dir(&exe) .arg("dir") .arg("rust-mingw") @@ -1855,7 +1855,7 @@ impl Step for Extended { let candle = |input: &Path| { let output = exe.join(input.file_stem().unwrap()).with_extension("wixobj"); let arch = if target.contains("x86_64") { "x64" } else { "x86" }; - let mut cmd = BootstrapCommand::new(&candle); + let mut cmd = command(&candle); cmd.current_dir(&exe) .arg("-nologo") .arg("-dRustcDir=rustc") @@ -1916,7 +1916,7 @@ impl Step for Extended { builder.info(&format!("building `msi` installer with {light:?}")); let filename = format!("{}-{}.msi", pkgname(builder, "rust"), target.triple); - let mut cmd = BootstrapCommand::new(&light); + let mut cmd = command(&light); cmd.arg("-nologo") .arg("-ext") .arg("WixUIExtension") @@ -2069,7 +2069,7 @@ fn maybe_install_llvm( } else if let llvm::LlvmBuildStatus::AlreadyBuilt(llvm::LlvmResult { llvm_config, .. }) = llvm::prebuilt_llvm_config(builder, target) { - let mut cmd = BootstrapCommand::new(llvm_config); + let mut cmd = command(llvm_config); cmd.arg("--libfiles"); builder.verbose(|| println!("running {cmd:?}")); let files = if builder.config.dry_run() { diff --git a/src/bootstrap/src/core/build_steps/format.rs b/src/bootstrap/src/core/build_steps/format.rs index 04b3ec770d20d..d3ac2bae1e875 100644 --- a/src/bootstrap/src/core/build_steps/format.rs +++ b/src/bootstrap/src/core/build_steps/format.rs @@ -1,7 +1,7 @@ //! Runs rustfmt on the repository. use crate::core::builder::Builder; -use crate::utils::exec::BootstrapCommand; +use crate::utils::exec::command; use crate::utils::helpers::{self, program_out_of_date, t}; use build_helper::ci::CiEnv; use build_helper::git::get_git_modified_files; @@ -54,7 +54,7 @@ fn rustfmt(src: &Path, rustfmt: &Path, paths: &[PathBuf], check: bool) -> impl F fn get_rustfmt_version(build: &Builder<'_>) -> Option<(String, PathBuf)> { let stamp_file = build.out.join("rustfmt.stamp"); - let mut cmd = BootstrapCommand::new(match build.initial_rustfmt() { + let mut cmd = command(match build.initial_rustfmt() { Some(p) => p, None => return None, }); diff --git a/src/bootstrap/src/core/build_steps/install.rs b/src/bootstrap/src/core/build_steps/install.rs index 2cb745deff615..d3e9d6d787564 100644 --- a/src/bootstrap/src/core/build_steps/install.rs +++ b/src/bootstrap/src/core/build_steps/install.rs @@ -10,7 +10,7 @@ use std::path::{Component, Path, PathBuf}; use crate::core::build_steps::dist; use crate::core::builder::{Builder, RunConfig, ShouldRun, Step}; use crate::core::config::{Config, TargetSelection}; -use crate::utils::exec::BootstrapCommand; +use crate::utils::exec::command; use crate::utils::helpers::t; use crate::utils::tarball::GeneratedTarball; use crate::{Compiler, Kind}; @@ -102,7 +102,7 @@ fn install_sh( let empty_dir = builder.out.join("tmp/empty_dir"); t!(fs::create_dir_all(&empty_dir)); - let mut cmd = BootstrapCommand::new(SHELL); + let mut cmd = command(SHELL); cmd.current_dir(&empty_dir) .arg(sanitize_sh(&tarball.decompressed_output().join("install.sh"))) .arg(format!("--prefix={}", prepare_dir(&destdir_env, prefix))) diff --git a/src/bootstrap/src/core/build_steps/llvm.rs b/src/bootstrap/src/core/build_steps/llvm.rs index 32414e4e3971e..bff731e13b0a9 100644 --- a/src/bootstrap/src/core/build_steps/llvm.rs +++ b/src/bootstrap/src/core/build_steps/llvm.rs @@ -24,7 +24,7 @@ use crate::utils::helpers::{ }; use crate::{generate_smart_stamp_hash, CLang, GitRepo, Kind}; -use crate::utils::exec::BootstrapCommand; +use crate::utils::exec::command; use build_helper::ci::CiEnv; use build_helper::git::get_git_merge_base; @@ -478,11 +478,8 @@ impl Step for Llvm { let LlvmResult { llvm_config, .. } = builder.ensure(Llvm { target: builder.config.build }); if !builder.config.dry_run() { - let llvm_bindir = BootstrapCommand::new(&llvm_config) - .capture_stdout() - .arg("--bindir") - .run(builder) - .stdout(); + let llvm_bindir = + command(&llvm_config).capture_stdout().arg("--bindir").run(builder).stdout(); let host_bin = Path::new(llvm_bindir.trim()); cfg.define( "LLVM_TABLEGEN", @@ -532,11 +529,8 @@ impl Step for Llvm { // Helper to find the name of LLVM's shared library on darwin and linux. let find_llvm_lib_name = |extension| { - let version = BootstrapCommand::new(&res.llvm_config) - .capture_stdout() - .arg("--version") - .run(builder) - .stdout(); + let version = + command(&res.llvm_config).capture_stdout().arg("--version").run(builder).stdout(); let major = version.split('.').next().unwrap(); match &llvm_version_suffix { @@ -592,8 +586,7 @@ fn check_llvm_version(builder: &Builder<'_>, llvm_config: &Path) { return; } - let version = - BootstrapCommand::new(llvm_config).capture_stdout().arg("--version").run(builder).stdout(); + let version = command(llvm_config).capture_stdout().arg("--version").run(builder).stdout(); let mut parts = version.split('.').take(2).filter_map(|s| s.parse::().ok()); if let (Some(major), Some(_minor)) = (parts.next(), parts.next()) { if major >= 17 { diff --git a/src/bootstrap/src/core/build_steps/run.rs b/src/bootstrap/src/core/build_steps/run.rs index 7088cd0d4c21d..3a2d3f675228d 100644 --- a/src/bootstrap/src/core/build_steps/run.rs +++ b/src/bootstrap/src/core/build_steps/run.rs @@ -11,7 +11,7 @@ use crate::core::build_steps::tool::{self, SourceType, Tool}; use crate::core::builder::{Builder, RunConfig, ShouldRun, Step}; use crate::core::config::flags::get_completion; use crate::core::config::TargetSelection; -use crate::utils::exec::BootstrapCommand; +use crate::utils::exec::command; use crate::Mode; #[derive(Debug, PartialOrd, Ord, Clone, Hash, PartialEq, Eq)] @@ -40,8 +40,7 @@ impl Step for BuildManifest { panic!("\n\nfailed to specify `dist.upload-addr` in `config.toml`\n\n") }); - let today = - BootstrapCommand::new("date").capture_stdout().arg("+%Y-%m-%d").run(builder).stdout(); + let today = command("date").capture_stdout().arg("+%Y-%m-%d").run(builder).stdout(); cmd.arg(sign); cmd.arg(distdir(builder)); diff --git a/src/bootstrap/src/core/build_steps/synthetic_targets.rs b/src/bootstrap/src/core/build_steps/synthetic_targets.rs index 0f3963ac6639d..021680302cde6 100644 --- a/src/bootstrap/src/core/build_steps/synthetic_targets.rs +++ b/src/bootstrap/src/core/build_steps/synthetic_targets.rs @@ -9,7 +9,7 @@ use crate::core::builder::{Builder, ShouldRun, Step}; use crate::core::config::TargetSelection; -use crate::utils::exec::BootstrapCommand; +use crate::utils::exec::command; use crate::Compiler; #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -56,7 +56,7 @@ fn create_synthetic_target( return TargetSelection::create_synthetic(&name, path.to_str().unwrap()); } - let mut cmd = BootstrapCommand::new(builder.rustc(compiler)); + let mut cmd = command(builder.rustc(compiler)); cmd.arg("--target").arg(base.rustc_target_arg()); cmd.args(["-Zunstable-options", "--print", "target-spec-json"]); diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index e48ef58eb0c34..7f4c4bd53dffa 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -26,7 +26,7 @@ use crate::core::builder::{Builder, Compiler, Kind, RunConfig, ShouldRun, Step}; use crate::core::config::flags::get_completion; use crate::core::config::flags::Subcommand; use crate::core::config::TargetSelection; -use crate::utils::exec::BootstrapCommand; +use crate::utils::exec::{command, BootstrapCommand}; use crate::utils::helpers::{ self, add_link_lib_path, add_rustdoc_cargo_linker_args, dylib_path, dylib_path_var, linker_args, linker_flags, t, target_supports_cranelift_backend, up_to_date, LldThreads, @@ -834,7 +834,7 @@ impl Step for RustdocJSStd { fn run(self, builder: &Builder<'_>) { let nodejs = builder.config.nodejs.as_ref().expect("need nodejs to run rustdoc-js-std tests"); - let mut command = BootstrapCommand::new(nodejs); + let mut command = command(nodejs); command .arg(builder.src.join("src/tools/rustdoc-js/tester.js")) .arg("--crate-name") @@ -910,7 +910,7 @@ fn get_browser_ui_test_version_inner( npm: &Path, global: bool, ) -> Option { - let mut command = BootstrapCommand::new(npm).capture(); + let mut command = command(npm).capture(); command.arg("list").arg("--parseable").arg("--long").arg("--depth=0"); if global { command.arg("--global"); @@ -1806,7 +1806,7 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the } let lldb_exe = builder.config.lldb.clone().unwrap_or_else(|| PathBuf::from("lldb")); - let lldb_version = BootstrapCommand::new(&lldb_exe) + let lldb_version = command(&lldb_exe) .capture() .allow_failure() .arg("--version") @@ -1815,7 +1815,7 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the .and_then(|v| if v.trim().is_empty() { None } else { Some(v) }); if let Some(ref vers) = lldb_version { cmd.arg("--lldb-version").arg(vers); - let lldb_python_dir = BootstrapCommand::new(&lldb_exe) + let lldb_python_dir = command(&lldb_exe) .allow_failure() .capture_stdout() .arg("-P") @@ -1877,11 +1877,10 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the let llvm::LlvmResult { llvm_config, .. } = builder.ensure(llvm::Llvm { target: builder.config.build }); if !builder.config.dry_run() { - let llvm_version = builder - .run(BootstrapCommand::new(&llvm_config).capture_stdout().arg("--version")) - .stdout(); + let llvm_version = + builder.run(command(&llvm_config).capture_stdout().arg("--version")).stdout(); let llvm_components = builder - .run(BootstrapCommand::new(&llvm_config).capture_stdout().arg("--components")) + .run(command(&llvm_config).capture_stdout().arg("--components")) .stdout(); // Remove trailing newline from llvm-config output. cmd.arg("--llvm-version") @@ -1901,9 +1900,8 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the // separate compilations. We can add LLVM's library path to the // platform-specific environment variable as a workaround. if !builder.config.dry_run() && suite.ends_with("fulldeps") { - let llvm_libdir = builder - .run(BootstrapCommand::new(&llvm_config).capture_stdout().arg("--libdir")) - .stdout(); + let llvm_libdir = + builder.run(command(&llvm_config).capture_stdout().arg("--libdir")).stdout(); add_link_lib_path(vec![llvm_libdir.trim().into()], &mut cmd); } @@ -2873,7 +2871,7 @@ impl Step for RemoteCopyLibs { // Spawn the emulator and wait for it to come online let tool = builder.tool_exe(Tool::RemoteTestClient); - let mut cmd = BootstrapCommand::new(&tool); + let mut cmd = command(&tool); cmd.arg("spawn-emulator").arg(target.triple).arg(&server).arg(builder.tempdir()); if let Some(rootfs) = builder.qemu_rootfs(target) { cmd.arg(rootfs); @@ -2885,7 +2883,7 @@ impl Step for RemoteCopyLibs { let f = t!(f); let name = f.file_name().into_string().unwrap(); if helpers::is_dylib(&name) { - builder.run(BootstrapCommand::new(&tool).arg("push").arg(f.path())); + builder.run(command(&tool).arg("push").arg(f.path())); } } } @@ -2916,22 +2914,20 @@ impl Step for Distcheck { builder.ensure(dist::PlainSourceTarball); builder.ensure(dist::Src); - let mut cmd = BootstrapCommand::new("tar"); + let mut cmd = command("tar"); cmd.arg("-xf") .arg(builder.ensure(dist::PlainSourceTarball).tarball()) .arg("--strip-components=1") .current_dir(&dir); cmd.run(builder); builder.run( - BootstrapCommand::new("./configure") + command("./configure") .args(&builder.config.configure_args) .arg("--enable-vendor") .current_dir(&dir), ); builder.run( - BootstrapCommand::new(helpers::make(&builder.config.build.triple)) - .arg("check") - .current_dir(&dir), + command(helpers::make(&builder.config.build.triple)).arg("check").current_dir(&dir), ); // Now make sure that rust-src has all of libstd's dependencies @@ -2940,7 +2936,7 @@ impl Step for Distcheck { let _ = fs::remove_dir_all(&dir); t!(fs::create_dir_all(&dir)); - let mut cmd = BootstrapCommand::new("tar"); + let mut cmd = command("tar"); cmd.arg("-xf") .arg(builder.ensure(dist::Src).tarball()) .arg("--strip-components=1") @@ -2949,7 +2945,7 @@ impl Step for Distcheck { let toml = dir.join("rust-src/lib/rustlib/src/rust/library/std/Cargo.toml"); builder.run( - BootstrapCommand::new(&builder.initial_cargo) + command(&builder.initial_cargo) // Will read the libstd Cargo.toml // which uses the unstable `public-dependency` feature. .env("RUSTC_BOOTSTRAP", "1") @@ -2978,7 +2974,7 @@ impl Step for Bootstrap { // Some tests require cargo submodule to be present. builder.build.update_submodule(Path::new("src/tools/cargo")); - let mut check_bootstrap = BootstrapCommand::new(builder.python()); + let mut check_bootstrap = command(builder.python()); check_bootstrap .args(["-m", "unittest", "bootstrap_test.py"]) .env("BUILD_DIR", &builder.out) @@ -2988,7 +2984,7 @@ impl Step for Bootstrap { // Use `python -m unittest` manually if you want to pass arguments. check_bootstrap.delay_failure().run(builder); - let mut cmd = BootstrapCommand::new(&builder.initial_cargo); + let mut cmd = command(&builder.initial_cargo); cmd.arg("test") .args(["--features", "bootstrap-self-test"]) .current_dir(builder.src.join("src/bootstrap")) @@ -3139,7 +3135,7 @@ impl Step for RustInstaller { return; } - let mut cmd = BootstrapCommand::new(builder.src.join("src/tools/rust-installer/test.sh")); + let mut cmd = command(builder.src.join("src/tools/rust-installer/test.sh")); let tmpdir = testdir(builder, compiler.host).join("rust-installer"); let _ = std::fs::remove_dir_all(&tmpdir); let _ = std::fs::create_dir_all(&tmpdir); diff --git a/src/bootstrap/src/core/build_steps/tool.rs b/src/bootstrap/src/core/build_steps/tool.rs index 7b4b5ff5a8cc3..ad92a01bce7f3 100644 --- a/src/bootstrap/src/core/build_steps/tool.rs +++ b/src/bootstrap/src/core/build_steps/tool.rs @@ -8,7 +8,7 @@ use crate::core::builder; use crate::core::builder::{Builder, Cargo as CargoCommand, RunConfig, ShouldRun, Step}; use crate::core::config::TargetSelection; use crate::utils::channel::GitInfo; -use crate::utils::exec::BootstrapCommand; +use crate::utils::exec::{command, BootstrapCommand}; use crate::utils::helpers::{add_dylib_path, exe, t}; use crate::Compiler; use crate::Mode; @@ -438,7 +438,7 @@ impl ErrorIndex { // for rustc_private and libLLVM.so, and `sysroot_lib` for libstd, etc. let host = builder.config.build; let compiler = builder.compiler_for(builder.top_stage, host, host); - let mut cmd = BootstrapCommand::new(builder.ensure(ErrorIndex { compiler })); + let mut cmd = command(builder.ensure(ErrorIndex { compiler })); let mut dylib_paths = builder.rustc_lib_paths(compiler); dylib_paths.push(PathBuf::from(&builder.sysroot_libdir(compiler, compiler.host))); add_dylib_path(dylib_paths, &mut cmd); @@ -912,7 +912,7 @@ impl Step for LibcxxVersionTool { } let compiler = builder.cxx(self.target).unwrap(); - let mut cmd = BootstrapCommand::new(compiler); + let mut cmd = command(compiler); cmd.arg("-o") .arg(&executable) @@ -925,8 +925,7 @@ impl Step for LibcxxVersionTool { } } - let version_output = - BootstrapCommand::new(executable).capture_stdout().run(builder).stdout(); + let version_output = command(executable).capture_stdout().run(builder).stdout(); let version_str = version_output.split_once("version:").unwrap().1; let version = version_str.trim().parse::().unwrap(); @@ -1050,7 +1049,7 @@ impl<'a> Builder<'a> { /// Gets a `BootstrapCommand` which is ready to run `tool` in `stage` built for /// `host`. pub fn tool_cmd(&self, tool: Tool) -> BootstrapCommand { - let mut cmd = BootstrapCommand::new(self.tool_exe(tool)); + let mut cmd = command(self.tool_exe(tool)); let compiler = self.compiler(0, self.config.build); let host = &compiler.host; // Prepares the `cmd` provided to be able to run the `compiler` provided. diff --git a/src/bootstrap/src/core/build_steps/vendor.rs b/src/bootstrap/src/core/build_steps/vendor.rs index 82cd95489d022..62342ee47928b 100644 --- a/src/bootstrap/src/core/build_steps/vendor.rs +++ b/src/bootstrap/src/core/build_steps/vendor.rs @@ -1,5 +1,5 @@ use crate::core::builder::{Builder, RunConfig, ShouldRun, Step}; -use crate::utils::exec::BootstrapCommand; +use crate::utils::exec::command; use std::path::{Path, PathBuf}; #[derive(Debug, Clone, Hash, PartialEq, Eq)] @@ -27,7 +27,7 @@ impl Step for Vendor { } fn run(self, builder: &Builder<'_>) -> Self::Output { - let mut cmd = BootstrapCommand::new(&builder.initial_cargo); + let mut cmd = command(&builder.initial_cargo); cmd.arg("vendor"); if self.versioned_dirs { diff --git a/src/bootstrap/src/core/builder.rs b/src/bootstrap/src/core/builder.rs index 91dfffdaf7e47..24bb96c6b88f2 100644 --- a/src/bootstrap/src/core/builder.rs +++ b/src/bootstrap/src/core/builder.rs @@ -23,7 +23,7 @@ use crate::utils::helpers::{check_cfg_arg, libdir, linker_flags, t, LldThreads}; use crate::EXTRA_CHECK_CFGS; use crate::{Build, CLang, Crate, DocTests, GitRepo, Mode}; -use crate::utils::exec::BootstrapCommand; +use crate::utils::exec::{command, BootstrapCommand}; pub use crate::Compiler; use clap::ValueEnum; @@ -1254,7 +1254,7 @@ impl<'a> Builder<'a> { if run_compiler.stage == 0 { // `ensure(Clippy { stage: 0 })` *builds* clippy with stage0, it doesn't use the beta clippy. let cargo_clippy = self.build.config.download_clippy(); - let mut cmd = BootstrapCommand::new(cargo_clippy); + let mut cmd = command(cargo_clippy); cmd.env("CARGO", &self.initial_cargo); return cmd; } @@ -1273,7 +1273,7 @@ impl<'a> Builder<'a> { let mut dylib_path = helpers::dylib_path(); dylib_path.insert(0, self.sysroot(run_compiler).join("lib")); - let mut cmd = BootstrapCommand::new(cargo_clippy); + let mut cmd = command(cargo_clippy); cmd.env(helpers::dylib_path_var(), env::join_paths(&dylib_path).unwrap()); cmd.env("CARGO", &self.initial_cargo); cmd @@ -1295,7 +1295,7 @@ impl<'a> Builder<'a> { extra_features: Vec::new(), }); // Invoke cargo-miri, make sure it can find miri and cargo. - let mut cmd = BootstrapCommand::new(cargo_miri); + let mut cmd = command(cargo_miri); cmd.env("MIRI", &miri); cmd.env("CARGO", &self.initial_cargo); // Need to add the `run_compiler` libs. Those are the libs produces *by* `build_compiler`, @@ -1311,7 +1311,7 @@ impl<'a> Builder<'a> { } pub fn rustdoc_cmd(&self, compiler: Compiler) -> BootstrapCommand { - let mut cmd = BootstrapCommand::new(self.bootstrap_out.join("rustdoc")); + let mut cmd = command(self.bootstrap_out.join("rustdoc")); cmd.env("RUSTC_STAGE", compiler.stage.to_string()) .env("RUSTC_SYSROOT", self.sysroot(compiler)) // Note that this is *not* the sysroot_libdir because rustdoc must be linked @@ -1365,7 +1365,7 @@ impl<'a> Builder<'a> { cargo = self.cargo_miri_cmd(compiler); cargo.arg("miri").arg(subcmd); } else { - cargo = BootstrapCommand::new(&self.initial_cargo); + cargo = command(&self.initial_cargo); cargo.arg(cmd); } @@ -1918,11 +1918,8 @@ impl<'a> Builder<'a> { // platform-specific environment variable as a workaround. if mode == Mode::ToolRustc || mode == Mode::Codegen { if let Some(llvm_config) = self.llvm_config(target) { - let llvm_libdir = BootstrapCommand::new(llvm_config) - .capture_stdout() - .arg("--libdir") - .run(self) - .stdout(); + let llvm_libdir = + command(llvm_config).capture_stdout().arg("--libdir").run(self).stdout(); add_link_lib_path(vec![llvm_libdir.trim().into()], &mut cargo); } } diff --git a/src/bootstrap/src/core/download.rs b/src/bootstrap/src/core/download.rs index c35398e2eb764..a7f4bb0cf146c 100644 --- a/src/bootstrap/src/core/download.rs +++ b/src/bootstrap/src/core/download.rs @@ -11,7 +11,7 @@ use std::{ use build_helper::ci::CiEnv; use xz2::bufread::XzDecoder; -use crate::utils::exec::BootstrapCommand; +use crate::utils::exec::{command, BootstrapCommand}; use crate::utils::helpers::hex_encode; use crate::utils::helpers::{check_run, exe, move_file, program_out_of_date}; use crate::{t, Config}; @@ -212,7 +212,7 @@ impl Config { fn download_http_with_retries(&self, tempfile: &Path, url: &str, help_on_error: &str) { println!("downloading {url}"); // Try curl. If that fails and we are on windows, fallback to PowerShell. - let mut curl = BootstrapCommand::new("curl"); + let mut curl = command("curl"); curl.args([ "-y", "30", diff --git a/src/bootstrap/src/core/metadata.rs b/src/bootstrap/src/core/metadata.rs index 83c22b0609994..b18da844014be 100644 --- a/src/bootstrap/src/core/metadata.rs +++ b/src/bootstrap/src/core/metadata.rs @@ -2,7 +2,7 @@ use std::path::PathBuf; use serde_derive::Deserialize; -use crate::utils::exec::BootstrapCommand; +use crate::utils::exec::command; use crate::{t, Build, Crate}; /// For more information, see the output of @@ -70,7 +70,7 @@ pub fn build(build: &mut Build) { /// particular crate (e.g., `x build sysroot` to build library/sysroot). fn workspace_members(build: &Build) -> Vec { let collect_metadata = |manifest_path| { - let mut cargo = BootstrapCommand::new(&build.initial_cargo); + let mut cargo = command(&build.initial_cargo); cargo // Will read the libstd Cargo.toml // which uses the unstable `public-dependency` feature. diff --git a/src/bootstrap/src/core/sanity.rs b/src/bootstrap/src/core/sanity.rs index e393d3df01f31..9995da3a1e5b8 100644 --- a/src/bootstrap/src/core/sanity.rs +++ b/src/bootstrap/src/core/sanity.rs @@ -23,7 +23,7 @@ use std::collections::HashSet; use crate::builder::Kind; use crate::core::config::Target; -use crate::utils::exec::BootstrapCommand; +use crate::utils::exec::command; use crate::Build; pub struct Finder { @@ -209,9 +209,7 @@ than building it. #[cfg(not(feature = "bootstrap-self-test"))] let stage0_supported_target_list: HashSet = crate::utils::helpers::output( - &mut BootstrapCommand::new(&build.config.initial_rustc) - .args(["--print", "target-list"]) - .command, + &mut command(&build.config.initial_rustc).args(["--print", "target-list"]).command, ) .lines() .map(|s| s.to_string()) @@ -354,8 +352,7 @@ than building it. // There are three builds of cmake on windows: MSVC, MinGW, and // Cygwin. The Cygwin build does not have generators for Visual // Studio, so detect that here and error. - let out = - BootstrapCommand::new("cmake").capture_stdout().arg("--help").run(build).stdout(); + let out = command("cmake").capture_stdout().arg("--help").run(build).stdout(); if !out.contains("Visual Studio") { panic!( " diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs index 6604b8efa1dee..f16afb2979651 100644 --- a/src/bootstrap/src/lib.rs +++ b/src/bootstrap/src/lib.rs @@ -41,7 +41,7 @@ use crate::core::builder::Kind; use crate::core::config::{flags, LldMode}; use crate::core::config::{DryRun, Target}; use crate::core::config::{LlvmLibunwind, TargetSelection}; -use crate::utils::exec::{BehaviorOnFailure, BootstrapCommand, CommandOutput}; +use crate::utils::exec::{command, BehaviorOnFailure, BootstrapCommand, CommandOutput}; use crate::utils::helpers::{self, dir_is_empty, exe, libdir, mtime, output, symlink_dir}; mod core; @@ -861,16 +861,14 @@ impl Build { if let Some(s) = target_config.and_then(|c| c.llvm_filecheck.as_ref()) { s.to_path_buf() } else if let Some(s) = target_config.and_then(|c| c.llvm_config.as_ref()) { - let llvm_bindir = - BootstrapCommand::new(s).capture_stdout().arg("--bindir").run(self).stdout(); + let llvm_bindir = command(s).capture_stdout().arg("--bindir").run(self).stdout(); let filecheck = Path::new(llvm_bindir.trim()).join(exe("FileCheck", target)); if filecheck.exists() { filecheck } else { // On Fedora the system LLVM installs FileCheck in the // llvm subdirectory of the libdir. - let llvm_libdir = - BootstrapCommand::new(s).capture_stdout().arg("--libdir").run(self).stdout(); + let llvm_libdir = command(s).capture_stdout().arg("--libdir").run(self).stdout(); let lib_filecheck = Path::new(llvm_libdir.trim()).join("llvm").join(exe("FileCheck", target)); if lib_filecheck.exists() { diff --git a/src/bootstrap/src/utils/cc_detect.rs b/src/bootstrap/src/utils/cc_detect.rs index 5d8a5223a2df2..d6fa7fc0bbebd 100644 --- a/src/bootstrap/src/utils/cc_detect.rs +++ b/src/bootstrap/src/utils/cc_detect.rs @@ -26,7 +26,7 @@ use std::path::{Path, PathBuf}; use std::{env, iter}; use crate::core::config::TargetSelection; -use crate::utils::exec::BootstrapCommand; +use crate::utils::exec::{command, BootstrapCommand}; use crate::{Build, CLang, GitRepo}; // The `cc` crate doesn't provide a way to obtain a path to the detected archiver, @@ -190,7 +190,7 @@ fn default_compiler( _ => return None, } let alternative = format!("e{gnu_compiler}"); - if BootstrapCommand::new(&alternative).capture().run(build).is_success() { + if command(&alternative).capture().run(build).is_success() { Some(PathBuf::from(alternative)) } else { None diff --git a/src/bootstrap/src/utils/exec.rs b/src/bootstrap/src/utils/exec.rs index 8940ea24385a3..b6872d1c99f41 100644 --- a/src/bootstrap/src/utils/exec.rs +++ b/src/bootstrap/src/utils/exec.rs @@ -162,6 +162,13 @@ enum CommandStatus { DidNotStart, } +/// Create a new BootstrapCommand. This is a helper function to make command creation +/// shorter than `BootstrapCommand::new`. +#[must_use] +pub fn command>(program: S) -> BootstrapCommand { + BootstrapCommand::new(program) +} + /// Represents the output of an executed process. #[allow(unused)] pub struct CommandOutput { diff --git a/src/bootstrap/src/utils/helpers.rs b/src/bootstrap/src/utils/helpers.rs index 0a81db3cd8e22..8ce0f59399f62 100644 --- a/src/bootstrap/src/utils/helpers.rs +++ b/src/bootstrap/src/utils/helpers.rs @@ -47,7 +47,7 @@ macro_rules! t { } }; } -use crate::utils::exec::BootstrapCommand; +use crate::utils::exec::{command, BootstrapCommand}; pub use t; pub fn exe(name: &str, target: TargetSelection) -> String { @@ -369,7 +369,7 @@ fn lld_flag_no_threads(builder: &Builder<'_>, lld_mode: LldMode, is_windows: boo let (windows_flag, other_flag) = LLD_NO_THREADS.get_or_init(|| { let newer_version = match lld_mode { LldMode::External => { - let mut cmd = BootstrapCommand::new("lld").capture_stdout(); + let mut cmd = command("lld").capture_stdout(); cmd.arg("-flavor").arg("ld").arg("--version"); let out = cmd.run(builder).stdout(); match (out.find(char::is_numeric), out.find('.')) { @@ -502,7 +502,7 @@ pub fn check_cfg_arg(name: &str, values: Option<&[&str]>) -> String { /// `BootstrapCommand::new("git")`, which is painful to ensure that the required change is applied /// on each one of them correctly. pub fn git(source_dir: Option<&Path>) -> BootstrapCommand { - let mut git = BootstrapCommand::new("git"); + let mut git = command("git"); if let Some(source_dir) = source_dir { git.current_dir(source_dir); From 14f4ed2ba3a86bbb2bca77690d036316c3d21fc8 Mon Sep 17 00:00:00 2001 From: Chris Denton Date: Thu, 4 Jul 2024 13:27:24 +0000 Subject: [PATCH 679/892] Add comments to windows_targets.rs --- library/std/src/sys/pal/windows/c/windows_targets.rs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/library/std/src/sys/pal/windows/c/windows_targets.rs b/library/std/src/sys/pal/windows/c/windows_targets.rs index cc3cc6e861194..56c563462d366 100644 --- a/library/std/src/sys/pal/windows/c/windows_targets.rs +++ b/library/std/src/sys/pal/windows/c/windows_targets.rs @@ -1,5 +1,14 @@ +//! Provides the `link!` macro used by the generated windows bindings. +//! +//! This is a simple wrapper around an `extern` block with a `#[link]` attribute. +//! It's very roughly equivalent to the windows-targets crate. + pub macro link { ($library:literal $abi:literal $($link_name:literal)? $(#[$doc:meta])? fn $($function:tt)*) => ( + // Note: the windows-targets crate uses a pre-built Windows.lib import library which we don't + // have in this repo. So instead we always link kernel32.lib and add the rest of the import + // libraries below by using an empty extern block. This works because extern blocks are not + // connected to the library given in the #[link] attribute. #[link(name = "kernel32")] extern $abi { $(#[link_name=$link_name])? From 0adb82528fa00467a3f14a282f4581bb30f91aba Mon Sep 17 00:00:00 2001 From: mu001999 Date: Thu, 4 Jul 2024 22:05:00 +0800 Subject: [PATCH 680/892] Improve dead code analysis --- compiler/rustc_passes/src/dead.rs | 40 ++++++------------- library/core/src/default.rs | 1 - .../salsa-macros/src/database_storage.rs | 8 ---- tests/ui-fulldeps/deriving-global.rs | 3 ++ tests/ui-fulldeps/deriving-hygiene.rs | 1 + .../ui/const-generics/issues/issue-86535-2.rs | 1 + tests/ui/const-generics/issues/issue-86535.rs | 1 + .../impl-trait/extra-impl-in-trait-impl.fixed | 2 + .../ui/impl-trait/extra-impl-in-trait-impl.rs | 2 + .../extra-impl-in-trait-impl.stderr | 8 ++-- tests/ui/lint/dead-code/issue-59003.rs | 2 +- .../lint-unused-adt-appeared-in-pattern.rs | 37 +++++++++++++++++ ...lint-unused-adt-appeared-in-pattern.stderr | 20 ++++++++++ .../not-lint-used-adt-appeared-in-pattern.rs | 32 +++++++++++++++ ...sed-adt-impl-pub-trait-with-assoc-const.rs | 36 +++++++++++------ ...adt-impl-pub-trait-with-assoc-const.stderr | 24 +++++++++-- .../dead-code/unused-struct-derive-default.rs | 1 + .../unused-struct-derive-default.stderr | 1 - tests/ui/parser/issues/issue-105366.fixed | 1 + tests/ui/parser/issues/issue-105366.rs | 1 + tests/ui/parser/issues/issue-105366.stderr | 2 +- 21 files changed, 164 insertions(+), 60 deletions(-) create mode 100644 tests/ui/lint/dead-code/lint-unused-adt-appeared-in-pattern.rs create mode 100644 tests/ui/lint/dead-code/lint-unused-adt-appeared-in-pattern.stderr create mode 100644 tests/ui/lint/dead-code/not-lint-used-adt-appeared-in-pattern.rs diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs index bbd586386dd27..0d55a6777647d 100644 --- a/compiler/rustc_passes/src/dead.rs +++ b/compiler/rustc_passes/src/dead.rs @@ -277,7 +277,10 @@ impl<'tcx> MarkSymbolVisitor<'tcx> { pats: &[hir::PatField<'_>], ) { let variant = match self.typeck_results().node_type(lhs.hir_id).kind() { - ty::Adt(adt, _) => adt.variant_of_res(res), + ty::Adt(adt, _) => { + self.check_def_id(adt.did()); + adt.variant_of_res(res) + } _ => span_bug!(lhs.span, "non-ADT in struct pattern"), }; for pat in pats { @@ -297,7 +300,10 @@ impl<'tcx> MarkSymbolVisitor<'tcx> { dotdot: hir::DotDotPos, ) { let variant = match self.typeck_results().node_type(lhs.hir_id).kind() { - ty::Adt(adt, _) => adt.variant_of_res(res), + ty::Adt(adt, _) => { + self.check_def_id(adt.did()); + adt.variant_of_res(res) + } _ => { self.tcx.dcx().span_delayed_bug(lhs.span, "non-ADT in tuple struct pattern"); return; @@ -402,31 +408,6 @@ impl<'tcx> MarkSymbolVisitor<'tcx> { return false; } - // don't ignore impls for Enums and pub Structs whose methods don't have self receiver, - // cause external crate may call such methods to construct values of these types - if let Some(local_impl_of) = impl_of.as_local() - && let Some(local_def_id) = def_id.as_local() - && let Some(fn_sig) = - self.tcx.hir().fn_sig_by_hir_id(self.tcx.local_def_id_to_hir_id(local_def_id)) - && matches!(fn_sig.decl.implicit_self, hir::ImplicitSelfKind::None) - && let TyKind::Path(hir::QPath::Resolved(_, path)) = - self.tcx.hir().expect_item(local_impl_of).expect_impl().self_ty.kind - && let Res::Def(def_kind, did) = path.res - { - match def_kind { - // for example, #[derive(Default)] pub struct T(i32); - // external crate can call T::default() to construct T, - // so that don't ignore impl Default for pub Enum and Structs - DefKind::Struct | DefKind::Union if self.tcx.visibility(did).is_public() => { - return false; - } - // don't ignore impl Default for Enums, - // cause we don't know which variant is constructed - DefKind::Enum => return false, - _ => (), - }; - } - if let Some(trait_of) = self.tcx.trait_id_of_impl(impl_of) && self.tcx.has_attr(trait_of, sym::rustc_trivial_field_reads) { @@ -690,6 +671,9 @@ impl<'tcx> Visitor<'tcx> for MarkSymbolVisitor<'tcx> { self.handle_field_pattern_match(pat, res, fields); } PatKind::Path(ref qpath) => { + if let ty::Adt(adt, _) = self.typeck_results().node_type(pat.hir_id).kind() { + self.check_def_id(adt.did()); + } let res = self.typeck_results().qpath_res(qpath, pat.hir_id); self.handle_res(res); } @@ -845,7 +829,7 @@ fn check_item<'tcx>( // mark the method live if the self_ty is public, // or the method is public and may construct self if tcx.visibility(local_def_id).is_public() - && (ty_and_all_fields_are_public || may_construct_self) + && (ty_and_all_fields_are_public || (ty_is_public && may_construct_self)) { // if the impl item is public, // and the ty may be constructed or can be constructed in foreign crates, diff --git a/library/core/src/default.rs b/library/core/src/default.rs index 5cacedcb241a5..4524b352ec817 100644 --- a/library/core/src/default.rs +++ b/library/core/src/default.rs @@ -103,7 +103,6 @@ use crate::ascii::Char as AsciiChar; /// ``` #[cfg_attr(not(test), rustc_diagnostic_item = "Default")] #[stable(feature = "rust1", since = "1.0.0")] -#[cfg_attr(not(bootstrap), rustc_trivial_field_reads)] pub trait Default: Sized { /// Returns the "default value" for a type. /// diff --git a/src/tools/rust-analyzer/crates/salsa/salsa-macros/src/database_storage.rs b/src/tools/rust-analyzer/crates/salsa/salsa-macros/src/database_storage.rs index 14238e2fed55d..f16d814b9f038 100644 --- a/src/tools/rust-analyzer/crates/salsa/salsa-macros/src/database_storage.rs +++ b/src/tools/rust-analyzer/crates/salsa/salsa-macros/src/database_storage.rs @@ -241,11 +241,3 @@ impl Parse for QueryGroup { Ok(QueryGroup { group_path }) } } - -struct Nothing; - -impl Parse for Nothing { - fn parse(_input: ParseStream<'_>) -> syn::Result { - Ok(Nothing) - } -} diff --git a/tests/ui-fulldeps/deriving-global.rs b/tests/ui-fulldeps/deriving-global.rs index 7783010be441d..0ba149c9ad654 100644 --- a/tests/ui-fulldeps/deriving-global.rs +++ b/tests/ui-fulldeps/deriving-global.rs @@ -17,18 +17,21 @@ mod submod { // if any of these are implemented without global calls for any // function calls, then being in a submodule will (correctly) // cause errors about unrecognised module `std` (or `extra`) + #[allow(dead_code)] #[derive(PartialEq, PartialOrd, Eq, Ord, Hash, Clone, Debug, Encodable, Decodable)] enum A { A1(usize), A2(isize), } + #[allow(dead_code)] #[derive(PartialEq, PartialOrd, Eq, Ord, Hash, Clone, Debug, Encodable, Decodable)] struct B { x: usize, y: isize, } + #[allow(dead_code)] #[derive(PartialEq, PartialOrd, Eq, Ord, Hash, Clone, Debug, Encodable, Decodable)] struct C(usize, isize); } diff --git a/tests/ui-fulldeps/deriving-hygiene.rs b/tests/ui-fulldeps/deriving-hygiene.rs index a3a6f9e022ebb..f948d6ac544e5 100644 --- a/tests/ui-fulldeps/deriving-hygiene.rs +++ b/tests/ui-fulldeps/deriving-hygiene.rs @@ -20,6 +20,7 @@ pub const s: u8 = 1; pub const state: u8 = 1; pub const cmp: u8 = 1; +#[allow(dead_code)] #[derive(Ord, Eq, PartialOrd, PartialEq, Debug, Decodable, Encodable, Hash)] struct Foo {} diff --git a/tests/ui/const-generics/issues/issue-86535-2.rs b/tests/ui/const-generics/issues/issue-86535-2.rs index 1ba3b6d5347c0..bd9431dbc85b5 100644 --- a/tests/ui/const-generics/issues/issue-86535-2.rs +++ b/tests/ui/const-generics/issues/issue-86535-2.rs @@ -7,6 +7,7 @@ pub trait Foo { fn foo() where [(); Self::ASSOC_C]:; } +#[allow(dead_code)] struct Bar; impl Foo for Bar { const ASSOC_C: usize = 3; diff --git a/tests/ui/const-generics/issues/issue-86535.rs b/tests/ui/const-generics/issues/issue-86535.rs index dd6bc88ad198f..cd9934a4a9971 100644 --- a/tests/ui/const-generics/issues/issue-86535.rs +++ b/tests/ui/const-generics/issues/issue-86535.rs @@ -2,6 +2,7 @@ #![feature(adt_const_params, generic_const_exprs)] #![allow(incomplete_features, unused_variables)] +#[allow(dead_code)] struct F; impl X for F<{ S }> { const W: usize = 3; diff --git a/tests/ui/impl-trait/extra-impl-in-trait-impl.fixed b/tests/ui/impl-trait/extra-impl-in-trait-impl.fixed index 886fc1d005802..3c4499f017337 100644 --- a/tests/ui/impl-trait/extra-impl-in-trait-impl.fixed +++ b/tests/ui/impl-trait/extra-impl-in-trait-impl.fixed @@ -1,6 +1,8 @@ //@ run-rustfix +#[allow(dead_code)] struct S(T); +#[allow(dead_code)] struct S2; impl Default for S { diff --git a/tests/ui/impl-trait/extra-impl-in-trait-impl.rs b/tests/ui/impl-trait/extra-impl-in-trait-impl.rs index f3271993867cb..ac0783295242e 100644 --- a/tests/ui/impl-trait/extra-impl-in-trait-impl.rs +++ b/tests/ui/impl-trait/extra-impl-in-trait-impl.rs @@ -1,6 +1,8 @@ //@ run-rustfix +#[allow(dead_code)] struct S(T); +#[allow(dead_code)] struct S2; impl impl Default for S { diff --git a/tests/ui/impl-trait/extra-impl-in-trait-impl.stderr b/tests/ui/impl-trait/extra-impl-in-trait-impl.stderr index 5aafc8b64d4ff..91c7da5a04fb4 100644 --- a/tests/ui/impl-trait/extra-impl-in-trait-impl.stderr +++ b/tests/ui/impl-trait/extra-impl-in-trait-impl.stderr @@ -1,23 +1,23 @@ error: unexpected `impl` keyword - --> $DIR/extra-impl-in-trait-impl.rs:6:18 + --> $DIR/extra-impl-in-trait-impl.rs:8:18 | LL | impl impl Default for S { | ^^^^^ help: remove the extra `impl` | note: this is parsed as an `impl Trait` type, but a trait is expected at this position - --> $DIR/extra-impl-in-trait-impl.rs:6:18 + --> $DIR/extra-impl-in-trait-impl.rs:8:18 | LL | impl impl Default for S { | ^^^^^^^^^^^^ error: unexpected `impl` keyword - --> $DIR/extra-impl-in-trait-impl.rs:12:6 + --> $DIR/extra-impl-in-trait-impl.rs:14:6 | LL | impl impl Default for S2 { | ^^^^^ help: remove the extra `impl` | note: this is parsed as an `impl Trait` type, but a trait is expected at this position - --> $DIR/extra-impl-in-trait-impl.rs:12:6 + --> $DIR/extra-impl-in-trait-impl.rs:14:6 | LL | impl impl Default for S2 { | ^^^^^^^^^^^^ diff --git a/tests/ui/lint/dead-code/issue-59003.rs b/tests/ui/lint/dead-code/issue-59003.rs index e3dcaca577889..319cf2db1495f 100644 --- a/tests/ui/lint/dead-code/issue-59003.rs +++ b/tests/ui/lint/dead-code/issue-59003.rs @@ -4,8 +4,8 @@ #![deny(dead_code)] +#[allow(dead_code)] struct Foo { - #[allow(dead_code)] inner: u32, } diff --git a/tests/ui/lint/dead-code/lint-unused-adt-appeared-in-pattern.rs b/tests/ui/lint/dead-code/lint-unused-adt-appeared-in-pattern.rs new file mode 100644 index 0000000000000..25777438456b6 --- /dev/null +++ b/tests/ui/lint/dead-code/lint-unused-adt-appeared-in-pattern.rs @@ -0,0 +1,37 @@ +#![deny(dead_code)] + +struct Foo(u8); //~ ERROR struct `Foo` is never constructed + +enum Bar { //~ ERROR enum `Bar` is never used + Var1(u8), + Var2(u8), +} + +pub trait Tr1 { + fn f1() -> Self; +} + +impl Tr1 for Foo { + fn f1() -> Foo { + let f = Foo(0); + let Foo(tag) = f; + Foo(tag) + } +} + +impl Tr1 for Bar { + fn f1() -> Bar { + let b = Bar::Var1(0); + let b = if let Bar::Var1(_) = b { + Bar::Var1(0) + } else { + Bar::Var2(0) + }; + match b { + Bar::Var1(_) => Bar::Var2(0), + Bar::Var2(_) => Bar::Var1(0), + } + } +} + +fn main() {} diff --git a/tests/ui/lint/dead-code/lint-unused-adt-appeared-in-pattern.stderr b/tests/ui/lint/dead-code/lint-unused-adt-appeared-in-pattern.stderr new file mode 100644 index 0000000000000..7c1a4b4597755 --- /dev/null +++ b/tests/ui/lint/dead-code/lint-unused-adt-appeared-in-pattern.stderr @@ -0,0 +1,20 @@ +error: struct `Foo` is never constructed + --> $DIR/lint-unused-adt-appeared-in-pattern.rs:3:8 + | +LL | struct Foo(u8); + | ^^^ + | +note: the lint level is defined here + --> $DIR/lint-unused-adt-appeared-in-pattern.rs:1:9 + | +LL | #![deny(dead_code)] + | ^^^^^^^^^ + +error: enum `Bar` is never used + --> $DIR/lint-unused-adt-appeared-in-pattern.rs:5:6 + | +LL | enum Bar { + | ^^^ + +error: aborting due to 2 previous errors + diff --git a/tests/ui/lint/dead-code/not-lint-used-adt-appeared-in-pattern.rs b/tests/ui/lint/dead-code/not-lint-used-adt-appeared-in-pattern.rs new file mode 100644 index 0000000000000..43a2e43190433 --- /dev/null +++ b/tests/ui/lint/dead-code/not-lint-used-adt-appeared-in-pattern.rs @@ -0,0 +1,32 @@ +//@ check-pass + +#![deny(dead_code)] + +#[repr(u8)] +#[derive(Copy, Clone, Debug)] +pub enum RecordField { + Target = 1, + Level, + Module, + File, + Line, + NumArgs, +} + +unsafe trait Pod {} + +#[repr(transparent)] +struct RecordFieldWrapper(RecordField); + +unsafe impl Pod for RecordFieldWrapper {} + +fn try_read(buf: &[u8]) -> T { + unsafe { std::ptr::read_unaligned(buf.as_ptr() as *const T) } +} + +pub fn foo(buf: &[u8]) -> RecordField { + let RecordFieldWrapper(tag) = try_read(buf); + tag +} + +fn main() {} diff --git a/tests/ui/lint/dead-code/unused-adt-impl-pub-trait-with-assoc-const.rs b/tests/ui/lint/dead-code/unused-adt-impl-pub-trait-with-assoc-const.rs index bf2fc243e8194..658cc3d6c613a 100644 --- a/tests/ui/lint/dead-code/unused-adt-impl-pub-trait-with-assoc-const.rs +++ b/tests/ui/lint/dead-code/unused-adt-impl-pub-trait-with-assoc-const.rs @@ -1,8 +1,9 @@ #![deny(dead_code)] struct T1; //~ ERROR struct `T1` is never constructed -pub struct T2(i32); //~ ERROR struct `T2` is never constructed -struct T3; +struct T2; //~ ERROR struct `T2` is never constructed +pub struct T3(i32); //~ ERROR struct `T3` is never constructed +pub struct T4(i32); //~ ERROR field `0` is never read trait Trait1 { //~ ERROR trait `Trait1` is never used const UNUSED: i32; @@ -11,13 +12,13 @@ trait Trait1 { //~ ERROR trait `Trait1` is never used } pub trait Trait2 { - const USED: i32; - fn used(&self) {} + const MAY_USED: i32; + fn may_used(&self) {} } pub trait Trait3 { - const USED: i32; - fn construct_self() -> Self; + const MAY_USED: i32; + fn may_used() -> Self; } impl Trait1 for T1 { @@ -30,23 +31,34 @@ impl Trait1 for T1 { impl Trait1 for T2 { const UNUSED: i32 = 0; fn construct_self() -> Self { - T2(0) + Self } } impl Trait2 for T1 { - const USED: i32 = 0; + const MAY_USED: i32 = 0; } impl Trait2 for T2 { - const USED: i32 = 0; + const MAY_USED: i32 = 0; } -impl Trait3 for T3 { - const USED: i32 = 0; - fn construct_self() -> Self { +impl Trait2 for T3 { + const MAY_USED: i32 = 0; +} + +impl Trait3 for T2 { + const MAY_USED: i32 = 0; + fn may_used() -> Self { Self } } +impl Trait3 for T4 { + const MAY_USED: i32 = 0; + fn may_used() -> Self { + T4(0) + } +} + fn main() {} diff --git a/tests/ui/lint/dead-code/unused-adt-impl-pub-trait-with-assoc-const.stderr b/tests/ui/lint/dead-code/unused-adt-impl-pub-trait-with-assoc-const.stderr index 174096d939883..08c7a5cb4b062 100644 --- a/tests/ui/lint/dead-code/unused-adt-impl-pub-trait-with-assoc-const.stderr +++ b/tests/ui/lint/dead-code/unused-adt-impl-pub-trait-with-assoc-const.stderr @@ -11,16 +11,32 @@ LL | #![deny(dead_code)] | ^^^^^^^^^ error: struct `T2` is never constructed - --> $DIR/unused-adt-impl-pub-trait-with-assoc-const.rs:4:12 + --> $DIR/unused-adt-impl-pub-trait-with-assoc-const.rs:4:8 | -LL | pub struct T2(i32); +LL | struct T2; + | ^^ + +error: struct `T3` is never constructed + --> $DIR/unused-adt-impl-pub-trait-with-assoc-const.rs:5:12 + | +LL | pub struct T3(i32); | ^^ +error: field `0` is never read + --> $DIR/unused-adt-impl-pub-trait-with-assoc-const.rs:6:15 + | +LL | pub struct T4(i32); + | -- ^^^ + | | + | field in this struct + | + = help: consider removing this field + error: trait `Trait1` is never used - --> $DIR/unused-adt-impl-pub-trait-with-assoc-const.rs:7:7 + --> $DIR/unused-adt-impl-pub-trait-with-assoc-const.rs:8:7 | LL | trait Trait1 { | ^^^^^^ -error: aborting due to 3 previous errors +error: aborting due to 5 previous errors diff --git a/tests/ui/lint/dead-code/unused-struct-derive-default.rs b/tests/ui/lint/dead-code/unused-struct-derive-default.rs index 330ad32dd5709..f20b7cb66ee51 100644 --- a/tests/ui/lint/dead-code/unused-struct-derive-default.rs +++ b/tests/ui/lint/dead-code/unused-struct-derive-default.rs @@ -22,4 +22,5 @@ pub struct T2 { fn main() { let _x: Used = Default::default(); + let _e: E = Default::default(); } diff --git a/tests/ui/lint/dead-code/unused-struct-derive-default.stderr b/tests/ui/lint/dead-code/unused-struct-derive-default.stderr index bbb0bd7be7064..7422f9a39f312 100644 --- a/tests/ui/lint/dead-code/unused-struct-derive-default.stderr +++ b/tests/ui/lint/dead-code/unused-struct-derive-default.stderr @@ -4,7 +4,6 @@ error: struct `T` is never constructed LL | struct T; | ^ | - = note: `T` has a derived impl for the trait `Default`, but this is intentionally ignored during dead code analysis note: the lint level is defined here --> $DIR/unused-struct-derive-default.rs:1:9 | diff --git a/tests/ui/parser/issues/issue-105366.fixed b/tests/ui/parser/issues/issue-105366.fixed index 7157b647524dd..95419dc07f2cc 100644 --- a/tests/ui/parser/issues/issue-105366.fixed +++ b/tests/ui/parser/issues/issue-105366.fixed @@ -1,5 +1,6 @@ //@ run-rustfix +#[allow(dead_code)] struct Foo; impl From for Foo { diff --git a/tests/ui/parser/issues/issue-105366.rs b/tests/ui/parser/issues/issue-105366.rs index dc3cb8b343d32..3278b73799125 100644 --- a/tests/ui/parser/issues/issue-105366.rs +++ b/tests/ui/parser/issues/issue-105366.rs @@ -1,5 +1,6 @@ //@ run-rustfix +#[allow(dead_code)] struct Foo; fn From for Foo { diff --git a/tests/ui/parser/issues/issue-105366.stderr b/tests/ui/parser/issues/issue-105366.stderr index 18c04dfaf2088..195305a2ec889 100644 --- a/tests/ui/parser/issues/issue-105366.stderr +++ b/tests/ui/parser/issues/issue-105366.stderr @@ -1,5 +1,5 @@ error: you might have meant to write `impl` instead of `fn` - --> $DIR/issue-105366.rs:5:1 + --> $DIR/issue-105366.rs:6:1 | LL | fn From for Foo { | ^^ From 40cad01f2f9d830aeb798057a0aeb761316ebf28 Mon Sep 17 00:00:00 2001 From: Oneirical Date: Wed, 19 Jun 2024 13:25:29 -0400 Subject: [PATCH 681/892] rewrite and rename include_bytes_deps to rmake --- src/tools/tidy/src/allowed_run_make_makefiles.txt | 1 - .../input.bin | 0 .../input.md | 0 .../input.txt | 0 .../main.rs | 0 tests/run-make/include-bytes-deps/rmake.rs | 15 +++++++++++++++ tests/run-make/include_bytes_deps/Makefile | 7 ------- 7 files changed, 15 insertions(+), 8 deletions(-) rename tests/run-make/{include_bytes_deps => include-bytes-deps}/input.bin (100%) rename tests/run-make/{include_bytes_deps => include-bytes-deps}/input.md (100%) rename tests/run-make/{include_bytes_deps => include-bytes-deps}/input.txt (100%) rename tests/run-make/{include_bytes_deps => include-bytes-deps}/main.rs (100%) create mode 100644 tests/run-make/include-bytes-deps/rmake.rs delete mode 100644 tests/run-make/include_bytes_deps/Makefile diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index 2da4e476e9016..6d13559818669 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -46,7 +46,6 @@ run-make/fmt-write-bloat/Makefile run-make/foreign-double-unwind/Makefile run-make/foreign-exceptions/Makefile run-make/foreign-rust-exceptions/Makefile -run-make/include_bytes_deps/Makefile run-make/incr-add-rust-src-component/Makefile run-make/incr-foreign-head-span/Makefile run-make/interdependent-c-libraries/Makefile diff --git a/tests/run-make/include_bytes_deps/input.bin b/tests/run-make/include-bytes-deps/input.bin similarity index 100% rename from tests/run-make/include_bytes_deps/input.bin rename to tests/run-make/include-bytes-deps/input.bin diff --git a/tests/run-make/include_bytes_deps/input.md b/tests/run-make/include-bytes-deps/input.md similarity index 100% rename from tests/run-make/include_bytes_deps/input.md rename to tests/run-make/include-bytes-deps/input.md diff --git a/tests/run-make/include_bytes_deps/input.txt b/tests/run-make/include-bytes-deps/input.txt similarity index 100% rename from tests/run-make/include_bytes_deps/input.txt rename to tests/run-make/include-bytes-deps/input.txt diff --git a/tests/run-make/include_bytes_deps/main.rs b/tests/run-make/include-bytes-deps/main.rs similarity index 100% rename from tests/run-make/include_bytes_deps/main.rs rename to tests/run-make/include-bytes-deps/main.rs diff --git a/tests/run-make/include-bytes-deps/rmake.rs b/tests/run-make/include-bytes-deps/rmake.rs new file mode 100644 index 0000000000000..6ca29fa664c98 --- /dev/null +++ b/tests/run-make/include-bytes-deps/rmake.rs @@ -0,0 +1,15 @@ +// include_bytes! and include_str! in `main.rs` +// should register the included file as of #24423, +// and this test checks that this is still the case. +// See https://github.com/rust-lang/rust/pull/24423 + +//FIXME(Oneirical): check if works without ignore freebsd + +use run_make_support::{invalid_utf8_contains, rustc}; + +fn main() { + rustc().emit("dep-info").input("main.rs").run(); + invalid_utf8_contains("main.d", "input.txt"); + invalid_utf8_contains("main.d", "input.bin"); + invalid_utf8_contains("main.d", "input.md"); +} diff --git a/tests/run-make/include_bytes_deps/Makefile b/tests/run-make/include_bytes_deps/Makefile deleted file mode 100644 index 696dfd207bbff..0000000000000 --- a/tests/run-make/include_bytes_deps/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -include ../tools.mk - -# ignore-freebsd - -all: - $(RUSTC) --emit dep-info main.rs - $(CGREP) "input.txt" "input.bin" "input.md" < $(TMPDIR)/main.d From 73d7dc7f220c8e451defc1f3817b99ed70079a4e Mon Sep 17 00:00:00 2001 From: Oneirical Date: Wed, 19 Jun 2024 14:06:17 -0400 Subject: [PATCH 682/892] rewrite optimization-remarks-dir-pgo to rmake --- .../tidy/src/allowed_run_make_makefiles.txt | 1 - .../optimization-remarks-dir-pgo/Makefile | 17 ----------------- .../optimization-remarks-dir-pgo/rmake.rs | 19 +++++++++++++++++++ 3 files changed, 19 insertions(+), 18 deletions(-) delete mode 100644 tests/run-make/optimization-remarks-dir-pgo/Makefile create mode 100644 tests/run-make/optimization-remarks-dir-pgo/rmake.rs diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index 6d13559818669..e26a1326f443a 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -101,7 +101,6 @@ run-make/no-alloc-shim/Makefile run-make/no-builtins-attribute/Makefile run-make/no-duplicate-libs/Makefile run-make/obey-crate-type-flag/Makefile -run-make/optimization-remarks-dir-pgo/Makefile run-make/optimization-remarks-dir/Makefile run-make/output-type-permutations/Makefile run-make/panic-abort-eh_frame/Makefile diff --git a/tests/run-make/optimization-remarks-dir-pgo/Makefile b/tests/run-make/optimization-remarks-dir-pgo/Makefile deleted file mode 100644 index 57ffd6e70f00b..0000000000000 --- a/tests/run-make/optimization-remarks-dir-pgo/Makefile +++ /dev/null @@ -1,17 +0,0 @@ -# needs-profiler-support -# ignore-cross-compile - -include ../tools.mk - -PROFILE_DIR=$(TMPDIR)/profiles - -check_hotness: - $(RUSTC) -Cprofile-generate="$(TMPDIR)"/profdata -O foo.rs -o$(TMPDIR)/foo - $(TMPDIR)/foo - "$(LLVM_BIN_DIR)"/llvm-profdata merge \ - -o "$(TMPDIR)"/merged.profdata \ - "$(TMPDIR)"/profdata/*.profraw - $(RUSTC) -Cprofile-use=$(TMPDIR)/merged.profdata -O foo.rs -Cremark=all -Zremark-dir=$(PROFILE_DIR) - - # Check that PGO hotness is included in the remark files - cat $(PROFILE_DIR)/*.opt.yaml | $(CGREP) -e "Hotness" diff --git a/tests/run-make/optimization-remarks-dir-pgo/rmake.rs b/tests/run-make/optimization-remarks-dir-pgo/rmake.rs new file mode 100644 index 0000000000000..678d9c2de8b40 --- /dev/null +++ b/tests/run-make/optimization-remarks-dir-pgo/rmake.rs @@ -0,0 +1,19 @@ +// This test checks the -Zremark-dir flag, which writes LLVM +// optimization remarks to the YAML format. When using PGO (Profile +// Guided Optimization), the Hotness attribute should be included in +// the output remark files. +// See https://github.com/rust-lang/rust/pull/114439 + +//@ needs-profiler-support +//@ ignore-cross-compile + +use run_make_support::{run, llvm_profdata, rustc, invalid_utf8_contains}; + +fn main() { + rustc().profile_generate("profdata").opt().input("foo.rs").output("foo").run(); + run("foo"); + llvm_profdata().merge().output("merged.profdata").input("profdata/default_15907418011457399462_0.profraw").run(); + rustc().profile_use("merged.profdata").opt().input("foo.rs").arg("-Cremark=all").arg("-Zremark-dir=profiles").run(); + // Check that PGO hotness is included in the remark files + invalid_utf8_contains("profiles/foo.cba44757bc0621b9-cgu.0.opt.opt.yaml", "Hotness"); +} From 651f02363d96ce75ae297d70104153a8b3b0981f Mon Sep 17 00:00:00 2001 From: Oneirical Date: Wed, 19 Jun 2024 14:30:47 -0400 Subject: [PATCH 683/892] rewrite optimization-remarks-dir to rmake --- .../tidy/src/allowed_run_make_makefiles.txt | 1 - .../optimization-remarks-dir-pgo/rmake.rs | 16 +++++++++--- .../optimization-remarks-dir/Makefile | 12 --------- .../optimization-remarks-dir/rmake.rs | 26 +++++++++++++++++++ 4 files changed, 39 insertions(+), 16 deletions(-) delete mode 100644 tests/run-make/optimization-remarks-dir/Makefile create mode 100644 tests/run-make/optimization-remarks-dir/rmake.rs diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index e26a1326f443a..4516bf86e2b35 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -101,7 +101,6 @@ run-make/no-alloc-shim/Makefile run-make/no-builtins-attribute/Makefile run-make/no-duplicate-libs/Makefile run-make/obey-crate-type-flag/Makefile -run-make/optimization-remarks-dir/Makefile run-make/output-type-permutations/Makefile run-make/panic-abort-eh_frame/Makefile run-make/pass-linker-flags-flavor/Makefile diff --git a/tests/run-make/optimization-remarks-dir-pgo/rmake.rs b/tests/run-make/optimization-remarks-dir-pgo/rmake.rs index 678d9c2de8b40..e527dcb0befa5 100644 --- a/tests/run-make/optimization-remarks-dir-pgo/rmake.rs +++ b/tests/run-make/optimization-remarks-dir-pgo/rmake.rs @@ -7,13 +7,23 @@ //@ needs-profiler-support //@ ignore-cross-compile -use run_make_support::{run, llvm_profdata, rustc, invalid_utf8_contains}; +use run_make_support::{invalid_utf8_contains, llvm_profdata, run, rustc}; fn main() { rustc().profile_generate("profdata").opt().input("foo.rs").output("foo").run(); run("foo"); - llvm_profdata().merge().output("merged.profdata").input("profdata/default_15907418011457399462_0.profraw").run(); - rustc().profile_use("merged.profdata").opt().input("foo.rs").arg("-Cremark=all").arg("-Zremark-dir=profiles").run(); + llvm_profdata() + .merge() + .output("merged.profdata") + .input("profdata/default_15907418011457399462_0.profraw") + .run(); + rustc() + .profile_use("merged.profdata") + .opt() + .input("foo.rs") + .arg("-Cremark=all") + .arg("-Zremark-dir=profiles") + .run(); // Check that PGO hotness is included in the remark files invalid_utf8_contains("profiles/foo.cba44757bc0621b9-cgu.0.opt.opt.yaml", "Hotness"); } diff --git a/tests/run-make/optimization-remarks-dir/Makefile b/tests/run-make/optimization-remarks-dir/Makefile deleted file mode 100644 index a8342c8ad14d5..0000000000000 --- a/tests/run-make/optimization-remarks-dir/Makefile +++ /dev/null @@ -1,12 +0,0 @@ -include ../tools.mk - -PROFILE_DIR=$(TMPDIR)/profiles - -all: check_inline check_filter - -check_inline: - $(RUSTC) -O foo.rs --crate-type=lib -Cremark=all -Zremark-dir=$(PROFILE_DIR) - cat $(PROFILE_DIR)/*.opt.yaml | $(CGREP) -e "inline" -check_filter: - $(RUSTC) -O foo.rs --crate-type=lib -Cremark=foo -Zremark-dir=$(PROFILE_DIR) - cat $(PROFILE_DIR)/*.opt.yaml | $(CGREP) -e -v "inline" diff --git a/tests/run-make/optimization-remarks-dir/rmake.rs b/tests/run-make/optimization-remarks-dir/rmake.rs new file mode 100644 index 0000000000000..d0c4ccd72d13a --- /dev/null +++ b/tests/run-make/optimization-remarks-dir/rmake.rs @@ -0,0 +1,26 @@ +// In this test, the function `bar` has #[inline(never)] and the function `foo` +// does not. This test outputs LLVM optimization remarks twice - first for all +// functions (including `bar`, and the `inline` mention), and then for only `foo` +// (should not have the `inline` mention). +// See https://github.com/rust-lang/rust/pull/113040 + +use run_make_support::{invalid_utf8_contains, invalid_utf8_not_contains, rustc}; + +fn main() { + rustc() + .opt() + .input("foo.rs") + .crate_type("lib") + .arg("-Cremark=all") + .arg("-Zremark-dir=profiles_all") + .run(); + invalid_utf8_contains("profiles_all/foo.5be5606e1f6aa79b-cgu.0.opt.opt.yaml", "inline"); + rustc() + .opt() + .input("foo.rs") + .crate_type("lib") + .arg("-Cremark=foo") + .arg("-Zremark-dir=profiles_foo") + .run(); + invalid_utf8_not_contains("profiles_foo/foo.5be5606e1f6aa79b-cgu.0.opt.opt.yaml", "inline"); +} From 5e23dfea9dee65b8a5b7ed54354b4c46d38f12ca Mon Sep 17 00:00:00 2001 From: Oneirical Date: Wed, 19 Jun 2024 14:55:22 -0400 Subject: [PATCH 684/892] rewrite and rename issue-40535 to rmake --- src/tools/tidy/src/allowed_run_make_makefiles.txt | 1 - tests/run-make/issue-40535/Makefile | 13 ------------- .../bar.rs | 0 .../baz.rs | 0 .../foo.rs | 0 tests/run-make/metadata-only-crate-no-ice/rmake.rs | 14 ++++++++++++++ 6 files changed, 14 insertions(+), 14 deletions(-) delete mode 100644 tests/run-make/issue-40535/Makefile rename tests/run-make/{issue-40535 => metadata-only-crate-no-ice}/bar.rs (100%) rename tests/run-make/{issue-40535 => metadata-only-crate-no-ice}/baz.rs (100%) rename tests/run-make/{issue-40535 => metadata-only-crate-no-ice}/foo.rs (100%) create mode 100644 tests/run-make/metadata-only-crate-no-ice/rmake.rs diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index 4516bf86e2b35..4fbfa442fcc54 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -63,7 +63,6 @@ run-make/issue-33329/Makefile run-make/issue-35164/Makefile run-make/issue-36710/Makefile run-make/issue-37839/Makefile -run-make/issue-40535/Makefile run-make/issue-47551/Makefile run-make/issue-69368/Makefile run-make/issue-83045/Makefile diff --git a/tests/run-make/issue-40535/Makefile b/tests/run-make/issue-40535/Makefile deleted file mode 100644 index 155c88252144d..0000000000000 --- a/tests/run-make/issue-40535/Makefile +++ /dev/null @@ -1,13 +0,0 @@ -include ../tools.mk - -# The ICE occurred in the following situation: -# * `foo` declares `extern crate bar, baz`, depends only on `bar` (forgetting `baz` in `Cargo.toml`) -# * `bar` declares and depends on `extern crate baz` -# * All crates built in metadata-only mode (`cargo check`) -all: - # cc https://github.com/rust-lang/rust/issues/40623 - $(RUSTC) baz.rs --emit=metadata - $(RUSTC) bar.rs --emit=metadata --extern baz=$(TMPDIR)/libbaz.rmeta - $(RUSTC) foo.rs --emit=metadata --extern bar=$(TMPDIR)/libbar.rmeta 2>&1 | \ - $(CGREP) -v "unexpectedly panicked" - # ^ Succeeds if it doesn't find the ICE message diff --git a/tests/run-make/issue-40535/bar.rs b/tests/run-make/metadata-only-crate-no-ice/bar.rs similarity index 100% rename from tests/run-make/issue-40535/bar.rs rename to tests/run-make/metadata-only-crate-no-ice/bar.rs diff --git a/tests/run-make/issue-40535/baz.rs b/tests/run-make/metadata-only-crate-no-ice/baz.rs similarity index 100% rename from tests/run-make/issue-40535/baz.rs rename to tests/run-make/metadata-only-crate-no-ice/baz.rs diff --git a/tests/run-make/issue-40535/foo.rs b/tests/run-make/metadata-only-crate-no-ice/foo.rs similarity index 100% rename from tests/run-make/issue-40535/foo.rs rename to tests/run-make/metadata-only-crate-no-ice/foo.rs diff --git a/tests/run-make/metadata-only-crate-no-ice/rmake.rs b/tests/run-make/metadata-only-crate-no-ice/rmake.rs new file mode 100644 index 0000000000000..825da12cfd1bc --- /dev/null +++ b/tests/run-make/metadata-only-crate-no-ice/rmake.rs @@ -0,0 +1,14 @@ +// In a dependency hierarchy, metadata-only crates could cause an Internal +// Compiler Error (ICE) due to a compiler bug - not correctly fetching sources for +// metadata-only crates. This test is a minimal reproduction of a program that triggered +// this bug, and checks that no ICE occurs. +// See https://github.com/rust-lang/rust/issues/40535 + +use run_make_support::rustc; + +fn main() { + rustc().input("baz.rs").emit("metadata").run(); + rustc().input("bar.rs").emit("metadata").extern_("baz", "libbaz.rmeta").run(); + // There should be no internal compiler error message. + rustc().input("foo.rs").emit("metadata").extern_("bar", "libbaz.rmeta").run().assert_stderr_not_contains("unexpectedly panicked"); +} From b167a15d64c0777afa6b90d7883368c629049a16 Mon Sep 17 00:00:00 2001 From: Oneirical Date: Wed, 19 Jun 2024 15:46:27 -0400 Subject: [PATCH 685/892] rewrite rmeta-preferred to rmake --- .../tidy/src/allowed_run_make_makefiles.txt | 1 - tests/run-make/include-bytes-deps/rmake.rs | 2 -- .../metadata-only-crate-no-ice/rmake.rs | 4 ++-- tests/run-make/rmeta-preferred/Makefile | 16 ---------------- tests/run-make/rmeta-preferred/rmake.rs | 18 ++++++++++++++++++ 5 files changed, 20 insertions(+), 21 deletions(-) delete mode 100644 tests/run-make/rmeta-preferred/Makefile create mode 100644 tests/run-make/rmeta-preferred/rmake.rs diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index 4fbfa442fcc54..70c1b055c6e40 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -132,7 +132,6 @@ run-make/return-non-c-like-enum-from-c/Makefile run-make/rlib-format-packed-bundled-libs-2/Makefile run-make/rlib-format-packed-bundled-libs-3/Makefile run-make/rlib-format-packed-bundled-libs/Makefile -run-make/rmeta-preferred/Makefile run-make/rustc-macro-dep-files/Makefile run-make/sanitizer-cdylib-link/Makefile run-make/sanitizer-dylib-link/Makefile diff --git a/tests/run-make/include-bytes-deps/rmake.rs b/tests/run-make/include-bytes-deps/rmake.rs index 6ca29fa664c98..ea371ddae5675 100644 --- a/tests/run-make/include-bytes-deps/rmake.rs +++ b/tests/run-make/include-bytes-deps/rmake.rs @@ -3,8 +3,6 @@ // and this test checks that this is still the case. // See https://github.com/rust-lang/rust/pull/24423 -//FIXME(Oneirical): check if works without ignore freebsd - use run_make_support::{invalid_utf8_contains, rustc}; fn main() { diff --git a/tests/run-make/metadata-only-crate-no-ice/rmake.rs b/tests/run-make/metadata-only-crate-no-ice/rmake.rs index 825da12cfd1bc..e6f852fca413a 100644 --- a/tests/run-make/metadata-only-crate-no-ice/rmake.rs +++ b/tests/run-make/metadata-only-crate-no-ice/rmake.rs @@ -9,6 +9,6 @@ use run_make_support::rustc; fn main() { rustc().input("baz.rs").emit("metadata").run(); rustc().input("bar.rs").emit("metadata").extern_("baz", "libbaz.rmeta").run(); - // There should be no internal compiler error message. - rustc().input("foo.rs").emit("metadata").extern_("bar", "libbaz.rmeta").run().assert_stderr_not_contains("unexpectedly panicked"); + // There should be no internal compiler error. + rustc().input("foo.rs").emit("metadata").extern_("bar", "libbaz.rmeta").run(); } diff --git a/tests/run-make/rmeta-preferred/Makefile b/tests/run-make/rmeta-preferred/Makefile deleted file mode 100644 index 3bf12cced29ab..0000000000000 --- a/tests/run-make/rmeta-preferred/Makefile +++ /dev/null @@ -1,16 +0,0 @@ -# ignore-cross-compile -include ../tools.mk - -# Test that using rlibs and rmeta dep crates work together. Specifically, that -# there can be both an rmeta and an rlib file and rustc will prefer the rmeta -# file. -# -# This behavior is simply making sure this doesn't accidentally change; in this -# case we want to make sure that the rlib isn't being used as that would cause -# bugs in -Zbinary-dep-depinfo (see #68298). - -all: - $(RUSTC) rmeta_aux.rs --crate-type=rlib --emit link,metadata - $(RUSTC) lib.rs --crate-type=rlib --emit dep-info -Zbinary-dep-depinfo - $(CGREP) "librmeta_aux.rmeta" < $(TMPDIR)/lib.d - $(CGREP) -v "librmeta_aux.rlib" < $(TMPDIR)/lib.d diff --git a/tests/run-make/rmeta-preferred/rmake.rs b/tests/run-make/rmeta-preferred/rmake.rs new file mode 100644 index 0000000000000..09cba06e2f509 --- /dev/null +++ b/tests/run-make/rmeta-preferred/rmake.rs @@ -0,0 +1,18 @@ +// This test compiles `lib.rs`'s dependency, `rmeta_aux.rs`, as both an rlib +// and an rmeta crate. By default, rustc should give the metadata crate (rmeta) +// precedence over the rust-lib (rlib). This test inspects the contents of the binary +// and that the correct (rmeta) crate was used. +// rlibs being preferred could indicate a resurgence of the -Zbinary-dep-depinfo bug +// seen in #68298. +// See https://github.com/rust-lang/rust/pull/37681 + +//@ ignore-cross-compile + +use run_make_support::{invalid_utf8_contains, invalid_utf8_not_contains, rustc}; + +fn main() { + rustc().input("rmeta_aux.rs").crate_type("rlib").emit("link,metadata").run(); + rustc().input("lib.rs").crate_type("rlib").emit("dep-info").arg("-Zbinary-dep-depinfo").run(); + invalid_utf8_contains("lib.d", "librmeta_aux.rmeta"); + invalid_utf8_not_contains("lib.d", "librmeta_aux.rlib"); +} From 3ea36f5bb6845bc0c0737d174e49fd3ff9380708 Mon Sep 17 00:00:00 2001 From: Oneirical Date: Thu, 20 Jun 2024 16:02:22 -0400 Subject: [PATCH 686/892] add shallow_find_files helper function to run-make-support --- src/tools/run-make-support/src/lib.rs | 34 +++++++++++++++++++ .../optimization-remarks-dir-pgo/rmake.rs | 26 ++++++++++---- .../optimization-remarks-dir/rmake.rs | 19 +++++++++-- 3 files changed, 69 insertions(+), 10 deletions(-) diff --git a/src/tools/run-make-support/src/lib.rs b/src/tools/run-make-support/src/lib.rs index 9a180fe4ad19a..af5ae6a8e608c 100644 --- a/src/tools/run-make-support/src/lib.rs +++ b/src/tools/run-make-support/src/lib.rs @@ -261,6 +261,40 @@ pub fn test_while_readonly, F: FnOnce() + std::panic::UnwindSafe> success.unwrap(); } +/// Browse the directory `path` non-recursively and return all files which respect the parameters +/// outlined by `closure`. +#[track_caller] +pub fn shallow_find_files, F: Fn(&PathBuf) -> bool>( + path: P, + closure: F, +) -> Vec { + let mut matching_files = Vec::new(); + for entry in fs_wrapper::read_dir(path) { + let entry = entry.expect("failed to read directory entry."); + let path = entry.path(); + + if path.is_file() && closure(&path) { + matching_files.push(path); + } + } + matching_files +} + +/// Returns true if the filename at `path` starts with `prefix`. +pub fn has_prefix>(path: P, prefix: &str) -> bool { + path.as_ref().file_name().is_some_and(|name| name.to_str().unwrap().starts_with(prefix)) +} + +/// Returns true if the filename at `path` has the extension `extension`. +pub fn has_extension>(path: P, extension: &str) -> bool { + path.as_ref().extension().is_some_and(|ext| ext == extension) +} + +/// Returns true if the filename at `path` does not contain `expected`. +pub fn not_contains>(path: P, expected: &str) -> bool { + !path.as_ref().file_name().is_some_and(|name| name.to_str().unwrap().contains(expected)) +} + /// Use `cygpath -w` on a path to get a Windows path string back. This assumes that `cygpath` is /// available on the platform! #[track_caller] diff --git a/tests/run-make/optimization-remarks-dir-pgo/rmake.rs b/tests/run-make/optimization-remarks-dir-pgo/rmake.rs index e527dcb0befa5..228c43cc5f18a 100644 --- a/tests/run-make/optimization-remarks-dir-pgo/rmake.rs +++ b/tests/run-make/optimization-remarks-dir-pgo/rmake.rs @@ -7,16 +7,20 @@ //@ needs-profiler-support //@ ignore-cross-compile -use run_make_support::{invalid_utf8_contains, llvm_profdata, run, rustc}; +use run_make_support::{ + has_extension, has_prefix, invalid_utf8_contains, llvm_profdata, run, rustc, shallow_find_files, +}; fn main() { rustc().profile_generate("profdata").opt().input("foo.rs").output("foo").run(); run("foo"); - llvm_profdata() - .merge() - .output("merged.profdata") - .input("profdata/default_15907418011457399462_0.profraw") - .run(); + // The profdata filename is a long sequence of numbers, fetch it by prefix and extension + // to keep the test working even if the filename changes. + let profdata_files = shallow_find_files("profdata", |path| { + has_prefix(path, "default") && has_extension(path, "profraw") + }); + let profdata_file = profdata_files.get(0).unwrap(); + llvm_profdata().merge().output("merged.profdata").input(profdata_file).run(); rustc() .profile_use("merged.profdata") .opt() @@ -25,5 +29,13 @@ fn main() { .arg("-Zremark-dir=profiles") .run(); // Check that PGO hotness is included in the remark files - invalid_utf8_contains("profiles/foo.cba44757bc0621b9-cgu.0.opt.opt.yaml", "Hotness"); + let remark_files = shallow_find_files("profiles", |path| { + has_prefix(path, "foo") && has_extension(path, "yaml") + }); + assert!(!remark_files.is_empty()); + for file in remark_files { + if !file.to_str().unwrap().contains("codegen") { + invalid_utf8_contains(file, "Hotness") + }; + } } diff --git a/tests/run-make/optimization-remarks-dir/rmake.rs b/tests/run-make/optimization-remarks-dir/rmake.rs index d0c4ccd72d13a..afcb8c3e3ebdb 100644 --- a/tests/run-make/optimization-remarks-dir/rmake.rs +++ b/tests/run-make/optimization-remarks-dir/rmake.rs @@ -4,7 +4,10 @@ // (should not have the `inline` mention). // See https://github.com/rust-lang/rust/pull/113040 -use run_make_support::{invalid_utf8_contains, invalid_utf8_not_contains, rustc}; +use run_make_support::{ + has_extension, has_prefix, invalid_utf8_contains, invalid_utf8_not_contains, not_contains, + rustc, shallow_find_files, +}; fn main() { rustc() @@ -14,7 +17,12 @@ fn main() { .arg("-Cremark=all") .arg("-Zremark-dir=profiles_all") .run(); - invalid_utf8_contains("profiles_all/foo.5be5606e1f6aa79b-cgu.0.opt.opt.yaml", "inline"); + let all_remark_files = shallow_find_files("profiles_all", |path| { + has_prefix(path, "foo") && has_extension(path, "yaml") && not_contains(path, "codegen") + }); + for file in all_remark_files { + invalid_utf8_contains(file, "inline") + } rustc() .opt() .input("foo.rs") @@ -22,5 +30,10 @@ fn main() { .arg("-Cremark=foo") .arg("-Zremark-dir=profiles_foo") .run(); - invalid_utf8_not_contains("profiles_foo/foo.5be5606e1f6aa79b-cgu.0.opt.opt.yaml", "inline"); + let foo_remark_files = shallow_find_files("profiles_foo", |path| { + has_prefix(path, "foo") && has_extension(path, "yaml") + }); + for file in foo_remark_files { + invalid_utf8_not_contains(file, "inline") + } } From 5cddb156d114d77bb5f9ba3876fb2dada7ad9276 Mon Sep 17 00:00:00 2001 From: Oneirical Date: Thu, 4 Jul 2024 11:15:57 -0400 Subject: [PATCH 687/892] rewrite target-specs to rmake --- tests/run-make/target-specs/Makefile | 12 ----- tests/run-make/target-specs/rmake.rs | 71 ++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+), 12 deletions(-) delete mode 100644 tests/run-make/target-specs/Makefile create mode 100644 tests/run-make/target-specs/rmake.rs diff --git a/tests/run-make/target-specs/Makefile b/tests/run-make/target-specs/Makefile deleted file mode 100644 index 161b66021857b..0000000000000 --- a/tests/run-make/target-specs/Makefile +++ /dev/null @@ -1,12 +0,0 @@ -include ../tools.mk -all: - $(RUSTC) foo.rs --target=my-awesome-platform.json --crate-type=lib --emit=asm - $(CGREP) -v morestack < $(TMPDIR)/foo.s - $(RUSTC) foo.rs --target=my-invalid-platform.json 2>&1 | $(CGREP) "Error loading target specification" - $(RUSTC) foo.rs --target=my-incomplete-platform.json 2>&1 | $(CGREP) 'Field llvm-target' - RUST_TARGET_PATH=. $(RUSTC) foo.rs --target=my-awesome-platform --crate-type=lib --emit=asm - RUST_TARGET_PATH=. $(RUSTC) foo.rs --target=my-x86_64-unknown-linux-gnu-platform --crate-type=lib --emit=asm - $(RUSTC) -Z unstable-options --target=my-awesome-platform.json --print target-spec-json > $(TMPDIR)/test-platform.json && $(RUSTC) -Z unstable-options --target=$(TMPDIR)/test-platform.json --print target-spec-json | diff -q $(TMPDIR)/test-platform.json - - $(RUSTC) foo.rs --target=definitely-not-builtin-target 2>&1 | $(CGREP) 'may not set is_builtin' - $(RUSTC) foo.rs --target=endianness-mismatch 2>&1 | $(CGREP) '"data-layout" claims architecture is little-endian' - $(RUSTC) foo.rs --target=mismatching-data-layout --crate-type=lib 2>&1 | $(CGREP) 'data-layout for target' diff --git a/tests/run-make/target-specs/rmake.rs b/tests/run-make/target-specs/rmake.rs new file mode 100644 index 0000000000000..10c2fa298303d --- /dev/null +++ b/tests/run-make/target-specs/rmake.rs @@ -0,0 +1,71 @@ +// Target-specific compilation in rustc used to have case-by-case peculiarities in 2014, +// with the compiler having redundant target types and unspecific names. An overarching rework +// in #161156 changed the way the target flag functions, and this test attempts compilation +// with the target flag's bundle of new features to check that compilation either succeeds while +// using them correctly, or fails with the right error message when using them improperly. +// See https://github.com/rust-lang/rust/pull/16156 + +use run_make_support::{diff, fs_wrapper, rustc}; + +fn main() { + rustc().input("foo.rs").target("my-awesome-platform.json").crate_type("lib").emit("asm").run(); + assert!(!fs_wrapper::read_to_string("foo.s").contains("morestack")); + rustc() + .input("foo.rs") + .target("my-invalid-platform.json") + .run_fail() + .assert_stderr_contains("Error loading target specification"); + rustc() + .input("foo.rs") + .target("my-incomplete-platform.json") + .run_fail() + .assert_stderr_contains("Field llvm-target"); + rustc() + .env("RUST_TARGET_PATH", ".") + .input("foo.rs") + .target("my-awesome-platform") + .crate_type("lib") + .emit("asm") + .run(); + rustc() + .env("RUST_TARGET_PATH", ".") + .input("foo.rs") + .target("my-x86_64-unknown-linux-gnu-platform") + .crate_type("lib") + .emit("asm") + .run(); + let test_platform = rustc() + .arg("-Zunstable-options") + .target("my-awesome-platform.json") + .print("target-spec-json") + .run() + .stdout_utf8(); + fs_wrapper::create_file("test-platform.json"); + fs_wrapper::write("test-platform.json", test_platform.as_bytes()); + let test_platform_2 = rustc() + .arg("-Zunstable-options") + .target("test-platform.json") + .print("target-spec-json") + .run() + .stdout_utf8(); + diff() + .expected_file("test-platform.json") + .actual_text("test-platform-2", test_platform_2) + .run(); + rustc() + .input("foo.rs") + .target("definitely-not-builtin-target") + .run_fail() + .assert_stderr_contains("may not set is_builtin"); + rustc() + .input("foo.rs") + .target("endianness-mismatch") + .run_fail() + .assert_stderr_contains(r#""data-layout" claims architecture is little-endian"#); + rustc() + .input("foo.rs") + .target("mismatching-data-layout") + .crate_type("lib") + .run_fail() + .assert_stderr_contains("data-layout for target"); +} From e45d72dee0cd4bc56b9c8946678e09daf17c9cf3 Mon Sep 17 00:00:00 2001 From: Oneirical Date: Thu, 4 Jul 2024 11:28:16 -0400 Subject: [PATCH 688/892] rewrite target-cpu-native to rmake --- tests/run-make/target-cpu-native/Makefile | 20 -------------------- tests/run-make/target-cpu-native/rmake.rs | 16 ++++++++++++++++ 2 files changed, 16 insertions(+), 20 deletions(-) delete mode 100644 tests/run-make/target-cpu-native/Makefile create mode 100644 tests/run-make/target-cpu-native/rmake.rs diff --git a/tests/run-make/target-cpu-native/Makefile b/tests/run-make/target-cpu-native/Makefile deleted file mode 100644 index eb3ca1e13aa62..0000000000000 --- a/tests/run-make/target-cpu-native/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -include ../tools.mk - -# only-linux -# only-x86_64 -# -# I *really* don't want to deal with a cross-platform way to compare file sizes, -# tests in `make` sort of are awful - -all: $(TMPDIR)/out.log - # Make sure no warnings about "unknown CPU `native`" were emitted - if [ "$$(wc -c $(TMPDIR)/out.log | cut -d' ' -f 1)" = "0" ]; then \ - echo no warnings generated; \ - else \ - exit 1; \ - fi - - -$(TMPDIR)/out.log: - $(RUSTC) foo.rs -C target-cpu=native 2>&1 | tee $(TMPDIR)/out.log - $(call RUN,foo) diff --git a/tests/run-make/target-cpu-native/rmake.rs b/tests/run-make/target-cpu-native/rmake.rs new file mode 100644 index 0000000000000..c5bd0245051a9 --- /dev/null +++ b/tests/run-make/target-cpu-native/rmake.rs @@ -0,0 +1,16 @@ +// target-cpu is a codegen flag that generates code for the processor of the host machine +// running the compilation. This test is a sanity test that this flag does not cause any +// warnings when used, and that binaries produced by it can also be successfully executed. +// See https://github.com/rust-lang/rust/pull/23238 + +// FIXME(Oneirical): only-linux only-x86_64 + +use run_make_support::{run, rustc}; + +fn main() { + let out = rustc().input("foo.rs").arg("-Ctarget-cpu=native").run().stderr_utf8(); + run("foo"); + // There should be zero warnings emitted - the bug would cause "unknown CPU `native`" + // to be printed out. + assert_eq!(out.len(), 0); +} From 36b1f4411db4a35fbbeaec58f0603e4e086e851f Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Mon, 22 Jan 2024 17:21:57 +0000 Subject: [PATCH 689/892] Add a test for `*const Tr` to `*const Tr` casts --- .../cast/ptr-to-trait-obj-different-args.rs | 30 +++++++++++++++++++ .../ptr-to-trait-obj-different-args.stderr | 11 +++++++ 2 files changed, 41 insertions(+) create mode 100644 tests/ui/cast/ptr-to-trait-obj-different-args.rs create mode 100644 tests/ui/cast/ptr-to-trait-obj-different-args.stderr diff --git a/tests/ui/cast/ptr-to-trait-obj-different-args.rs b/tests/ui/cast/ptr-to-trait-obj-different-args.rs new file mode 100644 index 0000000000000..2cb661ba016e0 --- /dev/null +++ b/tests/ui/cast/ptr-to-trait-obj-different-args.rs @@ -0,0 +1,30 @@ +// check-fail +// +// issue: + + +trait A {} +impl A for T {} +trait B {} +impl B for T {} + +trait Trait {} +struct X; +impl Trait for T {} +struct Y; +impl Trait for T {} + +fn main() { + let a: *const dyn A = &(); + let b: *const dyn B = a as _; //~ error: casting `*const dyn A` as `*const dyn B` is invalid + + let x: *const dyn Trait = &(); + let y: *const dyn Trait = x as _; + + _ = (b, y); +} + +fn generic(x: *const dyn Trait, t: *const dyn Trait) { + let _: *const dyn Trait = x as _; + let _: *const dyn Trait = t as _; +} diff --git a/tests/ui/cast/ptr-to-trait-obj-different-args.stderr b/tests/ui/cast/ptr-to-trait-obj-different-args.stderr new file mode 100644 index 0000000000000..14e8a48ffd922 --- /dev/null +++ b/tests/ui/cast/ptr-to-trait-obj-different-args.stderr @@ -0,0 +1,11 @@ +error[E0606]: casting `*const dyn A` as `*const dyn B` is invalid + --> $DIR/ptr-to-trait-obj-different-args.rs:19:27 + | +LL | let b: *const dyn B = a as _; + | ^^^^^^ + | + = note: vtable kinds may not match + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0606`. From d06cf5b3997aaf9fcb3a9a8f1dc608c3cdfafde5 Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Mon, 22 Jan 2024 17:22:09 +0000 Subject: [PATCH 690/892] Forbid casts of raw pointers to trait objects with the same trait, but different args --- compiler/rustc_hir_typeck/src/cast.rs | 6 ++--- tests/ui/cast/cast-rfc0401-vtable-kinds.rs | 12 --------- .../cast/ptr-to-trait-obj-different-args.rs | 6 ++--- .../ptr-to-trait-obj-different-args.stderr | 26 ++++++++++++++++++- 4 files changed, 31 insertions(+), 19 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/cast.rs b/compiler/rustc_hir_typeck/src/cast.rs index cb1a412d17eef..3207e4ea533c5 100644 --- a/compiler/rustc_hir_typeck/src/cast.rs +++ b/compiler/rustc_hir_typeck/src/cast.rs @@ -44,7 +44,7 @@ use rustc_middle::ty::error::TypeError; use rustc_middle::ty::TyCtxt; use rustc_middle::ty::{self, Ty, TypeAndMut, TypeVisitableExt, VariantDef}; use rustc_session::lint; -use rustc_span::def_id::{DefId, LOCAL_CRATE}; +use rustc_span::def_id::LOCAL_CRATE; use rustc_span::symbol::sym; use rustc_span::Span; use rustc_span::DUMMY_SP; @@ -73,7 +73,7 @@ enum PointerKind<'tcx> { /// No metadata attached, ie pointer to sized type or foreign type Thin, /// A trait object - VTable(Option), + VTable(Option>>), /// Slice Length, /// The unsize info of this projection or opaque type @@ -101,7 +101,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { Ok(match *t.kind() { ty::Slice(_) | ty::Str => Some(PointerKind::Length), - ty::Dynamic(tty, _, ty::Dyn) => Some(PointerKind::VTable(tty.principal_def_id())), + ty::Dynamic(tty, _, ty::Dyn) => Some(PointerKind::VTable(tty.principal())), ty::Adt(def, args) if def.is_struct() => match def.non_enum_variant().tail_opt() { None => Some(PointerKind::Thin), Some(f) => { diff --git a/tests/ui/cast/cast-rfc0401-vtable-kinds.rs b/tests/ui/cast/cast-rfc0401-vtable-kinds.rs index 0d8f92f013fba..b13ea94c4c910 100644 --- a/tests/ui/cast/cast-rfc0401-vtable-kinds.rs +++ b/tests/ui/cast/cast-rfc0401-vtable-kinds.rs @@ -16,13 +16,6 @@ impl Foo for () {} impl Foo for u32 { fn foo(&self, _: u32) -> u32 { self+43 } } impl Bar for () {} -unsafe fn round_trip_and_call<'a>(t: *const (dyn Foo+'a)) -> u32 { - let foo_e : *const dyn Foo = t as *const _; - let r_1 = foo_e as *mut dyn Foo; - - (&*r_1).foo(0) -} - #[repr(C)] struct FooS(T); #[repr(C)] @@ -38,11 +31,6 @@ fn tuple_i32_to_u32(u: *const (i32, T)) -> *const (u32, T) { fn main() { - let x = 4u32; - let y : &dyn Foo = &x; - let fl = unsafe { round_trip_and_call(y as *const dyn Foo) }; - assert_eq!(fl, (43+4)); - let s = FooS([0,1,2]); let u: &FooS<[u32]> = &s; let u: *const FooS<[u32]> = u; diff --git a/tests/ui/cast/ptr-to-trait-obj-different-args.rs b/tests/ui/cast/ptr-to-trait-obj-different-args.rs index 2cb661ba016e0..e1c0c66433dd0 100644 --- a/tests/ui/cast/ptr-to-trait-obj-different-args.rs +++ b/tests/ui/cast/ptr-to-trait-obj-different-args.rs @@ -19,12 +19,12 @@ fn main() { let b: *const dyn B = a as _; //~ error: casting `*const dyn A` as `*const dyn B` is invalid let x: *const dyn Trait = &(); - let y: *const dyn Trait = x as _; + let y: *const dyn Trait = x as _; //~ error: casting `*const dyn Trait` as `*const dyn Trait` is invalid _ = (b, y); } fn generic(x: *const dyn Trait, t: *const dyn Trait) { - let _: *const dyn Trait = x as _; - let _: *const dyn Trait = t as _; + let _: *const dyn Trait = x as _; //~ error: casting `*const (dyn Trait + 'static)` as `*const dyn Trait` is invalid + let _: *const dyn Trait = t as _; //~ error: casting `*const (dyn Trait + 'static)` as `*const dyn Trait` is invalid } diff --git a/tests/ui/cast/ptr-to-trait-obj-different-args.stderr b/tests/ui/cast/ptr-to-trait-obj-different-args.stderr index 14e8a48ffd922..cd67b52ad27dd 100644 --- a/tests/ui/cast/ptr-to-trait-obj-different-args.stderr +++ b/tests/ui/cast/ptr-to-trait-obj-different-args.stderr @@ -6,6 +6,30 @@ LL | let b: *const dyn B = a as _; | = note: vtable kinds may not match -error: aborting due to 1 previous error +error[E0606]: casting `*const dyn Trait` as `*const dyn Trait` is invalid + --> $DIR/ptr-to-trait-obj-different-args.rs:22:34 + | +LL | let y: *const dyn Trait = x as _; + | ^^^^^^ + | + = note: vtable kinds may not match + +error[E0606]: casting `*const (dyn Trait + 'static)` as `*const dyn Trait` is invalid + --> $DIR/ptr-to-trait-obj-different-args.rs:28:34 + | +LL | let _: *const dyn Trait = x as _; + | ^^^^^^ + | + = note: vtable kinds may not match + +error[E0606]: casting `*const (dyn Trait + 'static)` as `*const dyn Trait` is invalid + --> $DIR/ptr-to-trait-obj-different-args.rs:29:34 + | +LL | let _: *const dyn Trait = t as _; + | ^^^^^^ + | + = note: vtable kinds may not match + +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0606`. From 9e8ef92da0fbca5935380e79a22142d9951ed050 Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Mon, 22 Jan 2024 19:08:19 +0000 Subject: [PATCH 691/892] Add tests for `*const Trait<'a>` -> `*const Trait<'b>` and similar casts --- tests/ui/cast/ptr-to-trait-obj-add-auto.rs | 9 +++++ .../cast/ptr-to-trait-obj-different-args.rs | 8 +++++ ...r-to-trait-obj-different-regions-lt-ext.rs | 31 +++++++++++++++++ ...ptr-to-trait-obj-different-regions-misc.rs | 34 +++++++++++++++++++ tests/ui/cast/ptr-to-trait-obj-ok.rs | 17 ++++++++++ 5 files changed, 99 insertions(+) create mode 100644 tests/ui/cast/ptr-to-trait-obj-add-auto.rs create mode 100644 tests/ui/cast/ptr-to-trait-obj-different-regions-lt-ext.rs create mode 100644 tests/ui/cast/ptr-to-trait-obj-different-regions-misc.rs create mode 100644 tests/ui/cast/ptr-to-trait-obj-ok.rs diff --git a/tests/ui/cast/ptr-to-trait-obj-add-auto.rs b/tests/ui/cast/ptr-to-trait-obj-add-auto.rs new file mode 100644 index 0000000000000..b719cfed600e3 --- /dev/null +++ b/tests/ui/cast/ptr-to-trait-obj-add-auto.rs @@ -0,0 +1,9 @@ +// check-pass + +trait Trait<'a> {} + +fn add_auto<'a>(x: *mut dyn Trait<'a>) -> *mut (dyn Trait<'a> + Send) { + x as _ +} + +fn main() {} diff --git a/tests/ui/cast/ptr-to-trait-obj-different-args.rs b/tests/ui/cast/ptr-to-trait-obj-different-args.rs index e1c0c66433dd0..c1418a9308825 100644 --- a/tests/ui/cast/ptr-to-trait-obj-different-args.rs +++ b/tests/ui/cast/ptr-to-trait-obj-different-args.rs @@ -28,3 +28,11 @@ fn generic(x: *const dyn Trait, t: *const dyn Trait) { let _: *const dyn Trait = x as _; //~ error: casting `*const (dyn Trait + 'static)` as `*const dyn Trait` is invalid let _: *const dyn Trait = t as _; //~ error: casting `*const (dyn Trait + 'static)` as `*const dyn Trait` is invalid } + +trait Assocked { + type Assoc: ?Sized; +} + +fn change_assoc(x: *mut dyn Assocked) -> *mut dyn Assocked { + x as _ +} \ No newline at end of file diff --git a/tests/ui/cast/ptr-to-trait-obj-different-regions-lt-ext.rs b/tests/ui/cast/ptr-to-trait-obj-different-regions-lt-ext.rs new file mode 100644 index 0000000000000..bafa5c95840b4 --- /dev/null +++ b/tests/ui/cast/ptr-to-trait-obj-different-regions-lt-ext.rs @@ -0,0 +1,31 @@ +// check-pass +// +// issue: + +#![feature(arbitrary_self_types)] + +trait Static<'a> { + fn proof(self: *const Self, s: &'a str) -> &'static str; +} + +fn bad_cast<'a>(x: *const dyn Static<'static>) -> *const dyn Static<'a> { + x as _ +} + +impl Static<'static> for () { + fn proof(self: *const Self, s: &'static str) -> &'static str { + s + } +} + +fn extend_lifetime(s: &str) -> &'static str { + bad_cast(&()).proof(s) +} + +fn main() { + let s = String::from("Hello World"); + let slice = extend_lifetime(&s); + println!("Now it exists: {slice}"); + drop(s); + println!("Now it’s gone: {slice}"); +} diff --git a/tests/ui/cast/ptr-to-trait-obj-different-regions-misc.rs b/tests/ui/cast/ptr-to-trait-obj-different-regions-misc.rs new file mode 100644 index 0000000000000..136673b6053c0 --- /dev/null +++ b/tests/ui/cast/ptr-to-trait-obj-different-regions-misc.rs @@ -0,0 +1,34 @@ +// check-pass + +trait Trait<'a> {} + +fn change_lt<'a, 'b>(x: *mut dyn Trait<'a>) -> *mut dyn Trait<'b> { + x as _ +} + +fn change_lt_ab<'a: 'b, 'b>(x: *mut dyn Trait<'a>) -> *mut dyn Trait<'b> { + x as _ +} + +fn change_lt_ba<'a, 'b: 'a>(x: *mut dyn Trait<'a>) -> *mut dyn Trait<'b> { + x as _ +} + +trait Assocked { + type Assoc: ?Sized; +} + +fn change_assoc_0<'a, 'b>( + x: *mut dyn Assocked, +) -> *mut dyn Assocked { + x as _ +} + +fn change_assoc_1<'a, 'b>( + x: *mut dyn Assocked>, +) -> *mut dyn Assocked> { + x as _ +} + + +fn main() {} diff --git a/tests/ui/cast/ptr-to-trait-obj-ok.rs b/tests/ui/cast/ptr-to-trait-obj-ok.rs new file mode 100644 index 0000000000000..84d11bcb8eba3 --- /dev/null +++ b/tests/ui/cast/ptr-to-trait-obj-ok.rs @@ -0,0 +1,17 @@ +// check-pass + +trait Trait<'a> {} + +fn remove_auto<'a>(x: *mut (dyn Trait<'a> + Send)) -> *mut dyn Trait<'a> { + x as _ +} + +fn cast_inherent_lt<'a, 'b>(x: *mut (dyn Trait<'static> + 'a)) -> *mut (dyn Trait<'static> + 'b) { + x as _ +} + +fn unprincipled<'a, 'b>(x: *mut (dyn Send + 'a)) -> *mut (dyn Sync + 'b) { + x as _ +} + +fn main() {} From 5645e8e28578e4b907383323fadde172375409f1 Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Mon, 12 Feb 2024 21:24:48 +0000 Subject: [PATCH 692/892] Add more checks for pointers with vtable meta The rules for casting `*mut X` -> `*mut Y` are as follows: - If `B` has a principal - `A` must have exactly the same principal (including generics) - Auto traits of `B` must be a subset of autotraits in `A` Note that `X<_>` and `Y<_>` can be identity, or arbitrary structs with last field being the dyn type. The lifetime of the trait object itself (`dyn ... + 'a`) is not checked. This prevents a few soundness issues with `#![feature(arbitrary_self_types)]` and trait upcasting. Namely, these checks make sure that vtable is always valid for the pointee. --- compiler/rustc_borrowck/src/type_check/mod.rs | 48 ++++++- compiler/rustc_hir_typeck/src/cast.rs | 102 +++++++++---- library/alloc/src/boxed.rs | 6 +- tests/ui/cast/ptr-to-trait-obj-add-auto.rs | 4 +- .../ui/cast/ptr-to-trait-obj-add-auto.stderr | 11 ++ .../cast/ptr-to-trait-obj-different-args.rs | 10 +- .../ptr-to-trait-obj-different-args.stderr | 44 ++++-- ...r-to-trait-obj-different-regions-lt-ext.rs | 4 +- ...-trait-obj-different-regions-lt-ext.stderr | 10 ++ ...ptr-to-trait-obj-different-regions-misc.rs | 15 +- ...to-trait-obj-different-regions-misc.stderr | 136 ++++++++++++++++++ tests/ui/mismatched_types/cast-rfc0401.rs | 2 +- tests/ui/mismatched_types/cast-rfc0401.stderr | 6 +- 13 files changed, 331 insertions(+), 67 deletions(-) create mode 100644 tests/ui/cast/ptr-to-trait-obj-add-auto.stderr create mode 100644 tests/ui/cast/ptr-to-trait-obj-different-regions-lt-ext.stderr create mode 100644 tests/ui/cast/ptr-to-trait-obj-different-regions-misc.stderr diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index aa25e3adf28af..2600c1fbff7bf 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -2319,7 +2319,41 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { let cast_ty_from = CastTy::from_ty(ty_from); let cast_ty_to = CastTy::from_ty(*ty); match (cast_ty_from, cast_ty_to) { - (Some(CastTy::Ptr(_)), Some(CastTy::Ptr(_))) => (), + (Some(CastTy::Ptr(src)), Some(CastTy::Ptr(dst))) => { + let src_tail = tcx.struct_tail_without_normalization(src.ty); + let dst_tail = tcx.struct_tail_without_normalization(dst.ty); + + if let ty::Dynamic(..) = src_tail.kind() + && let ty::Dynamic(dst_tty, ..) = dst_tail.kind() + && dst_tty.principal().is_some() + { + // Erase trait object lifetimes, to allow casts like `*mut dyn FnOnce()` -> `*mut dyn FnOnce() + 'static`. + let src_tail = + erase_single_trait_object_lifetime(tcx, src_tail); + let dst_tail = + erase_single_trait_object_lifetime(tcx, dst_tail); + + let trait_ref = ty::TraitRef::new( + tcx, + tcx.require_lang_item(LangItem::Unsize, Some(span)), + [src_tail, dst_tail], + ); + + self.prove_trait_ref( + trait_ref, + location.to_locations(), + ConstraintCategory::Cast { + unsize_to: Some(tcx.fold_regions(dst_tail, |r, _| { + if let ty::ReVar(_) = r.kind() { + tcx.lifetimes.re_erased + } else { + r + } + })), + }, + ); + } + } _ => { span_mirbug!( self, @@ -2842,3 +2876,15 @@ impl<'tcx> TypeOp<'tcx> for InstantiateOpaqueType<'tcx> { Ok(output) } } + +fn erase_single_trait_object_lifetime<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> { + let &ty::Dynamic(tty, region, dyn_kind @ ty::Dyn) = ty.kind() else { + bug!("expected trait object") + }; + + if region.is_erased() { + return ty; + } + + tcx.mk_ty_from_kind(ty::Dynamic(tty, tcx.lifetimes.re_erased, dyn_kind)) +} diff --git a/compiler/rustc_hir_typeck/src/cast.rs b/compiler/rustc_hir_typeck/src/cast.rs index 3207e4ea533c5..74be8529ec8f0 100644 --- a/compiler/rustc_hir_typeck/src/cast.rs +++ b/compiler/rustc_hir_typeck/src/cast.rs @@ -32,9 +32,9 @@ use super::FnCtxt; use crate::errors; use crate::type_error_struct; -use hir::ExprKind; use rustc_errors::{codes::*, Applicability, Diag, ErrorGuaranteed}; -use rustc_hir as hir; +use rustc_hir::{self as hir, ExprKind, LangItem}; +use rustc_infer::traits::Obligation; use rustc_macros::{TypeFoldable, TypeVisitable}; use rustc_middle::bug; use rustc_middle::mir::Mutability; @@ -73,7 +73,7 @@ enum PointerKind<'tcx> { /// No metadata attached, ie pointer to sized type or foreign type Thin, /// A trait object - VTable(Option>>), + VTable(&'tcx ty::List>>), /// Slice Length, /// The unsize info of this projection or opaque type @@ -101,7 +101,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { Ok(match *t.kind() { ty::Slice(_) | ty::Str => Some(PointerKind::Length), - ty::Dynamic(tty, _, ty::Dyn) => Some(PointerKind::VTable(tty.principal())), + ty::Dynamic(tty, _, ty::Dyn) => Some(PointerKind::VTable(tty)), ty::Adt(def, args) if def.is_struct() => match def.non_enum_variant().tail_opt() { None => Some(PointerKind::Thin), Some(f) => { @@ -759,7 +759,7 @@ impl<'a, 'tcx> CastCheck<'tcx> { Err(CastError::IllegalCast) } - // ptr -> * + // ptr -> ptr (Ptr(m_e), Ptr(m_c)) => self.check_ptr_ptr_cast(fcx, m_e, m_c), // ptr-ptr-cast // ptr-addr-cast @@ -803,40 +803,82 @@ impl<'a, 'tcx> CastCheck<'tcx> { fn check_ptr_ptr_cast( &self, fcx: &FnCtxt<'a, 'tcx>, - m_expr: ty::TypeAndMut<'tcx>, - m_cast: ty::TypeAndMut<'tcx>, + m_src: ty::TypeAndMut<'tcx>, + m_dst: ty::TypeAndMut<'tcx>, ) -> Result { - debug!("check_ptr_ptr_cast m_expr={:?} m_cast={:?}", m_expr, m_cast); + debug!("check_ptr_ptr_cast m_expr={:?} m_cast={:?}", m_src, m_dst); // ptr-ptr cast. vtables must match. - let expr_kind = fcx.pointer_kind(m_expr.ty, self.span)?; - let cast_kind = fcx.pointer_kind(m_cast.ty, self.span)?; + let src_kind = fcx.tcx.erase_regions(fcx.pointer_kind(m_src.ty, self.span)?); + let dst_kind = fcx.tcx.erase_regions(fcx.pointer_kind(m_dst.ty, self.span)?); - let Some(cast_kind) = cast_kind else { + match (src_kind, dst_kind) { // We can't cast if target pointer kind is unknown - return Err(CastError::UnknownCastPtrKind); - }; - - // Cast to thin pointer is OK - if cast_kind == PointerKind::Thin { - return Ok(CastKind::PtrPtrCast); - } + (_, None) => Err(CastError::UnknownCastPtrKind), + // Cast to thin pointer is OK + (_, Some(PointerKind::Thin)) => Ok(CastKind::PtrPtrCast), - let Some(expr_kind) = expr_kind else { // We can't cast to fat pointer if source pointer kind is unknown - return Err(CastError::UnknownExprPtrKind); - }; + (None, _) => Err(CastError::UnknownExprPtrKind), + + // thin -> fat? report invalid cast (don't complain about vtable kinds) + (Some(PointerKind::Thin), _) => Err(CastError::SizedUnsizedCast), + + // trait object -> trait object? need to do additional checks + (Some(PointerKind::VTable(src_tty)), Some(PointerKind::VTable(dst_tty))) => { + match (src_tty.principal(), dst_tty.principal()) { + // A -> B. need to make sure + // - traits are the same & have the same generic arguments + // - Auto' is a subset of Auto + // + // This is checked by checking `dyn Trait + Auto + 'erased: Unsize`. + (Some(_), Some(_)) => { + let tcx = fcx.tcx; + + // We need to reconstruct trait object types. + // `m_src` and `m_dst` won't work for us here because they will potentially + // contain wrappers, which we do not care about. + // + // e.g. we want to allow `dyn T -> (dyn T,)`, etc. + let src_obj = tcx.mk_ty_from_kind(ty::Dynamic(src_tty, tcx.lifetimes.re_erased, ty::Dyn)); + let dst_obj = tcx.mk_ty_from_kind(ty::Dynamic(dst_tty, tcx.lifetimes.re_erased, ty::Dyn)); + + // `dyn Src: Unsize` + let cause = fcx.misc(self.span); + let obligation = Obligation::new( + tcx, + cause, + fcx.param_env, + ty::TraitRef::new( + tcx, + tcx.require_lang_item(LangItem::Unsize, Some(self.span)), + [src_obj, dst_obj], + ) + ); - // thin -> fat? report invalid cast (don't complain about vtable kinds) - if expr_kind == PointerKind::Thin { - return Err(CastError::SizedUnsizedCast); - } + fcx.register_predicate(obligation); - // vtable kinds must match - if fcx.tcx.erase_regions(cast_kind) == fcx.tcx.erase_regions(expr_kind) { - Ok(CastKind::PtrPtrCast) - } else { - Err(CastError::DifferingKinds) + // FIXME: ideally we'd maybe add a flag here, so that borrowck knows that + // it needs to borrowck this ptr cast. this is made annoying by the + // fact that `thir` does not have `CastKind` and mir restores it + // from types. + Ok(CastKind::PtrPtrCast) + } + + // dyn Auto -> dyn Auto'? ok. + (None, None) + // dyn Trait -> dyn Auto? ok. + | (Some(_), None)=> Ok(CastKind::PtrPtrCast), + + // dyn Auto -> dyn Trait? not ok. + (None, Some(_)) => Err(CastError::DifferingKinds), + } + } + + // fat -> fat? metadata kinds must match + (Some(src_kind), Some(dst_kind)) if src_kind == dst_kind => Ok(CastKind::PtrPtrCast), + + (_, _) => Err(CastError::DifferingKinds), } } diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs index 1ec095a46f704..65bcb241e4aec 100644 --- a/library/alloc/src/boxed.rs +++ b/library/alloc/src/boxed.rs @@ -2374,7 +2374,7 @@ impl dyn Error + Send { let err: Box = self; ::downcast(err).map_err(|s| unsafe { // Reapply the `Send` marker. - Box::from_raw(Box::into_raw(s) as *mut (dyn Error + Send)) + mem::transmute::, Box>(s) }) } } @@ -2387,8 +2387,8 @@ impl dyn Error + Send + Sync { pub fn downcast(self: Box) -> Result, Box> { let err: Box = self; ::downcast(err).map_err(|s| unsafe { - // Reapply the `Send + Sync` marker. - Box::from_raw(Box::into_raw(s) as *mut (dyn Error + Send + Sync)) + // Reapply the `Send + Sync` markers. + mem::transmute::, Box>(s) }) } } diff --git a/tests/ui/cast/ptr-to-trait-obj-add-auto.rs b/tests/ui/cast/ptr-to-trait-obj-add-auto.rs index b719cfed600e3..4758132b65d84 100644 --- a/tests/ui/cast/ptr-to-trait-obj-add-auto.rs +++ b/tests/ui/cast/ptr-to-trait-obj-add-auto.rs @@ -1,9 +1,9 @@ -// check-pass +// check-fail trait Trait<'a> {} fn add_auto<'a>(x: *mut dyn Trait<'a>) -> *mut (dyn Trait<'a> + Send) { - x as _ + x as _ //~ error: the trait bound `dyn Trait<'_>: Unsize + Send>` is not satisfied } fn main() {} diff --git a/tests/ui/cast/ptr-to-trait-obj-add-auto.stderr b/tests/ui/cast/ptr-to-trait-obj-add-auto.stderr new file mode 100644 index 0000000000000..0c35db57b307d --- /dev/null +++ b/tests/ui/cast/ptr-to-trait-obj-add-auto.stderr @@ -0,0 +1,11 @@ +error[E0277]: the trait bound `dyn Trait<'_>: Unsize + Send>` is not satisfied + --> $DIR/ptr-to-trait-obj-add-auto.rs:6:5 + | +LL | x as _ + | ^^^^^^ the trait `Unsize + Send>` is not implemented for `dyn Trait<'_>` + | + = note: all implementations of `Unsize` are provided automatically by the compiler, see for more information + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/cast/ptr-to-trait-obj-different-args.rs b/tests/ui/cast/ptr-to-trait-obj-different-args.rs index c1418a9308825..1859dd8dac0b2 100644 --- a/tests/ui/cast/ptr-to-trait-obj-different-args.rs +++ b/tests/ui/cast/ptr-to-trait-obj-different-args.rs @@ -16,17 +16,17 @@ impl Trait for T {} fn main() { let a: *const dyn A = &(); - let b: *const dyn B = a as _; //~ error: casting `*const dyn A` as `*const dyn B` is invalid + let b: *const dyn B = a as _; //~ error: the trait bound `dyn A: Unsize` is not satisfied let x: *const dyn Trait = &(); - let y: *const dyn Trait = x as _; //~ error: casting `*const dyn Trait` as `*const dyn Trait` is invalid + let y: *const dyn Trait = x as _; //~ error: the trait bound `dyn Trait: Unsize>` is not satisfied _ = (b, y); } fn generic(x: *const dyn Trait, t: *const dyn Trait) { - let _: *const dyn Trait = x as _; //~ error: casting `*const (dyn Trait + 'static)` as `*const dyn Trait` is invalid - let _: *const dyn Trait = t as _; //~ error: casting `*const (dyn Trait + 'static)` as `*const dyn Trait` is invalid + let _: *const dyn Trait = x as _; //~ error: the trait bound `dyn Trait: Unsize>` is not satisfied + let _: *const dyn Trait = t as _; //~ error: the trait bound `dyn Trait: Unsize>` is not satisfied } trait Assocked { @@ -34,5 +34,5 @@ trait Assocked { } fn change_assoc(x: *mut dyn Assocked) -> *mut dyn Assocked { - x as _ + x as _ //~ error: the trait bound `dyn Assocked: Unsize>` is not satisfied } \ No newline at end of file diff --git a/tests/ui/cast/ptr-to-trait-obj-different-args.stderr b/tests/ui/cast/ptr-to-trait-obj-different-args.stderr index cd67b52ad27dd..e2cd9c8fa9070 100644 --- a/tests/ui/cast/ptr-to-trait-obj-different-args.stderr +++ b/tests/ui/cast/ptr-to-trait-obj-different-args.stderr @@ -1,35 +1,51 @@ -error[E0606]: casting `*const dyn A` as `*const dyn B` is invalid +error[E0277]: the trait bound `dyn A: Unsize` is not satisfied --> $DIR/ptr-to-trait-obj-different-args.rs:19:27 | LL | let b: *const dyn B = a as _; - | ^^^^^^ + | ^^^^^^ the trait `Unsize` is not implemented for `dyn A` | - = note: vtable kinds may not match + = note: all implementations of `Unsize` are provided automatically by the compiler, see for more information -error[E0606]: casting `*const dyn Trait` as `*const dyn Trait` is invalid +error[E0277]: the trait bound `dyn Trait: Unsize>` is not satisfied --> $DIR/ptr-to-trait-obj-different-args.rs:22:34 | LL | let y: *const dyn Trait = x as _; - | ^^^^^^ + | ^^^^^^ the trait `Unsize>` is not implemented for `dyn Trait` | - = note: vtable kinds may not match + = note: all implementations of `Unsize` are provided automatically by the compiler, see for more information -error[E0606]: casting `*const (dyn Trait + 'static)` as `*const dyn Trait` is invalid +error[E0277]: the trait bound `dyn Trait: Unsize>` is not satisfied --> $DIR/ptr-to-trait-obj-different-args.rs:28:34 | LL | let _: *const dyn Trait = x as _; - | ^^^^^^ + | ^^^^^^ the trait `Unsize>` is not implemented for `dyn Trait` | - = note: vtable kinds may not match + = note: all implementations of `Unsize` are provided automatically by the compiler, see for more information +help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement + | +LL | fn generic(x: *const dyn Trait, t: *const dyn Trait) where dyn Trait: Unsize> { + | ++++++++++++++++++++++++++++++++++++++++ -error[E0606]: casting `*const (dyn Trait + 'static)` as `*const dyn Trait` is invalid +error[E0277]: the trait bound `dyn Trait: Unsize>` is not satisfied --> $DIR/ptr-to-trait-obj-different-args.rs:29:34 | LL | let _: *const dyn Trait = t as _; - | ^^^^^^ + | ^^^^^^ the trait `Unsize>` is not implemented for `dyn Trait` + | + = note: all implementations of `Unsize` are provided automatically by the compiler, see for more information +help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement + | +LL | fn generic(x: *const dyn Trait, t: *const dyn Trait) where dyn Trait: Unsize> { + | ++++++++++++++++++++++++++++++++++++++++ + +error[E0277]: the trait bound `dyn Assocked: Unsize>` is not satisfied + --> $DIR/ptr-to-trait-obj-different-args.rs:37:5 + | +LL | x as _ + | ^^^^^^ the trait `Unsize>` is not implemented for `dyn Assocked` | - = note: vtable kinds may not match + = note: all implementations of `Unsize` are provided automatically by the compiler, see for more information -error: aborting due to 4 previous errors +error: aborting due to 5 previous errors -For more information about this error, try `rustc --explain E0606`. +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/cast/ptr-to-trait-obj-different-regions-lt-ext.rs b/tests/ui/cast/ptr-to-trait-obj-different-regions-lt-ext.rs index bafa5c95840b4..d994723981fb6 100644 --- a/tests/ui/cast/ptr-to-trait-obj-different-regions-lt-ext.rs +++ b/tests/ui/cast/ptr-to-trait-obj-different-regions-lt-ext.rs @@ -1,4 +1,4 @@ -// check-pass +// check-fail // // issue: @@ -9,7 +9,7 @@ trait Static<'a> { } fn bad_cast<'a>(x: *const dyn Static<'static>) -> *const dyn Static<'a> { - x as _ + x as _ //~ error: lifetime may not live long enough } impl Static<'static> for () { diff --git a/tests/ui/cast/ptr-to-trait-obj-different-regions-lt-ext.stderr b/tests/ui/cast/ptr-to-trait-obj-different-regions-lt-ext.stderr new file mode 100644 index 0000000000000..b7319e3356bd0 --- /dev/null +++ b/tests/ui/cast/ptr-to-trait-obj-different-regions-lt-ext.stderr @@ -0,0 +1,10 @@ +error: lifetime may not live long enough + --> $DIR/ptr-to-trait-obj-different-regions-lt-ext.rs:12:5 + | +LL | fn bad_cast<'a>(x: *const dyn Static<'static>) -> *const dyn Static<'a> { + | -- lifetime `'a` defined here +LL | x as _ + | ^^^^^^ returning this value requires that `'a` must outlive `'static` + +error: aborting due to 1 previous error + diff --git a/tests/ui/cast/ptr-to-trait-obj-different-regions-misc.rs b/tests/ui/cast/ptr-to-trait-obj-different-regions-misc.rs index 136673b6053c0..ea17fcd0da56c 100644 --- a/tests/ui/cast/ptr-to-trait-obj-different-regions-misc.rs +++ b/tests/ui/cast/ptr-to-trait-obj-different-regions-misc.rs @@ -1,17 +1,18 @@ -// check-pass +// check-fail trait Trait<'a> {} fn change_lt<'a, 'b>(x: *mut dyn Trait<'a>) -> *mut dyn Trait<'b> { - x as _ + x as _ //~ error: lifetime may not live long enough + //~| error: lifetime may not live long enough } fn change_lt_ab<'a: 'b, 'b>(x: *mut dyn Trait<'a>) -> *mut dyn Trait<'b> { - x as _ + x as _ //~ error: lifetime may not live long enough } fn change_lt_ba<'a, 'b: 'a>(x: *mut dyn Trait<'a>) -> *mut dyn Trait<'b> { - x as _ + x as _ //~ error: lifetime may not live long enough } trait Assocked { @@ -21,13 +22,15 @@ trait Assocked { fn change_assoc_0<'a, 'b>( x: *mut dyn Assocked, ) -> *mut dyn Assocked { - x as _ + x as _ //~ error: lifetime may not live long enough + //~| error: lifetime may not live long enough } fn change_assoc_1<'a, 'b>( x: *mut dyn Assocked>, ) -> *mut dyn Assocked> { - x as _ + x as _ //~ error: lifetime may not live long enough + //~| error: lifetime may not live long enough } diff --git a/tests/ui/cast/ptr-to-trait-obj-different-regions-misc.stderr b/tests/ui/cast/ptr-to-trait-obj-different-regions-misc.stderr new file mode 100644 index 0000000000000..7044e4dec1fe5 --- /dev/null +++ b/tests/ui/cast/ptr-to-trait-obj-different-regions-misc.stderr @@ -0,0 +1,136 @@ +error: lifetime may not live long enough + --> $DIR/ptr-to-trait-obj-different-regions-misc.rs:6:5 + | +LL | fn change_lt<'a, 'b>(x: *mut dyn Trait<'a>) -> *mut dyn Trait<'b> { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +LL | x as _ + | ^^^^^^ 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` + = note: requirement occurs because of a mutable pointer to `dyn Trait<'_>` + = note: mutable pointers are invariant over their type parameter + = help: see for more information about variance + +error: lifetime may not live long enough + --> $DIR/ptr-to-trait-obj-different-regions-misc.rs:6:5 + | +LL | fn change_lt<'a, 'b>(x: *mut dyn Trait<'a>) -> *mut dyn Trait<'b> { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +LL | x as _ + | ^^^^^^ 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` + = note: requirement occurs because of a mutable pointer to `dyn Trait<'_>` + = note: mutable pointers are invariant over their type parameter + = help: see for more information about variance + +help: `'b` and `'a` must be the same: replace one with the other + +error: lifetime may not live long enough + --> $DIR/ptr-to-trait-obj-different-regions-misc.rs:11:5 + | +LL | fn change_lt_ab<'a: 'b, 'b>(x: *mut dyn Trait<'a>) -> *mut dyn Trait<'b> { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +LL | x as _ + | ^^^^^^ 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` + = note: requirement occurs because of a mutable pointer to `dyn Trait<'_>` + = note: mutable pointers are invariant over their type parameter + = help: see for more information about variance + +error: lifetime may not live long enough + --> $DIR/ptr-to-trait-obj-different-regions-misc.rs:15:5 + | +LL | fn change_lt_ba<'a, 'b: 'a>(x: *mut dyn Trait<'a>) -> *mut dyn Trait<'b> { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +LL | x as _ + | ^^^^^^ 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` + = note: requirement occurs because of a mutable pointer to `dyn Trait<'_>` + = note: mutable pointers are invariant over their type parameter + = help: see for more information about variance + +error: lifetime may not live long enough + --> $DIR/ptr-to-trait-obj-different-regions-misc.rs:25:5 + | +LL | fn change_assoc_0<'a, 'b>( + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +... +LL | x as _ + | ^^^^^^ 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` + = note: requirement occurs because of a mutable pointer to `dyn Assocked` + = note: mutable pointers are invariant over their type parameter + = help: see for more information about variance + +error: lifetime may not live long enough + --> $DIR/ptr-to-trait-obj-different-regions-misc.rs:25:5 + | +LL | fn change_assoc_0<'a, 'b>( + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +... +LL | x as _ + | ^^^^^^ 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` + = note: requirement occurs because of a mutable pointer to `dyn Assocked` + = note: mutable pointers are invariant over their type parameter + = help: see for more information about variance + +help: `'b` and `'a` must be the same: replace one with the other + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: lifetime may not live long enough + --> $DIR/ptr-to-trait-obj-different-regions-misc.rs:32:5 + | +LL | fn change_assoc_1<'a, 'b>( + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +... +LL | x as _ + | ^^^^^^ 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` + = note: requirement occurs because of a mutable pointer to `dyn Assocked>` + = note: mutable pointers are invariant over their type parameter + = help: see for more information about variance + +error: lifetime may not live long enough + --> $DIR/ptr-to-trait-obj-different-regions-misc.rs:32:5 + | +LL | fn change_assoc_1<'a, 'b>( + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +... +LL | x as _ + | ^^^^^^ 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` + = note: requirement occurs because of a mutable pointer to `dyn Assocked>` + = note: mutable pointers are invariant over their type parameter + = help: see for more information about variance + +help: `'b` and `'a` must be the same: replace one with the other + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: aborting due to 8 previous errors + diff --git a/tests/ui/mismatched_types/cast-rfc0401.rs b/tests/ui/mismatched_types/cast-rfc0401.rs index 57222f45947b4..05e39f86cdfc5 100644 --- a/tests/ui/mismatched_types/cast-rfc0401.rs +++ b/tests/ui/mismatched_types/cast-rfc0401.rs @@ -66,7 +66,7 @@ fn main() let cf: *const dyn Foo = &0; let _ = cf as *const [u16]; //~ ERROR is invalid - let _ = cf as *const dyn Bar; //~ ERROR is invalid + let _ = cf as *const dyn Bar; //~ ERROR the trait bound `dyn Foo: Unsize` is not satisfied vec![0.0].iter().map(|s| s as f32).collect::>(); //~ ERROR is invalid } diff --git a/tests/ui/mismatched_types/cast-rfc0401.stderr b/tests/ui/mismatched_types/cast-rfc0401.stderr index 142a52aef13d0..9f4a7aa858edf 100644 --- a/tests/ui/mismatched_types/cast-rfc0401.stderr +++ b/tests/ui/mismatched_types/cast-rfc0401.stderr @@ -210,13 +210,13 @@ LL | let _ = cf as *const [u16]; | = note: vtable kinds may not match -error[E0606]: casting `*const dyn Foo` as `*const dyn Bar` is invalid +error[E0277]: the trait bound `dyn Foo: Unsize` is not satisfied --> $DIR/cast-rfc0401.rs:69:13 | LL | let _ = cf as *const dyn Bar; - | ^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^ the trait `Unsize` is not implemented for `dyn Foo` | - = note: vtable kinds may not match + = note: all implementations of `Unsize` are provided automatically by the compiler, see for more information error[E0277]: the size for values of type `[u8]` cannot be known at compilation time --> $DIR/cast-rfc0401.rs:53:13 From bb651d358d63e5fac626e200c32147b43a330ea0 Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Tue, 13 Feb 2024 00:17:19 +0000 Subject: [PATCH 693/892] blessings --- tests/ui/cast/cast-rfc0401-vtable-kinds.rs | 6 ------ tests/ui/cast/cast-rfc0401-vtable-kinds.stderr | 2 +- tests/ui/cast/ptr-to-trait-obj-different-args.rs | 2 +- .../issue-114797-bad-parentheses-dyn-trait.fixed | 4 ++-- .../issue-114797-bad-parentheses-dyn-trait.rs | 4 ++-- .../issue-114797-bad-parentheses-dyn-trait.stderr | 10 +++++----- tests/ui/traits/upcast_soundness_bug.rs | 8 +++++--- tests/ui/traits/upcast_soundness_bug.stderr | 11 +++++++++++ 8 files changed, 27 insertions(+), 20 deletions(-) create mode 100644 tests/ui/traits/upcast_soundness_bug.stderr diff --git a/tests/ui/cast/cast-rfc0401-vtable-kinds.rs b/tests/ui/cast/cast-rfc0401-vtable-kinds.rs index b13ea94c4c910..5704a33cc870b 100644 --- a/tests/ui/cast/cast-rfc0401-vtable-kinds.rs +++ b/tests/ui/cast/cast-rfc0401-vtable-kinds.rs @@ -4,16 +4,10 @@ #![feature(unsized_tuple_coercion)] -trait Foo { - fn foo(&self, _: T) -> u32 { 42 } -} - trait Bar { //~ WARN trait `Bar` is never used fn bar(&self) { println!("Bar!"); } } -impl Foo for () {} -impl Foo for u32 { fn foo(&self, _: u32) -> u32 { self+43 } } impl Bar for () {} #[repr(C)] diff --git a/tests/ui/cast/cast-rfc0401-vtable-kinds.stderr b/tests/ui/cast/cast-rfc0401-vtable-kinds.stderr index 952687e98d0ef..4f57e2e7df75e 100644 --- a/tests/ui/cast/cast-rfc0401-vtable-kinds.stderr +++ b/tests/ui/cast/cast-rfc0401-vtable-kinds.stderr @@ -1,5 +1,5 @@ warning: trait `Bar` is never used - --> $DIR/cast-rfc0401-vtable-kinds.rs:11:7 + --> $DIR/cast-rfc0401-vtable-kinds.rs:7:7 | LL | trait Bar { | ^^^ diff --git a/tests/ui/cast/ptr-to-trait-obj-different-args.rs b/tests/ui/cast/ptr-to-trait-obj-different-args.rs index 1859dd8dac0b2..7488cf5ee9746 100644 --- a/tests/ui/cast/ptr-to-trait-obj-different-args.rs +++ b/tests/ui/cast/ptr-to-trait-obj-different-args.rs @@ -35,4 +35,4 @@ trait Assocked { fn change_assoc(x: *mut dyn Assocked) -> *mut dyn Assocked { x as _ //~ error: the trait bound `dyn Assocked: Unsize>` is not satisfied -} \ No newline at end of file +} diff --git a/tests/ui/suggestions/issue-114797-bad-parentheses-dyn-trait.fixed b/tests/ui/suggestions/issue-114797-bad-parentheses-dyn-trait.fixed index e072c476c6bc7..4e562193f0d89 100644 --- a/tests/ui/suggestions/issue-114797-bad-parentheses-dyn-trait.fixed +++ b/tests/ui/suggestions/issue-114797-bad-parentheses-dyn-trait.fixed @@ -3,9 +3,9 @@ trait Trait {} -fn assert_send(ptr: *mut dyn Trait) -> *mut (dyn Trait + Send) { +fn assert_send() -> *mut (dyn Trait + Send) { //~^ ERROR incorrect parentheses around trait bounds - ptr as _ + loop {} } fn foo2(_: &(dyn Trait + Send)) {} diff --git a/tests/ui/suggestions/issue-114797-bad-parentheses-dyn-trait.rs b/tests/ui/suggestions/issue-114797-bad-parentheses-dyn-trait.rs index 8899514142632..4a00059400c04 100644 --- a/tests/ui/suggestions/issue-114797-bad-parentheses-dyn-trait.rs +++ b/tests/ui/suggestions/issue-114797-bad-parentheses-dyn-trait.rs @@ -3,9 +3,9 @@ trait Trait {} -fn assert_send(ptr: *mut dyn Trait) -> *mut dyn (Trait + Send) { +fn assert_send() -> *mut dyn (Trait + Send) { //~^ ERROR incorrect parentheses around trait bounds - ptr as _ + loop {} } fn foo2(_: &dyn (Trait + Send)) {} diff --git a/tests/ui/suggestions/issue-114797-bad-parentheses-dyn-trait.stderr b/tests/ui/suggestions/issue-114797-bad-parentheses-dyn-trait.stderr index 2d1abe91a1eb7..c67557fa14f97 100644 --- a/tests/ui/suggestions/issue-114797-bad-parentheses-dyn-trait.stderr +++ b/tests/ui/suggestions/issue-114797-bad-parentheses-dyn-trait.stderr @@ -1,13 +1,13 @@ error: incorrect parentheses around trait bounds - --> $DIR/issue-114797-bad-parentheses-dyn-trait.rs:6:49 + --> $DIR/issue-114797-bad-parentheses-dyn-trait.rs:6:30 | -LL | fn assert_send(ptr: *mut dyn Trait) -> *mut dyn (Trait + Send) { - | ^ ^ +LL | fn assert_send() -> *mut dyn (Trait + Send) { + | ^ ^ | help: fix the parentheses | -LL - fn assert_send(ptr: *mut dyn Trait) -> *mut dyn (Trait + Send) { -LL + fn assert_send(ptr: *mut dyn Trait) -> *mut (dyn Trait + Send) { +LL - fn assert_send() -> *mut dyn (Trait + Send) { +LL + fn assert_send() -> *mut (dyn Trait + Send) { | error: incorrect parentheses around trait bounds diff --git a/tests/ui/traits/upcast_soundness_bug.rs b/tests/ui/traits/upcast_soundness_bug.rs index 95b48cdf379e8..3229a74f3ce29 100644 --- a/tests/ui/traits/upcast_soundness_bug.rs +++ b/tests/ui/traits/upcast_soundness_bug.rs @@ -1,7 +1,8 @@ #![feature(trait_upcasting)] -//@ known-bug: #120222 -//@ check-pass -//! This will segfault at runtime. +// check-fail +// +// issue: +//! This would segfault at runtime. pub trait SupSupA { fn method(&self) {} @@ -56,6 +57,7 @@ pub fn user2() -> &'static dyn Trait { fn main() { let p: *const dyn Trait = &(); let p = p as *const dyn Trait; // <- this is bad! + //~^ error: the trait bound `dyn Trait: Unsize>` is not satisfied let p = p as *const dyn Super; // <- this upcast accesses improper vtable entry // accessing from L__unnamed_2 the position for the 'Super vtable (pointer)', // thus reading 'null pointer for missing_method' diff --git a/tests/ui/traits/upcast_soundness_bug.stderr b/tests/ui/traits/upcast_soundness_bug.stderr new file mode 100644 index 0000000000000..ef2aeb3b1ec71 --- /dev/null +++ b/tests/ui/traits/upcast_soundness_bug.stderr @@ -0,0 +1,11 @@ +error[E0277]: the trait bound `dyn Trait: Unsize>` is not satisfied + --> $DIR/upcast_soundness_bug.rs:59:13 + | +LL | let p = p as *const dyn Trait; // <- this is bad! + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Unsize>` is not implemented for `dyn Trait` + | + = note: all implementations of `Unsize` are provided automatically by the compiler, see for more information + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. From eac4916c90eb198e2c135cec9ac253d48e10395d Mon Sep 17 00:00:00 2001 From: Waffle Lapkin Date: Tue, 4 Jun 2024 14:39:51 +0200 Subject: [PATCH 694/892] Disallow `dyn Trait -> dyn Auto` back I think it's fine, but let's ask T-lang separately. --- compiler/rustc_hir_typeck/src/cast.rs | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/cast.rs b/compiler/rustc_hir_typeck/src/cast.rs index 74be8529ec8f0..5a0e307ef6fae 100644 --- a/compiler/rustc_hir_typeck/src/cast.rs +++ b/compiler/rustc_hir_typeck/src/cast.rs @@ -840,8 +840,16 @@ impl<'a, 'tcx> CastCheck<'tcx> { // contain wrappers, which we do not care about. // // e.g. we want to allow `dyn T -> (dyn T,)`, etc. - let src_obj = tcx.mk_ty_from_kind(ty::Dynamic(src_tty, tcx.lifetimes.re_erased, ty::Dyn)); - let dst_obj = tcx.mk_ty_from_kind(ty::Dynamic(dst_tty, tcx.lifetimes.re_erased, ty::Dyn)); + let src_obj = tcx.mk_ty_from_kind(ty::Dynamic( + src_tty, + tcx.lifetimes.re_erased, + ty::Dyn, + )); + let dst_obj = tcx.mk_ty_from_kind(ty::Dynamic( + dst_tty, + tcx.lifetimes.re_erased, + ty::Dyn, + )); // `dyn Src: Unsize` let cause = fcx.misc(self.span); @@ -853,7 +861,7 @@ impl<'a, 'tcx> CastCheck<'tcx> { tcx, tcx.require_lang_item(LangItem::Unsize, Some(self.span)), [src_obj, dst_obj], - ) + ), ); fcx.register_predicate(obligation); @@ -866,9 +874,11 @@ impl<'a, 'tcx> CastCheck<'tcx> { } // dyn Auto -> dyn Auto'? ok. - (None, None) - // dyn Trait -> dyn Auto? ok. - | (Some(_), None)=> Ok(CastKind::PtrPtrCast), + (None, None) => Ok(CastKind::PtrPtrCast), + + // dyn Trait -> dyn Auto? should be ok, but we used to not allow it. + // FIXME: allow this + (Some(_), None) => Err(CastError::DifferingKinds), // dyn Auto -> dyn Trait? not ok. (None, Some(_)) => Err(CastError::DifferingKinds), From e85295c3215bb9125e221df65feb563987045225 Mon Sep 17 00:00:00 2001 From: Waffle Lapkin Date: Tue, 4 Jun 2024 15:21:09 +0200 Subject: [PATCH 695/892] test blessing --- tests/ui/cast/ptr-to-trait-obj-add-auto.rs | 2 +- tests/ui/cast/ptr-to-trait-obj-different-args.rs | 3 +-- tests/ui/cast/ptr-to-trait-obj-different-args.stderr | 10 +++++----- .../cast/ptr-to-trait-obj-different-regions-lt-ext.rs | 2 +- .../ui/cast/ptr-to-trait-obj-different-regions-misc.rs | 2 +- tests/ui/cast/ptr-to-trait-obj-ok.rs | 2 +- tests/ui/traits/upcast_soundness_bug.rs | 2 +- 7 files changed, 11 insertions(+), 12 deletions(-) diff --git a/tests/ui/cast/ptr-to-trait-obj-add-auto.rs b/tests/ui/cast/ptr-to-trait-obj-add-auto.rs index 4758132b65d84..27c6ffb61cc4f 100644 --- a/tests/ui/cast/ptr-to-trait-obj-add-auto.rs +++ b/tests/ui/cast/ptr-to-trait-obj-add-auto.rs @@ -1,4 +1,4 @@ -// check-fail +//@ check-fail trait Trait<'a> {} diff --git a/tests/ui/cast/ptr-to-trait-obj-different-args.rs b/tests/ui/cast/ptr-to-trait-obj-different-args.rs index 7488cf5ee9746..41b6633d68aef 100644 --- a/tests/ui/cast/ptr-to-trait-obj-different-args.rs +++ b/tests/ui/cast/ptr-to-trait-obj-different-args.rs @@ -1,8 +1,7 @@ -// check-fail +//@ check-fail // // issue: - trait A {} impl A for T {} trait B {} diff --git a/tests/ui/cast/ptr-to-trait-obj-different-args.stderr b/tests/ui/cast/ptr-to-trait-obj-different-args.stderr index e2cd9c8fa9070..74a95d85d4e62 100644 --- a/tests/ui/cast/ptr-to-trait-obj-different-args.stderr +++ b/tests/ui/cast/ptr-to-trait-obj-different-args.stderr @@ -1,5 +1,5 @@ error[E0277]: the trait bound `dyn A: Unsize` is not satisfied - --> $DIR/ptr-to-trait-obj-different-args.rs:19:27 + --> $DIR/ptr-to-trait-obj-different-args.rs:18:27 | LL | let b: *const dyn B = a as _; | ^^^^^^ the trait `Unsize` is not implemented for `dyn A` @@ -7,7 +7,7 @@ LL | let b: *const dyn B = a as _; = note: all implementations of `Unsize` are provided automatically by the compiler, see for more information error[E0277]: the trait bound `dyn Trait: Unsize>` is not satisfied - --> $DIR/ptr-to-trait-obj-different-args.rs:22:34 + --> $DIR/ptr-to-trait-obj-different-args.rs:21:34 | LL | let y: *const dyn Trait = x as _; | ^^^^^^ the trait `Unsize>` is not implemented for `dyn Trait` @@ -15,7 +15,7 @@ LL | let y: *const dyn Trait = x as _; = note: all implementations of `Unsize` are provided automatically by the compiler, see for more information error[E0277]: the trait bound `dyn Trait: Unsize>` is not satisfied - --> $DIR/ptr-to-trait-obj-different-args.rs:28:34 + --> $DIR/ptr-to-trait-obj-different-args.rs:27:34 | LL | let _: *const dyn Trait = x as _; | ^^^^^^ the trait `Unsize>` is not implemented for `dyn Trait` @@ -27,7 +27,7 @@ LL | fn generic(x: *const dyn Trait, t: *const dyn Trait) where dyn Tra | ++++++++++++++++++++++++++++++++++++++++ error[E0277]: the trait bound `dyn Trait: Unsize>` is not satisfied - --> $DIR/ptr-to-trait-obj-different-args.rs:29:34 + --> $DIR/ptr-to-trait-obj-different-args.rs:28:34 | LL | let _: *const dyn Trait = t as _; | ^^^^^^ the trait `Unsize>` is not implemented for `dyn Trait` @@ -39,7 +39,7 @@ LL | fn generic(x: *const dyn Trait, t: *const dyn Trait) where dyn Tra | ++++++++++++++++++++++++++++++++++++++++ error[E0277]: the trait bound `dyn Assocked: Unsize>` is not satisfied - --> $DIR/ptr-to-trait-obj-different-args.rs:37:5 + --> $DIR/ptr-to-trait-obj-different-args.rs:36:5 | LL | x as _ | ^^^^^^ the trait `Unsize>` is not implemented for `dyn Assocked` diff --git a/tests/ui/cast/ptr-to-trait-obj-different-regions-lt-ext.rs b/tests/ui/cast/ptr-to-trait-obj-different-regions-lt-ext.rs index d994723981fb6..96345de01c960 100644 --- a/tests/ui/cast/ptr-to-trait-obj-different-regions-lt-ext.rs +++ b/tests/ui/cast/ptr-to-trait-obj-different-regions-lt-ext.rs @@ -1,4 +1,4 @@ -// check-fail +//@ check-fail // // issue: diff --git a/tests/ui/cast/ptr-to-trait-obj-different-regions-misc.rs b/tests/ui/cast/ptr-to-trait-obj-different-regions-misc.rs index ea17fcd0da56c..01c347bfae5a0 100644 --- a/tests/ui/cast/ptr-to-trait-obj-different-regions-misc.rs +++ b/tests/ui/cast/ptr-to-trait-obj-different-regions-misc.rs @@ -1,4 +1,4 @@ -// check-fail +//@ check-fail trait Trait<'a> {} diff --git a/tests/ui/cast/ptr-to-trait-obj-ok.rs b/tests/ui/cast/ptr-to-trait-obj-ok.rs index 84d11bcb8eba3..656c99c58dc9a 100644 --- a/tests/ui/cast/ptr-to-trait-obj-ok.rs +++ b/tests/ui/cast/ptr-to-trait-obj-ok.rs @@ -1,4 +1,4 @@ -// check-pass +//@ check-pass trait Trait<'a> {} diff --git a/tests/ui/traits/upcast_soundness_bug.rs b/tests/ui/traits/upcast_soundness_bug.rs index 3229a74f3ce29..dd59f8cee505c 100644 --- a/tests/ui/traits/upcast_soundness_bug.rs +++ b/tests/ui/traits/upcast_soundness_bug.rs @@ -1,5 +1,5 @@ #![feature(trait_upcasting)] -// check-fail +//@ check-fail // // issue: //! This would segfault at runtime. From c7435571ad725791494c32a48be1cd2c027af30b Mon Sep 17 00:00:00 2001 From: Waffle Lapkin Date: Tue, 4 Jun 2024 15:47:16 +0200 Subject: [PATCH 696/892] Actually check that the traits are the same for casting pointers to dyn _ --- compiler/rustc_hir_typeck/src/cast.rs | 13 +++++++++---- tests/ui/cast/ptr-to-trait-obj-different-args.rs | 2 +- .../ui/cast/ptr-to-trait-obj-different-args.stderr | 9 +++++---- tests/ui/cast/ptr-to-trait-obj-wrap-upcast.rs | 14 ++++++++++++++ tests/ui/cast/ptr-to-trait-obj-wrap-upcast.stderr | 11 +++++++++++ tests/ui/mismatched_types/cast-rfc0401.rs | 2 +- tests/ui/mismatched_types/cast-rfc0401.stderr | 6 +++--- 7 files changed, 44 insertions(+), 13 deletions(-) create mode 100644 tests/ui/cast/ptr-to-trait-obj-wrap-upcast.rs create mode 100644 tests/ui/cast/ptr-to-trait-obj-wrap-upcast.stderr diff --git a/compiler/rustc_hir_typeck/src/cast.rs b/compiler/rustc_hir_typeck/src/cast.rs index 5a0e307ef6fae..1809f5e4b04fb 100644 --- a/compiler/rustc_hir_typeck/src/cast.rs +++ b/compiler/rustc_hir_typeck/src/cast.rs @@ -828,13 +828,18 @@ impl<'a, 'tcx> CastCheck<'tcx> { (Some(PointerKind::VTable(src_tty)), Some(PointerKind::VTable(dst_tty))) => { match (src_tty.principal(), dst_tty.principal()) { // A -> B. need to make sure - // - traits are the same & have the same generic arguments + // - traits are the same + // - traits have the same generic arguments // - Auto' is a subset of Auto - // - // This is checked by checking `dyn Trait + Auto + 'erased: Unsize`. - (Some(_), Some(_)) => { + (Some(src_principal), Some(dst_principal)) => { let tcx = fcx.tcx; + // Check that the traits are actually the same + // (this is required as the `Unsize` check below would allow upcasting, etc) + if src_principal.def_id() != dst_principal.def_id() { + return Err(CastError::DifferingKinds); + } + // We need to reconstruct trait object types. // `m_src` and `m_dst` won't work for us here because they will potentially // contain wrappers, which we do not care about. diff --git a/tests/ui/cast/ptr-to-trait-obj-different-args.rs b/tests/ui/cast/ptr-to-trait-obj-different-args.rs index 41b6633d68aef..88632f5506bc7 100644 --- a/tests/ui/cast/ptr-to-trait-obj-different-args.rs +++ b/tests/ui/cast/ptr-to-trait-obj-different-args.rs @@ -15,7 +15,7 @@ impl Trait for T {} fn main() { let a: *const dyn A = &(); - let b: *const dyn B = a as _; //~ error: the trait bound `dyn A: Unsize` is not satisfied + let b: *const dyn B = a as _; //~ error: casting `*const dyn A` as `*const dyn B` is invalid let x: *const dyn Trait = &(); let y: *const dyn Trait = x as _; //~ error: the trait bound `dyn Trait: Unsize>` is not satisfied diff --git a/tests/ui/cast/ptr-to-trait-obj-different-args.stderr b/tests/ui/cast/ptr-to-trait-obj-different-args.stderr index 74a95d85d4e62..65f0be8541fc9 100644 --- a/tests/ui/cast/ptr-to-trait-obj-different-args.stderr +++ b/tests/ui/cast/ptr-to-trait-obj-different-args.stderr @@ -1,10 +1,10 @@ -error[E0277]: the trait bound `dyn A: Unsize` is not satisfied +error[E0606]: casting `*const dyn A` as `*const dyn B` is invalid --> $DIR/ptr-to-trait-obj-different-args.rs:18:27 | LL | let b: *const dyn B = a as _; - | ^^^^^^ the trait `Unsize` is not implemented for `dyn A` + | ^^^^^^ | - = note: all implementations of `Unsize` are provided automatically by the compiler, see for more information + = note: vtable kinds may not match error[E0277]: the trait bound `dyn Trait: Unsize>` is not satisfied --> $DIR/ptr-to-trait-obj-different-args.rs:21:34 @@ -48,4 +48,5 @@ LL | x as _ error: aborting due to 5 previous errors -For more information about this error, try `rustc --explain E0277`. +Some errors have detailed explanations: E0277, E0606. +For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/cast/ptr-to-trait-obj-wrap-upcast.rs b/tests/ui/cast/ptr-to-trait-obj-wrap-upcast.rs new file mode 100644 index 0000000000000..ff2c4cacfb1f7 --- /dev/null +++ b/tests/ui/cast/ptr-to-trait-obj-wrap-upcast.rs @@ -0,0 +1,14 @@ +trait Super {} +trait Sub: Super {} + +struct Wrapper(T); + +// This cast should not compile. +// Upcasting can't work here, because we are also changing the type (`Wrapper`), +// and reinterpreting would be confusing/surprising. +// See +fn cast(ptr: *const dyn Sub) -> *const Wrapper { + ptr as _ //~ error: casting `*const (dyn Sub + 'static)` as `*const Wrapper` is invalid +} + +fn main() {} diff --git a/tests/ui/cast/ptr-to-trait-obj-wrap-upcast.stderr b/tests/ui/cast/ptr-to-trait-obj-wrap-upcast.stderr new file mode 100644 index 0000000000000..38c8ba96bc5b7 --- /dev/null +++ b/tests/ui/cast/ptr-to-trait-obj-wrap-upcast.stderr @@ -0,0 +1,11 @@ +error[E0606]: casting `*const (dyn Sub + 'static)` as `*const Wrapper` is invalid + --> $DIR/ptr-to-trait-obj-wrap-upcast.rs:11:5 + | +LL | ptr as _ + | ^^^^^^^^ + | + = note: vtable kinds may not match + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0606`. diff --git a/tests/ui/mismatched_types/cast-rfc0401.rs b/tests/ui/mismatched_types/cast-rfc0401.rs index 05e39f86cdfc5..b2ff5b4a0c063 100644 --- a/tests/ui/mismatched_types/cast-rfc0401.rs +++ b/tests/ui/mismatched_types/cast-rfc0401.rs @@ -66,7 +66,7 @@ fn main() let cf: *const dyn Foo = &0; let _ = cf as *const [u16]; //~ ERROR is invalid - let _ = cf as *const dyn Bar; //~ ERROR the trait bound `dyn Foo: Unsize` is not satisfied + let _ = cf as *const dyn Bar; //~ ERROR casting `*const dyn Foo` as `*const dyn Bar` is invalid vec![0.0].iter().map(|s| s as f32).collect::>(); //~ ERROR is invalid } diff --git a/tests/ui/mismatched_types/cast-rfc0401.stderr b/tests/ui/mismatched_types/cast-rfc0401.stderr index 9f4a7aa858edf..142a52aef13d0 100644 --- a/tests/ui/mismatched_types/cast-rfc0401.stderr +++ b/tests/ui/mismatched_types/cast-rfc0401.stderr @@ -210,13 +210,13 @@ LL | let _ = cf as *const [u16]; | = note: vtable kinds may not match -error[E0277]: the trait bound `dyn Foo: Unsize` is not satisfied +error[E0606]: casting `*const dyn Foo` as `*const dyn Bar` is invalid --> $DIR/cast-rfc0401.rs:69:13 | LL | let _ = cf as *const dyn Bar; - | ^^^^^^^^^^^^^^^^^^^^ the trait `Unsize` is not implemented for `dyn Foo` + | ^^^^^^^^^^^^^^^^^^^^ | - = note: all implementations of `Unsize` are provided automatically by the compiler, see for more information + = note: vtable kinds may not match error[E0277]: the size for values of type `[u8]` cannot be known at compilation time --> $DIR/cast-rfc0401.rs:53:13 From 340d69be12ffc03709340ec2d342db32406cd25f Mon Sep 17 00:00:00 2001 From: Maybe Lapkin Date: Sun, 23 Jun 2024 19:55:17 +0200 Subject: [PATCH 697/892] Align the changes to the lang decision --- compiler/rustc_borrowck/src/type_check/mod.rs | 37 ++++++++++--- compiler/rustc_hir_typeck/messages.ftl | 5 ++ compiler/rustc_hir_typeck/src/cast.rs | 46 +++++++++++++--- compiler/rustc_hir_typeck/src/errors.rs | 8 +++ compiler/rustc_lint_defs/src/builtin.rs | 54 +++++++++++++++++++ compiler/rustc_middle/src/ty/predicate.rs | 8 +++ tests/ui/cast/ptr-to-trait-obj-add-auto.rs | 6 ++- .../ui/cast/ptr-to-trait-obj-add-auto.stderr | 22 ++++++-- 8 files changed, 165 insertions(+), 21 deletions(-) diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 2600c1fbff7bf..f98ac80a4c94c 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -2323,27 +2323,48 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { let src_tail = tcx.struct_tail_without_normalization(src.ty); let dst_tail = tcx.struct_tail_without_normalization(dst.ty); - if let ty::Dynamic(..) = src_tail.kind() + if let ty::Dynamic(src_tty, ..) = src_tail.kind() && let ty::Dynamic(dst_tty, ..) = dst_tail.kind() + && src_tty.principal().is_some() && dst_tty.principal().is_some() { - // Erase trait object lifetimes, to allow casts like `*mut dyn FnOnce()` -> `*mut dyn FnOnce() + 'static`. - let src_tail = - erase_single_trait_object_lifetime(tcx, src_tail); - let dst_tail = - erase_single_trait_object_lifetime(tcx, dst_tail); + // Erase trait object lifetimes, to allow casts like `*mut dyn FnOnce()` -> `*mut dyn FnOnce() + 'static` + // and remove auto traits. + let src_obj = tcx.mk_ty_from_kind(ty::Dynamic( + tcx.mk_poly_existential_predicates( + &src_tty.without_auto_traits().collect::>(), + ), + tcx.lifetimes.re_erased, + ty::Dyn, + )); + let dst_obj = tcx.mk_ty_from_kind(ty::Dynamic( + tcx.mk_poly_existential_predicates( + &dst_tty.without_auto_traits().collect::>(), + ), + tcx.lifetimes.re_erased, + ty::Dyn, + )); + + // FIXME: + // this currently does nothing, but once we make `ptr_cast_add_auto_to_object` + // into a hard error, we can remove the above removal of auto traits and only + // keep this. + let src_obj = erase_single_trait_object_lifetime(tcx, src_obj); + let dst_obj = erase_single_trait_object_lifetime(tcx, dst_obj); let trait_ref = ty::TraitRef::new( tcx, tcx.require_lang_item(LangItem::Unsize, Some(span)), - [src_tail, dst_tail], + [src_obj, dst_obj], ); + debug!(?src_tty, ?dst_tty, ?src_obj, ?dst_obj); + self.prove_trait_ref( trait_ref, location.to_locations(), ConstraintCategory::Cast { - unsize_to: Some(tcx.fold_regions(dst_tail, |r, _| { + unsize_to: Some(tcx.fold_regions(dst_obj, |r, _| { if let ty::ReVar(_) = r.kind() { tcx.lifetimes.re_erased } else { diff --git a/compiler/rustc_hir_typeck/messages.ftl b/compiler/rustc_hir_typeck/messages.ftl index d6f3f4d640bd5..f05da5ad48a6c 100644 --- a/compiler/rustc_hir_typeck/messages.ftl +++ b/compiler/rustc_hir_typeck/messages.ftl @@ -123,6 +123,11 @@ hir_typeck_option_result_asref = use `{$def_path}::as_ref` to convert `{$expecte hir_typeck_option_result_cloned = use `{$def_path}::cloned` to clone the value inside the `{$def_path}` hir_typeck_option_result_copied = use `{$def_path}::copied` to copy the value inside the `{$def_path}` +hir_typeck_ptr_cast_add_auto_to_object = adding an auto {$traits_len -> + [1] trait {$traits} + *[other] traits {$traits} +} to a trait object in a pointer cast may cause UB later on + hir_typeck_remove_semi_for_coerce = you might have meant to return the `match` expression hir_typeck_remove_semi_for_coerce_expr = this could be implicitly returned but it is a statement, not a tail expression hir_typeck_remove_semi_for_coerce_ret = the `match` arms can conform to this return type diff --git a/compiler/rustc_hir_typeck/src/cast.rs b/compiler/rustc_hir_typeck/src/cast.rs index 1809f5e4b04fb..c2f481e6c2fc1 100644 --- a/compiler/rustc_hir_typeck/src/cast.rs +++ b/compiler/rustc_hir_typeck/src/cast.rs @@ -32,6 +32,8 @@ use super::FnCtxt; use crate::errors; use crate::type_error_struct; +use itertools::Itertools; +use rustc_data_structures::fx::FxHashSet; use rustc_errors::{codes::*, Applicability, Diag, ErrorGuaranteed}; use rustc_hir::{self as hir, ExprKind, LangItem}; use rustc_infer::traits::Obligation; @@ -827,15 +829,16 @@ impl<'a, 'tcx> CastCheck<'tcx> { // trait object -> trait object? need to do additional checks (Some(PointerKind::VTable(src_tty)), Some(PointerKind::VTable(dst_tty))) => { match (src_tty.principal(), dst_tty.principal()) { - // A -> B. need to make sure - // - traits are the same + // A + SrcAuto> -> B + DstAuto>. need to make sure + // - `Src` and `Dst` traits are the same // - traits have the same generic arguments - // - Auto' is a subset of Auto + // - `SrcAuto` is a superset of `DstAuto` (Some(src_principal), Some(dst_principal)) => { let tcx = fcx.tcx; // Check that the traits are actually the same // (this is required as the `Unsize` check below would allow upcasting, etc) + // N.B.: this is only correct as long as we don't support `trait A: A<()>`. if src_principal.def_id() != dst_principal.def_id() { return Err(CastError::DifferingKinds); } @@ -845,18 +848,24 @@ impl<'a, 'tcx> CastCheck<'tcx> { // contain wrappers, which we do not care about. // // e.g. we want to allow `dyn T -> (dyn T,)`, etc. + // + // We also need to skip auto traits to emit an FCW and not an error. let src_obj = tcx.mk_ty_from_kind(ty::Dynamic( - src_tty, + tcx.mk_poly_existential_predicates( + &src_tty.without_auto_traits().collect::>(), + ), tcx.lifetimes.re_erased, ty::Dyn, )); let dst_obj = tcx.mk_ty_from_kind(ty::Dynamic( - dst_tty, + tcx.mk_poly_existential_predicates( + &dst_tty.without_auto_traits().collect::>(), + ), tcx.lifetimes.re_erased, ty::Dyn, )); - // `dyn Src: Unsize` + // `dyn Src: Unsize`, this checks for matching generics let cause = fcx.misc(self.span); let obligation = Obligation::new( tcx, @@ -871,6 +880,31 @@ impl<'a, 'tcx> CastCheck<'tcx> { fcx.register_predicate(obligation); + // Check that `SrcAuto` is a superset of `DstAuto`. + // Emit an FCW otherwise. + let src_auto = src_tty.auto_traits().collect::>(); + let added = dst_tty + .auto_traits() + .filter(|trait_did| !src_auto.contains(trait_did)) + .collect::>(); + + if !added.is_empty() { + tcx.emit_node_span_lint( + lint::builtin::PTR_CAST_ADD_AUTO_TO_OBJECT, + self.expr.hir_id, + self.span, + errors::PtrCastAddAutoToObject { + traits_len: added.len(), + traits: added + .into_iter() + .map(|trait_did| { + format!("`{}`", tcx.def_path_str(trait_did)) + }) + .join(", "), + }, + ) + } + // FIXME: ideally we'd maybe add a flag here, so that borrowck knows that // it needs to borrowck this ptr cast. this is made annoying by the // fact that `thir` does not have `CastKind` and mir restores it diff --git a/compiler/rustc_hir_typeck/src/errors.rs b/compiler/rustc_hir_typeck/src/errors.rs index 98add86252c52..6c10047cfd409 100644 --- a/compiler/rustc_hir_typeck/src/errors.rs +++ b/compiler/rustc_hir_typeck/src/errors.rs @@ -253,6 +253,14 @@ pub struct LossyProvenanceInt2Ptr<'tcx> { pub sugg: LossyProvenanceInt2PtrSuggestion, } +#[derive(LintDiagnostic)] +#[diag(hir_typeck_ptr_cast_add_auto_to_object)] +//#[help] +pub struct PtrCastAddAutoToObject { + pub traits_len: usize, + pub traits: String, +} + #[derive(Subdiagnostic)] #[multipart_suggestion(hir_typeck_suggestion, applicability = "has-placeholders")] pub struct LossyProvenanceInt2PtrSuggestion { diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index 2ade6964ca89e..6af6f7c473e9f 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -80,6 +80,7 @@ declare_lint_pass! { PRIVATE_BOUNDS, PRIVATE_INTERFACES, PROC_MACRO_DERIVE_RESOLUTION_FALLBACK, + PTR_CAST_ADD_AUTO_TO_OBJECT, PUB_USE_OF_PRIVATE_EXTERN_CRATE, REDUNDANT_LIFETIMES, REFINING_IMPL_TRAIT_INTERNAL, @@ -4937,6 +4938,59 @@ declare_lint! { }; } +declare_lint! { + /// The `ptr_cast_add_auto_to_object` lint detects casts of raw pointers to trait + /// objects, which add auto traits. + /// + /// ### Example + /// + /// ```rust,edition2021,compile_fail + /// let ptr: *const dyn core::any::Any = &(); + /// _ = ptr as *const dyn core::any::Any + Send; + /// ``` + /// + /// {{produces}} + /// + /// ### Explanation + /// + /// Adding an auto trait can make the vtable invalid, potentially causing + /// UB in safe code afterwards. For example: + /// + /// ```ignore (causes a warning) + /// #![feature(arbitrary_self_types)] + /// + /// trait Trait { + /// fn f(self: *const Self) + /// where + /// Self: Send; + /// } + /// + /// impl Trait for *const () { + /// fn f(self: *const Self) { + /// unreachable!() + /// } + /// } + /// + /// fn main() { + /// let unsend: *const () = &(); + /// let unsend: *const dyn Trait = &unsend; + /// let send_bad: *const (dyn Trait + Send) = unsend as _; + /// send_bad.f(); // this crashes, since vtable for `*const ()` does not have an entry for `f` + /// } + /// ``` + /// + /// Generally you must ensure that vtable is right for the pointer's type, + /// before passing the pointer to safe code. + pub PTR_CAST_ADD_AUTO_TO_OBJECT, + Warn, + "detects `as` casts from pointers to `dyn Trait` to pointers to `dyn Trait + Auto`", + @future_incompatible = FutureIncompatibleInfo { + reason: FutureIncompatibilityReason::FutureReleaseErrorReportInDeps, + // FIXME: actually write an issue with an explanation + reference: "issue #125289 ", + }; +} + declare_lint! { /// The `out_of_scope_macro_calls` lint detects `macro_rules` called when they are not in scope, /// above their definition, which may happen in key-value attributes. diff --git a/compiler/rustc_middle/src/ty/predicate.rs b/compiler/rustc_middle/src/ty/predicate.rs index e9b37503bb3e5..3c327eb5b1d20 100644 --- a/compiler/rustc_middle/src/ty/predicate.rs +++ b/compiler/rustc_middle/src/ty/predicate.rs @@ -341,6 +341,14 @@ impl<'tcx> ty::List> { _ => None, }) } + + pub fn without_auto_traits( + &self, + ) -> impl Iterator> + '_ { + self.iter().filter(|predicate| { + !matches!(predicate.as_ref().skip_binder(), ExistentialPredicate::AutoTrait(_)) + }) + } } pub type PolyTraitRef<'tcx> = ty::Binder<'tcx, TraitRef<'tcx>>; diff --git a/tests/ui/cast/ptr-to-trait-obj-add-auto.rs b/tests/ui/cast/ptr-to-trait-obj-add-auto.rs index 27c6ffb61cc4f..75b568169842f 100644 --- a/tests/ui/cast/ptr-to-trait-obj-add-auto.rs +++ b/tests/ui/cast/ptr-to-trait-obj-add-auto.rs @@ -1,9 +1,11 @@ -//@ check-fail +//@ check-pass trait Trait<'a> {} fn add_auto<'a>(x: *mut dyn Trait<'a>) -> *mut (dyn Trait<'a> + Send) { - x as _ //~ error: the trait bound `dyn Trait<'_>: Unsize + Send>` is not satisfied + x as _ + //~^ warning: adding an auto trait `Send` to a trait object in a pointer cast may cause UB later on + //~| warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! } fn main() {} diff --git a/tests/ui/cast/ptr-to-trait-obj-add-auto.stderr b/tests/ui/cast/ptr-to-trait-obj-add-auto.stderr index 0c35db57b307d..ff8c7057c96b6 100644 --- a/tests/ui/cast/ptr-to-trait-obj-add-auto.stderr +++ b/tests/ui/cast/ptr-to-trait-obj-add-auto.stderr @@ -1,11 +1,23 @@ -error[E0277]: the trait bound `dyn Trait<'_>: Unsize + Send>` is not satisfied +warning: adding an auto trait `Send` to a trait object in a pointer cast may cause UB later on --> $DIR/ptr-to-trait-obj-add-auto.rs:6:5 | LL | x as _ - | ^^^^^^ the trait `Unsize + Send>` is not implemented for `dyn Trait<'_>` + | ^^^^^^ | - = note: all implementations of `Unsize` are provided automatically by the compiler, see for more information + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #125289 + = note: `#[warn(ptr_cast_add_auto_to_object)]` on by default -error: aborting due to 1 previous error +warning: 1 warning emitted + +Future incompatibility report: Future breakage diagnostic: +warning: adding an auto trait `Send` to a trait object in a pointer cast may cause UB later on + --> $DIR/ptr-to-trait-obj-add-auto.rs:6:5 + | +LL | x as _ + | ^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #125289 + = note: `#[warn(ptr_cast_add_auto_to_object)]` on by default -For more information about this error, try `rustc --explain E0277`. From 06863eeebf3dd16119c6605e5234e6938e6c1e95 Mon Sep 17 00:00:00 2001 From: Maybe Lapkin Date: Sun, 23 Jun 2024 22:27:28 +0200 Subject: [PATCH 698/892] Delete `CloneAny` from `rust-analyzer`'s fork of `AnyMap` ...because it's very sketchy and causes FCWs. In this case it *is* actually sound, but still. I should write a better fork of anymap... --- .../rust-analyzer/crates/stdx/src/anymap.rs | 71 ------------------- 1 file changed, 71 deletions(-) diff --git a/src/tools/rust-analyzer/crates/stdx/src/anymap.rs b/src/tools/rust-analyzer/crates/stdx/src/anymap.rs index d189b56a468fc..4eafcfb060f22 100644 --- a/src/tools/rust-analyzer/crates/stdx/src/anymap.rs +++ b/src/tools/rust-analyzer/crates/stdx/src/anymap.rs @@ -68,8 +68,6 @@ pub type RawMap = hash_map::HashMap, BuildHasherDefault`) to add those /// auto traits. /// @@ -79,9 +77,6 @@ pub type RawMap = hash_map::HashMap, BuildHasherDefault[Map]<dyn [core::any::Any] + Send> /// - [Map]<dyn [core::any::Any] + Send + Sync> -/// - [Map]<dyn [CloneAny]> -/// - [Map]<dyn [CloneAny] + Send> -/// - [Map]<dyn [CloneAny] + Send + Sync> /// /// ## Example /// @@ -205,12 +200,6 @@ mod tests { assert_debug::>(); assert_debug::>(); assert_debug::>(); - assert_send::>(); - assert_send::>(); - assert_sync::>(); - assert_debug::>(); - assert_debug::>(); - assert_debug::>(); } #[test] @@ -232,53 +221,6 @@ mod tests { } } -// impl some traits for dyn Any -use core::fmt; - -#[doc(hidden)] -pub trait CloneToAny { - /// Clone `self` into a new `Box` object. - fn clone_to_any(&self) -> Box; -} - -impl CloneToAny for T { - #[inline] - fn clone_to_any(&self) -> Box { - Box::new(self.clone()) - } -} - -macro_rules! impl_clone { - ($t:ty) => { - impl Clone for Box<$t> { - #[inline] - fn clone(&self) -> Box<$t> { - // SAFETY: this dance is to reapply any Send/Sync marker. I’m not happy about this - // approach, given that I used to do it in safe code, but then came a dodgy - // future-compatibility warning where_clauses_object_safety, which is spurious for - // auto traits but still super annoying (future-compatibility lints seem to mean - // your bin crate needs a corresponding allow!). Although I explained my plight¹ - // and it was all explained and agreed upon, no action has been taken. So I finally - // caved and worked around it by doing it this way, which matches what’s done for - // core::any², so it’s probably not *too* bad. - // - // ¹ https://github.com/rust-lang/rust/issues/51443#issuecomment-421988013 - // ² https://github.com/rust-lang/rust/blob/e7825f2b690c9a0d21b6f6d84c404bb53b151b38/library/alloc/src/boxed.rs#L1613-L1616 - let clone: Box = (**self).clone_to_any(); - let raw: *mut dyn CloneAny = Box::into_raw(clone); - unsafe { Box::from_raw(raw as *mut $t) } - } - } - - impl fmt::Debug for $t { - #[inline] - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.pad(stringify!($t)) - } - } - }; -} - /// Methods for downcasting from an `Any`-like trait object. /// /// This should only be implemented on trait objects for subtraits of `Any`, though you can @@ -350,16 +292,3 @@ macro_rules! implement { implement!(Any); implement!(Any + Send); implement!(Any + Send + Sync); - -/// [`Any`], but with cloning. -/// -/// Every type with no non-`'static` references that implements `Clone` implements `CloneAny`. -/// See [`core::any`] for more details on `Any` in general. -pub trait CloneAny: Any + CloneToAny {} -impl CloneAny for T {} -implement!(CloneAny); -implement!(CloneAny + Send); -implement!(CloneAny + Send + Sync); -impl_clone!(dyn CloneAny); -impl_clone!(dyn CloneAny + Send); -impl_clone!(dyn CloneAny + Send + Sync); From cf7032f751d45bb807ce5ec3d3816870ef3a5beb Mon Sep 17 00:00:00 2001 From: Maybe Lapkin Date: Sun, 23 Jun 2024 22:29:08 +0200 Subject: [PATCH 699/892] Small fixes from review --- compiler/rustc_hir_typeck/messages.ftl | 6 +++--- compiler/rustc_hir_typeck/src/cast.rs | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_hir_typeck/messages.ftl b/compiler/rustc_hir_typeck/messages.ftl index f05da5ad48a6c..fda3a8e256f67 100644 --- a/compiler/rustc_hir_typeck/messages.ftl +++ b/compiler/rustc_hir_typeck/messages.ftl @@ -123,9 +123,9 @@ hir_typeck_option_result_asref = use `{$def_path}::as_ref` to convert `{$expecte hir_typeck_option_result_cloned = use `{$def_path}::cloned` to clone the value inside the `{$def_path}` hir_typeck_option_result_copied = use `{$def_path}::copied` to copy the value inside the `{$def_path}` -hir_typeck_ptr_cast_add_auto_to_object = adding an auto {$traits_len -> - [1] trait {$traits} - *[other] traits {$traits} +hir_typeck_ptr_cast_add_auto_to_object = adding {$traits_len -> + [1] an auto trait {$traits} + *[other] auto traits {$traits} } to a trait object in a pointer cast may cause UB later on hir_typeck_remove_semi_for_coerce = you might have meant to return the `match` expression diff --git a/compiler/rustc_hir_typeck/src/cast.rs b/compiler/rustc_hir_typeck/src/cast.rs index c2f481e6c2fc1..5787208516d7a 100644 --- a/compiler/rustc_hir_typeck/src/cast.rs +++ b/compiler/rustc_hir_typeck/src/cast.rs @@ -808,7 +808,7 @@ impl<'a, 'tcx> CastCheck<'tcx> { m_src: ty::TypeAndMut<'tcx>, m_dst: ty::TypeAndMut<'tcx>, ) -> Result { - debug!("check_ptr_ptr_cast m_expr={:?} m_cast={:?}", m_src, m_dst); + debug!("check_ptr_ptr_cast m_src={m_src:?} m_dst={m_dst:?}"); // ptr-ptr cast. vtables must match. let src_kind = fcx.tcx.erase_regions(fcx.pointer_kind(m_src.ty, self.span)?); From b16f8034316d4cd1d4a8766899d8cf30f7d73730 Mon Sep 17 00:00:00 2001 From: Maybe Lapkin Date: Thu, 4 Jul 2024 16:45:13 +0200 Subject: [PATCH 700/892] Make `DiagSymbolList` more generic --- compiler/rustc_errors/src/diagnostic_impls.rs | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_errors/src/diagnostic_impls.rs b/compiler/rustc_errors/src/diagnostic_impls.rs index 0af80bc5c67b6..e6ca1bf7bc45f 100644 --- a/compiler/rustc_errors/src/diagnostic_impls.rs +++ b/compiler/rustc_errors/src/diagnostic_impls.rs @@ -298,15 +298,21 @@ impl IntoDiagArg for hir::def::Namespace { } #[derive(Clone)] -pub struct DiagSymbolList(Vec); +pub struct DiagSymbolList(Vec); -impl From> for DiagSymbolList { - fn from(v: Vec) -> Self { +impl From> for DiagSymbolList { + fn from(v: Vec) -> Self { DiagSymbolList(v) } } -impl IntoDiagArg for DiagSymbolList { +impl FromIterator for DiagSymbolList { + fn from_iter>(iter: T) -> Self { + iter.into_iter().collect::>().into() + } +} + +impl IntoDiagArg for DiagSymbolList { fn into_diag_arg(self) -> DiagArgValue { DiagArgValue::StrListSepByAnd( self.0.into_iter().map(|sym| Cow::Owned(format!("`{sym}`"))).collect(), From dc420a282b0cbfb717e1958bc28cc8ba0e335d6f Mon Sep 17 00:00:00 2001 From: Maybe Lapkin Date: Thu, 4 Jul 2024 16:46:00 +0200 Subject: [PATCH 701/892] Use `DiagSymbolList` for a lint diagnostic --- compiler/rustc_hir_typeck/src/cast.rs | 7 ++---- compiler/rustc_hir_typeck/src/errors.rs | 6 ++--- tests/ui/cast/ptr-to-trait-obj-add-auto.rs | 7 ++++++ .../ui/cast/ptr-to-trait-obj-add-auto.stderr | 22 ++++++++++++++++++- 4 files changed, 33 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/cast.rs b/compiler/rustc_hir_typeck/src/cast.rs index 5787208516d7a..840a139b9bf9a 100644 --- a/compiler/rustc_hir_typeck/src/cast.rs +++ b/compiler/rustc_hir_typeck/src/cast.rs @@ -32,7 +32,6 @@ use super::FnCtxt; use crate::errors; use crate::type_error_struct; -use itertools::Itertools; use rustc_data_structures::fx::FxHashSet; use rustc_errors::{codes::*, Applicability, Diag, ErrorGuaranteed}; use rustc_hir::{self as hir, ExprKind, LangItem}; @@ -897,10 +896,8 @@ impl<'a, 'tcx> CastCheck<'tcx> { traits_len: added.len(), traits: added .into_iter() - .map(|trait_did| { - format!("`{}`", tcx.def_path_str(trait_did)) - }) - .join(", "), + .map(|trait_did| tcx.def_path_str(trait_did)) + .collect(), }, ) } diff --git a/compiler/rustc_hir_typeck/src/errors.rs b/compiler/rustc_hir_typeck/src/errors.rs index 6c10047cfd409..cdc160d13fef1 100644 --- a/compiler/rustc_hir_typeck/src/errors.rs +++ b/compiler/rustc_hir_typeck/src/errors.rs @@ -4,8 +4,8 @@ use std::borrow::Cow; use crate::fluent_generated as fluent; use rustc_errors::{ - codes::*, Applicability, Diag, DiagArgValue, EmissionGuarantee, IntoDiagArg, MultiSpan, - SubdiagMessageOp, Subdiagnostic, + codes::*, Applicability, Diag, DiagArgValue, DiagSymbolList, EmissionGuarantee, IntoDiagArg, + MultiSpan, SubdiagMessageOp, Subdiagnostic, }; use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic}; use rustc_middle::ty::{self, Ty}; @@ -258,7 +258,7 @@ pub struct LossyProvenanceInt2Ptr<'tcx> { //#[help] pub struct PtrCastAddAutoToObject { pub traits_len: usize, - pub traits: String, + pub traits: DiagSymbolList, } #[derive(Subdiagnostic)] diff --git a/tests/ui/cast/ptr-to-trait-obj-add-auto.rs b/tests/ui/cast/ptr-to-trait-obj-add-auto.rs index 75b568169842f..70293b28ee0ab 100644 --- a/tests/ui/cast/ptr-to-trait-obj-add-auto.rs +++ b/tests/ui/cast/ptr-to-trait-obj-add-auto.rs @@ -8,4 +8,11 @@ fn add_auto<'a>(x: *mut dyn Trait<'a>) -> *mut (dyn Trait<'a> + Send) { //~| warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! } +// (to test diagnostic list formatting) +fn add_multiple_auto<'a>(x: *mut dyn Trait<'a>) -> *mut (dyn Trait<'a> + Send + Sync + Unpin) { + x as _ + //~^ warning: adding auto traits `Sync`, `Send`, and `Unpin` to a trait object in a pointer cast may cause UB later on + //~| warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! +} + fn main() {} diff --git a/tests/ui/cast/ptr-to-trait-obj-add-auto.stderr b/tests/ui/cast/ptr-to-trait-obj-add-auto.stderr index ff8c7057c96b6..beb71eb100b51 100644 --- a/tests/ui/cast/ptr-to-trait-obj-add-auto.stderr +++ b/tests/ui/cast/ptr-to-trait-obj-add-auto.stderr @@ -8,7 +8,16 @@ LL | x as _ = note: for more information, see issue #125289 = note: `#[warn(ptr_cast_add_auto_to_object)]` on by default -warning: 1 warning emitted +warning: adding auto traits `Sync`, `Send`, and `Unpin` to a trait object in a pointer cast may cause UB later on + --> $DIR/ptr-to-trait-obj-add-auto.rs:13:5 + | +LL | x as _ + | ^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #125289 + +warning: 2 warnings emitted Future incompatibility report: Future breakage diagnostic: warning: adding an auto trait `Send` to a trait object in a pointer cast may cause UB later on @@ -21,3 +30,14 @@ LL | x as _ = note: for more information, see issue #125289 = note: `#[warn(ptr_cast_add_auto_to_object)]` on by default +Future breakage diagnostic: +warning: adding auto traits `Sync`, `Send`, and `Unpin` to a trait object in a pointer cast may cause UB later on + --> $DIR/ptr-to-trait-obj-add-auto.rs:13:5 + | +LL | x as _ + | ^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #125289 + = note: `#[warn(ptr_cast_add_auto_to_object)]` on by default + From 52ba120700daaeca7d26574f200dcbb527f739de Mon Sep 17 00:00:00 2001 From: Maybe Lapkin Date: Thu, 4 Jul 2024 17:51:36 +0200 Subject: [PATCH 702/892] Remove unhelpful comments and add helpful ones --- compiler/rustc_borrowck/src/type_check/mod.rs | 4 ++++ compiler/rustc_hir_typeck/src/cast.rs | 7 +++---- compiler/rustc_hir_typeck/src/errors.rs | 1 - 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index f98ac80a4c94c..81ce741885203 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -2323,6 +2323,10 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { let src_tail = tcx.struct_tail_without_normalization(src.ty); let dst_tail = tcx.struct_tail_without_normalization(dst.ty); + // This checks (lifetime part of) vtable validity for pointer casts, + // which is irrelevant when there are aren't principal traits on both sides (aka only auto traits). + // + // Note that other checks (such as denying `dyn Send` -> `dyn Debug`) are in `rustc_hir_typeck`. if let ty::Dynamic(src_tty, ..) = src_tail.kind() && let ty::Dynamic(dst_tty, ..) = dst_tail.kind() && src_tty.principal().is_some() diff --git a/compiler/rustc_hir_typeck/src/cast.rs b/compiler/rustc_hir_typeck/src/cast.rs index 840a139b9bf9a..887d124bd7a46 100644 --- a/compiler/rustc_hir_typeck/src/cast.rs +++ b/compiler/rustc_hir_typeck/src/cast.rs @@ -838,6 +838,9 @@ impl<'a, 'tcx> CastCheck<'tcx> { // Check that the traits are actually the same // (this is required as the `Unsize` check below would allow upcasting, etc) // N.B.: this is only correct as long as we don't support `trait A: A<()>`. + // + // Note that trait upcasting goes through a different mechanism (`coerce_unsized`) + // and is unaffected by this check. if src_principal.def_id() != dst_principal.def_id() { return Err(CastError::DifferingKinds); } @@ -902,10 +905,6 @@ impl<'a, 'tcx> CastCheck<'tcx> { ) } - // FIXME: ideally we'd maybe add a flag here, so that borrowck knows that - // it needs to borrowck this ptr cast. this is made annoying by the - // fact that `thir` does not have `CastKind` and mir restores it - // from types. Ok(CastKind::PtrPtrCast) } diff --git a/compiler/rustc_hir_typeck/src/errors.rs b/compiler/rustc_hir_typeck/src/errors.rs index cdc160d13fef1..dfc74b0e65dcf 100644 --- a/compiler/rustc_hir_typeck/src/errors.rs +++ b/compiler/rustc_hir_typeck/src/errors.rs @@ -255,7 +255,6 @@ pub struct LossyProvenanceInt2Ptr<'tcx> { #[derive(LintDiagnostic)] #[diag(hir_typeck_ptr_cast_add_auto_to_object)] -//#[help] pub struct PtrCastAddAutoToObject { pub traits_len: usize, pub traits: DiagSymbolList, From 9ef533e8de83aba38a460eae4eec41859f188bf1 Mon Sep 17 00:00:00 2001 From: Maybe Lapkin Date: Thu, 4 Jul 2024 17:52:01 +0200 Subject: [PATCH 703/892] Fill in tracking issue --- compiler/rustc_lint_defs/src/builtin.rs | 3 +-- tests/ui/cast/ptr-to-trait-obj-add-auto.stderr | 8 ++++---- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index 6af6f7c473e9f..baf2000ec454c 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -4986,8 +4986,7 @@ declare_lint! { "detects `as` casts from pointers to `dyn Trait` to pointers to `dyn Trait + Auto`", @future_incompatible = FutureIncompatibleInfo { reason: FutureIncompatibilityReason::FutureReleaseErrorReportInDeps, - // FIXME: actually write an issue with an explanation - reference: "issue #125289 ", + reference: "issue #127323 ", }; } diff --git a/tests/ui/cast/ptr-to-trait-obj-add-auto.stderr b/tests/ui/cast/ptr-to-trait-obj-add-auto.stderr index beb71eb100b51..175c5c981450d 100644 --- a/tests/ui/cast/ptr-to-trait-obj-add-auto.stderr +++ b/tests/ui/cast/ptr-to-trait-obj-add-auto.stderr @@ -5,7 +5,7 @@ LL | x as _ | ^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #125289 + = note: for more information, see issue #127323 = note: `#[warn(ptr_cast_add_auto_to_object)]` on by default warning: adding auto traits `Sync`, `Send`, and `Unpin` to a trait object in a pointer cast may cause UB later on @@ -15,7 +15,7 @@ LL | x as _ | ^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #125289 + = note: for more information, see issue #127323 warning: 2 warnings emitted @@ -27,7 +27,7 @@ LL | x as _ | ^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #125289 + = note: for more information, see issue #127323 = note: `#[warn(ptr_cast_add_auto_to_object)]` on by default Future breakage diagnostic: @@ -38,6 +38,6 @@ LL | x as _ | ^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #125289 + = note: for more information, see issue #127323 = note: `#[warn(ptr_cast_add_auto_to_object)]` on by default From a1f20f17c86a7a0a51728be48afd121d5ae2df64 Mon Sep 17 00:00:00 2001 From: Maybe Lapkin Date: Thu, 4 Jul 2024 17:53:37 +0200 Subject: [PATCH 704/892] Properly normalize types in bck when checking pointer casts --- compiler/rustc_borrowck/src/type_check/mod.rs | 7 +++-- ...to-trait-obj-different-regions-id-trait.rs | 27 +++++++++++++++++++ ...rait-obj-different-regions-id-trait.stderr | 15 +++++++++++ 3 files changed, 47 insertions(+), 2 deletions(-) create mode 100644 tests/ui/cast/ptr-to-trait-obj-different-regions-id-trait.rs create mode 100644 tests/ui/cast/ptr-to-trait-obj-different-regions-id-trait.stderr diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 81ce741885203..6fd49c8027b00 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -2320,8 +2320,11 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { let cast_ty_to = CastTy::from_ty(*ty); match (cast_ty_from, cast_ty_to) { (Some(CastTy::Ptr(src)), Some(CastTy::Ptr(dst))) => { - let src_tail = tcx.struct_tail_without_normalization(src.ty); - let dst_tail = tcx.struct_tail_without_normalization(dst.ty); + let mut normalize = |t| self.normalize(t, location); + let src_tail = + tcx.struct_tail_with_normalize(src.ty, &mut normalize, || ()); + let dst_tail = + tcx.struct_tail_with_normalize(dst.ty, &mut normalize, || ()); // This checks (lifetime part of) vtable validity for pointer casts, // which is irrelevant when there are aren't principal traits on both sides (aka only auto traits). diff --git a/tests/ui/cast/ptr-to-trait-obj-different-regions-id-trait.rs b/tests/ui/cast/ptr-to-trait-obj-different-regions-id-trait.rs new file mode 100644 index 0000000000000..cdd55e243927c --- /dev/null +++ b/tests/ui/cast/ptr-to-trait-obj-different-regions-id-trait.rs @@ -0,0 +1,27 @@ +//@ check-fail +// +// Make sure we can't trick the compiler by using a projection. + +trait Cat<'a> {} +impl Cat<'_> for () {} + +trait Id { + type Id: ?Sized; +} +impl Id for T { + type Id = T; +} + +struct S { + tail: ::Id, +} + +fn m<'a>() { + let unsend: *const dyn Cat<'a> = &(); + let _send = unsend as *const S>; + //~^ error: lifetime may not live long enough +} + +fn main() { + m(); +} diff --git a/tests/ui/cast/ptr-to-trait-obj-different-regions-id-trait.stderr b/tests/ui/cast/ptr-to-trait-obj-different-regions-id-trait.stderr new file mode 100644 index 0000000000000..d1d598e603f18 --- /dev/null +++ b/tests/ui/cast/ptr-to-trait-obj-different-regions-id-trait.stderr @@ -0,0 +1,15 @@ +error: lifetime may not live long enough + --> $DIR/ptr-to-trait-obj-different-regions-id-trait.rs:21:17 + | +LL | fn m<'a>() { + | -- lifetime `'a` defined here +LL | let unsend: *const dyn Cat<'a> = &(); +LL | let _send = unsend as *const S>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static` + | + = note: requirement occurs because of the type `S>`, which makes the generic argument `dyn Cat<'_>` invariant + = note: the struct `S` is invariant over the parameter `T` + = help: see for more information about variance + +error: aborting due to 1 previous error + From 56de9da1f8bbde9dad8ed79dcf45f73e08f0354f Mon Sep 17 00:00:00 2001 From: Maybe Lapkin Date: Thu, 4 Jul 2024 18:38:18 +0200 Subject: [PATCH 705/892] Sort trait names before printing --- compiler/rustc_hir_typeck/src/cast.rs | 13 +++++++++---- tests/ui/cast/ptr-to-trait-obj-add-auto.rs | 2 +- tests/ui/cast/ptr-to-trait-obj-add-auto.stderr | 4 ++-- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/cast.rs b/compiler/rustc_hir_typeck/src/cast.rs index 887d124bd7a46..c78d9e578024d 100644 --- a/compiler/rustc_hir_typeck/src/cast.rs +++ b/compiler/rustc_hir_typeck/src/cast.rs @@ -897,10 +897,15 @@ impl<'a, 'tcx> CastCheck<'tcx> { self.span, errors::PtrCastAddAutoToObject { traits_len: added.len(), - traits: added - .into_iter() - .map(|trait_did| tcx.def_path_str(trait_did)) - .collect(), + traits: { + let mut traits: Vec<_> = added + .into_iter() + .map(|trait_did| tcx.def_path_str(trait_did)) + .collect(); + + traits.sort(); + traits.into() + }, }, ) } diff --git a/tests/ui/cast/ptr-to-trait-obj-add-auto.rs b/tests/ui/cast/ptr-to-trait-obj-add-auto.rs index 70293b28ee0ab..46e72ea08779c 100644 --- a/tests/ui/cast/ptr-to-trait-obj-add-auto.rs +++ b/tests/ui/cast/ptr-to-trait-obj-add-auto.rs @@ -11,7 +11,7 @@ fn add_auto<'a>(x: *mut dyn Trait<'a>) -> *mut (dyn Trait<'a> + Send) { // (to test diagnostic list formatting) fn add_multiple_auto<'a>(x: *mut dyn Trait<'a>) -> *mut (dyn Trait<'a> + Send + Sync + Unpin) { x as _ - //~^ warning: adding auto traits `Sync`, `Send`, and `Unpin` to a trait object in a pointer cast may cause UB later on + //~^ warning: adding auto traits `Send`, `Sync`, and `Unpin` to a trait object in a pointer cast may cause UB later on //~| warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! } diff --git a/tests/ui/cast/ptr-to-trait-obj-add-auto.stderr b/tests/ui/cast/ptr-to-trait-obj-add-auto.stderr index 175c5c981450d..e5ef8bf76b447 100644 --- a/tests/ui/cast/ptr-to-trait-obj-add-auto.stderr +++ b/tests/ui/cast/ptr-to-trait-obj-add-auto.stderr @@ -8,7 +8,7 @@ LL | x as _ = note: for more information, see issue #127323 = note: `#[warn(ptr_cast_add_auto_to_object)]` on by default -warning: adding auto traits `Sync`, `Send`, and `Unpin` to a trait object in a pointer cast may cause UB later on +warning: adding auto traits `Send`, `Sync`, and `Unpin` to a trait object in a pointer cast may cause UB later on --> $DIR/ptr-to-trait-obj-add-auto.rs:13:5 | LL | x as _ @@ -31,7 +31,7 @@ LL | x as _ = note: `#[warn(ptr_cast_add_auto_to_object)]` on by default Future breakage diagnostic: -warning: adding auto traits `Sync`, `Send`, and `Unpin` to a trait object in a pointer cast may cause UB later on +warning: adding auto traits `Send`, `Sync`, and `Unpin` to a trait object in a pointer cast may cause UB later on --> $DIR/ptr-to-trait-obj-add-auto.rs:13:5 | LL | x as _ From f11ab15e9af77b87a4d201eedb2e16f9947b6e85 Mon Sep 17 00:00:00 2001 From: Oneirical Date: Thu, 4 Jul 2024 11:58:49 -0400 Subject: [PATCH 706/892] rewrite pass-linker-flags to rmake --- .../tidy/src/allowed_run_make_makefiles.txt | 1 - tests/run-make/pass-linker-flags/Makefile | 5 ---- tests/run-make/pass-linker-flags/rmake.rs | 27 +++++++++++++++++++ 3 files changed, 27 insertions(+), 6 deletions(-) delete mode 100644 tests/run-make/pass-linker-flags/Makefile create mode 100644 tests/run-make/pass-linker-flags/rmake.rs diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index 2da4e476e9016..bdb20255dd98c 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -108,7 +108,6 @@ run-make/output-type-permutations/Makefile run-make/panic-abort-eh_frame/Makefile run-make/pass-linker-flags-flavor/Makefile run-make/pass-linker-flags-from-dep/Makefile -run-make/pass-linker-flags/Makefile run-make/pass-non-c-like-enum-to-c/Makefile run-make/pdb-buildinfo-cl-cmd/Makefile run-make/pgo-gen-lto/Makefile diff --git a/tests/run-make/pass-linker-flags/Makefile b/tests/run-make/pass-linker-flags/Makefile deleted file mode 100644 index 226943e93bdc0..0000000000000 --- a/tests/run-make/pass-linker-flags/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -include ../tools.mk - -all: - $(RUSTC) empty.rs -Z unstable-options -l static=l1 -l link-arg=a1 -l static=l2 -l link-arg=a2 -l dylib=d1 -l link-arg=a3 --print link-args | $(CGREP) -e 'l1.*a1.*l2.*a2.*d1.*a3' - $(RUSTC) attribute.rs --print link-args | $(CGREP) -e 'l1.*a1.*l2.*a2.*d1.*a3' diff --git a/tests/run-make/pass-linker-flags/rmake.rs b/tests/run-make/pass-linker-flags/rmake.rs new file mode 100644 index 0000000000000..cc6c5d066de9b --- /dev/null +++ b/tests/run-make/pass-linker-flags/rmake.rs @@ -0,0 +1,27 @@ +// This test checks the proper function of `-l link-arg=NAME`, which, unlike +// -C link-arg, is supposed to guarantee that the order relative to other -l +// options will be respected. In this test, compilation fails (because none of the +// link arguments like `a1` exist), but it is still checked if the output contains the +// link arguments in the exact order they were passed in. `attribute.rs` is a variant +// of the test where the flags are defined in the rust file itself. +// See https://github.com/rust-lang/rust/issues/99427 + +use run_make_support::{regex, rustc}; + +fn main() { + let out = rustc() + .input("empty.rs") + .arg("-Zunstable-options") + .args(&["-l", "static=l1"]) + .arg("-llink-arg=a1") + .arg("-lstatic=l2") + .arg("-llink-arg=a2") + .arg("-ldylib=d1") + .arg("-llink-arg=a3") + .print("link-args") + .run_unchecked() + .stdout_utf8(); + let out2 = rustc().input("attribute.rs").print("link-args").run_unchecked().stdout_utf8(); + let re = regex::Regex::new("l1.*a1.*l2.*a2.*d1.*a3").unwrap(); + assert!(re.is_match(&out) && re.is_match(&out2)); +} From bc765929fbc61c381440175ad93b3a44e1c324a1 Mon Sep 17 00:00:00 2001 From: Oneirical Date: Thu, 4 Jul 2024 13:16:11 -0400 Subject: [PATCH 707/892] rewrite pass-linker-flags-flavor to rmake --- .../tidy/src/allowed_run_make_makefiles.txt | 1 - .../pass-linker-flags-flavor/Makefile | 11 --- .../pass-linker-flags-flavor/rmake.rs | 83 +++++++++++++++++++ tests/run-make/pass-linker-flags/rmake.rs | 5 +- 4 files changed, 86 insertions(+), 14 deletions(-) delete mode 100644 tests/run-make/pass-linker-flags-flavor/Makefile create mode 100644 tests/run-make/pass-linker-flags-flavor/rmake.rs diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index bdb20255dd98c..1520075287987 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -106,7 +106,6 @@ run-make/optimization-remarks-dir-pgo/Makefile run-make/optimization-remarks-dir/Makefile run-make/output-type-permutations/Makefile run-make/panic-abort-eh_frame/Makefile -run-make/pass-linker-flags-flavor/Makefile run-make/pass-linker-flags-from-dep/Makefile run-make/pass-non-c-like-enum-to-c/Makefile run-make/pdb-buildinfo-cl-cmd/Makefile diff --git a/tests/run-make/pass-linker-flags-flavor/Makefile b/tests/run-make/pass-linker-flags-flavor/Makefile deleted file mode 100644 index 1bb05d0f97478..0000000000000 --- a/tests/run-make/pass-linker-flags-flavor/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -# only-linux - -include ../tools.mk - -all: - $(RUSTC) empty.rs -Z unstable-options -C linker-flavor=gnu-cc -l static=l1 -l link-arg=a1 -l static=l2 -l link-arg=a2 -l dylib=d1 -l link-arg=a3 --print link-args | $(CGREP) -e 'l1.*-Wl,a1.*l2.*-Wl,a2.*d1.*-Wl,a3' - $(RUSTC) empty.rs -Z unstable-options -C linker-flavor=gnu-cc -l static=l1 -l link-arg:+verbatim=a1 -l static=l2 -l link-arg=a2 -l dylib=d1 -l link-arg=a3 --print link-args | $(CGREP) -e 'l1.*"a1".*l2.*-Wl,a2.*d1.*-Wl,a3' - $(RUSTC) empty.rs -Z unstable-options -C linker-flavor=ld -l static=l1 -l link-arg=a1 -l static=l2 -l link-arg=a2 -l dylib=d1 -l link-arg=a3 --print link-args | $(CGREP) -e 'l1.*"a1".*l2.*"a2".*d1.*"a3"' - $(RUSTC) attribute.rs -Z unstable-options -C linker-flavor=gnu-cc --print link-args | $(CGREP) -e 'l1.*-Wl,a1.*l2.*-Wl,a2.*d1.*-Wl,a3' - $(RUSTC) --cfg 'feature="verbatim"' attribute.rs -Z unstable-options -C linker-flavor=gnu-cc --print link-args | $(CGREP) -e 'l1.*"a1".*l2.*-Wl,a2.*d1.*-Wl,a3' - $(RUSTC) attribute.rs -C linker-flavor=ld --print link-args | $(CGREP) -e 'l1.*"a1".*l2.*"a2".*d1.*"a3"' diff --git a/tests/run-make/pass-linker-flags-flavor/rmake.rs b/tests/run-make/pass-linker-flags-flavor/rmake.rs new file mode 100644 index 0000000000000..9efb89cea092a --- /dev/null +++ b/tests/run-make/pass-linker-flags-flavor/rmake.rs @@ -0,0 +1,83 @@ +// Setting the linker flavor as a C compiler should cause the output of the -l flags to be +// prefixed by -Wl, except when a flag is requested to be verbatim. A bare linker (ld) should +// never cause prefixes to appear in the output. This test checks this ruleset twice, once with +// explicit flags and then with those flags passed inside the rust source code. +// See https://github.com/rust-lang/rust/pull/118202 + +//FIXME(Oneirical): only-linux + +use run_make_support::{regex, rustc}; + +fn main() { + let out_gnu = rustc() + .input("empty.rs") + .linker_flavor("gnu-cc") + .arg("-Zunstable-options") + .arg("-lstatic=l1") + .arg("-llink-arg=a1") + .arg("-lstatic=l2") + .arg("-llink-arg=a2") + .arg("-ldylib=d1") + .arg("-llink-arg=a3") + .print("link-args") + .run_unchecked() + .stdout_utf8(); + let out_gnu_verbatim = rustc() + .input("empty.rs") + .linker_flavor("gnu-cc") + .arg("-Zunstable-options") + .arg("-lstatic=l1") + .arg("-llink-arg:+verbatim=a1") + .arg("-lstatic=l2") + .arg("-llink-arg=a2") + .arg("-ldylib=d1") + .arg("-llink-arg=a3") + .print("link-args") + .run_unchecked() + .stdout_utf8(); + let out_ld = rustc() + .input("empty.rs") + .linker_flavor("ld") + .arg("-Zunstable-options") + .arg("-lstatic=l1") + .arg("-llink-arg=a1") + .arg("-lstatic=l2") + .arg("-llink-arg=a2") + .arg("-ldylib=d1") + .arg("-llink-arg=a3") + .print("link-args") + .run_unchecked() + .stdout_utf8(); + let out_att_gnu = rustc() + .arg("-Zunstable-options") + .linker_flavor("gnu-cc") + .input("attribute.rs") + .print("link-args") + .run_unchecked() + .stdout_utf8(); + let out_att_gnu_verbatim = rustc() + .cfg(r#"feature="verbatim""#) + .arg("-Zunstable-options") + .linker_flavor("gnu-cc") + .input("attribute.rs") + .print("link-args") + .run_unchecked() + .stdout_utf8(); + let out_att_ld = rustc() + .linker_flavor("ld") + .input("attribute.rs") + .print("link-args") + .run_unchecked() + .stdout_utf8(); + + let no_verbatim = regex::Regex::new("l1.*-Wl,a1.*l2.*-Wl,a2.*d1.*-Wl,a3").unwrap(); + let one_verbatim = regex::Regex::new(r#"l1.*"a1".*l2.*-Wl,a2.*d1.*-Wl,a3"#).unwrap(); + let ld = regex::Regex::new(r#"l1.*"a1".*l2.*"a2".*d1.*"a3""#).unwrap(); + + assert!(no_verbatim.is_match(&out_gnu)); + assert!(no_verbatim.is_match(&out_att_gnu)); + assert!(one_verbatim.is_match(&out_gnu_verbatim)); + assert!(one_verbatim.is_match(&out_att_gnu_verbatim)); + assert!(ld.is_match(&out_ld)); + assert!(ld.is_match(&out_att_ld)); +} diff --git a/tests/run-make/pass-linker-flags/rmake.rs b/tests/run-make/pass-linker-flags/rmake.rs index cc6c5d066de9b..de69567a6e60c 100644 --- a/tests/run-make/pass-linker-flags/rmake.rs +++ b/tests/run-make/pass-linker-flags/rmake.rs @@ -12,7 +12,7 @@ fn main() { let out = rustc() .input("empty.rs") .arg("-Zunstable-options") - .args(&["-l", "static=l1"]) + .arg("-lstatic=l1") .arg("-llink-arg=a1") .arg("-lstatic=l2") .arg("-llink-arg=a2") @@ -23,5 +23,6 @@ fn main() { .stdout_utf8(); let out2 = rustc().input("attribute.rs").print("link-args").run_unchecked().stdout_utf8(); let re = regex::Regex::new("l1.*a1.*l2.*a2.*d1.*a3").unwrap(); - assert!(re.is_match(&out) && re.is_match(&out2)); + assert!(re.is_match(&out)); + assert!(re.is_match(&out2)); } From eb19e8106b5828085a46aa0b86206459c293fa70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Thu, 4 Jul 2024 23:44:10 +0200 Subject: [PATCH 708/892] crashes: add latest --- tests/crashes/126896.rs | 17 +++++++++++++++++ tests/crashes/126939.rs | 21 +++++++++++++++++++++ tests/crashes/126942.rs | 11 +++++++++++ tests/crashes/126944.rs | 38 ++++++++++++++++++++++++++++++++++++++ tests/crashes/126966.rs | 29 +++++++++++++++++++++++++++++ tests/crashes/126969.rs | 9 +++++++++ tests/crashes/126982.rs | 18 ++++++++++++++++++ tests/crashes/127222.rs | 3 +++ tests/crashes/127266.rs | 17 +++++++++++++++++ tests/crashes/127299.rs | 12 ++++++++++++ tests/crashes/127304.rs | 20 ++++++++++++++++++++ tests/crashes/127332.rs | 9 +++++++++ 12 files changed, 204 insertions(+) create mode 100644 tests/crashes/126896.rs create mode 100644 tests/crashes/126939.rs create mode 100644 tests/crashes/126942.rs create mode 100644 tests/crashes/126944.rs create mode 100644 tests/crashes/126966.rs create mode 100644 tests/crashes/126969.rs create mode 100644 tests/crashes/126982.rs create mode 100644 tests/crashes/127222.rs create mode 100644 tests/crashes/127266.rs create mode 100644 tests/crashes/127299.rs create mode 100644 tests/crashes/127304.rs create mode 100644 tests/crashes/127332.rs diff --git a/tests/crashes/126896.rs b/tests/crashes/126896.rs new file mode 100644 index 0000000000000..35bf9d5207ac1 --- /dev/null +++ b/tests/crashes/126896.rs @@ -0,0 +1,17 @@ +//@ known-bug: rust-lang/rust#126896 +//@ compile-flags: -Zpolymorphize=on -Zinline-mir=yes + +#![feature(type_alias_impl_trait)] +type Two<'a, 'b> = impl std::fmt::Debug; + +fn set(x: &mut isize) -> isize { + *x +} + +fn d(x: Two) { + let c1 = || set(x); + c1; +} + +fn main() { +} diff --git a/tests/crashes/126939.rs b/tests/crashes/126939.rs new file mode 100644 index 0000000000000..1edf748460604 --- /dev/null +++ b/tests/crashes/126939.rs @@ -0,0 +1,21 @@ +//@ known-bug: rust-lang/rust#126939 + +struct MySlice(bool, T); +type MySliceBool = MySlice<[bool]>; + +use std::mem; + +struct P2 { + a: T, + b: MySliceBool, +} + +macro_rules! check { + ($t:ty, $align:expr) => ({ + assert_eq!(mem::align_of::<$t>(), $align); + }); +} + +pub fn main() { + check!(P2, 1); +} diff --git a/tests/crashes/126942.rs b/tests/crashes/126942.rs new file mode 100644 index 0000000000000..e4adc8fab287e --- /dev/null +++ b/tests/crashes/126942.rs @@ -0,0 +1,11 @@ +//@ known-bug: rust-lang/rust#126942 +struct Thing; + +pub trait Every { + type Assoc; +} +impl Every for Thing { + type Assoc = T; +} + +static I: ::Assoc = 3; diff --git a/tests/crashes/126944.rs b/tests/crashes/126944.rs new file mode 100644 index 0000000000000..c0c5622e26020 --- /dev/null +++ b/tests/crashes/126944.rs @@ -0,0 +1,38 @@ +//@ known-bug: rust-lang/rust#126944 +// Step 1: Create two names for a single type: `Thing` and `AlsoThing` + +struct Thing; +struct Dummy; +pub trait DummyTrait { + type DummyType; +} +impl DummyTrait for Dummy { + type DummyType = Thing; +} +type AlsoThing = ::DummyType; + +// Step 2: Create names for a single trait object type: `TraitObject` and `AlsoTraitObject` + +pub trait SomeTrait { + type Item; +} +type TraitObject = dyn SomeTrait; +type AlsoTraitObject = dyn SomeTrait; + +// Step 3: Force the compiler to check whether the two names are the same type + +pub trait Supertrait { + type Foo; +} +pub trait Subtrait: Supertrait {} + +pub trait HasOutput { + type Output; +} + +fn foo() -> F::Output +where + F: HasOutput>, +{ + todo!() +} diff --git a/tests/crashes/126966.rs b/tests/crashes/126966.rs new file mode 100644 index 0000000000000..edeedc68c40d7 --- /dev/null +++ b/tests/crashes/126966.rs @@ -0,0 +1,29 @@ +//@ known-bug: rust-lang/rust#126966 +mod assert { + use std::mem::{Assume, BikeshedIntrinsicFrom}; + + pub fn is_transmutable() + where + Dst: BikeshedIntrinsicFrom, + { + } +} + +#[repr(u32)] +enum Ox00 { + V = 0x00, +} + +#[repr(C, packed(2))] +enum OxFF { + V = 0xFF, +} + +fn test() { + union Superset { + a: Ox00, + b: OxFF, + } + + assert::is_transmutable::(); +} diff --git a/tests/crashes/126969.rs b/tests/crashes/126969.rs new file mode 100644 index 0000000000000..676563d059caf --- /dev/null +++ b/tests/crashes/126969.rs @@ -0,0 +1,9 @@ +//@ known-bug: rust-lang/rust#126969 + +struct S { + _: union { t: T }, +} + +fn f(S::<&i8> { .. }: S<&i8>) {} + +fn main() {} diff --git a/tests/crashes/126982.rs b/tests/crashes/126982.rs new file mode 100644 index 0000000000000..8522d9415eb88 --- /dev/null +++ b/tests/crashes/126982.rs @@ -0,0 +1,18 @@ +//@ known-bug: rust-lang/rust#126982 + +#![feature(coerce_unsized)] +use std::ops::CoerceUnsized; + +struct Foo { + a: T, +} + +impl CoerceUnsized for Foo {} + +union U { + a: usize, +} + +const C: U = Foo { a: 10 }; + +fn main() {} diff --git a/tests/crashes/127222.rs b/tests/crashes/127222.rs new file mode 100644 index 0000000000000..eda0ea3d9b729 --- /dev/null +++ b/tests/crashes/127222.rs @@ -0,0 +1,3 @@ +//@ known-bug: rust-lang/rust#127222 +#[marker] +trait Foo = PartialEq + Send; diff --git a/tests/crashes/127266.rs b/tests/crashes/127266.rs new file mode 100644 index 0000000000000..2bdbe03e373a9 --- /dev/null +++ b/tests/crashes/127266.rs @@ -0,0 +1,17 @@ +//@ known-bug: rust-lang/rust#127266 +#![feature(const_mut_refs)] +#![feature(const_refs_to_static)] + +struct Meh { + x: &'static dyn UnsafeCell, +} + +const MUH: Meh = Meh { + x: &mut *(READONLY as *mut _), +}; + +static READONLY: i32 = 0; + +trait UnsafeCell<'a> {} + +pub fn main() {} diff --git a/tests/crashes/127299.rs b/tests/crashes/127299.rs new file mode 100644 index 0000000000000..7eb78387997ab --- /dev/null +++ b/tests/crashes/127299.rs @@ -0,0 +1,12 @@ +//@ known-bug: rust-lang/rust#127299 +trait Qux { + fn bar() -> i32; +} + +pub struct Lint { + pub desc: &'static Qux, +} + +static FOO: &Lint = &Lint { desc: "desc" }; + +fn main() {} diff --git a/tests/crashes/127304.rs b/tests/crashes/127304.rs new file mode 100644 index 0000000000000..2975fc27f6766 --- /dev/null +++ b/tests/crashes/127304.rs @@ -0,0 +1,20 @@ +//@ known-bug: rust-lang/rust #127304 +#![feature(adt_const_params)] + +trait Trait {} +impl Trait for () {} + +struct MyStr(str); +impl std::marker::ConstParamTy for MyStr {} + +fn function_with_my_str() -> &'static MyStr { + S +} + +impl MyStr { + const fn new(s: &Trait str) -> &'static MyStr {} +} + +pub fn main() { + let f = function_with_my_str::<{ MyStr::new("hello") }>(); +} diff --git a/tests/crashes/127332.rs b/tests/crashes/127332.rs new file mode 100644 index 0000000000000..5c14af01cece8 --- /dev/null +++ b/tests/crashes/127332.rs @@ -0,0 +1,9 @@ +//@ known-bug: rust-lang/rust #127332 + +async fn fun() { + enum Foo { + A { x: u32 }, + } + let orig = Foo::A { x: 5 }; + Foo::A { x: 6, ..orig }; +} From dd790ab8ef8cc2a89f04f2be73c86230595a48a3 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 4 Jul 2024 17:50:53 +1000 Subject: [PATCH 709/892] Remove some unnecessary integer conversions. These should have been removed in #127233 when the positions were changed from `usize` to `u32`. --- compiler/rustc_parse/src/parser/attr.rs | 4 ++-- compiler/rustc_parse/src/parser/attr_wrapper.rs | 4 +--- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_parse/src/parser/attr.rs b/compiler/rustc_parse/src/parser/attr.rs index 58fef9b6c4562..1d31669d2074e 100644 --- a/compiler/rustc_parse/src/parser/attr.rs +++ b/compiler/rustc_parse/src/parser/attr.rs @@ -282,7 +282,7 @@ impl<'a> Parser<'a> { pub fn parse_inner_attributes(&mut self) -> PResult<'a, ast::AttrVec> { let mut attrs = ast::AttrVec::new(); loop { - let start_pos: u32 = self.num_bump_calls.try_into().unwrap(); + let start_pos = self.num_bump_calls; // Only try to parse if it is an inner attribute (has `!`). let attr = if self.check(&token::Pound) && self.look_ahead(1, |t| t == &token::Not) { Some(self.parse_attribute(InnerAttrPolicy::Permitted)?) @@ -303,7 +303,7 @@ impl<'a> Parser<'a> { None }; if let Some(attr) = attr { - let end_pos: u32 = self.num_bump_calls.try_into().unwrap(); + let end_pos = self.num_bump_calls; // If we are currently capturing tokens, mark the location of this inner attribute. // If capturing ends up creating a `LazyAttrTokenStream`, we will include // this replace range with it, removing the inner attribute from the final diff --git a/compiler/rustc_parse/src/parser/attr_wrapper.rs b/compiler/rustc_parse/src/parser/attr_wrapper.rs index 13a647adfe3b5..53565ffe2c903 100644 --- a/compiler/rustc_parse/src/parser/attr_wrapper.rs +++ b/compiler/rustc_parse/src/parser/attr_wrapper.rs @@ -8,7 +8,6 @@ use rustc_errors::PResult; use rustc_session::parse::ParseSess; use rustc_span::{sym, Span, DUMMY_SP}; -use std::ops::Range; use std::{iter, mem}; /// A wrapper type to ensure that the parser handles outer attributes correctly. @@ -356,8 +355,7 @@ impl<'a> Parser<'a> { let new_tokens = vec![(FlatToken::AttrTarget(attr_data), Spacing::Alone)]; assert!(!self.break_last_token, "Should not have unglued last token with cfg attr"); - let range: Range = (start_pos.try_into().unwrap())..(end_pos.try_into().unwrap()); - self.capture_state.replace_ranges.push((range, new_tokens)); + self.capture_state.replace_ranges.push((start_pos..end_pos, new_tokens)); self.capture_state.replace_ranges.extend(inner_attr_replace_ranges); } From 86a19467c1da6eb9353ad878979a8f74a8b5b230 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Fri, 5 Jul 2024 00:52:01 +0000 Subject: [PATCH 710/892] Tweak `-1 as usize` suggestion When writing a negative unsigned integer literal, use a verbose suggestion and account for `as` casting. --- compiler/rustc_hir_typeck/src/op.rs | 13 +++++++-- .../feature-gate-negate-unsigned.stderr | 9 ++++--- tests/ui/unsigned-literal-negation.stderr | 27 ++++++++++--------- 3 files changed, 31 insertions(+), 18 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/op.rs b/compiler/rustc_hir_typeck/src/op.rs index 5a11cb7096f33..7264bc5a78d82 100644 --- a/compiler/rustc_hir_typeck/src/op.rs +++ b/compiler/rustc_hir_typeck/src/op.rs @@ -838,8 +838,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }, ) = ex.kind { - err.span_suggestion( - ex.span, + let span = if let hir::Node::Expr(parent) = + self.tcx.parent_hir_node(ex.hir_id) + && let hir::ExprKind::Cast(..) = parent.kind + { + // `-1 as usize` -> `usize::MAX` + parent.span + } else { + ex.span + }; + err.span_suggestion_verbose( + span, format!( "you may have meant the maximum value of `{actual}`", ), diff --git a/tests/ui/feature-gates/feature-gate-negate-unsigned.stderr b/tests/ui/feature-gates/feature-gate-negate-unsigned.stderr index d1f4ed5cb04b8..696326157ce29 100644 --- a/tests/ui/feature-gates/feature-gate-negate-unsigned.stderr +++ b/tests/ui/feature-gates/feature-gate-negate-unsigned.stderr @@ -2,12 +2,13 @@ error[E0600]: cannot apply unary operator `-` to type `usize` --> $DIR/feature-gate-negate-unsigned.rs:10:23 | LL | let _max: usize = -1; - | ^^ - | | - | cannot apply unary operator `-` - | help: you may have meant the maximum value of `usize`: `usize::MAX` + | ^^ cannot apply unary operator `-` | = note: unsigned values cannot be negated +help: you may have meant the maximum value of `usize` + | +LL | let _max: usize = usize::MAX; + | ~~~~~~~~~~ error[E0600]: cannot apply unary operator `-` to type `u8` --> $DIR/feature-gate-negate-unsigned.rs:14:14 diff --git a/tests/ui/unsigned-literal-negation.stderr b/tests/ui/unsigned-literal-negation.stderr index 0aaa8c3b72f9d..b0a730477a1b0 100644 --- a/tests/ui/unsigned-literal-negation.stderr +++ b/tests/ui/unsigned-literal-negation.stderr @@ -2,34 +2,37 @@ error[E0600]: cannot apply unary operator `-` to type `usize` --> $DIR/unsigned-literal-negation.rs:2:13 | LL | let x = -1 as usize; - | ^^ - | | - | cannot apply unary operator `-` - | help: you may have meant the maximum value of `usize`: `usize::MAX` + | ^^ cannot apply unary operator `-` | = note: unsigned values cannot be negated +help: you may have meant the maximum value of `usize` + | +LL | let x = usize::MAX; + | ~~~~~~~~~~ error[E0600]: cannot apply unary operator `-` to type `usize` --> $DIR/unsigned-literal-negation.rs:3:13 | LL | let x = (-1) as usize; - | ^^^^ - | | - | cannot apply unary operator `-` - | help: you may have meant the maximum value of `usize`: `usize::MAX` + | ^^^^ cannot apply unary operator `-` | = note: unsigned values cannot be negated +help: you may have meant the maximum value of `usize` + | +LL | let x = usize::MAX; + | ~~~~~~~~~~ error[E0600]: cannot apply unary operator `-` to type `u32` --> $DIR/unsigned-literal-negation.rs:4:18 | LL | let x: u32 = -1; - | ^^ - | | - | cannot apply unary operator `-` - | help: you may have meant the maximum value of `u32`: `u32::MAX` + | ^^ cannot apply unary operator `-` | = note: unsigned values cannot be negated +help: you may have meant the maximum value of `u32` + | +LL | let x: u32 = u32::MAX; + | ~~~~~~~~ error: aborting due to 3 previous errors From c147805a6ab62ae52df7fb79067a05358d95fe72 Mon Sep 17 00:00:00 2001 From: Jubilee Young Date: Mon, 24 Jun 2024 13:57:06 -0700 Subject: [PATCH 711/892] library: outline VaList into ffi::va_list and reexport --- library/core/src/ffi/mod.rs | 414 ++------------------------------ library/core/src/ffi/va_list.rs | 407 +++++++++++++++++++++++++++++++ src/tools/tidy/src/pal.rs | 2 + 3 files changed, 423 insertions(+), 400 deletions(-) create mode 100644 library/core/src/ffi/va_list.rs diff --git a/library/core/src/ffi/mod.rs b/library/core/src/ffi/mod.rs index 6d1f10f521176..88adc378477fd 100644 --- a/library/core/src/ffi/mod.rs +++ b/library/core/src/ffi/mod.rs @@ -10,8 +10,6 @@ #![allow(non_camel_case_types)] use crate::fmt; -use crate::marker::PhantomData; -use crate::ops::{Deref, DerefMut}; #[doc(no_inline)] #[stable(feature = "core_c_str", since = "1.64.0")] @@ -28,6 +26,20 @@ pub use self::c_str::CStr; #[unstable(feature = "c_str_module", issue = "112134")] pub mod c_str; +#[unstable( + feature = "c_variadic", + issue = "44930", + reason = "the `c_variadic` feature has not been properly tested on all supported platforms" +)] +pub use self::va_list::{VaList, VaListImpl}; + +#[unstable( + feature = "c_variadic", + issue = "44930", + reason = "the `c_variadic` feature has not been properly tested on all supported platforms" +)] +pub mod va_list; + macro_rules! type_alias { { $Docfile:tt, $Alias:ident = $Real:ty; @@ -205,404 +217,6 @@ impl fmt::Debug for c_void { } } -/// Basic implementation of a `va_list`. -// The name is WIP, using `VaListImpl` for now. -#[cfg(any( - all( - not(target_arch = "aarch64"), - not(target_arch = "powerpc"), - not(target_arch = "s390x"), - not(target_arch = "x86_64") - ), - all(target_arch = "aarch64", target_vendor = "apple"), - target_family = "wasm", - target_os = "uefi", - windows, -))] -#[cfg_attr(not(doc), repr(transparent))] // work around https://github.com/rust-lang/rust/issues/90435 -#[unstable( - feature = "c_variadic", - reason = "the `c_variadic` feature has not been properly tested on \ - all supported platforms", - issue = "44930" -)] -#[lang = "va_list"] -pub struct VaListImpl<'f> { - ptr: *mut c_void, - - // Invariant over `'f`, so each `VaListImpl<'f>` object is tied to - // the region of the function it's defined in - _marker: PhantomData<&'f mut &'f c_void>, -} - -#[cfg(any( - all( - not(target_arch = "aarch64"), - not(target_arch = "powerpc"), - not(target_arch = "s390x"), - not(target_arch = "x86_64") - ), - all(target_arch = "aarch64", target_vendor = "apple"), - target_family = "wasm", - target_os = "uefi", - windows, -))] -#[unstable( - feature = "c_variadic", - reason = "the `c_variadic` feature has not been properly tested on \ - all supported platforms", - issue = "44930" -)] -impl<'f> fmt::Debug for VaListImpl<'f> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "va_list* {:p}", self.ptr) - } -} - -/// AArch64 ABI implementation of a `va_list`. See the -/// [AArch64 Procedure Call Standard] for more details. -/// -/// [AArch64 Procedure Call Standard]: -/// http://infocenter.arm.com/help/topic/com.arm.doc.ihi0055b/IHI0055B_aapcs64.pdf -#[cfg(all( - target_arch = "aarch64", - not(target_vendor = "apple"), - not(target_os = "uefi"), - not(windows), -))] -#[cfg_attr(not(doc), repr(C))] // work around https://github.com/rust-lang/rust/issues/66401 -#[derive(Debug)] -#[unstable( - feature = "c_variadic", - reason = "the `c_variadic` feature has not been properly tested on \ - all supported platforms", - issue = "44930" -)] -#[lang = "va_list"] -pub struct VaListImpl<'f> { - stack: *mut c_void, - gr_top: *mut c_void, - vr_top: *mut c_void, - gr_offs: i32, - vr_offs: i32, - _marker: PhantomData<&'f mut &'f c_void>, -} - -/// PowerPC ABI implementation of a `va_list`. -#[cfg(all(target_arch = "powerpc", not(target_os = "uefi"), not(windows)))] -#[cfg_attr(not(doc), repr(C))] // work around https://github.com/rust-lang/rust/issues/66401 -#[derive(Debug)] -#[unstable( - feature = "c_variadic", - reason = "the `c_variadic` feature has not been properly tested on \ - all supported platforms", - issue = "44930" -)] -#[lang = "va_list"] -pub struct VaListImpl<'f> { - gpr: u8, - fpr: u8, - reserved: u16, - overflow_arg_area: *mut c_void, - reg_save_area: *mut c_void, - _marker: PhantomData<&'f mut &'f c_void>, -} - -/// s390x ABI implementation of a `va_list`. -#[cfg(target_arch = "s390x")] -#[cfg_attr(not(doc), repr(C))] // work around https://github.com/rust-lang/rust/issues/66401 -#[derive(Debug)] -#[unstable( - feature = "c_variadic", - reason = "the `c_variadic` feature has not been properly tested on \ - all supported platforms", - issue = "44930" -)] -#[lang = "va_list"] -pub struct VaListImpl<'f> { - gpr: i64, - fpr: i64, - overflow_arg_area: *mut c_void, - reg_save_area: *mut c_void, - _marker: PhantomData<&'f mut &'f c_void>, -} - -/// x86_64 ABI implementation of a `va_list`. -#[cfg(all(target_arch = "x86_64", not(target_os = "uefi"), not(windows)))] -#[cfg_attr(not(doc), repr(C))] // work around https://github.com/rust-lang/rust/issues/66401 -#[derive(Debug)] -#[unstable( - feature = "c_variadic", - reason = "the `c_variadic` feature has not been properly tested on \ - all supported platforms", - issue = "44930" -)] -#[lang = "va_list"] -pub struct VaListImpl<'f> { - gp_offset: i32, - fp_offset: i32, - overflow_arg_area: *mut c_void, - reg_save_area: *mut c_void, - _marker: PhantomData<&'f mut &'f c_void>, -} - -/// A wrapper for a `va_list` -#[cfg_attr(not(doc), repr(transparent))] // work around https://github.com/rust-lang/rust/issues/90435 -#[derive(Debug)] -#[unstable( - feature = "c_variadic", - reason = "the `c_variadic` feature has not been properly tested on \ - all supported platforms", - issue = "44930" -)] -pub struct VaList<'a, 'f: 'a> { - #[cfg(any( - all( - not(target_arch = "aarch64"), - not(target_arch = "powerpc"), - not(target_arch = "s390x"), - not(target_arch = "x86_64") - ), - all(target_arch = "aarch64", target_vendor = "apple"), - target_family = "wasm", - target_os = "uefi", - windows, - ))] - inner: VaListImpl<'f>, - - #[cfg(all( - any( - target_arch = "aarch64", - target_arch = "powerpc", - target_arch = "s390x", - target_arch = "x86_64" - ), - any(not(target_arch = "aarch64"), not(target_vendor = "apple")), - not(target_family = "wasm"), - not(target_os = "uefi"), - not(windows), - ))] - inner: &'a mut VaListImpl<'f>, - - _marker: PhantomData<&'a mut VaListImpl<'f>>, -} - -#[cfg(any( - all( - not(target_arch = "aarch64"), - not(target_arch = "powerpc"), - not(target_arch = "s390x"), - not(target_arch = "x86_64") - ), - all(target_arch = "aarch64", target_vendor = "apple"), - target_family = "wasm", - target_os = "uefi", - windows, -))] -#[unstable( - feature = "c_variadic", - reason = "the `c_variadic` feature has not been properly tested on \ - all supported platforms", - issue = "44930" -)] -impl<'f> VaListImpl<'f> { - /// Convert a `VaListImpl` into a `VaList` that is binary-compatible with C's `va_list`. - #[inline] - pub fn as_va_list<'a>(&'a mut self) -> VaList<'a, 'f> { - VaList { inner: VaListImpl { ..*self }, _marker: PhantomData } - } -} - -#[cfg(all( - any( - target_arch = "aarch64", - target_arch = "powerpc", - target_arch = "s390x", - target_arch = "x86_64" - ), - any(not(target_arch = "aarch64"), not(target_vendor = "apple")), - not(target_family = "wasm"), - not(target_os = "uefi"), - not(windows), -))] -#[unstable( - feature = "c_variadic", - reason = "the `c_variadic` feature has not been properly tested on \ - all supported platforms", - issue = "44930" -)] -impl<'f> VaListImpl<'f> { - /// Convert a `VaListImpl` into a `VaList` that is binary-compatible with C's `va_list`. - #[inline] - pub fn as_va_list<'a>(&'a mut self) -> VaList<'a, 'f> { - VaList { inner: self, _marker: PhantomData } - } -} - -#[unstable( - feature = "c_variadic", - reason = "the `c_variadic` feature has not been properly tested on \ - all supported platforms", - issue = "44930" -)] -impl<'a, 'f: 'a> Deref for VaList<'a, 'f> { - type Target = VaListImpl<'f>; - - #[inline] - fn deref(&self) -> &VaListImpl<'f> { - &self.inner - } -} - -#[unstable( - feature = "c_variadic", - reason = "the `c_variadic` feature has not been properly tested on \ - all supported platforms", - issue = "44930" -)] -impl<'a, 'f: 'a> DerefMut for VaList<'a, 'f> { - #[inline] - fn deref_mut(&mut self) -> &mut VaListImpl<'f> { - &mut self.inner - } -} - -// The VaArgSafe trait needs to be used in public interfaces, however, the trait -// itself must not be allowed to be used outside this module. Allowing users to -// implement the trait for a new type (thereby allowing the va_arg intrinsic to -// be used on a new type) is likely to cause undefined behavior. -// -// FIXME(dlrobertson): In order to use the VaArgSafe trait in a public interface -// but also ensure it cannot be used elsewhere, the trait needs to be public -// within a private module. Once RFC 2145 has been implemented look into -// improving this. -mod sealed_trait { - /// Trait which permits the allowed types to be used with [super::VaListImpl::arg]. - #[unstable( - feature = "c_variadic", - reason = "the `c_variadic` feature has not been properly tested on \ - all supported platforms", - issue = "44930" - )] - pub unsafe trait VaArgSafe {} -} - -macro_rules! impl_va_arg_safe { - ($($t:ty),+) => { - $( - #[unstable(feature = "c_variadic", - reason = "the `c_variadic` feature has not been properly tested on \ - all supported platforms", - issue = "44930")] - unsafe impl sealed_trait::VaArgSafe for $t {} - )+ - } -} - -impl_va_arg_safe! {i8, i16, i32, i64, usize} -impl_va_arg_safe! {u8, u16, u32, u64, isize} -impl_va_arg_safe! {f64} - -#[unstable( - feature = "c_variadic", - reason = "the `c_variadic` feature has not been properly tested on \ - all supported platforms", - issue = "44930" -)] -unsafe impl sealed_trait::VaArgSafe for *mut T {} - -#[unstable( - feature = "c_variadic", - reason = "the `c_variadic` feature has not been properly tested on \ - all supported platforms", - issue = "44930" -)] -unsafe impl sealed_trait::VaArgSafe for *const T {} - -#[unstable( - feature = "c_variadic", - reason = "the `c_variadic` feature has not been properly tested on \ - all supported platforms", - issue = "44930" -)] -impl<'f> VaListImpl<'f> { - /// Advance to the next arg. - #[inline] - pub unsafe fn arg(&mut self) -> T { - // SAFETY: the caller must uphold the safety contract for `va_arg`. - unsafe { va_arg(self) } - } - - /// Copies the `va_list` at the current location. - pub unsafe fn with_copy(&self, f: F) -> R - where - F: for<'copy> FnOnce(VaList<'copy, 'f>) -> R, - { - let mut ap = self.clone(); - let ret = f(ap.as_va_list()); - // SAFETY: the caller must uphold the safety contract for `va_end`. - unsafe { - va_end(&mut ap); - } - ret - } -} - -#[unstable( - feature = "c_variadic", - reason = "the `c_variadic` feature has not been properly tested on \ - all supported platforms", - issue = "44930" -)] -impl<'f> Clone for VaListImpl<'f> { - #[inline] - fn clone(&self) -> Self { - let mut dest = crate::mem::MaybeUninit::uninit(); - // SAFETY: we write to the `MaybeUninit`, thus it is initialized and `assume_init` is legal - unsafe { - va_copy(dest.as_mut_ptr(), self); - dest.assume_init() - } - } -} - -#[unstable( - feature = "c_variadic", - reason = "the `c_variadic` feature has not been properly tested on \ - all supported platforms", - issue = "44930" -)] -impl<'f> Drop for VaListImpl<'f> { - fn drop(&mut self) { - // FIXME: this should call `va_end`, but there's no clean way to - // guarantee that `drop` always gets inlined into its caller, - // so the `va_end` would get directly called from the same function as - // the corresponding `va_copy`. `man va_end` states that C requires this, - // and LLVM basically follows the C semantics, so we need to make sure - // that `va_end` is always called from the same function as `va_copy`. - // For more details, see https://github.com/rust-lang/rust/pull/59625 - // and https://llvm.org/docs/LangRef.html#llvm-va-end-intrinsic. - // - // This works for now, since `va_end` is a no-op on all current LLVM targets. - } -} - -extern "rust-intrinsic" { - /// Destroy the arglist `ap` after initialization with `va_start` or - /// `va_copy`. - #[rustc_nounwind] - fn va_end(ap: &mut VaListImpl<'_>); - - /// Copies the current location of arglist `src` to the arglist `dst`. - #[rustc_nounwind] - fn va_copy<'f>(dest: *mut VaListImpl<'f>, src: &VaListImpl<'f>); - - /// Loads an argument of type `T` from the `va_list` `ap` and increment the - /// argument `ap` points to. - #[rustc_nounwind] - fn va_arg(ap: &mut VaListImpl<'_>) -> T; -} - // Link the MSVC default lib #[cfg(all(windows, target_env = "msvc"))] #[link( diff --git a/library/core/src/ffi/va_list.rs b/library/core/src/ffi/va_list.rs new file mode 100644 index 0000000000000..88c5909b1130e --- /dev/null +++ b/library/core/src/ffi/va_list.rs @@ -0,0 +1,407 @@ +//! C's "variable arguments" +//! +//! Better known as "varargs". + +use crate::ffi::c_void; + +#[allow(unused_imports)] +use crate::fmt; +use crate::marker::PhantomData; +use crate::ops::{Deref, DerefMut}; + +/// Basic implementation of a `va_list`. +// The name is WIP, using `VaListImpl` for now. +#[cfg(any( + all( + not(target_arch = "aarch64"), + not(target_arch = "powerpc"), + not(target_arch = "s390x"), + not(target_arch = "x86_64") + ), + all(target_arch = "aarch64", target_vendor = "apple"), + target_family = "wasm", + target_os = "uefi", + windows, +))] +#[cfg_attr(not(doc), repr(transparent))] // work around https://github.com/rust-lang/rust/issues/90435 +#[unstable( + feature = "c_variadic", + reason = "the `c_variadic` feature has not been properly tested on \ + all supported platforms", + issue = "44930" +)] +#[lang = "va_list"] +pub struct VaListImpl<'f> { + ptr: *mut c_void, + + // Invariant over `'f`, so each `VaListImpl<'f>` object is tied to + // the region of the function it's defined in + _marker: PhantomData<&'f mut &'f c_void>, +} + +#[cfg(any( + all( + not(target_arch = "aarch64"), + not(target_arch = "powerpc"), + not(target_arch = "s390x"), + not(target_arch = "x86_64") + ), + all(target_arch = "aarch64", target_vendor = "apple"), + target_family = "wasm", + target_os = "uefi", + windows, +))] +#[unstable( + feature = "c_variadic", + reason = "the `c_variadic` feature has not been properly tested on \ + all supported platforms", + issue = "44930" +)] +impl<'f> fmt::Debug for VaListImpl<'f> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "va_list* {:p}", self.ptr) + } +} + +/// AArch64 ABI implementation of a `va_list`. See the +/// [AArch64 Procedure Call Standard] for more details. +/// +/// [AArch64 Procedure Call Standard]: +/// http://infocenter.arm.com/help/topic/com.arm.doc.ihi0055b/IHI0055B_aapcs64.pdf +#[cfg(all( + target_arch = "aarch64", + not(target_vendor = "apple"), + not(target_os = "uefi"), + not(windows), +))] +#[cfg_attr(not(doc), repr(C))] // work around https://github.com/rust-lang/rust/issues/66401 +#[derive(Debug)] +#[unstable( + feature = "c_variadic", + reason = "the `c_variadic` feature has not been properly tested on \ + all supported platforms", + issue = "44930" +)] +#[lang = "va_list"] +pub struct VaListImpl<'f> { + stack: *mut c_void, + gr_top: *mut c_void, + vr_top: *mut c_void, + gr_offs: i32, + vr_offs: i32, + _marker: PhantomData<&'f mut &'f c_void>, +} + +/// PowerPC ABI implementation of a `va_list`. +#[cfg(all(target_arch = "powerpc", not(target_os = "uefi"), not(windows)))] +#[cfg_attr(not(doc), repr(C))] // work around https://github.com/rust-lang/rust/issues/66401 +#[derive(Debug)] +#[unstable( + feature = "c_variadic", + reason = "the `c_variadic` feature has not been properly tested on \ + all supported platforms", + issue = "44930" +)] +#[lang = "va_list"] +pub struct VaListImpl<'f> { + gpr: u8, + fpr: u8, + reserved: u16, + overflow_arg_area: *mut c_void, + reg_save_area: *mut c_void, + _marker: PhantomData<&'f mut &'f c_void>, +} + +/// s390x ABI implementation of a `va_list`. +#[cfg(target_arch = "s390x")] +#[cfg_attr(not(doc), repr(C))] // work around https://github.com/rust-lang/rust/issues/66401 +#[derive(Debug)] +#[unstable( + feature = "c_variadic", + reason = "the `c_variadic` feature has not been properly tested on \ + all supported platforms", + issue = "44930" +)] +#[lang = "va_list"] +pub struct VaListImpl<'f> { + gpr: i64, + fpr: i64, + overflow_arg_area: *mut c_void, + reg_save_area: *mut c_void, + _marker: PhantomData<&'f mut &'f c_void>, +} + +/// x86_64 ABI implementation of a `va_list`. +#[cfg(all(target_arch = "x86_64", not(target_os = "uefi"), not(windows)))] +#[cfg_attr(not(doc), repr(C))] // work around https://github.com/rust-lang/rust/issues/66401 +#[derive(Debug)] +#[unstable( + feature = "c_variadic", + reason = "the `c_variadic` feature has not been properly tested on \ + all supported platforms", + issue = "44930" +)] +#[lang = "va_list"] +pub struct VaListImpl<'f> { + gp_offset: i32, + fp_offset: i32, + overflow_arg_area: *mut c_void, + reg_save_area: *mut c_void, + _marker: PhantomData<&'f mut &'f c_void>, +} + +/// A wrapper for a `va_list` +#[cfg_attr(not(doc), repr(transparent))] // work around https://github.com/rust-lang/rust/issues/90435 +#[derive(Debug)] +#[unstable( + feature = "c_variadic", + reason = "the `c_variadic` feature has not been properly tested on \ + all supported platforms", + issue = "44930" +)] +pub struct VaList<'a, 'f: 'a> { + #[cfg(any( + all( + not(target_arch = "aarch64"), + not(target_arch = "powerpc"), + not(target_arch = "s390x"), + not(target_arch = "x86_64") + ), + all(target_arch = "aarch64", target_vendor = "apple"), + target_family = "wasm", + target_os = "uefi", + windows, + ))] + inner: VaListImpl<'f>, + + #[cfg(all( + any( + target_arch = "aarch64", + target_arch = "powerpc", + target_arch = "s390x", + target_arch = "x86_64" + ), + any(not(target_arch = "aarch64"), not(target_vendor = "apple")), + not(target_family = "wasm"), + not(target_os = "uefi"), + not(windows), + ))] + inner: &'a mut VaListImpl<'f>, + + _marker: PhantomData<&'a mut VaListImpl<'f>>, +} + +#[cfg(any( + all( + not(target_arch = "aarch64"), + not(target_arch = "powerpc"), + not(target_arch = "s390x"), + not(target_arch = "x86_64") + ), + all(target_arch = "aarch64", target_vendor = "apple"), + target_family = "wasm", + target_os = "uefi", + windows, +))] +#[unstable( + feature = "c_variadic", + reason = "the `c_variadic` feature has not been properly tested on \ + all supported platforms", + issue = "44930" +)] +impl<'f> VaListImpl<'f> { + /// Convert a `VaListImpl` into a `VaList` that is binary-compatible with C's `va_list`. + #[inline] + pub fn as_va_list<'a>(&'a mut self) -> VaList<'a, 'f> { + VaList { inner: VaListImpl { ..*self }, _marker: PhantomData } + } +} + +#[cfg(all( + any( + target_arch = "aarch64", + target_arch = "powerpc", + target_arch = "s390x", + target_arch = "x86_64" + ), + any(not(target_arch = "aarch64"), not(target_vendor = "apple")), + not(target_family = "wasm"), + not(target_os = "uefi"), + not(windows), +))] +#[unstable( + feature = "c_variadic", + reason = "the `c_variadic` feature has not been properly tested on \ + all supported platforms", + issue = "44930" +)] +impl<'f> VaListImpl<'f> { + /// Convert a `VaListImpl` into a `VaList` that is binary-compatible with C's `va_list`. + #[inline] + pub fn as_va_list<'a>(&'a mut self) -> VaList<'a, 'f> { + VaList { inner: self, _marker: PhantomData } + } +} + +#[unstable( + feature = "c_variadic", + reason = "the `c_variadic` feature has not been properly tested on \ + all supported platforms", + issue = "44930" +)] +impl<'a, 'f: 'a> Deref for VaList<'a, 'f> { + type Target = VaListImpl<'f>; + + #[inline] + fn deref(&self) -> &VaListImpl<'f> { + &self.inner + } +} + +#[unstable( + feature = "c_variadic", + reason = "the `c_variadic` feature has not been properly tested on \ + all supported platforms", + issue = "44930" +)] +impl<'a, 'f: 'a> DerefMut for VaList<'a, 'f> { + #[inline] + fn deref_mut(&mut self) -> &mut VaListImpl<'f> { + &mut self.inner + } +} + +// The VaArgSafe trait needs to be used in public interfaces, however, the trait +// itself must not be allowed to be used outside this module. Allowing users to +// implement the trait for a new type (thereby allowing the va_arg intrinsic to +// be used on a new type) is likely to cause undefined behavior. +// +// FIXME(dlrobertson): In order to use the VaArgSafe trait in a public interface +// but also ensure it cannot be used elsewhere, the trait needs to be public +// within a private module. Once RFC 2145 has been implemented look into +// improving this. +mod sealed_trait { + /// Trait which permits the allowed types to be used with [super::VaListImpl::arg]. + #[unstable( + feature = "c_variadic", + reason = "the `c_variadic` feature has not been properly tested on \ + all supported platforms", + issue = "44930" + )] + pub unsafe trait VaArgSafe {} +} + +macro_rules! impl_va_arg_safe { + ($($t:ty),+) => { + $( + #[unstable(feature = "c_variadic", + reason = "the `c_variadic` feature has not been properly tested on \ + all supported platforms", + issue = "44930")] + unsafe impl sealed_trait::VaArgSafe for $t {} + )+ + } +} + +impl_va_arg_safe! {i8, i16, i32, i64, usize} +impl_va_arg_safe! {u8, u16, u32, u64, isize} +impl_va_arg_safe! {f64} + +#[unstable( + feature = "c_variadic", + reason = "the `c_variadic` feature has not been properly tested on \ + all supported platforms", + issue = "44930" +)] +unsafe impl sealed_trait::VaArgSafe for *mut T {} +#[unstable( + feature = "c_variadic", + reason = "the `c_variadic` feature has not been properly tested on \ + all supported platforms", + issue = "44930" +)] +unsafe impl sealed_trait::VaArgSafe for *const T {} + +#[unstable( + feature = "c_variadic", + reason = "the `c_variadic` feature has not been properly tested on \ + all supported platforms", + issue = "44930" +)] +impl<'f> VaListImpl<'f> { + /// Advance to the next arg. + #[inline] + pub unsafe fn arg(&mut self) -> T { + // SAFETY: the caller must uphold the safety contract for `va_arg`. + unsafe { va_arg(self) } + } + + /// Copies the `va_list` at the current location. + pub unsafe fn with_copy(&self, f: F) -> R + where + F: for<'copy> FnOnce(VaList<'copy, 'f>) -> R, + { + let mut ap = self.clone(); + let ret = f(ap.as_va_list()); + // SAFETY: the caller must uphold the safety contract for `va_end`. + unsafe { + va_end(&mut ap); + } + ret + } +} + +#[unstable( + feature = "c_variadic", + reason = "the `c_variadic` feature has not been properly tested on \ + all supported platforms", + issue = "44930" +)] +impl<'f> Clone for VaListImpl<'f> { + #[inline] + fn clone(&self) -> Self { + let mut dest = crate::mem::MaybeUninit::uninit(); + // SAFETY: we write to the `MaybeUninit`, thus it is initialized and `assume_init` is legal + unsafe { + va_copy(dest.as_mut_ptr(), self); + dest.assume_init() + } + } +} + +#[unstable( + feature = "c_variadic", + reason = "the `c_variadic` feature has not been properly tested on \ + all supported platforms", + issue = "44930" +)] +impl<'f> Drop for VaListImpl<'f> { + fn drop(&mut self) { + // FIXME: this should call `va_end`, but there's no clean way to + // guarantee that `drop` always gets inlined into its caller, + // so the `va_end` would get directly called from the same function as + // the corresponding `va_copy`. `man va_end` states that C requires this, + // and LLVM basically follows the C semantics, so we need to make sure + // that `va_end` is always called from the same function as `va_copy`. + // For more details, see https://github.com/rust-lang/rust/pull/59625 + // and https://llvm.org/docs/LangRef.html#llvm-va-end-intrinsic. + // + // This works for now, since `va_end` is a no-op on all current LLVM targets. + } +} + +extern "rust-intrinsic" { + /// Destroy the arglist `ap` after initialization with `va_start` or + /// `va_copy`. + #[rustc_nounwind] + fn va_end(ap: &mut VaListImpl<'_>); + + /// Copies the current location of arglist `src` to the arglist `dst`. + #[rustc_nounwind] + fn va_copy<'f>(dest: *mut VaListImpl<'f>, src: &VaListImpl<'f>); + + /// Loads an argument of type `T` from the `va_list` `ap` and increment the + /// argument `ap` points to. + #[rustc_nounwind] + fn va_arg(ap: &mut VaListImpl<'_>) -> T; +} diff --git a/src/tools/tidy/src/pal.rs b/src/tools/tidy/src/pal.rs index 7e5656926abe2..2f8abc77566cd 100644 --- a/src/tools/tidy/src/pal.rs +++ b/src/tools/tidy/src/pal.rs @@ -45,6 +45,8 @@ const EXCEPTION_PATHS: &[&str] = &[ // pointer regardless of the target architecture. As a result, // we must use `#[cfg(windows)]` to conditionally compile the // correct `VaList` structure for windows. + "library/core/src/ffi/va_list.rs", + // We placed a linkage against Windows libraries here "library/core/src/ffi/mod.rs", "library/std/src/sys", // Platform-specific code for std lives here. "library/std/src/os", // Platform-specific public interfaces From c1a29b30d157689caafa34238e87313cda0fccc5 Mon Sep 17 00:00:00 2001 From: Jubilee Young Date: Mon, 24 Jun 2024 14:09:30 -0700 Subject: [PATCH 712/892] core: erase redundant stability attrs in va_list Now that VaList, et al. have a module, they only need one `#[unstable]`. --- library/core/src/ffi/va_list.rs | 106 -------------------------------- 1 file changed, 106 deletions(-) diff --git a/library/core/src/ffi/va_list.rs b/library/core/src/ffi/va_list.rs index 88c5909b1130e..6a2e8b67d0c2a 100644 --- a/library/core/src/ffi/va_list.rs +++ b/library/core/src/ffi/va_list.rs @@ -24,12 +24,6 @@ use crate::ops::{Deref, DerefMut}; windows, ))] #[cfg_attr(not(doc), repr(transparent))] // work around https://github.com/rust-lang/rust/issues/90435 -#[unstable( - feature = "c_variadic", - reason = "the `c_variadic` feature has not been properly tested on \ - all supported platforms", - issue = "44930" -)] #[lang = "va_list"] pub struct VaListImpl<'f> { ptr: *mut c_void, @@ -51,12 +45,6 @@ pub struct VaListImpl<'f> { target_os = "uefi", windows, ))] -#[unstable( - feature = "c_variadic", - reason = "the `c_variadic` feature has not been properly tested on \ - all supported platforms", - issue = "44930" -)] impl<'f> fmt::Debug for VaListImpl<'f> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "va_list* {:p}", self.ptr) @@ -76,12 +64,6 @@ impl<'f> fmt::Debug for VaListImpl<'f> { ))] #[cfg_attr(not(doc), repr(C))] // work around https://github.com/rust-lang/rust/issues/66401 #[derive(Debug)] -#[unstable( - feature = "c_variadic", - reason = "the `c_variadic` feature has not been properly tested on \ - all supported platforms", - issue = "44930" -)] #[lang = "va_list"] pub struct VaListImpl<'f> { stack: *mut c_void, @@ -96,12 +78,6 @@ pub struct VaListImpl<'f> { #[cfg(all(target_arch = "powerpc", not(target_os = "uefi"), not(windows)))] #[cfg_attr(not(doc), repr(C))] // work around https://github.com/rust-lang/rust/issues/66401 #[derive(Debug)] -#[unstable( - feature = "c_variadic", - reason = "the `c_variadic` feature has not been properly tested on \ - all supported platforms", - issue = "44930" -)] #[lang = "va_list"] pub struct VaListImpl<'f> { gpr: u8, @@ -116,12 +92,6 @@ pub struct VaListImpl<'f> { #[cfg(target_arch = "s390x")] #[cfg_attr(not(doc), repr(C))] // work around https://github.com/rust-lang/rust/issues/66401 #[derive(Debug)] -#[unstable( - feature = "c_variadic", - reason = "the `c_variadic` feature has not been properly tested on \ - all supported platforms", - issue = "44930" -)] #[lang = "va_list"] pub struct VaListImpl<'f> { gpr: i64, @@ -135,12 +105,6 @@ pub struct VaListImpl<'f> { #[cfg(all(target_arch = "x86_64", not(target_os = "uefi"), not(windows)))] #[cfg_attr(not(doc), repr(C))] // work around https://github.com/rust-lang/rust/issues/66401 #[derive(Debug)] -#[unstable( - feature = "c_variadic", - reason = "the `c_variadic` feature has not been properly tested on \ - all supported platforms", - issue = "44930" -)] #[lang = "va_list"] pub struct VaListImpl<'f> { gp_offset: i32, @@ -153,12 +117,6 @@ pub struct VaListImpl<'f> { /// A wrapper for a `va_list` #[cfg_attr(not(doc), repr(transparent))] // work around https://github.com/rust-lang/rust/issues/90435 #[derive(Debug)] -#[unstable( - feature = "c_variadic", - reason = "the `c_variadic` feature has not been properly tested on \ - all supported platforms", - issue = "44930" -)] pub struct VaList<'a, 'f: 'a> { #[cfg(any( all( @@ -203,12 +161,6 @@ pub struct VaList<'a, 'f: 'a> { target_os = "uefi", windows, ))] -#[unstable( - feature = "c_variadic", - reason = "the `c_variadic` feature has not been properly tested on \ - all supported platforms", - issue = "44930" -)] impl<'f> VaListImpl<'f> { /// Convert a `VaListImpl` into a `VaList` that is binary-compatible with C's `va_list`. #[inline] @@ -229,12 +181,6 @@ impl<'f> VaListImpl<'f> { not(target_os = "uefi"), not(windows), ))] -#[unstable( - feature = "c_variadic", - reason = "the `c_variadic` feature has not been properly tested on \ - all supported platforms", - issue = "44930" -)] impl<'f> VaListImpl<'f> { /// Convert a `VaListImpl` into a `VaList` that is binary-compatible with C's `va_list`. #[inline] @@ -243,12 +189,6 @@ impl<'f> VaListImpl<'f> { } } -#[unstable( - feature = "c_variadic", - reason = "the `c_variadic` feature has not been properly tested on \ - all supported platforms", - issue = "44930" -)] impl<'a, 'f: 'a> Deref for VaList<'a, 'f> { type Target = VaListImpl<'f>; @@ -258,12 +198,6 @@ impl<'a, 'f: 'a> Deref for VaList<'a, 'f> { } } -#[unstable( - feature = "c_variadic", - reason = "the `c_variadic` feature has not been properly tested on \ - all supported platforms", - issue = "44930" -)] impl<'a, 'f: 'a> DerefMut for VaList<'a, 'f> { #[inline] fn deref_mut(&mut self) -> &mut VaListImpl<'f> { @@ -282,22 +216,12 @@ impl<'a, 'f: 'a> DerefMut for VaList<'a, 'f> { // improving this. mod sealed_trait { /// Trait which permits the allowed types to be used with [super::VaListImpl::arg]. - #[unstable( - feature = "c_variadic", - reason = "the `c_variadic` feature has not been properly tested on \ - all supported platforms", - issue = "44930" - )] pub unsafe trait VaArgSafe {} } macro_rules! impl_va_arg_safe { ($($t:ty),+) => { $( - #[unstable(feature = "c_variadic", - reason = "the `c_variadic` feature has not been properly tested on \ - all supported platforms", - issue = "44930")] unsafe impl sealed_trait::VaArgSafe for $t {} )+ } @@ -307,27 +231,9 @@ impl_va_arg_safe! {i8, i16, i32, i64, usize} impl_va_arg_safe! {u8, u16, u32, u64, isize} impl_va_arg_safe! {f64} -#[unstable( - feature = "c_variadic", - reason = "the `c_variadic` feature has not been properly tested on \ - all supported platforms", - issue = "44930" -)] unsafe impl sealed_trait::VaArgSafe for *mut T {} -#[unstable( - feature = "c_variadic", - reason = "the `c_variadic` feature has not been properly tested on \ - all supported platforms", - issue = "44930" -)] unsafe impl sealed_trait::VaArgSafe for *const T {} -#[unstable( - feature = "c_variadic", - reason = "the `c_variadic` feature has not been properly tested on \ - all supported platforms", - issue = "44930" -)] impl<'f> VaListImpl<'f> { /// Advance to the next arg. #[inline] @@ -351,12 +257,6 @@ impl<'f> VaListImpl<'f> { } } -#[unstable( - feature = "c_variadic", - reason = "the `c_variadic` feature has not been properly tested on \ - all supported platforms", - issue = "44930" -)] impl<'f> Clone for VaListImpl<'f> { #[inline] fn clone(&self) -> Self { @@ -369,12 +269,6 @@ impl<'f> Clone for VaListImpl<'f> { } } -#[unstable( - feature = "c_variadic", - reason = "the `c_variadic` feature has not been properly tested on \ - all supported platforms", - issue = "44930" -)] impl<'f> Drop for VaListImpl<'f> { fn drop(&mut self) { // FIXME: this should call `va_end`, but there's no clean way to From f095de4bf105e92b035a7cd64c34bcce56b7cb78 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Thu, 4 Jul 2024 23:52:49 +1000 Subject: [PATCH 713/892] coverage: Rename `mir::coverage::BranchInfo` to `CoverageInfoHi` This opens the door to collecting and storing coverage information that is unrelated to branch coverage or MC/DC. --- compiler/rustc_middle/src/mir/coverage.rs | 11 +- compiler/rustc_middle/src/mir/mod.rs | 13 ++- compiler/rustc_middle/src/mir/pretty.rs | 16 ++- .../rustc_mir_build/src/build/coverageinfo.rs | 107 ++++++++++-------- .../src/build/coverageinfo/mcdc.rs | 12 +- .../rustc_mir_build/src/build/custom/mod.rs | 2 +- .../rustc_mir_build/src/build/matches/mod.rs | 4 +- compiler/rustc_mir_build/src/build/mod.rs | 8 +- .../src/coverage/mappings.rs | 22 ++-- 9 files changed, 110 insertions(+), 85 deletions(-) diff --git a/compiler/rustc_middle/src/mir/coverage.rs b/compiler/rustc_middle/src/mir/coverage.rs index da25fbb0a82b3..beaaadd497d3a 100644 --- a/compiler/rustc_middle/src/mir/coverage.rs +++ b/compiler/rustc_middle/src/mir/coverage.rs @@ -103,7 +103,7 @@ pub enum CoverageKind { SpanMarker, /// Marks its enclosing basic block with an ID that can be referred to by - /// side data in [`BranchInfo`]. + /// side data in [`CoverageInfoHi`]. /// /// Should be erased before codegen (at some point after `InstrumentCoverage`). BlockMarker { id: BlockMarkerId }, @@ -274,10 +274,15 @@ pub struct FunctionCoverageInfo { pub mcdc_num_condition_bitmaps: usize, } -/// Branch information recorded during THIR-to-MIR lowering, and stored in MIR. +/// Coverage information for a function, recorded during MIR building and +/// attached to the corresponding `mir::Body`. Used by the `InstrumentCoverage` +/// MIR pass. +/// +/// ("Hi" indicates that this is "high-level" information collected at the +/// THIR/MIR boundary, before the MIR-based coverage instrumentation pass.) #[derive(Clone, Debug)] #[derive(TyEncodable, TyDecodable, Hash, HashStable, TypeFoldable, TypeVisitable)] -pub struct BranchInfo { +pub struct CoverageInfoHi { /// 1 more than the highest-numbered [`CoverageKind::BlockMarker`] that was /// injected into the MIR body. This makes it possible to allocate per-ID /// data structures without having to scan the entire body first. diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index ef88b253864bd..83e3898cebfa4 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -430,11 +430,12 @@ pub struct Body<'tcx> { pub tainted_by_errors: Option, - /// Branch coverage information collected during MIR building, to be used by - /// the `InstrumentCoverage` pass. + /// Coverage information collected from THIR/MIR during MIR building, + /// to be used by the `InstrumentCoverage` pass. /// - /// Only present if branch coverage is enabled and this function is eligible. - pub coverage_branch_info: Option>, + /// Only present if coverage is enabled and this function is eligible. + /// Boxed to limit space overhead in non-coverage builds. + pub coverage_info_hi: Option>, /// Per-function coverage information added by the `InstrumentCoverage` /// pass, to be used in conjunction with the coverage statements injected @@ -484,7 +485,7 @@ impl<'tcx> Body<'tcx> { is_polymorphic: false, injection_phase: None, tainted_by_errors, - coverage_branch_info: None, + coverage_info_hi: None, function_coverage_info: None, }; body.is_polymorphic = body.has_non_region_param(); @@ -515,7 +516,7 @@ impl<'tcx> Body<'tcx> { is_polymorphic: false, injection_phase: None, tainted_by_errors: None, - coverage_branch_info: None, + coverage_info_hi: None, function_coverage_info: None, }; body.is_polymorphic = body.has_non_region_param(); diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs index 4453ce44b0371..5b2c603ce25ac 100644 --- a/compiler/rustc_middle/src/mir/pretty.rs +++ b/compiler/rustc_middle/src/mir/pretty.rs @@ -473,8 +473,8 @@ pub fn write_mir_intro<'tcx>( // Add an empty line before the first block is printed. writeln!(w)?; - if let Some(branch_info) = &body.coverage_branch_info { - write_coverage_branch_info(branch_info, w)?; + if let Some(coverage_info_hi) = &body.coverage_info_hi { + write_coverage_info_hi(coverage_info_hi, w)?; } if let Some(function_coverage_info) = &body.function_coverage_info { write_function_coverage_info(function_coverage_info, w)?; @@ -483,12 +483,16 @@ pub fn write_mir_intro<'tcx>( Ok(()) } -fn write_coverage_branch_info( - branch_info: &coverage::BranchInfo, +fn write_coverage_info_hi( + coverage_info_hi: &coverage::CoverageInfoHi, w: &mut dyn io::Write, ) -> io::Result<()> { - let coverage::BranchInfo { branch_spans, mcdc_branch_spans, mcdc_decision_spans, .. } = - branch_info; + let coverage::CoverageInfoHi { + num_block_markers: _, + branch_spans, + mcdc_branch_spans, + mcdc_decision_spans, + } = coverage_info_hi; for coverage::BranchSpan { span, true_marker, false_marker } in branch_spans { writeln!( diff --git a/compiler/rustc_mir_build/src/build/coverageinfo.rs b/compiler/rustc_mir_build/src/build/coverageinfo.rs index 876faca5172ac..204ee45bfa2d7 100644 --- a/compiler/rustc_mir_build/src/build/coverageinfo.rs +++ b/compiler/rustc_mir_build/src/build/coverageinfo.rs @@ -2,7 +2,7 @@ use std::assert_matches::assert_matches; use std::collections::hash_map::Entry; use rustc_data_structures::fx::FxHashMap; -use rustc_middle::mir::coverage::{BlockMarkerId, BranchSpan, CoverageKind}; +use rustc_middle::mir::coverage::{BlockMarkerId, BranchSpan, CoverageInfoHi, CoverageKind}; use rustc_middle::mir::{self, BasicBlock, SourceInfo, UnOp}; use rustc_middle::thir::{ExprId, ExprKind, Pat, Thir}; use rustc_middle::ty::TyCtxt; @@ -13,16 +13,25 @@ use crate::build::{Builder, CFG}; mod mcdc; -pub(crate) struct BranchInfoBuilder { +/// Collects coverage-related information during MIR building, to eventually be +/// turned into a function's [`CoverageInfoHi`] when MIR building is complete. +pub(crate) struct CoverageInfoBuilder { /// Maps condition expressions to their enclosing `!`, for better instrumentation. nots: FxHashMap, markers: BlockMarkerGen, - branch_spans: Vec, + /// Present if branch coverage is enabled. + branch_info: Option, + /// Present if MC/DC coverage is enabled. mcdc_info: Option, } +#[derive(Default)] +struct BranchInfo { + branch_spans: Vec, +} + #[derive(Clone, Copy)] struct NotInfo { /// When visiting the associated expression as a branch condition, treat this @@ -62,20 +71,20 @@ impl BlockMarkerGen { } } -impl BranchInfoBuilder { - /// Creates a new branch info builder, but only if branch coverage instrumentation +impl CoverageInfoBuilder { + /// Creates a new coverage info builder, but only if coverage instrumentation /// is enabled and `def_id` represents a function that is eligible for coverage. pub(crate) fn new_if_enabled(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option { - if tcx.sess.instrument_coverage_branch() && tcx.is_eligible_for_coverage(def_id) { - Some(Self { - nots: FxHashMap::default(), - markers: BlockMarkerGen::default(), - branch_spans: vec![], - mcdc_info: tcx.sess.instrument_coverage_mcdc().then(MCDCInfoBuilder::new), - }) - } else { - None + if !tcx.sess.instrument_coverage() || !tcx.is_eligible_for_coverage(def_id) { + return None; } + + Some(Self { + nots: FxHashMap::default(), + markers: BlockMarkerGen::default(), + branch_info: tcx.sess.instrument_coverage_branch().then(BranchInfo::default), + mcdc_info: tcx.sess.instrument_coverage_mcdc().then(MCDCInfoBuilder::new), + }) } /// Unary `!` expressions inside an `if` condition are lowered by lowering @@ -88,6 +97,12 @@ impl BranchInfoBuilder { pub(crate) fn visit_unary_not(&mut self, thir: &Thir<'_>, unary_not: ExprId) { assert_matches!(thir[unary_not].kind, ExprKind::Unary { op: UnOp::Not, .. }); + // The information collected by this visitor is only needed when branch + // coverage or higher is enabled. + if self.branch_info.is_none() { + return; + } + self.visit_with_not_info( thir, unary_not, @@ -137,40 +152,40 @@ impl BranchInfoBuilder { false_block, inject_block_marker, ); - } else { - let true_marker = self.markers.inject_block_marker(cfg, source_info, true_block); - let false_marker = self.markers.inject_block_marker(cfg, source_info, false_block); - - self.branch_spans.push(BranchSpan { - span: source_info.span, - true_marker, - false_marker, - }); + return; } + + // Bail out if branch coverage is not enabled. + let Some(branch_info) = self.branch_info.as_mut() else { return }; + + let true_marker = self.markers.inject_block_marker(cfg, source_info, true_block); + let false_marker = self.markers.inject_block_marker(cfg, source_info, false_block); + + branch_info.branch_spans.push(BranchSpan { + span: source_info.span, + true_marker, + false_marker, + }); } - pub(crate) fn into_done(self) -> Option> { - let Self { - nots: _, - markers: BlockMarkerGen { num_block_markers }, - branch_spans, - mcdc_info, - } = self; + pub(crate) fn into_done(self) -> Box { + let Self { nots: _, markers: BlockMarkerGen { num_block_markers }, branch_info, mcdc_info } = + self; - if num_block_markers == 0 { - assert!(branch_spans.is_empty()); - return None; - } + let branch_spans = + branch_info.map(|branch_info| branch_info.branch_spans).unwrap_or_default(); let (mcdc_decision_spans, mcdc_branch_spans) = mcdc_info.map(MCDCInfoBuilder::into_done).unwrap_or_default(); - Some(Box::new(mir::coverage::BranchInfo { + // For simplicity, always return an info struct (without Option), even + // if there's nothing interesting in it. + Box::new(CoverageInfoHi { num_block_markers, branch_spans, mcdc_branch_spans, mcdc_decision_spans, - })) + }) } } @@ -184,7 +199,7 @@ impl<'tcx> Builder<'_, 'tcx> { block: &mut BasicBlock, ) { // Bail out if condition coverage is not enabled for this function. - let Some(branch_info) = self.coverage_branch_info.as_mut() else { return }; + let Some(coverage_info) = self.coverage_info.as_mut() else { return }; if !self.tcx.sess.instrument_coverage_condition() { return; }; @@ -224,7 +239,7 @@ impl<'tcx> Builder<'_, 'tcx> { ); // Separate path for handling branches when MC/DC is enabled. - branch_info.register_two_way_branch( + coverage_info.register_two_way_branch( self.tcx, &mut self.cfg, source_info, @@ -247,12 +262,12 @@ impl<'tcx> Builder<'_, 'tcx> { mut then_block: BasicBlock, mut else_block: BasicBlock, ) { - // Bail out if branch coverage is not enabled for this function. - let Some(branch_info) = self.coverage_branch_info.as_mut() else { return }; + // Bail out if coverage is not enabled for this function. + let Some(coverage_info) = self.coverage_info.as_mut() else { return }; // If this condition expression is nested within one or more `!` expressions, // replace it with the enclosing `!` collected by `visit_unary_not`. - if let Some(&NotInfo { enclosing_not, is_flipped }) = branch_info.nots.get(&expr_id) { + if let Some(&NotInfo { enclosing_not, is_flipped }) = coverage_info.nots.get(&expr_id) { expr_id = enclosing_not; if is_flipped { std::mem::swap(&mut then_block, &mut else_block); @@ -261,7 +276,7 @@ impl<'tcx> Builder<'_, 'tcx> { let source_info = SourceInfo { span: self.thir[expr_id].span, scope: self.source_scope }; - branch_info.register_two_way_branch( + coverage_info.register_two_way_branch( self.tcx, &mut self.cfg, source_info, @@ -280,13 +295,11 @@ impl<'tcx> Builder<'_, 'tcx> { true_block: BasicBlock, false_block: BasicBlock, ) { - // Bail out if branch coverage is not enabled for this function. - let Some(branch_info) = self.coverage_branch_info.as_mut() else { return }; - - // FIXME(#124144) This may need special handling when MC/DC is enabled. + // Bail out if coverage is not enabled for this function. + let Some(coverage_info) = self.coverage_info.as_mut() else { return }; let source_info = SourceInfo { span: pattern.span, scope: self.source_scope }; - branch_info.register_two_way_branch( + coverage_info.register_two_way_branch( self.tcx, &mut self.cfg, source_info, diff --git a/compiler/rustc_mir_build/src/build/coverageinfo/mcdc.rs b/compiler/rustc_mir_build/src/build/coverageinfo/mcdc.rs index f97e9ef60a297..3aa6e708476d5 100644 --- a/compiler/rustc_mir_build/src/build/coverageinfo/mcdc.rs +++ b/compiler/rustc_mir_build/src/build/coverageinfo/mcdc.rs @@ -250,24 +250,24 @@ impl MCDCInfoBuilder { impl Builder<'_, '_> { pub(crate) fn visit_coverage_branch_operation(&mut self, logical_op: LogicalOp, span: Span) { - if let Some(branch_info) = self.coverage_branch_info.as_mut() - && let Some(mcdc_info) = branch_info.mcdc_info.as_mut() + if let Some(coverage_info) = self.coverage_info.as_mut() + && let Some(mcdc_info) = coverage_info.mcdc_info.as_mut() { mcdc_info.state.record_conditions(logical_op, span); } } pub(crate) fn mcdc_increment_depth_if_enabled(&mut self) { - if let Some(branch_info) = self.coverage_branch_info.as_mut() - && let Some(mcdc_info) = branch_info.mcdc_info.as_mut() + if let Some(coverage_info) = self.coverage_info.as_mut() + && let Some(mcdc_info) = coverage_info.mcdc_info.as_mut() { mcdc_info.state.decision_ctx_stack.push(MCDCDecisionCtx::default()); }; } pub(crate) fn mcdc_decrement_depth_if_enabled(&mut self) { - if let Some(branch_info) = self.coverage_branch_info.as_mut() - && let Some(mcdc_info) = branch_info.mcdc_info.as_mut() + if let Some(coverage_info) = self.coverage_info.as_mut() + && let Some(mcdc_info) = coverage_info.mcdc_info.as_mut() { if mcdc_info.state.decision_ctx_stack.pop().is_none() { bug!("Unexpected empty decision stack"); diff --git a/compiler/rustc_mir_build/src/build/custom/mod.rs b/compiler/rustc_mir_build/src/build/custom/mod.rs index a0a512a2effcf..f6ebcbcbdc949 100644 --- a/compiler/rustc_mir_build/src/build/custom/mod.rs +++ b/compiler/rustc_mir_build/src/build/custom/mod.rs @@ -62,7 +62,7 @@ pub(super) fn build_custom_mir<'tcx>( tainted_by_errors: None, injection_phase: None, pass_count: 0, - coverage_branch_info: None, + coverage_info_hi: None, function_coverage_info: None, }; diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs index efed52231e3fa..e435e2f92883c 100644 --- a/compiler/rustc_mir_build/src/build/matches/mod.rs +++ b/compiler/rustc_mir_build/src/build/matches/mod.rs @@ -160,8 +160,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // Improve branch coverage instrumentation by noting conditions // nested within one or more `!` expressions. // (Skipped if branch coverage is not enabled.) - if let Some(branch_info) = this.coverage_branch_info.as_mut() { - branch_info.visit_unary_not(this.thir, expr_id); + if let Some(coverage_info) = this.coverage_info.as_mut() { + coverage_info.visit_unary_not(this.thir, expr_id); } let local_scope = this.local_scope(); diff --git a/compiler/rustc_mir_build/src/build/mod.rs b/compiler/rustc_mir_build/src/build/mod.rs index 601e5d4d3dc79..0f9746cb719ca 100644 --- a/compiler/rustc_mir_build/src/build/mod.rs +++ b/compiler/rustc_mir_build/src/build/mod.rs @@ -218,8 +218,8 @@ struct Builder<'a, 'tcx> { lint_level_roots_cache: GrowableBitSet, /// Collects additional coverage information during MIR building. - /// Only present if branch coverage is enabled and this function is eligible. - coverage_branch_info: Option, + /// Only present if coverage is enabled and this function is eligible. + coverage_info: Option, } type CaptureMap<'tcx> = SortedIndexMultiMap>; @@ -773,7 +773,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { unit_temp: None, var_debug_info: vec![], lint_level_roots_cache: GrowableBitSet::new_empty(), - coverage_branch_info: coverageinfo::BranchInfoBuilder::new_if_enabled(tcx, def), + coverage_info: coverageinfo::CoverageInfoBuilder::new_if_enabled(tcx, def), }; assert_eq!(builder.cfg.start_new_block(), START_BLOCK); @@ -802,7 +802,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { self.coroutine, None, ); - body.coverage_branch_info = self.coverage_branch_info.and_then(|b| b.into_done()); + body.coverage_info_hi = self.coverage_info.map(|b| b.into_done()); body } diff --git a/compiler/rustc_mir_transform/src/coverage/mappings.rs b/compiler/rustc_mir_transform/src/coverage/mappings.rs index 235992ac5470d..25297245172ac 100644 --- a/compiler/rustc_mir_transform/src/coverage/mappings.rs +++ b/compiler/rustc_mir_transform/src/coverage/mappings.rs @@ -3,7 +3,9 @@ use std::collections::BTreeSet; use rustc_data_structures::graph::DirectedGraph; use rustc_index::bit_set::BitSet; use rustc_index::IndexVec; -use rustc_middle::mir::coverage::{BlockMarkerId, BranchSpan, ConditionInfo, CoverageKind}; +use rustc_middle::mir::coverage::{ + BlockMarkerId, BranchSpan, ConditionInfo, CoverageInfoHi, CoverageKind, +}; use rustc_middle::mir::{self, BasicBlock, StatementKind}; use rustc_middle::ty::TyCtxt; use rustc_span::Span; @@ -157,12 +159,12 @@ impl ExtractedMappings { } fn resolve_block_markers( - branch_info: &mir::coverage::BranchInfo, + coverage_info_hi: &CoverageInfoHi, mir_body: &mir::Body<'_>, ) -> IndexVec> { let mut block_markers = IndexVec::>::from_elem_n( None, - branch_info.num_block_markers, + coverage_info_hi.num_block_markers, ); // Fill out the mapping from block marker IDs to their enclosing blocks. @@ -188,11 +190,11 @@ pub(super) fn extract_branch_pairs( hir_info: &ExtractedHirInfo, basic_coverage_blocks: &CoverageGraph, ) -> Vec { - let Some(branch_info) = mir_body.coverage_branch_info.as_deref() else { return vec![] }; + let Some(coverage_info_hi) = mir_body.coverage_info_hi.as_deref() else { return vec![] }; - let block_markers = resolve_block_markers(branch_info, mir_body); + let block_markers = resolve_block_markers(coverage_info_hi, mir_body); - branch_info + coverage_info_hi .branch_spans .iter() .filter_map(|&BranchSpan { span: raw_span, true_marker, false_marker }| { @@ -222,9 +224,9 @@ pub(super) fn extract_mcdc_mappings( mcdc_branches: &mut impl Extend, mcdc_decisions: &mut impl Extend, ) { - let Some(branch_info) = mir_body.coverage_branch_info.as_deref() else { return }; + let Some(coverage_info_hi) = mir_body.coverage_info_hi.as_deref() else { return }; - let block_markers = resolve_block_markers(branch_info, mir_body); + let block_markers = resolve_block_markers(coverage_info_hi, mir_body); let bcb_from_marker = |marker: BlockMarkerId| basic_coverage_blocks.bcb_from_bb(block_markers[marker]?); @@ -243,7 +245,7 @@ pub(super) fn extract_mcdc_mappings( Some((span, true_bcb, false_bcb)) }; - mcdc_branches.extend(branch_info.mcdc_branch_spans.iter().filter_map( + mcdc_branches.extend(coverage_info_hi.mcdc_branch_spans.iter().filter_map( |&mir::coverage::MCDCBranchSpan { span: raw_span, condition_info, @@ -257,7 +259,7 @@ pub(super) fn extract_mcdc_mappings( }, )); - mcdc_decisions.extend(branch_info.mcdc_decision_spans.iter().filter_map( + mcdc_decisions.extend(coverage_info_hi.mcdc_decision_spans.iter().filter_map( |decision: &mir::coverage::MCDCDecisionSpan| { let span = unexpand_into_body_span(decision.span, body_span)?; From f96f4436310d889da0ace73659f73500cc6c93c3 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Fri, 5 Jul 2024 13:07:30 +1000 Subject: [PATCH 714/892] Tweak how the extra newline is printed after coverage info --- compiler/rustc_middle/src/mir/pretty.rs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs index 5b2c603ce25ac..af19ed95193a7 100644 --- a/compiler/rustc_middle/src/mir/pretty.rs +++ b/compiler/rustc_middle/src/mir/pretty.rs @@ -494,11 +494,15 @@ fn write_coverage_info_hi( mcdc_decision_spans, } = coverage_info_hi; + // Only add an extra trailing newline if we printed at least one thing. + let mut did_print = false; + for coverage::BranchSpan { span, true_marker, false_marker } in branch_spans { writeln!( w, "{INDENT}coverage branch {{ true: {true_marker:?}, false: {false_marker:?} }} => {span:?}", )?; + did_print = true; } for coverage::MCDCBranchSpan { @@ -514,6 +518,7 @@ fn write_coverage_info_hi( "{INDENT}coverage mcdc branch {{ condition_id: {:?}, true: {true_marker:?}, false: {false_marker:?}, depth: {decision_depth:?} }} => {span:?}", condition_info.map(|info| info.condition_id) )?; + did_print = true; } for coverage::MCDCDecisionSpan { span, num_conditions, end_markers, decision_depth } in @@ -523,10 +528,10 @@ fn write_coverage_info_hi( w, "{INDENT}coverage mcdc decision {{ num_conditions: {num_conditions:?}, end: {end_markers:?}, depth: {decision_depth:?} }} => {span:?}" )?; + did_print = true; } - if !branch_spans.is_empty() || !mcdc_branch_spans.is_empty() || !mcdc_decision_spans.is_empty() - { + if did_print { writeln!(w)?; } From 90cbd0bfb4dd973b69cbea9509073eba4a33f6ce Mon Sep 17 00:00:00 2001 From: Sky Date: Fri, 28 Jun 2024 14:05:45 -0400 Subject: [PATCH 715/892] impl FusedIterator and a size hint for the error sources iter --- library/core/src/error.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/library/core/src/error.rs b/library/core/src/error.rs index 150e4f3f31857..ca8983d4cbcfe 100644 --- a/library/core/src/error.rs +++ b/library/core/src/error.rs @@ -1008,8 +1008,15 @@ impl<'a> Iterator for Source<'a> { self.current = self.current.and_then(Error::source); current } + + fn size_hint(&self) -> (usize, Option) { + if self.current.is_some() { (1, None) } else { (0, Some(0)) } + } } +#[unstable(feature = "error_iter", issue = "58520")] +impl<'a> crate::iter::FusedIterator for Source<'a> {} + #[stable(feature = "error_by_ref", since = "1.51.0")] impl<'a, T: Error + ?Sized> Error for &'a T { #[allow(deprecated, deprecated_in_future)] From ccd8dccfc6c19329e9c82e727a877113b8af9860 Mon Sep 17 00:00:00 2001 From: Nicholas Bishop Date: Fri, 5 Jul 2024 01:55:01 -0400 Subject: [PATCH 716/892] Describe Sized requirements for mem::offset_of The container doesn't have to be sized, but the field must be sized (at least until https://github.com/rust-lang/rust/issues/126151 is stable). --- library/core/src/mem/mod.rs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/library/core/src/mem/mod.rs b/library/core/src/mem/mod.rs index 9054ade2d7968..dd4b6e823434e 100644 --- a/library/core/src/mem/mod.rs +++ b/library/core/src/mem/mod.rs @@ -1266,6 +1266,20 @@ impl SizedTypeProperties for T {} /// // ^^^ error[E0616]: field `private` of struct `Struct` is private /// ``` /// +/// Only [`Sized`] fields are supported, but the container may be unsized: +/// ``` +/// # use core::mem; +/// #[repr(C)] +/// pub struct Struct { +/// a: u8, +/// b: [u8], +/// } +/// +/// assert_eq!(mem::offset_of!(Struct, a), 0); // OK +/// // assert_eq!(mem::offset_of!(Struct, b), 1); +/// // ^^^ error[E0277]: doesn't have a size known at compile-time +/// ``` +/// /// Note that type layout is, in general, [subject to change and /// platform-specific](https://doc.rust-lang.org/reference/type-layout.html). If /// layout stability is required, consider using an [explicit `repr` attribute]. From 3e4368053ffa72183f32c2c7c790cd6b29713f95 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 2 Jul 2024 12:04:32 +0200 Subject: [PATCH 717/892] Improve `Command::args` API in `run-make-support` --- src/tools/run-make-support/src/command.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/tools/run-make-support/src/command.rs b/src/tools/run-make-support/src/command.rs index ee651704c6fd0..c506c3d6b61a2 100644 --- a/src/tools/run-make-support/src/command.rs +++ b/src/tools/run-make-support/src/command.rs @@ -75,11 +75,12 @@ impl Command { /// Generic command arguments provider. Prefer specific helper methods if possible. /// Note that for some executables, arguments might be platform specific. For C/C++ /// compilers, arguments might be platform *and* compiler specific. - pub fn args(&mut self, args: &[S]) -> &mut Self + pub fn args(&mut self, args: V) -> &mut Self where S: AsRef, + V: AsRef<[S]>, { - self.cmd.args(args); + self.cmd.args(args.as_ref()); self } From 415e202c48d349dae9ad138c3adb78dc51d5ad9c Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 5 Jul 2024 11:19:52 +0200 Subject: [PATCH 718/892] Improve code of `run-make/llvm-ident` test --- tests/run-make/llvm-ident/rmake.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/run-make/llvm-ident/rmake.rs b/tests/run-make/llvm-ident/rmake.rs index f460829288e8c..6934a4b36d013 100644 --- a/tests/run-make/llvm-ident/rmake.rs +++ b/tests/run-make/llvm-ident/rmake.rs @@ -28,7 +28,7 @@ fn main() { files.push(path.to_path_buf()); } }); - cmd(llvm_bin_dir().join("llvm-dis")).args(&files).run(); + cmd(llvm_bin_dir().join("llvm-dis")).args(files).run(); // Check LLVM IR files (including temporary outputs) have `!llvm.ident` // named metadata, reusing the related codegen test. From 4abc51a2196657adb20f1a83fb7c04063c7c7586 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 5 Jul 2024 14:05:29 +0200 Subject: [PATCH 719/892] Improve readability of some fmt code examples --- library/core/src/fmt/mod.rs | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/library/core/src/fmt/mod.rs b/library/core/src/fmt/mod.rs index d0e188dfcd1d8..25ab5b2db9641 100644 --- a/library/core/src/fmt/mod.rs +++ b/library/core/src/fmt/mod.rs @@ -517,7 +517,10 @@ impl Display for Arguments<'_> { /// /// let origin = Point { x: 0, y: 0 }; /// -/// assert_eq!(format!("The origin is: {origin:?}"), "The origin is: Point { x: 0, y: 0 }"); +/// assert_eq!( +/// format!("The origin is: {origin:?}"), +/// "The origin is: Point { x: 0, y: 0 }", +/// ); /// ``` /// /// Manually implementing: @@ -541,7 +544,10 @@ impl Display for Arguments<'_> { /// /// let origin = Point { x: 0, y: 0 }; /// -/// assert_eq!(format!("The origin is: {origin:?}"), "The origin is: Point { x: 0, y: 0 }"); +/// assert_eq!( +/// format!("The origin is: {origin:?}"), +/// "The origin is: Point { x: 0, y: 0 }", +/// ); /// ``` /// /// There are a number of helper methods on the [`Formatter`] struct to help you with manual @@ -582,11 +588,11 @@ impl Display for Arguments<'_> { /// /// let origin = Point { x: 0, y: 0 }; /// -/// assert_eq!(format!("The origin is: {origin:#?}"), -/// "The origin is: Point { +/// let expected = "The origin is: Point { /// x: 0, /// y: 0, -/// }"); +/// }"; +/// assert_eq!(format!("The origin is: {origin:#?}"), expected); /// ``` #[stable(feature = "rust1", since = "1.0.0")] @@ -738,8 +744,10 @@ pub trait Display { /// } /// } /// - /// assert_eq!("(1.987, 2.983)", - /// format!("{}", Position { longitude: 1.987, latitude: 2.983, })); + /// assert_eq!( + /// "(1.987, 2.983)", + /// format!("{}", Position { longitude: 1.987, latitude: 2.983, }), + /// ); /// ``` #[stable(feature = "rust1", since = "1.0.0")] fn fmt(&self, f: &mut Formatter<'_>) -> Result; From f77d5d2b351f4a86e0c6ead5db83ef0fb3d22d40 Mon Sep 17 00:00:00 2001 From: Oneirical Date: Thu, 4 Jul 2024 15:36:24 -0400 Subject: [PATCH 720/892] rewrite emit-shared-files to rmake --- .../tidy/src/allowed_run_make_makefiles.txt | 1 - tests/run-make/emit-shared-files/Makefile | 46 -------- tests/run-make/emit-shared-files/rmake.rs | 102 ++++++++++++++++++ 3 files changed, 102 insertions(+), 47 deletions(-) delete mode 100644 tests/run-make/emit-shared-files/Makefile create mode 100644 tests/run-make/emit-shared-files/rmake.rs diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index 70c1b055c6e40..73d6af50ea03a 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -24,7 +24,6 @@ run-make/dep-info/Makefile run-make/dump-ice-to-disk/Makefile run-make/dump-mono-stats/Makefile run-make/emit-path-unhashed/Makefile -run-make/emit-shared-files/Makefile run-make/emit-to-stdout/Makefile run-make/env-dep-info/Makefile run-make/export-executable-symbols/Makefile diff --git a/tests/run-make/emit-shared-files/Makefile b/tests/run-make/emit-shared-files/Makefile deleted file mode 100644 index 27c72b003686d..0000000000000 --- a/tests/run-make/emit-shared-files/Makefile +++ /dev/null @@ -1,46 +0,0 @@ -include ../tools.mk - -INVOCATION_ONLY = $(TMPDIR)/invocation-only -TOOLCHAIN_ONLY = $(TMPDIR)/toolchain-only -ALL_SHARED = $(TMPDIR)/all-shared - -all: invocation-only toolchain-only all-shared - -invocation-only: - $(RUSTDOC) -Z unstable-options --emit=invocation-specific --output $(INVOCATION_ONLY) --resource-suffix=-xxx --theme y.css --extend-css z.css x.rs - [ -e $(INVOCATION_ONLY)/search-index-xxx.js ] - [ -e $(INVOCATION_ONLY)/settings.html ] - [ -e $(INVOCATION_ONLY)/x/all.html ] - [ -e $(INVOCATION_ONLY)/x/index.html ] - [ -e $(INVOCATION_ONLY)/theme-xxx.css ] # generated from z.css - ! [ -e $(INVOCATION_ONLY)/storage-xxx.js ] - ! [ -e $(INVOCATION_ONLY)/SourceSerif4-It.ttf.woff2 ] - - # FIXME: this probably shouldn't have a suffix - [ -e $(INVOCATION_ONLY)/y-xxx.css ] - # FIXME: this is technically incorrect (see `write_shared`) - ! [ -e $(INVOCATION_ONLY)/main-xxx.js ] - -toolchain-only: - $(RUSTDOC) -Z unstable-options --emit=toolchain-shared-resources --output $(TOOLCHAIN_ONLY) --resource-suffix=-xxx --extend-css z.css x.rs - [ -e $(TOOLCHAIN_ONLY)/static.files/storage-*.js ] - [ -e $(TOOLCHAIN_ONLY)/static.files/SourceSerif4-It-*.ttf.woff2 ] - ! [ -e $(TOOLCHAIN_ONLY)/search-index-xxx.js ] - ! [ -e $(TOOLCHAIN_ONLY)/x/index.html ] - ! [ -e $(TOOLCHAIN_ONLY)/theme.css ] - - [ -e $(TOOLCHAIN_ONLY)/static.files/main-*.js ] - ! [ -e $(TOOLCHAIN_ONLY)/y-xxx.css ] - -all-shared: - $(RUSTDOC) -Z unstable-options --emit=toolchain-shared-resources,unversioned-shared-resources --output $(ALL_SHARED) --resource-suffix=-xxx --extend-css z.css x.rs - [ -e $(ALL_SHARED)/static.files/storage-*.js ] - [ -e $(ALL_SHARED)/static.files/SourceSerif4-It-*.ttf.woff2 ] - ! [ -e $(ALL_SHARED)/search-index-xxx.js ] - ! [ -e $(ALL_SHARED)/settings.html ] - ! [ -e $(ALL_SHARED)/x ] - ! [ -e $(ALL_SHARED)/src ] - ! [ -e $(ALL_SHARED)/theme.css ] - - [ -e $(ALL_SHARED)/static.files/main-*.js ] - ! [ -e $(ALL_SHARED)/y-xxx.css ] diff --git a/tests/run-make/emit-shared-files/rmake.rs b/tests/run-make/emit-shared-files/rmake.rs new file mode 100644 index 0000000000000..33c1231024624 --- /dev/null +++ b/tests/run-make/emit-shared-files/rmake.rs @@ -0,0 +1,102 @@ +// This test checks the functionality of one of rustdoc's unstable options, +// the ability to specify emit restrictions with `--emit`. +// `invocation-only` should only emit crate-specific files. +// `toolchain-only` should only emit toolchain-specific files. +// `all-shared` should only emit files that can be shared between crates. +// See https://github.com/rust-lang/rust/pull/83478 + +use run_make_support::{has_extension, has_prefix, rustdoc, shallow_find_files}; +use std::path::Path; + +fn main() { + rustdoc() + .arg("-Zunstable-options") + .arg("--emit=invocation-specific") + .output("invocation-only") + .arg("--resource-suffix=-xxx") + .args(&["--theme", "y.css"]) + .args(&["--extend-css", "z.css"]) + .input("x.rs") + .run(); + assert!(Path::new("invocation-only/search-index-xxx.js").exists()); + assert!(Path::new("invocation-only/settings.html").exists()); + assert!(Path::new("invocation-only/x/all.html").exists()); + assert!(Path::new("invocation-only/x/index.html").exists()); + assert!(Path::new("invocation-only/theme-xxx.css").exists()); // generated from z.css + assert!(!Path::new("invocation-only/storage-xxx.js").exists()); + assert!(!Path::new("invocation-only/SourceSerif4-It.ttf.woff2").exists()); + // FIXME: this probably shouldn't have a suffix + assert!(Path::new("invocation-only/y-xxx.css").exists()); + // FIXME: this is technically incorrect (see `write_shared`) + assert!(!Path::new("invocation-only/main-xxx.js").exists()); + + rustdoc() + .arg("-Zunstable-options") + .arg("--emit=toolchain-shared-resources") + .output("toolchain-only") + .arg("--resource-suffix=-xxx") + .args(&["--extend-css", "z.css"]) + .input("x.rs") + .run(); + assert_eq!( + shallow_find_files("toolchain-only/static.files", |path| { + has_prefix(path, "storage-") && has_extension(path, "js") + }) + .len(), + 1 + ); + assert_eq!( + shallow_find_files("toolchain-only/static.files", |path| { + has_prefix(path, "SourceSerif4-It-") && has_extension(path, "woff2") + }) + .len(), + 1 + ); + assert_eq!( + shallow_find_files("toolchain-only/static.files", |path| { + has_prefix(path, "main-") && has_extension(path, "js") + }) + .len(), + 1 + ); + assert!(!Path::new("toolchain-only/search-index-xxx.js").exists()); + assert!(!Path::new("toolchain-only/x/index.html").exists()); + assert!(!Path::new("toolchain-only/theme.css").exists()); + assert!(!Path::new("toolchain-only/y-xxx.css").exists()); + + rustdoc() + .arg("-Zunstable-options") + .arg("--emit=toolchain-shared-resources,unversioned-shared-resources") + .output("all-shared") + .arg("--resource-suffix=-xxx") + .args(&["--extend-css", "z.css"]) + .input("x.rs") + .run(); + assert_eq!( + shallow_find_files("all-shared/static.files", |path| { + has_prefix(path, "storage-") && has_extension(path, "js") + }) + .len(), + 1 + ); + assert_eq!( + shallow_find_files("all-shared/static.files", |path| { + has_prefix(path, "SourceSerif4-It-") && has_extension(path, "woff2") + }) + .len(), + 1 + ); + assert!(!Path::new("all-shared/search-index-xxx.js").exists()); + assert!(!Path::new("all-shared/settings.html").exists()); + assert!(!Path::new("all-shared/x").exists()); + assert!(!Path::new("all-shared/src").exists()); + assert!(!Path::new("all-shared/theme.css").exists()); + assert_eq!( + shallow_find_files("all-shared/static.files", |path| { + has_prefix(path, "main-") && has_extension(path, "js") + }) + .len(), + 1 + ); + assert!(!Path::new("all-shared/y-xxx.css").exists()); +} From 4a15fe44e3574040c469dd8ed66f26ca4d2d09c5 Mon Sep 17 00:00:00 2001 From: Oneirical Date: Thu, 4 Jul 2024 16:02:45 -0400 Subject: [PATCH 721/892] rewrite emit-path-unhashed to rmake --- src/tools/run-make-support/src/diff/mod.rs | 34 +++++++++++++++-- .../tidy/src/allowed_run_make_makefiles.txt | 1 - tests/run-make/emit-path-unhashed/Makefile | 37 ------------------- tests/run-make/emit-path-unhashed/rmake.rs | 34 +++++++++++++++++ 4 files changed, 65 insertions(+), 41 deletions(-) delete mode 100644 tests/run-make/emit-path-unhashed/Makefile create mode 100644 tests/run-make/emit-path-unhashed/rmake.rs diff --git a/src/tools/run-make-support/src/diff/mod.rs b/src/tools/run-make-support/src/diff/mod.rs index 3e0bdc1c6f64c..24fa88af82ec2 100644 --- a/src/tools/run-make-support/src/diff/mod.rs +++ b/src/tools/run-make-support/src/diff/mod.rs @@ -87,9 +87,7 @@ impl Diff { self } - #[track_caller] - pub fn run(&mut self) { - self.drop_bomb.defuse(); + fn run_common(&self) -> (&str, &str, String, String) { let expected = self.expected.as_ref().expect("expected text not set"); let mut actual = self.actual.as_ref().expect("actual text not set").to_string(); let expected_name = self.expected_name.as_ref().unwrap(); @@ -104,6 +102,14 @@ impl Diff { .header(expected_name, actual_name) .to_string(); + (expected_name, actual_name, output, actual) + } + + #[track_caller] + pub fn run(&mut self) { + self.drop_bomb.defuse(); + let (expected_name, actual_name, output, actual) = self.run_common(); + if !output.is_empty() { // If we can bless (meaning we have a file to write into and the `RUSTC_BLESS_TEST` // environment variable set), then we write into the file and return. @@ -120,4 +126,26 @@ impl Diff { ) } } + + #[track_caller] + pub fn run_fail(&mut self) { + self.drop_bomb.defuse(); + let (expected_name, actual_name, output, actual) = self.run_common(); + + if output.is_empty() { + // If we can bless (meaning we have a file to write into and the `RUSTC_BLESS_TEST` + // environment variable set), then we write into the file and return. + if let Some(ref expected_file) = self.expected_file { + if std::env::var("RUSTC_BLESS_TEST").is_ok() { + println!("Blessing `{}`", expected_file.display()); + fs_wrapper::write(expected_file, actual); + return; + } + } + panic!( + "test failed: `{}` is not different from `{}`\n\n{}", + expected_name, actual_name, output + ) + } + } } diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index 73d6af50ea03a..13fe75aac0f9b 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -23,7 +23,6 @@ run-make/dep-info-spaces/Makefile run-make/dep-info/Makefile run-make/dump-ice-to-disk/Makefile run-make/dump-mono-stats/Makefile -run-make/emit-path-unhashed/Makefile run-make/emit-to-stdout/Makefile run-make/env-dep-info/Makefile run-make/export-executable-symbols/Makefile diff --git a/tests/run-make/emit-path-unhashed/Makefile b/tests/run-make/emit-path-unhashed/Makefile deleted file mode 100644 index 611f8578140e4..0000000000000 --- a/tests/run-make/emit-path-unhashed/Makefile +++ /dev/null @@ -1,37 +0,0 @@ -include ../tools.mk - -OUT=$(TMPDIR)/emit - -# --emit KIND=PATH should not affect crate hash vs --emit KIND -all: $(OUT)/a/libfoo.rlib $(OUT)/b/libfoo.rlib $(OUT)/c/libfoo.rlib \ - $(TMPDIR)/libfoo.rlib - $(RUSTC) -Zls=root $(TMPDIR)/libfoo.rlib > $(TMPDIR)/base.txt - $(RUSTC) -Zls=root $(OUT)/a/libfoo.rlib > $(TMPDIR)/a.txt - $(RUSTC) -Zls=root $(OUT)/b/libfoo.rlib > $(TMPDIR)/b.txt - $(RUSTC) -Zls=root $(OUT)/c/libfoo.rlib > $(TMPDIR)/c.txt - - diff $(TMPDIR)/base.txt $(TMPDIR)/a.txt - diff $(TMPDIR)/base.txt $(TMPDIR)/b.txt - - # Different KIND parameters do affect hash. - # diff exits 1 on difference, 2 on trouble - diff $(TMPDIR)/base.txt $(TMPDIR)/c.txt ; test "$$?" -eq 1 - -# Default output name -$(TMPDIR)/libfoo.rlib: foo.rs - $(RUSTC) --emit link foo.rs - -# Output named with -o -$(OUT)/a/libfoo.rlib: foo.rs - mkdir -p $(OUT)/a - $(RUSTC) --emit link -o $@ foo.rs - -# Output named with KIND=PATH -$(OUT)/b/libfoo.rlib: foo.rs - mkdir -p $(OUT)/b - $(RUSTC) --emit link=$@ foo.rs - -# Output multiple kinds -$(OUT)/c/libfoo.rlib: foo.rs - mkdir -p $(OUT)/c - $(RUSTC) --emit link=$@,metadata foo.rs diff --git a/tests/run-make/emit-path-unhashed/rmake.rs b/tests/run-make/emit-path-unhashed/rmake.rs new file mode 100644 index 0000000000000..ce56c19758868 --- /dev/null +++ b/tests/run-make/emit-path-unhashed/rmake.rs @@ -0,0 +1,34 @@ +// Specifying how rustc outputs a file can be done in different ways, such as +// the output flag or the KIND=NAME syntax. However, some of these methods used +// to result in different hashes on output files even though they yielded the +// exact same result otherwise. This was fixed in #86045, and this test checks +// that the hash is only modified when the output is made different, such as by +// adding a new output type (in this test, metadata). +// See https://github.com/rust-lang/rust/issues/86044 + +use run_make_support::{diff, fs_wrapper, rustc}; + +fn main() { + fs_wrapper::create_dir("emit"); + fs_wrapper::create_dir("emit/a"); + fs_wrapper::create_dir("emit/b"); + fs_wrapper::create_dir("emit/c"); + // The default output name. + rustc().emit("link").input("foo.rs").run(); + // The output is named with the output flag. + rustc().emit("link").output("emit/a/libfoo.rlib").input("foo.rs").run(); + // The output is named with link=NAME. + rustc().emit("link=emit/b/libfoo.rlib").input("foo.rs").run(); + // The output is named with link=NAME, with an additional kind tacked on. + rustc().emit("link=emit/c/libfoo.rlib,metadata").input("foo.rs").run(); + + let base = rustc().arg("-Zls=root").input("libfoo.rlib").run().stdout_utf8(); + let a = rustc().arg("-Zls=root").input("emit/a/libfoo.rlib").run().stdout_utf8(); + let b = rustc().arg("-Zls=root").input("emit/b/libfoo.rlib").run().stdout_utf8(); + let c = rustc().arg("-Zls=root").input("emit/c/libfoo.rlib").run().stdout_utf8(); + // Both the output flag and link=NAME methods do not modify the hash of the output file. + diff().expected_text("base", &base).actual_text("a", a).run(); + diff().expected_text("base", &base).actual_text("b", b).run(); + // However, having multiple types of outputs does modify the hash. + diff().expected_text("base", &base).actual_text("c", c).run_fail(); +} From 3d699a4fa1eee76a8d8951e449d5df37061af658 Mon Sep 17 00:00:00 2001 From: DianQK Date: Fri, 5 Jul 2024 22:06:57 +0800 Subject: [PATCH 722/892] Update LLVM submodule --- src/llvm-project | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/llvm-project b/src/llvm-project index e6a6470d1eb4c..c54cff0e6e4d1 160000 --- a/src/llvm-project +++ b/src/llvm-project @@ -1 +1 @@ -Subproject commit e6a6470d1eb4c88fee4b1ea98cd8e0ac4a181c16 +Subproject commit c54cff0e6e4d1a0d0a2df7c1ce3d96cdd554763e From f763d621494d2f6358c3e774596468275e6ad046 Mon Sep 17 00:00:00 2001 From: Alona Enraght-Moony Date: Fri, 5 Jul 2024 14:14:35 +0000 Subject: [PATCH 723/892] Fix a few doc comment for compiler-interal API docs. They only used `//` instead of `///` so weren't picked up by rustdoc. --- .../rustc_hir_typeck/src/typeck_root_ctxt.rs | 2 +- .../src/elaborate_drops.rs | 20 +++++++++---------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/typeck_root_ctxt.rs b/compiler/rustc_hir_typeck/src/typeck_root_ctxt.rs index b6e9000ef9506..c99e8a7fe8ecf 100644 --- a/compiler/rustc_hir_typeck/src/typeck_root_ctxt.rs +++ b/compiler/rustc_hir_typeck/src/typeck_root_ctxt.rs @@ -18,7 +18,7 @@ use rustc_trait_selection::traits::{ use std::cell::RefCell; use std::ops::Deref; -// Data shared between a "typeck root" and its nested bodies, +/// Data shared between a "typeck root" and its nested bodies, /// e.g. closures defined within the function. For example: /// ```ignore (illustrative) /// fn foo() { diff --git a/compiler/rustc_mir_transform/src/elaborate_drops.rs b/compiler/rustc_mir_transform/src/elaborate_drops.rs index fbbb8c5e47245..25bebb0539a4f 100644 --- a/compiler/rustc_mir_transform/src/elaborate_drops.rs +++ b/compiler/rustc_mir_transform/src/elaborate_drops.rs @@ -33,16 +33,16 @@ use std::fmt; /// as it would allow running a destructor on a place behind a reference: /// /// ```text -// fn drop_term(t: &mut T) { -// mir! { -// { -// Drop(*t, exit) -// } -// exit = { -// Return() -// } -// } -// } +/// fn drop_term(t: &mut T) { +/// mir! { +/// { +/// Drop(*t, exit) +/// } +/// exit = { +/// Return() +/// } +/// } +/// } /// ``` pub struct ElaborateDrops; From 1e4d821136033fb08ac5140127f37f35ff687273 Mon Sep 17 00:00:00 2001 From: Oneirical Date: Tue, 25 Jun 2024 13:22:02 -0400 Subject: [PATCH 724/892] rewrite pgo-gen to rmake --- src/tools/run-make-support/src/lib.rs | 1 - .../tidy/src/allowed_run_make_makefiles.txt | 1 - tests/run-make/pgo-gen/Makefile | 11 ----------- tests/run-make/pgo-gen/rmake.rs | 18 ++++++++++++++++++ 4 files changed, 18 insertions(+), 13 deletions(-) delete mode 100644 tests/run-make/pgo-gen/Makefile create mode 100644 tests/run-make/pgo-gen/rmake.rs diff --git a/src/tools/run-make-support/src/lib.rs b/src/tools/run-make-support/src/lib.rs index af5ae6a8e608c..6c1bcc6d7cd90 100644 --- a/src/tools/run-make-support/src/lib.rs +++ b/src/tools/run-make-support/src/lib.rs @@ -272,7 +272,6 @@ pub fn shallow_find_files, F: Fn(&PathBuf) -> bool>( for entry in fs_wrapper::read_dir(path) { let entry = entry.expect("failed to read directory entry."); let path = entry.path(); - if path.is_file() && closure(&path) { matching_files.push(path); } diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index 70c1b055c6e40..97990e5923561 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -109,7 +109,6 @@ run-make/pass-non-c-like-enum-to-c/Makefile run-make/pdb-buildinfo-cl-cmd/Makefile run-make/pgo-gen-lto/Makefile run-make/pgo-gen-no-imp-symbols/Makefile -run-make/pgo-gen/Makefile run-make/pgo-indirect-call-promotion/Makefile run-make/pgo-use/Makefile run-make/pointer-auth-link-with-c/Makefile diff --git a/tests/run-make/pgo-gen/Makefile b/tests/run-make/pgo-gen/Makefile deleted file mode 100644 index c1d456986fb28..0000000000000 --- a/tests/run-make/pgo-gen/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -# needs-profiler-support -# ignore-cross-compile - -include ../tools.mk - -COMPILE_FLAGS=-g -Cprofile-generate="$(TMPDIR)" - -all: - $(RUSTC) $(COMPILE_FLAGS) test.rs - $(call RUN,test) || exit 1 - [ -e "$(TMPDIR)"/default_*.profraw ] || (echo "No .profraw file"; exit 1) diff --git a/tests/run-make/pgo-gen/rmake.rs b/tests/run-make/pgo-gen/rmake.rs new file mode 100644 index 0000000000000..d35b29302648e --- /dev/null +++ b/tests/run-make/pgo-gen/rmake.rs @@ -0,0 +1,18 @@ +// -C profile-generate, when used with rustc, is supposed to output +// profile files (.profraw) after running a binary to analyze how the compiler +// optimizes code. This test checks that these files are generated. +// See https://github.com/rust-lang/rust/pull/48346 + +//@ needs-profiler-support +//@ ignore-cross-compile + +use run_make_support::{cwd, find_files_by_prefix_and_extension, run, rustc}; + +fn main() { + rustc().arg("-g").profile_generate(cwd()).run(); + run("test"); + assert!( + find_files_by_prefix_and_extension(cwd(), "default", "profraw").len() > 0, + "no .profraw file generated" + ); +} From a1555eb0d618eb1abae39d07e6428e2688788b7b Mon Sep 17 00:00:00 2001 From: Oneirical Date: Tue, 25 Jun 2024 13:46:20 -0400 Subject: [PATCH 725/892] rewrite pgo-use to rmake --- .../tidy/src/allowed_run_make_makefiles.txt | 1 - tests/run-make/pgo-use/Makefile | 43 --------------- tests/run-make/pgo-use/rmake.rs | 54 +++++++++++++++++++ 3 files changed, 54 insertions(+), 44 deletions(-) delete mode 100644 tests/run-make/pgo-use/Makefile create mode 100644 tests/run-make/pgo-use/rmake.rs diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index 97990e5923561..2050189cead96 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -110,7 +110,6 @@ run-make/pdb-buildinfo-cl-cmd/Makefile run-make/pgo-gen-lto/Makefile run-make/pgo-gen-no-imp-symbols/Makefile run-make/pgo-indirect-call-promotion/Makefile -run-make/pgo-use/Makefile run-make/pointer-auth-link-with-c/Makefile run-make/print-calling-conventions/Makefile run-make/print-target-list/Makefile diff --git a/tests/run-make/pgo-use/Makefile b/tests/run-make/pgo-use/Makefile deleted file mode 100644 index 92098a4019c47..0000000000000 --- a/tests/run-make/pgo-use/Makefile +++ /dev/null @@ -1,43 +0,0 @@ -# needs-profiler-support -# ignore-cross-compile - -include ../tools.mk - -# This test makes sure that PGO profiling data leads to cold functions being -# marked as `cold` and hot functions with `inlinehint`. -# The test program contains an `if` were actual execution only ever takes the -# `else` branch. Accordingly, we expect the function that is never called to -# be marked as cold. -# -# Disable the pre-inlining pass (i.e. a pass that does some inlining before -# it adds the profiling instrumentation). Disabling this pass leads to -# rather predictable IR which we need for this test to be stable. - -COMMON_FLAGS=-Copt-level=2 -Ccodegen-units=1 -Cllvm-args=-disable-preinline - -ifeq ($(UNAME),Darwin) -# macOS does not have the `tac` command, but `tail -r` does the same thing -TAC := tail -r -else -# some other platforms don't support the `-r` flag for `tail`, so use `tac` -TAC := tac -endif - -all: - # Compile the test program with instrumentation - $(RUSTC) $(COMMON_FLAGS) -Cprofile-generate="$(TMPDIR)" main.rs - # Run it in order to generate some profiling data - $(call RUN,main some-argument) || exit 1 - # Postprocess the profiling data so it can be used by the compiler - "$(LLVM_BIN_DIR)"/llvm-profdata merge \ - -o "$(TMPDIR)"/merged.profdata \ - "$(TMPDIR)"/default_*.profraw - # Compile the test program again, making use of the profiling data - $(RUSTC) $(COMMON_FLAGS) -Cprofile-use="$(TMPDIR)"/merged.profdata --emit=llvm-ir main.rs - # Check that the generate IR contains some things that we expect - # - # We feed the file into LLVM FileCheck tool *in reverse* so that we see the - # line with the function name before the line with the function attributes. - # FileCheck only supports checking that something matches on the next line, - # but not if something matches on the previous line. - $(TAC) "$(TMPDIR)"/main.ll | "$(LLVM_FILECHECK)" filecheck-patterns.txt diff --git a/tests/run-make/pgo-use/rmake.rs b/tests/run-make/pgo-use/rmake.rs new file mode 100644 index 0000000000000..04777821b51b0 --- /dev/null +++ b/tests/run-make/pgo-use/rmake.rs @@ -0,0 +1,54 @@ +// This test makes sure that PGO profiling data leads to cold functions being +// marked as `cold` and hot functions with `inlinehint`. +// The test program contains an `if` where actual execution only ever takes the +// `else` branch. Accordingly, we expect the function that is never called to +// be marked as cold. +// See https://github.com/rust-lang/rust/pull/60262 + +//@ needs-profiler-support +//@ ignore-cross-compile + +use run_make_support::{ + cwd, find_files_by_prefix_and_extension, fs_wrapper, llvm_filecheck, llvm_profdata, + run_with_args, rustc, +}; + +fn main() { + // Compile the test program with instrumentation + // Disable the pre-inlining pass (i.e. a pass that does some inlining before + // it adds the profiling instrumentation). Disabling this pass leads to + // rather predictable IR which we need for this test to be stable. + rustc() + .opt_level("2") + .codegen_units(1) + .arg("-Cllvm-args=-disable-preinline") + .profile_generate(cwd()) + .input("main.rs") + .run(); + // Run it in order to generate some profiling data + run_with_args("main", &["some-argument"]); + // Postprocess the profiling data so it can be used by the compiler + llvm_profdata() + .merge() + .output("merged.profdata") + .input(find_files_by_prefix_and_extension(cwd(), "default", "profraw").get(0).unwrap()) + .run(); + // Compile the test program again, making use of the profiling data + rustc() + .opt_level("2") + .codegen_units(1) + .arg("-Cllvm-args=-disable-preinline") + .profile_use("merged.profdata") + .emit("llvm-ir") + .input("main.rs") + .run(); + // Check that the generate IR contains some things that we expect + // + // We feed the file into LLVM FileCheck tool *in reverse* so that we see the + // line with the function name before the line with the function attributes. + // FileCheck only supports checking that something matches on the next line, + // but not if something matches on the previous line. + let mut bytes = fs_wrapper::read("interesting.ll"); + bytes.reverse(); + llvm_filecheck().patterns("filecheck-patterns.txt").stdin(bytes).run(); +} From b15e72a9ed8f34b98d32eba2eb5d3a3d9befea77 Mon Sep 17 00:00:00 2001 From: Oneirical Date: Tue, 25 Jun 2024 13:58:48 -0400 Subject: [PATCH 726/892] rewrite profile to rmake --- .../tidy/src/allowed_run_make_makefiles.txt | 1 - tests/run-make/profile/Makefile | 13 ----------- tests/run-make/profile/rmake.rs | 22 +++++++++++++++++++ 3 files changed, 22 insertions(+), 14 deletions(-) delete mode 100644 tests/run-make/profile/Makefile create mode 100644 tests/run-make/profile/rmake.rs diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index 2050189cead96..0cb3275d7e934 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -113,7 +113,6 @@ run-make/pgo-indirect-call-promotion/Makefile run-make/pointer-auth-link-with-c/Makefile run-make/print-calling-conventions/Makefile run-make/print-target-list/Makefile -run-make/profile/Makefile run-make/prune-link-args/Makefile run-make/raw-dylib-alt-calling-convention/Makefile run-make/raw-dylib-c/Makefile diff --git a/tests/run-make/profile/Makefile b/tests/run-make/profile/Makefile deleted file mode 100644 index 7919b18ba74a5..0000000000000 --- a/tests/run-make/profile/Makefile +++ /dev/null @@ -1,13 +0,0 @@ -# needs-profiler-support -# ignore-cross-compile - -include ../tools.mk - -all: - $(RUSTC) -g -Z profile test.rs - $(call RUN,test) || exit 1 - [ -e "$(TMPDIR)/test.gcno" ] || (echo "No .gcno file"; exit 1) - [ -e "$(TMPDIR)/test.gcda" ] || (echo "No .gcda file"; exit 1) - $(RUSTC) -g -Z profile -Z profile-emit=$(TMPDIR)/abc/abc.gcda test.rs - $(call RUN,test) || exit 1 - [ -e "$(TMPDIR)/abc/abc.gcda" ] || (echo "gcda file not emitted to defined path"; exit 1) diff --git a/tests/run-make/profile/rmake.rs b/tests/run-make/profile/rmake.rs new file mode 100644 index 0000000000000..8d41978baecdd --- /dev/null +++ b/tests/run-make/profile/rmake.rs @@ -0,0 +1,22 @@ +// This test revolves around the rustc flag -Z profile, which should +// generate a .gcno file (initial profiling information) as well +// as a .gcda file (branch counters). The path where these are emitted +// should also be configurable with -Z profile-emit. This test checks +// that the files are produced, and then that the latter flag is respected. +// See https://github.com/rust-lang/rust/pull/42433 + +//@ ignore-cross-compile +//@ needs-profiler-support + +use run_make_support::{run, rustc}; +use std::path::Path; + +fn main() { + rustc().arg("-g").arg("-Zprofile").input("test.rs").run(); + run("test"); + assert!(Path::new("test.gcno").exists(), "no .gcno file"); + assert!(Path::new("test.gcda").exists(), "no .gcda file"); + rustc().arg("-g").arg("-Zprofile").arg("-Zprofile-emit=abc/abc.gcda").input("test.rs").run(); + run("test"); + assert!(Path::new("abc/abc.gcda").exists(), "gcda file not emitted to defined path"); +} From 3cdce7ee1050930b696683906430c0641e55b3fc Mon Sep 17 00:00:00 2001 From: Oneirical Date: Fri, 28 Jun 2024 16:25:12 -0400 Subject: [PATCH 727/892] rewrite output-type-permutations to rmake --- .../tidy/src/allowed_run_make_makefiles.txt | 1 - .../output-type-permutations/Makefile | 147 --------------- .../output-type-permutations/rmake.rs | 178 ++++++++++++++++++ 3 files changed, 178 insertions(+), 148 deletions(-) delete mode 100644 tests/run-make/output-type-permutations/Makefile create mode 100644 tests/run-make/output-type-permutations/rmake.rs diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index 70c1b055c6e40..3a9755e5658c0 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -100,7 +100,6 @@ run-make/no-alloc-shim/Makefile run-make/no-builtins-attribute/Makefile run-make/no-duplicate-libs/Makefile run-make/obey-crate-type-flag/Makefile -run-make/output-type-permutations/Makefile run-make/panic-abort-eh_frame/Makefile run-make/pass-linker-flags-flavor/Makefile run-make/pass-linker-flags-from-dep/Makefile diff --git a/tests/run-make/output-type-permutations/Makefile b/tests/run-make/output-type-permutations/Makefile deleted file mode 100644 index 035033b9fddd3..0000000000000 --- a/tests/run-make/output-type-permutations/Makefile +++ /dev/null @@ -1,147 +0,0 @@ -# ignore-cross-compile -include ../tools.mk - -all: - $(RUSTC) foo.rs --crate-type=rlib,dylib,staticlib - $(call REMOVE_RLIBS,bar) - $(call REMOVE_DYLIBS,bar) - rm $(call STATICLIB,bar) - rm -f $(TMPDIR)/{lib,}bar.{dll.exp,dll.lib,pdb,dll.a} - # Check that $(TMPDIR) is empty. - [ "$$(ls -1 $(TMPDIR) | wc -l)" -eq "0" ] - - $(RUSTC) foo.rs --crate-type=bin - rm $(TMPDIR)/$(call BIN,bar) - rm -f $(TMPDIR)/bar.pdb - [ "$$(ls -1 $(TMPDIR) | wc -l)" -eq "0" ] - - $(RUSTC) foo.rs --emit=asm,llvm-ir,llvm-bc,obj,link - rm $(TMPDIR)/bar.ll - rm $(TMPDIR)/bar.bc - rm $(TMPDIR)/bar.s - rm $(TMPDIR)/bar.o - rm $(TMPDIR)/$(call BIN,bar) - rm -f $(TMPDIR)/bar.pdb - [ "$$(ls -1 $(TMPDIR) | wc -l)" -eq "0" ] - - $(RUSTC) foo.rs --emit asm -o $(TMPDIR)/foo - rm $(TMPDIR)/foo - $(RUSTC) foo.rs --emit asm=$(TMPDIR)/foo - rm $(TMPDIR)/foo - $(RUSTC) foo.rs --emit=asm=$(TMPDIR)/foo - rm $(TMPDIR)/foo - [ "$$(ls -1 $(TMPDIR) | wc -l)" -eq "0" ] - - $(RUSTC) foo.rs --emit llvm-bc -o $(TMPDIR)/foo - rm $(TMPDIR)/foo - $(RUSTC) foo.rs --emit llvm-bc=$(TMPDIR)/foo - rm $(TMPDIR)/foo - $(RUSTC) foo.rs --emit=llvm-bc=$(TMPDIR)/foo - rm $(TMPDIR)/foo - [ "$$(ls -1 $(TMPDIR) | wc -l)" -eq "0" ] - - $(RUSTC) foo.rs --emit llvm-ir -o $(TMPDIR)/foo - rm $(TMPDIR)/foo - $(RUSTC) foo.rs --emit llvm-ir=$(TMPDIR)/foo - rm $(TMPDIR)/foo - $(RUSTC) foo.rs --emit=llvm-ir=$(TMPDIR)/foo - rm $(TMPDIR)/foo - [ "$$(ls -1 $(TMPDIR) | wc -l)" -eq "0" ] - - $(RUSTC) foo.rs --emit obj -o $(TMPDIR)/foo - rm $(TMPDIR)/foo - $(RUSTC) foo.rs --emit obj=$(TMPDIR)/foo - rm $(TMPDIR)/foo - $(RUSTC) foo.rs --emit=obj=$(TMPDIR)/foo - rm $(TMPDIR)/foo - [ "$$(ls -1 $(TMPDIR) | wc -l)" -eq "0" ] - - $(RUSTC) foo.rs --emit link -o $(TMPDIR)/$(call BIN,foo) - rm $(TMPDIR)/$(call BIN,foo) - $(RUSTC) foo.rs --emit link=$(TMPDIR)/$(call BIN,foo) - rm $(TMPDIR)/$(call BIN,foo) - $(RUSTC) foo.rs --emit=link=$(TMPDIR)/$(call BIN,foo) - rm $(TMPDIR)/$(call BIN,foo) - rm -f $(TMPDIR)/foo.pdb - [ "$$(ls -1 $(TMPDIR) | wc -l)" -eq "0" ] - - $(RUSTC) foo.rs --crate-type=rlib -o $(TMPDIR)/foo - rm $(TMPDIR)/foo - $(RUSTC) foo.rs --crate-type=rlib --emit link=$(TMPDIR)/foo - rm $(TMPDIR)/foo - $(RUSTC) foo.rs --crate-type=rlib --emit=link=$(TMPDIR)/foo - rm $(TMPDIR)/foo - [ "$$(ls -1 $(TMPDIR) | wc -l)" -eq "0" ] - - $(RUSTC) foo.rs --crate-type=dylib -o $(TMPDIR)/$(call BIN,foo) - rm $(TMPDIR)/$(call BIN,foo) - $(RUSTC) foo.rs --crate-type=dylib --emit link=$(TMPDIR)/$(call BIN,foo) - rm $(TMPDIR)/$(call BIN,foo) - $(RUSTC) foo.rs --crate-type=dylib --emit=link=$(TMPDIR)/$(call BIN,foo) - rm $(TMPDIR)/$(call BIN,foo) - rm -f $(TMPDIR)/{lib,}foo.{dll.exp,dll.lib,pdb,dll.a,exe.a} - [ "$$(ls -1 $(TMPDIR) | wc -l)" -eq "0" ] || (ls -1 $(TMPDIR) && exit 1) - - $(RUSTC) foo.rs --crate-type=staticlib -o $(TMPDIR)/foo - rm $(TMPDIR)/foo - $(RUSTC) foo.rs --crate-type=staticlib --emit link=$(TMPDIR)/foo - rm $(TMPDIR)/foo - $(RUSTC) foo.rs --crate-type=staticlib --emit=link=$(TMPDIR)/foo - rm $(TMPDIR)/foo - [ "$$(ls -1 $(TMPDIR) | wc -l)" -eq "0" ] - - $(RUSTC) foo.rs --crate-type=bin -o $(TMPDIR)/$(call BIN,foo) - rm $(TMPDIR)/$(call BIN,foo) - $(RUSTC) foo.rs --crate-type=bin --emit link=$(TMPDIR)/$(call BIN,foo) - rm $(TMPDIR)/$(call BIN,foo) - $(RUSTC) foo.rs --crate-type=bin --emit=link=$(TMPDIR)/$(call BIN,foo) - rm $(TMPDIR)/$(call BIN,foo) - rm -f $(TMPDIR)/foo.pdb - [ "$$(ls -1 $(TMPDIR) | wc -l)" -eq "0" ] - - $(RUSTC) foo.rs --emit llvm-ir=$(TMPDIR)/ir \ - --emit link \ - --crate-type=rlib - rm $(TMPDIR)/ir - rm $(TMPDIR)/libbar.rlib - [ "$$(ls -1 $(TMPDIR) | wc -l)" -eq "0" ] - - $(RUSTC) foo.rs --emit asm=$(TMPDIR)/asm \ - --emit llvm-ir=$(TMPDIR)/ir \ - --emit llvm-bc=$(TMPDIR)/bc \ - --emit obj=$(TMPDIR)/obj \ - --emit link=$(TMPDIR)/link \ - --crate-type=staticlib - rm $(TMPDIR)/asm - rm $(TMPDIR)/ir - rm $(TMPDIR)/bc - rm $(TMPDIR)/obj - rm $(TMPDIR)/link - $(RUSTC) foo.rs --emit=asm=$(TMPDIR)/asm \ - --emit llvm-ir=$(TMPDIR)/ir \ - --emit=llvm-bc=$(TMPDIR)/bc \ - --emit obj=$(TMPDIR)/obj \ - --emit=link=$(TMPDIR)/link \ - --crate-type=staticlib - rm $(TMPDIR)/asm - rm $(TMPDIR)/ir - rm $(TMPDIR)/bc - rm $(TMPDIR)/obj - rm $(TMPDIR)/link - [ "$$(ls -1 $(TMPDIR) | wc -l)" -eq "0" ] - - $(RUSTC) foo.rs --emit=asm,llvm-ir,llvm-bc,obj,link --crate-type=staticlib - rm $(TMPDIR)/bar.ll - rm $(TMPDIR)/bar.s - rm $(TMPDIR)/bar.o - rm $(call STATICLIB,bar) - mv $(TMPDIR)/bar.bc $(TMPDIR)/foo.bc - # Don't check that the $(TMPDIR) is empty - we left `foo.bc` for later - # comparison. - - $(RUSTC) foo.rs --emit=llvm-bc,link --crate-type=rlib - cmp $(TMPDIR)/foo.bc $(TMPDIR)/bar.bc - rm $(TMPDIR)/bar.bc - rm $(TMPDIR)/foo.bc - $(call REMOVE_RLIBS,bar) - [ "$$(ls -1 $(TMPDIR) | wc -l)" -eq "0" ] diff --git a/tests/run-make/output-type-permutations/rmake.rs b/tests/run-make/output-type-permutations/rmake.rs new file mode 100644 index 0000000000000..69af1274c68a1 --- /dev/null +++ b/tests/run-make/output-type-permutations/rmake.rs @@ -0,0 +1,178 @@ +// In 2014, rustc's output flags were reworked to be a lot more modular. +// This test uses these output flags in an expansive variety of combinations +// and syntax styles, checking that compilation is successful and that no unexpected +// files are created. +// The assert_eq! checks that "1 file remains" at the end of each part of the test, +// because foo.rs counts as a file, and should be the only remaining one. +// See https://github.com/rust-lang/rust/pull/12020 + +use run_make_support::{ + bin_name, cwd, dynamic_lib_name, fs_wrapper, rust_lib_name, rustc, static_lib_name, +}; + +fn remove_artifacts() { + std::fs::remove_file("libbar.ddl.exp").unwrap_or_default(); + std::fs::remove_file("libbar.dll.lib").unwrap_or_default(); + std::fs::remove_file("libbar.pdb").unwrap_or_default(); + std::fs::remove_file("libbar.dll.a").unwrap_or_default(); + std::fs::remove_file("libbar.exe.a").unwrap_or_default(); + std::fs::remove_file("bar.ddl.exp").unwrap_or_default(); + std::fs::remove_file("bar.dll.lib").unwrap_or_default(); + std::fs::remove_file("bar.pdb").unwrap_or_default(); + std::fs::remove_file("bar.dll.a").unwrap_or_default(); + std::fs::remove_file("bar.exe.a").unwrap_or_default(); +} + +fn main() { + rustc().input("foo.rs").crate_type("rlib,dylib,staticlib").run(); + fs_wrapper::remove_file(rust_lib_name("bar")); + fs_wrapper::remove_file(dynamic_lib_name("bar")); + fs_wrapper::remove_file(static_lib_name("bar")); + remove_artifacts(); + assert_eq!(fs_wrapper::read_dir(cwd()).count(), 1); + + rustc().input("foo.rs").crate_type("bin").run(); + fs_wrapper::remove_file(bin_name("bar")); + std::fs::remove_file("bar.pdb").unwrap_or_default(); + assert_eq!(fs_wrapper::read_dir(cwd()).count(), 1); + + rustc().input("foo.rs").emit("asm,llvm-ir,llvm-bc,obj,link").run(); + fs_wrapper::remove_file("bar.ll"); + fs_wrapper::remove_file("bar.bc"); + fs_wrapper::remove_file("bar.s"); + fs_wrapper::remove_file("bar.o"); + fs_wrapper::remove_file(bin_name("bar")); + std::fs::remove_file("bar.pdb").unwrap_or_default(); + assert_eq!(fs_wrapper::read_dir(cwd()).count(), 1); + + rustc().input("foo.rs").emit("asm").output("foo").run(); + fs_wrapper::remove_file("foo"); + rustc().input("foo.rs").emit("asm=foo").run(); + fs_wrapper::remove_file("foo"); + rustc().input("foo.rs").arg("--emit=asm=foo").run(); + fs_wrapper::remove_file("foo"); + assert_eq!(fs_wrapper::read_dir(cwd()).count(), 1); + + rustc().input("foo.rs").emit("llvm-bc").output("foo").run(); + fs_wrapper::remove_file("foo"); + rustc().input("foo.rs").emit("llvm-bc=foo").run(); + fs_wrapper::remove_file("foo"); + rustc().input("foo.rs").arg("--emit=llvm-bc=foo").run(); + fs_wrapper::remove_file("foo"); + assert_eq!(fs_wrapper::read_dir(cwd()).count(), 1); + + rustc().input("foo.rs").emit("llvm-ir").output("foo").run(); + fs_wrapper::remove_file("foo"); + rustc().input("foo.rs").emit("llvm-ir=foo").run(); + fs_wrapper::remove_file("foo"); + rustc().input("foo.rs").arg("--emit=llvm-ir=foo").run(); + fs_wrapper::remove_file("foo"); + assert_eq!(fs_wrapper::read_dir(cwd()).count(), 1); + + rustc().input("foo.rs").emit("obj").output("foo").run(); + fs_wrapper::remove_file("foo"); + rustc().input("foo.rs").emit("obj=foo").run(); + fs_wrapper::remove_file("foo"); + rustc().input("foo.rs").arg("--emit=obj=foo").run(); + fs_wrapper::remove_file("foo"); + assert_eq!(fs_wrapper::read_dir(cwd()).count(), 1); + + let bin_foo = bin_name("foo"); + rustc().input("foo.rs").emit("link").output(&bin_foo).run(); + fs_wrapper::remove_file(&bin_foo); + rustc().input("foo.rs").emit(&format!("link={bin_foo}")).run(); + fs_wrapper::remove_file(&bin_foo); + rustc().input("foo.rs").arg(&format!("--emit=link={bin_foo}")).run(); + fs_wrapper::remove_file(&bin_foo); + std::fs::remove_file("foo.pdb").unwrap_or_default(); + assert_eq!(fs_wrapper::read_dir(cwd()).count(), 1); + + rustc().input("foo.rs").crate_type("rlib").output("foo").run(); + fs_wrapper::remove_file("foo"); + rustc().input("foo.rs").crate_type("rlib").emit("link=foo").run(); + fs_wrapper::remove_file("foo"); + rustc().input("foo.rs").crate_type("rlib").arg("--emit=link=foo").run(); + fs_wrapper::remove_file("foo"); + assert_eq!(fs_wrapper::read_dir(cwd()).count(), 1); + + rustc().input("foo.rs").crate_type("dylib").output(&bin_foo).run(); + fs_wrapper::remove_file(&bin_foo); + rustc().input("foo.rs").crate_type("dylib").emit(&format!("link={bin_foo}")).run(); + fs_wrapper::remove_file(&bin_foo); + rustc().input("foo.rs").crate_type("dylib").arg(&format!("--emit=link={bin_foo}")).run(); + fs_wrapper::remove_file(&bin_foo); + remove_artifacts(); + assert_eq!(fs_wrapper::read_dir(cwd()).count(), 1); + + rustc().input("foo.rs").crate_type("staticlib").emit("link").output("foo").run(); + fs_wrapper::remove_file("foo"); + rustc().input("foo.rs").crate_type("staticlib").emit("link=foo").run(); + fs_wrapper::remove_file("foo"); + rustc().input("foo.rs").crate_type("staticlib").arg("--emit=link=foo").run(); + fs_wrapper::remove_file("foo"); + assert_eq!(fs_wrapper::read_dir(cwd()).count(), 1); + + rustc().input("foo.rs").crate_type("bin").output(&bin_foo).run(); + fs_wrapper::remove_file(&bin_foo); + rustc().input("foo.rs").crate_type("bin").emit(&format!("link={bin_foo}")).run(); + fs_wrapper::remove_file(&bin_foo); + rustc().input("foo.rs").crate_type("bin").arg(&format!("--emit=link={bin_foo}")).run(); + fs_wrapper::remove_file(&bin_foo); + std::fs::remove_file("foo.pdb").unwrap_or_default(); + assert_eq!(fs_wrapper::read_dir(cwd()).count(), 1); + + rustc().input("foo.rs").emit("llvm-ir=ir").emit("link").crate_type("rlib").run(); + fs_wrapper::remove_file("ir"); + fs_wrapper::remove_file(rust_lib_name("bar")); + assert_eq!(fs_wrapper::read_dir(cwd()).count(), 1); + + rustc() + .input("foo.rs") + .emit("asm=asm") + .emit("llvm-ir=ir") + .emit("llvm-bc=bc") + .emit("obj=obj") + .emit("link=link") + .crate_type("staticlib") + .run(); + fs_wrapper::remove_file("asm"); + fs_wrapper::remove_file("ir"); + fs_wrapper::remove_file("bc"); + fs_wrapper::remove_file("obj"); + fs_wrapper::remove_file("link"); + assert_eq!(fs_wrapper::read_dir(cwd()).count(), 1); + + rustc() + .input("foo.rs") + .arg("--emit=asm=asm") + .arg("--emit") + .arg("llvm-ir=ir") + .arg("--emit=llvm-bc=bc") + .arg("--emit") + .arg("obj=obj") + .arg("--emit=link=link") + .crate_type("staticlib") + .run(); + fs_wrapper::remove_file("asm"); + fs_wrapper::remove_file("ir"); + fs_wrapper::remove_file("bc"); + fs_wrapper::remove_file("obj"); + fs_wrapper::remove_file("link"); + assert_eq!(fs_wrapper::read_dir(cwd()).count(), 1); + + rustc().input("foo.rs").emit("asm,llvm-ir,llvm-bc,obj,link").crate_type("staticlib").run(); + fs_wrapper::remove_file("bar.ll"); + fs_wrapper::remove_file("bar.s"); + fs_wrapper::remove_file("bar.o"); + fs_wrapper::remove_file(static_lib_name("bar")); + fs_wrapper::rename("bar.bc", "foo.bc"); + // Don't check that no files except foo.rs remain - we left `foo.bc` for later + // comparison. + + rustc().input("foo.rs").emit("llvm-bc,link").crate_type("rlib").run(); + assert_eq!(fs_wrapper::read("foo.bc"), fs_wrapper::read("bar.bc")); + fs_wrapper::remove_file("bar.bc"); + fs_wrapper::remove_file("foo.bc"); + fs_wrapper::remove_file(rust_lib_name("bar")); + assert_eq!(fs_wrapper::read_dir(cwd()).count(), 1); +} From 73994719b466350c1faf88d0bfbf20b44c29a8aa Mon Sep 17 00:00:00 2001 From: Oneirical Date: Tue, 2 Jul 2024 15:25:26 -0400 Subject: [PATCH 728/892] add shallow_find_files helper to run_make_support --- src/tools/run-make-support/src/lib.rs | 5 + .../output-type-permutations/rmake.rs | 447 +++++++++++------- 2 files changed, 285 insertions(+), 167 deletions(-) diff --git a/src/tools/run-make-support/src/lib.rs b/src/tools/run-make-support/src/lib.rs index af5ae6a8e608c..20ceb03defef9 100644 --- a/src/tools/run-make-support/src/lib.rs +++ b/src/tools/run-make-support/src/lib.rs @@ -295,6 +295,11 @@ pub fn not_contains>(path: P, expected: &str) -> bool { !path.as_ref().file_name().is_some_and(|name| name.to_str().unwrap().contains(expected)) } +/// Returns true if the filename at `path` is not in `expected`. +pub fn name_not_among>(path: P, expected: &[&'static str]) -> bool { + path.as_ref().file_name().is_some_and(|name| !expected.contains(&name.to_str().unwrap())) +} + /// Use `cygpath -w` on a path to get a Windows path string back. This assumes that `cygpath` is /// available on the platform! #[track_caller] diff --git a/tests/run-make/output-type-permutations/rmake.rs b/tests/run-make/output-type-permutations/rmake.rs index 69af1274c68a1..eb166307f6800 100644 --- a/tests/run-make/output-type-permutations/rmake.rs +++ b/tests/run-make/output-type-permutations/rmake.rs @@ -1,178 +1,291 @@ // In 2014, rustc's output flags were reworked to be a lot more modular. // This test uses these output flags in an expansive variety of combinations -// and syntax styles, checking that compilation is successful and that no unexpected -// files are created. -// The assert_eq! checks that "1 file remains" at the end of each part of the test, -// because foo.rs counts as a file, and should be the only remaining one. +// and syntax styles, checking that compilation is successful and that output +// files are exactly what is expected, no more, no less. // See https://github.com/rust-lang/rust/pull/12020 use run_make_support::{ - bin_name, cwd, dynamic_lib_name, fs_wrapper, rust_lib_name, rustc, static_lib_name, + bin_name, cwd, dynamic_lib_name, fs_wrapper, name_not_among, rust_lib_name, rustc, + shallow_find_files, static_lib_name, }; -fn remove_artifacts() { - std::fs::remove_file("libbar.ddl.exp").unwrap_or_default(); - std::fs::remove_file("libbar.dll.lib").unwrap_or_default(); - std::fs::remove_file("libbar.pdb").unwrap_or_default(); - std::fs::remove_file("libbar.dll.a").unwrap_or_default(); - std::fs::remove_file("libbar.exe.a").unwrap_or_default(); - std::fs::remove_file("bar.ddl.exp").unwrap_or_default(); - std::fs::remove_file("bar.dll.lib").unwrap_or_default(); - std::fs::remove_file("bar.pdb").unwrap_or_default(); - std::fs::remove_file("bar.dll.a").unwrap_or_default(); - std::fs::remove_file("bar.exe.a").unwrap_or_default(); +// Each test takes 4 arguments: +// `must_exist`: output files which must be found - if any are absent, the test fails +// `can_exist`: optional output files which will not trigger a failure +// `dir`: the name of the directory where the test happens +// `rustc_invocation`: the rustc command being tested +// Any unexpected output files not listed in `must_exist` or `can_exist` will cause a failure. +fn assert_expected_output_files( + must_exist: &[&'static str], + can_exist: &[&'static str], + dir: &str, + rustc_invocation: impl Fn(), +) { + fs_wrapper::create_dir(dir); + rustc_invocation(); + for file in must_exist { + fs_wrapper::remove_file(dir.to_owned() + "/" + file); + } + let actual_output_files = shallow_find_files(dir, |path| name_not_among(path, can_exist)); + if !&actual_output_files.is_empty() { + dbg!(&actual_output_files); + panic!("unexpected output artifacts detected"); + } } fn main() { - rustc().input("foo.rs").crate_type("rlib,dylib,staticlib").run(); - fs_wrapper::remove_file(rust_lib_name("bar")); - fs_wrapper::remove_file(dynamic_lib_name("bar")); - fs_wrapper::remove_file(static_lib_name("bar")); - remove_artifacts(); - assert_eq!(fs_wrapper::read_dir(cwd()).count(), 1); - - rustc().input("foo.rs").crate_type("bin").run(); - fs_wrapper::remove_file(bin_name("bar")); - std::fs::remove_file("bar.pdb").unwrap_or_default(); - assert_eq!(fs_wrapper::read_dir(cwd()).count(), 1); - - rustc().input("foo.rs").emit("asm,llvm-ir,llvm-bc,obj,link").run(); - fs_wrapper::remove_file("bar.ll"); - fs_wrapper::remove_file("bar.bc"); - fs_wrapper::remove_file("bar.s"); - fs_wrapper::remove_file("bar.o"); - fs_wrapper::remove_file(bin_name("bar")); - std::fs::remove_file("bar.pdb").unwrap_or_default(); - assert_eq!(fs_wrapper::read_dir(cwd()).count(), 1); - - rustc().input("foo.rs").emit("asm").output("foo").run(); - fs_wrapper::remove_file("foo"); - rustc().input("foo.rs").emit("asm=foo").run(); - fs_wrapper::remove_file("foo"); - rustc().input("foo.rs").arg("--emit=asm=foo").run(); - fs_wrapper::remove_file("foo"); - assert_eq!(fs_wrapper::read_dir(cwd()).count(), 1); - - rustc().input("foo.rs").emit("llvm-bc").output("foo").run(); - fs_wrapper::remove_file("foo"); - rustc().input("foo.rs").emit("llvm-bc=foo").run(); - fs_wrapper::remove_file("foo"); - rustc().input("foo.rs").arg("--emit=llvm-bc=foo").run(); - fs_wrapper::remove_file("foo"); - assert_eq!(fs_wrapper::read_dir(cwd()).count(), 1); - - rustc().input("foo.rs").emit("llvm-ir").output("foo").run(); - fs_wrapper::remove_file("foo"); - rustc().input("foo.rs").emit("llvm-ir=foo").run(); - fs_wrapper::remove_file("foo"); - rustc().input("foo.rs").arg("--emit=llvm-ir=foo").run(); - fs_wrapper::remove_file("foo"); - assert_eq!(fs_wrapper::read_dir(cwd()).count(), 1); - - rustc().input("foo.rs").emit("obj").output("foo").run(); - fs_wrapper::remove_file("foo"); - rustc().input("foo.rs").emit("obj=foo").run(); - fs_wrapper::remove_file("foo"); - rustc().input("foo.rs").arg("--emit=obj=foo").run(); - fs_wrapper::remove_file("foo"); - assert_eq!(fs_wrapper::read_dir(cwd()).count(), 1); - - let bin_foo = bin_name("foo"); - rustc().input("foo.rs").emit("link").output(&bin_foo).run(); - fs_wrapper::remove_file(&bin_foo); - rustc().input("foo.rs").emit(&format!("link={bin_foo}")).run(); - fs_wrapper::remove_file(&bin_foo); - rustc().input("foo.rs").arg(&format!("--emit=link={bin_foo}")).run(); - fs_wrapper::remove_file(&bin_foo); - std::fs::remove_file("foo.pdb").unwrap_or_default(); - assert_eq!(fs_wrapper::read_dir(cwd()).count(), 1); - - rustc().input("foo.rs").crate_type("rlib").output("foo").run(); - fs_wrapper::remove_file("foo"); - rustc().input("foo.rs").crate_type("rlib").emit("link=foo").run(); - fs_wrapper::remove_file("foo"); - rustc().input("foo.rs").crate_type("rlib").arg("--emit=link=foo").run(); - fs_wrapper::remove_file("foo"); - assert_eq!(fs_wrapper::read_dir(cwd()).count(), 1); - - rustc().input("foo.rs").crate_type("dylib").output(&bin_foo).run(); - fs_wrapper::remove_file(&bin_foo); - rustc().input("foo.rs").crate_type("dylib").emit(&format!("link={bin_foo}")).run(); - fs_wrapper::remove_file(&bin_foo); - rustc().input("foo.rs").crate_type("dylib").arg(&format!("--emit=link={bin_foo}")).run(); - fs_wrapper::remove_file(&bin_foo); - remove_artifacts(); - assert_eq!(fs_wrapper::read_dir(cwd()).count(), 1); - - rustc().input("foo.rs").crate_type("staticlib").emit("link").output("foo").run(); - fs_wrapper::remove_file("foo"); - rustc().input("foo.rs").crate_type("staticlib").emit("link=foo").run(); - fs_wrapper::remove_file("foo"); - rustc().input("foo.rs").crate_type("staticlib").arg("--emit=link=foo").run(); - fs_wrapper::remove_file("foo"); - assert_eq!(fs_wrapper::read_dir(cwd()).count(), 1); - - rustc().input("foo.rs").crate_type("bin").output(&bin_foo).run(); - fs_wrapper::remove_file(&bin_foo); - rustc().input("foo.rs").crate_type("bin").emit(&format!("link={bin_foo}")).run(); - fs_wrapper::remove_file(&bin_foo); - rustc().input("foo.rs").crate_type("bin").arg(&format!("--emit=link={bin_foo}")).run(); - fs_wrapper::remove_file(&bin_foo); - std::fs::remove_file("foo.pdb").unwrap_or_default(); - assert_eq!(fs_wrapper::read_dir(cwd()).count(), 1); - - rustc().input("foo.rs").emit("llvm-ir=ir").emit("link").crate_type("rlib").run(); - fs_wrapper::remove_file("ir"); - fs_wrapper::remove_file(rust_lib_name("bar")); - assert_eq!(fs_wrapper::read_dir(cwd()).count(), 1); - - rustc() - .input("foo.rs") - .emit("asm=asm") - .emit("llvm-ir=ir") - .emit("llvm-bc=bc") - .emit("obj=obj") - .emit("link=link") - .crate_type("staticlib") - .run(); - fs_wrapper::remove_file("asm"); - fs_wrapper::remove_file("ir"); - fs_wrapper::remove_file("bc"); - fs_wrapper::remove_file("obj"); - fs_wrapper::remove_file("link"); - assert_eq!(fs_wrapper::read_dir(cwd()).count(), 1); - - rustc() - .input("foo.rs") - .arg("--emit=asm=asm") - .arg("--emit") - .arg("llvm-ir=ir") - .arg("--emit=llvm-bc=bc") - .arg("--emit") - .arg("obj=obj") - .arg("--emit=link=link") - .crate_type("staticlib") - .run(); - fs_wrapper::remove_file("asm"); - fs_wrapper::remove_file("ir"); - fs_wrapper::remove_file("bc"); - fs_wrapper::remove_file("obj"); - fs_wrapper::remove_file("link"); - assert_eq!(fs_wrapper::read_dir(cwd()).count(), 1); - - rustc().input("foo.rs").emit("asm,llvm-ir,llvm-bc,obj,link").crate_type("staticlib").run(); - fs_wrapper::remove_file("bar.ll"); - fs_wrapper::remove_file("bar.s"); - fs_wrapper::remove_file("bar.o"); - fs_wrapper::remove_file(static_lib_name("bar")); - fs_wrapper::rename("bar.bc", "foo.bc"); - // Don't check that no files except foo.rs remain - we left `foo.bc` for later - // comparison. - - rustc().input("foo.rs").emit("llvm-bc,link").crate_type("rlib").run(); - assert_eq!(fs_wrapper::read("foo.bc"), fs_wrapper::read("bar.bc")); - fs_wrapper::remove_file("bar.bc"); - fs_wrapper::remove_file("foo.bc"); - fs_wrapper::remove_file(rust_lib_name("bar")); - assert_eq!(fs_wrapper::read_dir(cwd()).count(), 1); + let bin_foo = Box::leak(Box::new(bin_name("foo"))); + let bin_bar = Box::leak(Box::new(bin_name("bar"))); + let static_bar = Box::leak(Box::new(static_lib_name("bar"))); + let dynamic_bar = Box::leak(Box::new(dynamic_lib_name("bar"))); + let rust_bar = Box::leak(Box::new(rust_lib_name("bar"))); + + assert_expected_output_files( + &[static_bar, dynamic_bar, rust_bar], + &[ + "libbar.ddl.exp", + "libbar.dll.lib", + "libbar.pdb", + "libbar.dll.a", + "libbar.exe.a", + "bar.ddl.exp", + "bar.dll.lib", + "bar.pdb", + "bar.dll.a", + "bar.exe.a", + ], + "three-crates", + || { + rustc() + .input("foo.rs") + .out_dir("three-crates") + .crate_type("rlib,dylib,staticlib") + .run(); + }, + ); + + assert_expected_output_files(&[bin_bar], &["bar.pdb"], "bin-crate", || { + rustc().input("foo.rs").crate_type("bin").out_dir("bin-crate").run(); + }); + + assert_expected_output_files( + &["bar.ll", "bar.bc", "bar.s", "bar.o", bin_bar], + &["bar.pdb"], + "all-emit", + || { + rustc().input("foo.rs").emit("asm,llvm-ir,llvm-bc,obj,link").out_dir("all-emit").run(); + }, + ); + + assert_expected_output_files(&["foo"], &[], "asm-emit", || { + rustc().input("foo.rs").emit("asm").output("asm-emit/foo").run(); + }); + assert_expected_output_files(&["foo"], &[], "asm-emit2", || { + rustc().input("foo.rs").emit("asm=asm-emit2/foo").run(); + }); + assert_expected_output_files(&["foo"], &[], "asm-emit3", || { + rustc().input("foo.rs").arg("--emit=asm=asm-emit3/foo").run(); + }); + + assert_expected_output_files(&["foo"], &[], "llvm-ir-emit", || { + rustc().input("foo.rs").emit("llvm-ir").output("llvm-ir-emit/foo").run(); + }); + assert_expected_output_files(&["foo"], &[], "llvm-ir-emit2", || { + rustc().input("foo.rs").emit("llvm-ir=llvm-ir-emit2/foo").run(); + }); + assert_expected_output_files(&["foo"], &[], "llvm-ir-emit3", || { + rustc().input("foo.rs").arg("--emit=llvm-ir=llvm-ir-emit3/foo").run(); + }); + + assert_expected_output_files(&["foo"], &[], "llvm-bc-emit", || { + rustc().input("foo.rs").emit("llvm-bc").output("llvm-bc-emit/foo").run(); + }); + assert_expected_output_files(&["foo"], &[], "llvm-bc-emit2", || { + rustc().input("foo.rs").emit("llvm-bc=llvm-bc-emit2/foo").run(); + }); + assert_expected_output_files(&["foo"], &[], "llvm-bc-emit3", || { + rustc().input("foo.rs").arg("--emit=llvm-bc=llvm-bc-emit3/foo").run(); + }); + + assert_expected_output_files(&["foo"], &[], "obj-emit", || { + rustc().input("foo.rs").emit("obj").output("obj-emit/foo").run(); + }); + assert_expected_output_files(&["foo"], &[], "obj-emit2", || { + rustc().input("foo.rs").emit("obj=obj-emit2/foo").run(); + }); + assert_expected_output_files(&["foo"], &[], "obj-emit3", || { + rustc().input("foo.rs").arg("--emit=obj=obj-emit3/foo").run(); + }); + + assert_expected_output_files(&[bin_foo], &[], "link-emit", || { + rustc().input("foo.rs").emit("link").output("link-emit/".to_owned() + bin_foo).run(); + }); + assert_expected_output_files(&[bin_foo], &[], "link-emit2", || { + rustc().input("foo.rs").emit(&format!("link=link-emit2/{bin_foo}")).run(); + }); + assert_expected_output_files(&[bin_foo], &[], "link-emit3", || { + rustc().input("foo.rs").arg(&format!("--emit=link=link-emit3/{bin_foo}")).run(); + }); + + assert_expected_output_files(&["foo"], &[], "rlib", || { + rustc().crate_type("rlib").input("foo.rs").output("rlib/foo").run(); + }); + assert_expected_output_files(&["foo"], &[], "rlib2", || { + rustc().crate_type("rlib").input("foo.rs").emit("link=rlib2/foo").run(); + }); + assert_expected_output_files(&["foo"], &[], "rlib3", || { + rustc().crate_type("rlib").input("foo.rs").arg("--emit=link=rlib3/foo").run(); + }); + + assert_expected_output_files( + &[bin_foo], + &[ + "libbar.ddl.exp", + "libbar.dll.lib", + "libbar.pdb", + "libbar.dll.a", + "libbar.exe.a", + "bar.ddl.exp", + "bar.dll.lib", + "bar.pdb", + "bar.dll.a", + "bar.exe.a", + ], + "dylib", + || { + rustc().crate_type("dylib").input("foo.rs").output("dylib/".to_owned() + bin_foo).run(); + }, + ); + assert_expected_output_files( + &[bin_foo], + &[ + "libbar.ddl.exp", + "libbar.dll.lib", + "libbar.pdb", + "libbar.dll.a", + "libbar.exe.a", + "bar.ddl.exp", + "bar.dll.lib", + "bar.pdb", + "bar.dll.a", + "bar.exe.a", + ], + "dylib2", + || { + rustc() + .crate_type("dylib") + .input("foo.rs") + .emit(&format!("link=dylib2/{bin_foo}")) + .run(); + }, + ); + assert_expected_output_files( + &[bin_foo], + &[ + "libbar.ddl.exp", + "libbar.dll.lib", + "libbar.pdb", + "libbar.dll.a", + "libbar.exe.a", + "bar.ddl.exp", + "bar.dll.lib", + "bar.pdb", + "bar.dll.a", + "bar.exe.a", + ], + "dylib3", + || { + rustc() + .crate_type("dylib") + .input("foo.rs") + .arg(&format!("--emit=link=dylib3/{bin_foo}")) + .run(); + }, + ); + + assert_expected_output_files(&["foo"], &[], "staticlib", || { + rustc().crate_type("staticlib").input("foo.rs").output("staticlib/foo").run(); + }); + assert_expected_output_files(&["foo"], &[], "staticlib2", || { + rustc().crate_type("staticlib").input("foo.rs").emit("link=staticlib2/foo").run(); + }); + assert_expected_output_files(&["foo"], &[], "staticlib3", || { + rustc().crate_type("staticlib").input("foo.rs").arg("--emit=link=staticlib3/foo").run(); + }); + + assert_expected_output_files(&["foo"], &["foo.pdb"], "bincrate", || { + rustc().crate_type("bin").input("foo.rs").output("bincrate/".to_owned() + bin_foo).run(); + }); + assert_expected_output_files(&["foo"], &["foo.pdb"], "bincrate2", || { + rustc().crate_type("bin").input("foo.rs").emit(&format!("link=bincrate2/{bin_foo}")).run(); + }); + assert_expected_output_files(&["foo"], &["foo.pdb"], "bincrate3", || { + rustc() + .crate_type("bin") + .input("foo.rs") + .arg(&format!("--emit=link=bincrate3/{bin_foo}")) + .run(); + }); + + assert_expected_output_files(&["ir", rust_bar], &[], "rlib-ir", || { + rustc() + .input("foo.rs") + .emit("llvm-ir=rlib-ir/ir") + .emit("link") + .crate_type("rlib") + .out_dir("rlib-ir") + .run(); + }); + + assert_expected_output_files(&["ir", "asm", "bc", "obj", "link"], &[], "staticlib-all", || { + rustc() + .input("foo.rs") + .emit("asm=staticlib-all/asm") + .emit("llvm-ir=staticlib-all/ir") + .emit("llvm-bc=staticlib-all/bc") + .emit("obj=staticlib-all/obj") + .emit("link=staticlib-all/link") + .crate_type("staticlib") + .run(); + }); + assert_expected_output_files( + &["ir", "asm", "bc", "obj", "link"], + &[], + "staticlib-all2", + || { + rustc() + .input("foo.rs") + .arg("--emit=asm=staticlib-all2/asm") + .arg("--emit") + .arg("llvm-ir=staticlib-all2/ir") + .arg("--emit=llvm-bc=staticlib-all2/bc") + .arg("--emit") + .arg("obj=staticlib-all2/obj") + .arg("--emit=link=staticlib-all2/link") + .crate_type("staticlib") + .run(); + }, + ); + + assert_expected_output_files( + &["bar.ll", "bar.s", "bar.o", static_bar], + &["bar.bc"], // keep this one for the next test + "staticlib-all3", + || { + rustc() + .input("foo.rs") + .emit("asm,llvm-ir,llvm-bc,obj,link") + .crate_type("staticlib") + .out_dir("staticlib-all3") + .run(); + }, + ); + + // the .bc file from the previous test should be equivalent to this one, despite the difference + // in crate type + assert_expected_output_files(&["bar.bc", rust_bar, "foo.bc"], &[], "rlib-emits", || { + fs_wrapper::rename("staticlib-all3/bar.bc", "rlib-emits/foo.bc"); + rustc().input("foo.rs").emit("llvm-bc,link").crate_type("rlib").out_dir("rlib-emits").run(); + assert_eq!(fs_wrapper::read("rlib-emits/foo.bc"), fs_wrapper::read("rlib-emits/bar.bc")); + }); } From 811532be6e999c42f8101c6cba62a300da2855cc Mon Sep 17 00:00:00 2001 From: Oneirical Date: Wed, 3 Jul 2024 11:48:19 -0400 Subject: [PATCH 729/892] Expectations struct for output-type-permutations --- src/tools/run-make-support/src/lib.rs | 10 +- .../output-type-permutations/rmake.rs | 632 ++++++++++++------ 2 files changed, 448 insertions(+), 194 deletions(-) diff --git a/src/tools/run-make-support/src/lib.rs b/src/tools/run-make-support/src/lib.rs index 20ceb03defef9..7bb89106de1b9 100644 --- a/src/tools/run-make-support/src/lib.rs +++ b/src/tools/run-make-support/src/lib.rs @@ -266,14 +266,14 @@ pub fn test_while_readonly, F: FnOnce() + std::panic::UnwindSafe> #[track_caller] pub fn shallow_find_files, F: Fn(&PathBuf) -> bool>( path: P, - closure: F, + filter: F, ) -> Vec { let mut matching_files = Vec::new(); for entry in fs_wrapper::read_dir(path) { let entry = entry.expect("failed to read directory entry."); let path = entry.path(); - if path.is_file() && closure(&path) { + if path.is_file() && filter(&path) { matching_files.push(path); } } @@ -296,8 +296,10 @@ pub fn not_contains>(path: P, expected: &str) -> bool { } /// Returns true if the filename at `path` is not in `expected`. -pub fn name_not_among>(path: P, expected: &[&'static str]) -> bool { - path.as_ref().file_name().is_some_and(|name| !expected.contains(&name.to_str().unwrap())) +pub fn filename_not_in_denylist>(path: P, expected: &[String]) -> bool { + path.as_ref() + .file_name() + .is_some_and(|name| !expected.contains(&name.to_str().unwrap().to_owned())) } /// Use `cygpath -w` on a path to get a Windows path string back. This assumes that `cygpath` is diff --git a/tests/run-make/output-type-permutations/rmake.rs b/tests/run-make/output-type-permutations/rmake.rs index eb166307f6800..30036dc7eeacd 100644 --- a/tests/run-make/output-type-permutations/rmake.rs +++ b/tests/run-make/output-type-permutations/rmake.rs @@ -5,9 +5,10 @@ // See https://github.com/rust-lang/rust/pull/12020 use run_make_support::{ - bin_name, cwd, dynamic_lib_name, fs_wrapper, name_not_among, rust_lib_name, rustc, + bin_name, dynamic_lib_name, filename_not_in_denylist, fs_wrapper, rust_lib_name, rustc, shallow_find_files, static_lib_name, }; +use std::path::PathBuf; // Each test takes 4 arguments: // `must_exist`: output files which must be found - if any are absent, the test fails @@ -15,46 +16,69 @@ use run_make_support::{ // `dir`: the name of the directory where the test happens // `rustc_invocation`: the rustc command being tested // Any unexpected output files not listed in `must_exist` or `can_exist` will cause a failure. -fn assert_expected_output_files( - must_exist: &[&'static str], - can_exist: &[&'static str], - dir: &str, - rustc_invocation: impl Fn(), -) { - fs_wrapper::create_dir(dir); +fn assert_expected_output_files(expectations: Expectations, rustc_invocation: impl Fn()) { + let must_exist = expectations.expected_files; + let can_exist = expectations.allowed_files; + let dir = expectations.test_dir; + + fs_wrapper::create_dir(&dir); rustc_invocation(); for file in must_exist { - fs_wrapper::remove_file(dir.to_owned() + "/" + file); + fs_wrapper::remove_file(PathBuf::from(&dir).join(&file)); } - let actual_output_files = shallow_find_files(dir, |path| name_not_among(path, can_exist)); + let actual_output_files = + shallow_find_files(dir, |path| filename_not_in_denylist(path, &can_exist)); if !&actual_output_files.is_empty() { dbg!(&actual_output_files); panic!("unexpected output artifacts detected"); } } +struct Expectations { + /// Output files which must be found. The test fails if any are absent. + expected_files: Vec, + /// Allowed output files which will not trigger a failure. + allowed_files: Vec, + /// Name of the directory where the test happens. + test_dir: String, +} + +macro_rules! s { + ( $( $x:expr ),* ) => { + { + let mut temp_vec = Vec::new(); + $( + temp_vec.push($x.to_string()); + )* + temp_vec + } + }; +} + fn main() { - let bin_foo = Box::leak(Box::new(bin_name("foo"))); - let bin_bar = Box::leak(Box::new(bin_name("bar"))); - let static_bar = Box::leak(Box::new(static_lib_name("bar"))); - let dynamic_bar = Box::leak(Box::new(dynamic_lib_name("bar"))); - let rust_bar = Box::leak(Box::new(rust_lib_name("bar"))); + let bin_foo = bin_name("foo"); assert_expected_output_files( - &[static_bar, dynamic_bar, rust_bar], - &[ - "libbar.ddl.exp", - "libbar.dll.lib", - "libbar.pdb", - "libbar.dll.a", - "libbar.exe.a", - "bar.ddl.exp", - "bar.dll.lib", - "bar.pdb", - "bar.dll.a", - "bar.exe.a", - ], - "three-crates", + Expectations { + expected_files: s![ + static_lib_name("bar"), + dynamic_lib_name("bar"), + rust_lib_name("bar") + ], + allowed_files: s![ + "libbar.dll.exp", + "libbar.dll.lib", + "libbar.pdb", + "libbar.dll.a", + "libbar.exe.a", + "bar.dll.exp", + "bar.dll.lib", + "bar.pdb", + "bar.dll.a", + "bar.exe.a" + ], + test_dir: "three-crates".to_string(), + }, || { rustc() .input("foo.rs") @@ -64,113 +88,256 @@ fn main() { }, ); - assert_expected_output_files(&[bin_bar], &["bar.pdb"], "bin-crate", || { - rustc().input("foo.rs").crate_type("bin").out_dir("bin-crate").run(); - }); + assert_expected_output_files( + Expectations { + expected_files: s![bin_name("bar")], + allowed_files: s!["bar.pdb"], + test_dir: "bin-crate".to_string(), + }, + || { + rustc().input("foo.rs").crate_type("bin").out_dir("bin-crate").run(); + }, + ); assert_expected_output_files( - &["bar.ll", "bar.bc", "bar.s", "bar.o", bin_bar], - &["bar.pdb"], - "all-emit", + Expectations { + expected_files: s!["bar.ll", "bar.bc", "bar.s", "bar.o", bin_name("bar")], + allowed_files: s!["bar.pdb"], + test_dir: "all-emit".to_string(), + }, || { rustc().input("foo.rs").emit("asm,llvm-ir,llvm-bc,obj,link").out_dir("all-emit").run(); }, ); - assert_expected_output_files(&["foo"], &[], "asm-emit", || { - rustc().input("foo.rs").emit("asm").output("asm-emit/foo").run(); - }); - assert_expected_output_files(&["foo"], &[], "asm-emit2", || { - rustc().input("foo.rs").emit("asm=asm-emit2/foo").run(); - }); - assert_expected_output_files(&["foo"], &[], "asm-emit3", || { - rustc().input("foo.rs").arg("--emit=asm=asm-emit3/foo").run(); - }); + assert_expected_output_files( + Expectations { + expected_files: s!["foo"], + allowed_files: s![], + test_dir: "asm-emit".to_string(), + }, + || { + rustc().input("foo.rs").emit("asm").output("asm-emit/foo").run(); + }, + ); + assert_expected_output_files( + Expectations { + expected_files: s!["foo"], + allowed_files: s![], + test_dir: "asm-emit2".to_string(), + }, + || { + rustc().input("foo.rs").emit("asm=asm-emit2/foo").run(); + }, + ); + assert_expected_output_files( + Expectations { + expected_files: s!["foo"], + allowed_files: s![], + test_dir: "asm-emit3".to_string(), + }, + || { + rustc().input("foo.rs").arg("--emit=asm=asm-emit3/foo").run(); + }, + ); - assert_expected_output_files(&["foo"], &[], "llvm-ir-emit", || { - rustc().input("foo.rs").emit("llvm-ir").output("llvm-ir-emit/foo").run(); - }); - assert_expected_output_files(&["foo"], &[], "llvm-ir-emit2", || { - rustc().input("foo.rs").emit("llvm-ir=llvm-ir-emit2/foo").run(); - }); - assert_expected_output_files(&["foo"], &[], "llvm-ir-emit3", || { - rustc().input("foo.rs").arg("--emit=llvm-ir=llvm-ir-emit3/foo").run(); - }); + assert_expected_output_files( + Expectations { + expected_files: s!["foo"], + allowed_files: s![], + test_dir: "llvm-ir-emit".to_string(), + }, + || { + rustc().input("foo.rs").emit("llvm-ir").output("llvm-ir-emit/foo").run(); + }, + ); + assert_expected_output_files( + Expectations { + expected_files: s!["foo"], + allowed_files: s![], + test_dir: "llvm-ir-emit2".to_string(), + }, + || { + rustc().input("foo.rs").emit("llvm-ir=llvm-ir-emit2/foo").run(); + }, + ); + assert_expected_output_files( + Expectations { + expected_files: s!["foo"], + allowed_files: s![], + test_dir: "llvm-ir-emit3".to_string(), + }, + || { + rustc().input("foo.rs").arg("--emit=llvm-ir=llvm-ir-emit3/foo").run(); + }, + ); - assert_expected_output_files(&["foo"], &[], "llvm-bc-emit", || { - rustc().input("foo.rs").emit("llvm-bc").output("llvm-bc-emit/foo").run(); - }); - assert_expected_output_files(&["foo"], &[], "llvm-bc-emit2", || { - rustc().input("foo.rs").emit("llvm-bc=llvm-bc-emit2/foo").run(); - }); - assert_expected_output_files(&["foo"], &[], "llvm-bc-emit3", || { - rustc().input("foo.rs").arg("--emit=llvm-bc=llvm-bc-emit3/foo").run(); - }); + assert_expected_output_files( + Expectations { + expected_files: s!["foo"], + allowed_files: s![], + test_dir: "llvm-bc-emit".to_string(), + }, + || { + rustc().input("foo.rs").emit("llvm-bc").output("llvm-bc-emit/foo").run(); + }, + ); + assert_expected_output_files( + Expectations { + expected_files: s!["foo"], + allowed_files: s![], + test_dir: "llvm-bc-emit2".to_string(), + }, + || { + rustc().input("foo.rs").emit("llvm-bc=llvm-bc-emit2/foo").run(); + }, + ); + assert_expected_output_files( + Expectations { + expected_files: s!["foo"], + allowed_files: s![], + test_dir: "llvm-bc-emit3".to_string(), + }, + || { + rustc().input("foo.rs").arg("--emit=llvm-bc=llvm-bc-emit3/foo").run(); + }, + ); - assert_expected_output_files(&["foo"], &[], "obj-emit", || { - rustc().input("foo.rs").emit("obj").output("obj-emit/foo").run(); - }); - assert_expected_output_files(&["foo"], &[], "obj-emit2", || { - rustc().input("foo.rs").emit("obj=obj-emit2/foo").run(); - }); - assert_expected_output_files(&["foo"], &[], "obj-emit3", || { - rustc().input("foo.rs").arg("--emit=obj=obj-emit3/foo").run(); - }); + assert_expected_output_files( + Expectations { + expected_files: s!["foo"], + allowed_files: s![], + test_dir: "obj-emit".to_string(), + }, + || { + rustc().input("foo.rs").emit("obj").output("obj-emit/foo").run(); + }, + ); + assert_expected_output_files( + Expectations { + expected_files: s!["foo"], + allowed_files: s![], + test_dir: "obj-emit2".to_string(), + }, + || { + rustc().input("foo.rs").emit("obj=obj-emit2/foo").run(); + }, + ); + assert_expected_output_files( + Expectations { + expected_files: s!["foo"], + allowed_files: s![], + test_dir: "obj-emit3".to_string(), + }, + || { + rustc().input("foo.rs").arg("--emit=obj=obj-emit3/foo").run(); + }, + ); - assert_expected_output_files(&[bin_foo], &[], "link-emit", || { - rustc().input("foo.rs").emit("link").output("link-emit/".to_owned() + bin_foo).run(); - }); - assert_expected_output_files(&[bin_foo], &[], "link-emit2", || { - rustc().input("foo.rs").emit(&format!("link=link-emit2/{bin_foo}")).run(); - }); - assert_expected_output_files(&[bin_foo], &[], "link-emit3", || { - rustc().input("foo.rs").arg(&format!("--emit=link=link-emit3/{bin_foo}")).run(); - }); + assert_expected_output_files( + Expectations { + expected_files: s![&bin_foo], + allowed_files: s!["foo.pdb"], + test_dir: "link-emit".to_string(), + }, + || { + rustc().input("foo.rs").emit("link").output("link-emit/".to_owned() + &bin_foo).run(); + }, + ); + assert_expected_output_files( + Expectations { + expected_files: s![&bin_foo], + allowed_files: s!["foo.pdb"], + test_dir: "link-emit2".to_string(), + }, + || { + rustc().input("foo.rs").emit(&format!("link=link-emit2/{bin_foo}")).run(); + }, + ); + assert_expected_output_files( + Expectations { + expected_files: s![&bin_foo], + allowed_files: s!["foo.pdb"], + test_dir: "link-emit3".to_string(), + }, + || { + rustc().input("foo.rs").arg(&format!("--emit=link=link-emit3/{bin_foo}")).run(); + }, + ); - assert_expected_output_files(&["foo"], &[], "rlib", || { - rustc().crate_type("rlib").input("foo.rs").output("rlib/foo").run(); - }); - assert_expected_output_files(&["foo"], &[], "rlib2", || { - rustc().crate_type("rlib").input("foo.rs").emit("link=rlib2/foo").run(); - }); - assert_expected_output_files(&["foo"], &[], "rlib3", || { - rustc().crate_type("rlib").input("foo.rs").arg("--emit=link=rlib3/foo").run(); - }); + assert_expected_output_files( + Expectations { + expected_files: s!["foo"], + allowed_files: s![], + test_dir: "rlib".to_string(), + }, + || { + rustc().crate_type("rlib").input("foo.rs").output("rlib/foo").run(); + }, + ); + assert_expected_output_files( + Expectations { + expected_files: s!["foo"], + allowed_files: s![], + test_dir: "rlib2".to_string(), + }, + || { + rustc().crate_type("rlib").input("foo.rs").emit("link=rlib2/foo").run(); + }, + ); + assert_expected_output_files( + Expectations { + expected_files: s!["foo"], + allowed_files: s![], + test_dir: "rlib3".to_string(), + }, + || { + rustc().crate_type("rlib").input("foo.rs").arg("--emit=link=rlib3/foo").run(); + }, + ); assert_expected_output_files( - &[bin_foo], - &[ - "libbar.ddl.exp", - "libbar.dll.lib", - "libbar.pdb", - "libbar.dll.a", - "libbar.exe.a", - "bar.ddl.exp", - "bar.dll.lib", - "bar.pdb", - "bar.dll.a", - "bar.exe.a", - ], - "dylib", - || { - rustc().crate_type("dylib").input("foo.rs").output("dylib/".to_owned() + bin_foo).run(); - }, - ); - assert_expected_output_files( - &[bin_foo], - &[ - "libbar.ddl.exp", - "libbar.dll.lib", - "libbar.pdb", - "libbar.dll.a", - "libbar.exe.a", - "bar.ddl.exp", - "bar.dll.lib", - "bar.pdb", - "bar.dll.a", - "bar.exe.a", - ], - "dylib2", + Expectations { + expected_files: s![bin_foo], + allowed_files: s![ + "libfoo.dll.exp", + "libfoo.dll.lib", + "libfoo.pdb", + "libfoo.dll.a", + "libfoo.exe.a", + "foo.dll.exp", + "foo.dll.lib", + "foo.pdb", + "foo.dll.a", + "foo.exe.a" + ], + test_dir: "dylib".to_string(), + }, + || { + rustc() + .crate_type("dylib") + .input("foo.rs") + .output("dylib/".to_owned() + &bin_foo) + .run(); + }, + ); + assert_expected_output_files( + Expectations { + expected_files: s![bin_foo], + allowed_files: s![ + "libfoo.dll.exp", + "libfoo.dll.lib", + "libfoo.pdb", + "libfoo.dll.a", + "libfoo.exe.a", + "foo.dll.exp", + "foo.dll.lib", + "foo.pdb", + "foo.dll.a", + "foo.exe.a" + ], + test_dir: "dylib2".to_string(), + }, || { rustc() .crate_type("dylib") @@ -180,20 +347,22 @@ fn main() { }, ); assert_expected_output_files( - &[bin_foo], - &[ - "libbar.ddl.exp", - "libbar.dll.lib", - "libbar.pdb", - "libbar.dll.a", - "libbar.exe.a", - "bar.ddl.exp", - "bar.dll.lib", - "bar.pdb", - "bar.dll.a", - "bar.exe.a", - ], - "dylib3", + Expectations { + expected_files: s![bin_foo], + allowed_files: s![ + "libfoo.dll.exp", + "libfoo.dll.lib", + "libfoo.pdb", + "libfoo.dll.a", + "libfoo.exe.a", + "foo.dll.exp", + "foo.dll.lib", + "foo.pdb", + "foo.dll.a", + "foo.exe.a" + ], + test_dir: "dylib3".to_string(), + }, || { rustc() .crate_type("dylib") @@ -203,55 +372,121 @@ fn main() { }, ); - assert_expected_output_files(&["foo"], &[], "staticlib", || { - rustc().crate_type("staticlib").input("foo.rs").output("staticlib/foo").run(); - }); - assert_expected_output_files(&["foo"], &[], "staticlib2", || { - rustc().crate_type("staticlib").input("foo.rs").emit("link=staticlib2/foo").run(); - }); - assert_expected_output_files(&["foo"], &[], "staticlib3", || { - rustc().crate_type("staticlib").input("foo.rs").arg("--emit=link=staticlib3/foo").run(); - }); + assert_expected_output_files( + Expectations { + expected_files: s!["foo"], + allowed_files: s![], + test_dir: "staticlib".to_string(), + }, + || { + rustc().crate_type("staticlib").input("foo.rs").output("staticlib/foo").run(); + }, + ); + assert_expected_output_files( + Expectations { + expected_files: s!["foo"], + allowed_files: s![], + test_dir: "staticlib2".to_string(), + }, + || { + rustc().crate_type("staticlib").input("foo.rs").emit("link=staticlib2/foo").run(); + }, + ); + assert_expected_output_files( + Expectations { + expected_files: s!["foo"], + allowed_files: s![], + test_dir: "staticlib3".to_string(), + }, + || { + rustc().crate_type("staticlib").input("foo.rs").arg("--emit=link=staticlib3/foo").run(); + }, + ); - assert_expected_output_files(&["foo"], &["foo.pdb"], "bincrate", || { - rustc().crate_type("bin").input("foo.rs").output("bincrate/".to_owned() + bin_foo).run(); - }); - assert_expected_output_files(&["foo"], &["foo.pdb"], "bincrate2", || { - rustc().crate_type("bin").input("foo.rs").emit(&format!("link=bincrate2/{bin_foo}")).run(); - }); - assert_expected_output_files(&["foo"], &["foo.pdb"], "bincrate3", || { - rustc() - .crate_type("bin") - .input("foo.rs") - .arg(&format!("--emit=link=bincrate3/{bin_foo}")) - .run(); - }); + assert_expected_output_files( + Expectations { + expected_files: s![bin_foo], + allowed_files: s!["foo.pdb"], + test_dir: "bincrate".to_string(), + }, + || { + rustc() + .crate_type("bin") + .input("foo.rs") + .output("bincrate/".to_owned() + &bin_foo) + .run(); + }, + ); + assert_expected_output_files( + Expectations { + expected_files: s![bin_foo], + allowed_files: s!["foo.pdb"], + test_dir: "bincrate2".to_string(), + }, + || { + rustc() + .crate_type("bin") + .input("foo.rs") + .emit(&format!("link=bincrate2/{bin_foo}")) + .run(); + }, + ); + assert_expected_output_files( + Expectations { + expected_files: s![bin_foo], + allowed_files: s!["foo.pdb"], + test_dir: "bincrate3".to_string(), + }, + || { + rustc() + .crate_type("bin") + .input("foo.rs") + .arg(&format!("--emit=link=bincrate3/{bin_foo}")) + .run(); + }, + ); - assert_expected_output_files(&["ir", rust_bar], &[], "rlib-ir", || { - rustc() - .input("foo.rs") - .emit("llvm-ir=rlib-ir/ir") - .emit("link") - .crate_type("rlib") - .out_dir("rlib-ir") - .run(); - }); + assert_expected_output_files( + Expectations { + expected_files: s!["ir", rust_lib_name("bar")], + allowed_files: s![], + test_dir: "rlib-ir".to_string(), + }, + || { + rustc() + .input("foo.rs") + .emit("llvm-ir=rlib-ir/ir") + .emit("link") + .crate_type("rlib") + .out_dir("rlib-ir") + .run(); + }, + ); - assert_expected_output_files(&["ir", "asm", "bc", "obj", "link"], &[], "staticlib-all", || { - rustc() - .input("foo.rs") - .emit("asm=staticlib-all/asm") - .emit("llvm-ir=staticlib-all/ir") - .emit("llvm-bc=staticlib-all/bc") - .emit("obj=staticlib-all/obj") - .emit("link=staticlib-all/link") - .crate_type("staticlib") - .run(); - }); - assert_expected_output_files( - &["ir", "asm", "bc", "obj", "link"], - &[], - "staticlib-all2", + assert_expected_output_files( + Expectations { + expected_files: s!["ir", "asm", "bc", "obj", "link"], + allowed_files: s![], + test_dir: "staticlib-all".to_string(), + }, + || { + rustc() + .input("foo.rs") + .emit("asm=staticlib-all/asm") + .emit("llvm-ir=staticlib-all/ir") + .emit("llvm-bc=staticlib-all/bc") + .emit("obj=staticlib-all/obj") + .emit("link=staticlib-all/link") + .crate_type("staticlib") + .run(); + }, + ); + assert_expected_output_files( + Expectations { + expected_files: s!["ir", "asm", "bc", "obj", "link"], + allowed_files: s![], + test_dir: "staticlib-all2".to_string(), + }, || { rustc() .input("foo.rs") @@ -268,9 +503,11 @@ fn main() { ); assert_expected_output_files( - &["bar.ll", "bar.s", "bar.o", static_bar], - &["bar.bc"], // keep this one for the next test - "staticlib-all3", + Expectations { + expected_files: s!["bar.ll", "bar.s", "bar.o", static_lib_name("bar")], + allowed_files: s!["bar.bc"], // keep this one for the next test + test_dir: "staticlib-all3".to_string(), + }, || { rustc() .input("foo.rs") @@ -283,9 +520,24 @@ fn main() { // the .bc file from the previous test should be equivalent to this one, despite the difference // in crate type - assert_expected_output_files(&["bar.bc", rust_bar, "foo.bc"], &[], "rlib-emits", || { - fs_wrapper::rename("staticlib-all3/bar.bc", "rlib-emits/foo.bc"); - rustc().input("foo.rs").emit("llvm-bc,link").crate_type("rlib").out_dir("rlib-emits").run(); - assert_eq!(fs_wrapper::read("rlib-emits/foo.bc"), fs_wrapper::read("rlib-emits/bar.bc")); - }); + assert_expected_output_files( + Expectations { + expected_files: s!["bar.bc", rust_lib_name("bar"), "foo.bc"], + allowed_files: s![], + test_dir: "rlib-emits".to_string(), + }, + || { + fs_wrapper::rename("staticlib-all3/bar.bc", "rlib-emits/foo.bc"); + rustc() + .input("foo.rs") + .emit("llvm-bc,link") + .crate_type("rlib") + .out_dir("rlib-emits") + .run(); + assert_eq!( + fs_wrapper::read("rlib-emits/foo.bc"), + fs_wrapper::read("rlib-emits/bar.bc") + ); + }, + ); } From c9be69fd0a6214902749338074c7617cb9f40366 Mon Sep 17 00:00:00 2001 From: Oneirical Date: Thu, 27 Jun 2024 13:51:53 -0400 Subject: [PATCH 730/892] Add shallow_find_files helper function to run-make-support --- src/tools/run-make-support/src/lib.rs | 1 + tests/run-make/pgo-gen/rmake.rs | 12 ++++++------ tests/run-make/pgo-use/rmake.rs | 27 ++++++++++++++------------- 3 files changed, 21 insertions(+), 19 deletions(-) diff --git a/src/tools/run-make-support/src/lib.rs b/src/tools/run-make-support/src/lib.rs index 6c1bcc6d7cd90..af5ae6a8e608c 100644 --- a/src/tools/run-make-support/src/lib.rs +++ b/src/tools/run-make-support/src/lib.rs @@ -272,6 +272,7 @@ pub fn shallow_find_files, F: Fn(&PathBuf) -> bool>( for entry in fs_wrapper::read_dir(path) { let entry = entry.expect("failed to read directory entry."); let path = entry.path(); + if path.is_file() && closure(&path) { matching_files.push(path); } diff --git a/tests/run-make/pgo-gen/rmake.rs b/tests/run-make/pgo-gen/rmake.rs index d35b29302648e..ad2f6388e8fff 100644 --- a/tests/run-make/pgo-gen/rmake.rs +++ b/tests/run-make/pgo-gen/rmake.rs @@ -6,13 +6,13 @@ //@ needs-profiler-support //@ ignore-cross-compile -use run_make_support::{cwd, find_files_by_prefix_and_extension, run, rustc}; +use run_make_support::{cwd, has_extension, has_prefix, run, rustc, shallow_find_files}; fn main() { - rustc().arg("-g").profile_generate(cwd()).run(); + rustc().arg("-g").profile_generate(cwd()).input("test.rs").run(); run("test"); - assert!( - find_files_by_prefix_and_extension(cwd(), "default", "profraw").len() > 0, - "no .profraw file generated" - ); + let profraw_files = shallow_find_files(cwd(), |path| { + has_prefix(path, "default") && has_extension(path, "profraw") + }); + assert!(!profraw_files.is_empty(), "no .profraw file generated"); } diff --git a/tests/run-make/pgo-use/rmake.rs b/tests/run-make/pgo-use/rmake.rs index 04777821b51b0..0f76aff80d0ca 100644 --- a/tests/run-make/pgo-use/rmake.rs +++ b/tests/run-make/pgo-use/rmake.rs @@ -9,8 +9,8 @@ //@ ignore-cross-compile use run_make_support::{ - cwd, find_files_by_prefix_and_extension, fs_wrapper, llvm_filecheck, llvm_profdata, - run_with_args, rustc, + cwd, fs_wrapper, has_extension, has_prefix, llvm_filecheck, llvm_profdata, run_with_args, + rustc, shallow_find_files, }; fn main() { @@ -28,11 +28,11 @@ fn main() { // Run it in order to generate some profiling data run_with_args("main", &["some-argument"]); // Postprocess the profiling data so it can be used by the compiler - llvm_profdata() - .merge() - .output("merged.profdata") - .input(find_files_by_prefix_and_extension(cwd(), "default", "profraw").get(0).unwrap()) - .run(); + let profraw_files = shallow_find_files(cwd(), |path| { + has_prefix(path, "default") && has_extension(path, "profraw") + }); + let profraw_file = profraw_files.get(0).unwrap(); + llvm_profdata().merge().output("merged.profdata").input(profraw_file).run(); // Compile the test program again, making use of the profiling data rustc() .opt_level("2") @@ -42,13 +42,14 @@ fn main() { .emit("llvm-ir") .input("main.rs") .run(); - // Check that the generate IR contains some things that we expect - // - // We feed the file into LLVM FileCheck tool *in reverse* so that we see the + // Check that the generate IR contains some things that we expect. + // We feed the file into LLVM FileCheck tool *with its lines reversed* so that we see the // line with the function name before the line with the function attributes. // FileCheck only supports checking that something matches on the next line, // but not if something matches on the previous line. - let mut bytes = fs_wrapper::read("interesting.ll"); - bytes.reverse(); - llvm_filecheck().patterns("filecheck-patterns.txt").stdin(bytes).run(); + let ir = fs_wrapper::read_to_string("main.ll"); + let lines: Vec<_> = ir.lines().rev().collect(); + let mut reversed_ir = lines.join("\n"); + reversed_ir.push('\n'); + llvm_filecheck().patterns("filecheck-patterns.txt").stdin(reversed_ir.as_bytes()).run(); } From 2d123d08c98419261bddec8f3ad8b80cadb82515 Mon Sep 17 00:00:00 2001 From: Antoni Boucher Date: Fri, 5 Jul 2024 10:42:03 -0400 Subject: [PATCH 731/892] Fix LTO tests FIXME: we now have fat LTO objects even when only bitcode is requested. --- .github/workflows/release.yml | 4 ++-- Readme.md | 11 ----------- build_system/src/config.rs | 6 ------ src/back/lto.rs | 14 +++++++------- src/back/write.rs | 15 ++++++++------- src/base.rs | 1 + src/lib.rs | 2 ++ tests/failing-ui-tests.txt | 1 + 8 files changed, 21 insertions(+), 33 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index d5242926eb4db..f0b1212986dd3 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -53,7 +53,7 @@ jobs: - name: Build run: | ./y.sh prepare --only-libcore - EMBED_LTO_BITCODE=1 ./y.sh build --sysroot --release --release-sysroot + ./y.sh build --sysroot --release --release-sysroot cargo test ./y.sh clean all @@ -70,4 +70,4 @@ 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 }} + ./y.sh test --release --clean --release-sysroot --build-sysroot ${{ matrix.commands }} diff --git a/Readme.md b/Readme.md index bd552b84f9282..d0b57d2c729c8 100644 --- a/Readme.md +++ b/Readme.md @@ -119,17 +119,6 @@ $ CHANNEL="release" $CG_GCCJIT_DIR/y.sh cargo run If you compiled cg_gccjit in debug mode (aka you didn't pass `--release` to `./y.sh test`) you should use `CHANNEL="debug"` instead or omit `CHANNEL="release"` completely. -### LTO - -To use LTO, you need to set the variable `FAT_LTO=1` and `EMBED_LTO_BITCODE=1` in addition to setting `lto = "fat"` in the `Cargo.toml`. -Don't set `FAT_LTO` when compiling the sysroot, though: only set `EMBED_LTO_BITCODE=1`. - -Failing to set `EMBED_LTO_BITCODE` will give you the following error: - -``` -error: failed to copy bitcode to object file: No such file or directory (os error 2) -``` - ### Rustc If you want to run `rustc` directly, you can do so with: diff --git a/build_system/src/config.rs b/build_system/src/config.rs index 30321939f64b8..965aedd8be891 100644 --- a/build_system/src/config.rs +++ b/build_system/src/config.rs @@ -387,12 +387,6 @@ impl ConfigInfo { rustflags.push("-Csymbol-mangling-version=v0".to_string()); } - // Since we don't support ThinLTO, disable LTO completely when not trying to do LTO. - // TODO(antoyo): remove when we can handle ThinLTO. - // TODO: remove: - /*if !env.contains_key(&"FAT_LTO".to_string()) { - rustflags.push("-Clto=off".to_string()); - }*/ // FIXME(antoyo): remove once the atomic shim is gone if os_name == "Darwin" { rustflags.extend_from_slice(&[ diff --git a/src/back/lto.rs b/src/back/lto.rs index 19573628b1b91..88eff198739ee 100644 --- a/src/back/lto.rs +++ b/src/back/lto.rs @@ -307,6 +307,7 @@ fn fat_lto( match bc_decoded { SerializedModule::Local(ref module_buffer) => { module.module_llvm.should_combine_object_files = true; + module.module_llvm.fat_lto = true; module .module_llvm .context @@ -489,7 +490,6 @@ fn thin_lto( //let path = module_buffer.0.to_str().expect("path"); //let my_path = PathBuf::from(path); //let exists = my_path.exists(); - //println!("Path: {:?}: {}", path, exists); /*module.module_llvm.should_combine_object_files = true; module .module_llvm @@ -626,11 +626,6 @@ pub unsafe fn optimize_thin_module( match *module { SerializedModule::Local(ref module_buffer) => { let path = module_buffer.0.to_str().expect("path"); - - //let my_path = PathBuf::from(path); - //let exists = my_path.exists(); - //println!("Path2: {:?}: {}", path, exists); - context.add_driver_option(path); should_combine_object_files = true; /*module.module_llvm.should_combine_object_files = true; @@ -648,7 +643,12 @@ 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, + fat_lto: false, + 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 b9bb62a0351dc..8922e7e742b27 100644 --- a/src/back/write.rs +++ b/src/back/write.rs @@ -32,12 +32,12 @@ 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. - let fat_lto = env::var("EMBED_LTO_BITCODE").as_deref() == Ok("1"); + let fat_lto = module.module_llvm.fat_lto; 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 { + if config.bitcode_needed() { let _timer = cgcx .prof .generic_activity_with_arg("GCC_module_codegen_make_bitcode", &*module.name); @@ -57,6 +57,8 @@ pub(crate) unsafe fn codegen( .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")); } @@ -118,12 +120,12 @@ pub(crate) unsafe fn codegen( if fat_lto { context.add_command_line_option("-flto=auto"); context.add_command_line_option("-flto-partition=one"); - - // NOTE: without -fuse-linker-plugin, we get the following error: - // lto1: internal compiler error: decompressed stream: Destination buffer is too small - context.add_driver_option("-fuse-linker-plugin"); } + // NOTE: without -fuse-linker-plugin, we get the following error: + // lto1: internal compiler error: decompressed stream: Destination buffer is too small + //context.add_driver_option("-fuse-linker-plugin"); + context.add_driver_option("-Wl,-r"); // NOTE: we need -nostdlib, otherwise, we get the following error: // /usr/bin/ld: cannot find -lgcc_s: No such file or directory @@ -135,7 +137,6 @@ pub(crate) unsafe fn codegen( obj_out.to_str().expect("path to str"), ); } else { - //println!("Combining to object file"); context.compile_to_file( OutputKind::ObjectFile, obj_out.to_str().expect("path to str"), diff --git a/src/base.rs b/src/base.rs index be149ffe5a16f..0287c73569a63 100644 --- a/src/base.rs +++ b/src/base.rs @@ -225,6 +225,7 @@ pub fn compile_codegen_unit( name: cgu_name.to_string(), module_llvm: GccContext { context: Arc::new(SyncContext::new(context)), + fat_lto: false, should_combine_object_files: false, temp_dir: None, }, diff --git a/src/lib.rs b/src/lib.rs index 1132b0cd2f5ab..123cebf51377d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -304,6 +304,7 @@ impl ExtraBackendMethods for GccCodegenBackend { ) -> Self::Module { let mut mods = GccContext { context: Arc::new(SyncContext::new(new_context(tcx))), + fat_lto: false, should_combine_object_files: false, temp_dir: None, }; @@ -336,6 +337,7 @@ impl ExtraBackendMethods for GccCodegenBackend { pub struct GccContext { context: Arc, should_combine_object_files: bool, + fat_lto: bool, // Temporary directory used by LTO. We keep it here so that it's not removed before linking. temp_dir: Option, } diff --git a/tests/failing-ui-tests.txt b/tests/failing-ui-tests.txt index ce867be7390c9..5a55bdb156e39 100644 --- a/tests/failing-ui-tests.txt +++ b/tests/failing-ui-tests.txt @@ -94,3 +94,4 @@ tests/ui/consts/const-eval/parse_ints.rs tests/ui/simd/intrinsic/generic-arithmetic-pass.rs tests/ui/backtrace/backtrace.rs tests/ui/lifetimes/tail-expr-lock-poisoning.rs +tests/ui/runtime/rt-explody-panic-payloads.rs From 7566f412099a6dd68df2d1bca0c73484113b2ab9 Mon Sep 17 00:00:00 2001 From: Chris Denton Date: Fri, 5 Jul 2024 14:48:39 +0000 Subject: [PATCH 732/892] Run alloc sync tests --- library/alloc/src/sync.rs | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs index 90672164cb932..1983ea8281aa0 100644 --- a/library/alloc/src/sync.rs +++ b/library/alloc/src/sync.rs @@ -197,11 +197,7 @@ macro_rules! acquire { /// /// Sharing some immutable data between threads: /// -// Note that we **do not** run these tests here. The windows builders get super -// unhappy if a thread outlives the main thread and then exits at the same time -// (something deadlocks) so we just avoid this entirely by not running these -// tests. -/// ```no_run +/// ``` /// use std::sync::Arc; /// use std::thread; /// @@ -220,7 +216,7 @@ macro_rules! acquire { /// /// [`AtomicUsize`]: core::sync::atomic::AtomicUsize "sync::atomic::AtomicUsize" /// -/// ```no_run +/// ``` /// use std::sync::Arc; /// use std::sync::atomic::{AtomicUsize, Ordering}; /// use std::thread; From 7dca61b68b50b7e38bf3cec027eec2002755b2a4 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Fri, 5 Jul 2024 15:00:40 +0000 Subject: [PATCH 733/892] Use `ControlFlow` results for visitors that are only looking for a single value --- .../src/diagnostics/conflict_errors.rs | 61 ++++++--------- .../src/deriving/default.rs | 2 +- .../src/collect/generics_of.rs | 74 ++++++++----------- .../src/fn_ctxt/inspect_obligations.rs | 2 - .../src/traits/object_safety.rs | 5 +- .../rustc_trait_selection/src/traits/wf.rs | 2 - 6 files changed, 59 insertions(+), 87 deletions(-) diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index e291ebd9bb832..c2c3f5bc79ed1 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -39,6 +39,7 @@ use rustc_trait_selection::traits::error_reporting::suggestions::TypeErrCtxtExt; use rustc_trait_selection::traits::error_reporting::FindExprBySpan; use rustc_trait_selection::traits::{Obligation, ObligationCause, ObligationCtxt}; use std::iter; +use std::ops::ControlFlow; use crate::borrow_set::TwoPhaseActivation; use crate::borrowck_errors; @@ -784,20 +785,20 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> { /// binding declaration within every scope we inspect. struct Finder { hir_id: hir::HirId, - found: bool, } impl<'hir> Visitor<'hir> for Finder { - fn visit_pat(&mut self, pat: &'hir hir::Pat<'hir>) { + type Result = ControlFlow<()>; + fn visit_pat(&mut self, pat: &'hir hir::Pat<'hir>) -> Self::Result { if pat.hir_id == self.hir_id { - self.found = true; + return ControlFlow::Break(()); } - hir::intravisit::walk_pat(self, pat); + hir::intravisit::walk_pat(self, pat) } - fn visit_expr(&mut self, ex: &'hir hir::Expr<'hir>) { + fn visit_expr(&mut self, ex: &'hir hir::Expr<'hir>) -> Self::Result { if ex.hir_id == self.hir_id { - self.found = true; + return ControlFlow::Break(()); } - hir::intravisit::walk_expr(self, ex); + hir::intravisit::walk_expr(self, ex) } } // The immediate HIR parent of the moved expression. We'll look for it to be a call. @@ -822,9 +823,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> { _ => continue, }; if let Some(&hir_id) = local_hir_id { - let mut finder = Finder { hir_id, found: false }; - finder.visit_expr(e); - if finder.found { + if (Finder { hir_id }).visit_expr(e).is_break() { // The current scope includes the declaration of the binding we're accessing, we // can't look up any further for loops. break; @@ -839,9 +838,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> { hir::Node::Expr(hir::Expr { kind: hir::ExprKind::If(cond, ..), .. }) => { - let mut finder = Finder { hir_id: expr.hir_id, found: false }; - finder.visit_expr(cond); - if finder.found { + if (Finder { hir_id: expr.hir_id }).visit_expr(cond).is_break() { // The expression where the move error happened is in a `while let` // condition Don't suggest clone as it will likely end in an // infinite loop. @@ -1837,7 +1834,6 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> { pub struct Holds<'tcx> { ty: Ty<'tcx>, - holds: bool, } impl<'tcx> TypeVisitor> for Holds<'tcx> { @@ -1845,7 +1841,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> { fn visit_ty(&mut self, t: Ty<'tcx>) -> Self::Result { if t == self.ty { - self.holds = true; + return ControlFlow::Break(()); } t.super_visit_with(self) } @@ -1863,9 +1859,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> { && rcvr_ty == ty && let ty::Ref(_, inner, _) = rcvr_ty.kind() && let inner = inner.peel_refs() - && let mut v = (Holds { ty: inner, holds: false }) - && let _ = v.visit_ty(local_ty) - && v.holds + && (Holds { ty: inner }).visit_ty(local_ty).is_break() && let None = self.infcx.type_implements_trait_shallow(clone, inner, self.param_env) { err.span_label( @@ -4325,15 +4319,14 @@ impl<'tcx> AnnotatedBorrowFnSignature<'tcx> { } /// Detect whether one of the provided spans is a statement nested within the top-most visited expr -struct ReferencedStatementsVisitor<'a>(&'a [Span], bool); +struct ReferencedStatementsVisitor<'a>(&'a [Span]); -impl<'a, 'v> Visitor<'v> for ReferencedStatementsVisitor<'a> { - fn visit_stmt(&mut self, s: &'v hir::Stmt<'v>) { +impl<'v> Visitor<'v> for ReferencedStatementsVisitor<'_> { + type Result = ControlFlow<()>; + fn visit_stmt(&mut self, s: &'v hir::Stmt<'v>) -> Self::Result { match s.kind { - hir::StmtKind::Semi(expr) if self.0.contains(&expr.span) => { - self.1 = true; - } - _ => {} + hir::StmtKind::Semi(expr) if self.0.contains(&expr.span) => ControlFlow::Break(()), + _ => ControlFlow::Continue(()), } } } @@ -4375,9 +4368,7 @@ impl<'b, 'v, 'tcx> Visitor<'v> for ConditionVisitor<'b, 'tcx> { hir::ExprKind::If(cond, body, None) => { // `if` expressions with no `else` that initialize the binding might be missing an // `else` arm. - let mut v = ReferencedStatementsVisitor(self.spans, false); - v.visit_expr(body); - if v.1 { + if ReferencedStatementsVisitor(self.spans).visit_expr(body).is_break() { self.errors.push(( cond.span, format!( @@ -4394,11 +4385,9 @@ impl<'b, 'v, 'tcx> Visitor<'v> for ConditionVisitor<'b, 'tcx> { hir::ExprKind::If(cond, body, Some(other)) => { // `if` expressions where the binding is only initialized in one of the two arms // might be missing a binding initialization. - let mut a = ReferencedStatementsVisitor(self.spans, false); - a.visit_expr(body); - let mut b = ReferencedStatementsVisitor(self.spans, false); - b.visit_expr(other); - match (a.1, b.1) { + let a = ReferencedStatementsVisitor(self.spans).visit_expr(body).is_break(); + let b = ReferencedStatementsVisitor(self.spans).visit_expr(other).is_break(); + match (a, b) { (true, true) | (false, false) => {} (true, false) => { if other.span.is_desugaring(DesugaringKind::WhileLoop) { @@ -4437,11 +4426,7 @@ impl<'b, 'v, 'tcx> Visitor<'v> for ConditionVisitor<'b, 'tcx> { // arms might be missing an initialization. let results: Vec = arms .iter() - .map(|arm| { - let mut v = ReferencedStatementsVisitor(self.spans, false); - v.visit_arm(arm); - v.1 - }) + .map(|arm| ReferencedStatementsVisitor(self.spans).visit_arm(arm).is_break()) .collect(); if results.iter().any(|x| *x) && !results.iter().all(|x| *x) { for (arm, seen) in arms.iter().zip(results) { diff --git a/compiler/rustc_builtin_macros/src/deriving/default.rs b/compiler/rustc_builtin_macros/src/deriving/default.rs index 577523a1d5a32..7a65ed97f00c2 100644 --- a/compiler/rustc_builtin_macros/src/deriving/default.rs +++ b/compiler/rustc_builtin_macros/src/deriving/default.rs @@ -240,7 +240,7 @@ fn has_a_default_variant(item: &Annotatable) -> bool { if v.attrs.iter().any(|attr| attr.has_name(kw::Default)) { ControlFlow::Break(()) } else { - // no need to subrecurse. + // no need to walk the variant, we are only looking for top level variants ControlFlow::Continue(()) } } diff --git a/compiler/rustc_hir_analysis/src/collect/generics_of.rs b/compiler/rustc_hir_analysis/src/collect/generics_of.rs index 9b02c1a61fa97..22d465c8e62be 100644 --- a/compiler/rustc_hir_analysis/src/collect/generics_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/generics_of.rs @@ -1,3 +1,5 @@ +use std::ops::ControlFlow; + use crate::middle::resolve_bound_vars as rbv; use hir::{ intravisit::{self, Visitor}, @@ -87,14 +89,9 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics { let mut in_param_ty = false; for (_parent, node) in tcx.hir().parent_iter(hir_id) { if let Some(generics) = node.generics() { - let mut visitor = AnonConstInParamTyDetector { - in_param_ty: false, - found_anon_const_in_param_ty: false, - ct: hir_id, - }; + let mut visitor = AnonConstInParamTyDetector { in_param_ty: false, ct: hir_id }; - visitor.visit_generics(generics); - in_param_ty = visitor.found_anon_const_in_param_ty; + in_param_ty = visitor.visit_generics(generics).is_break(); break; } } @@ -460,50 +457,45 @@ fn has_late_bound_regions<'tcx>(tcx: TyCtxt<'tcx>, node: Node<'tcx>) -> Option { tcx: TyCtxt<'tcx>, outer_index: ty::DebruijnIndex, - has_late_bound_regions: Option, } impl<'tcx> Visitor<'tcx> for LateBoundRegionsDetector<'tcx> { - fn visit_ty(&mut self, ty: &'tcx hir::Ty<'tcx>) { - if self.has_late_bound_regions.is_some() { - return; - } + type Result = ControlFlow; + fn visit_ty(&mut self, ty: &'tcx hir::Ty<'tcx>) -> ControlFlow { match ty.kind { hir::TyKind::BareFn(..) => { self.outer_index.shift_in(1); - intravisit::walk_ty(self, ty); + let res = intravisit::walk_ty(self, ty); self.outer_index.shift_out(1); + res } _ => intravisit::walk_ty(self, ty), } } - fn visit_poly_trait_ref(&mut self, tr: &'tcx hir::PolyTraitRef<'tcx>) { - if self.has_late_bound_regions.is_some() { - return; - } + fn visit_poly_trait_ref(&mut self, tr: &'tcx hir::PolyTraitRef<'tcx>) -> ControlFlow { self.outer_index.shift_in(1); - intravisit::walk_poly_trait_ref(self, tr); + let res = intravisit::walk_poly_trait_ref(self, tr); self.outer_index.shift_out(1); + res } - fn visit_lifetime(&mut self, lt: &'tcx hir::Lifetime) { - if self.has_late_bound_regions.is_some() { - return; - } - + fn visit_lifetime(&mut self, lt: &'tcx hir::Lifetime) -> ControlFlow { match self.tcx.named_bound_var(lt.hir_id) { - Some(rbv::ResolvedArg::StaticLifetime | rbv::ResolvedArg::EarlyBound(..)) => {} + Some(rbv::ResolvedArg::StaticLifetime | rbv::ResolvedArg::EarlyBound(..)) => { + ControlFlow::Continue(()) + } Some(rbv::ResolvedArg::LateBound(debruijn, _, _)) - if debruijn < self.outer_index => {} + if debruijn < self.outer_index => + { + ControlFlow::Continue(()) + } Some( rbv::ResolvedArg::LateBound(..) | rbv::ResolvedArg::Free(..) | rbv::ResolvedArg::Error(_), ) - | None => { - self.has_late_bound_regions = Some(lt.ident.span); - } + | None => ControlFlow::Break(lt.ident.span), } } } @@ -513,11 +505,7 @@ fn has_late_bound_regions<'tcx>(tcx: TyCtxt<'tcx>, node: Node<'tcx>) -> Option, decl: &'tcx hir::FnDecl<'tcx>, ) -> Option { - let mut visitor = LateBoundRegionsDetector { - tcx, - outer_index: ty::INNERMOST, - has_late_bound_regions: None, - }; + let mut visitor = LateBoundRegionsDetector { tcx, outer_index: ty::INNERMOST }; for param in generics.params { if let GenericParamKind::Lifetime { .. } = param.kind { if tcx.is_late_bound(param.hir_id) { @@ -525,8 +513,7 @@ fn has_late_bound_regions<'tcx>(tcx: TyCtxt<'tcx>, node: Node<'tcx>) -> Option(tcx: TyCtxt<'tcx>, node: Node<'tcx>) -> Option Visitor<'v> for AnonConstInParamTyDetector { - fn visit_generic_param(&mut self, p: &'v hir::GenericParam<'v>) { + type Result = ControlFlow<()>; + + fn visit_generic_param(&mut self, p: &'v hir::GenericParam<'v>) -> Self::Result { if let GenericParamKind::Const { ty, default: _, is_host_effect: _, synthetic: _ } = p.kind { let prev = self.in_param_ty; self.in_param_ty = true; - self.visit_ty(ty); + let res = self.visit_ty(ty); self.in_param_ty = prev; + res + } else { + ControlFlow::Continue(()) } } - fn visit_anon_const(&mut self, c: &'v hir::AnonConst) { + fn visit_anon_const(&mut self, c: &'v hir::AnonConst) -> Self::Result { if self.in_param_ty && self.ct == c.hir_id { - self.found_anon_const_in_param_ty = true; - } else { - intravisit::walk_anon_const(self, c) + return ControlFlow::Break(()); } + intravisit::walk_anon_const(self, c) } } diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/inspect_obligations.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/inspect_obligations.rs index fab7eb7495c5f..90dd5f73586b3 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/inspect_obligations.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/inspect_obligations.rs @@ -104,8 +104,6 @@ struct NestedObligationsForSelfTy<'a, 'tcx> { } impl<'a, 'tcx> ProofTreeVisitor<'tcx> for NestedObligationsForSelfTy<'a, 'tcx> { - type Result = (); - fn span(&self) -> Span { self.root_cause.span } diff --git a/compiler/rustc_trait_selection/src/traits/object_safety.rs b/compiler/rustc_trait_selection/src/traits/object_safety.rs index f1611bd049de9..5b2c8fb1950d8 100644 --- a/compiler/rustc_trait_selection/src/traits/object_safety.rs +++ b/compiler/rustc_trait_selection/src/traits/object_safety.rs @@ -805,10 +805,11 @@ fn contains_illegal_self_type_reference<'tcx, T: TypeVisitable>>( .unwrap() .contains(&data.trait_ref(self.tcx).def_id); + // only walk contained types if it's not a super trait if is_supertrait_of_current_trait { - ControlFlow::Continue(()) // do not walk contained types, do not report error, do collect $200 + ControlFlow::Continue(()) } else { - t.super_visit_with(self) // DO walk contained types, POSSIBLY reporting an error + t.super_visit_with(self) // POSSIBLY reporting an error } } _ => t.super_visit_with(self), // walk contained types, if any diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index e3952679f96b3..f071dc6c78486 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -640,8 +640,6 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { } impl<'a, 'tcx> TypeVisitor> for WfPredicates<'a, 'tcx> { - type Result = (); - fn visit_ty(&mut self, t: Ty<'tcx>) -> Self::Result { debug!("wf bounds for t={:?} t.kind={:#?}", t, t.kind()); From 5fd5b650935c27754dcf8cef06df37c3b91818eb Mon Sep 17 00:00:00 2001 From: Jules Bertholet Date: Fri, 5 Jul 2024 11:06:18 -0400 Subject: [PATCH 734/892] Rename edition 2021 fail test --- ....rs => ref_pat_eat_one_layer_2021_fail.rs} | 0 ...=> ref_pat_eat_one_layer_2021_fail.stderr} | 20 +++++++++---------- 2 files changed, 10 insertions(+), 10 deletions(-) rename tests/ui/match/ref_pat_eat_one_layer_2024/{ref_pat_eat_one_layer_2021.rs => ref_pat_eat_one_layer_2021_fail.rs} (100%) rename tests/ui/match/ref_pat_eat_one_layer_2024/{ref_pat_eat_one_layer_2021.stderr => ref_pat_eat_one_layer_2021_fail.stderr} (88%) diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2021.rs b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2021_fail.rs similarity index 100% rename from tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2021.rs rename to tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2021_fail.rs diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2021.stderr b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2021_fail.stderr similarity index 88% rename from tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2021.stderr rename to tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2021_fail.stderr index 28706f89c066b..1a921234ea069 100644 --- a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2021.stderr +++ b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2021_fail.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2021.rs:5:22 + --> $DIR/ref_pat_eat_one_layer_2021_fail.rs:5:22 | LL | if let Some(Some(&x)) = &Some(&Some(0)) { | ^^ --------------- this expression has type `&Option<&Option<{integer}>>` @@ -14,7 +14,7 @@ LL | if let Some(Some(x)) = &Some(&Some(0)) { | ~ error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2021.rs:10:23 + --> $DIR/ref_pat_eat_one_layer_2021_fail.rs:10:23 | LL | let _: &u32 = x; | ---- ^ expected `&u32`, found integer @@ -27,7 +27,7 @@ LL | let _: &u32 = &x; | + error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2021.rs:13:23 + --> $DIR/ref_pat_eat_one_layer_2021_fail.rs:13:23 | LL | if let Some(Some(&&x)) = &Some(Some(&0)) { | ^^ --------------- this expression has type `&Option>` @@ -43,7 +43,7 @@ LL + if let Some(Some(&x)) = &Some(Some(&0)) { | error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2021.rs:17:17 + --> $DIR/ref_pat_eat_one_layer_2021_fail.rs:17:17 | LL | if let Some(&Some(x)) = &Some(Some(0)) { | ^^^^^^^^ -------------- this expression has type `&Option>` @@ -54,7 +54,7 @@ LL | if let Some(&Some(x)) = &Some(Some(0)) { found reference `&_` error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2021.rs:21:22 + --> $DIR/ref_pat_eat_one_layer_2021_fail.rs:21:22 | LL | if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) { | ^^^^^^ ----------------------- this expression has type `&mut Option<&mut Option<{integer}>>` @@ -64,7 +64,7 @@ LL | if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) { = note: expected type `{integer}` found mutable reference `&mut _` note: to declare a mutable binding use: `mut x` - --> $DIR/ref_pat_eat_one_layer_2021.rs:21:22 + --> $DIR/ref_pat_eat_one_layer_2021_fail.rs:21:22 | LL | if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) { | ^^^^^^ @@ -74,7 +74,7 @@ LL | if let Some(Some(x)) = &mut Some(&mut Some(0)) { | ~ error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2021.rs:25:22 + --> $DIR/ref_pat_eat_one_layer_2021_fail.rs:25:22 | LL | if let Some(Some(&x)) = &Some(&Some(0)) { | ^^ --------------- this expression has type `&Option<&Option<{integer}>>` @@ -89,7 +89,7 @@ LL | if let Some(Some(x)) = &Some(&Some(0)) { | ~ error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2021.rs:29:27 + --> $DIR/ref_pat_eat_one_layer_2021_fail.rs:29:27 | LL | if let Some(&mut Some(&x)) = &Some(&mut Some(0)) { | ^^ ------------------- this expression has type `&Option<&mut Option<{integer}>>` @@ -104,7 +104,7 @@ LL | if let Some(&mut Some(x)) = &Some(&mut Some(0)) { | ~ error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2021.rs:33:23 + --> $DIR/ref_pat_eat_one_layer_2021_fail.rs:33:23 | LL | if let Some(&Some(&mut x)) = &mut Some(&Some(0)) { | ^^^^^^ ------------------- this expression has type `&mut Option<&Option<{integer}>>` @@ -114,7 +114,7 @@ LL | if let Some(&Some(&mut x)) = &mut Some(&Some(0)) { = note: expected type `{integer}` found mutable reference `&mut _` note: to declare a mutable binding use: `mut x` - --> $DIR/ref_pat_eat_one_layer_2021.rs:33:23 + --> $DIR/ref_pat_eat_one_layer_2021_fail.rs:33:23 | LL | if let Some(&Some(&mut x)) = &mut Some(&Some(0)) { | ^^^^^^ From 291ed596f71b4a9829cb1d93a177a52b677deabd Mon Sep 17 00:00:00 2001 From: Yoh Deadfall Date: Fri, 5 Jul 2024 18:10:05 +0300 Subject: [PATCH 735/892] Added dots at the sentence ends of rustc AST doc --- compiler/rustc_ast/src/ast.rs | 64 +++++++++++++++++------------------ 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index dbbc4980050de..1e1339fe14457 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -176,7 +176,7 @@ pub enum GenericArgs { AngleBracketed(AngleBracketedArgs), /// The `(A, B)` and `C` in `Foo(A, B) -> C`. Parenthesized(ParenthesizedArgs), - /// `(..)` in return type notation + /// `(..)` in return type notation. ParenthesizedElided(Span), } @@ -197,11 +197,11 @@ impl GenericArgs { /// Concrete argument in the sequence of generic args. #[derive(Clone, Encodable, Decodable, Debug)] pub enum GenericArg { - /// `'a` in `Foo<'a>` + /// `'a` in `Foo<'a>`. Lifetime(Lifetime), - /// `Bar` in `Foo` + /// `Bar` in `Foo`. Type(P), - /// `1` in `Foo<1>` + /// `1` in `Foo<1>`. Const(AnonConst), } @@ -355,7 +355,7 @@ pub enum GenericParamKind { ty: P, /// Span of the `const` keyword. kw_span: Span, - /// Optional default value for the const generic param + /// Optional default value for the const generic param. default: Option, }, } @@ -832,7 +832,7 @@ pub enum PatKind { /// only one rest pattern may occur in the pattern sequences. Rest, - // A never pattern `!` + // A never pattern `!`. Never, /// Parentheses in patterns used for grouping (i.e., `(PAT)`). @@ -1121,9 +1121,9 @@ impl LocalKind { #[derive(Clone, Encodable, Decodable, Debug)] pub struct Arm { pub attrs: AttrVec, - /// Match arm pattern, e.g. `10` in `match foo { 10 => {}, _ => {} }` + /// Match arm pattern, e.g. `10` in `match foo { 10 => {}, _ => {} }`. pub pat: P, - /// Match arm guard, e.g. `n > 10` in `match foo { n if n > 10 => {}, _ => {} }` + /// Match arm guard, e.g. `n > 10` in `match foo { n if n > 10 => {}, _ => {} }`. pub guard: Option>, /// Match arm body. Omitted if the pattern is a never pattern. pub body: Option>, @@ -1354,12 +1354,12 @@ pub struct Closure { pub fn_arg_span: Span, } -/// Limit types of a range (inclusive or exclusive) +/// Limit types of a range (inclusive or exclusive). #[derive(Copy, Clone, PartialEq, Encodable, Decodable, Debug)] pub enum RangeLimits { - /// Inclusive at the beginning, exclusive at the end + /// Inclusive at the beginning, exclusive at the end. HalfOpen, - /// Inclusive at the beginning and end + /// Inclusive at the beginning and end. Closed, } @@ -1400,9 +1400,9 @@ pub struct StructExpr { pub enum ExprKind { /// An array (e.g, `[a, b, c, d]`). Array(ThinVec>), - /// Allow anonymous constants from an inline `const` block + /// Allow anonymous constants from an inline `const` block. ConstBlock(AnonConst), - /// A function call + /// A function call. /// /// The first field resolves to the function itself, /// and the second field is the list of arguments. @@ -1456,7 +1456,7 @@ pub enum ExprKind { /// A block (`'label: { ... }`). Block(P, Option

    ` (where P is one of the previous types except `Self`) error[E0307]: invalid `self` parameter type: `&Bar` - --> $DIR/method_resolution3.rs:21:18 + --> $DIR/method_resolution3.rs:20:18 | LL | fn baz(self: &Bar) { | ^^^^^^^^^ diff --git a/tests/ui/type-alias-impl-trait/method_resolution3.next.stderr b/tests/ui/type-alias-impl-trait/method_resolution3.next.stderr index 9272017cdf5d1..09efd7a9e7e2d 100644 --- a/tests/ui/type-alias-impl-trait/method_resolution3.next.stderr +++ b/tests/ui/type-alias-impl-trait/method_resolution3.next.stderr @@ -1,15 +1,21 @@ -error[E0271]: type mismatch resolving `Foo == u32` +error[E0307]: invalid `self` parameter type: `Bar` --> $DIR/method_resolution3.rs:16:18 | LL | fn bar(self: Bar) { - | ^^^^^^^^ types differ + | ^^^^^^^^ + | + = note: type of `self` must be `Self` or a type that dereferences to it + = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

    ` (where P is one of the previous types except `Self`) -error[E0271]: type mismatch resolving `Foo == u32` - --> $DIR/method_resolution3.rs:21:18 +error[E0307]: invalid `self` parameter type: `&Bar` + --> $DIR/method_resolution3.rs:20:18 | LL | fn baz(self: &Bar) { - | ^^^^^^^^^ types differ + | ^^^^^^^^^ + | + = note: type of `self` must be `Self` or a type that dereferences to it + = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

    ` (where P is one of the previous types except `Self`) error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0271`. +For more information about this error, try `rustc --explain E0307`. diff --git a/tests/ui/type-alias-impl-trait/method_resolution3.rs b/tests/ui/type-alias-impl-trait/method_resolution3.rs index 447f3144b822c..0e6176bfe03c7 100644 --- a/tests/ui/type-alias-impl-trait/method_resolution3.rs +++ b/tests/ui/type-alias-impl-trait/method_resolution3.rs @@ -14,13 +14,11 @@ struct Bar(T); impl Bar { fn bar(self: Bar) { - //[current]~^ ERROR: invalid `self` parameter - //[next]~^^ ERROR: type mismatch resolving `Foo == u32` + //~^ ERROR: invalid `self` parameter self.foo() } fn baz(self: &Bar) { - //[current]~^ ERROR: invalid `self` parameter - //[next]~^^ ERROR: type mismatch resolving `Foo == u32` + //~^ ERROR: invalid `self` parameter self.foo() } } diff --git a/tests/ui/type-alias-impl-trait/method_resolution4.current.stderr b/tests/ui/type-alias-impl-trait/method_resolution4.current.stderr index 3a2ca18f89097..8ffdb21f2517b 100644 --- a/tests/ui/type-alias-impl-trait/method_resolution4.current.stderr +++ b/tests/ui/type-alias-impl-trait/method_resolution4.current.stderr @@ -8,7 +8,7 @@ LL | fn foo(self: Bar) { = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

    ` (where P is one of the previous types except `Self`) error[E0307]: invalid `self` parameter type: `&Bar` - --> $DIR/method_resolution4.rs:32:20 + --> $DIR/method_resolution4.rs:31:20 | LL | fn foomp(self: &Bar) { | ^^^^^^^^^ diff --git a/tests/ui/type-alias-impl-trait/method_resolution4.next.stderr b/tests/ui/type-alias-impl-trait/method_resolution4.next.stderr index 33ed2800ebe0c..8ffdb21f2517b 100644 --- a/tests/ui/type-alias-impl-trait/method_resolution4.next.stderr +++ b/tests/ui/type-alias-impl-trait/method_resolution4.next.stderr @@ -1,15 +1,21 @@ -error[E0271]: type mismatch resolving `u32 == Foo` +error[E0307]: invalid `self` parameter type: `Bar` --> $DIR/method_resolution4.rs:27:18 | LL | fn foo(self: Bar) { - | ^^^^^^^^ types differ + | ^^^^^^^^ + | + = note: type of `self` must be `Self` or a type that dereferences to it + = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

    ` (where P is one of the previous types except `Self`) -error[E0271]: type mismatch resolving `u32 == Foo` - --> $DIR/method_resolution4.rs:32:20 +error[E0307]: invalid `self` parameter type: `&Bar` + --> $DIR/method_resolution4.rs:31:20 | LL | fn foomp(self: &Bar) { - | ^^^^^^^^^ types differ + | ^^^^^^^^^ + | + = note: type of `self` must be `Self` or a type that dereferences to it + = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

    ` (where P is one of the previous types except `Self`) error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0271`. +For more information about this error, try `rustc --explain E0307`. diff --git a/tests/ui/type-alias-impl-trait/method_resolution4.rs b/tests/ui/type-alias-impl-trait/method_resolution4.rs index 42ed04b3c30f6..f33b4e473ae86 100644 --- a/tests/ui/type-alias-impl-trait/method_resolution4.rs +++ b/tests/ui/type-alias-impl-trait/method_resolution4.rs @@ -25,13 +25,11 @@ impl Bar { impl Bar { fn foo(self: Bar) { - //[current]~^ ERROR: invalid `self` parameter - //[next]~^^ ERROR: type mismatch resolving `u32 == Foo` + //~^ ERROR: invalid `self` parameter self.bar() } fn foomp(self: &Bar) { - //[current]~^ ERROR: invalid `self` parameter - //[next]~^^ ERROR: type mismatch resolving `u32 == Foo` + //~^ ERROR: invalid `self` parameter self.bar() } } From 465e7d546e0d76e3c3807154947d346cada6002a Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 2 Jul 2024 17:19:46 -0400 Subject: [PATCH 742/892] Rework receiver_is_valid --- .../rustc_hir_analysis/src/check/wfcheck.rs | 92 +++++++++---------- 1 file changed, 42 insertions(+), 50 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 1e27aa1d75635..30ff272ce129b 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -29,7 +29,6 @@ use rustc_session::parse::feature_err; use rustc_span::symbol::{sym, Ident}; use rustc_span::{Span, DUMMY_SP}; use rustc_target::spec::abi::Abi; -use rustc_trait_selection::infer::InferCtxtExt; use rustc_trait_selection::regions::InferCtxtRegionExt; use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt; use rustc_trait_selection::traits::misc::{ @@ -40,6 +39,7 @@ use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _ use rustc_trait_selection::traits::{ self, FulfillmentError, ObligationCause, ObligationCauseCode, ObligationCtxt, WellFormedLoc, }; +use rustc_type_ir::solve::NoSolution; use rustc_type_ir::TypeFlags; use std::cell::LazyCell; @@ -1713,13 +1713,12 @@ fn receiver_is_valid<'tcx>( let cause = ObligationCause::new(span, wfcx.body_def_id, traits::ObligationCauseCode::MethodReceiver); - let can_eq_self = |ty| infcx.can_eq(wfcx.param_env, self_ty, ty); - - // `self: Self` is always valid. - if can_eq_self(receiver_ty) { - if let Err(err) = wfcx.eq(&cause, wfcx.param_env, self_ty, receiver_ty) { - infcx.err_ctxt().report_mismatched_types(&cause, self_ty, receiver_ty, err).emit(); - } + // Special case `receiver == self_ty`, which doesn't necessarily require the `Receiver` lang item. + if let Ok(()) = wfcx.infcx.commit_if_ok(|_| { + let ocx = ObligationCtxt::new(wfcx.infcx); + ocx.eq(&cause, wfcx.param_env, self_ty, receiver_ty)?; + if ocx.select_all_or_error().is_empty() { Ok(()) } else { Err(NoSolution) } + }) { return true; } @@ -1730,58 +1729,51 @@ fn receiver_is_valid<'tcx>( autoderef = autoderef.include_raw_pointers(); } - // The first type is `receiver_ty`, which we know its not equal to `self_ty`; skip it. - autoderef.next(); - let receiver_trait_def_id = tcx.require_lang_item(LangItem::Receiver, Some(span)); // Keep dereferencing `receiver_ty` until we get to `self_ty`. - loop { - if let Some((potential_self_ty, _)) = autoderef.next() { - debug!( - "receiver_is_valid: potential self type `{:?}` to match `{:?}`", - potential_self_ty, self_ty - ); - - if can_eq_self(potential_self_ty) { - wfcx.register_obligations(autoderef.into_obligations()); + while let Some((potential_self_ty, _)) = autoderef.next() { + debug!( + "receiver_is_valid: potential self type `{:?}` to match `{:?}`", + potential_self_ty, self_ty + ); - if let Err(err) = wfcx.eq(&cause, wfcx.param_env, self_ty, potential_self_ty) { - infcx - .err_ctxt() - .report_mismatched_types(&cause, self_ty, potential_self_ty, err) - .emit(); - } + // Check if the self type unifies. If it does, then commit the result + // since it may have region side-effects. + if let Ok(()) = wfcx.infcx.commit_if_ok(|_| { + let ocx = ObligationCtxt::new(wfcx.infcx); + ocx.eq(&cause, wfcx.param_env, self_ty, potential_self_ty)?; + if ocx.select_all_or_error().is_empty() { Ok(()) } else { Err(NoSolution) } + }) { + wfcx.register_obligations(autoderef.into_obligations()); + return true; + } + // Without `feature(arbitrary_self_types)`, we require that each step in the + // deref chain implement `receiver`. + if !arbitrary_self_types_enabled { + if !receiver_is_implemented( + wfcx, + receiver_trait_def_id, + cause.clone(), + potential_self_ty, + ) { + // We cannot proceed. break; - } else { - // Without `feature(arbitrary_self_types)`, we require that each step in the - // deref chain implement `receiver` - if !arbitrary_self_types_enabled - && !receiver_is_implemented( - wfcx, - receiver_trait_def_id, - cause.clone(), - potential_self_ty, - ) - { - return false; - } } - } else { - debug!("receiver_is_valid: type `{:?}` does not deref to `{:?}`", receiver_ty, self_ty); - return false; - } - } - // Without `feature(arbitrary_self_types)`, we require that `receiver_ty` implements `Receiver`. - if !arbitrary_self_types_enabled - && !receiver_is_implemented(wfcx, receiver_trait_def_id, cause.clone(), receiver_ty) - { - return false; + // Register the bound, in case it has any region side-effects. + wfcx.register_bound( + cause.clone(), + wfcx.param_env, + potential_self_ty, + receiver_trait_def_id, + ); + } } - true + debug!("receiver_is_valid: type `{:?}` does not deref to `{:?}`", receiver_ty, self_ty); + false } fn receiver_is_implemented<'tcx>( From 9f994b633a4ca0ed4f75066ee27ca052e56453dc Mon Sep 17 00:00:00 2001 From: Oneirical Date: Thu, 4 Jul 2024 13:46:26 -0400 Subject: [PATCH 743/892] rewrite pass-linker-flags-from-dep to rmake --- .../tidy/src/allowed_run_make_makefiles.txt | 1 - .../pass-linker-flags-flavor/rmake.rs | 3 +- .../pass-linker-flags-from-dep/Makefile | 12 ------ .../pass-linker-flags-from-dep/rmake.rs | 43 +++++++++++++++++++ 4 files changed, 45 insertions(+), 14 deletions(-) delete mode 100644 tests/run-make/pass-linker-flags-from-dep/Makefile create mode 100644 tests/run-make/pass-linker-flags-from-dep/rmake.rs diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index 1520075287987..c2a4866352f00 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -106,7 +106,6 @@ run-make/optimization-remarks-dir-pgo/Makefile run-make/optimization-remarks-dir/Makefile run-make/output-type-permutations/Makefile run-make/panic-abort-eh_frame/Makefile -run-make/pass-linker-flags-from-dep/Makefile run-make/pass-non-c-like-enum-to-c/Makefile run-make/pdb-buildinfo-cl-cmd/Makefile run-make/pgo-gen-lto/Makefile diff --git a/tests/run-make/pass-linker-flags-flavor/rmake.rs b/tests/run-make/pass-linker-flags-flavor/rmake.rs index 9efb89cea092a..e36d68cc88432 100644 --- a/tests/run-make/pass-linker-flags-flavor/rmake.rs +++ b/tests/run-make/pass-linker-flags-flavor/rmake.rs @@ -4,7 +4,8 @@ // explicit flags and then with those flags passed inside the rust source code. // See https://github.com/rust-lang/rust/pull/118202 -//FIXME(Oneirical): only-linux +//@ only-linux +// Reason: the `gnu-cc` linker is only available on linux use run_make_support::{regex, rustc}; diff --git a/tests/run-make/pass-linker-flags-from-dep/Makefile b/tests/run-make/pass-linker-flags-from-dep/Makefile deleted file mode 100644 index 48b3b26ce81e6..0000000000000 --- a/tests/run-make/pass-linker-flags-from-dep/Makefile +++ /dev/null @@ -1,12 +0,0 @@ -include ../tools.mk - -all: - # Build deps - $(RUSTC) native_dep_1.rs --crate-type=staticlib - $(RUSTC) native_dep_2.rs --crate-type=staticlib - $(RUSTC) rust_dep_flag.rs -l static:-bundle=native_dep_1 -l link-arg=some_flag -l static:-bundle=native_dep_2 --crate-type=lib -Z unstable-options - $(RUSTC) rust_dep_attr.rs --crate-type=lib - - # Check sequence of linker args - $(RUSTC) main.rs --extern lib=$(TMPDIR)/librust_dep_flag.rlib --crate-type=bin --print link-args | $(CGREP) -e 'native_dep_1.*some_flag.*native_dep_2' - $(RUSTC) main.rs --extern lib=$(TMPDIR)/librust_dep_attr.rlib --crate-type=bin --print link-args | $(CGREP) -e 'native_dep_1.*some_flag.*native_dep_2' diff --git a/tests/run-make/pass-linker-flags-from-dep/rmake.rs b/tests/run-make/pass-linker-flags-from-dep/rmake.rs new file mode 100644 index 0000000000000..4b8e0486e1427 --- /dev/null +++ b/tests/run-make/pass-linker-flags-from-dep/rmake.rs @@ -0,0 +1,43 @@ +// A similar test to pass-linker-flags, testing that the `-l link-arg` flag +// respects the order relative to other `-l` flags, but this time, the flags +// are passed on the compilation of a dependency. This test checks that the +// downstream compiled binary contains the linker arguments of the dependency, +// and in the correct order. +// See https://github.com/rust-lang/rust/issues/99427 + +use run_make_support::{regex, rust_lib_name, rustc}; + +fn main() { + // Build dependencies + rustc().input("native_dep_1.rs").crate_type("staticlib").run(); + rustc().input("native_dep_2.rs").crate_type("staticlib").run(); + rustc() + .input("rust_dep_flag.rs") + .arg("-lstatic:-bundle=native_dep_1") + .arg("-llink-arg=some_flag") + .arg("-lstatic:-bundle=native_dep_2") + .crate_type("lib") + .arg("-Zunstable-options") + .run(); + rustc().input("rust_dep_attr.rs").crate_type("lib").run(); + + // Check sequence of linker arguments + let out_flag = rustc() + .input("main.rs") + .extern_("lib", rust_lib_name("rust_dep_flag")) + .crate_type("bin") + .print("link-args") + .run_unchecked() + .stdout_utf8(); + let out_attr = rustc() + .input("main.rs") + .extern_("lib", rust_lib_name("rust_dep_attr")) + .crate_type("bin") + .print("link-args") + .run_unchecked() + .stdout_utf8(); + + let re = regex::Regex::new("native_dep_1.*some_flag.*native_dep_2").unwrap(); + assert!(re.is_match(&out_flag)); + assert!(re.is_match(&out_attr)); +} From 8daf82fece0d047b555e55e7511c9b3fdd29a53c Mon Sep 17 00:00:00 2001 From: Oneirical Date: Fri, 5 Jul 2024 13:20:32 -0400 Subject: [PATCH 744/892] rewrite and rename issue-37839 to rmake --- src/tools/run-make-support/src/lib.rs | 2 +- src/tools/run-make-support/src/rustc.rs | 15 ++++++++++++- .../tidy/src/allowed_run_make_makefiles.txt | 1 - tests/run-make/issue-37839/Makefile | 7 ------ .../a.rs | 0 .../b.rs | 0 .../c.rs | 0 .../run-make/proc-macro-three-crates/rmake.rs | 22 +++++++++++++++++++ 8 files changed, 37 insertions(+), 10 deletions(-) delete mode 100644 tests/run-make/issue-37839/Makefile rename tests/run-make/{issue-37839 => proc-macro-three-crates}/a.rs (100%) rename tests/run-make/{issue-37839 => proc-macro-three-crates}/b.rs (100%) rename tests/run-make/{issue-37839 => proc-macro-three-crates}/c.rs (100%) create mode 100644 tests/run-make/proc-macro-three-crates/rmake.rs diff --git a/src/tools/run-make-support/src/lib.rs b/src/tools/run-make-support/src/lib.rs index af5ae6a8e608c..cb58f08a0fc9f 100644 --- a/src/tools/run-make-support/src/lib.rs +++ b/src/tools/run-make-support/src/lib.rs @@ -35,7 +35,7 @@ pub use llvm::{ LlvmProfdata, LlvmReadobj, }; pub use run::{cmd, run, run_fail, run_with_args}; -pub use rustc::{aux_build, rustc, Rustc}; +pub use rustc::{aux_build, bare_rustc, rustc, Rustc}; pub use rustdoc::{bare_rustdoc, rustdoc, Rustdoc}; #[track_caller] diff --git a/src/tools/run-make-support/src/rustc.rs b/src/tools/run-make-support/src/rustc.rs index 885b361f72a3f..a2a7c8064dca1 100644 --- a/src/tools/run-make-support/src/rustc.rs +++ b/src/tools/run-make-support/src/rustc.rs @@ -10,6 +10,12 @@ pub fn rustc() -> Rustc { Rustc::new() } +/// Construct a plain `rustc` invocation with no flags set. +#[track_caller] +pub fn bare_rustc() -> Rustc { + Rustc::bare() +} + /// Construct a new `rustc` aux-build invocation. #[track_caller] pub fn aux_build() -> Rustc { @@ -30,7 +36,6 @@ fn setup_common() -> Command { let rustc = env_var("RUSTC"); let mut cmd = Command::new(rustc); set_host_rpath(&mut cmd); - cmd.arg("-L").arg(cwd()); cmd } @@ -40,6 +45,14 @@ impl Rustc { /// Construct a new `rustc` invocation. #[track_caller] pub fn new() -> Self { + let mut cmd = setup_common(); + cmd.arg("-L").arg(cwd()); + Self { cmd } + } + + /// Construct a bare `rustc` invocation with no flags set. + #[track_caller] + pub fn bare() -> Self { let cmd = setup_common(); Self { cmd } } diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index 70c1b055c6e40..79b3f4b829519 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -62,7 +62,6 @@ run-make/issue-28595/Makefile run-make/issue-33329/Makefile run-make/issue-35164/Makefile run-make/issue-36710/Makefile -run-make/issue-37839/Makefile run-make/issue-47551/Makefile run-make/issue-69368/Makefile run-make/issue-83045/Makefile diff --git a/tests/run-make/issue-37839/Makefile b/tests/run-make/issue-37839/Makefile deleted file mode 100644 index 6bad27b7bdcd2..0000000000000 --- a/tests/run-make/issue-37839/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -# ignore-cross-compile -include ../tools.mk - -all: - $(RUSTC) a.rs && $(RUSTC) b.rs - $(BARE_RUSTC) c.rs -L dependency=$(TMPDIR) --extern b=$(TMPDIR)/libb.rlib \ - --out-dir=$(TMPDIR) diff --git a/tests/run-make/issue-37839/a.rs b/tests/run-make/proc-macro-three-crates/a.rs similarity index 100% rename from tests/run-make/issue-37839/a.rs rename to tests/run-make/proc-macro-three-crates/a.rs diff --git a/tests/run-make/issue-37839/b.rs b/tests/run-make/proc-macro-three-crates/b.rs similarity index 100% rename from tests/run-make/issue-37839/b.rs rename to tests/run-make/proc-macro-three-crates/b.rs diff --git a/tests/run-make/issue-37839/c.rs b/tests/run-make/proc-macro-three-crates/c.rs similarity index 100% rename from tests/run-make/issue-37839/c.rs rename to tests/run-make/proc-macro-three-crates/c.rs diff --git a/tests/run-make/proc-macro-three-crates/rmake.rs b/tests/run-make/proc-macro-three-crates/rmake.rs new file mode 100644 index 0000000000000..62dc547fcfb53 --- /dev/null +++ b/tests/run-make/proc-macro-three-crates/rmake.rs @@ -0,0 +1,22 @@ +// A compiler bug caused the following issue: +// If a crate A depends on crate B, and crate B +// depends on crate C, and crate C contains a procedural +// macro, compiling crate A would fail. +// This was fixed in #37846, and this test checks +// that this bug does not make a resurgence. + +//FIXME(Oneirical): ignore-cross-compile + +use run_make_support::{bare_rustc, cwd, rust_lib_name, rustc}; + +fn main() { + rustc().input("a.rs").run(); + rustc().input("b.rs").run(); + let curr_dir = cwd().display().to_string(); + bare_rustc() + .input("c.rs") + .arg(format!("-Ldependency={curr_dir}")) + .extern_("b", cwd().join(rust_lib_name("b"))) + .out_dir(cwd()) + .run(); +} From fbb6300fc28aabd434c34b1aeece754def13b96d Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Fri, 5 Jul 2024 10:23:59 -0700 Subject: [PATCH 745/892] rustdoc-search: stop constructing pointless arrays in decode I'm not sure why I ever thought that would be okay. This is clearly hot code, and should avoid Array.prototype.map when it's not needed. In any case, it shows up in the profiler. rustdoc-js-profiler: https://notriddle.com/rustdoc-html-demo-11/decode-opt-1/index.html Firefox profiler: [Before](https://share.firefox.dev/3RRH2fR) [After](https://share.firefox.dev/3Wblcq8) --- src/librustdoc/html/static/js/search.js | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/src/librustdoc/html/static/js/search.js b/src/librustdoc/html/static/js/search.js index a0ab262bf0b02..86af38f3ee75e 100644 --- a/src/librustdoc/html/static/js/search.js +++ b/src/librustdoc/html/static/js/search.js @@ -3293,10 +3293,9 @@ ${item.displayPath}${name}\ } // call after consuming `{` decodeList() { - const cb = "}".charCodeAt(0); let c = this.string.charCodeAt(this.offset); const ret = []; - while (c !== cb) { + while (c !== 125) { // 125 = "}" ret.push(this.decode()); c = this.string.charCodeAt(this.offset); } @@ -3305,14 +3304,13 @@ ${item.displayPath}${name}\ } // consumes and returns a list or integer decode() { - const [ob, la] = ["{", "`"].map(c => c.charCodeAt(0)); let n = 0; let c = this.string.charCodeAt(this.offset); - if (c === ob) { + if (c === 123) { // 123 = "{" this.offset += 1; return this.decodeList(); } - while (c < la) { + while (c < 96) { // 96 = "`" n = (n << 4) | (c & 0xF); this.offset += 1; c = this.string.charCodeAt(this.offset); @@ -3325,15 +3323,14 @@ ${item.displayPath}${name}\ } next() { const c = this.string.charCodeAt(this.offset); - const [zero, ua, la] = ["0", "@", "`"].map(c => c.charCodeAt(0)); // sixteen characters after "0" are backref - if (c >= zero && c < ua) { + if (c >= 48 && c < 64) { // 48 = "0", 64 = "@" this.offset += 1; - return this.backrefQueue[c - zero]; + return this.backrefQueue[c - 48]; } // special exception: 0 doesn't use backref encoding // it's already one character, and it's always nullish - if (c === la) { + if (c === 96) { // 96 = "`" this.offset += 1; return this.cons(0); } @@ -3472,7 +3469,6 @@ ${item.displayPath}${name}\ searchIndex = []; searchIndexDeprecated = new Map(); searchIndexEmptyDesc = new Map(); - const charA = "A".charCodeAt(0); let currentIndex = 0; let id = 0; @@ -3639,7 +3635,7 @@ ${item.displayPath}${name}\ // object defined above. const row = { crate, - ty: itemTypes.charCodeAt(i) - charA, + ty: itemTypes.charCodeAt(i) - 65, // 65 = "A" name: itemNames[i], path, descShard, From a0f4114ba939f8df47d2c56ffd3dd19ed6e094aa Mon Sep 17 00:00:00 2001 From: tison Date: Fri, 5 Jul 2024 10:29:35 -0700 Subject: [PATCH 746/892] update comments Signed-off-by: tison --- library/std/src/path.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/library/std/src/path.rs b/library/std/src/path.rs index a6f6042eaefaf..8d565e26a1609 100644 --- a/library/std/src/path.rs +++ b/library/std/src/path.rs @@ -1524,9 +1524,6 @@ impl PathBuf { /// Returns `false` and does nothing if [`self.file_name`] is [`None`], /// returns `true` and updates the extension otherwise. /// - /// If [`self.extension`] is [`None`], the extension is added; otherwise - /// it is appended. - /// /// # Caveats /// /// The appended `extension` may contain dots and will be used in its entirety, @@ -2727,7 +2724,7 @@ impl Path { new_path } - /// Creates an owned [`PathBuf`] like `self` but with an extra extension. + /// Creates an owned [`PathBuf`] like `self` but with the extension added. /// /// See [`PathBuf::add_extension`] for more details. /// From 48a9d4b68ae439e41c4c6747948d975b299a7db4 Mon Sep 17 00:00:00 2001 From: Oneirical Date: Fri, 5 Jul 2024 13:33:51 -0400 Subject: [PATCH 747/892] rewrite track-path-dep-info to rmake --- src/tools/tidy/src/allowed_run_make_makefiles.txt | 1 - tests/run-make/track-path-dep-info/Makefile | 13 ------------- tests/run-make/track-path-dep-info/rmake.rs | 15 +++++++++++++++ 3 files changed, 15 insertions(+), 14 deletions(-) delete mode 100644 tests/run-make/track-path-dep-info/Makefile create mode 100644 tests/run-make/track-path-dep-info/rmake.rs diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index 79b3f4b829519..118e76fdbcd26 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -158,7 +158,6 @@ run-make/target-without-atomic-cas/Makefile run-make/test-benches/Makefile run-make/thumb-none-cortex-m/Makefile run-make/thumb-none-qemu/Makefile -run-make/track-path-dep-info/Makefile run-make/track-pgo-dep-info/Makefile run-make/translation/Makefile run-make/type-mismatch-same-crate-name/Makefile diff --git a/tests/run-make/track-path-dep-info/Makefile b/tests/run-make/track-path-dep-info/Makefile deleted file mode 100644 index 0d6c9b1d2f01d..0000000000000 --- a/tests/run-make/track-path-dep-info/Makefile +++ /dev/null @@ -1,13 +0,0 @@ -include ../tools.mk - -# FIXME(eddyb) provide `HOST_RUSTC` and `TARGET_RUSTC` -# instead of hardcoding them everywhere they're needed. -ifeq ($(IS_MUSL_HOST),1) -ADDITIONAL_ARGS := $(RUSTFLAGS) -endif - -all: - # Proc macro - $(BARE_RUSTC) $(ADDITIONAL_ARGS) --out-dir $(TMPDIR) macro_def.rs - EXISTING_PROC_MACRO_ENV=1 $(RUSTC) --emit dep-info macro_use.rs - $(CGREP) "emojis.txt:" < $(TMPDIR)/macro_use.d diff --git a/tests/run-make/track-path-dep-info/rmake.rs b/tests/run-make/track-path-dep-info/rmake.rs new file mode 100644 index 0000000000000..f4a77c7fc2187 --- /dev/null +++ b/tests/run-make/track-path-dep-info/rmake.rs @@ -0,0 +1,15 @@ +// This test checks the functionality of `tracked_path::path`, a procedural macro +// feature that adds a dependency to another file inside the procmacro. In this case, +// the text file is added through this method, and the test checks that the compilation +// output successfully added the file as a dependency. +// See https://github.com/rust-lang/rust/pull/84029 + +//FIXME(Oneirical): Try it on musl + +use run_make_support::{bare_rustc, fs_wrapper, rustc}; + +fn main() { + bare_rustc().input("macro_def.rs").run(); + rustc().env("EXISTING_PROC_MACRO_ENV", "1").emit("dep-info").input("macro_use.rs").run(); + assert!(fs_wrapper::read_to_string("macro_use.d").contains("emojis.txt:")); +} From 3aa2abdd3db150394ce883dbefddf0f0d5f4f029 Mon Sep 17 00:00:00 2001 From: tison Date: Fri, 5 Jul 2024 10:44:15 -0700 Subject: [PATCH 748/892] add unit tests for extra extension feature Signed-off-by: tison --- library/std/src/path/tests.rs | 74 +++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) diff --git a/library/std/src/path/tests.rs b/library/std/src/path/tests.rs index 92702b395dfe1..bb6126e494177 100644 --- a/library/std/src/path/tests.rs +++ b/library/std/src/path/tests.rs @@ -1401,6 +1401,37 @@ pub fn test_set_extension() { tfe!("/", "foo", "/", false); } +#[test] +pub fn test_add_extension() { + macro_rules! tfe ( + ($path:expr, $ext:expr, $expected:expr, $output:expr) => ({ + let mut p = PathBuf::from($path); + let output = p.add_extension($ext); + assert!(p.to_str() == Some($expected) && output == $output, + "adding extension of {:?} to {:?}: Expected {:?}/{:?}, got {:?}/{:?}", + $path, $ext, $expected, $output, + p.to_str().unwrap(), output); + }); + ); + + tfe!("foo", "txt", "foo.txt", true); + tfe!("foo.bar", "txt", "foo.bar.txt", true); + tfe!("foo.bar.baz", "txt", "foo.bar.baz.txt", true); + tfe!(".test", "txt", ".test.txt", true); + tfe!("foo.txt", "", "foo.txt", true); + tfe!("foo", "", "foo", true); + tfe!("", "foo", "", false); + tfe!(".", "foo", ".", false); + tfe!("foo/", "bar", "foo.bar", true); + tfe!("foo/.", "bar", "foo.bar", true); + tfe!("..", "foo", "..", false); + tfe!("foo/..", "bar", "foo/..", false); + tfe!("/", "foo", "/", false); + + // edge cases + tfe!("/foo.ext////", "bar", "/foo.ext.bar", true); +} + #[test] pub fn test_with_extension() { macro_rules! twe ( @@ -1441,6 +1472,49 @@ pub fn test_with_extension() { twe!("ccc.bbb_bbb", "aaa_aaa_aaa", "ccc.aaa_aaa_aaa"); } +#[test] +pub fn test_with_added_extension() { + macro_rules! twe ( + ($input:expr, $extension:expr, $expected:expr) => ({ + let input = Path::new($input); + let output = input.with_added_extension($extension); + + assert!( + output.to_str() == Some($expected), + "calling Path::new({:?}).with_added_extension({:?}): Expected {:?}, got {:?}", + $input, $extension, $expected, output, + ); + }); + ); + + twe!("foo", "txt", "foo.txt"); + twe!("foo.bar", "txt", "foo.bar.txt"); + twe!("foo.bar.baz", "txt", "foo.bar.baz.txt"); + twe!(".test", "txt", ".test.txt"); + twe!("foo.txt", "", "foo.txt"); + twe!("foo", "", "foo"); + twe!("", "foo", ""); + twe!(".", "foo", "."); + twe!("foo/", "bar", "foo.bar"); + twe!("foo/.", "bar", "foo.bar"); + twe!("..", "foo", ".."); + twe!("foo/..", "bar", "foo/.."); + twe!("/", "foo", "/"); + + // edge cases + twe!("/foo.ext////", "bar", "/foo.ext.bar"); + + // New extension is smaller than file name + twe!("aaa_aaa_aaa", "bbb_bbb", "aaa_aaa_aaa.bbb_bbb"); + // New extension is greater than file name + twe!("bbb_bbb", "aaa_aaa_aaa", "bbb_bbb.aaa_aaa_aaa"); + + // New extension is smaller than previous extension + twe!("ccc.aaa_aaa_aaa", "bbb_bbb", "ccc.aaa_aaa_aaa.bbb_bbb"); + // New extension is greater than previous extension + twe!("ccc.bbb_bbb", "aaa_aaa_aaa", "ccc.bbb_bbb.aaa_aaa_aaa"); +} + #[test] fn test_eq_receivers() { use crate::borrow::Cow; From 14d327a265dde1df05cf15e23c6956197a22f141 Mon Sep 17 00:00:00 2001 From: Antoni Boucher Date: Fri, 5 Jul 2024 13:11:24 -0400 Subject: [PATCH 749/892] Disable run-make tests --- build_system/src/test.rs | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/build_system/src/test.rs b/build_system/src/test.rs index 5efdac9444dfe..8d088a3aac318 100644 --- a/build_system/src/test.rs +++ b/build_system/src/test.rs @@ -1038,18 +1038,19 @@ where } fn test_rustc(env: &Env, args: &TestArg) -> Result<(), String> { - test_rustc_inner(env, args, |_| Ok(false), false, "run-make")?; + //test_rustc_inner(env, args, |_| Ok(false), false, "run-make")?; test_rustc_inner(env, args, |_| Ok(false), false, "ui") } fn test_failing_rustc(env: &Env, args: &TestArg) -> Result<(), String> { - let result1 = test_rustc_inner( + let result1 = Ok(()); + /*test_rustc_inner( env, args, retain_files_callback("tests/failing-run-make-tests.txt", "run-make"), false, "run-make", - ); + )*/ let result2 = test_rustc_inner( env, @@ -1070,13 +1071,14 @@ fn test_successful_rustc(env: &Env, args: &TestArg) -> Result<(), String> { false, "ui", )?; - test_rustc_inner( + Ok(()) + /*test_rustc_inner( env, args, remove_files_callback("tests/failing-run-make-tests.txt", "run-make"), false, "run-make", - ) + )*/ } fn test_failing_ui_pattern_tests(env: &Env, args: &TestArg) -> Result<(), String> { From 0b5be441cf5e25beba8990b201be30293072245e Mon Sep 17 00:00:00 2001 From: Antoni Boucher Date: Fri, 5 Jul 2024 14:14:18 -0400 Subject: [PATCH 750/892] Fix for gcc-13 without int128 --- src/intrinsic/mod.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/intrinsic/mod.rs b/src/intrinsic/mod.rs index a739e6ff3fcba..839ebf3f29876 100644 --- a/src/intrinsic/mod.rs +++ b/src/intrinsic/mod.rs @@ -791,6 +791,7 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { } else { arg }; + let arg_type = arg.get_type(); let (count_trailing_zeroes, expected_type) = // TODO(antoyo): write a new function Type::is_compatible_with(&Type) and use it here // instead of using is_uint(). From 5681c3cf681d0dc5acdafbd28eed1b8a7ad751fa Mon Sep 17 00:00:00 2001 From: Antoni Boucher Date: Fri, 5 Jul 2024 15:35:57 -0400 Subject: [PATCH 751/892] Cleanup --- .github/workflows/gcc12.yml | 1 - Cargo.toml | 3 +-- example/example.rs | 1 - 3 files changed, 1 insertion(+), 4 deletions(-) diff --git a/.github/workflows/gcc12.yml b/.github/workflows/gcc12.yml index b0775646c5c95..5977ed33c56ec 100644 --- a/.github/workflows/gcc12.yml +++ b/.github/workflows/gcc12.yml @@ -70,7 +70,6 @@ jobs: ./y.sh build --no-default-features --sysroot-panic-abort # Uncomment when we no longer need to remove global variables. #./y.sh build --sysroot --no-default-features --sysroot-panic-abort - #./y.sh build --sysroot --no-default-features --sysroot-panic-abort #cargo test --no-default-features #./y.sh clean all diff --git a/Cargo.toml b/Cargo.toml index 309746f04e014..5caca63f63480 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,8 +22,7 @@ master = ["gccjit/master"] default = ["master"] [dependencies] -#gccjit = "2.0" -gccjit = { git = "https://github.com/rust-lang/gccjit.rs" } +gccjit = "2.1" # Local copy. #gccjit = { path = "../gccjit.rs" } diff --git a/example/example.rs b/example/example.rs index 30e3c3c30c220..03470b74d0a13 100644 --- a/example/example.rs +++ b/example/example.rs @@ -153,7 +153,6 @@ fn array_as_slice(arr: &[u8; 3]) -> &[u8] { arr } -// FIXME: fix the intrinsic implementation to work with the new ->u32 signature unsafe fn use_ctlz_nonzero(a: u16) -> u32 { intrinsics::ctlz_nonzero(a) } From 8e9a3661a8ec7078f480f21f1dfe4b07d31e4c79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Fri, 5 Jul 2024 19:40:09 +0000 Subject: [PATCH 752/892] Use verbose style for argument removal suggestion --- .../rustc_hir_typeck/src/fn_ctxt/checks.rs | 2 +- tests/ui/argument-suggestions/basic.stderr | 10 +- .../argument-suggestions/exotic-calls.stderr | 40 +++-- .../extra_arguments.stderr | 169 ++++++++++-------- ...uggest-better-removing-issue-126246.stderr | 60 ++++--- tests/ui/error-codes/E0057.stderr | 10 +- .../opaque-used-in-extraneous-argument.stderr | 20 ++- ...r-var-leaked-out-of-rollback-122098.stderr | 10 +- tests/ui/issues/issue-16939.stderr | 10 +- tests/ui/issues/issue-4935.stderr | 10 +- tests/ui/methods/method-call-err-msg.stderr | 10 +- .../resolve/resolve-primitive-fallback.stderr | 10 +- tests/ui/span/issue-34264.stderr | 20 ++- tests/ui/tuple/wrong_argument_ice-4.stderr | 13 +- ...e-ascription-instead-of-initializer.stderr | 10 +- tests/ui/typeck/remove-extra-argument.stderr | 10 +- tests/ui/typeck/struct-enum-wrong-args.stderr | 30 ++-- 17 files changed, 264 insertions(+), 180 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index 56dff0808676b..047d0850d4ca1 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -1384,7 +1384,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { Some(format!("provide the argument{}", if plural { "s" } else { "" })) } SuggestionText::Remove(plural) => { - err.multipart_suggestion( + err.multipart_suggestion_verbose( format!("remove the extra argument{}", if plural { "s" } else { "" }), suggestions, Applicability::HasPlaceholders, diff --git a/tests/ui/argument-suggestions/basic.stderr b/tests/ui/argument-suggestions/basic.stderr index c74186285f9f0..ea58ca97cfaf8 100644 --- a/tests/ui/argument-suggestions/basic.stderr +++ b/tests/ui/argument-suggestions/basic.stderr @@ -16,16 +16,18 @@ error[E0061]: this function takes 0 arguments but 1 argument was supplied --> $DIR/basic.rs:21:5 | LL | extra(""); - | ^^^^^ -- - | | - | unexpected argument of type `&'static str` - | help: remove the extra argument + | ^^^^^ -- unexpected argument of type `&'static str` | note: function defined here --> $DIR/basic.rs:14:4 | LL | fn extra() {} | ^^^^^ +help: remove the extra argument + | +LL - extra(""); +LL + extra(); + | error[E0061]: this function takes 1 argument but 0 arguments were supplied --> $DIR/basic.rs:22:5 diff --git a/tests/ui/argument-suggestions/exotic-calls.stderr b/tests/ui/argument-suggestions/exotic-calls.stderr index ff795b507f218..aca3b8a343343 100644 --- a/tests/ui/argument-suggestions/exotic-calls.stderr +++ b/tests/ui/argument-suggestions/exotic-calls.stderr @@ -2,61 +2,69 @@ error[E0057]: this function takes 0 arguments but 1 argument was supplied --> $DIR/exotic-calls.rs:2:5 | LL | t(1i32); - | ^ ---- - | | - | unexpected argument of type `i32` - | help: remove the extra argument + | ^ ---- unexpected argument of type `i32` | note: callable defined here --> $DIR/exotic-calls.rs:1:11 | LL | fn foo(t: T) { | ^^^^ +help: remove the extra argument + | +LL - t(1i32); +LL + t(); + | error[E0057]: this function takes 0 arguments but 1 argument was supplied --> $DIR/exotic-calls.rs:7:5 | LL | t(1i32); - | ^ ---- - | | - | unexpected argument of type `i32` - | help: remove the extra argument + | ^ ---- unexpected argument of type `i32` | note: type parameter defined here --> $DIR/exotic-calls.rs:6:11 | LL | fn bar(t: impl Fn()) { | ^^^^^^^^^ +help: remove the extra argument + | +LL - t(1i32); +LL + t(); + | error[E0057]: this function takes 0 arguments but 1 argument was supplied --> $DIR/exotic-calls.rs:16:5 | LL | baz()(1i32) - | ^^^^^ ---- - | | - | unexpected argument of type `i32` - | help: remove the extra argument + | ^^^^^ ---- unexpected argument of type `i32` | note: opaque type defined here --> $DIR/exotic-calls.rs:11:13 | LL | fn baz() -> impl Fn() { | ^^^^^^^^^ +help: remove the extra argument + | +LL - baz()(1i32) +LL + baz()() + | error[E0057]: this function takes 0 arguments but 1 argument was supplied --> $DIR/exotic-calls.rs:22:5 | LL | x(1i32); - | ^ ---- - | | - | unexpected argument of type `i32` - | help: remove the extra argument + | ^ ---- unexpected argument of type `i32` | note: closure defined here --> $DIR/exotic-calls.rs:21:13 | LL | let x = || {}; | ^^ +help: remove the extra argument + | +LL - x(1i32); +LL + x(); + | error: aborting due to 4 previous errors diff --git a/tests/ui/argument-suggestions/extra_arguments.stderr b/tests/ui/argument-suggestions/extra_arguments.stderr index 5ad8e35920a10..dec3da7518658 100644 --- a/tests/ui/argument-suggestions/extra_arguments.stderr +++ b/tests/ui/argument-suggestions/extra_arguments.stderr @@ -2,16 +2,18 @@ error[E0061]: this function takes 0 arguments but 1 argument was supplied --> $DIR/extra_arguments.rs:19:3 | LL | empty(""); - | ^^^^^ -- - | | - | unexpected argument of type `&'static str` - | help: remove the extra argument + | ^^^^^ -- unexpected argument of type `&'static str` | note: function defined here --> $DIR/extra_arguments.rs:1:4 | LL | fn empty() {} | ^^^^^ +help: remove the extra argument + | +LL - empty(""); +LL + empty(); + | error[E0061]: this function takes 0 arguments but 2 arguments were supplied --> $DIR/extra_arguments.rs:20:3 @@ -36,31 +38,35 @@ error[E0061]: this function takes 1 argument but 2 arguments were supplied --> $DIR/extra_arguments.rs:22:3 | LL | one_arg(1, 1); - | ^^^^^^^ --- - | | | - | | unexpected argument of type `{integer}` - | help: remove the extra argument + | ^^^^^^^ - unexpected argument of type `{integer}` | note: function defined here --> $DIR/extra_arguments.rs:2:4 | LL | fn one_arg(_a: T) {} | ^^^^^^^ ----- +help: remove the extra argument + | +LL - one_arg(1, 1); +LL + one_arg(1); + | error[E0061]: this function takes 1 argument but 2 arguments were supplied --> $DIR/extra_arguments.rs:23:3 | LL | one_arg(1, ""); - | ^^^^^^^ ---- - | | | - | | unexpected argument of type `&'static str` - | help: remove the extra argument + | ^^^^^^^ -- unexpected argument of type `&'static str` | note: function defined here --> $DIR/extra_arguments.rs:2:4 | LL | fn one_arg(_a: T) {} | ^^^^^^^ ----- +help: remove the extra argument + | +LL - one_arg(1, ""); +LL + one_arg(1); + | error[E0061]: this function takes 1 argument but 3 arguments were supplied --> $DIR/extra_arguments.rs:24:3 @@ -85,61 +91,69 @@ error[E0061]: this function takes 2 arguments but 3 arguments were supplied --> $DIR/extra_arguments.rs:26:3 | LL | two_arg_same(1, 1, 1); - | ^^^^^^^^^^^^ --- - | | | - | | unexpected argument of type `{integer}` - | help: remove the extra argument + | ^^^^^^^^^^^^ - unexpected argument of type `{integer}` | note: function defined here --> $DIR/extra_arguments.rs:3:4 | LL | fn two_arg_same(_a: i32, _b: i32) {} | ^^^^^^^^^^^^ ------- ------- +help: remove the extra argument + | +LL - two_arg_same(1, 1, 1); +LL + two_arg_same(1, 1); + | error[E0061]: this function takes 2 arguments but 3 arguments were supplied --> $DIR/extra_arguments.rs:27:3 | LL | two_arg_same(1, 1, 1.0); - | ^^^^^^^^^^^^ ----- - | | | - | | unexpected argument of type `{float}` - | help: remove the extra argument + | ^^^^^^^^^^^^ --- unexpected argument of type `{float}` | note: function defined here --> $DIR/extra_arguments.rs:3:4 | LL | fn two_arg_same(_a: i32, _b: i32) {} | ^^^^^^^^^^^^ ------- ------- +help: remove the extra argument + | +LL - two_arg_same(1, 1, 1.0); +LL + two_arg_same(1, 1); + | error[E0061]: this function takes 2 arguments but 3 arguments were supplied --> $DIR/extra_arguments.rs:29:3 | LL | two_arg_diff(1, 1, ""); - | ^^^^^^^^^^^^ --- - | | | - | | unexpected argument of type `{integer}` - | help: remove the extra argument + | ^^^^^^^^^^^^ - unexpected argument of type `{integer}` | note: function defined here --> $DIR/extra_arguments.rs:4:4 | LL | fn two_arg_diff(_a: i32, _b: &str) {} | ^^^^^^^^^^^^ ------- -------- +help: remove the extra argument + | +LL - two_arg_diff(1, 1, ""); +LL + two_arg_diff(1, ""); + | error[E0061]: this function takes 2 arguments but 3 arguments were supplied --> $DIR/extra_arguments.rs:30:3 | LL | two_arg_diff(1, "", ""); - | ^^^^^^^^^^^^ ---- - | | | - | | unexpected argument of type `&'static str` - | help: remove the extra argument + | ^^^^^^^^^^^^ -- unexpected argument of type `&'static str` | note: function defined here --> $DIR/extra_arguments.rs:4:4 | LL | fn two_arg_diff(_a: i32, _b: &str) {} | ^^^^^^^^^^^^ ------- -------- +help: remove the extra argument + | +LL - two_arg_diff(1, "", ""); +LL + two_arg_diff(1, ""); + | error[E0061]: this function takes 2 arguments but 4 arguments were supplied --> $DIR/extra_arguments.rs:31:3 @@ -183,70 +197,75 @@ error[E0061]: this function takes 2 arguments but 3 arguments were supplied --> $DIR/extra_arguments.rs:35:3 | LL | two_arg_same(1, 1, ""); - | ^^^^^^^^^^^^ -------- - | | | - | | unexpected argument of type `&'static str` - | help: remove the extra argument + | ^^^^^^^^^^^^ -- unexpected argument of type `&'static str` | note: function defined here --> $DIR/extra_arguments.rs:3:4 | LL | fn two_arg_same(_a: i32, _b: i32) {} | ^^^^^^^^^^^^ ------- ------- +help: remove the extra argument + | +LL - two_arg_same(1, 1, ""); +LL + two_arg_same(1, 1); + | error[E0061]: this function takes 2 arguments but 3 arguments were supplied --> $DIR/extra_arguments.rs:36:3 | LL | two_arg_diff(1, 1, ""); - | ^^^^^^^^^^^^ --- - | | | - | | unexpected argument of type `{integer}` - | help: remove the extra argument + | ^^^^^^^^^^^^ - unexpected argument of type `{integer}` | note: function defined here --> $DIR/extra_arguments.rs:4:4 | LL | fn two_arg_diff(_a: i32, _b: &str) {} | ^^^^^^^^^^^^ ------- -------- +help: remove the extra argument + | +LL - two_arg_diff(1, 1, ""); +LL + two_arg_diff(1, ""); + | error[E0061]: this function takes 2 arguments but 3 arguments were supplied --> $DIR/extra_arguments.rs:37:3 | -LL | two_arg_same( - | ^^^^^^^^^^^^ -LL | 1, -LL | 1, - | ______- -LL | | "" - | | -- - | |_____|| - | |help: remove the extra argument - | unexpected argument of type `&'static str` +LL | two_arg_same( + | ^^^^^^^^^^^^ +... +LL | "" + | -- unexpected argument of type `&'static str` | note: function defined here --> $DIR/extra_arguments.rs:3:4 | LL | fn two_arg_same(_a: i32, _b: i32) {} | ^^^^^^^^^^^^ ------- ------- +help: remove the extra argument + | +LL - 1, +LL - "" +LL + 1 + | error[E0061]: this function takes 2 arguments but 3 arguments were supplied --> $DIR/extra_arguments.rs:43:3 | -LL | two_arg_diff( - | ^^^^^^^^^^^^ -LL | 1, - | ______- -LL | | 1, - | | - - | | | - | |_____unexpected argument of type `{integer}` - | help: remove the extra argument +LL | two_arg_diff( + | ^^^^^^^^^^^^ +LL | 1, +LL | 1, + | - unexpected argument of type `{integer}` | note: function defined here --> $DIR/extra_arguments.rs:4:4 | LL | fn two_arg_diff(_a: i32, _b: &str) {} | ^^^^^^^^^^^^ ------- -------- +help: remove the extra argument + | +LL - 1, + | error[E0061]: this function takes 0 arguments but 2 arguments were supplied --> $DIR/extra_arguments.rs:8:9 @@ -310,61 +329,69 @@ error[E0061]: this function takes 1 argument but 2 arguments were supplied --> $DIR/extra_arguments.rs:53:3 | LL | one_arg(1, panic!()); - | ^^^^^^^ ---------- - | | | - | | unexpected argument - | help: remove the extra argument + | ^^^^^^^ -------- unexpected argument | note: function defined here --> $DIR/extra_arguments.rs:2:4 | LL | fn one_arg(_a: T) {} | ^^^^^^^ ----- +help: remove the extra argument + | +LL - one_arg(1, panic!()); +LL + one_arg(1); + | error[E0061]: this function takes 1 argument but 2 arguments were supplied --> $DIR/extra_arguments.rs:54:3 | LL | one_arg(panic!(), 1); - | ^^^^^^^ --- - | | | - | | unexpected argument of type `{integer}` - | help: remove the extra argument + | ^^^^^^^ - unexpected argument of type `{integer}` | note: function defined here --> $DIR/extra_arguments.rs:2:4 | LL | fn one_arg(_a: T) {} | ^^^^^^^ ----- +help: remove the extra argument + | +LL - one_arg(panic!(), 1); +LL + one_arg(panic!()); + | error[E0061]: this function takes 1 argument but 2 arguments were supplied --> $DIR/extra_arguments.rs:55:3 | LL | one_arg(stringify!($e), 1); - | ^^^^^^^ --- - | | | - | | unexpected argument of type `{integer}` - | help: remove the extra argument + | ^^^^^^^ - unexpected argument of type `{integer}` | note: function defined here --> $DIR/extra_arguments.rs:2:4 | LL | fn one_arg(_a: T) {} | ^^^^^^^ ----- +help: remove the extra argument + | +LL - one_arg(stringify!($e), 1); +LL + one_arg(stringify!($e)); + | error[E0061]: this function takes 1 argument but 2 arguments were supplied --> $DIR/extra_arguments.rs:60:3 | LL | one_arg(for _ in 1.. {}, 1); - | ^^^^^^^ --- - | | | - | | unexpected argument of type `{integer}` - | help: remove the extra argument + | ^^^^^^^ - unexpected argument of type `{integer}` | note: function defined here --> $DIR/extra_arguments.rs:2:4 | LL | fn one_arg(_a: T) {} | ^^^^^^^ ----- +help: remove the extra argument + | +LL - one_arg(for _ in 1.. {}, 1); +LL + one_arg(for _ in 1.. {}); + | error: aborting due to 22 previous errors diff --git a/tests/ui/argument-suggestions/suggest-better-removing-issue-126246.stderr b/tests/ui/argument-suggestions/suggest-better-removing-issue-126246.stderr index 7c4daa3ffe95b..dc293945eb600 100644 --- a/tests/ui/argument-suggestions/suggest-better-removing-issue-126246.stderr +++ b/tests/ui/argument-suggestions/suggest-better-removing-issue-126246.stderr @@ -32,91 +32,103 @@ error[E0061]: this function takes 1 argument but 2 arguments were supplied --> $DIR/suggest-better-removing-issue-126246.rs:10:5 | LL | add_one(2, 2); - | ^^^^^^^ --- - | | | - | | unexpected argument of type `{integer}` - | help: remove the extra argument + | ^^^^^^^ - unexpected argument of type `{integer}` | note: function defined here --> $DIR/suggest-better-removing-issue-126246.rs:1:4 | LL | fn add_one(x: i32) -> i32 { | ^^^^^^^ ------ +help: remove the extra argument + | +LL - add_one(2, 2); +LL + add_one(2); + | error[E0061]: this function takes 1 argument but 2 arguments were supplied --> $DIR/suggest-better-removing-issue-126246.rs:11:5 | LL | add_one(no_such_local, 10); - | ^^^^^^^ --------------- - | | - | unexpected argument - | help: remove the extra argument + | ^^^^^^^ ------------- unexpected argument | note: function defined here --> $DIR/suggest-better-removing-issue-126246.rs:1:4 | LL | fn add_one(x: i32) -> i32 { | ^^^^^^^ ------ +help: remove the extra argument + | +LL - add_one(no_such_local, 10); +LL + add_one(10); + | error[E0061]: this function takes 1 argument but 2 arguments were supplied --> $DIR/suggest-better-removing-issue-126246.rs:13:5 | LL | add_one(10, no_such_local); - | ^^^^^^^ --------------- - | | | - | | unexpected argument - | help: remove the extra argument + | ^^^^^^^ ------------- unexpected argument | note: function defined here --> $DIR/suggest-better-removing-issue-126246.rs:1:4 | LL | fn add_one(x: i32) -> i32 { | ^^^^^^^ ------ +help: remove the extra argument + | +LL - add_one(10, no_such_local); +LL + add_one(10); + | error[E0061]: this function takes 2 arguments but 3 arguments were supplied --> $DIR/suggest-better-removing-issue-126246.rs:15:5 | LL | add_two(10, no_such_local, 10); - | ^^^^^^^ --------------- - | | | - | | unexpected argument - | help: remove the extra argument + | ^^^^^^^ ------------- unexpected argument | note: function defined here --> $DIR/suggest-better-removing-issue-126246.rs:5:4 | LL | fn add_two(x: i32, y: i32) -> i32 { | ^^^^^^^ ------ ------ +help: remove the extra argument + | +LL - add_two(10, no_such_local, 10); +LL + add_two(10, 10); + | error[E0061]: this function takes 2 arguments but 3 arguments were supplied --> $DIR/suggest-better-removing-issue-126246.rs:17:5 | LL | add_two(no_such_local, 10, 10); - | ^^^^^^^ --------------- - | | - | unexpected argument - | help: remove the extra argument + | ^^^^^^^ ------------- unexpected argument | note: function defined here --> $DIR/suggest-better-removing-issue-126246.rs:5:4 | LL | fn add_two(x: i32, y: i32) -> i32 { | ^^^^^^^ ------ ------ +help: remove the extra argument + | +LL - add_two(no_such_local, 10, 10); +LL + add_two(10, 10); + | error[E0061]: this function takes 2 arguments but 3 arguments were supplied --> $DIR/suggest-better-removing-issue-126246.rs:19:5 | LL | add_two(10, 10, no_such_local); - | ^^^^^^^ --------------- - | | | - | | unexpected argument - | help: remove the extra argument + | ^^^^^^^ ------------- unexpected argument | note: function defined here --> $DIR/suggest-better-removing-issue-126246.rs:5:4 | LL | fn add_two(x: i32, y: i32) -> i32 { | ^^^^^^^ ------ ------ +help: remove the extra argument + | +LL - add_two(10, 10, no_such_local); +LL + add_two(10, 10); + | error: aborting due to 11 previous errors diff --git a/tests/ui/error-codes/E0057.stderr b/tests/ui/error-codes/E0057.stderr index 9b0cf069824a6..efd2af6d609bd 100644 --- a/tests/ui/error-codes/E0057.stderr +++ b/tests/ui/error-codes/E0057.stderr @@ -18,16 +18,18 @@ error[E0057]: this function takes 1 argument but 2 arguments were supplied --> $DIR/E0057.rs:5:13 | LL | let c = f(2, 3); - | ^ --- - | | | - | | unexpected argument of type `{integer}` - | help: remove the extra argument + | ^ - unexpected argument of type `{integer}` | note: closure defined here --> $DIR/E0057.rs:2:13 | LL | let f = |x| x * 3; | ^^^ +help: remove the extra argument + | +LL - let c = f(2, 3); +LL + let c = f(2); + | error: aborting due to 2 previous errors diff --git a/tests/ui/impl-trait/opaque-used-in-extraneous-argument.stderr b/tests/ui/impl-trait/opaque-used-in-extraneous-argument.stderr index 6d41748853332..caaac5434c56a 100644 --- a/tests/ui/impl-trait/opaque-used-in-extraneous-argument.stderr +++ b/tests/ui/impl-trait/opaque-used-in-extraneous-argument.stderr @@ -57,31 +57,35 @@ error[E0061]: this function takes 0 arguments but 1 argument was supplied --> $DIR/opaque-used-in-extraneous-argument.rs:17:20 | LL | let old_path = frob("hello"); - | ^^^^ ------- - | | - | unexpected argument of type `&'static str` - | help: remove the extra argument + | ^^^^ ------- unexpected argument of type `&'static str` | note: function defined here --> $DIR/opaque-used-in-extraneous-argument.rs:5:4 | LL | fn frob() -> impl Fn + '_ {} | ^^^^ +help: remove the extra argument + | +LL - let old_path = frob("hello"); +LL + let old_path = frob(); + | error[E0061]: this function takes 0 arguments but 1 argument was supplied --> $DIR/opaque-used-in-extraneous-argument.rs:20:5 | LL | open_parent(&old_path) - | ^^^^^^^^^^^ --------- - | | - | unexpected argument of type `&impl FnOnce<{type error}, Output = {type error}> + Fn<{type error}> + 'static` - | help: remove the extra argument + | ^^^^^^^^^^^ --------- unexpected argument of type `&impl FnOnce<{type error}, Output = {type error}> + Fn<{type error}> + 'static` | note: function defined here --> $DIR/opaque-used-in-extraneous-argument.rs:12:4 | LL | fn open_parent<'path>() { | ^^^^^^^^^^^ +help: remove the extra argument + | +LL - open_parent(&old_path) +LL + open_parent() + | error: aborting due to 7 previous errors diff --git a/tests/ui/inference/ice-ifer-var-leaked-out-of-rollback-122098.stderr b/tests/ui/inference/ice-ifer-var-leaked-out-of-rollback-122098.stderr index e2ddf474c4a97..a5cd057e28421 100644 --- a/tests/ui/inference/ice-ifer-var-leaked-out-of-rollback-122098.stderr +++ b/tests/ui/inference/ice-ifer-var-leaked-out-of-rollback-122098.stderr @@ -55,16 +55,18 @@ error[E0061]: this function takes 0 arguments but 1 argument was supplied --> $DIR/ice-ifer-var-leaked-out-of-rollback-122098.rs:21:31 | LL | LendingIterator::for_each(Query::new(&data), Box::new); - | ^^^^^^^^^^ ----- - | | - | unexpected argument of type `&fn() {data}` - | help: remove the extra argument + | ^^^^^^^^^^ ----- unexpected argument of type `&fn() {data}` | note: associated function defined here --> $DIR/ice-ifer-var-leaked-out-of-rollback-122098.rs:17:12 | LL | pub fn new() -> Self {} | ^^^ +help: remove the extra argument + | +LL - LendingIterator::for_each(Query::new(&data), Box::new); +LL + LendingIterator::for_each(Query::new(), Box::new); + | error: aborting due to 6 previous errors diff --git a/tests/ui/issues/issue-16939.stderr b/tests/ui/issues/issue-16939.stderr index 229ff9f181773..6e0889b89635b 100644 --- a/tests/ui/issues/issue-16939.stderr +++ b/tests/ui/issues/issue-16939.stderr @@ -2,16 +2,18 @@ error[E0057]: this function takes 0 arguments but 1 argument was supplied --> $DIR/issue-16939.rs:5:9 | LL | |t| f(t); - | ^ - - | | - | unexpected argument - | help: remove the extra argument + | ^ - unexpected argument | note: callable defined here --> $DIR/issue-16939.rs:4:12 | LL | fn _foo (f: F) { | ^^^^ +help: remove the extra argument + | +LL - |t| f(t); +LL + |t| f(); + | error: aborting due to 1 previous error diff --git a/tests/ui/issues/issue-4935.stderr b/tests/ui/issues/issue-4935.stderr index 25f299ae5f3bb..f18cf66f14d08 100644 --- a/tests/ui/issues/issue-4935.stderr +++ b/tests/ui/issues/issue-4935.stderr @@ -2,16 +2,18 @@ error[E0061]: this function takes 1 argument but 2 arguments were supplied --> $DIR/issue-4935.rs:5:13 | LL | fn main() { foo(5, 6) } - | ^^^ --- - | | | - | | unexpected argument of type `{integer}` - | help: remove the extra argument + | ^^^ - unexpected argument of type `{integer}` | note: function defined here --> $DIR/issue-4935.rs:3:4 | LL | fn foo(a: usize) {} | ^^^ -------- +help: remove the extra argument + | +LL - fn main() { foo(5, 6) } +LL + fn main() { foo(5) } + | error: aborting due to 1 previous error diff --git a/tests/ui/methods/method-call-err-msg.stderr b/tests/ui/methods/method-call-err-msg.stderr index 5a76449e9f95b..0855a17b33394 100644 --- a/tests/ui/methods/method-call-err-msg.stderr +++ b/tests/ui/methods/method-call-err-msg.stderr @@ -2,16 +2,18 @@ error[E0061]: this method takes 0 arguments but 1 argument was supplied --> $DIR/method-call-err-msg.rs:13:7 | LL | x.zero(0) - | ^^^^ - - | | - | unexpected argument of type `{integer}` - | help: remove the extra argument + | ^^^^ - unexpected argument of type `{integer}` | note: method defined here --> $DIR/method-call-err-msg.rs:5:8 | LL | fn zero(self) -> Foo { self } | ^^^^ +help: remove the extra argument + | +LL - x.zero(0) +LL + x.zero() + | error[E0061]: this method takes 1 argument but 0 arguments were supplied --> $DIR/method-call-err-msg.rs:14:7 diff --git a/tests/ui/resolve/resolve-primitive-fallback.stderr b/tests/ui/resolve/resolve-primitive-fallback.stderr index e3a5d4edcf102..d0583966459be 100644 --- a/tests/ui/resolve/resolve-primitive-fallback.stderr +++ b/tests/ui/resolve/resolve-primitive-fallback.stderr @@ -24,13 +24,15 @@ error[E0061]: this function takes 0 arguments but 1 argument was supplied --> $DIR/resolve-primitive-fallback.rs:3:5 | LL | std::mem::size_of(u16); - | ^^^^^^^^^^^^^^^^^ --- - | | - | unexpected argument - | help: remove the extra argument + | ^^^^^^^^^^^^^^^^^ --- unexpected argument | note: function defined here --> $SRC_DIR/core/src/mem/mod.rs:LL:COL +help: remove the extra argument + | +LL - std::mem::size_of(u16); +LL + std::mem::size_of(); + | error: aborting due to 3 previous errors diff --git a/tests/ui/span/issue-34264.stderr b/tests/ui/span/issue-34264.stderr index f0dea66f6128d..89c67719b5ae2 100644 --- a/tests/ui/span/issue-34264.stderr +++ b/tests/ui/span/issue-34264.stderr @@ -54,16 +54,18 @@ error[E0061]: this function takes 2 arguments but 3 arguments were supplied --> $DIR/issue-34264.rs:7:5 | LL | foo(Some(42), 2, ""); - | ^^^ ---- - | | | - | | unexpected argument of type `&'static str` - | help: remove the extra argument + | ^^^ -- unexpected argument of type `&'static str` | note: function defined here --> $DIR/issue-34264.rs:1:4 | LL | fn foo(Option, String) {} | ^^^ ----------- ------ +help: remove the extra argument + | +LL - foo(Some(42), 2, ""); +LL + foo(Some(42), 2); + | error[E0308]: mismatched types --> $DIR/issue-34264.rs:8:13 @@ -83,16 +85,18 @@ error[E0061]: this function takes 2 arguments but 3 arguments were supplied --> $DIR/issue-34264.rs:10:5 | LL | bar(1, 2, 3); - | ^^^ --- - | | | - | | unexpected argument of type `{integer}` - | help: remove the extra argument + | ^^^ - unexpected argument of type `{integer}` | note: function defined here --> $DIR/issue-34264.rs:3:4 | LL | fn bar(x, y: usize) {} | ^^^ - -------- +help: remove the extra argument + | +LL - bar(1, 2, 3); +LL + bar(1, 2); + | error: aborting due to 6 previous errors diff --git a/tests/ui/tuple/wrong_argument_ice-4.stderr b/tests/ui/tuple/wrong_argument_ice-4.stderr index 3c7d6699be2b5..10191faf7bf03 100644 --- a/tests/ui/tuple/wrong_argument_ice-4.stderr +++ b/tests/ui/tuple/wrong_argument_ice-4.stderr @@ -6,16 +6,21 @@ LL | (|| {})(|| { LL | | LL | | let b = 1; LL | | }); - | | - - | | | - | |_____unexpected argument of type `{closure@$DIR/wrong_argument_ice-4.rs:2:13: 2:15}` - | help: remove the extra argument + | |_____- unexpected argument of type `{closure@$DIR/wrong_argument_ice-4.rs:2:13: 2:15}` | note: closure defined here --> $DIR/wrong_argument_ice-4.rs:2:6 | LL | (|| {})(|| { | ^^ +help: remove the extra argument + | +LL - (|| {})(|| { +LL - +LL - let b = 1; +LL - }); +LL + (|| {})(); + | error: aborting due to 1 previous error diff --git a/tests/ui/type/type-ascription-instead-of-initializer.stderr b/tests/ui/type/type-ascription-instead-of-initializer.stderr index efa917334bf0c..224ff6e740486 100644 --- a/tests/ui/type/type-ascription-instead-of-initializer.stderr +++ b/tests/ui/type/type-ascription-instead-of-initializer.stderr @@ -11,13 +11,15 @@ error[E0061]: this function takes 1 argument but 2 arguments were supplied --> $DIR/type-ascription-instead-of-initializer.rs:2:12 | LL | let x: Vec::with_capacity(10, 20); - | ^^^^^^^^^^^^^^^^^^ ---- - | | | - | | unexpected argument of type `{integer}` - | help: remove the extra argument + | ^^^^^^^^^^^^^^^^^^ -- unexpected argument of type `{integer}` | note: associated function defined here --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL +help: remove the extra argument + | +LL - let x: Vec::with_capacity(10, 20); +LL + let x: Vec::with_capacity(10); + | error: aborting due to 2 previous errors diff --git a/tests/ui/typeck/remove-extra-argument.stderr b/tests/ui/typeck/remove-extra-argument.stderr index 9557c41457dcd..4bab2959651b7 100644 --- a/tests/ui/typeck/remove-extra-argument.stderr +++ b/tests/ui/typeck/remove-extra-argument.stderr @@ -2,16 +2,18 @@ error[E0061]: this function takes 1 argument but 2 arguments were supplied --> $DIR/remove-extra-argument.rs:6:5 | LL | l(vec![], vec![]) - | ^ -------- - | | | - | | unexpected argument of type `Vec<_>` - | help: remove the extra argument + | ^ ------ unexpected argument of type `Vec<_>` | note: function defined here --> $DIR/remove-extra-argument.rs:3:4 | LL | fn l(_a: Vec) {} | ^ ----------- +help: remove the extra argument + | +LL - l(vec![], vec![]) +LL + l(vec![]) + | error: aborting due to 1 previous error diff --git a/tests/ui/typeck/struct-enum-wrong-args.stderr b/tests/ui/typeck/struct-enum-wrong-args.stderr index 57cbd1d2005c3..d005eca841ecb 100644 --- a/tests/ui/typeck/struct-enum-wrong-args.stderr +++ b/tests/ui/typeck/struct-enum-wrong-args.stderr @@ -2,13 +2,15 @@ error[E0061]: this enum variant takes 1 argument but 2 arguments were supplied --> $DIR/struct-enum-wrong-args.rs:6:13 | LL | let _ = Some(3, 2); - | ^^^^ --- - | | | - | | unexpected argument of type `{integer}` - | help: remove the extra argument + | ^^^^ - unexpected argument of type `{integer}` | note: tuple variant defined here --> $SRC_DIR/core/src/option.rs:LL:COL +help: remove the extra argument + | +LL - let _ = Some(3, 2); +LL + let _ = Some(3); + | error[E0061]: this enum variant takes 1 argument but 3 arguments were supplied --> $DIR/struct-enum-wrong-args.rs:7:13 @@ -59,16 +61,18 @@ error[E0061]: this struct takes 1 argument but 2 arguments were supplied --> $DIR/struct-enum-wrong-args.rs:10:13 | LL | let _ = Wrapper(5, 2); - | ^^^^^^^ --- - | | | - | | unexpected argument of type `{integer}` - | help: remove the extra argument + | ^^^^^^^ - unexpected argument of type `{integer}` | note: tuple struct defined here --> $DIR/struct-enum-wrong-args.rs:2:8 | LL | struct Wrapper(i32); | ^^^^^^^ +help: remove the extra argument + | +LL - let _ = Wrapper(5, 2); +LL + let _ = Wrapper(5); + | error[E0061]: this struct takes 2 arguments but 0 arguments were supplied --> $DIR/struct-enum-wrong-args.rs:11:13 @@ -106,16 +110,18 @@ error[E0061]: this struct takes 2 arguments but 3 arguments were supplied --> $DIR/struct-enum-wrong-args.rs:13:13 | LL | let _ = DoubleWrapper(5, 2, 7); - | ^^^^^^^^^^^^^ --- - | | | - | | unexpected argument of type `{integer}` - | help: remove the extra argument + | ^^^^^^^^^^^^^ - unexpected argument of type `{integer}` | note: tuple struct defined here --> $DIR/struct-enum-wrong-args.rs:3:8 | LL | struct DoubleWrapper(i32, i32); | ^^^^^^^^^^^^^ +help: remove the extra argument + | +LL - let _ = DoubleWrapper(5, 2, 7); +LL + let _ = DoubleWrapper(5, 2); + | error: aborting due to 8 previous errors From e5412da723d8d8ff68461ee6b43d5725c3d37968 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 5 Jul 2024 15:51:53 -0400 Subject: [PATCH 753/892] Supertrait elaboration doesn't need to use Predicates --- compiler/rustc_infer/src/traits/util.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_infer/src/traits/util.rs b/compiler/rustc_infer/src/traits/util.rs index 24cf9f03fcdb3..def341beceb9d 100644 --- a/compiler/rustc_infer/src/traits/util.rs +++ b/compiler/rustc_infer/src/traits/util.rs @@ -405,14 +405,14 @@ impl<'tcx, O: Elaboratable<'tcx>> Iterator for Elaborator<'tcx, O> { pub fn supertraits<'tcx>( tcx: TyCtxt<'tcx>, trait_ref: ty::PolyTraitRef<'tcx>, -) -> FilterToTraits>> { +) -> FilterToTraits>> { elaborate(tcx, [trait_ref.upcast(tcx)]).filter_only_self().filter_to_traits() } pub fn transitive_bounds<'tcx>( tcx: TyCtxt<'tcx>, trait_refs: impl Iterator>, -) -> FilterToTraits>> { +) -> FilterToTraits>> { elaborate(tcx, trait_refs.map(|trait_ref| trait_ref.upcast(tcx))) .filter_only_self() .filter_to_traits() @@ -427,7 +427,7 @@ pub fn transitive_bounds_that_define_assoc_item<'tcx>( tcx: TyCtxt<'tcx>, trait_refs: impl Iterator>, assoc_name: Ident, -) -> FilterToTraits>> { +) -> FilterToTraits>> { elaborate(tcx, trait_refs.map(|trait_ref| trait_ref.upcast(tcx))) .filter_only_self_that_defines(assoc_name) .filter_to_traits() @@ -437,7 +437,7 @@ pub fn transitive_bounds_that_define_assoc_item<'tcx>( // Other /////////////////////////////////////////////////////////////////////////// -impl<'tcx> Elaborator<'tcx, ty::Predicate<'tcx>> { +impl<'tcx> Elaborator<'tcx, ty::Clause<'tcx>> { fn filter_to_traits(self) -> FilterToTraits { FilterToTraits { base_iterator: self } } @@ -449,7 +449,7 @@ pub struct FilterToTraits { base_iterator: I, } -impl<'tcx, I: Iterator>> Iterator for FilterToTraits { +impl<'tcx, I: Iterator>> Iterator for FilterToTraits { type Item = ty::PolyTraitRef<'tcx>; fn next(&mut self) -> Option> { From 073f3a263b179ed446a1ab1209da9d9990bc6f74 Mon Sep 17 00:00:00 2001 From: Maybe Lapkin Date: Fri, 5 Jul 2024 22:35:14 +0200 Subject: [PATCH 754/892] Equate types instead of using `Unsize` --- compiler/rustc_borrowck/src/type_check/mod.rs | 65 ++++++++----------- compiler/rustc_hir_typeck/src/cast.rs | 25 ++----- .../cast/ptr-to-trait-obj-different-args.rs | 8 +-- .../ptr-to-trait-obj-different-args.stderr | 45 ++++++------- tests/ui/traits/upcast_soundness_bug.rs | 2 +- tests/ui/traits/upcast_soundness_bug.stderr | 10 +-- 6 files changed, 68 insertions(+), 87 deletions(-) diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 6fd49c8027b00..a457283ab7d54 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -38,6 +38,7 @@ use rustc_span::def_id::CRATE_DEF_ID; use rustc_span::source_map::Spanned; use rustc_span::symbol::sym; use rustc_span::Span; +use rustc_span::DUMMY_SP; use rustc_target::abi::{FieldIdx, FIRST_VARIANT}; use rustc_trait_selection::traits::query::type_op::custom::scrape_region_constraints; use rustc_trait_selection::traits::query::type_op::custom::CustomTypeOp; @@ -49,6 +50,7 @@ use rustc_mir_dataflow::impls::MaybeInitializedPlaces; use rustc_mir_dataflow::move_paths::MoveData; use rustc_mir_dataflow::ResultsCursor; +use crate::renumber::RegionCtxt; use crate::session_diagnostics::{MoveUnsized, SimdIntrinsicArgConst}; use crate::{ borrow_set::BorrowSet, @@ -2335,51 +2337,39 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { && src_tty.principal().is_some() && dst_tty.principal().is_some() { - // Erase trait object lifetimes, to allow casts like `*mut dyn FnOnce()` -> `*mut dyn FnOnce() + 'static` - // and remove auto traits. + // Remove auto traits. + // Auto trait checks are handled in `rustc_hir_typeck` as FCW. let src_obj = tcx.mk_ty_from_kind(ty::Dynamic( tcx.mk_poly_existential_predicates( &src_tty.without_auto_traits().collect::>(), ), - tcx.lifetimes.re_erased, + tcx.lifetimes.re_static, ty::Dyn, )); let dst_obj = tcx.mk_ty_from_kind(ty::Dynamic( tcx.mk_poly_existential_predicates( &dst_tty.without_auto_traits().collect::>(), ), - tcx.lifetimes.re_erased, + tcx.lifetimes.re_static, ty::Dyn, )); - // FIXME: - // this currently does nothing, but once we make `ptr_cast_add_auto_to_object` - // into a hard error, we can remove the above removal of auto traits and only - // keep this. - let src_obj = erase_single_trait_object_lifetime(tcx, src_obj); - let dst_obj = erase_single_trait_object_lifetime(tcx, dst_obj); - - let trait_ref = ty::TraitRef::new( - tcx, - tcx.require_lang_item(LangItem::Unsize, Some(span)), - [src_obj, dst_obj], - ); + // Replace trait object lifetimes with fresh vars, to allow casts like + // `*mut dyn FnOnce() + 'a` -> `*mut dyn FnOnce() + 'static`, + let src_obj = + freshen_single_trait_object_lifetime(self.infcx, src_obj); + let dst_obj = + freshen_single_trait_object_lifetime(self.infcx, dst_obj); debug!(?src_tty, ?dst_tty, ?src_obj, ?dst_obj); - self.prove_trait_ref( - trait_ref, + self.eq_types( + src_obj, + dst_obj, location.to_locations(), - ConstraintCategory::Cast { - unsize_to: Some(tcx.fold_regions(dst_obj, |r, _| { - if let ty::ReVar(_) = r.kind() { - tcx.lifetimes.re_erased - } else { - r - } - })), - }, - ); + ConstraintCategory::Cast { unsize_to: None }, + ) + .unwrap(); } } _ => { @@ -2905,14 +2895,15 @@ impl<'tcx> TypeOp<'tcx> for InstantiateOpaqueType<'tcx> { } } -fn erase_single_trait_object_lifetime<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> { - let &ty::Dynamic(tty, region, dyn_kind @ ty::Dyn) = ty.kind() else { - bug!("expected trait object") - }; - - if region.is_erased() { - return ty; - } +fn freshen_single_trait_object_lifetime<'tcx>( + infcx: &BorrowckInferCtxt<'tcx>, + ty: Ty<'tcx>, +) -> Ty<'tcx> { + let &ty::Dynamic(tty, _, dyn_kind @ ty::Dyn) = ty.kind() else { bug!("expected trait object") }; - tcx.mk_ty_from_kind(ty::Dynamic(tty, tcx.lifetimes.re_erased, dyn_kind)) + let fresh = infcx + .next_region_var(rustc_infer::infer::RegionVariableOrigin::MiscVariable(DUMMY_SP), || { + RegionCtxt::Unknown + }); + infcx.tcx.mk_ty_from_kind(ty::Dynamic(tty, fresh, dyn_kind)) } diff --git a/compiler/rustc_hir_typeck/src/cast.rs b/compiler/rustc_hir_typeck/src/cast.rs index c78d9e578024d..7b27a4b3ba7ed 100644 --- a/compiler/rustc_hir_typeck/src/cast.rs +++ b/compiler/rustc_hir_typeck/src/cast.rs @@ -34,8 +34,7 @@ use crate::errors; use crate::type_error_struct; use rustc_data_structures::fx::FxHashSet; use rustc_errors::{codes::*, Applicability, Diag, ErrorGuaranteed}; -use rustc_hir::{self as hir, ExprKind, LangItem}; -use rustc_infer::traits::Obligation; +use rustc_hir::{self as hir, ExprKind}; use rustc_macros::{TypeFoldable, TypeVisitable}; use rustc_middle::bug; use rustc_middle::mir::Mutability; @@ -835,9 +834,9 @@ impl<'a, 'tcx> CastCheck<'tcx> { (Some(src_principal), Some(dst_principal)) => { let tcx = fcx.tcx; - // Check that the traits are actually the same - // (this is required as the `Unsize` check below would allow upcasting, etc) - // N.B.: this is only correct as long as we don't support `trait A: A<()>`. + // Check that the traits are actually the same. + // The `dyn Src = dyn Dst` check below would suffice, + // but this may produce a better diagnostic. // // Note that trait upcasting goes through a different mechanism (`coerce_unsized`) // and is unaffected by this check. @@ -867,20 +866,8 @@ impl<'a, 'tcx> CastCheck<'tcx> { ty::Dyn, )); - // `dyn Src: Unsize`, this checks for matching generics - let cause = fcx.misc(self.span); - let obligation = Obligation::new( - tcx, - cause, - fcx.param_env, - ty::TraitRef::new( - tcx, - tcx.require_lang_item(LangItem::Unsize, Some(self.span)), - [src_obj, dst_obj], - ), - ); - - fcx.register_predicate(obligation); + // `dyn Src = dyn Dst`, this checks for matching traits/generics + fcx.demand_eqtype(self.span, src_obj, dst_obj); // Check that `SrcAuto` is a superset of `DstAuto`. // Emit an FCW otherwise. diff --git a/tests/ui/cast/ptr-to-trait-obj-different-args.rs b/tests/ui/cast/ptr-to-trait-obj-different-args.rs index 88632f5506bc7..c6038cfe86401 100644 --- a/tests/ui/cast/ptr-to-trait-obj-different-args.rs +++ b/tests/ui/cast/ptr-to-trait-obj-different-args.rs @@ -18,14 +18,14 @@ fn main() { let b: *const dyn B = a as _; //~ error: casting `*const dyn A` as `*const dyn B` is invalid let x: *const dyn Trait = &(); - let y: *const dyn Trait = x as _; //~ error: the trait bound `dyn Trait: Unsize>` is not satisfied + let y: *const dyn Trait = x as _; //~ error: mismatched types _ = (b, y); } fn generic(x: *const dyn Trait, t: *const dyn Trait) { - let _: *const dyn Trait = x as _; //~ error: the trait bound `dyn Trait: Unsize>` is not satisfied - let _: *const dyn Trait = t as _; //~ error: the trait bound `dyn Trait: Unsize>` is not satisfied + let _: *const dyn Trait = x as _; //~ error: mismatched types + let _: *const dyn Trait = t as _; //~ error: mismatched types } trait Assocked { @@ -33,5 +33,5 @@ trait Assocked { } fn change_assoc(x: *mut dyn Assocked) -> *mut dyn Assocked { - x as _ //~ error: the trait bound `dyn Assocked: Unsize>` is not satisfied + x as _ //~ error: mismatched types } diff --git a/tests/ui/cast/ptr-to-trait-obj-different-args.stderr b/tests/ui/cast/ptr-to-trait-obj-different-args.stderr index 65f0be8541fc9..b04289ae74748 100644 --- a/tests/ui/cast/ptr-to-trait-obj-different-args.stderr +++ b/tests/ui/cast/ptr-to-trait-obj-different-args.stderr @@ -6,47 +6,48 @@ LL | let b: *const dyn B = a as _; | = note: vtable kinds may not match -error[E0277]: the trait bound `dyn Trait: Unsize>` is not satisfied +error[E0308]: mismatched types --> $DIR/ptr-to-trait-obj-different-args.rs:21:34 | LL | let y: *const dyn Trait = x as _; - | ^^^^^^ the trait `Unsize>` is not implemented for `dyn Trait` + | ^^^^^^ expected `X`, found `Y` | - = note: all implementations of `Unsize` are provided automatically by the compiler, see for more information + = note: expected trait object `dyn Trait` + found trait object `dyn Trait` -error[E0277]: the trait bound `dyn Trait: Unsize>` is not satisfied +error[E0308]: mismatched types --> $DIR/ptr-to-trait-obj-different-args.rs:27:34 | +LL | fn generic(x: *const dyn Trait, t: *const dyn Trait) { + | - found this type parameter LL | let _: *const dyn Trait = x as _; - | ^^^^^^ the trait `Unsize>` is not implemented for `dyn Trait` + | ^^^^^^ expected `X`, found type parameter `T` | - = note: all implementations of `Unsize` are provided automatically by the compiler, see for more information -help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement - | -LL | fn generic(x: *const dyn Trait, t: *const dyn Trait) where dyn Trait: Unsize> { - | ++++++++++++++++++++++++++++++++++++++++ + = note: expected trait object `dyn Trait` + found trait object `dyn Trait` -error[E0277]: the trait bound `dyn Trait: Unsize>` is not satisfied +error[E0308]: mismatched types --> $DIR/ptr-to-trait-obj-different-args.rs:28:34 | +LL | fn generic(x: *const dyn Trait, t: *const dyn Trait) { + | - expected this type parameter +LL | let _: *const dyn Trait = x as _; LL | let _: *const dyn Trait = t as _; - | ^^^^^^ the trait `Unsize>` is not implemented for `dyn Trait` - | - = note: all implementations of `Unsize` are provided automatically by the compiler, see for more information -help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement + | ^^^^^^ expected type parameter `T`, found `X` | -LL | fn generic(x: *const dyn Trait, t: *const dyn Trait) where dyn Trait: Unsize> { - | ++++++++++++++++++++++++++++++++++++++++ + = note: expected trait object `dyn Trait` + found trait object `dyn Trait` -error[E0277]: the trait bound `dyn Assocked: Unsize>` is not satisfied +error[E0308]: mismatched types --> $DIR/ptr-to-trait-obj-different-args.rs:36:5 | LL | x as _ - | ^^^^^^ the trait `Unsize>` is not implemented for `dyn Assocked` + | ^^^^^^ expected `u8`, found `u32` | - = note: all implementations of `Unsize` are provided automatically by the compiler, see for more information + = note: expected trait object `dyn Assocked` + found trait object `dyn Assocked` error: aborting due to 5 previous errors -Some errors have detailed explanations: E0277, E0606. -For more information about an error, try `rustc --explain E0277`. +Some errors have detailed explanations: E0308, E0606. +For more information about an error, try `rustc --explain E0308`. diff --git a/tests/ui/traits/upcast_soundness_bug.rs b/tests/ui/traits/upcast_soundness_bug.rs index dd59f8cee505c..5eaa58f7efe7f 100644 --- a/tests/ui/traits/upcast_soundness_bug.rs +++ b/tests/ui/traits/upcast_soundness_bug.rs @@ -57,7 +57,7 @@ pub fn user2() -> &'static dyn Trait { fn main() { let p: *const dyn Trait = &(); let p = p as *const dyn Trait; // <- this is bad! - //~^ error: the trait bound `dyn Trait: Unsize>` is not satisfied + //~^ error: mismatched types let p = p as *const dyn Super; // <- this upcast accesses improper vtable entry // accessing from L__unnamed_2 the position for the 'Super vtable (pointer)', // thus reading 'null pointer for missing_method' diff --git a/tests/ui/traits/upcast_soundness_bug.stderr b/tests/ui/traits/upcast_soundness_bug.stderr index ef2aeb3b1ec71..5864abcdb41f5 100644 --- a/tests/ui/traits/upcast_soundness_bug.stderr +++ b/tests/ui/traits/upcast_soundness_bug.stderr @@ -1,11 +1,13 @@ -error[E0277]: the trait bound `dyn Trait: Unsize>` is not satisfied +error[E0308]: mismatched types --> $DIR/upcast_soundness_bug.rs:59:13 | LL | let p = p as *const dyn Trait; // <- this is bad! - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Unsize>` is not implemented for `dyn Trait` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `u8`, found `u16` | - = note: all implementations of `Unsize` are provided automatically by the compiler, see for more information + = note: expected trait object `dyn Trait` + found trait object `dyn Trait` + = help: `dyn Trait` 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 E0277`. +For more information about this error, try `rustc --explain E0308`. From fca286a39edc17480bce0ce9215a1eab349e9497 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Fri, 5 Jul 2024 20:38:16 +0000 Subject: [PATCH 755/892] Use verbose suggestion for `ptr::null_mut()` --- compiler/rustc_hir_typeck/src/errors.rs | 1 + tests/ui/typeck/ptr-null-mutability-suggestions.stderr | 10 ++++++---- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/errors.rs b/compiler/rustc_hir_typeck/src/errors.rs index e49b921e63cac..f1ed2ade3d44e 100644 --- a/compiler/rustc_hir_typeck/src/errors.rs +++ b/compiler/rustc_hir_typeck/src/errors.rs @@ -501,6 +501,7 @@ pub enum SuggestBoxing { #[suggestion( hir_typeck_suggest_ptr_null_mut, applicability = "maybe-incorrect", + style = "verbose", code = "core::ptr::null_mut()" )] pub struct SuggestPtrNullMut { diff --git a/tests/ui/typeck/ptr-null-mutability-suggestions.stderr b/tests/ui/typeck/ptr-null-mutability-suggestions.stderr index b615d9fb45cbe..2912977a461a3 100644 --- a/tests/ui/typeck/ptr-null-mutability-suggestions.stderr +++ b/tests/ui/typeck/ptr-null-mutability-suggestions.stderr @@ -2,10 +2,8 @@ error[E0308]: mismatched types --> $DIR/ptr-null-mutability-suggestions.rs:9:24 | LL | expecting_null_mut(ptr::null()); - | ------------------ ^^^^^^^^^^^ - | | | - | | types differ in mutability - | | help: consider using `core::ptr::null_mut` instead: `core::ptr::null_mut()` + | ------------------ ^^^^^^^^^^^ types differ in mutability + | | | arguments to this function are incorrect | = note: expected raw pointer `*mut u8` @@ -15,6 +13,10 @@ note: function defined here | LL | fn expecting_null_mut(_: *mut u8) {} | ^^^^^^^^^^^^^^^^^^ ---------- +help: consider using `core::ptr::null_mut` instead + | +LL | expecting_null_mut(core::ptr::null_mut()); + | ~~~~~~~~~~~~~~~~~~~~~ error: aborting due to 1 previous error From 27588d1de346b50831c62e78f43bf2b81afbf073 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 5 Jul 2024 16:39:24 -0400 Subject: [PATCH 756/892] Split SolverDelegate back out from InferCtxtLike --- Cargo.lock | 1 + compiler/rustc_infer/Cargo.toml | 1 + compiler/rustc_infer/src/infer/context.rs | 172 ++++++++++++++++++ compiler/rustc_infer/src/infer/mod.rs | 1 + .../src/canonicalizer.rs | 3 +- .../rustc_next_trait_solver/src/delegate.rs | 96 +--------- .../rustc_next_trait_solver/src/resolve.rs | 2 +- .../src/solve/eval_ctxt/canonical.rs | 2 +- .../src/solve/eval_ctxt/mod.rs | 2 +- .../src/solve/eval_ctxt/probe.rs | 2 +- .../src/solve/delegate.rs | 171 +---------------- compiler/rustc_type_ir/src/infer_ctxt.rs | 93 ++++++++++ compiler/rustc_type_ir/src/lib.rs | 2 + 13 files changed, 286 insertions(+), 262 deletions(-) create mode 100644 compiler/rustc_infer/src/infer/context.rs create mode 100644 compiler/rustc_type_ir/src/infer_ctxt.rs diff --git a/Cargo.lock b/Cargo.lock index fbe1abf2a3317..d1889fb6861ac 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4170,6 +4170,7 @@ dependencies = [ "rustc_middle", "rustc_span", "rustc_target", + "rustc_type_ir", "smallvec", "tracing", ] diff --git a/compiler/rustc_infer/Cargo.toml b/compiler/rustc_infer/Cargo.toml index c1565a7d40fd5..5136ab79a0f84 100644 --- a/compiler/rustc_infer/Cargo.toml +++ b/compiler/rustc_infer/Cargo.toml @@ -18,6 +18,7 @@ rustc_macros = { path = "../rustc_macros" } rustc_middle = { path = "../rustc_middle" } rustc_span = { path = "../rustc_span" } rustc_target = { path = "../rustc_target" } +rustc_type_ir = { path = "../rustc_type_ir" } smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } tracing = "0.1" # tidy-alphabetical-end diff --git a/compiler/rustc_infer/src/infer/context.rs b/compiler/rustc_infer/src/infer/context.rs new file mode 100644 index 0000000000000..209996b12e2ed --- /dev/null +++ b/compiler/rustc_infer/src/infer/context.rs @@ -0,0 +1,172 @@ +///! Definition of `InferCtxtLike` from the librarified type layer. +use rustc_hir::def_id::{DefId, LocalDefId}; +use rustc_middle::traits::solve::{Goal, NoSolution, SolverMode}; +use rustc_middle::traits::ObligationCause; +use rustc_middle::ty::fold::TypeFoldable; +use rustc_middle::ty::{self, Ty, TyCtxt}; +use rustc_span::DUMMY_SP; +use rustc_type_ir::relate::Relate; +use rustc_type_ir::InferCtxtLike; + +use super::{BoundRegionConversionTime, InferCtxt, SubregionOrigin}; + +impl<'tcx> InferCtxtLike for InferCtxt<'tcx> { + type Interner = TyCtxt<'tcx>; + + fn cx(&self) -> TyCtxt<'tcx> { + self.tcx + } + + fn solver_mode(&self) -> ty::solve::SolverMode { + match self.intercrate { + true => SolverMode::Coherence, + false => SolverMode::Normal, + } + } + + fn universe(&self) -> ty::UniverseIndex { + self.universe() + } + + fn create_next_universe(&self) -> ty::UniverseIndex { + self.create_next_universe() + } + + fn universe_of_ty(&self, vid: ty::TyVid) -> Option { + match self.probe_ty_var(vid) { + Err(universe) => Some(universe), + Ok(_) => None, + } + } + + fn universe_of_lt(&self, lt: ty::RegionVid) -> Option { + match self.inner.borrow_mut().unwrap_region_constraints().probe_value(lt) { + Err(universe) => Some(universe), + Ok(_) => None, + } + } + + fn universe_of_ct(&self, ct: ty::ConstVid) -> Option { + match self.probe_const_var(ct) { + Err(universe) => Some(universe), + Ok(_) => None, + } + } + + fn root_ty_var(&self, var: ty::TyVid) -> ty::TyVid { + self.root_var(var) + } + + fn root_const_var(&self, var: ty::ConstVid) -> ty::ConstVid { + self.root_const_var(var) + } + + fn opportunistic_resolve_ty_var(&self, vid: ty::TyVid) -> Ty<'tcx> { + match self.probe_ty_var(vid) { + Ok(ty) => ty, + Err(_) => Ty::new_var(self.tcx, self.root_var(vid)), + } + } + + fn opportunistic_resolve_int_var(&self, vid: ty::IntVid) -> Ty<'tcx> { + self.opportunistic_resolve_int_var(vid) + } + + fn opportunistic_resolve_float_var(&self, vid: ty::FloatVid) -> Ty<'tcx> { + self.opportunistic_resolve_float_var(vid) + } + + fn opportunistic_resolve_ct_var(&self, vid: ty::ConstVid) -> ty::Const<'tcx> { + match self.probe_const_var(vid) { + Ok(ct) => ct, + Err(_) => ty::Const::new_var(self.tcx, self.root_const_var(vid)), + } + } + + fn opportunistic_resolve_effect_var(&self, vid: ty::EffectVid) -> ty::Const<'tcx> { + match self.probe_effect_var(vid) { + Some(ct) => ct, + None => { + ty::Const::new_infer(self.tcx, ty::InferConst::EffectVar(self.root_effect_var(vid))) + } + } + } + + fn opportunistic_resolve_lt_var(&self, vid: ty::RegionVid) -> ty::Region<'tcx> { + self.inner.borrow_mut().unwrap_region_constraints().opportunistic_resolve_var(self.tcx, vid) + } + + fn defining_opaque_types(&self) -> &'tcx ty::List { + self.defining_opaque_types() + } + + fn next_ty_infer(&self) -> Ty<'tcx> { + self.next_ty_var(DUMMY_SP) + } + + fn next_const_infer(&self) -> ty::Const<'tcx> { + self.next_const_var(DUMMY_SP) + } + + fn fresh_args_for_item(&self, def_id: DefId) -> ty::GenericArgsRef<'tcx> { + self.fresh_args_for_item(DUMMY_SP, def_id) + } + + fn instantiate_binder_with_infer> + Copy>( + &self, + value: ty::Binder<'tcx, T>, + ) -> T { + self.instantiate_binder_with_fresh_vars( + DUMMY_SP, + BoundRegionConversionTime::HigherRankedType, + value, + ) + } + + fn enter_forall> + Copy, U>( + &self, + value: ty::Binder<'tcx, T>, + f: impl FnOnce(T) -> U, + ) -> U { + self.enter_forall(value, f) + } + + fn relate>>( + &self, + param_env: ty::ParamEnv<'tcx>, + lhs: T, + variance: ty::Variance, + rhs: T, + ) -> Result>>, NoSolution> { + self.at(&ObligationCause::dummy(), param_env).relate_no_trace(lhs, variance, rhs) + } + + fn eq_structurally_relating_aliases>>( + &self, + param_env: ty::ParamEnv<'tcx>, + lhs: T, + rhs: T, + ) -> Result>>, NoSolution> { + self.at(&ObligationCause::dummy(), param_env) + .eq_structurally_relating_aliases_no_trace(lhs, rhs) + } + + fn resolve_vars_if_possible(&self, value: T) -> T + where + T: TypeFoldable>, + { + self.resolve_vars_if_possible(value) + } + + fn probe(&self, probe: impl FnOnce() -> T) -> T { + self.probe(|_| probe()) + } + + fn sub_regions(&self, sub: ty::Region<'tcx>, sup: ty::Region<'tcx>) { + self.sub_regions(SubregionOrigin::RelateRegionParamBound(DUMMY_SP), sub, sup) + } + + fn register_ty_outlives(&self, ty: Ty<'tcx>, r: ty::Region<'tcx>) { + self.register_region_obligation_with_cause(ty, r, &ObligationCause::dummy()); + } +} diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index ff593d7ffb7df..edbb741036f07 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -53,6 +53,7 @@ use type_variable::TypeVariableOrigin; pub mod at; pub mod canonical; +mod context; pub mod error_reporting; pub mod free_regions; mod freshen; diff --git a/compiler/rustc_next_trait_solver/src/canonicalizer.rs b/compiler/rustc_next_trait_solver/src/canonicalizer.rs index 695d02705abd2..82488088e30e6 100644 --- a/compiler/rustc_next_trait_solver/src/canonicalizer.rs +++ b/compiler/rustc_next_trait_solver/src/canonicalizer.rs @@ -4,7 +4,8 @@ use rustc_type_ir::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable}; use rustc_type_ir::inherent::*; use rustc_type_ir::visit::TypeVisitableExt; use rustc_type_ir::{ - self as ty, Canonical, CanonicalTyVarKind, CanonicalVarInfo, CanonicalVarKind, Interner, + self as ty, Canonical, CanonicalTyVarKind, CanonicalVarInfo, CanonicalVarKind, InferCtxtLike, + Interner, }; use crate::delegate::SolverDelegate; diff --git a/compiler/rustc_next_trait_solver/src/delegate.rs b/compiler/rustc_next_trait_solver/src/delegate.rs index 6626acfe9639e..31032dc679ac3 100644 --- a/compiler/rustc_next_trait_solver/src/delegate.rs +++ b/compiler/rustc_next_trait_solver/src/delegate.rs @@ -1,18 +1,20 @@ use std::fmt::Debug; +use std::ops::Deref; use rustc_type_ir::fold::TypeFoldable; -use rustc_type_ir::relate::Relate; use rustc_type_ir::solve::{Certainty, Goal, NoSolution, SolverMode}; -use rustc_type_ir::{self as ty, Interner}; +use rustc_type_ir::{self as ty, InferCtxtLike, Interner}; -pub trait SolverDelegate: Sized { +pub trait SolverDelegate: + Deref::Interner>> + Sized +{ type Interner: Interner; - fn cx(&self) -> Self::Interner; + fn cx(&self) -> Self::Interner { + (**self).cx() + } type Span: Copy; - fn solver_mode(&self) -> SolverMode; - fn build_with_canonical( cx: Self::Interner, solver_mode: SolverMode, @@ -21,82 +23,12 @@ pub trait SolverDelegate: Sized { where V: TypeFoldable; - fn universe(&self) -> ty::UniverseIndex; - fn create_next_universe(&self) -> ty::UniverseIndex; - - fn universe_of_ty(&self, ty: ty::TyVid) -> Option; - fn universe_of_lt(&self, lt: ty::RegionVid) -> Option; - fn universe_of_ct(&self, ct: ty::ConstVid) -> Option; - - fn root_ty_var(&self, var: ty::TyVid) -> ty::TyVid; - fn root_const_var(&self, var: ty::ConstVid) -> ty::ConstVid; - - fn opportunistic_resolve_ty_var(&self, vid: ty::TyVid) -> ::Ty; - fn opportunistic_resolve_int_var(&self, vid: ty::IntVid) -> ::Ty; - fn opportunistic_resolve_float_var( - &self, - vid: ty::FloatVid, - ) -> ::Ty; - fn opportunistic_resolve_ct_var( - &self, - vid: ty::ConstVid, - ) -> ::Const; - fn opportunistic_resolve_effect_var( - &self, - vid: ty::EffectVid, - ) -> ::Const; - fn opportunistic_resolve_lt_var( - &self, - vid: ty::RegionVid, - ) -> ::Region; - - fn defining_opaque_types(&self) -> ::DefiningOpaqueTypes; - - fn next_ty_infer(&self) -> ::Ty; - fn next_const_infer(&self) -> ::Const; - fn fresh_args_for_item( - &self, - def_id: ::DefId, - ) -> ::GenericArgs; - fn fresh_var_for_kind_with_span( &self, arg: ::GenericArg, span: Self::Span, ) -> ::GenericArg; - fn instantiate_binder_with_infer + Copy>( - &self, - value: ty::Binder, - ) -> T; - - fn enter_forall + Copy, U>( - &self, - value: ty::Binder, - f: impl FnOnce(T) -> U, - ) -> U; - - fn relate>( - &self, - param_env: ::ParamEnv, - lhs: T, - variance: ty::Variance, - rhs: T, - ) -> Result::Predicate>>, NoSolution>; - - fn eq_structurally_relating_aliases>( - &self, - param_env: ::ParamEnv, - lhs: T, - rhs: T, - ) -> Result::Predicate>>, NoSolution>; - - fn resolve_vars_if_possible(&self, value: T) -> T - where - T: TypeFoldable; - - fn probe(&self, probe: impl FnOnce() -> T) -> T; - // FIXME: Uplift the leak check into this crate. fn leak_check(&self, max_input_universe: ty::UniverseIndex) -> Result<(), NoSolution>; @@ -112,18 +44,6 @@ pub trait SolverDelegate: Sized { unevaluated: ty::UnevaluatedConst, ) -> Option<::Const>; - fn sub_regions( - &self, - sub: ::Region, - sup: ::Region, - ); - - fn register_ty_outlives( - &self, - ty: ::Ty, - r: ::Region, - ); - // FIXME: This only is here because `wf::obligations` is in `rustc_trait_selection`! fn well_formed_goals( &self, diff --git a/compiler/rustc_next_trait_solver/src/resolve.rs b/compiler/rustc_next_trait_solver/src/resolve.rs index 6ed58d0e4fb66..254ee514f8bde 100644 --- a/compiler/rustc_next_trait_solver/src/resolve.rs +++ b/compiler/rustc_next_trait_solver/src/resolve.rs @@ -2,7 +2,7 @@ use crate::delegate::SolverDelegate; use rustc_type_ir::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable}; use rustc_type_ir::inherent::*; use rustc_type_ir::visit::TypeVisitableExt; -use rustc_type_ir::{self as ty, Interner}; +use rustc_type_ir::{self as ty, InferCtxtLike, Interner}; /////////////////////////////////////////////////////////////////////////// // EAGER RESOLUTION diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs index 0a313c6a95133..9474d501d6ff0 100644 --- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs +++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs @@ -14,7 +14,7 @@ use std::iter; use rustc_index::IndexVec; use rustc_type_ir::fold::TypeFoldable; use rustc_type_ir::inherent::*; -use rustc_type_ir::{self as ty, Canonical, CanonicalVarValues, Interner}; +use rustc_type_ir::{self as ty, Canonical, CanonicalVarValues, InferCtxtLike, Interner}; use tracing::{instrument, trace}; use crate::canonicalizer::{CanonicalizeMode, Canonicalizer}; diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs index 87342eefb33e5..d8a3acc655a45 100644 --- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs @@ -7,7 +7,7 @@ use rustc_type_ir::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable}; use rustc_type_ir::inherent::*; use rustc_type_ir::relate::Relate; use rustc_type_ir::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor}; -use rustc_type_ir::{self as ty, CanonicalVarValues, Interner}; +use rustc_type_ir::{self as ty, CanonicalVarValues, InferCtxtLike, Interner}; use rustc_type_ir_macros::{Lift_Generic, TypeFoldable_Generic, TypeVisitable_Generic}; use tracing::{instrument, trace}; diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/probe.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/probe.rs index e9516c60c70f9..4258dd9263a4e 100644 --- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/probe.rs +++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/probe.rs @@ -1,6 +1,6 @@ use std::marker::PhantomData; -use rustc_type_ir::Interner; +use rustc_type_ir::{InferCtxtLike, Interner}; use tracing::instrument; use crate::delegate::SolverDelegate; diff --git a/compiler/rustc_trait_selection/src/solve/delegate.rs b/compiler/rustc_trait_selection/src/solve/delegate.rs index 643d5f804808a..f98744e906f05 100644 --- a/compiler/rustc_trait_selection/src/solve/delegate.rs +++ b/compiler/rustc_trait_selection/src/solve/delegate.rs @@ -1,21 +1,18 @@ use std::ops::Deref; use rustc_data_structures::fx::FxHashSet; -use rustc_hir::def_id::{DefId, LocalDefId}; +use rustc_hir::def_id::DefId; use rustc_infer::infer::canonical::query_response::make_query_region_constraints; use rustc_infer::infer::canonical::{ Canonical, CanonicalExt as _, CanonicalVarInfo, CanonicalVarValues, }; -use rustc_infer::infer::{ - BoundRegionConversionTime, InferCtxt, RegionVariableOrigin, SubregionOrigin, TyCtxtInferExt, -}; +use rustc_infer::infer::{InferCtxt, RegionVariableOrigin, TyCtxtInferExt}; use rustc_infer::traits::solve::Goal; use rustc_infer::traits::util::supertraits; use rustc_infer::traits::{ObligationCause, Reveal}; use rustc_middle::ty::fold::TypeFoldable; use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt as _}; use rustc_span::{ErrorGuaranteed, Span, DUMMY_SP}; -use rustc_type_ir::relate::Relate; use rustc_type_ir::solve::{Certainty, NoSolution, SolverMode}; use crate::traits::coherence::trait_ref_is_knowable; @@ -48,13 +45,6 @@ impl<'tcx> rustc_next_trait_solver::delegate::SolverDelegate for SolverDelegate< type Span = Span; - fn solver_mode(&self) -> ty::solve::SolverMode { - match self.intercrate { - true => SolverMode::Coherence, - false => SolverMode::Normal, - } - } - fn build_with_canonical( interner: TyCtxt<'tcx>, solver_mode: SolverMode, @@ -74,104 +64,6 @@ impl<'tcx> rustc_next_trait_solver::delegate::SolverDelegate for SolverDelegate< (SolverDelegate(infcx), value, vars) } - fn universe(&self) -> ty::UniverseIndex { - self.0.universe() - } - - fn create_next_universe(&self) -> ty::UniverseIndex { - self.0.create_next_universe() - } - - fn universe_of_ty(&self, vid: ty::TyVid) -> Option { - // FIXME(BoxyUwU): this is kind of jank and means that printing unresolved - // ty infers will give you the universe of the var it resolved to not the universe - // it actually had. It also means that if you have a `?0.1` and infer it to `u8` then - // try to print out `?0.1` it will just print `?0`. - match self.0.probe_ty_var(vid) { - Err(universe) => Some(universe), - Ok(_) => None, - } - } - - fn universe_of_lt(&self, lt: ty::RegionVid) -> Option { - match self.0.inner.borrow_mut().unwrap_region_constraints().probe_value(lt) { - Err(universe) => Some(universe), - Ok(_) => None, - } - } - - fn universe_of_ct(&self, ct: ty::ConstVid) -> Option { - // Same issue as with `universe_of_ty` - match self.0.probe_const_var(ct) { - Err(universe) => Some(universe), - Ok(_) => None, - } - } - - fn root_ty_var(&self, var: ty::TyVid) -> ty::TyVid { - self.0.root_var(var) - } - - fn root_const_var(&self, var: ty::ConstVid) -> ty::ConstVid { - self.0.root_const_var(var) - } - - fn opportunistic_resolve_ty_var(&self, vid: ty::TyVid) -> Ty<'tcx> { - match self.0.probe_ty_var(vid) { - Ok(ty) => ty, - Err(_) => Ty::new_var(self.0.tcx, self.0.root_var(vid)), - } - } - - fn opportunistic_resolve_int_var(&self, vid: ty::IntVid) -> Ty<'tcx> { - self.0.opportunistic_resolve_int_var(vid) - } - - fn opportunistic_resolve_float_var(&self, vid: ty::FloatVid) -> Ty<'tcx> { - self.0.opportunistic_resolve_float_var(vid) - } - - fn opportunistic_resolve_ct_var(&self, vid: ty::ConstVid) -> ty::Const<'tcx> { - match self.0.probe_const_var(vid) { - Ok(ct) => ct, - Err(_) => ty::Const::new_var(self.0.tcx, self.0.root_const_var(vid)), - } - } - - fn opportunistic_resolve_effect_var(&self, vid: ty::EffectVid) -> ty::Const<'tcx> { - match self.0.probe_effect_var(vid) { - Some(ct) => ct, - None => ty::Const::new_infer( - self.0.tcx, - ty::InferConst::EffectVar(self.0.root_effect_var(vid)), - ), - } - } - - fn opportunistic_resolve_lt_var(&self, vid: ty::RegionVid) -> ty::Region<'tcx> { - self.0 - .inner - .borrow_mut() - .unwrap_region_constraints() - .opportunistic_resolve_var(self.0.tcx, vid) - } - - fn defining_opaque_types(&self) -> &'tcx ty::List { - self.0.defining_opaque_types() - } - - fn next_ty_infer(&self) -> Ty<'tcx> { - self.0.next_ty_var(DUMMY_SP) - } - - fn next_const_infer(&self) -> ty::Const<'tcx> { - self.0.next_const_var(DUMMY_SP) - } - - fn fresh_args_for_item(&self, def_id: DefId) -> ty::GenericArgsRef<'tcx> { - self.0.fresh_args_for_item(DUMMY_SP, def_id) - } - fn fresh_var_for_kind_with_span( &self, arg: ty::GenericArg<'tcx>, @@ -186,57 +78,6 @@ impl<'tcx> rustc_next_trait_solver::delegate::SolverDelegate for SolverDelegate< } } - fn instantiate_binder_with_infer> + Copy>( - &self, - value: ty::Binder<'tcx, T>, - ) -> T { - self.0.instantiate_binder_with_fresh_vars( - DUMMY_SP, - BoundRegionConversionTime::HigherRankedType, - value, - ) - } - - fn enter_forall> + Copy, U>( - &self, - value: ty::Binder<'tcx, T>, - f: impl FnOnce(T) -> U, - ) -> U { - self.0.enter_forall(value, f) - } - - fn relate>>( - &self, - param_env: ty::ParamEnv<'tcx>, - lhs: T, - variance: ty::Variance, - rhs: T, - ) -> Result>>, NoSolution> { - self.0.at(&ObligationCause::dummy(), param_env).relate_no_trace(lhs, variance, rhs) - } - - fn eq_structurally_relating_aliases>>( - &self, - param_env: ty::ParamEnv<'tcx>, - lhs: T, - rhs: T, - ) -> Result>>, NoSolution> { - self.0 - .at(&ObligationCause::dummy(), param_env) - .eq_structurally_relating_aliases_no_trace(lhs, rhs) - } - - fn resolve_vars_if_possible(&self, value: T) -> T - where - T: TypeFoldable>, - { - self.0.resolve_vars_if_possible(value) - } - - fn probe(&self, probe: impl FnOnce() -> T) -> T { - self.0.probe(|_| probe()) - } - fn leak_check(&self, max_input_universe: ty::UniverseIndex) -> Result<(), NoSolution> { self.0.leak_check(max_input_universe, None).map_err(|_| NoSolution) } @@ -265,14 +106,6 @@ impl<'tcx> rustc_next_trait_solver::delegate::SolverDelegate for SolverDelegate< } } - fn sub_regions(&self, sub: ty::Region<'tcx>, sup: ty::Region<'tcx>) { - self.0.sub_regions(SubregionOrigin::RelateRegionParamBound(DUMMY_SP), sub, sup) - } - - fn register_ty_outlives(&self, ty: Ty<'tcx>, r: ty::Region<'tcx>) { - self.0.register_region_obligation_with_cause(ty, r, &ObligationCause::dummy()); - } - fn well_formed_goals( &self, param_env: ty::ParamEnv<'tcx>, diff --git a/compiler/rustc_type_ir/src/infer_ctxt.rs b/compiler/rustc_type_ir/src/infer_ctxt.rs new file mode 100644 index 0000000000000..2c80ee0a73d4a --- /dev/null +++ b/compiler/rustc_type_ir/src/infer_ctxt.rs @@ -0,0 +1,93 @@ +use crate::fold::TypeFoldable; +use crate::relate::Relate; +use crate::solve::{Goal, NoSolution, SolverMode}; +use crate::{self as ty, Interner}; + +pub trait InferCtxtLike { + type Interner: Interner; + fn cx(&self) -> Self::Interner; + + fn solver_mode(&self) -> SolverMode; + + fn universe(&self) -> ty::UniverseIndex; + fn create_next_universe(&self) -> ty::UniverseIndex; + + fn universe_of_ty(&self, ty: ty::TyVid) -> Option; + fn universe_of_lt(&self, lt: ty::RegionVid) -> Option; + fn universe_of_ct(&self, ct: ty::ConstVid) -> Option; + + fn root_ty_var(&self, var: ty::TyVid) -> ty::TyVid; + fn root_const_var(&self, var: ty::ConstVid) -> ty::ConstVid; + + fn opportunistic_resolve_ty_var(&self, vid: ty::TyVid) -> ::Ty; + fn opportunistic_resolve_int_var(&self, vid: ty::IntVid) -> ::Ty; + fn opportunistic_resolve_float_var( + &self, + vid: ty::FloatVid, + ) -> ::Ty; + fn opportunistic_resolve_ct_var( + &self, + vid: ty::ConstVid, + ) -> ::Const; + fn opportunistic_resolve_effect_var( + &self, + vid: ty::EffectVid, + ) -> ::Const; + fn opportunistic_resolve_lt_var( + &self, + vid: ty::RegionVid, + ) -> ::Region; + + fn defining_opaque_types(&self) -> ::DefiningOpaqueTypes; + + fn next_ty_infer(&self) -> ::Ty; + fn next_const_infer(&self) -> ::Const; + fn fresh_args_for_item( + &self, + def_id: ::DefId, + ) -> ::GenericArgs; + + fn instantiate_binder_with_infer + Copy>( + &self, + value: ty::Binder, + ) -> T; + + fn enter_forall + Copy, U>( + &self, + value: ty::Binder, + f: impl FnOnce(T) -> U, + ) -> U; + + fn relate>( + &self, + param_env: ::ParamEnv, + lhs: T, + variance: ty::Variance, + rhs: T, + ) -> Result::Predicate>>, NoSolution>; + + fn eq_structurally_relating_aliases>( + &self, + param_env: ::ParamEnv, + lhs: T, + rhs: T, + ) -> Result::Predicate>>, NoSolution>; + + fn resolve_vars_if_possible(&self, value: T) -> T + where + T: TypeFoldable; + + fn probe(&self, probe: impl FnOnce() -> T) -> T; + + fn sub_regions( + &self, + sub: ::Region, + sup: ::Region, + ); + + fn register_ty_outlives( + &self, + ty: ::Ty, + r: ::Region, + ); +} diff --git a/compiler/rustc_type_ir/src/lib.rs b/compiler/rustc_type_ir/src/lib.rs index fedc8959cf715..c57ac74cdfdc7 100644 --- a/compiler/rustc_type_ir/src/lib.rs +++ b/compiler/rustc_type_ir/src/lib.rs @@ -39,6 +39,7 @@ mod const_kind; mod effects; mod flags; mod generic_arg; +mod infer_ctxt; mod interner; mod opaque_ty; mod predicate; @@ -56,6 +57,7 @@ pub use const_kind::*; pub use effects::*; pub use flags::*; pub use generic_arg::*; +pub use infer_ctxt::*; pub use interner::*; pub use opaque_ty::*; pub use predicate::*; From 75692056e1ab8ca8a5e0c8e2def4cabcf2f3b445 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Fri, 5 Jul 2024 20:58:33 +0000 Subject: [PATCH 757/892] Use verbose suggestion for changing arg type --- .../src/check/compare_impl_item.rs | 6 ++-- .../defaults-specialization.stderr | 18 +++++----- tests/ui/compare-method/bad-self-type.stderr | 18 +++++----- tests/ui/compare-method/issue-90444.stderr | 18 +++++----- .../reordered-type-param.stderr | 10 +++--- ...-gate-unboxed-closures-manual-impls.stderr | 18 +++++----- .../impl-generic-mismatch-ab.stderr | 10 +++--- .../in-assoc-type-unconstrained.stderr | 9 ++--- .../method-signature-matches.lt.stderr | 10 +++--- .../method-signature-matches.mismatch.stderr | 9 ++--- ...od-signature-matches.mismatch_async.stderr | 9 ++--- .../opaque-and-lifetime-mismatch.stderr | 9 ++--- .../in-trait/specialization-broken.stderr | 9 ++--- ...s-impl-trait-declaration-too-subtle.stderr | 18 +++++----- tests/ui/impl-trait/trait_type.stderr | 9 ++--- tests/ui/impl-trait/where-allowed.stderr | 9 ++--- tests/ui/issues/issue-20225.stderr | 27 +++++++------- tests/ui/issues/issue-21332.stderr | 9 ++--- tests/ui/mismatched_types/E0053.stderr | 18 +++++----- tests/ui/mismatched_types/issue-112036.stderr | 9 ++--- tests/ui/mismatched_types/issue-13033.stderr | 9 ++--- .../trait-impl-fn-incompatibility.stderr | 18 +++++----- tests/ui/traits/issue-35869.stderr | 36 ++++++++++--------- .../traits/wrong-mul-method-signature.stderr | 27 +++++++------- .../unnameable_type.stderr | 9 ++--- .../typeck/mismatched-map-under-self.stderr | 9 ++--- tests/ui/ufcs/ufcs-explicit-self-bad.stderr | 9 ++--- 27 files changed, 206 insertions(+), 163 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 b5b68471b9d16..0dbe64c3ea7f7 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -981,7 +981,7 @@ fn report_trait_method_mismatch<'tcx>( .next() .unwrap_or(impl_err_span); - diag.span_suggestion( + diag.span_suggestion_verbose( span, "change the self-receiver type to match the trait", sugg, @@ -1005,12 +1005,12 @@ fn report_trait_method_mismatch<'tcx>( } hir::FnRetTy::Return(hir_ty) => { let sugg = trait_sig.output(); - diag.span_suggestion(hir_ty.span, msg, sugg, ap); + diag.span_suggestion_verbose(hir_ty.span, msg, sugg, ap); } }; }; } else if let Some(trait_ty) = trait_sig.inputs().get(*i) { - diag.span_suggestion( + diag.span_suggestion_verbose( impl_err_span, "change the parameter type to match the trait", trait_ty, diff --git a/tests/ui/associated-types/defaults-specialization.stderr b/tests/ui/associated-types/defaults-specialization.stderr index 7ef433d859fa4..b4ed99f36f44a 100644 --- a/tests/ui/associated-types/defaults-specialization.stderr +++ b/tests/ui/associated-types/defaults-specialization.stderr @@ -12,10 +12,7 @@ error[E0053]: method `make` has an incompatible type for trait --> $DIR/defaults-specialization.rs:19:18 | LL | fn make() -> u8 { 0 } - | ^^ - | | - | expected associated type, found `u8` - | help: change the output type to match the trait: ` as Tr>::Ty` + | ^^ expected associated type, found `u8` | note: type in trait --> $DIR/defaults-specialization.rs:9:18 @@ -24,6 +21,10 @@ LL | fn make() -> Self::Ty { | ^^^^^^^^ = note: expected signature `fn() -> as Tr>::Ty` found signature `fn() -> u8` +help: change the output type to match the trait + | +LL | fn make() -> as Tr>::Ty { 0 } + | ~~~~~~~~~~~~~~~~ error[E0053]: method `make` has an incompatible type for trait --> $DIR/defaults-specialization.rs:35:18 @@ -32,10 +33,7 @@ LL | default type Ty = bool; | ----------------------- associated type is `default` and may be overridden LL | LL | fn make() -> bool { true } - | ^^^^ - | | - | expected associated type, found `bool` - | help: change the output type to match the trait: ` as Tr>::Ty` + | ^^^^ expected associated type, found `bool` | note: type in trait --> $DIR/defaults-specialization.rs:9:18 @@ -44,6 +42,10 @@ LL | fn make() -> Self::Ty { | ^^^^^^^^ = note: expected signature `fn() -> as Tr>::Ty` found signature `fn() -> bool` +help: change the output type to match the trait + | +LL | fn make() -> as Tr>::Ty { true } + | ~~~~~~~~~~~~~~~~ error[E0308]: mismatched types --> $DIR/defaults-specialization.rs:10:9 diff --git a/tests/ui/compare-method/bad-self-type.stderr b/tests/ui/compare-method/bad-self-type.stderr index a87b713c2b4bd..29ebbc5dffb11 100644 --- a/tests/ui/compare-method/bad-self-type.stderr +++ b/tests/ui/compare-method/bad-self-type.stderr @@ -2,22 +2,20 @@ error[E0053]: method `poll` has an incompatible type for trait --> $DIR/bad-self-type.rs:10:13 | LL | fn poll(self, _: &mut Context<'_>) -> Poll<()> { - | ^^^^ - | | - | expected `Pin<&mut MyFuture>`, found `MyFuture` - | help: change the self-receiver type to match the trait: `self: Pin<&mut MyFuture>` + | ^^^^ expected `Pin<&mut MyFuture>`, found `MyFuture` | = note: expected signature `fn(Pin<&mut MyFuture>, &mut Context<'_>) -> Poll<_>` found signature `fn(MyFuture, &mut Context<'_>) -> Poll<_>` +help: change the self-receiver type to match the trait + | +LL | fn poll(self: Pin<&mut MyFuture>, _: &mut Context<'_>) -> Poll<()> { + | ~~~~~~~~~~~~~~~~~~~~~~~~ error[E0053]: method `foo` has an incompatible type for trait --> $DIR/bad-self-type.rs:22:18 | LL | fn foo(self: Box) {} - | ------^^^^^^^^^ - | | | - | | expected `MyFuture`, found `Box` - | help: change the self-receiver type to match the trait: `self` + | ^^^^^^^^^ expected `MyFuture`, found `Box` | note: type in trait --> $DIR/bad-self-type.rs:17:12 @@ -26,6 +24,10 @@ LL | fn foo(self); | ^^^^ = note: expected signature `fn(MyFuture)` found signature `fn(Box)` +help: change the self-receiver type to match the trait + | +LL | fn foo(self) {} + | ~~~~ error[E0053]: method `bar` has an incompatible type for trait --> $DIR/bad-self-type.rs:24:17 diff --git a/tests/ui/compare-method/issue-90444.stderr b/tests/ui/compare-method/issue-90444.stderr index 52e23d03b148b..f05c9939c0096 100644 --- a/tests/ui/compare-method/issue-90444.stderr +++ b/tests/ui/compare-method/issue-90444.stderr @@ -2,25 +2,27 @@ error[E0053]: method `from` has an incompatible type for trait --> $DIR/issue-90444.rs:3:16 | LL | fn from(_: fn((), (), &mut ())) -> Self { - | ^^^^^^^^^^^^^^^^^^^ - | | - | types differ in mutability - | help: change the parameter type to match the trait: `for<'a> fn((), (), &'a ())` + | ^^^^^^^^^^^^^^^^^^^ types differ in mutability | = note: expected signature `fn(for<'a> fn((), (), &'a ())) -> A` found signature `fn(for<'a> fn((), (), &'a mut ())) -> A` +help: change the parameter type to match the trait + | +LL | fn from(_: for<'a> fn((), (), &'a ())) -> Self { + | ~~~~~~~~~~~~~~~~~~~~~~~~~~ error[E0053]: method `from` has an incompatible type for trait --> $DIR/issue-90444.rs:11:16 | LL | fn from(_: fn((), (), u64)) -> Self { - | ^^^^^^^^^^^^^^^ - | | - | expected `u32`, found `u64` - | help: change the parameter type to match the trait: `fn((), (), u32)` + | ^^^^^^^^^^^^^^^ expected `u32`, found `u64` | = note: expected signature `fn(fn((), (), u32)) -> B` found signature `fn(fn((), (), u64)) -> B` +help: change the parameter type to match the trait + | +LL | fn from(_: fn((), (), u32)) -> Self { + | ~~~~~~~~~~~~~~~ error: aborting due to 2 previous errors diff --git a/tests/ui/compare-method/reordered-type-param.stderr b/tests/ui/compare-method/reordered-type-param.stderr index 8a439acee13de..1e8266e213d7f 100644 --- a/tests/ui/compare-method/reordered-type-param.stderr +++ b/tests/ui/compare-method/reordered-type-param.stderr @@ -2,10 +2,8 @@ error[E0053]: method `b` has an incompatible type for trait --> $DIR/reordered-type-param.rs:16:30 | LL | fn b(&self, _x: G) -> G { panic!() } - | - - ^ - | | | | - | | | expected type parameter `F`, found type parameter `G` - | | | help: change the parameter type to match the trait: `F` + | - - ^ expected type parameter `F`, found type parameter `G` + | | | | | found type parameter | expected type parameter | @@ -18,6 +16,10 @@ LL | fn b(&self, x: C) -> C; found signature `fn(&E, G) -> G` = note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters +help: change the parameter type to match the trait + | +LL | fn b(&self, _x: F) -> G { panic!() } + | ~ error: aborting due to 1 previous error diff --git a/tests/ui/feature-gates/feature-gate-unboxed-closures-manual-impls.stderr b/tests/ui/feature-gates/feature-gate-unboxed-closures-manual-impls.stderr index 1b9febd431d6f..06a606b09dc97 100644 --- a/tests/ui/feature-gates/feature-gate-unboxed-closures-manual-impls.stderr +++ b/tests/ui/feature-gates/feature-gate-unboxed-closures-manual-impls.stderr @@ -89,13 +89,14 @@ error[E0053]: method `call` has an incompatible type for trait --> $DIR/feature-gate-unboxed-closures-manual-impls.rs:13:32 | LL | extern "rust-call" fn call(self, args: ()) -> () {} - | ^^^^ - | | - | expected `&Foo`, found `Foo` - | help: change the self-receiver type to match the trait: `&self` + | ^^^^ expected `&Foo`, found `Foo` | = note: expected signature `extern "rust-call" fn(&Foo, ()) -> _` found signature `extern "rust-call" fn(Foo, ())` +help: change the self-receiver type to match the trait + | +LL | extern "rust-call" fn call(&self, args: ()) -> () {} + | ~~~~~ error[E0183]: manual implementations of `FnOnce` are experimental --> $DIR/feature-gate-unboxed-closures-manual-impls.rs:18:6 @@ -158,13 +159,14 @@ error[E0053]: method `call_mut` has an incompatible type for trait --> $DIR/feature-gate-unboxed-closures-manual-impls.rs:30:36 | LL | extern "rust-call" fn call_mut(&self, args: ()) -> () {} - | ^^^^^ - | | - | types differ in mutability - | help: change the self-receiver type to match the trait: `&mut self` + | ^^^^^ types differ in mutability | = note: expected signature `extern "rust-call" fn(&mut Bar, ()) -> _` found signature `extern "rust-call" fn(&Bar, ())` +help: change the self-receiver type to match the trait + | +LL | extern "rust-call" fn call_mut(&mut self, args: ()) -> () {} + | ~~~~~~~~~ error[E0046]: not all trait items implemented, missing: `Output` --> $DIR/feature-gate-unboxed-closures-manual-impls.rs:35:1 diff --git a/tests/ui/impl-trait/impl-generic-mismatch-ab.stderr b/tests/ui/impl-trait/impl-generic-mismatch-ab.stderr index 7046e729e1834..90c31c9e3fc19 100644 --- a/tests/ui/impl-trait/impl-generic-mismatch-ab.stderr +++ b/tests/ui/impl-trait/impl-generic-mismatch-ab.stderr @@ -2,10 +2,8 @@ error[E0053]: method `foo` has an incompatible type for trait --> $DIR/impl-generic-mismatch-ab.rs:8:32 | LL | fn foo(&self, a: &impl Debug, b: &B) { } - | - ^^^^^^^^^^^ - | | | - | | expected type parameter `B`, found type parameter `impl Debug` - | | help: change the parameter type to match the trait: `&B` + | - ^^^^^^^^^^^ expected type parameter `B`, found type parameter `impl Debug` + | | | expected type parameter | note: type in trait @@ -17,6 +15,10 @@ LL | fn foo(&self, a: &A, b: &impl Debug); found signature `fn(&(), &impl Debug, &B)` = note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters +help: change the parameter type to match the trait + | +LL | fn foo(&self, a: &B, b: &B) { } + | ~~ error: aborting due to 1 previous error diff --git a/tests/ui/impl-trait/in-assoc-type-unconstrained.stderr b/tests/ui/impl-trait/in-assoc-type-unconstrained.stderr index 8e61a65abe4be..e32c59a75c699 100644 --- a/tests/ui/impl-trait/in-assoc-type-unconstrained.stderr +++ b/tests/ui/impl-trait/in-assoc-type-unconstrained.stderr @@ -27,10 +27,7 @@ LL | type Ty = impl Sized; | ---------- the expected opaque type LL | LL | fn method() -> () {} - | ^^ - | | - | expected opaque type, found `()` - | help: change the output type to match the trait: `<() as compare_method::Trait>::Ty` + | ^^ expected opaque type, found `()` | note: type in trait --> $DIR/in-assoc-type-unconstrained.rs:17:24 @@ -44,6 +41,10 @@ note: this item must have the opaque type in its signature in order to be able t | LL | fn method() -> () {} | ^^^^^^ +help: change the output type to match the trait + | +LL | fn method() -> <() as compare_method::Trait>::Ty {} + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: unconstrained opaque type --> $DIR/in-assoc-type-unconstrained.rs:20:19 diff --git a/tests/ui/impl-trait/in-trait/method-signature-matches.lt.stderr b/tests/ui/impl-trait/in-trait/method-signature-matches.lt.stderr index 2231205327cb0..6f6b787b6fe1b 100644 --- a/tests/ui/impl-trait/in-trait/method-signature-matches.lt.stderr +++ b/tests/ui/impl-trait/in-trait/method-signature-matches.lt.stderr @@ -2,10 +2,8 @@ error[E0053]: method `early` has an incompatible type for trait --> $DIR/method-signature-matches.rs:55:27 | LL | fn early<'late, T>(_: &'late ()) {} - | - ^^^^^^^^^ - | | | - | | expected type parameter `T`, found `()` - | | help: change the parameter type to match the trait: `&T` + | - ^^^^^^^^^ expected type parameter `T`, found `()` + | | | expected this type parameter | note: type in trait @@ -15,6 +13,10 @@ LL | fn early<'early, T>(x: &'early T) -> impl Sized; | ^^^^^^^^^ = note: expected signature `fn(&T)` found signature `fn(&'late ())` +help: change the parameter type to match the trait + | +LL | fn early<'late, T>(_: &T) {} + | ~~ error: aborting due to 1 previous error diff --git a/tests/ui/impl-trait/in-trait/method-signature-matches.mismatch.stderr b/tests/ui/impl-trait/in-trait/method-signature-matches.mismatch.stderr index ec2a126865d5c..9e18517e48c55 100644 --- a/tests/ui/impl-trait/in-trait/method-signature-matches.mismatch.stderr +++ b/tests/ui/impl-trait/in-trait/method-signature-matches.mismatch.stderr @@ -2,10 +2,7 @@ error[E0053]: method `owo` has an incompatible type for trait --> $DIR/method-signature-matches.rs:11:15 | LL | fn owo(_: u8) {} - | ^^ - | | - | expected `()`, found `u8` - | help: change the parameter type to match the trait: `()` + | ^^ expected `()`, found `u8` | note: type in trait --> $DIR/method-signature-matches.rs:6:15 @@ -14,6 +11,10 @@ LL | fn owo(x: ()) -> impl Sized; | ^^ = note: expected signature `fn(())` found signature `fn(u8)` +help: change the parameter type to match the trait + | +LL | fn owo(_: ()) {} + | ~~ error: aborting due to 1 previous error diff --git a/tests/ui/impl-trait/in-trait/method-signature-matches.mismatch_async.stderr b/tests/ui/impl-trait/in-trait/method-signature-matches.mismatch_async.stderr index 4d3e64e8050f9..c01d7322d117e 100644 --- a/tests/ui/impl-trait/in-trait/method-signature-matches.mismatch_async.stderr +++ b/tests/ui/impl-trait/in-trait/method-signature-matches.mismatch_async.stderr @@ -2,10 +2,7 @@ error[E0053]: method `owo` has an incompatible type for trait --> $DIR/method-signature-matches.rs:22:21 | LL | async fn owo(_: u8) {} - | ^^ - | | - | expected `()`, found `u8` - | help: change the parameter type to match the trait: `()` + | ^^ expected `()`, found `u8` | note: type in trait --> $DIR/method-signature-matches.rs:17:21 @@ -14,6 +11,10 @@ LL | async fn owo(x: ()) {} | ^^ = note: expected signature `fn(()) -> _` found signature `fn(u8) -> _` +help: change the parameter type to match the trait + | +LL | async fn owo(_: ()) {} + | ~~ error: aborting due to 1 previous error diff --git a/tests/ui/impl-trait/in-trait/opaque-and-lifetime-mismatch.stderr b/tests/ui/impl-trait/in-trait/opaque-and-lifetime-mismatch.stderr index d7fc40fa3426f..1f8a0d5edd781 100644 --- a/tests/ui/impl-trait/in-trait/opaque-and-lifetime-mismatch.stderr +++ b/tests/ui/impl-trait/in-trait/opaque-and-lifetime-mismatch.stderr @@ -75,10 +75,7 @@ error[E0053]: method `bar` has an incompatible type for trait --> $DIR/opaque-and-lifetime-mismatch.rs:10:17 | LL | fn bar() -> i32 { - | ^^^ - | | - | expected `Wrapper<'static>`, found `i32` - | help: change the output type to match the trait: `Wrapper<'static>` + | ^^^ expected `Wrapper<'static>`, found `i32` | note: type in trait --> $DIR/opaque-and-lifetime-mismatch.rs:4:17 @@ -87,6 +84,10 @@ LL | fn bar() -> Wrapper; | ^^^^^^^^^^^^^^^^^^^ = note: expected signature `fn() -> Wrapper<'static>` found signature `fn() -> i32` +help: change the output type to match the trait + | +LL | fn bar() -> Wrapper<'static> { + | ~~~~~~~~~~~~~~~~ error[E0107]: struct takes 0 generic arguments but 1 generic argument was supplied --> $DIR/opaque-and-lifetime-mismatch.rs:24:17 diff --git a/tests/ui/impl-trait/in-trait/specialization-broken.stderr b/tests/ui/impl-trait/in-trait/specialization-broken.stderr index b8a8e2401b229..8c9f265601540 100644 --- a/tests/ui/impl-trait/in-trait/specialization-broken.stderr +++ b/tests/ui/impl-trait/in-trait/specialization-broken.stderr @@ -5,10 +5,7 @@ LL | default impl Foo for U | - found this type parameter ... LL | fn bar(&self) -> U { - | ^ - | | - | expected associated type, found type parameter `U` - | help: change the output type to match the trait: `impl Sized` + | ^ expected associated type, found type parameter `U` | note: type in trait --> $DIR/specialization-broken.rs:8:22 @@ -17,6 +14,10 @@ LL | fn bar(&self) -> impl Sized; | ^^^^^^^^^^ = note: expected signature `fn(&_) -> impl Sized` found signature `fn(&_) -> U` +help: change the output type to match the trait + | +LL | fn bar(&self) -> impl Sized { + | ~~~~~~~~~~ error: method with return-position `impl Trait` in trait cannot be specialized --> $DIR/specialization-broken.rs:15:5 diff --git a/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.stderr b/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.stderr index 4352af1c0df76..3692cc77b0fb4 100644 --- a/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.stderr +++ b/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.stderr @@ -26,13 +26,14 @@ LL | type Foo = impl PartialEq<(Foo, i32)>; | -------------------------- the found opaque type ... LL | fn eq(&self, _other: &(Foo, i32)) -> bool { - | ^^^^^^^^^^^ - | | - | expected `a::Bar`, found opaque type - | help: change the parameter type to match the trait: `&(a::Bar, i32)` + | ^^^^^^^^^^^ expected `a::Bar`, found opaque type | = note: expected signature `fn(&a::Bar, &(a::Bar, _)) -> _` found signature `fn(&a::Bar, &(a::Foo, _)) -> _` +help: change the parameter type to match the trait + | +LL | fn eq(&self, _other: &(a::Bar, i32)) -> bool { + | ~~~~~~~~~~~~~~ error: unconstrained opaque type --> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:19:16 @@ -49,10 +50,7 @@ LL | type Foo = impl PartialEq<(Foo, i32)>; | -------------------------- the expected opaque type ... LL | fn eq(&self, _other: &(Bar, i32)) -> bool { - | ^^^^^^^^^^^ - | | - | expected opaque type, found `b::Bar` - | help: change the parameter type to match the trait: `&(b::Foo, i32)` + | ^^^^^^^^^^^ expected opaque type, found `b::Bar` | = note: expected signature `fn(&b::Bar, &(b::Foo, _)) -> _` found signature `fn(&b::Bar, &(b::Bar, _)) -> _` @@ -61,6 +59,10 @@ note: this item must have the opaque type in its signature in order to be able t | LL | fn eq(&self, _other: &(Bar, i32)) -> bool { | ^^ +help: change the parameter type to match the trait + | +LL | fn eq(&self, _other: &(b::Foo, i32)) -> bool { + | ~~~~~~~~~~~~~~ error: aborting due to 5 previous errors diff --git a/tests/ui/impl-trait/trait_type.stderr b/tests/ui/impl-trait/trait_type.stderr index 81e4c933e53f4..0eb132c7a1901 100644 --- a/tests/ui/impl-trait/trait_type.stderr +++ b/tests/ui/impl-trait/trait_type.stderr @@ -2,13 +2,14 @@ error[E0053]: method `fmt` has an incompatible type for trait --> $DIR/trait_type.rs:7:21 | LL | fn fmt(&self, x: &str) -> () { } - | ^^^^ - | | - | types differ in mutability - | help: change the parameter type to match the trait: `&mut Formatter<'_>` + | ^^^^ types differ in mutability | = note: expected signature `fn(&MyType, &mut Formatter<'_>) -> Result<(), std::fmt::Error>` found signature `fn(&MyType, &str)` +help: change the parameter type to match the trait + | +LL | fn fmt(&self, x: &mut Formatter<'_>) -> () { } + | ~~~~~~~~~~~~~~~~~~ error[E0050]: method `fmt` has 1 parameter but the declaration in trait `std::fmt::Display::fmt` has 2 --> $DIR/trait_type.rs:12:11 diff --git a/tests/ui/impl-trait/where-allowed.stderr b/tests/ui/impl-trait/where-allowed.stderr index bffe0447f8bb4..f0d259d01de94 100644 --- a/tests/ui/impl-trait/where-allowed.stderr +++ b/tests/ui/impl-trait/where-allowed.stderr @@ -397,10 +397,7 @@ LL | type Out = impl Debug; | ---------- the expected opaque type ... LL | fn in_trait_impl_return() -> impl Debug { () } - | ^^^^^^^^^^ - | | - | expected opaque type, found a different opaque type - | help: change the output type to match the trait: `<() as DummyTrait>::Out` + | ^^^^^^^^^^ expected opaque type, found a different opaque type | note: type in trait --> $DIR/where-allowed.rs:119:34 @@ -410,6 +407,10 @@ LL | fn in_trait_impl_return() -> Self::Out; = note: expected signature `fn() -> <() as DummyTrait>::Out` found signature `fn() -> impl Debug` = note: distinct uses of `impl Trait` result in different opaque types +help: change the output type to match the trait + | +LL | fn in_trait_impl_return() -> <() as DummyTrait>::Out { () } + | ~~~~~~~~~~~~~~~~~~~~~~~ error: unconstrained opaque type --> $DIR/where-allowed.rs:122:16 diff --git a/tests/ui/issues/issue-20225.stderr b/tests/ui/issues/issue-20225.stderr index 2d24a5bbd50ab..7d6b09cf7f893 100644 --- a/tests/ui/issues/issue-20225.stderr +++ b/tests/ui/issues/issue-20225.stderr @@ -4,13 +4,14 @@ error[E0053]: method `call` has an incompatible type for trait LL | impl<'a, T> Fn<(&'a T,)> for Foo { | - found this type parameter LL | extern "rust-call" fn call(&self, (_,): (T,)) {} - | ^^^^ - | | - | expected `&'a T`, found type parameter `T` - | help: change the parameter type to match the trait: `(&'a T,)` + | ^^^^ expected `&'a T`, found type parameter `T` | = note: expected signature `extern "rust-call" fn(&Foo, (&'a _,))` found signature `extern "rust-call" fn(&Foo, (_,))` +help: change the parameter type to match the trait + | +LL | extern "rust-call" fn call(&self, (_,): (&'a T,)) {} + | ~~~~~~~~ error[E0053]: method `call_mut` has an incompatible type for trait --> $DIR/issue-20225.rs:11:51 @@ -18,13 +19,14 @@ error[E0053]: method `call_mut` has an incompatible type for trait LL | impl<'a, T> FnMut<(&'a T,)> for Foo { | - found this type parameter LL | extern "rust-call" fn call_mut(&mut self, (_,): (T,)) {} - | ^^^^ - | | - | expected `&'a T`, found type parameter `T` - | help: change the parameter type to match the trait: `(&'a T,)` + | ^^^^ expected `&'a T`, found type parameter `T` | = note: expected signature `extern "rust-call" fn(&mut Foo, (&'a _,))` found signature `extern "rust-call" fn(&mut Foo, (_,))` +help: change the parameter type to match the trait + | +LL | extern "rust-call" fn call_mut(&mut self, (_,): (&'a T,)) {} + | ~~~~~~~~ error[E0053]: method `call_once` has an incompatible type for trait --> $DIR/issue-20225.rs:18:47 @@ -33,13 +35,14 @@ LL | impl<'a, T> FnOnce<(&'a T,)> for Foo { | - found this type parameter ... LL | extern "rust-call" fn call_once(self, (_,): (T,)) {} - | ^^^^ - | | - | expected `&'a T`, found type parameter `T` - | help: change the parameter type to match the trait: `(&'a T,)` + | ^^^^ expected `&'a T`, found type parameter `T` | = note: expected signature `extern "rust-call" fn(Foo, (&'a _,))` found signature `extern "rust-call" fn(Foo, (_,))` +help: change the parameter type to match the trait + | +LL | extern "rust-call" fn call_once(self, (_,): (&'a T,)) {} + | ~~~~~~~~ error: aborting due to 3 previous errors diff --git a/tests/ui/issues/issue-21332.stderr b/tests/ui/issues/issue-21332.stderr index 96e0f5fdb31db..7c960f7646db7 100644 --- a/tests/ui/issues/issue-21332.stderr +++ b/tests/ui/issues/issue-21332.stderr @@ -2,13 +2,14 @@ error[E0053]: method `next` has an incompatible type for trait --> $DIR/issue-21332.rs:5:27 | LL | fn next(&mut self) -> Result { Ok(7) } - | ^^^^^^^^^^^^^^^^ - | | - | expected `Option`, found `Result` - | help: change the output type to match the trait: `Option` + | ^^^^^^^^^^^^^^^^ expected `Option`, found `Result` | = note: expected signature `fn(&mut S) -> Option` found signature `fn(&mut S) -> Result` +help: change the output type to match the trait + | +LL | fn next(&mut self) -> Option { Ok(7) } + | ~~~~~~~~~~~ error: aborting due to 1 previous error diff --git a/tests/ui/mismatched_types/E0053.stderr b/tests/ui/mismatched_types/E0053.stderr index d0bd5b46cf59f..2559d4487491e 100644 --- a/tests/ui/mismatched_types/E0053.stderr +++ b/tests/ui/mismatched_types/E0053.stderr @@ -2,10 +2,7 @@ error[E0053]: method `foo` has an incompatible type for trait --> $DIR/E0053.rs:9:15 | LL | fn foo(x: i16) { } - | ^^^ - | | - | expected `u16`, found `i16` - | help: change the parameter type to match the trait: `u16` + | ^^^ expected `u16`, found `i16` | note: type in trait --> $DIR/E0053.rs:2:15 @@ -14,15 +11,16 @@ LL | fn foo(x: u16); | ^^^ = note: expected signature `fn(u16)` found signature `fn(i16)` +help: change the parameter type to match the trait + | +LL | fn foo(x: u16) { } + | ~~~ error[E0053]: method `bar` has an incompatible type for trait --> $DIR/E0053.rs:11:12 | LL | fn bar(&mut self) { } - | ^^^^^^^^^ - | | - | types differ in mutability - | help: change the self-receiver type to match the trait: `&self` + | ^^^^^^^^^ types differ in mutability | note: type in trait --> $DIR/E0053.rs:3:12 @@ -31,6 +29,10 @@ LL | fn bar(&self); | ^^^^^ = note: expected signature `fn(&Bar)` found signature `fn(&mut Bar)` +help: change the self-receiver type to match the trait + | +LL | fn bar(&self) { } + | ~~~~~ error: aborting due to 2 previous errors diff --git a/tests/ui/mismatched_types/issue-112036.stderr b/tests/ui/mismatched_types/issue-112036.stderr index b93ce4a8674c2..bd446b3d78cb2 100644 --- a/tests/ui/mismatched_types/issue-112036.stderr +++ b/tests/ui/mismatched_types/issue-112036.stderr @@ -2,13 +2,14 @@ error[E0053]: method `drop` has an incompatible type for trait --> $DIR/issue-112036.rs:4:13 | LL | fn drop(self) {} - | ^^^^ - | | - | expected `&mut Foo`, found `Foo` - | help: change the self-receiver type to match the trait: `&mut self` + | ^^^^ expected `&mut Foo`, found `Foo` | = note: expected signature `fn(&mut Foo)` found signature `fn(Foo)` +help: change the self-receiver type to match the trait + | +LL | fn drop(&mut self) {} + | ~~~~~~~~~ error: aborting due to 1 previous error diff --git a/tests/ui/mismatched_types/issue-13033.stderr b/tests/ui/mismatched_types/issue-13033.stderr index 4886fa30e89b1..2a266d40e7717 100644 --- a/tests/ui/mismatched_types/issue-13033.stderr +++ b/tests/ui/mismatched_types/issue-13033.stderr @@ -2,10 +2,7 @@ error[E0053]: method `bar` has an incompatible type for trait --> $DIR/issue-13033.rs:8:30 | LL | fn bar(&mut self, other: &dyn Foo) {} - | ^^^^^^^^ - | | - | types differ in mutability - | help: change the parameter type to match the trait: `&mut dyn Foo` + | ^^^^^^^^ types differ in mutability | note: type in trait --> $DIR/issue-13033.rs:2:30 @@ -14,6 +11,10 @@ LL | fn bar(&mut self, other: &mut dyn Foo); | ^^^^^^^^^^^^ = note: expected signature `fn(&mut Baz, &mut dyn Foo)` found signature `fn(&mut Baz, &dyn Foo)` +help: change the parameter type to match the trait + | +LL | fn bar(&mut self, other: &mut dyn Foo) {} + | ~~~~~~~~~~~~ error: aborting due to 1 previous error diff --git a/tests/ui/mismatched_types/trait-impl-fn-incompatibility.stderr b/tests/ui/mismatched_types/trait-impl-fn-incompatibility.stderr index 6e7bf5eb46d92..2e544a62223a0 100644 --- a/tests/ui/mismatched_types/trait-impl-fn-incompatibility.stderr +++ b/tests/ui/mismatched_types/trait-impl-fn-incompatibility.stderr @@ -2,10 +2,7 @@ error[E0053]: method `foo` has an incompatible type for trait --> $DIR/trait-impl-fn-incompatibility.rs:9:15 | LL | fn foo(x: i16) { } - | ^^^ - | | - | expected `u16`, found `i16` - | help: change the parameter type to match the trait: `u16` + | ^^^ expected `u16`, found `i16` | note: type in trait --> $DIR/trait-impl-fn-incompatibility.rs:2:15 @@ -14,15 +11,16 @@ LL | fn foo(x: u16); | ^^^ = note: expected signature `fn(u16)` found signature `fn(i16)` +help: change the parameter type to match the trait + | +LL | fn foo(x: u16) { } + | ~~~ error[E0053]: method `bar` has an incompatible type for trait --> $DIR/trait-impl-fn-incompatibility.rs:10:28 | LL | fn bar(&mut self, bar: &Bar) { } - | ^^^^ - | | - | types differ in mutability - | help: change the parameter type to match the trait: `&mut Bar` + | ^^^^ types differ in mutability | note: type in trait --> $DIR/trait-impl-fn-incompatibility.rs:3:28 @@ -31,6 +29,10 @@ LL | fn bar(&mut self, bar: &mut Bar); | ^^^^^^^^ = note: expected signature `fn(&mut Bar, &mut Bar)` found signature `fn(&mut Bar, &Bar)` +help: change the parameter type to match the trait + | +LL | fn bar(&mut self, bar: &mut Bar) { } + | ~~~~~~~~ error: aborting due to 2 previous errors diff --git a/tests/ui/traits/issue-35869.stderr b/tests/ui/traits/issue-35869.stderr index 6d985bdeaf859..503f9cee246e9 100644 --- a/tests/ui/traits/issue-35869.stderr +++ b/tests/ui/traits/issue-35869.stderr @@ -2,10 +2,7 @@ error[E0053]: method `foo` has an incompatible type for trait --> $DIR/issue-35869.rs:11:15 | LL | fn foo(_: fn(u16) -> ()) {} - | ^^^^^^^^^^^^^ - | | - | expected `u8`, found `u16` - | help: change the parameter type to match the trait: `fn(u8)` + | ^^^^^^^^^^^^^ expected `u8`, found `u16` | note: type in trait --> $DIR/issue-35869.rs:2:15 @@ -14,15 +11,16 @@ LL | fn foo(_: fn(u8) -> ()); | ^^^^^^^^^^^^ = note: expected signature `fn(fn(u8))` found signature `fn(fn(u16))` +help: change the parameter type to match the trait + | +LL | fn foo(_: fn(u8)) {} + | ~~~~~~ error[E0053]: method `bar` has an incompatible type for trait --> $DIR/issue-35869.rs:13:15 | LL | fn bar(_: Option) {} - | ^^^^^^^^^^^ - | | - | expected `u8`, found `u16` - | help: change the parameter type to match the trait: `Option` + | ^^^^^^^^^^^ expected `u8`, found `u16` | note: type in trait --> $DIR/issue-35869.rs:3:15 @@ -31,15 +29,16 @@ LL | fn bar(_: Option); | ^^^^^^^^^^ = note: expected signature `fn(Option)` found signature `fn(Option)` +help: change the parameter type to match the trait + | +LL | fn bar(_: Option) {} + | ~~~~~~~~~~ error[E0053]: method `baz` has an incompatible type for trait --> $DIR/issue-35869.rs:15:15 | LL | fn baz(_: (u16, u16)) {} - | ^^^^^^^^^^ - | | - | expected `u8`, found `u16` - | help: change the parameter type to match the trait: `(u8, u16)` + | ^^^^^^^^^^ expected `u8`, found `u16` | note: type in trait --> $DIR/issue-35869.rs:4:15 @@ -48,15 +47,16 @@ LL | fn baz(_: (u8, u16)); | ^^^^^^^^^ = note: expected signature `fn((u8, _))` found signature `fn((u16, _))` +help: change the parameter type to match the trait + | +LL | fn baz(_: (u8, u16)) {} + | ~~~~~~~~~ error[E0053]: method `qux` has an incompatible type for trait --> $DIR/issue-35869.rs:17:17 | LL | fn qux() -> u16 { 5u16 } - | ^^^ - | | - | expected `u8`, found `u16` - | help: change the output type to match the trait: `u8` + | ^^^ expected `u8`, found `u16` | note: type in trait --> $DIR/issue-35869.rs:5:17 @@ -65,6 +65,10 @@ LL | fn qux() -> u8; | ^^ = note: expected signature `fn() -> u8` found signature `fn() -> u16` +help: change the output type to match the trait + | +LL | fn qux() -> u8 { 5u16 } + | ~~ error: aborting due to 4 previous errors diff --git a/tests/ui/traits/wrong-mul-method-signature.stderr b/tests/ui/traits/wrong-mul-method-signature.stderr index 91162cbc1231f..e30b61622ae01 100644 --- a/tests/ui/traits/wrong-mul-method-signature.stderr +++ b/tests/ui/traits/wrong-mul-method-signature.stderr @@ -2,37 +2,40 @@ error[E0053]: method `mul` has an incompatible type for trait --> $DIR/wrong-mul-method-signature.rs:16:21 | LL | fn mul(self, s: &f64) -> Vec1 { - | ^^^^ - | | - | expected `f64`, found `&f64` - | help: change the parameter type to match the trait: `f64` + | ^^^^ expected `f64`, found `&f64` | = note: expected signature `fn(Vec1, _) -> Vec1` found signature `fn(Vec1, &_) -> Vec1` +help: change the parameter type to match the trait + | +LL | fn mul(self, s: f64) -> Vec1 { + | ~~~ error[E0053]: method `mul` has an incompatible type for trait --> $DIR/wrong-mul-method-signature.rs:33:21 | LL | fn mul(self, s: f64) -> Vec2 { - | ^^^ - | | - | expected `Vec2`, found `f64` - | help: change the parameter type to match the trait: `Vec2` + | ^^^ expected `Vec2`, found `f64` | = note: expected signature `fn(Vec2, Vec2) -> f64` found signature `fn(Vec2, f64) -> Vec2` +help: change the parameter type to match the trait + | +LL | fn mul(self, s: Vec2) -> Vec2 { + | ~~~~ error[E0053]: method `mul` has an incompatible type for trait --> $DIR/wrong-mul-method-signature.rs:52:29 | LL | fn mul(self, s: f64) -> f64 { - | ^^^ - | | - | expected `i32`, found `f64` - | help: change the output type to match the trait: `i32` + | ^^^ expected `i32`, found `f64` | = note: expected signature `fn(Vec3, _) -> i32` found signature `fn(Vec3, _) -> f64` +help: change the output type to match the trait + | +LL | fn mul(self, s: f64) -> i32 { + | ~~~ error[E0308]: mismatched types --> $DIR/wrong-mul-method-signature.rs:63:45 diff --git a/tests/ui/type-alias-impl-trait/unnameable_type.stderr b/tests/ui/type-alias-impl-trait/unnameable_type.stderr index f567b01d29a1b..5b331c5660d9c 100644 --- a/tests/ui/type-alias-impl-trait/unnameable_type.stderr +++ b/tests/ui/type-alias-impl-trait/unnameable_type.stderr @@ -5,10 +5,7 @@ LL | type MyPrivate = impl Sized; | ---------- the found opaque type LL | impl Trait for u32 { LL | fn dont_define_this(private: MyPrivate) { - | ^^^^^^^^^ - | | - | expected `Private`, found opaque type - | help: change the parameter type to match the trait: `Private` + | ^^^^^^^^^ expected `Private`, found opaque type | note: type in trait --> $DIR/unnameable_type.rs:10:39 @@ -17,6 +14,10 @@ LL | fn dont_define_this(_private: Private) {} | ^^^^^^^ = note: expected signature `fn(Private)` found signature `fn(MyPrivate)` +help: change the parameter type to match the trait + | +LL | fn dont_define_this(private: Private) { + | ~~~~~~~ error: aborting due to 1 previous error diff --git a/tests/ui/typeck/mismatched-map-under-self.stderr b/tests/ui/typeck/mismatched-map-under-self.stderr index 322bf349f92fc..59de00a58bbea 100644 --- a/tests/ui/typeck/mismatched-map-under-self.stderr +++ b/tests/ui/typeck/mismatched-map-under-self.stderr @@ -2,10 +2,7 @@ error[E0053]: method `values` has an incompatible type for trait --> $DIR/mismatched-map-under-self.rs:10:15 | LL | fn values(self) -> Self::Values { - | ^^^^ - | | - | expected `&Option`, found `Option` - | help: change the self-receiver type to match the trait: `&self` + | ^^^^ expected `&Option`, found `Option` | note: type in trait --> $DIR/mismatched-map-under-self.rs:4:15 @@ -14,6 +11,10 @@ LL | fn values(&self) -> Self::Values; | ^^^^^ = note: expected signature `fn(&Option<_>)` found signature `fn(Option<_>)` +help: change the self-receiver type to match the trait + | +LL | fn values(&self) -> Self::Values { + | ~~~~~ error[E0631]: type mismatch in function arguments --> $DIR/mismatched-map-under-self.rs:12:18 diff --git a/tests/ui/ufcs/ufcs-explicit-self-bad.stderr b/tests/ui/ufcs/ufcs-explicit-self-bad.stderr index c48d094daea20..2a8c4edbdb5f3 100644 --- a/tests/ui/ufcs/ufcs-explicit-self-bad.stderr +++ b/tests/ui/ufcs/ufcs-explicit-self-bad.stderr @@ -2,10 +2,7 @@ error[E0053]: method `dummy2` has an incompatible type for trait --> $DIR/ufcs-explicit-self-bad.rs:37:21 | LL | fn dummy2(self: &Bar) {} - | ------^^^^^^^ - | | | - | | expected `&'a Bar`, found `Bar` - | help: change the self-receiver type to match the trait: `&self` + | ^^^^^^^ expected `&'a Bar`, found `Bar` | note: type in trait --> $DIR/ufcs-explicit-self-bad.rs:31:15 @@ -14,6 +11,10 @@ LL | fn dummy2(&self); | ^^^^^ = note: expected signature `fn(&&'a Bar<_>)` found signature `fn(&Bar<_>)` +help: change the self-receiver type to match the trait + | +LL | fn dummy2(&self) {} + | ~~~~~ error[E0307]: invalid `self` parameter type: `isize` --> $DIR/ufcs-explicit-self-bad.rs:8:18 From 9f66af43199bb5e89a2279956123d294e43bf364 Mon Sep 17 00:00:00 2001 From: clubby789 Date: Fri, 5 Jul 2024 22:08:13 +0100 Subject: [PATCH 758/892] Remove clubby789 from review rotation --- triagebot.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/triagebot.toml b/triagebot.toml index 8ae454d412a6f..746a663005277 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -952,7 +952,6 @@ bootstrap = [ "@Mark-Simulacrum", "@albertlarsan68", "@onur-ozkan", - "@clubby789", "@kobzol", ] infra-ci = [ From ffea65bf6101ddecf14787c1a29a1460320c5a91 Mon Sep 17 00:00:00 2001 From: Peter Jaszkowiak Date: Sun, 19 May 2024 12:28:26 -0600 Subject: [PATCH 759/892] add `new_range_api` for RFC 3550 This includes a `From for RangeInclusive` impl for convenience, instead of the `TryFrom` impl from the RFC. Having `From` is highly convenient and the assertion is unlikely to be a problem in practice. This includes re-exports of all existing `Range` types under `core::range`, plus the range-related traits (`RangeBounds`, `Step`, `OneSidedRange`) and the `Bound` enum. Currently the iterators are just wrappers around the old range types, and most other trait impls delegate to the old rage types as well. Also includes an `.iter()` shorthand for `.clone().into_iter()` --- library/core/src/lib.rs | 2 + library/core/src/range.rs | 494 +++++++++++++++++++++++ library/core/src/range/iter.rs | 340 ++++++++++++++++ library/core/src/range/legacy.rs | 10 + library/core/src/slice/index.rs | 124 +++++- library/core/src/str/traits.rs | 195 +++++++++ src/tools/linkchecker/main.rs | 2 + tests/ui/range/issue-54505-no-std.stderr | 6 +- 8 files changed, 1168 insertions(+), 5 deletions(-) create mode 100644 library/core/src/range.rs create mode 100644 library/core/src/range/iter.rs create mode 100644 library/core/src/range/legacy.rs diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index c5a1fca667bc3..0f82f01e57a71 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -395,6 +395,8 @@ pub mod panicking; #[unstable(feature = "core_pattern_types", issue = "none")] pub mod pat; pub mod pin; +#[unstable(feature = "new_range_api", issue = "125687")] +pub mod range; pub mod result; pub mod sync; diff --git a/library/core/src/range.rs b/library/core/src/range.rs new file mode 100644 index 0000000000000..bfbbf123b1ca5 --- /dev/null +++ b/library/core/src/range.rs @@ -0,0 +1,494 @@ +//! # Experimental replacement range types +//! +//! The types within this module are meant to replace the existing +//! `Range`, `RangeInclusive`, and `RangeFrom` types in a future edition. +//! +//! ``` +//! #![feature(new_range_api)] +//! use core::range::{Range, RangeFrom, RangeInclusive}; +//! +//! let arr = [0, 1, 2, 3, 4]; +//! assert_eq!(arr[ .. ], [0, 1, 2, 3, 4]); +//! assert_eq!(arr[ .. 3 ], [0, 1, 2 ]); +//! assert_eq!(arr[ ..=3 ], [0, 1, 2, 3 ]); +//! assert_eq!(arr[ RangeFrom::from(1.. )], [ 1, 2, 3, 4]); +//! assert_eq!(arr[ Range::from(1..3 )], [ 1, 2 ]); +//! assert_eq!(arr[RangeInclusive::from(1..=3)], [ 1, 2, 3 ]); +//! ``` + +use crate::fmt; +use crate::hash::Hash; + +mod iter; + +#[unstable(feature = "new_range_api", issue = "125687")] +pub mod legacy; + +#[doc(inline)] +pub use crate::ops::{Bound, OneSidedRange, RangeBounds, RangeFull, RangeTo, RangeToInclusive}; + +use Bound::{Excluded, Included, Unbounded}; + +#[doc(inline)] +pub use crate::iter::Step; + +#[doc(inline)] +pub use iter::{IterRange, IterRangeFrom, IterRangeInclusive}; + +/// A (half-open) range bounded inclusively below and exclusively above +/// (`start..end` in a future edition). +/// +/// The range `start..end` contains all values with `start <= x < end`. +/// It is empty if `start >= end`. +/// +/// # Examples +/// +/// ``` +/// #![feature(new_range_api)] +/// use core::range::Range; +/// +/// assert_eq!(Range::from(3..5), Range { start: 3, end: 5 }); +/// assert_eq!(3 + 4 + 5, Range::from(3..6).into_iter().sum()); +/// ``` +#[derive(Clone, Copy, Default, PartialEq, Eq, Hash)] +#[unstable(feature = "new_range_api", issue = "125687")] +pub struct Range { + /// The lower bound of the range (inclusive). + #[unstable(feature = "new_range_api", issue = "125687")] + pub start: Idx, + /// The upper bound of the range (exclusive). + #[unstable(feature = "new_range_api", issue = "125687")] + pub end: Idx, +} + +#[unstable(feature = "new_range_api", issue = "125687")] +impl fmt::Debug for Range { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { + self.start.fmt(fmt)?; + write!(fmt, "..")?; + self.end.fmt(fmt)?; + Ok(()) + } +} + +impl Range { + /// Create an iterator over the elements within this range. + /// + /// Shorthand for `.clone().into_iter()` + /// + /// # Examples + /// + /// ``` + /// #![feature(new_range_api)] + /// use core::range::Range; + /// + /// let mut i = Range::from(3..9).iter().map(|n| n*n); + /// assert_eq!(i.next(), Some(9)); + /// assert_eq!(i.next(), Some(16)); + /// assert_eq!(i.next(), Some(25)); + /// ``` + #[unstable(feature = "new_range_api", issue = "125687")] + #[inline] + pub fn iter(&self) -> IterRange { + self.clone().into_iter() + } +} + +impl> Range { + /// Returns `true` if `item` is contained in the range. + /// + /// # Examples + /// + /// ``` + /// #![feature(new_range_api)] + /// use core::range::Range; + /// + /// assert!(!Range::from(3..5).contains(&2)); + /// assert!( Range::from(3..5).contains(&3)); + /// assert!( Range::from(3..5).contains(&4)); + /// assert!(!Range::from(3..5).contains(&5)); + /// + /// assert!(!Range::from(3..3).contains(&3)); + /// assert!(!Range::from(3..2).contains(&3)); + /// + /// assert!( Range::from(0.0..1.0).contains(&0.5)); + /// assert!(!Range::from(0.0..1.0).contains(&f32::NAN)); + /// assert!(!Range::from(0.0..f32::NAN).contains(&0.5)); + /// assert!(!Range::from(f32::NAN..1.0).contains(&0.5)); + /// ``` + #[inline] + #[unstable(feature = "new_range_api", issue = "125687")] + pub fn contains(&self, item: &U) -> bool + where + Idx: PartialOrd, + U: ?Sized + PartialOrd, + { + >::contains(self, item) + } + + /// Returns `true` if the range contains no items. + /// + /// # Examples + /// + /// ``` + /// #![feature(new_range_api)] + /// use core::range::Range; + /// + /// assert!(!Range::from(3..5).is_empty()); + /// assert!( Range::from(3..3).is_empty()); + /// assert!( Range::from(3..2).is_empty()); + /// ``` + /// + /// The range is empty if either side is incomparable: + /// + /// ``` + /// #![feature(new_range_api)] + /// use core::range::Range; + /// + /// assert!(!Range::from(3.0..5.0).is_empty()); + /// assert!( Range::from(3.0..f32::NAN).is_empty()); + /// assert!( Range::from(f32::NAN..5.0).is_empty()); + /// ``` + #[inline] + #[unstable(feature = "new_range_api", issue = "125687")] + pub fn is_empty(&self) -> bool { + !(self.start < self.end) + } +} + +#[unstable(feature = "new_range_api", issue = "125687")] +impl RangeBounds for Range { + fn start_bound(&self) -> Bound<&T> { + Included(&self.start) + } + fn end_bound(&self) -> Bound<&T> { + Excluded(&self.end) + } +} + +#[unstable(feature = "new_range_api", issue = "125687")] +impl RangeBounds for Range<&T> { + fn start_bound(&self) -> Bound<&T> { + Included(self.start) + } + fn end_bound(&self) -> Bound<&T> { + Excluded(self.end) + } +} + +#[unstable(feature = "new_range_api", issue = "125687")] +impl From> for legacy::Range { + #[inline] + fn from(value: Range) -> Self { + Self { start: value.start, end: value.end } + } +} +#[unstable(feature = "new_range_api", issue = "125687")] +impl From> for Range { + #[inline] + fn from(value: legacy::Range) -> Self { + Self { start: value.start, end: value.end } + } +} + +/// A range bounded inclusively below and above (`start..=end`). +/// +/// The `RangeInclusive` `start..=end` contains all values with `x >= start` +/// and `x <= end`. It is empty unless `start <= end`. +/// +/// # Examples +/// +/// The `start..=end` syntax is a `RangeInclusive`: +/// +/// ``` +/// #![feature(new_range_api)] +/// use core::range::RangeInclusive; +/// +/// assert_eq!(RangeInclusive::from(3..=5), RangeInclusive { start: 3, end: 5 }); +/// assert_eq!(3 + 4 + 5, RangeInclusive::from(3..=5).into_iter().sum()); +/// ``` +#[derive(Clone, Copy, PartialEq, Eq, Hash)] +#[unstable(feature = "new_range_api", issue = "125687")] +pub struct RangeInclusive { + /// The lower bound of the range (inclusive). + #[unstable(feature = "new_range_api", issue = "125687")] + pub start: Idx, + /// The upper bound of the range (inclusive). + #[unstable(feature = "new_range_api", issue = "125687")] + pub end: Idx, +} + +#[unstable(feature = "new_range_api", issue = "125687")] +impl fmt::Debug for RangeInclusive { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { + self.start.fmt(fmt)?; + write!(fmt, "..=")?; + self.end.fmt(fmt)?; + Ok(()) + } +} + +impl> RangeInclusive { + /// Returns `true` if `item` is contained in the range. + /// + /// # Examples + /// + /// ``` + /// #![feature(new_range_api)] + /// use core::range::RangeInclusive; + /// + /// assert!(!RangeInclusive::from(3..=5).contains(&2)); + /// assert!( RangeInclusive::from(3..=5).contains(&3)); + /// assert!( RangeInclusive::from(3..=5).contains(&4)); + /// assert!( RangeInclusive::from(3..=5).contains(&5)); + /// assert!(!RangeInclusive::from(3..=5).contains(&6)); + /// + /// assert!( RangeInclusive::from(3..=3).contains(&3)); + /// assert!(!RangeInclusive::from(3..=2).contains(&3)); + /// + /// assert!( RangeInclusive::from(0.0..=1.0).contains(&1.0)); + /// assert!(!RangeInclusive::from(0.0..=1.0).contains(&f32::NAN)); + /// assert!(!RangeInclusive::from(0.0..=f32::NAN).contains(&0.0)); + /// assert!(!RangeInclusive::from(f32::NAN..=1.0).contains(&1.0)); + /// ``` + #[inline] + #[unstable(feature = "new_range_api", issue = "125687")] + pub fn contains(&self, item: &U) -> bool + where + Idx: PartialOrd, + U: ?Sized + PartialOrd, + { + >::contains(self, item) + } + + /// Returns `true` if the range contains no items. + /// + /// # Examples + /// + /// ``` + /// #![feature(new_range_api)] + /// use core::range::RangeInclusive; + /// + /// assert!(!RangeInclusive::from(3..=5).is_empty()); + /// assert!(!RangeInclusive::from(3..=3).is_empty()); + /// assert!( RangeInclusive::from(3..=2).is_empty()); + /// ``` + /// + /// The range is empty if either side is incomparable: + /// + /// ``` + /// #![feature(new_range_api)] + /// use core::range::RangeInclusive; + /// + /// assert!(!RangeInclusive::from(3.0..=5.0).is_empty()); + /// assert!( RangeInclusive::from(3.0..=f32::NAN).is_empty()); + /// assert!( RangeInclusive::from(f32::NAN..=5.0).is_empty()); + /// ``` + #[unstable(feature = "new_range_api", issue = "125687")] + #[inline] + pub fn is_empty(&self) -> bool { + !(self.start <= self.end) + } +} + +impl RangeInclusive { + /// Create an iterator over the elements within this range. + /// + /// Shorthand for `.clone().into_iter()` + /// + /// # Examples + /// + /// ``` + /// #![feature(new_range_api)] + /// use core::range::RangeInclusive; + /// + /// let mut i = RangeInclusive::from(3..=8).iter().map(|n| n*n); + /// assert_eq!(i.next(), Some(9)); + /// assert_eq!(i.next(), Some(16)); + /// assert_eq!(i.next(), Some(25)); + /// ``` + #[unstable(feature = "new_range_api", issue = "125687")] + #[inline] + pub fn iter(&self) -> IterRangeInclusive { + self.clone().into_iter() + } +} + +impl RangeInclusive { + /// Converts to an exclusive `Range` for `SliceIndex` implementations. + /// The caller is responsible for dealing with `end == usize::MAX`. + #[inline] + pub(crate) const fn into_slice_range(self) -> Range { + Range { start: self.start, end: self.end + 1 } + } +} + +#[unstable(feature = "new_range_api", issue = "125687")] +impl RangeBounds for RangeInclusive { + fn start_bound(&self) -> Bound<&T> { + Included(&self.start) + } + fn end_bound(&self) -> Bound<&T> { + Included(&self.end) + } +} + +#[unstable(feature = "new_range_api", issue = "125687")] +impl RangeBounds for RangeInclusive<&T> { + fn start_bound(&self) -> Bound<&T> { + Included(self.start) + } + fn end_bound(&self) -> Bound<&T> { + Included(self.end) + } +} + +#[unstable(feature = "new_range_api", issue = "125687")] +impl From> for legacy::RangeInclusive { + #[inline] + fn from(value: RangeInclusive) -> Self { + Self::new(value.start, value.end) + } +} +#[unstable(feature = "new_range_api", issue = "125687")] +impl From> for RangeInclusive { + #[inline] + fn from(value: legacy::RangeInclusive) -> Self { + assert!( + !value.exhausted, + "attempted to convert from an exhausted `legacy::RangeInclusive` (unspecified behavior)" + ); + + let (start, end) = value.into_inner(); + RangeInclusive { start, end } + } +} + +/// A range only bounded inclusively below (`start..`). +/// +/// The `RangeFrom` `start..` contains all values with `x >= start`. +/// +/// *Note*: Overflow in the [`Iterator`] implementation (when the contained +/// data type reaches its numerical limit) is allowed to panic, wrap, or +/// saturate. This behavior is defined by the implementation of the [`Step`] +/// trait. For primitive integers, this follows the normal rules, and respects +/// the overflow checks profile (panic in debug, wrap in release). Note also +/// that overflow happens earlier than you might assume: the overflow happens +/// in the call to `next` that yields the maximum value, as the range must be +/// set to a state to yield the next value. +/// +/// [`Step`]: crate::iter::Step +/// +/// # Examples +/// +/// The `start..` syntax is a `RangeFrom`: +/// +/// ``` +/// #![feature(new_range_api)] +/// use core::range::RangeFrom; +/// +/// assert_eq!(RangeFrom::from(2..), core::range::RangeFrom { start: 2 }); +/// assert_eq!(2 + 3 + 4, RangeFrom::from(2..).into_iter().take(3).sum()); +/// ``` +#[derive(Clone, Copy, PartialEq, Eq, Hash)] +#[unstable(feature = "new_range_api", issue = "125687")] +pub struct RangeFrom { + /// The lower bound of the range (inclusive). + #[unstable(feature = "new_range_api", issue = "125687")] + pub start: Idx, +} + +#[unstable(feature = "new_range_api", issue = "125687")] +impl fmt::Debug for RangeFrom { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { + self.start.fmt(fmt)?; + write!(fmt, "..")?; + Ok(()) + } +} + +impl RangeFrom { + /// Create an iterator over the elements within this range. + /// + /// Shorthand for `.clone().into_iter()` + /// + /// # Examples + /// + /// ``` + /// #![feature(new_range_api)] + /// use core::range::RangeFrom; + /// + /// let mut i = RangeFrom::from(3..).iter().map(|n| n*n); + /// assert_eq!(i.next(), Some(9)); + /// assert_eq!(i.next(), Some(16)); + /// assert_eq!(i.next(), Some(25)); + /// ``` + #[unstable(feature = "new_range_api", issue = "125687")] + #[inline] + pub fn iter(&self) -> IterRangeFrom { + self.clone().into_iter() + } +} + +impl> RangeFrom { + /// Returns `true` if `item` is contained in the range. + /// + /// # Examples + /// + /// ``` + /// #![feature(new_range_api)] + /// use core::range::RangeFrom; + /// + /// assert!(!RangeFrom::from(3..).contains(&2)); + /// assert!( RangeFrom::from(3..).contains(&3)); + /// assert!( RangeFrom::from(3..).contains(&1_000_000_000)); + /// + /// assert!( RangeFrom::from(0.0..).contains(&0.5)); + /// assert!(!RangeFrom::from(0.0..).contains(&f32::NAN)); + /// assert!(!RangeFrom::from(f32::NAN..).contains(&0.5)); + /// ``` + #[inline] + #[unstable(feature = "new_range_api", issue = "125687")] + pub fn contains(&self, item: &U) -> bool + where + Idx: PartialOrd, + U: ?Sized + PartialOrd, + { + >::contains(self, item) + } +} + +#[unstable(feature = "new_range_api", issue = "125687")] +impl RangeBounds for RangeFrom { + fn start_bound(&self) -> Bound<&T> { + Included(&self.start) + } + fn end_bound(&self) -> Bound<&T> { + Unbounded + } +} + +#[unstable(feature = "new_range_api", issue = "125687")] +impl RangeBounds for RangeFrom<&T> { + fn start_bound(&self) -> Bound<&T> { + Included(self.start) + } + fn end_bound(&self) -> Bound<&T> { + Unbounded + } +} + +#[unstable(feature = "new_range_api", issue = "125687")] +impl From> for legacy::RangeFrom { + #[inline] + fn from(value: RangeFrom) -> Self { + Self { start: value.start } + } +} +#[unstable(feature = "new_range_api", issue = "125687")] +impl From> for RangeFrom { + #[inline] + fn from(value: legacy::RangeFrom) -> Self { + Self { start: value.start } + } +} diff --git a/library/core/src/range/iter.rs b/library/core/src/range/iter.rs new file mode 100644 index 0000000000000..2b7db475ffb2c --- /dev/null +++ b/library/core/src/range/iter.rs @@ -0,0 +1,340 @@ +use crate::num::NonZero; +use crate::range::{legacy, Range, RangeFrom, RangeInclusive}; + +use crate::iter::{ + FusedIterator, Step, TrustedLen, TrustedRandomAccess, TrustedRandomAccessNoCoerce, TrustedStep, +}; + +/// By-value [`Range`] iterator. +#[unstable(feature = "new_range_api", issue = "125687")] +#[derive(Debug, Clone)] +pub struct IterRange(legacy::Range); + +impl IterRange { + /// Returns the remainder of the range being iterated over. + pub fn remainder(self) -> Range { + Range { start: self.0.start, end: self.0.end } + } +} + +/// Safety: This macro must only be used on types that are `Copy` and result in ranges +/// which have an exact `size_hint()` where the upper bound must not be `None`. +macro_rules! unsafe_range_trusted_random_access_impl { + ($($t:ty)*) => ($( + #[doc(hidden)] + #[unstable(feature = "trusted_random_access", issue = "none")] + unsafe impl TrustedRandomAccess for IterRange<$t> {} + + #[doc(hidden)] + #[unstable(feature = "trusted_random_access", issue = "none")] + unsafe impl TrustedRandomAccessNoCoerce for IterRange<$t> { + const MAY_HAVE_SIDE_EFFECT: bool = false; + } + )*) +} + +unsafe_range_trusted_random_access_impl! { + usize u8 u16 + isize i8 i16 +} + +#[cfg(target_pointer_width = "32")] +unsafe_range_trusted_random_access_impl! { + u32 i32 +} + +#[cfg(target_pointer_width = "64")] +unsafe_range_trusted_random_access_impl! { + u32 i32 + u64 i64 +} + +#[unstable(feature = "new_range_api", issue = "125687")] +impl Iterator for IterRange { + type Item = A; + + #[inline] + fn next(&mut self) -> Option { + self.0.next() + } + + #[inline] + fn size_hint(&self) -> (usize, Option) { + self.0.size_hint() + } + + #[inline] + fn count(self) -> usize { + self.0.count() + } + + #[inline] + fn nth(&mut self, n: usize) -> Option { + self.0.nth(n) + } + + #[inline] + fn last(self) -> Option { + self.0.last() + } + + #[inline] + fn min(self) -> Option + where + A: Ord, + { + self.0.min() + } + + #[inline] + fn max(self) -> Option + where + A: Ord, + { + self.0.max() + } + + #[inline] + fn is_sorted(self) -> bool { + true + } + + #[inline] + fn advance_by(&mut self, n: usize) -> Result<(), NonZero> { + self.0.advance_by(n) + } + + #[inline] + unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item + where + Self: TrustedRandomAccessNoCoerce, + { + // SAFETY: The TrustedRandomAccess contract requires that callers only pass an index + // that is in bounds. + // Additionally Self: TrustedRandomAccess is only implemented for Copy types + // which means even repeated reads of the same index would be safe. + unsafe { Step::forward_unchecked(self.0.start.clone(), idx) } + } +} + +#[unstable(feature = "new_range_api", issue = "125687")] +impl DoubleEndedIterator for IterRange { + #[inline] + fn next_back(&mut self) -> Option { + self.0.next_back() + } + + #[inline] + fn nth_back(&mut self, n: usize) -> Option { + self.0.nth_back(n) + } + + #[inline] + fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero> { + self.0.advance_back_by(n) + } +} + +#[unstable(feature = "trusted_len", issue = "37572")] +unsafe impl TrustedLen for IterRange {} + +#[unstable(feature = "new_range_api", issue = "125687")] +impl FusedIterator for IterRange {} + +#[unstable(feature = "new_range_api", issue = "125687")] +impl IntoIterator for Range { + type Item = A; + type IntoIter = IterRange; + + fn into_iter(self) -> Self::IntoIter { + IterRange(self.into()) + } +} + +/// By-value [`RangeInclusive`] iterator. +#[unstable(feature = "new_range_api", issue = "125687")] +#[derive(Debug, Clone)] +pub struct IterRangeInclusive(legacy::RangeInclusive); + +impl IterRangeInclusive { + /// Returns the remainder of the range being iterated over. + /// + /// If the iterator is exhausted or empty, returns `None`. + pub fn remainder(self) -> Option> { + if self.0.is_empty() { + return None; + } + + Some(RangeInclusive { start: self.0.start, end: self.0.end }) + } +} + +#[unstable(feature = "trusted_random_access", issue = "none")] +impl Iterator for IterRangeInclusive { + type Item = A; + + #[inline] + fn next(&mut self) -> Option { + self.0.next() + } + + #[inline] + fn size_hint(&self) -> (usize, Option) { + self.0.size_hint() + } + + #[inline] + fn count(self) -> usize { + self.0.count() + } + + #[inline] + fn nth(&mut self, n: usize) -> Option { + self.0.nth(n) + } + + #[inline] + fn last(self) -> Option { + self.0.last() + } + + #[inline] + fn min(self) -> Option + where + A: Ord, + { + self.0.min() + } + + #[inline] + fn max(self) -> Option + where + A: Ord, + { + self.0.max() + } + + #[inline] + fn is_sorted(self) -> bool { + true + } + + #[inline] + fn advance_by(&mut self, n: usize) -> Result<(), NonZero> { + self.0.advance_by(n) + } +} + +#[unstable(feature = "new_range_api", issue = "125687")] +impl DoubleEndedIterator for IterRangeInclusive { + #[inline] + fn next_back(&mut self) -> Option { + self.0.next_back() + } + + #[inline] + fn nth_back(&mut self, n: usize) -> Option { + self.0.nth_back(n) + } + + #[inline] + fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero> { + self.0.advance_back_by(n) + } +} + +#[unstable(feature = "trusted_len", issue = "37572")] +unsafe impl TrustedLen for IterRangeInclusive {} + +#[unstable(feature = "new_range_api", issue = "125687")] +impl FusedIterator for IterRangeInclusive {} + +#[unstable(feature = "new_range_api", issue = "125687")] +impl IntoIterator for RangeInclusive { + type Item = A; + type IntoIter = IterRangeInclusive; + + fn into_iter(self) -> Self::IntoIter { + IterRangeInclusive(self.into()) + } +} + +// These macros generate `ExactSizeIterator` impls for various range types. +// +// * `ExactSizeIterator::len` is required to always return an exact `usize`, +// so no range can be longer than `usize::MAX`. +// * For integer types in `Range<_>` this is the case for types narrower than or as wide as `usize`. +// For integer types in `RangeInclusive<_>` +// this is the case for types *strictly narrower* than `usize` +// since e.g. `(0..=u64::MAX).len()` would be `u64::MAX + 1`. +macro_rules! range_exact_iter_impl { + ($($t:ty)*) => ($( + #[unstable(feature = "new_range_api", issue = "125687")] + impl ExactSizeIterator for IterRange<$t> { } + )*) +} + +macro_rules! range_incl_exact_iter_impl { + ($($t:ty)*) => ($( + #[unstable(feature = "new_range_api", issue = "125687")] + impl ExactSizeIterator for IterRangeInclusive<$t> { } + )*) +} + +range_exact_iter_impl! { + usize u8 u16 + isize i8 i16 +} + +range_incl_exact_iter_impl! { + u8 + i8 +} + +/// By-value [`RangeFrom`] iterator. +#[unstable(feature = "new_range_api", issue = "125687")] +#[derive(Debug, Clone)] +pub struct IterRangeFrom(legacy::RangeFrom); + +impl IterRangeFrom { + /// Returns the remainder of the range being iterated over. + pub fn remainder(self) -> RangeFrom { + RangeFrom { start: self.0.start } + } +} + +#[unstable(feature = "trusted_random_access", issue = "none")] +impl Iterator for IterRangeFrom { + type Item = A; + + #[inline] + fn next(&mut self) -> Option { + self.0.next() + } + + #[inline] + fn size_hint(&self) -> (usize, Option) { + self.0.size_hint() + } + + #[inline] + fn nth(&mut self, n: usize) -> Option { + self.0.nth(n) + } +} + +#[unstable(feature = "trusted_len", issue = "37572")] +unsafe impl TrustedLen for IterRangeFrom {} + +#[unstable(feature = "new_range_api", issue = "125687")] +impl FusedIterator for IterRangeFrom {} + +#[unstable(feature = "new_range_api", issue = "125687")] +impl IntoIterator for RangeFrom { + type Item = A; + type IntoIter = IterRangeFrom; + + fn into_iter(self) -> Self::IntoIter { + IterRangeFrom(self.into()) + } +} diff --git a/library/core/src/range/legacy.rs b/library/core/src/range/legacy.rs new file mode 100644 index 0000000000000..6723c4903f756 --- /dev/null +++ b/library/core/src/range/legacy.rs @@ -0,0 +1,10 @@ +//! # Legacy range types +//! +//! The types within this module will be replaced by the types +//! [`Range`], [`RangeInclusive`], and [`RangeFrom`] in the parent +//! module, [`core::range`]. +//! +//! The types here are equivalent to those in [`core::ops`]. + +#[doc(inline)] +pub use crate::ops::{Range, RangeFrom, RangeInclusive}; diff --git a/library/core/src/slice/index.rs b/library/core/src/slice/index.rs index 143dbd8a496d0..2624a44bb4bcb 100644 --- a/library/core/src/slice/index.rs +++ b/library/core/src/slice/index.rs @@ -2,6 +2,7 @@ use crate::intrinsics::const_eval_select; use crate::ops; +use crate::range; use crate::ub_checks::assert_unsafe_precondition; #[stable(feature = "rust1", since = "1.0.0")] @@ -147,7 +148,8 @@ const unsafe fn get_offset_len_mut_noubcheck( } mod private_slice_index { - use super::ops; + use super::{ops, range}; + #[stable(feature = "slice_get_slice", since = "1.28.0")] pub trait Sealed {} @@ -168,6 +170,13 @@ mod private_slice_index { #[stable(feature = "slice_index_with_ops_bound_pair", since = "1.53.0")] impl Sealed for (ops::Bound, ops::Bound) {} + #[unstable(feature = "new_range_api", issue = "125687")] + impl Sealed for range::Range {} + #[unstable(feature = "new_range_api", issue = "125687")] + impl Sealed for range::RangeInclusive {} + #[unstable(feature = "new_range_api", issue = "125687")] + impl Sealed for range::RangeFrom {} + impl Sealed for ops::IndexRange {} } @@ -473,6 +482,43 @@ unsafe impl SliceIndex<[T]> for ops::Range { } } +#[unstable(feature = "new_range_api", issue = "125687")] +unsafe impl SliceIndex<[T]> for range::Range { + type Output = [T]; + + #[inline] + fn get(self, slice: &[T]) -> Option<&[T]> { + ops::Range::from(self).get(slice) + } + + #[inline] + fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> { + ops::Range::from(self).get_mut(slice) + } + + #[inline] + unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] { + // SAFETY: the caller has to uphold the safety contract for `get_unchecked`. + unsafe { ops::Range::from(self).get_unchecked(slice) } + } + + #[inline] + unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] { + // SAFETY: the caller has to uphold the safety contract for `get_unchecked_mut`. + unsafe { ops::Range::from(self).get_unchecked_mut(slice) } + } + + #[inline(always)] + fn index(self, slice: &[T]) -> &[T] { + ops::Range::from(self).index(slice) + } + + #[inline] + fn index_mut(self, slice: &mut [T]) -> &mut [T] { + ops::Range::from(self).index_mut(slice) + } +} + /// The methods `index` and `index_mut` panic if the end of the range is out of bounds. #[stable(feature = "slice_get_slice_impls", since = "1.15.0")] #[rustc_const_unstable(feature = "const_slice_index", issue = "none")] @@ -559,6 +605,43 @@ unsafe impl SliceIndex<[T]> for ops::RangeFrom { } } +#[unstable(feature = "new_range_api", issue = "125687")] +unsafe impl SliceIndex<[T]> for range::RangeFrom { + type Output = [T]; + + #[inline] + fn get(self, slice: &[T]) -> Option<&[T]> { + ops::RangeFrom::from(self).get(slice) + } + + #[inline] + fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> { + ops::RangeFrom::from(self).get_mut(slice) + } + + #[inline] + unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] { + // SAFETY: the caller has to uphold the safety contract for `get_unchecked`. + unsafe { ops::RangeFrom::from(self).get_unchecked(slice) } + } + + #[inline] + unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] { + // SAFETY: the caller has to uphold the safety contract for `get_unchecked_mut`. + unsafe { ops::RangeFrom::from(self).get_unchecked_mut(slice) } + } + + #[inline] + fn index(self, slice: &[T]) -> &[T] { + ops::RangeFrom::from(self).index(slice) + } + + #[inline] + fn index_mut(self, slice: &mut [T]) -> &mut [T] { + ops::RangeFrom::from(self).index_mut(slice) + } +} + #[stable(feature = "slice_get_slice_impls", since = "1.15.0")] #[rustc_const_unstable(feature = "const_slice_index", issue = "none")] unsafe impl SliceIndex<[T]> for ops::RangeFull { @@ -643,6 +726,43 @@ unsafe impl SliceIndex<[T]> for ops::RangeInclusive { } } +#[unstable(feature = "new_range_api", issue = "125687")] +unsafe impl SliceIndex<[T]> for range::RangeInclusive { + type Output = [T]; + + #[inline] + fn get(self, slice: &[T]) -> Option<&[T]> { + ops::RangeInclusive::from(self).get(slice) + } + + #[inline] + fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> { + ops::RangeInclusive::from(self).get_mut(slice) + } + + #[inline] + unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] { + // SAFETY: the caller has to uphold the safety contract for `get_unchecked`. + unsafe { ops::RangeInclusive::from(self).get_unchecked(slice) } + } + + #[inline] + unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] { + // SAFETY: the caller has to uphold the safety contract for `get_unchecked_mut`. + unsafe { ops::RangeInclusive::from(self).get_unchecked_mut(slice) } + } + + #[inline] + fn index(self, slice: &[T]) -> &[T] { + ops::RangeInclusive::from(self).index(slice) + } + + #[inline] + fn index_mut(self, slice: &mut [T]) -> &mut [T] { + ops::RangeInclusive::from(self).index_mut(slice) + } +} + /// The methods `index` and `index_mut` panic if the end of the range is out of bounds. #[stable(feature = "inclusive_range", since = "1.26.0")] #[rustc_const_unstable(feature = "const_slice_index", issue = "none")] @@ -780,7 +900,7 @@ where /// Performs bounds-checking of a range without panicking. /// -/// This is a version of [`range`] that returns [`None`] instead of panicking. +/// This is a version of [`range()`] that returns [`None`] instead of panicking. /// /// # Examples /// diff --git a/library/core/src/str/traits.rs b/library/core/src/str/traits.rs index ba2d6f644962e..3de5546c4d4e3 100644 --- a/library/core/src/str/traits.rs +++ b/library/core/src/str/traits.rs @@ -4,6 +4,7 @@ use crate::cmp::Ordering; use crate::intrinsics::unchecked_sub; use crate::ops; use crate::ptr; +use crate::range; use crate::slice::SliceIndex; use crate::ub_checks::assert_unsafe_precondition; @@ -261,6 +262,108 @@ unsafe impl SliceIndex for ops::Range { } } +#[unstable(feature = "new_range_api", issue = "125687")] +unsafe impl SliceIndex for range::Range { + type Output = str; + #[inline] + fn get(self, slice: &str) -> Option<&Self::Output> { + if self.start <= self.end + && slice.is_char_boundary(self.start) + && slice.is_char_boundary(self.end) + { + // SAFETY: just checked that `start` and `end` are on a char boundary, + // and we are passing in a safe reference, so the return value will also be one. + // We also checked char boundaries, so this is valid UTF-8. + Some(unsafe { &*self.get_unchecked(slice) }) + } else { + None + } + } + #[inline] + fn get_mut(self, slice: &mut str) -> Option<&mut Self::Output> { + if self.start <= self.end + && slice.is_char_boundary(self.start) + && slice.is_char_boundary(self.end) + { + // SAFETY: just checked that `start` and `end` are on a char boundary. + // We know the pointer is unique because we got it from `slice`. + Some(unsafe { &mut *self.get_unchecked_mut(slice) }) + } else { + None + } + } + #[inline] + unsafe fn get_unchecked(self, slice: *const str) -> *const Self::Output { + let slice = slice as *const [u8]; + + assert_unsafe_precondition!( + // We'd like to check that the bounds are on char boundaries, + // but there's not really a way to do so without reading + // behind the pointer, which has aliasing implications. + // It's also not possible to move this check up to + // `str::get_unchecked` without adding a special function + // to `SliceIndex` just for this. + check_library_ub, + "str::get_unchecked requires that the range is within the string slice", + ( + start: usize = self.start, + end: usize = self.end, + len: usize = slice.len() + ) => end >= start && end <= len, + ); + + // SAFETY: the caller guarantees that `self` is in bounds of `slice` + // which satisfies all the conditions for `add`. + unsafe { + let new_len = unchecked_sub(self.end, self.start); + ptr::slice_from_raw_parts(slice.as_ptr().add(self.start), new_len) as *const str + } + } + #[inline] + unsafe fn get_unchecked_mut(self, slice: *mut str) -> *mut Self::Output { + let slice = slice as *mut [u8]; + + assert_unsafe_precondition!( + check_library_ub, + "str::get_unchecked_mut requires that the range is within the string slice", + ( + start: usize = self.start, + end: usize = self.end, + len: usize = slice.len() + ) => end >= start && end <= len, + ); + + // SAFETY: see comments for `get_unchecked`. + unsafe { + let new_len = unchecked_sub(self.end, self.start); + ptr::slice_from_raw_parts_mut(slice.as_mut_ptr().add(self.start), new_len) as *mut str + } + } + #[inline] + fn index(self, slice: &str) -> &Self::Output { + let (start, end) = (self.start, self.end); + match self.get(slice) { + Some(s) => s, + None => super::slice_error_fail(slice, start, end), + } + } + #[inline] + fn index_mut(self, slice: &mut str) -> &mut Self::Output { + // is_char_boundary checks that the index is in [0, .len()] + // cannot reuse `get` as above, because of NLL trouble + if self.start <= self.end + && slice.is_char_boundary(self.start) + && slice.is_char_boundary(self.end) + { + // SAFETY: just checked that `start` and `end` are on a char boundary, + // and we are passing in a safe reference, so the return value will also be one. + unsafe { &mut *self.get_unchecked_mut(slice) } + } else { + super::slice_error_fail(slice, self.start, self.end) + } + } +} + /// Implements substring slicing for arbitrary bounds. /// /// Returns a slice of the given string bounded by the byte indices @@ -453,6 +556,61 @@ unsafe impl SliceIndex for ops::RangeFrom { } } +#[unstable(feature = "new_range_api", issue = "125687")] +unsafe impl SliceIndex for range::RangeFrom { + type Output = str; + #[inline] + fn get(self, slice: &str) -> Option<&Self::Output> { + if slice.is_char_boundary(self.start) { + // SAFETY: just checked that `start` is on a char boundary, + // and we are passing in a safe reference, so the return value will also be one. + Some(unsafe { &*self.get_unchecked(slice) }) + } else { + None + } + } + #[inline] + fn get_mut(self, slice: &mut str) -> Option<&mut Self::Output> { + if slice.is_char_boundary(self.start) { + // SAFETY: just checked that `start` is on a char boundary, + // and we are passing in a safe reference, so the return value will also be one. + Some(unsafe { &mut *self.get_unchecked_mut(slice) }) + } else { + None + } + } + #[inline] + unsafe fn get_unchecked(self, slice: *const str) -> *const Self::Output { + let len = (slice as *const [u8]).len(); + // SAFETY: the caller has to uphold the safety contract for `get_unchecked`. + unsafe { (self.start..len).get_unchecked(slice) } + } + #[inline] + unsafe fn get_unchecked_mut(self, slice: *mut str) -> *mut Self::Output { + let len = (slice as *mut [u8]).len(); + // SAFETY: the caller has to uphold the safety contract for `get_unchecked_mut`. + unsafe { (self.start..len).get_unchecked_mut(slice) } + } + #[inline] + fn index(self, slice: &str) -> &Self::Output { + let (start, end) = (self.start, slice.len()); + match self.get(slice) { + Some(s) => s, + None => super::slice_error_fail(slice, start, end), + } + } + #[inline] + fn index_mut(self, slice: &mut str) -> &mut Self::Output { + if slice.is_char_boundary(self.start) { + // SAFETY: just checked that `start` is on a char boundary, + // and we are passing in a safe reference, so the return value will also be one. + unsafe { &mut *self.get_unchecked_mut(slice) } + } else { + super::slice_error_fail(slice, self.start, slice.len()) + } + } +} + /// Implements substring slicing with syntax `&self[begin ..= end]` or `&mut /// self[begin ..= end]`. /// @@ -507,6 +665,43 @@ unsafe impl SliceIndex for ops::RangeInclusive { } } +#[unstable(feature = "new_range_api", issue = "125687")] +unsafe impl SliceIndex for range::RangeInclusive { + type Output = str; + #[inline] + fn get(self, slice: &str) -> Option<&Self::Output> { + if self.end == usize::MAX { None } else { self.into_slice_range().get(slice) } + } + #[inline] + fn get_mut(self, slice: &mut str) -> Option<&mut Self::Output> { + if self.end == usize::MAX { None } else { self.into_slice_range().get_mut(slice) } + } + #[inline] + unsafe fn get_unchecked(self, slice: *const str) -> *const Self::Output { + // SAFETY: the caller must uphold the safety contract for `get_unchecked`. + unsafe { self.into_slice_range().get_unchecked(slice) } + } + #[inline] + unsafe fn get_unchecked_mut(self, slice: *mut str) -> *mut Self::Output { + // SAFETY: the caller must uphold the safety contract for `get_unchecked_mut`. + unsafe { self.into_slice_range().get_unchecked_mut(slice) } + } + #[inline] + fn index(self, slice: &str) -> &Self::Output { + if self.end == usize::MAX { + str_index_overflow_fail(); + } + self.into_slice_range().index(slice) + } + #[inline] + fn index_mut(self, slice: &mut str) -> &mut Self::Output { + if self.end == usize::MAX { + str_index_overflow_fail(); + } + self.into_slice_range().index_mut(slice) + } +} + /// Implements substring slicing with syntax `&self[..= end]` or `&mut /// self[..= end]`. /// diff --git a/src/tools/linkchecker/main.rs b/src/tools/linkchecker/main.rs index 7321bd1bb52f2..72ae3ed26e89f 100644 --- a/src/tools/linkchecker/main.rs +++ b/src/tools/linkchecker/main.rs @@ -59,6 +59,8 @@ const INTRA_DOC_LINK_EXCEPTIONS: &[(&str, &[&str])] = &[ // This is being used in the sense of 'inclusive range', not a markdown link ("core/ops/struct.RangeInclusive.html", &["begin, end"]), ("std/ops/struct.RangeInclusive.html", &["begin, end"]), + ("core/range/legacy/struct.RangeInclusive.html", &["begin, end"]), + ("std/range/legacy/struct.RangeInclusive.html", &["begin, end"]), ("core/slice/trait.SliceIndex.html", &["begin, end"]), ("alloc/slice/trait.SliceIndex.html", &["begin, end"]), ("std/slice/trait.SliceIndex.html", &["begin, end"]), diff --git a/tests/ui/range/issue-54505-no-std.stderr b/tests/ui/range/issue-54505-no-std.stderr index 1694d514f4251..f15a0ae61389a 100644 --- a/tests/ui/range/issue-54505-no-std.stderr +++ b/tests/ui/range/issue-54505-no-std.stderr @@ -7,7 +7,7 @@ LL | take_range(0..1); | arguments to this function are incorrect | = note: expected reference `&_` - found struct `Range<{integer}>` + found struct `core::ops::Range<{integer}>` note: function defined here --> $DIR/issue-54505-no-std.rs:25:4 | @@ -27,7 +27,7 @@ LL | take_range(1..); | arguments to this function are incorrect | = note: expected reference `&_` - found struct `RangeFrom<{integer}>` + found struct `core::ops::RangeFrom<{integer}>` note: function defined here --> $DIR/issue-54505-no-std.rs:25:4 | @@ -67,7 +67,7 @@ LL | take_range(0..=1); | arguments to this function are incorrect | = note: expected reference `&_` - found struct `RangeInclusive<{integer}>` + found struct `core::ops::RangeInclusive<{integer}>` note: function defined here --> $DIR/issue-54505-no-std.rs:25:4 | From 6aebb2cfec13f42e6dbae95416074f3040054b0d Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Fri, 5 Jul 2024 22:54:42 +0000 Subject: [PATCH 760/892] Add test. --- tests/ui/mir/alignment/misaligned-constant-gvn.rs | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 tests/ui/mir/alignment/misaligned-constant-gvn.rs diff --git a/tests/ui/mir/alignment/misaligned-constant-gvn.rs b/tests/ui/mir/alignment/misaligned-constant-gvn.rs new file mode 100644 index 0000000000000..363d5c0ed34c6 --- /dev/null +++ b/tests/ui/mir/alignment/misaligned-constant-gvn.rs @@ -0,0 +1,8 @@ +//@ build-pass +//@ compile-flags: -Zmir-opt-level=0 -Zmir-enable-passes=+GVN + +fn main() { + let variant: Option = None; + let transmuted: u64 = unsafe { std::mem::transmute(variant) }; + println!("{transmuted}"); +} From b97f83b27fb23a0930630f23e3c113b8b542a43d Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Fri, 5 Jul 2024 22:55:09 +0000 Subject: [PATCH 761/892] Verify that allocations output by GVN are sufficiently aligned. --- compiler/rustc_mir_transform/src/gvn.rs | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_mir_transform/src/gvn.rs b/compiler/rustc_mir_transform/src/gvn.rs index 2b7d9be6d350b..2c20c75df1f12 100644 --- a/compiler/rustc_mir_transform/src/gvn.rs +++ b/compiler/rustc_mir_transform/src/gvn.rs @@ -1391,11 +1391,15 @@ fn op_to_prop_const<'tcx>( let (prov, offset) = pointer.into_parts(); let alloc_id = prov.alloc_id(); intern_const_alloc_for_constprop(ecx, alloc_id).ok()?; - if matches!(ecx.tcx.global_alloc(alloc_id), GlobalAlloc::Memory(_)) { - // `alloc_id` may point to a static. Codegen will choke on an `Indirect` with anything - // by `GlobalAlloc::Memory`, so do fall through to copying if needed. - // FIXME: find a way to treat this more uniformly - // (probably by fixing codegen) + + // `alloc_id` may point to a static. Codegen will choke on an `Indirect` with anything + // by `GlobalAlloc::Memory`, so do fall through to copying if needed. + // FIXME: find a way to treat this more uniformly (probably by fixing codegen) + if let GlobalAlloc::Memory(alloc) = ecx.tcx.global_alloc(alloc_id) + // Transmuting a constant is just an offset in the allocation. If the alignement of the + // allocation is noe enough, fallback to copying into a properly aligned value. + && alloc.inner().align >= op.layout.align.abi + { return Some(ConstValue::Indirect { alloc_id, offset }); } } From 99429a6a18cbc671c313ac8df17aa163729bc284 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 5 Jul 2024 16:02:35 -0400 Subject: [PATCH 762/892] Split out transitive_bounds_that_define_assoc_item --- compiler/rustc_infer/src/traits/util.rs | 39 ++++++++++++++++--------- 1 file changed, 25 insertions(+), 14 deletions(-) diff --git a/compiler/rustc_infer/src/traits/util.rs b/compiler/rustc_infer/src/traits/util.rs index def341beceb9d..18d36c3a5df34 100644 --- a/compiler/rustc_infer/src/traits/util.rs +++ b/compiler/rustc_infer/src/traits/util.rs @@ -3,6 +3,7 @@ use smallvec::smallvec; use crate::infer::outlives::components::{push_outlives_components, Component}; use crate::traits::{self, Obligation, ObligationCauseCode, PredicateObligation}; use rustc_data_structures::fx::FxHashSet; +use rustc_middle::ty::ToPolyTraitRef; use rustc_middle::ty::{self, Ty, TyCtxt, Upcast}; use rustc_span::symbol::Ident; use rustc_span::Span; @@ -82,7 +83,6 @@ pub struct Elaborator<'tcx, O> { enum Filter { All, OnlySelf, - OnlySelfThatDefines(Ident), } /// Describes how to elaborate an obligation into a sub-obligation. @@ -252,12 +252,6 @@ impl<'tcx, O: Elaboratable<'tcx>> Elaborator<'tcx, O> { self } - /// Filter to only the supertraits of trait predicates that define the assoc_ty. - pub fn filter_only_self_that_defines(mut self, assoc_ty: Ident) -> Self { - self.mode = Filter::OnlySelfThatDefines(assoc_ty); - self - } - fn elaborate(&mut self, elaboratable: &O) { let tcx = self.visited.tcx; @@ -277,9 +271,6 @@ impl<'tcx, O: Elaboratable<'tcx>> Elaborator<'tcx, O> { let predicates = match self.mode { Filter::All => tcx.explicit_implied_predicates_of(data.def_id()), Filter::OnlySelf => tcx.explicit_super_predicates_of(data.def_id()), - Filter::OnlySelfThatDefines(ident) => { - tcx.explicit_supertraits_containing_assoc_item((data.def_id(), ident)) - } }; let obligations = @@ -427,10 +418,30 @@ pub fn transitive_bounds_that_define_assoc_item<'tcx>( tcx: TyCtxt<'tcx>, trait_refs: impl Iterator>, assoc_name: Ident, -) -> FilterToTraits>> { - elaborate(tcx, trait_refs.map(|trait_ref| trait_ref.upcast(tcx))) - .filter_only_self_that_defines(assoc_name) - .filter_to_traits() +) -> impl Iterator> { + let mut seen = FxHashSet::default(); + let mut stack: Vec<_> = trait_refs.collect(); + + std::iter::from_fn(move || { + while let Some(trait_ref) = stack.pop() { + if !seen.insert(tcx.anonymize_bound_vars(trait_ref)) { + continue; + } + + stack.extend( + tcx.explicit_supertraits_containing_assoc_item((trait_ref.def_id(), assoc_name)) + .instantiate_own_identity() + .map(|(clause, _)| clause.instantiate_supertrait(tcx, trait_ref)) + .filter_map(|clause| clause.as_trait_clause()) + // FIXME: Negative supertraits are elaborated here lol + .map(|trait_pred| trait_pred.to_poly_trait_ref()), + ); + + return Some(trait_ref); + } + + None + }) } /////////////////////////////////////////////////////////////////////////// From 09b3fcebf4939d19635b17a04a3d108a29b65149 Mon Sep 17 00:00:00 2001 From: trevyn <230691+trevyn@users.noreply.github.com> Date: Sat, 6 Jul 2024 09:13:14 +0300 Subject: [PATCH 763/892] Correct description of E0502 --- compiler/rustc_error_codes/src/error_codes/E0502.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_error_codes/src/error_codes/E0502.md b/compiler/rustc_error_codes/src/error_codes/E0502.md index dc3ffdfddd9de..85f38b9286f91 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0502.md +++ b/compiler/rustc_error_codes/src/error_codes/E0502.md @@ -1,4 +1,5 @@ -A variable already borrowed as immutable was borrowed as mutable. +A variable already borrowed with a certain mutability (either mutable or +immutable) was borrowed again with a different mutability. Erroneous code example: @@ -13,7 +14,7 @@ fn foo(a: &mut i32) { ``` To fix this error, ensure that you don't have any other references to the -variable before trying to access it mutably: +variable before trying to access it with a different mutability: ``` fn bar(x: &mut i32) {} From 12edc8db876515e6922623006c9b8d0c34b15f51 Mon Sep 17 00:00:00 2001 From: Camille Gillot Date: Sat, 6 Jul 2024 12:45:23 +0200 Subject: [PATCH 764/892] Update compiler/rustc_mir_transform/src/gvn.rs Co-authored-by: Michael Goulet --- compiler/rustc_mir_transform/src/gvn.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_mir_transform/src/gvn.rs b/compiler/rustc_mir_transform/src/gvn.rs index 2c20c75df1f12..1002746e553d7 100644 --- a/compiler/rustc_mir_transform/src/gvn.rs +++ b/compiler/rustc_mir_transform/src/gvn.rs @@ -1396,8 +1396,8 @@ fn op_to_prop_const<'tcx>( // by `GlobalAlloc::Memory`, so do fall through to copying if needed. // FIXME: find a way to treat this more uniformly (probably by fixing codegen) if let GlobalAlloc::Memory(alloc) = ecx.tcx.global_alloc(alloc_id) - // Transmuting a constant is just an offset in the allocation. If the alignement of the - // allocation is noe enough, fallback to copying into a properly aligned value. + // Transmuting a constant is just an offset in the allocation. If the alignment of the + // allocation is not enough, fallback to copying into a properly aligned value. && alloc.inner().align >= op.layout.align.abi { return Some(ConstValue::Indirect { alloc_id, offset }); From 0184c6f52e727f1ac3053f6abb5b25b38d4ab045 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sat, 6 Jul 2024 11:49:52 +0000 Subject: [PATCH 765/892] Cache hir_owner_nodes in ParentHirIterator. --- compiler/rustc_middle/src/hir/map/mod.rs | 34 ++++++++++++++++++------ 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs index 305ba1ef3bbc8..2f3a6ee601b15 100644 --- a/compiler/rustc_middle/src/hir/map/mod.rs +++ b/compiler/rustc_middle/src/hir/map/mod.rs @@ -31,9 +31,18 @@ pub struct Map<'hir> { /// An iterator that walks up the ancestor tree of a given `HirId`. /// Constructed using `tcx.hir().parent_iter(hir_id)`. -pub struct ParentHirIterator<'hir> { +struct ParentHirIterator<'hir> { current_id: HirId, map: Map<'hir>, + // Cache the current value of `hir_owner_nodes` to avoid repeatedly calling the same query for + // the same owner, which will uselessly record many times the same query dependency. + current_owner_nodes: Option<&'hir OwnerNodes<'hir>>, +} + +impl<'hir> ParentHirIterator<'hir> { + fn new(map: Map<'hir>, current_id: HirId) -> ParentHirIterator<'hir> { + ParentHirIterator { current_id, map, current_owner_nodes: None } + } } impl<'hir> Iterator for ParentHirIterator<'hir> { @@ -44,13 +53,22 @@ impl<'hir> Iterator for ParentHirIterator<'hir> { return None; } - // There are nodes that do not have entries, so we need to skip them. - let parent_id = self.map.tcx.parent_hir_id(self.current_id); + let HirId { owner, local_id } = self.current_id; - if parent_id == self.current_id { - self.current_id = CRATE_HIR_ID; - return None; - } + let parent_id = if local_id == ItemLocalId::ZERO { + // We go from an owner to its parent, so clear the cache. + self.current_owner_nodes = None; + self.map.tcx.hir_owner_parent(owner) + } else { + let owner_nodes = + self.current_owner_nodes.get_or_insert_with(|| self.map.tcx.hir_owner_nodes(owner)); + let parent_local_id = owner_nodes.nodes[local_id].parent; + // HIR indexing should have checked that. + debug_assert_ne!(parent_local_id, local_id); + HirId { owner, local_id: parent_local_id } + }; + + debug_assert_ne!(parent_id, self.current_id); self.current_id = parent_id; return Some(parent_id); @@ -479,7 +497,7 @@ impl<'hir> Map<'hir> { /// until the crate root is reached. Prefer this over your own loop using `parent_id`. #[inline] pub fn parent_id_iter(self, current_id: HirId) -> impl Iterator + 'hir { - ParentHirIterator { current_id, map: self } + ParentHirIterator::new(self, current_id) } /// Returns an iterator for the nodes in the ancestor tree of the `current_id` From 3e9c9a05a825005cf0b199d4f68edf8817599ade Mon Sep 17 00:00:00 2001 From: lukas Date: Thu, 4 Jul 2024 16:47:20 +0200 Subject: [PATCH 766/892] Mark format! with must_use hint --- .../alloc/src/collections/btree/map/tests.rs | 18 ++--- .../alloc/src/collections/btree/set/tests.rs | 6 +- library/alloc/src/fmt.rs | 4 ++ library/alloc/src/lib.rs | 1 + library/alloc/src/macros.rs | 12 ++-- library/alloc/tests/fmt.rs | 10 +-- library/core/tests/fmt/builders.rs | 6 +- src/bootstrap/src/core/build_steps/llvm.rs | 6 +- src/bootstrap/src/core/builder.rs | 2 +- src/tools/clippy/tests/ui/or_fun_call.fixed | 2 +- src/tools/clippy/tests/ui/or_fun_call.stderr | 8 ++- src/tools/miri/tests/pass/intptrcast.rs | 4 +- src/tools/miri/tests/pass/packed_struct.rs | 2 +- src/tools/miri/tests/pass/shims/fs.rs | 4 +- src/tools/miri/tests/pass/shims/io.rs | 2 +- src/tools/miri/tests/pass/vecdeque.rs | 4 +- tests/pretty/issue-4264.pp | 21 +++--- tests/ui/deriving/deriving-in-fn.rs | 2 +- .../struct-field-as-captured-argument.fixed | 14 ++-- .../fmt/struct-field-as-captured-argument.rs | 14 ++-- .../struct-field-as-captured-argument.stderr | 70 +++++++++---------- tests/ui/issues/issue-20676.rs | 2 +- 22 files changed, 115 insertions(+), 99 deletions(-) diff --git a/library/alloc/src/collections/btree/map/tests.rs b/library/alloc/src/collections/btree/map/tests.rs index 56620cf890db7..ba1f38dcc3e52 100644 --- a/library/alloc/src/collections/btree/map/tests.rs +++ b/library/alloc/src/collections/btree/map/tests.rs @@ -1796,18 +1796,18 @@ fn test_ord_absence() { } fn map_debug(mut map: BTreeMap) { - format!("{map:?}"); - format!("{:?}", map.iter()); - format!("{:?}", map.iter_mut()); - format!("{:?}", map.keys()); - format!("{:?}", map.values()); - format!("{:?}", map.values_mut()); + let _ = format!("{map:?}"); + let _ = format!("{:?}", map.iter()); + let _ = format!("{:?}", map.iter_mut()); + let _ = format!("{:?}", map.keys()); + let _ = format!("{:?}", map.values()); + let _ = format!("{:?}", map.values_mut()); if true { - format!("{:?}", map.into_iter()); + let _ = format!("{:?}", map.into_iter()); } else if true { - format!("{:?}", map.into_keys()); + let _ = format!("{:?}", map.into_keys()); } else { - format!("{:?}", map.into_values()); + let _ = format!("{:?}", map.into_values()); } } diff --git a/library/alloc/src/collections/btree/set/tests.rs b/library/alloc/src/collections/btree/set/tests.rs index 688ce57e9da6a..48bf767413835 100644 --- a/library/alloc/src/collections/btree/set/tests.rs +++ b/library/alloc/src/collections/btree/set/tests.rs @@ -705,9 +705,9 @@ fn test_ord_absence() { } fn set_debug(set: BTreeSet) { - format!("{set:?}"); - format!("{:?}", set.iter()); - format!("{:?}", set.into_iter()); + let _ = format!("{set:?}"); + let _ = format!("{:?}", set.iter()); + let _ = format!("{:?}", set.into_iter()); } fn set_clone(mut set: BTreeSet) { diff --git a/library/alloc/src/fmt.rs b/library/alloc/src/fmt.rs index ae44cab8131b5..c6bba619ae646 100644 --- a/library/alloc/src/fmt.rs +++ b/library/alloc/src/fmt.rs @@ -12,6 +12,7 @@ //! Some examples of the [`format!`] extension are: //! //! ``` +//! # #![allow(unused_must_use)] //! format!("Hello"); // => "Hello" //! format!("Hello, {}!", "world"); // => "Hello, world!" //! format!("The number is {}", 1); // => "The number is 1" @@ -50,6 +51,7 @@ //! the iterator advances. This leads to behavior like this: //! //! ``` +//! # #![allow(unused_must_use)] //! format!("{1} {} {0} {}", 1, 2); // => "2 1 1 2" //! ``` //! @@ -77,6 +79,7 @@ //! For example, the following [`format!`] expressions all use named arguments: //! //! ``` +//! # #![allow(unused_must_use)] //! format!("{argument}", argument = "test"); // => "test" //! format!("{name} {}", 1, name = 2); // => "2 1" //! format!("{a} {c} {b}", a="a", b='b', c=3); // => "a 3 b" @@ -86,6 +89,7 @@ //! reference a variable with that name in the current scope. //! //! ``` +//! # #![allow(unused_must_use)] //! let argument = 2 + 2; //! format!("{argument}"); // => "4" //! diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs index 703538d0f355d..f7447f2dd8e8e 100644 --- a/library/alloc/src/lib.rs +++ b/library/alloc/src/lib.rs @@ -256,6 +256,7 @@ pub mod vec; #[unstable(feature = "liballoc_internals", issue = "none", reason = "implementation detail")] pub mod __export { pub use core::format_args; + pub use core::hint::must_use; } #[cfg(test)] diff --git a/library/alloc/src/macros.rs b/library/alloc/src/macros.rs index d5ca5c4ed27a2..8c6a367869ce0 100644 --- a/library/alloc/src/macros.rs +++ b/library/alloc/src/macros.rs @@ -111,6 +111,7 @@ macro_rules! vec { /// # Examples /// /// ``` +/// # #![allow(unused_must_use)] /// format!("test"); // => "test" /// format!("hello {}", "world!"); // => "hello world!" /// format!("x = {}, y = {val}", 10, val = 30); // => "x = 10, y = 30" @@ -119,10 +120,13 @@ macro_rules! vec { /// ``` #[macro_export] #[stable(feature = "rust1", since = "1.0.0")] +#[allow_internal_unstable(hint_must_use, liballoc_internals)] #[cfg_attr(not(test), rustc_diagnostic_item = "format_macro")] macro_rules! format { - ($($arg:tt)*) => {{ - let res = $crate::fmt::format($crate::__export::format_args!($($arg)*)); - res - }} + ($($arg:tt)*) => { + $crate::__export::must_use({ + let res = $crate::fmt::format($crate::__export::format_args!($($arg)*)); + res + }) + } } diff --git a/library/alloc/tests/fmt.rs b/library/alloc/tests/fmt.rs index 379e09ab69a3c..ce24a40f4c051 100644 --- a/library/alloc/tests/fmt.rs +++ b/library/alloc/tests/fmt.rs @@ -217,19 +217,19 @@ fn test_format_macro_interface() { // make sure that format! doesn't move out of local variables let a = Box::new(3); - format!("{a}"); - format!("{a}"); + let _ = format!("{a}"); + let _ = format!("{a}"); // make sure that format! doesn't cause spurious unused-unsafe warnings when // it's inside of an outer unsafe block unsafe { let a: isize = ::std::mem::transmute(3_usize); - format!("{a}"); + let _ = format!("{a}"); } // test that trailing commas are acceptable - format!("{}", "test",); - format!("{foo}", foo = "test",); + let _ = format!("{}", "test",); + let _ = format!("{foo}", foo = "test",); } // Basic test to make sure that we can invoke the `write!` macro with an diff --git a/library/core/tests/fmt/builders.rs b/library/core/tests/fmt/builders.rs index 487ce46be28d7..2bdc334b7c027 100644 --- a/library/core/tests/fmt/builders.rs +++ b/library/core/tests/fmt/builders.rs @@ -441,7 +441,7 @@ mod debug_map { } } - format!("{Foo:?}"); + let _ = format!("{Foo:?}"); } #[test] @@ -455,7 +455,7 @@ mod debug_map { } } - format!("{Foo:?}"); + let _ = format!("{Foo:?}"); } #[test] @@ -469,7 +469,7 @@ mod debug_map { } } - format!("{Foo:?}"); + let _ = format!("{Foo:?}"); } } diff --git a/src/bootstrap/src/core/build_steps/llvm.rs b/src/bootstrap/src/core/build_steps/llvm.rs index 4f1c1f87d1c6c..e467a89f7e1b9 100644 --- a/src/bootstrap/src/core/build_steps/llvm.rs +++ b/src/bootstrap/src/core/build_steps/llvm.rs @@ -755,7 +755,7 @@ fn configure_cmake( } if builder.config.llvm_clang_cl.is_some() { - cflags.push(&format!(" --target={target}")); + cflags.push(format!(" --target={target}")); } cfg.define("CMAKE_C_FLAGS", cflags); let mut cxxflags: OsString = builder @@ -774,7 +774,7 @@ fn configure_cmake( cxxflags.push(s); } if builder.config.llvm_clang_cl.is_some() { - cxxflags.push(&format!(" --target={target}")); + cxxflags.push(format!(" --target={target}")); } cfg.define("CMAKE_CXX_FLAGS", cxxflags); if let Some(ar) = builder.ar(target) { @@ -915,7 +915,7 @@ impl Step for Lld { // Find clang's runtime library directory and push that as a search path to the // cmake linker flags. let clang_rt_dir = get_clang_cl_resource_dir(clang_cl_path); - ldflags.push_all(&format!("/libpath:{}", clang_rt_dir.display())); + ldflags.push_all(format!("/libpath:{}", clang_rt_dir.display())); } } diff --git a/src/bootstrap/src/core/builder.rs b/src/bootstrap/src/core/builder.rs index 4da912994c3ee..a859e97033173 100644 --- a/src/bootstrap/src/core/builder.rs +++ b/src/bootstrap/src/core/builder.rs @@ -2527,7 +2527,7 @@ impl Cargo { if let Some(target_linker) = builder.linker(target) { let target = crate::envify(&target.triple); - self.command.env(&format!("CARGO_TARGET_{target}_LINKER"), target_linker); + self.command.env(format!("CARGO_TARGET_{target}_LINKER"), target_linker); } // We want to set -Clinker using Cargo, therefore we only call `linker_flags` and not // `linker_args` here. diff --git a/src/tools/clippy/tests/ui/or_fun_call.fixed b/src/tools/clippy/tests/ui/or_fun_call.fixed index 7657ef470c589..c76f7a81843b2 100644 --- a/src/tools/clippy/tests/ui/or_fun_call.fixed +++ b/src/tools/clippy/tests/ui/or_fun_call.fixed @@ -98,7 +98,7 @@ fn or_fun_call() { let opt = Some(1); let hello = "Hello"; - let _ = opt.ok_or(format!("{} world.", hello)); + let _ = opt.ok_or_else(|| format!("{} world.", hello)); // index let map = HashMap::::new(); diff --git a/src/tools/clippy/tests/ui/or_fun_call.stderr b/src/tools/clippy/tests/ui/or_fun_call.stderr index b5a30f2992316..3070db22fc5a6 100644 --- a/src/tools/clippy/tests/ui/or_fun_call.stderr +++ b/src/tools/clippy/tests/ui/or_fun_call.stderr @@ -100,6 +100,12 @@ error: use of `unwrap_or` to construct default value LL | let _ = stringy.unwrap_or(String::new()); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()` +error: use of `ok_or` followed by a function call + --> tests/ui/or_fun_call.rs:101:17 + | +LL | let _ = opt.ok_or(format!("{} world.", hello)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `ok_or_else(|| format!("{} world.", hello))` + error: use of `unwrap_or` followed by a function call --> tests/ui/or_fun_call.rs:105:21 | @@ -190,5 +196,5 @@ error: use of `unwrap_or_else` to construct default value LL | let _ = stringy.unwrap_or_else(String::new); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()` -error: aborting due to 31 previous errors +error: aborting due to 32 previous errors diff --git a/src/tools/miri/tests/pass/intptrcast.rs b/src/tools/miri/tests/pass/intptrcast.rs index 4e9fa12c18142..fb1a1dfae5d14 100644 --- a/src/tools/miri/tests/pass/intptrcast.rs +++ b/src/tools/miri/tests/pass/intptrcast.rs @@ -35,7 +35,7 @@ fn cast_dangling() { fn format() { // Pointer string formatting! We can't check the output as it changes when libstd changes, // but we can make sure Miri does not error. - format!("{:?}", &mut 13 as *mut _); + let _ = format!("{:?}", &mut 13 as *mut _); } fn transmute() { @@ -52,7 +52,7 @@ fn ptr_bitops1() { let one = bytes.as_ptr().wrapping_offset(1); let three = bytes.as_ptr().wrapping_offset(3); let res = (one as usize) | (three as usize); - format!("{}", res); + let _ = format!("{}", res); } fn ptr_bitops2() { diff --git a/src/tools/miri/tests/pass/packed_struct.rs b/src/tools/miri/tests/pass/packed_struct.rs index b86235e0c67f3..039eb5adef09f 100644 --- a/src/tools/miri/tests/pass/packed_struct.rs +++ b/src/tools/miri/tests/pass/packed_struct.rs @@ -138,7 +138,7 @@ fn test_derive() { assert_eq!(x.partial_cmp(&y).unwrap(), x.cmp(&y)); x.hash(&mut DefaultHasher::new()); P::default(); - format!("{:?}", x); + let _ = format!("{:?}", x); } fn main() { diff --git a/src/tools/miri/tests/pass/shims/fs.rs b/src/tools/miri/tests/pass/shims/fs.rs index 35980fad15dd0..16d3e8cab30ab 100644 --- a/src/tools/miri/tests/pass/shims/fs.rs +++ b/src/tools/miri/tests/pass/shims/fs.rs @@ -202,7 +202,7 @@ fn test_errors() { // Opening a non-existing file should fail with a "not found" error. assert_eq!(ErrorKind::NotFound, File::open(&path).unwrap_err().kind()); // Make sure we can also format this. - format!("{0}: {0:?}", File::open(&path).unwrap_err()); + let _ = format!("{0}: {0:?}", File::open(&path).unwrap_err()); // Removing a non-existing file should fail with a "not found" error. assert_eq!(ErrorKind::NotFound, remove_file(&path).unwrap_err().kind()); // Reading the metadata of a non-existing file should fail with a "not found" error. @@ -301,5 +301,5 @@ fn test_from_raw_os_error() { let error = Error::from_raw_os_error(code); assert!(matches!(error.kind(), ErrorKind::Uncategorized)); // Make sure we can also format this. - format!("{error:?}"); + let _ = format!("{error:?}"); } diff --git a/src/tools/miri/tests/pass/shims/io.rs b/src/tools/miri/tests/pass/shims/io.rs index d20fc75b79355..420ef95a0cbf4 100644 --- a/src/tools/miri/tests/pass/shims/io.rs +++ b/src/tools/miri/tests/pass/shims/io.rs @@ -15,5 +15,5 @@ fn main() { panic!("unsupported OS") }; let err = io::Error::from_raw_os_error(raw_os_error); - format!("{err}: {err:?}"); + let _ = format!("{err}: {err:?}"); } diff --git a/src/tools/miri/tests/pass/vecdeque.rs b/src/tools/miri/tests/pass/vecdeque.rs index 77c4ca5a04e6a..9153c428e184d 100644 --- a/src/tools/miri/tests/pass/vecdeque.rs +++ b/src/tools/miri/tests/pass/vecdeque.rs @@ -31,8 +31,8 @@ fn main() { } // Regression test for Debug impl's - format!("{:?} {:?}", dst, dst.iter()); - format!("{:?}", VecDeque::::new().iter()); + let _ = format!("{:?} {:?}", dst, dst.iter()); + let _ = format!("{:?}", VecDeque::::new().iter()); for a in dst { assert_eq!(*a, 2); diff --git a/tests/pretty/issue-4264.pp b/tests/pretty/issue-4264.pp index 018ccf82daebf..fa958d9f1e8f8 100644 --- a/tests/pretty/issue-4264.pp +++ b/tests/pretty/issue-4264.pp @@ -29,16 +29,17 @@ - ({ - let res = - ((::alloc::fmt::format as - for<'a> fn(Arguments<'a>) -> String {format})(((format_arguments::new_const - as - fn(&[&'static str; 1]) -> Arguments<'_> {Arguments::<'_>::new_const::<1>})((&([("test" - as &str)] as [&str; 1]) as &[&str; 1])) as Arguments<'_>)) - as String); - (res as String) - } as String); + ((::alloc::__export::must_use as + fn(String) -> String {must_use::})(({ + let res = + ((::alloc::fmt::format as + for<'a> fn(Arguments<'a>) -> String {format})(((format_arguments::new_const + as + fn(&[&'static str; 1]) -> Arguments<'_> {Arguments::<'_>::new_const::<1>})((&([("test" + as &str)] as [&str; 1]) as &[&str; 1])) as Arguments<'_>)) + as String); + (res as String) + } as String)) as String); } as ()) type Foo = [i32; (3 as usize)]; struct Bar { diff --git a/tests/ui/deriving/deriving-in-fn.rs b/tests/ui/deriving/deriving-in-fn.rs index 72da2148350fd..13f3d39597ce3 100644 --- a/tests/ui/deriving/deriving-in-fn.rs +++ b/tests/ui/deriving/deriving-in-fn.rs @@ -9,5 +9,5 @@ pub fn main() { } let f = Foo { foo: 10 }; - format!("{:?}", f); + let _ = format!("{:?}", f); } diff --git a/tests/ui/fmt/struct-field-as-captured-argument.fixed b/tests/ui/fmt/struct-field-as-captured-argument.fixed index e13af744ec869..0da40737354f7 100644 --- a/tests/ui/fmt/struct-field-as-captured-argument.fixed +++ b/tests/ui/fmt/struct-field-as-captured-argument.fixed @@ -8,11 +8,11 @@ struct Foo { fn main() { let foo = Foo { field: 0 }; let bar = 3; - format!("{0}", foo.field); //~ ERROR invalid format string: field access isn't supported - format!("{1} {} {bar}", "aa", foo.field); //~ ERROR invalid format string: field access isn't supported - format!("{2} {} {1} {bar}", "aa", "bb", foo.field); //~ ERROR invalid format string: field access isn't supported - format!("{1} {} {baz}", "aa", foo.field, baz = 3); //~ ERROR invalid format string: field access isn't supported - format!("{1:?} {} {baz}", "aa", foo.field, baz = 3); //~ ERROR invalid format string: field access isn't supported - format!("{1:#?} {} {baz}", "aa", foo.field, baz = 3); //~ ERROR invalid format string: field access isn't supported - format!("{1:.3} {} {baz}", "aa", foo.field, baz = 3); //~ ERROR invalid format string: field access isn't supported + let _ = format!("{0}", foo.field); //~ ERROR invalid format string: field access isn't supported + let _ = format!("{1} {} {bar}", "aa", foo.field); //~ ERROR invalid format string: field access isn't supported + let _ = format!("{2} {} {1} {bar}", "aa", "bb", foo.field); //~ ERROR invalid format string: field access isn't supported + let _ = format!("{1} {} {baz}", "aa", foo.field, baz = 3); //~ ERROR invalid format string: field access isn't supported + let _ = format!("{1:?} {} {baz}", "aa", foo.field, baz = 3); //~ ERROR invalid format string: field access isn't supported + let _ = format!("{1:#?} {} {baz}", "aa", foo.field, baz = 3); //~ ERROR invalid format string: field access isn't supported + let _ = format!("{1:.3} {} {baz}", "aa", foo.field, baz = 3); //~ ERROR invalid format string: field access isn't supported } diff --git a/tests/ui/fmt/struct-field-as-captured-argument.rs b/tests/ui/fmt/struct-field-as-captured-argument.rs index 6a875a85848f5..325b4e3a21878 100644 --- a/tests/ui/fmt/struct-field-as-captured-argument.rs +++ b/tests/ui/fmt/struct-field-as-captured-argument.rs @@ -8,11 +8,11 @@ struct Foo { fn main() { let foo = Foo { field: 0 }; let bar = 3; - format!("{foo.field}"); //~ ERROR invalid format string: field access isn't supported - format!("{foo.field} {} {bar}", "aa"); //~ ERROR invalid format string: field access isn't supported - format!("{foo.field} {} {1} {bar}", "aa", "bb"); //~ ERROR invalid format string: field access isn't supported - format!("{foo.field} {} {baz}", "aa", baz = 3); //~ ERROR invalid format string: field access isn't supported - format!("{foo.field:?} {} {baz}", "aa", baz = 3); //~ ERROR invalid format string: field access isn't supported - format!("{foo.field:#?} {} {baz}", "aa", baz = 3); //~ ERROR invalid format string: field access isn't supported - format!("{foo.field:.3} {} {baz}", "aa", baz = 3); //~ ERROR invalid format string: field access isn't supported + let _ = format!("{foo.field}"); //~ ERROR invalid format string: field access isn't supported + let _ = format!("{foo.field} {} {bar}", "aa"); //~ ERROR invalid format string: field access isn't supported + let _ = format!("{foo.field} {} {1} {bar}", "aa", "bb"); //~ ERROR invalid format string: field access isn't supported + let _ = format!("{foo.field} {} {baz}", "aa", baz = 3); //~ ERROR invalid format string: field access isn't supported + let _ = format!("{foo.field:?} {} {baz}", "aa", baz = 3); //~ ERROR invalid format string: field access isn't supported + let _ = format!("{foo.field:#?} {} {baz}", "aa", baz = 3); //~ ERROR invalid format string: field access isn't supported + let _ = format!("{foo.field:.3} {} {baz}", "aa", baz = 3); //~ ERROR invalid format string: field access isn't supported } diff --git a/tests/ui/fmt/struct-field-as-captured-argument.stderr b/tests/ui/fmt/struct-field-as-captured-argument.stderr index 7ea8b4068f272..4ef022cecb042 100644 --- a/tests/ui/fmt/struct-field-as-captured-argument.stderr +++ b/tests/ui/fmt/struct-field-as-captured-argument.stderr @@ -1,79 +1,79 @@ error: invalid format string: field access isn't supported - --> $DIR/struct-field-as-captured-argument.rs:11:15 + --> $DIR/struct-field-as-captured-argument.rs:11:23 | -LL | format!("{foo.field}"); - | ^^^^^^^^^ not supported in format string +LL | let _ = format!("{foo.field}"); + | ^^^^^^^^^ not supported in format string | help: consider using a positional formatting argument instead | -LL | format!("{0}", foo.field); - | ~ +++++++++++ +LL | let _ = format!("{0}", foo.field); + | ~ +++++++++++ error: invalid format string: field access isn't supported - --> $DIR/struct-field-as-captured-argument.rs:12:15 + --> $DIR/struct-field-as-captured-argument.rs:12:23 | -LL | format!("{foo.field} {} {bar}", "aa"); - | ^^^^^^^^^ not supported in format string +LL | let _ = format!("{foo.field} {} {bar}", "aa"); + | ^^^^^^^^^ not supported in format string | help: consider using a positional formatting argument instead | -LL | format!("{1} {} {bar}", "aa", foo.field); - | ~ +++++++++++ +LL | let _ = format!("{1} {} {bar}", "aa", foo.field); + | ~ +++++++++++ error: invalid format string: field access isn't supported - --> $DIR/struct-field-as-captured-argument.rs:13:15 + --> $DIR/struct-field-as-captured-argument.rs:13:23 | -LL | format!("{foo.field} {} {1} {bar}", "aa", "bb"); - | ^^^^^^^^^ not supported in format string +LL | let _ = format!("{foo.field} {} {1} {bar}", "aa", "bb"); + | ^^^^^^^^^ not supported in format string | help: consider using a positional formatting argument instead | -LL | format!("{2} {} {1} {bar}", "aa", "bb", foo.field); - | ~ +++++++++++ +LL | let _ = format!("{2} {} {1} {bar}", "aa", "bb", foo.field); + | ~ +++++++++++ error: invalid format string: field access isn't supported - --> $DIR/struct-field-as-captured-argument.rs:14:15 + --> $DIR/struct-field-as-captured-argument.rs:14:23 | -LL | format!("{foo.field} {} {baz}", "aa", baz = 3); - | ^^^^^^^^^ not supported in format string +LL | let _ = format!("{foo.field} {} {baz}", "aa", baz = 3); + | ^^^^^^^^^ not supported in format string | help: consider using a positional formatting argument instead | -LL | format!("{1} {} {baz}", "aa", foo.field, baz = 3); - | ~ +++++++++++ +LL | let _ = format!("{1} {} {baz}", "aa", foo.field, baz = 3); + | ~ +++++++++++ error: invalid format string: field access isn't supported - --> $DIR/struct-field-as-captured-argument.rs:15:15 + --> $DIR/struct-field-as-captured-argument.rs:15:23 | -LL | format!("{foo.field:?} {} {baz}", "aa", baz = 3); - | ^^^^^^^^^ not supported in format string +LL | let _ = format!("{foo.field:?} {} {baz}", "aa", baz = 3); + | ^^^^^^^^^ not supported in format string | help: consider using a positional formatting argument instead | -LL | format!("{1:?} {} {baz}", "aa", foo.field, baz = 3); - | ~ +++++++++++ +LL | let _ = format!("{1:?} {} {baz}", "aa", foo.field, baz = 3); + | ~ +++++++++++ error: invalid format string: field access isn't supported - --> $DIR/struct-field-as-captured-argument.rs:16:15 + --> $DIR/struct-field-as-captured-argument.rs:16:23 | -LL | format!("{foo.field:#?} {} {baz}", "aa", baz = 3); - | ^^^^^^^^^ not supported in format string +LL | let _ = format!("{foo.field:#?} {} {baz}", "aa", baz = 3); + | ^^^^^^^^^ not supported in format string | help: consider using a positional formatting argument instead | -LL | format!("{1:#?} {} {baz}", "aa", foo.field, baz = 3); - | ~ +++++++++++ +LL | let _ = format!("{1:#?} {} {baz}", "aa", foo.field, baz = 3); + | ~ +++++++++++ error: invalid format string: field access isn't supported - --> $DIR/struct-field-as-captured-argument.rs:17:15 + --> $DIR/struct-field-as-captured-argument.rs:17:23 | -LL | format!("{foo.field:.3} {} {baz}", "aa", baz = 3); - | ^^^^^^^^^ not supported in format string +LL | let _ = format!("{foo.field:.3} {} {baz}", "aa", baz = 3); + | ^^^^^^^^^ not supported in format string | help: consider using a positional formatting argument instead | -LL | format!("{1:.3} {} {baz}", "aa", foo.field, baz = 3); - | ~ +++++++++++ +LL | let _ = format!("{1:.3} {} {baz}", "aa", foo.field, baz = 3); + | ~ +++++++++++ error: aborting due to 7 previous errors diff --git a/tests/ui/issues/issue-20676.rs b/tests/ui/issues/issue-20676.rs index b3319950b42a5..2059365c7d628 100644 --- a/tests/ui/issues/issue-20676.rs +++ b/tests/ui/issues/issue-20676.rs @@ -8,5 +8,5 @@ use std::fmt; fn main() { let a: &dyn fmt::Debug = &1; - format!("{:?}", a); + let _ = format!("{:?}", a); } From 83cf471361ed8e5d07111312a80b29b6ecb3290b Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Wed, 26 Jun 2024 13:00:51 +0300 Subject: [PATCH 767/892] out_of_scope_macro_calls: Detect calls inside attributes more precisely --- compiler/rustc_resolve/src/def_collector.rs | 23 ++++++++++++++----- compiler/rustc_resolve/src/lib.rs | 5 ++-- compiler/rustc_resolve/src/macros.rs | 9 ++++---- .../out-of-scope-calls-false-positives.rs | 10 ++++++++ 4 files changed, 35 insertions(+), 12 deletions(-) create mode 100644 tests/ui/macros/out-of-scope-calls-false-positives.rs diff --git a/compiler/rustc_resolve/src/def_collector.rs b/compiler/rustc_resolve/src/def_collector.rs index 80619c59cc381..a4fdb4a0bafaa 100644 --- a/compiler/rustc_resolve/src/def_collector.rs +++ b/compiler/rustc_resolve/src/def_collector.rs @@ -8,6 +8,7 @@ use rustc_hir::def_id::LocalDefId; use rustc_span::hygiene::LocalExpnId; use rustc_span::symbol::{kw, sym, Symbol}; use rustc_span::Span; +use std::mem; use tracing::debug; pub(crate) fn collect_definitions( @@ -15,8 +16,9 @@ pub(crate) fn collect_definitions( fragment: &AstFragment, expansion: LocalExpnId, ) { - let (parent_def, impl_trait_context) = resolver.invocation_parents[&expansion]; - fragment.visit_with(&mut DefCollector { resolver, parent_def, expansion, impl_trait_context }); + let (parent_def, impl_trait_context, in_attr) = resolver.invocation_parents[&expansion]; + let mut visitor = DefCollector { resolver, parent_def, expansion, impl_trait_context, in_attr }; + fragment.visit_with(&mut visitor); } /// Creates `DefId`s for nodes in the AST. @@ -24,6 +26,7 @@ struct DefCollector<'a, 'b, 'tcx> { resolver: &'a mut Resolver<'b, 'tcx>, parent_def: LocalDefId, impl_trait_context: ImplTraitContext, + in_attr: bool, expansion: LocalExpnId, } @@ -53,7 +56,7 @@ impl<'a, 'b, 'tcx> DefCollector<'a, 'b, 'tcx> { } fn with_parent(&mut self, parent_def: LocalDefId, f: F) { - let orig_parent_def = std::mem::replace(&mut self.parent_def, parent_def); + let orig_parent_def = mem::replace(&mut self.parent_def, parent_def); f(self); self.parent_def = orig_parent_def; } @@ -63,7 +66,7 @@ impl<'a, 'b, 'tcx> DefCollector<'a, 'b, 'tcx> { impl_trait_context: ImplTraitContext, f: F, ) { - let orig_itc = std::mem::replace(&mut self.impl_trait_context, impl_trait_context); + let orig_itc = mem::replace(&mut self.impl_trait_context, impl_trait_context); f(self); self.impl_trait_context = orig_itc; } @@ -105,8 +108,10 @@ impl<'a, 'b, 'tcx> DefCollector<'a, 'b, 'tcx> { fn visit_macro_invoc(&mut self, id: NodeId) { let id = id.placeholder_to_expn_id(); - let old_parent = - self.resolver.invocation_parents.insert(id, (self.parent_def, self.impl_trait_context)); + let old_parent = self + .resolver + .invocation_parents + .insert(id, (self.parent_def, self.impl_trait_context, self.in_attr)); assert!(old_parent.is_none(), "parent `LocalDefId` is reset for an invocation"); } } @@ -413,4 +418,10 @@ impl<'a, 'b, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'b, 'tcx> { visit::walk_crate(self, krate) } } + + fn visit_attribute(&mut self, attr: &'a Attribute) -> Self::Result { + let orig_in_attr = mem::replace(&mut self.in_attr, true); + visit::walk_attribute(self, attr); + self.in_attr = orig_in_attr; + } } diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 38963ef4ef092..610cb1d2aadbb 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -1139,7 +1139,7 @@ pub struct Resolver<'a, 'tcx> { /// When collecting definitions from an AST fragment produced by a macro invocation `ExpnId` /// we know what parent node that fragment should be attached to thanks to this table, /// and how the `impl Trait` fragments were introduced. - invocation_parents: FxHashMap, + invocation_parents: FxHashMap, /// Some way to know that we are in a *trait* impl in `visit_assoc_item`. /// FIXME: Replace with a more general AST map (together with some other fields). @@ -1371,7 +1371,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { node_id_to_def_id.insert(CRATE_NODE_ID, crate_feed); let mut invocation_parents = FxHashMap::default(); - invocation_parents.insert(LocalExpnId::ROOT, (CRATE_DEF_ID, ImplTraitContext::Existential)); + invocation_parents + .insert(LocalExpnId::ROOT, (CRATE_DEF_ID, ImplTraitContext::Existential, false)); let mut extern_prelude: FxHashMap> = tcx .sess diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs index 026a2ca14128e..cb9bebd33d306 100644 --- a/compiler/rustc_resolve/src/macros.rs +++ b/compiler/rustc_resolve/src/macros.rs @@ -297,11 +297,12 @@ impl<'a, 'tcx> ResolverExpand for Resolver<'a, 'tcx> { .invocation_parents .get(&invoc_id) .or_else(|| self.invocation_parents.get(&eager_expansion_root)) - .map(|&(mod_def_id, _)| mod_def_id) - .filter(|&mod_def_id| { - invoc.fragment_kind == AstFragmentKind::Expr + .filter(|&&(mod_def_id, _, in_attr)| { + in_attr + && invoc.fragment_kind == AstFragmentKind::Expr && self.tcx.def_kind(mod_def_id) == DefKind::Mod - }); + }) + .map(|&(mod_def_id, ..)| mod_def_id); let (ext, res) = self.smart_resolve_macro_path( path, kind, diff --git a/tests/ui/macros/out-of-scope-calls-false-positives.rs b/tests/ui/macros/out-of-scope-calls-false-positives.rs new file mode 100644 index 0000000000000..8d696c177e441 --- /dev/null +++ b/tests/ui/macros/out-of-scope-calls-false-positives.rs @@ -0,0 +1,10 @@ +//@ check-pass +//@ needs-asm-support + +macro_rules! mac { () => { "" } } +macro_rules! mac2 { () => { "auxiliary/issue-40469.rs" } } + +std::arch::global_asm!(mac!()); // OK +include!(mac2!()); // OK + +fn main() {} From f46c4129e0310b4fb6a75dbe28c2a86e00c9be27 Mon Sep 17 00:00:00 2001 From: yukang Date: Sat, 6 Jul 2024 16:41:16 +0800 Subject: [PATCH 768/892] show unit output when there is only output diff in diagnostics --- .../src/infer/error_reporting/mod.rs | 11 ++++++-- tests/ui/compare-method/bad-self-type.stderr | 2 +- tests/ui/error-codes/E0308.stderr | 2 +- .../in-assoc-type-unconstrained.stderr | 2 +- .../start_lang_item_args.missing_ret.stderr | 2 +- tests/ui/method-output-diff-issue-127263.rs | 8 ++++++ .../ui/method-output-diff-issue-127263.stderr | 25 +++++++++++++++++++ 7 files changed, 46 insertions(+), 6 deletions(-) create mode 100644 tests/ui/method-output-diff-issue-127263.rs create mode 100644 tests/ui/method-output-diff-issue-127263.stderr diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index a8fd3ca8c59bd..1ee535b68b0de 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -1168,14 +1168,21 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { let output1 = sig1.output(); let output2 = sig2.output(); let (x1, x2) = self.cmp(output1, output2); - if !output1.is_unit() { + let only_output_diff = !lifetime_diff + && sig1.c_variadic == sig2.c_variadic + && sig1.safety == sig2.safety + && sig1.abi == sig2.abi + && sig1.inputs() == sig2.inputs() + && x1 != x2; + if !output1.is_unit() || only_output_diff { values.0.push_normal(" -> "); (values.0).0.extend(x1.0); } - if !output2.is_unit() { + if !output2.is_unit() || only_output_diff { values.1.push_normal(" -> "); (values.1).0.extend(x2.0); } + values } diff --git a/tests/ui/compare-method/bad-self-type.stderr b/tests/ui/compare-method/bad-self-type.stderr index 29ebbc5dffb11..a3a31f4344717 100644 --- a/tests/ui/compare-method/bad-self-type.stderr +++ b/tests/ui/compare-method/bad-self-type.stderr @@ -41,7 +41,7 @@ note: type in trait LL | fn bar(self) -> Option<()>; | ^^^^^^^^^^ = note: expected signature `fn(MyFuture) -> Option<()>` - found signature `fn(MyFuture)` + found signature `fn(MyFuture) -> ()` help: change the output type to match the trait | LL | fn bar(self) -> Option<()> {} diff --git a/tests/ui/error-codes/E0308.stderr b/tests/ui/error-codes/E0308.stderr index bc6c5a632a1a8..709b311927625 100644 --- a/tests/ui/error-codes/E0308.stderr +++ b/tests/ui/error-codes/E0308.stderr @@ -5,7 +5,7 @@ LL | fn size_of(); | ^ expected `usize`, found `()` | = note: expected signature `extern "rust-intrinsic" fn() -> usize` - found signature `extern "rust-intrinsic" fn()` + found signature `extern "rust-intrinsic" fn() -> ()` error: aborting due to 1 previous error diff --git a/tests/ui/impl-trait/in-assoc-type-unconstrained.stderr b/tests/ui/impl-trait/in-assoc-type-unconstrained.stderr index e32c59a75c699..75cbe43eeb4a1 100644 --- a/tests/ui/impl-trait/in-assoc-type-unconstrained.stderr +++ b/tests/ui/impl-trait/in-assoc-type-unconstrained.stderr @@ -35,7 +35,7 @@ note: type in trait LL | fn method() -> Self::Ty; | ^^^^^^^^ = note: expected signature `fn() -> <() as compare_method::Trait>::Ty` - found signature `fn()` + found signature `fn() -> ()` note: this item must have the opaque type in its signature in order to be able to register hidden types --> $DIR/in-assoc-type-unconstrained.rs:22:12 | diff --git a/tests/ui/lang-items/start_lang_item_args.missing_ret.stderr b/tests/ui/lang-items/start_lang_item_args.missing_ret.stderr index aa1b1b73baefb..2672efe51c9aa 100644 --- a/tests/ui/lang-items/start_lang_item_args.missing_ret.stderr +++ b/tests/ui/lang-items/start_lang_item_args.missing_ret.stderr @@ -5,7 +5,7 @@ LL | fn start(_main: fn() -> T, _argc: isize, _argv: *const *const u8, _sigpi | ^ expected `isize`, found `()` | = note: expected signature `fn(fn() -> _, _, _, _) -> isize` - found signature `fn(fn() -> _, _, _, _)` + found signature `fn(fn() -> _, _, _, _) -> ()` error: aborting due to 1 previous error diff --git a/tests/ui/method-output-diff-issue-127263.rs b/tests/ui/method-output-diff-issue-127263.rs new file mode 100644 index 0000000000000..85a903e245360 --- /dev/null +++ b/tests/ui/method-output-diff-issue-127263.rs @@ -0,0 +1,8 @@ +fn bar() {} +fn foo(x: i32) -> u32 { + 0 +} +fn main() { + let b: fn() -> u32 = bar; //~ ERROR mismatched types [E0308] + let f: fn(i32) = foo; //~ ERROR mismatched types [E0308] +} diff --git a/tests/ui/method-output-diff-issue-127263.stderr b/tests/ui/method-output-diff-issue-127263.stderr new file mode 100644 index 0000000000000..35b86114f16d0 --- /dev/null +++ b/tests/ui/method-output-diff-issue-127263.stderr @@ -0,0 +1,25 @@ +error[E0308]: mismatched types + --> $DIR/method-output-diff-issue-127263.rs:6:26 + | +LL | let b: fn() -> u32 = bar; + | ----------- ^^^ expected fn pointer, found fn item + | | + | expected due to this + | + = note: expected fn pointer `fn() -> u32` + found fn item `fn() -> () {bar}` + +error[E0308]: mismatched types + --> $DIR/method-output-diff-issue-127263.rs:7:22 + | +LL | let f: fn(i32) = foo; + | ------- ^^^ expected fn pointer, found fn item + | | + | expected due to this + | + = note: expected fn pointer `fn(_) -> ()` + found fn item `fn(_) -> u32 {foo}` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0308`. From e5d6a416e8a4662e8d9a26f9224247a117df5275 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 12 Jun 2024 14:58:10 -0400 Subject: [PATCH 769/892] Uplift PredicateEmittingRelation first --- Cargo.lock | 1 + .../src/type_check/relate_tys.rs | 9 ++--- compiler/rustc_infer/Cargo.toml | 1 + .../rustc_infer/src/infer/relate/combine.rs | 36 +++---------------- .../src/infer/relate/generalize.rs | 4 +-- compiler/rustc_infer/src/infer/relate/glb.rs | 2 +- .../rustc_infer/src/infer/relate/lattice.rs | 2 +- compiler/rustc_infer/src/infer/relate/lub.rs | 2 +- compiler/rustc_infer/src/infer/relate/mod.rs | 4 ++- .../src/infer/relate/type_relating.rs | 4 +-- compiler/rustc_middle/src/ty/context.rs | 2 ++ compiler/rustc_middle/src/ty/relate.rs | 12 ------- compiler/rustc_next_trait_solver/src/lib.rs | 1 + .../rustc_next_trait_solver/src/relate.rs | 15 ++++++++ .../src/relate/combine.rs | 34 ++++++++++++++++++ compiler/rustc_type_ir/src/interner.rs | 1 + 16 files changed, 75 insertions(+), 55 deletions(-) create mode 100644 compiler/rustc_next_trait_solver/src/relate.rs create mode 100644 compiler/rustc_next_trait_solver/src/relate/combine.rs diff --git a/Cargo.lock b/Cargo.lock index d1889fb6861ac..afeb9faec097e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4168,6 +4168,7 @@ dependencies = [ "rustc_index", "rustc_macros", "rustc_middle", + "rustc_next_trait_solver", "rustc_span", "rustc_target", "rustc_type_ir", diff --git a/compiler/rustc_borrowck/src/type_check/relate_tys.rs b/compiler/rustc_borrowck/src/type_check/relate_tys.rs index b9a82046e59ad..02b9c2d48b11b 100644 --- a/compiler/rustc_borrowck/src/type_check/relate_tys.rs +++ b/compiler/rustc_borrowck/src/type_check/relate_tys.rs @@ -1,8 +1,9 @@ use rustc_data_structures::fx::FxHashMap; use rustc_errors::ErrorGuaranteed; -use rustc_infer::infer::relate::{PredicateEmittingRelation, StructurallyRelateAliases}; -use rustc_infer::infer::relate::{Relate, RelateResult, TypeRelation}; -use rustc_infer::infer::NllRegionVariableOrigin; +use rustc_infer::infer::relate::{ + PredicateEmittingRelation, Relate, RelateResult, StructurallyRelateAliases, TypeRelation, +}; +use rustc_infer::infer::{InferCtxt, NllRegionVariableOrigin}; use rustc_infer::traits::solve::Goal; use rustc_infer::traits::Obligation; use rustc_middle::mir::ConstraintCategory; @@ -522,7 +523,7 @@ impl<'bccx, 'tcx> TypeRelation> for NllTypeRelating<'_, 'bccx, 'tcx } } -impl<'bccx, 'tcx> PredicateEmittingRelation<'tcx> for NllTypeRelating<'_, 'bccx, 'tcx> { +impl<'bccx, 'tcx> PredicateEmittingRelation> for NllTypeRelating<'_, 'bccx, 'tcx> { fn span(&self) -> Span { self.locations.span(self.type_checker.body) } diff --git a/compiler/rustc_infer/Cargo.toml b/compiler/rustc_infer/Cargo.toml index 5136ab79a0f84..1f616710200f8 100644 --- a/compiler/rustc_infer/Cargo.toml +++ b/compiler/rustc_infer/Cargo.toml @@ -16,6 +16,7 @@ rustc_hir = { path = "../rustc_hir" } rustc_index = { path = "../rustc_index" } rustc_macros = { path = "../rustc_macros" } rustc_middle = { path = "../rustc_middle" } +rustc_next_trait_solver = { path = "../rustc_next_trait_solver" } rustc_span = { path = "../rustc_span" } rustc_target = { path = "../rustc_target" } rustc_type_ir = { path = "../rustc_type_ir" } diff --git a/compiler/rustc_infer/src/infer/relate/combine.rs b/compiler/rustc_infer/src/infer/relate/combine.rs index 0a2e85cc8919f..c93b89756f936 100644 --- a/compiler/rustc_infer/src/infer/relate/combine.rs +++ b/compiler/rustc_infer/src/infer/relate/combine.rs @@ -18,11 +18,13 @@ //! On success, the LUB/GLB operations return the appropriate bound. The //! return value of `Equate` or `Sub` shouldn't really be used. +pub use rustc_next_trait_solver::relate::combine::*; + use super::glb::Glb; use super::lub::Lub; use super::type_relating::TypeRelating; +use super::RelateResult; use super::StructurallyRelateAliases; -use super::{RelateResult, TypeRelation}; use crate::infer::relate; use crate::infer::{DefineOpaqueTypes, InferCtxt, TypeTrace}; use crate::traits::{Obligation, PredicateObligation}; @@ -32,7 +34,6 @@ use rustc_middle::traits::solve::Goal; use rustc_middle::ty::error::{ExpectedFound, TypeError}; use rustc_middle::ty::{self, InferConst, Ty, TyCtxt, TypeVisitableExt, Upcast}; use rustc_middle::ty::{IntType, UintType}; -use rustc_span::Span; #[derive(Clone)] pub struct CombineFields<'infcx, 'tcx> { @@ -76,7 +77,7 @@ impl<'tcx> InferCtxt<'tcx> { b: Ty<'tcx>, ) -> RelateResult<'tcx, Ty<'tcx>> where - R: PredicateEmittingRelation<'tcx>, + R: PredicateEmittingRelation>, { debug_assert!(!a.has_escaping_bound_vars()); debug_assert!(!b.has_escaping_bound_vars()); @@ -171,7 +172,7 @@ impl<'tcx> InferCtxt<'tcx> { b: ty::Const<'tcx>, ) -> RelateResult<'tcx, ty::Const<'tcx>> where - R: PredicateEmittingRelation<'tcx>, + R: PredicateEmittingRelation>, { debug!("{}.consts({:?}, {:?})", relation.tag(), a, b); debug_assert!(!a.has_escaping_bound_vars()); @@ -323,30 +324,3 @@ impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> { ) } } - -pub trait PredicateEmittingRelation<'tcx>: TypeRelation> { - fn span(&self) -> Span; - - fn param_env(&self) -> ty::ParamEnv<'tcx>; - - /// Whether aliases should be related structurally. This is pretty much - /// always `No` unless you're equating in some specific locations of the - /// new solver. See the comments in these use-cases for more details. - fn structurally_relate_aliases(&self) -> StructurallyRelateAliases; - - /// Register obligations that must hold in order for this relation to hold - fn register_goals( - &mut self, - obligations: impl IntoIterator>>, - ); - - /// Register predicates that must hold in order for this relation to hold. - /// This uses the default `param_env` of the obligation. - fn register_predicates( - &mut self, - obligations: impl IntoIterator, ty::Predicate<'tcx>>>, - ); - - /// Register `AliasRelate` obligation(s) that both types must be related to each other. - fn register_alias_relate_predicate(&mut self, a: Ty<'tcx>, b: Ty<'tcx>); -} diff --git a/compiler/rustc_infer/src/infer/relate/generalize.rs b/compiler/rustc_infer/src/infer/relate/generalize.rs index d6e57d8538772..fe3b8d60fb91b 100644 --- a/compiler/rustc_infer/src/infer/relate/generalize.rs +++ b/compiler/rustc_infer/src/infer/relate/generalize.rs @@ -30,7 +30,7 @@ impl<'tcx> InferCtxt<'tcx> { /// `TypeRelation`. Do not use this, and instead please use `At::eq`, for all /// other usecases (i.e. setting the value of a type var). #[instrument(level = "debug", skip(self, relation))] - pub fn instantiate_ty_var>( + pub fn instantiate_ty_var>>( &self, relation: &mut R, target_is_expected: bool, @@ -178,7 +178,7 @@ impl<'tcx> InferCtxt<'tcx> { /// /// See `tests/ui/const-generics/occurs-check/` for more examples where this is relevant. #[instrument(level = "debug", skip(self, relation))] - pub(super) fn instantiate_const_var>( + pub(super) fn instantiate_const_var>>( &self, relation: &mut R, target_is_expected: bool, diff --git a/compiler/rustc_infer/src/infer/relate/glb.rs b/compiler/rustc_infer/src/infer/relate/glb.rs index 067004ecaebbf..5bb8a113e173e 100644 --- a/compiler/rustc_infer/src/infer/relate/glb.rs +++ b/compiler/rustc_infer/src/infer/relate/glb.rs @@ -123,7 +123,7 @@ impl<'combine, 'infcx, 'tcx> LatticeDir<'infcx, 'tcx> for Glb<'combine, 'infcx, } } -impl<'tcx> PredicateEmittingRelation<'tcx> for Glb<'_, '_, 'tcx> { +impl<'tcx> PredicateEmittingRelation> for Glb<'_, '_, 'tcx> { fn span(&self) -> Span { self.fields.trace.span() } diff --git a/compiler/rustc_infer/src/infer/relate/lattice.rs b/compiler/rustc_infer/src/infer/relate/lattice.rs index 6cc8d6d910ade..46e7466141a58 100644 --- a/compiler/rustc_infer/src/infer/relate/lattice.rs +++ b/compiler/rustc_infer/src/infer/relate/lattice.rs @@ -30,7 +30,7 @@ use rustc_middle::ty::{self, Ty}; /// /// GLB moves "down" the lattice (to smaller values); LUB moves /// "up" the lattice (to bigger values). -pub trait LatticeDir<'f, 'tcx>: PredicateEmittingRelation<'tcx> { +pub trait LatticeDir<'f, 'tcx>: PredicateEmittingRelation> { fn infcx(&self) -> &'f InferCtxt<'tcx>; fn cause(&self) -> &ObligationCause<'tcx>; diff --git a/compiler/rustc_infer/src/infer/relate/lub.rs b/compiler/rustc_infer/src/infer/relate/lub.rs index 2184416b4ccef..94c1464817f73 100644 --- a/compiler/rustc_infer/src/infer/relate/lub.rs +++ b/compiler/rustc_infer/src/infer/relate/lub.rs @@ -123,7 +123,7 @@ impl<'combine, 'infcx, 'tcx> LatticeDir<'infcx, 'tcx> for Lub<'combine, 'infcx, } } -impl<'tcx> PredicateEmittingRelation<'tcx> for Lub<'_, '_, 'tcx> { +impl<'tcx> PredicateEmittingRelation> for Lub<'_, '_, 'tcx> { fn span(&self) -> Span { self.fields.trace.span() } diff --git a/compiler/rustc_infer/src/infer/relate/mod.rs b/compiler/rustc_infer/src/infer/relate/mod.rs index 41cc945492daf..dd97dc061fe2c 100644 --- a/compiler/rustc_infer/src/infer/relate/mod.rs +++ b/compiler/rustc_infer/src/infer/relate/mod.rs @@ -2,11 +2,13 @@ //! (except for some relations used for diagnostics and heuristics in the compiler). //! As well as the implementation of `Relate` for interned things (`Ty`/`Const`/etc). -pub use rustc_middle::ty::relate::*; +pub use rustc_middle::ty::relate::RelateResult; +pub use rustc_next_trait_solver::relate::*; pub use self::combine::CombineFields; pub use self::combine::PredicateEmittingRelation; +#[allow(hidden_glob_reexports)] pub(super) mod combine; mod generalize; mod glb; diff --git a/compiler/rustc_infer/src/infer/relate/type_relating.rs b/compiler/rustc_infer/src/infer/relate/type_relating.rs index f2bec9392d542..e206f530519b5 100644 --- a/compiler/rustc_infer/src/infer/relate/type_relating.rs +++ b/compiler/rustc_infer/src/infer/relate/type_relating.rs @@ -1,7 +1,7 @@ use super::combine::CombineFields; use crate::infer::relate::{PredicateEmittingRelation, StructurallyRelateAliases}; use crate::infer::BoundRegionConversionTime::HigherRankedType; -use crate::infer::{DefineOpaqueTypes, SubregionOrigin}; +use crate::infer::{DefineOpaqueTypes, InferCtxt, SubregionOrigin}; use rustc_middle::traits::solve::Goal; use rustc_middle::ty::relate::{ relate_args_invariantly, relate_args_with_variances, Relate, RelateResult, TypeRelation, @@ -296,7 +296,7 @@ impl<'tcx> TypeRelation> for TypeRelating<'_, '_, 'tcx> { } } -impl<'tcx> PredicateEmittingRelation<'tcx> for TypeRelating<'_, '_, 'tcx> { +impl<'tcx> PredicateEmittingRelation> for TypeRelating<'_, '_, 'tcx> { fn span(&self) -> Span { self.fields.trace.span() } diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 055749ba3a322..dca48069974f0 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -92,6 +92,8 @@ use std::ops::{Bound, Deref}; impl<'tcx> Interner for TyCtxt<'tcx> { type DefId = DefId; type LocalDefId = LocalDefId; + type Span = Span; + type GenericArgs = ty::GenericArgsRef<'tcx>; type GenericArgsSlice = &'tcx [ty::GenericArg<'tcx>]; diff --git a/compiler/rustc_middle/src/ty/relate.rs b/compiler/rustc_middle/src/ty/relate.rs index b169d672a8468..ebf0d7ed737fa 100644 --- a/compiler/rustc_middle/src/ty/relate.rs +++ b/compiler/rustc_middle/src/ty/relate.rs @@ -10,18 +10,6 @@ use crate::ty::{self as ty, Ty, TyCtxt}; pub type RelateResult<'tcx, T> = rustc_type_ir::relate::RelateResult, T>; -/// Whether aliases should be related structurally or not. Used -/// to adjust the behavior of generalization and combine. -/// -/// This should always be `No` unless in a few special-cases when -/// instantiating canonical responses and in the new solver. Each -/// such case should have a comment explaining why it is used. -#[derive(Debug, Copy, Clone)] -pub enum StructurallyRelateAliases { - Yes, - No, -} - impl<'tcx> Relate> for ty::ImplSubject<'tcx> { #[inline] fn relate>>( diff --git a/compiler/rustc_next_trait_solver/src/lib.rs b/compiler/rustc_next_trait_solver/src/lib.rs index a6a9c01faaa0f..761475d3d6b08 100644 --- a/compiler/rustc_next_trait_solver/src/lib.rs +++ b/compiler/rustc_next_trait_solver/src/lib.rs @@ -6,5 +6,6 @@ pub mod canonicalizer; pub mod delegate; +pub mod relate; pub mod resolve; pub mod solve; diff --git a/compiler/rustc_next_trait_solver/src/relate.rs b/compiler/rustc_next_trait_solver/src/relate.rs new file mode 100644 index 0000000000000..db819961bbd75 --- /dev/null +++ b/compiler/rustc_next_trait_solver/src/relate.rs @@ -0,0 +1,15 @@ +pub use rustc_type_ir::relate::*; + +pub mod combine; + +/// Whether aliases should be related structurally or not. Used +/// to adjust the behavior of generalization and combine. +/// +/// This should always be `No` unless in a few special-cases when +/// instantiating canonical responses and in the new solver. Each +/// such case should have a comment explaining why it is used. +#[derive(Debug, Copy, Clone)] +pub enum StructurallyRelateAliases { + Yes, + No, +} diff --git a/compiler/rustc_next_trait_solver/src/relate/combine.rs b/compiler/rustc_next_trait_solver/src/relate/combine.rs new file mode 100644 index 0000000000000..96968327d8ee3 --- /dev/null +++ b/compiler/rustc_next_trait_solver/src/relate/combine.rs @@ -0,0 +1,34 @@ +pub use rustc_type_ir::relate::*; +use rustc_type_ir::solve::Goal; +use rustc_type_ir::{InferCtxtLike, Interner, Upcast}; + +use super::StructurallyRelateAliases; + +pub trait PredicateEmittingRelation::Interner>: + TypeRelation +where + Infcx: InferCtxtLike, + I: Interner, +{ + fn span(&self) -> I::Span; + + fn param_env(&self) -> I::ParamEnv; + + /// Whether aliases should be related structurally. This is pretty much + /// always `No` unless you're equating in some specific locations of the + /// new solver. See the comments in these use-cases for more details. + fn structurally_relate_aliases(&self) -> StructurallyRelateAliases; + + /// Register obligations that must hold in order for this relation to hold + fn register_goals(&mut self, obligations: impl IntoIterator>); + + /// Register predicates that must hold in order for this relation to hold. + /// This uses the default `param_env` of the obligation. + fn register_predicates( + &mut self, + obligations: impl IntoIterator>, + ); + + /// Register `AliasRelate` obligation(s) that both types must be related to each other. + fn register_alias_relate_predicate(&mut self, a: I::Ty, b: I::Ty); +} diff --git a/compiler/rustc_type_ir/src/interner.rs b/compiler/rustc_type_ir/src/interner.rs index db97bdca3823d..646939d847565 100644 --- a/compiler/rustc_type_ir/src/interner.rs +++ b/compiler/rustc_type_ir/src/interner.rs @@ -32,6 +32,7 @@ pub trait Interner: { type DefId: DefId; type LocalDefId: Copy + Debug + Hash + Eq + Into + TypeFoldable; + type Span: Copy + Debug + Hash + Eq; type GenericArgs: GenericArgs; type GenericArgsSlice: Copy + Debug + Hash + Eq + SliceLike; From 23c6f23b218f2ba3bb7459215e48032bd5ba0b60 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 5 Jul 2024 15:28:47 -0400 Subject: [PATCH 770/892] Uplift push_outlives_components --- .../src/infer/outlives/components.rs | 266 -------------- .../rustc_infer/src/infer/outlives/mod.rs | 3 +- .../src/infer/outlives/obligations.rs | 2 +- .../rustc_infer/src/infer/outlives/verify.rs | 4 +- compiler/rustc_middle/src/ty/consts/kind.rs | 7 + .../query/type_op/implied_outlives_bounds.rs | 2 +- compiler/rustc_type_ir/src/inherent.rs | 8 + compiler/rustc_type_ir/src/interner.rs | 2 +- compiler/rustc_type_ir/src/lib.rs | 1 + compiler/rustc_type_ir/src/outlives.rs | 335 ++++++++++++++++++ .../in-trait/async-generics-and-bounds.stderr | 12 +- .../in-trait/async-generics.stderr | 12 +- 12 files changed, 370 insertions(+), 284 deletions(-) delete mode 100644 compiler/rustc_infer/src/infer/outlives/components.rs create mode 100644 compiler/rustc_type_ir/src/outlives.rs diff --git a/compiler/rustc_infer/src/infer/outlives/components.rs b/compiler/rustc_infer/src/infer/outlives/components.rs deleted file mode 100644 index 6bab3ad6ba3c8..0000000000000 --- a/compiler/rustc_infer/src/infer/outlives/components.rs +++ /dev/null @@ -1,266 +0,0 @@ -// The outlines relation `T: 'a` or `'a: 'b`. This code frequently -// refers to rules defined in RFC 1214 (`OutlivesFooBar`), so see that -// RFC for reference. - -use rustc_data_structures::sso::SsoHashSet; -use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt}; -use rustc_middle::ty::{GenericArg, GenericArgKind}; -use smallvec::{smallvec, SmallVec}; - -#[derive(Debug)] -pub enum Component<'tcx> { - Region(ty::Region<'tcx>), - Param(ty::ParamTy), - Placeholder(ty::PlaceholderType), - UnresolvedInferenceVariable(ty::InferTy), - - // Projections like `T::Foo` are tricky because a constraint like - // `T::Foo: 'a` can be satisfied in so many ways. There may be a - // where-clause that says `T::Foo: 'a`, or the defining trait may - // include a bound like `type Foo: 'static`, or -- in the most - // conservative way -- we can prove that `T: 'a` (more generally, - // that all components in the projection outlive `'a`). This code - // is not in a position to judge which is the best technique, so - // we just product the projection as a component and leave it to - // the consumer to decide (but see `EscapingProjection` below). - Alias(ty::AliasTy<'tcx>), - - // In the case where a projection has escaping regions -- meaning - // regions bound within the type itself -- we always use - // the most conservative rule, which requires that all components - // outlive the bound. So for example if we had a type like this: - // - // for<'a> Trait1< >::Foo > - // ~~~~~~~~~~~~~~~~~~~~~~~~~ - // - // then the inner projection (underlined) has an escaping region - // `'a`. We consider that outer trait `'c` to meet a bound if `'b` - // outlives `'b: 'c`, and we don't consider whether the trait - // declares that `Foo: 'static` etc. Therefore, we just return the - // free components of such a projection (in this case, `'b`). - // - // However, in the future, we may want to get smarter, and - // actually return a "higher-ranked projection" here. Therefore, - // we mark that these components are part of an escaping - // projection, so that implied bounds code can avoid relying on - // them. This gives us room to improve the regionck reasoning in - // the future without breaking backwards compat. - EscapingAlias(Vec>), -} - -/// Push onto `out` all the things that must outlive `'a` for the condition -/// `ty0: 'a` to hold. Note that `ty0` must be a **fully resolved type**. -pub fn push_outlives_components<'tcx>( - tcx: TyCtxt<'tcx>, - ty0: Ty<'tcx>, - out: &mut SmallVec<[Component<'tcx>; 4]>, -) { - let mut visited = SsoHashSet::new(); - compute_components(tcx, ty0, out, &mut visited); - debug!("components({:?}) = {:?}", ty0, out); -} - -fn compute_components<'tcx>( - tcx: TyCtxt<'tcx>, - ty: Ty<'tcx>, - out: &mut SmallVec<[Component<'tcx>; 4]>, - visited: &mut SsoHashSet>, -) { - // Descend through the types, looking for the various "base" - // components and collecting them into `out`. This is not written - // with `collect()` because of the need to sometimes skip subtrees - // in the `subtys` iterator (e.g., when encountering a - // projection). - match *ty.kind() { - ty::FnDef(_, args) => { - // HACK(eddyb) ignore lifetimes found shallowly in `args`. - // This is inconsistent with `ty::Adt` (including all args) - // and with `ty::Closure` (ignoring all args other than - // upvars, of which a `ty::FnDef` doesn't have any), but - // consistent with previous (accidental) behavior. - // See https://github.com/rust-lang/rust/issues/70917 - // for further background and discussion. - for child in args { - match child.unpack() { - GenericArgKind::Type(ty) => { - compute_components(tcx, ty, out, visited); - } - GenericArgKind::Lifetime(_) => {} - GenericArgKind::Const(_) => { - compute_components_recursive(tcx, child, out, visited); - } - } - } - } - - ty::Pat(element, _) | - ty::Array(element, _) => { - // Don't look into the len const as it doesn't affect regions - compute_components(tcx, element, out, visited); - } - - ty::Closure(_, args) => { - let tupled_ty = args.as_closure().tupled_upvars_ty(); - compute_components(tcx, tupled_ty, out, visited); - } - - ty::CoroutineClosure(_, args) => { - let tupled_ty = args.as_coroutine_closure().tupled_upvars_ty(); - compute_components(tcx, tupled_ty, out, visited); - } - - ty::Coroutine(_, args) => { - // Same as the closure case - let tupled_ty = args.as_coroutine().tupled_upvars_ty(); - compute_components(tcx, tupled_ty, out, visited); - - // We ignore regions in the coroutine interior as we don't - // want these to affect region inference - } - - // All regions are bound inside a witness - ty::CoroutineWitness(..) => (), - - // OutlivesTypeParameterEnv -- the actual checking that `X:'a` - // is implied by the environment is done in regionck. - ty::Param(p) => { - out.push(Component::Param(p)); - } - - ty::Placeholder(p) => { - out.push(Component::Placeholder(p)); - } - - // For projections, we prefer to generate an obligation like - // `>::Foo: 'a`, because this gives the - // regionck more ways to prove that it holds. However, - // regionck is not (at least currently) prepared to deal with - // higher-ranked regions that may appear in the - // trait-ref. Therefore, if we see any higher-ranked regions, - // we simply fallback to the most restrictive rule, which - // requires that `Pi: 'a` for all `i`. - ty::Alias(_, alias_ty) => { - if !alias_ty.has_escaping_bound_vars() { - // best case: no escaping regions, so push the - // projection and skip the subtree (thus generating no - // constraints for Pi). This defers the choice between - // the rules OutlivesProjectionEnv, - // OutlivesProjectionTraitDef, and - // OutlivesProjectionComponents to regionck. - out.push(Component::Alias(alias_ty)); - } else { - // fallback case: hard code - // OutlivesProjectionComponents. Continue walking - // through and constrain Pi. - let mut subcomponents = smallvec![]; - let mut subvisited = SsoHashSet::new(); - compute_alias_components_recursive(tcx, ty, &mut subcomponents, &mut subvisited); - out.push(Component::EscapingAlias(subcomponents.into_iter().collect())); - } - } - - // We assume that inference variables are fully resolved. - // So, if we encounter an inference variable, just record - // the unresolved variable as a component. - ty::Infer(infer_ty) => { - out.push(Component::UnresolvedInferenceVariable(infer_ty)); - } - - // Most types do not introduce any region binders, nor - // involve any other subtle cases, and so the WF relation - // simply constraints any regions referenced directly by - // the type and then visits the types that are lexically - // contained within. (The comments refer to relevant rules - // from RFC1214.) - ty::Bool | // OutlivesScalar - ty::Char | // OutlivesScalar - ty::Int(..) | // OutlivesScalar - ty::Uint(..) | // OutlivesScalar - ty::Float(..) | // OutlivesScalar - ty::Never | // ... - ty::Adt(..) | // OutlivesNominalType - ty::Foreign(..) | // OutlivesNominalType - ty::Str | // OutlivesScalar (ish) - ty::Slice(..) | // ... - ty::RawPtr(..) | // ... - ty::Ref(..) | // OutlivesReference - ty::Tuple(..) | // ... - ty::FnPtr(_) | // OutlivesFunction (*) - ty::Dynamic(..) | // OutlivesObject, OutlivesFragment (*) - ty::Bound(..) | - ty::Error(_) => { - // (*) Function pointers and trait objects are both binders. - // In the RFC, this means we would add the bound regions to - // the "bound regions list". In our representation, no such - // list is maintained explicitly, because bound regions - // themselves can be readily identified. - compute_components_recursive(tcx, ty.into(), out, visited); - } - } -} - -/// Collect [Component]s for *all* the args of `parent`. -/// -/// This should not be used to get the components of `parent` itself. -/// Use [push_outlives_components] instead. -pub(super) fn compute_alias_components_recursive<'tcx>( - tcx: TyCtxt<'tcx>, - alias_ty: Ty<'tcx>, - out: &mut SmallVec<[Component<'tcx>; 4]>, - visited: &mut SsoHashSet>, -) { - let ty::Alias(kind, alias_ty) = alias_ty.kind() else { - unreachable!("can only call `compute_alias_components_recursive` on an alias type") - }; - let opt_variances = if *kind == ty::Opaque { tcx.variances_of(alias_ty.def_id) } else { &[] }; - for (index, child) in alias_ty.args.iter().enumerate() { - if opt_variances.get(index) == Some(&ty::Bivariant) { - continue; - } - if !visited.insert(child) { - continue; - } - match child.unpack() { - GenericArgKind::Type(ty) => { - compute_components(tcx, ty, out, visited); - } - GenericArgKind::Lifetime(lt) => { - // Ignore higher ranked regions. - if !lt.is_bound() { - out.push(Component::Region(lt)); - } - } - GenericArgKind::Const(_) => { - compute_components_recursive(tcx, child, out, visited); - } - } - } -} - -/// Collect [Component]s for *all* the args of `parent`. -/// -/// This should not be used to get the components of `parent` itself. -/// Use [push_outlives_components] instead. -fn compute_components_recursive<'tcx>( - tcx: TyCtxt<'tcx>, - parent: GenericArg<'tcx>, - out: &mut SmallVec<[Component<'tcx>; 4]>, - visited: &mut SsoHashSet>, -) { - for child in parent.walk_shallow(visited) { - match child.unpack() { - GenericArgKind::Type(ty) => { - compute_components(tcx, ty, out, visited); - } - GenericArgKind::Lifetime(lt) => { - // Ignore higher ranked regions. - if !lt.is_bound() { - out.push(Component::Region(lt)); - } - } - GenericArgKind::Const(_) => { - compute_components_recursive(tcx, child, out, visited); - } - } - } -} diff --git a/compiler/rustc_infer/src/infer/outlives/mod.rs b/compiler/rustc_infer/src/infer/outlives/mod.rs index 48d006e7fbcf9..6e1b044cbac49 100644 --- a/compiler/rustc_infer/src/infer/outlives/mod.rs +++ b/compiler/rustc_infer/src/infer/outlives/mod.rs @@ -7,8 +7,9 @@ use crate::infer::free_regions::RegionRelations; use crate::infer::lexical_region_resolve; use rustc_middle::traits::query::{NoSolution, OutlivesBound}; use rustc_middle::ty; +// TODO: Remove me +pub use rustc_type_ir::outlives as components; -pub mod components; pub mod env; pub mod for_liveness; pub mod obligations; diff --git a/compiler/rustc_infer/src/infer/outlives/obligations.rs b/compiler/rustc_infer/src/infer/outlives/obligations.rs index 32c790523b64c..c09b5de23b595 100644 --- a/compiler/rustc_infer/src/infer/outlives/obligations.rs +++ b/compiler/rustc_infer/src/infer/outlives/obligations.rs @@ -291,7 +291,7 @@ where fn components_must_outlive( &mut self, origin: infer::SubregionOrigin<'tcx>, - components: &[Component<'tcx>], + components: &[Component>], region: ty::Region<'tcx>, category: ConstraintCategory<'tcx>, ) { diff --git a/compiler/rustc_infer/src/infer/outlives/verify.rs b/compiler/rustc_infer/src/infer/outlives/verify.rs index 7e977b9b95455..27dec66ca7746 100644 --- a/compiler/rustc_infer/src/infer/outlives/verify.rs +++ b/compiler/rustc_infer/src/infer/outlives/verify.rs @@ -139,7 +139,7 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> { fn bound_from_components( &self, - components: &[Component<'tcx>], + components: &[Component>], visited: &mut SsoHashSet>, ) -> VerifyBound<'tcx> { let mut bounds = components @@ -158,7 +158,7 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> { fn bound_from_single_component( &self, - component: &Component<'tcx>, + component: &Component>, visited: &mut SsoHashSet>, ) -> VerifyBound<'tcx> { match *component { diff --git a/compiler/rustc_middle/src/ty/consts/kind.rs b/compiler/rustc_middle/src/ty/consts/kind.rs index bf834ef760742..98f35b6b8ab99 100644 --- a/compiler/rustc_middle/src/ty/consts/kind.rs +++ b/compiler/rustc_middle/src/ty/consts/kind.rs @@ -54,6 +54,13 @@ pub struct Expr<'tcx> { pub kind: ExprKind, args: ty::GenericArgsRef<'tcx>, } + +impl<'tcx> rustc_type_ir::inherent::ExprConst> for Expr<'tcx> { + fn args(self) -> ty::GenericArgsRef<'tcx> { + self.args + } +} + impl<'tcx> Expr<'tcx> { pub fn new_binop( tcx: TyCtxt<'tcx>, diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs index b38841db9233e..40fdf54996984 100644 --- a/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs +++ b/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs @@ -284,7 +284,7 @@ pub fn compute_implied_outlives_bounds_compat_inner<'tcx>( /// those relationships. fn implied_bounds_from_components<'tcx>( sub_region: ty::Region<'tcx>, - sup_components: SmallVec<[Component<'tcx>; 4]>, + sup_components: SmallVec<[Component>; 4]>, ) -> Vec> { sup_components .into_iter() diff --git a/compiler/rustc_type_ir/src/inherent.rs b/compiler/rustc_type_ir/src/inherent.rs index ffe16964ae515..68c2575258d2f 100644 --- a/compiler/rustc_type_ir/src/inherent.rs +++ b/compiler/rustc_type_ir/src/inherent.rs @@ -232,6 +232,10 @@ pub trait Region>: fn new_anon_bound(interner: I, debruijn: ty::DebruijnIndex, var: ty::BoundVar) -> Self; fn new_static(interner: I) -> Self; + + fn is_bound(self) -> bool { + matches!(self.kind(), ty::ReBound(..)) + } } pub trait Const>: @@ -272,6 +276,10 @@ pub trait Const>: } } +pub trait ExprConst>: Copy + Debug + Hash + Eq + Relate { + fn args(self) -> I::GenericArgs; +} + pub trait GenericsOf> { fn count(&self) -> usize; } diff --git a/compiler/rustc_type_ir/src/interner.rs b/compiler/rustc_type_ir/src/interner.rs index db97bdca3823d..61a42fb72625b 100644 --- a/compiler/rustc_type_ir/src/interner.rs +++ b/compiler/rustc_type_ir/src/interner.rs @@ -109,7 +109,7 @@ pub trait Interner: type ParamConst: Copy + Debug + Hash + Eq + ParamLike; type BoundConst: Copy + Debug + Hash + Eq + BoundVarLike; type ValueConst: Copy + Debug + Hash + Eq; - type ExprConst: Copy + Debug + Hash + Eq + Relate; + type ExprConst: ExprConst; // Kinds of regions type Region: Region; diff --git a/compiler/rustc_type_ir/src/lib.rs b/compiler/rustc_type_ir/src/lib.rs index c57ac74cdfdc7..2a909b06baf3a 100644 --- a/compiler/rustc_type_ir/src/lib.rs +++ b/compiler/rustc_type_ir/src/lib.rs @@ -27,6 +27,7 @@ pub mod inherent; pub mod ir_print; pub mod lang_items; pub mod lift; +pub mod outlives; pub mod relate; pub mod solve; diff --git a/compiler/rustc_type_ir/src/outlives.rs b/compiler/rustc_type_ir/src/outlives.rs new file mode 100644 index 0000000000000..61dfa2643d884 --- /dev/null +++ b/compiler/rustc_type_ir/src/outlives.rs @@ -0,0 +1,335 @@ +//! The outlives relation `T: 'a` or `'a: 'b`. This code frequently +//! refers to rules defined in RFC 1214 (`OutlivesFooBar`), so see that +//! RFC for reference. + +use smallvec::{smallvec, SmallVec}; +use tracing::debug; + +use crate::data_structures::SsoHashSet; +use crate::inherent::*; +use crate::visit::TypeVisitableExt as _; +use crate::{self as ty, Interner}; + +#[derive(derivative::Derivative)] +#[derivative(Debug(bound = ""))] +pub enum Component { + Region(I::Region), + Param(I::ParamTy), + Placeholder(I::PlaceholderTy), + UnresolvedInferenceVariable(ty::InferTy), + + // Projections like `T::Foo` are tricky because a constraint like + // `T::Foo: 'a` can be satisfied in so many ways. There may be a + // where-clause that says `T::Foo: 'a`, or the defining trait may + // include a bound like `type Foo: 'static`, or -- in the most + // conservative way -- we can prove that `T: 'a` (more generally, + // that all components in the projection outlive `'a`). This code + // is not in a position to judge which is the best technique, so + // we just product the projection as a component and leave it to + // the consumer to decide (but see `EscapingProjection` below). + Alias(ty::AliasTy), + + // In the case where a projection has escaping regions -- meaning + // regions bound within the type itself -- we always use + // the most conservative rule, which requires that all components + // outlive the bound. So for example if we had a type like this: + // + // for<'a> Trait1< >::Foo > + // ~~~~~~~~~~~~~~~~~~~~~~~~~ + // + // then the inner projection (underlined) has an escaping region + // `'a`. We consider that outer trait `'c` to meet a bound if `'b` + // outlives `'b: 'c`, and we don't consider whether the trait + // declares that `Foo: 'static` etc. Therefore, we just return the + // free components of such a projection (in this case, `'b`). + // + // However, in the future, we may want to get smarter, and + // actually return a "higher-ranked projection" here. Therefore, + // we mark that these components are part of an escaping + // projection, so that implied bounds code can avoid relying on + // them. This gives us room to improve the regionck reasoning in + // the future without breaking backwards compat. + EscapingAlias(Vec>), +} + +/// Push onto `out` all the things that must outlive `'a` for the condition +/// `ty0: 'a` to hold. Note that `ty0` must be a **fully resolved type**. +pub fn push_outlives_components( + tcx: I, + ty0: I::Ty, + out: &mut SmallVec<[Component; 4]>, +) { + let mut visited = SsoHashSet::new(); + compute_components_for_ty(tcx, ty0, out, &mut visited); + debug!("components({:?}) = {:?}", ty0, out); +} + +fn compute_components_for_arg( + tcx: I, + arg: I::GenericArg, + out: &mut SmallVec<[Component; 4]>, + visited: &mut SsoHashSet, +) { + match arg.kind() { + ty::GenericArgKind::Type(ty) => { + compute_components_for_ty(tcx, ty, out, visited); + } + ty::GenericArgKind::Lifetime(lt) => { + compute_components_for_lt(lt, out); + } + ty::GenericArgKind::Const(ct) => { + compute_components_for_const(tcx, ct, out, visited); + } + } +} + +fn compute_components_for_ty( + tcx: I, + ty: I::Ty, + out: &mut SmallVec<[Component; 4]>, + visited: &mut SsoHashSet, +) { + if !visited.insert(ty.into()) { + return; + } + // Descend through the types, looking for the various "base" + // components and collecting them into `out`. This is not written + // with `collect()` because of the need to sometimes skip subtrees + // in the `subtys` iterator (e.g., when encountering a + // projection). + match ty.kind() { + ty::FnDef(_, args) => { + // HACK(eddyb) ignore lifetimes found shallowly in `args`. + // This is inconsistent with `ty::Adt` (including all args) + // and with `ty::Closure` (ignoring all args other than + // upvars, of which a `ty::FnDef` doesn't have any), but + // consistent with previous (accidental) behavior. + // See https://github.com/rust-lang/rust/issues/70917 + // for further background and discussion. + for child in args.iter() { + match child.kind() { + ty::GenericArgKind::Type(ty) => { + compute_components_for_ty(tcx, ty, out, visited); + } + ty::GenericArgKind::Lifetime(_) => {} + ty::GenericArgKind::Const(ct) => { + compute_components_for_const(tcx, ct, out, visited); + } + } + } + } + + ty::Pat(element, _) | ty::Array(element, _) => { + compute_components_for_ty(tcx, element, out, visited); + } + + ty::Closure(_, args) => { + let tupled_ty = args.as_closure().tupled_upvars_ty(); + compute_components_for_ty(tcx, tupled_ty, out, visited); + } + + ty::CoroutineClosure(_, args) => { + let tupled_ty = args.as_coroutine_closure().tupled_upvars_ty(); + compute_components_for_ty(tcx, tupled_ty, out, visited); + } + + ty::Coroutine(_, args) => { + // Same as the closure case + let tupled_ty = args.as_coroutine().tupled_upvars_ty(); + compute_components_for_ty(tcx, tupled_ty, out, visited); + + // We ignore regions in the coroutine interior as we don't + // want these to affect region inference + } + + // All regions are bound inside a witness, and we don't emit + // higher-ranked outlives components currently. + ty::CoroutineWitness(..) => {}, + + // OutlivesTypeParameterEnv -- the actual checking that `X:'a` + // is implied by the environment is done in regionck. + ty::Param(p) => { + out.push(Component::Param(p)); + } + + ty::Placeholder(p) => { + out.push(Component::Placeholder(p)); + } + + // For projections, we prefer to generate an obligation like + // `>::Foo: 'a`, because this gives the + // regionck more ways to prove that it holds. However, + // regionck is not (at least currently) prepared to deal with + // higher-ranked regions that may appear in the + // trait-ref. Therefore, if we see any higher-ranked regions, + // we simply fallback to the most restrictive rule, which + // requires that `Pi: 'a` for all `i`. + ty::Alias(_, alias_ty) => { + if !alias_ty.has_escaping_bound_vars() { + // best case: no escaping regions, so push the + // projection and skip the subtree (thus generating no + // constraints for Pi). This defers the choice between + // the rules OutlivesProjectionEnv, + // OutlivesProjectionTraitDef, and + // OutlivesProjectionComponents to regionck. + out.push(Component::Alias(alias_ty)); + } else { + // fallback case: hard code + // OutlivesProjectionComponents. Continue walking + // through and constrain Pi. + let mut subcomponents = smallvec![]; + let mut subvisited = SsoHashSet::new(); + compute_alias_components_recursive(tcx, ty, &mut subcomponents, &mut subvisited); + out.push(Component::EscapingAlias(subcomponents.into_iter().collect())); + } + } + + // We assume that inference variables are fully resolved. + // So, if we encounter an inference variable, just record + // the unresolved variable as a component. + ty::Infer(infer_ty) => { + out.push(Component::UnresolvedInferenceVariable(infer_ty)); + } + + // Most types do not introduce any region binders, nor + // involve any other subtle cases, and so the WF relation + // simply constraints any regions referenced directly by + // the type and then visits the types that are lexically + // contained within. (The comments refer to relevant rules + // from RFC1214.) + + ty::Bool | // OutlivesScalar + ty::Char | // OutlivesScalar + ty::Int(..) | // OutlivesScalar + ty::Uint(..) | // OutlivesScalar + ty::Float(..) | // OutlivesScalar + ty::Never | // OutlivesScalar + ty::Foreign(..) | // OutlivesNominalType + ty::Str | // OutlivesScalar (ish) + ty::Bound(..) | + ty::Error(_) => { + // Trivial. + } + + // OutlivesNominalType + ty::Adt(_, args) => { + for arg in args.iter() { + compute_components_for_arg(tcx, arg, out, visited); + } + } + + // OutlivesNominalType + ty::Slice(ty) | + ty::RawPtr(ty, _) => { + compute_components_for_ty(tcx, ty, out, visited); + } + ty::Tuple(tys) => { + for ty in tys.iter() { + compute_components_for_ty(tcx, ty, out, visited); + } + } + + // OutlivesReference + ty::Ref(lt, ty, _) => { + compute_components_for_lt(lt, out); + compute_components_for_ty(tcx, ty, out, visited); + } + + ty::Dynamic(preds, lt, _) => { + compute_components_for_lt(lt, out); + for pred in preds.iter() { + match pred.skip_binder() { + ty::ExistentialPredicate::Trait(tr) => { + for arg in tr.args.iter() { + compute_components_for_arg(tcx, arg, out, visited); + } + } + ty::ExistentialPredicate::Projection(proj) => { + for arg in proj.args.iter() { + compute_components_for_arg(tcx, arg, out, visited); + } + match proj.term.kind() { + ty::TermKind::Ty(ty) => { + compute_components_for_ty(tcx, ty, out, visited) + } + ty::TermKind::Const(ct) => { + compute_components_for_const(tcx, ct, out, visited) + } + } + } + ty::ExistentialPredicate::AutoTrait(..) => {} + } + } + } + + ty::FnPtr(sig) => { + for ty in sig.skip_binder().inputs_and_output.iter() { + compute_components_for_ty(tcx, ty, out, visited); + } + } + } +} + +/// Collect [Component]s for *all* the args of `parent`. +/// +/// This should not be used to get the components of `parent` itself. +/// Use [push_outlives_components] instead. +pub fn compute_alias_components_recursive( + tcx: I, + alias_ty: I::Ty, + out: &mut SmallVec<[Component; 4]>, + visited: &mut SsoHashSet, +) { + let ty::Alias(kind, alias_ty) = alias_ty.kind() else { + unreachable!("can only call `compute_alias_components_recursive` on an alias type") + }; + + let opt_variances = + if kind == ty::Opaque { Some(tcx.variances_of(alias_ty.def_id)) } else { None }; + + for (index, child) in alias_ty.args.iter().enumerate() { + if opt_variances.and_then(|variances| variances.get(index)) == Some(ty::Bivariant) { + continue; + } + compute_components_for_arg(tcx, child, out, visited); + } +} + +fn compute_components_for_lt(lt: I::Region, out: &mut SmallVec<[Component; 4]>) { + if !lt.is_bound() { + out.push(Component::Region(lt)); + } +} + +fn compute_components_for_const( + tcx: I, + ct: I::Const, + out: &mut SmallVec<[Component; 4]>, + visited: &mut SsoHashSet, +) { + if !visited.insert(ct.into()) { + return; + } + match ct.kind() { + ty::ConstKind::Param(_) + | ty::ConstKind::Bound(_, _) + | ty::ConstKind::Infer(_) + | ty::ConstKind::Placeholder(_) + | ty::ConstKind::Error(_) => { + // Trivial + } + ty::ConstKind::Expr(e) => { + for arg in e.args().iter() { + compute_components_for_arg(tcx, arg, out, visited); + } + } + ty::ConstKind::Value(ty, _) => { + compute_components_for_ty(tcx, ty, out, visited); + } + ty::ConstKind::Unevaluated(uv) => { + for arg in uv.args.iter() { + compute_components_for_arg(tcx, arg, out, visited); + } + } + } +} diff --git a/tests/ui/async-await/in-trait/async-generics-and-bounds.stderr b/tests/ui/async-await/in-trait/async-generics-and-bounds.stderr index 3cc35b21409a4..b547da7126a44 100644 --- a/tests/ui/async-await/in-trait/async-generics-and-bounds.stderr +++ b/tests/ui/async-await/in-trait/async-generics-and-bounds.stderr @@ -1,29 +1,29 @@ -error[E0311]: the parameter type `U` may not live long enough +error[E0311]: the parameter type `T` may not live long enough --> $DIR/async-generics-and-bounds.rs:9:5 | LL | async fn foo(&self) -> &(T, U) where T: Debug + Sized, U: Hash; | ^^^^^^^^^^^^^-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | | | - | | the parameter type `U` must be valid for the anonymous lifetime as defined here... + | | the parameter type `T` must be valid for the anonymous lifetime as defined here... | ...so that the reference type `&(T, U)` does not outlive the data it points at | help: consider adding an explicit lifetime bound | -LL | async fn foo<'a>(&'a self) -> &'a (T, U) where T: Debug + Sized, U: Hash, U: 'a; +LL | async fn foo<'a>(&'a self) -> &'a (T, U) where T: Debug + Sized, U: Hash, T: 'a; | ++++ ++ ++ +++++++ -error[E0311]: the parameter type `T` may not live long enough +error[E0311]: the parameter type `U` may not live long enough --> $DIR/async-generics-and-bounds.rs:9:5 | LL | async fn foo(&self) -> &(T, U) where T: Debug + Sized, U: Hash; | ^^^^^^^^^^^^^-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | | | - | | the parameter type `T` must be valid for the anonymous lifetime as defined here... + | | the parameter type `U` must be valid for the anonymous lifetime as defined here... | ...so that the reference type `&(T, U)` does not outlive the data it points at | help: consider adding an explicit lifetime bound | -LL | async fn foo<'a>(&'a self) -> &'a (T, U) where T: Debug + Sized, U: Hash, T: 'a; +LL | async fn foo<'a>(&'a self) -> &'a (T, U) where T: Debug + Sized, U: Hash, U: 'a; | ++++ ++ ++ +++++++ error: aborting due to 2 previous errors diff --git a/tests/ui/async-await/in-trait/async-generics.stderr b/tests/ui/async-await/in-trait/async-generics.stderr index 3b27f8fe2f090..2e29a9bcc77a7 100644 --- a/tests/ui/async-await/in-trait/async-generics.stderr +++ b/tests/ui/async-await/in-trait/async-generics.stderr @@ -1,29 +1,29 @@ -error[E0311]: the parameter type `U` may not live long enough +error[E0311]: the parameter type `T` may not live long enough --> $DIR/async-generics.rs:6:5 | LL | async fn foo(&self) -> &(T, U); | ^^^^^^^^^^^^^-^^^^^^^^^^^^^^^^^ | | | - | | the parameter type `U` must be valid for the anonymous lifetime as defined here... + | | the parameter type `T` must be valid for the anonymous lifetime as defined here... | ...so that the reference type `&(T, U)` does not outlive the data it points at | help: consider adding an explicit lifetime bound | -LL | async fn foo<'a>(&'a self) -> &'a (T, U) where U: 'a; +LL | async fn foo<'a>(&'a self) -> &'a (T, U) where T: 'a; | ++++ ++ ++ +++++++++++ -error[E0311]: the parameter type `T` may not live long enough +error[E0311]: the parameter type `U` may not live long enough --> $DIR/async-generics.rs:6:5 | LL | async fn foo(&self) -> &(T, U); | ^^^^^^^^^^^^^-^^^^^^^^^^^^^^^^^ | | | - | | the parameter type `T` must be valid for the anonymous lifetime as defined here... + | | the parameter type `U` must be valid for the anonymous lifetime as defined here... | ...so that the reference type `&(T, U)` does not outlive the data it points at | help: consider adding an explicit lifetime bound | -LL | async fn foo<'a>(&'a self) -> &'a (T, U) where T: 'a; +LL | async fn foo<'a>(&'a self) -> &'a (T, U) where U: 'a; | ++++ ++ ++ +++++++++++ error: aborting due to 2 previous errors From cc6c5de39d51ea41a0189c863130650870526f5d Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 5 Jul 2024 15:30:57 -0400 Subject: [PATCH 771/892] Import via rustc_type_ir::outlives We could use rustc_middle::ty::outlives I guess? --- compiler/rustc_hir_analysis/src/outlives/utils.rs | 2 +- compiler/rustc_infer/src/infer/outlives/mod.rs | 2 -- compiler/rustc_infer/src/infer/outlives/obligations.rs | 2 +- compiler/rustc_infer/src/infer/outlives/verify.rs | 2 +- compiler/rustc_infer/src/traits/util.rs | 2 +- .../src/traits/query/type_op/implied_outlives_bounds.rs | 2 +- 6 files changed, 5 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/outlives/utils.rs b/compiler/rustc_hir_analysis/src/outlives/utils.rs index 5086c2af3f658..08015c28a26ea 100644 --- a/compiler/rustc_hir_analysis/src/outlives/utils.rs +++ b/compiler/rustc_hir_analysis/src/outlives/utils.rs @@ -1,9 +1,9 @@ use rustc_data_structures::fx::FxIndexMap; -use rustc_infer::infer::outlives::components::{push_outlives_components, Component}; use rustc_middle::ty::{self, Region, Ty, TyCtxt}; use rustc_middle::ty::{GenericArg, GenericArgKind}; use rustc_middle::{bug, span_bug}; use rustc_span::Span; +use rustc_type_ir::outlives::{push_outlives_components, Component}; use smallvec::smallvec; /// Tracks the `T: 'a` or `'a: 'a` predicates that we have inferred diff --git a/compiler/rustc_infer/src/infer/outlives/mod.rs b/compiler/rustc_infer/src/infer/outlives/mod.rs index 6e1b044cbac49..89ff460456027 100644 --- a/compiler/rustc_infer/src/infer/outlives/mod.rs +++ b/compiler/rustc_infer/src/infer/outlives/mod.rs @@ -7,8 +7,6 @@ use crate::infer::free_regions::RegionRelations; use crate::infer::lexical_region_resolve; use rustc_middle::traits::query::{NoSolution, OutlivesBound}; use rustc_middle::ty; -// TODO: Remove me -pub use rustc_type_ir::outlives as components; pub mod env; pub mod for_liveness; diff --git a/compiler/rustc_infer/src/infer/outlives/obligations.rs b/compiler/rustc_infer/src/infer/outlives/obligations.rs index c09b5de23b595..9bb5f775e4ade 100644 --- a/compiler/rustc_infer/src/infer/outlives/obligations.rs +++ b/compiler/rustc_infer/src/infer/outlives/obligations.rs @@ -59,7 +59,6 @@ //! might later infer `?U` to something like `&'b u32`, which would //! imply that `'b: 'a`. -use crate::infer::outlives::components::{push_outlives_components, Component}; use crate::infer::outlives::env::RegionBoundPairs; use crate::infer::outlives::verify::VerifyBoundCx; use crate::infer::resolve::OpportunisticRegionResolver; @@ -75,6 +74,7 @@ use rustc_middle::ty::{ }; use rustc_middle::ty::{GenericArgKind, PolyTypeOutlivesPredicate}; use rustc_span::DUMMY_SP; +use rustc_type_ir::outlives::{push_outlives_components, Component}; use smallvec::smallvec; use super::env::OutlivesEnvironment; diff --git a/compiler/rustc_infer/src/infer/outlives/verify.rs b/compiler/rustc_infer/src/infer/outlives/verify.rs index 27dec66ca7746..ad102dfcc1ffd 100644 --- a/compiler/rustc_infer/src/infer/outlives/verify.rs +++ b/compiler/rustc_infer/src/infer/outlives/verify.rs @@ -1,10 +1,10 @@ -use crate::infer::outlives::components::{compute_alias_components_recursive, Component}; use crate::infer::outlives::env::RegionBoundPairs; use crate::infer::region_constraints::VerifyIfEq; use crate::infer::{GenericKind, VerifyBound}; use rustc_data_structures::sso::SsoHashSet; use rustc_middle::ty::GenericArg; use rustc_middle::ty::{self, OutlivesPredicate, Ty, TyCtxt}; +use rustc_type_ir::outlives::{compute_alias_components_recursive, Component}; use smallvec::smallvec; diff --git a/compiler/rustc_infer/src/traits/util.rs b/compiler/rustc_infer/src/traits/util.rs index 24cf9f03fcdb3..118e1ae81934d 100644 --- a/compiler/rustc_infer/src/traits/util.rs +++ b/compiler/rustc_infer/src/traits/util.rs @@ -1,11 +1,11 @@ use smallvec::smallvec; -use crate::infer::outlives::components::{push_outlives_components, Component}; use crate::traits::{self, Obligation, ObligationCauseCode, PredicateObligation}; use rustc_data_structures::fx::FxHashSet; use rustc_middle::ty::{self, Ty, TyCtxt, Upcast}; use rustc_span::symbol::Ident; use rustc_span::Span; +use rustc_type_ir::outlives::{push_outlives_components, Component}; pub fn anonymize_predicate<'tcx>( tcx: TyCtxt<'tcx>, diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs index 40fdf54996984..8525215a3bc61 100644 --- a/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs +++ b/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs @@ -3,7 +3,6 @@ use crate::traits::wf; use crate::traits::ObligationCtxt; use rustc_infer::infer::canonical::Canonical; -use rustc_infer::infer::outlives::components::{push_outlives_components, Component}; use rustc_infer::infer::resolve::OpportunisticRegionResolver; use rustc_infer::traits::query::OutlivesBound; use rustc_macros::{HashStable, TypeFoldable, TypeVisitable}; @@ -12,6 +11,7 @@ use rustc_middle::traits::ObligationCause; use rustc_middle::ty::{self, ParamEnvAnd, Ty, TyCtxt, TypeFolder, TypeVisitableExt}; use rustc_span::def_id::CRATE_DEF_ID; use rustc_span::DUMMY_SP; +use rustc_type_ir::outlives::{push_outlives_components, Component}; use smallvec::{smallvec, SmallVec}; #[derive(Copy, Clone, Debug, HashStable, TypeFoldable, TypeVisitable)] From c2a88ea6cad74bfdad451e055a59b0794d0909ff Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 5 Jul 2024 16:13:20 -0400 Subject: [PATCH 772/892] Remove walk_shallow --- compiler/rustc_middle/src/ty/walk.rs | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/compiler/rustc_middle/src/ty/walk.rs b/compiler/rustc_middle/src/ty/walk.rs index e0f204a687f6e..efcaf89081f77 100644 --- a/compiler/rustc_middle/src/ty/walk.rs +++ b/compiler/rustc_middle/src/ty/walk.rs @@ -78,23 +78,6 @@ impl<'tcx> GenericArg<'tcx> { pub fn walk(self) -> TypeWalker<'tcx> { TypeWalker::new(self) } - - /// Iterator that walks the immediate children of `self`. Hence - /// `Foo, u32>` yields the sequence `[Bar, u32]` - /// (but not `i32`, like `walk`). - /// - /// Iterator only walks items once. - /// It accepts visited set, updates it with all visited types - /// and skips any types that are already there. - pub fn walk_shallow( - self, - visited: &mut SsoHashSet>, - ) -> impl Iterator> { - let mut stack = SmallVec::new(); - push_inner(&mut stack, self); - stack.retain(|a| visited.insert(*a)); - stack.into_iter() - } } impl<'tcx> Ty<'tcx> { From 81c86ddf8e1405062c5f9854d6f94f125abd8e93 Mon Sep 17 00:00:00 2001 From: yukang Date: Sat, 6 Jul 2024 20:59:43 +0800 Subject: [PATCH 773/892] show fnsig's output when there is difference --- compiler/rustc_infer/src/infer/error_reporting/mod.rs | 11 +++-------- .../feature-gate-unboxed-closures-manual-impls.stderr | 4 ++-- tests/ui/fn/fn_def_opaque_coercion_to_fn_ptr.stderr | 4 ++-- tests/ui/impl-trait/trait_type.stderr | 2 +- .../panic-handler-bad-signature-1.stderr | 2 +- tests/ui/traits/impl-method-mismatch.stderr | 2 +- 6 files changed, 10 insertions(+), 15 deletions(-) diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index 1ee535b68b0de..cebb9d09a4798 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -1168,17 +1168,12 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { let output1 = sig1.output(); let output2 = sig2.output(); let (x1, x2) = self.cmp(output1, output2); - let only_output_diff = !lifetime_diff - && sig1.c_variadic == sig2.c_variadic - && sig1.safety == sig2.safety - && sig1.abi == sig2.abi - && sig1.inputs() == sig2.inputs() - && x1 != x2; - if !output1.is_unit() || only_output_diff { + let output_diff = x1 != x2; + if !output1.is_unit() || output_diff { values.0.push_normal(" -> "); (values.0).0.extend(x1.0); } - if !output2.is_unit() || only_output_diff { + if !output2.is_unit() || output_diff { values.1.push_normal(" -> "); (values.1).0.extend(x2.0); } diff --git a/tests/ui/feature-gates/feature-gate-unboxed-closures-manual-impls.stderr b/tests/ui/feature-gates/feature-gate-unboxed-closures-manual-impls.stderr index 06a606b09dc97..584724dfe59cc 100644 --- a/tests/ui/feature-gates/feature-gate-unboxed-closures-manual-impls.stderr +++ b/tests/ui/feature-gates/feature-gate-unboxed-closures-manual-impls.stderr @@ -92,7 +92,7 @@ LL | extern "rust-call" fn call(self, args: ()) -> () {} | ^^^^ expected `&Foo`, found `Foo` | = note: expected signature `extern "rust-call" fn(&Foo, ()) -> _` - found signature `extern "rust-call" fn(Foo, ())` + found signature `extern "rust-call" fn(Foo, ()) -> ()` help: change the self-receiver type to match the trait | LL | extern "rust-call" fn call(&self, args: ()) -> () {} @@ -162,7 +162,7 @@ LL | extern "rust-call" fn call_mut(&self, args: ()) -> () {} | ^^^^^ types differ in mutability | = note: expected signature `extern "rust-call" fn(&mut Bar, ()) -> _` - found signature `extern "rust-call" fn(&Bar, ())` + found signature `extern "rust-call" fn(&Bar, ()) -> ()` help: change the self-receiver type to match the trait | LL | extern "rust-call" fn call_mut(&mut self, args: ()) -> () {} diff --git a/tests/ui/fn/fn_def_opaque_coercion_to_fn_ptr.stderr b/tests/ui/fn/fn_def_opaque_coercion_to_fn_ptr.stderr index 0b3331b040d85..5000601e90f86 100644 --- a/tests/ui/fn/fn_def_opaque_coercion_to_fn_ptr.stderr +++ b/tests/ui/fn/fn_def_opaque_coercion_to_fn_ptr.stderr @@ -10,7 +10,7 @@ LL | x = foo::<()>; | ^^^^^^^^^ expected fn item, found a different fn item | = note: expected fn item `fn(F) -> F {bar::}` - found fn item `fn(()) {foo::<()>}` + found fn item `fn(()) -> () {foo::<()>}` error[E0308]: mismatched types --> $DIR/fn_def_opaque_coercion_to_fn_ptr.rs:27:9 @@ -26,7 +26,7 @@ LL | let mut x = bar::<()>; LL | x = foo::; | ^^^^^^^^ expected fn item, found a different fn item | - = note: expected fn item `fn(()) {bar::<()>}` + = note: expected fn item `fn(()) -> () {bar::<()>}` found fn item `fn(I) -> I {foo::}` help: use parentheses to call this function | diff --git a/tests/ui/impl-trait/trait_type.stderr b/tests/ui/impl-trait/trait_type.stderr index 0eb132c7a1901..989779a617835 100644 --- a/tests/ui/impl-trait/trait_type.stderr +++ b/tests/ui/impl-trait/trait_type.stderr @@ -5,7 +5,7 @@ LL | fn fmt(&self, x: &str) -> () { } | ^^^^ types differ in mutability | = note: expected signature `fn(&MyType, &mut Formatter<'_>) -> Result<(), std::fmt::Error>` - found signature `fn(&MyType, &str)` + found signature `fn(&MyType, &str) -> ()` help: change the parameter type to match the trait | LL | fn fmt(&self, x: &mut Formatter<'_>) -> () { } diff --git a/tests/ui/panic-handler/panic-handler-bad-signature-1.stderr b/tests/ui/panic-handler/panic-handler-bad-signature-1.stderr index 812f7a0692f4b..4fea52fec6e11 100644 --- a/tests/ui/panic-handler/panic-handler-bad-signature-1.stderr +++ b/tests/ui/panic-handler/panic-handler-bad-signature-1.stderr @@ -5,7 +5,7 @@ LL | fn panic(info: PanicInfo) -> () {} | ^^^^^^^^^ expected `&PanicInfo<'_>`, found `PanicInfo<'_>` | = note: expected signature `for<'a, 'b> fn(&'a PanicInfo<'b>) -> !` - found signature `for<'a> fn(PanicInfo<'a>)` + found signature `for<'a> fn(PanicInfo<'a>) -> ()` error: aborting due to 1 previous error diff --git a/tests/ui/traits/impl-method-mismatch.stderr b/tests/ui/traits/impl-method-mismatch.stderr index 77d542c729a93..db457b77a2342 100644 --- a/tests/ui/traits/impl-method-mismatch.stderr +++ b/tests/ui/traits/impl-method-mismatch.stderr @@ -10,7 +10,7 @@ note: type in trait LL | fn jumbo(&self, x: &usize) -> usize; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: expected signature `fn(&_, &_) -> usize` - found signature `unsafe fn(&_, &_)` + found signature `unsafe fn(&_, &_) -> ()` error: aborting due to 1 previous error From 061edfe1fa02a194c94d3aadc3eb4ac579ba3bda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Thu, 4 Jul 2024 15:26:09 +0200 Subject: [PATCH 774/892] Add `#[must_use]` attribute to several command-related methods This should make it harder to accidentally forget to use results of methods on `BootstrapCommand` and `CommandStatus`. --- src/bootstrap/src/utils/exec.rs | 12 ++++++++++++ src/bootstrap/src/utils/helpers.rs | 2 +- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/bootstrap/src/utils/exec.rs b/src/bootstrap/src/utils/exec.rs index b6872d1c99f41..ba963f52dc2b8 100644 --- a/src/bootstrap/src/utils/exec.rs +++ b/src/bootstrap/src/utils/exec.rs @@ -109,14 +109,17 @@ impl BootstrapCommand { self } + #[must_use] pub fn delay_failure(self) -> Self { Self { failure_behavior: BehaviorOnFailure::DelayFail, ..self } } + #[must_use] pub fn fail_fast(self) -> Self { Self { failure_behavior: BehaviorOnFailure::Exit, ..self } } + #[must_use] pub fn allow_failure(self) -> Self { Self { failure_behavior: BehaviorOnFailure::Ignore, ..self } } @@ -127,11 +130,13 @@ impl BootstrapCommand { } /// Capture all output of the command, do not print it. + #[must_use] pub fn capture(self) -> Self { Self { stdout: OutputMode::Capture, stderr: OutputMode::Capture, ..self } } /// Capture stdout of the command, do not print it. + #[must_use] pub fn capture_stdout(self) -> Self { Self { stdout: OutputMode::Capture, ..self } } @@ -178,10 +183,12 @@ pub struct CommandOutput { } impl CommandOutput { + #[must_use] pub fn did_not_start() -> Self { Self { status: CommandStatus::DidNotStart, stdout: vec![], stderr: vec![] } } + #[must_use] pub fn is_success(&self) -> bool { match self.status { CommandStatus::Finished(status) => status.success(), @@ -189,10 +196,12 @@ impl CommandOutput { } } + #[must_use] pub fn is_failure(&self) -> bool { !self.is_success() } + #[must_use] pub fn status(&self) -> Option { match self.status { CommandStatus::Finished(status) => Some(status), @@ -200,14 +209,17 @@ impl CommandOutput { } } + #[must_use] pub fn stdout(&self) -> String { String::from_utf8(self.stdout.clone()).expect("Cannot parse process stdout as UTF-8") } + #[must_use] pub fn stdout_if_ok(&self) -> Option { if self.is_success() { Some(self.stdout()) } else { None } } + #[must_use] pub fn stderr(&self) -> String { String::from_utf8(self.stderr.clone()).expect("Cannot parse process stderr as UTF-8") } diff --git a/src/bootstrap/src/utils/helpers.rs b/src/bootstrap/src/utils/helpers.rs index 8ce0f59399f62..5dd3ba96786ca 100644 --- a/src/bootstrap/src/utils/helpers.rs +++ b/src/bootstrap/src/utils/helpers.rs @@ -499,7 +499,7 @@ pub fn check_cfg_arg(name: &str, values: Option<&[&str]>) -> String { /// Whenever a git invocation is needed, this function should be preferred over /// manually building a git `BootstrapCommand`. This approach allows us to manage /// bootstrap-specific needs/hacks from a single source, rather than applying them on next to every -/// `BootstrapCommand::new("git")`, which is painful to ensure that the required change is applied +/// git command creation, which is painful to ensure that the required change is applied /// on each one of them correctly. pub fn git(source_dir: Option<&Path>) -> BootstrapCommand { let mut git = command("git"); From d6276b37eace2e49794679fb927b6b499e00a064 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 5 Jul 2024 21:59:07 -0400 Subject: [PATCH 775/892] Don't try to label ObligationCauseCode::CompareImplItem for an RPITIT, since it has no name --- .../src/traits/error_reporting/suggestions.rs | 4 + tests/crashes/125099.rs | 24 --- ...-predicate-entailment-error.current.stderr | 173 ++++++++++++++++++ ...lse-positive-predicate-entailment-error.rs | 51 ++++++ 4 files changed, 228 insertions(+), 24 deletions(-) delete mode 100644 tests/crashes/125099.rs create mode 100644 tests/ui/impl-trait/in-trait/false-positive-predicate-entailment-error.current.stderr create mode 100644 tests/ui/impl-trait/in-trait/false-positive-predicate-entailment-error.rs diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index a0a8e5963f109..52edffce61459 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -3472,6 +3472,10 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { ) }); } + // Suppress `compare_type_predicate_entailment` errors for RPITITs, since they + // should be implied by the parent method. + ObligationCauseCode::CompareImplItem { trait_item_def_id, .. } + if tcx.is_impl_trait_in_trait(trait_item_def_id) => {} ObligationCauseCode::CompareImplItem { trait_item_def_id, kind, .. } => { let item_name = tcx.item_name(trait_item_def_id); let msg = format!( diff --git a/tests/crashes/125099.rs b/tests/crashes/125099.rs deleted file mode 100644 index bfc8c8fdcf683..0000000000000 --- a/tests/crashes/125099.rs +++ /dev/null @@ -1,24 +0,0 @@ -//@ known-bug: rust-lang/rust#125099 - -pub trait ContFn: Fn(T) -> Self::Future { - type Future; -} -impl ContFn for F -where - F: Fn(T), -{ - type Future = (); -} - -pub trait SeqHandler { - type Requires; - fn process>() -> impl Sized; -} - -pub struct ConvertToU64; -impl SeqHandler for ConvertToU64 { - type Requires = u64; - fn process>() -> impl Sized {} -} - -fn main() {} diff --git a/tests/ui/impl-trait/in-trait/false-positive-predicate-entailment-error.current.stderr b/tests/ui/impl-trait/in-trait/false-positive-predicate-entailment-error.current.stderr new file mode 100644 index 0000000000000..d71c1768a6a3b --- /dev/null +++ b/tests/ui/impl-trait/in-trait/false-positive-predicate-entailment-error.current.stderr @@ -0,0 +1,173 @@ +error[E0277]: the trait bound `F: MyFn` is not satisfied + --> $DIR/false-positive-predicate-entailment-error.rs:36:5 + | +LL | / fn autobatch(self) -> impl Trait +LL | | +LL | | +LL | | +... | +LL | | where +LL | | F: Callback, + | |_______________________________________^ the trait `MyFn` is not implemented for `F`, which is required by `F: Callback` + | +note: required for `F` to implement `Callback` + --> $DIR/false-positive-predicate-entailment-error.rs:14:21 + | +LL | impl> Callback for F { + | ------- ^^^^^^^^^^^ ^ + | | + | unsatisfied trait bound introduced here +help: consider further restricting this bound + | +LL | F: Callback + MyFn, + | +++++++++++ + +error[E0277]: the trait bound `F: MyFn` is not satisfied + --> $DIR/false-positive-predicate-entailment-error.rs:36:30 + | +LL | fn autobatch(self) -> impl Trait + | ^^^^^^^^^^ the trait `MyFn` is not implemented for `F`, which is required by `F: Callback` + | +note: required for `F` to implement `Callback` + --> $DIR/false-positive-predicate-entailment-error.rs:14:21 + | +LL | impl> Callback for F { + | ------- ^^^^^^^^^^^ ^ + | | + | unsatisfied trait bound introduced here +note: required by a bound in `::autobatch` + --> $DIR/false-positive-predicate-entailment-error.rs:43:12 + | +LL | fn autobatch(self) -> impl Trait + | --------- required by a bound in this associated function +... +LL | F: Callback, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `::autobatch` +help: consider further restricting this bound + | +LL | F: Callback + MyFn, + | +++++++++++ + +error[E0277]: the trait bound `F: MyFn` is not satisfied + --> $DIR/false-positive-predicate-entailment-error.rs:36:5 + | +LL | / fn autobatch(self) -> impl Trait +LL | | +LL | | +LL | | +... | +LL | | where +LL | | F: Callback, + | |_______________________________________^ the trait `MyFn` is not implemented for `F`, which is required by `F: Callback` + | +note: required for `F` to implement `Callback` + --> $DIR/false-positive-predicate-entailment-error.rs:14:21 + | +LL | impl> Callback for F { + | ------- ^^^^^^^^^^^ ^ + | | + | unsatisfied trait bound introduced here + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` +help: consider further restricting this bound + | +LL | F: Callback + MyFn, + | +++++++++++ + +error[E0277]: the trait bound `F: Callback` is not satisfied + --> $DIR/false-positive-predicate-entailment-error.rs:43:12 + | +LL | F: Callback, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `MyFn` is not implemented for `F`, which is required by `F: Callback` + | +note: required for `F` to implement `Callback` + --> $DIR/false-positive-predicate-entailment-error.rs:14:21 + | +LL | impl> Callback for F { + | ------- ^^^^^^^^^^^ ^ + | | + | unsatisfied trait bound introduced here +note: the requirement `F: Callback` appears on the `impl`'s method `autobatch` but not on the corresponding trait's method + --> $DIR/false-positive-predicate-entailment-error.rs:25:8 + | +LL | trait ChannelSender { + | ------------- in this trait +... +LL | fn autobatch(self) -> impl Trait + | ^^^^^^^^^ this trait's method doesn't have the requirement `F: Callback` +help: consider further restricting this bound + | +LL | F: Callback + MyFn, + | +++++++++++ + +error[E0277]: the trait bound `F: MyFn` is not satisfied + --> $DIR/false-positive-predicate-entailment-error.rs:36:30 + | +LL | fn autobatch(self) -> impl Trait + | ^^^^^^^^^^ the trait `MyFn` is not implemented for `F`, which is required by `F: Callback` + | +note: required for `F` to implement `Callback` + --> $DIR/false-positive-predicate-entailment-error.rs:14:21 + | +LL | impl> Callback for F { + | ------- ^^^^^^^^^^^ ^ + | | + | unsatisfied trait bound introduced here + +error[E0277]: the trait bound `F: Callback` is not satisfied + --> $DIR/false-positive-predicate-entailment-error.rs:27:12 + | +LL | F: Callback; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `MyFn` is not implemented for `F`, which is required by `F: Callback` + | +note: required for `F` to implement `Callback` + --> $DIR/false-positive-predicate-entailment-error.rs:14:21 + | +LL | impl> Callback for F { + | ------- ^^^^^^^^^^^ ^ + | | + | unsatisfied trait bound introduced here + +error[E0277]: the trait bound `F: MyFn` is not satisfied + --> $DIR/false-positive-predicate-entailment-error.rs:36:5 + | +LL | / fn autobatch(self) -> impl Trait +LL | | +LL | | +LL | | +... | +LL | | where +LL | | F: Callback, + | |_______________________________________^ the trait `MyFn` is not implemented for `F`, which is required by `F: Callback` + | +note: required for `F` to implement `Callback` + --> $DIR/false-positive-predicate-entailment-error.rs:14:21 + | +LL | impl> Callback for F { + | ------- ^^^^^^^^^^^ ^ + | | + | unsatisfied trait bound introduced here + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` +help: consider further restricting this bound + | +LL | F: Callback + MyFn, + | +++++++++++ + +error[E0277]: the trait bound `F: MyFn` is not satisfied + --> $DIR/false-positive-predicate-entailment-error.rs:43:12 + | +LL | F: Callback, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `MyFn` is not implemented for `F` + | +note: required by a bound in `Callback` + --> $DIR/false-positive-predicate-entailment-error.rs:10:20 + | +LL | trait Callback: MyFn { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Callback` +help: consider further restricting this bound + | +LL | F: Callback + MyFn, + | +++++++++++ + +error: aborting due to 8 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/impl-trait/in-trait/false-positive-predicate-entailment-error.rs b/tests/ui/impl-trait/in-trait/false-positive-predicate-entailment-error.rs new file mode 100644 index 0000000000000..59fdeab9e0a9f --- /dev/null +++ b/tests/ui/impl-trait/in-trait/false-positive-predicate-entailment-error.rs @@ -0,0 +1,51 @@ +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver +//@[next] check-pass + +trait MyFn { + type Output; +} + +trait Callback: MyFn { + type Ret; +} + +impl> Callback for F { + type Ret = F::Output; +} + +struct Thing; +trait Trait {} +impl Trait for Thing {} + +trait ChannelSender { + type CallbackArg; + + fn autobatch(self) -> impl Trait + where + F: Callback; + //[current]~^ ERROR the trait bound `F: Callback` is not satisfied +} + +struct Sender; + +impl ChannelSender for Sender { + type CallbackArg = i32; + + fn autobatch(self) -> impl Trait + //[current]~^ ERROR the trait bound `F: MyFn` is not satisfied + //[current]~| ERROR the trait bound `F: MyFn` is not satisfied + //[current]~| ERROR the trait bound `F: MyFn` is not satisfied + //[current]~| ERROR the trait bound `F: MyFn` is not satisfied + //[current]~| ERROR the trait bound `F: MyFn` is not satisfied + where + F: Callback, + //[current]~^ ERROR the trait bound `F: Callback` is not satisfied + //[current]~| ERROR the trait bound `F: MyFn` is not satisfied + { + Thing + } +} + +fn main() {} From 8c2ea715e9b0df15881392b248576a2ee8c13075 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Sat, 6 Jul 2024 19:21:22 +0000 Subject: [PATCH 776/892] Use field ident spans directly instead of the full field span in diagnostics on local fields --- .../rustc_resolve/src/build_reduced_graph.rs | 10 ++++- compiler/rustc_resolve/src/diagnostics.rs | 6 +-- .../rustc_resolve/src/late/diagnostics.rs | 44 ++++++++----------- compiler/rustc_resolve/src/lib.rs | 18 +++++--- ...d-in-self-not-available-in-assoc-fn.stderr | 4 +- tests/ui/resolve/issue-2356.stderr | 4 +- tests/ui/resolve/issue-60057.stderr | 2 +- ...e-with-name-similar-to-struct-field.stderr | 4 +- .../unresolved_static_type_field.stderr | 2 +- 9 files changed, 49 insertions(+), 45 deletions(-) diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs index 4e0f2792d9749..92cf73870ff13 100644 --- a/compiler/rustc_resolve/src/build_reduced_graph.rs +++ b/compiler/rustc_resolve/src/build_reduced_graph.rs @@ -321,8 +321,14 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> { // The fields are not expanded yet. return; } - let def_ids = fields.iter().map(|field| self.r.local_def_id(field.id).to_def_id()); - self.r.field_def_ids.insert(def_id, self.r.tcx.arena.alloc_from_iter(def_ids)); + let fields = fields + .iter() + .enumerate() + .map(|(i, field)| { + field.ident.unwrap_or_else(|| Ident::from_str_and_span(&format!("{i}"), field.span)) + }) + .collect(); + self.r.field_names.insert(def_id, fields); } fn insert_field_visibilities_local(&mut self, def_id: DefId, fields: &[ast::FieldDef]) { diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index 50a4e03d233a7..ffd495aa9857e 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -1726,11 +1726,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { )) = binding.kind { let def_id = self.tcx.parent(ctor_def_id); - return self - .field_def_ids(def_id)? - .iter() - .map(|&field_id| self.def_span(field_id)) - .reduce(Span::to); // None for `struct Foo()` + return self.field_idents(def_id)?.iter().map(|&f| f.span).reduce(Span::to); // None for `struct Foo()` } None } diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 764cc350182a6..941fb6436df92 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -1532,17 +1532,17 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { if !this.has_private_fields(def_id) { // If the fields of the type are private, we shouldn't be suggesting using // the struct literal syntax at all, as that will cause a subsequent error. - let field_ids = this.r.field_def_ids(def_id); - let (fields, applicability) = match field_ids { - Some(field_ids) => { - let fields = field_ids.iter().map(|&id| this.r.tcx.item_name(id)); - + let fields = this.r.field_idents(def_id); + let has_fields = fields.as_ref().is_some_and(|f| !f.is_empty()); + let (fields, applicability) = match fields { + Some(fields) => { let fields = if let Some(old_fields) = old_fields { fields + .iter() .enumerate() .map(|(idx, new)| (new, old_fields.get(idx))) .map(|(new, old)| { - let new = new.to_ident_string(); + let new = new.name.to_ident_string(); if let Some(Some(old)) = old && new != *old { @@ -1553,17 +1553,17 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { }) .collect::>() } else { - fields.map(|f| format!("{f}{tail}")).collect::>() + fields + .iter() + .map(|f| format!("{f}{tail}")) + .collect::>() }; (fields.join(", "), applicability) } None => ("/* fields */".to_string(), Applicability::HasPlaceholders), }; - let pad = match field_ids { - Some([]) => "", - _ => " ", - }; + let pad = if has_fields { " " } else { "" }; err.span_suggestion( span, format!("use struct {descr} syntax instead"), @@ -1723,12 +1723,9 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { &args[..], ); // Use spans of the tuple struct definition. - self.r.field_def_ids(def_id).map(|field_ids| { - field_ids - .iter() - .map(|&field_id| self.r.def_span(field_id)) - .collect::>() - }) + self.r + .field_idents(def_id) + .map(|fields| fields.iter().map(|f| f.span).collect::>()) } _ => None, }; @@ -1791,7 +1788,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { (Res::Def(DefKind::Ctor(_, CtorKind::Fn), ctor_def_id), _) if ns == ValueNS => { let def_id = self.r.tcx.parent(ctor_def_id); err.span_label(self.r.def_span(def_id), format!("`{path_str}` defined here")); - let fields = self.r.field_def_ids(def_id).map_or_else( + let fields = self.r.field_idents(def_id).map_or_else( || "/* fields */".to_string(), |field_ids| vec!["_"; field_ids.len()].join(", "), ); @@ -2017,12 +2014,9 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { if let Some(Res::Def(DefKind::Struct | DefKind::Union, did)) = resolution.full_res() { - if let Some(field_ids) = self.r.field_def_ids(did) { - if let Some(field_id) = field_ids - .iter() - .find(|&&field_id| ident.name == self.r.tcx.item_name(field_id)) - { - return Some(AssocSuggestion::Field(self.r.def_span(*field_id))); + if let Some(fields) = self.r.field_idents(did) { + if let Some(field) = fields.iter().find(|id| ident.name == id.name) { + return Some(AssocSuggestion::Field(field.span)); } } } @@ -2418,7 +2412,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { match kind { CtorKind::Const => false, CtorKind::Fn => { - !self.r.field_def_ids(def_id).is_some_and(|field_ids| field_ids.is_empty()) + !self.r.field_idents(def_id).is_some_and(|field_ids| field_ids.is_empty()) } } }; diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 38963ef4ef092..7bf32a023f1e1 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -991,7 +991,7 @@ pub struct Resolver<'a, 'tcx> { extern_prelude: FxHashMap>, /// N.B., this is used only for better diagnostics, not name resolution itself. - field_def_ids: LocalDefIdMap<&'tcx [DefId]>, + field_names: LocalDefIdMap>, /// Span of the privacy modifier in fields of an item `DefId` accessible with dot syntax. /// Used for hints during error reporting. @@ -1406,7 +1406,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { prelude: None, extern_prelude, - field_def_ids: Default::default(), + field_names: Default::default(), field_visibility_spans: FxHashMap::default(), determined_imports: Vec::new(), @@ -2127,10 +2127,18 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { } } - fn field_def_ids(&self, def_id: DefId) -> Option<&'tcx [DefId]> { + fn field_idents(&self, def_id: DefId) -> Option> { match def_id.as_local() { - Some(def_id) => self.field_def_ids.get(&def_id).copied(), - None => Some(self.tcx.associated_item_def_ids(def_id)), + Some(def_id) => self.field_names.get(&def_id).cloned(), + None => Some( + self.tcx + .associated_item_def_ids(def_id) + .iter() + .map(|&def_id| { + Ident::new(self.tcx.item_name(def_id), self.tcx.def_span(def_id)) + }) + .collect(), + ), } } diff --git a/tests/ui/resolve/field-and-method-in-self-not-available-in-assoc-fn.stderr b/tests/ui/resolve/field-and-method-in-self-not-available-in-assoc-fn.stderr index 3c44c1c249ce2..2f624f24804c8 100644 --- a/tests/ui/resolve/field-and-method-in-self-not-available-in-assoc-fn.stderr +++ b/tests/ui/resolve/field-and-method-in-self-not-available-in-assoc-fn.stderr @@ -2,7 +2,7 @@ error[E0425]: cannot find value `field` in this scope --> $DIR/field-and-method-in-self-not-available-in-assoc-fn.rs:11:9 | LL | field: u32, - | ---------- a field by that name exists in `Self` + | ----- a field by that name exists in `Self` ... LL | fn field(&self) -> u32 { | ----- a method by that name is available on `Self` here @@ -14,7 +14,7 @@ error[E0425]: cannot find value `field` in this scope --> $DIR/field-and-method-in-self-not-available-in-assoc-fn.rs:12:15 | LL | field: u32, - | ---------- a field by that name exists in `Self` + | ----- a field by that name exists in `Self` ... LL | fn field(&self) -> u32 { | ----- a method by that name is available on `Self` here diff --git a/tests/ui/resolve/issue-2356.stderr b/tests/ui/resolve/issue-2356.stderr index 5f75ae988702f..74a2c9268a2f9 100644 --- a/tests/ui/resolve/issue-2356.stderr +++ b/tests/ui/resolve/issue-2356.stderr @@ -2,7 +2,7 @@ error[E0425]: cannot find value `whiskers` in this scope --> $DIR/issue-2356.rs:39:5 | LL | whiskers: isize, - | --------------- a field by that name exists in `Self` + | -------- a field by that name exists in `Self` ... LL | whiskers -= other; | ^^^^^^^^ @@ -35,7 +35,7 @@ error[E0425]: cannot find value `whiskers` in this scope --> $DIR/issue-2356.rs:84:5 | LL | whiskers: isize, - | --------------- a field by that name exists in `Self` + | -------- a field by that name exists in `Self` ... LL | whiskers = 4; | ^^^^^^^^ diff --git a/tests/ui/resolve/issue-60057.stderr b/tests/ui/resolve/issue-60057.stderr index a2ab86443536c..8737cf770015f 100644 --- a/tests/ui/resolve/issue-60057.stderr +++ b/tests/ui/resolve/issue-60057.stderr @@ -2,7 +2,7 @@ error[E0425]: cannot find value `banana` in this scope --> $DIR/issue-60057.rs:8:21 | LL | banana: u8, - | ---------- a field by that name exists in `Self` + | ------ a field by that name exists in `Self` ... LL | banana: banana | ^^^^^^ diff --git a/tests/ui/resolve/typo-suggestion-for-variable-with-name-similar-to-struct-field.stderr b/tests/ui/resolve/typo-suggestion-for-variable-with-name-similar-to-struct-field.stderr index 0306c8af87d85..5662021a2d523 100644 --- a/tests/ui/resolve/typo-suggestion-for-variable-with-name-similar-to-struct-field.stderr +++ b/tests/ui/resolve/typo-suggestion-for-variable-with-name-similar-to-struct-field.stderr @@ -2,7 +2,7 @@ error[E0425]: cannot find value `config` in this scope --> $DIR/typo-suggestion-for-variable-with-name-similar-to-struct-field.rs:7:16 | LL | config: String, - | -------------- a field by that name exists in `Self` + | ------ a field by that name exists in `Self` ... LL | Self { config } | ^^^^^^ help: a local variable with a similar name exists: `cofig` @@ -11,7 +11,7 @@ error[E0425]: cannot find value `config` in this scope --> $DIR/typo-suggestion-for-variable-with-name-similar-to-struct-field.rs:11:20 | LL | config: String, - | -------------- a field by that name exists in `Self` + | ------ a field by that name exists in `Self` ... LL | println!("{config}"); | ^^^^^^ help: a local variable with a similar name exists: `cofig` diff --git a/tests/ui/resolve/unresolved_static_type_field.stderr b/tests/ui/resolve/unresolved_static_type_field.stderr index e3de0a3fb74b3..f039eef2e06b9 100644 --- a/tests/ui/resolve/unresolved_static_type_field.stderr +++ b/tests/ui/resolve/unresolved_static_type_field.stderr @@ -2,7 +2,7 @@ error[E0425]: cannot find value `cx` in this scope --> $DIR/unresolved_static_type_field.rs:9:11 | LL | cx: bool, - | -------- a field by that name exists in `Self` + | -- a field by that name exists in `Self` ... LL | f(cx); | ^^ From 8d8504300fe7ad9b20a7690cce8025290847f155 Mon Sep 17 00:00:00 2001 From: Elisha Hollander Date: Sat, 6 Jul 2024 20:11:42 +0000 Subject: [PATCH 777/892] remove regexes --- src/tools/tidy/src/style.rs | 36 ++++++++++++++++++------------- src/tools/tidy/src/style/tests.rs | 19 ++++++---------- 2 files changed, 27 insertions(+), 28 deletions(-) diff --git a/src/tools/tidy/src/style.rs b/src/tools/tidy/src/style.rs index e4d54d2a2b589..f65001e8de881 100644 --- a/src/tools/tidy/src/style.rs +++ b/src/tools/tidy/src/style.rs @@ -18,9 +18,8 @@ // ignore-tidy-dbg use crate::walk::{filter_dirs, walk}; -use regex::RegexSet; use rustc_hash::FxHashMap; -use std::{ffi::OsStr, path::Path}; +use std::{ffi::OsStr, path::Path, sync::LazyLock}; #[cfg(test)] mod tests; @@ -110,15 +109,32 @@ const ROOT_PROBLEMATIC_CONSTS: &[u32] = &[ 173390526, 721077, ]; +#[cfg(not(test))] +const LETTER_DIGIT: &[(char, char)] = &[('A', '4'), ('B', '8'), ('E', '3')]; + +#[cfg(test)] +const LETTER_DIGIT: &[(char, char)] = &[('A', '4'), ('B', '8'), ('E', '3'), ('0', 'F')]; // use "futile" F intentionally + fn generate_problematic_strings( consts: &[u32], letter_digit: &FxHashMap, ) -> Vec { generate_problems(consts, letter_digit) - .flat_map(|v| vec![v.to_string(), format!("{:x}", v), format!("{:X}", v)]) + .flat_map(|v| vec![v.to_string(), format!("{:X}", v)]) .collect() } +static PROBLEMATIC_CONSTS_STRINGS: LazyLock> = LazyLock::new(|| { + generate_problematic_strings( + ROOT_PROBLEMATIC_CONSTS, + &FxHashMap::from_iter(LETTER_DIGIT.iter().copied()), + ) +}); + +fn contains_problematic_const(trimmed: &str) -> bool { + PROBLEMATIC_CONSTS_STRINGS.iter().any(|s| trimmed.to_uppercase().contains(s)) +} + const INTERNAL_COMPILER_DOCS_LINE: &str = "#### This error code is internal to the compiler and will not be emitted with normal Rust code."; /// Parser states for `line_is_url`. @@ -315,11 +331,6 @@ pub fn check(path: &Path, bad: &mut bool) { // We only check CSS files in rustdoc. path.extension().map_or(false, |e| e == "css") && !is_in(path, "src", "librustdoc") } - let problematic_consts_strings = generate_problematic_strings( - ROOT_PROBLEMATIC_CONSTS, - &[('A', '4'), ('B', '8'), ('E', '3')].iter().cloned().collect(), - ); - let problematic_regex = RegexSet::new(problematic_consts_strings.as_slice()).unwrap(); walk(path, skip, &mut |entry, contents| { let file = entry.path(); @@ -389,7 +400,6 @@ pub fn check(path: &Path, bad: &mut bool) { let is_test = file.components().any(|c| c.as_os_str() == "tests"); // scanning the whole file for multiple needles at once is more efficient than // executing lines times needles separate searches. - let any_problematic_line = problematic_regex.is_match(contents); for (i, line) in contents.split('\n').enumerate() { if line.is_empty() { if i == 0 { @@ -459,12 +469,8 @@ pub fn check(path: &Path, bad: &mut bool) { if trimmed.contains("//") && trimmed.contains(" XXX") { err("Instead of XXX use FIXME") } - if any_problematic_line { - for s in problematic_consts_strings.iter() { - if trimmed.contains(s) { - err("Don't use magic numbers that spell things (consider 0x12345678)"); - } - } + if contains_problematic_const(trimmed) { + err("Don't use magic numbers that spell things (consider 0x12345678)"); } } // for now we just check libcore diff --git a/src/tools/tidy/src/style/tests.rs b/src/tools/tidy/src/style/tests.rs index 292e23916d241..47fec89043212 100644 --- a/src/tools/tidy/src/style/tests.rs +++ b/src/tools/tidy/src/style/tests.rs @@ -1,17 +1,10 @@ use super::*; #[test] -fn test_generate_problematic_strings() { - let problematic_regex = RegexSet::new( - generate_problematic_strings( - ROOT_PROBLEMATIC_CONSTS, - &[('A', '4'), ('B', '8'), ('E', '3'), ('0', 'F')].iter().cloned().collect(), // use "futile" F intentionally - ) - .as_slice(), - ) - .unwrap(); - assert!(problematic_regex.is_match("786357")); // check with no "decimal" hex digits - converted to integer - assert!(problematic_regex.is_match("589701")); // check with "decimal" replacements - converted to integer - assert!(problematic_regex.is_match("8FF85")); // check for hex display - assert!(!problematic_regex.is_match("1193046")); // check for non-matching value +fn test_contains_problematic_const() { + assert!(contains_problematic_const("786357")); // check with no "decimal" hex digits - converted to integer + assert!(contains_problematic_const("589701")); // check with "decimal" replacements - converted to integer + assert!(contains_problematic_const("8FF85")); // check for hex display + assert!(contains_problematic_const("8fF85")); // check for case-alternating hex display + assert!(!contains_problematic_const("1193046")); // check for non-matching value } From c990e00f15f71cbff847f6988be4f512aca318bc Mon Sep 17 00:00:00 2001 From: Caio Date: Sat, 6 Jul 2024 18:00:04 -0300 Subject: [PATCH 778/892] Add support for literals --- compiler/rustc_expand/src/mbe/metavar_expr.rs | 74 ++++++++---- compiler/rustc_expand/src/mbe/transcribe.rs | 32 +++++- .../allowed-operations.rs | 12 ++ .../raw-identifiers.rs | 6 +- .../raw-identifiers.stderr | 6 +- .../syntax-errors.rs | 78 ++++++++++++- .../syntax-errors.stderr | 107 ++++++++++++++---- .../unicode-expansion.rs | 14 +++ .../syntax-errors.stderr | 2 +- 9 files changed, 272 insertions(+), 59 deletions(-) create mode 100644 tests/ui/macros/macro-metavar-expr-concat/unicode-expansion.rs diff --git a/compiler/rustc_expand/src/mbe/metavar_expr.rs b/compiler/rustc_expand/src/mbe/metavar_expr.rs index 25958e03028f4..dbbd948fd7073 100644 --- a/compiler/rustc_expand/src/mbe/metavar_expr.rs +++ b/compiler/rustc_expand/src/mbe/metavar_expr.rs @@ -1,4 +1,4 @@ -use rustc_ast::token::{self, Delimiter, IdentIsRaw}; +use rustc_ast::token::{self, Delimiter, IdentIsRaw, Lit, Token, TokenKind}; use rustc_ast::tokenstream::{RefTokenTreeCursor, TokenStream, TokenTree}; use rustc_ast::{LitIntType, LitKind}; use rustc_ast_pretty::pprust; @@ -6,9 +6,10 @@ use rustc_errors::{Applicability, PResult}; use rustc_macros::{Decodable, Encodable}; use rustc_session::parse::ParseSess; use rustc_span::symbol::Ident; -use rustc_span::Span; +use rustc_span::{Span, Symbol}; pub(crate) const RAW_IDENT_ERR: &str = "`${concat(..)}` currently does not support raw identifiers"; +pub(crate) const UNSUPPORTED_CONCAT_ELEM_ERR: &str = "expected identifier or string literal"; /// A meta-variable expression, for expansions based on properties of meta-variables. #[derive(Debug, PartialEq, Encodable, Decodable)] @@ -51,11 +52,26 @@ impl MetaVarExpr { let mut result = Vec::new(); loop { let is_var = try_eat_dollar(&mut iter); - let element_ident = parse_ident(&mut iter, psess, outer_span)?; + let token = parse_token(&mut iter, psess, outer_span)?; let element = if is_var { - MetaVarExprConcatElem::Var(element_ident) + MetaVarExprConcatElem::Var(parse_ident_from_token(psess, token)?) + } else if let TokenKind::Literal(Lit { + kind: token::LitKind::Str, + symbol, + suffix: None, + }) = token.kind + { + MetaVarExprConcatElem::Literal(symbol) } else { - MetaVarExprConcatElem::Ident(element_ident) + match parse_ident_from_token(psess, token) { + Err(err) => { + err.cancel(); + return Err(psess + .dcx() + .struct_span_err(token.span, UNSUPPORTED_CONCAT_ELEM_ERR)); + } + Ok(elem) => MetaVarExprConcatElem::Ident(elem), + } }; result.push(element); if iter.look_ahead(0).is_none() { @@ -105,11 +121,13 @@ impl MetaVarExpr { #[derive(Debug, Decodable, Encodable, PartialEq)] pub(crate) enum MetaVarExprConcatElem { - /// There is NO preceding dollar sign, which means that this identifier should be interpreted - /// as a literal. + /// Identifier WITHOUT a preceding dollar sign, which means that this identifier should be + /// interpreted as a literal. Ident(Ident), - /// There is a preceding dollar sign, which means that this identifier should be expanded - /// and interpreted as a variable. + /// For example, a number or a string. + Literal(Symbol), + /// Identifier WITH a preceding dollar sign, which means that this identifier should be + /// expanded and interpreted as a variable. Var(Ident), } @@ -158,7 +176,7 @@ fn parse_depth<'psess>( span: Span, ) -> PResult<'psess, usize> { let Some(tt) = iter.next() else { return Ok(0) }; - let TokenTree::Token(token::Token { kind: token::TokenKind::Literal(lit), .. }, _) = tt else { + let TokenTree::Token(Token { kind: TokenKind::Literal(lit), .. }, _) = tt else { return Err(psess .dcx() .struct_span_err(span, "meta-variable expression depth must be a literal")); @@ -180,12 +198,14 @@ fn parse_ident<'psess>( psess: &'psess ParseSess, fallback_span: Span, ) -> PResult<'psess, Ident> { - let Some(tt) = iter.next() else { - return Err(psess.dcx().struct_span_err(fallback_span, "expected identifier")); - }; - let TokenTree::Token(token, _) = tt else { - return Err(psess.dcx().struct_span_err(tt.span(), "expected identifier")); - }; + let token = parse_token(iter, psess, fallback_span)?; + parse_ident_from_token(psess, token) +} + +fn parse_ident_from_token<'psess>( + psess: &'psess ParseSess, + token: &Token, +) -> PResult<'psess, Ident> { if let Some((elem, is_raw)) = token.ident() { if let IdentIsRaw::Yes = is_raw { return Err(psess.dcx().struct_span_err(elem.span, RAW_IDENT_ERR)); @@ -205,10 +225,24 @@ fn parse_ident<'psess>( Err(err) } +fn parse_token<'psess, 't>( + iter: &mut RefTokenTreeCursor<'t>, + psess: &'psess ParseSess, + fallback_span: Span, +) -> PResult<'psess, &'t Token> { + let Some(tt) = iter.next() else { + return Err(psess.dcx().struct_span_err(fallback_span, UNSUPPORTED_CONCAT_ELEM_ERR)); + }; + let TokenTree::Token(token, _) = tt else { + return Err(psess.dcx().struct_span_err(tt.span(), UNSUPPORTED_CONCAT_ELEM_ERR)); + }; + Ok(token) +} + /// Tries to move the iterator forward returning `true` if there is a comma. If not, then the /// iterator is not modified and the result is `false`. fn try_eat_comma(iter: &mut RefTokenTreeCursor<'_>) -> bool { - if let Some(TokenTree::Token(token::Token { kind: token::Comma, .. }, _)) = iter.look_ahead(0) { + if let Some(TokenTree::Token(Token { kind: token::Comma, .. }, _)) = iter.look_ahead(0) { let _ = iter.next(); return true; } @@ -218,8 +252,7 @@ fn try_eat_comma(iter: &mut RefTokenTreeCursor<'_>) -> bool { /// Tries to move the iterator forward returning `true` if there is a dollar sign. If not, then the /// iterator is not modified and the result is `false`. fn try_eat_dollar(iter: &mut RefTokenTreeCursor<'_>) -> bool { - if let Some(TokenTree::Token(token::Token { kind: token::Dollar, .. }, _)) = iter.look_ahead(0) - { + if let Some(TokenTree::Token(Token { kind: token::Dollar, .. }, _)) = iter.look_ahead(0) { let _ = iter.next(); return true; } @@ -232,8 +265,7 @@ fn eat_dollar<'psess>( psess: &'psess ParseSess, span: Span, ) -> PResult<'psess, ()> { - if let Some(TokenTree::Token(token::Token { kind: token::Dollar, .. }, _)) = iter.look_ahead(0) - { + if let Some(TokenTree::Token(Token { kind: token::Dollar, .. }, _)) = iter.look_ahead(0) { let _ = iter.next(); return Ok(()); } diff --git a/compiler/rustc_expand/src/mbe/transcribe.rs b/compiler/rustc_expand/src/mbe/transcribe.rs index f935f1b77e0b2..9b4dc13c703a1 100644 --- a/compiler/rustc_expand/src/mbe/transcribe.rs +++ b/compiler/rustc_expand/src/mbe/transcribe.rs @@ -11,11 +11,13 @@ use rustc_ast::token::{self, Delimiter, Token, TokenKind}; use rustc_ast::tokenstream::{DelimSpacing, DelimSpan, Spacing, TokenStream, TokenTree}; use rustc_data_structures::fx::FxHashMap; use rustc_errors::{pluralize, Diag, DiagCtxtHandle, PResult}; +use rustc_parse::lexer::nfc_normalize; use rustc_parse::parser::ParseNtResult; use rustc_session::parse::ParseSess; +use rustc_session::parse::SymbolGallery; use rustc_span::hygiene::{LocalExpnId, Transparency}; use rustc_span::symbol::{sym, Ident, MacroRulesNormalizedIdent}; -use rustc_span::{with_metavar_spans, Span, Symbol, SyntaxContext}; +use rustc_span::{with_metavar_spans, Span, SyntaxContext}; use smallvec::{smallvec, SmallVec}; use std::mem; @@ -312,7 +314,16 @@ pub(super) fn transcribe<'a>( // Replace meta-variable expressions with the result of their expansion. mbe::TokenTree::MetaVarExpr(sp, expr) => { - transcribe_metavar_expr(dcx, expr, interp, &mut marker, &repeats, &mut result, sp)?; + transcribe_metavar_expr( + dcx, + expr, + interp, + &mut marker, + &repeats, + &mut result, + sp, + &psess.symbol_gallery, + )?; } // If we are entering a new delimiter, we push its contents to the `stack` to be @@ -669,6 +680,7 @@ fn transcribe_metavar_expr<'a>( repeats: &[(usize, usize)], result: &mut Vec, sp: &DelimSpan, + symbol_gallery: &SymbolGallery, ) -> PResult<'a, ()> { let mut visited_span = || { let mut span = sp.entire(); @@ -680,16 +692,26 @@ fn transcribe_metavar_expr<'a>( let mut concatenated = String::new(); for element in elements.into_iter() { let string = match element { - MetaVarExprConcatElem::Ident(ident) => ident.to_string(), - MetaVarExprConcatElem::Var(ident) => extract_ident(dcx, *ident, interp)?, + MetaVarExprConcatElem::Ident(elem) => elem.to_string(), + MetaVarExprConcatElem::Literal(elem) => elem.as_str().into(), + MetaVarExprConcatElem::Var(elem) => extract_ident(dcx, *elem, interp)?, }; concatenated.push_str(&string); } + let symbol = nfc_normalize(&concatenated); + let concatenated_span = visited_span(); + if !rustc_lexer::is_ident(symbol.as_str()) { + return Err(dcx.struct_span_err( + concatenated_span, + "`${concat(..)}` is not generating a valid identifier", + )); + } + symbol_gallery.insert(symbol, concatenated_span); // The current implementation marks the span as coming from the macro regardless of // contexts of the concatenated identifiers but this behavior may change in the // future. result.push(TokenTree::Token( - Token::from_ast_ident(Ident::new(Symbol::intern(&concatenated), visited_span())), + Token::from_ast_ident(Ident::new(symbol, concatenated_span)), Spacing::Alone, )); } diff --git a/tests/ui/macros/macro-metavar-expr-concat/allowed-operations.rs b/tests/ui/macros/macro-metavar-expr-concat/allowed-operations.rs index e44eeffb01be8..1acefa314aab8 100644 --- a/tests/ui/macros/macro-metavar-expr-concat/allowed-operations.rs +++ b/tests/ui/macros/macro-metavar-expr-concat/allowed-operations.rs @@ -37,6 +37,16 @@ macro_rules! without_dollar_sign_is_an_ident { }; } +macro_rules! literals { + ($ident:ident) => {{ + let ${concat(_a, "_b")}: () = (); + let ${concat("_b", _a)}: () = (); + + let ${concat($ident, "_b")}: () = (); + let ${concat("_b", $ident)}: () = (); + }}; +} + fn main() { create_things!(behold); behold_separated_idents_in_a_fn(); @@ -55,4 +65,6 @@ fn main() { without_dollar_sign_is_an_ident!(_123); assert_eq!(VARident, 1); assert_eq!(VAR_123, 2); + + literals!(_hello); } diff --git a/tests/ui/macros/macro-metavar-expr-concat/raw-identifiers.rs b/tests/ui/macros/macro-metavar-expr-concat/raw-identifiers.rs index f72b9baca89f8..b1cb2141cc42f 100644 --- a/tests/ui/macros/macro-metavar-expr-concat/raw-identifiers.rs +++ b/tests/ui/macros/macro-metavar-expr-concat/raw-identifiers.rs @@ -26,14 +26,14 @@ macro_rules! idents_11 { macro_rules! no_params { () => { let ${concat(r#abc, abc)}: () = (); - //~^ ERROR `${concat(..)}` currently does not support raw identifiers + //~^ ERROR expected identifier or string literal //~| ERROR expected pattern, found `$` let ${concat(abc, r#abc)}: () = (); - //~^ ERROR `${concat(..)}` currently does not support raw identifiers + //~^ ERROR expected identifier or string literal let ${concat(r#abc, r#abc)}: () = (); - //~^ ERROR `${concat(..)}` currently does not support raw identifiers + //~^ ERROR expected identifier or string literal }; } diff --git a/tests/ui/macros/macro-metavar-expr-concat/raw-identifiers.stderr b/tests/ui/macros/macro-metavar-expr-concat/raw-identifiers.stderr index dd525cf0801be..4e11e20acc551 100644 --- a/tests/ui/macros/macro-metavar-expr-concat/raw-identifiers.stderr +++ b/tests/ui/macros/macro-metavar-expr-concat/raw-identifiers.stderr @@ -1,16 +1,16 @@ -error: `${concat(..)}` currently does not support raw identifiers +error: expected identifier or string literal --> $DIR/raw-identifiers.rs:28:22 | LL | let ${concat(r#abc, abc)}: () = (); | ^^^^^ -error: `${concat(..)}` currently does not support raw identifiers +error: expected identifier or string literal --> $DIR/raw-identifiers.rs:32:27 | LL | let ${concat(abc, r#abc)}: () = (); | ^^^^^ -error: `${concat(..)}` currently does not support raw identifiers +error: expected identifier or string literal --> $DIR/raw-identifiers.rs:35:22 | LL | let ${concat(r#abc, r#abc)}: () = (); diff --git a/tests/ui/macros/macro-metavar-expr-concat/syntax-errors.rs b/tests/ui/macros/macro-metavar-expr-concat/syntax-errors.rs index bf47442ea76fb..b2845c8d1c1fc 100644 --- a/tests/ui/macros/macro-metavar-expr-concat/syntax-errors.rs +++ b/tests/ui/macros/macro-metavar-expr-concat/syntax-errors.rs @@ -11,9 +11,6 @@ macro_rules! wrong_concat_declarations { ${concat(aaaa,)} //~^ ERROR expected identifier - ${concat(aaaa, 1)} - //~^ ERROR expected identifier - ${concat(_, aaaa)} ${concat(aaaa aaaa)} @@ -30,9 +27,6 @@ macro_rules! wrong_concat_declarations { ${concat($ex, aaaa,)} //~^ ERROR expected identifier - - ${concat($ex, aaaa, 123)} - //~^ ERROR expected identifier }; } @@ -43,8 +37,80 @@ macro_rules! dollar_sign_without_referenced_ident { }; } +macro_rules! starting_number { + ($ident:ident) => {{ + let ${concat("1", $ident)}: () = (); + //~^ ERROR `${concat(..)}` is not generating a valid identifier + }}; +} + +macro_rules! starting_valid_unicode { + ($ident:ident) => {{ + let ${concat("Ý", $ident)}: () = (); + }}; +} + +macro_rules! starting_invalid_unicode { + ($ident:ident) => {{ + let ${concat("\u{00BD}", $ident)}: () = (); + //~^ ERROR `${concat(..)}` is not generating a valid identifier + }}; +} + +macro_rules! ending_number { + ($ident:ident) => {{ + let ${concat($ident, "1")}: () = (); + }}; +} + +macro_rules! ending_valid_unicode { + ($ident:ident) => {{ + let ${concat($ident, "Ý")}: () = (); + }}; +} + +macro_rules! ending_invalid_unicode { + ($ident:ident) => {{ + let ${concat($ident, "\u{00BD}")}: () = (); + //~^ ERROR `${concat(..)}` is not generating a valid identifier + }}; +} + +macro_rules! empty { + () => {{ + let ${concat("", "")}: () = (); + //~^ ERROR `${concat(..)}` is not generating a valid identifier + }}; +} + +macro_rules! unsupported_literals { + ($ident:ident) => {{ + let ${concat(_a, 'b')}: () = (); + //~^ ERROR expected identifier or string literal + //~| ERROR expected pattern + let ${concat(_a, 1)}: () = (); + //~^ ERROR expected identifier or string literal + + let ${concat($ident, 'b')}: () = (); + //~^ ERROR expected identifier or string literal + let ${concat($ident, 1)}: () = (); + //~^ ERROR expected identifier or string literal + }}; +} + fn main() { wrong_concat_declarations!(1); dollar_sign_without_referenced_ident!(VAR); + + starting_number!(_abc); + starting_valid_unicode!(_abc); + starting_invalid_unicode!(_abc); + + ending_number!(_abc); + ending_valid_unicode!(_abc); + ending_invalid_unicode!(_abc); + unsupported_literals!(_abc); + + empty!(); } diff --git a/tests/ui/macros/macro-metavar-expr-concat/syntax-errors.stderr b/tests/ui/macros/macro-metavar-expr-concat/syntax-errors.stderr index b216a86d59abe..2fe5842b39eb5 100644 --- a/tests/ui/macros/macro-metavar-expr-concat/syntax-errors.stderr +++ b/tests/ui/macros/macro-metavar-expr-concat/syntax-errors.stderr @@ -1,4 +1,4 @@ -error: expected identifier +error: expected identifier or string literal --> $DIR/syntax-errors.rs:5:10 | LL | ${concat()} @@ -10,59 +10,126 @@ error: `concat` must have at least two elements LL | ${concat(aaaa)} | ^^^^^^ -error: expected identifier +error: expected identifier or string literal --> $DIR/syntax-errors.rs:11:10 | LL | ${concat(aaaa,)} | ^^^^^^^^^^^^^^^ -error: expected identifier, found `1` - --> $DIR/syntax-errors.rs:14:24 - | -LL | ${concat(aaaa, 1)} - | ^ help: try removing `1` - error: expected comma - --> $DIR/syntax-errors.rs:19:10 + --> $DIR/syntax-errors.rs:16:10 | LL | ${concat(aaaa aaaa)} | ^^^^^^^^^^^^^^^^^^^ error: `concat` must have at least two elements - --> $DIR/syntax-errors.rs:22:11 + --> $DIR/syntax-errors.rs:19:11 | LL | ${concat($ex)} | ^^^^^^ error: expected comma - --> $DIR/syntax-errors.rs:28:10 + --> $DIR/syntax-errors.rs:25:10 | LL | ${concat($ex, aaaa 123)} | ^^^^^^^^^^^^^^^^^^^^^^^ -error: expected identifier - --> $DIR/syntax-errors.rs:31:10 +error: expected identifier or string literal + --> $DIR/syntax-errors.rs:28:10 | LL | ${concat($ex, aaaa,)} | ^^^^^^^^^^^^^^^^^^^^ -error: expected identifier, found `123` - --> $DIR/syntax-errors.rs:34:29 +error: expected identifier or string literal + --> $DIR/syntax-errors.rs:88:26 | -LL | ${concat($ex, aaaa, 123)} - | ^^^ help: try removing `123` +LL | let ${concat(_a, 'b')}: () = (); + | ^^^ + +error: expected identifier or string literal + --> $DIR/syntax-errors.rs:91:26 + | +LL | let ${concat(_a, 1)}: () = (); + | ^ + +error: expected identifier or string literal + --> $DIR/syntax-errors.rs:94:30 + | +LL | let ${concat($ident, 'b')}: () = (); + | ^^^ + +error: expected identifier or string literal + --> $DIR/syntax-errors.rs:96:30 + | +LL | let ${concat($ident, 1)}: () = (); + | ^ error: `${concat(..)}` currently only accepts identifiers or meta-variables as parameters - --> $DIR/syntax-errors.rs:25:19 + --> $DIR/syntax-errors.rs:22:19 | LL | ${concat($ex, aaaa)} | ^^ error: variable `foo` is not recognized in meta-variable expression - --> $DIR/syntax-errors.rs:41:30 + --> $DIR/syntax-errors.rs:35:30 | LL | const ${concat(FOO, $foo)}: i32 = 2; | ^^^ -error: aborting due to 11 previous errors +error: `${concat(..)}` is not generating a valid identifier + --> $DIR/syntax-errors.rs:42:14 + | +LL | let ${concat("1", $ident)}: () = (); + | ^^^^^^^^^^^^^^^^^^^^^ +... +LL | starting_number!(_abc); + | ---------------------- in this macro invocation + | + = note: this error originates in the macro `starting_number` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: `${concat(..)}` is not generating a valid identifier + --> $DIR/syntax-errors.rs:55:14 + | +LL | let ${concat("\u{00BD}", $ident)}: () = (); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | starting_invalid_unicode!(_abc); + | ------------------------------- in this macro invocation + | + = note: this error originates in the macro `starting_invalid_unicode` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: `${concat(..)}` is not generating a valid identifier + --> $DIR/syntax-errors.rs:74:14 + | +LL | let ${concat($ident, "\u{00BD}")}: () = (); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | ending_invalid_unicode!(_abc); + | ----------------------------- in this macro invocation + | + = note: this error originates in the macro `ending_invalid_unicode` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: expected pattern, found `$` + --> $DIR/syntax-errors.rs:88:13 + | +LL | let ${concat(_a, 'b')}: () = (); + | ^ expected pattern +... +LL | unsupported_literals!(_abc); + | --------------------------- in this macro invocation + | + = note: this error originates in the macro `unsupported_literals` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: `${concat(..)}` is not generating a valid identifier + --> $DIR/syntax-errors.rs:81:14 + | +LL | let ${concat("", "")}: () = (); + | ^^^^^^^^^^^^^^^^ +... +LL | empty!(); + | -------- in this macro invocation + | + = note: this error originates in the macro `empty` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 18 previous errors diff --git a/tests/ui/macros/macro-metavar-expr-concat/unicode-expansion.rs b/tests/ui/macros/macro-metavar-expr-concat/unicode-expansion.rs new file mode 100644 index 0000000000000..b2cfb211e2d1e --- /dev/null +++ b/tests/ui/macros/macro-metavar-expr-concat/unicode-expansion.rs @@ -0,0 +1,14 @@ +//@ run-pass + +#![feature(macro_metavar_expr_concat)] + +macro_rules! turn_to_page { + ($ident:ident) => { + const ${concat("Ḧ", $ident)}: i32 = 394; + }; +} + +fn main() { + turn_to_page!(P); + assert_eq!(ḦP, 394); +} diff --git a/tests/ui/macros/rfc-3086-metavar-expr/syntax-errors.stderr b/tests/ui/macros/rfc-3086-metavar-expr/syntax-errors.stderr index 8e4ba192d79f5..2c44ad2e0a4ad 100644 --- a/tests/ui/macros/rfc-3086-metavar-expr/syntax-errors.stderr +++ b/tests/ui/macros/rfc-3086-metavar-expr/syntax-errors.stderr @@ -190,7 +190,7 @@ error: unrecognized meta-variable expression LL | ( $( $i:ident ),* ) => { ${ aaaaaaaaaaaaaa(i) } }; | ^^^^^^^^^^^^^^ help: supported expressions are count, ignore, index and len -error: expected identifier +error: expected identifier or string literal --> $DIR/syntax-errors.rs:118:33 | LL | ( $( $i:ident ),* ) => { ${ {} } }; From 87d61f254097d4d8a2de1a83bb74609a3651e0a3 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sat, 6 Jul 2024 11:11:05 -0400 Subject: [PATCH 779/892] Don't track visited outlives bounds when decomposing verify for alias --- .../src/infer/outlives/obligations.rs | 2 +- .../rustc_infer/src/infer/outlives/verify.rs | 34 +++++++------------ 2 files changed, 14 insertions(+), 22 deletions(-) diff --git a/compiler/rustc_infer/src/infer/outlives/obligations.rs b/compiler/rustc_infer/src/infer/outlives/obligations.rs index 9bb5f775e4ade..d82ae7b4fb888 100644 --- a/compiler/rustc_infer/src/infer/outlives/obligations.rs +++ b/compiler/rustc_infer/src/infer/outlives/obligations.rs @@ -471,7 +471,7 @@ where // projection outlive; in some cases, this may add insufficient // edges into the inference graph, leading to inference failures // even though a satisfactory solution exists. - let verify_bound = self.verify_bound.alias_bound(alias_ty, &mut Default::default()); + let verify_bound = self.verify_bound.alias_bound(alias_ty); debug!("alias_must_outlive: pushing {:?}", verify_bound); self.delegate.push_verify(origin, GenericKind::Alias(alias_ty), region, verify_bound); } diff --git a/compiler/rustc_infer/src/infer/outlives/verify.rs b/compiler/rustc_infer/src/infer/outlives/verify.rs index ad102dfcc1ffd..da9ba26373c16 100644 --- a/compiler/rustc_infer/src/infer/outlives/verify.rs +++ b/compiler/rustc_infer/src/infer/outlives/verify.rs @@ -1,8 +1,6 @@ use crate::infer::outlives::env::RegionBoundPairs; use crate::infer::region_constraints::VerifyIfEq; use crate::infer::{GenericKind, VerifyBound}; -use rustc_data_structures::sso::SsoHashSet; -use rustc_middle::ty::GenericArg; use rustc_middle::ty::{self, OutlivesPredicate, Ty, TyCtxt}; use rustc_type_ir::outlives::{compute_alias_components_recursive, Component}; @@ -99,12 +97,8 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> { self.declared_generic_bounds_from_env_for_erased_ty(erased_alias_ty) } - #[instrument(level = "debug", skip(self, visited))] - pub fn alias_bound( - &self, - alias_ty: ty::AliasTy<'tcx>, - visited: &mut SsoHashSet>, - ) -> VerifyBound<'tcx> { + #[instrument(level = "debug", skip(self))] + pub fn alias_bound(&self, alias_ty: ty::AliasTy<'tcx>) -> VerifyBound<'tcx> { let alias_ty_as_ty = alias_ty.to_ty(self.tcx); // Search the env for where clauses like `P: 'a`. @@ -130,21 +124,22 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> { // see the extensive comment in projection_must_outlive let recursive_bound = { let mut components = smallvec![]; - compute_alias_components_recursive(self.tcx, alias_ty_as_ty, &mut components, visited); - self.bound_from_components(&components, visited) + compute_alias_components_recursive( + self.tcx, + alias_ty_as_ty, + &mut components, + &mut Default::default(), + ); + self.bound_from_components(&components) }; VerifyBound::AnyBound(env_bounds.chain(definition_bounds).collect()).or(recursive_bound) } - fn bound_from_components( - &self, - components: &[Component>], - visited: &mut SsoHashSet>, - ) -> VerifyBound<'tcx> { + fn bound_from_components(&self, components: &[Component>]) -> VerifyBound<'tcx> { let mut bounds = components .iter() - .map(|component| self.bound_from_single_component(component, visited)) + .map(|component| self.bound_from_single_component(component)) // Remove bounds that must hold, since they are not interesting. .filter(|bound| !bound.must_hold()); @@ -159,7 +154,6 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> { fn bound_from_single_component( &self, component: &Component>, - visited: &mut SsoHashSet>, ) -> VerifyBound<'tcx> { match *component { Component::Region(lt) => VerifyBound::OutlivedBy(lt), @@ -167,10 +161,8 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> { Component::Placeholder(placeholder_ty) => { self.param_or_placeholder_bound(Ty::new_placeholder(self.tcx, placeholder_ty)) } - Component::Alias(alias_ty) => self.alias_bound(alias_ty, visited), - Component::EscapingAlias(ref components) => { - self.bound_from_components(components, visited) - } + Component::Alias(alias_ty) => self.alias_bound(alias_ty), + Component::EscapingAlias(ref components) => self.bound_from_components(components), Component::UnresolvedInferenceVariable(v) => { // Ignore this, we presume it will yield an error later, since // if a type variable is not resolved by this point it never From 54556f49d368ba96a92fd6ec352cf6b12e9542ef Mon Sep 17 00:00:00 2001 From: Chayim Refael Friedman Date: Sun, 7 Jul 2024 06:58:52 +0300 Subject: [PATCH 780/892] Specialize `TrustedLen` for `Iterator::unzip()` Don't check the capacity every time (and also for `Extend` for tuples, as this is how `unzip()` is implemented). I did this with an unsafe method on `Extend` that doesn't check for growth (`extend_one_unchecked()`). I've marked it as perma-unstable currently, although we may want to expose it in the future so collections outside of std can benefit from it. Then specialize `Extend for (A, B)` for `TrustedLen` to call it. It may seem that an alternative way of implementing this is to have a semi-public trait (`#[doc(hidden)]` public, so collections outside of core can implement it) for `extend()` inside tuples, and specialize it from collections. However, it is impossible due to limitations of `min_specialization`. A concern that may arise with the current approach is that implementing `extend_one_unchecked()` correctly must also incur implementing `extend_reserve()`, otherwise you can have UB. This is a somewhat non-local safety invariant. However, I believe this is fine, since to have actual UB you must have unsafe code inside your `extend_one_unchecked()` that makes incorrect assumption, *and* not implement `extend_reserve()`. I've also documented this requirement. --- .../alloc/src/collections/vec_deque/mod.rs | 30 +++++ .../src/collections/vec_deque/spec_extend.rs | 13 +- library/alloc/src/lib.rs | 1 + library/alloc/src/vec/mod.rs | 20 +++ library/core/src/iter/traits/collect.rs | 122 +++++++++++++++--- 5 files changed, 160 insertions(+), 26 deletions(-) diff --git a/library/alloc/src/collections/vec_deque/mod.rs b/library/alloc/src/collections/vec_deque/mod.rs index 61d05afccfd1a..a07f250d7d88c 100644 --- a/library/alloc/src/collections/vec_deque/mod.rs +++ b/library/alloc/src/collections/vec_deque/mod.rs @@ -164,6 +164,20 @@ impl VecDeque { self.buf.ptr() } + /// Appends an element to the buffer. + /// + /// # Safety + /// + /// May only be called if `deque.len() < deque.capacity()` + #[inline] + unsafe fn push_unchecked(&mut self, element: T) { + // SAFETY: Because of the precondition, it's guaranteed that there is space + // in the logical array after the last element. + unsafe { self.buffer_write(self.to_physical_idx(self.len), element) }; + // This can't overflow because `deque.len() < deque.capacity() <= usize::MAX`. + self.len += 1; + } + /// Moves an element out of the buffer #[inline] unsafe fn buffer_read(&mut self, off: usize) -> T { @@ -2911,6 +2925,14 @@ impl Extend for VecDeque { fn extend_reserve(&mut self, additional: usize) { self.reserve(additional); } + + #[inline] + unsafe fn extend_one_unchecked(&mut self, item: T) { + // SAFETY: Our preconditions ensure the space has been reserved, and `extend_reserve` is implemented correctly. + unsafe { + self.push_unchecked(item); + } + } } #[stable(feature = "extend_ref", since = "1.2.0")] @@ -2928,6 +2950,14 @@ impl<'a, T: 'a + Copy, A: Allocator> Extend<&'a T> for VecDeque { fn extend_reserve(&mut self, additional: usize) { self.reserve(additional); } + + #[inline] + unsafe fn extend_one_unchecked(&mut self, &item: &'a T) { + // SAFETY: Our preconditions ensure the space has been reserved, and `extend_reserve` is implemented correctly. + unsafe { + self.push_unchecked(item); + } + } } #[stable(feature = "rust1", since = "1.0.0")] diff --git a/library/alloc/src/collections/vec_deque/spec_extend.rs b/library/alloc/src/collections/vec_deque/spec_extend.rs index dccf40ccb38aa..6a89abc3ef9b6 100644 --- a/library/alloc/src/collections/vec_deque/spec_extend.rs +++ b/library/alloc/src/collections/vec_deque/spec_extend.rs @@ -21,21 +21,12 @@ where // self.push_back(item); // } - // May only be called if `deque.len() < deque.capacity()` - unsafe fn push_unchecked(deque: &mut VecDeque, element: T) { - // SAFETY: Because of the precondition, it's guaranteed that there is space - // in the logical array after the last element. - unsafe { deque.buffer_write(deque.to_physical_idx(deque.len), element) }; - // This can't overflow because `deque.len() < deque.capacity() <= usize::MAX`. - deque.len += 1; - } - while let Some(element) = iter.next() { let (lower, _) = iter.size_hint(); self.reserve(lower.saturating_add(1)); // SAFETY: We just reserved space for at least one element. - unsafe { push_unchecked(self, element) }; + unsafe { self.push_unchecked(element) }; // Inner loop to avoid repeatedly calling `reserve`. while self.len < self.capacity() { @@ -43,7 +34,7 @@ where return; }; // SAFETY: The loop condition guarantees that `self.len() < self.capacity()`. - unsafe { push_unchecked(self, element) }; + unsafe { self.push_unchecked(element) }; } } } diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs index 703538d0f355d..3237d8654c281 100644 --- a/library/alloc/src/lib.rs +++ b/library/alloc/src/lib.rs @@ -124,6 +124,7 @@ #![feature(error_generic_member_access)] #![feature(exact_size_is_empty)] #![feature(extend_one)] +#![feature(extend_one_unchecked)] #![feature(fmt_internals)] #![feature(fn_traits)] #![feature(hasher_prefixfree_extras)] diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index f1706e31bb80a..6e9b017ad75cf 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -3048,6 +3048,16 @@ impl Extend for Vec { fn extend_reserve(&mut self, additional: usize) { self.reserve(additional); } + + #[inline] + unsafe fn extend_one_unchecked(&mut self, item: T) { + // SAFETY: Our preconditions ensure the space has been reserved, and `extend_reserve` is implemented correctly. + unsafe { + let len = self.len(); + ptr::write(self.as_mut_ptr().add(len), item); + self.set_len(len + 1); + } + } } impl Vec { @@ -3244,6 +3254,16 @@ impl<'a, T: Copy + 'a, A: Allocator> Extend<&'a T> for Vec { fn extend_reserve(&mut self, additional: usize) { self.reserve(additional); } + + #[inline] + unsafe fn extend_one_unchecked(&mut self, &item: &'a T) { + // SAFETY: Our preconditions ensure the space has been reserved, and `extend_reserve` is implemented correctly. + unsafe { + let len = self.len(); + ptr::write(self.as_mut_ptr().add(len), item); + self.set_len(len + 1); + } + } } /// Implements comparison of vectors, [lexicographically](Ord#lexicographical-comparison). diff --git a/library/core/src/iter/traits/collect.rs b/library/core/src/iter/traits/collect.rs index 61a457890134c..86660f2e375c3 100644 --- a/library/core/src/iter/traits/collect.rs +++ b/library/core/src/iter/traits/collect.rs @@ -1,3 +1,5 @@ +use super::TrustedLen; + /// Conversion from an [`Iterator`]. /// /// By implementing `FromIterator` for a type, you define how it will be @@ -460,6 +462,27 @@ pub trait Extend { fn extend_reserve(&mut self, additional: usize) { let _ = additional; } + + /// Extends a collection with one element, without checking there is enough capacity for it. + /// + /// # Safety + /// + /// **For callers:** This must only be called when we know the collection has enough capacity + /// to contain the new item, for example because we previously called `extend_reserve`. + /// + /// **For implementors:** For a collection to unsafely rely on this method's safety precondition (that is, + /// invoke UB if they are violated), it must implement `extend_reserve` correctly. In other words, + /// callers may assume that if they `extend_reserve`ed enough space they can call this method. + + // This method is for internal usage only. It is only on the trait because of specialization's limitations. + #[unstable(feature = "extend_one_unchecked", issue = "none")] + #[doc(hidden)] + unsafe fn extend_one_unchecked(&mut self, item: A) + where + Self: Sized, + { + self.extend_one(item); + } } #[stable(feature = "extend_for_unit", since = "1.28.0")] @@ -499,33 +522,102 @@ where fn extend>(&mut self, into_iter: T) { let (a, b) = self; let iter = into_iter.into_iter(); + SpecTupleExtend::extend(iter, a, b); + } + + fn extend_one(&mut self, item: (A, B)) { + self.0.extend_one(item.0); + self.1.extend_one(item.1); + } + + fn extend_reserve(&mut self, additional: usize) { + self.0.extend_reserve(additional); + self.1.extend_reserve(additional); + } + + unsafe fn extend_one_unchecked(&mut self, item: (A, B)) { + // SAFETY: Those are our safety preconditions, and we correctly forward `extend_reserve`. + unsafe { + self.0.extend_one_unchecked(item.0); + self.1.extend_one_unchecked(item.1); + } + } +} + +fn default_extend_tuple( + iter: impl Iterator, + a: &mut ExtendA, + b: &mut ExtendB, +) where + ExtendA: Extend, + ExtendB: Extend, +{ + fn extend<'a, A, B>( + a: &'a mut impl Extend, + b: &'a mut impl Extend, + ) -> impl FnMut((), (A, B)) + 'a { + move |(), (t, u)| { + a.extend_one(t); + b.extend_one(u); + } + } + + let (lower_bound, _) = iter.size_hint(); + if lower_bound > 0 { + a.extend_reserve(lower_bound); + b.extend_reserve(lower_bound); + } + + iter.fold((), extend(a, b)); +} + +trait SpecTupleExtend { + fn extend(self, a: &mut A, b: &mut B); +} +impl SpecTupleExtend for Iter +where + ExtendA: Extend, + ExtendB: Extend, + Iter: Iterator, +{ + default fn extend(self, a: &mut ExtendA, b: &mut ExtendB) { + default_extend_tuple(self, a, b); + } +} + +impl SpecTupleExtend for Iter +where + ExtendA: Extend, + ExtendB: Extend, + Iter: TrustedLen, +{ + fn extend(self, a: &mut ExtendA, b: &mut ExtendB) { fn extend<'a, A, B>( a: &'a mut impl Extend, b: &'a mut impl Extend, ) -> impl FnMut((), (A, B)) + 'a { - move |(), (t, u)| { - a.extend_one(t); - b.extend_one(u); + // SAFETY: We reserve enough space for the `size_hint`, and the iterator is `TrustedLen` + // so its `size_hint` is exact. + move |(), (t, u)| unsafe { + a.extend_one_unchecked(t); + b.extend_one_unchecked(u); } } - let (lower_bound, _) = iter.size_hint(); + let (lower_bound, upper_bound) = self.size_hint(); + + if upper_bound.is_none() { + // We cannot reserve more than `usize::MAX` items, and this is likely to go out of memory anyway. + default_extend_tuple(self, a, b); + return; + } + if lower_bound > 0 { a.extend_reserve(lower_bound); b.extend_reserve(lower_bound); } - iter.fold((), extend(a, b)); - } - - fn extend_one(&mut self, item: (A, B)) { - self.0.extend_one(item.0); - self.1.extend_one(item.1); - } - - fn extend_reserve(&mut self, additional: usize) { - self.0.extend_reserve(additional); - self.1.extend_reserve(additional); + self.fold((), extend(a, b)); } } From 58aad3c72c32936b49f92f552e0157b9c8c862ee Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sat, 6 Jul 2024 11:54:22 -0400 Subject: [PATCH 781/892] iter_identity is a better name --- .../rustc_hir_analysis/src/check/wfcheck.rs | 23 +++++++++---------- compiler/rustc_hir_typeck/src/coercion.rs | 9 ++++---- .../src/opaque_hidden_inferred_bound.rs | 4 +--- compiler/rustc_lint/src/unused.rs | 4 +--- compiler/rustc_middle/src/ty/generics.rs | 2 +- .../src/traits/object_safety.rs | 2 +- compiler/rustc_ty_utils/src/opaque_types.rs | 6 ++--- compiler/rustc_ty_utils/src/sig_types.rs | 2 +- compiler/rustc_type_ir/src/binder.rs | 6 ++--- src/librustdoc/clean/mod.rs | 3 +-- src/tools/clippy/clippy_utils/src/ty.rs | 2 +- 11 files changed, 26 insertions(+), 37 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 2230528a5ae11..c31f7487dcdfb 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -477,7 +477,7 @@ fn check_gat_where_clauses(tcx: TyCtxt<'_>, trait_def_id: LocalDefId) { param_env, item_def_id, tcx.explicit_item_bounds(item_def_id) - .instantiate_identity_iter_copied() + .iter_identity_copied() .collect::>(), &FxIndexSet::default(), gat_def_id, @@ -1204,17 +1204,16 @@ fn check_associated_type_bounds(wfcx: &WfCheckingCtxt<'_, '_>, item: ty::AssocIt let bounds = wfcx.tcx().explicit_item_bounds(item.def_id); debug!("check_associated_type_bounds: bounds={:?}", bounds); - let wf_obligations = - bounds.instantiate_identity_iter_copied().flat_map(|(bound, bound_span)| { - let normalized_bound = wfcx.normalize(span, None, bound); - traits::wf::clause_obligations( - wfcx.infcx, - wfcx.param_env, - wfcx.body_def_id, - normalized_bound, - bound_span, - ) - }); + let wf_obligations = bounds.iter_identity_copied().flat_map(|(bound, bound_span)| { + let normalized_bound = wfcx.normalize(span, None, bound); + traits::wf::clause_obligations( + wfcx.infcx, + wfcx.param_env, + wfcx.body_def_id, + normalized_bound, + bound_span, + ) + }); wfcx.register_obligations(wf_obligations); } diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs index f72e8a4afdef6..4f0a089ee956f 100644 --- a/compiler/rustc_hir_typeck/src/coercion.rs +++ b/compiler/rustc_hir_typeck/src/coercion.rs @@ -1752,10 +1752,8 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { fcx.probe(|_| { let ocx = ObligationCtxt::new(fcx); ocx.register_obligations( - fcx.tcx - .item_super_predicates(rpit_def_id) - .instantiate_identity_iter() - .filter_map(|clause| { + fcx.tcx.item_super_predicates(rpit_def_id).iter_identity().filter_map( + |clause| { let predicate = clause .kind() .map_bound(|clause| match clause { @@ -1776,7 +1774,8 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { fcx.param_env, predicate, )) - }), + }, + ), ); ocx.select_where_possible().is_empty() }) diff --git a/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs b/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs index 8b669bcc13f0b..5ee73dbfdc658 100644 --- a/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs +++ b/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs @@ -76,9 +76,7 @@ impl<'tcx> LateLintPass<'tcx> for OpaqueHiddenInferredBound { // For every projection predicate in the opaque type's explicit bounds, // check that the type that we're assigning actually satisfies the bounds // of the associated type. - for (pred, pred_span) in - cx.tcx.explicit_item_bounds(def_id).instantiate_identity_iter_copied() - { + for (pred, pred_span) in cx.tcx.explicit_item_bounds(def_id).iter_identity_copied() { infcx.enter_forall(pred.kind(), |predicate| { let ty::ClauseKind::Projection(proj) = predicate else { return; diff --git a/compiler/rustc_lint/src/unused.rs b/compiler/rustc_lint/src/unused.rs index 195a0f72475f0..65d42ed8054f9 100644 --- a/compiler/rustc_lint/src/unused.rs +++ b/compiler/rustc_lint/src/unused.rs @@ -298,9 +298,7 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults { ty::Alias(ty::Opaque | ty::Projection, ty::AliasTy { def_id: def, .. }) => { elaborate( cx.tcx, - cx.tcx - .explicit_item_super_predicates(def) - .instantiate_identity_iter_copied(), + cx.tcx.explicit_item_super_predicates(def).iter_identity_copied(), ) // We only care about self bounds for the impl-trait .filter_only_self() diff --git a/compiler/rustc_middle/src/ty/generics.rs b/compiler/rustc_middle/src/ty/generics.rs index 844023df1e315..11ed0bdaa7028 100644 --- a/compiler/rustc_middle/src/ty/generics.rs +++ b/compiler/rustc_middle/src/ty/generics.rs @@ -394,7 +394,7 @@ impl<'tcx> GenericPredicates<'tcx> { } pub fn instantiate_own_identity(&self) -> impl Iterator, Span)> { - EarlyBinder::bind(self.predicates).instantiate_identity_iter_copied() + EarlyBinder::bind(self.predicates).iter_identity_copied() } #[instrument(level = "debug", skip(self, tcx))] diff --git a/compiler/rustc_trait_selection/src/traits/object_safety.rs b/compiler/rustc_trait_selection/src/traits/object_safety.rs index 5b2c8fb1950d8..1c6993bdd3729 100644 --- a/compiler/rustc_trait_selection/src/traits/object_safety.rs +++ b/compiler/rustc_trait_selection/src/traits/object_safety.rs @@ -203,7 +203,7 @@ fn bounds_reference_self(tcx: TyCtxt<'_>, trait_def_id: DefId) -> SmallVec<[Span tcx.associated_items(trait_def_id) .in_definition_order() .filter(|item| item.kind == ty::AssocKind::Type) - .flat_map(|item| tcx.explicit_item_bounds(item.def_id).instantiate_identity_iter_copied()) + .flat_map(|item| tcx.explicit_item_bounds(item.def_id).iter_identity_copied()) .filter_map(|c| predicate_references_self(tcx, c)) .collect() } diff --git a/compiler/rustc_ty_utils/src/opaque_types.rs b/compiler/rustc_ty_utils/src/opaque_types.rs index 686f2f04ad9a7..5e91320f89753 100644 --- a/compiler/rustc_ty_utils/src/opaque_types.rs +++ b/compiler/rustc_ty_utils/src/opaque_types.rs @@ -169,10 +169,8 @@ impl<'tcx> OpaqueTypeCollector<'tcx> { // Collect opaque types nested within the associated type bounds of this opaque type. // We use identity args here, because we already know that the opaque type uses // only generic parameters, and thus instantiating would not give us more information. - for (pred, span) in self - .tcx - .explicit_item_bounds(alias_ty.def_id) - .instantiate_identity_iter_copied() + for (pred, span) in + self.tcx.explicit_item_bounds(alias_ty.def_id).iter_identity_copied() { trace!(?pred); self.visit_spanned(span, pred); diff --git a/compiler/rustc_ty_utils/src/sig_types.rs b/compiler/rustc_ty_utils/src/sig_types.rs index 97a1b94263e90..eb6cb369974fd 100644 --- a/compiler/rustc_ty_utils/src/sig_types.rs +++ b/compiler/rustc_ty_utils/src/sig_types.rs @@ -62,7 +62,7 @@ pub fn walk_types<'tcx, V: SpannedTypeVisitor<'tcx>>( } } DefKind::OpaqueTy => { - for (pred, span) in tcx.explicit_item_bounds(item).instantiate_identity_iter_copied() { + for (pred, span) in tcx.explicit_item_bounds(item).iter_identity_copied() { try_visit!(visitor.visit(span, pred)); } } diff --git a/compiler/rustc_type_ir/src/binder.rs b/compiler/rustc_type_ir/src/binder.rs index 491ef34430c15..2531219baecc8 100644 --- a/compiler/rustc_type_ir/src/binder.rs +++ b/compiler/rustc_type_ir/src/binder.rs @@ -448,7 +448,7 @@ where /// Similar to [`instantiate_identity`](EarlyBinder::instantiate_identity), /// but on an iterator of `TypeFoldable` values. - pub fn instantiate_identity_iter(self) -> Iter::IntoIter { + pub fn iter_identity(self) -> Iter::IntoIter { self.value.into_iter() } } @@ -515,9 +515,7 @@ where /// Similar to [`instantiate_identity`](EarlyBinder::instantiate_identity), /// but on an iterator of values that deref to a `TypeFoldable`. - pub fn instantiate_identity_iter_copied( - self, - ) -> impl Iterator::Target> { + pub fn iter_identity_copied(self) -> impl Iterator::Target> { self.value.into_iter().map(|v| *v) } } diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index b5660cd849246..aa596897fc42f 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1404,8 +1404,7 @@ pub(crate) fn clean_middle_assoc_item<'tcx>( let mut predicates = tcx.explicit_predicates_of(assoc_item.def_id).predicates; if let ty::TraitContainer = assoc_item.container { - let bounds = - tcx.explicit_item_bounds(assoc_item.def_id).instantiate_identity_iter_copied(); + let bounds = tcx.explicit_item_bounds(assoc_item.def_id).iter_identity_copied(); predicates = tcx.arena.alloc_from_iter(bounds.chain(predicates.iter().copied())); } let mut generics = clean_ty_generics( diff --git a/src/tools/clippy/clippy_utils/src/ty.rs b/src/tools/clippy/clippy_utils/src/ty.rs index e5d2056419681..acaeb93f44a6e 100644 --- a/src/tools/clippy/clippy_utils/src/ty.rs +++ b/src/tools/clippy/clippy_utils/src/ty.rs @@ -99,7 +99,7 @@ pub fn contains_ty_adt_constructor_opaque<'tcx>(cx: &LateContext<'tcx>, ty: Ty<' for (predicate, _span) in cx .tcx .explicit_item_super_predicates(def_id) - .instantiate_identity_iter_copied() + .iter_identity_copied() { match predicate.kind().skip_binder() { // For `impl Trait`, it will register a predicate of `T: Trait`, so we go through From 14b859fa3be22289d810df1cc8bd2aaf6fc299be Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 4 Jul 2024 09:04:51 +1000 Subject: [PATCH 782/892] Rename `Attribute::tokens` (the inherent method). To distinguish it from the `HasTokens` method. --- compiler/rustc_ast/src/attr/mod.rs | 3 ++- compiler/rustc_ast/src/tokenstream.rs | 4 ++-- compiler/rustc_expand/src/config.rs | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_ast/src/attr/mod.rs b/compiler/rustc_ast/src/attr/mod.rs index 65f1b5dbaf5b7..088ae9ba44102 100644 --- a/compiler/rustc_ast/src/attr/mod.rs +++ b/compiler/rustc_ast/src/attr/mod.rs @@ -202,7 +202,8 @@ impl Attribute { } } - pub fn tokens(&self) -> TokenStream { + // Named `get_tokens` to distinguish it from the `::tokens` method. + pub fn get_tokens(&self) -> TokenStream { match &self.kind { AttrKind::Normal(normal) => TokenStream::new( normal diff --git a/compiler/rustc_ast/src/tokenstream.rs b/compiler/rustc_ast/src/tokenstream.rs index 655c18e45597a..06a669e795754 100644 --- a/compiler/rustc_ast/src/tokenstream.rs +++ b/compiler/rustc_ast/src/tokenstream.rs @@ -227,7 +227,7 @@ impl AttrTokenStream { let mut stream = TokenStream::default(); for inner_attr in inner_attrs { - stream.push_stream(inner_attr.tokens()); + stream.push_stream(inner_attr.get_tokens()); } stream.push_stream(delim_tokens.clone()); *tree = TokenTree::Delimited(*span, *spacing, *delim, stream); @@ -242,7 +242,7 @@ impl AttrTokenStream { ); } for attr in outer_attrs { - res.extend(attr.tokens().0.iter().cloned()); + res.extend(attr.get_tokens().0.iter().cloned()); } res.extend(target_tokens); } diff --git a/compiler/rustc_expand/src/config.rs b/compiler/rustc_expand/src/config.rs index 56cbb54fcecf7..561ac6bdd513b 100644 --- a/compiler/rustc_expand/src/config.rs +++ b/compiler/rustc_expand/src/config.rs @@ -294,7 +294,7 @@ impl<'a> StripUnconfigured<'a> { attr: &Attribute, (item, item_span): (ast::AttrItem, Span), ) -> Attribute { - let orig_tokens = attr.tokens(); + let orig_tokens = attr.get_tokens(); // We are taking an attribute of the form `#[cfg_attr(pred, attr)]` // and producing an attribute of the form `#[attr]`. We From 88373e9f0c81dd55dd3a663bcfbaa27052c53beb Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 4 Jul 2024 09:30:03 +1000 Subject: [PATCH 783/892] Remove an unnecessary local variable. --- compiler/rustc_expand/src/config.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/compiler/rustc_expand/src/config.rs b/compiler/rustc_expand/src/config.rs index 561ac6bdd513b..21ff56febb378 100644 --- a/compiler/rustc_expand/src/config.rs +++ b/compiler/rustc_expand/src/config.rs @@ -310,12 +310,11 @@ impl<'a> StripUnconfigured<'a> { else { panic!("Bad tokens for attribute {attr:?}"); }; - let pound_span = pound_token.span; // We don't really have a good span to use for the synthesized `[]` // in `#[attr]`, so just use the span of the `#` token. let bracket_group = AttrTokenTree::Delimited( - DelimSpan::from_single(pound_span), + DelimSpan::from_single(pound_token.span), DelimSpacing::new(Spacing::JointHidden, Spacing::Alone), Delimiter::Bracket, item.tokens From b261501b71c64ede374f71abae914a71dd723072 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 4 Jul 2024 11:27:39 +1000 Subject: [PATCH 784/892] Remove `HasSpan` trait. The only place it is meaningfully used is in a panic message in `TokenStream::from_ast`. But `node.span()` doesn't need to be printed because `node` is also printed and it must contain the span. --- compiler/rustc_ast/src/ast_traits.rs | 33 --------------------------- compiler/rustc_ast/src/lib.rs | 2 +- compiler/rustc_ast/src/tokenstream.rs | 6 ++--- compiler/rustc_resolve/src/late.rs | 2 +- 4 files changed, 5 insertions(+), 38 deletions(-) diff --git a/compiler/rustc_ast/src/ast_traits.rs b/compiler/rustc_ast/src/ast_traits.rs index 2cf811e9122f6..7754ca0a0f503 100644 --- a/compiler/rustc_ast/src/ast_traits.rs +++ b/compiler/rustc_ast/src/ast_traits.rs @@ -10,8 +10,6 @@ use crate::{AssocItem, Expr, ForeignItem, Item, NodeId}; use crate::{AttrItem, AttrKind, Block, Pat, Path, Ty, Visibility}; use crate::{AttrVec, Attribute, Stmt, StmtKind}; -use rustc_span::Span; - use std::fmt; use std::marker::PhantomData; @@ -91,37 +89,6 @@ impl> HasNodeId for T { } } -/// A trait for AST nodes having a span. -pub trait HasSpan { - fn span(&self) -> Span; -} - -macro_rules! impl_has_span { - ($($T:ty),+ $(,)?) => { - $( - impl HasSpan for $T { - fn span(&self) -> Span { - self.span - } - } - )+ - }; -} - -impl_has_span!(AssocItem, Block, Expr, ForeignItem, Item, Pat, Path, Stmt, Ty, Visibility); - -impl> HasSpan for T { - fn span(&self) -> Span { - self.ast_deref().span() - } -} - -impl HasSpan for AttrItem { - fn span(&self) -> Span { - self.span() - } -} - /// A trait for AST nodes having (or not having) collected tokens. pub trait HasTokens { fn tokens(&self) -> Option<&LazyAttrTokenStream>; diff --git a/compiler/rustc_ast/src/lib.rs b/compiler/rustc_ast/src/lib.rs index 7ca950e50e610..846a108091fcc 100644 --- a/compiler/rustc_ast/src/lib.rs +++ b/compiler/rustc_ast/src/lib.rs @@ -44,7 +44,7 @@ pub mod tokenstream; pub mod visit; pub use self::ast::*; -pub use self::ast_traits::{AstDeref, AstNodeWrapper, HasAttrs, HasNodeId, HasSpan, HasTokens}; +pub use self::ast_traits::{AstDeref, AstNodeWrapper, HasAttrs, HasNodeId, HasTokens}; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; diff --git a/compiler/rustc_ast/src/tokenstream.rs b/compiler/rustc_ast/src/tokenstream.rs index 06a669e795754..a84e33e5f92af 100644 --- a/compiler/rustc_ast/src/tokenstream.rs +++ b/compiler/rustc_ast/src/tokenstream.rs @@ -14,7 +14,7 @@ //! ownership of the original. use crate::ast::{AttrStyle, StmtKind}; -use crate::ast_traits::{HasAttrs, HasSpan, HasTokens}; +use crate::ast_traits::{HasAttrs, HasTokens}; use crate::token::{self, Delimiter, Nonterminal, Token, TokenKind}; use crate::AttrVec; @@ -436,9 +436,9 @@ impl TokenStream { TokenStream::new(vec![TokenTree::token_alone(kind, span)]) } - pub fn from_ast(node: &(impl HasAttrs + HasSpan + HasTokens + fmt::Debug)) -> TokenStream { + pub fn from_ast(node: &(impl HasAttrs + HasTokens + fmt::Debug)) -> TokenStream { let Some(tokens) = node.tokens() else { - panic!("missing tokens for node at {:?}: {:?}", node.span(), node); + panic!("missing tokens for node: {:?}", node); }; let attrs = node.attrs(); let attr_stream = if attrs.is_empty() { diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index ad4e222f4deda..1d37264f96a3c 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -1744,7 +1744,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { ) { self.r.dcx().emit_err(errors::LendingIteratorReportError { lifetime: lifetime.ident.span, - ty: ty.span(), + ty: ty.span, }); } else { self.r.dcx().emit_err(errors::AnonymousLivetimeNonGatReportError { From 9d33a8fe513fa237d5c008317e6a268143071597 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 4 Jul 2024 17:51:16 +1000 Subject: [PATCH 785/892] Simplify `ReplaceRange`. Currently the second element is a `Vec<(FlatToken, Spacing)>`. But the vector always has zero or one elements, and the `FlatToken` is always `FlatToken::AttrTarget` (which contains an `AttributesData`), and the spacing is always `Alone`. So we can simplify it to `Option`. An assertion in `to_attr_token_stream` can can also be removed, because `new_tokens.len()` was always 0 or 1, which means than `range.len()` is always greater than or equal to it, because `range.is_empty()` is always false (as per the earlier assertion). --- compiler/rustc_parse/src/parser/attr.rs | 2 +- .../rustc_parse/src/parser/attr_wrapper.rs | 39 +++++++++---------- compiler/rustc_parse/src/parser/mod.rs | 4 +- 3 files changed, 21 insertions(+), 24 deletions(-) diff --git a/compiler/rustc_parse/src/parser/attr.rs b/compiler/rustc_parse/src/parser/attr.rs index 1d31669d2074e..a8fe35f45b31e 100644 --- a/compiler/rustc_parse/src/parser/attr.rs +++ b/compiler/rustc_parse/src/parser/attr.rs @@ -313,7 +313,7 @@ impl<'a> Parser<'a> { // corresponding macro). let range = start_pos..end_pos; if let Capturing::Yes = self.capture_state.capturing { - self.capture_state.inner_attr_ranges.insert(attr.id, (range, vec![])); + self.capture_state.inner_attr_ranges.insert(attr.id, (range, None)); } attrs.push(attr); } else { diff --git a/compiler/rustc_parse/src/parser/attr_wrapper.rs b/compiler/rustc_parse/src/parser/attr_wrapper.rs index 53565ffe2c903..1aebbbe3559b9 100644 --- a/compiler/rustc_parse/src/parser/attr_wrapper.rs +++ b/compiler/rustc_parse/src/parser/attr_wrapper.rs @@ -145,24 +145,23 @@ impl ToAttrTokenStream for LazyAttrTokenStreamImpl { // start position, we ensure that any replace range which encloses // another replace range will capture the *replaced* tokens for the inner // range, not the original tokens. - for (range, new_tokens) in replace_ranges.into_iter().rev() { + for (range, attr_data) in replace_ranges.into_iter().rev() { assert!(!range.is_empty(), "Cannot replace an empty range: {range:?}"); - // Replace ranges are only allowed to decrease the number of tokens. - assert!( - range.len() >= new_tokens.len(), - "Range {range:?} has greater len than {new_tokens:?}" - ); - - // Replace any removed tokens with `FlatToken::Empty`. - // This keeps the total length of `tokens` constant throughout the - // replacement process, allowing us to use all of the `ReplaceRanges` entries - // without adjusting indices. - let filler = iter::repeat((FlatToken::Empty, Spacing::Alone)) - .take(range.len() - new_tokens.len()); + // Replace the tokens in range with zero or one `FlatToken::AttrTarget`s, plus + // enough `FlatToken::Empty`s to fill up the rest of the range. This keeps the + // total length of `tokens` constant throughout the replacement process, allowing + // us to use all of the `ReplaceRanges` entries without adjusting indices. + let attr_data_len = attr_data.is_some() as usize; tokens.splice( (range.start as usize)..(range.end as usize), - new_tokens.into_iter().chain(filler), + attr_data + .into_iter() + .map(|attr_data| (FlatToken::AttrTarget(attr_data), Spacing::Alone)) + .chain( + iter::repeat((FlatToken::Empty, Spacing::Alone)) + .take(range.len() - attr_data_len), + ), ); } make_attr_token_stream(tokens.into_iter(), self.break_last_token) @@ -315,7 +314,7 @@ impl<'a> Parser<'a> { .iter() .cloned() .chain(inner_attr_replace_ranges.iter().cloned()) - .map(|(range, tokens)| ((range.start - start_pos)..(range.end - start_pos), tokens)) + .map(|(range, data)| ((range.start - start_pos)..(range.end - start_pos), data)) .collect() }; @@ -345,17 +344,15 @@ impl<'a> Parser<'a> { && matches!(self.capture_state.capturing, Capturing::Yes) && has_cfg_or_cfg_attr(final_attrs) { - let attr_data = AttributesData { attrs: final_attrs.iter().cloned().collect(), tokens }; + assert!(!self.break_last_token, "Should not have unglued last token with cfg attr"); // Replace the entire AST node that we just parsed, including attributes, - // with a `FlatToken::AttrTarget`. If this AST node is inside an item + // with `attr_data`. If this AST node is inside an item // that has `#[derive]`, then this will allow us to cfg-expand this // AST node. let start_pos = if has_outer_attrs { attrs.start_pos } else { start_pos }; - let new_tokens = vec![(FlatToken::AttrTarget(attr_data), Spacing::Alone)]; - - assert!(!self.break_last_token, "Should not have unglued last token with cfg attr"); - self.capture_state.replace_ranges.push((start_pos..end_pos, new_tokens)); + let attr_data = AttributesData { attrs: final_attrs.iter().cloned().collect(), tokens }; + self.capture_state.replace_ranges.push((start_pos..end_pos, Some(attr_data))); self.capture_state.replace_ranges.extend(inner_attr_replace_ranges); } diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs index 5f16a3e1f3784..1072e6392921d 100644 --- a/compiler/rustc_parse/src/parser/mod.rs +++ b/compiler/rustc_parse/src/parser/mod.rs @@ -203,7 +203,7 @@ struct ClosureSpans { } /// Indicates a range of tokens that should be replaced by -/// the tokens in the provided vector. This is used in two +/// the tokens in the provided `AttributesData`. This is used in two /// places during token collection: /// /// 1. During the parsing of an AST node that may have a `#[derive]` @@ -219,7 +219,7 @@ struct ClosureSpans { /// the first macro inner attribute to invoke a proc-macro). /// When create a `TokenStream`, the inner attributes get inserted /// into the proper place in the token stream. -type ReplaceRange = (Range, Vec<(FlatToken, Spacing)>); +type ReplaceRange = (Range, Option); /// Controls how we capture tokens. Capturing can be expensive, /// so we try to avoid performing capturing in cases where From 3a5c4b6e4e4c99f9d2d10cb64a0eb591c08322e4 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Sun, 7 Jul 2024 16:14:30 +1000 Subject: [PATCH 786/892] Rename some attribute types for consistency. - `AttributesData` -> `AttrsTarget` - `AttrTokenTree::Attributes` -> `AttrTokenTree::AttrsTarget` - `FlatToken::AttrTarget` -> `FlatToken::AttrsTarget` --- compiler/rustc_ast/src/mut_visit.rs | 2 +- compiler/rustc_ast/src/tokenstream.rs | 22 +++++++------- compiler/rustc_builtin_macros/src/cfg_eval.rs | 2 +- compiler/rustc_expand/src/config.rs | 14 ++++----- .../rustc_parse/src/parser/attr_wrapper.rs | 29 +++++++++---------- compiler/rustc_parse/src/parser/mod.rs | 17 +++++------ 6 files changed, 42 insertions(+), 44 deletions(-) diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index f816375b912d6..cbf21317f1a77 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -704,7 +704,7 @@ fn visit_attr_tt(tt: &mut AttrTokenTree, vis: &mut T) { visit_attr_tts(tts, vis); visit_delim_span(dspan, vis); } - AttrTokenTree::Attributes(AttributesData { attrs, tokens }) => { + AttrTokenTree::AttrsTarget(AttrsTarget { attrs, tokens }) => { visit_attrs(attrs, vis); visit_lazy_tts_opt_mut(Some(tokens), vis); } diff --git a/compiler/rustc_ast/src/tokenstream.rs b/compiler/rustc_ast/src/tokenstream.rs index a84e33e5f92af..f3b6dc2cfa198 100644 --- a/compiler/rustc_ast/src/tokenstream.rs +++ b/compiler/rustc_ast/src/tokenstream.rs @@ -170,8 +170,8 @@ pub enum AttrTokenTree { Delimited(DelimSpan, DelimSpacing, Delimiter, AttrTokenStream), /// Stores the attributes for an attribute target, /// along with the tokens for that attribute target. - /// See `AttributesData` for more information - Attributes(AttributesData), + /// See `AttrsTarget` for more information + AttrsTarget(AttrsTarget), } impl AttrTokenStream { @@ -180,7 +180,7 @@ impl AttrTokenStream { } /// Converts this `AttrTokenStream` to a plain `Vec`. - /// During conversion, `AttrTokenTree::Attributes` get 'flattened' + /// During conversion, `AttrTokenTree::AttrsTarget` get 'flattened' /// back to a `TokenStream` of the form `outer_attr attr_target`. /// If there are inner attributes, they are inserted into the proper /// place in the attribute target tokens. @@ -199,13 +199,13 @@ impl AttrTokenStream { TokenStream::new(stream.to_token_trees()), )) } - AttrTokenTree::Attributes(data) => { - let idx = data + AttrTokenTree::AttrsTarget(target) => { + let idx = target .attrs .partition_point(|attr| matches!(attr.style, crate::AttrStyle::Outer)); - let (outer_attrs, inner_attrs) = data.attrs.split_at(idx); + let (outer_attrs, inner_attrs) = target.attrs.split_at(idx); - let mut target_tokens = data.tokens.to_attr_token_stream().to_token_trees(); + let mut target_tokens = target.tokens.to_attr_token_stream().to_token_trees(); if !inner_attrs.is_empty() { let mut found = false; // Check the last two trees (to account for a trailing semi) @@ -262,7 +262,7 @@ impl AttrTokenStream { /// have an `attrs` field containing the `#[cfg(FALSE)]` attr, /// and a `tokens` field storing the (unparsed) tokens `struct Foo {}` #[derive(Clone, Debug, Encodable, Decodable)] -pub struct AttributesData { +pub struct AttrsTarget { /// Attributes, both outer and inner. /// These are stored in the original order that they were parsed in. pub attrs: AttrVec, @@ -444,9 +444,9 @@ impl TokenStream { let attr_stream = if attrs.is_empty() { tokens.to_attr_token_stream() } else { - let attr_data = - AttributesData { attrs: attrs.iter().cloned().collect(), tokens: tokens.clone() }; - AttrTokenStream::new(vec![AttrTokenTree::Attributes(attr_data)]) + let target = + AttrsTarget { attrs: attrs.iter().cloned().collect(), tokens: tokens.clone() }; + AttrTokenStream::new(vec![AttrTokenTree::AttrsTarget(target)]) }; TokenStream::new(attr_stream.to_token_trees()) } diff --git a/compiler/rustc_builtin_macros/src/cfg_eval.rs b/compiler/rustc_builtin_macros/src/cfg_eval.rs index 884cebf1939e4..b09975c0ba79e 100644 --- a/compiler/rustc_builtin_macros/src/cfg_eval.rs +++ b/compiler/rustc_builtin_macros/src/cfg_eval.rs @@ -193,7 +193,7 @@ impl CfgEval<'_> { // Re-parse the tokens, setting the `capture_cfg` flag to save extra information // to the captured `AttrTokenStream` (specifically, we capture - // `AttrTokenTree::AttributesData` for all occurrences of `#[cfg]` and `#[cfg_attr]`) + // `AttrTokenTree::AttrsTarget` for all occurrences of `#[cfg]` and `#[cfg_attr]`) let mut parser = Parser::new(&self.0.sess.psess, orig_tokens, None); parser.capture_cfg = true; match parse_annotatable_with(&mut parser) { diff --git a/compiler/rustc_expand/src/config.rs b/compiler/rustc_expand/src/config.rs index 21ff56febb378..be46b2af6cae9 100644 --- a/compiler/rustc_expand/src/config.rs +++ b/compiler/rustc_expand/src/config.rs @@ -172,7 +172,7 @@ impl<'a> StripUnconfigured<'a> { fn configure_tokens(&self, stream: &AttrTokenStream) -> AttrTokenStream { fn can_skip(stream: &AttrTokenStream) -> bool { stream.0.iter().all(|tree| match tree { - AttrTokenTree::Attributes(_) => false, + AttrTokenTree::AttrsTarget(_) => false, AttrTokenTree::Token(..) => true, AttrTokenTree::Delimited(.., inner) => can_skip(inner), }) @@ -186,14 +186,14 @@ impl<'a> StripUnconfigured<'a> { .0 .iter() .flat_map(|tree| match tree.clone() { - AttrTokenTree::Attributes(mut data) => { - data.attrs.flat_map_in_place(|attr| self.process_cfg_attr(&attr)); + AttrTokenTree::AttrsTarget(mut target) => { + target.attrs.flat_map_in_place(|attr| self.process_cfg_attr(&attr)); - if self.in_cfg(&data.attrs) { - data.tokens = LazyAttrTokenStream::new( - self.configure_tokens(&data.tokens.to_attr_token_stream()), + if self.in_cfg(&target.attrs) { + target.tokens = LazyAttrTokenStream::new( + self.configure_tokens(&target.tokens.to_attr_token_stream()), ); - Some(AttrTokenTree::Attributes(data)).into_iter() + Some(AttrTokenTree::AttrsTarget(target)).into_iter() } else { None.into_iter() } diff --git a/compiler/rustc_parse/src/parser/attr_wrapper.rs b/compiler/rustc_parse/src/parser/attr_wrapper.rs index 1aebbbe3559b9..2e421a7f19306 100644 --- a/compiler/rustc_parse/src/parser/attr_wrapper.rs +++ b/compiler/rustc_parse/src/parser/attr_wrapper.rs @@ -1,6 +1,6 @@ use super::{Capturing, FlatToken, ForceCollect, Parser, ReplaceRange, TokenCursor, TrailingToken}; use rustc_ast::token::{self, Delimiter, Token, TokenKind}; -use rustc_ast::tokenstream::{AttrTokenStream, AttrTokenTree, AttributesData, DelimSpacing}; +use rustc_ast::tokenstream::{AttrTokenStream, AttrTokenTree, AttrsTarget, DelimSpacing}; use rustc_ast::tokenstream::{DelimSpan, LazyAttrTokenStream, Spacing, ToAttrTokenStream}; use rustc_ast::{self as ast}; use rustc_ast::{AttrVec, Attribute, HasAttrs, HasTokens}; @@ -145,22 +145,22 @@ impl ToAttrTokenStream for LazyAttrTokenStreamImpl { // start position, we ensure that any replace range which encloses // another replace range will capture the *replaced* tokens for the inner // range, not the original tokens. - for (range, attr_data) in replace_ranges.into_iter().rev() { + for (range, target) in replace_ranges.into_iter().rev() { assert!(!range.is_empty(), "Cannot replace an empty range: {range:?}"); - // Replace the tokens in range with zero or one `FlatToken::AttrTarget`s, plus + // Replace the tokens in range with zero or one `FlatToken::AttrsTarget`s, plus // enough `FlatToken::Empty`s to fill up the rest of the range. This keeps the // total length of `tokens` constant throughout the replacement process, allowing // us to use all of the `ReplaceRanges` entries without adjusting indices. - let attr_data_len = attr_data.is_some() as usize; + let target_len = target.is_some() as usize; tokens.splice( (range.start as usize)..(range.end as usize), - attr_data + target .into_iter() - .map(|attr_data| (FlatToken::AttrTarget(attr_data), Spacing::Alone)) + .map(|target| (FlatToken::AttrsTarget(target), Spacing::Alone)) .chain( iter::repeat((FlatToken::Empty, Spacing::Alone)) - .take(range.len() - attr_data_len), + .take(range.len() - target_len), ), ); } @@ -346,13 +346,12 @@ impl<'a> Parser<'a> { { assert!(!self.break_last_token, "Should not have unglued last token with cfg attr"); - // Replace the entire AST node that we just parsed, including attributes, - // with `attr_data`. If this AST node is inside an item - // that has `#[derive]`, then this will allow us to cfg-expand this - // AST node. + // Replace the entire AST node that we just parsed, including attributes, with + // `target`. If this AST node is inside an item that has `#[derive]`, then this will + // allow us to cfg-expand this AST node. let start_pos = if has_outer_attrs { attrs.start_pos } else { start_pos }; - let attr_data = AttributesData { attrs: final_attrs.iter().cloned().collect(), tokens }; - self.capture_state.replace_ranges.push((start_pos..end_pos, Some(attr_data))); + let target = AttrsTarget { attrs: final_attrs.iter().cloned().collect(), tokens }; + self.capture_state.replace_ranges.push((start_pos..end_pos, Some(target))); self.capture_state.replace_ranges.extend(inner_attr_replace_ranges); } @@ -414,11 +413,11 @@ fn make_attr_token_stream( .expect("Bottom token frame is missing!") .inner .push(AttrTokenTree::Token(token, spacing)), - FlatToken::AttrTarget(data) => stack + FlatToken::AttrsTarget(target) => stack .last_mut() .expect("Bottom token frame is missing!") .inner - .push(AttrTokenTree::Attributes(data)), + .push(AttrTokenTree::AttrsTarget(target)), FlatToken::Empty => {} } token_and_spacing = iter.next(); diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs index 1072e6392921d..45ca267fe5d1e 100644 --- a/compiler/rustc_parse/src/parser/mod.rs +++ b/compiler/rustc_parse/src/parser/mod.rs @@ -20,7 +20,7 @@ use path::PathStyle; use rustc_ast::ptr::P; use rustc_ast::token::{self, Delimiter, IdentIsRaw, Nonterminal, Token, TokenKind}; -use rustc_ast::tokenstream::{AttributesData, DelimSpacing, DelimSpan, Spacing}; +use rustc_ast::tokenstream::{AttrsTarget, DelimSpacing, DelimSpan, Spacing}; use rustc_ast::tokenstream::{TokenStream, TokenTree, TokenTreeCursor}; use rustc_ast::util::case::Case; use rustc_ast::{ @@ -203,13 +203,13 @@ struct ClosureSpans { } /// Indicates a range of tokens that should be replaced by -/// the tokens in the provided `AttributesData`. This is used in two +/// the tokens in the provided `AttrsTarget`. This is used in two /// places during token collection: /// /// 1. During the parsing of an AST node that may have a `#[derive]` /// attribute, we parse a nested AST node that has `#[cfg]` or `#[cfg_attr]` /// In this case, we use a `ReplaceRange` to replace the entire inner AST node -/// with `FlatToken::AttrTarget`, allowing us to perform eager cfg-expansion +/// with `FlatToken::AttrsTarget`, allowing us to perform eager cfg-expansion /// on an `AttrTokenStream`. /// /// 2. When we parse an inner attribute while collecting tokens. We @@ -219,7 +219,7 @@ struct ClosureSpans { /// the first macro inner attribute to invoke a proc-macro). /// When create a `TokenStream`, the inner attributes get inserted /// into the proper place in the token stream. -type ReplaceRange = (Range, Option); +type ReplaceRange = (Range, Option); /// Controls how we capture tokens. Capturing can be expensive, /// so we try to avoid performing capturing in cases where @@ -1608,11 +1608,10 @@ enum FlatToken { /// A token - this holds both delimiter (e.g. '{' and '}') /// and non-delimiter tokens Token(Token), - /// Holds the `AttributesData` for an AST node. The - /// `AttributesData` is inserted directly into the - /// constructed `AttrTokenStream` as - /// an `AttrTokenTree::Attributes`. - AttrTarget(AttributesData), + /// Holds the `AttrsTarget` for an AST node. The `AttrsTarget` is inserted + /// directly into the constructed `AttrTokenStream` as an + /// `AttrTokenTree::AttrsTarget`. + AttrsTarget(AttrsTarget), /// A special 'empty' token that is ignored during the conversion /// to an `AttrTokenStream`. This is used to simplify the /// handling of replace ranges. From 022582ca46d9bedecf0b434b6a4130c9a2a4657d Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Sun, 7 Jul 2024 16:24:51 +1000 Subject: [PATCH 787/892] Remove `Clone` derive from `LazyAttrTokenStreamImpl`. --- compiler/rustc_parse/src/parser/attr_wrapper.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/compiler/rustc_parse/src/parser/attr_wrapper.rs b/compiler/rustc_parse/src/parser/attr_wrapper.rs index 2e421a7f19306..38f18022e3c58 100644 --- a/compiler/rustc_parse/src/parser/attr_wrapper.rs +++ b/compiler/rustc_parse/src/parser/attr_wrapper.rs @@ -87,7 +87,6 @@ fn has_cfg_or_cfg_attr(attrs: &[Attribute]) -> bool { // // This also makes `Parser` very cheap to clone, since // there is no intermediate collection buffer to clone. -#[derive(Clone)] struct LazyAttrTokenStreamImpl { start_token: (Token, Spacing), cursor_snapshot: TokenCursor, From 9f16f1f6f637d729c92789cae26a1adb7eee40cd Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Sun, 7 Jul 2024 16:25:22 +1000 Subject: [PATCH 788/892] Add an size assertion. `Option` is the type that's actually used in all the aST nodes. --- compiler/rustc_ast/src/tokenstream.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/compiler/rustc_ast/src/tokenstream.rs b/compiler/rustc_ast/src/tokenstream.rs index f3b6dc2cfa198..ee068f19332a5 100644 --- a/compiler/rustc_ast/src/tokenstream.rs +++ b/compiler/rustc_ast/src/tokenstream.rs @@ -765,6 +765,7 @@ mod size_asserts { static_assert_size!(AttrTokenStream, 8); static_assert_size!(AttrTokenTree, 32); static_assert_size!(LazyAttrTokenStream, 8); + static_assert_size!(Option, 8); // must be small, used in many AST nodes static_assert_size!(TokenStream, 8); static_assert_size!(TokenTree, 32); // tidy-alphabetical-end From 9e0aab71a46692e4ddd455d7931cbb7336b9d732 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Sun, 7 Jul 2024 16:29:07 +1000 Subject: [PATCH 789/892] Use `filter_map` instead of `flat_map` in `configure_tokens`. All the branches produce either zero or one elements. --- compiler/rustc_expand/src/config.rs | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_expand/src/config.rs b/compiler/rustc_expand/src/config.rs index be46b2af6cae9..40e16b4511575 100644 --- a/compiler/rustc_expand/src/config.rs +++ b/compiler/rustc_expand/src/config.rs @@ -185,7 +185,7 @@ impl<'a> StripUnconfigured<'a> { let trees: Vec<_> = stream .0 .iter() - .flat_map(|tree| match tree.clone() { + .filter_map(|tree| match tree.clone() { AttrTokenTree::AttrsTarget(mut target) => { target.attrs.flat_map_in_place(|attr| self.process_cfg_attr(&attr)); @@ -193,14 +193,14 @@ impl<'a> StripUnconfigured<'a> { target.tokens = LazyAttrTokenStream::new( self.configure_tokens(&target.tokens.to_attr_token_stream()), ); - Some(AttrTokenTree::AttrsTarget(target)).into_iter() + Some(AttrTokenTree::AttrsTarget(target)) } else { - None.into_iter() + None } } AttrTokenTree::Delimited(sp, spacing, delim, mut inner) => { inner = self.configure_tokens(&inner); - Some(AttrTokenTree::Delimited(sp, spacing, delim, inner)).into_iter() + Some(AttrTokenTree::Delimited(sp, spacing, delim, inner)) } AttrTokenTree::Token( Token { @@ -220,9 +220,7 @@ impl<'a> StripUnconfigured<'a> { ) => { panic!("Should be `AttrTokenTree::Delimited`, not delim tokens: {:?}", tree); } - AttrTokenTree::Token(token, spacing) => { - Some(AttrTokenTree::Token(token, spacing)).into_iter() - } + AttrTokenTree::Token(token, spacing) => Some(AttrTokenTree::Token(token, spacing)), }) .collect(); AttrTokenStream::new(trees) From bee9120458dd3eb2c1486dd6c2344ec2c582f1b8 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 7 Jul 2024 09:19:32 +0200 Subject: [PATCH 790/892] once_lock: make test not take as long in Miri --- library/std/src/sync/once_lock.rs | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/library/std/src/sync/once_lock.rs b/library/std/src/sync/once_lock.rs index f52b9e52c54de..fe243550606f3 100644 --- a/library/std/src/sync/once_lock.rs +++ b/library/std/src/sync/once_lock.rs @@ -80,14 +80,21 @@ use crate::sync::Once; /// static LIST: OnceList = OnceList::new(); /// static COUNTER: AtomicU32 = AtomicU32::new(0); /// -/// let vec = (0..thread::available_parallelism().unwrap().get()).map(|_| thread::spawn(|| { -/// while let i @ 0..=1000 = COUNTER.fetch_add(1, Ordering::Relaxed) { -/// LIST.push(i); +/// # const LEN: u32 = if cfg!(miri) { 50 } else { 1000 }; +/// # /* +/// const LEN: u32 = 1000; +/// # */ +/// thread::scope(|s| { +/// for _ in 0..thread::available_parallelism().unwrap().get() { +/// s.spawn(|| { +/// while let i @ 0..LEN = COUNTER.fetch_add(1, Ordering::Relaxed) { +/// LIST.push(i); +/// } +/// }); /// } -/// })).collect::>>(); -/// vec.into_iter().for_each(|handle| handle.join().unwrap()); +/// }); /// -/// for i in 0..=1000 { +/// for i in 0..LEN { /// assert!(LIST.contains(&i)); /// } /// From 9da3638c6a90748cc913a3e2e02a74eb851ec48a Mon Sep 17 00:00:00 2001 From: Gurinder Singh Date: Sun, 7 Jul 2024 15:44:55 +0530 Subject: [PATCH 791/892] Move a span_bug under a condition that cx is tainted Fixes an ICE caused when a with expression is not a struct --- compiler/rustc_hir_typeck/src/expr_use_visitor.rs | 4 +++- tests/crashes/127332.rs | 9 --------- .../ui/typeck/ice-with-expr-not-struct-127332.rs | 15 +++++++++++++++ .../typeck/ice-with-expr-not-struct-127332.stderr | 9 +++++++++ 4 files changed, 27 insertions(+), 10 deletions(-) delete mode 100644 tests/crashes/127332.rs create mode 100644 tests/ui/typeck/ice-with-expr-not-struct-127332.rs create mode 100644 tests/ui/typeck/ice-with-expr-not-struct-127332.stderr diff --git a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs index c8ab0429ffc70..193dbbbcdf44d 100644 --- a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs +++ b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs @@ -734,7 +734,9 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx // struct; however, when EUV is run during typeck, it // may not. This will generate an error earlier in typeck, // so we can just ignore it. - span_bug!(with_expr.span, "with expression doesn't evaluate to a struct"); + if self.cx.tainted_by_errors().is_ok() { + span_bug!(with_expr.span, "with expression doesn't evaluate to a struct"); + } } } diff --git a/tests/crashes/127332.rs b/tests/crashes/127332.rs deleted file mode 100644 index 5c14af01cece8..0000000000000 --- a/tests/crashes/127332.rs +++ /dev/null @@ -1,9 +0,0 @@ -//@ known-bug: rust-lang/rust #127332 - -async fn fun() { - enum Foo { - A { x: u32 }, - } - let orig = Foo::A { x: 5 }; - Foo::A { x: 6, ..orig }; -} diff --git a/tests/ui/typeck/ice-with-expr-not-struct-127332.rs b/tests/ui/typeck/ice-with-expr-not-struct-127332.rs new file mode 100644 index 0000000000000..f3ea360e7e982 --- /dev/null +++ b/tests/ui/typeck/ice-with-expr-not-struct-127332.rs @@ -0,0 +1,15 @@ +// Regression test for ICE #127332 + +// Tests that we do not ICE when a with expr is +// not a struct but something else like an enum + +fn main() { + let x = || { + enum Foo { + A { x: u32 }, + } + let orig = Foo::A { x: 5 }; + Foo::A { x: 6, ..orig }; + //~^ ERROR functional record update syntax requires a struct + }; +} diff --git a/tests/ui/typeck/ice-with-expr-not-struct-127332.stderr b/tests/ui/typeck/ice-with-expr-not-struct-127332.stderr new file mode 100644 index 0000000000000..446f49e863924 --- /dev/null +++ b/tests/ui/typeck/ice-with-expr-not-struct-127332.stderr @@ -0,0 +1,9 @@ +error[E0436]: functional record update syntax requires a struct + --> $DIR/ice-with-expr-not-struct-127332.rs:12:26 + | +LL | Foo::A { x: 6, ..orig }; + | ^^^^ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0436`. From 39bb14e34a5670603386a7e6d4029b5e6699de6c Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sun, 7 Jul 2024 13:05:07 +0200 Subject: [PATCH 792/892] Improve `run-make/output-type-permutations` code and improve `filename_not_in_denylist` API --- src/tools/run-make-support/src/lib.rs | 3 ++- tests/run-make/output-type-permutations/rmake.rs | 5 ++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/tools/run-make-support/src/lib.rs b/src/tools/run-make-support/src/lib.rs index 7bb89106de1b9..f464a109e7711 100644 --- a/src/tools/run-make-support/src/lib.rs +++ b/src/tools/run-make-support/src/lib.rs @@ -296,7 +296,8 @@ pub fn not_contains>(path: P, expected: &str) -> bool { } /// Returns true if the filename at `path` is not in `expected`. -pub fn filename_not_in_denylist>(path: P, expected: &[String]) -> bool { +pub fn filename_not_in_denylist, V: AsRef<[String]>>(path: P, expected: V) -> bool { + let expected = expected.as_ref(); path.as_ref() .file_name() .is_some_and(|name| !expected.contains(&name.to_str().unwrap().to_owned())) diff --git a/tests/run-make/output-type-permutations/rmake.rs b/tests/run-make/output-type-permutations/rmake.rs index 30036dc7eeacd..1d1637a744ec0 100644 --- a/tests/run-make/output-type-permutations/rmake.rs +++ b/tests/run-make/output-type-permutations/rmake.rs @@ -17,9 +17,8 @@ use std::path::PathBuf; // `rustc_invocation`: the rustc command being tested // Any unexpected output files not listed in `must_exist` or `can_exist` will cause a failure. fn assert_expected_output_files(expectations: Expectations, rustc_invocation: impl Fn()) { - let must_exist = expectations.expected_files; - let can_exist = expectations.allowed_files; - let dir = expectations.test_dir; + let Expectations { expected_files: must_exist, allowed_files: can_exist, test_dir: dir } = + expectations; fs_wrapper::create_dir(&dir); rustc_invocation(); From 4f54193ccfd67149c3fe6aa5bda10983b98a3982 Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Sun, 7 Jul 2024 11:18:35 +0000 Subject: [PATCH 793/892] Fix intrinsic const parameter counting with `effects` --- .../rustc_hir_analysis/src/check/intrinsic.rs | 18 ++++--- tests/ui/intrinsics/not-overridden.rs | 2 +- .../safe-intrinsic-mismatch.effects.stderr | 52 +++++++++++++++++++ .../ui/intrinsics/safe-intrinsic-mismatch.rs | 7 ++- ...r => safe-intrinsic-mismatch.stock.stderr} | 12 ++--- .../effects/minicore.rs | 42 +++++++++++++-- .../effects/minicore.stderr | 24 ++++----- 7 files changed, 126 insertions(+), 31 deletions(-) create mode 100644 tests/ui/intrinsics/safe-intrinsic-mismatch.effects.stderr rename tests/ui/intrinsics/{safe-intrinsic-mismatch.stderr => safe-intrinsic-mismatch.stock.stderr} (86%) diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs index f21aeb4c0b98c..6282499883ba4 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs +++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs @@ -26,15 +26,12 @@ fn equate_intrinsic_type<'tcx>( n_cts: usize, sig: ty::PolyFnSig<'tcx>, ) { - let (own_counts, span) = match tcx.hir_node_by_def_id(def_id) { + let (generics, span) = match tcx.hir_node_by_def_id(def_id) { hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn(_, generics, _), .. }) | hir::Node::ForeignItem(hir::ForeignItem { kind: hir::ForeignItemKind::Fn(.., generics, _), .. - }) => { - let own_counts = tcx.generics_of(def_id).own_counts(); - (own_counts, generics.span) - } + }) => (tcx.generics_of(def_id), generics.span), _ => { struct_span_code_err!(tcx.dcx(), span, E0622, "intrinsic must be a function") .with_span_label(span, "expected a function") @@ -42,6 +39,7 @@ fn equate_intrinsic_type<'tcx>( return; } }; + let own_counts = generics.own_counts(); let gen_count_ok = |found: usize, expected: usize, descr: &str| -> bool { if found != expected { @@ -57,9 +55,17 @@ fn equate_intrinsic_type<'tcx>( } }; + // the host effect param should be invisible as it shouldn't matter + // whether effects is enabled for the intrinsic provider crate. + let consts_count = if generics.host_effect_index.is_some() { + own_counts.consts - 1 + } else { + own_counts.consts + }; + if gen_count_ok(own_counts.lifetimes, n_lts, "lifetime") && gen_count_ok(own_counts.types, n_tps, "type") - && gen_count_ok(own_counts.consts, n_cts, "const") + && gen_count_ok(consts_count, n_cts, "const") { let _ = check_function_signature( tcx, diff --git a/tests/ui/intrinsics/not-overridden.rs b/tests/ui/intrinsics/not-overridden.rs index a53071e304d89..93b408331b862 100644 --- a/tests/ui/intrinsics/not-overridden.rs +++ b/tests/ui/intrinsics/not-overridden.rs @@ -1,6 +1,6 @@ //! Check that intrinsics that do not get overridden, but are marked as such, //! cause an error instead of silently invoking the body. -#![feature(rustc_attrs/* , effects*/)] // FIXME(effects) +#![feature(rustc_attrs)] //@ build-fail //@ failure-status:101 //@ normalize-stderr-test ".*note: .*\n\n" -> "" diff --git a/tests/ui/intrinsics/safe-intrinsic-mismatch.effects.stderr b/tests/ui/intrinsics/safe-intrinsic-mismatch.effects.stderr new file mode 100644 index 0000000000000..d9a4960feec4d --- /dev/null +++ b/tests/ui/intrinsics/safe-intrinsic-mismatch.effects.stderr @@ -0,0 +1,52 @@ +error: using `#![feature(effects)]` without enabling next trait solver globally + | + = note: the next trait solver must be enabled globally for the effects feature to work correctly + = help: use `-Znext-solver` to enable + +error: intrinsic safety mismatch between list of intrinsics within the compiler and core library intrinsics for intrinsic `size_of` + --> $DIR/safe-intrinsic-mismatch.rs:11:5 + | +LL | fn size_of() -> usize; + | ^^^^^^^^^^^^^^^^^^^^^^^^ + +error: intrinsic safety mismatch between list of intrinsics within the compiler and core library intrinsics for intrinsic `size_of` + --> $DIR/safe-intrinsic-mismatch.rs:11:5 + | +LL | fn size_of() -> usize; + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: intrinsic safety mismatch between list of intrinsics within the compiler and core library intrinsics for intrinsic `assume` + --> $DIR/safe-intrinsic-mismatch.rs:16:1 + | +LL | const fn assume(_b: bool) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0308]: intrinsic has wrong type + --> $DIR/safe-intrinsic-mismatch.rs:16:16 + | +LL | const fn assume(_b: bool) {} + | ^ expected unsafe fn, found safe fn + | + = note: expected signature `unsafe fn(_)` + found signature `fn(_)` + +error: intrinsic safety mismatch between list of intrinsics within the compiler and core library intrinsics for intrinsic `const_deallocate` + --> $DIR/safe-intrinsic-mismatch.rs:20:1 + | +LL | const fn const_deallocate(_ptr: *mut u8, _size: usize, _align: usize) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0308]: intrinsic has wrong type + --> $DIR/safe-intrinsic-mismatch.rs:20:26 + | +LL | const fn const_deallocate(_ptr: *mut u8, _size: usize, _align: usize) {} + | ^ expected unsafe fn, found safe fn + | + = note: expected signature `unsafe fn(_, _, _)` + found signature `fn(_, _, _)` + +error: aborting due to 7 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/intrinsics/safe-intrinsic-mismatch.rs b/tests/ui/intrinsics/safe-intrinsic-mismatch.rs index c116ba7a62eeb..af563e996c1df 100644 --- a/tests/ui/intrinsics/safe-intrinsic-mismatch.rs +++ b/tests/ui/intrinsics/safe-intrinsic-mismatch.rs @@ -1,6 +1,11 @@ +//@ revisions: stock effects #![feature(intrinsics)] #![feature(rustc_attrs)] -// FIXME(effects) do this with revisions #![feature(effects)] +// as effects insert a const generic param to const intrinsics, +// check here that it doesn't report a const param mismatch either +// enabling or disabling effects. +#![cfg_attr(effects, feature(effects))] +#![allow(incomplete_features)] extern "rust-intrinsic" { fn size_of() -> usize; //~ ERROR intrinsic safety mismatch diff --git a/tests/ui/intrinsics/safe-intrinsic-mismatch.stderr b/tests/ui/intrinsics/safe-intrinsic-mismatch.stock.stderr similarity index 86% rename from tests/ui/intrinsics/safe-intrinsic-mismatch.stderr rename to tests/ui/intrinsics/safe-intrinsic-mismatch.stock.stderr index 7f37e0f821118..6864c0f36ded0 100644 --- a/tests/ui/intrinsics/safe-intrinsic-mismatch.stderr +++ b/tests/ui/intrinsics/safe-intrinsic-mismatch.stock.stderr @@ -1,11 +1,11 @@ error: intrinsic safety mismatch between list of intrinsics within the compiler and core library intrinsics for intrinsic `size_of` - --> $DIR/safe-intrinsic-mismatch.rs:6:5 + --> $DIR/safe-intrinsic-mismatch.rs:11:5 | LL | fn size_of() -> usize; | ^^^^^^^^^^^^^^^^^^^^^^^^ error: intrinsic safety mismatch between list of intrinsics within the compiler and core library intrinsics for intrinsic `size_of` - --> $DIR/safe-intrinsic-mismatch.rs:6:5 + --> $DIR/safe-intrinsic-mismatch.rs:11:5 | LL | fn size_of() -> usize; | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -13,13 +13,13 @@ LL | fn size_of() -> usize; = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: intrinsic safety mismatch between list of intrinsics within the compiler and core library intrinsics for intrinsic `assume` - --> $DIR/safe-intrinsic-mismatch.rs:11:1 + --> $DIR/safe-intrinsic-mismatch.rs:16:1 | LL | const fn assume(_b: bool) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0308]: intrinsic has wrong type - --> $DIR/safe-intrinsic-mismatch.rs:11:16 + --> $DIR/safe-intrinsic-mismatch.rs:16:16 | LL | const fn assume(_b: bool) {} | ^ expected unsafe fn, found safe fn @@ -28,13 +28,13 @@ LL | const fn assume(_b: bool) {} found signature `fn(_)` error: intrinsic safety mismatch between list of intrinsics within the compiler and core library intrinsics for intrinsic `const_deallocate` - --> $DIR/safe-intrinsic-mismatch.rs:15:1 + --> $DIR/safe-intrinsic-mismatch.rs:20:1 | LL | const fn const_deallocate(_ptr: *mut u8, _size: usize, _align: usize) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0308]: intrinsic has wrong type - --> $DIR/safe-intrinsic-mismatch.rs:15:26 + --> $DIR/safe-intrinsic-mismatch.rs:20:26 | LL | const fn const_deallocate(_ptr: *mut u8, _size: usize, _align: usize) {} | ^ expected unsafe fn, found safe fn diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/minicore.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/minicore.rs index af88a73b4d692..63c353c7d6627 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/minicore.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/minicore.rs @@ -1,12 +1,16 @@ //@ known-bug: #110395 +//@ failure-status: 101 +//@ normalize-stderr-test ".*note: .*\n\n" -> "" +//@ normalize-stderr-test "thread 'rustc' panicked.*:\n.*\n" -> "" +//@ rustc-env:RUST_BACKTRACE=0 // FIXME(effects) check-pass -// FIXME(effects) fix intrinsics const parameter counting +//@ compile-flags: -Znext-solver #![crate_type = "lib"] #![feature(no_core, lang_items, unboxed_closures, auto_traits, intrinsics, rustc_attrs, staged_api)] -#![feature(fundamental)] +#![feature(fundamental, marker_trait_attr)] #![feature(const_trait_impl, effects, const_mut_refs)] -#![allow(internal_features)] +#![allow(internal_features, incomplete_features)] #![no_std] #![no_core] #![stable(feature = "minicore", since = "1.0.0")] @@ -532,3 +536,35 @@ fn test_const_eval_select() { const_eval_select((), const_fn, rt_fn); } + +mod effects { + use super::Sized; + + #[lang = "EffectsNoRuntime"] + pub struct NoRuntime; + #[lang = "EffectsMaybe"] + pub struct Maybe; + #[lang = "EffectsRuntime"] + pub struct Runtime; + + #[lang = "EffectsCompat"] + pub trait Compat<#[rustc_runtime] const RUNTIME: bool> {} + + impl Compat for NoRuntime {} + impl Compat for Runtime {} + impl<#[rustc_runtime] const RUNTIME: bool> Compat for Maybe {} + + #[lang = "EffectsTyCompat"] + #[marker] + pub trait TyCompat {} + + impl TyCompat for T {} + impl TyCompat for Maybe {} + impl TyCompat for T {} + + #[lang = "EffectsIntersection"] + pub trait Intersection { + #[lang = "EffectsIntersectionOutput"] + type Output: ?Sized; + } +} diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/minicore.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/minicore.stderr index 1963332b856de..823ab69df9cb5 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/minicore.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/minicore.stderr @@ -1,17 +1,13 @@ -warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/minicore.rs:8:30 - | -LL | #![feature(const_trait_impl, effects, const_mut_refs)] - | ^^^^^^^ - | - = note: see issue #102090 for more information - = note: `#[warn(incomplete_features)]` on by default +error: the compiler unexpectedly panicked. this is a bug. -error: requires `EffectsCompat` lang_item - --> $DIR/minicore.rs:455:9 - | -LL | impl Clone for RefCell { - | ^^^^^ +query stack during panic: +#0 [check_well_formed] checking that `` is well-formed +#1 [check_mod_type_wf] checking that types are well-formed in top-level module +end of query stack -error: aborting due to 1 previous error; 1 warning emitted +error: the compiler unexpectedly panicked. this is a bug. +query stack during panic: +#0 [check_well_formed] checking that `drop` is well-formed +#1 [check_mod_type_wf] checking that types are well-formed in top-level module +end of query stack From 76ba11994e3b94890ec61bd75c2d2b9a428d151d Mon Sep 17 00:00:00 2001 From: Nilstrieb <48135649+Nilstrieb@users.noreply.github.com> Date: Sun, 7 Jul 2024 14:22:06 +0200 Subject: [PATCH 794/892] Revert "remove regexes" This reverts commit 8d8504300fe7ad9b20a7690cce8025290847f155. The regexes are important for performance. --- src/tools/tidy/src/style.rs | 36 +++++++++++++------------------ src/tools/tidy/src/style/tests.rs | 19 ++++++++++------ 2 files changed, 28 insertions(+), 27 deletions(-) diff --git a/src/tools/tidy/src/style.rs b/src/tools/tidy/src/style.rs index f65001e8de881..e4d54d2a2b589 100644 --- a/src/tools/tidy/src/style.rs +++ b/src/tools/tidy/src/style.rs @@ -18,8 +18,9 @@ // ignore-tidy-dbg use crate::walk::{filter_dirs, walk}; +use regex::RegexSet; use rustc_hash::FxHashMap; -use std::{ffi::OsStr, path::Path, sync::LazyLock}; +use std::{ffi::OsStr, path::Path}; #[cfg(test)] mod tests; @@ -109,32 +110,15 @@ const ROOT_PROBLEMATIC_CONSTS: &[u32] = &[ 173390526, 721077, ]; -#[cfg(not(test))] -const LETTER_DIGIT: &[(char, char)] = &[('A', '4'), ('B', '8'), ('E', '3')]; - -#[cfg(test)] -const LETTER_DIGIT: &[(char, char)] = &[('A', '4'), ('B', '8'), ('E', '3'), ('0', 'F')]; // use "futile" F intentionally - fn generate_problematic_strings( consts: &[u32], letter_digit: &FxHashMap, ) -> Vec { generate_problems(consts, letter_digit) - .flat_map(|v| vec![v.to_string(), format!("{:X}", v)]) + .flat_map(|v| vec![v.to_string(), format!("{:x}", v), format!("{:X}", v)]) .collect() } -static PROBLEMATIC_CONSTS_STRINGS: LazyLock> = LazyLock::new(|| { - generate_problematic_strings( - ROOT_PROBLEMATIC_CONSTS, - &FxHashMap::from_iter(LETTER_DIGIT.iter().copied()), - ) -}); - -fn contains_problematic_const(trimmed: &str) -> bool { - PROBLEMATIC_CONSTS_STRINGS.iter().any(|s| trimmed.to_uppercase().contains(s)) -} - const INTERNAL_COMPILER_DOCS_LINE: &str = "#### This error code is internal to the compiler and will not be emitted with normal Rust code."; /// Parser states for `line_is_url`. @@ -331,6 +315,11 @@ pub fn check(path: &Path, bad: &mut bool) { // We only check CSS files in rustdoc. path.extension().map_or(false, |e| e == "css") && !is_in(path, "src", "librustdoc") } + let problematic_consts_strings = generate_problematic_strings( + ROOT_PROBLEMATIC_CONSTS, + &[('A', '4'), ('B', '8'), ('E', '3')].iter().cloned().collect(), + ); + let problematic_regex = RegexSet::new(problematic_consts_strings.as_slice()).unwrap(); walk(path, skip, &mut |entry, contents| { let file = entry.path(); @@ -400,6 +389,7 @@ pub fn check(path: &Path, bad: &mut bool) { let is_test = file.components().any(|c| c.as_os_str() == "tests"); // scanning the whole file for multiple needles at once is more efficient than // executing lines times needles separate searches. + let any_problematic_line = problematic_regex.is_match(contents); for (i, line) in contents.split('\n').enumerate() { if line.is_empty() { if i == 0 { @@ -469,8 +459,12 @@ pub fn check(path: &Path, bad: &mut bool) { if trimmed.contains("//") && trimmed.contains(" XXX") { err("Instead of XXX use FIXME") } - if contains_problematic_const(trimmed) { - err("Don't use magic numbers that spell things (consider 0x12345678)"); + if any_problematic_line { + for s in problematic_consts_strings.iter() { + if trimmed.contains(s) { + err("Don't use magic numbers that spell things (consider 0x12345678)"); + } + } } } // for now we just check libcore diff --git a/src/tools/tidy/src/style/tests.rs b/src/tools/tidy/src/style/tests.rs index 47fec89043212..292e23916d241 100644 --- a/src/tools/tidy/src/style/tests.rs +++ b/src/tools/tidy/src/style/tests.rs @@ -1,10 +1,17 @@ use super::*; #[test] -fn test_contains_problematic_const() { - assert!(contains_problematic_const("786357")); // check with no "decimal" hex digits - converted to integer - assert!(contains_problematic_const("589701")); // check with "decimal" replacements - converted to integer - assert!(contains_problematic_const("8FF85")); // check for hex display - assert!(contains_problematic_const("8fF85")); // check for case-alternating hex display - assert!(!contains_problematic_const("1193046")); // check for non-matching value +fn test_generate_problematic_strings() { + let problematic_regex = RegexSet::new( + generate_problematic_strings( + ROOT_PROBLEMATIC_CONSTS, + &[('A', '4'), ('B', '8'), ('E', '3'), ('0', 'F')].iter().cloned().collect(), // use "futile" F intentionally + ) + .as_slice(), + ) + .unwrap(); + assert!(problematic_regex.is_match("786357")); // check with no "decimal" hex digits - converted to integer + assert!(problematic_regex.is_match("589701")); // check with "decimal" replacements - converted to integer + assert!(problematic_regex.is_match("8FF85")); // check for hex display + assert!(!problematic_regex.is_match("1193046")); // check for non-matching value } From 1cfc89ad691f807ff157ed99104aee9118fdc3fe Mon Sep 17 00:00:00 2001 From: Nilstrieb <48135649+Nilstrieb@users.noreply.github.com> Date: Sun, 7 Jul 2024 14:23:36 +0200 Subject: [PATCH 795/892] Add note about performance of tidy problematic consts --- src/tools/tidy/src/style.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/tools/tidy/src/style.rs b/src/tools/tidy/src/style.rs index e4d54d2a2b589..8e693c35adcbf 100644 --- a/src/tools/tidy/src/style.rs +++ b/src/tools/tidy/src/style.rs @@ -110,6 +110,7 @@ const ROOT_PROBLEMATIC_CONSTS: &[u32] = &[ 173390526, 721077, ]; +// Returns all permutations of problematic consts, over 2000 elements. fn generate_problematic_strings( consts: &[u32], letter_digit: &FxHashMap, @@ -319,6 +320,8 @@ pub fn check(path: &Path, bad: &mut bool) { ROOT_PROBLEMATIC_CONSTS, &[('A', '4'), ('B', '8'), ('E', '3')].iter().cloned().collect(), ); + // This creates a RegexSet as regex contains performance optimizations to be able to deal with these over + // 2000 needles efficiently. This runs over the entire source code, so performance matters. let problematic_regex = RegexSet::new(problematic_consts_strings.as_slice()).unwrap(); walk(path, skip, &mut |entry, contents| { From 8e7314f6e06a15c6cdced279008f37d0ff5374c5 Mon Sep 17 00:00:00 2001 From: schvv31n Date: Sun, 7 Jul 2024 15:02:30 +0100 Subject: [PATCH 796/892] rustdoc-json: add trait/type alias tests --- tests/rustdoc-json/trait_alias.rs | 18 ++++++++++++++++++ tests/rustdoc-json/type_alias.rs | 15 +++++++++++++++ 2 files changed, 33 insertions(+) create mode 100644 tests/rustdoc-json/trait_alias.rs create mode 100644 tests/rustdoc-json/type_alias.rs diff --git a/tests/rustdoc-json/trait_alias.rs b/tests/rustdoc-json/trait_alias.rs new file mode 100644 index 0000000000000..dc930550ef1ec --- /dev/null +++ b/tests/rustdoc-json/trait_alias.rs @@ -0,0 +1,18 @@ +// ignore-tidy-linelength +#![feature(trait_alias)] + +// @set StrLike = "$.index[*][?(@.name=='StrLike')].id" +// @is "$.index[*][?(@.name=='StrLike')].visibility" \"public\" +// @has "$.index[*][?(@.name=='StrLike')].inner.trait_alias" +// @is "$.index[*][?(@.name=='StrLike')].span.filename" $FILE +pub trait StrLike = AsRef; + +// @is "$.index[*][?(@.name=='f')].inner.function.decl.output.impl_trait[0].trait_bound.trait.id" $StrLike +pub fn f() -> impl StrLike { + "heya" +} + +// @!is "$.index[*][?(@.name=='g')].inner.function.decl.output.impl_trait[0].trait_bound.trait.id" $StrLike +pub fn g() -> impl AsRef { + "heya" +} diff --git a/tests/rustdoc-json/type_alias.rs b/tests/rustdoc-json/type_alias.rs new file mode 100644 index 0000000000000..7a938c50ba0b2 --- /dev/null +++ b/tests/rustdoc-json/type_alias.rs @@ -0,0 +1,15 @@ +// @set IntVec = "$.index[*][?(@.name=='IntVec')].id" +// @is "$.index[*][?(@.name=='IntVec')].visibility" \"public\" +// @has "$.index[*][?(@.name=='IntVec')].inner.type_alias" +// @is "$.index[*][?(@.name=='IntVec')].span.filename" $FILE +pub type IntVec = Vec; + +// @is "$.index[*][?(@.name=='f')].inner.function.decl.output.resolved_path.id" $IntVec +pub fn f() -> IntVec { + vec![0; 32] +} + +// @!is "$.index[*][?(@.name=='g')].inner.function.decl.output.resolved_path.id" $IntVec +pub fn g() -> Vec { + vec![0; 32] +} From d58a2391f5c442565b680b92154ad8f421952401 Mon Sep 17 00:00:00 2001 From: Weihang Lo Date: Sun, 7 Jul 2024 10:21:28 -0400 Subject: [PATCH 797/892] Update cargo --- src/tools/cargo | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/cargo b/src/tools/cargo index a515d463427b3..154fdac39ae96 160000 --- a/src/tools/cargo +++ b/src/tools/cargo @@ -1 +1 @@ -Subproject commit a515d463427b3912ec0365d106791f88c1c14e1b +Subproject commit 154fdac39ae9629954e19e9986fd2cf2cdd8d964 From b2e30bdec480d38d050b7a8a3281cbd71fdcb075 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sat, 6 Jul 2024 18:16:02 -0400 Subject: [PATCH 798/892] Add fundamental to trait def --- compiler/rustc_hir_analysis/src/collect.rs | 2 ++ compiler/rustc_middle/src/ty/trait_def.rs | 7 ++++++- compiler/rustc_trait_selection/src/traits/coherence.rs | 2 +- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index 41fbef489405c..843e4d41e001e 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -1201,6 +1201,7 @@ fn trait_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::TraitDef { let is_marker = tcx.has_attr(def_id, sym::marker); let rustc_coinductive = tcx.has_attr(def_id, sym::rustc_coinductive); + let is_fundamental = tcx.has_attr(def_id, sym::fundamental); // FIXME: We could probably do way better attribute validation here. let mut skip_array_during_method_dispatch = false; @@ -1352,6 +1353,7 @@ fn trait_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::TraitDef { has_auto_impl: is_auto, is_marker, is_coinductive: rustc_coinductive || is_auto, + is_fundamental, skip_array_during_method_dispatch, skip_boxed_slice_during_method_dispatch, specialization_kind, diff --git a/compiler/rustc_middle/src/ty/trait_def.rs b/compiler/rustc_middle/src/ty/trait_def.rs index 4dba97c3b5b83..076a74ca6f8d7 100644 --- a/compiler/rustc_middle/src/ty/trait_def.rs +++ b/compiler/rustc_middle/src/ty/trait_def.rs @@ -31,7 +31,7 @@ pub struct TraitDef { /// and thus `impl`s of it are allowed to overlap. pub is_marker: bool, - /// If `true`, then this trait has to `#[rustc_coinductive]` attribute or + /// If `true`, then this trait has the `#[rustc_coinductive]` attribute or /// is an auto trait. This indicates that trait solver cycles involving an /// `X: ThisTrait` goal are accepted. /// @@ -40,6 +40,11 @@ pub struct TraitDef { /// also have already switched to the new trait solver. pub is_coinductive: bool, + /// If `true`, then this trait has the `#[fundamental]` attribute. This + /// affects how conherence computes whether a trait may have trait implementations + /// added in the future. + pub is_fundamental: bool, + /// If `true`, then this trait has the `#[rustc_skip_during_method_dispatch(array)]` /// attribute, indicating that editions before 2021 should not consider this trait /// during method dispatch if the receiver is an array. diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs index 9f0d84e7d4526..57ba6c33ac5a5 100644 --- a/compiler/rustc_trait_selection/src/traits/coherence.rs +++ b/compiler/rustc_trait_selection/src/traits/coherence.rs @@ -666,7 +666,7 @@ pub fn trait_ref_is_local_or_fundamental<'tcx>( tcx: TyCtxt<'tcx>, trait_ref: ty::TraitRef<'tcx>, ) -> bool { - trait_ref.def_id.is_local() || tcx.has_attr(trait_ref.def_id, sym::fundamental) + trait_ref.def_id.is_local() || tcx.trait_def(trait_ref.def_id).is_fundamental } #[derive(Debug, Copy, Clone)] From a982471e07a87f1a379682d3b6241f61b4c9f135 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sat, 6 Jul 2024 18:24:51 -0400 Subject: [PATCH 799/892] Uplift trait_ref_is_knowable and friends --- .../src/coherence/orphan.rs | 15 +- compiler/rustc_hir_analysis/src/lib.rs | 1 + compiler/rustc_infer/src/infer/context.rs | 4 + compiler/rustc_middle/src/ty/adt.rs | 4 + compiler/rustc_middle/src/ty/context.rs | 8 + .../rustc_next_trait_solver/src/coherence.rs | 469 ++++++++++++++++++ compiler/rustc_next_trait_solver/src/lib.rs | 1 + compiler/rustc_trait_selection/src/lib.rs | 1 + .../src/traits/coherence.rs | 450 +---------------- .../src/traits/select/mod.rs | 2 +- compiler/rustc_type_ir/src/infer_ctxt.rs | 5 + compiler/rustc_type_ir/src/inherent.rs | 4 + compiler/rustc_type_ir/src/interner.rs | 2 + 13 files changed, 508 insertions(+), 458 deletions(-) create mode 100644 compiler/rustc_next_trait_solver/src/coherence.rs diff --git a/compiler/rustc_hir_analysis/src/coherence/orphan.rs b/compiler/rustc_hir_analysis/src/coherence/orphan.rs index 5cb91603fd067..16f72f38d6088 100644 --- a/compiler/rustc_hir_analysis/src/coherence/orphan.rs +++ b/compiler/rustc_hir_analysis/src/coherence/orphan.rs @@ -286,7 +286,7 @@ fn orphan_check<'tcx>( tcx: TyCtxt<'tcx>, impl_def_id: LocalDefId, mode: OrphanCheckMode, -) -> Result<(), OrphanCheckErr<'tcx, FxIndexSet>> { +) -> Result<(), OrphanCheckErr, FxIndexSet>> { // We only accept this routine to be invoked on implementations // of a trait, not inherent implementations. let trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap(); @@ -326,17 +326,16 @@ fn orphan_check<'tcx>( ty }; - Ok(ty) + Ok::<_, !>(ty) }; - let Ok(result) = traits::orphan_check_trait_ref::( + let result = traits::orphan_check_trait_ref( &infcx, trait_ref, traits::InCrate::Local { mode }, lazily_normalize_ty, - ) else { - unreachable!() - }; + ) + .into_ok(); // (2) Try to map the remaining inference vars back to generic params. result.map_err(|err| match err { @@ -369,7 +368,7 @@ fn emit_orphan_check_error<'tcx>( tcx: TyCtxt<'tcx>, trait_ref: ty::TraitRef<'tcx>, impl_def_id: LocalDefId, - err: traits::OrphanCheckErr<'tcx, FxIndexSet>, + err: traits::OrphanCheckErr, FxIndexSet>, ) -> ErrorGuaranteed { match err { traits::OrphanCheckErr::NonLocalInputType(tys) => { @@ -482,7 +481,7 @@ fn emit_orphan_check_error<'tcx>( fn lint_uncovered_ty_params<'tcx>( tcx: TyCtxt<'tcx>, - UncoveredTyParams { uncovered, local_ty }: UncoveredTyParams<'tcx, FxIndexSet>, + UncoveredTyParams { uncovered, local_ty }: UncoveredTyParams, FxIndexSet>, impl_def_id: LocalDefId, ) { let hir_id = tcx.local_def_id_to_hir_id(impl_def_id); diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs index 44f1830a3b17b..2f6b0a582e58c 100644 --- a/compiler/rustc_hir_analysis/src/lib.rs +++ b/compiler/rustc_hir_analysis/src/lib.rs @@ -71,6 +71,7 @@ This API is completely unstable and subject to change. #![feature(rustdoc_internals)] #![feature(slice_partition_dedup)] #![feature(try_blocks)] +#![feature(unwrap_infallible)] // tidy-alphabetical-end #[macro_use] diff --git a/compiler/rustc_infer/src/infer/context.rs b/compiler/rustc_infer/src/infer/context.rs index 209996b12e2ed..f35a8162d96f1 100644 --- a/compiler/rustc_infer/src/infer/context.rs +++ b/compiler/rustc_infer/src/infer/context.rs @@ -151,6 +151,10 @@ impl<'tcx> InferCtxtLike for InferCtxt<'tcx> { .eq_structurally_relating_aliases_no_trace(lhs, rhs) } + fn shallow_resolve(&self, ty: Ty<'tcx>) -> Ty<'tcx> { + self.shallow_resolve(ty) + } + fn resolve_vars_if_possible(&self, value: T) -> T where T: TypeFoldable>, diff --git a/compiler/rustc_middle/src/ty/adt.rs b/compiler/rustc_middle/src/ty/adt.rs index 8e221cdc603ba..88ee32eae9529 100644 --- a/compiler/rustc_middle/src/ty/adt.rs +++ b/compiler/rustc_middle/src/ty/adt.rs @@ -229,6 +229,10 @@ impl<'tcx> rustc_type_ir::inherent::AdtDef> for AdtDef<'tcx> { fn sized_constraint(self, tcx: TyCtxt<'tcx>) -> Option>> { self.sized_constraint(tcx) } + + fn is_fundamental(self) -> bool { + self.is_fundamental() + } } #[derive(Copy, Clone, Debug, Eq, PartialEq, HashStable, TyEncodable, TyDecodable)] diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index dca48069974f0..dab3d3dbae452 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -524,6 +524,10 @@ impl<'tcx> Interner for TyCtxt<'tcx> { self.is_object_safe(trait_def_id) } + fn trait_is_fundamental(self, def_id: DefId) -> bool { + self.trait_def(def_id).is_fundamental + } + fn trait_may_be_implemented_via_object(self, trait_def_id: DefId) -> bool { self.trait_def(trait_def_id).implement_via_object } @@ -635,6 +639,10 @@ bidirectional_lang_item_map! { } impl<'tcx> rustc_type_ir::inherent::DefId> for DefId { + fn is_local(self) -> bool { + self.is_local() + } + fn as_local(self) -> Option { self.as_local() } diff --git a/compiler/rustc_next_trait_solver/src/coherence.rs b/compiler/rustc_next_trait_solver/src/coherence.rs new file mode 100644 index 0000000000000..55f602d907bbd --- /dev/null +++ b/compiler/rustc_next_trait_solver/src/coherence.rs @@ -0,0 +1,469 @@ +use std::fmt::Debug; +use std::ops::ControlFlow; + +use rustc_type_ir::inherent::*; +use rustc_type_ir::visit::{TypeVisitable, TypeVisitableExt, TypeVisitor}; +use rustc_type_ir::{self as ty, InferCtxtLike, Interner}; +use tracing::instrument; + +/// Whether we do the orphan check relative to this crate or to some remote crate. +#[derive(Copy, Clone, Debug)] +pub enum InCrate { + Local { mode: OrphanCheckMode }, + Remote, +} + +#[derive(Copy, Clone, Debug)] +pub enum OrphanCheckMode { + /// Proper orphan check. + Proper, + /// Improper orphan check for backward compatibility. + /// + /// In this mode, type params inside projections are considered to be covered + /// even if the projection may normalize to a type that doesn't actually cover + /// them. This is unsound. See also [#124559] and [#99554]. + /// + /// [#124559]: https://github.com/rust-lang/rust/issues/124559 + /// [#99554]: https://github.com/rust-lang/rust/issues/99554 + Compat, +} + +#[derive(Debug, Copy, Clone)] +pub enum Conflict { + Upstream, + Downstream, +} + +/// Returns whether all impls which would apply to the `trait_ref` +/// e.g. `Ty: Trait` are already known in the local crate. +/// +/// This both checks whether any downstream or sibling crates could +/// implement it and whether an upstream crate can add this impl +/// without breaking backwards compatibility. +#[instrument(level = "debug", skip(infcx, lazily_normalize_ty), ret)] +pub fn trait_ref_is_knowable( + infcx: &Infcx, + trait_ref: ty::TraitRef, + mut lazily_normalize_ty: impl FnMut(I::Ty) -> Result, +) -> Result, E> +where + Infcx: InferCtxtLike, + I: Interner, + E: Debug, +{ + if orphan_check_trait_ref(infcx, trait_ref, InCrate::Remote, &mut lazily_normalize_ty)?.is_ok() + { + // A downstream or cousin crate is allowed to implement some + // generic parameters of this trait-ref. + return Ok(Err(Conflict::Downstream)); + } + + if trait_ref_is_local_or_fundamental(infcx.cx(), trait_ref) { + // This is a local or fundamental trait, so future-compatibility + // is no concern. We know that downstream/cousin crates are not + // allowed to implement a generic parameter of this trait ref, + // which means impls could only come from dependencies of this + // crate, which we already know about. + return Ok(Ok(())); + } + + // This is a remote non-fundamental trait, so if another crate + // can be the "final owner" of the generic parameters of this trait-ref, + // they are allowed to implement it future-compatibly. + // + // However, if we are a final owner, then nobody else can be, + // and if we are an intermediate owner, then we don't care + // about future-compatibility, which means that we're OK if + // we are an owner. + if orphan_check_trait_ref( + infcx, + trait_ref, + InCrate::Local { mode: OrphanCheckMode::Proper }, + &mut lazily_normalize_ty, + )? + .is_ok() + { + Ok(Ok(())) + } else { + Ok(Err(Conflict::Upstream)) + } +} + +pub fn trait_ref_is_local_or_fundamental(tcx: I, trait_ref: ty::TraitRef) -> bool { + trait_ref.def_id.is_local() || tcx.trait_is_fundamental(trait_ref.def_id) +} + +#[derive(Debug, Copy, Clone)] +pub enum IsFirstInputType { + No, + Yes, +} + +impl From for IsFirstInputType { + fn from(b: bool) -> IsFirstInputType { + match b { + false => IsFirstInputType::No, + true => IsFirstInputType::Yes, + } + } +} + +#[derive(derivative::Derivative)] +#[derivative(Debug(bound = "T: Debug"))] +pub enum OrphanCheckErr { + NonLocalInputType(Vec<(I::Ty, IsFirstInputType)>), + UncoveredTyParams(UncoveredTyParams), +} + +#[derive(derivative::Derivative)] +#[derivative(Debug(bound = "T: Debug"))] +pub struct UncoveredTyParams { + pub uncovered: T, + pub local_ty: Option, +} + +/// Checks whether a trait-ref is potentially implementable by a crate. +/// +/// The current rule is that a trait-ref orphan checks in a crate C: +/// +/// 1. Order the parameters in the trait-ref in generic parameters order +/// - Self first, others linearly (e.g., `>` is U < V < W). +/// 2. Of these type parameters, there is at least one type parameter +/// in which, walking the type as a tree, you can reach a type local +/// to C where all types in-between are fundamental types. Call the +/// first such parameter the "local key parameter". +/// - e.g., `Box` is OK, because you can visit LocalType +/// going through `Box`, which is fundamental. +/// - similarly, `FundamentalPair, Box>` is OK for +/// the same reason. +/// - but (knowing that `Vec` is non-fundamental, and assuming it's +/// not local), `Vec` is bad, because `Vec<->` is between +/// the local type and the type parameter. +/// 3. Before this local type, no generic type parameter of the impl must +/// be reachable through fundamental types. +/// - e.g. `impl Trait for Vec` is fine, as `Vec` is not fundamental. +/// - while `impl Trait for Box` results in an error, as `T` is +/// reachable through the fundamental type `Box`. +/// 4. Every type in the local key parameter not known in C, going +/// through the parameter's type tree, must appear only as a subtree of +/// a type local to C, with only fundamental types between the type +/// local to C and the local key parameter. +/// - e.g., `Vec>>` (or equivalently `Box>>`) +/// is bad, because the only local type with `T` as a subtree is +/// `LocalType`, and `Vec<->` is between it and the type parameter. +/// - similarly, `FundamentalPair, T>` is bad, because +/// the second occurrence of `T` is not a subtree of *any* local type. +/// - however, `LocalType>` is OK, because `T` is a subtree of +/// `LocalType>`, which is local and has no types between it and +/// the type parameter. +/// +/// The orphan rules actually serve several different purposes: +/// +/// 1. They enable link-safety - i.e., 2 mutually-unknowing crates (where +/// every type local to one crate is unknown in the other) can't implement +/// the same trait-ref. This follows because it can be seen that no such +/// type can orphan-check in 2 such crates. +/// +/// To check that a local impl follows the orphan rules, we check it in +/// InCrate::Local mode, using type parameters for the "generic" types. +/// +/// In InCrate::Local mode the orphan check succeeds if the current crate +/// is definitely allowed to implement the given trait (no false positives). +/// +/// 2. They ground negative reasoning for coherence. If a user wants to +/// write both a conditional blanket impl and a specific impl, we need to +/// make sure they do not overlap. For example, if we write +/// ```ignore (illustrative) +/// impl IntoIterator for Vec +/// impl IntoIterator for T +/// ``` +/// We need to be able to prove that `Vec<$0>: !Iterator` for every type $0. +/// We can observe that this holds in the current crate, but we need to make +/// sure this will also hold in all unknown crates (both "independent" crates, +/// which we need for link-safety, and also child crates, because we don't want +/// child crates to get error for impl conflicts in a *dependency*). +/// +/// For that, we only allow negative reasoning if, for every assignment to the +/// inference variables, every unknown crate would get an orphan error if they +/// try to implement this trait-ref. To check for this, we use InCrate::Remote +/// mode. That is sound because we already know all the impls from known crates. +/// +/// In InCrate::Remote mode the orphan check succeeds if a foreign crate +/// *could* implement the given trait (no false negatives). +/// +/// 3. For non-`#[fundamental]` traits, they guarantee that parent crates can +/// add "non-blanket" impls without breaking negative reasoning in dependent +/// crates. This is the "rebalancing coherence" (RFC 1023) restriction. +/// +/// For that, we only allow a crate to perform negative reasoning on +/// non-local-non-`#[fundamental]` if there's a local key parameter as per (2). +/// +/// Because we never perform negative reasoning generically (coherence does +/// not involve type parameters), this can be interpreted as doing the full +/// orphan check (using InCrate::Local mode), instantiating non-local known +/// types for all inference variables. +/// +/// This allows for crates to future-compatibly add impls as long as they +/// can't apply to types with a key parameter in a child crate - applying +/// the rules, this basically means that every type parameter in the impl +/// must appear behind a non-fundamental type (because this is not a +/// type-system requirement, crate owners might also go for "semantic +/// future-compatibility" involving things such as sealed traits, but +/// the above requirement is sufficient, and is necessary in "open world" +/// cases). +/// +/// Note that this function is never called for types that have both type +/// parameters and inference variables. +#[instrument(level = "trace", skip(infcx, lazily_normalize_ty), ret)] +pub fn orphan_check_trait_ref( + infcx: &Infcx, + trait_ref: ty::TraitRef, + in_crate: InCrate, + lazily_normalize_ty: impl FnMut(I::Ty) -> Result, +) -> Result>, E> +where + Infcx: InferCtxtLike, + I: Interner, + E: Debug, +{ + if trait_ref.has_param() { + panic!("orphan check only expects inference variables: {trait_ref:?}"); + } + + let mut checker = OrphanChecker::new(infcx, in_crate, lazily_normalize_ty); + Ok(match trait_ref.visit_with(&mut checker) { + ControlFlow::Continue(()) => Err(OrphanCheckErr::NonLocalInputType(checker.non_local_tys)), + ControlFlow::Break(residual) => match residual { + OrphanCheckEarlyExit::NormalizationFailure(err) => return Err(err), + OrphanCheckEarlyExit::UncoveredTyParam(ty) => { + // Does there exist some local type after the `ParamTy`. + checker.search_first_local_ty = true; + let local_ty = match trait_ref.visit_with(&mut checker) { + ControlFlow::Break(OrphanCheckEarlyExit::LocalTy(local_ty)) => Some(local_ty), + _ => None, + }; + Err(OrphanCheckErr::UncoveredTyParams(UncoveredTyParams { + uncovered: ty, + local_ty, + })) + } + OrphanCheckEarlyExit::LocalTy(_) => Ok(()), + }, + }) +} + +struct OrphanChecker<'a, Infcx, I: Interner, F> { + infcx: &'a Infcx, + in_crate: InCrate, + in_self_ty: bool, + lazily_normalize_ty: F, + /// Ignore orphan check failures and exclusively search for the first local type. + search_first_local_ty: bool, + non_local_tys: Vec<(I::Ty, IsFirstInputType)>, +} + +impl<'a, Infcx, I, F, E> OrphanChecker<'a, Infcx, I, F> +where + Infcx: InferCtxtLike, + I: Interner, + F: FnOnce(I::Ty) -> Result, +{ + fn new(infcx: &'a Infcx, in_crate: InCrate, lazily_normalize_ty: F) -> Self { + OrphanChecker { + infcx, + in_crate, + in_self_ty: true, + lazily_normalize_ty, + search_first_local_ty: false, + non_local_tys: Vec::new(), + } + } + + fn found_non_local_ty(&mut self, t: I::Ty) -> ControlFlow> { + self.non_local_tys.push((t, self.in_self_ty.into())); + ControlFlow::Continue(()) + } + + fn found_uncovered_ty_param(&mut self, ty: I::Ty) -> ControlFlow> { + if self.search_first_local_ty { + return ControlFlow::Continue(()); + } + + ControlFlow::Break(OrphanCheckEarlyExit::UncoveredTyParam(ty)) + } + + fn def_id_is_local(&mut self, def_id: I::DefId) -> bool { + match self.in_crate { + InCrate::Local { .. } => def_id.is_local(), + InCrate::Remote => false, + } + } +} + +enum OrphanCheckEarlyExit { + NormalizationFailure(E), + UncoveredTyParam(I::Ty), + LocalTy(I::Ty), +} + +impl<'a, Infcx, I, F, E> TypeVisitor for OrphanChecker<'a, Infcx, I, F> +where + Infcx: InferCtxtLike, + I: Interner, + F: FnMut(I::Ty) -> Result, +{ + type Result = ControlFlow>; + + fn visit_region(&mut self, _r: I::Region) -> Self::Result { + ControlFlow::Continue(()) + } + + fn visit_ty(&mut self, ty: I::Ty) -> Self::Result { + let ty = self.infcx.shallow_resolve(ty); + let ty = match (self.lazily_normalize_ty)(ty) { + Ok(norm_ty) if norm_ty.is_ty_var() => ty, + Ok(norm_ty) => norm_ty, + Err(err) => return ControlFlow::Break(OrphanCheckEarlyExit::NormalizationFailure(err)), + }; + + let result = match ty.kind() { + ty::Bool + | ty::Char + | ty::Int(..) + | ty::Uint(..) + | ty::Float(..) + | ty::Str + | ty::FnDef(..) + | ty::Pat(..) + | ty::FnPtr(_) + | ty::Array(..) + | ty::Slice(..) + | ty::RawPtr(..) + | ty::Never + | ty::Tuple(..) => self.found_non_local_ty(ty), + + ty::Param(..) => panic!("unexpected ty param"), + + ty::Placeholder(..) | ty::Bound(..) | ty::Infer(..) => { + match self.in_crate { + InCrate::Local { .. } => self.found_uncovered_ty_param(ty), + // The inference variable might be unified with a local + // type in that remote crate. + InCrate::Remote => ControlFlow::Break(OrphanCheckEarlyExit::LocalTy(ty)), + } + } + + // A rigid alias may normalize to anything. + // * If it references an infer var, placeholder or bound ty, it may + // normalize to that, so we have to treat it as an uncovered ty param. + // * Otherwise it may normalize to any non-type-generic type + // be it local or non-local. + ty::Alias(kind, _) => { + if ty.has_type_flags( + ty::TypeFlags::HAS_TY_PLACEHOLDER + | ty::TypeFlags::HAS_TY_BOUND + | ty::TypeFlags::HAS_TY_INFER, + ) { + match self.in_crate { + InCrate::Local { mode } => match kind { + ty::Projection => { + if let OrphanCheckMode::Compat = mode { + ControlFlow::Continue(()) + } else { + self.found_uncovered_ty_param(ty) + } + } + _ => self.found_uncovered_ty_param(ty), + }, + InCrate::Remote => { + // The inference variable might be unified with a local + // type in that remote crate. + ControlFlow::Break(OrphanCheckEarlyExit::LocalTy(ty)) + } + } + } else { + // Regarding *opaque types* specifically, we choose to treat them as non-local, + // even those that appear within the same crate. This seems somewhat surprising + // at first, but makes sense when you consider that opaque types are supposed + // to hide the underlying type *within the same crate*. When an opaque type is + // used from outside the module where it is declared, it should be impossible to + // observe anything about it other than the traits that it implements. + // + // The alternative would be to look at the underlying type to determine whether + // or not the opaque type itself should be considered local. + // + // However, this could make it a breaking change to switch the underlying hidden + // type from a local type to a remote type. This would violate the rule that + // opaque types should be completely opaque apart from the traits that they + // implement, so we don't use this behavior. + // Addendum: Moreover, revealing the underlying type is likely to cause cycle + // errors as we rely on coherence / the specialization graph during typeck. + + self.found_non_local_ty(ty) + } + } + + // For fundamental types, we just look inside of them. + ty::Ref(_, ty, _) => ty.visit_with(self), + ty::Adt(def, args) => { + if self.def_id_is_local(def.def_id()) { + ControlFlow::Break(OrphanCheckEarlyExit::LocalTy(ty)) + } else if def.is_fundamental() { + args.visit_with(self) + } else { + self.found_non_local_ty(ty) + } + } + ty::Foreign(def_id) => { + if self.def_id_is_local(def_id) { + ControlFlow::Break(OrphanCheckEarlyExit::LocalTy(ty)) + } else { + self.found_non_local_ty(ty) + } + } + ty::Dynamic(tt, ..) => { + let principal = tt.principal().map(|p| p.def_id()); + if principal.is_some_and(|p| self.def_id_is_local(p)) { + ControlFlow::Break(OrphanCheckEarlyExit::LocalTy(ty)) + } else { + self.found_non_local_ty(ty) + } + } + ty::Error(_) => ControlFlow::Break(OrphanCheckEarlyExit::LocalTy(ty)), + ty::Closure(did, ..) | ty::CoroutineClosure(did, ..) | ty::Coroutine(did, ..) => { + if self.def_id_is_local(did) { + ControlFlow::Break(OrphanCheckEarlyExit::LocalTy(ty)) + } else { + self.found_non_local_ty(ty) + } + } + // This should only be created when checking whether we have to check whether some + // auto trait impl applies. There will never be multiple impls, so we can just + // act as if it were a local type here. + ty::CoroutineWitness(..) => ControlFlow::Break(OrphanCheckEarlyExit::LocalTy(ty)), + }; + // A bit of a hack, the `OrphanChecker` is only used to visit a `TraitRef`, so + // the first type we visit is always the self type. + self.in_self_ty = false; + result + } + + /// All possible values for a constant parameter already exist + /// in the crate defining the trait, so they are always non-local[^1]. + /// + /// Because there's no way to have an impl where the first local + /// generic argument is a constant, we also don't have to fail + /// the orphan check when encountering a parameter or a generic constant. + /// + /// This means that we can completely ignore constants during the orphan check. + /// + /// See `tests/ui/coherence/const-generics-orphan-check-ok.rs` for examples. + /// + /// [^1]: This might not hold for function pointers or trait objects in the future. + /// As these should be quite rare as const arguments and especially rare as impl + /// parameters, allowing uncovered const parameters in impls seems more useful + /// than allowing `impl Trait for i32` to compile. + fn visit_const(&mut self, _c: I::Const) -> Self::Result { + ControlFlow::Continue(()) + } +} diff --git a/compiler/rustc_next_trait_solver/src/lib.rs b/compiler/rustc_next_trait_solver/src/lib.rs index 761475d3d6b08..0a5b427805865 100644 --- a/compiler/rustc_next_trait_solver/src/lib.rs +++ b/compiler/rustc_next_trait_solver/src/lib.rs @@ -5,6 +5,7 @@ //! So if you got to this crate from the old solver, it's totally normal. pub mod canonicalizer; +pub mod coherence; pub mod delegate; pub mod relate; pub mod resolve; diff --git a/compiler/rustc_trait_selection/src/lib.rs b/compiler/rustc_trait_selection/src/lib.rs index 50c618bb3bde5..37008baca2899 100644 --- a/compiler/rustc_trait_selection/src/lib.rs +++ b/compiler/rustc_trait_selection/src/lib.rs @@ -26,6 +26,7 @@ #![feature(never_type)] #![feature(rustdoc_internals)] #![feature(type_alias_impl_trait)] +#![feature(unwrap_infallible)] #![recursion_limit = "512"] // For rustdoc // tidy-alphabetical-end diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs index 57ba6c33ac5a5..fc390bf318dc1 100644 --- a/compiler/rustc_trait_selection/src/traits/coherence.rs +++ b/compiler/rustc_trait_selection/src/traits/coherence.rs @@ -25,42 +25,14 @@ use rustc_middle::traits::specialization_graph::OverlapMode; use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams}; use rustc_middle::ty::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor}; use rustc_middle::ty::{self, Ty, TyCtxt}; +pub use rustc_next_trait_solver::coherence::*; use rustc_span::symbol::sym; use rustc_span::{Span, DUMMY_SP}; use std::fmt::Debug; -use std::ops::ControlFlow; use super::error_reporting::suggest_new_overflow_limit; use super::ObligationCtxt; -/// Whether we do the orphan check relative to this crate or to some remote crate. -#[derive(Copy, Clone, Debug)] -pub enum InCrate { - Local { mode: OrphanCheckMode }, - Remote, -} - -#[derive(Copy, Clone, Debug)] -pub enum OrphanCheckMode { - /// Proper orphan check. - Proper, - /// Improper orphan check for backward compatibility. - /// - /// In this mode, type params inside projections are considered to be covered - /// even if the projection may normalize to a type that doesn't actually cover - /// them. This is unsound. See also [#124559] and [#99554]. - /// - /// [#124559]: https://github.com/rust-lang/rust/issues/124559 - /// [#99554]: https://github.com/rust-lang/rust/issues/99554 - Compat, -} - -#[derive(Debug, Copy, Clone)] -pub enum Conflict { - Upstream, - Downstream, -} - pub struct OverlapResult<'tcx> { pub impl_header: ty::ImplHeader<'tcx>, pub intercrate_ambiguity_causes: FxIndexSet>, @@ -612,426 +584,6 @@ fn try_prove_negated_where_clause<'tcx>( true } -/// Returns whether all impls which would apply to the `trait_ref` -/// e.g. `Ty: Trait` are already known in the local crate. -/// -/// This both checks whether any downstream or sibling crates could -/// implement it and whether an upstream crate can add this impl -/// without breaking backwards compatibility. -#[instrument(level = "debug", skip(infcx, lazily_normalize_ty), ret)] -pub fn trait_ref_is_knowable<'tcx, E: Debug>( - infcx: &InferCtxt<'tcx>, - trait_ref: ty::TraitRef<'tcx>, - mut lazily_normalize_ty: impl FnMut(Ty<'tcx>) -> Result, E>, -) -> Result, E> { - if orphan_check_trait_ref(infcx, trait_ref, InCrate::Remote, &mut lazily_normalize_ty)?.is_ok() - { - // A downstream or cousin crate is allowed to implement some - // generic parameters of this trait-ref. - return Ok(Err(Conflict::Downstream)); - } - - if trait_ref_is_local_or_fundamental(infcx.tcx, trait_ref) { - // This is a local or fundamental trait, so future-compatibility - // is no concern. We know that downstream/cousin crates are not - // allowed to implement a generic parameter of this trait ref, - // which means impls could only come from dependencies of this - // crate, which we already know about. - return Ok(Ok(())); - } - - // This is a remote non-fundamental trait, so if another crate - // can be the "final owner" of the generic parameters of this trait-ref, - // they are allowed to implement it future-compatibly. - // - // However, if we are a final owner, then nobody else can be, - // and if we are an intermediate owner, then we don't care - // about future-compatibility, which means that we're OK if - // we are an owner. - if orphan_check_trait_ref( - infcx, - trait_ref, - InCrate::Local { mode: OrphanCheckMode::Proper }, - &mut lazily_normalize_ty, - )? - .is_ok() - { - Ok(Ok(())) - } else { - Ok(Err(Conflict::Upstream)) - } -} - -pub fn trait_ref_is_local_or_fundamental<'tcx>( - tcx: TyCtxt<'tcx>, - trait_ref: ty::TraitRef<'tcx>, -) -> bool { - trait_ref.def_id.is_local() || tcx.trait_def(trait_ref.def_id).is_fundamental -} - -#[derive(Debug, Copy, Clone)] -pub enum IsFirstInputType { - No, - Yes, -} - -impl From for IsFirstInputType { - fn from(b: bool) -> IsFirstInputType { - match b { - false => IsFirstInputType::No, - true => IsFirstInputType::Yes, - } - } -} - -#[derive(Debug)] -pub enum OrphanCheckErr<'tcx, T> { - NonLocalInputType(Vec<(Ty<'tcx>, IsFirstInputType)>), - UncoveredTyParams(UncoveredTyParams<'tcx, T>), -} - -#[derive(Debug)] -pub struct UncoveredTyParams<'tcx, T> { - pub uncovered: T, - pub local_ty: Option>, -} - -/// Checks whether a trait-ref is potentially implementable by a crate. -/// -/// The current rule is that a trait-ref orphan checks in a crate C: -/// -/// 1. Order the parameters in the trait-ref in generic parameters order -/// - Self first, others linearly (e.g., `>` is U < V < W). -/// 2. Of these type parameters, there is at least one type parameter -/// in which, walking the type as a tree, you can reach a type local -/// to C where all types in-between are fundamental types. Call the -/// first such parameter the "local key parameter". -/// - e.g., `Box` is OK, because you can visit LocalType -/// going through `Box`, which is fundamental. -/// - similarly, `FundamentalPair, Box>` is OK for -/// the same reason. -/// - but (knowing that `Vec` is non-fundamental, and assuming it's -/// not local), `Vec` is bad, because `Vec<->` is between -/// the local type and the type parameter. -/// 3. Before this local type, no generic type parameter of the impl must -/// be reachable through fundamental types. -/// - e.g. `impl Trait for Vec` is fine, as `Vec` is not fundamental. -/// - while `impl Trait for Box` results in an error, as `T` is -/// reachable through the fundamental type `Box`. -/// 4. Every type in the local key parameter not known in C, going -/// through the parameter's type tree, must appear only as a subtree of -/// a type local to C, with only fundamental types between the type -/// local to C and the local key parameter. -/// - e.g., `Vec>>` (or equivalently `Box>>`) -/// is bad, because the only local type with `T` as a subtree is -/// `LocalType`, and `Vec<->` is between it and the type parameter. -/// - similarly, `FundamentalPair, T>` is bad, because -/// the second occurrence of `T` is not a subtree of *any* local type. -/// - however, `LocalType>` is OK, because `T` is a subtree of -/// `LocalType>`, which is local and has no types between it and -/// the type parameter. -/// -/// The orphan rules actually serve several different purposes: -/// -/// 1. They enable link-safety - i.e., 2 mutually-unknowing crates (where -/// every type local to one crate is unknown in the other) can't implement -/// the same trait-ref. This follows because it can be seen that no such -/// type can orphan-check in 2 such crates. -/// -/// To check that a local impl follows the orphan rules, we check it in -/// InCrate::Local mode, using type parameters for the "generic" types. -/// -/// In InCrate::Local mode the orphan check succeeds if the current crate -/// is definitely allowed to implement the given trait (no false positives). -/// -/// 2. They ground negative reasoning for coherence. If a user wants to -/// write both a conditional blanket impl and a specific impl, we need to -/// make sure they do not overlap. For example, if we write -/// ```ignore (illustrative) -/// impl IntoIterator for Vec -/// impl IntoIterator for T -/// ``` -/// We need to be able to prove that `Vec<$0>: !Iterator` for every type $0. -/// We can observe that this holds in the current crate, but we need to make -/// sure this will also hold in all unknown crates (both "independent" crates, -/// which we need for link-safety, and also child crates, because we don't want -/// child crates to get error for impl conflicts in a *dependency*). -/// -/// For that, we only allow negative reasoning if, for every assignment to the -/// inference variables, every unknown crate would get an orphan error if they -/// try to implement this trait-ref. To check for this, we use InCrate::Remote -/// mode. That is sound because we already know all the impls from known crates. -/// -/// In InCrate::Remote mode the orphan check succeeds if a foreign crate -/// *could* implement the given trait (no false negatives). -/// -/// 3. For non-`#[fundamental]` traits, they guarantee that parent crates can -/// add "non-blanket" impls without breaking negative reasoning in dependent -/// crates. This is the "rebalancing coherence" (RFC 1023) restriction. -/// -/// For that, we only allow a crate to perform negative reasoning on -/// non-local-non-`#[fundamental]` if there's a local key parameter as per (2). -/// -/// Because we never perform negative reasoning generically (coherence does -/// not involve type parameters), this can be interpreted as doing the full -/// orphan check (using InCrate::Local mode), instantiating non-local known -/// types for all inference variables. -/// -/// This allows for crates to future-compatibly add impls as long as they -/// can't apply to types with a key parameter in a child crate - applying -/// the rules, this basically means that every type parameter in the impl -/// must appear behind a non-fundamental type (because this is not a -/// type-system requirement, crate owners might also go for "semantic -/// future-compatibility" involving things such as sealed traits, but -/// the above requirement is sufficient, and is necessary in "open world" -/// cases). -/// -/// Note that this function is never called for types that have both type -/// parameters and inference variables. -#[instrument(level = "trace", skip(infcx, lazily_normalize_ty), ret)] -pub fn orphan_check_trait_ref<'tcx, E: Debug>( - infcx: &InferCtxt<'tcx>, - trait_ref: ty::TraitRef<'tcx>, - in_crate: InCrate, - lazily_normalize_ty: impl FnMut(Ty<'tcx>) -> Result, E>, -) -> Result>>, E> { - if trait_ref.has_param() { - bug!("orphan check only expects inference variables: {trait_ref:?}"); - } - - let mut checker = OrphanChecker::new(infcx, in_crate, lazily_normalize_ty); - Ok(match trait_ref.visit_with(&mut checker) { - ControlFlow::Continue(()) => Err(OrphanCheckErr::NonLocalInputType(checker.non_local_tys)), - ControlFlow::Break(residual) => match residual { - OrphanCheckEarlyExit::NormalizationFailure(err) => return Err(err), - OrphanCheckEarlyExit::UncoveredTyParam(ty) => { - // Does there exist some local type after the `ParamTy`. - checker.search_first_local_ty = true; - let local_ty = match trait_ref.visit_with(&mut checker).break_value() { - Some(OrphanCheckEarlyExit::LocalTy(local_ty)) => Some(local_ty), - _ => None, - }; - Err(OrphanCheckErr::UncoveredTyParams(UncoveredTyParams { - uncovered: ty, - local_ty, - })) - } - OrphanCheckEarlyExit::LocalTy(_) => Ok(()), - }, - }) -} - -struct OrphanChecker<'a, 'tcx, F> { - infcx: &'a InferCtxt<'tcx>, - in_crate: InCrate, - in_self_ty: bool, - lazily_normalize_ty: F, - /// Ignore orphan check failures and exclusively search for the first local type. - search_first_local_ty: bool, - non_local_tys: Vec<(Ty<'tcx>, IsFirstInputType)>, -} - -impl<'a, 'tcx, F, E> OrphanChecker<'a, 'tcx, F> -where - F: FnOnce(Ty<'tcx>) -> Result, E>, -{ - fn new(infcx: &'a InferCtxt<'tcx>, in_crate: InCrate, lazily_normalize_ty: F) -> Self { - OrphanChecker { - infcx, - in_crate, - in_self_ty: true, - lazily_normalize_ty, - search_first_local_ty: false, - non_local_tys: Vec::new(), - } - } - - fn found_non_local_ty(&mut self, t: Ty<'tcx>) -> ControlFlow> { - self.non_local_tys.push((t, self.in_self_ty.into())); - ControlFlow::Continue(()) - } - - fn found_uncovered_ty_param( - &mut self, - ty: Ty<'tcx>, - ) -> ControlFlow> { - if self.search_first_local_ty { - return ControlFlow::Continue(()); - } - - ControlFlow::Break(OrphanCheckEarlyExit::UncoveredTyParam(ty)) - } - - fn def_id_is_local(&mut self, def_id: DefId) -> bool { - match self.in_crate { - InCrate::Local { .. } => def_id.is_local(), - InCrate::Remote => false, - } - } -} - -enum OrphanCheckEarlyExit<'tcx, E> { - NormalizationFailure(E), - UncoveredTyParam(Ty<'tcx>), - LocalTy(Ty<'tcx>), -} - -impl<'a, 'tcx, F, E> TypeVisitor> for OrphanChecker<'a, 'tcx, F> -where - F: FnMut(Ty<'tcx>) -> Result, E>, -{ - type Result = ControlFlow>; - - fn visit_region(&mut self, _r: ty::Region<'tcx>) -> Self::Result { - ControlFlow::Continue(()) - } - - fn visit_ty(&mut self, ty: Ty<'tcx>) -> Self::Result { - let ty = self.infcx.shallow_resolve(ty); - let ty = match (self.lazily_normalize_ty)(ty) { - Ok(norm_ty) if norm_ty.is_ty_var() => ty, - Ok(norm_ty) => norm_ty, - Err(err) => return ControlFlow::Break(OrphanCheckEarlyExit::NormalizationFailure(err)), - }; - - let result = match *ty.kind() { - ty::Bool - | ty::Char - | ty::Int(..) - | ty::Uint(..) - | ty::Float(..) - | ty::Str - | ty::FnDef(..) - | ty::Pat(..) - | ty::FnPtr(_) - | ty::Array(..) - | ty::Slice(..) - | ty::RawPtr(..) - | ty::Never - | ty::Tuple(..) => self.found_non_local_ty(ty), - - ty::Param(..) => bug!("unexpected ty param"), - - ty::Placeholder(..) | ty::Bound(..) | ty::Infer(..) => { - match self.in_crate { - InCrate::Local { .. } => self.found_uncovered_ty_param(ty), - // The inference variable might be unified with a local - // type in that remote crate. - InCrate::Remote => ControlFlow::Break(OrphanCheckEarlyExit::LocalTy(ty)), - } - } - - // A rigid alias may normalize to anything. - // * If it references an infer var, placeholder or bound ty, it may - // normalize to that, so we have to treat it as an uncovered ty param. - // * Otherwise it may normalize to any non-type-generic type - // be it local or non-local. - ty::Alias(kind, _) => { - if ty.has_type_flags( - ty::TypeFlags::HAS_TY_PLACEHOLDER - | ty::TypeFlags::HAS_TY_BOUND - | ty::TypeFlags::HAS_TY_INFER, - ) { - match self.in_crate { - InCrate::Local { mode } => match kind { - ty::Projection if let OrphanCheckMode::Compat = mode => { - ControlFlow::Continue(()) - } - _ => self.found_uncovered_ty_param(ty), - }, - InCrate::Remote => { - // The inference variable might be unified with a local - // type in that remote crate. - ControlFlow::Break(OrphanCheckEarlyExit::LocalTy(ty)) - } - } - } else { - // Regarding *opaque types* specifically, we choose to treat them as non-local, - // even those that appear within the same crate. This seems somewhat surprising - // at first, but makes sense when you consider that opaque types are supposed - // to hide the underlying type *within the same crate*. When an opaque type is - // used from outside the module where it is declared, it should be impossible to - // observe anything about it other than the traits that it implements. - // - // The alternative would be to look at the underlying type to determine whether - // or not the opaque type itself should be considered local. - // - // However, this could make it a breaking change to switch the underlying hidden - // type from a local type to a remote type. This would violate the rule that - // opaque types should be completely opaque apart from the traits that they - // implement, so we don't use this behavior. - // Addendum: Moreover, revealing the underlying type is likely to cause cycle - // errors as we rely on coherence / the specialization graph during typeck. - - self.found_non_local_ty(ty) - } - } - - // For fundamental types, we just look inside of them. - ty::Ref(_, ty, _) => ty.visit_with(self), - ty::Adt(def, args) => { - if self.def_id_is_local(def.did()) { - ControlFlow::Break(OrphanCheckEarlyExit::LocalTy(ty)) - } else if def.is_fundamental() { - args.visit_with(self) - } else { - self.found_non_local_ty(ty) - } - } - ty::Foreign(def_id) => { - if self.def_id_is_local(def_id) { - ControlFlow::Break(OrphanCheckEarlyExit::LocalTy(ty)) - } else { - self.found_non_local_ty(ty) - } - } - ty::Dynamic(tt, ..) => { - let principal = tt.principal().map(|p| p.def_id()); - if principal.is_some_and(|p| self.def_id_is_local(p)) { - ControlFlow::Break(OrphanCheckEarlyExit::LocalTy(ty)) - } else { - self.found_non_local_ty(ty) - } - } - ty::Error(_) => ControlFlow::Break(OrphanCheckEarlyExit::LocalTy(ty)), - ty::Closure(did, ..) | ty::CoroutineClosure(did, ..) | ty::Coroutine(did, ..) => { - if self.def_id_is_local(did) { - ControlFlow::Break(OrphanCheckEarlyExit::LocalTy(ty)) - } else { - self.found_non_local_ty(ty) - } - } - // This should only be created when checking whether we have to check whether some - // auto trait impl applies. There will never be multiple impls, so we can just - // act as if it were a local type here. - ty::CoroutineWitness(..) => ControlFlow::Break(OrphanCheckEarlyExit::LocalTy(ty)), - }; - // A bit of a hack, the `OrphanChecker` is only used to visit a `TraitRef`, so - // the first type we visit is always the self type. - self.in_self_ty = false; - result - } - - /// All possible values for a constant parameter already exist - /// in the crate defining the trait, so they are always non-local[^1]. - /// - /// Because there's no way to have an impl where the first local - /// generic argument is a constant, we also don't have to fail - /// the orphan check when encountering a parameter or a generic constant. - /// - /// This means that we can completely ignore constants during the orphan check. - /// - /// See `tests/ui/coherence/const-generics-orphan-check-ok.rs` for examples. - /// - /// [^1]: This might not hold for function pointers or trait objects in the future. - /// As these should be quite rare as const arguments and especially rare as impl - /// parameters, allowing uncovered const parameters in impls seems more useful - /// than allowing `impl Trait for i32` to compile. - fn visit_const(&mut self, _c: ty::Const<'tcx>) -> Self::Result { - ControlFlow::Continue(()) - } -} - /// Compute the `intercrate_ambiguity_causes` for the new solver using /// "proof trees". /// diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 68cc04bc8e63d..460c4c3cbb3cb 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -1523,7 +1523,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // bound regions. let trait_ref = predicate.skip_binder().trait_ref; - coherence::trait_ref_is_knowable::(self.infcx, trait_ref, |ty| Ok(ty)).unwrap() + coherence::trait_ref_is_knowable(self.infcx, trait_ref, |ty| Ok::<_, !>(ty)).into_ok() } /// Returns `true` if the global caches can be used. diff --git a/compiler/rustc_type_ir/src/infer_ctxt.rs b/compiler/rustc_type_ir/src/infer_ctxt.rs index 2c80ee0a73d4a..a1070d985ab97 100644 --- a/compiler/rustc_type_ir/src/infer_ctxt.rs +++ b/compiler/rustc_type_ir/src/infer_ctxt.rs @@ -73,6 +73,11 @@ pub trait InferCtxtLike { rhs: T, ) -> Result::Predicate>>, NoSolution>; + fn shallow_resolve( + &self, + ty: ::Ty, + ) -> ::Ty; + fn resolve_vars_if_possible(&self, value: T) -> T where T: TypeFoldable; diff --git a/compiler/rustc_type_ir/src/inherent.rs b/compiler/rustc_type_ir/src/inherent.rs index 68c2575258d2f..97414473737f4 100644 --- a/compiler/rustc_type_ir/src/inherent.rs +++ b/compiler/rustc_type_ir/src/inherent.rs @@ -514,6 +514,8 @@ pub trait AdtDef: Copy + Debug + Hash + Eq { fn all_field_tys(self, interner: I) -> ty::EarlyBinder>; fn sized_constraint(self, interner: I) -> Option>; + + fn is_fundamental(self) -> bool; } pub trait ParamEnv: Copy + Debug + Hash + Eq + TypeFoldable { @@ -558,6 +560,8 @@ pub trait EvaluationCache { } pub trait DefId: Copy + Debug + Hash + Eq + TypeFoldable { + fn is_local(self) -> bool; + fn as_local(self) -> Option; } diff --git a/compiler/rustc_type_ir/src/interner.rs b/compiler/rustc_type_ir/src/interner.rs index 6e013768c3ea8..8386c30716e06 100644 --- a/compiler/rustc_type_ir/src/interner.rs +++ b/compiler/rustc_type_ir/src/interner.rs @@ -246,6 +246,8 @@ pub trait Interner: fn trait_is_object_safe(self, trait_def_id: Self::DefId) -> bool; + fn trait_is_fundamental(self, def_id: Self::DefId) -> bool; + fn trait_may_be_implemented_via_object(self, trait_def_id: Self::DefId) -> bool; fn supertrait_def_ids(self, trait_def_id: Self::DefId) From ab27c2fa771f589f333eb798b892c506e1f436fa Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sat, 6 Jul 2024 18:32:06 -0400 Subject: [PATCH 800/892] Get rid of trait_ref_is_knowable from delegate --- compiler/rustc_next_trait_solver/src/delegate.rs | 9 --------- .../rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs | 4 +++- compiler/rustc_trait_selection/src/solve/delegate.rs | 10 ---------- compiler/rustc_type_ir/src/infer_ctxt.rs | 2 +- 4 files changed, 4 insertions(+), 21 deletions(-) diff --git a/compiler/rustc_next_trait_solver/src/delegate.rs b/compiler/rustc_next_trait_solver/src/delegate.rs index 31032dc679ac3..21c976dec5276 100644 --- a/compiler/rustc_next_trait_solver/src/delegate.rs +++ b/compiler/rustc_next_trait_solver/src/delegate.rs @@ -1,4 +1,3 @@ -use std::fmt::Debug; use std::ops::Deref; use rustc_type_ir::fold::TypeFoldable; @@ -99,14 +98,6 @@ pub trait SolverDelegate: fn reset_opaque_types(&self); - fn trait_ref_is_knowable( - &self, - trait_ref: ty::TraitRef, - lazily_normalize_ty: impl FnMut( - ::Ty, - ) -> Result<::Ty, E>, - ) -> Result; - fn fetch_eligible_assoc_item( &self, param_env: ::ParamEnv, diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs index d8a3acc655a45..c90f8e761633b 100644 --- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs @@ -11,6 +11,7 @@ use rustc_type_ir::{self as ty, CanonicalVarValues, InferCtxtLike, Interner}; use rustc_type_ir_macros::{Lift_Generic, TypeFoldable_Generic, TypeVisitable_Generic}; use tracing::{instrument, trace}; +use crate::coherence; use crate::delegate::SolverDelegate; use crate::solve::inspect::{self, ProofTreeBuilder}; use crate::solve::search_graph::SearchGraph; @@ -906,7 +907,8 @@ where ) -> Result { let delegate = self.delegate; let lazily_normalize_ty = |ty| self.structurally_normalize_ty(param_env, ty); - delegate.trait_ref_is_knowable(trait_ref, lazily_normalize_ty) + coherence::trait_ref_is_knowable(&**delegate, trait_ref, lazily_normalize_ty) + .map(|is_knowable| is_knowable.is_ok()) } pub(super) fn fetch_eligible_assoc_item( diff --git a/compiler/rustc_trait_selection/src/solve/delegate.rs b/compiler/rustc_trait_selection/src/solve/delegate.rs index f98744e906f05..5fad7129c6427 100644 --- a/compiler/rustc_trait_selection/src/solve/delegate.rs +++ b/compiler/rustc_trait_selection/src/solve/delegate.rs @@ -15,7 +15,6 @@ use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt as _}; use rustc_span::{ErrorGuaranteed, Span, DUMMY_SP}; use rustc_type_ir::solve::{Certainty, NoSolution, SolverMode}; -use crate::traits::coherence::trait_ref_is_knowable; use crate::traits::specialization_graph; #[repr(transparent)] @@ -200,15 +199,6 @@ impl<'tcx> rustc_next_trait_solver::delegate::SolverDelegate for SolverDelegate< let _ = self.take_opaque_types(); } - fn trait_ref_is_knowable( - &self, - trait_ref: ty::TraitRef<'tcx>, - lazily_normalize_ty: impl FnMut(Ty<'tcx>) -> Result, E>, - ) -> Result { - trait_ref_is_knowable(&self.0, trait_ref, lazily_normalize_ty) - .map(|is_knowable| is_knowable.is_ok()) - } - fn fetch_eligible_assoc_item( &self, param_env: ty::ParamEnv<'tcx>, diff --git a/compiler/rustc_type_ir/src/infer_ctxt.rs b/compiler/rustc_type_ir/src/infer_ctxt.rs index a1070d985ab97..1d0b2345b805f 100644 --- a/compiler/rustc_type_ir/src/infer_ctxt.rs +++ b/compiler/rustc_type_ir/src/infer_ctxt.rs @@ -3,7 +3,7 @@ use crate::relate::Relate; use crate::solve::{Goal, NoSolution, SolverMode}; use crate::{self as ty, Interner}; -pub trait InferCtxtLike { +pub trait InferCtxtLike: Sized { type Interner: Interner; fn cx(&self) -> Self::Interner; From 484152d562f6babaacb3fae08cc5f70ee550e9ee Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Thu, 15 Feb 2024 19:54:37 +0000 Subject: [PATCH 801/892] Support tail calls in mir via `TerminatorKind::TailCall` --- compiler/rustc_borrowck/src/lib.rs | 9 ++- .../src/polonius/loan_invalidations.rs | 6 ++ compiler/rustc_borrowck/src/type_check/mod.rs | 20 ++++- compiler/rustc_codegen_cranelift/src/base.rs | 5 ++ .../rustc_codegen_cranelift/src/constant.rs | 1 + compiler/rustc_codegen_ssa/src/mir/analyze.rs | 1 + compiler/rustc_codegen_ssa/src/mir/block.rs | 7 ++ .../src/check_consts/check.rs | 15 +++- .../src/check_consts/post_drop_elaboration.rs | 1 + .../src/interpret/terminator.rs | 2 + compiler/rustc_middle/src/mir/pretty.rs | 17 +++- compiler/rustc_middle/src/mir/syntax.rs | 31 ++++++++ compiler/rustc_middle/src/mir/terminator.rs | 13 +++- compiler/rustc_middle/src/mir/visit.rs | 11 +++ .../rustc_mir_build/src/build/expr/stmt.rs | 35 ++++++++- compiler/rustc_mir_build/src/build/scope.rs | 1 + compiler/rustc_mir_build/src/lints.rs | 2 + .../src/impls/borrowed_locals.rs | 1 + .../src/impls/storage_liveness.rs | 2 + .../src/move_paths/builder.rs | 6 ++ .../rustc_mir_dataflow/src/value_analysis.rs | 3 + compiler/rustc_mir_transform/src/coroutine.rs | 5 ++ .../rustc_mir_transform/src/coverage/graph.rs | 9 ++- .../src/coverage/spans/from_mir.rs | 3 +- compiler/rustc_mir_transform/src/dest_prop.rs | 6 ++ compiler/rustc_mir_transform/src/inline.rs | 9 +++ .../rustc_mir_transform/src/jump_threading.rs | 1 + .../src/known_panics_lint.rs | 1 + .../src/mentioned_items.rs | 2 +- .../src/remove_noop_landing_pads.rs | 1 + compiler/rustc_mir_transform/src/validate.rs | 77 +++++++++++-------- compiler/rustc_monomorphize/src/collector.rs | 3 +- .../rustc_smir/src/rustc_smir/convert/mir.rs | 1 + tests/ui/explicit-tail-calls/constck.rs | 22 ++++++ tests/ui/explicit-tail-calls/constck.stderr | 19 +++++ .../explicit-tail-calls/return-mismatches.rs | 2 +- .../return-mismatches.stderr | 13 +--- tests/ui/explicit-tail-calls/unsafeck.rs | 11 +++ tests/ui/explicit-tail-calls/unsafeck.stderr | 11 +++ tests/ui/parser/bad-let-else-statement.rs | 16 ++-- tests/ui/parser/bad-let-else-statement.stderr | 15 +--- 41 files changed, 328 insertions(+), 88 deletions(-) create mode 100644 tests/ui/explicit-tail-calls/constck.rs create mode 100644 tests/ui/explicit-tail-calls/constck.stderr create mode 100644 tests/ui/explicit-tail-calls/unsafeck.rs create mode 100644 tests/ui/explicit-tail-calls/unsafeck.stderr diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index e6f8ffd428d06..df532c739509e 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -728,6 +728,12 @@ impl<'a, 'mir, 'tcx, R> rustc_mir_dataflow::ResultsVisitor<'mir, 'tcx, R> } self.mutate_place(loc, (*destination, span), Deep, flow_state); } + TerminatorKind::TailCall { func, args, fn_span: _ } => { + self.consume_operand(loc, (func, span), flow_state); + for arg in args { + self.consume_operand(loc, (&arg.node, arg.span), flow_state); + } + } TerminatorKind::Assert { cond, expected: _, msg, target: _, unwind: _ } => { self.consume_operand(loc, (cond, span), flow_state); if let AssertKind::BoundsCheck { len, index } = &**msg { @@ -814,9 +820,8 @@ impl<'a, 'mir, 'tcx, R> rustc_mir_dataflow::ResultsVisitor<'mir, 'tcx, R> TerminatorKind::UnwindResume | TerminatorKind::Return + | TerminatorKind::TailCall { .. } | TerminatorKind::CoroutineDrop => { - // Returning from the function implicitly kills storage for all locals and statics. - // Often, the storage will already have been killed by an explicit // StorageDead, but we don't always emit those (notably on unwind paths), // so this "extra check" serves as a kind of backup. let borrow_set = self.borrow_set.clone(); diff --git a/compiler/rustc_borrowck/src/polonius/loan_invalidations.rs b/compiler/rustc_borrowck/src/polonius/loan_invalidations.rs index 6979910a02d73..30dfc4c21b06a 100644 --- a/compiler/rustc_borrowck/src/polonius/loan_invalidations.rs +++ b/compiler/rustc_borrowck/src/polonius/loan_invalidations.rs @@ -125,6 +125,12 @@ impl<'cx, 'tcx> Visitor<'tcx> for LoanInvalidationsGenerator<'cx, 'tcx> { } self.mutate_place(location, *destination, Deep); } + TerminatorKind::TailCall { func, args, .. } => { + self.consume_operand(location, func); + for arg in args { + self.consume_operand(location, &arg.node); + } + } TerminatorKind::Assert { cond, expected: _, msg, target: _, unwind: _ } => { self.consume_operand(location, cond); use rustc_middle::mir::AssertKind; diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index aa25e3adf28af..8bba7ef425520 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -1352,7 +1352,14 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { } // FIXME: check the values } - TerminatorKind::Call { func, args, destination, call_source, target, .. } => { + TerminatorKind::Call { func, args, .. } + | TerminatorKind::TailCall { func, args, .. } => { + let call_source = match term.kind { + TerminatorKind::Call { call_source, .. } => call_source, + TerminatorKind::TailCall { .. } => CallSource::Normal, + _ => unreachable!(), + }; + self.check_operand(func, term_location); for arg in args { self.check_operand(&arg.node, term_location); @@ -1425,7 +1432,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { ); } - self.check_call_dest(body, term, &sig, *destination, *target, term_location); + if let TerminatorKind::Call { destination, target, .. } = term.kind { + self.check_call_dest(body, term, &sig, destination, target, term_location); + } // The ordinary liveness rules will ensure that all // regions in the type of the callee are live here. We @@ -1443,7 +1452,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { .add_location(region_vid, term_location); } - self.check_call_inputs(body, term, func, &sig, args, term_location, *call_source); + self.check_call_inputs(body, term, func, &sig, args, term_location, call_source); } TerminatorKind::Assert { cond, msg, .. } => { self.check_operand(cond, term_location); @@ -1675,6 +1684,11 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { span_mirbug!(self, block_data, "return on cleanup block") } } + TerminatorKind::TailCall { .. } => { + if is_cleanup { + span_mirbug!(self, block_data, "tailcall on cleanup block") + } + } TerminatorKind::CoroutineDrop { .. } => { if is_cleanup { span_mirbug!(self, block_data, "coroutine_drop in cleanup block") diff --git a/compiler/rustc_codegen_cranelift/src/base.rs b/compiler/rustc_codegen_cranelift/src/base.rs index c5b4277015a9e..5adbbb09ac85f 100644 --- a/compiler/rustc_codegen_cranelift/src/base.rs +++ b/compiler/rustc_codegen_cranelift/src/base.rs @@ -491,6 +491,11 @@ fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) { ) }); } + // FIXME(explicit_tail_calls): add support for tail calls to the cranelift backend, once cranelift supports tail calls + TerminatorKind::TailCall { fn_span, .. } => span_bug!( + *fn_span, + "tail calls are not yet supported in `rustc_codegen_cranelift` backend" + ), TerminatorKind::InlineAsm { template, operands, diff --git a/compiler/rustc_codegen_cranelift/src/constant.rs b/compiler/rustc_codegen_cranelift/src/constant.rs index 87c5da3b7c3ed..fc12f0ff738ba 100644 --- a/compiler/rustc_codegen_cranelift/src/constant.rs +++ b/compiler/rustc_codegen_cranelift/src/constant.rs @@ -565,6 +565,7 @@ pub(crate) fn mir_operand_get_const_val<'tcx>( { return None; } + TerminatorKind::TailCall { .. } => return None, TerminatorKind::Call { .. } => {} } } diff --git a/compiler/rustc_codegen_ssa/src/mir/analyze.rs b/compiler/rustc_codegen_ssa/src/mir/analyze.rs index 0577ba32ffdcc..ac2b6ca4e9520 100644 --- a/compiler/rustc_codegen_ssa/src/mir/analyze.rs +++ b/compiler/rustc_codegen_ssa/src/mir/analyze.rs @@ -281,6 +281,7 @@ pub fn cleanup_kinds(mir: &mir::Body<'_>) -> IndexVec> FunctionCx<'a, 'tcx, Bx> { fn_span, mergeable_succ(), ), + mir::TerminatorKind::TailCall { .. } => { + // FIXME(explicit_tail_calls): implement tail calls in ssa backend + span_bug!( + terminator.source_info.span, + "`TailCall` terminator is not yet supported by `rustc_codegen_ssa`" + ) + } mir::TerminatorKind::CoroutineDrop | mir::TerminatorKind::Yield { .. } => { bug!("coroutine ops in codegen") } diff --git a/compiler/rustc_const_eval/src/check_consts/check.rs b/compiler/rustc_const_eval/src/check_consts/check.rs index 0d8a17775dd3d..412effba32dc6 100644 --- a/compiler/rustc_const_eval/src/check_consts/check.rs +++ b/compiler/rustc_const_eval/src/check_consts/check.rs @@ -135,6 +135,8 @@ impl<'mir, 'tcx> Qualifs<'mir, 'tcx> { ccx: &'mir ConstCx<'mir, 'tcx>, tainted_by_errors: Option, ) -> ConstQualifs { + // FIXME(explicit_tail_calls): uhhhh I think we can return without return now, does it change anything + // Find the `Return` terminator if one exists. // // If no `Return` terminator exists, this MIR is divergent. Just return the conservative @@ -711,7 +713,14 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { self.super_terminator(terminator, location); match &terminator.kind { - TerminatorKind::Call { func, args, fn_span, call_source, .. } => { + TerminatorKind::Call { func, args, fn_span, .. } + | TerminatorKind::TailCall { func, args, fn_span, .. } => { + let call_source = match terminator.kind { + TerminatorKind::Call { call_source, .. } => call_source, + TerminatorKind::TailCall { .. } => CallSource::Normal, + _ => unreachable!(), + }; + let ConstCx { tcx, body, param_env, .. } = *self.ccx; let caller = self.def_id(); @@ -783,7 +792,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { callee, args: fn_args, span: *fn_span, - call_source: *call_source, + call_source, feature: Some(if tcx.features().const_trait_impl { sym::effects } else { @@ -830,7 +839,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { callee, args: fn_args, span: *fn_span, - call_source: *call_source, + call_source, feature: None, }); return; diff --git a/compiler/rustc_const_eval/src/check_consts/post_drop_elaboration.rs b/compiler/rustc_const_eval/src/check_consts/post_drop_elaboration.rs index f0763f1e490ff..f5e745454ab84 100644 --- a/compiler/rustc_const_eval/src/check_consts/post_drop_elaboration.rs +++ b/compiler/rustc_const_eval/src/check_consts/post_drop_elaboration.rs @@ -108,6 +108,7 @@ impl<'tcx> Visitor<'tcx> for CheckLiveDrops<'_, 'tcx> { mir::TerminatorKind::UnwindTerminate(_) | mir::TerminatorKind::Call { .. } + | mir::TerminatorKind::TailCall { .. } | mir::TerminatorKind::Assert { .. } | mir::TerminatorKind::FalseEdge { .. } | mir::TerminatorKind::FalseUnwind { .. } diff --git a/compiler/rustc_const_eval/src/interpret/terminator.rs b/compiler/rustc_const_eval/src/interpret/terminator.rs index 68acddf63d86e..7d1a48d6ded6f 100644 --- a/compiler/rustc_const_eval/src/interpret/terminator.rs +++ b/compiler/rustc_const_eval/src/interpret/terminator.rs @@ -172,6 +172,8 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { } } + TailCall { func: _, args: _, fn_span: _ } => todo!(), + Drop { place, target, unwind, replace: _ } => { let place = self.eval_place(place)?; let instance = Instance::resolve_drop_in_place(*self.tcx, place.layout.ty); diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs index 4657f4dcf8132..23251d7b7bf61 100644 --- a/compiler/rustc_middle/src/mir/pretty.rs +++ b/compiler/rustc_middle/src/mir/pretty.rs @@ -845,6 +845,16 @@ impl<'tcx> TerminatorKind<'tcx> { } write!(fmt, ")") } + TailCall { func, args, .. } => { + write!(fmt, "tailcall {func:?}(")?; + for (index, arg) in args.iter().enumerate() { + if index > 0 { + write!(fmt, ", ")?; + } + write!(fmt, "{:?}", arg)?; + } + write!(fmt, ")") + } Assert { cond, expected, msg, .. } => { write!(fmt, "assert(")?; if !expected { @@ -912,7 +922,12 @@ impl<'tcx> TerminatorKind<'tcx> { pub fn fmt_successor_labels(&self) -> Vec> { use self::TerminatorKind::*; match *self { - Return | UnwindResume | UnwindTerminate(_) | Unreachable | CoroutineDrop => vec![], + Return + | TailCall { .. } + | UnwindResume + | UnwindTerminate(_) + | Unreachable + | CoroutineDrop => vec![], Goto { .. } => vec!["".into()], SwitchInt { ref targets, .. } => targets .values diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs index 2c2884f189743..deaa1259f6b73 100644 --- a/compiler/rustc_middle/src/mir/syntax.rs +++ b/compiler/rustc_middle/src/mir/syntax.rs @@ -744,6 +744,36 @@ pub enum TerminatorKind<'tcx> { fn_span: Span, }, + /// Tail call. + /// + /// Roughly speaking this is a chimera of [`Call`] and [`Return`], with some caveats. + /// Semantically tail calls consists of two actions: + /// - pop of the current stack frame + /// - a call to the `func`, with the return address of the **current** caller + /// - so that a `return` inside `func` returns to the caller of the caller + /// of the function that is currently being executed + /// + /// Note that in difference with [`Call`] this is missing + /// - `destination` (because it's always the return place) + /// - `target` (because it's always taken from the current stack frame) + /// - `unwind` (because it's always taken from the current stack frame) + /// + /// [`Call`]: TerminatorKind::Call + /// [`Return`]: TerminatorKind::Return + TailCall { + /// The function that’s being called. + func: Operand<'tcx>, + /// Arguments the function is called with. + /// These are owned by the callee, which is free to modify them. + /// This allows the memory occupied by "by-value" arguments to be + /// reused across function calls without duplicating the contents. + args: Vec>>, + // FIXME(explicit_tail_calls): should we have the span for `become`? is this span accurate? do we need it? + /// This `Span` is the span of the function, without the dot and receiver + /// (e.g. `foo(a, b)` in `x.foo(a, b)` + fn_span: Span, + }, + /// Evaluates the operand, which must have type `bool`. If it is not equal to `expected`, /// initiates a panic. Initiating a panic corresponds to a `Call` terminator with some /// unspecified constant as the function to call, all the operands stored in the `AssertMessage` @@ -870,6 +900,7 @@ impl TerminatorKind<'_> { TerminatorKind::Unreachable => "Unreachable", TerminatorKind::Drop { .. } => "Drop", TerminatorKind::Call { .. } => "Call", + TerminatorKind::TailCall { .. } => "TailCall", TerminatorKind::Assert { .. } => "Assert", TerminatorKind::Yield { .. } => "Yield", TerminatorKind::CoroutineDrop => "CoroutineDrop", diff --git a/compiler/rustc_middle/src/mir/terminator.rs b/compiler/rustc_middle/src/mir/terminator.rs index ed592612358be..5b035d9579d76 100644 --- a/compiler/rustc_middle/src/mir/terminator.rs +++ b/compiler/rustc_middle/src/mir/terminator.rs @@ -439,6 +439,7 @@ mod helper { | CoroutineDrop | Return | Unreachable + | TailCall { .. } | Call { target: None, unwind: _, .. } => (&[]).into_iter().copied().chain(None), InlineAsm { ref targets, unwind: UnwindAction::Cleanup(u), .. } => { targets.iter().copied().chain(Some(u)) @@ -479,6 +480,7 @@ mod helper { | CoroutineDrop | Return | Unreachable + | TailCall { .. } | Call { target: None, unwind: _, .. } => (&mut []).into_iter().chain(None), InlineAsm { ref mut targets, unwind: UnwindAction::Cleanup(ref mut u), .. } => { targets.iter_mut().chain(Some(u)) @@ -501,6 +503,7 @@ impl<'tcx> TerminatorKind<'tcx> { | TerminatorKind::UnwindResume | TerminatorKind::UnwindTerminate(_) | TerminatorKind::Return + | TerminatorKind::TailCall { .. } | TerminatorKind::Unreachable | TerminatorKind::CoroutineDrop | TerminatorKind::Yield { .. } @@ -521,6 +524,7 @@ impl<'tcx> TerminatorKind<'tcx> { | TerminatorKind::UnwindResume | TerminatorKind::UnwindTerminate(_) | TerminatorKind::Return + | TerminatorKind::TailCall { .. } | TerminatorKind::Unreachable | TerminatorKind::CoroutineDrop | TerminatorKind::Yield { .. } @@ -606,9 +610,12 @@ impl<'tcx> TerminatorKind<'tcx> { pub fn edges(&self) -> TerminatorEdges<'_, 'tcx> { use TerminatorKind::*; match *self { - Return | UnwindResume | UnwindTerminate(_) | CoroutineDrop | Unreachable => { - TerminatorEdges::None - } + Return + | TailCall { .. } + | UnwindResume + | UnwindTerminate(_) + | CoroutineDrop + | Unreachable => TerminatorEdges::None, Goto { target } => TerminatorEdges::Single(target), diff --git a/compiler/rustc_middle/src/mir/visit.rs b/compiler/rustc_middle/src/mir/visit.rs index 7628a1ed2fe2b..0d3c419748b7a 100644 --- a/compiler/rustc_middle/src/mir/visit.rs +++ b/compiler/rustc_middle/src/mir/visit.rs @@ -540,6 +540,17 @@ macro_rules! make_mir_visitor { ); } + TerminatorKind::TailCall { + func, + args, + fn_span: _, + } => { + self.visit_operand(func, location); + for arg in args { + self.visit_operand(&$($mutability)? arg.node, location); + } + }, + TerminatorKind::Assert { cond, expected: _, diff --git a/compiler/rustc_mir_build/src/build/expr/stmt.rs b/compiler/rustc_mir_build/src/build/expr/stmt.rs index 2bdeb579a02de..60ab843257d5d 100644 --- a/compiler/rustc_mir_build/src/build/expr/stmt.rs +++ b/compiler/rustc_mir_build/src/build/expr/stmt.rs @@ -2,7 +2,9 @@ use crate::build::scope::BreakableTarget; use crate::build::{BlockAnd, BlockAndExtension, BlockFrame, Builder}; use rustc_middle::middle::region; use rustc_middle::mir::*; +use rustc_middle::span_bug; use rustc_middle::thir::*; +use rustc_span::source_map::Spanned; use tracing::debug; impl<'a, 'tcx> Builder<'a, 'tcx> { @@ -91,9 +93,38 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { ExprKind::Return { value } => { this.break_scope(block, value, BreakableTarget::Return, source_info) } - // FIXME(explicit_tail_calls): properly lower tail calls here ExprKind::Become { value } => { - this.break_scope(block, Some(value), BreakableTarget::Return, source_info) + let v = &this.thir[value]; + let ExprKind::Scope { value, .. } = v.kind else { + span_bug!(v.span, "`thir_check_tail_calls` should have disallowed this {v:?}") + }; + + let v = &this.thir[value]; + let ExprKind::Call { ref args, fun, fn_span, .. } = v.kind else { + span_bug!(v.span, "`thir_check_tail_calls` should have disallowed this {v:?}") + }; + + let fun = unpack!(block = this.as_local_operand(block, fun)); + let args: Vec<_> = args + .into_iter() + .copied() + .map(|arg| Spanned { + node: unpack!(block = this.as_local_call_operand(block, arg)), + span: this.thir.exprs[arg].span, + }) + .collect(); + + this.record_operands_moved(&args); + + debug!("expr_into_dest: fn_span={:?}", fn_span); + + this.cfg.terminate( + block, + source_info, + TerminatorKind::TailCall { func: fun, args, fn_span }, + ); + + this.cfg.start_new_block().unit() } _ => { assert!( diff --git a/compiler/rustc_mir_build/src/build/scope.rs b/compiler/rustc_mir_build/src/build/scope.rs index 5b6de39bb2e78..9e7534a283d9d 100644 --- a/compiler/rustc_mir_build/src/build/scope.rs +++ b/compiler/rustc_mir_build/src/build/scope.rs @@ -1523,6 +1523,7 @@ impl<'tcx> DropTreeBuilder<'tcx> for Unwind { | TerminatorKind::UnwindResume | TerminatorKind::UnwindTerminate(_) | TerminatorKind::Return + | TerminatorKind::TailCall { .. } | TerminatorKind::Unreachable | TerminatorKind::Yield { .. } | TerminatorKind::CoroutineDrop diff --git a/compiler/rustc_mir_build/src/lints.rs b/compiler/rustc_mir_build/src/lints.rs index 1c7aa9f9ed095..3cb83a48ffe1b 100644 --- a/compiler/rustc_mir_build/src/lints.rs +++ b/compiler/rustc_mir_build/src/lints.rs @@ -196,6 +196,8 @@ impl<'mir, 'tcx, C: TerminatorClassifier<'tcx>> TriColorVisitor ControlFlow::Break(NonRecursive), diff --git a/compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs b/compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs index 706bb796349fb..574da949b0ed3 100644 --- a/compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs +++ b/compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs @@ -145,6 +145,7 @@ where | TerminatorKind::InlineAsm { .. } | TerminatorKind::UnwindResume | TerminatorKind::Return + | TerminatorKind::TailCall { .. } | TerminatorKind::SwitchInt { .. } | TerminatorKind::Unreachable | TerminatorKind::Yield { .. } => {} diff --git a/compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs b/compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs index 29169c31263bd..f850a71027739 100644 --- a/compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs +++ b/compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs @@ -288,6 +288,7 @@ impl<'tcx> crate::GenKillAnalysis<'tcx> for MaybeRequiresStorage<'_, 'tcx> { | TerminatorKind::Goto { .. } | TerminatorKind::UnwindResume | TerminatorKind::Return + | TerminatorKind::TailCall { .. } | TerminatorKind::SwitchInt { .. } | TerminatorKind::Unreachable => {} } @@ -325,6 +326,7 @@ impl<'tcx> crate::GenKillAnalysis<'tcx> for MaybeRequiresStorage<'_, 'tcx> { | TerminatorKind::Goto { .. } | TerminatorKind::UnwindResume | TerminatorKind::Return + | TerminatorKind::TailCall { .. } | TerminatorKind::SwitchInt { .. } | TerminatorKind::Unreachable => {} } diff --git a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs index 1fb77bef3d410..7b39db821d839 100644 --- a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs +++ b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs @@ -489,6 +489,12 @@ impl<'b, 'a, 'tcx, F: Fn(Ty<'tcx>) -> bool> Gatherer<'b, 'a, 'tcx, F> { self.gather_init(destination.as_ref(), InitKind::NonPanicPathOnly); } } + TerminatorKind::TailCall { ref func, ref args, .. } => { + self.gather_operand(func); + for arg in args { + self.gather_operand(&arg.node); + } + } TerminatorKind::InlineAsm { template: _, ref operands, diff --git a/compiler/rustc_mir_dataflow/src/value_analysis.rs b/compiler/rustc_mir_dataflow/src/value_analysis.rs index 7c1ff6fda53f7..1582c2e8a9061 100644 --- a/compiler/rustc_mir_dataflow/src/value_analysis.rs +++ b/compiler/rustc_mir_dataflow/src/value_analysis.rs @@ -269,6 +269,9 @@ pub trait ValueAnalysis<'tcx> { TerminatorKind::SwitchInt { discr, targets } => { return self.handle_switch_int(discr, targets, state); } + TerminatorKind::TailCall { .. } => { + // FIXME(explicit_tail_calls): determine if we need to do something here (probably not) + } TerminatorKind::Goto { .. } | TerminatorKind::UnwindResume | TerminatorKind::UnwindTerminate(_) diff --git a/compiler/rustc_mir_transform/src/coroutine.rs b/compiler/rustc_mir_transform/src/coroutine.rs index 9d44001f91512..fa5da89e8ba56 100644 --- a/compiler/rustc_mir_transform/src/coroutine.rs +++ b/compiler/rustc_mir_transform/src/coroutine.rs @@ -1367,6 +1367,10 @@ fn can_unwind<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>) -> bool { | TerminatorKind::Call { .. } | TerminatorKind::InlineAsm { .. } | TerminatorKind::Assert { .. } => return true, + + TerminatorKind::TailCall { .. } => { + unreachable!("tail calls can't be present in generators") + } } } @@ -1916,6 +1920,7 @@ impl<'tcx> Visitor<'tcx> for EnsureCoroutineFieldAssignmentsNeverAlias<'_> { | TerminatorKind::UnwindResume | TerminatorKind::UnwindTerminate(_) | TerminatorKind::Return + | TerminatorKind::TailCall { .. } | TerminatorKind::Unreachable | TerminatorKind::Drop { .. } | TerminatorKind::Assert { .. } diff --git a/compiler/rustc_mir_transform/src/coverage/graph.rs b/compiler/rustc_mir_transform/src/coverage/graph.rs index 360dccb240dc6..83fb9ff974369 100644 --- a/compiler/rustc_mir_transform/src/coverage/graph.rs +++ b/compiler/rustc_mir_transform/src/coverage/graph.rs @@ -358,9 +358,12 @@ fn bcb_filtered_successors<'a, 'tcx>(terminator: &'a Terminator<'tcx>) -> Covera } // These terminators have no coverage-relevant successors. - CoroutineDrop | Return | Unreachable | UnwindResume | UnwindTerminate(_) => { - CoverageSuccessors::NotChainable(&[]) - } + CoroutineDrop + | Return + | TailCall { .. } + | Unreachable + | UnwindResume + | UnwindTerminate(_) => CoverageSuccessors::NotChainable(&[]), } } diff --git a/compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs b/compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs index 2ca166929eec8..a0f8f580b1d38 100644 --- a/compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs +++ b/compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs @@ -193,7 +193,8 @@ fn filtered_terminator_span(terminator: &Terminator<'_>) -> Option { | TerminatorKind::Goto { .. } => None, // Call `func` operand can have a more specific span when part of a chain of calls - | TerminatorKind::Call { ref func, .. } => { + TerminatorKind::Call { ref func, .. } + | TerminatorKind::TailCall { ref func, .. } => { let mut span = terminator.source_info.span; if let mir::Operand::Constant(box constant) = func { if constant.span.lo() > span.lo() { diff --git a/compiler/rustc_mir_transform/src/dest_prop.rs b/compiler/rustc_mir_transform/src/dest_prop.rs index b1016c0867c62..ab73a8af317a7 100644 --- a/compiler/rustc_mir_transform/src/dest_prop.rs +++ b/compiler/rustc_mir_transform/src/dest_prop.rs @@ -628,6 +628,12 @@ impl WriteInfo { self.add_operand(&arg.node); } } + TerminatorKind::TailCall { func, args, .. } => { + self.add_operand(func); + for arg in args { + self.add_operand(&arg.node); + } + } TerminatorKind::InlineAsm { operands, .. } => { for asm_operand in operands { match asm_operand { diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs index 5075e0727548f..fe73715480f8b 100644 --- a/compiler/rustc_mir_transform/src/inline.rs +++ b/compiler/rustc_mir_transform/src/inline.rs @@ -383,6 +383,8 @@ impl<'tcx> Inliner<'tcx> { ) -> Option> { // Only consider direct calls to functions let terminator = bb_data.terminator(); + + // FIXME(explicit_tail_calls): figure out if we can inline tail calls if let TerminatorKind::Call { ref func, fn_span, .. } = terminator.kind { let func_ty = func.ty(caller_body, self.tcx); if let ty::FnDef(def_id, args) = *func_ty.kind() { @@ -550,6 +552,9 @@ impl<'tcx> Inliner<'tcx> { // inline-asm is detected. LLVM will still possibly do an inline later on // if the no-attribute function ends up with the same instruction set anyway. return Err("Cannot move inline-asm across instruction sets"); + } else if let TerminatorKind::TailCall { .. } = term.kind { + // FIXME(explicit_tail_calls): figure out how exactly functions containing tail calls can be inlined (and if they even should) + return Err("can't inline functions with tail calls"); } else { work_list.extend(term.successors()) } @@ -1038,6 +1043,10 @@ impl<'tcx> MutVisitor<'tcx> for Integrator<'_, 'tcx> { *target = self.map_block(*target); *unwind = self.map_unwind(*unwind); } + TerminatorKind::TailCall { .. } => { + // check_mir_body forbids tail calls + unreachable!() + } TerminatorKind::Call { ref mut target, ref mut unwind, .. } => { if let Some(ref mut tgt) = *target { *tgt = self.map_block(*tgt); diff --git a/compiler/rustc_mir_transform/src/jump_threading.rs b/compiler/rustc_mir_transform/src/jump_threading.rs index 85a61f95ca36f..97ec0cb39ded3 100644 --- a/compiler/rustc_mir_transform/src/jump_threading.rs +++ b/compiler/rustc_mir_transform/src/jump_threading.rs @@ -596,6 +596,7 @@ impl<'tcx, 'a> TOFinder<'tcx, 'a> { TerminatorKind::UnwindResume | TerminatorKind::UnwindTerminate(_) | TerminatorKind::Return + | TerminatorKind::TailCall { .. } | TerminatorKind::Unreachable | TerminatorKind::CoroutineDrop => bug!("{term:?} has no terminators"), // Disallowed during optimizations. diff --git a/compiler/rustc_mir_transform/src/known_panics_lint.rs b/compiler/rustc_mir_transform/src/known_panics_lint.rs index 8d6c00bbedbae..82ad8879d17b3 100644 --- a/compiler/rustc_mir_transform/src/known_panics_lint.rs +++ b/compiler/rustc_mir_transform/src/known_panics_lint.rs @@ -799,6 +799,7 @@ impl<'tcx> Visitor<'tcx> for ConstPropagator<'_, 'tcx> { | TerminatorKind::UnwindResume | TerminatorKind::UnwindTerminate(_) | TerminatorKind::Return + | TerminatorKind::TailCall { .. } | TerminatorKind::Unreachable | TerminatorKind::Drop { .. } | TerminatorKind::Yield { .. } diff --git a/compiler/rustc_mir_transform/src/mentioned_items.rs b/compiler/rustc_mir_transform/src/mentioned_items.rs index db2bb60bdac34..d928d7cf76445 100644 --- a/compiler/rustc_mir_transform/src/mentioned_items.rs +++ b/compiler/rustc_mir_transform/src/mentioned_items.rs @@ -38,7 +38,7 @@ impl<'tcx> Visitor<'tcx> for MentionedItemsVisitor<'_, 'tcx> { self.super_terminator(terminator, location); let span = || self.body.source_info(location).span; match &terminator.kind { - mir::TerminatorKind::Call { func, .. } => { + mir::TerminatorKind::Call { func, .. } | mir::TerminatorKind::TailCall { func, .. } => { let callee_ty = func.ty(self.body, self.tcx); self.mentioned_items .push(Spanned { node: MentionedItem::Fn(callee_ty), span: span() }); diff --git a/compiler/rustc_mir_transform/src/remove_noop_landing_pads.rs b/compiler/rustc_mir_transform/src/remove_noop_landing_pads.rs index fb52bfa468a01..1df5737e85974 100644 --- a/compiler/rustc_mir_transform/src/remove_noop_landing_pads.rs +++ b/compiler/rustc_mir_transform/src/remove_noop_landing_pads.rs @@ -75,6 +75,7 @@ impl RemoveNoopLandingPads { | TerminatorKind::UnwindTerminate(_) | TerminatorKind::Unreachable | TerminatorKind::Call { .. } + | TerminatorKind::TailCall { .. } | TerminatorKind::Assert { .. } | TerminatorKind::Drop { .. } | TerminatorKind::InlineAsm { .. } => false, diff --git a/compiler/rustc_mir_transform/src/validate.rs b/compiler/rustc_mir_transform/src/validate.rs index 2018a8fe667d7..ab5c25c493773 100644 --- a/compiler/rustc_mir_transform/src/validate.rs +++ b/compiler/rustc_mir_transform/src/validate.rs @@ -400,40 +400,44 @@ impl<'a, 'tcx> Visitor<'tcx> for CfgChecker<'a, 'tcx> { self.check_edge(location, *target, EdgeKind::Normal); self.check_unwind_edge(location, *unwind); } - TerminatorKind::Call { args, destination, target, unwind, .. } => { - if let Some(target) = target { - self.check_edge(location, *target, EdgeKind::Normal); - } - self.check_unwind_edge(location, *unwind); + TerminatorKind::Call { args, .. } | TerminatorKind::TailCall { args, .. } => { + // FIXME(explicit_tail_calls): refactor this & add tail-call specific checks + if let TerminatorKind::Call { target, unwind, destination, .. } = terminator.kind { + if let Some(target) = target { + self.check_edge(location, target, EdgeKind::Normal); + } + self.check_unwind_edge(location, unwind); + + // The code generation assumes that there are no critical call edges. The assumption + // is used to simplify inserting code that should be executed along the return edge + // from the call. FIXME(tmiasko): Since this is a strictly code generation concern, + // the code generation should be responsible for handling it. + if self.mir_phase >= MirPhase::Runtime(RuntimePhase::Optimized) + && self.is_critical_call_edge(target, unwind) + { + self.fail( + location, + format!( + "encountered critical edge in `Call` terminator {:?}", + terminator.kind, + ), + ); + } - // The code generation assumes that there are no critical call edges. The assumption - // is used to simplify inserting code that should be executed along the return edge - // from the call. FIXME(tmiasko): Since this is a strictly code generation concern, - // the code generation should be responsible for handling it. - if self.mir_phase >= MirPhase::Runtime(RuntimePhase::Optimized) - && self.is_critical_call_edge(*target, *unwind) - { - self.fail( - location, - format!( - "encountered critical edge in `Call` terminator {:?}", - terminator.kind, - ), - ); + // The call destination place and Operand::Move place used as an argument might be + // passed by a reference to the callee. Consequently they cannot be packed. + if is_within_packed(self.tcx, &self.body.local_decls, destination).is_some() { + // This is bad! The callee will expect the memory to be aligned. + self.fail( + location, + format!( + "encountered packed place in `Call` terminator destination: {:?}", + terminator.kind, + ), + ); + } } - // The call destination place and Operand::Move place used as an argument might be - // passed by a reference to the callee. Consequently they cannot be packed. - if is_within_packed(self.tcx, &self.body.local_decls, *destination).is_some() { - // This is bad! The callee will expect the memory to be aligned. - self.fail( - location, - format!( - "encountered packed place in `Call` terminator destination: {:?}", - terminator.kind, - ), - ); - } for arg in args { if let Operand::Move(place) = &arg.node { if is_within_packed(self.tcx, &self.body.local_decls, *place).is_some() { @@ -1498,15 +1502,22 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { } } } - TerminatorKind::Call { func, .. } => { + TerminatorKind::Call { func, .. } | TerminatorKind::TailCall { func, .. } => { let func_ty = func.ty(&self.body.local_decls, self.tcx); match func_ty.kind() { ty::FnPtr(..) | ty::FnDef(..) => {} _ => self.fail( location, - format!("encountered non-callable type {func_ty} in `Call` terminator"), + format!( + "encountered non-callable type {func_ty} in `{}` terminator", + terminator.kind.name() + ), ), } + + if let TerminatorKind::TailCall { .. } = terminator.kind { + // FIXME(explicit_tail_calls): implement tail-call specific checks here (such as signature matching, forbidding closures, etc) + } } TerminatorKind::Assert { cond, .. } => { let cond_ty = cond.ty(&self.body.local_decls, self.tcx); diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index 342c01ff69731..3ef8da4a9c51c 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -755,7 +755,8 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirUsedCollector<'a, 'tcx> { }; match terminator.kind { - mir::TerminatorKind::Call { ref func, ref args, ref fn_span, .. } => { + mir::TerminatorKind::Call { ref func, ref args, ref fn_span, .. } + | mir::TerminatorKind::TailCall { ref func, ref args, ref fn_span } => { let callee_ty = func.ty(self.body, tcx); // *Before* monomorphizing, record that we already handled this mention. self.used_mentioned_items.insert(MentionedItem::Fn(callee_ty)); diff --git a/compiler/rustc_smir/src/rustc_smir/convert/mir.rs b/compiler/rustc_smir/src/rustc_smir/convert/mir.rs index f15b82d0c031f..3367cea9897ae 100644 --- a/compiler/rustc_smir/src/rustc_smir/convert/mir.rs +++ b/compiler/rustc_smir/src/rustc_smir/convert/mir.rs @@ -644,6 +644,7 @@ impl<'tcx> Stable<'tcx> for mir::TerminatorKind<'tcx> { target: target.map(|t| t.as_usize()), unwind: unwind.stable(tables), }, + mir::TerminatorKind::TailCall { func: _, args: _, fn_span: _ } => todo!(), mir::TerminatorKind::Assert { cond, expected, msg, target, unwind } => { TerminatorKind::Assert { cond: cond.stable(tables), diff --git a/tests/ui/explicit-tail-calls/constck.rs b/tests/ui/explicit-tail-calls/constck.rs new file mode 100644 index 0000000000000..938f15f12c091 --- /dev/null +++ b/tests/ui/explicit-tail-calls/constck.rs @@ -0,0 +1,22 @@ +#![allow(incomplete_features)] +#![feature(explicit_tail_calls)] + +const fn f() { + if false { + become not_const(); + //~^ error: cannot call non-const fn `not_const` in constant functions + } +} + +const fn g((): ()) { + if false { + become yes_const(not_const()); + //~^ error: cannot call non-const fn `not_const` in constant functions + } +} + +fn not_const() {} + +const fn yes_const((): ()) {} + +fn main() {} diff --git a/tests/ui/explicit-tail-calls/constck.stderr b/tests/ui/explicit-tail-calls/constck.stderr new file mode 100644 index 0000000000000..d9967c45fa03c --- /dev/null +++ b/tests/ui/explicit-tail-calls/constck.stderr @@ -0,0 +1,19 @@ +error[E0015]: cannot call non-const fn `not_const` in constant functions + --> $DIR/constck.rs:6:16 + | +LL | become not_const(); + | ^^^^^^^^^^^ + | + = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants + +error[E0015]: cannot call non-const fn `not_const` in constant functions + --> $DIR/constck.rs:13:26 + | +LL | become yes_const(not_const()); + | ^^^^^^^^^^^ + | + = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0015`. diff --git a/tests/ui/explicit-tail-calls/return-mismatches.rs b/tests/ui/explicit-tail-calls/return-mismatches.rs index 8094a192913bc..935a1a1d28b02 100644 --- a/tests/ui/explicit-tail-calls/return-mismatches.rs +++ b/tests/ui/explicit-tail-calls/return-mismatches.rs @@ -13,7 +13,7 @@ fn _f1() { become _g1(); //~ error: mismatched types } -fn _g1() -> ! { //~ WARN: cannot return without recursing +fn _g1() -> ! { become _g1(); } diff --git a/tests/ui/explicit-tail-calls/return-mismatches.stderr b/tests/ui/explicit-tail-calls/return-mismatches.stderr index 31c7a46ded911..1dcc35797c130 100644 --- a/tests/ui/explicit-tail-calls/return-mismatches.stderr +++ b/tests/ui/explicit-tail-calls/return-mismatches.stderr @@ -22,17 +22,6 @@ error[E0308]: mismatched types LL | become _g2(); | ^^^^^^^^^^^^ expected `u32`, found `u16` -warning: function cannot return without recursing - --> $DIR/return-mismatches.rs:16:1 - | -LL | fn _g1() -> ! { - | ^^^^^^^^^^^^^ cannot return without recursing -LL | become _g1(); - | ----- recursive call site - | - = help: a `loop` may express intention better if this is on purpose - = note: `#[warn(unconditional_recursion)]` on by default - -error: aborting due to 3 previous errors; 1 warning emitted +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/explicit-tail-calls/unsafeck.rs b/tests/ui/explicit-tail-calls/unsafeck.rs new file mode 100644 index 0000000000000..872a70ca3a0a7 --- /dev/null +++ b/tests/ui/explicit-tail-calls/unsafeck.rs @@ -0,0 +1,11 @@ +#![allow(incomplete_features)] +#![feature(explicit_tail_calls)] + +const fn f() { + become dangerous(); + //~^ error: call to unsafe function `dangerous` is unsafe and requires unsafe function or block +} + +const unsafe fn dangerous() {} + +fn main() {} diff --git a/tests/ui/explicit-tail-calls/unsafeck.stderr b/tests/ui/explicit-tail-calls/unsafeck.stderr new file mode 100644 index 0000000000000..25b8967e17b6d --- /dev/null +++ b/tests/ui/explicit-tail-calls/unsafeck.stderr @@ -0,0 +1,11 @@ +error[E0133]: call to unsafe function `dangerous` is unsafe and requires unsafe function or block + --> $DIR/unsafeck.rs:5:12 + | +LL | become dangerous(); + | ^^^^^^^^^^^ call to unsafe function + | + = note: consult the function's documentation for information on how to avoid undefined behavior + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0133`. diff --git a/tests/ui/parser/bad-let-else-statement.rs b/tests/ui/parser/bad-let-else-statement.rs index ff6619cbc9864..3ede26dbcd06c 100644 --- a/tests/ui/parser/bad-let-else-statement.rs +++ b/tests/ui/parser/bad-let-else-statement.rs @@ -147,14 +147,14 @@ fn o() -> Result<(), ()> { }; } -fn p() { - let 0 = become { - () - } else { - //~^ ERROR right curly brace `}` before `else` in a `let...else` statement not allowed - return; - }; -} +// fn p() { // FIXME(explicit_tail_calls): this currently trips an assertion... +// let 0 = become { +// () +// } else { +// // ~^ ERROR right curly brace `}` before `else` in a `let...else` statement not allowed +// return; +// }; +// } fn q() { let foo = |x: i32| { diff --git a/tests/ui/parser/bad-let-else-statement.stderr b/tests/ui/parser/bad-let-else-statement.stderr index 0bf6a346dfb17..79d722bb7ac44 100644 --- a/tests/ui/parser/bad-let-else-statement.stderr +++ b/tests/ui/parser/bad-let-else-statement.stderr @@ -203,19 +203,6 @@ LL | () LL ~ }) else { | -error: right curly brace `}` before `else` in a `let...else` statement not allowed - --> $DIR/bad-let-else-statement.rs:153:5 - | -LL | } else { - | ^ - | -help: wrap the expression in parentheses - | -LL ~ let 0 = become ({ -LL | () -LL ~ }) else { - | - error: right curly brace `}` before `else` in a `let...else` statement not allowed --> $DIR/bad-let-else-statement.rs:163:5 | @@ -325,5 +312,5 @@ LL | | } else { = note: this pattern will always match, so the `else` clause is useless = help: consider removing the `else` clause -error: aborting due to 20 previous errors; 5 warnings emitted +error: aborting due to 19 previous errors; 5 warnings emitted From 4187cdc0135ee05802733632d4cbf6467da22847 Mon Sep 17 00:00:00 2001 From: DrMeepster <19316085+DrMeepster@users.noreply.github.com> Date: Wed, 14 Jun 2023 01:12:25 -0700 Subject: [PATCH 802/892] Properly handle drops for tail calls --- .../rustc_mir_build/src/build/expr/stmt.rs | 40 ++-- compiler/rustc_mir_build/src/build/scope.rs | 85 ++++++++ ...ll_drops.f.ElaborateDrops.panic-abort.diff | 108 ++++++++++ ...l_drops.f.ElaborateDrops.panic-unwind.diff | 109 ++++++++++ ...l_call_drops.f.built.after.panic-abort.mir | 118 ++++++++++ ..._call_drops.f.built.after.panic-unwind.mir | 118 ++++++++++ ...f_with_arg.ElaborateDrops.panic-abort.diff | 184 ++++++++++++++++ ..._with_arg.ElaborateDrops.panic-unwind.diff | 184 ++++++++++++++++ ...ops.f_with_arg.built.after.panic-abort.mir | 202 ++++++++++++++++++ ...ps.f_with_arg.built.after.panic-unwind.mir | 202 ++++++++++++++++++ tests/mir-opt/tail_call_drops.rs | 41 ++++ tests/ui/explicit-tail-calls/drop-order.rs | 70 ++++++ 12 files changed, 1443 insertions(+), 18 deletions(-) create mode 100644 tests/mir-opt/tail_call_drops.f.ElaborateDrops.panic-abort.diff create mode 100644 tests/mir-opt/tail_call_drops.f.ElaborateDrops.panic-unwind.diff create mode 100644 tests/mir-opt/tail_call_drops.f.built.after.panic-abort.mir create mode 100644 tests/mir-opt/tail_call_drops.f.built.after.panic-unwind.mir create mode 100644 tests/mir-opt/tail_call_drops.f_with_arg.ElaborateDrops.panic-abort.diff create mode 100644 tests/mir-opt/tail_call_drops.f_with_arg.ElaborateDrops.panic-unwind.diff create mode 100644 tests/mir-opt/tail_call_drops.f_with_arg.built.after.panic-abort.mir create mode 100644 tests/mir-opt/tail_call_drops.f_with_arg.built.after.panic-unwind.mir create mode 100644 tests/mir-opt/tail_call_drops.rs create mode 100644 tests/ui/explicit-tail-calls/drop-order.rs diff --git a/compiler/rustc_mir_build/src/build/expr/stmt.rs b/compiler/rustc_mir_build/src/build/expr/stmt.rs index 60ab843257d5d..7d2c32e000b90 100644 --- a/compiler/rustc_mir_build/src/build/expr/stmt.rs +++ b/compiler/rustc_mir_build/src/build/expr/stmt.rs @@ -95,7 +95,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } ExprKind::Become { value } => { let v = &this.thir[value]; - let ExprKind::Scope { value, .. } = v.kind else { + let ExprKind::Scope { value, lint_level, region_scope } = v.kind else { span_bug!(v.span, "`thir_check_tail_calls` should have disallowed this {v:?}") }; @@ -104,27 +104,31 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { span_bug!(v.span, "`thir_check_tail_calls` should have disallowed this {v:?}") }; - let fun = unpack!(block = this.as_local_operand(block, fun)); - let args: Vec<_> = args - .into_iter() - .copied() - .map(|arg| Spanned { - node: unpack!(block = this.as_local_call_operand(block, arg)), - span: this.thir.exprs[arg].span, - }) - .collect(); + this.in_scope((region_scope, source_info), lint_level, |this| { + let fun = unpack!(block = this.as_local_operand(block, fun)); + let args: Vec<_> = args + .into_iter() + .copied() + .map(|arg| Spanned { + node: unpack!(block = this.as_local_call_operand(block, arg)), + span: this.thir.exprs[arg].span, + }) + .collect(); - this.record_operands_moved(&args); + this.record_operands_moved(&args); - debug!("expr_into_dest: fn_span={:?}", fn_span); + debug!("expr_into_dest: fn_span={:?}", fn_span); - this.cfg.terminate( - block, - source_info, - TerminatorKind::TailCall { func: fun, args, fn_span }, - ); + unpack!(block = this.break_for_tail_call(block, &args, source_info)); - this.cfg.start_new_block().unit() + this.cfg.terminate( + block, + source_info, + TerminatorKind::TailCall { func: fun, args, fn_span }, + ); + + this.cfg.start_new_block().unit() + }) } _ => { assert!( diff --git a/compiler/rustc_mir_build/src/build/scope.rs b/compiler/rustc_mir_build/src/build/scope.rs index 9e7534a283d9d..948301e2ece4d 100644 --- a/compiler/rustc_mir_build/src/build/scope.rs +++ b/compiler/rustc_mir_build/src/build/scope.rs @@ -745,6 +745,91 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { self.cfg.terminate(block, source_info, TerminatorKind::UnwindResume); } + /// Sets up the drops for explict tail calls. + /// + /// Unlike other kinds of early exits, tail calls do not go through the drop tree. + /// Instead, all scheduled drops are immediately added to the CFG. + pub(crate) fn break_for_tail_call( + &mut self, + mut block: BasicBlock, + args: &[Spanned>], + source_info: SourceInfo, + ) -> BlockAnd<()> { + let arg_drops: Vec<_> = args + .iter() + .rev() + .filter_map(|arg| match &arg.node { + Operand::Copy(_) => bug!("copy op in tail call args"), + Operand::Move(place) => { + let local = + place.as_local().unwrap_or_else(|| bug!("projection in tail call args")); + + Some(DropData { source_info, local, kind: DropKind::Value }) + } + Operand::Constant(_) => None, + }) + .collect(); + + let mut unwind_to = self.diverge_cleanup_target( + self.scopes.scopes.iter().rev().nth(1).unwrap().region_scope, + DUMMY_SP, + ); + let unwind_drops = &mut self.scopes.unwind_drops; + + // the innermost scope contains only the destructors for the tail call arguments + // we only want to drop these in case of a panic, so we skip it + for scope in self.scopes.scopes[1..].iter().rev().skip(1) { + // FIXME(explicit_tail_calls) code duplication with `build_scope_drops` + for drop_data in scope.drops.iter().rev() { + let source_info = drop_data.source_info; + let local = drop_data.local; + + match drop_data.kind { + DropKind::Value => { + // `unwind_to` should drop the value that we're about to + // schedule. If dropping this value panics, then we continue + // with the *next* value on the unwind path. + debug_assert_eq!(unwind_drops.drops[unwind_to].data.local, drop_data.local); + debug_assert_eq!(unwind_drops.drops[unwind_to].data.kind, drop_data.kind); + unwind_to = unwind_drops.drops[unwind_to].next; + + let mut unwind_entry_point = unwind_to; + + // the tail call arguments must be dropped if any of these drops panic + for drop in arg_drops.iter().copied() { + unwind_entry_point = unwind_drops.add_drop(drop, unwind_entry_point); + } + + unwind_drops.add_entry_point(block, unwind_entry_point); + + let next = self.cfg.start_new_block(); + self.cfg.terminate( + block, + source_info, + TerminatorKind::Drop { + place: local.into(), + target: next, + unwind: UnwindAction::Continue, + replace: false, + }, + ); + block = next; + } + DropKind::Storage => { + // Only temps and vars need their storage dead. + assert!(local.index() > self.arg_count); + self.cfg.push( + block, + Statement { source_info, kind: StatementKind::StorageDead(local) }, + ); + } + } + } + } + + block.unit() + } + fn leave_top_scope(&mut self, block: BasicBlock) -> BasicBlock { // If we are emitting a `drop` statement, we need to have the cached // diverge cleanup pads ready in case that drop panics. diff --git a/tests/mir-opt/tail_call_drops.f.ElaborateDrops.panic-abort.diff b/tests/mir-opt/tail_call_drops.f.ElaborateDrops.panic-abort.diff new file mode 100644 index 0000000000000..44673ea00a966 --- /dev/null +++ b/tests/mir-opt/tail_call_drops.f.ElaborateDrops.panic-abort.diff @@ -0,0 +1,108 @@ +- // MIR for `f` before ElaborateDrops ++ // MIR for `f` after ElaborateDrops + + fn f() -> () { + let mut _0: (); + let mut _1: !; + let _2: std::string::String; + let _6: (); + let mut _7: std::string::String; ++ let mut _8: bool; + scope 1 { + debug _a => _2; + let _3: i32; + scope 2 { + debug _b => _3; + let _4: std::string::String; + scope 3 { + debug _c => _4; + let _5: std::string::String; + scope 4 { + debug _d => _5; + } + } + } + } + + bb0: { ++ _8 = const false; + StorageLive(_2); + _2 = String::new() -> [return: bb1, unwind: bb12]; + } + + bb1: { + StorageLive(_3); + _3 = const 12_i32; + StorageLive(_4); + _4 = String::new() -> [return: bb2, unwind: bb11]; + } + + bb2: { ++ _8 = const true; + StorageLive(_5); + _5 = String::new() -> [return: bb3, unwind: bb10]; + } + + bb3: { + StorageLive(_6); + StorageLive(_7); ++ _8 = const false; + _7 = move _4; + _6 = std::mem::drop::(move _7) -> [return: bb4, unwind: bb8]; + } + + bb4: { + StorageDead(_7); + StorageDead(_6); + drop(_5) -> [return: bb5, unwind: bb10]; + } + + bb5: { + StorageDead(_5); +- drop(_4) -> [return: bb6, unwind: bb11]; ++ goto -> bb6; + } + + bb6: { ++ _8 = const false; + StorageDead(_4); + StorageDead(_3); + drop(_2) -> [return: bb7, unwind: bb12]; + } + + bb7: { + StorageDead(_2); + tailcall g(); + } + + bb8 (cleanup): { +- drop(_7) -> [return: bb9, unwind terminate(cleanup)]; ++ goto -> bb9; + } + + bb9 (cleanup): { + drop(_5) -> [return: bb10, unwind terminate(cleanup)]; + } + + bb10 (cleanup): { +- drop(_4) -> [return: bb11, unwind terminate(cleanup)]; ++ goto -> bb14; + } + + bb11 (cleanup): { + drop(_2) -> [return: bb12, unwind terminate(cleanup)]; + } + + bb12 (cleanup): { + resume; ++ } ++ ++ bb13 (cleanup): { ++ drop(_4) -> [return: bb11, unwind terminate(cleanup)]; ++ } ++ ++ bb14 (cleanup): { ++ switchInt(_8) -> [0: bb11, otherwise: bb13]; + } + } + diff --git a/tests/mir-opt/tail_call_drops.f.ElaborateDrops.panic-unwind.diff b/tests/mir-opt/tail_call_drops.f.ElaborateDrops.panic-unwind.diff new file mode 100644 index 0000000000000..a6d33a2459543 --- /dev/null +++ b/tests/mir-opt/tail_call_drops.f.ElaborateDrops.panic-unwind.diff @@ -0,0 +1,109 @@ +- // MIR for `f` before ElaborateDrops ++ // MIR for `f` after ElaborateDrops + + fn f() -> () { + let mut _0: (); + let mut _1: !; + let _2: std::string::String; + let _6: (); + let mut _7: std::string::String; ++ let mut _8: bool; + scope 1 { + debug _a => _2; + let _3: i32; + scope 2 { + debug _b => _3; + let _4: std::string::String; + scope 3 { + debug _c => _4; + let _5: std::string::String; + scope 4 { + debug _d => _5; + } + } + } + } + + bb0: { ++ _8 = const false; + StorageLive(_2); + _2 = String::new() -> [return: bb1, unwind continue]; + } + + bb1: { + StorageLive(_3); + _3 = const 12_i32; + StorageLive(_4); + _4 = String::new() -> [return: bb2, unwind: bb11]; + } + + bb2: { ++ _8 = const true; + StorageLive(_5); + _5 = String::new() -> [return: bb3, unwind: bb10]; + } + + bb3: { + StorageLive(_6); + StorageLive(_7); ++ _8 = const false; + _7 = move _4; + _6 = std::mem::drop::(move _7) -> [return: bb4, unwind: bb8]; + } + + bb4: { + StorageDead(_7); + StorageDead(_6); + drop(_5) -> [return: bb5, unwind: bb10]; + } + + bb5: { + StorageDead(_5); +- drop(_4) -> [return: bb6, unwind: bb11]; ++ goto -> bb6; + } + + bb6: { ++ _8 = const false; + StorageDead(_4); + StorageDead(_3); +- drop(_2) -> [return: bb7, unwind continue]; ++ drop(_2) -> [return: bb7, unwind: bb12]; + } + + bb7: { + StorageDead(_2); + tailcall g(); + } + + bb8 (cleanup): { +- drop(_7) -> [return: bb9, unwind terminate(cleanup)]; ++ goto -> bb9; + } + + bb9 (cleanup): { + drop(_5) -> [return: bb10, unwind terminate(cleanup)]; + } + + bb10 (cleanup): { +- drop(_4) -> [return: bb11, unwind terminate(cleanup)]; ++ goto -> bb14; + } + + bb11 (cleanup): { + drop(_2) -> [return: bb12, unwind terminate(cleanup)]; + } + + bb12 (cleanup): { + resume; ++ } ++ ++ bb13 (cleanup): { ++ drop(_4) -> [return: bb11, unwind terminate(cleanup)]; ++ } ++ ++ bb14 (cleanup): { ++ switchInt(_8) -> [0: bb11, otherwise: bb13]; + } + } + diff --git a/tests/mir-opt/tail_call_drops.f.built.after.panic-abort.mir b/tests/mir-opt/tail_call_drops.f.built.after.panic-abort.mir new file mode 100644 index 0000000000000..2c3d62491d715 --- /dev/null +++ b/tests/mir-opt/tail_call_drops.f.built.after.panic-abort.mir @@ -0,0 +1,118 @@ +// MIR for `f` after built + +fn f() -> () { + let mut _0: (); + let mut _1: !; + let _2: std::string::String; + let _6: (); + let mut _7: std::string::String; + scope 1 { + debug _a => _2; + let _3: i32; + scope 2 { + debug _b => _3; + let _4: std::string::String; + scope 3 { + debug _c => _4; + let _5: std::string::String; + scope 4 { + debug _d => _5; + } + } + } + } + + bb0: { + StorageLive(_2); + _2 = String::new() -> [return: bb1, unwind: bb17]; + } + + bb1: { + FakeRead(ForLet(None), _2); + StorageLive(_3); + _3 = const 12_i32; + FakeRead(ForLet(None), _3); + StorageLive(_4); + _4 = String::new() -> [return: bb2, unwind: bb16]; + } + + bb2: { + FakeRead(ForLet(None), _4); + StorageLive(_5); + _5 = String::new() -> [return: bb3, unwind: bb15]; + } + + bb3: { + FakeRead(ForLet(None), _5); + StorageLive(_6); + StorageLive(_7); + _7 = move _4; + _6 = std::mem::drop::(move _7) -> [return: bb4, unwind: bb13]; + } + + bb4: { + StorageDead(_7); + StorageDead(_6); + drop(_5) -> [return: bb5, unwind: bb15]; + } + + bb5: { + StorageDead(_5); + drop(_4) -> [return: bb6, unwind: bb16]; + } + + bb6: { + StorageDead(_4); + StorageDead(_3); + drop(_2) -> [return: bb7, unwind: bb17]; + } + + bb7: { + StorageDead(_2); + tailcall g(); + } + + bb8: { + drop(_5) -> [return: bb9, unwind: bb15]; + } + + bb9: { + StorageDead(_5); + drop(_4) -> [return: bb10, unwind: bb16]; + } + + bb10: { + StorageDead(_4); + StorageDead(_3); + drop(_2) -> [return: bb11, unwind: bb17]; + } + + bb11: { + StorageDead(_2); + unreachable; + } + + bb12: { + return; + } + + bb13 (cleanup): { + drop(_7) -> [return: bb14, unwind terminate(cleanup)]; + } + + bb14 (cleanup): { + drop(_5) -> [return: bb15, unwind terminate(cleanup)]; + } + + bb15 (cleanup): { + drop(_4) -> [return: bb16, unwind terminate(cleanup)]; + } + + bb16 (cleanup): { + drop(_2) -> [return: bb17, unwind terminate(cleanup)]; + } + + bb17 (cleanup): { + resume; + } +} diff --git a/tests/mir-opt/tail_call_drops.f.built.after.panic-unwind.mir b/tests/mir-opt/tail_call_drops.f.built.after.panic-unwind.mir new file mode 100644 index 0000000000000..2c3d62491d715 --- /dev/null +++ b/tests/mir-opt/tail_call_drops.f.built.after.panic-unwind.mir @@ -0,0 +1,118 @@ +// MIR for `f` after built + +fn f() -> () { + let mut _0: (); + let mut _1: !; + let _2: std::string::String; + let _6: (); + let mut _7: std::string::String; + scope 1 { + debug _a => _2; + let _3: i32; + scope 2 { + debug _b => _3; + let _4: std::string::String; + scope 3 { + debug _c => _4; + let _5: std::string::String; + scope 4 { + debug _d => _5; + } + } + } + } + + bb0: { + StorageLive(_2); + _2 = String::new() -> [return: bb1, unwind: bb17]; + } + + bb1: { + FakeRead(ForLet(None), _2); + StorageLive(_3); + _3 = const 12_i32; + FakeRead(ForLet(None), _3); + StorageLive(_4); + _4 = String::new() -> [return: bb2, unwind: bb16]; + } + + bb2: { + FakeRead(ForLet(None), _4); + StorageLive(_5); + _5 = String::new() -> [return: bb3, unwind: bb15]; + } + + bb3: { + FakeRead(ForLet(None), _5); + StorageLive(_6); + StorageLive(_7); + _7 = move _4; + _6 = std::mem::drop::(move _7) -> [return: bb4, unwind: bb13]; + } + + bb4: { + StorageDead(_7); + StorageDead(_6); + drop(_5) -> [return: bb5, unwind: bb15]; + } + + bb5: { + StorageDead(_5); + drop(_4) -> [return: bb6, unwind: bb16]; + } + + bb6: { + StorageDead(_4); + StorageDead(_3); + drop(_2) -> [return: bb7, unwind: bb17]; + } + + bb7: { + StorageDead(_2); + tailcall g(); + } + + bb8: { + drop(_5) -> [return: bb9, unwind: bb15]; + } + + bb9: { + StorageDead(_5); + drop(_4) -> [return: bb10, unwind: bb16]; + } + + bb10: { + StorageDead(_4); + StorageDead(_3); + drop(_2) -> [return: bb11, unwind: bb17]; + } + + bb11: { + StorageDead(_2); + unreachable; + } + + bb12: { + return; + } + + bb13 (cleanup): { + drop(_7) -> [return: bb14, unwind terminate(cleanup)]; + } + + bb14 (cleanup): { + drop(_5) -> [return: bb15, unwind terminate(cleanup)]; + } + + bb15 (cleanup): { + drop(_4) -> [return: bb16, unwind terminate(cleanup)]; + } + + bb16 (cleanup): { + drop(_2) -> [return: bb17, unwind terminate(cleanup)]; + } + + bb17 (cleanup): { + resume; + } +} diff --git a/tests/mir-opt/tail_call_drops.f_with_arg.ElaborateDrops.panic-abort.diff b/tests/mir-opt/tail_call_drops.f_with_arg.ElaborateDrops.panic-abort.diff new file mode 100644 index 0000000000000..c7df2bb2207fb --- /dev/null +++ b/tests/mir-opt/tail_call_drops.f_with_arg.ElaborateDrops.panic-abort.diff @@ -0,0 +1,184 @@ +- // MIR for `f_with_arg` before ElaborateDrops ++ // MIR for `f_with_arg` after ElaborateDrops + + fn f_with_arg(_1: String, _2: String) -> () { + debug _arg1 => _1; + debug _arg2 => _2; + let mut _0: (); + let mut _3: !; + let _4: std::string::String; + let _8: (); + let mut _9: std::string::String; + let mut _10: std::string::String; + let mut _11: std::string::String; ++ let mut _12: bool; + scope 1 { + debug _a => _4; + let _5: i32; + scope 2 { + debug _b => _5; + let _6: std::string::String; + scope 3 { + debug _c => _6; + let _7: std::string::String; + scope 4 { + debug _d => _7; + } + } + } + } + + bb0: { ++ _12 = const false; + StorageLive(_4); + _4 = String::new() -> [return: bb1, unwind: bb27]; + } + + bb1: { + StorageLive(_5); + _5 = const 12_i32; + StorageLive(_6); + _6 = String::new() -> [return: bb2, unwind: bb26]; + } + + bb2: { ++ _12 = const true; + StorageLive(_7); + _7 = String::new() -> [return: bb3, unwind: bb25]; + } + + bb3: { + StorageLive(_8); + StorageLive(_9); ++ _12 = const false; + _9 = move _6; + _8 = std::mem::drop::(move _9) -> [return: bb4, unwind: bb23]; + } + + bb4: { + StorageDead(_9); + StorageDead(_8); + StorageLive(_10); + _10 = String::new() -> [return: bb5, unwind: bb24]; + } + + bb5: { + StorageLive(_11); + _11 = String::new() -> [return: bb6, unwind: bb22]; + } + + bb6: { + drop(_7) -> [return: bb7, unwind: bb20]; + } + + bb7: { + StorageDead(_7); +- drop(_6) -> [return: bb8, unwind: bb18]; ++ goto -> bb8; + } + + bb8: { ++ _12 = const false; + StorageDead(_6); + StorageDead(_5); + drop(_4) -> [return: bb9, unwind: bb16]; + } + + bb9: { + StorageDead(_4); + drop(_2) -> [return: bb10, unwind: bb14]; + } + + bb10: { + drop(_1) -> [return: bb11, unwind: bb12]; + } + + bb11: { + tailcall g_with_arg(Spanned { node: move _10, span: $DIR/tail_call_drops.rs:36:23: 36:36 (#0) }, Spanned { node: move _11, span: $DIR/tail_call_drops.rs:36:38: 36:51 (#0) }); + } + + bb12 (cleanup): { + drop(_10) -> [return: bb13, unwind terminate(cleanup)]; + } + + bb13 (cleanup): { + drop(_11) -> [return: bb29, unwind terminate(cleanup)]; + } + + bb14 (cleanup): { + drop(_10) -> [return: bb15, unwind terminate(cleanup)]; + } + + bb15 (cleanup): { + drop(_11) -> [return: bb28, unwind terminate(cleanup)]; + } + + bb16 (cleanup): { + drop(_10) -> [return: bb17, unwind terminate(cleanup)]; + } + + bb17 (cleanup): { + drop(_11) -> [return: bb27, unwind terminate(cleanup)]; + } + + bb18 (cleanup): { +- drop(_10) -> [return: bb19, unwind terminate(cleanup)]; ++ goto -> bb19; + } + + bb19 (cleanup): { +- drop(_11) -> [return: bb26, unwind terminate(cleanup)]; ++ goto -> bb26; + } + + bb20 (cleanup): { + drop(_10) -> [return: bb21, unwind terminate(cleanup)]; + } + + bb21 (cleanup): { + drop(_11) -> [return: bb25, unwind terminate(cleanup)]; + } + + bb22 (cleanup): { + drop(_10) -> [return: bb24, unwind terminate(cleanup)]; + } + + bb23 (cleanup): { +- drop(_9) -> [return: bb24, unwind terminate(cleanup)]; ++ goto -> bb24; + } + + bb24 (cleanup): { + drop(_7) -> [return: bb25, unwind terminate(cleanup)]; + } + + bb25 (cleanup): { +- drop(_6) -> [return: bb26, unwind terminate(cleanup)]; ++ goto -> bb31; + } + + bb26 (cleanup): { + drop(_4) -> [return: bb27, unwind terminate(cleanup)]; + } + + bb27 (cleanup): { + drop(_2) -> [return: bb28, unwind terminate(cleanup)]; + } + + bb28 (cleanup): { + drop(_1) -> [return: bb29, unwind terminate(cleanup)]; + } + + bb29 (cleanup): { + resume; ++ } ++ ++ bb30 (cleanup): { ++ drop(_6) -> [return: bb26, unwind terminate(cleanup)]; ++ } ++ ++ bb31 (cleanup): { ++ switchInt(_12) -> [0: bb26, otherwise: bb30]; + } + } + diff --git a/tests/mir-opt/tail_call_drops.f_with_arg.ElaborateDrops.panic-unwind.diff b/tests/mir-opt/tail_call_drops.f_with_arg.ElaborateDrops.panic-unwind.diff new file mode 100644 index 0000000000000..c7df2bb2207fb --- /dev/null +++ b/tests/mir-opt/tail_call_drops.f_with_arg.ElaborateDrops.panic-unwind.diff @@ -0,0 +1,184 @@ +- // MIR for `f_with_arg` before ElaborateDrops ++ // MIR for `f_with_arg` after ElaborateDrops + + fn f_with_arg(_1: String, _2: String) -> () { + debug _arg1 => _1; + debug _arg2 => _2; + let mut _0: (); + let mut _3: !; + let _4: std::string::String; + let _8: (); + let mut _9: std::string::String; + let mut _10: std::string::String; + let mut _11: std::string::String; ++ let mut _12: bool; + scope 1 { + debug _a => _4; + let _5: i32; + scope 2 { + debug _b => _5; + let _6: std::string::String; + scope 3 { + debug _c => _6; + let _7: std::string::String; + scope 4 { + debug _d => _7; + } + } + } + } + + bb0: { ++ _12 = const false; + StorageLive(_4); + _4 = String::new() -> [return: bb1, unwind: bb27]; + } + + bb1: { + StorageLive(_5); + _5 = const 12_i32; + StorageLive(_6); + _6 = String::new() -> [return: bb2, unwind: bb26]; + } + + bb2: { ++ _12 = const true; + StorageLive(_7); + _7 = String::new() -> [return: bb3, unwind: bb25]; + } + + bb3: { + StorageLive(_8); + StorageLive(_9); ++ _12 = const false; + _9 = move _6; + _8 = std::mem::drop::(move _9) -> [return: bb4, unwind: bb23]; + } + + bb4: { + StorageDead(_9); + StorageDead(_8); + StorageLive(_10); + _10 = String::new() -> [return: bb5, unwind: bb24]; + } + + bb5: { + StorageLive(_11); + _11 = String::new() -> [return: bb6, unwind: bb22]; + } + + bb6: { + drop(_7) -> [return: bb7, unwind: bb20]; + } + + bb7: { + StorageDead(_7); +- drop(_6) -> [return: bb8, unwind: bb18]; ++ goto -> bb8; + } + + bb8: { ++ _12 = const false; + StorageDead(_6); + StorageDead(_5); + drop(_4) -> [return: bb9, unwind: bb16]; + } + + bb9: { + StorageDead(_4); + drop(_2) -> [return: bb10, unwind: bb14]; + } + + bb10: { + drop(_1) -> [return: bb11, unwind: bb12]; + } + + bb11: { + tailcall g_with_arg(Spanned { node: move _10, span: $DIR/tail_call_drops.rs:36:23: 36:36 (#0) }, Spanned { node: move _11, span: $DIR/tail_call_drops.rs:36:38: 36:51 (#0) }); + } + + bb12 (cleanup): { + drop(_10) -> [return: bb13, unwind terminate(cleanup)]; + } + + bb13 (cleanup): { + drop(_11) -> [return: bb29, unwind terminate(cleanup)]; + } + + bb14 (cleanup): { + drop(_10) -> [return: bb15, unwind terminate(cleanup)]; + } + + bb15 (cleanup): { + drop(_11) -> [return: bb28, unwind terminate(cleanup)]; + } + + bb16 (cleanup): { + drop(_10) -> [return: bb17, unwind terminate(cleanup)]; + } + + bb17 (cleanup): { + drop(_11) -> [return: bb27, unwind terminate(cleanup)]; + } + + bb18 (cleanup): { +- drop(_10) -> [return: bb19, unwind terminate(cleanup)]; ++ goto -> bb19; + } + + bb19 (cleanup): { +- drop(_11) -> [return: bb26, unwind terminate(cleanup)]; ++ goto -> bb26; + } + + bb20 (cleanup): { + drop(_10) -> [return: bb21, unwind terminate(cleanup)]; + } + + bb21 (cleanup): { + drop(_11) -> [return: bb25, unwind terminate(cleanup)]; + } + + bb22 (cleanup): { + drop(_10) -> [return: bb24, unwind terminate(cleanup)]; + } + + bb23 (cleanup): { +- drop(_9) -> [return: bb24, unwind terminate(cleanup)]; ++ goto -> bb24; + } + + bb24 (cleanup): { + drop(_7) -> [return: bb25, unwind terminate(cleanup)]; + } + + bb25 (cleanup): { +- drop(_6) -> [return: bb26, unwind terminate(cleanup)]; ++ goto -> bb31; + } + + bb26 (cleanup): { + drop(_4) -> [return: bb27, unwind terminate(cleanup)]; + } + + bb27 (cleanup): { + drop(_2) -> [return: bb28, unwind terminate(cleanup)]; + } + + bb28 (cleanup): { + drop(_1) -> [return: bb29, unwind terminate(cleanup)]; + } + + bb29 (cleanup): { + resume; ++ } ++ ++ bb30 (cleanup): { ++ drop(_6) -> [return: bb26, unwind terminate(cleanup)]; ++ } ++ ++ bb31 (cleanup): { ++ switchInt(_12) -> [0: bb26, otherwise: bb30]; + } + } + diff --git a/tests/mir-opt/tail_call_drops.f_with_arg.built.after.panic-abort.mir b/tests/mir-opt/tail_call_drops.f_with_arg.built.after.panic-abort.mir new file mode 100644 index 0000000000000..744f1989acc92 --- /dev/null +++ b/tests/mir-opt/tail_call_drops.f_with_arg.built.after.panic-abort.mir @@ -0,0 +1,202 @@ +// MIR for `f_with_arg` after built + +fn f_with_arg(_1: String, _2: String) -> () { + debug _arg1 => _1; + debug _arg2 => _2; + let mut _0: (); + let mut _3: !; + let _4: std::string::String; + let _8: (); + let mut _9: std::string::String; + let mut _10: std::string::String; + let mut _11: std::string::String; + scope 1 { + debug _a => _4; + let _5: i32; + scope 2 { + debug _b => _5; + let _6: std::string::String; + scope 3 { + debug _c => _6; + let _7: std::string::String; + scope 4 { + debug _d => _7; + } + } + } + } + + bb0: { + StorageLive(_4); + _4 = String::new() -> [return: bb1, unwind: bb34]; + } + + bb1: { + FakeRead(ForLet(None), _4); + StorageLive(_5); + _5 = const 12_i32; + FakeRead(ForLet(None), _5); + StorageLive(_6); + _6 = String::new() -> [return: bb2, unwind: bb33]; + } + + bb2: { + FakeRead(ForLet(None), _6); + StorageLive(_7); + _7 = String::new() -> [return: bb3, unwind: bb32]; + } + + bb3: { + FakeRead(ForLet(None), _7); + StorageLive(_8); + StorageLive(_9); + _9 = move _6; + _8 = std::mem::drop::(move _9) -> [return: bb4, unwind: bb30]; + } + + bb4: { + StorageDead(_9); + StorageDead(_8); + StorageLive(_10); + _10 = String::new() -> [return: bb5, unwind: bb31]; + } + + bb5: { + StorageLive(_11); + _11 = String::new() -> [return: bb6, unwind: bb29]; + } + + bb6: { + drop(_7) -> [return: bb7, unwind: bb27]; + } + + bb7: { + StorageDead(_7); + drop(_6) -> [return: bb8, unwind: bb25]; + } + + bb8: { + StorageDead(_6); + StorageDead(_5); + drop(_4) -> [return: bb9, unwind: bb23]; + } + + bb9: { + StorageDead(_4); + drop(_2) -> [return: bb10, unwind: bb21]; + } + + bb10: { + drop(_1) -> [return: bb11, unwind: bb19]; + } + + bb11: { + tailcall g_with_arg(Spanned { node: move _10, span: $DIR/tail_call_drops.rs:36:23: 36:36 (#0) }, Spanned { node: move _11, span: $DIR/tail_call_drops.rs:36:38: 36:51 (#0) }); + } + + bb12: { + StorageDead(_11); + StorageDead(_10); + drop(_7) -> [return: bb13, unwind: bb32]; + } + + bb13: { + StorageDead(_7); + drop(_6) -> [return: bb14, unwind: bb33]; + } + + bb14: { + StorageDead(_6); + StorageDead(_5); + drop(_4) -> [return: bb15, unwind: bb34]; + } + + bb15: { + StorageDead(_4); + unreachable; + } + + bb16: { + drop(_2) -> [return: bb17, unwind: bb35]; + } + + bb17: { + drop(_1) -> [return: bb18, unwind: bb36]; + } + + bb18: { + return; + } + + bb19 (cleanup): { + drop(_10) -> [return: bb20, unwind terminate(cleanup)]; + } + + bb20 (cleanup): { + drop(_11) -> [return: bb36, unwind terminate(cleanup)]; + } + + bb21 (cleanup): { + drop(_10) -> [return: bb22, unwind terminate(cleanup)]; + } + + bb22 (cleanup): { + drop(_11) -> [return: bb35, unwind terminate(cleanup)]; + } + + bb23 (cleanup): { + drop(_10) -> [return: bb24, unwind terminate(cleanup)]; + } + + bb24 (cleanup): { + drop(_11) -> [return: bb34, unwind terminate(cleanup)]; + } + + bb25 (cleanup): { + drop(_10) -> [return: bb26, unwind terminate(cleanup)]; + } + + bb26 (cleanup): { + drop(_11) -> [return: bb33, unwind terminate(cleanup)]; + } + + bb27 (cleanup): { + drop(_10) -> [return: bb28, unwind terminate(cleanup)]; + } + + bb28 (cleanup): { + drop(_11) -> [return: bb32, unwind terminate(cleanup)]; + } + + bb29 (cleanup): { + drop(_10) -> [return: bb31, unwind terminate(cleanup)]; + } + + bb30 (cleanup): { + drop(_9) -> [return: bb31, unwind terminate(cleanup)]; + } + + bb31 (cleanup): { + drop(_7) -> [return: bb32, unwind terminate(cleanup)]; + } + + bb32 (cleanup): { + drop(_6) -> [return: bb33, unwind terminate(cleanup)]; + } + + bb33 (cleanup): { + drop(_4) -> [return: bb34, unwind terminate(cleanup)]; + } + + bb34 (cleanup): { + drop(_2) -> [return: bb35, unwind terminate(cleanup)]; + } + + bb35 (cleanup): { + drop(_1) -> [return: bb36, unwind terminate(cleanup)]; + } + + bb36 (cleanup): { + resume; + } +} diff --git a/tests/mir-opt/tail_call_drops.f_with_arg.built.after.panic-unwind.mir b/tests/mir-opt/tail_call_drops.f_with_arg.built.after.panic-unwind.mir new file mode 100644 index 0000000000000..744f1989acc92 --- /dev/null +++ b/tests/mir-opt/tail_call_drops.f_with_arg.built.after.panic-unwind.mir @@ -0,0 +1,202 @@ +// MIR for `f_with_arg` after built + +fn f_with_arg(_1: String, _2: String) -> () { + debug _arg1 => _1; + debug _arg2 => _2; + let mut _0: (); + let mut _3: !; + let _4: std::string::String; + let _8: (); + let mut _9: std::string::String; + let mut _10: std::string::String; + let mut _11: std::string::String; + scope 1 { + debug _a => _4; + let _5: i32; + scope 2 { + debug _b => _5; + let _6: std::string::String; + scope 3 { + debug _c => _6; + let _7: std::string::String; + scope 4 { + debug _d => _7; + } + } + } + } + + bb0: { + StorageLive(_4); + _4 = String::new() -> [return: bb1, unwind: bb34]; + } + + bb1: { + FakeRead(ForLet(None), _4); + StorageLive(_5); + _5 = const 12_i32; + FakeRead(ForLet(None), _5); + StorageLive(_6); + _6 = String::new() -> [return: bb2, unwind: bb33]; + } + + bb2: { + FakeRead(ForLet(None), _6); + StorageLive(_7); + _7 = String::new() -> [return: bb3, unwind: bb32]; + } + + bb3: { + FakeRead(ForLet(None), _7); + StorageLive(_8); + StorageLive(_9); + _9 = move _6; + _8 = std::mem::drop::(move _9) -> [return: bb4, unwind: bb30]; + } + + bb4: { + StorageDead(_9); + StorageDead(_8); + StorageLive(_10); + _10 = String::new() -> [return: bb5, unwind: bb31]; + } + + bb5: { + StorageLive(_11); + _11 = String::new() -> [return: bb6, unwind: bb29]; + } + + bb6: { + drop(_7) -> [return: bb7, unwind: bb27]; + } + + bb7: { + StorageDead(_7); + drop(_6) -> [return: bb8, unwind: bb25]; + } + + bb8: { + StorageDead(_6); + StorageDead(_5); + drop(_4) -> [return: bb9, unwind: bb23]; + } + + bb9: { + StorageDead(_4); + drop(_2) -> [return: bb10, unwind: bb21]; + } + + bb10: { + drop(_1) -> [return: bb11, unwind: bb19]; + } + + bb11: { + tailcall g_with_arg(Spanned { node: move _10, span: $DIR/tail_call_drops.rs:36:23: 36:36 (#0) }, Spanned { node: move _11, span: $DIR/tail_call_drops.rs:36:38: 36:51 (#0) }); + } + + bb12: { + StorageDead(_11); + StorageDead(_10); + drop(_7) -> [return: bb13, unwind: bb32]; + } + + bb13: { + StorageDead(_7); + drop(_6) -> [return: bb14, unwind: bb33]; + } + + bb14: { + StorageDead(_6); + StorageDead(_5); + drop(_4) -> [return: bb15, unwind: bb34]; + } + + bb15: { + StorageDead(_4); + unreachable; + } + + bb16: { + drop(_2) -> [return: bb17, unwind: bb35]; + } + + bb17: { + drop(_1) -> [return: bb18, unwind: bb36]; + } + + bb18: { + return; + } + + bb19 (cleanup): { + drop(_10) -> [return: bb20, unwind terminate(cleanup)]; + } + + bb20 (cleanup): { + drop(_11) -> [return: bb36, unwind terminate(cleanup)]; + } + + bb21 (cleanup): { + drop(_10) -> [return: bb22, unwind terminate(cleanup)]; + } + + bb22 (cleanup): { + drop(_11) -> [return: bb35, unwind terminate(cleanup)]; + } + + bb23 (cleanup): { + drop(_10) -> [return: bb24, unwind terminate(cleanup)]; + } + + bb24 (cleanup): { + drop(_11) -> [return: bb34, unwind terminate(cleanup)]; + } + + bb25 (cleanup): { + drop(_10) -> [return: bb26, unwind terminate(cleanup)]; + } + + bb26 (cleanup): { + drop(_11) -> [return: bb33, unwind terminate(cleanup)]; + } + + bb27 (cleanup): { + drop(_10) -> [return: bb28, unwind terminate(cleanup)]; + } + + bb28 (cleanup): { + drop(_11) -> [return: bb32, unwind terminate(cleanup)]; + } + + bb29 (cleanup): { + drop(_10) -> [return: bb31, unwind terminate(cleanup)]; + } + + bb30 (cleanup): { + drop(_9) -> [return: bb31, unwind terminate(cleanup)]; + } + + bb31 (cleanup): { + drop(_7) -> [return: bb32, unwind terminate(cleanup)]; + } + + bb32 (cleanup): { + drop(_6) -> [return: bb33, unwind terminate(cleanup)]; + } + + bb33 (cleanup): { + drop(_4) -> [return: bb34, unwind terminate(cleanup)]; + } + + bb34 (cleanup): { + drop(_2) -> [return: bb35, unwind terminate(cleanup)]; + } + + bb35 (cleanup): { + drop(_1) -> [return: bb36, unwind terminate(cleanup)]; + } + + bb36 (cleanup): { + resume; + } +} diff --git a/tests/mir-opt/tail_call_drops.rs b/tests/mir-opt/tail_call_drops.rs new file mode 100644 index 0000000000000..56f4852a95f4b --- /dev/null +++ b/tests/mir-opt/tail_call_drops.rs @@ -0,0 +1,41 @@ +// skip-filecheck +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY +#![allow(incomplete_features)] +#![feature(explicit_tail_calls)] + +// EMIT_MIR tail_call_drops.f.built.after.mir +// Expected result: +// drop(_d) -> drop(_c) -> drop(_a) -> tailcall g() +// +// EMIT_MIR tail_call_drops.f.ElaborateDrops.diff +// Expected result: +// drop(_d) -> drop(_a) -> tailcall g() +fn f() { + let _a = String::new(); + let _b = 12; + let _c = String::new(); + let _d = String::new(); + + drop(_c); + + become g(); +} + +fn g() {} + +// EMIT_MIR tail_call_drops.f_with_arg.built.after.mir +// EMIT_MIR tail_call_drops.f_with_arg.ElaborateDrops.diff +fn f_with_arg(_arg1: String, _arg2: String) { + let _a = String::new(); + let _b = 12; + let _c = String::new(); + let _d = String::new(); + + drop(_c); + + become g_with_arg(String::new(), String::new()); +} + +fn g_with_arg(_arg1: String, _arg2: String) {} + +fn main() {} diff --git a/tests/ui/explicit-tail-calls/drop-order.rs b/tests/ui/explicit-tail-calls/drop-order.rs new file mode 100644 index 0000000000000..e20730446ec55 --- /dev/null +++ b/tests/ui/explicit-tail-calls/drop-order.rs @@ -0,0 +1,70 @@ +// FIXME(explicit_tail_calls): enable this test once rustc_codegen_ssa supports tail calls +//@ ignore-test: tail calls are not implemented in rustc_codegen_ssa yet, so this causes 🧊 +//@ run-pass +#![allow(incomplete_features)] +#![feature(explicit_tail_calls)] +use std::cell::RefCell; + +fn main() { + let tail_counter = Default::default(); + tail_recursive(0, &tail_counter); + assert_eq!(tail_counter.into_inner(), (0..128).collect::>()); + + let simply_counter = Default::default(); + simply_recursive(0, &simply_counter); + assert_eq!(simply_counter.into_inner(), (0..128).rev().collect::>()); + + let scope_counter = Default::default(); + out_of_inner_scope(&scope_counter); + assert_eq!(scope_counter.into_inner(), (0..8).collect::>()); +} + +fn tail_recursive(n: u8, order: &RefCell>) { + if n >= 128 { + return; + } + + let _local = DropCounter(n, order); + + become tail_recursive(n + 1, order) +} + +fn simply_recursive(n: u8, order: &RefCell>) { + if n >= 128 { + return; + } + + let _local = DropCounter(n, order); + + return simply_recursive(n + 1, order); +} + +fn out_of_inner_scope(order: &RefCell>) { + fn inner(order: &RefCell>) { + let _7 = DropCounter(7, order); + let _6 = DropCounter(6, order); + } + + let _5 = DropCounter(5, order); + let _4 = DropCounter(4, order); + + if true { + let _3 = DropCounter(3, order); + let _2 = DropCounter(2, order); + loop { + let _1 = DropCounter(1, order); + let _0 = DropCounter(0, order); + + become inner(order); + } + } +} + +struct DropCounter<'a>(u8, &'a RefCell>); + +impl Drop for DropCounter<'_> { + #[track_caller] + fn drop(&mut self) { + self.1.borrow_mut().push(self.0); + } +} From 3b5a5ee6c8b2b055e772de2163379d99e0d463df Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Wed, 28 Jun 2023 15:34:10 +0000 Subject: [PATCH 803/892] Support tail calls in the interpreter --- .../src/interpret/terminator.rs | 72 ++++++++++++++++++- .../ctfe-arg-bad-borrow.rs | 14 ++++ .../ctfe-arg-bad-borrow.stderr | 14 ++++ .../ctfe-arg-good-borrow.rs | 13 ++++ tests/ui/explicit-tail-calls/ctfe-arg-move.rs | 15 ++++ .../ctfe-collatz-multi-rec.rs | 43 +++++++++++ .../ctfe-id-unlimited.return.stderr | 36 ++++++++++ .../explicit-tail-calls/ctfe-id-unlimited.rs | 35 +++++++++ .../ctfe-tail-call-panic.rs | 19 +++++ .../ctfe-tail-call-panic.stderr | 21 ++++++ 10 files changed, 281 insertions(+), 1 deletion(-) create mode 100644 tests/ui/explicit-tail-calls/ctfe-arg-bad-borrow.rs create mode 100644 tests/ui/explicit-tail-calls/ctfe-arg-bad-borrow.stderr create mode 100644 tests/ui/explicit-tail-calls/ctfe-arg-good-borrow.rs create mode 100644 tests/ui/explicit-tail-calls/ctfe-arg-move.rs create mode 100644 tests/ui/explicit-tail-calls/ctfe-collatz-multi-rec.rs create mode 100644 tests/ui/explicit-tail-calls/ctfe-id-unlimited.return.stderr create mode 100644 tests/ui/explicit-tail-calls/ctfe-id-unlimited.rs create mode 100644 tests/ui/explicit-tail-calls/ctfe-tail-call-panic.rs create mode 100644 tests/ui/explicit-tail-calls/ctfe-tail-call-panic.stderr diff --git a/compiler/rustc_const_eval/src/interpret/terminator.rs b/compiler/rustc_const_eval/src/interpret/terminator.rs index 7d1a48d6ded6f..d77bcdd709731 100644 --- a/compiler/rustc_const_eval/src/interpret/terminator.rs +++ b/compiler/rustc_const_eval/src/interpret/terminator.rs @@ -172,7 +172,77 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { } } - TailCall { func: _, args: _, fn_span: _ } => todo!(), + TailCall { ref func, ref args, fn_span: _ } => { + // FIXME(explicit_tail_calls): a lot of code here is duplicated with normal calls, can we refactor this? + let old_frame_idx = self.frame_idx(); + let func = self.eval_operand(func, None)?; + let args = self.eval_fn_call_arguments(args)?; + + let fn_sig_binder = func.layout.ty.fn_sig(*self.tcx); + let fn_sig = + self.tcx.normalize_erasing_late_bound_regions(self.param_env, fn_sig_binder); + let extra_args = &args[fn_sig.inputs().len()..]; + let extra_args = + self.tcx.mk_type_list_from_iter(extra_args.iter().map(|arg| arg.layout().ty)); + + let (fn_val, fn_abi, with_caller_location) = match *func.layout.ty.kind() { + ty::FnPtr(_sig) => { + let fn_ptr = self.read_pointer(&func)?; + let fn_val = self.get_ptr_fn(fn_ptr)?; + (fn_val, self.fn_abi_of_fn_ptr(fn_sig_binder, extra_args)?, false) + } + ty::FnDef(def_id, substs) => { + let instance = self.resolve(def_id, substs)?; + ( + FnVal::Instance(instance), + self.fn_abi_of_instance(instance, extra_args)?, + instance.def.requires_caller_location(*self.tcx), + ) + } + _ => span_bug!( + terminator.source_info.span, + "invalid callee of type {:?}", + func.layout.ty + ), + }; + + // This is the "canonical" implementation of tails calls, + // a pop of the current stack frame, followed by a normal call + // which pushes a new stack frame, with the return address from + // the popped stack frame. + // + // Note that we can't use `pop_stack_frame` as it "executes" + // the goto to the return block, but we don't want to, + // only the tail called function should return to the current + // return block. + let Some(prev_frame) = self.stack_mut().pop() else { + span_bug!( + terminator.source_info.span, + "empty stack while evaluating this tail call" + ) + }; + + let StackPopCleanup::Goto { ret, unwind } = prev_frame.return_to_block else { + span_bug!(terminator.source_info.span, "tail call with the root stack frame") + }; + + self.eval_fn_call( + fn_val, + (fn_sig.abi, fn_abi), + &args, + with_caller_location, + &prev_frame.return_place, + ret, + unwind, + )?; + + if self.frame_idx() != old_frame_idx { + span_bug!( + terminator.source_info.span, + "evaluating this tail call pushed a new stack frame" + ); + } + } Drop { place, target, unwind, replace: _ } => { let place = self.eval_place(place)?; diff --git a/tests/ui/explicit-tail-calls/ctfe-arg-bad-borrow.rs b/tests/ui/explicit-tail-calls/ctfe-arg-bad-borrow.rs new file mode 100644 index 0000000000000..5a105ee4eb59d --- /dev/null +++ b/tests/ui/explicit-tail-calls/ctfe-arg-bad-borrow.rs @@ -0,0 +1,14 @@ +#![allow(incomplete_features)] +#![feature(explicit_tail_calls)] + +pub const fn test(_: &Type) { + const fn takes_borrow(_: &Type) {} + + let local = Type; + become takes_borrow(&local); + //~^ error: `local` does not live long enough +} + +struct Type; + +fn main() {} diff --git a/tests/ui/explicit-tail-calls/ctfe-arg-bad-borrow.stderr b/tests/ui/explicit-tail-calls/ctfe-arg-bad-borrow.stderr new file mode 100644 index 0000000000000..75fb13c378c24 --- /dev/null +++ b/tests/ui/explicit-tail-calls/ctfe-arg-bad-borrow.stderr @@ -0,0 +1,14 @@ +error[E0597]: `local` does not live long enough + --> $DIR/ctfe-arg-bad-borrow.rs:8:25 + | +LL | let local = Type; + | ----- binding `local` declared here +LL | become takes_borrow(&local); + | ^^^^^^ borrowed value does not live long enough +LL | +LL | } + | - `local` dropped here while still borrowed + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0597`. diff --git a/tests/ui/explicit-tail-calls/ctfe-arg-good-borrow.rs b/tests/ui/explicit-tail-calls/ctfe-arg-good-borrow.rs new file mode 100644 index 0000000000000..50bf6c946ca8f --- /dev/null +++ b/tests/ui/explicit-tail-calls/ctfe-arg-good-borrow.rs @@ -0,0 +1,13 @@ +//@ check-pass +#![allow(incomplete_features)] +#![feature(explicit_tail_calls)] + +pub const fn test(x: &Type) { + const fn takes_borrow(_: &Type) {} + + become takes_borrow(x); +} + +pub struct Type; + +fn main() {} diff --git a/tests/ui/explicit-tail-calls/ctfe-arg-move.rs b/tests/ui/explicit-tail-calls/ctfe-arg-move.rs new file mode 100644 index 0000000000000..88ff3a4a5ad13 --- /dev/null +++ b/tests/ui/explicit-tail-calls/ctfe-arg-move.rs @@ -0,0 +1,15 @@ +//@ check-pass +#![allow(incomplete_features)] +#![feature(explicit_tail_calls)] + +pub const fn test(s: String) -> String { + const fn takes_string(s: String) -> String { + s + } + + become takes_string(s); +} + +struct Type; + +fn main() {} diff --git a/tests/ui/explicit-tail-calls/ctfe-collatz-multi-rec.rs b/tests/ui/explicit-tail-calls/ctfe-collatz-multi-rec.rs new file mode 100644 index 0000000000000..2e6bb0e1ac5b7 --- /dev/null +++ b/tests/ui/explicit-tail-calls/ctfe-collatz-multi-rec.rs @@ -0,0 +1,43 @@ +//@ run-pass +#![allow(incomplete_features)] +#![feature(explicit_tail_calls)] + +/// A very unnecessarily complicated "implementation" of the callatz conjecture. +/// Returns the number of steps to reach `1`. +/// +/// This is just a test for tail calls, which involves multiple functions calling each other. +/// +/// Panics if `x == 0`. +const fn collatz(x: u32) -> u32 { + assert!(x > 0); + + const fn switch(x: u32, steps: u32) -> u32 { + match x { + 1 => steps, + _ if x & 1 == 0 => become div2(x, steps + 1), + _ => become mul3plus1(x, steps + 1), + } + } + + const fn div2(x: u32, steps: u32) -> u32 { + become switch(x >> 1, steps) + } + + const fn mul3plus1(x: u32, steps: u32) -> u32 { + become switch(3 * x + 1, steps) + } + + switch(x, 0) +} + +const ASSERTS: () = { + assert!(collatz(1) == 0); + assert!(collatz(2) == 1); + assert!(collatz(3) == 7); + assert!(collatz(4) == 2); + assert!(collatz(6171) == 261); +}; + +fn main() { + let _ = ASSERTS; +} diff --git a/tests/ui/explicit-tail-calls/ctfe-id-unlimited.return.stderr b/tests/ui/explicit-tail-calls/ctfe-id-unlimited.return.stderr new file mode 100644 index 0000000000000..4a1e50b4111e3 --- /dev/null +++ b/tests/ui/explicit-tail-calls/ctfe-id-unlimited.return.stderr @@ -0,0 +1,36 @@ +error[E0080]: evaluation of constant value failed + --> $DIR/ctfe-id-unlimited.rs:17:42 + | +LL | #[cfg(r#return)] _ => return inner(acc + 1, n - 1), + | ^^^^^^^^^^^^^^^^^^^^^ reached the configured maximum number of stack frames + | +note: inside `inner` + --> $DIR/ctfe-id-unlimited.rs:17:42 + | +LL | #[cfg(r#return)] _ => return inner(acc + 1, n - 1), + | ^^^^^^^^^^^^^^^^^^^^^ +note: [... 125 additional calls inside `inner` ...] + --> $DIR/ctfe-id-unlimited.rs:17:42 + | +LL | #[cfg(r#return)] _ => return inner(acc + 1, n - 1), + | ^^^^^^^^^^^^^^^^^^^^^ +note: inside `rec_id` + --> $DIR/ctfe-id-unlimited.rs:22:5 + | +LL | inner(0, n) + | ^^^^^^^^^^^ +note: inside `ID_ED` + --> $DIR/ctfe-id-unlimited.rs:29:20 + | +LL | const ID_ED: u32 = rec_id(ORIGINAL); + | ^^^^^^^^^^^^^^^^ + +note: erroneous constant encountered + --> $DIR/ctfe-id-unlimited.rs:31:40 + | +LL | const ASSERT: () = assert!(ORIGINAL == ID_ED); + | ^^^^^ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/explicit-tail-calls/ctfe-id-unlimited.rs b/tests/ui/explicit-tail-calls/ctfe-id-unlimited.rs new file mode 100644 index 0000000000000..54e68b2b7f793 --- /dev/null +++ b/tests/ui/explicit-tail-calls/ctfe-id-unlimited.rs @@ -0,0 +1,35 @@ +//@ revisions: become return +//@ [become] run-pass +#![allow(incomplete_features)] +#![feature(explicit_tail_calls)] + +// This is an identity function (`|x| x`), but implemented using recursion. +// Each step we increment accumulator and decrement the number. +// +// With normal calls this fails compilation because of the recursion limit, +// but with tail calls/`become` we don't grow the stack/spend recursion limit +// so this should compile. +const fn rec_id(n: u32) -> u32 { + const fn inner(acc: u32, n: u32) -> u32 { + match n { + 0 => acc, + #[cfg(r#become)] _ => become inner(acc + 1, n - 1), + #[cfg(r#return)] _ => return inner(acc + 1, n - 1), + //[return]~^ error: evaluation of constant value failed + } + } + + inner(0, n) +} + +// Some relatively big number that is higher than recursion limit +const ORIGINAL: u32 = 12345; +// Original number, but with identity function applied +// (this is the same, but requires execution of the recursion) +const ID_ED: u32 = rec_id(ORIGINAL); +// Assert to make absolutely sure the computation actually happens +const ASSERT: () = assert!(ORIGINAL == ID_ED); + +fn main() { + let _ = ASSERT; +} diff --git a/tests/ui/explicit-tail-calls/ctfe-tail-call-panic.rs b/tests/ui/explicit-tail-calls/ctfe-tail-call-panic.rs new file mode 100644 index 0000000000000..3d69cde29895a --- /dev/null +++ b/tests/ui/explicit-tail-calls/ctfe-tail-call-panic.rs @@ -0,0 +1,19 @@ +#![allow(incomplete_features)] +#![feature(explicit_tail_calls)] + +pub const fn f() { + become g(); +} + +const fn g() { + panic!() + //~^ error: evaluation of constant value failed + //~| note: in this expansion of panic! + //~| note: inside `g` + //~| note: in this expansion of panic! +} + +const _: () = f(); +//~^ note: inside `_` + +fn main() {} diff --git a/tests/ui/explicit-tail-calls/ctfe-tail-call-panic.stderr b/tests/ui/explicit-tail-calls/ctfe-tail-call-panic.stderr new file mode 100644 index 0000000000000..8c07051210578 --- /dev/null +++ b/tests/ui/explicit-tail-calls/ctfe-tail-call-panic.stderr @@ -0,0 +1,21 @@ +error[E0080]: evaluation of constant value failed + --> $DIR/ctfe-tail-call-panic.rs:9:5 + | +LL | panic!() + | ^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/ctfe-tail-call-panic.rs:9:5 + | +note: inside `g` + --> $DIR/ctfe-tail-call-panic.rs:9:5 + | +LL | panic!() + | ^^^^^^^^ +note: inside `_` + --> $DIR/ctfe-tail-call-panic.rs:16:15 + | +LL | const _: () = f(); + | ^^^ + = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0080`. From 45c70318f796cb20f47120ebe9de66919f948f91 Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Fri, 30 Jun 2023 18:27:43 +0000 Subject: [PATCH 804/892] Refactor common part of evaluating `Call`&`TailCall` in the interpreter --- .../src/interpret/terminator.rs | 119 +++++++++--------- 1 file changed, 56 insertions(+), 63 deletions(-) diff --git a/compiler/rustc_const_eval/src/interpret/terminator.rs b/compiler/rustc_const_eval/src/interpret/terminator.rs index d77bcdd709731..6644e70e039a8 100644 --- a/compiler/rustc_const_eval/src/interpret/terminator.rs +++ b/compiler/rustc_const_eval/src/interpret/terminator.rs @@ -47,6 +47,15 @@ impl<'tcx, Prov: Provenance> FnArg<'tcx, Prov> { } } +struct EvaluatedCalleeAndArgs<'tcx, M: Machine<'tcx>> { + callee: FnVal<'tcx, M::ExtraFnVal>, + args: Vec>, + fn_sig: ty::FnSig<'tcx>, + fn_abi: &'tcx FnAbi<'tcx, Ty<'tcx>>, + /// True if the function is marked as `#[track_caller]` ([`ty::InstanceDef::requires_caller_location`]) + with_caller_location: bool, +} + impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { /// Make a copy of the given fn_arg. Any `InPlace` are degenerated to copies, no protection of the /// original memory occurs. @@ -124,40 +133,13 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { } => { let old_stack = self.frame_idx(); let old_loc = self.frame().loc; - let func = self.eval_operand(func, None)?; - let args = self.eval_fn_call_arguments(args)?; - - let fn_sig_binder = func.layout.ty.fn_sig(*self.tcx); - let fn_sig = - self.tcx.normalize_erasing_late_bound_regions(self.param_env, fn_sig_binder); - let extra_args = &args[fn_sig.inputs().len()..]; - let extra_args = - self.tcx.mk_type_list_from_iter(extra_args.iter().map(|arg| arg.layout().ty)); - - let (fn_val, fn_abi, with_caller_location) = match *func.layout.ty.kind() { - ty::FnPtr(_sig) => { - let fn_ptr = self.read_pointer(&func)?; - let fn_val = self.get_ptr_fn(fn_ptr)?; - (fn_val, self.fn_abi_of_fn_ptr(fn_sig_binder, extra_args)?, false) - } - ty::FnDef(def_id, args) => { - let instance = self.resolve(def_id, args)?; - ( - FnVal::Instance(instance), - self.fn_abi_of_instance(instance, extra_args)?, - instance.def.requires_caller_location(*self.tcx), - ) - } - _ => span_bug!( - terminator.source_info.span, - "invalid callee of type {}", - func.layout.ty - ), - }; + + let EvaluatedCalleeAndArgs { callee, args, fn_sig, fn_abi, with_caller_location } = + self.eval_callee_and_args(terminator, func, args)?; let destination = self.force_allocation(&self.eval_place(destination)?)?; self.eval_fn_call( - fn_val, + callee, (fn_sig.abi, fn_abi), &args, with_caller_location, @@ -173,38 +155,10 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { } TailCall { ref func, ref args, fn_span: _ } => { - // FIXME(explicit_tail_calls): a lot of code here is duplicated with normal calls, can we refactor this? let old_frame_idx = self.frame_idx(); - let func = self.eval_operand(func, None)?; - let args = self.eval_fn_call_arguments(args)?; - - let fn_sig_binder = func.layout.ty.fn_sig(*self.tcx); - let fn_sig = - self.tcx.normalize_erasing_late_bound_regions(self.param_env, fn_sig_binder); - let extra_args = &args[fn_sig.inputs().len()..]; - let extra_args = - self.tcx.mk_type_list_from_iter(extra_args.iter().map(|arg| arg.layout().ty)); - - let (fn_val, fn_abi, with_caller_location) = match *func.layout.ty.kind() { - ty::FnPtr(_sig) => { - let fn_ptr = self.read_pointer(&func)?; - let fn_val = self.get_ptr_fn(fn_ptr)?; - (fn_val, self.fn_abi_of_fn_ptr(fn_sig_binder, extra_args)?, false) - } - ty::FnDef(def_id, substs) => { - let instance = self.resolve(def_id, substs)?; - ( - FnVal::Instance(instance), - self.fn_abi_of_instance(instance, extra_args)?, - instance.def.requires_caller_location(*self.tcx), - ) - } - _ => span_bug!( - terminator.source_info.span, - "invalid callee of type {:?}", - func.layout.ty - ), - }; + + let EvaluatedCalleeAndArgs { callee, args, fn_sig, fn_abi, with_caller_location } = + self.eval_callee_and_args(terminator, func, args)?; // This is the "canonical" implementation of tails calls, // a pop of the current stack frame, followed by a normal call @@ -227,7 +181,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { }; self.eval_fn_call( - fn_val, + callee, (fn_sig.abi, fn_abi), &args, with_caller_location, @@ -586,6 +540,45 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { Ok(()) } + /// Shared part of `Call` and `TailCall` implementation — finding and evaluating all the + /// necessary information about callee and arguments to make a call. + fn eval_callee_and_args( + &self, + terminator: &mir::Terminator<'tcx>, + func: &mir::Operand<'tcx>, + args: &[Spanned>], + ) -> InterpResult<'tcx, EvaluatedCalleeAndArgs<'tcx, M>> { + let func = self.eval_operand(func, None)?; + let args = self.eval_fn_call_arguments(args)?; + + let fn_sig_binder = func.layout.ty.fn_sig(*self.tcx); + let fn_sig = self.tcx.normalize_erasing_late_bound_regions(self.param_env, fn_sig_binder); + let extra_args = &args[fn_sig.inputs().len()..]; + let extra_args = + self.tcx.mk_type_list_from_iter(extra_args.iter().map(|arg| arg.layout().ty)); + + let (callee, fn_abi, with_caller_location) = match *func.layout.ty.kind() { + ty::FnPtr(_sig) => { + let fn_ptr = self.read_pointer(&func)?; + let fn_val = self.get_ptr_fn(fn_ptr)?; + (fn_val, self.fn_abi_of_fn_ptr(fn_sig_binder, extra_args)?, false) + } + ty::FnDef(def_id, args) => { + let instance = self.resolve(def_id, args)?; + ( + FnVal::Instance(instance), + self.fn_abi_of_instance(instance, extra_args)?, + instance.def.requires_caller_location(*self.tcx), + ) + } + _ => { + span_bug!(terminator.source_info.span, "invalid callee of type {}", func.layout.ty) + } + }; + + Ok(EvaluatedCalleeAndArgs { callee, args, fn_sig, fn_abi, with_caller_location }) + } + /// Call this function -- pushing the stack frame and initializing the arguments. /// /// `caller_fn_abi` is used to determine if all the arguments are passed the proper way. From 5f4caae11c7a640350fbe90ddc465d8e2fa0156e Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Tue, 18 Jul 2023 16:25:59 +0000 Subject: [PATCH 805/892] Fix unconditional recursion lint wrt tail calls --- compiler/rustc_mir_build/src/lints.rs | 18 ++++++++++++-- ...lint-unconditional-recursion-tail-calls.rs | 24 +++++++++++++++++++ ...-unconditional-recursion-tail-calls.stderr | 18 ++++++++++++++ 3 files changed, 58 insertions(+), 2 deletions(-) create mode 100644 tests/ui/lint/lint-unconditional-recursion-tail-calls.rs create mode 100644 tests/ui/lint/lint-unconditional-recursion-tail-calls.stderr diff --git a/compiler/rustc_mir_build/src/lints.rs b/compiler/rustc_mir_build/src/lints.rs index 3cb83a48ffe1b..263e777d03ae1 100644 --- a/compiler/rustc_mir_build/src/lints.rs +++ b/compiler/rustc_mir_build/src/lints.rs @@ -196,8 +196,6 @@ impl<'mir, 'tcx, C: TerminatorClassifier<'tcx>> TriColorVisitor ControlFlow::Break(NonRecursive), @@ -219,12 +217,28 @@ impl<'mir, 'tcx, C: TerminatorClassifier<'tcx>> TriColorVisitor ControlFlow::Continue(()), + + // Note that tail call terminator technically returns to the caller, + // but for purposes of this lint it makes sense to count it as possibly recursive, + // since it's still a call. + // + // If this'll be repurposed for something else, this might need to be changed. + TerminatorKind::TailCall { .. } => ControlFlow::Continue(()), } } fn node_settled(&mut self, bb: BasicBlock) -> ControlFlow { // When we examine a node for the last time, remember it if it is a recursive call. let terminator = self.body[bb].terminator(); + + // FIXME(explicit_tail_calls): highlight tail calls as "recursive call site" + // + // We don't want to lint functions that recurse only through tail calls + // (such as `fn g() { become () }`), so just adding `| TailCall { ... }` + // here won't work. + // + // But at the same time we would like to highlight both calls in a function like + // `fn f() { if false { become f() } else { f() } }`, so we need to figure something out. if self.classifier.is_recursive_terminator(self.tcx, self.body, terminator) { self.reachable_recursive_calls.push(terminator.source_info.span); } diff --git a/tests/ui/lint/lint-unconditional-recursion-tail-calls.rs b/tests/ui/lint/lint-unconditional-recursion-tail-calls.rs new file mode 100644 index 0000000000000..c94bf03257972 --- /dev/null +++ b/tests/ui/lint/lint-unconditional-recursion-tail-calls.rs @@ -0,0 +1,24 @@ +#![allow(incomplete_features, dead_code)] +#![deny(unconditional_recursion)] //~ note: the lint level is defined here +#![feature(explicit_tail_calls)] + +fn f(x: bool) { + //~^ error: function cannot return without recursing + //~| note: cannot return without recursing + if x { + become f(!x) + } else { + f(!x) //~ note: recursive call site + } +} + +// This should *not* lint, tail-recursive functions which never return is a reasonable thing +fn g(x: bool) { + if x { + become g(!x) + } else { + become g(!x) + } +} + +fn main() {} diff --git a/tests/ui/lint/lint-unconditional-recursion-tail-calls.stderr b/tests/ui/lint/lint-unconditional-recursion-tail-calls.stderr new file mode 100644 index 0000000000000..52f9740d027e4 --- /dev/null +++ b/tests/ui/lint/lint-unconditional-recursion-tail-calls.stderr @@ -0,0 +1,18 @@ +error: function cannot return without recursing + --> $DIR/lint-unconditional-recursion-tail-calls.rs:5:1 + | +LL | fn f(x: bool) { + | ^^^^^^^^^^^^^ cannot return without recursing +... +LL | f(!x) + | ----- recursive call site + | + = help: a `loop` may express intention better if this is on purpose +note: the lint level is defined here + --> $DIR/lint-unconditional-recursion-tail-calls.rs:2:9 + | +LL | #![deny(unconditional_recursion)] + | ^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + From 30b18d7c3621e4b6c2cb84b7f84e72c8efd3ff3f Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Tue, 9 May 2023 21:30:28 +0000 Subject: [PATCH 806/892] Add support for `mir::TerminatorKind::TailCall` in clippy --- src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs index 42b10f69c0cdf..f206b2ceebcb1 100644 --- a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs +++ b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs @@ -330,7 +330,8 @@ fn check_terminator<'tcx>( target: _, unwind: _, fn_span: _, - } => { + } + | TerminatorKind::TailCall { func, args, fn_span: _ } => { let fn_ty = func.ty(body, tcx); if let ty::FnDef(fn_def_id, _) = *fn_ty.kind() { if !is_const_fn(tcx, fn_def_id, msrv) { From c895985e759522d813442b6e83372770158a9001 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sat, 6 Jul 2024 11:31:41 -0400 Subject: [PATCH 807/892] Make push_outlives_components into a visitor --- .../rustc_infer/src/infer/outlives/verify.rs | 7 +- compiler/rustc_type_ir/src/outlives.rs | 343 ++++++------------ 2 files changed, 119 insertions(+), 231 deletions(-) diff --git a/compiler/rustc_infer/src/infer/outlives/verify.rs b/compiler/rustc_infer/src/infer/outlives/verify.rs index da9ba26373c16..2392a82025a46 100644 --- a/compiler/rustc_infer/src/infer/outlives/verify.rs +++ b/compiler/rustc_infer/src/infer/outlives/verify.rs @@ -124,12 +124,7 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> { // see the extensive comment in projection_must_outlive let recursive_bound = { let mut components = smallvec![]; - compute_alias_components_recursive( - self.tcx, - alias_ty_as_ty, - &mut components, - &mut Default::default(), - ); + compute_alias_components_recursive(self.tcx, alias_ty_as_ty, &mut components); self.bound_from_components(&components) }; diff --git a/compiler/rustc_type_ir/src/outlives.rs b/compiler/rustc_type_ir/src/outlives.rs index 61dfa2643d884..10b6f3355d92a 100644 --- a/compiler/rustc_type_ir/src/outlives.rs +++ b/compiler/rustc_type_ir/src/outlives.rs @@ -3,11 +3,10 @@ //! RFC for reference. use smallvec::{smallvec, SmallVec}; -use tracing::debug; use crate::data_structures::SsoHashSet; use crate::inherent::*; -use crate::visit::TypeVisitableExt as _; +use crate::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitableExt as _, TypeVisitor}; use crate::{self as ty, Interner}; #[derive(derivative::Derivative)] @@ -56,216 +55,148 @@ pub enum Component { /// `ty0: 'a` to hold. Note that `ty0` must be a **fully resolved type**. pub fn push_outlives_components( tcx: I, - ty0: I::Ty, + ty: I::Ty, out: &mut SmallVec<[Component; 4]>, ) { - let mut visited = SsoHashSet::new(); - compute_components_for_ty(tcx, ty0, out, &mut visited); - debug!("components({:?}) = {:?}", ty0, out); + ty.visit_with(&mut OutlivesCollector { tcx, out, visited: Default::default() }); } -fn compute_components_for_arg( +struct OutlivesCollector<'a, I: Interner> { tcx: I, - arg: I::GenericArg, - out: &mut SmallVec<[Component; 4]>, - visited: &mut SsoHashSet, -) { - match arg.kind() { - ty::GenericArgKind::Type(ty) => { - compute_components_for_ty(tcx, ty, out, visited); - } - ty::GenericArgKind::Lifetime(lt) => { - compute_components_for_lt(lt, out); - } - ty::GenericArgKind::Const(ct) => { - compute_components_for_const(tcx, ct, out, visited); - } - } + out: &'a mut SmallVec<[Component; 4]>, + visited: SsoHashSet, } -fn compute_components_for_ty( - tcx: I, - ty: I::Ty, - out: &mut SmallVec<[Component; 4]>, - visited: &mut SsoHashSet, -) { - if !visited.insert(ty.into()) { - return; - } - // Descend through the types, looking for the various "base" - // components and collecting them into `out`. This is not written - // with `collect()` because of the need to sometimes skip subtrees - // in the `subtys` iterator (e.g., when encountering a - // projection). - match ty.kind() { - ty::FnDef(_, args) => { - // HACK(eddyb) ignore lifetimes found shallowly in `args`. - // This is inconsistent with `ty::Adt` (including all args) - // and with `ty::Closure` (ignoring all args other than - // upvars, of which a `ty::FnDef` doesn't have any), but - // consistent with previous (accidental) behavior. - // See https://github.com/rust-lang/rust/issues/70917 - // for further background and discussion. - for child in args.iter() { - match child.kind() { - ty::GenericArgKind::Type(ty) => { - compute_components_for_ty(tcx, ty, out, visited); - } - ty::GenericArgKind::Lifetime(_) => {} - ty::GenericArgKind::Const(ct) => { - compute_components_for_const(tcx, ct, out, visited); +impl TypeVisitor for OutlivesCollector<'_, I> { + fn visit_ty(&mut self, ty: I::Ty) -> Self::Result { + if !self.visited.insert(ty) { + return; + } + // Descend through the types, looking for the various "base" + // components and collecting them into `out`. This is not written + // with `collect()` because of the need to sometimes skip subtrees + // in the `subtys` iterator (e.g., when encountering a + // projection). + match ty.kind() { + ty::FnDef(_, args) => { + // HACK(eddyb) ignore lifetimes found shallowly in `args`. + // This is inconsistent with `ty::Adt` (including all args) + // and with `ty::Closure` (ignoring all args other than + // upvars, of which a `ty::FnDef` doesn't have any), but + // consistent with previous (accidental) behavior. + // See https://github.com/rust-lang/rust/issues/70917 + // for further background and discussion. + for child in args.iter() { + match child.kind() { + ty::GenericArgKind::Lifetime(_) => {} + ty::GenericArgKind::Type(_) | ty::GenericArgKind::Const(_) => { + child.visit_with(self); + } } } } - } - - ty::Pat(element, _) | ty::Array(element, _) => { - compute_components_for_ty(tcx, element, out, visited); - } - - ty::Closure(_, args) => { - let tupled_ty = args.as_closure().tupled_upvars_ty(); - compute_components_for_ty(tcx, tupled_ty, out, visited); - } - - ty::CoroutineClosure(_, args) => { - let tupled_ty = args.as_coroutine_closure().tupled_upvars_ty(); - compute_components_for_ty(tcx, tupled_ty, out, visited); - } - ty::Coroutine(_, args) => { - // Same as the closure case - let tupled_ty = args.as_coroutine().tupled_upvars_ty(); - compute_components_for_ty(tcx, tupled_ty, out, visited); + ty::Closure(_, args) => { + args.as_closure().tupled_upvars_ty().visit_with(self); + } - // We ignore regions in the coroutine interior as we don't - // want these to affect region inference - } + ty::CoroutineClosure(_, args) => { + args.as_coroutine_closure().tupled_upvars_ty().visit_with(self); + } - // All regions are bound inside a witness, and we don't emit - // higher-ranked outlives components currently. - ty::CoroutineWitness(..) => {}, + ty::Coroutine(_, args) => { + args.as_coroutine().tupled_upvars_ty().visit_with(self); - // OutlivesTypeParameterEnv -- the actual checking that `X:'a` - // is implied by the environment is done in regionck. - ty::Param(p) => { - out.push(Component::Param(p)); - } + // We ignore regions in the coroutine interior as we don't + // want these to affect region inference + } - ty::Placeholder(p) => { - out.push(Component::Placeholder(p)); - } + // All regions are bound inside a witness, and we don't emit + // higher-ranked outlives components currently. + ty::CoroutineWitness(..) => {} - // For projections, we prefer to generate an obligation like - // `>::Foo: 'a`, because this gives the - // regionck more ways to prove that it holds. However, - // regionck is not (at least currently) prepared to deal with - // higher-ranked regions that may appear in the - // trait-ref. Therefore, if we see any higher-ranked regions, - // we simply fallback to the most restrictive rule, which - // requires that `Pi: 'a` for all `i`. - ty::Alias(_, alias_ty) => { - if !alias_ty.has_escaping_bound_vars() { - // best case: no escaping regions, so push the - // projection and skip the subtree (thus generating no - // constraints for Pi). This defers the choice between - // the rules OutlivesProjectionEnv, - // OutlivesProjectionTraitDef, and - // OutlivesProjectionComponents to regionck. - out.push(Component::Alias(alias_ty)); - } else { - // fallback case: hard code - // OutlivesProjectionComponents. Continue walking - // through and constrain Pi. - let mut subcomponents = smallvec![]; - let mut subvisited = SsoHashSet::new(); - compute_alias_components_recursive(tcx, ty, &mut subcomponents, &mut subvisited); - out.push(Component::EscapingAlias(subcomponents.into_iter().collect())); + // OutlivesTypeParameterEnv -- the actual checking that `X:'a` + // is implied by the environment is done in regionck. + ty::Param(p) => { + self.out.push(Component::Param(p)); } - } - // We assume that inference variables are fully resolved. - // So, if we encounter an inference variable, just record - // the unresolved variable as a component. - ty::Infer(infer_ty) => { - out.push(Component::UnresolvedInferenceVariable(infer_ty)); - } - - // Most types do not introduce any region binders, nor - // involve any other subtle cases, and so the WF relation - // simply constraints any regions referenced directly by - // the type and then visits the types that are lexically - // contained within. (The comments refer to relevant rules - // from RFC1214.) + ty::Placeholder(p) => { + self.out.push(Component::Placeholder(p)); + } - ty::Bool | // OutlivesScalar - ty::Char | // OutlivesScalar - ty::Int(..) | // OutlivesScalar - ty::Uint(..) | // OutlivesScalar - ty::Float(..) | // OutlivesScalar - ty::Never | // OutlivesScalar - ty::Foreign(..) | // OutlivesNominalType - ty::Str | // OutlivesScalar (ish) - ty::Bound(..) | - ty::Error(_) => { - // Trivial. - } + // For projections, we prefer to generate an obligation like + // `>::Foo: 'a`, because this gives the + // regionck more ways to prove that it holds. However, + // regionck is not (at least currently) prepared to deal with + // higher-ranked regions that may appear in the + // trait-ref. Therefore, if we see any higher-ranked regions, + // we simply fallback to the most restrictive rule, which + // requires that `Pi: 'a` for all `i`. + ty::Alias(_, alias_ty) => { + if !alias_ty.has_escaping_bound_vars() { + // best case: no escaping regions, so push the + // projection and skip the subtree (thus generating no + // constraints for Pi). This defers the choice between + // the rules OutlivesProjectionEnv, + // OutlivesProjectionTraitDef, and + // OutlivesProjectionComponents to regionck. + self.out.push(Component::Alias(alias_ty)); + } else { + // fallback case: hard code + // OutlivesProjectionComponents. Continue walking + // through and constrain Pi. + let mut subcomponents = smallvec![]; + compute_alias_components_recursive(self.tcx, ty, &mut subcomponents); + self.out.push(Component::EscapingAlias(subcomponents.into_iter().collect())); + } + } - // OutlivesNominalType - ty::Adt(_, args) => { - for arg in args.iter() { - compute_components_for_arg(tcx, arg, out, visited); + // We assume that inference variables are fully resolved. + // So, if we encounter an inference variable, just record + // the unresolved variable as a component. + ty::Infer(infer_ty) => { + self.out.push(Component::UnresolvedInferenceVariable(infer_ty)); } - } - // OutlivesNominalType - ty::Slice(ty) | - ty::RawPtr(ty, _) => { - compute_components_for_ty(tcx, ty, out, visited); - } - ty::Tuple(tys) => { - for ty in tys.iter() { - compute_components_for_ty(tcx, ty, out, visited); + // Most types do not introduce any region binders, nor + // involve any other subtle cases, and so the WF relation + // simply constraints any regions referenced directly by + // the type and then visits the types that are lexically + // contained within. + ty::Bool + | ty::Char + | ty::Int(_) + | ty::Uint(_) + | ty::Float(_) + | ty::Str + | ty::Never + | ty::Error(_) => { + // Trivial } - } - // OutlivesReference - ty::Ref(lt, ty, _) => { - compute_components_for_lt(lt, out); - compute_components_for_ty(tcx, ty, out, visited); - } + ty::Bound(_, _) => { + // FIXME: Bound vars matter here! + } - ty::Dynamic(preds, lt, _) => { - compute_components_for_lt(lt, out); - for pred in preds.iter() { - match pred.skip_binder() { - ty::ExistentialPredicate::Trait(tr) => { - for arg in tr.args.iter() { - compute_components_for_arg(tcx, arg, out, visited); - } - } - ty::ExistentialPredicate::Projection(proj) => { - for arg in proj.args.iter() { - compute_components_for_arg(tcx, arg, out, visited); - } - match proj.term.kind() { - ty::TermKind::Ty(ty) => { - compute_components_for_ty(tcx, ty, out, visited) - } - ty::TermKind::Const(ct) => { - compute_components_for_const(tcx, ct, out, visited) - } - } - } - ty::ExistentialPredicate::AutoTrait(..) => {} - } + ty::Adt(_, _) + | ty::Foreign(_) + | ty::Array(_, _) + | ty::Pat(_, _) + | ty::Slice(_) + | ty::RawPtr(_, _) + | ty::Ref(_, _, _) + | ty::FnPtr(_) + | ty::Dynamic(_, _, _) + | ty::Tuple(_) => { + ty.super_visit_with(self); } } + } - ty::FnPtr(sig) => { - for ty in sig.skip_binder().inputs_and_output.iter() { - compute_components_for_ty(tcx, ty, out, visited); - } + fn visit_region(&mut self, lt: I::Region) -> Self::Result { + if !lt.is_bound() { + self.out.push(Component::Region(lt)); } } } @@ -278,7 +209,6 @@ pub fn compute_alias_components_recursive( tcx: I, alias_ty: I::Ty, out: &mut SmallVec<[Component; 4]>, - visited: &mut SsoHashSet, ) { let ty::Alias(kind, alias_ty) = alias_ty.kind() else { unreachable!("can only call `compute_alias_components_recursive` on an alias type") @@ -287,49 +217,12 @@ pub fn compute_alias_components_recursive( let opt_variances = if kind == ty::Opaque { Some(tcx.variances_of(alias_ty.def_id)) } else { None }; + let mut visitor = OutlivesCollector { tcx, out, visited: Default::default() }; + for (index, child) in alias_ty.args.iter().enumerate() { if opt_variances.and_then(|variances| variances.get(index)) == Some(ty::Bivariant) { continue; } - compute_components_for_arg(tcx, child, out, visited); - } -} - -fn compute_components_for_lt(lt: I::Region, out: &mut SmallVec<[Component; 4]>) { - if !lt.is_bound() { - out.push(Component::Region(lt)); - } -} - -fn compute_components_for_const( - tcx: I, - ct: I::Const, - out: &mut SmallVec<[Component; 4]>, - visited: &mut SsoHashSet, -) { - if !visited.insert(ct.into()) { - return; - } - match ct.kind() { - ty::ConstKind::Param(_) - | ty::ConstKind::Bound(_, _) - | ty::ConstKind::Infer(_) - | ty::ConstKind::Placeholder(_) - | ty::ConstKind::Error(_) => { - // Trivial - } - ty::ConstKind::Expr(e) => { - for arg in e.args().iter() { - compute_components_for_arg(tcx, arg, out, visited); - } - } - ty::ConstKind::Value(ty, _) => { - compute_components_for_ty(tcx, ty, out, visited); - } - ty::ConstKind::Unevaluated(uv) => { - for arg in uv.args.iter() { - compute_components_for_arg(tcx, arg, out, visited); - } - } + child.visit_with(&mut visitor); } } From 90423a7abbddd98b6fbb22e9780991c736b51ca4 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sat, 6 Jul 2024 12:21:00 -0400 Subject: [PATCH 808/892] Uplift elaboration --- compiler/rustc_infer/src/traits/util.rs | 349 +----------------- compiler/rustc_middle/src/ty/context.rs | 21 +- .../rustc_middle/src/ty/elaborate_impl.rs | 84 +++++ compiler/rustc_middle/src/ty/mod.rs | 1 + compiler/rustc_middle/src/ty/predicate.rs | 10 +- compiler/rustc_middle/src/ty/sty.rs | 8 + .../src/solve/assembly/structural_traits.rs | 4 +- compiler/rustc_type_ir/src/elaborate.rs | 277 ++++++++++++++ compiler/rustc_type_ir/src/inherent.rs | 37 +- compiler/rustc_type_ir/src/interner.rs | 14 +- compiler/rustc_type_ir/src/lib.rs | 1 + 11 files changed, 437 insertions(+), 369 deletions(-) create mode 100644 compiler/rustc_middle/src/ty/elaborate_impl.rs create mode 100644 compiler/rustc_type_ir/src/elaborate.rs diff --git a/compiler/rustc_infer/src/traits/util.rs b/compiler/rustc_infer/src/traits/util.rs index b269bfcbfebc2..f54d041859581 100644 --- a/compiler/rustc_infer/src/traits/util.rs +++ b/compiler/rustc_infer/src/traits/util.rs @@ -1,12 +1,10 @@ -use smallvec::smallvec; - use crate::traits::{self, Obligation, ObligationCauseCode, PredicateObligation}; use rustc_data_structures::fx::FxHashSet; use rustc_middle::ty::ToPolyTraitRef; -use rustc_middle::ty::{self, Ty, TyCtxt, Upcast}; +use rustc_middle::ty::{self, TyCtxt}; use rustc_span::symbol::Ident; use rustc_span::Span; -use rustc_type_ir::outlives::{push_outlives_components, Component}; +pub use rustc_type_ir::elaborate::*; pub fn anonymize_predicate<'tcx>( tcx: TyCtxt<'tcx>, @@ -64,50 +62,9 @@ impl<'tcx> Extend> for PredicateSet<'tcx> { } } -/////////////////////////////////////////////////////////////////////////// -// `Elaboration` iterator -/////////////////////////////////////////////////////////////////////////// - -/// "Elaboration" is the process of identifying all the predicates that -/// are implied by a source predicate. Currently, this basically means -/// walking the "supertraits" and other similar assumptions. For example, -/// if we know that `T: Ord`, the elaborator would deduce that `T: PartialOrd` -/// holds as well. Similarly, if we have `trait Foo: 'static`, and we know that -/// `T: Foo`, then we know that `T: 'static`. -pub struct Elaborator<'tcx, O> { - stack: Vec, - visited: PredicateSet<'tcx>, - mode: Filter, -} - -enum Filter { - All, - OnlySelf, -} - -/// Describes how to elaborate an obligation into a sub-obligation. -/// /// For [`Obligation`], a sub-obligation is combined with the current obligation's -/// param-env and cause code. For [`ty::Predicate`], none of this is needed, since -/// there is no param-env or cause code to copy over. -pub trait Elaboratable<'tcx> { - fn predicate(&self) -> ty::Predicate<'tcx>; - - // Makes a new `Self` but with a different clause that comes from elaboration. - fn child(&self, clause: ty::Clause<'tcx>) -> Self; - - // Makes a new `Self` but with a different clause and a different cause - // code (if `Self` has one, such as [`PredicateObligation`]). - fn child_with_derived_cause( - &self, - clause: ty::Clause<'tcx>, - span: Span, - parent_trait_pred: ty::PolyTraitPredicate<'tcx>, - index: usize, - ) -> Self; -} - -impl<'tcx> Elaboratable<'tcx> for PredicateObligation<'tcx> { +/// param-env and cause code. +impl<'tcx> Elaboratable> for PredicateObligation<'tcx> { fn predicate(&self) -> ty::Predicate<'tcx> { self.predicate } @@ -145,270 +102,6 @@ impl<'tcx> Elaboratable<'tcx> for PredicateObligation<'tcx> { } } -impl<'tcx> Elaboratable<'tcx> for ty::Predicate<'tcx> { - fn predicate(&self) -> ty::Predicate<'tcx> { - *self - } - - fn child(&self, clause: ty::Clause<'tcx>) -> Self { - clause.as_predicate() - } - - fn child_with_derived_cause( - &self, - clause: ty::Clause<'tcx>, - _span: Span, - _parent_trait_pred: ty::PolyTraitPredicate<'tcx>, - _index: usize, - ) -> Self { - clause.as_predicate() - } -} - -impl<'tcx> Elaboratable<'tcx> for (ty::Predicate<'tcx>, Span) { - fn predicate(&self) -> ty::Predicate<'tcx> { - self.0 - } - - fn child(&self, clause: ty::Clause<'tcx>) -> Self { - (clause.as_predicate(), self.1) - } - - fn child_with_derived_cause( - &self, - clause: ty::Clause<'tcx>, - _span: Span, - _parent_trait_pred: ty::PolyTraitPredicate<'tcx>, - _index: usize, - ) -> Self { - (clause.as_predicate(), self.1) - } -} - -impl<'tcx> Elaboratable<'tcx> for (ty::Clause<'tcx>, Span) { - fn predicate(&self) -> ty::Predicate<'tcx> { - self.0.as_predicate() - } - - fn child(&self, clause: ty::Clause<'tcx>) -> Self { - (clause, self.1) - } - - fn child_with_derived_cause( - &self, - clause: ty::Clause<'tcx>, - _span: Span, - _parent_trait_pred: ty::PolyTraitPredicate<'tcx>, - _index: usize, - ) -> Self { - (clause, self.1) - } -} - -impl<'tcx> Elaboratable<'tcx> for ty::Clause<'tcx> { - fn predicate(&self) -> ty::Predicate<'tcx> { - self.as_predicate() - } - - fn child(&self, clause: ty::Clause<'tcx>) -> Self { - clause - } - - fn child_with_derived_cause( - &self, - clause: ty::Clause<'tcx>, - _span: Span, - _parent_trait_pred: ty::PolyTraitPredicate<'tcx>, - _index: usize, - ) -> Self { - clause - } -} - -pub fn elaborate<'tcx, O: Elaboratable<'tcx>>( - tcx: TyCtxt<'tcx>, - obligations: impl IntoIterator, -) -> Elaborator<'tcx, O> { - let mut elaborator = - Elaborator { stack: Vec::new(), visited: PredicateSet::new(tcx), mode: Filter::All }; - elaborator.extend_deduped(obligations); - elaborator -} - -impl<'tcx, O: Elaboratable<'tcx>> Elaborator<'tcx, O> { - fn extend_deduped(&mut self, obligations: impl IntoIterator) { - // Only keep those bounds that we haven't already seen. - // This is necessary to prevent infinite recursion in some - // cases. One common case is when people define - // `trait Sized: Sized { }` rather than `trait Sized { }`. - // let visited = &mut self.visited; - self.stack.extend(obligations.into_iter().filter(|o| self.visited.insert(o.predicate()))); - } - - /// Filter to only the supertraits of trait predicates, i.e. only the predicates - /// that have `Self` as their self type, instead of all implied predicates. - pub fn filter_only_self(mut self) -> Self { - self.mode = Filter::OnlySelf; - self - } - - fn elaborate(&mut self, elaboratable: &O) { - let tcx = self.visited.tcx; - - // We only elaborate clauses. - let Some(clause) = elaboratable.predicate().as_clause() else { - return; - }; - - let bound_clause = clause.kind(); - match bound_clause.skip_binder() { - ty::ClauseKind::Trait(data) => { - // Negative trait bounds do not imply any supertrait bounds - if data.polarity != ty::PredicatePolarity::Positive { - return; - } - // Get predicates implied by the trait, or only super predicates if we only care about self predicates. - let predicates = match self.mode { - Filter::All => tcx.explicit_implied_predicates_of(data.def_id()), - Filter::OnlySelf => tcx.explicit_super_predicates_of(data.def_id()), - }; - - let obligations = - predicates.predicates.iter().enumerate().map(|(index, &(clause, span))| { - elaboratable.child_with_derived_cause( - clause.instantiate_supertrait(tcx, bound_clause.rebind(data.trait_ref)), - span, - bound_clause.rebind(data), - index, - ) - }); - debug!(?data, ?obligations, "super_predicates"); - self.extend_deduped(obligations); - } - ty::ClauseKind::TypeOutlives(ty::OutlivesPredicate(ty_max, r_min)) => { - // We know that `T: 'a` for some type `T`. We can - // often elaborate this. For example, if we know that - // `[U]: 'a`, that implies that `U: 'a`. Similarly, if - // we know `&'a U: 'b`, then we know that `'a: 'b` and - // `U: 'b`. - // - // We can basically ignore bound regions here. So for - // example `for<'c> Foo<'a,'c>: 'b` can be elaborated to - // `'a: 'b`. - - // Ignore `for<'a> T: 'a` -- we might in the future - // consider this as evidence that `T: 'static`, but - // I'm a bit wary of such constructions and so for now - // I want to be conservative. --nmatsakis - if r_min.is_bound() { - return; - } - - let mut components = smallvec![]; - push_outlives_components(tcx, ty_max, &mut components); - self.extend_deduped( - components - .into_iter() - .filter_map(|component| match component { - Component::Region(r) => { - if r.is_bound() { - None - } else { - Some(ty::ClauseKind::RegionOutlives(ty::OutlivesPredicate( - r, r_min, - ))) - } - } - - Component::Param(p) => { - let ty = Ty::new_param(tcx, p.index, p.name); - Some(ty::ClauseKind::TypeOutlives(ty::OutlivesPredicate(ty, r_min))) - } - - Component::Placeholder(p) => { - let ty = Ty::new_placeholder(tcx, p); - Some(ty::ClauseKind::TypeOutlives(ty::OutlivesPredicate(ty, r_min))) - } - - Component::UnresolvedInferenceVariable(_) => None, - - Component::Alias(alias_ty) => { - // We might end up here if we have `Foo<::Assoc>: 'a`. - // With this, we can deduce that `::Assoc: 'a`. - Some(ty::ClauseKind::TypeOutlives(ty::OutlivesPredicate( - alias_ty.to_ty(tcx), - r_min, - ))) - } - - Component::EscapingAlias(_) => { - // We might be able to do more here, but we don't - // want to deal with escaping vars right now. - None - } - }) - .map(|clause| elaboratable.child(bound_clause.rebind(clause).upcast(tcx))), - ); - } - ty::ClauseKind::RegionOutlives(..) => { - // Nothing to elaborate from `'a: 'b`. - } - ty::ClauseKind::WellFormed(..) => { - // Currently, we do not elaborate WF predicates, - // although we easily could. - } - ty::ClauseKind::Projection(..) => { - // Nothing to elaborate in a projection predicate. - } - ty::ClauseKind::ConstEvaluatable(..) => { - // Currently, we do not elaborate const-evaluatable - // predicates. - } - ty::ClauseKind::ConstArgHasType(..) => { - // Nothing to elaborate - } - } - } -} - -impl<'tcx, O: Elaboratable<'tcx>> Iterator for Elaborator<'tcx, O> { - type Item = O; - - fn size_hint(&self) -> (usize, Option) { - (self.stack.len(), None) - } - - fn next(&mut self) -> Option { - // Extract next item from top-most stack frame, if any. - if let Some(obligation) = self.stack.pop() { - self.elaborate(&obligation); - Some(obligation) - } else { - None - } - } -} - -/////////////////////////////////////////////////////////////////////////// -// Supertrait iterator -/////////////////////////////////////////////////////////////////////////// - -pub fn supertraits<'tcx>( - tcx: TyCtxt<'tcx>, - trait_ref: ty::PolyTraitRef<'tcx>, -) -> FilterToTraits>> { - elaborate(tcx, [trait_ref.upcast(tcx)]).filter_only_self().filter_to_traits() -} - -pub fn transitive_bounds<'tcx>( - tcx: TyCtxt<'tcx>, - trait_refs: impl Iterator>, -) -> FilterToTraits>> { - elaborate(tcx, trait_refs.map(|trait_ref| trait_ref.upcast(tcx))) - .filter_only_self() - .filter_to_traits() -} - /// A specialized variant of `elaborate` that only elaborates trait references that may /// define the given associated item with the name `assoc_name`. It uses the /// `explicit_supertraits_containing_assoc_item` query to avoid enumerating super-predicates that @@ -443,37 +136,3 @@ pub fn transitive_bounds_that_define_assoc_item<'tcx>( None }) } - -/////////////////////////////////////////////////////////////////////////// -// Other -/////////////////////////////////////////////////////////////////////////// - -impl<'tcx> Elaborator<'tcx, ty::Clause<'tcx>> { - fn filter_to_traits(self) -> FilterToTraits { - FilterToTraits { base_iterator: self } - } -} - -/// A filter around an iterator of predicates that makes it yield up -/// just trait references. -pub struct FilterToTraits { - base_iterator: I, -} - -impl<'tcx, I: Iterator>> Iterator for FilterToTraits { - type Item = ty::PolyTraitRef<'tcx>; - - fn next(&mut self) -> Option> { - while let Some(pred) = self.base_iterator.next() { - if let Some(data) = pred.as_trait_clause() { - return Some(data.map_bound(|t| t.trait_ref)); - } - } - None - } - - fn size_hint(&self) -> (usize, Option) { - let (_, upper) = self.base_iterator.size_hint(); - (0, upper) - } -} diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index dca48069974f0..59ab5d791399b 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -347,12 +347,16 @@ impl<'tcx> Interner for TyCtxt<'tcx> { fn explicit_super_predicates_of( self, def_id: DefId, - ) -> ty::EarlyBinder<'tcx, impl IntoIterator>> { + ) -> ty::EarlyBinder<'tcx, impl IntoIterator, Span)>> { + ty::EarlyBinder::bind(self.explicit_super_predicates_of(def_id).instantiate_identity(self)) + } + + fn explicit_implied_predicates_of( + self, + def_id: DefId, + ) -> ty::EarlyBinder<'tcx, impl IntoIterator, Span)>> { ty::EarlyBinder::bind( - self.explicit_super_predicates_of(def_id) - .instantiate_identity(self) - .predicates - .into_iter(), + self.explicit_implied_predicates_of(def_id).instantiate_identity(self), ) } @@ -569,6 +573,13 @@ impl<'tcx> Interner for TyCtxt<'tcx> { ) -> Ty<'tcx> { placeholder.find_const_ty_from_env(param_env) } + + fn anonymize_bound_vars>>( + self, + binder: ty::Binder<'tcx, T>, + ) -> ty::Binder<'tcx, T> { + self.anonymize_bound_vars(binder) + } } macro_rules! bidirectional_lang_item_map { diff --git a/compiler/rustc_middle/src/ty/elaborate_impl.rs b/compiler/rustc_middle/src/ty/elaborate_impl.rs new file mode 100644 index 0000000000000..8c89a2d884b30 --- /dev/null +++ b/compiler/rustc_middle/src/ty/elaborate_impl.rs @@ -0,0 +1,84 @@ +use rustc_span::Span; +use rustc_type_ir::elaborate::Elaboratable; + +use crate::ty::{self, TyCtxt}; + +impl<'tcx> Elaboratable> for ty::Clause<'tcx> { + fn predicate(&self) -> ty::Predicate<'tcx> { + self.as_predicate() + } + + fn child(&self, clause: ty::Clause<'tcx>) -> Self { + clause + } + + fn child_with_derived_cause( + &self, + clause: ty::Clause<'tcx>, + _span: Span, + _parent_trait_pred: ty::PolyTraitPredicate<'tcx>, + _index: usize, + ) -> Self { + clause + } +} + +impl<'tcx> Elaboratable> for ty::Predicate<'tcx> { + fn predicate(&self) -> ty::Predicate<'tcx> { + *self + } + + fn child(&self, clause: ty::Clause<'tcx>) -> Self { + clause.as_predicate() + } + + fn child_with_derived_cause( + &self, + clause: ty::Clause<'tcx>, + _span: Span, + _parent_trait_pred: ty::PolyTraitPredicate<'tcx>, + _index: usize, + ) -> Self { + clause.as_predicate() + } +} + +impl<'tcx> Elaboratable> for (ty::Predicate<'tcx>, Span) { + fn predicate(&self) -> ty::Predicate<'tcx> { + self.0 + } + + fn child(&self, clause: ty::Clause<'tcx>) -> Self { + (clause.as_predicate(), self.1) + } + + fn child_with_derived_cause( + &self, + clause: ty::Clause<'tcx>, + _span: Span, + _parent_trait_pred: ty::PolyTraitPredicate<'tcx>, + _index: usize, + ) -> Self { + (clause.as_predicate(), self.1) + } +} + +impl<'tcx> Elaboratable> for (ty::Clause<'tcx>, Span) { + fn predicate(&self) -> ty::Predicate<'tcx> { + self.0.as_predicate() + } + + fn child(&self, clause: ty::Clause<'tcx>) -> Self { + (clause, self.1) + } + + fn child_with_derived_cause( + &self, + clause: ty::Clause<'tcx>, + _span: Span, + _parent_trait_pred: ty::PolyTraitPredicate<'tcx>, + _index: usize, + ) -> Self { + (clause, self.1) + } +} diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 7d57d88f40f4a..4470db47474cb 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -148,6 +148,7 @@ mod closure; mod consts; mod context; mod diagnostics; +mod elaborate_impl; mod erase_regions; mod generic_args; mod generics; diff --git a/compiler/rustc_middle/src/ty/predicate.rs b/compiler/rustc_middle/src/ty/predicate.rs index e9b37503bb3e5..c2cc3be3aaa56 100644 --- a/compiler/rustc_middle/src/ty/predicate.rs +++ b/compiler/rustc_middle/src/ty/predicate.rs @@ -46,6 +46,10 @@ pub struct Predicate<'tcx>( ); impl<'tcx> rustc_type_ir::inherent::Predicate> for Predicate<'tcx> { + fn as_clause(self) -> Option> { + self.as_clause() + } + fn is_coinductive(self, interner: TyCtxt<'tcx>) -> bool { self.is_coinductive(interner) } @@ -173,7 +177,11 @@ pub struct Clause<'tcx>( pub(super) Interned<'tcx, WithCachedTypeInfo>>>, ); -impl<'tcx> rustc_type_ir::inherent::Clause> for Clause<'tcx> {} +impl<'tcx> rustc_type_ir::inherent::Clause> for Clause<'tcx> { + fn instantiate_supertrait(self, tcx: TyCtxt<'tcx>, trait_ref: ty::PolyTraitRef<'tcx>) -> Self { + self.instantiate_supertrait(tcx, trait_ref) + } +} impl<'tcx> rustc_type_ir::inherent::IntoKind for Clause<'tcx> { type Kind = ty::Binder<'tcx, ClauseKind<'tcx>>; diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 52690ae678d6c..d2b444a066bcc 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -811,6 +811,14 @@ impl<'tcx> rustc_type_ir::inherent::Ty> for Ty<'tcx> { Ty::new_var(tcx, vid) } + fn new_param(tcx: TyCtxt<'tcx>, param: ty::ParamTy) -> Self { + Ty::new_param(tcx, param.index, param.name) + } + + fn new_placeholder(tcx: TyCtxt<'tcx>, placeholder: ty::PlaceholderType) -> Self { + Ty::new_placeholder(tcx, placeholder) + } + fn new_bound(interner: TyCtxt<'tcx>, debruijn: ty::DebruijnIndex, var: ty::BoundTy) -> Self { Ty::new_bound(interner, debruijn, var) } diff --git a/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs b/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs index 3447b39fa5b40..7df14e81ab5d4 100644 --- a/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs +++ b/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs @@ -669,7 +669,9 @@ where let cx = ecx.cx(); let mut requirements = vec![]; requirements.extend( - cx.explicit_super_predicates_of(trait_ref.def_id).iter_instantiated(cx, trait_ref.args), + cx.explicit_super_predicates_of(trait_ref.def_id) + .iter_instantiated(cx, trait_ref.args) + .map(|(pred, _)| pred), ); // FIXME(associated_const_equality): Also add associated consts to diff --git a/compiler/rustc_type_ir/src/elaborate.rs b/compiler/rustc_type_ir/src/elaborate.rs new file mode 100644 index 0000000000000..04cdf29a77799 --- /dev/null +++ b/compiler/rustc_type_ir/src/elaborate.rs @@ -0,0 +1,277 @@ +use std::marker::PhantomData; + +use smallvec::smallvec; + +use crate::data_structures::HashSet; +use crate::outlives::{push_outlives_components, Component}; +use crate::{self as ty, Interner}; +use crate::{inherent::*, Upcast as _}; + +/// "Elaboration" is the process of identifying all the predicates that +/// are implied by a source predicate. Currently, this basically means +/// walking the "supertraits" and other similar assumptions. For example, +/// if we know that `T: Ord`, the elaborator would deduce that `T: PartialOrd` +/// holds as well. Similarly, if we have `trait Foo: 'static`, and we know that +/// `T: Foo`, then we know that `T: 'static`. +pub struct Elaborator { + cx: I, + stack: Vec, + visited: HashSet>>, + mode: Filter, +} + +enum Filter { + All, + OnlySelf, +} + +/// Describes how to elaborate an obligation into a sub-obligation. +pub trait Elaboratable { + fn predicate(&self) -> I::Predicate; + + // Makes a new `Self` but with a different clause that comes from elaboration. + fn child(&self, clause: I::Clause) -> Self; + + // Makes a new `Self` but with a different clause and a different cause + // code (if `Self` has one, such as [`PredicateObligation`]). + fn child_with_derived_cause( + &self, + clause: I::Clause, + span: I::Span, + parent_trait_pred: ty::Binder>, + index: usize, + ) -> Self; +} + +pub fn elaborate>( + cx: I, + obligations: impl IntoIterator, +) -> Elaborator { + let mut elaborator = + Elaborator { cx, stack: Vec::new(), visited: HashSet::default(), mode: Filter::All }; + elaborator.extend_deduped(obligations); + elaborator +} + +impl> Elaborator { + fn extend_deduped(&mut self, obligations: impl IntoIterator) { + // Only keep those bounds that we haven't already seen. + // This is necessary to prevent infinite recursion in some + // cases. One common case is when people define + // `trait Sized: Sized { }` rather than `trait Sized { }`. + self.stack.extend( + obligations.into_iter().filter(|o| { + self.visited.insert(self.cx.anonymize_bound_vars(o.predicate().kind())) + }), + ); + } + + /// Filter to only the supertraits of trait predicates, i.e. only the predicates + /// that have `Self` as their self type, instead of all implied predicates. + pub fn filter_only_self(mut self) -> Self { + self.mode = Filter::OnlySelf; + self + } + + fn elaborate(&mut self, elaboratable: &O) { + let cx = self.cx; + + // We only elaborate clauses. + let Some(clause) = elaboratable.predicate().as_clause() else { + return; + }; + + let bound_clause = clause.kind(); + match bound_clause.skip_binder() { + ty::ClauseKind::Trait(data) => { + // Negative trait bounds do not imply any supertrait bounds + if data.polarity != ty::PredicatePolarity::Positive { + return; + } + + let map_to_child_clause = + |(index, (clause, span)): (usize, (I::Clause, I::Span))| { + elaboratable.child_with_derived_cause( + clause.instantiate_supertrait(cx, bound_clause.rebind(data.trait_ref)), + span, + bound_clause.rebind(data), + index, + ) + }; + + // Get predicates implied by the trait, or only super predicates if we only care about self predicates. + match self.mode { + Filter::All => self.extend_deduped( + cx.explicit_implied_predicates_of(data.def_id()) + .iter_identity() + .enumerate() + .map(map_to_child_clause), + ), + Filter::OnlySelf => self.extend_deduped( + cx.explicit_super_predicates_of(data.def_id()) + .iter_identity() + .enumerate() + .map(map_to_child_clause), + ), + }; + } + ty::ClauseKind::TypeOutlives(ty::OutlivesPredicate(ty_max, r_min)) => { + // We know that `T: 'a` for some type `T`. We can + // often elaborate this. For example, if we know that + // `[U]: 'a`, that implies that `U: 'a`. Similarly, if + // we know `&'a U: 'b`, then we know that `'a: 'b` and + // `U: 'b`. + // + // We can basically ignore bound regions here. So for + // example `for<'c> Foo<'a,'c>: 'b` can be elaborated to + // `'a: 'b`. + + // Ignore `for<'a> T: 'a` -- we might in the future + // consider this as evidence that `T: 'static`, but + // I'm a bit wary of such constructions and so for now + // I want to be conservative. --nmatsakis + if r_min.is_bound() { + return; + } + + let mut components = smallvec![]; + push_outlives_components(cx, ty_max, &mut components); + self.extend_deduped( + components + .into_iter() + .filter_map(|component| elaborate_component_to_clause(cx, component, r_min)) + .map(|clause| elaboratable.child(bound_clause.rebind(clause).upcast(cx))), + ); + } + ty::ClauseKind::RegionOutlives(..) => { + // Nothing to elaborate from `'a: 'b`. + } + ty::ClauseKind::WellFormed(..) => { + // Currently, we do not elaborate WF predicates, + // although we easily could. + } + ty::ClauseKind::Projection(..) => { + // Nothing to elaborate in a projection predicate. + } + ty::ClauseKind::ConstEvaluatable(..) => { + // Currently, we do not elaborate const-evaluatable + // predicates. + } + ty::ClauseKind::ConstArgHasType(..) => { + // Nothing to elaborate + } + } + } +} + +fn elaborate_component_to_clause( + cx: I, + component: Component, + outlives_region: I::Region, +) -> Option> { + match component { + Component::Region(r) => { + if r.is_bound() { + None + } else { + Some(ty::ClauseKind::RegionOutlives(ty::OutlivesPredicate(r, outlives_region))) + } + } + + Component::Param(p) => { + let ty = Ty::new_param(cx, p); + Some(ty::ClauseKind::TypeOutlives(ty::OutlivesPredicate(ty, outlives_region))) + } + + Component::Placeholder(p) => { + let ty = Ty::new_placeholder(cx, p); + Some(ty::ClauseKind::TypeOutlives(ty::OutlivesPredicate(ty, outlives_region))) + } + + Component::UnresolvedInferenceVariable(_) => None, + + Component::Alias(alias_ty) => { + // We might end up here if we have `Foo<::Assoc>: 'a`. + // With this, we can deduce that `::Assoc: 'a`. + Some(ty::ClauseKind::TypeOutlives(ty::OutlivesPredicate( + alias_ty.to_ty(cx), + outlives_region, + ))) + } + + Component::EscapingAlias(_) => { + // We might be able to do more here, but we don't + // want to deal with escaping vars right now. + None + } + } +} + +impl> Iterator for Elaborator { + type Item = O; + + fn size_hint(&self) -> (usize, Option) { + (self.stack.len(), None) + } + + fn next(&mut self) -> Option { + // Extract next item from top-most stack frame, if any. + if let Some(obligation) = self.stack.pop() { + self.elaborate(&obligation); + Some(obligation) + } else { + None + } + } +} + +/////////////////////////////////////////////////////////////////////////// +// Supertrait iterator +/////////////////////////////////////////////////////////////////////////// + +pub fn supertraits( + tcx: I, + trait_ref: ty::Binder>, +) -> FilterToTraits> { + elaborate(tcx, [trait_ref.upcast(tcx)]).filter_only_self().filter_to_traits() +} + +pub fn transitive_bounds( + tcx: I, + trait_refs: impl Iterator>>, +) -> FilterToTraits> { + elaborate(tcx, trait_refs.map(|trait_ref| trait_ref.upcast(tcx))) + .filter_only_self() + .filter_to_traits() +} + +impl Elaborator { + fn filter_to_traits(self) -> FilterToTraits { + FilterToTraits { _cx: PhantomData, base_iterator: self } + } +} + +/// A filter around an iterator of predicates that makes it yield up +/// just trait references. +pub struct FilterToTraits> { + _cx: PhantomData, + base_iterator: It, +} + +impl> Iterator for FilterToTraits { + type Item = ty::Binder>; + + fn next(&mut self) -> Option>> { + while let Some(pred) = self.base_iterator.next() { + if let Some(data) = pred.as_trait_clause() { + return Some(data.map_bound(|t| t.trait_ref)); + } + } + None + } + + fn size_hint(&self) -> (usize, Option) { + let (_, upper) = self.base_iterator.size_hint(); + (0, upper) + } +} diff --git a/compiler/rustc_type_ir/src/inherent.rs b/compiler/rustc_type_ir/src/inherent.rs index 68c2575258d2f..1db55b26719b0 100644 --- a/compiler/rustc_type_ir/src/inherent.rs +++ b/compiler/rustc_type_ir/src/inherent.rs @@ -9,6 +9,7 @@ use std::hash::Hash; use rustc_ast_ir::Mutability; use crate::data_structures::HashSet; +use crate::elaborate::Elaboratable; use crate::fold::{TypeFoldable, TypeSuperFoldable}; use crate::relate::Relate; use crate::solve::{CacheData, CanonicalInput, QueryResult, Reveal}; @@ -40,6 +41,10 @@ pub trait Ty>: fn new_var(interner: I, var: ty::TyVid) -> Self; + fn new_param(interner: I, param: I::ParamTy) -> Self; + + fn new_placeholder(interner: I, param: I::PlaceholderTy) -> Self; + fn new_bound(interner: I, debruijn: ty::DebruijnIndex, var: I::BoundTy) -> Self; fn new_anon_bound(interner: I, debruijn: ty::DebruijnIndex, var: ty::BoundVar) -> Self; @@ -429,6 +434,8 @@ pub trait Predicate>: + UpcastFrom> + IntoKind>> { + fn as_clause(self) -> Option; + fn is_coinductive(self, interner: I) -> bool; // FIXME: Eventually uplift the impl out of rustc and make this defaulted. @@ -441,35 +448,35 @@ pub trait Clause>: + Hash + Eq + TypeFoldable - // FIXME: Remove these, uplift the `Upcast` impls. + + UpcastFrom>> + UpcastFrom> + UpcastFrom>> + UpcastFrom> + UpcastFrom>> + IntoKind>> + + Elaboratable { fn as_trait_clause(self) -> Option>> { self.kind() - .map_bound(|clause| { - if let ty::ClauseKind::Trait(t) = clause { - Some(t) - } else { - None - } - }) + .map_bound(|clause| if let ty::ClauseKind::Trait(t) = clause { Some(t) } else { None }) .transpose() } + fn as_projection_clause(self) -> Option>> { self.kind() - .map_bound(|clause| { - if let ty::ClauseKind::Projection(p) = clause { - Some(p) - } else { - None - } - }) + .map_bound( + |clause| { + if let ty::ClauseKind::Projection(p) = clause { Some(p) } else { None } + }, + ) .transpose() } + + /// Performs a instantiation suitable for going from a + /// poly-trait-ref to supertraits that must hold if that + /// poly-trait-ref holds. This is slightly different from a normal + /// instantiation in terms of what happens with bound regions. + fn instantiate_supertrait(self, tcx: I, trait_ref: ty::Binder>) -> Self; } /// Common capabilities of placeholder kinds diff --git a/compiler/rustc_type_ir/src/interner.rs b/compiler/rustc_type_ir/src/interner.rs index 6e013768c3ea8..446a4060e62f8 100644 --- a/compiler/rustc_type_ir/src/interner.rs +++ b/compiler/rustc_type_ir/src/interner.rs @@ -32,7 +32,7 @@ pub trait Interner: { type DefId: DefId; type LocalDefId: Copy + Debug + Hash + Eq + Into + TypeFoldable; - type Span: Copy + Debug + Hash + Eq; + type Span: Copy + Debug + Hash + Eq + TypeFoldable; type GenericArgs: GenericArgs; type GenericArgsSlice: Copy + Debug + Hash + Eq + SliceLike; @@ -213,7 +213,12 @@ pub trait Interner: fn explicit_super_predicates_of( self, def_id: Self::DefId, - ) -> ty::EarlyBinder>; + ) -> ty::EarlyBinder>; + + fn explicit_implied_predicates_of( + self, + def_id: Self::DefId, + ) -> ty::EarlyBinder>; fn has_target_features(self, def_id: Self::DefId) -> bool; @@ -268,6 +273,11 @@ pub trait Interner: param_env: Self::ParamEnv, placeholder: Self::PlaceholderConst, ) -> Self::Ty; + + fn anonymize_bound_vars>( + self, + binder: ty::Binder, + ) -> ty::Binder; } /// Imagine you have a function `F: FnOnce(&[T]) -> R`, plus an iterator `iter` diff --git a/compiler/rustc_type_ir/src/lib.rs b/compiler/rustc_type_ir/src/lib.rs index 2a909b06baf3a..b14a65fc77958 100644 --- a/compiler/rustc_type_ir/src/lib.rs +++ b/compiler/rustc_type_ir/src/lib.rs @@ -20,6 +20,7 @@ pub mod visit; #[cfg(feature = "nightly")] pub mod codec; pub mod data_structures; +pub mod elaborate; pub mod error; pub mod fast_reject; pub mod fold; From 66eb346770a97fe96c02a79a740cb151e5232010 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sat, 6 Jul 2024 12:33:03 -0400 Subject: [PATCH 809/892] Get rid of the redundant elaboration in middle --- compiler/rustc_middle/src/traits/mod.rs | 1 - compiler/rustc_middle/src/traits/util.rs | 62 ------------------- compiler/rustc_middle/src/ty/context.rs | 26 +------- compiler/rustc_middle/src/ty/print/pretty.rs | 15 ++--- .../src/solve/trait_goals.rs | 5 +- compiler/rustc_type_ir/src/elaborate.rs | 28 +++++++++ compiler/rustc_type_ir/src/interner.rs | 3 - 7 files changed, 40 insertions(+), 100 deletions(-) delete mode 100644 compiler/rustc_middle/src/traits/util.rs diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs index b4e3fae1b43b0..b74775142e487 100644 --- a/compiler/rustc_middle/src/traits/mod.rs +++ b/compiler/rustc_middle/src/traits/mod.rs @@ -7,7 +7,6 @@ pub mod select; pub mod solve; pub mod specialization_graph; mod structural_impls; -pub mod util; use crate::mir::ConstraintCategory; use crate::ty::abstract_const::NotConstEvaluatable; diff --git a/compiler/rustc_middle/src/traits/util.rs b/compiler/rustc_middle/src/traits/util.rs deleted file mode 100644 index 7437be7a74c14..0000000000000 --- a/compiler/rustc_middle/src/traits/util.rs +++ /dev/null @@ -1,62 +0,0 @@ -use rustc_data_structures::fx::FxHashSet; - -use crate::ty::{Clause, PolyTraitRef, ToPolyTraitRef, TyCtxt, Upcast}; - -/// Given a [`PolyTraitRef`], get the [`Clause`]s implied by the trait's definition. -/// -/// This only exists in `rustc_middle` because the more powerful elaborator depends on -/// `rustc_infer` for elaborating outlives bounds -- this should only be used for pretty -/// printing. -pub fn super_predicates_for_pretty_printing<'tcx>( - tcx: TyCtxt<'tcx>, - trait_ref: PolyTraitRef<'tcx>, -) -> impl Iterator> { - let clause = trait_ref.upcast(tcx); - Elaborator { tcx, visited: FxHashSet::from_iter([clause]), stack: vec![clause] } -} - -/// Like [`super_predicates_for_pretty_printing`], except it only returns traits and filters out -/// all other [`Clause`]s. -pub fn supertraits_for_pretty_printing<'tcx>( - tcx: TyCtxt<'tcx>, - trait_ref: PolyTraitRef<'tcx>, -) -> impl Iterator> { - super_predicates_for_pretty_printing(tcx, trait_ref).filter_map(|clause| { - clause.as_trait_clause().map(|trait_clause| trait_clause.to_poly_trait_ref()) - }) -} - -struct Elaborator<'tcx> { - tcx: TyCtxt<'tcx>, - visited: FxHashSet>, - stack: Vec>, -} - -impl<'tcx> Elaborator<'tcx> { - fn elaborate(&mut self, trait_ref: PolyTraitRef<'tcx>) { - let super_predicates = - self.tcx.explicit_super_predicates_of(trait_ref.def_id()).predicates.iter().filter_map( - |&(pred, _)| { - let clause = pred.instantiate_supertrait(self.tcx, trait_ref); - self.visited.insert(clause).then_some(clause) - }, - ); - - self.stack.extend(super_predicates); - } -} - -impl<'tcx> Iterator for Elaborator<'tcx> { - type Item = Clause<'tcx>; - - fn next(&mut self) -> Option> { - if let Some(clause) = self.stack.pop() { - if let Some(trait_clause) = clause.as_trait_clause() { - self.elaborate(trait_clause.to_poly_trait_ref()); - } - Some(clause) - } else { - None - } - } -} diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 59ab5d791399b..c249579c5d723 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -37,7 +37,7 @@ use crate::ty::{GenericArg, GenericArgs, GenericArgsRef}; use rustc_ast::{self as ast, attr}; use rustc_data_structures::defer; use rustc_data_structures::fingerprint::Fingerprint; -use rustc_data_structures::fx::{FxHashMap, FxHashSet}; +use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::intern::Interned; use rustc_data_structures::profiling::SelfProfilerRef; use rustc_data_structures::sharded::{IntoPointer, ShardedHashMap}; @@ -532,10 +532,6 @@ impl<'tcx> Interner for TyCtxt<'tcx> { self.trait_def(trait_def_id).implement_via_object } - fn supertrait_def_ids(self, trait_def_id: DefId) -> impl IntoIterator { - self.supertrait_def_ids(trait_def_id) - } - fn delay_bug(self, msg: impl ToString) -> ErrorGuaranteed { self.dcx().span_delayed_bug(DUMMY_SP, msg.to_string()) } @@ -2495,25 +2491,7 @@ impl<'tcx> TyCtxt<'tcx> { /// to identify which traits may define a given associated type to help avoid cycle errors, /// and to make size estimates for vtable layout computation. pub fn supertrait_def_ids(self, trait_def_id: DefId) -> impl Iterator + 'tcx { - let mut set = FxHashSet::default(); - let mut stack = vec![trait_def_id]; - - set.insert(trait_def_id); - - iter::from_fn(move || -> Option { - let trait_did = stack.pop()?; - let generic_predicates = self.explicit_super_predicates_of(trait_did); - - for (predicate, _) in generic_predicates.predicates { - if let ty::ClauseKind::Trait(data) = predicate.kind().skip_binder() { - if set.insert(data.def_id()) { - stack.push(data.def_id()); - } - } - } - - Some(trait_did) - }) + rustc_type_ir::elaborate::supertrait_def_ids(self, trait_def_id) } /// Given a closure signature, returns an equivalent fn signature. Detuples diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 7e64c50740659..df080b2887b89 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -1,7 +1,6 @@ use crate::mir::interpret::{AllocRange, GlobalAlloc, Pointer, Provenance, Scalar}; use crate::query::IntoQueryParam; use crate::query::Providers; -use crate::traits::util::{super_predicates_for_pretty_printing, supertraits_for_pretty_printing}; use crate::ty::GenericArgKind; use crate::ty::{ ConstInt, Expr, ParamConst, ScalarInt, Term, TermKind, TypeFoldable, TypeSuperFoldable, @@ -23,6 +22,7 @@ use rustc_span::symbol::{kw, Ident, Symbol}; use rustc_span::FileNameDisplayPreference; use rustc_target::abi::Size; use rustc_target::spec::abi::Abi; +use rustc_type_ir::{elaborate, Upcast as _}; use smallvec::SmallVec; use std::cell::Cell; @@ -1255,14 +1255,14 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { entry.has_fn_once = true; return; } else if self.tcx().is_lang_item(trait_def_id, LangItem::FnMut) { - let super_trait_ref = supertraits_for_pretty_printing(self.tcx(), trait_ref) + let super_trait_ref = elaborate::supertraits(self.tcx(), trait_ref) .find(|super_trait_ref| super_trait_ref.def_id() == fn_once_trait) .unwrap(); fn_traits.entry(super_trait_ref).or_default().fn_mut_trait_ref = Some(trait_ref); return; } else if self.tcx().is_lang_item(trait_def_id, LangItem::Fn) { - let super_trait_ref = supertraits_for_pretty_printing(self.tcx(), trait_ref) + let super_trait_ref = elaborate::supertraits(self.tcx(), trait_ref) .find(|super_trait_ref| super_trait_ref.def_id() == fn_once_trait) .unwrap(); @@ -1343,10 +1343,11 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { let bound_principal_with_self = bound_principal .with_self_ty(cx.tcx(), cx.tcx().types.trait_object_dummy_self); - let super_projections: Vec<_> = - super_predicates_for_pretty_printing(cx.tcx(), bound_principal_with_self) - .filter_map(|clause| clause.as_projection_clause()) - .collect(); + let clause: ty::Clause<'tcx> = bound_principal_with_self.upcast(cx.tcx()); + let super_projections: Vec<_> = elaborate::elaborate(cx.tcx(), [clause]) + .filter_only_self() + .filter_map(|clause| clause.as_projection_clause()) + .collect(); let mut projections: Vec<_> = predicates .projection_bounds() diff --git a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs index b2a59eece0d16..f1128f70aaaa6 100644 --- a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs +++ b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs @@ -6,7 +6,7 @@ use rustc_type_ir::fast_reject::{DeepRejectCtxt, TreatParams}; use rustc_type_ir::inherent::*; use rustc_type_ir::lang_items::TraitSolverLangItem; use rustc_type_ir::visit::TypeVisitableExt as _; -use rustc_type_ir::{self as ty, Interner, TraitPredicate, Upcast as _}; +use rustc_type_ir::{self as ty, elaborate, Interner, TraitPredicate, Upcast as _}; use tracing::{instrument, trace}; use crate::delegate::SolverDelegate; @@ -862,8 +862,7 @@ where .auto_traits() .into_iter() .chain(a_data.principal_def_id().into_iter().flat_map(|principal_def_id| { - self.cx() - .supertrait_def_ids(principal_def_id) + elaborate::supertrait_def_ids(self.cx(), principal_def_id) .into_iter() .filter(|def_id| self.cx().trait_is_auto(*def_id)) })) diff --git a/compiler/rustc_type_ir/src/elaborate.rs b/compiler/rustc_type_ir/src/elaborate.rs index 04cdf29a77799..0def7d12f742a 100644 --- a/compiler/rustc_type_ir/src/elaborate.rs +++ b/compiler/rustc_type_ir/src/elaborate.rs @@ -229,6 +229,34 @@ impl> Iterator for Elaborator { // Supertrait iterator /////////////////////////////////////////////////////////////////////////// +/// Computes the def-ids of the transitive supertraits of `trait_def_id`. This (intentionally) +/// does not compute the full elaborated super-predicates but just the set of def-ids. It is used +/// to identify which traits may define a given associated type to help avoid cycle errors, +/// and to make size estimates for vtable layout computation. +pub fn supertrait_def_ids( + cx: I, + trait_def_id: I::DefId, +) -> impl Iterator { + let mut set = HashSet::default(); + let mut stack = vec![trait_def_id]; + + set.insert(trait_def_id); + + std::iter::from_fn(move || { + let trait_def_id = stack.pop()?; + + for (predicate, _) in cx.explicit_super_predicates_of(trait_def_id).iter_identity() { + if let ty::ClauseKind::Trait(data) = predicate.kind().skip_binder() { + if set.insert(data.def_id()) { + stack.push(data.def_id()); + } + } + } + + Some(trait_def_id) + }) +} + pub fn supertraits( tcx: I, trait_ref: ty::Binder>, diff --git a/compiler/rustc_type_ir/src/interner.rs b/compiler/rustc_type_ir/src/interner.rs index 446a4060e62f8..6a291a02d6126 100644 --- a/compiler/rustc_type_ir/src/interner.rs +++ b/compiler/rustc_type_ir/src/interner.rs @@ -253,9 +253,6 @@ pub trait Interner: fn trait_may_be_implemented_via_object(self, trait_def_id: Self::DefId) -> bool; - fn supertrait_def_ids(self, trait_def_id: Self::DefId) - -> impl IntoIterator; - fn delay_bug(self, msg: impl ToString) -> Self::ErrorGuaranteed; fn is_general_coroutine(self, coroutine_def_id: Self::DefId) -> bool; From 15d16f1cd6f4daea12c7be4e34ff3b5a776671d2 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sat, 6 Jul 2024 12:37:04 -0400 Subject: [PATCH 810/892] Finish uplifting supertraits --- compiler/rustc_next_trait_solver/src/delegate.rs | 6 ------ .../rustc_next_trait_solver/src/solve/assembly/mod.rs | 3 ++- compiler/rustc_next_trait_solver/src/solve/trait_goals.rs | 2 +- compiler/rustc_trait_selection/src/solve/delegate.rs | 8 -------- 4 files changed, 3 insertions(+), 16 deletions(-) diff --git a/compiler/rustc_next_trait_solver/src/delegate.rs b/compiler/rustc_next_trait_solver/src/delegate.rs index 31032dc679ac3..cdea7363d0e62 100644 --- a/compiler/rustc_next_trait_solver/src/delegate.rs +++ b/compiler/rustc_next_trait_solver/src/delegate.rs @@ -32,12 +32,6 @@ pub trait SolverDelegate: // FIXME: Uplift the leak check into this crate. fn leak_check(&self, max_input_universe: ty::UniverseIndex) -> Result<(), NoSolution>; - // FIXME: This is only here because elaboration lives in `rustc_infer`! - fn elaborate_supertraits( - cx: Self::Interner, - trait_ref: ty::Binder>, - ) -> impl Iterator>>; - fn try_const_eval_resolve( &self, param_env: ::ParamEnv, diff --git a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs index 38a4f7dfe25cb..01dde9ca587ca 100644 --- a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs @@ -2,6 +2,7 @@ pub(super) mod structural_traits; +use rustc_type_ir::elaborate; use rustc_type_ir::fold::TypeFoldable; use rustc_type_ir::inherent::*; use rustc_type_ir::lang_items::TraitSolverLangItem; @@ -667,7 +668,7 @@ where // a projection goal. if let Some(principal) = bounds.principal() { let principal_trait_ref = principal.with_self_ty(cx, self_ty); - for (idx, assumption) in D::elaborate_supertraits(cx, principal_trait_ref).enumerate() { + for (idx, assumption) in elaborate::supertraits(cx, principal_trait_ref).enumerate() { candidates.extend(G::probe_and_consider_object_bound_candidate( self, CandidateSource::BuiltinImpl(BuiltinImplSource::Object(idx)), diff --git a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs index f1128f70aaaa6..4474bbc235198 100644 --- a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs +++ b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs @@ -787,7 +787,7 @@ where )); } else if let Some(a_principal) = a_data.principal() { for new_a_principal in - D::elaborate_supertraits(self.cx(), a_principal.with_self_ty(cx, a_ty)).skip(1) + elaborate::supertraits(self.cx(), a_principal.with_self_ty(cx, a_ty)).skip(1) { responses.extend(self.consider_builtin_upcast_to_principal( goal, diff --git a/compiler/rustc_trait_selection/src/solve/delegate.rs b/compiler/rustc_trait_selection/src/solve/delegate.rs index f98744e906f05..03743e57333a7 100644 --- a/compiler/rustc_trait_selection/src/solve/delegate.rs +++ b/compiler/rustc_trait_selection/src/solve/delegate.rs @@ -8,7 +8,6 @@ use rustc_infer::infer::canonical::{ }; use rustc_infer::infer::{InferCtxt, RegionVariableOrigin, TyCtxtInferExt}; use rustc_infer::traits::solve::Goal; -use rustc_infer::traits::util::supertraits; use rustc_infer::traits::{ObligationCause, Reveal}; use rustc_middle::ty::fold::TypeFoldable; use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt as _}; @@ -82,13 +81,6 @@ impl<'tcx> rustc_next_trait_solver::delegate::SolverDelegate for SolverDelegate< self.0.leak_check(max_input_universe, None).map_err(|_| NoSolution) } - fn elaborate_supertraits( - interner: TyCtxt<'tcx>, - trait_ref: ty::Binder<'tcx, ty::TraitRef<'tcx>>, - ) -> impl Iterator>> { - supertraits(interner, trait_ref) - } - fn try_const_eval_resolve( &self, param_env: ty::ParamEnv<'tcx>, From a0f2b41d03bd5118df86f29d5a75756990bc4cd9 Mon Sep 17 00:00:00 2001 From: Ashton Hunt Date: Sun, 7 Jul 2024 09:29:16 -0600 Subject: [PATCH 811/892] clarify `sys::unix::fd::FileDesc::drop` comment (#66876) --- library/std/src/os/fd/owned.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/library/std/src/os/fd/owned.rs b/library/std/src/os/fd/owned.rs index 8c7fc4cb2e453..a1f83029d2727 100644 --- a/library/std/src/os/fd/owned.rs +++ b/library/std/src/os/fd/owned.rs @@ -175,6 +175,11 @@ impl Drop for OwnedFd { // the file descriptor was closed or not, and if we retried (for // something like EINTR), we might close another valid file descriptor // opened after we closed ours. + // However, this is usually justified, as some of the major Unices + // do make sure to always close the FD, even when `close()` is interrupted, + // and the scenario is rare to begin with. + // Helpful link to an epic discussion by POSIX workgroup: + // http://austingroupbugs.net/view.php?id=529 #[cfg(not(target_os = "hermit"))] { #[cfg(unix)] From 54aa9e8ba2efe68bfcf5c407a5a9cf1a8d17b354 Mon Sep 17 00:00:00 2001 From: Charles Celerier Date: Sat, 6 Jul 2024 05:15:38 +0000 Subject: [PATCH 812/892] [fuchsia-test-runner] Remove runner logs from stdout and stderr Many tests use stdout and stderr to validate whether the test emitted the correct output. Because fuchsia-test-runner.py was sending all logs, including test output, to stdout, tests could not validate output properly. This change removes the runner logs from stdout and stderr entirely with the exception of output from the test. All runner logs are still available in the "log" file. Fixed: https://fxbug.dev/351356417 --- src/ci/docker/scripts/fuchsia-test-runner.py | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/src/ci/docker/scripts/fuchsia-test-runner.py b/src/ci/docker/scripts/fuchsia-test-runner.py index 6db25ff1a809e..1a2e69712a92f 100755 --- a/src/ci/docker/scripts/fuchsia-test-runner.py +++ b/src/ci/docker/scripts/fuchsia-test-runner.py @@ -271,13 +271,6 @@ def setup_logging(self, log_to_file=False): logfile_handler.setLevel(logging.DEBUG) logfile_handler.setFormatter(fs) logging.getLogger().addHandler(logfile_handler) - stream_handler = logging.StreamHandler(sys.stdout) - stream_handler.setFormatter(fs) - if self.verbose: - stream_handler.setLevel(logging.DEBUG) - else: - stream_handler.setLevel(logging.INFO) - logging.getLogger().addHandler(stream_handler) logging.getLogger().setLevel(logging.DEBUG) @property @@ -927,7 +920,7 @@ def run(self, args): ) else: with open(stdout_path, encoding="utf-8", errors="ignore") as f: - runner_logger.info(f.read()) + sys.stdout.write(f.read()) if stderr_path is not None: if not os.path.exists(stderr_path): runner_logger.error( @@ -935,7 +928,7 @@ def run(self, args): ) else: with open(stderr_path, encoding="utf-8", errors="ignore") as f: - runner_logger.error(f.read()) + sys.stderr.write(f.read()) runner_logger.info("Done!") return return_code From 3d5b4d8f7cd721ded6589edc2e6e350a8575848f Mon Sep 17 00:00:00 2001 From: Charles Celerier Date: Sun, 7 Jul 2024 15:33:31 +0000 Subject: [PATCH 813/892] [fuchsia-test-runner] Reformat fuchsia-test-runner.py Applied formatting suggestions from isort and black via pylsp. --- src/ci/docker/scripts/fuchsia-test-runner.py | 52 ++++++-------------- 1 file changed, 15 insertions(+), 37 deletions(-) diff --git a/src/ci/docker/scripts/fuchsia-test-runner.py b/src/ci/docker/scripts/fuchsia-test-runner.py index 1a2e69712a92f..00269e68422d3 100755 --- a/src/ci/docker/scripts/fuchsia-test-runner.py +++ b/src/ci/docker/scripts/fuchsia-test-runner.py @@ -8,8 +8,6 @@ """ import argparse -from concurrent.futures import ThreadPoolExecutor -from dataclasses import dataclass import glob import io import json @@ -20,6 +18,8 @@ import shutil import subprocess import sys +from concurrent.futures import ThreadPoolExecutor +from dataclasses import dataclass from pathlib import Path from typing import ClassVar, List, Optional @@ -42,12 +42,8 @@ def exhaust_pipe(handler, pipe): for line in pipe: handler(line.rstrip()) - executor_out = executor.submit( - exhaust_pipe, stdout_handler, process.stdout - ) - executor_err = executor.submit( - exhaust_pipe, stderr_handler, process.stderr - ) + executor_out = executor.submit(exhaust_pipe, stdout_handler, process.stdout) + executor_err = executor.submit(exhaust_pipe, stderr_handler, process.stderr) executor_out.result() executor_err.result() retcode = process.poll() @@ -203,9 +199,7 @@ def build_id(self, binary): raise Exception(f"Unreadable build-id for binary {binary}") data = json.loads(process.stdout) if len(data) != 1: - raise Exception( - f"Unreadable output from llvm-readelf for binary {binary}" - ) + raise Exception(f"Unreadable output from llvm-readelf for binary {binary}") notes = data[0]["Notes"] for note in notes: note_section = note["NoteSection"] @@ -265,9 +259,7 @@ def write_to_file(self): def setup_logging(self, log_to_file=False): fs = logging.Formatter("%(asctime)s %(levelname)s:%(name)s:%(message)s") if log_to_file: - logfile_handler = logging.FileHandler( - self.tmp_dir().joinpath("log") - ) + logfile_handler = logging.FileHandler(self.tmp_dir().joinpath("log")) logfile_handler.setLevel(logging.DEBUG) logfile_handler.setFormatter(fs) logging.getLogger().addHandler(logfile_handler) @@ -447,9 +439,7 @@ def start(self): # Initialize temp directory os.makedirs(self.tmp_dir(), exist_ok=True) if len(os.listdir(self.tmp_dir())) != 0: - raise Exception( - f"Temp directory is not clean (in {self.tmp_dir()})" - ) + raise Exception(f"Temp directory is not clean (in {self.tmp_dir()})") self.setup_logging(log_to_file=True) os.mkdir(self.output_dir) @@ -486,9 +476,7 @@ def start(self): shutil.rmtree(self.local_pb_path, ignore_errors=True) # Look up the product bundle transfer manifest. - self.env_logger.info( - "Looking up the product bundle transfer manifest..." - ) + self.env_logger.info("Looking up the product bundle transfer manifest...") product_name = "minimal." + self.triple_to_arch(self.target) sdk_version = self.read_sdk_version() @@ -510,9 +498,7 @@ def start(self): ) try: - transfer_manifest_url = json.loads(output)[ - "transfer_manifest_url" - ] + transfer_manifest_url = json.loads(output)["transfer_manifest_url"] except Exception as e: print(e) raise Exception("Unable to parse transfer manifest") from e @@ -762,9 +748,7 @@ def run(self, args): # Use /tmp as the test temporary directory env_vars += '\n "RUST_TEST_TMPDIR=/tmp",' - cml.write( - self.CML_TEMPLATE.format(env_vars=env_vars, exe_name=exe_name) - ) + cml.write(self.CML_TEMPLATE.format(env_vars=env_vars, exe_name=exe_name)) runner_logger.info("Compiling CML...") @@ -915,17 +899,13 @@ def run(self, args): if stdout_path is not None: if not os.path.exists(stdout_path): - runner_logger.error( - f"stdout file {stdout_path} does not exist." - ) + runner_logger.error(f"stdout file {stdout_path} does not exist.") else: with open(stdout_path, encoding="utf-8", errors="ignore") as f: sys.stdout.write(f.read()) if stderr_path is not None: if not os.path.exists(stderr_path): - runner_logger.error( - f"stderr file {stderr_path} does not exist." - ) + runner_logger.error(f"stderr file {stderr_path} does not exist.") else: with open(stderr_path, encoding="utf-8", errors="ignore") as f: sys.stderr.write(f.read()) @@ -1030,7 +1010,7 @@ def debug(self, args): f"--symbol-path={self.rust_dir}/lib/rustlib/{self.target}/lib", ] - # Add rust source if it's available + # Add rust source if it's available rust_src_map = None if args.rust_src is not None: # This matches the remapped prefix used by compiletest. There's no @@ -1203,7 +1183,7 @@ def print_help(args): start_parser.add_argument( "--use-local-product-bundle-if-exists", help="if the product bundle already exists in the local path, use " - "it instead of downloading it again", + "it instead of downloading it again", action="store_true", ) start_parser.set_defaults(func=start) @@ -1239,9 +1219,7 @@ def print_help(args): ) cleanup_parser.set_defaults(func=cleanup) - syslog_parser = subparsers.add_parser( - "syslog", help="prints the device syslog" - ) + syslog_parser = subparsers.add_parser("syslog", help="prints the device syslog") syslog_parser.set_defaults(func=syslog) debug_parser = subparsers.add_parser( From cda25e56c8d4f810d19034ebf5d0e4fdb155a264 Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Fri, 15 Mar 2024 15:08:20 +0000 Subject: [PATCH 814/892] Refactor & fixup interpreter implementation of tail calls --- .../src/interpret/eval_context.rs | 145 +++++++++++++----- .../rustc_const_eval/src/interpret/machine.rs | 3 + .../rustc_const_eval/src/interpret/step.rs | 2 +- .../src/interpret/terminator.rs | 82 ++++++---- 4 files changed, 162 insertions(+), 70 deletions(-) diff --git a/compiler/rustc_const_eval/src/interpret/eval_context.rs b/compiler/rustc_const_eval/src/interpret/eval_context.rs index 830c4bd3e26e0..fd063575e5d98 100644 --- a/compiler/rustc_const_eval/src/interpret/eval_context.rs +++ b/compiler/rustc_const_eval/src/interpret/eval_context.rs @@ -159,6 +159,13 @@ pub enum StackPopCleanup { Root { cleanup: bool }, } +/// Return type of [`InterpCx::pop_stack_frame`]. +pub struct StackPop<'tcx, Prov: Provenance> { + pub jump: StackPopJump, + pub target: StackPopCleanup, + pub destination: MPlaceTy<'tcx, Prov>, +} + /// State of a local variable including a memoized layout #[derive(Clone)] pub struct LocalState<'tcx, Prov: Provenance = CtfeProvenance> { @@ -803,14 +810,31 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { return_to_block: StackPopCleanup, ) -> InterpResult<'tcx> { trace!("body: {:#?}", body); + + // First push a stack frame so we have access to the local args + self.push_new_stack_frame(instance, body, return_to_block, return_place.clone())?; + + self.after_stack_frame_push(instance, body)?; + + Ok(()) + } + + /// Creates a new stack frame, initializes it and pushes it unto the stack. + /// A private helper for [`push_stack_frame`](InterpCx::push_stack_frame). + fn push_new_stack_frame( + &mut self, + instance: ty::Instance<'tcx>, + body: &'tcx mir::Body<'tcx>, + return_to_block: StackPopCleanup, + return_place: MPlaceTy<'tcx, M::Provenance>, + ) -> InterpResult<'tcx> { let dead_local = LocalState { value: LocalValue::Dead, layout: Cell::new(None) }; let locals = IndexVec::from_elem(dead_local, &body.local_decls); - // First push a stack frame so we have access to the local args let pre_frame = Frame { body, loc: Right(body.span), // Span used for errors caused during preamble. return_to_block, - return_place: return_place.clone(), + return_place, locals, instance, tracing_span: SpanGuard::new(), @@ -819,6 +843,15 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { let frame = M::init_frame(self, pre_frame)?; self.stack_mut().push(frame); + Ok(()) + } + + /// A private helper for [`push_stack_frame`](InterpCx::push_stack_frame). + fn after_stack_frame_push( + &mut self, + instance: ty::Instance<'tcx>, + body: &'tcx mir::Body<'tcx>, + ) -> InterpResult<'tcx> { // Make sure all the constants required by this frame evaluate successfully (post-monomorphization check). for &const_ in &body.required_consts { let c = @@ -839,6 +872,59 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { Ok(()) } + /// Pops a stack frame from the stack and returns some information about it. + /// + /// This also deallocates locals, if necessary. + /// + /// [`M::before_stack_pop`] should be called before calling this function. + /// [`M::after_stack_pop`] is called by this function automatically. + /// + /// [`M::before_stack_pop`]: Machine::before_stack_pop + /// [`M::after_stack_pop`]: Machine::after_stack_pop + pub fn pop_stack_frame( + &mut self, + unwinding: bool, + ) -> InterpResult<'tcx, StackPop<'tcx, M::Provenance>> { + let cleanup = self.cleanup_current_frame_locals()?; + + let frame = + self.stack_mut().pop().expect("tried to pop a stack frame, but there were none"); + + let target = frame.return_to_block; + let destination = frame.return_place.clone(); + + let jump = if cleanup { + M::after_stack_pop(self, frame, unwinding)? + } else { + StackPopJump::NoCleanup + }; + + Ok(StackPop { jump, target, destination }) + } + + /// A private helper for [`push_stack_frame`](InterpCx::push_stack_frame). + /// Returns whatever the cleanup was done. + fn cleanup_current_frame_locals(&mut self) -> InterpResult<'tcx, bool> { + // Cleanup: deallocate locals. + // Usually we want to clean up (deallocate locals), but in a few rare cases we don't. + // We do this while the frame is still on the stack, so errors point to the callee. + let return_to_block = self.frame().return_to_block; + let cleanup = match return_to_block { + StackPopCleanup::Goto { .. } => true, + StackPopCleanup::Root { cleanup, .. } => cleanup, + }; + + if cleanup { + // We need to take the locals out, since we need to mutate while iterating. + let locals = mem::take(&mut self.frame_mut().locals); + for local in &locals { + self.deallocate_local(local.value)?; + } + } + + Ok(cleanup) + } + /// Jump to the given block. #[inline] pub fn go_to_block(&mut self, target: mir::BasicBlock) { @@ -886,7 +972,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { } /// Pops the current frame from the stack, deallocating the - /// memory for allocated locals. + /// memory for allocated locals, and jumps to an appropriate place. /// /// If `unwinding` is `false`, then we are performing a normal return /// from a function. In this case, we jump back into the frame of the caller, @@ -899,7 +985,10 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { /// The cleanup block ends with a special `Resume` terminator, which will /// cause us to continue unwinding. #[instrument(skip(self), level = "debug")] - pub(super) fn pop_stack_frame(&mut self, unwinding: bool) -> InterpResult<'tcx> { + pub(super) fn return_from_current_stack_frame( + &mut self, + unwinding: bool, + ) -> InterpResult<'tcx> { info!( "popping stack frame ({})", if unwinding { "during unwinding" } else { "returning from function" } @@ -947,45 +1036,31 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { Ok(()) }; - // Cleanup: deallocate locals. - // Usually we want to clean up (deallocate locals), but in a few rare cases we don't. - // We do this while the frame is still on the stack, so errors point to the callee. - let return_to_block = self.frame().return_to_block; - let cleanup = match return_to_block { - StackPopCleanup::Goto { .. } => true, - StackPopCleanup::Root { cleanup, .. } => cleanup, - }; - if cleanup { - // We need to take the locals out, since we need to mutate while iterating. - let locals = mem::take(&mut self.frame_mut().locals); - for local in &locals { - self.deallocate_local(local.value)?; - } - } - // All right, now it is time to actually pop the frame. - // Note that its locals are gone already, but that's fine. - let frame = - self.stack_mut().pop().expect("tried to pop a stack frame, but there were none"); + let frame = self.pop_stack_frame(unwinding)?; + // Report error from return value copy, if any. copy_ret_result?; - // If we are not doing cleanup, also skip everything else. - if !cleanup { - assert!(self.stack().is_empty(), "only the topmost frame should ever be leaked"); - assert!(!unwinding, "tried to skip cleanup during unwinding"); - // Skip machine hook. - return Ok(()); - } - if M::after_stack_pop(self, frame, unwinding)? == StackPopJump::NoJump { - // The hook already did everything. - return Ok(()); + match frame.jump { + StackPopJump::Normal => {} + StackPopJump::NoJump => { + // The hook already did everything. + return Ok(()); + } + StackPopJump::NoCleanup => { + // If we are not doing cleanup, also skip everything else. + assert!(self.stack().is_empty(), "only the topmost frame should ever be leaked"); + assert!(!unwinding, "tried to skip cleanup during unwinding"); + // Skip machine hook. + return Ok(()); + } } // Normal return, figure out where to jump. if unwinding { // Follow the unwind edge. - let unwind = match return_to_block { + let unwind = match frame.target { StackPopCleanup::Goto { unwind, .. } => unwind, StackPopCleanup::Root { .. } => { panic!("encountered StackPopCleanup::Root when unwinding!") @@ -995,7 +1070,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { self.unwind_to_block(unwind) } else { // Follow the normal return edge. - match return_to_block { + match frame.target { StackPopCleanup::Goto { ret, .. } => self.return_to_block(ret), StackPopCleanup::Root { .. } => { assert!( diff --git a/compiler/rustc_const_eval/src/interpret/machine.rs b/compiler/rustc_const_eval/src/interpret/machine.rs index e91ab7c179163..b8a651a744aa6 100644 --- a/compiler/rustc_const_eval/src/interpret/machine.rs +++ b/compiler/rustc_const_eval/src/interpret/machine.rs @@ -36,6 +36,9 @@ pub enum StackPopJump { /// Indicates that we should *not* jump to the return/unwind address, as the callback already /// took care of everything. NoJump, + + /// Returned by [`InterpCx::pop_stack_frame`] when no cleanup should be done. + NoCleanup, } /// Whether this kind of memory is allowed to leak diff --git a/compiler/rustc_const_eval/src/interpret/step.rs b/compiler/rustc_const_eval/src/interpret/step.rs index 1baf62baa816f..b3124dfdfbc01 100644 --- a/compiler/rustc_const_eval/src/interpret/step.rs +++ b/compiler/rustc_const_eval/src/interpret/step.rs @@ -32,7 +32,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { // We are unwinding and this fn has no cleanup code. // Just go on unwinding. trace!("unwinding: skipping frame"); - self.pop_stack_frame(/* unwinding */ true)?; + self.return_from_current_stack_frame(/* unwinding */ true)?; return Ok(true); }; let basic_block = &self.body().basic_blocks[loc.block]; diff --git a/compiler/rustc_const_eval/src/interpret/terminator.rs b/compiler/rustc_const_eval/src/interpret/terminator.rs index 6644e70e039a8..a8d18405b6e56 100644 --- a/compiler/rustc_const_eval/src/interpret/terminator.rs +++ b/compiler/rustc_const_eval/src/interpret/terminator.rs @@ -4,9 +4,8 @@ use either::Either; use rustc_middle::ty::TyCtxt; use tracing::trace; -use rustc_middle::span_bug; use rustc_middle::{ - mir, + bug, mir, span_bug, ty::{ self, layout::{FnAbiOf, IntegerExt, LayoutOf, TyAndLayout}, @@ -26,7 +25,10 @@ use super::{ InterpResult, MPlaceTy, Machine, OpTy, PlaceTy, Projectable, Provenance, Scalar, StackPopCleanup, }; -use crate::fluent_generated as fluent; +use crate::{ + fluent_generated as fluent, + interpret::{eval_context::StackPop, StackPopJump}, +}; /// An argment passed to a function. #[derive(Clone, Debug)] @@ -93,7 +95,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { use rustc_middle::mir::TerminatorKind::*; match terminator.kind { Return => { - self.pop_stack_frame(/* unwinding */ false)? + self.return_from_current_stack_frame(/* unwinding */ false)? } Goto { target } => self.go_to_block(target), @@ -160,35 +162,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { let EvaluatedCalleeAndArgs { callee, args, fn_sig, fn_abi, with_caller_location } = self.eval_callee_and_args(terminator, func, args)?; - // This is the "canonical" implementation of tails calls, - // a pop of the current stack frame, followed by a normal call - // which pushes a new stack frame, with the return address from - // the popped stack frame. - // - // Note that we can't use `pop_stack_frame` as it "executes" - // the goto to the return block, but we don't want to, - // only the tail called function should return to the current - // return block. - let Some(prev_frame) = self.stack_mut().pop() else { - span_bug!( - terminator.source_info.span, - "empty stack while evaluating this tail call" - ) - }; - - let StackPopCleanup::Goto { ret, unwind } = prev_frame.return_to_block else { - span_bug!(terminator.source_info.span, "tail call with the root stack frame") - }; - - self.eval_fn_call( - callee, - (fn_sig.abi, fn_abi), - &args, - with_caller_location, - &prev_frame.return_place, - ret, - unwind, - )?; + self.eval_fn_tail_call(callee, (fn_sig.abi, fn_abi), &args, with_caller_location)?; if self.frame_idx() != old_frame_idx { span_bug!( @@ -235,7 +209,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { trace!("unwinding: resuming from cleanup"); // By definition, a Resume terminator means // that we're unwinding - self.pop_stack_frame(/* unwinding */ true)?; + self.return_from_current_stack_frame(/* unwinding */ true)?; return Ok(()); } @@ -989,6 +963,46 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { } } + pub(crate) fn eval_fn_tail_call( + &mut self, + fn_val: FnVal<'tcx, M::ExtraFnVal>, + (caller_abi, caller_fn_abi): (Abi, &FnAbi<'tcx, Ty<'tcx>>), + args: &[FnArg<'tcx, M::Provenance>], + with_caller_location: bool, + ) -> InterpResult<'tcx> { + trace!("eval_fn_call: {:#?}", fn_val); + + // This is the "canonical" implementation of tails calls, + // a pop of the current stack frame, followed by a normal call + // which pushes a new stack frame, with the return address from + // the popped stack frame. + // + // Note that we can't use `pop_stack_frame` as it "executes" + // the goto to the return block, but we don't want to, + // only the tail called function should return to the current + // return block. + + M::before_stack_pop(self, self.frame())?; + + let StackPop { jump, target, destination } = self.pop_stack_frame(false)?; + + assert_eq!(jump, StackPopJump::Normal); + + let StackPopCleanup::Goto { ret, unwind } = target else { + bug!("can't tailcall as root"); + }; + + self.eval_fn_call( + fn_val, + (caller_abi, caller_fn_abi), + args, + with_caller_location, + &destination, + ret, + unwind, + ) + } + fn check_fn_target_features(&self, instance: ty::Instance<'tcx>) -> InterpResult<'tcx, ()> { // Calling functions with `#[target_feature]` is not unsafe on WASM, see #84988 let attrs = self.tcx.codegen_fn_attrs(instance.def_id()); From 6d4995f4e6d3f4fe6ac54943a5b01c3cf752dd5d Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Mon, 17 Jun 2024 15:37:33 +0000 Subject: [PATCH 815/892] add miri tests and a fixme --- .../src/interpret/terminator.rs | 4 ++ .../miri/tests/fail/tail_calls/cc-mismatch.rs | 10 +++++ .../tests/fail/tail_calls/cc-mismatch.stderr | 25 ++++++++++++ .../fail/tail_calls/signature-mismatch-arg.rs | 17 ++++++++ .../tail_calls/signature-mismatch-arg.stderr | 17 ++++++++ src/tools/miri/tests/pass/tail_call.rs | 39 +++++++++++++++++++ 6 files changed, 112 insertions(+) create mode 100644 src/tools/miri/tests/fail/tail_calls/cc-mismatch.rs create mode 100644 src/tools/miri/tests/fail/tail_calls/cc-mismatch.stderr create mode 100644 src/tools/miri/tests/fail/tail_calls/signature-mismatch-arg.rs create mode 100644 src/tools/miri/tests/fail/tail_calls/signature-mismatch-arg.stderr create mode 100644 src/tools/miri/tests/pass/tail_call.rs diff --git a/compiler/rustc_const_eval/src/interpret/terminator.rs b/compiler/rustc_const_eval/src/interpret/terminator.rs index a8d18405b6e56..9f4ca93a3e8d6 100644 --- a/compiler/rustc_const_eval/src/interpret/terminator.rs +++ b/compiler/rustc_const_eval/src/interpret/terminator.rs @@ -992,6 +992,10 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { bug!("can't tailcall as root"); }; + // FIXME(explicit_tail_calls): + // we should check if both caller&callee can/n't unwind, + // see + self.eval_fn_call( fn_val, (caller_abi, caller_fn_abi), diff --git a/src/tools/miri/tests/fail/tail_calls/cc-mismatch.rs b/src/tools/miri/tests/fail/tail_calls/cc-mismatch.rs new file mode 100644 index 0000000000000..5f00dbf257366 --- /dev/null +++ b/src/tools/miri/tests/fail/tail_calls/cc-mismatch.rs @@ -0,0 +1,10 @@ +//@error-in-other-file: Undefined Behavior: calling a function with calling convention C using calling convention Rust +#![feature(explicit_tail_calls)] +#![allow(incomplete_features)] + +fn main() { + let f = unsafe { std::mem::transmute::(f) }; + become f(); +} + +extern "C" fn f() {} diff --git a/src/tools/miri/tests/fail/tail_calls/cc-mismatch.stderr b/src/tools/miri/tests/fail/tail_calls/cc-mismatch.stderr new file mode 100644 index 0000000000000..708972e6eff13 --- /dev/null +++ b/src/tools/miri/tests/fail/tail_calls/cc-mismatch.stderr @@ -0,0 +1,25 @@ +error: Undefined Behavior: calling a function with calling convention C using calling convention Rust + --> RUSTLIB/core/src/ops/function.rs:LL:CC + | +LL | extern "rust-call" fn call_once(self, args: Args) -> Self::Output; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ calling a function with calling convention C using calling convention Rust + | + = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior + = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information + = note: BACKTRACE: + = note: inside `>::call_once - shim(fn())` at RUSTLIB/core/src/ops/function.rs:LL:CC + = note: inside `std::sys_common::backtrace::__rust_begin_short_backtrace::` at RUSTLIB/std/src/sys_common/backtrace.rs:LL:CC + = note: inside closure at RUSTLIB/std/src/rt.rs:LL:CC + = note: inside `std::ops::function::impls:: for &dyn std::ops::Fn() -> i32 + std::marker::Sync + std::panic::RefUnwindSafe>::call_once` at RUSTLIB/core/src/ops/function.rs:LL:CC + = note: inside `std::panicking::r#try::do_call::<&dyn std::ops::Fn() -> i32 + std::marker::Sync + std::panic::RefUnwindSafe, i32>` at RUSTLIB/std/src/panicking.rs:LL:CC + = note: inside `std::panicking::r#try:: i32 + std::marker::Sync + std::panic::RefUnwindSafe>` at RUSTLIB/std/src/panicking.rs:LL:CC + = note: inside `std::panic::catch_unwind::<&dyn std::ops::Fn() -> i32 + std::marker::Sync + std::panic::RefUnwindSafe, i32>` at RUSTLIB/std/src/panic.rs:LL:CC + = note: inside closure at RUSTLIB/std/src/rt.rs:LL:CC + = note: inside `std::panicking::r#try::do_call::<{closure@std::rt::lang_start_internal::{closure#2}}, isize>` at RUSTLIB/std/src/panicking.rs:LL:CC + = note: inside `std::panicking::r#try::` at RUSTLIB/std/src/panicking.rs:LL:CC + = note: inside `std::panic::catch_unwind::<{closure@std::rt::lang_start_internal::{closure#2}}, isize>` at RUSTLIB/std/src/panic.rs:LL:CC + = note: inside `std::rt::lang_start_internal` at RUSTLIB/std/src/rt.rs:LL:CC + = note: inside `std::rt::lang_start::<()>` at RUSTLIB/std/src/rt.rs:LL:CC + +error: aborting due to 1 previous error + diff --git a/src/tools/miri/tests/fail/tail_calls/signature-mismatch-arg.rs b/src/tools/miri/tests/fail/tail_calls/signature-mismatch-arg.rs new file mode 100644 index 0000000000000..3264a74d159e3 --- /dev/null +++ b/src/tools/miri/tests/fail/tail_calls/signature-mismatch-arg.rs @@ -0,0 +1,17 @@ +#![feature(explicit_tail_calls)] +#![allow(incomplete_features)] + +fn main() { + // FIXME(explicit_tail_calls): + // the error should point to `become f(x)`, + // but tail calls mess up the backtrace it seems like... + f(0); + //~^ error: Undefined Behavior: calling a function with argument of type i32 passing data of type u32 +} + +fn f(x: u32) { + let g = unsafe { std::mem::transmute::(g) }; + become g(x); +} + +fn g(_: i32) {} diff --git a/src/tools/miri/tests/fail/tail_calls/signature-mismatch-arg.stderr b/src/tools/miri/tests/fail/tail_calls/signature-mismatch-arg.stderr new file mode 100644 index 0000000000000..2ecc5674c6537 --- /dev/null +++ b/src/tools/miri/tests/fail/tail_calls/signature-mismatch-arg.stderr @@ -0,0 +1,17 @@ +error: Undefined Behavior: calling a function with argument of type i32 passing data of type u32 + --> $DIR/signature-mismatch-arg.rs:LL:CC + | +LL | f(0); + | ^^^^ calling a function with argument of type i32 passing data of type u32 + | + = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior + = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information + = help: this means these two types are not *guaranteed* to be ABI-compatible across all targets + = help: if you think this code should be accepted anyway, please report an issue + = note: BACKTRACE: + = note: inside `main` at $DIR/signature-mismatch-arg.rs:LL:CC + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to 1 previous error + diff --git a/src/tools/miri/tests/pass/tail_call.rs b/src/tools/miri/tests/pass/tail_call.rs new file mode 100644 index 0000000000000..f620070639801 --- /dev/null +++ b/src/tools/miri/tests/pass/tail_call.rs @@ -0,0 +1,39 @@ +#![allow(incomplete_features)] +#![feature(explicit_tail_calls)] + +fn main() { + assert_eq!(factorial(10), 3_628_800); + assert_eq!(mutually_recursive_identity(1000), 1000); +} + +fn factorial(n: u32) -> u32 { + fn factorial_acc(n: u32, acc: u32) -> u32 { + match n { + 0 => acc, + _ => become factorial_acc(n - 1, acc * n), + } + } + + factorial_acc(n, 1) +} + +// this is of course very silly, but we need to demonstrate mutual recursion somehow so... +fn mutually_recursive_identity(x: u32) -> u32 { + fn switch(src: u32, tgt: u32) -> u32 { + match src { + 0 => tgt, + _ if src % 7 == 0 => become advance_with_extra_steps(src, tgt), + _ => become advance(src, tgt), + } + } + + fn advance(src: u32, tgt: u32) -> u32 { + become switch(src - 1, tgt + 1) + } + + fn advance_with_extra_steps(src: u32, tgt: u32) -> u32 { + become advance(src, tgt) + } + + switch(x, 0) +} From cda6f0c25d6421fd6814bd55a25701205da23585 Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Mon, 17 Jun 2024 17:04:28 +0000 Subject: [PATCH 816/892] doc fixups from review --- compiler/rustc_const_eval/src/interpret/eval_context.rs | 6 +++--- compiler/rustc_const_eval/src/interpret/terminator.rs | 8 +++----- tests/ui/explicit-tail-calls/ctfe-collatz-multi-rec.rs | 2 +- 3 files changed, 7 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_const_eval/src/interpret/eval_context.rs b/compiler/rustc_const_eval/src/interpret/eval_context.rs index fd063575e5d98..9517e3d359744 100644 --- a/compiler/rustc_const_eval/src/interpret/eval_context.rs +++ b/compiler/rustc_const_eval/src/interpret/eval_context.rs @@ -819,7 +819,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { Ok(()) } - /// Creates a new stack frame, initializes it and pushes it unto the stack. + /// Creates a new stack frame, initializes it and pushes it onto the stack. /// A private helper for [`push_stack_frame`](InterpCx::push_stack_frame). fn push_new_stack_frame( &mut self, @@ -902,8 +902,8 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { Ok(StackPop { jump, target, destination }) } - /// A private helper for [`push_stack_frame`](InterpCx::push_stack_frame). - /// Returns whatever the cleanup was done. + /// A private helper for [`pop_stack_frame`](InterpCx::pop_stack_frame). + /// Returns `true` if cleanup has been done, `false` otherwise. fn cleanup_current_frame_locals(&mut self) -> InterpResult<'tcx, bool> { // Cleanup: deallocate locals. // Usually we want to clean up (deallocate locals), but in a few rare cases we don't. diff --git a/compiler/rustc_const_eval/src/interpret/terminator.rs b/compiler/rustc_const_eval/src/interpret/terminator.rs index 9f4ca93a3e8d6..589ab6029f9bc 100644 --- a/compiler/rustc_const_eval/src/interpret/terminator.rs +++ b/compiler/rustc_const_eval/src/interpret/terminator.rs @@ -977,11 +977,9 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { // which pushes a new stack frame, with the return address from // the popped stack frame. // - // Note that we can't use `pop_stack_frame` as it "executes" - // the goto to the return block, but we don't want to, - // only the tail called function should return to the current - // return block. - + // Note that we are using `pop_stack_frame` and not `return_from_current_stack_frame`, + // as the latter "executes" the goto to the return block, but we don't want to, + // only the tail called function should return to the current return block. M::before_stack_pop(self, self.frame())?; let StackPop { jump, target, destination } = self.pop_stack_frame(false)?; diff --git a/tests/ui/explicit-tail-calls/ctfe-collatz-multi-rec.rs b/tests/ui/explicit-tail-calls/ctfe-collatz-multi-rec.rs index 2e6bb0e1ac5b7..86041b669601d 100644 --- a/tests/ui/explicit-tail-calls/ctfe-collatz-multi-rec.rs +++ b/tests/ui/explicit-tail-calls/ctfe-collatz-multi-rec.rs @@ -2,7 +2,7 @@ #![allow(incomplete_features)] #![feature(explicit_tail_calls)] -/// A very unnecessarily complicated "implementation" of the callatz conjecture. +/// A very unnecessarily complicated "implementation" of the Collatz conjecture. /// Returns the number of steps to reach `1`. /// /// This is just a test for tail calls, which involves multiple functions calling each other. From 236352024b25c2e834c7a73fc9219ddc84c0bcf9 Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Mon, 17 Jun 2024 17:25:14 +0000 Subject: [PATCH 817/892] make `StackPop` field names less confusing --- .../src/interpret/eval_context.rs | 38 +++++++++++-------- .../rustc_const_eval/src/interpret/machine.rs | 11 +++--- .../rustc_const_eval/src/interpret/mod.rs | 2 +- .../src/interpret/terminator.rs | 11 +++--- src/tools/miri/src/machine.rs | 2 +- src/tools/miri/src/shims/panic.rs | 6 +-- 6 files changed, 39 insertions(+), 31 deletions(-) diff --git a/compiler/rustc_const_eval/src/interpret/eval_context.rs b/compiler/rustc_const_eval/src/interpret/eval_context.rs index 9517e3d359744..bc15e41343fcd 100644 --- a/compiler/rustc_const_eval/src/interpret/eval_context.rs +++ b/compiler/rustc_const_eval/src/interpret/eval_context.rs @@ -26,8 +26,8 @@ use rustc_target::abi::{call::FnAbi, Align, HasDataLayout, Size, TargetDataLayou use super::{ err_inval, throw_inval, throw_ub, throw_ub_custom, throw_unsup, GlobalId, Immediate, InterpErrorInfo, InterpResult, MPlaceTy, Machine, MemPlace, MemPlaceMeta, Memory, MemoryKind, - OpTy, Operand, Place, PlaceTy, Pointer, PointerArithmetic, Projectable, Provenance, Scalar, - StackPopJump, + OpTy, Operand, Place, PlaceTy, Pointer, PointerArithmetic, Projectable, Provenance, + ReturnAction, Scalar, }; use crate::errors; use crate::util; @@ -161,9 +161,15 @@ pub enum StackPopCleanup { /// Return type of [`InterpCx::pop_stack_frame`]. pub struct StackPop<'tcx, Prov: Provenance> { - pub jump: StackPopJump, - pub target: StackPopCleanup, - pub destination: MPlaceTy<'tcx, Prov>, + /// Additional information about the action to be performed when returning from the popped + /// stack frame. + pub return_action: ReturnAction, + + /// [`return_to_block`](Frame::return_to_block) of the popped stack frame. + pub return_to_block: StackPopCleanup, + + /// [`return_place`](Frame::return_place) of the popped stack frame. + pub return_place: MPlaceTy<'tcx, Prov>, } /// State of a local variable including a memoized layout @@ -890,16 +896,16 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { let frame = self.stack_mut().pop().expect("tried to pop a stack frame, but there were none"); - let target = frame.return_to_block; - let destination = frame.return_place.clone(); + let return_to_block = frame.return_to_block; + let return_place = frame.return_place.clone(); - let jump = if cleanup { + let return_action = if cleanup { M::after_stack_pop(self, frame, unwinding)? } else { - StackPopJump::NoCleanup + ReturnAction::NoCleanup }; - Ok(StackPop { jump, target, destination }) + Ok(StackPop { return_action, return_to_block, return_place }) } /// A private helper for [`pop_stack_frame`](InterpCx::pop_stack_frame). @@ -1042,13 +1048,13 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { // Report error from return value copy, if any. copy_ret_result?; - match frame.jump { - StackPopJump::Normal => {} - StackPopJump::NoJump => { + match frame.return_action { + ReturnAction::Normal => {} + ReturnAction::NoJump => { // The hook already did everything. return Ok(()); } - StackPopJump::NoCleanup => { + ReturnAction::NoCleanup => { // If we are not doing cleanup, also skip everything else. assert!(self.stack().is_empty(), "only the topmost frame should ever be leaked"); assert!(!unwinding, "tried to skip cleanup during unwinding"); @@ -1060,7 +1066,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { // Normal return, figure out where to jump. if unwinding { // Follow the unwind edge. - let unwind = match frame.target { + let unwind = match frame.return_to_block { StackPopCleanup::Goto { unwind, .. } => unwind, StackPopCleanup::Root { .. } => { panic!("encountered StackPopCleanup::Root when unwinding!") @@ -1070,7 +1076,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { self.unwind_to_block(unwind) } else { // Follow the normal return edge. - match frame.target { + match frame.return_to_block { StackPopCleanup::Goto { ret, .. } => self.return_to_block(ret), StackPopCleanup::Root { .. } => { assert!( diff --git a/compiler/rustc_const_eval/src/interpret/machine.rs b/compiler/rustc_const_eval/src/interpret/machine.rs index b8a651a744aa6..7f2e9ce06a5a0 100644 --- a/compiler/rustc_const_eval/src/interpret/machine.rs +++ b/compiler/rustc_const_eval/src/interpret/machine.rs @@ -23,10 +23,11 @@ use super::{ MemoryKind, Misalignment, OpTy, PlaceTy, Pointer, Provenance, }; -/// Data returned by Machine::stack_pop, -/// to provide further control over the popping of the stack frame +/// Data returned by [`Machine::after_stack_pop`], and consumed by +/// [`InterpCx::return_from_current_stack_frame`] to determine what actions should be done when +/// returning from a stack frame. #[derive(Eq, PartialEq, Debug, Copy, Clone)] -pub enum StackPopJump { +pub enum ReturnAction { /// Indicates that no special handling should be /// done - we'll either return normally or unwind /// based on the terminator for the function @@ -525,10 +526,10 @@ pub trait Machine<'tcx>: Sized { _ecx: &mut InterpCx<'tcx, Self>, _frame: Frame<'tcx, Self::Provenance, Self::FrameExtra>, unwinding: bool, - ) -> InterpResult<'tcx, StackPopJump> { + ) -> InterpResult<'tcx, ReturnAction> { // By default, we do not support unwinding from panics assert!(!unwinding); - Ok(StackPopJump::Normal) + Ok(ReturnAction::Normal) } /// Called immediately after actual memory was allocated for a local diff --git a/compiler/rustc_const_eval/src/interpret/mod.rs b/compiler/rustc_const_eval/src/interpret/mod.rs index 7d7b421f86935..f703c6fbe3ea3 100644 --- a/compiler/rustc_const_eval/src/interpret/mod.rs +++ b/compiler/rustc_const_eval/src/interpret/mod.rs @@ -26,7 +26,7 @@ pub use self::intern::{ intern_const_alloc_for_constprop, intern_const_alloc_recursive, HasStaticRootDefId, InternKind, InternResult, }; -pub use self::machine::{compile_time_machine, AllocMap, Machine, MayLeak, StackPopJump}; +pub use self::machine::{compile_time_machine, AllocMap, Machine, MayLeak, ReturnAction}; pub use self::memory::{AllocKind, AllocRef, AllocRefMut, FnVal, Memory, MemoryKind}; pub use self::operand::{ImmTy, Immediate, OpTy, Readable}; pub use self::place::{MPlaceTy, MemPlaceMeta, PlaceTy, Writeable}; diff --git a/compiler/rustc_const_eval/src/interpret/terminator.rs b/compiler/rustc_const_eval/src/interpret/terminator.rs index 589ab6029f9bc..8886d7d8af571 100644 --- a/compiler/rustc_const_eval/src/interpret/terminator.rs +++ b/compiler/rustc_const_eval/src/interpret/terminator.rs @@ -27,7 +27,7 @@ use super::{ }; use crate::{ fluent_generated as fluent, - interpret::{eval_context::StackPop, StackPopJump}, + interpret::{eval_context::StackPop, ReturnAction}, }; /// An argment passed to a function. @@ -982,11 +982,12 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { // only the tail called function should return to the current return block. M::before_stack_pop(self, self.frame())?; - let StackPop { jump, target, destination } = self.pop_stack_frame(false)?; + let StackPop { return_action, return_to_block, return_place } = + self.pop_stack_frame(false)?; - assert_eq!(jump, StackPopJump::Normal); + assert_eq!(return_action, ReturnAction::Normal); - let StackPopCleanup::Goto { ret, unwind } = target else { + let StackPopCleanup::Goto { ret, unwind } = return_to_block else { bug!("can't tailcall as root"); }; @@ -999,7 +1000,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { (caller_abi, caller_fn_abi), args, with_caller_location, - &destination, + &return_place, ret, unwind, ) diff --git a/src/tools/miri/src/machine.rs b/src/tools/miri/src/machine.rs index 0d91279f9f4c4..d4d50ebdd14a9 100644 --- a/src/tools/miri/src/machine.rs +++ b/src/tools/miri/src/machine.rs @@ -1434,7 +1434,7 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> { ecx: &mut InterpCx<'tcx, Self>, frame: Frame<'tcx, Provenance, FrameExtra<'tcx>>, unwinding: bool, - ) -> InterpResult<'tcx, StackPopJump> { + ) -> InterpResult<'tcx, ReturnAction> { if frame.extra.is_user_relevant { // All that we store is whether or not the frame we just removed is local, so now we // have no idea where the next topmost local frame is. So we recompute it. diff --git a/src/tools/miri/src/shims/panic.rs b/src/tools/miri/src/shims/panic.rs index ef832f5bbbd15..306dce5edcd3d 100644 --- a/src/tools/miri/src/shims/panic.rs +++ b/src/tools/miri/src/shims/panic.rs @@ -113,7 +113,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { &mut self, mut extra: FrameExtra<'tcx>, unwinding: bool, - ) -> InterpResult<'tcx, StackPopJump> { + ) -> InterpResult<'tcx, ReturnAction> { let this = self.eval_context_mut(); trace!("handle_stack_pop_unwind(extra = {:?}, unwinding = {})", extra, unwinding); @@ -150,9 +150,9 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { )?; // We pushed a new stack frame, the engine should not do any jumping now! - Ok(StackPopJump::NoJump) + Ok(ReturnAction::NoJump) } else { - Ok(StackPopJump::Normal) + Ok(ReturnAction::Normal) } } From dd5a447b5abaabcefd1b8e6e03470aa345226e1e Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Mon, 17 Jun 2024 17:36:26 +0000 Subject: [PATCH 818/892] Do renames proposed by review --- .../rustc_const_eval/src/interpret/eval_context.rs | 14 +++++++------- .../rustc_const_eval/src/interpret/terminator.rs | 4 ++-- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_const_eval/src/interpret/eval_context.rs b/compiler/rustc_const_eval/src/interpret/eval_context.rs index bc15e41343fcd..23ade4b0106dd 100644 --- a/compiler/rustc_const_eval/src/interpret/eval_context.rs +++ b/compiler/rustc_const_eval/src/interpret/eval_context.rs @@ -160,7 +160,7 @@ pub enum StackPopCleanup { } /// Return type of [`InterpCx::pop_stack_frame`]. -pub struct StackPop<'tcx, Prov: Provenance> { +pub struct StackPopInfo<'tcx, Prov: Provenance> { /// Additional information about the action to be performed when returning from the popped /// stack frame. pub return_action: ReturnAction, @@ -890,7 +890,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { pub fn pop_stack_frame( &mut self, unwinding: bool, - ) -> InterpResult<'tcx, StackPop<'tcx, M::Provenance>> { + ) -> InterpResult<'tcx, StackPopInfo<'tcx, M::Provenance>> { let cleanup = self.cleanup_current_frame_locals()?; let frame = @@ -905,7 +905,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { ReturnAction::NoCleanup }; - Ok(StackPop { return_action, return_to_block, return_place }) + Ok(StackPopInfo { return_action, return_to_block, return_place }) } /// A private helper for [`pop_stack_frame`](InterpCx::pop_stack_frame). @@ -1043,12 +1043,12 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { }; // All right, now it is time to actually pop the frame. - let frame = self.pop_stack_frame(unwinding)?; + let stack_pop_info = self.pop_stack_frame(unwinding)?; // Report error from return value copy, if any. copy_ret_result?; - match frame.return_action { + match stack_pop_info.return_action { ReturnAction::Normal => {} ReturnAction::NoJump => { // The hook already did everything. @@ -1066,7 +1066,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { // Normal return, figure out where to jump. if unwinding { // Follow the unwind edge. - let unwind = match frame.return_to_block { + let unwind = match stack_pop_info.return_to_block { StackPopCleanup::Goto { unwind, .. } => unwind, StackPopCleanup::Root { .. } => { panic!("encountered StackPopCleanup::Root when unwinding!") @@ -1076,7 +1076,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { self.unwind_to_block(unwind) } else { // Follow the normal return edge. - match frame.return_to_block { + match stack_pop_info.return_to_block { StackPopCleanup::Goto { ret, .. } => self.return_to_block(ret), StackPopCleanup::Root { .. } => { assert!( diff --git a/compiler/rustc_const_eval/src/interpret/terminator.rs b/compiler/rustc_const_eval/src/interpret/terminator.rs index 8886d7d8af571..76051f4651f56 100644 --- a/compiler/rustc_const_eval/src/interpret/terminator.rs +++ b/compiler/rustc_const_eval/src/interpret/terminator.rs @@ -27,7 +27,7 @@ use super::{ }; use crate::{ fluent_generated as fluent, - interpret::{eval_context::StackPop, ReturnAction}, + interpret::{eval_context::StackPopInfo, ReturnAction}, }; /// An argment passed to a function. @@ -982,7 +982,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { // only the tail called function should return to the current return block. M::before_stack_pop(self, self.frame())?; - let StackPop { return_action, return_to_block, return_place } = + let StackPopInfo { return_action, return_to_block, return_place } = self.pop_stack_frame(false)?; assert_eq!(return_action, ReturnAction::Normal); From 54e11cf378d5f3a423d98b9a8bcbc6c25078995a Mon Sep 17 00:00:00 2001 From: Maybe Lapkin Date: Sun, 7 Jul 2024 17:01:28 +0200 Subject: [PATCH 819/892] add an assertion that machine hook doesn't return NoCleanup --- compiler/rustc_const_eval/src/interpret/eval_context.rs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_const_eval/src/interpret/eval_context.rs b/compiler/rustc_const_eval/src/interpret/eval_context.rs index 23ade4b0106dd..6d3e5ea103148 100644 --- a/compiler/rustc_const_eval/src/interpret/eval_context.rs +++ b/compiler/rustc_const_eval/src/interpret/eval_context.rs @@ -899,10 +899,12 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { let return_to_block = frame.return_to_block; let return_place = frame.return_place.clone(); - let return_action = if cleanup { - M::after_stack_pop(self, frame, unwinding)? + let return_action; + if cleanup { + return_action = M::after_stack_pop(self, frame, unwinding)?; + assert_ne!(return_action, ReturnAction::NoCleanup); } else { - ReturnAction::NoCleanup + return_action = ReturnAction::NoCleanup; }; Ok(StackPopInfo { return_action, return_to_block, return_place }) From 7fd0c55a1a85b42b02c378ba5472243cc17211dd Mon Sep 17 00:00:00 2001 From: Maybe Lapkin Date: Sun, 7 Jul 2024 18:04:29 +0200 Subject: [PATCH 820/892] Fix conflicts after rebase - r-l/r 126784 - r-l/r 127113 - r-l/miri 3562 --- compiler/rustc_middle/src/mir/syntax.rs | 2 +- compiler/rustc_mir_build/src/build/expr/stmt.rs | 2 +- compiler/rustc_mir_transform/src/cost_checker.rs | 7 ++++++- src/tools/miri/tests/fail/tail_calls/cc-mismatch.stderr | 2 +- .../tests/fail/tail_calls/signature-mismatch-arg.stderr | 2 +- 5 files changed, 10 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs index deaa1259f6b73..620fa962d791f 100644 --- a/compiler/rustc_middle/src/mir/syntax.rs +++ b/compiler/rustc_middle/src/mir/syntax.rs @@ -767,7 +767,7 @@ pub enum TerminatorKind<'tcx> { /// These are owned by the callee, which is free to modify them. /// This allows the memory occupied by "by-value" arguments to be /// reused across function calls without duplicating the contents. - args: Vec>>, + args: Box<[Spanned>]>, // FIXME(explicit_tail_calls): should we have the span for `become`? is this span accurate? do we need it? /// This `Span` is the span of the function, without the dot and receiver /// (e.g. `foo(a, b)` in `x.foo(a, b)` diff --git a/compiler/rustc_mir_build/src/build/expr/stmt.rs b/compiler/rustc_mir_build/src/build/expr/stmt.rs index 7d2c32e000b90..88b76c46c90bf 100644 --- a/compiler/rustc_mir_build/src/build/expr/stmt.rs +++ b/compiler/rustc_mir_build/src/build/expr/stmt.rs @@ -106,7 +106,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { this.in_scope((region_scope, source_info), lint_level, |this| { let fun = unpack!(block = this.as_local_operand(block, fun)); - let args: Vec<_> = args + let args: Box<[_]> = args .into_iter() .copied() .map(|arg| Spanned { diff --git a/compiler/rustc_mir_transform/src/cost_checker.rs b/compiler/rustc_mir_transform/src/cost_checker.rs index 3333bebff3a6e..a1c1422912ee3 100644 --- a/compiler/rustc_mir_transform/src/cost_checker.rs +++ b/compiler/rustc_mir_transform/src/cost_checker.rs @@ -40,7 +40,9 @@ impl<'b, 'tcx> CostChecker<'b, 'tcx> { fn is_call_like(bbd: &BasicBlockData<'_>) -> bool { use TerminatorKind::*; match bbd.terminator().kind { - Call { .. } | Drop { .. } | Assert { .. } | InlineAsm { .. } => true, + Call { .. } | TailCall { .. } | Drop { .. } | Assert { .. } | InlineAsm { .. } => { + true + } Goto { .. } | SwitchInt { .. } @@ -137,6 +139,9 @@ impl<'tcx> Visitor<'tcx> for CostChecker<'_, 'tcx> { self.penalty += LANDINGPAD_PENALTY; } } + TerminatorKind::TailCall { .. } => { + self.penalty += CALL_PENALTY; + } TerminatorKind::SwitchInt { discr, targets } => { if discr.constant().is_some() { // Not only will this become a `Goto`, but likely other diff --git a/src/tools/miri/tests/fail/tail_calls/cc-mismatch.stderr b/src/tools/miri/tests/fail/tail_calls/cc-mismatch.stderr index 708972e6eff13..b157e9f0b211a 100644 --- a/src/tools/miri/tests/fail/tail_calls/cc-mismatch.stderr +++ b/src/tools/miri/tests/fail/tail_calls/cc-mismatch.stderr @@ -8,7 +8,7 @@ LL | extern "rust-call" fn call_once(self, args: Args) -> Self::Output; = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information = note: BACKTRACE: = note: inside `>::call_once - shim(fn())` at RUSTLIB/core/src/ops/function.rs:LL:CC - = note: inside `std::sys_common::backtrace::__rust_begin_short_backtrace::` at RUSTLIB/std/src/sys_common/backtrace.rs:LL:CC + = note: inside `std::sys::backtrace::__rust_begin_short_backtrace::` at RUSTLIB/std/src/sys/backtrace.rs:LL:CC = note: inside closure at RUSTLIB/std/src/rt.rs:LL:CC = note: inside `std::ops::function::impls:: for &dyn std::ops::Fn() -> i32 + std::marker::Sync + std::panic::RefUnwindSafe>::call_once` at RUSTLIB/core/src/ops/function.rs:LL:CC = note: inside `std::panicking::r#try::do_call::<&dyn std::ops::Fn() -> i32 + std::marker::Sync + std::panic::RefUnwindSafe, i32>` at RUSTLIB/std/src/panicking.rs:LL:CC diff --git a/src/tools/miri/tests/fail/tail_calls/signature-mismatch-arg.stderr b/src/tools/miri/tests/fail/tail_calls/signature-mismatch-arg.stderr index 2ecc5674c6537..8823ab9b97059 100644 --- a/src/tools/miri/tests/fail/tail_calls/signature-mismatch-arg.stderr +++ b/src/tools/miri/tests/fail/tail_calls/signature-mismatch-arg.stderr @@ -7,7 +7,7 @@ LL | f(0); = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information = help: this means these two types are not *guaranteed* to be ABI-compatible across all targets - = help: if you think this code should be accepted anyway, please report an issue + = help: if you think this code should be accepted anyway, please report an issue with Miri = note: BACKTRACE: = note: inside `main` at $DIR/signature-mismatch-arg.rs:LL:CC From f3c13bf2809f02d2e8f79496a27cf41c7a1fbd80 Mon Sep 17 00:00:00 2001 From: Maybe Lapkin Date: Sun, 7 Jul 2024 20:07:01 +0200 Subject: [PATCH 821/892] Allow casting `*mut dyn T`->`*mut (dyn T + Send)` if `T` has `Send` super trait --- compiler/rustc_hir_typeck/src/cast.rs | 11 +++++++++-- tests/ui/cast/ptr-to-trait-obj-add-super-auto.rs | 9 +++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) create mode 100644 tests/ui/cast/ptr-to-trait-obj-add-super-auto.rs diff --git a/compiler/rustc_hir_typeck/src/cast.rs b/compiler/rustc_hir_typeck/src/cast.rs index 7b27a4b3ba7ed..57175f11baf33 100644 --- a/compiler/rustc_hir_typeck/src/cast.rs +++ b/compiler/rustc_hir_typeck/src/cast.rs @@ -869,9 +869,16 @@ impl<'a, 'tcx> CastCheck<'tcx> { // `dyn Src = dyn Dst`, this checks for matching traits/generics fcx.demand_eqtype(self.span, src_obj, dst_obj); - // Check that `SrcAuto` is a superset of `DstAuto`. + // Check that `SrcAuto` (+auto traits implied by `Src`) is a superset of `DstAuto`. // Emit an FCW otherwise. - let src_auto = src_tty.auto_traits().collect::>(); + let src_auto: FxHashSet<_> = src_tty + .auto_traits() + .chain( + tcx.supertrait_def_ids(src_principal.def_id()) + .filter(|def_id| tcx.trait_is_auto(*def_id)), + ) + .collect(); + let added = dst_tty .auto_traits() .filter(|trait_did| !src_auto.contains(trait_did)) diff --git a/tests/ui/cast/ptr-to-trait-obj-add-super-auto.rs b/tests/ui/cast/ptr-to-trait-obj-add-super-auto.rs new file mode 100644 index 0000000000000..ac8108d8ec41b --- /dev/null +++ b/tests/ui/cast/ptr-to-trait-obj-add-super-auto.rs @@ -0,0 +1,9 @@ +//@ check-pass + +trait Trait: Send {} +impl Trait for () {} + +fn main() { + // This is OK: `Trait` has `Send` super trait. + &() as *const dyn Trait as *const (dyn Trait + Send); +} From 39eaefc15db286dc295134f0c65704e90eae1d0e Mon Sep 17 00:00:00 2001 From: Maybe Lapkin Date: Sun, 7 Jul 2024 20:16:48 +0200 Subject: [PATCH 822/892] Fixup conflict with r-l/r/126567 --- compiler/rustc_const_eval/src/interpret/terminator.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_const_eval/src/interpret/terminator.rs b/compiler/rustc_const_eval/src/interpret/terminator.rs index 76051f4651f56..25f6bd640554e 100644 --- a/compiler/rustc_const_eval/src/interpret/terminator.rs +++ b/compiler/rustc_const_eval/src/interpret/terminator.rs @@ -54,7 +54,7 @@ struct EvaluatedCalleeAndArgs<'tcx, M: Machine<'tcx>> { args: Vec>, fn_sig: ty::FnSig<'tcx>, fn_abi: &'tcx FnAbi<'tcx, Ty<'tcx>>, - /// True if the function is marked as `#[track_caller]` ([`ty::InstanceDef::requires_caller_location`]) + /// True if the function is marked as `#[track_caller]` ([`ty::InstanceKind::requires_caller_location`]) with_caller_location: bool, } From 14e5d5fbee637af09759f924e14f97685e5c24ea Mon Sep 17 00:00:00 2001 From: Maybe Lapkin Date: Sun, 7 Jul 2024 20:18:42 +0200 Subject: [PATCH 823/892] Fixup a typo in a comment in a test --- src/tools/miri/tests/fail/tail_calls/signature-mismatch-arg.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/miri/tests/fail/tail_calls/signature-mismatch-arg.rs b/src/tools/miri/tests/fail/tail_calls/signature-mismatch-arg.rs index 3264a74d159e3..6df132d325591 100644 --- a/src/tools/miri/tests/fail/tail_calls/signature-mismatch-arg.rs +++ b/src/tools/miri/tests/fail/tail_calls/signature-mismatch-arg.rs @@ -3,7 +3,7 @@ fn main() { // FIXME(explicit_tail_calls): - // the error should point to `become f(x)`, + // the error should point to `become g(x)`, // but tail calls mess up the backtrace it seems like... f(0); //~^ error: Undefined Behavior: calling a function with argument of type i32 passing data of type u32 From 8076a33fb7a32e1065154a31a2da9c55f4ca3175 Mon Sep 17 00:00:00 2001 From: Pavel Grigorenko Date: Sun, 7 Jul 2024 21:58:59 +0300 Subject: [PATCH 824/892] bootstrap: once_cell::sync::Lazy -> std::sync::LazyLock --- src/bootstrap/Cargo.lock | 1 - src/bootstrap/Cargo.toml | 1 - src/bootstrap/src/core/builder.rs | 7 +++---- src/bootstrap/src/utils/cache.rs | 7 ++----- 4 files changed, 5 insertions(+), 11 deletions(-) diff --git a/src/bootstrap/Cargo.lock b/src/bootstrap/Cargo.lock index 9c24742cff1fc..c095127da1404 100644 --- a/src/bootstrap/Cargo.lock +++ b/src/bootstrap/Cargo.lock @@ -54,7 +54,6 @@ dependencies = [ "junction", "libc", "object", - "once_cell", "opener", "pretty_assertions", "semver", diff --git a/src/bootstrap/Cargo.toml b/src/bootstrap/Cargo.toml index 32dd3efa7a6e7..df7b5b881931f 100644 --- a/src/bootstrap/Cargo.toml +++ b/src/bootstrap/Cargo.toml @@ -49,7 +49,6 @@ home = "0.5" ignore = "0.4" libc = "0.2" object = { version = "0.32", default-features = false, features = ["archive", "coff", "read_core", "unaligned"] } -once_cell = "1.19" opener = "0.5" semver = "1.0" serde = "1.0" diff --git a/src/bootstrap/src/core/builder.rs b/src/bootstrap/src/core/builder.rs index 24bb96c6b88f2..9f19e8781da13 100644 --- a/src/bootstrap/src/core/builder.rs +++ b/src/bootstrap/src/core/builder.rs @@ -8,6 +8,7 @@ use std::fs; use std::hash::Hash; use std::ops::Deref; use std::path::{Path, PathBuf}; +use std::sync::LazyLock; use std::time::{Duration, Instant}; use crate::core::build_steps::tool::{self, SourceType}; @@ -27,8 +28,6 @@ use crate::utils::exec::{command, BootstrapCommand}; pub use crate::Compiler; use clap::ValueEnum; -// FIXME: replace with std::lazy after it gets stabilized and reaches beta -use once_cell::sync::Lazy; #[cfg(test)] mod tests; @@ -498,7 +497,7 @@ impl StepDescription { enum ReallyDefault<'a> { Bool(bool), - Lazy(Lazy bool + 'a>>), + Lazy(LazyLock bool + 'a>>), } pub struct ShouldRun<'a> { @@ -529,7 +528,7 @@ impl<'a> ShouldRun<'a> { } pub fn lazy_default_condition(mut self, lazy_cond: Box bool + 'a>) -> Self { - self.is_really_default = ReallyDefault::Lazy(Lazy::new(lazy_cond)); + self.is_really_default = ReallyDefault::Lazy(LazyLock::new(lazy_cond)); self } diff --git a/src/bootstrap/src/utils/cache.rs b/src/bootstrap/src/utils/cache.rs index e18dcbb47bea0..d60b54dc703f2 100644 --- a/src/bootstrap/src/utils/cache.rs +++ b/src/bootstrap/src/utils/cache.rs @@ -9,10 +9,7 @@ use std::marker::PhantomData; use std::mem; use std::ops::Deref; use std::path::PathBuf; -use std::sync::Mutex; - -// FIXME: replace with std::lazy after it gets stabilized and reaches beta -use once_cell::sync::Lazy; +use std::sync::{LazyLock, Mutex}; use crate::core::builder::Step; @@ -196,7 +193,7 @@ impl Interner { } } -pub static INTERNER: Lazy = Lazy::new(Interner::default); +pub static INTERNER: LazyLock = LazyLock::new(Interner::default); /// This is essentially a `HashMap` which allows storing any type in its input and /// any type in its output. It is a write-once cache; values are never evicted, From b40adc9d3b56f230f295011ff78b0dfd378683ef Mon Sep 17 00:00:00 2001 From: trevyn <230691+trevyn@users.noreply.github.com> Date: Sat, 6 Jul 2024 13:14:53 +0300 Subject: [PATCH 825/892] Add suggestions for possible missing `fn`, `struct`, or `enum` keywords --- compiler/rustc_parse/messages.ftl | 19 +-- compiler/rustc_parse/src/errors.rs | 31 ++++- compiler/rustc_parse/src/parser/item.rs | 112 ++++++++++-------- tests/ui/did_you_mean/issue-40006.rs | 4 +- tests/ui/did_you_mean/issue-40006.stderr | 28 +++-- tests/ui/mismatched_types/recovered-block.rs | 2 +- .../mismatched_types/recovered-block.stderr | 12 +- tests/ui/parser/extern-no-fn.rs | 4 +- tests/ui/parser/extern-no-fn.stderr | 12 +- tests/ui/parser/missing-enum-issue-125446.rs | 6 + .../parser/missing-enum-issue-125446.stderr | 13 ++ .../missing-enum-or-struct-issue-125446.rs | 2 + ...missing-enum-or-struct-issue-125446.stderr | 8 ++ tests/ui/parser/missing-fn-issue-125446.rs | 7 ++ .../ui/parser/missing-fn-issue-125446.stderr | 13 ++ tests/ui/parser/missing-fn-issue-65381-1.rs | 4 + .../ui/parser/missing-fn-issue-65381-1.stderr | 13 ++ tests/ui/parser/missing-fn-issue-65381-2.rs | 3 + .../ui/parser/missing-fn-issue-65381-2.stderr | 13 ++ tests/ui/parser/missing-fn-issue-65381-3.rs | 4 + .../ui/parser/missing-fn-issue-65381-3.stderr | 13 ++ .../ui/parser/missing-struct-issue-125446.rs | 5 + .../parser/missing-struct-issue-125446.stderr | 13 ++ tests/ui/pub/pub-ident-fn-2.stderr | 6 +- tests/ui/pub/pub-ident-fn-or-struct.stderr | 9 +- tests/ui/pub/pub-ident-fn-with-lifetime-2.rs | 2 +- .../pub/pub-ident-fn-with-lifetime-2.stderr | 8 +- tests/ui/pub/pub-ident-fn-with-lifetime.rs | 2 +- .../ui/pub/pub-ident-fn-with-lifetime.stderr | 8 +- tests/ui/pub/pub-ident-fn.rs | 2 +- tests/ui/pub/pub-ident-fn.stderr | 8 +- tests/ui/pub/pub-ident-struct-2.stderr | 6 +- tests/ui/pub/pub-ident-struct-3.stderr | 6 +- tests/ui/pub/pub-ident-struct-4.stderr | 6 +- .../ui/pub/pub-ident-struct-with-lifetime.rs | 2 +- .../pub/pub-ident-struct-with-lifetime.stderr | 11 +- tests/ui/pub/pub-ident-struct.fixed | 6 - tests/ui/pub/pub-ident-struct.rs | 4 +- tests/ui/pub/pub-ident-struct.stderr | 11 +- .../pub/pub-ident-with-lifetime-incomplete.rs | 2 +- .../pub-ident-with-lifetime-incomplete.stderr | 6 +- tests/ui/track-diagnostics/track4.stderr | 10 +- 42 files changed, 309 insertions(+), 147 deletions(-) create mode 100644 tests/ui/parser/missing-enum-issue-125446.rs create mode 100644 tests/ui/parser/missing-enum-issue-125446.stderr create mode 100644 tests/ui/parser/missing-enum-or-struct-issue-125446.rs create mode 100644 tests/ui/parser/missing-enum-or-struct-issue-125446.stderr create mode 100644 tests/ui/parser/missing-fn-issue-125446.rs create mode 100644 tests/ui/parser/missing-fn-issue-125446.stderr create mode 100644 tests/ui/parser/missing-fn-issue-65381-1.rs create mode 100644 tests/ui/parser/missing-fn-issue-65381-1.stderr create mode 100644 tests/ui/parser/missing-fn-issue-65381-2.rs create mode 100644 tests/ui/parser/missing-fn-issue-65381-2.stderr create mode 100644 tests/ui/parser/missing-fn-issue-65381-3.rs create mode 100644 tests/ui/parser/missing-fn-issue-65381-3.stderr create mode 100644 tests/ui/parser/missing-struct-issue-125446.rs create mode 100644 tests/ui/parser/missing-struct-issue-125446.stderr delete mode 100644 tests/ui/pub/pub-ident-struct.fixed diff --git a/compiler/rustc_parse/messages.ftl b/compiler/rustc_parse/messages.ftl index e4c75ac11454a..02c3c87313bcd 100644 --- a/compiler/rustc_parse/messages.ftl +++ b/compiler/rustc_parse/messages.ftl @@ -1,9 +1,5 @@ parse_add_paren = try adding parentheses -parse_ambiguous_missing_keyword_for_item_definition = missing `fn` or `struct` for function or struct definition - .suggestion = if you meant to call a macro, try - .help = if you meant to call a macro, remove the `pub` and add a trailing `!` after the identifier - parse_ambiguous_range_pattern = the range pattern here has ambiguous interpretation .suggestion = add parentheses to clarify the precedence @@ -528,14 +524,23 @@ parse_missing_comma_after_match_arm = expected `,` following `match` arm parse_missing_const_type = missing type for `{$kind}` item .suggestion = provide a type for the item +parse_missing_enum_for_enum_definition = missing `enum` for enum definition + .suggestion = add `enum` here to parse `{$ident}` as an enum + +parse_missing_enum_or_struct_for_item_definition = missing `enum` or `struct` for enum or struct definition + parse_missing_expression_in_for_loop = missing expression to iterate on in `for` loop .suggestion = try adding an expression to the `for` loop parse_missing_fn_for_function_definition = missing `fn` for function definition - .suggestion = add `fn` here to parse `{$ident}` as a public function + .suggestion = add `fn` here to parse `{$ident}` as a function parse_missing_fn_for_method_definition = missing `fn` for method definition - .suggestion = add `fn` here to parse `{$ident}` as a public method + .suggestion = add `fn` here to parse `{$ident}` as a method + +parse_missing_fn_or_struct_for_item_definition = missing `fn` or `struct` for function or struct definition + .suggestion = if you meant to call a macro, try + .help = if you meant to call a macro, remove the `pub` and add a trailing `!` after the identifier parse_missing_fn_params = missing parameters for function definition .suggestion = add a parameter list @@ -555,7 +560,7 @@ parse_missing_semicolon_before_array = expected `;`, found `[` .suggestion = consider adding `;` here parse_missing_struct_for_struct_definition = missing `struct` for struct definition - .suggestion = add `struct` here to parse `{$ident}` as a public struct + .suggestion = add `struct` here to parse `{$ident}` as a struct parse_missing_trait_in_trait_impl = missing trait in a trait impl .suggestion_add_trait = add a trait here diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs index 6894f470d88fd..3ae9b6dad998d 100644 --- a/compiler/rustc_parse/src/errors.rs +++ b/compiler/rustc_parse/src/errors.rs @@ -1612,28 +1612,44 @@ pub(crate) struct DefaultNotFollowedByItem { #[derive(Diagnostic)] pub(crate) enum MissingKeywordForItemDefinition { + #[diag(parse_missing_enum_for_enum_definition)] + Enum { + #[primary_span] + span: Span, + #[suggestion(style = "verbose", applicability = "maybe-incorrect", code = "enum ")] + insert_span: Span, + ident: Ident, + }, + #[diag(parse_missing_enum_or_struct_for_item_definition)] + EnumOrStruct { + #[primary_span] + span: Span, + }, #[diag(parse_missing_struct_for_struct_definition)] Struct { #[primary_span] - #[suggestion(style = "short", applicability = "maybe-incorrect", code = " struct ")] span: Span, + #[suggestion(style = "verbose", applicability = "maybe-incorrect", code = "struct ")] + insert_span: Span, ident: Ident, }, #[diag(parse_missing_fn_for_function_definition)] Function { #[primary_span] - #[suggestion(style = "short", applicability = "maybe-incorrect", code = " fn ")] span: Span, + #[suggestion(style = "verbose", applicability = "maybe-incorrect", code = "fn ")] + insert_span: Span, ident: Ident, }, #[diag(parse_missing_fn_for_method_definition)] Method { #[primary_span] - #[suggestion(style = "short", applicability = "maybe-incorrect", code = " fn ")] span: Span, + #[suggestion(style = "verbose", applicability = "maybe-incorrect", code = "fn ")] + insert_span: Span, ident: Ident, }, - #[diag(parse_ambiguous_missing_keyword_for_item_definition)] + #[diag(parse_missing_fn_or_struct_for_item_definition)] Ambiguous { #[primary_span] span: Span, @@ -1644,7 +1660,12 @@ pub(crate) enum MissingKeywordForItemDefinition { #[derive(Subdiagnostic)] pub(crate) enum AmbiguousMissingKwForItemSub { - #[suggestion(parse_suggestion, applicability = "maybe-incorrect", code = "{snippet}!")] + #[suggestion( + parse_suggestion, + style = "verbose", + applicability = "maybe-incorrect", + code = "{snippet}!" + )] SuggestMacro { #[primary_span] span: Span, diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index abb6b51cebd68..f31e634f55c8b 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -239,6 +239,7 @@ impl<'a> Parser<'a> { self.recover_const_impl(const_span, attrs, def_())? } else { self.recover_const_mut(const_span); + self.recover_missing_kw_before_item()?; let (ident, generics, ty, expr) = self.parse_const_item()?; ( ident, @@ -311,6 +312,9 @@ impl<'a> Parser<'a> { Case::Insensitive, ); } else if macros_allowed && self.check_path() { + if self.isnt_macro_invocation() { + self.recover_missing_kw_before_item()?; + } // MACRO INVOCATION ITEM (Ident::empty(), ItemKind::MacCall(P(self.parse_item_macro(vis)?))) } else { @@ -374,25 +378,25 @@ impl<'a> Parser<'a> { self.check_ident() && self.look_ahead(1, |t| *t != token::Not && *t != token::PathSep) } - /// Recover on encountering a struct or method definition where the user - /// forgot to add the `struct` or `fn` keyword after writing `pub`: `pub S {}`. + /// Recover on encountering a struct, enum, or method definition where the user + /// forgot to add the `struct`, `enum`, or `fn` keyword fn recover_missing_kw_before_item(&mut self) -> PResult<'a, ()> { - // Space between `pub` keyword and the identifier - // - // pub S {} - // ^^^ `sp` points here - let sp = self.prev_token.span.between(self.token.span); - let full_sp = self.prev_token.span.to(self.token.span); - let ident_sp = self.token.span; - - let ident = if self.look_ahead(1, |t| { - [ - token::Lt, - token::OpenDelim(Delimiter::Brace), - token::OpenDelim(Delimiter::Parenthesis), - ] - .contains(&t.kind) - }) { + let is_pub = self.prev_token.is_keyword(kw::Pub); + let is_const = self.prev_token.is_keyword(kw::Const); + let ident_span = self.token.span; + let span = if is_pub { self.prev_token.span.to(ident_span) } else { ident_span }; + let insert_span = ident_span.shrink_to_lo(); + + let ident = if (!is_const + || self.look_ahead(1, |t| *t == token::OpenDelim(Delimiter::Parenthesis))) + && self.look_ahead(1, |t| { + [ + token::Lt, + token::OpenDelim(Delimiter::Brace), + token::OpenDelim(Delimiter::Parenthesis), + ] + .contains(&t.kind) + }) { self.parse_ident().unwrap() } else { return Ok(()); @@ -406,46 +410,56 @@ impl<'a> Parser<'a> { } let err = if self.check(&token::OpenDelim(Delimiter::Brace)) { - // possible public struct definition where `struct` was forgotten - Some(errors::MissingKeywordForItemDefinition::Struct { span: sp, ident }) + // possible struct or enum definition where `struct` or `enum` was forgotten + if self.look_ahead(1, |t| *t == token::CloseDelim(Delimiter::Brace)) { + // `S {}` could be unit enum or struct + Some(errors::MissingKeywordForItemDefinition::EnumOrStruct { span }) + } else if self.look_ahead(2, |t| *t == token::Colon) + || self.look_ahead(3, |t| *t == token::Colon) + { + // `S { f:` or `S { pub f:` + Some(errors::MissingKeywordForItemDefinition::Struct { span, insert_span, ident }) + } else { + Some(errors::MissingKeywordForItemDefinition::Enum { span, insert_span, ident }) + } } else if self.check(&token::OpenDelim(Delimiter::Parenthesis)) { - // possible public function or tuple struct definition where `fn`/`struct` was - // forgotten + // possible function or tuple struct definition where `fn` or `struct` was forgotten self.bump(); // `(` let is_method = self.recover_self_param(); self.consume_block(Delimiter::Parenthesis, ConsumeClosingDelim::Yes); - let err = - if self.check(&token::RArrow) || self.check(&token::OpenDelim(Delimiter::Brace)) { - self.eat_to_tokens(&[&token::OpenDelim(Delimiter::Brace)]); - self.bump(); // `{` - self.consume_block(Delimiter::Brace, ConsumeClosingDelim::Yes); - if is_method { - errors::MissingKeywordForItemDefinition::Method { span: sp, ident } - } else { - errors::MissingKeywordForItemDefinition::Function { span: sp, ident } - } - } else if self.check(&token::Semi) { - errors::MissingKeywordForItemDefinition::Struct { span: sp, ident } + let err = if self.check(&token::RArrow) + || self.check(&token::OpenDelim(Delimiter::Brace)) + { + self.eat_to_tokens(&[&token::OpenDelim(Delimiter::Brace)]); + self.bump(); // `{` + self.consume_block(Delimiter::Brace, ConsumeClosingDelim::Yes); + if is_method { + errors::MissingKeywordForItemDefinition::Method { span, insert_span, ident } } else { - errors::MissingKeywordForItemDefinition::Ambiguous { - span: sp, - subdiag: if found_generics { - None - } else if let Ok(snippet) = self.span_to_snippet(ident_sp) { - Some(errors::AmbiguousMissingKwForItemSub::SuggestMacro { - span: full_sp, - snippet, - }) - } else { - Some(errors::AmbiguousMissingKwForItemSub::HelpMacro) - }, - } - }; + errors::MissingKeywordForItemDefinition::Function { span, insert_span, ident } + } + } else if is_pub && self.check(&token::Semi) { + errors::MissingKeywordForItemDefinition::Struct { span, insert_span, ident } + } else { + errors::MissingKeywordForItemDefinition::Ambiguous { + span, + subdiag: if found_generics { + None + } else if let Ok(snippet) = self.span_to_snippet(ident_span) { + Some(errors::AmbiguousMissingKwForItemSub::SuggestMacro { + span: ident_span, + snippet, + }) + } else { + Some(errors::AmbiguousMissingKwForItemSub::HelpMacro) + }, + } + }; Some(err) } else if found_generics { - Some(errors::MissingKeywordForItemDefinition::Ambiguous { span: sp, subdiag: None }) + Some(errors::MissingKeywordForItemDefinition::Ambiguous { span, subdiag: None }) } else { None }; diff --git a/tests/ui/did_you_mean/issue-40006.rs b/tests/ui/did_you_mean/issue-40006.rs index 74f304d81a0f1..fff31bfc85e3e 100644 --- a/tests/ui/did_you_mean/issue-40006.rs +++ b/tests/ui/did_you_mean/issue-40006.rs @@ -5,7 +5,7 @@ impl dyn A { struct S; trait X { - X() {} //~ ERROR expected one of `!` or `::`, found `(` + X() {} //~ ERROR missing `fn` for function definition fn xxx() { ### } L = M; Z = { 2 + 3 }; @@ -13,7 +13,7 @@ trait X { } trait A { - X() {} //~ ERROR expected one of `!` or `::`, found `(` + X() {} //~ ERROR missing `fn` for function definition } trait B { fn xxx() { ### } //~ ERROR expected diff --git a/tests/ui/did_you_mean/issue-40006.stderr b/tests/ui/did_you_mean/issue-40006.stderr index bdbfa4dd7136b..303806a14de67 100644 --- a/tests/ui/did_you_mean/issue-40006.stderr +++ b/tests/ui/did_you_mean/issue-40006.stderr @@ -11,26 +11,36 @@ LL | } | unexpected token | the item list ends here -error: expected one of `!` or `::`, found `(` - --> $DIR/issue-40006.rs:8:6 +error: missing `fn` for function definition + --> $DIR/issue-40006.rs:8:5 | LL | trait X { | - while parsing this item list starting here LL | X() {} - | ^ expected one of `!` or `::` + | ^ ... LL | } | - the item list ends here + | +help: add `fn` here to parse `X` as a function + | +LL | fn X() {} + | ++ -error: expected one of `!` or `::`, found `(` - --> $DIR/issue-40006.rs:16:6 +error: missing `fn` for function definition + --> $DIR/issue-40006.rs:16:5 | LL | trait A { | - while parsing this item list starting here LL | X() {} - | ^ expected one of `!` or `::` + | ^ LL | } | - the item list ends here + | +help: add `fn` here to parse `X` as a function + | +LL | fn X() {} + | ++ error: expected one of `!` or `[`, found `#` --> $DIR/issue-40006.rs:19:17 @@ -69,17 +79,17 @@ LL | } | - the item list ends here error: missing `fn` for method definition - --> $DIR/issue-40006.rs:32:8 + --> $DIR/issue-40006.rs:32:5 | LL | impl S { | - while parsing this item list starting here LL | pub hello_method(&self) { - | ^ + | ^^^^^^^^^^^^^^^^ ... LL | } | - the item list ends here | -help: add `fn` here to parse `hello_method` as a public method +help: add `fn` here to parse `hello_method` as a method | LL | pub fn hello_method(&self) { | ++ diff --git a/tests/ui/mismatched_types/recovered-block.rs b/tests/ui/mismatched_types/recovered-block.rs index a91bbe7083bc2..f3078f4648940 100644 --- a/tests/ui/mismatched_types/recovered-block.rs +++ b/tests/ui/mismatched_types/recovered-block.rs @@ -10,6 +10,6 @@ pub fn foo() -> Foo { pub Foo { text } } -//~^^ ERROR missing `struct` for struct definition +//~^^ ERROR missing `enum` for enum definition fn main() {} diff --git a/tests/ui/mismatched_types/recovered-block.stderr b/tests/ui/mismatched_types/recovered-block.stderr index 51b5f3b1af2fc..35ce134ab61b0 100644 --- a/tests/ui/mismatched_types/recovered-block.stderr +++ b/tests/ui/mismatched_types/recovered-block.stderr @@ -1,13 +1,13 @@ -error: missing `struct` for struct definition - --> $DIR/recovered-block.rs:11:8 +error: missing `enum` for enum definition + --> $DIR/recovered-block.rs:11:5 | LL | pub Foo { text } - | ^ + | ^^^^^^^ | -help: add `struct` here to parse `Foo` as a public struct +help: add `enum` here to parse `Foo` as an enum | -LL | pub struct Foo { text } - | ++++++ +LL | pub enum Foo { text } + | ++++ error: aborting due to 1 previous error diff --git a/tests/ui/parser/extern-no-fn.rs b/tests/ui/parser/extern-no-fn.rs index 73568609cdfce..e965b390f07a8 100644 --- a/tests/ui/parser/extern-no-fn.rs +++ b/tests/ui/parser/extern-no-fn.rs @@ -1,5 +1,7 @@ extern "C" { - f(); //~ ERROR expected one of `!` or `::`, found `(` + f(); + //~^ ERROR missing `fn` or `struct` for function or struct definition + //~| HELP if you meant to call a macro, try } fn main() { diff --git a/tests/ui/parser/extern-no-fn.stderr b/tests/ui/parser/extern-no-fn.stderr index 2e434afb218c9..03826e4a93b7a 100644 --- a/tests/ui/parser/extern-no-fn.stderr +++ b/tests/ui/parser/extern-no-fn.stderr @@ -1,12 +1,18 @@ -error: expected one of `!` or `::`, found `(` - --> $DIR/extern-no-fn.rs:2:6 +error: missing `fn` or `struct` for function or struct definition + --> $DIR/extern-no-fn.rs:2:5 | LL | extern "C" { | - while parsing this item list starting here LL | f(); - | ^ expected one of `!` or `::` + | ^ +... LL | } | - the item list ends here + | +help: if you meant to call a macro, try + | +LL | f!(); + | ~~ error: aborting due to 1 previous error diff --git a/tests/ui/parser/missing-enum-issue-125446.rs b/tests/ui/parser/missing-enum-issue-125446.rs new file mode 100644 index 0000000000000..8d2cdb0dc40d8 --- /dev/null +++ b/tests/ui/parser/missing-enum-issue-125446.rs @@ -0,0 +1,6 @@ +Whoops { +//~^ ERROR missing `enum` for enum definition +//~| HELP add `enum` here to parse `Whoops` as an enum + OptionA, + OptionB, +} diff --git a/tests/ui/parser/missing-enum-issue-125446.stderr b/tests/ui/parser/missing-enum-issue-125446.stderr new file mode 100644 index 0000000000000..113b147473ca1 --- /dev/null +++ b/tests/ui/parser/missing-enum-issue-125446.stderr @@ -0,0 +1,13 @@ +error: missing `enum` for enum definition + --> $DIR/missing-enum-issue-125446.rs:1:1 + | +LL | Whoops { + | ^^^^^^ + | +help: add `enum` here to parse `Whoops` as an enum + | +LL | enum Whoops { + | ++++ + +error: aborting due to 1 previous error + diff --git a/tests/ui/parser/missing-enum-or-struct-issue-125446.rs b/tests/ui/parser/missing-enum-or-struct-issue-125446.rs new file mode 100644 index 0000000000000..c817ffaf859f7 --- /dev/null +++ b/tests/ui/parser/missing-enum-or-struct-issue-125446.rs @@ -0,0 +1,2 @@ +Whoops {} +//~^ ERROR missing `enum` or `struct` for enum or struct definition diff --git a/tests/ui/parser/missing-enum-or-struct-issue-125446.stderr b/tests/ui/parser/missing-enum-or-struct-issue-125446.stderr new file mode 100644 index 0000000000000..15916cebf458c --- /dev/null +++ b/tests/ui/parser/missing-enum-or-struct-issue-125446.stderr @@ -0,0 +1,8 @@ +error: missing `enum` or `struct` for enum or struct definition + --> $DIR/missing-enum-or-struct-issue-125446.rs:1:1 + | +LL | Whoops {} + | ^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/parser/missing-fn-issue-125446.rs b/tests/ui/parser/missing-fn-issue-125446.rs new file mode 100644 index 0000000000000..73c9c3a60e1fb --- /dev/null +++ b/tests/ui/parser/missing-fn-issue-125446.rs @@ -0,0 +1,7 @@ +whoops() {} +//~^ ERROR missing `fn` for function definition +//~| HELP add `fn` here to parse `whoops` as a function + +fn main() { + whoops(); +} diff --git a/tests/ui/parser/missing-fn-issue-125446.stderr b/tests/ui/parser/missing-fn-issue-125446.stderr new file mode 100644 index 0000000000000..2a92e0062cb9a --- /dev/null +++ b/tests/ui/parser/missing-fn-issue-125446.stderr @@ -0,0 +1,13 @@ +error: missing `fn` for function definition + --> $DIR/missing-fn-issue-125446.rs:1:1 + | +LL | whoops() {} + | ^^^^^^ + | +help: add `fn` here to parse `whoops` as a function + | +LL | fn whoops() {} + | ++ + +error: aborting due to 1 previous error + diff --git a/tests/ui/parser/missing-fn-issue-65381-1.rs b/tests/ui/parser/missing-fn-issue-65381-1.rs new file mode 100644 index 0000000000000..ac0299ae37bd8 --- /dev/null +++ b/tests/ui/parser/missing-fn-issue-65381-1.rs @@ -0,0 +1,4 @@ +main() { +//~^ ERROR missing `fn` for function definition +//~| HELP add `fn` here to parse `main` as a function +} diff --git a/tests/ui/parser/missing-fn-issue-65381-1.stderr b/tests/ui/parser/missing-fn-issue-65381-1.stderr new file mode 100644 index 0000000000000..95ccd8518ee99 --- /dev/null +++ b/tests/ui/parser/missing-fn-issue-65381-1.stderr @@ -0,0 +1,13 @@ +error: missing `fn` for function definition + --> $DIR/missing-fn-issue-65381-1.rs:1:1 + | +LL | main() { + | ^^^^ + | +help: add `fn` here to parse `main` as a function + | +LL | fn main() { + | ++ + +error: aborting due to 1 previous error + diff --git a/tests/ui/parser/missing-fn-issue-65381-2.rs b/tests/ui/parser/missing-fn-issue-65381-2.rs new file mode 100644 index 0000000000000..e8c214a58b6cc --- /dev/null +++ b/tests/ui/parser/missing-fn-issue-65381-2.rs @@ -0,0 +1,3 @@ +main(); +//~^ ERROR missing `fn` or `struct` for function or struct definition +//~| HELP if you meant to call a macro, try diff --git a/tests/ui/parser/missing-fn-issue-65381-2.stderr b/tests/ui/parser/missing-fn-issue-65381-2.stderr new file mode 100644 index 0000000000000..e13d395d70d7f --- /dev/null +++ b/tests/ui/parser/missing-fn-issue-65381-2.stderr @@ -0,0 +1,13 @@ +error: missing `fn` or `struct` for function or struct definition + --> $DIR/missing-fn-issue-65381-2.rs:1:1 + | +LL | main(); + | ^^^^ + | +help: if you meant to call a macro, try + | +LL | main!(); + | ~~~~~ + +error: aborting due to 1 previous error + diff --git a/tests/ui/parser/missing-fn-issue-65381-3.rs b/tests/ui/parser/missing-fn-issue-65381-3.rs new file mode 100644 index 0000000000000..28e5b5aa430d0 --- /dev/null +++ b/tests/ui/parser/missing-fn-issue-65381-3.rs @@ -0,0 +1,4 @@ +pub const initial_value() -> Self { +//~^ ERROR missing `fn` for function definition +//~| HELP add `fn` here to parse `initial_value` as a function +} diff --git a/tests/ui/parser/missing-fn-issue-65381-3.stderr b/tests/ui/parser/missing-fn-issue-65381-3.stderr new file mode 100644 index 0000000000000..883295baede1a --- /dev/null +++ b/tests/ui/parser/missing-fn-issue-65381-3.stderr @@ -0,0 +1,13 @@ +error: missing `fn` for function definition + --> $DIR/missing-fn-issue-65381-3.rs:1:11 + | +LL | pub const initial_value() -> Self { + | ^^^^^^^^^^^^^ + | +help: add `fn` here to parse `initial_value` as a function + | +LL | pub const fn initial_value() -> Self { + | ++ + +error: aborting due to 1 previous error + diff --git a/tests/ui/parser/missing-struct-issue-125446.rs b/tests/ui/parser/missing-struct-issue-125446.rs new file mode 100644 index 0000000000000..439087aeec9f1 --- /dev/null +++ b/tests/ui/parser/missing-struct-issue-125446.rs @@ -0,0 +1,5 @@ +Whoops { +//~^ ERROR missing `struct` for struct definition +//~| HELP add `struct` here to parse `Whoops` as a struct + value: u64, +} diff --git a/tests/ui/parser/missing-struct-issue-125446.stderr b/tests/ui/parser/missing-struct-issue-125446.stderr new file mode 100644 index 0000000000000..ff3135b2357be --- /dev/null +++ b/tests/ui/parser/missing-struct-issue-125446.stderr @@ -0,0 +1,13 @@ +error: missing `struct` for struct definition + --> $DIR/missing-struct-issue-125446.rs:1:1 + | +LL | Whoops { + | ^^^^^^ + | +help: add `struct` here to parse `Whoops` as a struct + | +LL | struct Whoops { + | ++++++ + +error: aborting due to 1 previous error + diff --git a/tests/ui/pub/pub-ident-fn-2.stderr b/tests/ui/pub/pub-ident-fn-2.stderr index e724278b23390..80f4b14da8952 100644 --- a/tests/ui/pub/pub-ident-fn-2.stderr +++ b/tests/ui/pub/pub-ident-fn-2.stderr @@ -1,10 +1,10 @@ error: missing `fn` for function definition - --> $DIR/pub-ident-fn-2.rs:3:4 + --> $DIR/pub-ident-fn-2.rs:3:1 | LL | pub foo(_s: usize) { bar() } - | ^ + | ^^^^^^^ | -help: add `fn` here to parse `foo` as a public function +help: add `fn` here to parse `foo` as a function | LL | pub fn foo(_s: usize) { bar() } | ++ diff --git a/tests/ui/pub/pub-ident-fn-or-struct.stderr b/tests/ui/pub/pub-ident-fn-or-struct.stderr index a8fa4bd3bd3b4..ceadc510c63ef 100644 --- a/tests/ui/pub/pub-ident-fn-or-struct.stderr +++ b/tests/ui/pub/pub-ident-fn-or-struct.stderr @@ -1,8 +1,13 @@ error: missing `fn` or `struct` for function or struct definition - --> $DIR/pub-ident-fn-or-struct.rs:1:4 + --> $DIR/pub-ident-fn-or-struct.rs:1:1 | LL | pub S (foo) bar - | ---^- help: if you meant to call a macro, try: `S!` + | ^^^^^ + | +help: if you meant to call a macro, try + | +LL | pub S! (foo) bar + | ~~ error: aborting due to 1 previous error diff --git a/tests/ui/pub/pub-ident-fn-with-lifetime-2.rs b/tests/ui/pub/pub-ident-fn-with-lifetime-2.rs index 1ee8c84f13bd3..3fb93cb669b74 100644 --- a/tests/ui/pub/pub-ident-fn-with-lifetime-2.rs +++ b/tests/ui/pub/pub-ident-fn-with-lifetime-2.rs @@ -1,4 +1,4 @@ -pub bar<'a>(&self, _s: &'a usize) -> bool { true } +pub bar<'a>(&self, _s: &'a usize) -> bool { true } //~^ ERROR missing `fn` for method definition fn main() { diff --git a/tests/ui/pub/pub-ident-fn-with-lifetime-2.stderr b/tests/ui/pub/pub-ident-fn-with-lifetime-2.stderr index b0d5ce9de5c98..e6523ca58ab43 100644 --- a/tests/ui/pub/pub-ident-fn-with-lifetime-2.stderr +++ b/tests/ui/pub/pub-ident-fn-with-lifetime-2.stderr @@ -1,10 +1,10 @@ error: missing `fn` for method definition - --> $DIR/pub-ident-fn-with-lifetime-2.rs:1:4 + --> $DIR/pub-ident-fn-with-lifetime-2.rs:1:1 | -LL | pub bar<'a>(&self, _s: &'a usize) -> bool { true } - | ^^^ +LL | pub bar<'a>(&self, _s: &'a usize) -> bool { true } + | ^^^^^^^ | -help: add `fn` here to parse `bar` as a public method +help: add `fn` here to parse `bar` as a method | LL | pub fn bar<'a>(&self, _s: &'a usize) -> bool { true } | ++ diff --git a/tests/ui/pub/pub-ident-fn-with-lifetime.rs b/tests/ui/pub/pub-ident-fn-with-lifetime.rs index 8cdc152f163aa..0fd25ca0b1c63 100644 --- a/tests/ui/pub/pub-ident-fn-with-lifetime.rs +++ b/tests/ui/pub/pub-ident-fn-with-lifetime.rs @@ -1,6 +1,6 @@ //@ run-rustfix -pub foo<'a>(_s: &'a usize) -> bool { true } +pub foo<'a>(_s: &'a usize) -> bool { true } //~^ ERROR missing `fn` for function definition fn main() { diff --git a/tests/ui/pub/pub-ident-fn-with-lifetime.stderr b/tests/ui/pub/pub-ident-fn-with-lifetime.stderr index 63fcf6bf5d59a..52c6206a75fa6 100644 --- a/tests/ui/pub/pub-ident-fn-with-lifetime.stderr +++ b/tests/ui/pub/pub-ident-fn-with-lifetime.stderr @@ -1,10 +1,10 @@ error: missing `fn` for function definition - --> $DIR/pub-ident-fn-with-lifetime.rs:3:4 + --> $DIR/pub-ident-fn-with-lifetime.rs:3:1 | -LL | pub foo<'a>(_s: &'a usize) -> bool { true } - | ^^^ +LL | pub foo<'a>(_s: &'a usize) -> bool { true } + | ^^^^^^^ | -help: add `fn` here to parse `foo` as a public function +help: add `fn` here to parse `foo` as a function | LL | pub fn foo<'a>(_s: &'a usize) -> bool { true } | ++ diff --git a/tests/ui/pub/pub-ident-fn.rs b/tests/ui/pub/pub-ident-fn.rs index 899ea82ccb7e7..1032f3375ea87 100644 --- a/tests/ui/pub/pub-ident-fn.rs +++ b/tests/ui/pub/pub-ident-fn.rs @@ -1,6 +1,6 @@ //@ run-rustfix -pub foo(_s: usize) -> bool { true } +pub foo(_s: usize) -> bool { true } //~^ ERROR missing `fn` for function definition fn main() { diff --git a/tests/ui/pub/pub-ident-fn.stderr b/tests/ui/pub/pub-ident-fn.stderr index 06dac616443b8..54360061fefed 100644 --- a/tests/ui/pub/pub-ident-fn.stderr +++ b/tests/ui/pub/pub-ident-fn.stderr @@ -1,10 +1,10 @@ error: missing `fn` for function definition - --> $DIR/pub-ident-fn.rs:3:4 + --> $DIR/pub-ident-fn.rs:3:1 | -LL | pub foo(_s: usize) -> bool { true } - | ^^^ +LL | pub foo(_s: usize) -> bool { true } + | ^^^^^^^ | -help: add `fn` here to parse `foo` as a public function +help: add `fn` here to parse `foo` as a function | LL | pub fn foo(_s: usize) -> bool { true } | ++ diff --git a/tests/ui/pub/pub-ident-struct-2.stderr b/tests/ui/pub/pub-ident-struct-2.stderr index 5e0f328d98616..ef2ff1d2f0efe 100644 --- a/tests/ui/pub/pub-ident-struct-2.stderr +++ b/tests/ui/pub/pub-ident-struct-2.stderr @@ -1,10 +1,10 @@ error: missing `struct` for struct definition - --> $DIR/pub-ident-struct-2.rs:4:8 + --> $DIR/pub-ident-struct-2.rs:4:5 | LL | pub bar(); - | ^ + | ^^^^^^^ | -help: add `struct` here to parse `bar` as a public struct +help: add `struct` here to parse `bar` as a struct | LL | pub struct bar(); | ++++++ diff --git a/tests/ui/pub/pub-ident-struct-3.stderr b/tests/ui/pub/pub-ident-struct-3.stderr index d08e5120570c8..0a23ad51211b6 100644 --- a/tests/ui/pub/pub-ident-struct-3.stderr +++ b/tests/ui/pub/pub-ident-struct-3.stderr @@ -1,10 +1,10 @@ error: missing `struct` for struct definition - --> $DIR/pub-ident-struct-3.rs:1:4 + --> $DIR/pub-ident-struct-3.rs:1:1 | LL | pub S(); - | ^ + | ^^^^^ | -help: add `struct` here to parse `S` as a public struct +help: add `struct` here to parse `S` as a struct | LL | pub struct S(); | ++++++ diff --git a/tests/ui/pub/pub-ident-struct-4.stderr b/tests/ui/pub/pub-ident-struct-4.stderr index ec1367832113b..d3072464e05cd 100644 --- a/tests/ui/pub/pub-ident-struct-4.stderr +++ b/tests/ui/pub/pub-ident-struct-4.stderr @@ -1,10 +1,10 @@ error: missing `struct` for struct definition - --> $DIR/pub-ident-struct-4.rs:4:4 + --> $DIR/pub-ident-struct-4.rs:4:1 | LL | pub T(String); - | ^ + | ^^^^^ | -help: add `struct` here to parse `T` as a public struct +help: add `struct` here to parse `T` as a struct | LL | pub struct T(String); | ++++++ diff --git a/tests/ui/pub/pub-ident-struct-with-lifetime.rs b/tests/ui/pub/pub-ident-struct-with-lifetime.rs index 2feb0266070d5..baa5dc8cfb95f 100644 --- a/tests/ui/pub/pub-ident-struct-with-lifetime.rs +++ b/tests/ui/pub/pub-ident-struct-with-lifetime.rs @@ -1,4 +1,4 @@ pub S<'a> { -//~^ ERROR missing `struct` for struct definition +//~^ ERROR missing `enum` or `struct` for enum or struct definition } fn main() {} diff --git a/tests/ui/pub/pub-ident-struct-with-lifetime.stderr b/tests/ui/pub/pub-ident-struct-with-lifetime.stderr index 0e08a5ff44922..1367c941f8061 100644 --- a/tests/ui/pub/pub-ident-struct-with-lifetime.stderr +++ b/tests/ui/pub/pub-ident-struct-with-lifetime.stderr @@ -1,13 +1,8 @@ -error: missing `struct` for struct definition - --> $DIR/pub-ident-struct-with-lifetime.rs:1:4 +error: missing `enum` or `struct` for enum or struct definition + --> $DIR/pub-ident-struct-with-lifetime.rs:1:1 | LL | pub S<'a> { - | ^ - | -help: add `struct` here to parse `S` as a public struct - | -LL | pub struct S<'a> { - | ++++++ + | ^^^^^ error: aborting due to 1 previous error diff --git a/tests/ui/pub/pub-ident-struct.fixed b/tests/ui/pub/pub-ident-struct.fixed deleted file mode 100644 index 3f0610cd765c2..0000000000000 --- a/tests/ui/pub/pub-ident-struct.fixed +++ /dev/null @@ -1,6 +0,0 @@ -//@ run-rustfix - -pub struct S { -//~^ ERROR missing `struct` for struct definition -} -fn main() {} diff --git a/tests/ui/pub/pub-ident-struct.rs b/tests/ui/pub/pub-ident-struct.rs index 6d06c406f6c7e..f9f31a9ed2b2b 100644 --- a/tests/ui/pub/pub-ident-struct.rs +++ b/tests/ui/pub/pub-ident-struct.rs @@ -1,6 +1,4 @@ -//@ run-rustfix - pub S { -//~^ ERROR missing `struct` for struct definition +//~^ ERROR missing `enum` or `struct` for enum or struct definition } fn main() {} diff --git a/tests/ui/pub/pub-ident-struct.stderr b/tests/ui/pub/pub-ident-struct.stderr index 2d5d61d938107..6d85305ceaffa 100644 --- a/tests/ui/pub/pub-ident-struct.stderr +++ b/tests/ui/pub/pub-ident-struct.stderr @@ -1,13 +1,8 @@ -error: missing `struct` for struct definition - --> $DIR/pub-ident-struct.rs:3:4 +error: missing `enum` or `struct` for enum or struct definition + --> $DIR/pub-ident-struct.rs:1:1 | LL | pub S { - | ^ - | -help: add `struct` here to parse `S` as a public struct - | -LL | pub struct S { - | ++++++ + | ^^^^^ error: aborting due to 1 previous error diff --git a/tests/ui/pub/pub-ident-with-lifetime-incomplete.rs b/tests/ui/pub/pub-ident-with-lifetime-incomplete.rs index c86a9f2fdd655..dec1a5026468b 100644 --- a/tests/ui/pub/pub-ident-with-lifetime-incomplete.rs +++ b/tests/ui/pub/pub-ident-with-lifetime-incomplete.rs @@ -1,5 +1,5 @@ fn main() { } -pub foo<'a> +pub foo<'a> //~^ ERROR missing `fn` or `struct` for function or struct definition diff --git a/tests/ui/pub/pub-ident-with-lifetime-incomplete.stderr b/tests/ui/pub/pub-ident-with-lifetime-incomplete.stderr index 750e2d17e0ad1..67b6b9c7ba8a5 100644 --- a/tests/ui/pub/pub-ident-with-lifetime-incomplete.stderr +++ b/tests/ui/pub/pub-ident-with-lifetime-incomplete.stderr @@ -1,8 +1,8 @@ error: missing `fn` or `struct` for function or struct definition - --> $DIR/pub-ident-with-lifetime-incomplete.rs:4:4 + --> $DIR/pub-ident-with-lifetime-incomplete.rs:4:1 | -LL | pub foo<'a> - | ^^^ +LL | pub foo<'a> + | ^^^^^^^ error: aborting due to 1 previous error diff --git a/tests/ui/track-diagnostics/track4.stderr b/tests/ui/track-diagnostics/track4.stderr index d9eaea93638d1..19499fa7abc51 100644 --- a/tests/ui/track-diagnostics/track4.stderr +++ b/tests/ui/track-diagnostics/track4.stderr @@ -1,14 +1,14 @@ -error: missing `struct` for struct definition +error: missing `enum` for enum definition --> $DIR/track4.rs:LL:CC | LL | pub onion { - | ^ + | ^^^^^^^^^ -Ztrack-diagnostics: created at compiler/rustc_parse/src/parser/item.rs:LL:CC | -help: add `struct` here to parse `onion` as a public struct +help: add `enum` here to parse `onion` as an enum | -LL | pub struct onion { - | ++++++ +LL | pub enum onion { + | ++++ error: aborting due to 1 previous error From 9b2c58d1faf2dba1aef0e8556cec8e0ca6b7b996 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Mon, 1 Jul 2024 17:04:38 +1000 Subject: [PATCH 826/892] coverage: Test for handling of nested item spans --- tests/coverage/holes.cov-map | 42 +++++++++++++++++++++ tests/coverage/holes.coverage | 70 +++++++++++++++++++++++++++++++++++ tests/coverage/holes.rs | 67 +++++++++++++++++++++++++++++++++ 3 files changed, 179 insertions(+) create mode 100644 tests/coverage/holes.cov-map create mode 100644 tests/coverage/holes.coverage create mode 100644 tests/coverage/holes.rs diff --git a/tests/coverage/holes.cov-map b/tests/coverage/holes.cov-map new file mode 100644 index 0000000000000..dda64e6de7a51 --- /dev/null +++ b/tests/coverage/holes.cov-map @@ -0,0 +1,42 @@ +Function name: ::_method (unused) +Raw bytes (9): 0x[01, 01, 00, 01, 00, 25, 09, 00, 1d] +Number of files: 1 +- file 0 => global file 1 +Number of expressions: 0 +Number of file 0 mappings: 1 +- Code(Zero) at (prev + 37, 9) to (start + 0, 29) + +Function name: holes::main +Raw bytes (19): 0x[01, 01, 00, 03, 01, 08, 01, 06, 11, 01, 0f, 05, 24, 0f, 01, 2b, 05, 01, 02] +Number of files: 1 +- file 0 => global file 1 +Number of expressions: 0 +Number of file 0 mappings: 3 +- Code(Counter(0)) at (prev + 8, 1) to (start + 6, 17) +- Code(Counter(0)) at (prev + 15, 5) to (start + 36, 15) +- Code(Counter(0)) at (prev + 43, 5) to (start + 1, 2) + +Function name: holes::main::_unused_fn (unused) +Raw bytes (9): 0x[01, 01, 00, 01, 00, 19, 05, 00, 17] +Number of files: 1 +- file 0 => global file 1 +Number of expressions: 0 +Number of file 0 mappings: 1 +- Code(Zero) at (prev + 25, 5) to (start + 0, 23) + +Function name: holes::main::{closure#0} (unused) +Raw bytes (9): 0x[01, 01, 00, 01, 00, 12, 09, 02, 0a] +Number of files: 1 +- file 0 => global file 1 +Number of expressions: 0 +Number of file 0 mappings: 1 +- Code(Zero) at (prev + 18, 9) to (start + 2, 10) + +Function name: holes::main::{closure#1} (unused) +Raw bytes (9): 0x[01, 01, 00, 01, 00, 3d, 09, 02, 0a] +Number of files: 1 +- file 0 => global file 1 +Number of expressions: 0 +Number of file 0 mappings: 1 +- Code(Zero) at (prev + 61, 9) to (start + 2, 10) + diff --git a/tests/coverage/holes.coverage b/tests/coverage/holes.coverage new file mode 100644 index 0000000000000..fc0037daf7647 --- /dev/null +++ b/tests/coverage/holes.coverage @@ -0,0 +1,70 @@ + LL| |//@ edition: 2021 + LL| | + LL| |// Nested items/closures should be treated as "holes", so that their spans are + LL| |// not displayed as executable code in the enclosing function. + LL| | + LL| |use core::hint::black_box; + LL| | + LL| 1|fn main() { + LL| 1| black_box(()); + LL| 1| + LL| 1| // Splitting this across multiple lines makes it easier to see where the + LL| 1| // coverage mapping regions begin and end. + LL| 1| #[rustfmt::skip] + LL| 1| let _closure = + LL| | | + LL| | _arg: (), + LL| | | + LL| 0| { + LL| 0| black_box(()); + LL| 0| } + LL| | ; + LL| | + LL| 1| black_box(()); + LL| 1| + LL| 1| fn _unused_fn() {} + ^0 + LL| 1| + LL| 1| black_box(()); + LL| 1| + LL| 1| struct MyStruct { + LL| 1| _x: u32, + LL| 1| _y: u32, + LL| 1| } + LL| 1| + LL| 1| black_box(()); + LL| 1| + LL| 1| impl MyStruct { + LL| 1| fn _method(&self) {} + ^0 + LL| 1| } + LL| 1| + LL| 1| black_box(()); + LL| 1| + LL| 1| macro_rules! _my_macro { + LL| 1| () => {}; + LL| 1| } + LL| 1| + LL| 1| black_box(()); + LL| 1| + LL| 1| #[rustfmt::skip] + LL| 1| let _const = + LL| 1| const + LL| 1| { + LL| 1| 7 + 4 + LL| 1| } + LL| 1| ; + LL| 1| + LL| 1| black_box(()); + LL| 1| + LL| 1| #[rustfmt::skip] + LL| 1| let _async = + LL| | async + LL| 0| { + LL| 0| 7 + 4 + LL| 0| } + LL| | ; + LL| | + LL| 1| black_box(()); + LL| 1|} + diff --git a/tests/coverage/holes.rs b/tests/coverage/holes.rs new file mode 100644 index 0000000000000..b3a71e759c830 --- /dev/null +++ b/tests/coverage/holes.rs @@ -0,0 +1,67 @@ +//@ edition: 2021 + +// Nested items/closures should be treated as "holes", so that their spans are +// not displayed as executable code in the enclosing function. + +use core::hint::black_box; + +fn main() { + black_box(()); + + // Splitting this across multiple lines makes it easier to see where the + // coverage mapping regions begin and end. + #[rustfmt::skip] + let _closure = + | + _arg: (), + | + { + black_box(()); + } + ; + + black_box(()); + + fn _unused_fn() {} + + black_box(()); + + struct MyStruct { + _x: u32, + _y: u32, + } + + black_box(()); + + impl MyStruct { + fn _method(&self) {} + } + + black_box(()); + + macro_rules! _my_macro { + () => {}; + } + + black_box(()); + + #[rustfmt::skip] + let _const = + const + { + 7 + 4 + } + ; + + black_box(()); + + #[rustfmt::skip] + let _async = + async + { + 7 + 4 + } + ; + + black_box(()); +} From 63c04f05e60ce27311fc1b874907188616beb558 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Mon, 1 Jul 2024 13:29:54 +1000 Subject: [PATCH 827/892] coverage: Extract hole spans from HIR instead of MIR This makes it possible to treat more kinds of nested item/code as holes, instead of being restricted to closures. --- .../rustc_mir_transform/src/coverage/mod.rs | 80 ++++++++++++++++++- .../rustc_mir_transform/src/coverage/spans.rs | 7 +- .../src/coverage/spans/from_mir.rs | 41 ++-------- tests/coverage-run-rustdoc/doctest.coverage | 8 +- tests/coverage/async.cov-map | 41 +++++----- tests/coverage/async.coverage | 20 ++--- tests/coverage/async.rs | 10 +-- tests/coverage/attr/nested.cov-map | 8 +- tests/coverage/attr/nested.coverage | 5 -- tests/coverage/attr/nested.rs | 5 -- tests/coverage/attr/off-on-sandwich.cov-map | 21 ++--- tests/coverage/attr/off-on-sandwich.coverage | 21 ++--- tests/coverage/attr/off-on-sandwich.rs | 5 -- tests/coverage/closure_macro.cov-map | 5 +- tests/coverage/closure_macro_async.cov-map | 5 +- tests/coverage/holes.cov-map | 13 ++- tests/coverage/holes.coverage | 52 ++++++------ tests/coverage/no_cov_crate.cov-map | 14 ++-- tests/coverage/no_cov_crate.coverage | 20 ++--- 19 files changed, 200 insertions(+), 181 deletions(-) diff --git a/compiler/rustc_mir_transform/src/coverage/mod.rs b/compiler/rustc_mir_transform/src/coverage/mod.rs index d55bde311c17e..2efca40d18047 100644 --- a/compiler/rustc_mir_transform/src/coverage/mod.rs +++ b/compiler/rustc_mir_transform/src/coverage/mod.rs @@ -8,6 +8,10 @@ mod spans; mod tests; mod unexpand; +use rustc_hir as hir; +use rustc_hir::intravisit::{walk_expr, Visitor}; +use rustc_middle::hir::map::Map; +use rustc_middle::hir::nested_filter; use rustc_middle::mir::coverage::{ CodeRegion, CoverageKind, DecisionInfo, FunctionCoverageInfo, Mapping, MappingKind, }; @@ -465,6 +469,9 @@ struct ExtractedHirInfo { /// Must have the same context and filename as the body span. fn_sig_span_extended: Option, body_span: Span, + /// "Holes" are regions within the body span that should not be included in + /// coverage spans for this function (e.g. closures and nested items). + hole_spans: Vec, } fn extract_hir_info<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> ExtractedHirInfo { @@ -480,7 +487,7 @@ fn extract_hir_info<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> ExtractedHir let mut body_span = hir_body.value.span; - use rustc_hir::{Closure, Expr, ExprKind, Node}; + use hir::{Closure, Expr, ExprKind, Node}; // Unexpand a closure's body span back to the context of its declaration. // This helps with closure bodies that consist of just a single bang-macro, // and also with closure bodies produced by async desugaring. @@ -507,11 +514,78 @@ fn extract_hir_info<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> ExtractedHir let function_source_hash = hash_mir_source(tcx, hir_body); - ExtractedHirInfo { function_source_hash, is_async_fn, fn_sig_span_extended, body_span } + let hole_spans = extract_hole_spans_from_hir(tcx, body_span, hir_body); + + ExtractedHirInfo { + function_source_hash, + is_async_fn, + fn_sig_span_extended, + body_span, + hole_spans, + } } -fn hash_mir_source<'tcx>(tcx: TyCtxt<'tcx>, hir_body: &'tcx rustc_hir::Body<'tcx>) -> u64 { +fn hash_mir_source<'tcx>(tcx: TyCtxt<'tcx>, hir_body: &'tcx hir::Body<'tcx>) -> u64 { // FIXME(cjgillot) Stop hashing HIR manually here. let owner = hir_body.id().hir_id.owner; tcx.hir_owner_nodes(owner).opt_hash_including_bodies.unwrap().to_smaller_hash().as_u64() } + +fn extract_hole_spans_from_hir<'tcx>( + tcx: TyCtxt<'tcx>, + body_span: Span, // Usually `hir_body.value.span`, but not always + hir_body: &hir::Body<'tcx>, +) -> Vec { + struct HolesVisitor<'hir, F> { + hir: Map<'hir>, + visit_hole_span: F, + } + + impl<'hir, F: FnMut(Span)> Visitor<'hir> for HolesVisitor<'hir, F> { + /// - We need `NestedFilter::INTRA = true` so that `visit_item` will be called. + /// - Bodies of nested items don't actually get visited, because of the + /// `visit_item` override. + /// - For nested bodies that are not part of an item, we do want to visit any + /// items contained within them. + type NestedFilter = nested_filter::All; + + fn nested_visit_map(&mut self) -> Self::Map { + self.hir + } + + fn visit_item(&mut self, item: &'hir hir::Item<'hir>) { + (self.visit_hole_span)(item.span); + // Having visited this item, we don't care about its children, + // so don't call `walk_item`. + } + + // We override `visit_expr` instead of the more specific expression + // visitors, so that we have direct access to the expression span. + fn visit_expr(&mut self, expr: &'hir hir::Expr<'hir>) { + match expr.kind { + hir::ExprKind::Closure(_) | hir::ExprKind::ConstBlock(_) => { + (self.visit_hole_span)(expr.span); + // Having visited this expression, we don't care about its + // children, so don't call `walk_expr`. + } + + // For other expressions, recursively visit as normal. + _ => walk_expr(self, expr), + } + } + } + + let mut hole_spans = vec![]; + let mut visitor = HolesVisitor { + hir: tcx.hir(), + visit_hole_span: |hole_span| { + // Discard any holes that aren't directly visible within the body span. + if body_span.contains(hole_span) && body_span.eq_ctxt(hole_span) { + hole_spans.push(hole_span); + } + }, + }; + + visitor.visit_body(hir_body); + hole_spans +} diff --git a/compiler/rustc_mir_transform/src/coverage/spans.rs b/compiler/rustc_mir_transform/src/coverage/spans.rs index 7612c01c52ec4..dbc26a2808edd 100644 --- a/compiler/rustc_mir_transform/src/coverage/spans.rs +++ b/compiler/rustc_mir_transform/src/coverage/spans.rs @@ -8,7 +8,7 @@ use rustc_span::Span; use crate::coverage::graph::{BasicCoverageBlock, CoverageGraph}; use crate::coverage::mappings; use crate::coverage::spans::from_mir::{ - extract_covspans_and_holes_from_mir, ExtractedCovspans, Hole, SpanFromMir, + extract_covspans_from_mir, ExtractedCovspans, Hole, SpanFromMir, }; use crate::coverage::ExtractedHirInfo; @@ -20,8 +20,8 @@ pub(super) fn extract_refined_covspans( basic_coverage_blocks: &CoverageGraph, code_mappings: &mut impl Extend, ) { - let ExtractedCovspans { mut covspans, mut holes } = - extract_covspans_and_holes_from_mir(mir_body, hir_info, basic_coverage_blocks); + let ExtractedCovspans { mut covspans } = + extract_covspans_from_mir(mir_body, hir_info, basic_coverage_blocks); // First, perform the passes that need macro information. covspans.sort_by(|a, b| basic_coverage_blocks.cmp_in_dominator_order(a.bcb, b.bcb)); @@ -45,6 +45,7 @@ pub(super) fn extract_refined_covspans( covspans.dedup_by(|b, a| a.span.source_equal(b.span)); // Sort the holes, and merge overlapping/adjacent holes. + let mut holes = hir_info.hole_spans.iter().map(|&span| Hole { span }).collect::>(); holes.sort_by(|a, b| compare_spans(a.span, b.span)); holes.dedup_by(|b, a| a.merge_if_overlapping_or_adjacent(b)); diff --git a/compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs b/compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs index a0f8f580b1d38..32bd25bf4b966 100644 --- a/compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs +++ b/compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs @@ -1,8 +1,7 @@ use rustc_middle::bug; use rustc_middle::mir::coverage::CoverageKind; use rustc_middle::mir::{ - self, AggregateKind, FakeReadCause, Rvalue, Statement, StatementKind, Terminator, - TerminatorKind, + self, FakeReadCause, Statement, StatementKind, Terminator, TerminatorKind, }; use rustc_span::{Span, Symbol}; @@ -15,13 +14,12 @@ use crate::coverage::ExtractedHirInfo; pub(crate) struct ExtractedCovspans { pub(crate) covspans: Vec, - pub(crate) holes: Vec, } /// Traverses the MIR body to produce an initial collection of coverage-relevant /// spans, each associated with a node in the coverage graph (BCB) and possibly /// other metadata. -pub(crate) fn extract_covspans_and_holes_from_mir( +pub(crate) fn extract_covspans_from_mir( mir_body: &mir::Body<'_>, hir_info: &ExtractedHirInfo, basic_coverage_blocks: &CoverageGraph, @@ -29,21 +27,13 @@ pub(crate) fn extract_covspans_and_holes_from_mir( let &ExtractedHirInfo { body_span, .. } = hir_info; let mut covspans = vec![]; - let mut holes = vec![]; for (bcb, bcb_data) in basic_coverage_blocks.iter_enumerated() { - bcb_to_initial_coverage_spans( - mir_body, - body_span, - bcb, - bcb_data, - &mut covspans, - &mut holes, - ); + bcb_to_initial_coverage_spans(mir_body, body_span, bcb, bcb_data, &mut covspans); } // Only add the signature span if we found at least one span in the body. - if !covspans.is_empty() || !holes.is_empty() { + if !covspans.is_empty() { // If there is no usable signature span, add a fake one (before refinement) // to avoid an ugly gap between the body start and the first real span. // FIXME: Find a more principled way to solve this problem. @@ -51,7 +41,7 @@ pub(crate) fn extract_covspans_and_holes_from_mir( covspans.push(SpanFromMir::for_fn_sig(fn_sig_span)); } - ExtractedCovspans { covspans, holes } + ExtractedCovspans { covspans } } // Generate a set of coverage spans from the filtered set of `Statement`s and `Terminator`s of @@ -65,7 +55,6 @@ fn bcb_to_initial_coverage_spans<'a, 'tcx>( bcb: BasicCoverageBlock, bcb_data: &'a BasicCoverageBlockData, initial_covspans: &mut Vec, - holes: &mut Vec, ) { for &bb in &bcb_data.basic_blocks { let data = &mir_body[bb]; @@ -81,13 +70,7 @@ fn bcb_to_initial_coverage_spans<'a, 'tcx>( let expn_span = filtered_statement_span(statement)?; let (span, visible_macro) = unexpand(expn_span)?; - // A statement that looks like the assignment of a closure expression - // is treated as a "hole" span, to be carved out of other spans. - if is_closure_like(statement) { - holes.push(Hole { span }); - } else { - initial_covspans.push(SpanFromMir::new(span, visible_macro, bcb)); - } + initial_covspans.push(SpanFromMir::new(span, visible_macro, bcb)); Some(()) }; for statement in data.statements.iter() { @@ -105,18 +88,6 @@ fn bcb_to_initial_coverage_spans<'a, 'tcx>( } } -fn is_closure_like(statement: &Statement<'_>) -> bool { - match statement.kind { - StatementKind::Assign(box (_, Rvalue::Aggregate(box ref agg_kind, _))) => match agg_kind { - AggregateKind::Closure(_, _) - | AggregateKind::Coroutine(_, _) - | AggregateKind::CoroutineClosure(..) => true, - _ => false, - }, - _ => false, - } -} - /// If the MIR `Statement` has a span contributive to computing coverage spans, /// return it; otherwise return `None`. fn filtered_statement_span(statement: &Statement<'_>) -> Option { diff --git a/tests/coverage-run-rustdoc/doctest.coverage b/tests/coverage-run-rustdoc/doctest.coverage index 1bbf364759ba1..396811c5487c1 100644 --- a/tests/coverage-run-rustdoc/doctest.coverage +++ b/tests/coverage-run-rustdoc/doctest.coverage @@ -34,10 +34,10 @@ $DIR/doctest.rs: LL| |//! LL| |//! doctest returning a result: LL| 1|//! ``` - LL| 1|//! #[derive(Debug, PartialEq)] - LL| 1|//! struct SomeError { - LL| 1|//! msg: String, - LL| 1|//! } + LL| |//! #[derive(Debug, PartialEq)] + LL| |//! struct SomeError { + LL| |//! msg: String, + LL| |//! } LL| 1|//! let mut res = Err(SomeError { msg: String::from("a message") }); LL| 1|//! if res.is_ok() { LL| 0|//! res?; diff --git a/tests/coverage/async.cov-map b/tests/coverage/async.cov-map index 7d16372375a7b..9e5a4bdc60fdd 100644 --- a/tests/coverage/async.cov-map +++ b/tests/coverage/async.cov-map @@ -167,15 +167,16 @@ Number of file 0 mappings: 14 = ((c6 + c7) + c8) Function name: async::j -Raw bytes (53): 0x[01, 01, 02, 07, 0d, 05, 09, 09, 01, 35, 01, 13, 0c, 05, 14, 09, 00, 0a, 01, 00, 0e, 00, 1b, 05, 00, 1f, 00, 27, 09, 01, 09, 00, 0a, 11, 00, 0e, 00, 1a, 09, 00, 1e, 00, 20, 0d, 01, 0e, 00, 10, 03, 02, 01, 00, 02] +Raw bytes (58): 0x[01, 01, 02, 07, 0d, 05, 09, 0a, 01, 35, 01, 00, 0d, 01, 0b, 0b, 00, 0c, 05, 01, 09, 00, 0a, 01, 00, 0e, 00, 1b, 05, 00, 1f, 00, 27, 09, 01, 09, 00, 0a, 11, 00, 0e, 00, 1a, 09, 00, 1e, 00, 20, 0d, 01, 0e, 00, 10, 03, 02, 01, 00, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 2 - expression 0 operands: lhs = Expression(1, Add), rhs = Counter(3) - expression 1 operands: lhs = Counter(1), rhs = Counter(2) -Number of file 0 mappings: 9 -- Code(Counter(0)) at (prev + 53, 1) to (start + 19, 12) -- Code(Counter(1)) at (prev + 20, 9) to (start + 0, 10) +Number of file 0 mappings: 10 +- Code(Counter(0)) at (prev + 53, 1) to (start + 0, 13) +- Code(Counter(0)) at (prev + 11, 11) to (start + 0, 12) +- Code(Counter(1)) at (prev + 1, 9) to (start + 0, 10) - Code(Counter(0)) at (prev + 0, 14) to (start + 0, 27) - Code(Counter(1)) at (prev + 0, 31) to (start + 0, 39) - Code(Counter(2)) at (prev + 1, 9) to (start + 0, 10) @@ -186,7 +187,7 @@ Number of file 0 mappings: 9 = ((c1 + c2) + c3) Function name: async::j::c -Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 37, 05, 01, 12, 05, 02, 0d, 00, 0e, 02, 0a, 0d, 00, 0e, 01, 02, 05, 00, 06] +Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 37, 05, 01, 12, 05, 02, 0d, 00, 0e, 02, 02, 0d, 00, 0e, 01, 02, 05, 00, 06] Number of files: 1 - file 0 => global file 1 Number of expressions: 1 @@ -194,40 +195,40 @@ Number of expressions: 1 Number of file 0 mappings: 4 - Code(Counter(0)) at (prev + 55, 5) to (start + 1, 18) - Code(Counter(1)) at (prev + 2, 13) to (start + 0, 14) -- Code(Expression(0, Sub)) at (prev + 10, 13) to (start + 0, 14) +- Code(Expression(0, Sub)) at (prev + 2, 13) to (start + 0, 14) = (c0 - c1) - Code(Counter(0)) at (prev + 2, 5) to (start + 0, 6) Function name: async::j::d -Raw bytes (9): 0x[01, 01, 00, 01, 01, 46, 05, 00, 17] +Raw bytes (9): 0x[01, 01, 00, 01, 01, 3e, 05, 00, 17] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 70, 5) to (start + 0, 23) +- Code(Counter(0)) at (prev + 62, 5) to (start + 0, 23) Function name: async::j::f -Raw bytes (9): 0x[01, 01, 00, 01, 01, 47, 05, 00, 17] +Raw bytes (9): 0x[01, 01, 00, 01, 01, 3f, 05, 00, 17] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 71, 5) to (start + 0, 23) +- Code(Counter(0)) at (prev + 63, 5) to (start + 0, 23) Function name: async::k (unused) -Raw bytes (29): 0x[01, 01, 00, 05, 00, 4f, 01, 01, 0c, 00, 02, 0e, 00, 10, 00, 01, 0e, 00, 10, 00, 01, 0e, 00, 10, 00, 02, 01, 00, 02] +Raw bytes (29): 0x[01, 01, 00, 05, 00, 47, 01, 01, 0c, 00, 02, 0e, 00, 10, 00, 01, 0e, 00, 10, 00, 01, 0e, 00, 10, 00, 02, 01, 00, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 5 -- Code(Zero) at (prev + 79, 1) to (start + 1, 12) +- Code(Zero) at (prev + 71, 1) to (start + 1, 12) - Code(Zero) at (prev + 2, 14) to (start + 0, 16) - Code(Zero) at (prev + 1, 14) to (start + 0, 16) - Code(Zero) at (prev + 1, 14) to (start + 0, 16) - Code(Zero) at (prev + 2, 1) to (start + 0, 2) Function name: async::l -Raw bytes (37): 0x[01, 01, 04, 01, 07, 05, 09, 0f, 02, 09, 05, 05, 01, 57, 01, 01, 0c, 02, 02, 0e, 00, 10, 05, 01, 0e, 00, 10, 09, 01, 0e, 00, 10, 0b, 02, 01, 00, 02] +Raw bytes (37): 0x[01, 01, 04, 01, 07, 05, 09, 0f, 02, 09, 05, 05, 01, 4f, 01, 01, 0c, 02, 02, 0e, 00, 10, 05, 01, 0e, 00, 10, 09, 01, 0e, 00, 10, 0b, 02, 01, 00, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 4 @@ -236,7 +237,7 @@ Number of expressions: 4 - expression 2 operands: lhs = Expression(3, Add), rhs = Expression(0, Sub) - expression 3 operands: lhs = Counter(2), rhs = Counter(1) Number of file 0 mappings: 5 -- Code(Counter(0)) at (prev + 87, 1) to (start + 1, 12) +- Code(Counter(0)) at (prev + 79, 1) to (start + 1, 12) - Code(Expression(0, Sub)) at (prev + 2, 14) to (start + 0, 16) = (c0 - (c1 + c2)) - Code(Counter(1)) at (prev + 1, 14) to (start + 0, 16) @@ -245,26 +246,26 @@ Number of file 0 mappings: 5 = ((c2 + c1) + (c0 - (c1 + c2))) Function name: async::m -Raw bytes (9): 0x[01, 01, 00, 01, 01, 5f, 01, 00, 19] +Raw bytes (9): 0x[01, 01, 00, 01, 01, 57, 01, 00, 19] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 95, 1) to (start + 0, 25) +- Code(Counter(0)) at (prev + 87, 1) to (start + 0, 25) Function name: async::m::{closure#0} (unused) -Raw bytes (9): 0x[01, 01, 00, 01, 00, 5f, 19, 00, 22] +Raw bytes (9): 0x[01, 01, 00, 01, 00, 57, 19, 00, 22] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Zero) at (prev + 95, 25) to (start + 0, 34) +- Code(Zero) at (prev + 87, 25) to (start + 0, 34) Function name: async::main -Raw bytes (9): 0x[01, 01, 00, 01, 01, 61, 01, 08, 02] +Raw bytes (9): 0x[01, 01, 00, 01, 01, 59, 01, 08, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 97, 1) to (start + 8, 2) +- Code(Counter(0)) at (prev + 89, 1) to (start + 8, 2) diff --git a/tests/coverage/async.coverage b/tests/coverage/async.coverage index e943911d31040..f5473829b028e 100644 --- a/tests/coverage/async.coverage +++ b/tests/coverage/async.coverage @@ -53,25 +53,15 @@ LL| 1|} LL| | LL| 1|fn j(x: u8) { - LL| 1| // non-async versions of `c()`, `d()`, and `f()` to make it similar to async `i()`. + LL| | // non-async versions of `c()`, `d()`, and `f()` to make it similar to async `i()`. LL| 1| fn c(x: u8) -> u8 { LL| 1| if x == 8 { - LL| 1| 1 // This line appears covered, but the 1-character expression span covering the `1` - ^0 - LL| 1| // is not executed. (`llvm-cov show` displays a `^0` below the `1` ). This is because - LL| 1| // `fn j()` executes the open brace for the function body, followed by the function's - LL| 1| // first executable statement, `match x`. Inner function declarations are not - LL| 1| // "visible" to the MIR for `j()`, so the code region counts all lines between the - LL| 1| // open brace and the first statement as executed, which is, in a sense, true. - LL| 1| // `llvm-cov show` overcomes this kind of situation by showing the actual counts - LL| 1| // of the enclosed coverages, (that is, the `1` expression was not executed, and - LL| 1| // accurately displays a `0`). - LL| 1| } else { + LL| 0| 1 + LL| | } else { LL| 1| 0 - LL| 1| } + LL| | } LL| 1| } - LL| 1| fn d() -> u8 { 1 } // inner function is defined in-line, but the function is not executed - ^0 + LL| 0| fn d() -> u8 { 1 } // inner function is defined in-line, but the function is not executed LL| 1| fn f() -> u8 { 1 } LL| 1| match x { LL| 1| y if c(x) == y + 1 => { d(); } diff --git a/tests/coverage/async.rs b/tests/coverage/async.rs index 5018ade0125f3..7e6ad761ecd34 100644 --- a/tests/coverage/async.rs +++ b/tests/coverage/async.rs @@ -54,15 +54,7 @@ fn j(x: u8) { // non-async versions of `c()`, `d()`, and `f()` to make it similar to async `i()`. fn c(x: u8) -> u8 { if x == 8 { - 1 // This line appears covered, but the 1-character expression span covering the `1` - // is not executed. (`llvm-cov show` displays a `^0` below the `1` ). This is because - // `fn j()` executes the open brace for the function body, followed by the function's - // first executable statement, `match x`. Inner function declarations are not - // "visible" to the MIR for `j()`, so the code region counts all lines between the - // open brace and the first statement as executed, which is, in a sense, true. - // `llvm-cov show` overcomes this kind of situation by showing the actual counts - // of the enclosed coverages, (that is, the `1` expression was not executed, and - // accurately displays a `0`). + 1 } else { 0 } diff --git a/tests/coverage/attr/nested.cov-map b/tests/coverage/attr/nested.cov-map index 0f2d5542f753a..466aec8956e0e 100644 --- a/tests/coverage/attr/nested.cov-map +++ b/tests/coverage/attr/nested.cov-map @@ -1,18 +1,18 @@ Function name: nested::closure_expr -Raw bytes (14): 0x[01, 01, 00, 02, 01, 44, 01, 01, 0f, 01, 0b, 05, 01, 02] +Raw bytes (14): 0x[01, 01, 00, 02, 01, 3f, 01, 01, 0f, 01, 0b, 05, 01, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 2 -- Code(Counter(0)) at (prev + 68, 1) to (start + 1, 15) +- Code(Counter(0)) at (prev + 63, 1) to (start + 1, 15) - Code(Counter(0)) at (prev + 11, 5) to (start + 1, 2) Function name: nested::closure_tail -Raw bytes (14): 0x[01, 01, 00, 02, 01, 53, 01, 01, 0f, 01, 11, 05, 01, 02] +Raw bytes (14): 0x[01, 01, 00, 02, 01, 4e, 01, 01, 0f, 01, 11, 05, 01, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 2 -- Code(Counter(0)) at (prev + 83, 1) to (start + 1, 15) +- Code(Counter(0)) at (prev + 78, 1) to (start + 1, 15) - Code(Counter(0)) at (prev + 17, 5) to (start + 1, 2) diff --git a/tests/coverage/attr/nested.coverage b/tests/coverage/attr/nested.coverage index bdd117b7dfaf5..2d64fe698ead9 100644 --- a/tests/coverage/attr/nested.coverage +++ b/tests/coverage/attr/nested.coverage @@ -4,11 +4,6 @@ LL| |// Demonstrates the interaction between #[coverage(off)] and various kinds of LL| |// nested function. LL| | - LL| |// FIXME(#126625): Coverage attributes should apply recursively to nested functions. - LL| |// FIXME(#126626): When an inner (non-closure) function has `#[coverage(off)]`, - LL| |// its lines can still be marked with misleading execution counts from its enclosing - LL| |// function. - LL| | LL| |#[coverage(off)] LL| |fn do_stuff() {} LL| | diff --git a/tests/coverage/attr/nested.rs b/tests/coverage/attr/nested.rs index c7ff835f44f32..8213e29b6fcd9 100644 --- a/tests/coverage/attr/nested.rs +++ b/tests/coverage/attr/nested.rs @@ -4,11 +4,6 @@ // Demonstrates the interaction between #[coverage(off)] and various kinds of // nested function. -// FIXME(#126625): Coverage attributes should apply recursively to nested functions. -// FIXME(#126626): When an inner (non-closure) function has `#[coverage(off)]`, -// its lines can still be marked with misleading execution counts from its enclosing -// function. - #[coverage(off)] fn do_stuff() {} diff --git a/tests/coverage/attr/off-on-sandwich.cov-map b/tests/coverage/attr/off-on-sandwich.cov-map index ed77d7d17e6a7..d5fbac6ebf74b 100644 --- a/tests/coverage/attr/off-on-sandwich.cov-map +++ b/tests/coverage/attr/off-on-sandwich.cov-map @@ -1,24 +1,27 @@ Function name: off_on_sandwich::dense_a::dense_b -Raw bytes (9): 0x[01, 01, 00, 01, 01, 14, 05, 07, 06] +Raw bytes (14): 0x[01, 01, 00, 02, 01, 0f, 05, 02, 12, 01, 07, 05, 00, 06] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 20, 5) to (start + 7, 6) +Number of file 0 mappings: 2 +- Code(Counter(0)) at (prev + 15, 5) to (start + 2, 18) +- Code(Counter(0)) at (prev + 7, 5) to (start + 0, 6) Function name: off_on_sandwich::sparse_a::sparse_b::sparse_c -Raw bytes (9): 0x[01, 01, 00, 01, 01, 26, 09, 0b, 0a] +Raw bytes (14): 0x[01, 01, 00, 02, 01, 21, 09, 02, 17, 01, 0b, 09, 00, 0a] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 38, 9) to (start + 11, 10) +Number of file 0 mappings: 2 +- Code(Counter(0)) at (prev + 33, 9) to (start + 2, 23) +- Code(Counter(0)) at (prev + 11, 9) to (start + 0, 10) Function name: off_on_sandwich::sparse_a::sparse_b::sparse_c::sparse_d -Raw bytes (9): 0x[01, 01, 00, 01, 01, 29, 0d, 07, 0e] +Raw bytes (14): 0x[01, 01, 00, 02, 01, 24, 0d, 02, 1b, 01, 07, 0d, 00, 0e] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 41, 13) to (start + 7, 14) +Number of file 0 mappings: 2 +- Code(Counter(0)) at (prev + 36, 13) to (start + 2, 27) +- Code(Counter(0)) at (prev + 7, 13) to (start + 0, 14) diff --git a/tests/coverage/attr/off-on-sandwich.coverage b/tests/coverage/attr/off-on-sandwich.coverage index 58c128b834241..675697906ee76 100644 --- a/tests/coverage/attr/off-on-sandwich.coverage +++ b/tests/coverage/attr/off-on-sandwich.coverage @@ -4,11 +4,6 @@ LL| |// Demonstrates the interaction of `#[coverage(off)]` and `#[coverage(on)]` LL| |// in nested functions. LL| | - LL| |// FIXME(#126625): Coverage attributes should apply recursively to nested functions. - LL| |// FIXME(#126626): When an inner (non-closure) function has `#[coverage(off)]`, - LL| |// its lines can still be marked with misleading execution counts from its enclosing - LL| |// function. - LL| | LL| |#[coverage(off)] LL| |fn do_stuff() {} LL| | @@ -20,10 +15,10 @@ LL| 2| fn dense_b() { LL| 2| dense_c(); LL| 2| dense_c(); - LL| 2| #[coverage(off)] - LL| 2| fn dense_c() { - LL| 2| do_stuff(); - LL| 2| } + LL| | #[coverage(off)] + LL| | fn dense_c() { + LL| | do_stuff(); + LL| | } LL| 2| } LL| |} LL| | @@ -41,10 +36,10 @@ LL| 8| fn sparse_d() { LL| 8| sparse_e(); LL| 8| sparse_e(); - LL| 8| #[coverage(off)] - LL| 8| fn sparse_e() { - LL| 8| do_stuff(); - LL| 8| } + LL| | #[coverage(off)] + LL| | fn sparse_e() { + LL| | do_stuff(); + LL| | } LL| 8| } LL| 4| } LL| | } diff --git a/tests/coverage/attr/off-on-sandwich.rs b/tests/coverage/attr/off-on-sandwich.rs index 6b21b180223eb..261634e00296a 100644 --- a/tests/coverage/attr/off-on-sandwich.rs +++ b/tests/coverage/attr/off-on-sandwich.rs @@ -4,11 +4,6 @@ // Demonstrates the interaction of `#[coverage(off)]` and `#[coverage(on)]` // in nested functions. -// FIXME(#126625): Coverage attributes should apply recursively to nested functions. -// FIXME(#126626): When an inner (non-closure) function has `#[coverage(off)]`, -// its lines can still be marked with misleading execution counts from its enclosing -// function. - #[coverage(off)] fn do_stuff() {} diff --git a/tests/coverage/closure_macro.cov-map b/tests/coverage/closure_macro.cov-map index 156947f4e21c1..eb5f94d108068 100644 --- a/tests/coverage/closure_macro.cov-map +++ b/tests/coverage/closure_macro.cov-map @@ -7,15 +7,16 @@ Number of file 0 mappings: 1 - Code(Counter(0)) at (prev + 29, 1) to (start + 2, 2) Function name: closure_macro::main -Raw bytes (31): 0x[01, 01, 01, 01, 05, 05, 01, 21, 01, 01, 21, 02, 02, 09, 00, 0f, 05, 00, 54, 00, 55, 02, 02, 09, 02, 0b, 01, 03, 01, 00, 02] +Raw bytes (36): 0x[01, 01, 01, 01, 05, 06, 01, 21, 01, 01, 21, 02, 02, 09, 00, 0f, 01, 00, 12, 00, 54, 05, 00, 54, 00, 55, 02, 02, 09, 02, 0b, 01, 03, 01, 00, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 1 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) -Number of file 0 mappings: 5 +Number of file 0 mappings: 6 - Code(Counter(0)) at (prev + 33, 1) to (start + 1, 33) - Code(Expression(0, Sub)) at (prev + 2, 9) to (start + 0, 15) = (c0 - c1) +- Code(Counter(0)) at (prev + 0, 18) to (start + 0, 84) - Code(Counter(1)) at (prev + 0, 84) to (start + 0, 85) - Code(Expression(0, Sub)) at (prev + 2, 9) to (start + 2, 11) = (c0 - c1) diff --git a/tests/coverage/closure_macro_async.cov-map b/tests/coverage/closure_macro_async.cov-map index 0f2b4e0174836..1286d663bd4de 100644 --- a/tests/coverage/closure_macro_async.cov-map +++ b/tests/coverage/closure_macro_async.cov-map @@ -15,15 +15,16 @@ Number of file 0 mappings: 1 - Code(Counter(0)) at (prev + 35, 1) to (start + 0, 43) Function name: closure_macro_async::test::{closure#0} -Raw bytes (31): 0x[01, 01, 01, 01, 05, 05, 01, 23, 2b, 01, 21, 02, 02, 09, 00, 0f, 05, 00, 54, 00, 55, 02, 02, 09, 02, 0b, 01, 03, 01, 00, 02] +Raw bytes (36): 0x[01, 01, 01, 01, 05, 06, 01, 23, 2b, 01, 21, 02, 02, 09, 00, 0f, 01, 00, 12, 00, 54, 05, 00, 54, 00, 55, 02, 02, 09, 02, 0b, 01, 03, 01, 00, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 1 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) -Number of file 0 mappings: 5 +Number of file 0 mappings: 6 - Code(Counter(0)) at (prev + 35, 43) to (start + 1, 33) - Code(Expression(0, Sub)) at (prev + 2, 9) to (start + 0, 15) = (c0 - c1) +- Code(Counter(0)) at (prev + 0, 18) to (start + 0, 84) - Code(Counter(1)) at (prev + 0, 84) to (start + 0, 85) - Code(Expression(0, Sub)) at (prev + 2, 9) to (start + 2, 11) = (c0 - c1) diff --git a/tests/coverage/holes.cov-map b/tests/coverage/holes.cov-map index dda64e6de7a51..9350bd9a405cc 100644 --- a/tests/coverage/holes.cov-map +++ b/tests/coverage/holes.cov-map @@ -7,14 +7,19 @@ Number of file 0 mappings: 1 - Code(Zero) at (prev + 37, 9) to (start + 0, 29) Function name: holes::main -Raw bytes (19): 0x[01, 01, 00, 03, 01, 08, 01, 06, 11, 01, 0f, 05, 24, 0f, 01, 2b, 05, 01, 02] +Raw bytes (44): 0x[01, 01, 00, 08, 01, 08, 01, 06, 11, 01, 0f, 05, 00, 12, 01, 04, 05, 00, 12, 01, 07, 05, 00, 12, 01, 06, 05, 00, 12, 01, 06, 05, 03, 0f, 01, 0a, 05, 03, 0f, 01, 0a, 05, 01, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 -Number of file 0 mappings: 3 +Number of file 0 mappings: 8 - Code(Counter(0)) at (prev + 8, 1) to (start + 6, 17) -- Code(Counter(0)) at (prev + 15, 5) to (start + 36, 15) -- Code(Counter(0)) at (prev + 43, 5) to (start + 1, 2) +- Code(Counter(0)) at (prev + 15, 5) to (start + 0, 18) +- Code(Counter(0)) at (prev + 4, 5) to (start + 0, 18) +- Code(Counter(0)) at (prev + 7, 5) to (start + 0, 18) +- Code(Counter(0)) at (prev + 6, 5) to (start + 0, 18) +- Code(Counter(0)) at (prev + 6, 5) to (start + 3, 15) +- Code(Counter(0)) at (prev + 10, 5) to (start + 3, 15) +- Code(Counter(0)) at (prev + 10, 5) to (start + 1, 2) Function name: holes::main::_unused_fn (unused) Raw bytes (9): 0x[01, 01, 00, 01, 00, 19, 05, 00, 17] diff --git a/tests/coverage/holes.coverage b/tests/coverage/holes.coverage index fc0037daf7647..6e65435f7e3fd 100644 --- a/tests/coverage/holes.coverage +++ b/tests/coverage/holes.coverage @@ -21,40 +21,38 @@ LL| | ; LL| | LL| 1| black_box(()); - LL| 1| - LL| 1| fn _unused_fn() {} - ^0 - LL| 1| + LL| | + LL| 0| fn _unused_fn() {} + LL| | LL| 1| black_box(()); - LL| 1| - LL| 1| struct MyStruct { - LL| 1| _x: u32, - LL| 1| _y: u32, - LL| 1| } - LL| 1| + LL| | + LL| | struct MyStruct { + LL| | _x: u32, + LL| | _y: u32, + LL| | } + LL| | LL| 1| black_box(()); - LL| 1| - LL| 1| impl MyStruct { - LL| 1| fn _method(&self) {} - ^0 - LL| 1| } - LL| 1| + LL| | + LL| | impl MyStruct { + LL| 0| fn _method(&self) {} + LL| | } + LL| | LL| 1| black_box(()); - LL| 1| - LL| 1| macro_rules! _my_macro { - LL| 1| () => {}; - LL| 1| } - LL| 1| + LL| | + LL| | macro_rules! _my_macro { + LL| | () => {}; + LL| | } + LL| | LL| 1| black_box(()); LL| 1| LL| 1| #[rustfmt::skip] LL| 1| let _const = - LL| 1| const - LL| 1| { - LL| 1| 7 + 4 - LL| 1| } - LL| 1| ; - LL| 1| + LL| | const + LL| | { + LL| | 7 + 4 + LL| | } + LL| | ; + LL| | LL| 1| black_box(()); LL| 1| LL| 1| #[rustfmt::skip] diff --git a/tests/coverage/no_cov_crate.cov-map b/tests/coverage/no_cov_crate.cov-map index 281efb6d00d9c..75234f6c3b7ba 100644 --- a/tests/coverage/no_cov_crate.cov-map +++ b/tests/coverage/no_cov_crate.cov-map @@ -31,20 +31,22 @@ Number of file 0 mappings: 1 - Code(Counter(0)) at (prev + 77, 1) to (start + 11, 2) Function name: no_cov_crate::nested_fns::outer -Raw bytes (9): 0x[01, 01, 00, 01, 01, 31, 05, 0c, 06] +Raw bytes (14): 0x[01, 01, 00, 02, 01, 31, 05, 02, 23, 01, 0c, 05, 00, 06] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 49, 5) to (start + 12, 6) +Number of file 0 mappings: 2 +- Code(Counter(0)) at (prev + 49, 5) to (start + 2, 35) +- Code(Counter(0)) at (prev + 12, 5) to (start + 0, 6) Function name: no_cov_crate::nested_fns::outer_both_covered -Raw bytes (9): 0x[01, 01, 00, 01, 01, 3f, 05, 0b, 06] +Raw bytes (14): 0x[01, 01, 00, 02, 01, 3f, 05, 02, 17, 01, 0b, 05, 00, 06] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 63, 5) to (start + 11, 6) +Number of file 0 mappings: 2 +- Code(Counter(0)) at (prev + 63, 5) to (start + 2, 23) +- Code(Counter(0)) at (prev + 11, 5) to (start + 0, 6) Function name: no_cov_crate::nested_fns::outer_both_covered::inner Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 43, 09, 01, 17, 05, 01, 18, 02, 0e, 02, 02, 14, 02, 0e, 01, 03, 09, 00, 0a] diff --git a/tests/coverage/no_cov_crate.coverage b/tests/coverage/no_cov_crate.coverage index 29ad1f979cf80..6a43e52652e00 100644 --- a/tests/coverage/no_cov_crate.coverage +++ b/tests/coverage/no_cov_crate.coverage @@ -49,21 +49,21 @@ LL| 1| pub fn outer(is_true: bool) { LL| 1| println!("called and covered"); LL| 1| inner_not_covered(is_true); - LL| 1| - LL| 1| #[coverage(off)] - LL| 1| fn inner_not_covered(is_true: bool) { - LL| 1| if is_true { - LL| 1| println!("called but not covered"); - LL| 1| } else { - LL| 1| println!("absolutely not covered"); - LL| 1| } - LL| 1| } + LL| | + LL| | #[coverage(off)] + LL| | fn inner_not_covered(is_true: bool) { + LL| | if is_true { + LL| | println!("called but not covered"); + LL| | } else { + LL| | println!("absolutely not covered"); + LL| | } + LL| | } LL| 1| } LL| | LL| 1| pub fn outer_both_covered(is_true: bool) { LL| 1| println!("called and covered"); LL| 1| inner(is_true); - LL| 1| + LL| | LL| 1| fn inner(is_true: bool) { LL| 1| if is_true { LL| 1| println!("called and covered"); From 198c809dd1b06d398c44f570c9635af640895ce9 Mon Sep 17 00:00:00 2001 From: Pietro Albini Date: Mon, 8 Jul 2024 15:16:28 +0200 Subject: [PATCH 828/892] set the correct executable for initial_{rustc,cargo} Due to the way the paths initial_rustc and initial_cargo were constructed before this commit, they mixed \ and / for path separators and they omitted the .exe suffix. This worked fine up until now, as Windows is capable of handling the mixed path separators and the Command::new API adds the ".exe" suffix if missing from the executable. This resulted in paths that didn't actually exist on disk though, due to the missing .exe suffix. This commit fixes that by adding the .exe suffix to initial_rustc and initial_cargo when --build is Windows. --- src/bootstrap/src/core/config/config.rs | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs index 6664c5b451c87..882bae8aeb6a1 100644 --- a/src/bootstrap/src/core/config/config.rs +++ b/src/bootstrap/src/core/config/config.rs @@ -1452,6 +1452,11 @@ impl Config { config.out = crate::utils::helpers::absolute(&config.out); } + // Hacky way to determine the executable suffix for the build target. We cannot use + // std::env::consts::EXE_SUFFIX as the build target might not be the target bootstrap was + // compiled with. + let initial_exe_suffix = if config.build.triple.contains("windows") { ".exe" } else { "" }; + config.initial_rustc = if let Some(rustc) = rustc { if !flags.skip_stage0_validation { config.check_stage0_version(&rustc, "rustc"); @@ -1459,7 +1464,12 @@ impl Config { rustc } else { config.download_beta_toolchain(); - config.out.join(config.build.triple).join("stage0/bin/rustc") + config + .out + .join(config.build.triple) + .join("stage0") + .join("bin") + .join(format!("rustc{initial_exe_suffix}")) }; config.initial_cargo = if let Some(cargo) = cargo { @@ -1469,7 +1479,12 @@ impl Config { cargo } else { config.download_beta_toolchain(); - config.out.join(config.build.triple).join("stage0/bin/cargo") + config + .out + .join(config.build.triple) + .join("stage0") + .join("bin") + .join(format!("cargo{initial_exe_suffix}")) }; // NOTE: it's important this comes *after* we set `initial_rustc` just above. From a4c72b627535c5ed9c58f1efbbe36491a820511a Mon Sep 17 00:00:00 2001 From: Oneirical Date: Tue, 11 Jun 2024 14:18:27 -0400 Subject: [PATCH 829/892] rewrite intrinsic-unreachable to rmake --- .../tidy/src/allowed_run_make_makefiles.txt | 1 - tests/run-make/intrinsic-unreachable/Makefile | 12 ------------ tests/run-make/intrinsic-unreachable/rmake.rs | 19 +++++++++++++++++++ 3 files changed, 19 insertions(+), 13 deletions(-) delete mode 100644 tests/run-make/intrinsic-unreachable/Makefile create mode 100644 tests/run-make/intrinsic-unreachable/rmake.rs diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index 31cb32d349ace..1cc414ecdc68a 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -47,7 +47,6 @@ run-make/foreign-rust-exceptions/Makefile run-make/incr-add-rust-src-component/Makefile run-make/incr-foreign-head-span/Makefile run-make/interdependent-c-libraries/Makefile -run-make/intrinsic-unreachable/Makefile run-make/issue-107094/Makefile run-make/issue-109934-lto-debuginfo/Makefile run-make/issue-14698/Makefile diff --git a/tests/run-make/intrinsic-unreachable/Makefile b/tests/run-make/intrinsic-unreachable/Makefile deleted file mode 100644 index ff9cc57098c6b..0000000000000 --- a/tests/run-make/intrinsic-unreachable/Makefile +++ /dev/null @@ -1,12 +0,0 @@ -include ../tools.mk - -# needs-asm-support -# ignore-windows-msvc -# -# Because of Windows exception handling, the code is not necessarily any shorter. -# https://github.com/llvm-mirror/llvm/commit/64b2297786f7fd6f5fa24cdd4db0298fbf211466 - -all: - $(RUSTC) -O --emit asm exit-ret.rs - $(RUSTC) -O --emit asm exit-unreachable.rs - test `wc -l < $(TMPDIR)/exit-unreachable.s` -lt `wc -l < $(TMPDIR)/exit-ret.s` diff --git a/tests/run-make/intrinsic-unreachable/rmake.rs b/tests/run-make/intrinsic-unreachable/rmake.rs new file mode 100644 index 0000000000000..6c951147604a1 --- /dev/null +++ b/tests/run-make/intrinsic-unreachable/rmake.rs @@ -0,0 +1,19 @@ +// intrinsics::unreachable tells the compiler that a certain point in the code +// is not reachable by any means, which enables some useful optimizations. +// In this test, exit-unreachable contains this instruction and exit-ret does not, +// which means the emitted artifacts should be shorter in length. +// See https://github.com/rust-lang/rust/pull/16970 + +//@ needs-asm-support +//@ ignore-windows-msvc +// Reason: Because of Windows exception handling, the code is not necessarily any shorter. + +use run_make_support::rustc; +use std::io::BufReader; +use std::fs::File; + +fn main() { + rustc().opt().emit("asm").input("exit-ret.rs").run(); + rustc().opt().emit("asm").input("exit-unreachable.rs").run(); + assert!(BufReader::new(File::open("exit-unreachable.s")).lines().count() < BufReader::new(File::open("exit-ret.s")).lines().count()); +} From 2dda1e31bead614a45e7f51c86dc14cf6a4ebe1c Mon Sep 17 00:00:00 2001 From: Oneirical Date: Wed, 12 Jun 2024 11:24:21 -0400 Subject: [PATCH 830/892] rewrite sepcomp-separate to rmake --- Cargo.lock | 1 + src/tools/run-make-support/src/fs_wrapper.rs | 27 ++++++++++++------- src/tools/run-make-support/src/lib.rs | 1 + .../tidy/src/allowed_run_make_makefiles.txt | 1 - tests/run-make/intrinsic-unreachable/rmake.rs | 13 +++++---- tests/run-make/sepcomp-separate/Makefile | 9 ------- tests/run-make/sepcomp-separate/rmake.rs | 24 +++++++++++++++++ 7 files changed, 51 insertions(+), 25 deletions(-) delete mode 100644 tests/run-make/sepcomp-separate/Makefile create mode 100644 tests/run-make/sepcomp-separate/rmake.rs diff --git a/Cargo.lock b/Cargo.lock index afeb9faec097e..05e5685270ef1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3421,6 +3421,7 @@ dependencies = [ "ar", "bstr", "gimli 0.28.1", + "glob", "object 0.34.0", "regex", "similar", diff --git a/src/tools/run-make-support/src/fs_wrapper.rs b/src/tools/run-make-support/src/fs_wrapper.rs index 8a2bfce8b4a72..d65c10b17c991 100644 --- a/src/tools/run-make-support/src/fs_wrapper.rs +++ b/src/tools/run-make-support/src/fs_wrapper.rs @@ -1,7 +1,7 @@ use std::fs; use std::path::Path; -/// A wrapper around [`std::fs::remove_file`] which includes the file path in the panic message.. +/// A wrapper around [`std::fs::remove_file`] which includes the file path in the panic message. #[track_caller] pub fn remove_file>(path: P) { fs::remove_file(path.as_ref()) @@ -18,21 +18,28 @@ pub fn copy, Q: AsRef>(from: P, to: Q) { )); } -/// A wrapper around [`std::fs::File::create`] which includes the file path in the panic message.. +/// A wrapper around [`std::fs::File::create`] which includes the file path in the panic message. #[track_caller] pub fn create_file>(path: P) { fs::File::create(path.as_ref()) .expect(&format!("the file in path \"{}\" could not be created", path.as_ref().display())); } -/// A wrapper around [`std::fs::read`] which includes the file path in the panic message.. +/// A wrapper around [`std::fs::File::open`] which includes the file path in the panic message. +#[track_caller] +pub fn open_file>(path: P) -> fs::File { + fs::File::open(path.as_ref()) + .expect(&format!("the file in path \"{}\" could not be opened", path.as_ref().display())) +} + +/// A wrapper around [`std::fs::read`] which includes the file path in the panic message. #[track_caller] pub fn read>(path: P) -> Vec { fs::read(path.as_ref()) .expect(&format!("the file in path \"{}\" could not be read", path.as_ref().display())) } -/// A wrapper around [`std::fs::read_to_string`] which includes the file path in the panic message.. +/// A wrapper around [`std::fs::read_to_string`] which includes the file path in the panic message. #[track_caller] pub fn read_to_string>(path: P) -> String { fs::read_to_string(path.as_ref()).expect(&format!( @@ -41,14 +48,14 @@ pub fn read_to_string>(path: P) -> String { )) } -/// A wrapper around [`std::fs::read_dir`] which includes the file path in the panic message.. +/// A wrapper around [`std::fs::read_dir`] which includes the file path in the panic message. #[track_caller] pub fn read_dir>(path: P) -> fs::ReadDir { fs::read_dir(path.as_ref()) .expect(&format!("the directory in path \"{}\" could not be read", path.as_ref().display())) } -/// A wrapper around [`std::fs::write`] which includes the file path in the panic message.. +/// A wrapper around [`std::fs::write`] which includes the file path in the panic message. #[track_caller] pub fn write, C: AsRef<[u8]>>(path: P, contents: C) { fs::write(path.as_ref(), contents.as_ref()).expect(&format!( @@ -57,7 +64,7 @@ pub fn write, C: AsRef<[u8]>>(path: P, contents: C) { )); } -/// A wrapper around [`std::fs::remove_dir_all`] which includes the file path in the panic message.. +/// A wrapper around [`std::fs::remove_dir_all`] which includes the file path in the panic message. #[track_caller] pub fn remove_dir_all>(path: P) { fs::remove_dir_all(path.as_ref()).expect(&format!( @@ -66,7 +73,7 @@ pub fn remove_dir_all>(path: P) { )); } -/// A wrapper around [`std::fs::create_dir`] which includes the file path in the panic message.. +/// A wrapper around [`std::fs::create_dir`] which includes the file path in the panic message. #[track_caller] pub fn create_dir>(path: P) { fs::create_dir(path.as_ref()).expect(&format!( @@ -75,7 +82,7 @@ pub fn create_dir>(path: P) { )); } -/// A wrapper around [`std::fs::create_dir_all`] which includes the file path in the panic message.. +/// A wrapper around [`std::fs::create_dir_all`] which includes the file path in the panic message. #[track_caller] pub fn create_dir_all>(path: P) { fs::create_dir_all(path.as_ref()).expect(&format!( @@ -84,7 +91,7 @@ pub fn create_dir_all>(path: P) { )); } -/// A wrapper around [`std::fs::metadata`] which includes the file path in the panic message.. +/// A wrapper around [`std::fs::metadata`] which includes the file path in the panic message. #[track_caller] pub fn metadata>(path: P) -> fs::Metadata { fs::metadata(path.as_ref()).expect(&format!( diff --git a/src/tools/run-make-support/src/lib.rs b/src/tools/run-make-support/src/lib.rs index f464a109e7711..068b022599e50 100644 --- a/src/tools/run-make-support/src/lib.rs +++ b/src/tools/run-make-support/src/lib.rs @@ -23,6 +23,7 @@ use std::path::{Path, PathBuf}; pub use bstr; pub use gimli; +pub use glob; pub use object; pub use regex; pub use wasmparser; diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index 1cc414ecdc68a..233c2d0b808de 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -131,7 +131,6 @@ run-make/sanitizer-dylib-link/Makefile run-make/sanitizer-staticlib-link/Makefile run-make/sepcomp-cci-copies/Makefile run-make/sepcomp-inlining/Makefile -run-make/sepcomp-separate/Makefile run-make/share-generics-dylib/Makefile run-make/silly-file-names/Makefile run-make/simd-ffi/Makefile diff --git a/tests/run-make/intrinsic-unreachable/rmake.rs b/tests/run-make/intrinsic-unreachable/rmake.rs index 6c951147604a1..5e62a966c5476 100644 --- a/tests/run-make/intrinsic-unreachable/rmake.rs +++ b/tests/run-make/intrinsic-unreachable/rmake.rs @@ -5,15 +5,18 @@ // See https://github.com/rust-lang/rust/pull/16970 //@ needs-asm-support -//@ ignore-windows-msvc +//@ ignore-windows // Reason: Because of Windows exception handling, the code is not necessarily any shorter. -use run_make_support::rustc; -use std::io::BufReader; -use std::fs::File; +use run_make_support::{fs_wrapper, rustc}; +use std::io::{BufRead, BufReader}; fn main() { rustc().opt().emit("asm").input("exit-ret.rs").run(); rustc().opt().emit("asm").input("exit-unreachable.rs").run(); - assert!(BufReader::new(File::open("exit-unreachable.s")).lines().count() < BufReader::new(File::open("exit-ret.s")).lines().count()); + let unreachable_file = fs_wrapper::open_file("exit-unreachable.s"); + let ret_file = fs_wrapper::open_file("exit-ret.s"); + assert!( + BufReader::new(unreachable_file).lines().count() < BufReader::new(ret_file).lines().count() + ); } diff --git a/tests/run-make/sepcomp-separate/Makefile b/tests/run-make/sepcomp-separate/Makefile deleted file mode 100644 index 62cf54a88fbe9..0000000000000 --- a/tests/run-make/sepcomp-separate/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -include ../tools.mk - -# Test that separate compilation actually puts code into separate compilation -# units. `foo.rs` defines `magic_fn` in three different modules, which should -# wind up in three different compilation units. - -all: - $(RUSTC) foo.rs --emit=llvm-ir -C codegen-units=3 - [ "$$(cat "$(TMPDIR)"/foo.*.ll | grep -c define\ .*magic_fn)" -eq "3" ] diff --git a/tests/run-make/sepcomp-separate/rmake.rs b/tests/run-make/sepcomp-separate/rmake.rs new file mode 100644 index 0000000000000..d3ef2450a847d --- /dev/null +++ b/tests/run-make/sepcomp-separate/rmake.rs @@ -0,0 +1,24 @@ +// Test that separate compilation actually puts code into separate compilation +// units. `foo.rs` defines `magic_fn` in three different modules, which should +// wind up in three different compilation units. +// See https://github.com/rust-lang/rust/pull/16367 + +use run_make_support::{fs_wrapper, glob, regex, rustc}; +use std::io::{BufRead, BufReader}; + +fn main() { + let mut match_count = 0; + rustc().input("foo.rs").emit("llvm-ir").codegen_units(3).run(); + let re = regex::Regex::new(r#"define.*magic_fn"#).unwrap(); + let paths = glob::glob("foo.*.ll").unwrap(); + paths.filter_map(|entry| entry.ok()).filter(|path| path.is_file()).for_each(|path| { + let file = fs_wrapper::open_file(path); + let reader = BufReader::new(file); + reader + .lines() + .filter_map(|line| line.ok()) + .filter(|line| re.is_match(line)) + .for_each(|_| match_count += 1); + }); + assert_eq!(match_count, 3); +} From f04d0c68eeeb32f2bf7477806482551f2a308ae0 Mon Sep 17 00:00:00 2001 From: Oneirical Date: Thu, 13 Jun 2024 15:02:08 -0400 Subject: [PATCH 831/892] rewrite sepcomp-inlining and -separate to rmake.rs --- Cargo.lock | 1 - src/tools/run-make-support/src/fs_wrapper.rs | 7 ------ src/tools/run-make-support/src/lib.rs | 15 +++++++++++- .../tidy/src/allowed_run_make_makefiles.txt | 2 -- tests/run-make/intrinsic-unreachable/rmake.rs | 6 ++--- tests/run-make/sepcomp-cci-copies/Makefile | 12 ---------- tests/run-make/sepcomp-cci-copies/rmake.rs | 17 ++++++++++++++ tests/run-make/sepcomp-inlining/Makefile | 15 ------------ tests/run-make/sepcomp-inlining/rmake.rs | 23 +++++++++++++++++++ tests/run-make/sepcomp-separate/rmake.rs | 21 +++++------------ 10 files changed, 62 insertions(+), 57 deletions(-) delete mode 100644 tests/run-make/sepcomp-cci-copies/Makefile create mode 100644 tests/run-make/sepcomp-cci-copies/rmake.rs delete mode 100644 tests/run-make/sepcomp-inlining/Makefile create mode 100644 tests/run-make/sepcomp-inlining/rmake.rs diff --git a/Cargo.lock b/Cargo.lock index 05e5685270ef1..afeb9faec097e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3421,7 +3421,6 @@ dependencies = [ "ar", "bstr", "gimli 0.28.1", - "glob", "object 0.34.0", "regex", "similar", diff --git a/src/tools/run-make-support/src/fs_wrapper.rs b/src/tools/run-make-support/src/fs_wrapper.rs index d65c10b17c991..0f0d6f6618ced 100644 --- a/src/tools/run-make-support/src/fs_wrapper.rs +++ b/src/tools/run-make-support/src/fs_wrapper.rs @@ -25,13 +25,6 @@ pub fn create_file>(path: P) { .expect(&format!("the file in path \"{}\" could not be created", path.as_ref().display())); } -/// A wrapper around [`std::fs::File::open`] which includes the file path in the panic message. -#[track_caller] -pub fn open_file>(path: P) -> fs::File { - fs::File::open(path.as_ref()) - .expect(&format!("the file in path \"{}\" could not be opened", path.as_ref().display())) -} - /// A wrapper around [`std::fs::read`] which includes the file path in the panic message. #[track_caller] pub fn read>(path: P) -> Vec { diff --git a/src/tools/run-make-support/src/lib.rs b/src/tools/run-make-support/src/lib.rs index 068b022599e50..3fdf94804f16a 100644 --- a/src/tools/run-make-support/src/lib.rs +++ b/src/tools/run-make-support/src/lib.rs @@ -23,7 +23,6 @@ use std::path::{Path, PathBuf}; pub use bstr; pub use gimli; -pub use glob; pub use object; pub use regex; pub use wasmparser; @@ -304,6 +303,20 @@ pub fn filename_not_in_denylist, V: AsRef<[String]>>(path: P, exp .is_some_and(|name| !expected.contains(&name.to_str().unwrap().to_owned())) } +/// Gathers all files in the current working directory that have the extension `ext`, and counts +/// the number of lines within that contain a match with the regex pattern `re`. +pub fn count_regex_matches_in_files_with_extension(re: ®ex::Regex, ext: &str) -> usize { + let fetched_files = shallow_find_files(cwd(), |path| has_extension(path, ext)); + + let mut count = 0; + for file in fetched_files { + let content = fs_wrapper::read_to_string(file); + count += content.lines().filter(|line| re.is_match(&line)).count(); + } + + count +} + /// Use `cygpath -w` on a path to get a Windows path string back. This assumes that `cygpath` is /// available on the platform! #[track_caller] diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index 233c2d0b808de..184ef22317afe 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -129,8 +129,6 @@ run-make/rustc-macro-dep-files/Makefile run-make/sanitizer-cdylib-link/Makefile run-make/sanitizer-dylib-link/Makefile run-make/sanitizer-staticlib-link/Makefile -run-make/sepcomp-cci-copies/Makefile -run-make/sepcomp-inlining/Makefile run-make/share-generics-dylib/Makefile run-make/silly-file-names/Makefile run-make/simd-ffi/Makefile diff --git a/tests/run-make/intrinsic-unreachable/rmake.rs b/tests/run-make/intrinsic-unreachable/rmake.rs index 5e62a966c5476..7e78c8288b821 100644 --- a/tests/run-make/intrinsic-unreachable/rmake.rs +++ b/tests/run-make/intrinsic-unreachable/rmake.rs @@ -9,14 +9,12 @@ // Reason: Because of Windows exception handling, the code is not necessarily any shorter. use run_make_support::{fs_wrapper, rustc}; -use std::io::{BufRead, BufReader}; fn main() { rustc().opt().emit("asm").input("exit-ret.rs").run(); rustc().opt().emit("asm").input("exit-unreachable.rs").run(); - let unreachable_file = fs_wrapper::open_file("exit-unreachable.s"); - let ret_file = fs_wrapper::open_file("exit-ret.s"); assert!( - BufReader::new(unreachable_file).lines().count() < BufReader::new(ret_file).lines().count() + fs_wrapper::read_to_string("exit-unreachable.s").lines().count() + < fs_wrapper::read_to_string("exit-ret.s").lines().count() ); } diff --git a/tests/run-make/sepcomp-cci-copies/Makefile b/tests/run-make/sepcomp-cci-copies/Makefile deleted file mode 100644 index df289d0b0b1a2..0000000000000 --- a/tests/run-make/sepcomp-cci-copies/Makefile +++ /dev/null @@ -1,12 +0,0 @@ -include ../tools.mk - -# Check that cross-crate inlined items are inlined in all compilation units -# that refer to them, and not in any other compilation units. -# Note that we have to pass `-C codegen-units=6` because up to two CGUs may be -# created for each source module (see `rustc_const_eval::monomorphize::partitioning`). - -all: - $(RUSTC) cci_lib.rs - $(RUSTC) foo.rs --emit=llvm-ir -C codegen-units=6 \ - -Z inline-in-all-cgus - [ "$$(cat "$(TMPDIR)"/foo.*.ll | grep -c define\ .*cci_fn)" -eq "2" ] diff --git a/tests/run-make/sepcomp-cci-copies/rmake.rs b/tests/run-make/sepcomp-cci-copies/rmake.rs new file mode 100644 index 0000000000000..612a73977feea --- /dev/null +++ b/tests/run-make/sepcomp-cci-copies/rmake.rs @@ -0,0 +1,17 @@ +// Check that cross-crate inlined items are inlined in all compilation units +// that refer to them, and not in any other compilation units. +// Note that we have to pass `-C codegen-units=6` because up to two CGUs may be +// created for each source module (see `rustc_const_eval::monomorphize::partitioning`). +// See https://github.com/rust-lang/rust/pull/16367 + +use run_make_support::{ + count_regex_matches_in_files_with_extension, cwd, fs_wrapper, has_extension, regex, rustc, + shallow_find_files, +}; + +fn main() { + rustc().input("cci_lib.rs").run(); + rustc().input("foo.rs").emit("llvm-ir").codegen_units(6).arg("-Zinline-in-all-cgus").run(); + let re = regex::Regex::new(r#"define\ .*cci_fn"#).unwrap(); + assert_eq!(count_regex_matches_in_files_with_extension(&re, "ll"), 2); +} diff --git a/tests/run-make/sepcomp-inlining/Makefile b/tests/run-make/sepcomp-inlining/Makefile deleted file mode 100644 index 327aeb75e5eda..0000000000000 --- a/tests/run-make/sepcomp-inlining/Makefile +++ /dev/null @@ -1,15 +0,0 @@ -include ../tools.mk - -# Test that #[inline] functions still get inlined across compilation unit -# boundaries. Compilation should produce three IR files, but only the two -# compilation units that have a usage of the #[inline] function should -# contain a definition. Also, the non-#[inline] function should be defined -# in only one compilation unit. - -all: - $(RUSTC) foo.rs --emit=llvm-ir -C codegen-units=3 \ - -Z inline-in-all-cgus - [ "$$(cat "$(TMPDIR)"/foo.*.ll | grep -c define\ i32\ .*inlined)" -eq "0" ] - [ "$$(cat "$(TMPDIR)"/foo.*.ll | grep -c define\ internal\ i32\ .*inlined)" -eq "2" ] - [ "$$(cat "$(TMPDIR)"/foo.*.ll | grep -c define\ hidden\ i32\ .*normal)" -eq "1" ] - [ "$$(cat "$(TMPDIR)"/foo.*.ll | grep -c declare\ hidden\ i32\ .*normal)" -eq "2" ] diff --git a/tests/run-make/sepcomp-inlining/rmake.rs b/tests/run-make/sepcomp-inlining/rmake.rs new file mode 100644 index 0000000000000..de7551b9a512d --- /dev/null +++ b/tests/run-make/sepcomp-inlining/rmake.rs @@ -0,0 +1,23 @@ +// Test that #[inline] functions still get inlined across compilation unit +// boundaries. Compilation should produce three IR files, but only the two +// compilation units that have a usage of the #[inline] function should +// contain a definition. Also, the non-#[inline] function should be defined +// in only one compilation unit. +// See https://github.com/rust-lang/rust/pull/16367 + +use run_make_support::{ + count_regex_matches_in_files_with_extension, cwd, fs_wrapper, has_extension, regex, rustc, + shallow_find_files, +}; + +fn main() { + rustc().input("foo.rs").emit("llvm-ir").codegen_units(3).arg("-Zinline-in-all-cgus").run(); + let re = regex::Regex::new(r#"define\ i32\ .*inlined"#).unwrap(); + assert_eq!(count_regex_matches_in_files_with_extension(&re, "ll"), 0); + let re = regex::Regex::new(r#"define\ internal\ .*inlined"#).unwrap(); + assert_eq!(count_regex_matches_in_files_with_extension(&re, "ll"), 2); + let re = regex::Regex::new(r#"define\ hidden\ i32\ .*normal"#).unwrap(); + assert_eq!(count_regex_matches_in_files_with_extension(&re, "ll"), 1); + let re = regex::Regex::new(r#"declare\ hidden\ i32\ .*normal"#).unwrap(); + assert_eq!(count_regex_matches_in_files_with_extension(&re, "ll"), 2); +} diff --git a/tests/run-make/sepcomp-separate/rmake.rs b/tests/run-make/sepcomp-separate/rmake.rs index d3ef2450a847d..6f1d22424b5b9 100644 --- a/tests/run-make/sepcomp-separate/rmake.rs +++ b/tests/run-make/sepcomp-separate/rmake.rs @@ -3,22 +3,13 @@ // wind up in three different compilation units. // See https://github.com/rust-lang/rust/pull/16367 -use run_make_support::{fs_wrapper, glob, regex, rustc}; -use std::io::{BufRead, BufReader}; +use run_make_support::{ + count_regex_matches_in_files_with_extension, cwd, fs_wrapper, has_extension, regex, rustc, + shallow_find_files, +}; fn main() { - let mut match_count = 0; rustc().input("foo.rs").emit("llvm-ir").codegen_units(3).run(); - let re = regex::Regex::new(r#"define.*magic_fn"#).unwrap(); - let paths = glob::glob("foo.*.ll").unwrap(); - paths.filter_map(|entry| entry.ok()).filter(|path| path.is_file()).for_each(|path| { - let file = fs_wrapper::open_file(path); - let reader = BufReader::new(file); - reader - .lines() - .filter_map(|line| line.ok()) - .filter(|line| re.is_match(line)) - .for_each(|_| match_count += 1); - }); - assert_eq!(match_count, 3); + let re = regex::Regex::new(r#"define\ .*magic_fn"#).unwrap(); + assert_eq!(count_regex_matches_in_files_with_extension(&re, "ll"), 3); } From 0d85ef2857824bf6aa8727f418ee91587de04016 Mon Sep 17 00:00:00 2001 From: Oneirical Date: Thu, 4 Jul 2024 11:37:16 -0400 Subject: [PATCH 832/892] rewrite target-without-atomic-cas to rmake --- .../tidy/src/allowed_run_make_makefiles.txt | 3 --- tests/run-make/target-cpu-native/rmake.rs | 4 +--- tests/run-make/target-specs/rmake.rs | 2 +- .../run-make/target-without-atomic-cas/Makefile | 5 ----- .../run-make/target-without-atomic-cas/rmake.rs | 16 ++++++++++++++++ 5 files changed, 18 insertions(+), 12 deletions(-) delete mode 100644 tests/run-make/target-without-atomic-cas/Makefile create mode 100644 tests/run-make/target-without-atomic-cas/rmake.rs diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index 276d2d694cda0..686cc2f9c43e9 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -162,9 +162,6 @@ run-make/symbol-mangling-hashed/Makefile run-make/symbol-visibility/Makefile run-make/symbols-include-type-name/Makefile run-make/sysroot-crates-are-unstable/Makefile -run-make/target-cpu-native/Makefile -run-make/target-specs/Makefile -run-make/target-without-atomic-cas/Makefile run-make/test-benches/Makefile run-make/test-harness/Makefile run-make/thumb-none-cortex-m/Makefile diff --git a/tests/run-make/target-cpu-native/rmake.rs b/tests/run-make/target-cpu-native/rmake.rs index c5bd0245051a9..fd5fb6193fe06 100644 --- a/tests/run-make/target-cpu-native/rmake.rs +++ b/tests/run-make/target-cpu-native/rmake.rs @@ -3,8 +3,6 @@ // warnings when used, and that binaries produced by it can also be successfully executed. // See https://github.com/rust-lang/rust/pull/23238 -// FIXME(Oneirical): only-linux only-x86_64 - use run_make_support::{run, rustc}; fn main() { @@ -12,5 +10,5 @@ fn main() { run("foo"); // There should be zero warnings emitted - the bug would cause "unknown CPU `native`" // to be printed out. - assert_eq!(out.len(), 0); + assert!(out.is_empty()); } diff --git a/tests/run-make/target-specs/rmake.rs b/tests/run-make/target-specs/rmake.rs index 10c2fa298303d..d2b5f65083808 100644 --- a/tests/run-make/target-specs/rmake.rs +++ b/tests/run-make/target-specs/rmake.rs @@ -1,6 +1,6 @@ // Target-specific compilation in rustc used to have case-by-case peculiarities in 2014, // with the compiler having redundant target types and unspecific names. An overarching rework -// in #161156 changed the way the target flag functions, and this test attempts compilation +// in #16156 changed the way the target flag functions, and this test attempts compilation // with the target flag's bundle of new features to check that compilation either succeeds while // using them correctly, or fails with the right error message when using them improperly. // See https://github.com/rust-lang/rust/pull/16156 diff --git a/tests/run-make/target-without-atomic-cas/Makefile b/tests/run-make/target-without-atomic-cas/Makefile deleted file mode 100644 index 451f03d66cd23..0000000000000 --- a/tests/run-make/target-without-atomic-cas/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -include ../tools.mk - -# The target used below doesn't support atomic CAS operations. Verify that's the case -all: - $(RUSTC) --print cfg --target thumbv6m-none-eabi | $(CGREP) -v 'target_has_atomic="ptr"' diff --git a/tests/run-make/target-without-atomic-cas/rmake.rs b/tests/run-make/target-without-atomic-cas/rmake.rs new file mode 100644 index 0000000000000..c8782b6d1a566 --- /dev/null +++ b/tests/run-make/target-without-atomic-cas/rmake.rs @@ -0,0 +1,16 @@ +// ARM Cortex-M are a class of processors supported by the rust compiler. However, +// they cannot support any atomic features, such as Arc. This test simply prints +// the configuration details of one Cortex target, and checks that the compiler +// does not falsely list atomic support. +// See https://github.com/rust-lang/rust/pull/36874 + +use run_make_support::rustc; + +// The target used below doesn't support atomic CAS operations. Verify that's the case +fn main() { + rustc() + .print("cfg") + .target("thumbv6m-none-eabi") + .run() + .assert_stdout_not_contains(r#"target_has_atomic="ptr""#); +} From 7c23872836f6b536ed4a59786a1d46fbb5f0dafd Mon Sep 17 00:00:00 2001 From: Oneirical Date: Fri, 5 Jul 2024 13:45:06 -0400 Subject: [PATCH 833/892] rewrite track-pgo-dep-info to rmake --- .../tidy/src/allowed_run_make_makefiles.txt | 1 - .../run-make/proc-macro-three-crates/rmake.rs | 2 -- tests/run-make/track-path-dep-info/rmake.rs | 6 ++--- tests/run-make/track-pgo-dep-info/Makefile | 25 ------------------- tests/run-make/track-pgo-dep-info/rmake.rs | 23 +++++++++++++++++ 5 files changed, 25 insertions(+), 32 deletions(-) delete mode 100644 tests/run-make/track-pgo-dep-info/Makefile create mode 100644 tests/run-make/track-pgo-dep-info/rmake.rs diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index 118e76fdbcd26..559782056e6ff 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -158,7 +158,6 @@ run-make/target-without-atomic-cas/Makefile run-make/test-benches/Makefile run-make/thumb-none-cortex-m/Makefile run-make/thumb-none-qemu/Makefile -run-make/track-pgo-dep-info/Makefile run-make/translation/Makefile run-make/type-mismatch-same-crate-name/Makefile run-make/unstable-flag-required/Makefile diff --git a/tests/run-make/proc-macro-three-crates/rmake.rs b/tests/run-make/proc-macro-three-crates/rmake.rs index 62dc547fcfb53..d3735540fdd47 100644 --- a/tests/run-make/proc-macro-three-crates/rmake.rs +++ b/tests/run-make/proc-macro-three-crates/rmake.rs @@ -5,8 +5,6 @@ // This was fixed in #37846, and this test checks // that this bug does not make a resurgence. -//FIXME(Oneirical): ignore-cross-compile - use run_make_support::{bare_rustc, cwd, rust_lib_name, rustc}; fn main() { diff --git a/tests/run-make/track-path-dep-info/rmake.rs b/tests/run-make/track-path-dep-info/rmake.rs index f4a77c7fc2187..f108dc6605129 100644 --- a/tests/run-make/track-path-dep-info/rmake.rs +++ b/tests/run-make/track-path-dep-info/rmake.rs @@ -4,12 +4,10 @@ // output successfully added the file as a dependency. // See https://github.com/rust-lang/rust/pull/84029 -//FIXME(Oneirical): Try it on musl - -use run_make_support::{bare_rustc, fs_wrapper, rustc}; +use run_make_support::{fs_wrapper, rustc}; fn main() { - bare_rustc().input("macro_def.rs").run(); + rustc().input("macro_def.rs").run(); rustc().env("EXISTING_PROC_MACRO_ENV", "1").emit("dep-info").input("macro_use.rs").run(); assert!(fs_wrapper::read_to_string("macro_use.d").contains("emojis.txt:")); } diff --git a/tests/run-make/track-pgo-dep-info/Makefile b/tests/run-make/track-pgo-dep-info/Makefile deleted file mode 100644 index 3afe3662fa753..0000000000000 --- a/tests/run-make/track-pgo-dep-info/Makefile +++ /dev/null @@ -1,25 +0,0 @@ -# needs-profiler-support - -include ../tools.mk - -# FIXME(eddyb) provide `HOST_RUSTC` and `TARGET_RUSTC` -# instead of hardcoding them everywhere they're needed. -ifeq ($(IS_MUSL_HOST),1) -ADDITIONAL_ARGS := $(RUSTFLAGS) -endif - -all: - # Generate PGO profiles - $(BARE_RUSTC) $(ADDITIONAL_ARGS) -Cprofile-generate=$(TMPDIR)/profiles --out-dir $(TMPDIR) main.rs - $(TMPDIR)/main - - # Merge profiles - "$(LLVM_BIN_DIR)/llvm-profdata" merge \ - -o "$(TMPDIR)/merged.profdata" \ - "$(TMPDIR)/profiles" || exit 1 - - # Use the profile - $(RUSTC) -Cprofile-use=$(TMPDIR)/merged.profdata --emit dep-info main.rs - - # Check that profile file is in depinfo - $(CGREP) "merged.profdata" < $(TMPDIR)/main.d diff --git a/tests/run-make/track-pgo-dep-info/rmake.rs b/tests/run-make/track-pgo-dep-info/rmake.rs new file mode 100644 index 0000000000000..acfe05cf8ea3d --- /dev/null +++ b/tests/run-make/track-pgo-dep-info/rmake.rs @@ -0,0 +1,23 @@ +// Emitting dep-info files used to not have any mention of PGO profiles used +// in compilation, which meant these profiles could be changed without consequence. +// After changing this in #100801, this test checks that the profile data is successfully +// included in dep-info emit files. +// See https://github.com/rust-lang/rust/pull/100801 + +//@ ignore-cross-compile +// Reason: the binary is executed +//@ needs-profiler-support + +use run_make_support::{fs_wrapper, llvm_profdata, run, rustc}; + +fn main() { + // Generate the profile-guided-optimization (PGO) profiles + rustc().profile_generate("profiles").input("main.rs").run(); + // Merge the profiles + run("main"); + llvm_profdata().merge().output("merged.profdata").input("profiles").run(); + // Use the profiles in compilation + rustc().profile_use("merged.profdata").emit("dep-info").input("main.rs").run(); + // Check that the profile file is in the dep-info emit file + assert!(fs_wrapper::read_to_string("main.d").contains("merged.profdata")); +} From f4f678f27e84254cc89fd53ae20e467a254982de Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sun, 7 Jul 2024 22:39:30 -0400 Subject: [PATCH 834/892] Infer async closure signature from old-style two-part Fn + Future bounds --- compiler/rustc_hir_typeck/src/closure.rs | 102 ++++++++++++++++-- ...signature-inference-from-two-part-bound.rs | 27 +++++ 2 files changed, 121 insertions(+), 8 deletions(-) create mode 100644 tests/ui/async-await/async-closures/signature-inference-from-two-part-bound.rs diff --git a/compiler/rustc_hir_typeck/src/closure.rs b/compiler/rustc_hir_typeck/src/closure.rs index ac7ed3e26f976..53cf121dfebcd 100644 --- a/compiler/rustc_hir_typeck/src/closure.rs +++ b/compiler/rustc_hir_typeck/src/closure.rs @@ -424,9 +424,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if let Some(trait_def_id) = trait_def_id { let found_kind = match closure_kind { hir::ClosureKind::Closure => self.tcx.fn_trait_kind_from_def_id(trait_def_id), - hir::ClosureKind::CoroutineClosure(hir::CoroutineDesugaring::Async) => { - self.tcx.async_fn_trait_kind_from_def_id(trait_def_id) - } + hir::ClosureKind::CoroutineClosure(hir::CoroutineDesugaring::Async) => self + .tcx + .async_fn_trait_kind_from_def_id(trait_def_id) + .or_else(|| self.tcx.fn_trait_kind_from_def_id(trait_def_id)), _ => None, }; @@ -470,14 +471,37 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // for closures and async closures, respectively. match closure_kind { hir::ClosureKind::Closure - if self.tcx.fn_trait_kind_from_def_id(trait_def_id).is_some() => {} + if self.tcx.fn_trait_kind_from_def_id(trait_def_id).is_some() => + { + self.extract_sig_from_projection(cause_span, projection) + } + hir::ClosureKind::CoroutineClosure(hir::CoroutineDesugaring::Async) + if self.tcx.async_fn_trait_kind_from_def_id(trait_def_id).is_some() => + { + self.extract_sig_from_projection(cause_span, projection) + } + // It's possible we've passed the closure to a (somewhat out-of-fashion) + // `F: FnOnce() -> Fut, Fut: Future` style bound. Let's still + // guide inference here, since it's beneficial for the user. hir::ClosureKind::CoroutineClosure(hir::CoroutineDesugaring::Async) - if self.tcx.async_fn_trait_kind_from_def_id(trait_def_id).is_some() => {} - _ => return None, + if self.tcx.fn_trait_kind_from_def_id(trait_def_id).is_some() => + { + self.extract_sig_from_projection_and_future_bound(cause_span, projection) + } + _ => None, } + } + + /// Given an `FnOnce::Output` or `AsyncFn::Output` projection, extract the args + /// and return type to infer a [`ty::PolyFnSig`] for the closure. + fn extract_sig_from_projection( + &self, + cause_span: Option, + projection: ty::PolyProjectionPredicate<'tcx>, + ) -> Option> { + let projection = self.resolve_vars_if_possible(projection); let arg_param_ty = projection.skip_binder().projection_term.args.type_at(1); - let arg_param_ty = self.resolve_vars_if_possible(arg_param_ty); debug!(?arg_param_ty); let ty::Tuple(input_tys) = *arg_param_ty.kind() else { @@ -486,7 +510,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Since this is a return parameter type it is safe to unwrap. let ret_param_ty = projection.skip_binder().term.expect_type(); - let ret_param_ty = self.resolve_vars_if_possible(ret_param_ty); debug!(?ret_param_ty); let sig = projection.rebind(self.tcx.mk_fn_sig( @@ -500,6 +523,69 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { Some(ExpectedSig { cause_span, sig }) } + /// When an async closure is passed to a function that has a "two-part" `Fn` + /// and `Future` trait bound, like: + /// + /// ```rust + /// use std::future::Future; + /// + /// fn not_exactly_an_async_closure(_f: F) + /// where + /// F: FnOnce(String, u32) -> Fut, + /// Fut: Future, + /// {} + /// ``` + /// + /// The we want to be able to extract the signature to guide inference in the async + /// closure. We will have two projection predicates registered in this case. First, + /// we identify the `FnOnce` bound, and if the output type is + /// an inference variable `?Fut`, we check if that is bounded by a `Future` + /// projection. + fn extract_sig_from_projection_and_future_bound( + &self, + cause_span: Option, + projection: ty::PolyProjectionPredicate<'tcx>, + ) -> Option> { + let projection = self.resolve_vars_if_possible(projection); + + let arg_param_ty = projection.skip_binder().projection_term.args.type_at(1); + debug!(?arg_param_ty); + + let ty::Tuple(input_tys) = *arg_param_ty.kind() else { + return None; + }; + + // If the return type is a type variable, look for bounds on it. + // We could theoretically support other kinds of return types here, + // but none of them would be useful, since async closures return + // concrete anonymous future types, and their futures are not coerced + // into any other type within the body of the async closure. + let ty::Infer(ty::TyVar(return_vid)) = *projection.skip_binder().term.expect_type().kind() + else { + return None; + }; + + // FIXME: We may want to elaborate here, though I assume this will be exceedingly rare. + for bound in self.obligations_for_self_ty(return_vid) { + if let Some(ret_projection) = bound.predicate.as_projection_clause() + && let Some(ret_projection) = ret_projection.no_bound_vars() + && self.tcx.is_lang_item(ret_projection.def_id(), LangItem::FutureOutput) + { + let sig = projection.rebind(self.tcx.mk_fn_sig( + input_tys, + ret_projection.term.expect_type(), + false, + hir::Safety::Safe, + Abi::Rust, + )); + + return Some(ExpectedSig { cause_span, sig }); + } + } + + None + } + fn sig_of_closure( &self, expr_def_id: LocalDefId, diff --git a/tests/ui/async-await/async-closures/signature-inference-from-two-part-bound.rs b/tests/ui/async-await/async-closures/signature-inference-from-two-part-bound.rs new file mode 100644 index 0000000000000..0e2d1ef12082b --- /dev/null +++ b/tests/ui/async-await/async-closures/signature-inference-from-two-part-bound.rs @@ -0,0 +1,27 @@ +//@ edition: 2021 +//@ check-pass +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver + +#![feature(async_closure)] + +use std::future::Future; +use std::any::Any; + +struct Struct; +impl Struct { + fn method(&self) {} +} + +fn fake_async_closure(_: F) +where + F: Fn(Struct) -> Fut, + Fut: Future, +{} + +fn main() { + fake_async_closure(async |s| { + s.method(); + }) +} From 04caa5555a23e46b9e67d809e43204fd83ca3247 Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Mon, 8 Jul 2024 12:27:26 -0400 Subject: [PATCH 835/892] Add `f16` and `f128` as SIMD types in LLVM --- compiler/rustc_codegen_llvm/src/intrinsic.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index e02c61cd29654..68c3d47e826bf 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -1469,8 +1469,10 @@ fn generic_simd_intrinsic<'ll, 'tcx>( let (elem_ty_str, elem_ty) = if let ty::Float(f) = in_elem.kind() { let elem_ty = bx.cx.type_float_from_ty(*f); match f.bit_width() { + 16 => ("f16", elem_ty), 32 => ("f32", elem_ty), 64 => ("f64", elem_ty), + 128 => ("f128", elem_ty), _ => return_error!(InvalidMonomorphization::FloatingPointVector { span, name, From aa1c24a908fb7c37b9ed2998e240f06101050047 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 8 Jul 2024 20:18:21 +0200 Subject: [PATCH 836/892] Improve code of `run-make/llvm-ident` --- tests/run-make/llvm-ident/rmake.rs | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/tests/run-make/llvm-ident/rmake.rs b/tests/run-make/llvm-ident/rmake.rs index 6934a4b36d013..9699d0579f6ef 100644 --- a/tests/run-make/llvm-ident/rmake.rs +++ b/tests/run-make/llvm-ident/rmake.rs @@ -2,9 +2,9 @@ //@ ignore-cross-compile use run_make_support::llvm::llvm_bin_dir; -use run_make_support::{cmd, env_var, llvm_filecheck, read_dir, rustc, source_root}; - -use std::ffi::OsStr; +use run_make_support::{ + cmd, env_var, has_extension, llvm_filecheck, rustc, shallow_find_files, source_root, +}; fn main() { // `-Ccodegen-units=16 -Copt-level=2` is used here to trigger thin LTO @@ -22,20 +22,14 @@ fn main() { // `llvm-dis` is used here since `--emit=llvm-ir` does not emit LLVM IR // for temporary outputs. - let mut files = Vec::new(); - read_dir(".", |path| { - if path.is_file() && path.extension().is_some_and(|ext| ext == OsStr::new("bc")) { - files.push(path.to_path_buf()); - } - }); + let files = shallow_find_files(".", |path| has_extension(path, "bc")); cmd(llvm_bin_dir().join("llvm-dis")).args(files).run(); // Check LLVM IR files (including temporary outputs) have `!llvm.ident` // named metadata, reusing the related codegen test. let llvm_ident_path = source_root().join("tests/codegen/llvm-ident.rs"); - read_dir(".", |path| { - if path.is_file() && path.extension().is_some_and(|ext| ext == OsStr::new("ll")) { - llvm_filecheck().input_file(path).arg(&llvm_ident_path).run(); - } - }); + let files = shallow_find_files(".", |path| has_extension(path, "ll")); + for file in files { + llvm_filecheck().input_file(file).arg(&llvm_ident_path).run(); + } } From 9e7918f70e3d8dc166034f936420a72ffb946d80 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Fri, 5 Jul 2024 08:14:40 +0000 Subject: [PATCH 837/892] Remove another `StructuredDiag` impl --- compiler/rustc_hir_analysis/messages.ftl | 4 -- compiler/rustc_hir_analysis/src/errors.rs | 14 ----- .../src/structured_errors.rs | 3 +- .../missing_cast_for_variadic_arg.rs | 57 ------------------- compiler/rustc_hir_typeck/messages.ftl | 6 ++ compiler/rustc_hir_typeck/src/errors.rs | 16 ++++++ .../rustc_hir_typeck/src/fn_ctxt/checks.rs | 18 +++++- 7 files changed, 38 insertions(+), 80 deletions(-) delete mode 100644 compiler/rustc_hir_analysis/src/structured_errors/missing_cast_for_variadic_arg.rs diff --git a/compiler/rustc_hir_analysis/messages.ftl b/compiler/rustc_hir_analysis/messages.ftl index 91b1506d1e4e5..24c5377a3b125 100644 --- a/compiler/rustc_hir_analysis/messages.ftl +++ b/compiler/rustc_hir_analysis/messages.ftl @@ -373,10 +373,6 @@ hir_analysis_paren_sugar_attribute = the `#[rustc_paren_sugar]` attribute is a t hir_analysis_parenthesized_fn_trait_expansion = parenthesized trait syntax expands to `{$expanded_type}` -hir_analysis_pass_to_variadic_function = can't pass `{$ty}` to variadic function - .suggestion = cast the value to `{$cast_ty}` - .help = cast the value to `{$cast_ty}` - hir_analysis_pattern_type_non_const_range = range patterns must have constant range start and end hir_analysis_pattern_type_wild_pat = wildcard patterns are not permitted for pattern types .label = this type is the same as the inner type without a pattern diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs index 7d44ac458de86..26cd7d80bd570 100644 --- a/compiler/rustc_hir_analysis/src/errors.rs +++ b/compiler/rustc_hir_analysis/src/errors.rs @@ -692,20 +692,6 @@ pub(crate) struct TypeOf<'tcx> { pub ty: Ty<'tcx>, } -#[derive(Diagnostic)] -#[diag(hir_analysis_pass_to_variadic_function, code = E0617)] -pub(crate) struct PassToVariadicFunction<'tcx, 'a> { - #[primary_span] - pub span: Span, - pub ty: Ty<'tcx>, - pub cast_ty: &'a str, - #[suggestion(code = "{replace}", applicability = "machine-applicable")] - pub sugg_span: Option, - pub replace: String, - #[help] - pub help: Option<()>, -} - #[derive(Diagnostic)] #[diag(hir_analysis_invalid_union_field, code = E0740)] pub(crate) struct InvalidUnionField { diff --git a/compiler/rustc_hir_analysis/src/structured_errors.rs b/compiler/rustc_hir_analysis/src/structured_errors.rs index 61a2400f9e434..af4d9efca5a63 100644 --- a/compiler/rustc_hir_analysis/src/structured_errors.rs +++ b/compiler/rustc_hir_analysis/src/structured_errors.rs @@ -1,7 +1,6 @@ -mod missing_cast_for_variadic_arg; mod wrong_number_of_generic_args; -pub use self::{missing_cast_for_variadic_arg::*, wrong_number_of_generic_args::*}; +pub use self::wrong_number_of_generic_args::*; use rustc_errors::{Diag, ErrCode}; use rustc_session::Session; diff --git a/compiler/rustc_hir_analysis/src/structured_errors/missing_cast_for_variadic_arg.rs b/compiler/rustc_hir_analysis/src/structured_errors/missing_cast_for_variadic_arg.rs deleted file mode 100644 index 0e78acbeae2d4..0000000000000 --- a/compiler/rustc_hir_analysis/src/structured_errors/missing_cast_for_variadic_arg.rs +++ /dev/null @@ -1,57 +0,0 @@ -use crate::{errors, structured_errors::StructuredDiag}; -use rustc_errors::{codes::*, Diag}; -use rustc_middle::ty::{Ty, TypeVisitableExt}; -use rustc_session::Session; -use rustc_span::Span; - -pub struct MissingCastForVariadicArg<'tcx, 's> { - pub sess: &'tcx Session, - pub span: Span, - pub ty: Ty<'tcx>, - pub cast_ty: &'s str, -} - -impl<'tcx> StructuredDiag<'tcx> for MissingCastForVariadicArg<'tcx, '_> { - fn session(&self) -> &Session { - self.sess - } - - fn code(&self) -> ErrCode { - E0617 - } - - fn diagnostic_common(&self) -> Diag<'tcx> { - let (sugg_span, replace, help) = - if let Ok(snippet) = self.sess.source_map().span_to_snippet(self.span) { - (Some(self.span), format!("{} as {}", snippet, self.cast_ty), None) - } else { - (None, "".to_string(), Some(())) - }; - - let mut err = self.sess.dcx().create_err(errors::PassToVariadicFunction { - span: self.span, - ty: self.ty, - cast_ty: self.cast_ty, - help, - replace, - sugg_span, - }); - - if self.ty.references_error() { - err.downgrade_to_delayed_bug(); - } - - err - } - - fn diagnostic_extended(&self, mut err: Diag<'tcx>) -> Diag<'tcx> { - err.note(format!( - "certain types, like `{}`, must be casted before passing them to a \ - variadic function, because of arcane ABI rules dictated by the C \ - standard", - self.ty - )); - - err - } -} diff --git a/compiler/rustc_hir_typeck/messages.ftl b/compiler/rustc_hir_typeck/messages.ftl index 239b0c4469027..39d430cf73b76 100644 --- a/compiler/rustc_hir_typeck/messages.ftl +++ b/compiler/rustc_hir_typeck/messages.ftl @@ -38,6 +38,7 @@ hir_typeck_cast_thin_pointer_to_fat_pointer = cannot cast thin pointer `{$expr_t For more information about casts, take a look at The Book: https://doc.rust-lang.org/reference/expressions/operator-expr.html#type-cast-expressions", + hir_typeck_cast_unknown_pointer = cannot cast {$to -> [true] to *[false] from @@ -138,6 +139,11 @@ hir_typeck_option_result_asref = use `{$def_path}::as_ref` to convert `{$expecte hir_typeck_option_result_cloned = use `{$def_path}::cloned` to clone the value inside the `{$def_path}` hir_typeck_option_result_copied = use `{$def_path}::copied` to copy the value inside the `{$def_path}` +hir_typeck_pass_to_variadic_function = can't pass `{$ty}` to variadic function + .suggestion = cast the value to `{$cast_ty}` + .help = cast the value to `{$cast_ty}` + .teach_help = certain types, like `{$ty}`, must be casted before passing them to a variadic function, because of arcane ABI rules dictated by the C standard + hir_typeck_ptr_cast_add_auto_to_object = adding {$traits_len -> [1] an auto trait {$traits} *[other] auto traits {$traits} diff --git a/compiler/rustc_hir_typeck/src/errors.rs b/compiler/rustc_hir_typeck/src/errors.rs index 8b5b0a9b92f29..9a38d6d4a7195 100644 --- a/compiler/rustc_hir_typeck/src/errors.rs +++ b/compiler/rustc_hir_typeck/src/errors.rs @@ -708,3 +708,19 @@ pub(crate) struct CastThinPointerToFatPointer<'tcx> { #[note(hir_typeck_teach_help)] pub(crate) teach: Option<()>, } + +#[derive(Diagnostic)] +#[diag(hir_typeck_pass_to_variadic_function, code = E0617)] +pub(crate) struct PassToVariadicFunction<'tcx, 'a> { + #[primary_span] + pub span: Span, + pub ty: Ty<'tcx>, + pub cast_ty: &'a str, + #[suggestion(code = "{replace}", applicability = "machine-applicable")] + pub sugg_span: Option, + pub replace: String, + #[help] + pub help: Option<()>, + #[note(hir_typeck_teach_help)] + pub(crate) teach: Option<()>, +} diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index 10092dce58766..ab0f356ce91f1 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -28,7 +28,6 @@ use rustc_hir::{ExprKind, HirId, Node, QPath}; use rustc_hir_analysis::check::intrinsicck::InlineAsmCtxt; use rustc_hir_analysis::check::potentially_plural_count; use rustc_hir_analysis::hir_ty_lowering::HirTyLowerer; -use rustc_hir_analysis::structured_errors::StructuredDiag; use rustc_index::IndexVec; use rustc_infer::infer::error_reporting::{FailureCode, ObligationCauseExt}; use rustc_infer::infer::TypeTrace; @@ -406,9 +405,22 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ty: Ty<'tcx>, cast_ty: &str, ) { - use rustc_hir_analysis::structured_errors::MissingCastForVariadicArg; + let (sugg_span, replace, help) = + if let Ok(snippet) = sess.source_map().span_to_snippet(span) { + (Some(span), format!("{snippet} as {cast_ty}"), None) + } else { + (None, "".to_string(), Some(())) + }; - MissingCastForVariadicArg { sess, span, ty, cast_ty }.diagnostic().emit(); + sess.dcx().emit_err(errors::PassToVariadicFunction { + span, + ty, + cast_ty, + help, + replace, + sugg_span, + teach: sess.teach(E0617).then_some(()), + }); } // There are a few types which get autopromoted when passed via varargs From 2f0368c902e912242e86e49f140c666c712b79c7 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Fri, 5 Jul 2024 08:28:09 +0000 Subject: [PATCH 838/892] Remove `StructuredDiag` --- .../src/hir_ty_lowering/generics.rs | 30 +++++---- .../src/structured_errors.rs | 29 --------- .../wrong_number_of_generic_args.rs | 62 +++++++++---------- 3 files changed, 43 insertions(+), 78 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs index e92c377f0ce2a..994416fbce5df 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs @@ -3,7 +3,7 @@ use crate::hir_ty_lowering::{ errors::prohibit_assoc_item_constraint, ExplicitLateBound, GenericArgCountMismatch, GenericArgCountResult, GenericArgPosition, GenericArgsLowerer, }; -use crate::structured_errors::{GenericArgsInfo, StructuredDiag, WrongNumberOfGenericArgs}; +use crate::structured_errors::{GenericArgsInfo, WrongNumberOfGenericArgs}; use rustc_ast::ast::ParamKindOrd; use rustc_errors::{ codes::*, struct_span_code_err, Applicability, Diag, ErrorGuaranteed, MultiSpan, @@ -486,7 +486,7 @@ pub(crate) fn check_generic_arg_count( GenericArgsInfo::MissingLifetimes { num_missing_args } }; - let reported = WrongNumberOfGenericArgs::new( + let reported = tcx.dcx().emit_err(WrongNumberOfGenericArgs::new( tcx, gen_args_info, seg, @@ -494,9 +494,7 @@ pub(crate) fn check_generic_arg_count( has_self as usize, gen_args, def_id, - ) - .diagnostic() - .emit(); + )); Err(reported) }; @@ -573,17 +571,17 @@ pub(crate) fn check_generic_arg_count( debug!(?gen_args_info); let reported = gen_args.has_err().unwrap_or_else(|| { - WrongNumberOfGenericArgs::new( - tcx, - gen_args_info, - seg, - gen_params, - params_offset, - gen_args, - def_id, - ) - .diagnostic() - .emit_unless(all_params_are_binded) + tcx.dcx() + .create_err(WrongNumberOfGenericArgs::new( + tcx, + gen_args_info, + seg, + gen_params, + params_offset, + gen_args, + def_id, + )) + .emit_unless(all_params_are_binded) }); Err(reported) diff --git a/compiler/rustc_hir_analysis/src/structured_errors.rs b/compiler/rustc_hir_analysis/src/structured_errors.rs index af4d9efca5a63..1d7b0e7d64aff 100644 --- a/compiler/rustc_hir_analysis/src/structured_errors.rs +++ b/compiler/rustc_hir_analysis/src/structured_errors.rs @@ -1,32 +1,3 @@ mod wrong_number_of_generic_args; pub use self::wrong_number_of_generic_args::*; - -use rustc_errors::{Diag, ErrCode}; -use rustc_session::Session; - -pub trait StructuredDiag<'tcx> { - fn session(&self) -> &Session; - - fn code(&self) -> ErrCode; - - fn diagnostic(&self) -> Diag<'tcx> { - let err = self.diagnostic_common(); - - if self.session().teach(self.code()) { - self.diagnostic_extended(err) - } else { - self.diagnostic_regular(err) - } - } - - fn diagnostic_common(&self) -> Diag<'tcx>; - - fn diagnostic_regular(&self, err: Diag<'tcx>) -> Diag<'tcx> { - err - } - - fn diagnostic_extended(&self, err: Diag<'tcx>) -> Diag<'tcx> { - err - } -} diff --git a/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs b/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs index 5d435a8edf9ff..6426ad9dc184f 100644 --- a/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs +++ b/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs @@ -1,8 +1,8 @@ -use crate::structured_errors::StructuredDiag; -use rustc_errors::{codes::*, pluralize, Applicability, Diag, MultiSpan}; +use rustc_errors::{ + codes::*, pluralize, Applicability, Diag, Diagnostic, EmissionGuarantee, MultiSpan, +}; use rustc_hir as hir; use rustc_middle::ty::{self as ty, AssocItems, AssocKind, TyCtxt}; -use rustc_session::Session; use rustc_span::def_id::DefId; use std::iter; @@ -541,14 +541,8 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> { } } - fn start_diagnostics(&self) -> Diag<'tcx> { - let span = self.path_segment.ident.span; - let msg = self.create_error_message(); - self.tcx.dcx().struct_span_err(span, msg).with_code(self.code()) - } - /// Builds the `expected 1 type argument / supplied 2 type arguments` message. - fn notify(&self, err: &mut Diag<'_>) { + fn notify(&self, err: &mut Diag<'_, impl EmissionGuarantee>) { let (quantifier, bound) = self.get_quantifier_and_bound(); let provided_args = self.num_provided_args(); @@ -600,7 +594,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> { } } - fn suggest(&self, err: &mut Diag<'_>) { + fn suggest(&self, err: &mut Diag<'_, impl EmissionGuarantee>) { debug!( "suggest(self.provided {:?}, self.gen_args.span(): {:?})", self.num_provided_args(), @@ -628,7 +622,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> { /// ```text /// type Map = HashMap; /// ``` - fn suggest_adding_args(&self, err: &mut Diag<'_>) { + fn suggest_adding_args(&self, err: &mut Diag<'_, impl EmissionGuarantee>) { if self.gen_args.parenthesized != hir::GenericArgsParentheses::No { return; } @@ -647,7 +641,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> { } } - fn suggest_adding_lifetime_args(&self, err: &mut Diag<'_>) { + fn suggest_adding_lifetime_args(&self, err: &mut Diag<'_, impl EmissionGuarantee>) { debug!("suggest_adding_lifetime_args(path_segment: {:?})", self.path_segment); let num_missing_args = self.num_missing_lifetime_args(); let num_params_to_take = num_missing_args; @@ -701,7 +695,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> { } } - fn suggest_adding_type_and_const_args(&self, err: &mut Diag<'_>) { + fn suggest_adding_type_and_const_args(&self, err: &mut Diag<'_, impl EmissionGuarantee>) { let num_missing_args = self.num_missing_type_or_const_args(); let msg = format!("add missing {} argument{}", self.kind(), pluralize!(num_missing_args)); @@ -761,7 +755,10 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> { /// ```compile_fail /// Into::into::>(42) // suggests considering `Into::>::into(42)` /// ``` - fn suggest_moving_args_from_assoc_fn_to_trait(&self, err: &mut Diag<'_>) { + fn suggest_moving_args_from_assoc_fn_to_trait( + &self, + err: &mut Diag<'_, impl EmissionGuarantee>, + ) { let trait_ = match self.tcx.trait_of_item(self.def_id) { Some(def_id) => def_id, None => return, @@ -817,7 +814,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> { fn suggest_moving_args_from_assoc_fn_to_trait_for_qualified_path( &self, - err: &mut Diag<'_>, + err: &mut Diag<'_, impl EmissionGuarantee>, qpath: &'tcx hir::QPath<'tcx>, msg: String, num_assoc_fn_excess_args: usize, @@ -850,7 +847,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> { fn suggest_moving_args_from_assoc_fn_to_trait_for_method_call( &self, - err: &mut Diag<'_>, + err: &mut Diag<'_, impl EmissionGuarantee>, trait_def_id: DefId, expr: &'tcx hir::Expr<'tcx>, msg: String, @@ -904,7 +901,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> { /// ```text /// type Map = HashMap; /// ``` - fn suggest_removing_args_or_generics(&self, err: &mut Diag<'_>) { + fn suggest_removing_args_or_generics(&self, err: &mut Diag<'_, impl EmissionGuarantee>) { let num_provided_lt_args = self.num_provided_lifetime_args(); let num_provided_type_const_args = self.num_provided_type_or_const_args(); let unbound_types = self.get_unbound_associated_types(); @@ -922,7 +919,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> { let provided_args_matches_unbound_traits = unbound_types.len() == num_redundant_type_or_const_args; - let remove_lifetime_args = |err: &mut Diag<'_>| { + let remove_lifetime_args = |err: &mut Diag<'_, _>| { let mut lt_arg_spans = Vec::new(); let mut found_redundant = false; for arg in self.gen_args.args { @@ -963,7 +960,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> { ); }; - let remove_type_or_const_args = |err: &mut Diag<'_>| { + let remove_type_or_const_args = |err: &mut Diag<'_, _>| { let mut gen_arg_spans = Vec::new(); let mut found_redundant = false; for arg in self.gen_args.args { @@ -1060,7 +1057,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> { } /// Builds the `type defined here` message. - fn show_definition(&self, err: &mut Diag<'_>) { + fn show_definition(&self, err: &mut Diag<'_, impl EmissionGuarantee>) { let mut spans: MultiSpan = if let Some(def_span) = self.tcx.def_ident_span(self.def_id) { if self.tcx.sess.source_map().is_span_accessible(def_span) { def_span.into() @@ -1111,7 +1108,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> { } /// Add note if `impl Trait` is explicitly specified. - fn note_synth_provided(&self, err: &mut Diag<'_>) { + fn note_synth_provided(&self, err: &mut Diag<'_, impl EmissionGuarantee>) { if !self.is_synth_provided() { return; } @@ -1120,17 +1117,16 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> { } } -impl<'tcx> StructuredDiag<'tcx> for WrongNumberOfGenericArgs<'_, 'tcx> { - fn session(&self) -> &Session { - self.tcx.sess - } - - fn code(&self) -> ErrCode { - E0107 - } - - fn diagnostic_common(&self) -> Diag<'tcx> { - let mut err = self.start_diagnostics(); +impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for WrongNumberOfGenericArgs<'_, '_> { + fn into_diag( + self, + dcx: rustc_errors::DiagCtxtHandle<'a>, + level: rustc_errors::Level, + ) -> Diag<'a, G> { + let msg = self.create_error_message(); + let mut err = Diag::new(dcx, level, msg); + err.code(E0107); + err.span(self.path_segment.ident.span); self.notify(&mut err); self.suggest(&mut err); From af9ab1b026b0d021d7a7d7d443f4398641f093ef Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Fri, 5 Jul 2024 08:59:31 +0000 Subject: [PATCH 839/892] Remove `structured_errors` module --- compiler/rustc_hir_analysis/src/errors.rs | 1 + .../wrong_number_of_generic_args.rs | 0 compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs | 2 +- compiler/rustc_hir_analysis/src/lib.rs | 1 - compiler/rustc_hir_analysis/src/structured_errors.rs | 3 --- 5 files changed, 2 insertions(+), 5 deletions(-) rename compiler/rustc_hir_analysis/src/{structured_errors => errors}/wrong_number_of_generic_args.rs (100%) delete mode 100644 compiler/rustc_hir_analysis/src/structured_errors.rs diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs index 26cd7d80bd570..0ee87a13e9e37 100644 --- a/compiler/rustc_hir_analysis/src/errors.rs +++ b/compiler/rustc_hir_analysis/src/errors.rs @@ -9,6 +9,7 @@ use rustc_middle::ty::Ty; use rustc_span::{symbol::Ident, Span, Symbol}; mod pattern_types; pub use pattern_types::*; +pub mod wrong_number_of_generic_args; mod precise_captures; pub(crate) use precise_captures::*; diff --git a/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs b/compiler/rustc_hir_analysis/src/errors/wrong_number_of_generic_args.rs similarity index 100% rename from compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs rename to compiler/rustc_hir_analysis/src/errors/wrong_number_of_generic_args.rs diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs index 994416fbce5df..90836f0a54f45 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs @@ -1,9 +1,9 @@ use super::IsMethodCall; +use crate::errors::wrong_number_of_generic_args::{GenericArgsInfo, WrongNumberOfGenericArgs}; use crate::hir_ty_lowering::{ errors::prohibit_assoc_item_constraint, ExplicitLateBound, GenericArgCountMismatch, GenericArgCountResult, GenericArgPosition, GenericArgsLowerer, }; -use crate::structured_errors::{GenericArgsInfo, WrongNumberOfGenericArgs}; use rustc_ast::ast::ParamKindOrd; use rustc_errors::{ codes::*, struct_span_code_err, Applicability, Diag, ErrorGuaranteed, MultiSpan, diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs index 2f6b0a582e58c..dd7fbba753bdd 100644 --- a/compiler/rustc_hir_analysis/src/lib.rs +++ b/compiler/rustc_hir_analysis/src/lib.rs @@ -92,7 +92,6 @@ mod errors; pub mod hir_wf_check; mod impl_wf_check; mod outlives; -pub mod structured_errors; mod variance; use rustc_hir as hir; diff --git a/compiler/rustc_hir_analysis/src/structured_errors.rs b/compiler/rustc_hir_analysis/src/structured_errors.rs deleted file mode 100644 index 1d7b0e7d64aff..0000000000000 --- a/compiler/rustc_hir_analysis/src/structured_errors.rs +++ /dev/null @@ -1,3 +0,0 @@ -mod wrong_number_of_generic_args; - -pub use self::wrong_number_of_generic_args::*; From fe4c995ccb292f5b8fdaba0bfc5f58c6ee8e7fed Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 8 Jul 2024 15:36:57 -0400 Subject: [PATCH 840/892] Move trait selection error reporting to its own top-level module --- .../src/diagnostics/conflict_errors.rs | 4 +- .../src/diagnostics/explain_borrow.rs | 2 +- .../rustc_borrowck/src/diagnostics/mod.rs | 2 +- .../src/diagnostics/move_errors.rs | 2 +- .../src/diagnostics/mutability_errors.rs | 2 +- .../src/region_infer/opaque_types.rs | 2 +- .../src/type_check/free_region_relations.rs | 2 +- .../src/check_consts/check.rs | 2 +- .../rustc_hir_analysis/src/check/check.rs | 4 +- .../src/check/compare_impl_item.rs | 2 +- .../rustc_hir_analysis/src/check/entry.rs | 2 +- compiler/rustc_hir_analysis/src/check/mod.rs | 4 +- .../rustc_hir_analysis/src/check/wfcheck.rs | 2 +- .../src/coherence/builtin.rs | 2 +- compiler/rustc_hir_analysis/src/collect.rs | 2 +- .../src/hir_ty_lowering/errors.rs | 2 +- .../src/hir_ty_lowering/lint.rs | 2 +- .../src/hir_ty_lowering/object_safety.rs | 2 +- .../src/impl_wf_check/min_specialization.rs | 2 +- compiler/rustc_hir_typeck/src/callee.rs | 2 +- compiler/rustc_hir_typeck/src/closure.rs | 4 +- compiler/rustc_hir_typeck/src/coercion.rs | 4 +- compiler/rustc_hir_typeck/src/expr.rs | 4 +- .../rustc_hir_typeck/src/fn_ctxt/_impl.rs | 2 +- .../src/fn_ctxt/suggestions.rs | 4 +- .../rustc_hir_typeck/src/method/suggest.rs | 4 +- compiler/rustc_hir_typeck/src/op.rs | 2 +- compiler/rustc_hir_typeck/src/writeback.rs | 2 +- compiler/rustc_lint/src/async_fn_in_trait.rs | 2 +- compiler/rustc_lint/src/non_local_def.rs | 4 +- compiler/rustc_mir_transform/src/coroutine.rs | 2 +- compiler/rustc_passes/src/check_attr.rs | 2 +- compiler/rustc_passes/src/layout_test.rs | 2 +- .../src/error_reporting/mod.rs | 1 + .../traits}/ambiguity.rs | 0 .../traits}/infer_ctxt_ext.rs | 0 .../traits}/mod.rs | 62 ++++++++++++++++++- .../traits}/on_unimplemented.rs | 2 +- .../traits}/suggestions.rs | 2 +- .../traits}/type_err_ctxt_ext.rs | 6 +- compiler/rustc_trait_selection/src/lib.rs | 1 + .../src/solve/normalize.rs | 2 +- .../src/traits/coherence.rs | 2 +- .../src/traits/engine.rs | 2 +- .../src/traits/fulfill.rs | 2 +- .../rustc_trait_selection/src/traits/mod.rs | 3 +- .../src/traits/normalize.rs | 4 +- .../src/traits/query/normalize.rs | 4 +- .../src/traits/select/mod.rs | 2 +- .../src/traits/specialize/mod.rs | 61 +----------------- compiler/rustc_traits/src/codegen.rs | 2 +- .../src/normalize_projection_ty.rs | 2 +- .../clippy/clippy_lints/src/eta_reduction.rs | 2 +- .../clippy_lints/src/future_not_send.rs | 2 +- .../src/unconditional_recursion.rs | 2 +- 55 files changed, 127 insertions(+), 123 deletions(-) create mode 100644 compiler/rustc_trait_selection/src/error_reporting/mod.rs rename compiler/rustc_trait_selection/src/{traits/error_reporting => error_reporting/traits}/ambiguity.rs (100%) rename compiler/rustc_trait_selection/src/{traits/error_reporting => error_reporting/traits}/infer_ctxt_ext.rs (100%) rename compiler/rustc_trait_selection/src/{traits/error_reporting => error_reporting/traits}/mod.rs (71%) rename compiler/rustc_trait_selection/src/{traits/error_reporting => error_reporting/traits}/on_unimplemented.rs (99%) rename compiler/rustc_trait_selection/src/{traits/error_reporting => error_reporting/traits}/suggestions.rs (99%) rename compiler/rustc_trait_selection/src/{traits/error_reporting => error_reporting/traits}/type_err_ctxt_ext.rs (99%) diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index c2c3f5bc79ed1..b1e302e5e27d3 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -34,9 +34,9 @@ use rustc_span::def_id::LocalDefId; use rustc_span::hygiene::DesugaringKind; use rustc_span::symbol::{kw, sym, Ident}; use rustc_span::{BytePos, Span, Symbol}; +use rustc_trait_selection::error_reporting::traits::suggestions::TypeErrCtxtExt; +use rustc_trait_selection::error_reporting::traits::FindExprBySpan; use rustc_trait_selection::infer::InferCtxtExt; -use rustc_trait_selection::traits::error_reporting::suggestions::TypeErrCtxtExt; -use rustc_trait_selection::traits::error_reporting::FindExprBySpan; use rustc_trait_selection::traits::{Obligation, ObligationCause, ObligationCtxt}; use std::iter; use std::ops::ControlFlow; diff --git a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs index 6165a718a3030..ffe52f939dd3b 100644 --- a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs +++ b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs @@ -17,7 +17,7 @@ use rustc_middle::ty::adjustment::PointerCoercion; use rustc_middle::ty::{self, RegionVid, Ty, TyCtxt}; use rustc_span::symbol::{kw, Symbol}; use rustc_span::{sym, DesugaringKind, Span}; -use rustc_trait_selection::traits::error_reporting::FindExprBySpan; +use rustc_trait_selection::error_reporting::traits::FindExprBySpan; use crate::region_infer::{BlameConstraint, ExtraConstraintInfo}; use crate::{ diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs index 4567a014fe83d..b7fbb71a0cfa5 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mod.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs @@ -27,8 +27,8 @@ use rustc_span::def_id::LocalDefId; use rustc_span::source_map::Spanned; use rustc_span::{symbol::sym, Span, Symbol, DUMMY_SP}; use rustc_target::abi::{FieldIdx, VariantIdx}; +use rustc_trait_selection::error_reporting::traits::suggestions::TypeErrCtxtExt as _; use rustc_trait_selection::infer::InferCtxtExt; -use rustc_trait_selection::traits::error_reporting::suggestions::TypeErrCtxtExt as _; use rustc_trait_selection::traits::{ type_known_to_meet_bound_modulo_regions, FulfillmentErrorCode, }; diff --git a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs index c817a80a541f7..4b6c1b29f285d 100644 --- a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs @@ -9,7 +9,7 @@ use rustc_middle::mir::*; use rustc_middle::ty::{self, Ty}; use rustc_mir_dataflow::move_paths::{LookupResult, MovePathIndex}; use rustc_span::{BytePos, ExpnKind, MacroKind, Span}; -use rustc_trait_selection::traits::error_reporting::FindExprBySpan; +use rustc_trait_selection::error_reporting::traits::FindExprBySpan; use crate::diagnostics::CapturedMessageOpt; use crate::diagnostics::{DescribePlaceOpt, UseSpans}; diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs index 677029f9d3f95..26b0d23b16642 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs @@ -16,9 +16,9 @@ use rustc_middle::{ use rustc_span::symbol::{kw, Symbol}; use rustc_span::{sym, BytePos, DesugaringKind, Span}; use rustc_target::abi::FieldIdx; +use rustc_trait_selection::error_reporting::traits::suggestions::TypeErrCtxtExt; use rustc_trait_selection::infer::InferCtxtExt; use rustc_trait_selection::traits; -use rustc_trait_selection::traits::error_reporting::suggestions::TypeErrCtxtExt; use crate::diagnostics::BorrowedContentSource; use crate::util::FindAssignments; diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs index e195ceded1bf3..c0e91ce32e37b 100644 --- a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs +++ b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs @@ -11,7 +11,7 @@ use rustc_middle::ty::visit::TypeVisitableExt; use rustc_middle::ty::{self, OpaqueHiddenType, OpaqueTypeKey, Ty, TyCtxt, TypeFoldable}; use rustc_middle::ty::{GenericArgKind, GenericArgs}; use rustc_span::Span; -use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt as _; +use rustc_trait_selection::error_reporting::traits::TypeErrCtxtExt as _; use rustc_trait_selection::traits::ObligationCtxt; use crate::session_diagnostics::LifetimeMismatchOpaqueParam; diff --git a/compiler/rustc_borrowck/src/type_check/free_region_relations.rs b/compiler/rustc_borrowck/src/type_check/free_region_relations.rs index 7553e3ee04fb4..431a704687d81 100644 --- a/compiler/rustc_borrowck/src/type_check/free_region_relations.rs +++ b/compiler/rustc_borrowck/src/type_check/free_region_relations.rs @@ -11,8 +11,8 @@ use rustc_middle::traits::query::OutlivesBound; use rustc_middle::traits::ObligationCause; use rustc_middle::ty::{self, RegionVid, Ty, TypeVisitableExt}; use rustc_span::{ErrorGuaranteed, Span}; +use rustc_trait_selection::error_reporting::traits::TypeErrCtxtExt; use rustc_trait_selection::solve::deeply_normalize; -use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt; use rustc_trait_selection::traits::query::type_op::{self, TypeOp}; use std::rc::Rc; use type_op::TypeOpOutput; diff --git a/compiler/rustc_const_eval/src/check_consts/check.rs b/compiler/rustc_const_eval/src/check_consts/check.rs index 412effba32dc6..523d55fe2d03d 100644 --- a/compiler/rustc_const_eval/src/check_consts/check.rs +++ b/compiler/rustc_const_eval/src/check_consts/check.rs @@ -13,7 +13,7 @@ use rustc_middle::ty::{self, adjustment::PointerCoercion, Ty, TyCtxt}; use rustc_middle::ty::{Instance, InstanceKind, TypeVisitableExt}; use rustc_mir_dataflow::Analysis; use rustc_span::{sym, Span, Symbol, DUMMY_SP}; -use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt as _; +use rustc_trait_selection::error_reporting::traits::TypeErrCtxtExt as _; use rustc_trait_selection::traits::{self, ObligationCauseCode, ObligationCtxt}; use rustc_type_ir::visit::{TypeSuperVisitable, TypeVisitor}; diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index f93777eda529e..bf8ef18c04fcc 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -25,9 +25,9 @@ use rustc_middle::ty::{ }; use rustc_session::lint::builtin::{UNINHABITED_STATIC, UNSUPPORTED_CALLING_CONVENTIONS}; use rustc_target::abi::FieldIdx; +use rustc_trait_selection::error_reporting::traits::on_unimplemented::OnUnimplementedDirective; +use rustc_trait_selection::error_reporting::traits::TypeErrCtxtExt as _; use rustc_trait_selection::traits; -use rustc_trait_selection::traits::error_reporting::on_unimplemented::OnUnimplementedDirective; -use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt as _; use rustc_trait_selection::traits::outlives_bounds::InferCtxtExt as _; use rustc_type_ir::fold::TypeFoldable; 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 8a1ee9374c3d6..6c53625b590ba 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -21,9 +21,9 @@ use rustc_middle::ty::{ use rustc_middle::ty::{GenericParamDefKind, TyCtxt}; use rustc_middle::{bug, span_bug}; use rustc_span::Span; +use rustc_trait_selection::error_reporting::traits::TypeErrCtxtExt; use rustc_trait_selection::infer::InferCtxtExt; use rustc_trait_selection::regions::InferCtxtRegionExt; -use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt; use rustc_trait_selection::traits::outlives_bounds::InferCtxtExt as _; use rustc_trait_selection::traits::{ self, FulfillmentError, ObligationCause, ObligationCauseCode, ObligationCtxt, Reveal, diff --git a/compiler/rustc_hir_analysis/src/check/entry.rs b/compiler/rustc_hir_analysis/src/check/entry.rs index cc52a7658020f..ce921f64481a3 100644 --- a/compiler/rustc_hir_analysis/src/check/entry.rs +++ b/compiler/rustc_hir_analysis/src/check/entry.rs @@ -7,7 +7,7 @@ use rustc_session::config::EntryFnType; use rustc_span::def_id::{DefId, LocalDefId, CRATE_DEF_ID}; use rustc_span::{symbol::sym, Span}; use rustc_target::spec::abi::Abi; -use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt as _; +use rustc_trait_selection::error_reporting::traits::TypeErrCtxtExt as _; use rustc_trait_selection::traits::{self, ObligationCause, ObligationCauseCode}; use std::ops::Not; diff --git a/compiler/rustc_hir_analysis/src/check/mod.rs b/compiler/rustc_hir_analysis/src/check/mod.rs index 8469cbbbc7d61..6a36938dd1d51 100644 --- a/compiler/rustc_hir_analysis/src/check/mod.rs +++ b/compiler/rustc_hir_analysis/src/check/mod.rs @@ -96,10 +96,10 @@ use rustc_span::symbol::{kw, sym, Ident}; use rustc_span::{def_id::CRATE_DEF_ID, BytePos, Span, Symbol, DUMMY_SP}; use rustc_target::abi::VariantIdx; use rustc_target::spec::abi::Abi; -use rustc_trait_selection::traits::error_reporting::suggestions::{ +use rustc_trait_selection::error_reporting::traits::suggestions::{ ReturnsVisitor, TypeErrCtxtExt as _, }; -use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt as _; +use rustc_trait_selection::error_reporting::traits::TypeErrCtxtExt as _; use rustc_trait_selection::traits::ObligationCtxt; use crate::errors; diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index a0eede31eb07f..b2ef07d65c5b4 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -29,8 +29,8 @@ use rustc_session::parse::feature_err; use rustc_span::symbol::{sym, Ident}; use rustc_span::{Span, DUMMY_SP}; use rustc_target::spec::abi::Abi; +use rustc_trait_selection::error_reporting::traits::TypeErrCtxtExt; use rustc_trait_selection::regions::InferCtxtRegionExt; -use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt; use rustc_trait_selection::traits::misc::{ type_allowed_to_implement_const_param_ty, ConstParamTyImplementationError, }; diff --git a/compiler/rustc_hir_analysis/src/coherence/builtin.rs b/compiler/rustc_hir_analysis/src/coherence/builtin.rs index 61adb7a3cbaeb..2ecb170ec8955 100644 --- a/compiler/rustc_hir_analysis/src/coherence/builtin.rs +++ b/compiler/rustc_hir_analysis/src/coherence/builtin.rs @@ -17,7 +17,7 @@ use rustc_middle::ty::adjustment::CoerceUnsizedInfo; use rustc_middle::ty::print::PrintTraitRefExt as _; use rustc_middle::ty::{self, suggest_constraining_type_params, Ty, TyCtxt, TypeVisitableExt}; use rustc_span::{Span, DUMMY_SP}; -use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt; +use rustc_trait_selection::error_reporting::traits::TypeErrCtxtExt; use rustc_trait_selection::traits::misc::{ type_allowed_to_implement_const_param_ty, type_allowed_to_implement_copy, ConstParamTyImplementationError, CopyImplementationError, InfringingFieldsReason, diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index 843e4d41e001e..b159f23a67ebd 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -35,8 +35,8 @@ use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::{Span, DUMMY_SP}; use rustc_target::abi::FieldIdx; use rustc_target::spec::abi; +use rustc_trait_selection::error_reporting::traits::suggestions::NextTypeParamName; use rustc_trait_selection::infer::InferCtxtExt; -use rustc_trait_selection::traits::error_reporting::suggestions::NextTypeParamName; use rustc_trait_selection::traits::ObligationCtxt; use std::cell::Cell; use std::iter; diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs index 2d240699105d6..e8bd7f2a5b223 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs @@ -4,7 +4,6 @@ use crate::errors::{ }; use crate::fluent_generated as fluent; use crate::hir_ty_lowering::HirTyLowerer; -use crate::traits::error_reporting::report_object_safety_error; use rustc_data_structures::fx::{FxIndexMap, FxIndexSet}; use rustc_data_structures::sorted_map::SortedMap; use rustc_data_structures::unord::UnordMap; @@ -27,6 +26,7 @@ use rustc_span::edit_distance::find_best_match_for_name; use rustc_span::symbol::{kw, sym, Ident}; use rustc_span::BytePos; use rustc_span::{Span, Symbol, DUMMY_SP}; +use rustc_trait_selection::error_reporting::traits::report_object_safety_error; use rustc_trait_selection::traits::FulfillmentError; use rustc_trait_selection::traits::{ object_safety_violations_for_assoc_item, TraitAliasExpansionInfo, diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs index 240a749de96a6..b7fa736ffcc6f 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs @@ -4,7 +4,7 @@ use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; use rustc_lint_defs::{builtin::BARE_TRAIT_OBJECTS, Applicability}; use rustc_span::Span; -use rustc_trait_selection::traits::error_reporting::suggestions::NextTypeParamName; +use rustc_trait_selection::error_reporting::traits::suggestions::NextTypeParamName; use super::HirTyLowerer; diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/object_safety.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/object_safety.rs index df69c1938dd75..8ef4740431c42 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/object_safety.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/object_safety.rs @@ -13,7 +13,7 @@ use rustc_middle::ty::fold::BottomUpFolder; use rustc_middle::ty::{self, ExistentialPredicateStableCmpExt as _, Ty, TyCtxt, TypeFoldable}; use rustc_middle::ty::{DynKind, Upcast}; use rustc_span::{ErrorGuaranteed, Span}; -use rustc_trait_selection::traits::error_reporting::report_object_safety_error; +use rustc_trait_selection::error_reporting::traits::report_object_safety_error; use rustc_trait_selection::traits::{self, hir_ty_lowering_object_safety_violations}; use smallvec::{smallvec, SmallVec}; diff --git a/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs b/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs index f3ce3ab66553e..5b8b6e981250d 100644 --- a/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs +++ b/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs @@ -78,7 +78,7 @@ use rustc_middle::ty::trait_def::TraitSpecializationKind; use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt}; use rustc_middle::ty::{GenericArg, GenericArgs, GenericArgsRef}; use rustc_span::{ErrorGuaranteed, Span}; -use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt; +use rustc_trait_selection::error_reporting::traits::TypeErrCtxtExt; use rustc_trait_selection::traits::outlives_bounds::InferCtxtExt as _; use rustc_trait_selection::traits::{self, translate_args_with_cause, wf, ObligationCtxt}; diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs index 3b199b7e3c26d..0d2a55a9507c2 100644 --- a/compiler/rustc_hir_typeck/src/callee.rs +++ b/compiler/rustc_hir_typeck/src/callee.rs @@ -24,8 +24,8 @@ use rustc_span::def_id::LocalDefId; use rustc_span::symbol::{sym, Ident}; use rustc_span::Span; use rustc_target::spec::abi; +use rustc_trait_selection::error_reporting::traits::DefIdOrName; use rustc_trait_selection::infer::InferCtxtExt as _; -use rustc_trait_selection::traits::error_reporting::DefIdOrName; use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _; use std::{iter, slice}; diff --git a/compiler/rustc_hir_typeck/src/closure.rs b/compiler/rustc_hir_typeck/src/closure.rs index ac7ed3e26f976..fef943fdab5e3 100644 --- a/compiler/rustc_hir_typeck/src/closure.rs +++ b/compiler/rustc_hir_typeck/src/closure.rs @@ -17,9 +17,9 @@ use rustc_middle::ty::{self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitor}; use rustc_span::def_id::LocalDefId; use rustc_span::Span; use rustc_target::spec::abi::Abi; +use rustc_trait_selection::error_reporting::traits::ArgKind; +use rustc_trait_selection::error_reporting::traits::InferCtxtExt as _; use rustc_trait_selection::traits; -use rustc_trait_selection::traits::error_reporting::ArgKind; -use rustc_trait_selection::traits::error_reporting::InferCtxtExt as _; use rustc_type_ir::ClosureKind; use std::iter; use std::ops::ControlFlow; diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs index 4f0a089ee956f..d1b99aae25b1d 100644 --- a/compiler/rustc_hir_typeck/src/coercion.rs +++ b/compiler/rustc_hir_typeck/src/coercion.rs @@ -58,9 +58,9 @@ use rustc_session::parse::feature_err; use rustc_span::symbol::sym; use rustc_span::{BytePos, DesugaringKind, Span, DUMMY_SP}; use rustc_target::spec::abi::Abi; +use rustc_trait_selection::error_reporting::traits::suggestions::TypeErrCtxtExt; +use rustc_trait_selection::error_reporting::traits::TypeErrCtxtExt as _; use rustc_trait_selection::infer::InferCtxtExt as _; -use rustc_trait_selection::traits::error_reporting::suggestions::TypeErrCtxtExt; -use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt as _; use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt; use rustc_trait_selection::traits::{ self, NormalizeExt, ObligationCause, ObligationCauseCode, ObligationCtxt, diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index bd5e5294983d2..432489330a667 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -53,9 +53,9 @@ use rustc_span::source_map::Spanned; use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::Span; use rustc_target::abi::{FieldIdx, FIRST_VARIANT}; +use rustc_trait_selection::error_reporting::traits::suggestions::TypeErrCtxtExt as _; +use rustc_trait_selection::error_reporting::traits::TypeErrCtxtExt; use rustc_trait_selection::infer::InferCtxtExt; -use rustc_trait_selection::traits::error_reporting::suggestions::TypeErrCtxtExt as _; -use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt; use rustc_trait_selection::traits::ObligationCtxt; use rustc_trait_selection::traits::{self, ObligationCauseCode}; diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index 5450243417f7f..e35130c66a22c 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -37,7 +37,7 @@ use rustc_span::hygiene::DesugaringKind; use rustc_span::symbol::{kw, sym}; use rustc_span::Span; use rustc_target::abi::FieldIdx; -use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt as _; +use rustc_trait_selection::error_reporting::traits::TypeErrCtxtExt as _; use rustc_trait_selection::traits::{ self, NormalizeExt, ObligationCauseCode, ObligationCtxt, StructurallyNormalizeExt, }; diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs index fca0a3e195d77..5f897c74482d6 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs @@ -32,10 +32,10 @@ use rustc_session::errors::ExprParenthesesNeeded; use rustc_span::source_map::Spanned; use rustc_span::symbol::{sym, Ident}; use rustc_span::{Span, Symbol}; +use rustc_trait_selection::error_reporting::traits::suggestions::TypeErrCtxtExt; +use rustc_trait_selection::error_reporting::traits::DefIdOrName; use rustc_trait_selection::infer::InferCtxtExt; use rustc_trait_selection::traits; -use rustc_trait_selection::traits::error_reporting::suggestions::TypeErrCtxtExt; -use rustc_trait_selection::traits::error_reporting::DefIdOrName; use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _; impl<'a, 'tcx> FnCtxt<'a, 'tcx> { diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index dba3edbc1d722..425289ce3c526 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -35,9 +35,9 @@ use rustc_span::def_id::DefIdSet; use rustc_span::symbol::{kw, sym, Ident}; use rustc_span::{edit_distance, ErrorGuaranteed, ExpnKind, FileName, MacroKind, Span}; use rustc_span::{Symbol, DUMMY_SP}; +use rustc_trait_selection::error_reporting::traits::on_unimplemented::OnUnimplementedNote; +use rustc_trait_selection::error_reporting::traits::on_unimplemented::TypeErrCtxtExt as _; use rustc_trait_selection::infer::InferCtxtExt; -use rustc_trait_selection::traits::error_reporting::on_unimplemented::OnUnimplementedNote; -use rustc_trait_selection::traits::error_reporting::on_unimplemented::TypeErrCtxtExt as _; use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _; use rustc_trait_selection::traits::{ supertraits, FulfillmentError, Obligation, ObligationCause, ObligationCauseCode, diff --git a/compiler/rustc_hir_typeck/src/op.rs b/compiler/rustc_hir_typeck/src/op.rs index 7264bc5a78d82..d59b8276d3ad4 100644 --- a/compiler/rustc_hir_typeck/src/op.rs +++ b/compiler/rustc_hir_typeck/src/op.rs @@ -18,8 +18,8 @@ use rustc_session::errors::ExprParenthesesNeeded; use rustc_span::source_map::Spanned; use rustc_span::symbol::{sym, Ident}; use rustc_span::Span; +use rustc_trait_selection::error_reporting::traits::suggestions::TypeErrCtxtExt as _; use rustc_trait_selection::infer::InferCtxtExt; -use rustc_trait_selection::traits::error_reporting::suggestions::TypeErrCtxtExt as _; use rustc_trait_selection::traits::{FulfillmentError, ObligationCtxt}; use rustc_type_ir::TyKind::*; diff --git a/compiler/rustc_hir_typeck/src/writeback.rs b/compiler/rustc_hir_typeck/src/writeback.rs index ceb7480686d90..e800c1a97d9eb 100644 --- a/compiler/rustc_hir_typeck/src/writeback.rs +++ b/compiler/rustc_hir_typeck/src/writeback.rs @@ -18,8 +18,8 @@ use rustc_middle::ty::TypeSuperFoldable; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_span::symbol::sym; use rustc_span::Span; +use rustc_trait_selection::error_reporting::traits::TypeErrCtxtExt; use rustc_trait_selection::solve; -use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt; use std::mem; diff --git a/compiler/rustc_lint/src/async_fn_in_trait.rs b/compiler/rustc_lint/src/async_fn_in_trait.rs index 40778542c75c9..6daee95dda6a2 100644 --- a/compiler/rustc_lint/src/async_fn_in_trait.rs +++ b/compiler/rustc_lint/src/async_fn_in_trait.rs @@ -3,7 +3,7 @@ use crate::LateContext; use crate::LateLintPass; use rustc_hir as hir; use rustc_session::{declare_lint, declare_lint_pass}; -use rustc_trait_selection::traits::error_reporting::suggestions::suggest_desugaring_async_fn_to_impl_future_in_trait; +use rustc_trait_selection::error_reporting::traits::suggestions::suggest_desugaring_async_fn_to_impl_future_in_trait; declare_lint! { /// The `async_fn_in_trait` lint detects use of `async fn` in the diff --git a/compiler/rustc_lint/src/non_local_def.rs b/compiler/rustc_lint/src/non_local_def.rs index 17429ed061f25..2f8eea6cd1816 100644 --- a/compiler/rustc_lint/src/non_local_def.rs +++ b/compiler/rustc_lint/src/non_local_def.rs @@ -11,10 +11,10 @@ use rustc_session::{declare_lint, impl_lint_pass}; use rustc_span::def_id::{DefId, LOCAL_CRATE}; use rustc_span::Span; use rustc_span::{sym, symbol::kw, ExpnKind, MacroKind, Symbol}; -use rustc_trait_selection::infer::TyCtxtInferExt; -use rustc_trait_selection::traits::error_reporting::ambiguity::{ +use rustc_trait_selection::error_reporting::traits::ambiguity::{ compute_applicable_impls_for_diagnostics, CandidateSource, }; +use rustc_trait_selection::infer::TyCtxtInferExt; use crate::fluent_generated as fluent; use crate::lints::{NonLocalDefinitionsCargoUpdateNote, NonLocalDefinitionsDiag}; diff --git a/compiler/rustc_mir_transform/src/coroutine.rs b/compiler/rustc_mir_transform/src/coroutine.rs index fa5da89e8ba56..261dcd52d710f 100644 --- a/compiler/rustc_mir_transform/src/coroutine.rs +++ b/compiler/rustc_mir_transform/src/coroutine.rs @@ -81,8 +81,8 @@ use rustc_span::symbol::sym; use rustc_span::Span; use rustc_target::abi::{FieldIdx, VariantIdx}; use rustc_target::spec::PanicStrategy; +use rustc_trait_selection::error_reporting::traits::TypeErrCtxtExt as _; use rustc_trait_selection::infer::TyCtxtInferExt as _; -use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt as _; use rustc_trait_selection::traits::ObligationCtxt; use rustc_trait_selection::traits::{ObligationCause, ObligationCauseCode}; use std::{iter, ops}; diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 0eb9d1ce59f1d..ce2fa83810fe8 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -34,8 +34,8 @@ use rustc_session::parse::feature_err; use rustc_span::symbol::{kw, sym, Symbol}; use rustc_span::{BytePos, Span, DUMMY_SP}; use rustc_target::spec::abi::Abi; +use rustc_trait_selection::error_reporting::traits::TypeErrCtxtExt; use rustc_trait_selection::infer::{TyCtxtInferExt, ValuePairs}; -use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt; use rustc_trait_selection::traits::ObligationCtxt; use std::cell::Cell; use std::collections::hash_map::Entry; diff --git a/compiler/rustc_passes/src/layout_test.rs b/compiler/rustc_passes/src/layout_test.rs index c9a4765045622..603e98cfa9222 100644 --- a/compiler/rustc_passes/src/layout_test.rs +++ b/compiler/rustc_passes/src/layout_test.rs @@ -8,7 +8,7 @@ use rustc_span::source_map::Spanned; use rustc_span::symbol::sym; use rustc_span::Span; use rustc_target::abi::{HasDataLayout, TargetDataLayout}; -use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt; +use rustc_trait_selection::error_reporting::traits::TypeErrCtxtExt; use rustc_trait_selection::{infer::TyCtxtInferExt, traits}; use crate::errors::{ diff --git a/compiler/rustc_trait_selection/src/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/error_reporting/mod.rs new file mode 100644 index 0000000000000..f6ac8fc7b614f --- /dev/null +++ b/compiler/rustc_trait_selection/src/error_reporting/mod.rs @@ -0,0 +1 @@ +pub mod traits; diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/ambiguity.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs similarity index 100% rename from compiler/rustc_trait_selection/src/traits/error_reporting/ambiguity.rs rename to compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/infer_ctxt_ext.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/infer_ctxt_ext.rs similarity index 100% rename from compiler/rustc_trait_selection/src/traits/error_reporting/infer_ctxt_ext.rs rename to compiler/rustc_trait_selection/src/error_reporting/traits/infer_ctxt_ext.rs diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs similarity index 71% rename from compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs rename to compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs index 633d488f7be5f..438b25056c338 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs @@ -6,10 +6,12 @@ pub mod on_unimplemented; pub mod suggestions; mod type_err_ctxt_ext; -use super::{Obligation, ObligationCause, ObligationCauseCode, PredicateObligation}; +use rustc_data_structures::fx::FxIndexSet; use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_hir::intravisit::Visitor; +use rustc_infer::traits::{Obligation, ObligationCause, ObligationCauseCode, PredicateObligation}; +use rustc_middle::ty::print::PrintTraitRefExt as _; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_span::Span; use std::ops::ControlFlow; @@ -180,3 +182,61 @@ pub enum DefIdOrName { DefId(DefId), Name(&'static str), } + +/// Recovers the "impl X for Y" signature from `impl_def_id` and returns it as a +/// string. +pub(crate) fn to_pretty_impl_header(tcx: TyCtxt<'_>, impl_def_id: DefId) -> Option { + use std::fmt::Write; + + let trait_ref = tcx.impl_trait_ref(impl_def_id)?.instantiate_identity(); + let mut w = "impl".to_owned(); + + let args = ty::GenericArgs::identity_for_item(tcx, impl_def_id); + + // FIXME: Currently only handles ?Sized. + // Needs to support ?Move and ?DynSized when they are implemented. + let mut types_without_default_bounds = FxIndexSet::default(); + let sized_trait = tcx.lang_items().sized_trait(); + + let arg_names = args.iter().map(|k| k.to_string()).filter(|k| k != "'_").collect::>(); + if !arg_names.is_empty() { + types_without_default_bounds.extend(args.types()); + w.push('<'); + w.push_str(&arg_names.join(", ")); + w.push('>'); + } + + write!( + w, + " {} for {}", + trait_ref.print_only_trait_path(), + tcx.type_of(impl_def_id).instantiate_identity() + ) + .unwrap(); + + // The predicates will contain default bounds like `T: Sized`. We need to + // remove these bounds, and add `T: ?Sized` to any untouched type parameters. + let predicates = tcx.predicates_of(impl_def_id).predicates; + let mut pretty_predicates = + Vec::with_capacity(predicates.len() + types_without_default_bounds.len()); + + for (p, _) in predicates { + if let Some(poly_trait_ref) = p.as_trait_clause() { + if Some(poly_trait_ref.def_id()) == sized_trait { + // FIXME(#120456) - is `swap_remove` correct? + types_without_default_bounds.swap_remove(&poly_trait_ref.self_ty().skip_binder()); + continue; + } + } + pretty_predicates.push(p.to_string()); + } + + pretty_predicates.extend(types_without_default_bounds.iter().map(|ty| format!("{ty}: ?Sized"))); + + if !pretty_predicates.is_empty() { + write!(w, "\n where {}", pretty_predicates.join(", ")).unwrap(); + } + + w.push(';'); + Some(w) +} diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs similarity index 99% rename from compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs rename to compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs index 94b28426f43b6..83c6798ba2ed1 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs @@ -1,10 +1,10 @@ use super::{ObligationCauseCode, PredicateObligation}; +use crate::error_reporting::traits::type_err_ctxt_ext::InferCtxtPrivExt; use crate::errors::{ EmptyOnClauseInOnUnimplemented, InvalidOnClauseInOnUnimplemented, NoValueInOnUnimplemented, }; use crate::infer::error_reporting::TypeErrCtxt; use crate::infer::InferCtxtExt; -use crate::traits::error_reporting::type_err_ctxt_ext::InferCtxtPrivExt; use rustc_ast::AttrArgs; use rustc_ast::AttrArgsEq; use rustc_ast::AttrKind; diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs similarity index 99% rename from compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs rename to compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs index 52edffce61459..fdc6db4abec0b 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs @@ -44,8 +44,8 @@ use std::assert_matches::debug_assert_matches; use std::borrow::Cow; use std::iter; +use crate::error_reporting::traits::type_err_ctxt_ext::InferCtxtPrivExt; use crate::infer::InferCtxtExt as _; -use crate::traits::error_reporting::type_err_ctxt_ext::InferCtxtPrivExt; use crate::traits::query::evaluate_obligation::InferCtxtExt as _; use rustc_middle::ty::print::{ with_forced_trimmed_paths, with_no_trimmed_paths, PrintPolyTraitPredicateExt as _, diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/type_err_ctxt_ext.rs similarity index 99% rename from compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs rename to compiler/rustc_trait_selection/src/error_reporting/traits/type_err_ctxt_ext.rs index 5461f9e65affe..7843a95d9667e 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/type_err_ctxt_ext.rs @@ -2,16 +2,16 @@ use super::on_unimplemented::{AppendConstMessage, OnUnimplementedNote, TypeErrCtxtExt as _}; use super::suggestions::{get_explanation_based_on_obligation, TypeErrCtxtExt as _}; +use crate::error_reporting::traits::infer_ctxt_ext::InferCtxtExt; +use crate::error_reporting::traits::to_pretty_impl_header; +use crate::error_reporting::traits::{ambiguity, ambiguity::CandidateSource::*}; use crate::errors::{ AsyncClosureNotFn, ClosureFnMutLabel, ClosureFnOnceLabel, ClosureKindMismatch, }; use crate::infer::error_reporting::{TyCategory, TypeAnnotationNeeded as ErrorCode}; use crate::infer::InferCtxtExt as _; use crate::infer::{self, InferCtxt}; -use crate::traits::error_reporting::infer_ctxt_ext::InferCtxtExt; -use crate::traits::error_reporting::{ambiguity, ambiguity::CandidateSource::*}; use crate::traits::query::evaluate_obligation::InferCtxtExt as _; -use crate::traits::specialize::to_pretty_impl_header; use crate::traits::NormalizeExt; use crate::traits::{ elaborate, FulfillmentError, FulfillmentErrorCode, MismatchedProjectionTypes, Obligation, diff --git a/compiler/rustc_trait_selection/src/lib.rs b/compiler/rustc_trait_selection/src/lib.rs index 37008baca2899..d0a12d73941d9 100644 --- a/compiler/rustc_trait_selection/src/lib.rs +++ b/compiler/rustc_trait_selection/src/lib.rs @@ -33,6 +33,7 @@ #[macro_use] extern crate tracing; +pub mod error_reporting; pub mod errors; pub mod infer; pub mod regions; diff --git a/compiler/rustc_trait_selection/src/solve/normalize.rs b/compiler/rustc_trait_selection/src/solve/normalize.rs index 2679da942b763..bda2137fa7368 100644 --- a/compiler/rustc_trait_selection/src/solve/normalize.rs +++ b/compiler/rustc_trait_selection/src/solve/normalize.rs @@ -1,7 +1,7 @@ use std::fmt::Debug; use std::marker::PhantomData; -use crate::traits::error_reporting::{OverflowCause, TypeErrCtxtExt}; +use crate::error_reporting::traits::{OverflowCause, TypeErrCtxtExt}; use crate::traits::query::evaluate_obligation::InferCtxtExt; use crate::traits::{BoundVarReplacer, PlaceholderReplacer, ScrubbedTraitError}; use rustc_data_structures::stack::ensure_sufficient_stack; diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs index fc390bf318dc1..7e996c5c5ef6e 100644 --- a/compiler/rustc_trait_selection/src/traits/coherence.rs +++ b/compiler/rustc_trait_selection/src/traits/coherence.rs @@ -30,8 +30,8 @@ use rustc_span::symbol::sym; use rustc_span::{Span, DUMMY_SP}; use std::fmt::Debug; -use super::error_reporting::suggest_new_overflow_limit; use super::ObligationCtxt; +use crate::error_reporting::traits::suggest_new_overflow_limit; pub struct OverlapResult<'tcx> { pub impl_header: ty::ImplHeader<'tcx>, diff --git a/compiler/rustc_trait_selection/src/traits/engine.rs b/compiler/rustc_trait_selection/src/traits/engine.rs index 811f61d2bf37f..bdc27e734f97e 100644 --- a/compiler/rustc_trait_selection/src/traits/engine.rs +++ b/compiler/rustc_trait_selection/src/traits/engine.rs @@ -3,10 +3,10 @@ use std::fmt::Debug; use super::{FromSolverError, TraitEngine}; use super::{FulfillmentContext, ScrubbedTraitError}; +use crate::error_reporting::traits::TypeErrCtxtExt; use crate::regions::InferCtxtRegionExt; use crate::solve::FulfillmentCtxt as NextFulfillmentCtxt; use crate::solve::NextSolverError; -use crate::traits::error_reporting::TypeErrCtxtExt; use crate::traits::fulfill::OldSolverError; use crate::traits::NormalizeExt; use crate::traits::StructurallyNormalizeExt; diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs index bce5c7101cc54..6f7e69798ee92 100644 --- a/compiler/rustc_trait_selection/src/traits/fulfill.rs +++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs @@ -1,5 +1,5 @@ +use crate::error_reporting::traits::TypeErrCtxtExt; use crate::infer::{InferCtxt, TyOrConstInferVar}; -use crate::traits::error_reporting::TypeErrCtxtExt; use crate::traits::normalize::normalize_with_depth_to; use rustc_data_structures::captures::Captures; use rustc_data_structures::obligation_forest::ProcessResult; diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index 662d95db8ba5c..703ff2f7f1698 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -6,7 +6,6 @@ pub mod auto_trait; pub(crate) mod coherence; pub mod const_evaluatable; mod engine; -pub mod error_reporting; mod fulfill; pub mod misc; pub mod normalize; @@ -24,10 +23,10 @@ mod util; pub mod vtable; pub mod wf; +use crate::error_reporting::traits::TypeErrCtxtExt as _; use crate::infer::outlives::env::OutlivesEnvironment; use crate::infer::{InferCtxt, TyCtxtInferExt}; use crate::regions::InferCtxtRegionExt; -use crate::traits::error_reporting::TypeErrCtxtExt as _; use crate::traits::query::evaluate_obligation::InferCtxtExt as _; use rustc_errors::ErrorGuaranteed; use rustc_middle::query::Providers; diff --git a/compiler/rustc_trait_selection/src/traits/normalize.rs b/compiler/rustc_trait_selection/src/traits/normalize.rs index a9ac0f7eb25bb..a34fd80446785 100644 --- a/compiler/rustc_trait_selection/src/traits/normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/normalize.rs @@ -1,9 +1,9 @@ //! Deeply normalize types using the old trait solver. -use super::error_reporting::OverflowCause; -use super::error_reporting::TypeErrCtxtExt; use super::SelectionContext; use super::{project, with_replaced_escaping_bound_vars, BoundVarReplacer, PlaceholderReplacer}; +use crate::error_reporting::traits::OverflowCause; +use crate::error_reporting::traits::TypeErrCtxtExt; use crate::solve::NextSolverError; use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_infer::infer::at::At; diff --git a/compiler/rustc_trait_selection/src/traits/query/normalize.rs b/compiler/rustc_trait_selection/src/traits/query/normalize.rs index bed76b84ee075..da4e4fef3cf78 100644 --- a/compiler/rustc_trait_selection/src/traits/query/normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/query/normalize.rs @@ -2,11 +2,11 @@ //! which folds deeply, invoking the underlying //! `normalize_canonicalized_projection_ty` query when it encounters projections. +use crate::error_reporting::traits::OverflowCause; +use crate::error_reporting::traits::TypeErrCtxtExt; use crate::infer::at::At; use crate::infer::canonical::OriginalQueryValues; use crate::infer::{InferCtxt, InferOk}; -use crate::traits::error_reporting::OverflowCause; -use crate::traits::error_reporting::TypeErrCtxtExt; use crate::traits::normalize::needs_normalization; use crate::traits::Normalized; use crate::traits::{BoundVarReplacer, PlaceholderReplacer, ScrubbedTraitError}; diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index cc082ad98aa99..1e55b2d015003 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -18,9 +18,9 @@ use super::{ TraitQueryMode, }; +use crate::error_reporting::traits::TypeErrCtxtExt; use crate::infer::{InferCtxt, InferCtxtExt, InferOk, TypeFreshener}; use crate::solve::InferCtxtSelectExt as _; -use crate::traits::error_reporting::TypeErrCtxtExt; use crate::traits::normalize::normalize_with_depth; use crate::traits::normalize::normalize_with_depth_to; use crate::traits::project::ProjectAndUnifyResult; diff --git a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs index c9bb0d330e1fd..6a904ef487eae 100644 --- a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs @@ -14,6 +14,7 @@ use rustc_infer::infer::DefineOpaqueTypes; use rustc_middle::ty::print::PrintTraitRefExt as _; use specialization_graph::GraphExt; +use crate::error_reporting::traits::to_pretty_impl_header; use crate::errors::NegativePositiveConflict; use crate::infer::{InferCtxt, InferOk, TyCtxtInferExt}; use crate::traits::select::IntercrateAmbiguityCause; @@ -25,8 +26,8 @@ use rustc_errors::{codes::*, Diag, EmissionGuarantee}; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_middle::bug; use rustc_middle::query::LocalCrate; +use rustc_middle::ty::GenericArgsRef; use rustc_middle::ty::{self, ImplSubject, Ty, TyCtxt, TypeVisitableExt}; -use rustc_middle::ty::{GenericArgs, GenericArgsRef}; use rustc_session::lint::builtin::COHERENCE_LEAK_CHECK; use rustc_session::lint::builtin::ORDER_DEPENDENT_TRAIT_OBJECTS; use rustc_span::{sym, ErrorGuaranteed, Span, DUMMY_SP}; @@ -485,61 +486,3 @@ fn report_conflicting_impls<'tcx>( } } } - -/// Recovers the "impl X for Y" signature from `impl_def_id` and returns it as a -/// string. -pub(crate) fn to_pretty_impl_header(tcx: TyCtxt<'_>, impl_def_id: DefId) -> Option { - use std::fmt::Write; - - let trait_ref = tcx.impl_trait_ref(impl_def_id)?.instantiate_identity(); - let mut w = "impl".to_owned(); - - let args = GenericArgs::identity_for_item(tcx, impl_def_id); - - // FIXME: Currently only handles ?Sized. - // Needs to support ?Move and ?DynSized when they are implemented. - let mut types_without_default_bounds = FxIndexSet::default(); - let sized_trait = tcx.lang_items().sized_trait(); - - let arg_names = args.iter().map(|k| k.to_string()).filter(|k| k != "'_").collect::>(); - if !arg_names.is_empty() { - types_without_default_bounds.extend(args.types()); - w.push('<'); - w.push_str(&arg_names.join(", ")); - w.push('>'); - } - - write!( - w, - " {} for {}", - trait_ref.print_only_trait_path(), - tcx.type_of(impl_def_id).instantiate_identity() - ) - .unwrap(); - - // The predicates will contain default bounds like `T: Sized`. We need to - // remove these bounds, and add `T: ?Sized` to any untouched type parameters. - let predicates = tcx.predicates_of(impl_def_id).predicates; - let mut pretty_predicates = - Vec::with_capacity(predicates.len() + types_without_default_bounds.len()); - - for (p, _) in predicates { - if let Some(poly_trait_ref) = p.as_trait_clause() { - if Some(poly_trait_ref.def_id()) == sized_trait { - // FIXME(#120456) - is `swap_remove` correct? - types_without_default_bounds.swap_remove(&poly_trait_ref.self_ty().skip_binder()); - continue; - } - } - pretty_predicates.push(p.to_string()); - } - - pretty_predicates.extend(types_without_default_bounds.iter().map(|ty| format!("{ty}: ?Sized"))); - - if !pretty_predicates.is_empty() { - write!(w, "\n where {}", pretty_predicates.join(", ")).unwrap(); - } - - w.push(';'); - Some(w) -} diff --git a/compiler/rustc_traits/src/codegen.rs b/compiler/rustc_traits/src/codegen.rs index c73ececd1d150..51ac7b2c7ac1b 100644 --- a/compiler/rustc_traits/src/codegen.rs +++ b/compiler/rustc_traits/src/codegen.rs @@ -7,7 +7,7 @@ use rustc_infer::infer::TyCtxtInferExt; use rustc_middle::bug; use rustc_middle::traits::CodegenObligationError; use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt}; -use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt; +use rustc_trait_selection::error_reporting::traits::TypeErrCtxtExt; use rustc_trait_selection::traits::{ ImplSource, Obligation, ObligationCause, ObligationCtxt, ScrubbedTraitError, SelectionContext, Unimplemented, diff --git a/compiler/rustc_traits/src/normalize_projection_ty.rs b/compiler/rustc_traits/src/normalize_projection_ty.rs index 0430e0bb70eb3..85d84983d28fa 100644 --- a/compiler/rustc_traits/src/normalize_projection_ty.rs +++ b/compiler/rustc_traits/src/normalize_projection_ty.rs @@ -2,8 +2,8 @@ use rustc_infer::infer::canonical::{Canonical, QueryResponse}; use rustc_infer::infer::TyCtxtInferExt; use rustc_middle::query::Providers; use rustc_middle::ty::{ParamEnvAnd, TyCtxt}; +use rustc_trait_selection::error_reporting::traits::TypeErrCtxtExt; use rustc_trait_selection::infer::InferCtxtBuilderExt; -use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt; use rustc_trait_selection::traits::query::{ normalize::NormalizationResult, CanonicalAliasGoal, NoSolution, }; diff --git a/src/tools/clippy/clippy_lints/src/eta_reduction.rs b/src/tools/clippy/clippy_lints/src/eta_reduction.rs index 42ec2c00823c8..d2a34c7558321 100644 --- a/src/tools/clippy/clippy_lints/src/eta_reduction.rs +++ b/src/tools/clippy/clippy_lints/src/eta_reduction.rs @@ -15,7 +15,7 @@ use rustc_middle::ty::{ use rustc_session::declare_lint_pass; use rustc_span::symbol::sym; use rustc_target::spec::abi::Abi; -use rustc_trait_selection::traits::error_reporting::InferCtxtExt as _; +use rustc_trait_selection::error_reporting::traits::InferCtxtExt as _; declare_clippy_lint! { /// ### What it does diff --git a/src/tools/clippy/clippy_lints/src/future_not_send.rs b/src/tools/clippy/clippy_lints/src/future_not_send.rs index cb1d0de1edff9..1fd8faf3ea883 100644 --- a/src/tools/clippy/clippy_lints/src/future_not_send.rs +++ b/src/tools/clippy/clippy_lints/src/future_not_send.rs @@ -9,7 +9,7 @@ use rustc_middle::ty::{self, AliasTy, ClauseKind, PredicateKind}; use rustc_session::declare_lint_pass; use rustc_span::def_id::LocalDefId; use rustc_span::{sym, Span}; -use rustc_trait_selection::traits::error_reporting::suggestions::TypeErrCtxtExt; +use rustc_trait_selection::error_reporting::traits::suggestions::TypeErrCtxtExt; use rustc_trait_selection::traits::{self, FulfillmentError, ObligationCtxt}; declare_clippy_lint! { diff --git a/src/tools/clippy/clippy_lints/src/unconditional_recursion.rs b/src/tools/clippy/clippy_lints/src/unconditional_recursion.rs index 5e41b3f4914ff..6ba98a92423c7 100644 --- a/src/tools/clippy/clippy_lints/src/unconditional_recursion.rs +++ b/src/tools/clippy/clippy_lints/src/unconditional_recursion.rs @@ -15,7 +15,7 @@ use rustc_middle::ty::{self, AssocKind, Ty, TyCtxt}; use rustc_session::impl_lint_pass; use rustc_span::symbol::{kw, Ident}; use rustc_span::{sym, Span}; -use rustc_trait_selection::traits::error_reporting::suggestions::ReturnsVisitor; +use rustc_trait_selection::error_reporting::traits::suggestions::ReturnsVisitor; declare_clippy_lint! { /// ### What it does From 321eba5e8fb56d7823b7feb0986528a7488eb10c Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Mon, 8 Jul 2024 18:02:14 -0400 Subject: [PATCH 841/892] Update f16/f128 FIXMEs that needed (NEG_)INFINITY --- .../half-open-range-pats-semantics.rs | 42 ++++++++----------- .../half-open-range-pats-thir-lower-empty.rs | 8 +++- ...lf-open-range-pats-thir-lower-empty.stderr | 40 +++++++++++------- 3 files changed, 51 insertions(+), 39 deletions(-) diff --git a/tests/ui/half-open-range-patterns/half-open-range-pats-semantics.rs b/tests/ui/half-open-range-patterns/half-open-range-pats-semantics.rs index 38ade060cb135..a89b229251287 100644 --- a/tests/ui/half-open-range-patterns/half-open-range-pats-semantics.rs +++ b/tests/ui/half-open-range-patterns/half-open-range-pats-semantics.rs @@ -45,9 +45,8 @@ fn range_to_inclusive() { // FIXME(f16_f128): remove gate when ABI issues are resolved #[cfg(all(target_arch = "aarch64", target_os = "linux"))] { - // FIXME(f16_f128): enable infinity tests when constants are available - // assert!(yes!(f16::NEG_INFINITY, ..=f16::NEG_INFINITY)); - // assert!(yes!(f16::NEG_INFINITY, ..=1.0f16)); + assert!(yes!(f16::NEG_INFINITY, ..=f16::NEG_INFINITY)); + assert!(yes!(f16::NEG_INFINITY, ..=1.0f16)); assert!(yes!(1.5f16, ..=1.5f16)); assert!(!yes!(1.6f16, ..=-1.5f16)); } @@ -68,9 +67,8 @@ fn range_to_inclusive() { // FIXME(f16_f128): remove gate when ABI issues are resolved #[cfg(all(target_arch = "aarch64", target_os = "linux"))] { - // FIXME(f16_f128): enable infinity tests when constants are available - // assert!(yes!(f128::NEG_INFINITY, ..=f128::NEG_INFINITY)); - // assert!(yes!(f128::NEG_INFINITY, ..=1.0f128)); + assert!(yes!(f128::NEG_INFINITY, ..=f128::NEG_INFINITY)); + assert!(yes!(f128::NEG_INFINITY, ..=1.0f128)); assert!(yes!(1.5f128, ..=1.5f128)); assert!(!yes!(1.6f128, ..=-1.5f128)); } @@ -111,8 +109,7 @@ fn range_to() { // FIXME(f16_f128): remove gate when ABI issues are resolved #[cfg(all(target_arch = "aarch64", target_os = "linux"))] { - // FIXME(f16_f128): enable infinity tests when constants are available - // assert!(yes!(f16::NEG_INFINITY, ..1.0f16)); + assert!(yes!(f16::NEG_INFINITY, ..1.0f16)); assert!(!yes!(1.5f16, ..1.5f16)); const E16: f16 = 1.5f16 + f16::EPSILON; assert!(yes!(1.5f16, ..E16)); @@ -137,8 +134,7 @@ fn range_to() { // FIXME(f16_f128): remove gate when ABI issues are resolved #[cfg(all(target_arch = "aarch64", target_os = "linux"))] { - // FIXME(f16_f128): enable infinity tests when constants are available - // assert!(yes!(f128::NEG_INFINITY, ..1.0f128)); + assert!(yes!(f128::NEG_INFINITY, ..1.0f128)); assert!(!yes!(1.5f128, ..1.5f128)); const E128: f128 = 1.5f128 + f128::EPSILON; assert!(yes!(1.5f128, ..E128)); @@ -181,15 +177,14 @@ fn range_from() { // FIXME(f16_f128): remove gate when ABI issues are resolved #[cfg(all(target_arch = "aarch64", target_os = "linux"))] { - // FIXME(f16_f128): enable infinity tests when constants are available - // assert!(yes!(f16::NEG_INFINITY, f16::NEG_INFINITY..)); - // assert!(yes!(f16::INFINITY, f16::NEG_INFINITY..)); - // assert!(!yes!(f16::NEG_INFINITY, 1.0f16..)); - // assert!(yes!(f16::INFINITY, 1.0f16..)); + assert!(yes!(f16::NEG_INFINITY, f16::NEG_INFINITY..)); + assert!(yes!(f16::INFINITY, f16::NEG_INFINITY..)); + assert!(!yes!(f16::NEG_INFINITY, 1.0f16..)); + assert!(yes!(f16::INFINITY, 1.0f16..)); assert!(!yes!(1.0f16 - f16::EPSILON, 1.0f16..)); assert!(yes!(1.0f16, 1.0f16..)); - // assert!(yes!(f16::INFINITY, 1.0f16..)); - // assert!(yes!(f16::INFINITY, f16::INFINITY..)); + assert!(yes!(f16::INFINITY, 1.0f16..)); + assert!(yes!(f16::INFINITY, f16::INFINITY..)); } // f32; `X..` @@ -216,15 +211,14 @@ fn range_from() { // FIXME(f16_f128): remove gate when ABI issues are resolved #[cfg(all(target_arch = "aarch64", target_os = "linux"))] { - // FIXME(f16_f128): enable infinity tests when constants are available - // assert!(yes!(f128::NEG_INFINITY, f128::NEG_INFINITY..)); - // assert!(yes!(f128::INFINITY, f128::NEG_INFINITY..)); - // assert!(!yes!(f128::NEG_INFINITY, 1.0f128..)); - // assert!(yes!(f128::INFINITY, 1.0f128..)); + assert!(yes!(f128::NEG_INFINITY, f128::NEG_INFINITY..)); + assert!(yes!(f128::INFINITY, f128::NEG_INFINITY..)); + assert!(!yes!(f128::NEG_INFINITY, 1.0f128..)); + assert!(yes!(f128::INFINITY, 1.0f128..)); assert!(!yes!(1.0f128 - f128::EPSILON, 1.0f128..)); assert!(yes!(1.0f128, 1.0f128..)); - // assert!(yes!(f128::INFINITY, 1.0f128..)); - // assert!(yes!(f128::INFINITY, f128::INFINITY..)); + assert!(yes!(f128::INFINITY, 1.0f128..)); + assert!(yes!(f128::INFINITY, f128::INFINITY..)); } } diff --git a/tests/ui/half-open-range-patterns/half-open-range-pats-thir-lower-empty.rs b/tests/ui/half-open-range-patterns/half-open-range-pats-thir-lower-empty.rs index a35bb51acbca3..6a0115de01605 100644 --- a/tests/ui/half-open-range-patterns/half-open-range-pats-thir-lower-empty.rs +++ b/tests/ui/half-open-range-patterns/half-open-range-pats-thir-lower-empty.rs @@ -1,3 +1,6 @@ +#![feature(f128)] +#![feature(f16)] + macro_rules! m { ($s:expr, $($t:tt)+) => { match $s { $($t)+ => {} } @@ -27,11 +30,14 @@ fn main() { m!(0, ..i128::MIN); //~^ ERROR lower range bound must be less than upper - // FIXME(f16_f128): add tests when NEG_INFINITY is available + m!(0f16, ..f16::NEG_INFINITY); + //~^ ERROR lower range bound must be less than upper m!(0f32, ..f32::NEG_INFINITY); //~^ ERROR lower range bound must be less than upper m!(0f64, ..f64::NEG_INFINITY); //~^ ERROR lower range bound must be less than upper + m!(0f128, ..f128::NEG_INFINITY); + //~^ ERROR lower range bound must be less than upper m!('a', ..'\u{0}'); //~^ ERROR lower range bound must be less than upper diff --git a/tests/ui/half-open-range-patterns/half-open-range-pats-thir-lower-empty.stderr b/tests/ui/half-open-range-patterns/half-open-range-pats-thir-lower-empty.stderr index fb2f1841a6dfc..f414a6bfd1830 100644 --- a/tests/ui/half-open-range-patterns/half-open-range-pats-thir-lower-empty.stderr +++ b/tests/ui/half-open-range-patterns/half-open-range-pats-thir-lower-empty.stderr @@ -1,81 +1,93 @@ error[E0579]: lower range bound must be less than upper - --> $DIR/half-open-range-pats-thir-lower-empty.rs:8:11 + --> $DIR/half-open-range-pats-thir-lower-empty.rs:11:11 | LL | m!(0, ..u8::MIN); | ^^^^^^^^^ error[E0579]: lower range bound must be less than upper - --> $DIR/half-open-range-pats-thir-lower-empty.rs:10:11 + --> $DIR/half-open-range-pats-thir-lower-empty.rs:13:11 | LL | m!(0, ..u16::MIN); | ^^^^^^^^^^ error[E0579]: lower range bound must be less than upper - --> $DIR/half-open-range-pats-thir-lower-empty.rs:12:11 + --> $DIR/half-open-range-pats-thir-lower-empty.rs:15:11 | LL | m!(0, ..u32::MIN); | ^^^^^^^^^^ error[E0579]: lower range bound must be less than upper - --> $DIR/half-open-range-pats-thir-lower-empty.rs:14:11 + --> $DIR/half-open-range-pats-thir-lower-empty.rs:17:11 | LL | m!(0, ..u64::MIN); | ^^^^^^^^^^ error[E0579]: lower range bound must be less than upper - --> $DIR/half-open-range-pats-thir-lower-empty.rs:16:11 + --> $DIR/half-open-range-pats-thir-lower-empty.rs:19:11 | LL | m!(0, ..u128::MIN); | ^^^^^^^^^^^ error[E0579]: lower range bound must be less than upper - --> $DIR/half-open-range-pats-thir-lower-empty.rs:19:11 + --> $DIR/half-open-range-pats-thir-lower-empty.rs:22:11 | LL | m!(0, ..i8::MIN); | ^^^^^^^^^ error[E0579]: lower range bound must be less than upper - --> $DIR/half-open-range-pats-thir-lower-empty.rs:21:11 + --> $DIR/half-open-range-pats-thir-lower-empty.rs:24:11 | LL | m!(0, ..i16::MIN); | ^^^^^^^^^^ error[E0579]: lower range bound must be less than upper - --> $DIR/half-open-range-pats-thir-lower-empty.rs:23:11 + --> $DIR/half-open-range-pats-thir-lower-empty.rs:26:11 | LL | m!(0, ..i32::MIN); | ^^^^^^^^^^ error[E0579]: lower range bound must be less than upper - --> $DIR/half-open-range-pats-thir-lower-empty.rs:25:11 + --> $DIR/half-open-range-pats-thir-lower-empty.rs:28:11 | LL | m!(0, ..i64::MIN); | ^^^^^^^^^^ error[E0579]: lower range bound must be less than upper - --> $DIR/half-open-range-pats-thir-lower-empty.rs:27:11 + --> $DIR/half-open-range-pats-thir-lower-empty.rs:30:11 | LL | m!(0, ..i128::MIN); | ^^^^^^^^^^^ error[E0579]: lower range bound must be less than upper - --> $DIR/half-open-range-pats-thir-lower-empty.rs:31:14 + --> $DIR/half-open-range-pats-thir-lower-empty.rs:33:14 + | +LL | m!(0f16, ..f16::NEG_INFINITY); + | ^^^^^^^^^^^^^^^^^^^ + +error[E0579]: lower range bound must be less than upper + --> $DIR/half-open-range-pats-thir-lower-empty.rs:35:14 | LL | m!(0f32, ..f32::NEG_INFINITY); | ^^^^^^^^^^^^^^^^^^^ error[E0579]: lower range bound must be less than upper - --> $DIR/half-open-range-pats-thir-lower-empty.rs:33:14 + --> $DIR/half-open-range-pats-thir-lower-empty.rs:37:14 | LL | m!(0f64, ..f64::NEG_INFINITY); | ^^^^^^^^^^^^^^^^^^^ error[E0579]: lower range bound must be less than upper - --> $DIR/half-open-range-pats-thir-lower-empty.rs:36:13 + --> $DIR/half-open-range-pats-thir-lower-empty.rs:39:15 + | +LL | m!(0f128, ..f128::NEG_INFINITY); + | ^^^^^^^^^^^^^^^^^^^^ + +error[E0579]: lower range bound must be less than upper + --> $DIR/half-open-range-pats-thir-lower-empty.rs:42:13 | LL | m!('a', ..'\u{0}'); | ^^^^^^^^^ -error: aborting due to 13 previous errors +error: aborting due to 15 previous errors For more information about this error, try `rustc --explain E0579`. From ec662e7606c9d03de536bbf46dbdeb0d6140bc85 Mon Sep 17 00:00:00 2001 From: Lieselotte <52315535+she3py@users.noreply.github.com> Date: Mon, 8 Jul 2024 23:12:31 +0200 Subject: [PATCH 842/892] `#[doc(alias)]`'s doc: say that ASCII spaces are allowed --- src/doc/rustdoc/src/advanced-features.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/doc/rustdoc/src/advanced-features.md b/src/doc/rustdoc/src/advanced-features.md index 1733c8fc9a246..4a1c091625320 100644 --- a/src/doc/rustdoc/src/advanced-features.md +++ b/src/doc/rustdoc/src/advanced-features.md @@ -80,7 +80,8 @@ pub struct BigX; Then, when looking for it through the `rustdoc` search, if you enter "x" or "big", search will show the `BigX` struct first. -There are some limitations on the doc alias names though: you can't use `"` or whitespace. +There are some limitations on the doc alias names though: they cannot contain quotes (`'`, `"`) +or most whitespace. ASCII space is allowed if it does not start or end the alias. You can add multiple aliases at the same time by using a list: From 96a791662aa30320fa05c84535667d1ed58e42da Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Mon, 8 Jul 2024 18:04:01 -0400 Subject: [PATCH 843/892] Update a f16/f128 FIXME to be more accurate --- compiler/rustc_lint/src/types.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs index f3a904022e9ed..c0364b3571642 100644 --- a/compiler/rustc_lint/src/types.rs +++ b/compiler/rustc_lint/src/types.rs @@ -563,7 +563,8 @@ fn lint_literal<'tcx>( ty::Float(t) => { let is_infinite = match lit.node { ast::LitKind::Float(v, _) => match t { - // FIXME(f16_f128): add this check once we have library support + // FIXME(f16_f128): add this check once `is_infinite` is reliable (ABI + // issues resolved). ty::FloatTy::F16 => Ok(false), ty::FloatTy::F32 => v.as_str().parse().map(f32::is_infinite), ty::FloatTy::F64 => v.as_str().parse().map(f64::is_infinite), From 9a92526b98ed5c0e3b5faad5b0809936170ba818 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 8 Jul 2024 20:35:26 -0400 Subject: [PATCH 844/892] Consolidate region error reporting in rustc_infer --- .../src/diagnostics/region_errors.rs | 12 +- .../src/infer/error_reporting/mod.rs | 851 +---------- .../src/infer/error_reporting/note.rs | 421 ------ .../src/infer/error_reporting/region.rs | 1259 +++++++++++++++++ 4 files changed, 1273 insertions(+), 1270 deletions(-) delete mode 100644 compiler/rustc_infer/src/infer/error_reporting/note.rs create mode 100644 compiler/rustc_infer/src/infer/error_reporting/region.rs diff --git a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs index 13839214adc05..55147ee337fde 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs @@ -10,14 +10,12 @@ use rustc_hir::GenericBound::Trait; use rustc_hir::QPath::Resolved; use rustc_hir::WherePredicate::BoundPredicate; use rustc_hir::{PolyTraitRef, TyKind, WhereBoundPredicate}; -use rustc_infer::infer::{ - error_reporting::nice_region_error::{ - self, find_anon_type, find_param_with_region, suggest_adding_lifetime_params, - HirTraitObjectVisitor, NiceRegionError, TraitObjectVisitor, - }, - error_reporting::unexpected_hidden_region_diagnostic, - NllRegionVariableOrigin, RelateParamBound, +use rustc_infer::infer::error_reporting::nice_region_error::{ + self, find_anon_type, find_param_with_region, suggest_adding_lifetime_params, + HirTraitObjectVisitor, NiceRegionError, TraitObjectVisitor, }; +use rustc_infer::infer::error_reporting::region::unexpected_hidden_region_diagnostic; +use rustc_infer::infer::{NllRegionVariableOrigin, RelateParamBound}; use rustc_middle::bug; use rustc_middle::hir::place::PlaceBase; use rustc_middle::mir::{ConstraintCategory, ReturnConstraint}; diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index cebb9d09a4798..bb1285ee8135d 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -45,13 +45,10 @@ //! ported to this system, and which relies on string concatenation at the //! time of error detection. -use super::lexical_region_resolve::RegionResolutionError; -use super::region_constraints::GenericKind; -use super::{InferCtxt, RegionVariableOrigin, SubregionOrigin, TypeTrace, ValuePairs}; +use super::{InferCtxt, TypeTrace, ValuePairs}; -use crate::errors::{self, ObligationCauseFailureCode, TypeErrorAdditionalDiags}; +use crate::errors::{ObligationCauseFailureCode, TypeErrorAdditionalDiags}; use crate::infer; -use crate::infer::error_reporting::nice_region_error::find_anon_type::find_anon_type; use crate::infer::ExpectedFound; use crate::traits::{ IfExpressionCause, MatchExpressionArmCause, ObligationCause, ObligationCauseCode, @@ -61,38 +58,36 @@ use crate::traits::{ use crate::infer::relate::{self, RelateResult, TypeRelation}; use rustc_data_structures::fx::{FxIndexMap, FxIndexSet}; use rustc_errors::{ - codes::*, pluralize, struct_span_code_err, Applicability, Diag, DiagCtxtHandle, - DiagStyledString, ErrorGuaranteed, IntoDiagArg, StringPart, + pluralize, Applicability, Diag, DiagCtxtHandle, DiagStyledString, IntoDiagArg, StringPart, }; use rustc_hir::def::DefKind; -use rustc_hir::def_id::{DefId, LocalDefId}; +use rustc_hir::def_id::DefId; use rustc_hir::intravisit::Visitor; use rustc_hir::lang_items::LangItem; -use rustc_hir::{self as hir, ParamName}; +use rustc_hir::{self as hir}; use rustc_macros::extension; use rustc_middle::bug; use rustc_middle::dep_graph::DepContext; use rustc_middle::ty::error::TypeErrorToStringExt; use rustc_middle::ty::print::{with_forced_trimmed_paths, PrintError, PrintTraitRefExt as _}; -use rustc_middle::ty::Upcast; use rustc_middle::ty::{ - self, error::TypeError, IsSuggestable, List, Region, Ty, TyCtxt, TypeFoldable, - TypeSuperVisitable, TypeVisitable, TypeVisitableExt, + self, error::TypeError, List, Region, Ty, TyCtxt, TypeFoldable, TypeSuperVisitable, + TypeVisitable, TypeVisitableExt, }; -use rustc_span::{sym, symbol::kw, BytePos, DesugaringKind, Pos, Span}; +use rustc_span::{sym, BytePos, DesugaringKind, Pos, Span}; use rustc_target::spec::abi; use std::borrow::Cow; use std::ops::{ControlFlow, Deref}; use std::path::PathBuf; use std::{cmp, fmt, iter}; -mod note; mod note_and_explain; mod suggest; pub(crate) mod need_type_info; pub mod sub_relations; pub use need_type_info::TypeAnnotationNeeded; +pub mod region; pub mod nice_region_error; @@ -159,245 +154,6 @@ impl<'tcx> Deref for TypeErrCtxt<'_, 'tcx> { } } -pub(super) fn note_and_explain_region<'tcx>( - tcx: TyCtxt<'tcx>, - err: &mut Diag<'_>, - generic_param_scope: LocalDefId, - prefix: &str, - region: ty::Region<'tcx>, - suffix: &str, - alt_span: Option, -) { - let (description, span) = match *region { - ty::ReEarlyParam(_) | ty::ReLateParam(_) | ty::RePlaceholder(_) | ty::ReStatic => { - msg_span_from_named_region(tcx, generic_param_scope, region, alt_span) - } - - ty::ReError(_) => return, - - // FIXME(#125431): `ReVar` shouldn't reach here. - ty::ReVar(_) => (format!("lifetime `{region}`"), alt_span), - - ty::ReBound(..) | ty::ReErased => { - bug!("unexpected region for note_and_explain_region: {:?}", region); - } - }; - - emit_msg_span(err, prefix, description, span, suffix); -} - -fn explain_free_region<'tcx>( - tcx: TyCtxt<'tcx>, - err: &mut Diag<'_>, - generic_param_scope: LocalDefId, - prefix: &str, - region: ty::Region<'tcx>, - suffix: &str, -) { - let (description, span) = msg_span_from_named_region(tcx, generic_param_scope, region, None); - - label_msg_span(err, prefix, description, span, suffix); -} - -fn msg_span_from_named_region<'tcx>( - tcx: TyCtxt<'tcx>, - generic_param_scope: LocalDefId, - region: ty::Region<'tcx>, - alt_span: Option, -) -> (String, Option) { - match *region { - ty::ReEarlyParam(br) => { - let scope = tcx - .parent(tcx.generics_of(generic_param_scope).region_param(br, tcx).def_id) - .expect_local(); - let span = if let Some(param) = - tcx.hir().get_generics(scope).and_then(|generics| generics.get_named(br.name)) - { - param.span - } else { - tcx.def_span(scope) - }; - let text = if br.has_name() { - format!("the lifetime `{}` as defined here", br.name) - } else { - "the anonymous lifetime as defined here".to_string() - }; - (text, Some(span)) - } - ty::ReLateParam(ref fr) => { - if !fr.bound_region.is_named() - && let Some((ty, _)) = - find_anon_type(tcx, generic_param_scope, region, &fr.bound_region) - { - ("the anonymous lifetime defined here".to_string(), Some(ty.span)) - } else { - match fr.bound_region { - ty::BoundRegionKind::BrNamed(_, name) => { - let span = if let Some(param) = tcx - .hir() - .get_generics(generic_param_scope) - .and_then(|generics| generics.get_named(name)) - { - param.span - } else { - tcx.def_span(generic_param_scope) - }; - let text = if name == kw::UnderscoreLifetime { - "the anonymous lifetime as defined here".to_string() - } else { - format!("the lifetime `{name}` as defined here") - }; - (text, Some(span)) - } - ty::BrAnon => ( - "the anonymous lifetime as defined here".to_string(), - Some(tcx.def_span(generic_param_scope)), - ), - _ => ( - format!("the lifetime `{region}` as defined here"), - Some(tcx.def_span(generic_param_scope)), - ), - } - } - } - ty::ReStatic => ("the static lifetime".to_owned(), alt_span), - ty::RePlaceholder(ty::PlaceholderRegion { - bound: ty::BoundRegion { kind: ty::BoundRegionKind::BrNamed(def_id, name), .. }, - .. - }) => (format!("the lifetime `{name}` as defined here"), Some(tcx.def_span(def_id))), - ty::RePlaceholder(ty::PlaceholderRegion { - bound: ty::BoundRegion { kind: ty::BoundRegionKind::BrAnon, .. }, - .. - }) => ("an anonymous lifetime".to_owned(), None), - _ => bug!("{:?}", region), - } -} - -fn emit_msg_span( - err: &mut Diag<'_>, - prefix: &str, - description: String, - span: Option, - suffix: &str, -) { - let message = format!("{prefix}{description}{suffix}"); - - if let Some(span) = span { - err.span_note(span, message); - } else { - err.note(message); - } -} - -fn label_msg_span( - err: &mut Diag<'_>, - prefix: &str, - description: String, - span: Option, - suffix: &str, -) { - let message = format!("{prefix}{description}{suffix}"); - - if let Some(span) = span { - err.span_label(span, message); - } else { - err.note(message); - } -} - -#[instrument(level = "trace", skip(infcx))] -pub fn unexpected_hidden_region_diagnostic<'a, 'tcx>( - infcx: &'a InferCtxt<'tcx>, - generic_param_scope: LocalDefId, - span: Span, - hidden_ty: Ty<'tcx>, - hidden_region: ty::Region<'tcx>, - opaque_ty_key: ty::OpaqueTypeKey<'tcx>, -) -> Diag<'a> { - let tcx = infcx.tcx; - let mut err = infcx.dcx().create_err(errors::OpaqueCapturesLifetime { - span, - opaque_ty: Ty::new_opaque(tcx, opaque_ty_key.def_id.to_def_id(), opaque_ty_key.args), - opaque_ty_span: tcx.def_span(opaque_ty_key.def_id), - }); - - // Explain the region we are capturing. - match *hidden_region { - ty::ReEarlyParam(_) | ty::ReLateParam(_) | ty::ReStatic => { - // Assuming regionck succeeded (*), we ought to always be - // capturing *some* region from the fn header, and hence it - // ought to be free. So under normal circumstances, we will go - // down this path which gives a decent human readable - // explanation. - // - // (*) if not, the `tainted_by_errors` field would be set to - // `Some(ErrorGuaranteed)` in any case, so we wouldn't be here at all. - explain_free_region( - tcx, - &mut err, - generic_param_scope, - &format!("hidden type `{hidden_ty}` captures "), - hidden_region, - "", - ); - if let Some(reg_info) = tcx.is_suitable_region(generic_param_scope, hidden_region) { - let fn_returns = tcx.return_type_impl_or_dyn_traits(reg_info.def_id); - nice_region_error::suggest_new_region_bound( - tcx, - &mut err, - fn_returns, - hidden_region.to_string(), - None, - format!("captures `{hidden_region}`"), - None, - Some(reg_info.def_id), - ) - } - } - ty::RePlaceholder(_) => { - explain_free_region( - tcx, - &mut err, - generic_param_scope, - &format!("hidden type `{}` captures ", hidden_ty), - hidden_region, - "", - ); - } - ty::ReError(_) => { - err.downgrade_to_delayed_bug(); - } - _ => { - // Ugh. This is a painful case: the hidden region is not one - // that we can easily summarize or explain. This can happen - // in a case like - // `tests/ui/multiple-lifetimes/ordinary-bounds-unsuited.rs`: - // - // ``` - // fn upper_bounds<'a, 'b>(a: Ordinary<'a>, b: Ordinary<'b>) -> impl Trait<'a, 'b> { - // if condition() { a } else { b } - // } - // ``` - // - // Here the captured lifetime is the intersection of `'a` and - // `'b`, which we can't quite express. - - // We can at least report a really cryptic error for now. - note_and_explain_region( - tcx, - &mut err, - generic_param_scope, - &format!("hidden type `{hidden_ty}` captures "), - hidden_region, - "", - None, - ); - } - } - - err -} - impl<'tcx> InferCtxt<'tcx> { pub fn get_impl_future_output_ty(&self, ty: Ty<'tcx>) -> Option> { let (def_id, args) = match *ty.kind() { @@ -438,193 +194,6 @@ impl<'tcx> InferCtxt<'tcx> { } impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { - pub fn report_region_errors( - &self, - generic_param_scope: LocalDefId, - errors: &[RegionResolutionError<'tcx>], - ) -> ErrorGuaranteed { - assert!(!errors.is_empty()); - - if let Some(guaranteed) = self.infcx.tainted_by_errors() { - return guaranteed; - } - - debug!("report_region_errors(): {} errors to start", errors.len()); - - // try to pre-process the errors, which will group some of them - // together into a `ProcessedErrors` group: - let errors = self.process_errors(errors); - - debug!("report_region_errors: {} errors after preprocessing", errors.len()); - - let mut guar = None; - for error in errors { - debug!("report_region_errors: error = {:?}", error); - - let e = if let Some(guar) = - self.try_report_nice_region_error(generic_param_scope, &error) - { - guar - } else { - match error.clone() { - // These errors could indicate all manner of different - // problems with many different solutions. Rather - // than generate a "one size fits all" error, what we - // attempt to do is go through a number of specific - // scenarios and try to find the best way to present - // the error. If all of these fails, we fall back to a rather - // general bit of code that displays the error information - RegionResolutionError::ConcreteFailure(origin, sub, sup) => { - if sub.is_placeholder() || sup.is_placeholder() { - self.report_placeholder_failure(generic_param_scope, origin, sub, sup) - .emit() - } else { - self.report_concrete_failure(generic_param_scope, origin, sub, sup) - .emit() - } - } - - RegionResolutionError::GenericBoundFailure(origin, param_ty, sub) => self - .report_generic_bound_failure( - generic_param_scope, - origin.span(), - Some(origin), - param_ty, - sub, - ), - - RegionResolutionError::SubSupConflict( - _, - var_origin, - sub_origin, - sub_r, - sup_origin, - sup_r, - _, - ) => { - if sub_r.is_placeholder() { - self.report_placeholder_failure( - generic_param_scope, - sub_origin, - sub_r, - sup_r, - ) - .emit() - } else if sup_r.is_placeholder() { - self.report_placeholder_failure( - generic_param_scope, - sup_origin, - sub_r, - sup_r, - ) - .emit() - } else { - self.report_sub_sup_conflict( - generic_param_scope, - var_origin, - sub_origin, - sub_r, - sup_origin, - sup_r, - ) - } - } - - RegionResolutionError::UpperBoundUniverseConflict( - _, - _, - _, - sup_origin, - sup_r, - ) => { - assert!(sup_r.is_placeholder()); - - // Make a dummy value for the "sub region" -- - // this is the initial value of the - // placeholder. In practice, we expect more - // tailored errors that don't really use this - // value. - let sub_r = self.tcx.lifetimes.re_erased; - - self.report_placeholder_failure( - generic_param_scope, - sup_origin, - sub_r, - sup_r, - ) - .emit() - } - - RegionResolutionError::CannotNormalize(clause, origin) => { - let clause: ty::Clause<'tcx> = - clause.map_bound(ty::ClauseKind::TypeOutlives).upcast(self.tcx); - self.tcx - .dcx() - .struct_span_err(origin.span(), format!("cannot normalize `{clause}`")) - .emit() - } - } - }; - - guar = Some(e) - } - - guar.unwrap() - } - - // This method goes through all the errors and try to group certain types - // of error together, for the purpose of suggesting explicit lifetime - // parameters to the user. This is done so that we can have a more - // complete view of what lifetimes should be the same. - // If the return value is an empty vector, it means that processing - // failed (so the return value of this method should not be used). - // - // The method also attempts to weed out messages that seem like - // duplicates that will be unhelpful to the end-user. But - // obviously it never weeds out ALL errors. - fn process_errors( - &self, - errors: &[RegionResolutionError<'tcx>], - ) -> Vec> { - debug!("process_errors()"); - - // We want to avoid reporting generic-bound failures if we can - // avoid it: these have a very high rate of being unhelpful in - // practice. This is because they are basically secondary - // checks that test the state of the region graph after the - // rest of inference is done, and the other kinds of errors - // indicate that the region constraint graph is internally - // inconsistent, so these test results are likely to be - // meaningless. - // - // Therefore, we filter them out of the list unless they are - // the only thing in the list. - - let is_bound_failure = |e: &RegionResolutionError<'tcx>| match *e { - RegionResolutionError::GenericBoundFailure(..) => true, - RegionResolutionError::ConcreteFailure(..) - | RegionResolutionError::SubSupConflict(..) - | RegionResolutionError::UpperBoundUniverseConflict(..) - | RegionResolutionError::CannotNormalize(..) => false, - }; - - let mut errors = if errors.iter().all(|e| is_bound_failure(e)) { - errors.to_owned() - } else { - errors.iter().filter(|&e| !is_bound_failure(e)).cloned().collect() - }; - - // sort the errors by span, for better error message stability. - errors.sort_by_key(|u| match *u { - RegionResolutionError::ConcreteFailure(ref sro, _, _) => sro.span(), - RegionResolutionError::GenericBoundFailure(ref sro, _, _) => sro.span(), - RegionResolutionError::SubSupConflict(_, ref rvo, _, _, _, _, _) => rvo.span(), - RegionResolutionError::UpperBoundUniverseConflict(_, ref rvo, _, _, _) => rvo.span(), - RegionResolutionError::CannotNormalize(_, ref sro) => sro.span(), - }); - errors - } - /// Adds a note if the types come from similarly named crates fn check_and_note_conflicting_crates(&self, err: &mut Diag<'_>, terr: TypeError<'tcx>) { use hir::def_id::CrateNum; @@ -2341,359 +1910,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { )) } - pub fn report_generic_bound_failure( - &self, - generic_param_scope: LocalDefId, - span: Span, - origin: Option>, - bound_kind: GenericKind<'tcx>, - sub: Region<'tcx>, - ) -> ErrorGuaranteed { - self.construct_generic_bound_failure(generic_param_scope, span, origin, bound_kind, sub) - .emit() - } - - pub fn construct_generic_bound_failure( - &self, - generic_param_scope: LocalDefId, - span: Span, - origin: Option>, - bound_kind: GenericKind<'tcx>, - sub: Region<'tcx>, - ) -> Diag<'a> { - if let Some(SubregionOrigin::CompareImplItemObligation { - span, - impl_item_def_id, - trait_item_def_id, - }) = origin - { - return self.infcx.report_extra_impl_obligation( - span, - impl_item_def_id, - trait_item_def_id, - &format!("`{bound_kind}: {sub}`"), - ); - } - - let labeled_user_string = match bound_kind { - GenericKind::Param(ref p) => format!("the parameter type `{p}`"), - GenericKind::Placeholder(ref p) => format!("the placeholder type `{p:?}`"), - GenericKind::Alias(ref p) => match p.kind(self.tcx) { - ty::Projection | ty::Inherent => { - format!("the associated type `{p}`") - } - ty::Weak => format!("the type alias `{p}`"), - ty::Opaque => format!("the opaque type `{p}`"), - }, - }; - - let mut err = self - .tcx - .dcx() - .struct_span_err(span, format!("{labeled_user_string} may not live long enough")); - err.code(match sub.kind() { - ty::ReEarlyParam(_) | ty::ReLateParam(_) if sub.has_name() => E0309, - ty::ReStatic => E0310, - _ => E0311, - }); - - '_explain: { - let (description, span) = match sub.kind() { - ty::ReEarlyParam(_) | ty::ReLateParam(_) | ty::ReStatic => { - msg_span_from_named_region(self.tcx, generic_param_scope, sub, Some(span)) - } - _ => (format!("lifetime `{sub}`"), Some(span)), - }; - let prefix = format!("{labeled_user_string} must be valid for "); - label_msg_span(&mut err, &prefix, description, span, "..."); - if let Some(origin) = origin { - self.note_region_origin(&mut err, &origin); - } - } - - 'suggestion: { - let msg = "consider adding an explicit lifetime bound"; - - if (bound_kind, sub).has_infer_regions() - || (bound_kind, sub).has_placeholders() - || !bound_kind.is_suggestable(self.tcx, false) - { - let lt_name = sub.get_name_or_anon().to_string(); - err.help(format!("{msg} `{bound_kind}: {lt_name}`...")); - break 'suggestion; - } - - let mut generic_param_scope = generic_param_scope; - while self.tcx.def_kind(generic_param_scope) == DefKind::OpaqueTy { - generic_param_scope = self.tcx.local_parent(generic_param_scope); - } - - // type_param_sugg_span is (span, has_bounds, needs_parentheses) - let (type_scope, type_param_sugg_span) = match bound_kind { - GenericKind::Param(param) => { - let generics = self.tcx.generics_of(generic_param_scope); - let type_param = generics.type_param(param, self.tcx); - let def_id = type_param.def_id.expect_local(); - let scope = self.tcx.local_def_id_to_hir_id(def_id).owner.def_id; - // Get the `hir::Param` to verify whether it already has any bounds. - // We do this to avoid suggesting code that ends up as `T: 'a'b`, - // instead we suggest `T: 'a + 'b` in that case. - let hir_generics = self.tcx.hir().get_generics(scope).unwrap(); - let sugg_span = match hir_generics.bounds_span_for_suggestions(def_id) { - Some((span, open_paren_sp)) => Some((span, true, open_paren_sp)), - // If `param` corresponds to `Self`, no usable suggestion span. - None if generics.has_self && param.index == 0 => None, - None => { - let span = if let Some(param) = - hir_generics.params.iter().find(|param| param.def_id == def_id) - && let ParamName::Plain(ident) = param.name - { - ident.span.shrink_to_hi() - } else { - let span = self.tcx.def_span(def_id); - span.shrink_to_hi() - }; - Some((span, false, None)) - } - }; - (scope, sugg_span) - } - _ => (generic_param_scope, None), - }; - let suggestion_scope = { - let lifetime_scope = match sub.kind() { - ty::ReStatic => hir::def_id::CRATE_DEF_ID, - _ => match self.tcx.is_suitable_region(generic_param_scope, sub) { - Some(info) => info.def_id, - None => generic_param_scope, - }, - }; - match self.tcx.is_descendant_of(type_scope.into(), lifetime_scope.into()) { - true => type_scope, - false => lifetime_scope, - } - }; - - let mut suggs = vec![]; - let lt_name = self.suggest_name_region(generic_param_scope, sub, &mut suggs); - - if let Some((sp, has_lifetimes, open_paren_sp)) = type_param_sugg_span - && suggestion_scope == type_scope - { - let suggestion = - if has_lifetimes { format!(" + {lt_name}") } else { format!(": {lt_name}") }; - - if let Some(open_paren_sp) = open_paren_sp { - suggs.push((open_paren_sp, "(".to_string())); - suggs.push((sp, format!("){suggestion}"))); - } else { - suggs.push((sp, suggestion)) - } - } else if let GenericKind::Alias(ref p) = bound_kind - && let ty::Projection = p.kind(self.tcx) - && let DefKind::AssocTy = self.tcx.def_kind(p.def_id) - && let Some(ty::ImplTraitInTraitData::Trait { .. }) = - self.tcx.opt_rpitit_info(p.def_id) - { - // The lifetime found in the `impl` is longer than the one on the RPITIT. - // Do not suggest `::{opaque}: 'static`. - } else if let Some(generics) = self.tcx.hir().get_generics(suggestion_scope) { - let pred = format!("{bound_kind}: {lt_name}"); - let suggestion = format!("{} {}", generics.add_where_or_trailing_comma(), pred); - suggs.push((generics.tail_span_for_predicate_suggestion(), suggestion)) - } else { - let consider = format!("{msg} `{bound_kind}: {sub}`..."); - err.help(consider); - } - - if !suggs.is_empty() { - err.multipart_suggestion_verbose( - msg, - suggs, - Applicability::MaybeIncorrect, // Issue #41966 - ); - } - } - - err - } - - pub fn suggest_name_region( - &self, - generic_param_scope: LocalDefId, - lifetime: Region<'tcx>, - add_lt_suggs: &mut Vec<(Span, String)>, - ) -> String { - struct LifetimeReplaceVisitor<'tcx, 'a> { - tcx: TyCtxt<'tcx>, - needle: hir::LifetimeName, - new_lt: &'a str, - add_lt_suggs: &'a mut Vec<(Span, String)>, - } - - impl<'hir, 'tcx> hir::intravisit::Visitor<'hir> for LifetimeReplaceVisitor<'tcx, '_> { - fn visit_lifetime(&mut self, lt: &'hir hir::Lifetime) { - if lt.res == self.needle { - let (pos, span) = lt.suggestion_position(); - let new_lt = &self.new_lt; - let sugg = match pos { - hir::LifetimeSuggestionPosition::Normal => format!("{new_lt}"), - hir::LifetimeSuggestionPosition::Ampersand => format!("{new_lt} "), - hir::LifetimeSuggestionPosition::ElidedPath => format!("<{new_lt}>"), - hir::LifetimeSuggestionPosition::ElidedPathArgument => { - format!("{new_lt}, ") - } - hir::LifetimeSuggestionPosition::ObjectDefault => format!("+ {new_lt}"), - }; - self.add_lt_suggs.push((span, sugg)); - } - } - - fn visit_ty(&mut self, ty: &'hir hir::Ty<'hir>) { - let hir::TyKind::OpaqueDef(item_id, _, _) = ty.kind else { - return hir::intravisit::walk_ty(self, ty); - }; - let opaque_ty = self.tcx.hir().item(item_id).expect_opaque_ty(); - if let Some(&(_, b)) = - opaque_ty.lifetime_mapping.iter().find(|&(a, _)| a.res == self.needle) - { - let prev_needle = - std::mem::replace(&mut self.needle, hir::LifetimeName::Param(b)); - for bound in opaque_ty.bounds { - self.visit_param_bound(bound); - } - self.needle = prev_needle; - } - } - } - - let (lifetime_def_id, lifetime_scope) = - match self.tcx.is_suitable_region(generic_param_scope, lifetime) { - Some(info) if !lifetime.has_name() => { - (info.bound_region.get_id().unwrap().expect_local(), info.def_id) - } - _ => return lifetime.get_name_or_anon().to_string(), - }; - - let new_lt = { - let generics = self.tcx.generics_of(lifetime_scope); - let mut used_names = - iter::successors(Some(generics), |g| g.parent.map(|p| self.tcx.generics_of(p))) - .flat_map(|g| &g.own_params) - .filter(|p| matches!(p.kind, ty::GenericParamDefKind::Lifetime)) - .map(|p| p.name) - .collect::>(); - let hir_id = self.tcx.local_def_id_to_hir_id(lifetime_scope); - // consider late-bound lifetimes ... - used_names.extend(self.tcx.late_bound_vars(hir_id).into_iter().filter_map( - |p| match p { - ty::BoundVariableKind::Region(lt) => lt.get_name(), - _ => None, - }, - )); - (b'a'..=b'z') - .map(|c| format!("'{}", c as char)) - .find(|candidate| !used_names.iter().any(|e| e.as_str() == candidate)) - .unwrap_or("'lt".to_string()) - }; - - let mut visitor = LifetimeReplaceVisitor { - tcx: self.tcx, - needle: hir::LifetimeName::Param(lifetime_def_id), - add_lt_suggs, - new_lt: &new_lt, - }; - match self.tcx.expect_hir_owner_node(lifetime_scope) { - hir::OwnerNode::Item(i) => visitor.visit_item(i), - hir::OwnerNode::ForeignItem(i) => visitor.visit_foreign_item(i), - hir::OwnerNode::ImplItem(i) => visitor.visit_impl_item(i), - hir::OwnerNode::TraitItem(i) => visitor.visit_trait_item(i), - hir::OwnerNode::Crate(_) => bug!("OwnerNode::Crate doesn't not have generics"), - hir::OwnerNode::Synthetic => unreachable!(), - } - - let ast_generics = self.tcx.hir().get_generics(lifetime_scope).unwrap(); - let sugg = ast_generics - .span_for_lifetime_suggestion() - .map(|span| (span, format!("{new_lt}, "))) - .unwrap_or_else(|| (ast_generics.span, format!("<{new_lt}>"))); - add_lt_suggs.push(sugg); - - new_lt - } - - fn report_sub_sup_conflict( - &self, - generic_param_scope: LocalDefId, - var_origin: RegionVariableOrigin, - sub_origin: SubregionOrigin<'tcx>, - sub_region: Region<'tcx>, - sup_origin: SubregionOrigin<'tcx>, - sup_region: Region<'tcx>, - ) -> ErrorGuaranteed { - let mut err = self.report_inference_failure(var_origin); - - note_and_explain_region( - self.tcx, - &mut err, - generic_param_scope, - "first, the lifetime cannot outlive ", - sup_region, - "...", - None, - ); - - debug!("report_sub_sup_conflict: var_origin={:?}", var_origin); - debug!("report_sub_sup_conflict: sub_region={:?}", sub_region); - debug!("report_sub_sup_conflict: sub_origin={:?}", sub_origin); - debug!("report_sub_sup_conflict: sup_region={:?}", sup_region); - debug!("report_sub_sup_conflict: sup_origin={:?}", sup_origin); - - if let infer::Subtype(ref sup_trace) = sup_origin - && let infer::Subtype(ref sub_trace) = sub_origin - && let Some((sup_expected, sup_found, _)) = self.values_str(sup_trace.values) - && let Some((sub_expected, sub_found, _)) = self.values_str(sub_trace.values) - && sub_expected == sup_expected - && sub_found == sup_found - { - note_and_explain_region( - self.tcx, - &mut err, - generic_param_scope, - "...but the lifetime must also be valid for ", - sub_region, - "...", - None, - ); - err.span_note( - sup_trace.cause.span, - format!("...so that the {}", sup_trace.cause.as_requirement_str()), - ); - - err.note_expected_found(&"", sup_expected, &"", sup_found); - return if sub_region.is_error() | sup_region.is_error() { - err.delay_as_bug() - } else { - err.emit() - }; - } - - self.note_region_origin(&mut err, &sup_origin); - - note_and_explain_region( - self.tcx, - &mut err, - generic_param_scope, - "but, the lifetime must be valid for ", - sub_region, - "...", - None, - ); - - self.note_region_origin(&mut err, &sub_origin); - if sub_region.is_error() | sup_region.is_error() { err.delay_as_bug() } else { err.emit() } - } - /// Determine whether an error associated with the given span and definition /// should be treated as being caused by the implicit `From` conversion /// within `?` desugaring. @@ -2792,55 +2008,6 @@ impl<'tcx> TypeRelation> for SameTypeModuloInfer<'_, 'tcx> { } } -impl<'tcx> InferCtxt<'tcx> { - fn report_inference_failure(&self, var_origin: RegionVariableOrigin) -> Diag<'_> { - let br_string = |br: ty::BoundRegionKind| { - let mut s = match br { - ty::BrNamed(_, name) => name.to_string(), - _ => String::new(), - }; - if !s.is_empty() { - s.push(' '); - } - s - }; - let var_description = match var_origin { - infer::MiscVariable(_) => String::new(), - infer::PatternRegion(_) => " for pattern".to_string(), - infer::AddrOfRegion(_) => " for borrow expression".to_string(), - infer::Autoref(_) => " for autoref".to_string(), - infer::Coercion(_) => " for automatic coercion".to_string(), - infer::BoundRegion(_, br, infer::FnCall) => { - format!(" for lifetime parameter {}in function call", br_string(br)) - } - infer::BoundRegion(_, br, infer::HigherRankedType) => { - format!(" for lifetime parameter {}in generic type", br_string(br)) - } - infer::BoundRegion(_, br, infer::AssocTypeProjection(def_id)) => format!( - " for lifetime parameter {}in trait containing associated type `{}`", - br_string(br), - self.tcx.associated_item(def_id).name - ), - infer::RegionParameterDefinition(_, name) => { - format!(" for lifetime parameter `{name}`") - } - infer::UpvarRegion(ref upvar_id, _) => { - let var_name = self.tcx.hir().name(upvar_id.var_path.hir_id); - format!(" for capture of `{var_name}` by closure") - } - infer::Nll(..) => bug!("NLL variable found in lexical phase"), - }; - - struct_span_code_err!( - self.dcx(), - var_origin.span(), - E0495, - "cannot infer an appropriate lifetime{} due to conflicting requirements", - var_description - ) - } -} - pub enum FailureCode { Error0317, Error0580, diff --git a/compiler/rustc_infer/src/infer/error_reporting/note.rs b/compiler/rustc_infer/src/infer/error_reporting/note.rs deleted file mode 100644 index d1fc9c9f140b1..0000000000000 --- a/compiler/rustc_infer/src/infer/error_reporting/note.rs +++ /dev/null @@ -1,421 +0,0 @@ -use crate::errors::{ - note_and_explain, FulfillReqLifetime, LfBoundNotSatisfied, OutlivesBound, OutlivesContent, - RefLongerThanData, RegionOriginNote, WhereClauseSuggestions, -}; -use crate::fluent_generated as fluent; -use crate::infer::error_reporting::{note_and_explain_region, TypeErrCtxt}; -use crate::infer::{self, SubregionOrigin}; -use rustc_errors::{Diag, Subdiagnostic}; -use rustc_hir::def_id::{DefId, LocalDefId}; -use rustc_middle::traits::ObligationCauseCode; -use rustc_middle::ty::error::TypeError; -use rustc_middle::ty::{self, IsSuggestable, Region, Ty}; -use rustc_span::symbol::kw; - -use super::ObligationCauseAsDiagArg; - -impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { - pub(super) fn note_region_origin(&self, err: &mut Diag<'_>, origin: &SubregionOrigin<'tcx>) { - match *origin { - infer::Subtype(ref trace) => RegionOriginNote::WithRequirement { - span: trace.cause.span, - requirement: ObligationCauseAsDiagArg(trace.cause.clone()), - expected_found: self.values_str(trace.values).map(|(e, f, _)| (e, f)), - } - .add_to_diag(err), - infer::Reborrow(span) => { - RegionOriginNote::Plain { span, msg: fluent::infer_reborrow }.add_to_diag(err) - } - infer::RelateObjectBound(span) => { - RegionOriginNote::Plain { span, msg: fluent::infer_relate_object_bound } - .add_to_diag(err); - } - infer::ReferenceOutlivesReferent(ty, span) => { - RegionOriginNote::WithName { - span, - msg: fluent::infer_reference_outlives_referent, - name: &self.ty_to_string(ty), - continues: false, - } - .add_to_diag(err); - } - infer::RelateParamBound(span, ty, opt_span) => { - RegionOriginNote::WithName { - span, - msg: fluent::infer_relate_param_bound, - name: &self.ty_to_string(ty), - continues: opt_span.is_some(), - } - .add_to_diag(err); - if let Some(span) = opt_span { - RegionOriginNote::Plain { span, msg: fluent::infer_relate_param_bound_2 } - .add_to_diag(err); - } - } - infer::RelateRegionParamBound(span) => { - RegionOriginNote::Plain { span, msg: fluent::infer_relate_region_param_bound } - .add_to_diag(err); - } - infer::CompareImplItemObligation { span, .. } => { - RegionOriginNote::Plain { span, msg: fluent::infer_compare_impl_item_obligation } - .add_to_diag(err); - } - infer::CheckAssociatedTypeBounds { ref parent, .. } => { - self.note_region_origin(err, parent); - } - infer::AscribeUserTypeProvePredicate(span) => { - RegionOriginNote::Plain { - span, - msg: fluent::infer_ascribe_user_type_prove_predicate, - } - .add_to_diag(err); - } - } - } - - pub(super) fn report_concrete_failure( - &self, - generic_param_scope: LocalDefId, - origin: SubregionOrigin<'tcx>, - sub: Region<'tcx>, - sup: Region<'tcx>, - ) -> Diag<'a> { - let mut err = match origin { - infer::Subtype(box trace) => { - let terr = TypeError::RegionsDoesNotOutlive(sup, sub); - let mut err = self.report_and_explain_type_error(trace, terr); - match (*sub, *sup) { - (ty::RePlaceholder(_), ty::RePlaceholder(_)) => {} - (ty::RePlaceholder(_), _) => { - note_and_explain_region( - self.tcx, - &mut err, - generic_param_scope, - "", - sup, - " doesn't meet the lifetime requirements", - None, - ); - } - (_, ty::RePlaceholder(_)) => { - note_and_explain_region( - self.tcx, - &mut err, - generic_param_scope, - "the required lifetime does not necessarily outlive ", - sub, - "", - None, - ); - } - _ => { - note_and_explain_region( - self.tcx, - &mut err, - generic_param_scope, - "", - sup, - "...", - None, - ); - note_and_explain_region( - self.tcx, - &mut err, - generic_param_scope, - "...does not necessarily outlive ", - sub, - "", - None, - ); - } - } - err - } - infer::Reborrow(span) => { - let reference_valid = note_and_explain::RegionExplanation::new( - self.tcx, - generic_param_scope, - sub, - None, - note_and_explain::PrefixKind::RefValidFor, - note_and_explain::SuffixKind::Continues, - ); - let content_valid = note_and_explain::RegionExplanation::new( - self.tcx, - generic_param_scope, - sup, - None, - note_and_explain::PrefixKind::ContentValidFor, - note_and_explain::SuffixKind::Empty, - ); - self.dcx().create_err(OutlivesContent { - span, - notes: reference_valid.into_iter().chain(content_valid).collect(), - }) - } - infer::RelateObjectBound(span) => { - let object_valid = note_and_explain::RegionExplanation::new( - self.tcx, - generic_param_scope, - sub, - None, - note_and_explain::PrefixKind::TypeObjValidFor, - note_and_explain::SuffixKind::Empty, - ); - let pointer_valid = note_and_explain::RegionExplanation::new( - self.tcx, - generic_param_scope, - sup, - None, - note_and_explain::PrefixKind::SourcePointerValidFor, - note_and_explain::SuffixKind::Empty, - ); - self.dcx().create_err(OutlivesBound { - span, - notes: object_valid.into_iter().chain(pointer_valid).collect(), - }) - } - infer::RelateParamBound(span, ty, opt_span) => { - let prefix = match *sub { - ty::ReStatic => note_and_explain::PrefixKind::TypeSatisfy, - _ => note_and_explain::PrefixKind::TypeOutlive, - }; - let suffix = if opt_span.is_some() { - note_and_explain::SuffixKind::ReqByBinding - } else { - note_and_explain::SuffixKind::Empty - }; - let note = note_and_explain::RegionExplanation::new( - self.tcx, - generic_param_scope, - sub, - opt_span, - prefix, - suffix, - ); - self.dcx().create_err(FulfillReqLifetime { - span, - ty: self.resolve_vars_if_possible(ty), - note, - }) - } - infer::RelateRegionParamBound(span) => { - let param_instantiated = note_and_explain::RegionExplanation::new( - self.tcx, - generic_param_scope, - sup, - None, - note_and_explain::PrefixKind::LfParamInstantiatedWith, - note_and_explain::SuffixKind::Empty, - ); - let param_must_outlive = note_and_explain::RegionExplanation::new( - self.tcx, - generic_param_scope, - sub, - None, - note_and_explain::PrefixKind::LfParamMustOutlive, - note_and_explain::SuffixKind::Empty, - ); - self.dcx().create_err(LfBoundNotSatisfied { - span, - notes: param_instantiated.into_iter().chain(param_must_outlive).collect(), - }) - } - infer::ReferenceOutlivesReferent(ty, span) => { - let pointer_valid = note_and_explain::RegionExplanation::new( - self.tcx, - generic_param_scope, - sub, - None, - note_and_explain::PrefixKind::PointerValidFor, - note_and_explain::SuffixKind::Empty, - ); - let data_valid = note_and_explain::RegionExplanation::new( - self.tcx, - generic_param_scope, - sup, - None, - note_and_explain::PrefixKind::DataValidFor, - note_and_explain::SuffixKind::Empty, - ); - self.dcx().create_err(RefLongerThanData { - span, - ty: self.resolve_vars_if_possible(ty), - notes: pointer_valid.into_iter().chain(data_valid).collect(), - }) - } - infer::CompareImplItemObligation { span, impl_item_def_id, trait_item_def_id } => { - let mut err = self.infcx.report_extra_impl_obligation( - span, - impl_item_def_id, - trait_item_def_id, - &format!("`{sup}: {sub}`"), - ); - // We should only suggest rewriting the `where` clause if the predicate is within that `where` clause - if let Some(generics) = self.tcx.hir().get_generics(impl_item_def_id) - && generics.where_clause_span.contains(span) - { - self.suggest_copy_trait_method_bounds( - trait_item_def_id, - impl_item_def_id, - &mut err, - ); - } - err - } - infer::CheckAssociatedTypeBounds { impl_item_def_id, trait_item_def_id, parent } => { - let mut err = self.report_concrete_failure(generic_param_scope, *parent, sub, sup); - - // Don't mention the item name if it's an RPITIT, since that'll just confuse - // folks. - if !self.tcx.is_impl_trait_in_trait(impl_item_def_id.to_def_id()) { - let trait_item_span = self.tcx.def_span(trait_item_def_id); - let item_name = self.tcx.item_name(impl_item_def_id.to_def_id()); - err.span_label( - trait_item_span, - format!("definition of `{item_name}` from trait"), - ); - } - - self.suggest_copy_trait_method_bounds( - trait_item_def_id, - impl_item_def_id, - &mut err, - ); - err - } - infer::AscribeUserTypeProvePredicate(span) => { - let instantiated = note_and_explain::RegionExplanation::new( - self.tcx, - generic_param_scope, - sup, - None, - note_and_explain::PrefixKind::LfInstantiatedWith, - note_and_explain::SuffixKind::Empty, - ); - let must_outlive = note_and_explain::RegionExplanation::new( - self.tcx, - generic_param_scope, - sub, - None, - note_and_explain::PrefixKind::LfMustOutlive, - note_and_explain::SuffixKind::Empty, - ); - self.dcx().create_err(LfBoundNotSatisfied { - span, - notes: instantiated.into_iter().chain(must_outlive).collect(), - }) - } - }; - if sub.is_error() || sup.is_error() { - err.downgrade_to_delayed_bug(); - } - err - } - - pub fn suggest_copy_trait_method_bounds( - &self, - trait_item_def_id: DefId, - impl_item_def_id: LocalDefId, - err: &mut Diag<'_>, - ) { - // FIXME(compiler-errors): Right now this is only being used for region - // predicate mismatches. Ideally, we'd use it for *all* predicate mismatches, - // but right now it's not really very smart when it comes to implicit `Sized` - // predicates and bounds on the trait itself. - - let Some(impl_def_id) = self.tcx.associated_item(impl_item_def_id).impl_container(self.tcx) - else { - return; - }; - let Some(trait_ref) = self.tcx.impl_trait_ref(impl_def_id) else { - return; - }; - let trait_args = trait_ref - .instantiate_identity() - // Replace the explicit self type with `Self` for better suggestion rendering - .with_self_ty(self.tcx, Ty::new_param(self.tcx, 0, kw::SelfUpper)) - .args; - let trait_item_args = ty::GenericArgs::identity_for_item(self.tcx, impl_item_def_id) - .rebase_onto(self.tcx, impl_def_id, trait_args); - - let Ok(trait_predicates) = - self.tcx - .explicit_predicates_of(trait_item_def_id) - .instantiate_own(self.tcx, trait_item_args) - .map(|(pred, _)| { - if pred.is_suggestable(self.tcx, false) { - Ok(pred.to_string()) - } else { - Err(()) - } - }) - .collect::, ()>>() - else { - return; - }; - - let Some(generics) = self.tcx.hir().get_generics(impl_item_def_id) else { - return; - }; - - let suggestion = if trait_predicates.is_empty() { - WhereClauseSuggestions::Remove { span: generics.where_clause_span } - } else { - let space = if generics.where_clause_span.is_empty() { " " } else { "" }; - WhereClauseSuggestions::CopyPredicates { - span: generics.where_clause_span, - space, - trait_predicates: trait_predicates.join(", "), - } - }; - err.subdiagnostic(suggestion); - } - - pub(super) fn report_placeholder_failure( - &self, - generic_param_scope: LocalDefId, - placeholder_origin: SubregionOrigin<'tcx>, - sub: Region<'tcx>, - sup: Region<'tcx>, - ) -> Diag<'a> { - // I can't think how to do better than this right now. -nikomatsakis - debug!(?placeholder_origin, ?sub, ?sup, "report_placeholder_failure"); - match placeholder_origin { - infer::Subtype(box ref trace) - if matches!( - &trace.cause.code().peel_derives(), - ObligationCauseCode::WhereClause(..) - | ObligationCauseCode::WhereClauseInExpr(..) - ) => - { - // Hack to get around the borrow checker because trace.cause has an `Rc`. - if let ObligationCauseCode::WhereClause(_, span) - | ObligationCauseCode::WhereClauseInExpr(_, span, ..) = - &trace.cause.code().peel_derives() - && !span.is_dummy() - { - let span = *span; - self.report_concrete_failure(generic_param_scope, placeholder_origin, sub, sup) - .with_span_note(span, "the lifetime requirement is introduced here") - } else { - unreachable!( - "control flow ensures we have a `BindingObligation` or `WhereClauseInExpr` here..." - ) - } - } - infer::Subtype(box trace) => { - let terr = TypeError::RegionsPlaceholderMismatch; - return self.report_and_explain_type_error(trace, terr); - } - _ => { - return self.report_concrete_failure( - generic_param_scope, - placeholder_origin, - sub, - sup, - ); - } - } - } -} diff --git a/compiler/rustc_infer/src/infer/error_reporting/region.rs b/compiler/rustc_infer/src/infer/error_reporting/region.rs new file mode 100644 index 0000000000000..5a465f46e47dc --- /dev/null +++ b/compiler/rustc_infer/src/infer/error_reporting/region.rs @@ -0,0 +1,1259 @@ +use std::iter; + +use rustc_errors::{ + struct_span_code_err, Applicability, Diag, Subdiagnostic, E0309, E0310, E0311, E0495, +}; +use rustc_hir::def::DefKind; +use rustc_hir::def_id::{DefId, LocalDefId}; +use rustc_hir::intravisit::Visitor; +use rustc_hir::{self as hir, ParamName}; +use rustc_middle::bug; +use rustc_middle::traits::ObligationCauseCode; +use rustc_middle::ty::error::TypeError; +use rustc_middle::ty::{self, IsSuggestable, Region, Ty, TyCtxt, TypeVisitableExt as _}; +use rustc_span::symbol::kw; +use rustc_span::{ErrorGuaranteed, Span}; +use rustc_type_ir::Upcast as _; + +use super::nice_region_error::find_anon_type; +use super::{nice_region_error, ObligationCauseAsDiagArg}; +use crate::errors::{ + self, note_and_explain, FulfillReqLifetime, LfBoundNotSatisfied, OutlivesBound, + OutlivesContent, RefLongerThanData, RegionOriginNote, WhereClauseSuggestions, +}; +use crate::fluent_generated as fluent; +use crate::infer::error_reporting::{ObligationCauseExt as _, TypeErrCtxt}; +use crate::infer::region_constraints::GenericKind; +use crate::infer::{self, InferCtxt, RegionResolutionError, RegionVariableOrigin, SubregionOrigin}; + +impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { + pub fn report_region_errors( + &self, + generic_param_scope: LocalDefId, + errors: &[RegionResolutionError<'tcx>], + ) -> ErrorGuaranteed { + assert!(!errors.is_empty()); + + if let Some(guaranteed) = self.infcx.tainted_by_errors() { + return guaranteed; + } + + debug!("report_region_errors(): {} errors to start", errors.len()); + + // try to pre-process the errors, which will group some of them + // together into a `ProcessedErrors` group: + let errors = self.process_errors(errors); + + debug!("report_region_errors: {} errors after preprocessing", errors.len()); + + let mut guar = None; + for error in errors { + debug!("report_region_errors: error = {:?}", error); + + let e = if let Some(guar) = + self.try_report_nice_region_error(generic_param_scope, &error) + { + guar + } else { + match error.clone() { + // These errors could indicate all manner of different + // problems with many different solutions. Rather + // than generate a "one size fits all" error, what we + // attempt to do is go through a number of specific + // scenarios and try to find the best way to present + // the error. If all of these fails, we fall back to a rather + // general bit of code that displays the error information + RegionResolutionError::ConcreteFailure(origin, sub, sup) => { + if sub.is_placeholder() || sup.is_placeholder() { + self.report_placeholder_failure(generic_param_scope, origin, sub, sup) + .emit() + } else { + self.report_concrete_failure(generic_param_scope, origin, sub, sup) + .emit() + } + } + + RegionResolutionError::GenericBoundFailure(origin, param_ty, sub) => self + .report_generic_bound_failure( + generic_param_scope, + origin.span(), + Some(origin), + param_ty, + sub, + ), + + RegionResolutionError::SubSupConflict( + _, + var_origin, + sub_origin, + sub_r, + sup_origin, + sup_r, + _, + ) => { + if sub_r.is_placeholder() { + self.report_placeholder_failure( + generic_param_scope, + sub_origin, + sub_r, + sup_r, + ) + .emit() + } else if sup_r.is_placeholder() { + self.report_placeholder_failure( + generic_param_scope, + sup_origin, + sub_r, + sup_r, + ) + .emit() + } else { + self.report_sub_sup_conflict( + generic_param_scope, + var_origin, + sub_origin, + sub_r, + sup_origin, + sup_r, + ) + } + } + + RegionResolutionError::UpperBoundUniverseConflict( + _, + _, + _, + sup_origin, + sup_r, + ) => { + assert!(sup_r.is_placeholder()); + + // Make a dummy value for the "sub region" -- + // this is the initial value of the + // placeholder. In practice, we expect more + // tailored errors that don't really use this + // value. + let sub_r = self.tcx.lifetimes.re_erased; + + self.report_placeholder_failure( + generic_param_scope, + sup_origin, + sub_r, + sup_r, + ) + .emit() + } + + RegionResolutionError::CannotNormalize(clause, origin) => { + let clause: ty::Clause<'tcx> = + clause.map_bound(ty::ClauseKind::TypeOutlives).upcast(self.tcx); + self.tcx + .dcx() + .struct_span_err(origin.span(), format!("cannot normalize `{clause}`")) + .emit() + } + } + }; + + guar = Some(e) + } + + guar.unwrap() + } + + // This method goes through all the errors and try to group certain types + // of error together, for the purpose of suggesting explicit lifetime + // parameters to the user. This is done so that we can have a more + // complete view of what lifetimes should be the same. + // If the return value is an empty vector, it means that processing + // failed (so the return value of this method should not be used). + // + // The method also attempts to weed out messages that seem like + // duplicates that will be unhelpful to the end-user. But + // obviously it never weeds out ALL errors. + fn process_errors( + &self, + errors: &[RegionResolutionError<'tcx>], + ) -> Vec> { + debug!("process_errors()"); + + // We want to avoid reporting generic-bound failures if we can + // avoid it: these have a very high rate of being unhelpful in + // practice. This is because they are basically secondary + // checks that test the state of the region graph after the + // rest of inference is done, and the other kinds of errors + // indicate that the region constraint graph is internally + // inconsistent, so these test results are likely to be + // meaningless. + // + // Therefore, we filter them out of the list unless they are + // the only thing in the list. + + let is_bound_failure = |e: &RegionResolutionError<'tcx>| match *e { + RegionResolutionError::GenericBoundFailure(..) => true, + RegionResolutionError::ConcreteFailure(..) + | RegionResolutionError::SubSupConflict(..) + | RegionResolutionError::UpperBoundUniverseConflict(..) + | RegionResolutionError::CannotNormalize(..) => false, + }; + + let mut errors = if errors.iter().all(|e| is_bound_failure(e)) { + errors.to_owned() + } else { + errors.iter().filter(|&e| !is_bound_failure(e)).cloned().collect() + }; + + // sort the errors by span, for better error message stability. + errors.sort_by_key(|u| match *u { + RegionResolutionError::ConcreteFailure(ref sro, _, _) => sro.span(), + RegionResolutionError::GenericBoundFailure(ref sro, _, _) => sro.span(), + RegionResolutionError::SubSupConflict(_, ref rvo, _, _, _, _, _) => rvo.span(), + RegionResolutionError::UpperBoundUniverseConflict(_, ref rvo, _, _, _) => rvo.span(), + RegionResolutionError::CannotNormalize(_, ref sro) => sro.span(), + }); + errors + } + + pub(super) fn note_region_origin(&self, err: &mut Diag<'_>, origin: &SubregionOrigin<'tcx>) { + match *origin { + infer::Subtype(ref trace) => RegionOriginNote::WithRequirement { + span: trace.cause.span, + requirement: ObligationCauseAsDiagArg(trace.cause.clone()), + expected_found: self.values_str(trace.values).map(|(e, f, _)| (e, f)), + } + .add_to_diag(err), + infer::Reborrow(span) => { + RegionOriginNote::Plain { span, msg: fluent::infer_reborrow }.add_to_diag(err) + } + infer::RelateObjectBound(span) => { + RegionOriginNote::Plain { span, msg: fluent::infer_relate_object_bound } + .add_to_diag(err); + } + infer::ReferenceOutlivesReferent(ty, span) => { + RegionOriginNote::WithName { + span, + msg: fluent::infer_reference_outlives_referent, + name: &self.ty_to_string(ty), + continues: false, + } + .add_to_diag(err); + } + infer::RelateParamBound(span, ty, opt_span) => { + RegionOriginNote::WithName { + span, + msg: fluent::infer_relate_param_bound, + name: &self.ty_to_string(ty), + continues: opt_span.is_some(), + } + .add_to_diag(err); + if let Some(span) = opt_span { + RegionOriginNote::Plain { span, msg: fluent::infer_relate_param_bound_2 } + .add_to_diag(err); + } + } + infer::RelateRegionParamBound(span) => { + RegionOriginNote::Plain { span, msg: fluent::infer_relate_region_param_bound } + .add_to_diag(err); + } + infer::CompareImplItemObligation { span, .. } => { + RegionOriginNote::Plain { span, msg: fluent::infer_compare_impl_item_obligation } + .add_to_diag(err); + } + infer::CheckAssociatedTypeBounds { ref parent, .. } => { + self.note_region_origin(err, parent); + } + infer::AscribeUserTypeProvePredicate(span) => { + RegionOriginNote::Plain { + span, + msg: fluent::infer_ascribe_user_type_prove_predicate, + } + .add_to_diag(err); + } + } + } + + pub(super) fn report_concrete_failure( + &self, + generic_param_scope: LocalDefId, + origin: SubregionOrigin<'tcx>, + sub: Region<'tcx>, + sup: Region<'tcx>, + ) -> Diag<'a> { + let mut err = match origin { + infer::Subtype(box trace) => { + let terr = TypeError::RegionsDoesNotOutlive(sup, sub); + let mut err = self.report_and_explain_type_error(trace, terr); + match (*sub, *sup) { + (ty::RePlaceholder(_), ty::RePlaceholder(_)) => {} + (ty::RePlaceholder(_), _) => { + note_and_explain_region( + self.tcx, + &mut err, + generic_param_scope, + "", + sup, + " doesn't meet the lifetime requirements", + None, + ); + } + (_, ty::RePlaceholder(_)) => { + note_and_explain_region( + self.tcx, + &mut err, + generic_param_scope, + "the required lifetime does not necessarily outlive ", + sub, + "", + None, + ); + } + _ => { + note_and_explain_region( + self.tcx, + &mut err, + generic_param_scope, + "", + sup, + "...", + None, + ); + note_and_explain_region( + self.tcx, + &mut err, + generic_param_scope, + "...does not necessarily outlive ", + sub, + "", + None, + ); + } + } + err + } + infer::Reborrow(span) => { + let reference_valid = note_and_explain::RegionExplanation::new( + self.tcx, + generic_param_scope, + sub, + None, + note_and_explain::PrefixKind::RefValidFor, + note_and_explain::SuffixKind::Continues, + ); + let content_valid = note_and_explain::RegionExplanation::new( + self.tcx, + generic_param_scope, + sup, + None, + note_and_explain::PrefixKind::ContentValidFor, + note_and_explain::SuffixKind::Empty, + ); + self.dcx().create_err(OutlivesContent { + span, + notes: reference_valid.into_iter().chain(content_valid).collect(), + }) + } + infer::RelateObjectBound(span) => { + let object_valid = note_and_explain::RegionExplanation::new( + self.tcx, + generic_param_scope, + sub, + None, + note_and_explain::PrefixKind::TypeObjValidFor, + note_and_explain::SuffixKind::Empty, + ); + let pointer_valid = note_and_explain::RegionExplanation::new( + self.tcx, + generic_param_scope, + sup, + None, + note_and_explain::PrefixKind::SourcePointerValidFor, + note_and_explain::SuffixKind::Empty, + ); + self.dcx().create_err(OutlivesBound { + span, + notes: object_valid.into_iter().chain(pointer_valid).collect(), + }) + } + infer::RelateParamBound(span, ty, opt_span) => { + let prefix = match *sub { + ty::ReStatic => note_and_explain::PrefixKind::TypeSatisfy, + _ => note_and_explain::PrefixKind::TypeOutlive, + }; + let suffix = if opt_span.is_some() { + note_and_explain::SuffixKind::ReqByBinding + } else { + note_and_explain::SuffixKind::Empty + }; + let note = note_and_explain::RegionExplanation::new( + self.tcx, + generic_param_scope, + sub, + opt_span, + prefix, + suffix, + ); + self.dcx().create_err(FulfillReqLifetime { + span, + ty: self.resolve_vars_if_possible(ty), + note, + }) + } + infer::RelateRegionParamBound(span) => { + let param_instantiated = note_and_explain::RegionExplanation::new( + self.tcx, + generic_param_scope, + sup, + None, + note_and_explain::PrefixKind::LfParamInstantiatedWith, + note_and_explain::SuffixKind::Empty, + ); + let param_must_outlive = note_and_explain::RegionExplanation::new( + self.tcx, + generic_param_scope, + sub, + None, + note_and_explain::PrefixKind::LfParamMustOutlive, + note_and_explain::SuffixKind::Empty, + ); + self.dcx().create_err(LfBoundNotSatisfied { + span, + notes: param_instantiated.into_iter().chain(param_must_outlive).collect(), + }) + } + infer::ReferenceOutlivesReferent(ty, span) => { + let pointer_valid = note_and_explain::RegionExplanation::new( + self.tcx, + generic_param_scope, + sub, + None, + note_and_explain::PrefixKind::PointerValidFor, + note_and_explain::SuffixKind::Empty, + ); + let data_valid = note_and_explain::RegionExplanation::new( + self.tcx, + generic_param_scope, + sup, + None, + note_and_explain::PrefixKind::DataValidFor, + note_and_explain::SuffixKind::Empty, + ); + self.dcx().create_err(RefLongerThanData { + span, + ty: self.resolve_vars_if_possible(ty), + notes: pointer_valid.into_iter().chain(data_valid).collect(), + }) + } + infer::CompareImplItemObligation { span, impl_item_def_id, trait_item_def_id } => { + let mut err = self.infcx.report_extra_impl_obligation( + span, + impl_item_def_id, + trait_item_def_id, + &format!("`{sup}: {sub}`"), + ); + // We should only suggest rewriting the `where` clause if the predicate is within that `where` clause + if let Some(generics) = self.tcx.hir().get_generics(impl_item_def_id) + && generics.where_clause_span.contains(span) + { + self.suggest_copy_trait_method_bounds( + trait_item_def_id, + impl_item_def_id, + &mut err, + ); + } + err + } + infer::CheckAssociatedTypeBounds { impl_item_def_id, trait_item_def_id, parent } => { + let mut err = self.report_concrete_failure(generic_param_scope, *parent, sub, sup); + + // Don't mention the item name if it's an RPITIT, since that'll just confuse + // folks. + if !self.tcx.is_impl_trait_in_trait(impl_item_def_id.to_def_id()) { + let trait_item_span = self.tcx.def_span(trait_item_def_id); + let item_name = self.tcx.item_name(impl_item_def_id.to_def_id()); + err.span_label( + trait_item_span, + format!("definition of `{item_name}` from trait"), + ); + } + + self.suggest_copy_trait_method_bounds( + trait_item_def_id, + impl_item_def_id, + &mut err, + ); + err + } + infer::AscribeUserTypeProvePredicate(span) => { + let instantiated = note_and_explain::RegionExplanation::new( + self.tcx, + generic_param_scope, + sup, + None, + note_and_explain::PrefixKind::LfInstantiatedWith, + note_and_explain::SuffixKind::Empty, + ); + let must_outlive = note_and_explain::RegionExplanation::new( + self.tcx, + generic_param_scope, + sub, + None, + note_and_explain::PrefixKind::LfMustOutlive, + note_and_explain::SuffixKind::Empty, + ); + self.dcx().create_err(LfBoundNotSatisfied { + span, + notes: instantiated.into_iter().chain(must_outlive).collect(), + }) + } + }; + if sub.is_error() || sup.is_error() { + err.downgrade_to_delayed_bug(); + } + err + } + + pub fn suggest_copy_trait_method_bounds( + &self, + trait_item_def_id: DefId, + impl_item_def_id: LocalDefId, + err: &mut Diag<'_>, + ) { + // FIXME(compiler-errors): Right now this is only being used for region + // predicate mismatches. Ideally, we'd use it for *all* predicate mismatches, + // but right now it's not really very smart when it comes to implicit `Sized` + // predicates and bounds on the trait itself. + + let Some(impl_def_id) = self.tcx.associated_item(impl_item_def_id).impl_container(self.tcx) + else { + return; + }; + let Some(trait_ref) = self.tcx.impl_trait_ref(impl_def_id) else { + return; + }; + let trait_args = trait_ref + .instantiate_identity() + // Replace the explicit self type with `Self` for better suggestion rendering + .with_self_ty(self.tcx, Ty::new_param(self.tcx, 0, kw::SelfUpper)) + .args; + let trait_item_args = ty::GenericArgs::identity_for_item(self.tcx, impl_item_def_id) + .rebase_onto(self.tcx, impl_def_id, trait_args); + + let Ok(trait_predicates) = + self.tcx + .explicit_predicates_of(trait_item_def_id) + .instantiate_own(self.tcx, trait_item_args) + .map(|(pred, _)| { + if pred.is_suggestable(self.tcx, false) { + Ok(pred.to_string()) + } else { + Err(()) + } + }) + .collect::, ()>>() + else { + return; + }; + + let Some(generics) = self.tcx.hir().get_generics(impl_item_def_id) else { + return; + }; + + let suggestion = if trait_predicates.is_empty() { + WhereClauseSuggestions::Remove { span: generics.where_clause_span } + } else { + let space = if generics.where_clause_span.is_empty() { " " } else { "" }; + WhereClauseSuggestions::CopyPredicates { + span: generics.where_clause_span, + space, + trait_predicates: trait_predicates.join(", "), + } + }; + err.subdiagnostic(suggestion); + } + + pub(super) fn report_placeholder_failure( + &self, + generic_param_scope: LocalDefId, + placeholder_origin: SubregionOrigin<'tcx>, + sub: Region<'tcx>, + sup: Region<'tcx>, + ) -> Diag<'a> { + // I can't think how to do better than this right now. -nikomatsakis + debug!(?placeholder_origin, ?sub, ?sup, "report_placeholder_failure"); + match placeholder_origin { + infer::Subtype(box ref trace) + if matches!( + &trace.cause.code().peel_derives(), + ObligationCauseCode::WhereClause(..) + | ObligationCauseCode::WhereClauseInExpr(..) + ) => + { + // Hack to get around the borrow checker because trace.cause has an `Rc`. + if let ObligationCauseCode::WhereClause(_, span) + | ObligationCauseCode::WhereClauseInExpr(_, span, ..) = + &trace.cause.code().peel_derives() + && !span.is_dummy() + { + let span = *span; + self.report_concrete_failure(generic_param_scope, placeholder_origin, sub, sup) + .with_span_note(span, "the lifetime requirement is introduced here") + } else { + unreachable!( + "control flow ensures we have a `BindingObligation` or `WhereClauseInExpr` here..." + ) + } + } + infer::Subtype(box trace) => { + let terr = TypeError::RegionsPlaceholderMismatch; + return self.report_and_explain_type_error(trace, terr); + } + _ => { + return self.report_concrete_failure( + generic_param_scope, + placeholder_origin, + sub, + sup, + ); + } + } + } + + pub fn report_generic_bound_failure( + &self, + generic_param_scope: LocalDefId, + span: Span, + origin: Option>, + bound_kind: GenericKind<'tcx>, + sub: Region<'tcx>, + ) -> ErrorGuaranteed { + self.construct_generic_bound_failure(generic_param_scope, span, origin, bound_kind, sub) + .emit() + } + + pub fn construct_generic_bound_failure( + &self, + generic_param_scope: LocalDefId, + span: Span, + origin: Option>, + bound_kind: GenericKind<'tcx>, + sub: Region<'tcx>, + ) -> Diag<'a> { + if let Some(SubregionOrigin::CompareImplItemObligation { + span, + impl_item_def_id, + trait_item_def_id, + }) = origin + { + return self.infcx.report_extra_impl_obligation( + span, + impl_item_def_id, + trait_item_def_id, + &format!("`{bound_kind}: {sub}`"), + ); + } + + let labeled_user_string = match bound_kind { + GenericKind::Param(ref p) => format!("the parameter type `{p}`"), + GenericKind::Placeholder(ref p) => format!("the placeholder type `{p:?}`"), + GenericKind::Alias(ref p) => match p.kind(self.tcx) { + ty::Projection | ty::Inherent => { + format!("the associated type `{p}`") + } + ty::Weak => format!("the type alias `{p}`"), + ty::Opaque => format!("the opaque type `{p}`"), + }, + }; + + let mut err = self + .tcx + .dcx() + .struct_span_err(span, format!("{labeled_user_string} may not live long enough")); + err.code(match sub.kind() { + ty::ReEarlyParam(_) | ty::ReLateParam(_) if sub.has_name() => E0309, + ty::ReStatic => E0310, + _ => E0311, + }); + + '_explain: { + let (description, span) = match sub.kind() { + ty::ReEarlyParam(_) | ty::ReLateParam(_) | ty::ReStatic => { + msg_span_from_named_region(self.tcx, generic_param_scope, sub, Some(span)) + } + _ => (format!("lifetime `{sub}`"), Some(span)), + }; + let prefix = format!("{labeled_user_string} must be valid for "); + label_msg_span(&mut err, &prefix, description, span, "..."); + if let Some(origin) = origin { + self.note_region_origin(&mut err, &origin); + } + } + + 'suggestion: { + let msg = "consider adding an explicit lifetime bound"; + + if (bound_kind, sub).has_infer_regions() + || (bound_kind, sub).has_placeholders() + || !bound_kind.is_suggestable(self.tcx, false) + { + let lt_name = sub.get_name_or_anon().to_string(); + err.help(format!("{msg} `{bound_kind}: {lt_name}`...")); + break 'suggestion; + } + + let mut generic_param_scope = generic_param_scope; + while self.tcx.def_kind(generic_param_scope) == DefKind::OpaqueTy { + generic_param_scope = self.tcx.local_parent(generic_param_scope); + } + + // type_param_sugg_span is (span, has_bounds, needs_parentheses) + let (type_scope, type_param_sugg_span) = match bound_kind { + GenericKind::Param(param) => { + let generics = self.tcx.generics_of(generic_param_scope); + let type_param = generics.type_param(param, self.tcx); + let def_id = type_param.def_id.expect_local(); + let scope = self.tcx.local_def_id_to_hir_id(def_id).owner.def_id; + // Get the `hir::Param` to verify whether it already has any bounds. + // We do this to avoid suggesting code that ends up as `T: 'a'b`, + // instead we suggest `T: 'a + 'b` in that case. + let hir_generics = self.tcx.hir().get_generics(scope).unwrap(); + let sugg_span = match hir_generics.bounds_span_for_suggestions(def_id) { + Some((span, open_paren_sp)) => Some((span, true, open_paren_sp)), + // If `param` corresponds to `Self`, no usable suggestion span. + None if generics.has_self && param.index == 0 => None, + None => { + let span = if let Some(param) = + hir_generics.params.iter().find(|param| param.def_id == def_id) + && let ParamName::Plain(ident) = param.name + { + ident.span.shrink_to_hi() + } else { + let span = self.tcx.def_span(def_id); + span.shrink_to_hi() + }; + Some((span, false, None)) + } + }; + (scope, sugg_span) + } + _ => (generic_param_scope, None), + }; + let suggestion_scope = { + let lifetime_scope = match sub.kind() { + ty::ReStatic => hir::def_id::CRATE_DEF_ID, + _ => match self.tcx.is_suitable_region(generic_param_scope, sub) { + Some(info) => info.def_id, + None => generic_param_scope, + }, + }; + match self.tcx.is_descendant_of(type_scope.into(), lifetime_scope.into()) { + true => type_scope, + false => lifetime_scope, + } + }; + + let mut suggs = vec![]; + let lt_name = self.suggest_name_region(generic_param_scope, sub, &mut suggs); + + if let Some((sp, has_lifetimes, open_paren_sp)) = type_param_sugg_span + && suggestion_scope == type_scope + { + let suggestion = + if has_lifetimes { format!(" + {lt_name}") } else { format!(": {lt_name}") }; + + if let Some(open_paren_sp) = open_paren_sp { + suggs.push((open_paren_sp, "(".to_string())); + suggs.push((sp, format!("){suggestion}"))); + } else { + suggs.push((sp, suggestion)) + } + } else if let GenericKind::Alias(ref p) = bound_kind + && let ty::Projection = p.kind(self.tcx) + && let DefKind::AssocTy = self.tcx.def_kind(p.def_id) + && let Some(ty::ImplTraitInTraitData::Trait { .. }) = + self.tcx.opt_rpitit_info(p.def_id) + { + // The lifetime found in the `impl` is longer than the one on the RPITIT. + // Do not suggest `::{opaque}: 'static`. + } else if let Some(generics) = self.tcx.hir().get_generics(suggestion_scope) { + let pred = format!("{bound_kind}: {lt_name}"); + let suggestion = format!("{} {}", generics.add_where_or_trailing_comma(), pred); + suggs.push((generics.tail_span_for_predicate_suggestion(), suggestion)) + } else { + let consider = format!("{msg} `{bound_kind}: {sub}`..."); + err.help(consider); + } + + if !suggs.is_empty() { + err.multipart_suggestion_verbose( + msg, + suggs, + Applicability::MaybeIncorrect, // Issue #41966 + ); + } + } + + err + } + + pub fn suggest_name_region( + &self, + generic_param_scope: LocalDefId, + lifetime: Region<'tcx>, + add_lt_suggs: &mut Vec<(Span, String)>, + ) -> String { + struct LifetimeReplaceVisitor<'tcx, 'a> { + tcx: TyCtxt<'tcx>, + needle: hir::LifetimeName, + new_lt: &'a str, + add_lt_suggs: &'a mut Vec<(Span, String)>, + } + + impl<'hir, 'tcx> hir::intravisit::Visitor<'hir> for LifetimeReplaceVisitor<'tcx, '_> { + fn visit_lifetime(&mut self, lt: &'hir hir::Lifetime) { + if lt.res == self.needle { + let (pos, span) = lt.suggestion_position(); + let new_lt = &self.new_lt; + let sugg = match pos { + hir::LifetimeSuggestionPosition::Normal => format!("{new_lt}"), + hir::LifetimeSuggestionPosition::Ampersand => format!("{new_lt} "), + hir::LifetimeSuggestionPosition::ElidedPath => format!("<{new_lt}>"), + hir::LifetimeSuggestionPosition::ElidedPathArgument => { + format!("{new_lt}, ") + } + hir::LifetimeSuggestionPosition::ObjectDefault => format!("+ {new_lt}"), + }; + self.add_lt_suggs.push((span, sugg)); + } + } + + fn visit_ty(&mut self, ty: &'hir hir::Ty<'hir>) { + let hir::TyKind::OpaqueDef(item_id, _, _) = ty.kind else { + return hir::intravisit::walk_ty(self, ty); + }; + let opaque_ty = self.tcx.hir().item(item_id).expect_opaque_ty(); + if let Some(&(_, b)) = + opaque_ty.lifetime_mapping.iter().find(|&(a, _)| a.res == self.needle) + { + let prev_needle = + std::mem::replace(&mut self.needle, hir::LifetimeName::Param(b)); + for bound in opaque_ty.bounds { + self.visit_param_bound(bound); + } + self.needle = prev_needle; + } + } + } + + let (lifetime_def_id, lifetime_scope) = + match self.tcx.is_suitable_region(generic_param_scope, lifetime) { + Some(info) if !lifetime.has_name() => { + (info.bound_region.get_id().unwrap().expect_local(), info.def_id) + } + _ => return lifetime.get_name_or_anon().to_string(), + }; + + let new_lt = { + let generics = self.tcx.generics_of(lifetime_scope); + let mut used_names = + iter::successors(Some(generics), |g| g.parent.map(|p| self.tcx.generics_of(p))) + .flat_map(|g| &g.own_params) + .filter(|p| matches!(p.kind, ty::GenericParamDefKind::Lifetime)) + .map(|p| p.name) + .collect::>(); + let hir_id = self.tcx.local_def_id_to_hir_id(lifetime_scope); + // consider late-bound lifetimes ... + used_names.extend(self.tcx.late_bound_vars(hir_id).into_iter().filter_map( + |p| match p { + ty::BoundVariableKind::Region(lt) => lt.get_name(), + _ => None, + }, + )); + (b'a'..=b'z') + .map(|c| format!("'{}", c as char)) + .find(|candidate| !used_names.iter().any(|e| e.as_str() == candidate)) + .unwrap_or("'lt".to_string()) + }; + + let mut visitor = LifetimeReplaceVisitor { + tcx: self.tcx, + needle: hir::LifetimeName::Param(lifetime_def_id), + add_lt_suggs, + new_lt: &new_lt, + }; + match self.tcx.expect_hir_owner_node(lifetime_scope) { + hir::OwnerNode::Item(i) => visitor.visit_item(i), + hir::OwnerNode::ForeignItem(i) => visitor.visit_foreign_item(i), + hir::OwnerNode::ImplItem(i) => visitor.visit_impl_item(i), + hir::OwnerNode::TraitItem(i) => visitor.visit_trait_item(i), + hir::OwnerNode::Crate(_) => bug!("OwnerNode::Crate doesn't not have generics"), + hir::OwnerNode::Synthetic => unreachable!(), + } + + let ast_generics = self.tcx.hir().get_generics(lifetime_scope).unwrap(); + let sugg = ast_generics + .span_for_lifetime_suggestion() + .map(|span| (span, format!("{new_lt}, "))) + .unwrap_or_else(|| (ast_generics.span, format!("<{new_lt}>"))); + add_lt_suggs.push(sugg); + + new_lt + } + + fn report_sub_sup_conflict( + &self, + generic_param_scope: LocalDefId, + var_origin: RegionVariableOrigin, + sub_origin: SubregionOrigin<'tcx>, + sub_region: Region<'tcx>, + sup_origin: SubregionOrigin<'tcx>, + sup_region: Region<'tcx>, + ) -> ErrorGuaranteed { + let mut err = self.report_inference_failure(var_origin); + + note_and_explain_region( + self.tcx, + &mut err, + generic_param_scope, + "first, the lifetime cannot outlive ", + sup_region, + "...", + None, + ); + + debug!("report_sub_sup_conflict: var_origin={:?}", var_origin); + debug!("report_sub_sup_conflict: sub_region={:?}", sub_region); + debug!("report_sub_sup_conflict: sub_origin={:?}", sub_origin); + debug!("report_sub_sup_conflict: sup_region={:?}", sup_region); + debug!("report_sub_sup_conflict: sup_origin={:?}", sup_origin); + + if let infer::Subtype(ref sup_trace) = sup_origin + && let infer::Subtype(ref sub_trace) = sub_origin + && let Some((sup_expected, sup_found, _)) = self.values_str(sup_trace.values) + && let Some((sub_expected, sub_found, _)) = self.values_str(sub_trace.values) + && sub_expected == sup_expected + && sub_found == sup_found + { + note_and_explain_region( + self.tcx, + &mut err, + generic_param_scope, + "...but the lifetime must also be valid for ", + sub_region, + "...", + None, + ); + err.span_note( + sup_trace.cause.span, + format!("...so that the {}", sup_trace.cause.as_requirement_str()), + ); + + err.note_expected_found(&"", sup_expected, &"", sup_found); + return if sub_region.is_error() | sup_region.is_error() { + err.delay_as_bug() + } else { + err.emit() + }; + } + + self.note_region_origin(&mut err, &sup_origin); + + note_and_explain_region( + self.tcx, + &mut err, + generic_param_scope, + "but, the lifetime must be valid for ", + sub_region, + "...", + None, + ); + + self.note_region_origin(&mut err, &sub_origin); + if sub_region.is_error() | sup_region.is_error() { err.delay_as_bug() } else { err.emit() } + } + + fn report_inference_failure(&self, var_origin: RegionVariableOrigin) -> Diag<'_> { + let br_string = |br: ty::BoundRegionKind| { + let mut s = match br { + ty::BrNamed(_, name) => name.to_string(), + _ => String::new(), + }; + if !s.is_empty() { + s.push(' '); + } + s + }; + let var_description = match var_origin { + infer::MiscVariable(_) => String::new(), + infer::PatternRegion(_) => " for pattern".to_string(), + infer::AddrOfRegion(_) => " for borrow expression".to_string(), + infer::Autoref(_) => " for autoref".to_string(), + infer::Coercion(_) => " for automatic coercion".to_string(), + infer::BoundRegion(_, br, infer::FnCall) => { + format!(" for lifetime parameter {}in function call", br_string(br)) + } + infer::BoundRegion(_, br, infer::HigherRankedType) => { + format!(" for lifetime parameter {}in generic type", br_string(br)) + } + infer::BoundRegion(_, br, infer::AssocTypeProjection(def_id)) => format!( + " for lifetime parameter {}in trait containing associated type `{}`", + br_string(br), + self.tcx.associated_item(def_id).name + ), + infer::RegionParameterDefinition(_, name) => { + format!(" for lifetime parameter `{name}`") + } + infer::UpvarRegion(ref upvar_id, _) => { + let var_name = self.tcx.hir().name(upvar_id.var_path.hir_id); + format!(" for capture of `{var_name}` by closure") + } + infer::Nll(..) => bug!("NLL variable found in lexical phase"), + }; + + struct_span_code_err!( + self.dcx(), + var_origin.span(), + E0495, + "cannot infer an appropriate lifetime{} due to conflicting requirements", + var_description + ) + } +} + +pub(super) fn note_and_explain_region<'tcx>( + tcx: TyCtxt<'tcx>, + err: &mut Diag<'_>, + generic_param_scope: LocalDefId, + prefix: &str, + region: ty::Region<'tcx>, + suffix: &str, + alt_span: Option, +) { + let (description, span) = match *region { + ty::ReEarlyParam(_) | ty::ReLateParam(_) | ty::RePlaceholder(_) | ty::ReStatic => { + msg_span_from_named_region(tcx, generic_param_scope, region, alt_span) + } + + ty::ReError(_) => return, + + // FIXME(#125431): `ReVar` shouldn't reach here. + ty::ReVar(_) => (format!("lifetime `{region}`"), alt_span), + + ty::ReBound(..) | ty::ReErased => { + bug!("unexpected region for note_and_explain_region: {:?}", region); + } + }; + + emit_msg_span(err, prefix, description, span, suffix); +} + +fn explain_free_region<'tcx>( + tcx: TyCtxt<'tcx>, + err: &mut Diag<'_>, + generic_param_scope: LocalDefId, + prefix: &str, + region: ty::Region<'tcx>, + suffix: &str, +) { + let (description, span) = msg_span_from_named_region(tcx, generic_param_scope, region, None); + + label_msg_span(err, prefix, description, span, suffix); +} + +fn msg_span_from_named_region<'tcx>( + tcx: TyCtxt<'tcx>, + generic_param_scope: LocalDefId, + region: ty::Region<'tcx>, + alt_span: Option, +) -> (String, Option) { + match *region { + ty::ReEarlyParam(br) => { + let scope = tcx + .parent(tcx.generics_of(generic_param_scope).region_param(br, tcx).def_id) + .expect_local(); + let span = if let Some(param) = + tcx.hir().get_generics(scope).and_then(|generics| generics.get_named(br.name)) + { + param.span + } else { + tcx.def_span(scope) + }; + let text = if br.has_name() { + format!("the lifetime `{}` as defined here", br.name) + } else { + "the anonymous lifetime as defined here".to_string() + }; + (text, Some(span)) + } + ty::ReLateParam(ref fr) => { + if !fr.bound_region.is_named() + && let Some((ty, _)) = + find_anon_type(tcx, generic_param_scope, region, &fr.bound_region) + { + ("the anonymous lifetime defined here".to_string(), Some(ty.span)) + } else { + match fr.bound_region { + ty::BoundRegionKind::BrNamed(_, name) => { + let span = if let Some(param) = tcx + .hir() + .get_generics(generic_param_scope) + .and_then(|generics| generics.get_named(name)) + { + param.span + } else { + tcx.def_span(generic_param_scope) + }; + let text = if name == kw::UnderscoreLifetime { + "the anonymous lifetime as defined here".to_string() + } else { + format!("the lifetime `{name}` as defined here") + }; + (text, Some(span)) + } + ty::BrAnon => ( + "the anonymous lifetime as defined here".to_string(), + Some(tcx.def_span(generic_param_scope)), + ), + _ => ( + format!("the lifetime `{region}` as defined here"), + Some(tcx.def_span(generic_param_scope)), + ), + } + } + } + ty::ReStatic => ("the static lifetime".to_owned(), alt_span), + ty::RePlaceholder(ty::PlaceholderRegion { + bound: ty::BoundRegion { kind: ty::BoundRegionKind::BrNamed(def_id, name), .. }, + .. + }) => (format!("the lifetime `{name}` as defined here"), Some(tcx.def_span(def_id))), + ty::RePlaceholder(ty::PlaceholderRegion { + bound: ty::BoundRegion { kind: ty::BoundRegionKind::BrAnon, .. }, + .. + }) => ("an anonymous lifetime".to_owned(), None), + _ => bug!("{:?}", region), + } +} + +fn emit_msg_span( + err: &mut Diag<'_>, + prefix: &str, + description: String, + span: Option, + suffix: &str, +) { + let message = format!("{prefix}{description}{suffix}"); + + if let Some(span) = span { + err.span_note(span, message); + } else { + err.note(message); + } +} + +fn label_msg_span( + err: &mut Diag<'_>, + prefix: &str, + description: String, + span: Option, + suffix: &str, +) { + let message = format!("{prefix}{description}{suffix}"); + + if let Some(span) = span { + err.span_label(span, message); + } else { + err.note(message); + } +} + +#[instrument(level = "trace", skip(infcx))] +pub fn unexpected_hidden_region_diagnostic<'a, 'tcx>( + infcx: &'a InferCtxt<'tcx>, + generic_param_scope: LocalDefId, + span: Span, + hidden_ty: Ty<'tcx>, + hidden_region: ty::Region<'tcx>, + opaque_ty_key: ty::OpaqueTypeKey<'tcx>, +) -> Diag<'a> { + let tcx = infcx.tcx; + let mut err = infcx.dcx().create_err(errors::OpaqueCapturesLifetime { + span, + opaque_ty: Ty::new_opaque(tcx, opaque_ty_key.def_id.to_def_id(), opaque_ty_key.args), + opaque_ty_span: tcx.def_span(opaque_ty_key.def_id), + }); + + // Explain the region we are capturing. + match *hidden_region { + ty::ReEarlyParam(_) | ty::ReLateParam(_) | ty::ReStatic => { + // Assuming regionck succeeded (*), we ought to always be + // capturing *some* region from the fn header, and hence it + // ought to be free. So under normal circumstances, we will go + // down this path which gives a decent human readable + // explanation. + // + // (*) if not, the `tainted_by_errors` field would be set to + // `Some(ErrorGuaranteed)` in any case, so we wouldn't be here at all. + explain_free_region( + tcx, + &mut err, + generic_param_scope, + &format!("hidden type `{hidden_ty}` captures "), + hidden_region, + "", + ); + if let Some(reg_info) = tcx.is_suitable_region(generic_param_scope, hidden_region) { + let fn_returns = tcx.return_type_impl_or_dyn_traits(reg_info.def_id); + nice_region_error::suggest_new_region_bound( + tcx, + &mut err, + fn_returns, + hidden_region.to_string(), + None, + format!("captures `{hidden_region}`"), + None, + Some(reg_info.def_id), + ) + } + } + ty::RePlaceholder(_) => { + explain_free_region( + tcx, + &mut err, + generic_param_scope, + &format!("hidden type `{}` captures ", hidden_ty), + hidden_region, + "", + ); + } + ty::ReError(_) => { + err.downgrade_to_delayed_bug(); + } + _ => { + // Ugh. This is a painful case: the hidden region is not one + // that we can easily summarize or explain. This can happen + // in a case like + // `tests/ui/multiple-lifetimes/ordinary-bounds-unsuited.rs`: + // + // ``` + // fn upper_bounds<'a, 'b>(a: Ordinary<'a>, b: Ordinary<'b>) -> impl Trait<'a, 'b> { + // if condition() { a } else { b } + // } + // ``` + // + // Here the captured lifetime is the intersection of `'a` and + // `'b`, which we can't quite express. + + // We can at least report a really cryptic error for now. + note_and_explain_region( + tcx, + &mut err, + generic_param_scope, + &format!("hidden type `{hidden_ty}` captures "), + hidden_region, + "", + None, + ); + } + } + + err +} From b058de90a3fb482aef147a9807602364b36c93a0 Mon Sep 17 00:00:00 2001 From: beetrees Date: Wed, 26 Jun 2024 18:18:32 +0100 Subject: [PATCH 845/892] Add Natvis visualiser and debuginfo tests for `f16` --- .../src/debuginfo/metadata.rs | 43 +++++++++++++- src/etc/natvis/intrinsic.natvis | 26 +++++++++ .../debuginfo/basic-types-globals-metadata.rs | 7 ++- tests/debuginfo/basic-types-globals.rs | 11 +++- tests/debuginfo/basic-types-metadata.rs | 4 ++ tests/debuginfo/basic-types-mut-globals.rs | 44 ++++++++------ tests/debuginfo/basic-types.rs | 14 +++-- tests/debuginfo/borrowed-basic.rs | 15 ++++- tests/debuginfo/borrowed-unique-basic.rs | 15 ++++- tests/debuginfo/f16-natvis.rs | 58 +++++++++++++++++++ tests/debuginfo/reference-debuginfo.rs | 17 +++++- 11 files changed, 218 insertions(+), 36 deletions(-) create mode 100644 tests/debuginfo/f16-natvis.rs diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs index 8de4e0effad28..64f173308c09e 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs @@ -705,10 +705,12 @@ impl MsvcBasicName for ty::UintTy { impl MsvcBasicName for ty::FloatTy { fn msvc_basic_name(self) -> &'static str { - // FIXME: f16 and f128 have no MSVC representation. We could improve the debuginfo. - // See: + // FIXME(f16_f128): `f16` and `f128` have no MSVC representation. We could improve the + // debuginfo. See: match self { - ty::FloatTy::F16 => "half", + ty::FloatTy::F16 => { + bug!("`f16` should have been handled in `build_basic_type_di_node`") + } ty::FloatTy::F32 => "float", ty::FloatTy::F64 => "double", ty::FloatTy::F128 => "fp128", @@ -716,6 +718,38 @@ impl MsvcBasicName for ty::FloatTy { } } +fn build_cpp_f16_di_node<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>) -> DINodeCreationResult<'ll> { + // MSVC has no native support for `f16`. Instead, emit `struct f16 { bits: u16 }` to allow the + // `f16`'s value to be displayed using a Natvis visualiser in `intrinsic.natvis`. + let float_ty = cx.tcx.types.f16; + let bits_ty = cx.tcx.types.u16; + type_map::build_type_with_children( + cx, + type_map::stub( + cx, + Stub::Struct, + UniqueTypeId::for_ty(cx.tcx, float_ty), + "f16", + cx.size_and_align_of(float_ty), + NO_SCOPE_METADATA, + DIFlags::FlagZero, + ), + // Fields: + |cx, float_di_node| { + smallvec![build_field_di_node( + cx, + float_di_node, + "bits", + cx.size_and_align_of(bits_ty), + Size::ZERO, + DIFlags::FlagZero, + type_di_node(cx, bits_ty), + )] + }, + NO_GENERICS, + ) +} + fn build_basic_type_di_node<'ll, 'tcx>( cx: &CodegenCx<'ll, 'tcx>, t: Ty<'tcx>, @@ -739,6 +773,9 @@ fn build_basic_type_di_node<'ll, 'tcx>( ty::Char => ("char", DW_ATE_UTF), ty::Int(int_ty) if cpp_like_debuginfo => (int_ty.msvc_basic_name(), DW_ATE_signed), ty::Uint(uint_ty) if cpp_like_debuginfo => (uint_ty.msvc_basic_name(), DW_ATE_unsigned), + ty::Float(ty::FloatTy::F16) if cpp_like_debuginfo => { + return build_cpp_f16_di_node(cx); + } ty::Float(float_ty) if cpp_like_debuginfo => (float_ty.msvc_basic_name(), DW_ATE_float), ty::Int(int_ty) => (int_ty.name_str(), DW_ATE_signed), ty::Uint(uint_ty) => (uint_ty.name_str(), DW_ATE_unsigned), diff --git a/src/etc/natvis/intrinsic.natvis b/src/etc/natvis/intrinsic.natvis index 8c16a562e349e..49e0ce319efac 100644 --- a/src/etc/natvis/intrinsic.natvis +++ b/src/etc/natvis/intrinsic.natvis @@ -33,6 +33,32 @@ + + + + + + + + + + + + + + + + + + + inf + -inf + NaN + + {(float) (sign() * raw_significand() / 16384.0)} + + {(float) (sign() * (raw_significand() + 1.0) * two_pow_exponent())} + () diff --git a/tests/debuginfo/basic-types-globals-metadata.rs b/tests/debuginfo/basic-types-globals-metadata.rs index 124be655c3523..d346b405555bc 100644 --- a/tests/debuginfo/basic-types-globals-metadata.rs +++ b/tests/debuginfo/basic-types-globals-metadata.rs @@ -39,6 +39,9 @@ // gdbg-command:whatis 'basic_types_globals_metadata::U64' // gdbr-command:whatis basic_types_globals_metadata::U64 // gdb-check:type = u64 +// gdbg-command:whatis 'basic_types_globals_metadata::F16' +// gdbr-command:whatis basic_types_globals_metadata::F16 +// gdb-check:type = f16 // gdbg-command:whatis 'basic_types_globals_metadata::F32' // gdbr-command:whatis basic_types_globals_metadata::F32 // gdb-check:type = f32 @@ -51,6 +54,7 @@ #![allow(dead_code)] #![feature(omit_gdb_pretty_printer_section)] #![omit_gdb_pretty_printer_section] +#![feature(f16)] // N.B. These are `mut` only so they don't constant fold away. static mut B: bool = false; @@ -65,13 +69,14 @@ static mut U8: u8 = 100; static mut U16: u16 = 16; static mut U32: u32 = 32; static mut U64: u64 = 64; +static mut F16: f16 = 1.5; static mut F32: f32 = 2.5; static mut F64: f64 = 3.5; fn main() { _zzz(); // #break - let a = unsafe { (B, I, C, I8, I16, I32, I64, U, U8, U16, U32, U64, F32, F64) }; + let a = unsafe { (B, I, C, I8, I16, I32, I64, U, U8, U16, U32, U64, F16, F32, F64) }; } fn _zzz() {()} diff --git a/tests/debuginfo/basic-types-globals.rs b/tests/debuginfo/basic-types-globals.rs index 319e86ad46015..0425d14fa5a34 100644 --- a/tests/debuginfo/basic-types-globals.rs +++ b/tests/debuginfo/basic-types-globals.rs @@ -49,17 +49,21 @@ // gdbg-command:print 'basic_types_globals::U64' // gdbr-command:print U64 // gdb-check:$12 = 64 +// gdbg-command:print 'basic_types_globals::F16' +// gdbr-command:print F16 +// gdb-check:$13 = 1.5 // gdbg-command:print 'basic_types_globals::F32' // gdbr-command:print F32 -// gdb-check:$13 = 2.5 +// gdb-check:$14 = 2.5 // gdbg-command:print 'basic_types_globals::F64' // gdbr-command:print F64 -// gdb-check:$14 = 3.5 +// gdb-check:$15 = 3.5 // gdb-command:continue #![allow(unused_variables)] #![feature(omit_gdb_pretty_printer_section)] #![omit_gdb_pretty_printer_section] +#![feature(f16)] // N.B. These are `mut` only so they don't constant fold away. static mut B: bool = false; @@ -74,13 +78,14 @@ static mut U8: u8 = 100; static mut U16: u16 = 16; static mut U32: u32 = 32; static mut U64: u64 = 64; +static mut F16: f16 = 1.5; static mut F32: f32 = 2.5; static mut F64: f64 = 3.5; fn main() { _zzz(); // #break - let a = unsafe { (B, I, C, I8, I16, I32, I64, U, U8, U16, U32, U64, F32, F64) }; + let a = unsafe { (B, I, C, I8, I16, I32, I64, U, U8, U16, U32, U64, F16, F32, F64) }; } fn _zzz() {()} diff --git a/tests/debuginfo/basic-types-metadata.rs b/tests/debuginfo/basic-types-metadata.rs index 8a25c0c452413..5f953c81a138d 100644 --- a/tests/debuginfo/basic-types-metadata.rs +++ b/tests/debuginfo/basic-types-metadata.rs @@ -29,6 +29,8 @@ // gdb-check:type = u32 // gdb-command:whatis u64 // gdb-check:type = u64 +// gdb-command:whatis f16 +// gdb-check:type = f16 // gdb-command:whatis f32 // gdb-check:type = f32 // gdb-command:whatis f64 @@ -66,6 +68,7 @@ #![allow(unused_variables)] #![feature(omit_gdb_pretty_printer_section)] #![omit_gdb_pretty_printer_section] +#![feature(f16)] fn main() { let unit: () = (); @@ -81,6 +84,7 @@ fn main() { let u16: u16 = 16; let u32: u32 = 32; let u64: u64 = 64; + let f16: f16 = 1.5; let f32: f32 = 2.5; let f64: f64 = 3.5; let fnptr : fn() = _zzz; diff --git a/tests/debuginfo/basic-types-mut-globals.rs b/tests/debuginfo/basic-types-mut-globals.rs index c3e5f2534d314..c676fd737714d 100644 --- a/tests/debuginfo/basic-types-mut-globals.rs +++ b/tests/debuginfo/basic-types-mut-globals.rs @@ -5,7 +5,6 @@ // its numerical value. //@ min-lldb-version: 310 -//@ ignore-gdb // Test temporarily ignored due to debuginfo tests being disabled, see PR 47155 //@ compile-flags:-g @@ -49,62 +48,69 @@ // gdbg-command:print 'basic_types_mut_globals::U64' // gdbr-command:print U64 // gdb-check:$12 = 64 +// gdbg-command:print 'basic_types_mut_globals::F16' +// gdbr-command:print F16 +// gdb-check:$13 = 1.5 // gdbg-command:print 'basic_types_mut_globals::F32' // gdbr-command:print F32 -// gdb-check:$13 = 2.5 +// gdb-check:$14 = 2.5 // gdbg-command:print 'basic_types_mut_globals::F64' // gdbr-command:print F64 -// gdb-check:$14 = 3.5 +// gdb-check:$15 = 3.5 // gdb-command:continue // Check new values // gdbg-command:print 'basic_types_mut_globals'::B // gdbr-command:print B -// gdb-check:$15 = true +// gdb-check:$16 = true // gdbg-command:print 'basic_types_mut_globals'::I // gdbr-command:print I -// gdb-check:$16 = 2 +// gdb-check:$17 = 2 // gdbg-command:print/d 'basic_types_mut_globals'::C // gdbr-command:print C -// gdbg-check:$17 = 102 -// gdbr-check:$17 = 102 'f' +// gdbg-check:$18 = 102 +// gdbr-check:$18 = 102 'f' // gdbg-command:print/d 'basic_types_mut_globals'::I8 // gdbr-command:print/d I8 -// gdb-check:$18 = 78 +// gdb-check:$19 = 78 // gdbg-command:print 'basic_types_mut_globals'::I16 // gdbr-command:print I16 -// gdb-check:$19 = -26 +// gdb-check:$20 = -26 // gdbg-command:print 'basic_types_mut_globals'::I32 // gdbr-command:print I32 -// gdb-check:$20 = -12 +// gdb-check:$21 = -12 // gdbg-command:print 'basic_types_mut_globals'::I64 // gdbr-command:print I64 -// gdb-check:$21 = -54 +// gdb-check:$22 = -54 // gdbg-command:print 'basic_types_mut_globals'::U // gdbr-command:print U -// gdb-check:$22 = 5 +// gdb-check:$23 = 5 // gdbg-command:print/d 'basic_types_mut_globals'::U8 // gdbr-command:print/d U8 -// gdb-check:$23 = 20 +// gdb-check:$24 = 20 // gdbg-command:print 'basic_types_mut_globals'::U16 // gdbr-command:print U16 -// gdb-check:$24 = 32 +// gdb-check:$25 = 32 // gdbg-command:print 'basic_types_mut_globals'::U32 // gdbr-command:print U32 -// gdb-check:$25 = 16 +// gdb-check:$26 = 16 // gdbg-command:print 'basic_types_mut_globals'::U64 // gdbr-command:print U64 -// gdb-check:$26 = 128 +// gdb-check:$27 = 128 +// gdbg-command:print 'basic_types_mut_globals'::F16 +// gdbr-command:print F16 +// gdb-check:$28 = 2.25 // gdbg-command:print 'basic_types_mut_globals'::F32 // gdbr-command:print F32 -// gdb-check:$27 = 5.75 +// gdb-check:$29 = 5.75 // gdbg-command:print 'basic_types_mut_globals'::F64 // gdbr-command:print F64 -// gdb-check:$28 = 9.25 +// gdb-check:$30 = 9.25 #![allow(unused_variables)] #![feature(omit_gdb_pretty_printer_section)] #![omit_gdb_pretty_printer_section] +#![feature(f16)] static mut B: bool = false; static mut I: isize = -1; @@ -118,6 +124,7 @@ static mut U8: u8 = 100; static mut U16: u16 = 16; static mut U32: u32 = 32; static mut U64: u64 = 64; +static mut F16: f16 = 1.5; static mut F32: f32 = 2.5; static mut F64: f64 = 3.5; @@ -137,6 +144,7 @@ fn main() { U16 = 32; U32 = 16; U64 = 128; + F16 = 2.25; F32 = 5.75; F64 = 9.25; } diff --git a/tests/debuginfo/basic-types.rs b/tests/debuginfo/basic-types.rs index 13d85d326ee3d..10ffd74d3e909 100644 --- a/tests/debuginfo/basic-types.rs +++ b/tests/debuginfo/basic-types.rs @@ -39,13 +39,15 @@ // gdb-check:$11 = 32 // gdb-command:print u64 // gdb-check:$12 = 64 +// gdb-command:print f16 +// gdb-check:$13 = 1.5 // gdb-command:print f32 -// gdb-check:$13 = 2.5 +// gdb-check:$14 = 2.5 // gdb-command:print f64 -// gdb-check:$14 = 3.5 +// gdb-check:$15 = 3.5 // gdb-command:print s -// gdbg-check:$15 = {data_ptr = [...] "Hello, World!", length = 13} -// gdbr-check:$15 = "Hello, World!" +// gdbg-check:$16 = {data_ptr = [...] "Hello, World!", length = 13} +// gdbr-check:$16 = "Hello, World!" // === LLDB TESTS ================================================================================== @@ -122,6 +124,8 @@ // cdb-check:u32 : 0x20 [Type: unsigned int] // cdb-command:dx u64 // cdb-check:u64 : 0x40 [Type: unsigned __int64] +// cdb-command:dx f16 +// cdb-check:f16 : 1.500000 [Type: f16] // cdb-command:dx f32 // cdb-check:f32 : 2.500000 [Type: float] // cdb-command:dx f64 @@ -134,6 +138,7 @@ #![allow(unused_variables)] #![feature(omit_gdb_pretty_printer_section)] #![omit_gdb_pretty_printer_section] +#![feature(f16)] fn main() { let b: bool = false; @@ -148,6 +153,7 @@ fn main() { let u16: u16 = 16; let u32: u32 = 32; let u64: u64 = 64; + let f16: f16 = 1.5; let f32: f32 = 2.5; let f64: f64 = 3.5; let s: &str = "Hello, World!"; diff --git a/tests/debuginfo/borrowed-basic.rs b/tests/debuginfo/borrowed-basic.rs index e48e3dd055e43..e3cf74dab1e75 100644 --- a/tests/debuginfo/borrowed-basic.rs +++ b/tests/debuginfo/borrowed-basic.rs @@ -42,11 +42,14 @@ // gdb-command:print *u64_ref // gdb-check:$12 = 64 +// gdb-command:print *f16_ref +// gdb-check:$13 = 1.5 + // gdb-command:print *f32_ref -// gdb-check:$13 = 2.5 +// gdb-check:$14 = 2.5 // gdb-command:print *f64_ref -// gdb-check:$14 = 3.5 +// gdb-check:$15 = 3.5 // === LLDB TESTS ================================================================================== @@ -100,6 +103,10 @@ // lldbg-check:[...] 64 // lldbr-check:(u64) *u64_ref = 64 +// lldb-command:v *f16_ref +// lldbg-check:[...] 1.5 +// lldbr-check:(f16) *f16_ref = 1.5 + // lldb-command:v *f32_ref // lldbg-check:[...] 2.5 // lldbr-check:(f32) *f32_ref = 2.5 @@ -111,6 +118,7 @@ #![allow(unused_variables)] #![feature(omit_gdb_pretty_printer_section)] #![omit_gdb_pretty_printer_section] +#![feature(f16)] fn main() { let bool_val: bool = true; @@ -149,6 +157,9 @@ fn main() { let u64_val: u64 = 64; let u64_ref: &u64 = &u64_val; + let f16_val: f16 = 1.5; + let f16_ref: &f16 = &f16_val; + let f32_val: f32 = 2.5; let f32_ref: &f32 = &f32_val; diff --git a/tests/debuginfo/borrowed-unique-basic.rs b/tests/debuginfo/borrowed-unique-basic.rs index d6948a12851a5..e952ec8cebb52 100644 --- a/tests/debuginfo/borrowed-unique-basic.rs +++ b/tests/debuginfo/borrowed-unique-basic.rs @@ -42,11 +42,14 @@ // gdb-command:print *u64_ref // gdb-check:$12 = 64 +// gdb-command:print *f16_ref +// gdb-check:$13 = 1.5 + // gdb-command:print *f32_ref -// gdb-check:$13 = 2.5 +// gdb-check:$14 = 2.5 // gdb-command:print *f64_ref -// gdb-check:$14 = 3.5 +// gdb-check:$15 = 3.5 // === LLDB TESTS ================================================================================== @@ -103,6 +106,10 @@ // lldbg-check:[...] 64 // lldbr-check:(u64) *u64_ref = 64 +// lldb-command:v *f16_ref +// lldbg-check:[...] 1.5 +// lldbr-check:(f16) *f16_ref = 1.5 + // lldb-command:v *f32_ref // lldbg-check:[...] 2.5 // lldbr-check:(f32) *f32_ref = 2.5 @@ -114,6 +121,7 @@ #![allow(unused_variables)] #![feature(omit_gdb_pretty_printer_section)] #![omit_gdb_pretty_printer_section] +#![feature(f16)] fn main() { let bool_box: Box = Box::new(true); @@ -152,6 +160,9 @@ fn main() { let u64_box: Box = Box::new(64); let u64_ref: &u64 = &*u64_box; + let f16_box: Box = Box::new(1.5); + let f16_ref: &f16 = &*f16_box; + let f32_box: Box = Box::new(2.5); let f32_ref: &f32 = &*f32_box; diff --git a/tests/debuginfo/f16-natvis.rs b/tests/debuginfo/f16-natvis.rs new file mode 100644 index 0000000000000..9b9749f2bad46 --- /dev/null +++ b/tests/debuginfo/f16-natvis.rs @@ -0,0 +1,58 @@ +//@ compile-flags: -g +//@ only-msvc + +// This tests the `f16` Natvis visualiser. +// cdb-command:g +// cdb-command:dx v0_0 +// cdb-check:v0_0 : 0.000000 [Type: f16] +// cdb-command:dx neg_0_0 +// cdb-check:neg_0_0 : -0.000000 [Type: f16] +// cdb-command:dx v1_0 +// cdb-check:v1_0 : 1.000000 [Type: f16] +// cdb-command:dx v1_5 +// cdb-check:v1_5 : 1.500000 [Type: f16] +// cdb-command:dx v72_3 +// cdb-check:v72_3 : 72.312500 [Type: f16] +// cdb-command:dx neg_0_126 +// cdb-check:neg_0_126 : -0.125977 [Type: f16] +// cdb-command:dx v0_00003 +// cdb-check:v0_00003 : 0.000030 [Type: f16] +// cdb-command:dx neg_0_00004 +// cdb-check:neg_0_00004 : -0.000040 [Type: f16] +// cdb-command:dx max +// cdb-check:max : 65504.000000 [Type: f16] +// cdb-command:dx min +// cdb-check:min : -65504.000000 [Type: f16] +// cdb-command:dx inf +// cdb-check:inf : inf [Type: f16] +// cdb-command:dx neg_inf +// cdb-check:neg_inf : -inf [Type: f16] +// cdb-command:dx nan +// cdb-check:nan : NaN [Type: f16] +// cdb-command:dx other_nan +// cdb-check:other_nan : NaN [Type: f16] + +#![feature(f16)] + +fn main() { + let v0_0 = 0.0_f16; + let neg_0_0 = -0.0_f16; + let v1_0 = 1.0_f16; + let v1_5 = 1.5_f16; + let v72_3 = 72.3_f16; + let neg_0_126 = -0.126_f16; + let v0_00003 = 0.00003_f16; + let neg_0_00004 = -0.00004_f16; + let max = f16::MAX; + let min = f16::MIN; + let inf = f16::INFINITY; + let neg_inf = f16::NEG_INFINITY; + let nan = f16::NAN; + let other_nan = f16::from_bits(0xfc02); + + _zzz(); // #break +} + +fn _zzz() { + () +} diff --git a/tests/debuginfo/reference-debuginfo.rs b/tests/debuginfo/reference-debuginfo.rs index 339839f07cca9..e2fb964ace521 100644 --- a/tests/debuginfo/reference-debuginfo.rs +++ b/tests/debuginfo/reference-debuginfo.rs @@ -46,14 +46,17 @@ // gdb-command:print *u64_ref // gdb-check:$12 = 64 +// gdb-command:print *f16_ref +// gdb-check:$13 = 1.5 + // gdb-command:print *f32_ref -// gdb-check:$13 = 2.5 +// gdb-check:$14 = 2.5 // gdb-command:print *f64_ref -// gdb-check:$14 = 3.5 +// gdb-check:$15 = 3.5 // gdb-command:print *f64_double_ref -// gdb-check:$15 = 3.5 +// gdb-check:$16 = 3.5 // === LLDB TESTS ================================================================================== @@ -107,6 +110,10 @@ // lldbg-check:[...] 64 // lldbr-check:(u64) *u64_ref = 64 +// lldb-command:v *f16_ref +// lldbg-check:[...] 1.5 +// lldbr-check:(f16) *f16_ref = 1.5 + // lldb-command:v *f32_ref // lldbg-check:[...] 2.5 // lldbr-check:(f32) *f32_ref = 2.5 @@ -122,6 +129,7 @@ #![allow(unused_variables)] #![feature(omit_gdb_pretty_printer_section)] #![omit_gdb_pretty_printer_section] +#![feature(f16)] fn main() { let bool_val: bool = true; @@ -160,6 +168,9 @@ fn main() { let u64_val: u64 = 64; let u64_ref: &u64 = &u64_val; + let f16_val: f16 = 1.5; + let f16_ref: &f16 = &f16_val; + let f32_val: f32 = 2.5; let f32_ref: &f32 = &f32_val; From 4f6140258f438fdc180bad140d313af472207fac Mon Sep 17 00:00:00 2001 From: zhuyunxing Date: Thu, 4 Jul 2024 17:59:38 +0800 Subject: [PATCH 846/892] coverage. Group mcdc tests in one directory --- .../coverage/{mcdc_if.cov-map => mcdc/if.cov-map} | 14 +++++++------- .../{mcdc_if.coverage => mcdc/if.coverage} | 0 tests/coverage/{mcdc_if.rs => mcdc/if.rs} | 0 .../nested_if.cov-map} | 8 ++++---- .../nested_if.coverage} | 0 .../{mcdc_nested_if.rs => mcdc/nested_if.rs} | 0 .../non_control_flow.cov-map} | 14 +++++++------- .../non_control_flow.coverage} | 0 .../non_control_flow.rs} | 0 9 files changed, 18 insertions(+), 18 deletions(-) rename tests/coverage/{mcdc_if.cov-map => mcdc/if.cov-map} (97%) rename tests/coverage/{mcdc_if.coverage => mcdc/if.coverage} (100%) rename tests/coverage/{mcdc_if.rs => mcdc/if.rs} (100%) rename tests/coverage/{mcdc_nested_if.cov-map => mcdc/nested_if.cov-map} (98%) rename tests/coverage/{mcdc_nested_if.coverage => mcdc/nested_if.coverage} (100%) rename tests/coverage/{mcdc_nested_if.rs => mcdc/nested_if.rs} (100%) rename tests/coverage/{mcdc_non_control_flow.cov-map => mcdc/non_control_flow.cov-map} (97%) rename tests/coverage/{mcdc_non_control_flow.coverage => mcdc/non_control_flow.coverage} (100%) rename tests/coverage/{mcdc_non_control_flow.rs => mcdc/non_control_flow.rs} (100%) diff --git a/tests/coverage/mcdc_if.cov-map b/tests/coverage/mcdc/if.cov-map similarity index 97% rename from tests/coverage/mcdc_if.cov-map rename to tests/coverage/mcdc/if.cov-map index 35a265684d2f6..9a7d15f700df0 100644 --- a/tests/coverage/mcdc_if.cov-map +++ b/tests/coverage/mcdc/if.cov-map @@ -1,4 +1,4 @@ -Function name: mcdc_if::mcdc_check_a +Function name: if::mcdc_check_a Raw bytes (64): 0x[01, 01, 04, 01, 05, 09, 02, 0d, 0f, 09, 02, 08, 01, 0f, 01, 01, 09, 28, 00, 02, 01, 08, 00, 0e, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 05, 00, 0d, 00, 0e, 30, 0d, 09, 02, 00, 00, 00, 0d, 00, 0e, 0d, 00, 0f, 02, 06, 0f, 02, 0c, 02, 06, 0b, 03, 01, 00, 02] Number of files: 1 - file 0 => global file 1 @@ -23,7 +23,7 @@ Number of file 0 mappings: 8 - Code(Expression(2, Add)) at (prev + 3, 1) to (start + 0, 2) = (c3 + (c2 + (c0 - c1))) -Function name: mcdc_if::mcdc_check_b +Function name: if::mcdc_check_b Raw bytes (64): 0x[01, 01, 04, 01, 05, 09, 02, 0d, 0f, 09, 02, 08, 01, 17, 01, 01, 09, 28, 00, 02, 01, 08, 00, 0e, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 05, 00, 0d, 00, 0e, 30, 0d, 09, 02, 00, 00, 00, 0d, 00, 0e, 0d, 00, 0f, 02, 06, 0f, 02, 0c, 02, 06, 0b, 03, 01, 00, 02] Number of files: 1 - file 0 => global file 1 @@ -48,7 +48,7 @@ Number of file 0 mappings: 8 - Code(Expression(2, Add)) at (prev + 3, 1) to (start + 0, 2) = (c3 + (c2 + (c0 - c1))) -Function name: mcdc_if::mcdc_check_both +Function name: if::mcdc_check_both Raw bytes (64): 0x[01, 01, 04, 01, 05, 09, 02, 0d, 0f, 09, 02, 08, 01, 1f, 01, 01, 09, 28, 00, 02, 01, 08, 00, 0e, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 05, 00, 0d, 00, 0e, 30, 0d, 09, 02, 00, 00, 00, 0d, 00, 0e, 0d, 00, 0f, 02, 06, 0f, 02, 0c, 02, 06, 0b, 03, 01, 00, 02] Number of files: 1 - file 0 => global file 1 @@ -73,7 +73,7 @@ Number of file 0 mappings: 8 - Code(Expression(2, Add)) at (prev + 3, 1) to (start + 0, 2) = (c3 + (c2 + (c0 - c1))) -Function name: mcdc_if::mcdc_check_neither +Function name: if::mcdc_check_neither Raw bytes (64): 0x[01, 01, 04, 01, 05, 09, 02, 0d, 0f, 09, 02, 08, 01, 07, 01, 01, 09, 28, 00, 02, 01, 08, 00, 0e, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 05, 00, 0d, 00, 0e, 30, 0d, 09, 02, 00, 00, 00, 0d, 00, 0e, 0d, 00, 0f, 02, 06, 0f, 02, 0c, 02, 06, 0b, 03, 01, 00, 02] Number of files: 1 - file 0 => global file 1 @@ -98,7 +98,7 @@ Number of file 0 mappings: 8 - Code(Expression(2, Add)) at (prev + 3, 1) to (start + 0, 2) = (c3 + (c2 + (c0 - c1))) -Function name: mcdc_if::mcdc_check_not_tree_decision +Function name: if::mcdc_check_not_tree_decision Raw bytes (87): 0x[01, 01, 08, 01, 05, 02, 09, 05, 09, 0d, 1e, 02, 09, 11, 1b, 0d, 1e, 02, 09, 0a, 01, 31, 01, 03, 0a, 28, 00, 03, 03, 08, 00, 15, 30, 05, 02, 01, 02, 03, 00, 09, 00, 0a, 02, 00, 0e, 00, 0f, 30, 09, 1e, 03, 02, 00, 00, 0e, 00, 0f, 0b, 00, 14, 00, 15, 30, 11, 0d, 02, 00, 00, 00, 14, 00, 15, 11, 00, 16, 02, 06, 1b, 02, 0c, 02, 06, 17, 03, 01, 00, 02] Number of files: 1 - file 0 => global file 1 @@ -133,7 +133,7 @@ Number of file 0 mappings: 10 - Code(Expression(5, Add)) at (prev + 3, 1) to (start + 0, 2) = (c4 + (c3 + ((c0 - c1) - c2))) -Function name: mcdc_if::mcdc_check_tree_decision +Function name: if::mcdc_check_tree_decision Raw bytes (87): 0x[01, 01, 08, 01, 05, 05, 0d, 05, 0d, 0d, 11, 09, 02, 1b, 1f, 0d, 11, 09, 02, 0a, 01, 27, 01, 03, 09, 28, 00, 03, 03, 08, 00, 15, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 05, 00, 0e, 00, 0f, 30, 0d, 0a, 02, 00, 03, 00, 0e, 00, 0f, 0a, 00, 13, 00, 14, 30, 11, 09, 03, 00, 00, 00, 13, 00, 14, 1b, 00, 16, 02, 06, 1f, 02, 0c, 02, 06, 17, 03, 01, 00, 02] Number of files: 1 - file 0 => global file 1 @@ -168,7 +168,7 @@ Number of file 0 mappings: 10 - Code(Expression(5, Add)) at (prev + 3, 1) to (start + 0, 2) = ((c3 + c4) + (c2 + (c0 - c1))) -Function name: mcdc_if::mcdc_nested_if +Function name: if::mcdc_nested_if Raw bytes (124): 0x[01, 01, 0d, 01, 05, 02, 09, 05, 09, 1b, 15, 05, 09, 1b, 15, 05, 09, 11, 15, 02, 09, 2b, 32, 0d, 2f, 11, 15, 02, 09, 0e, 01, 3b, 01, 01, 09, 28, 00, 02, 01, 08, 00, 0e, 30, 05, 02, 01, 00, 02, 00, 08, 00, 09, 02, 00, 0d, 00, 0e, 30, 09, 32, 02, 00, 00, 00, 0d, 00, 0e, 1b, 01, 09, 01, 0d, 28, 01, 02, 01, 0c, 00, 12, 30, 16, 15, 01, 02, 00, 00, 0c, 00, 0d, 16, 00, 11, 00, 12, 30, 0d, 11, 02, 00, 00, 00, 11, 00, 12, 0d, 00, 13, 02, 0a, 2f, 02, 0a, 00, 0b, 32, 01, 0c, 02, 06, 27, 03, 01, 00, 02] Number of files: 1 - file 0 => global file 1 diff --git a/tests/coverage/mcdc_if.coverage b/tests/coverage/mcdc/if.coverage similarity index 100% rename from tests/coverage/mcdc_if.coverage rename to tests/coverage/mcdc/if.coverage diff --git a/tests/coverage/mcdc_if.rs b/tests/coverage/mcdc/if.rs similarity index 100% rename from tests/coverage/mcdc_if.rs rename to tests/coverage/mcdc/if.rs diff --git a/tests/coverage/mcdc_nested_if.cov-map b/tests/coverage/mcdc/nested_if.cov-map similarity index 98% rename from tests/coverage/mcdc_nested_if.cov-map rename to tests/coverage/mcdc/nested_if.cov-map index 2f35ffad8a98e..adeb6cbc1fb89 100644 --- a/tests/coverage/mcdc_nested_if.cov-map +++ b/tests/coverage/mcdc/nested_if.cov-map @@ -1,4 +1,4 @@ -Function name: mcdc_nested_if::doubly_nested_if_in_condition +Function name: nested_if::doubly_nested_if_in_condition Raw bytes (168): 0x[01, 01, 0e, 01, 05, 05, 11, 05, 11, 26, 19, 05, 11, 19, 1d, 19, 1d, 1d, 22, 26, 19, 05, 11, 11, 15, 09, 02, 0d, 37, 09, 02, 14, 01, 0f, 01, 01, 09, 28, 02, 02, 01, 08, 00, 4e, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 30, 0d, 09, 02, 00, 00, 00, 0d, 00, 4e, 05, 00, 10, 00, 11, 28, 01, 02, 00, 10, 00, 36, 30, 11, 26, 01, 00, 02, 00, 10, 00, 11, 30, 15, 21, 02, 00, 00, 00, 15, 00, 36, 26, 00, 18, 00, 19, 28, 00, 02, 00, 18, 00, 1e, 30, 19, 22, 01, 02, 00, 00, 18, 00, 19, 19, 00, 1d, 00, 1e, 30, 1a, 1d, 02, 00, 00, 00, 1d, 00, 1e, 1a, 00, 21, 00, 25, 1f, 00, 2f, 00, 34, 2b, 00, 39, 00, 3e, 21, 00, 48, 00, 4c, 0d, 00, 4f, 02, 06, 37, 02, 0c, 02, 06, 33, 03, 01, 00, 02] Number of files: 1 - file 0 => global file 1 @@ -57,7 +57,7 @@ Number of file 0 mappings: 20 - Code(Expression(12, Add)) at (prev + 3, 1) to (start + 0, 2) = (c3 + (c2 + (c0 - c1))) -Function name: mcdc_nested_if::nested_if_in_condition +Function name: nested_if::nested_if_in_condition Raw bytes (120): 0x[01, 01, 0b, 01, 05, 05, 11, 05, 11, 1e, 15, 05, 11, 11, 15, 1e, 15, 05, 11, 09, 02, 0d, 2b, 09, 02, 0e, 01, 07, 01, 01, 09, 28, 01, 02, 01, 08, 00, 2e, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 30, 0d, 09, 02, 00, 00, 00, 0d, 00, 2e, 05, 00, 10, 00, 11, 28, 00, 02, 00, 10, 00, 16, 30, 11, 1e, 01, 00, 02, 00, 10, 00, 11, 1e, 00, 15, 00, 16, 30, 15, 1a, 02, 00, 00, 00, 15, 00, 16, 17, 00, 19, 00, 1d, 1a, 00, 27, 00, 2c, 0d, 00, 2f, 02, 06, 2b, 02, 0c, 02, 06, 27, 03, 01, 00, 02] Number of files: 1 - file 0 => global file 1 @@ -102,7 +102,7 @@ Number of file 0 mappings: 14 - Code(Expression(9, Add)) at (prev + 3, 1) to (start + 0, 2) = (c3 + (c2 + (c0 - c1))) -Function name: mcdc_nested_if::nested_in_then_block_in_condition +Function name: nested_if::nested_in_then_block_in_condition Raw bytes (176): 0x[01, 01, 12, 01, 05, 05, 11, 05, 11, 3a, 15, 05, 11, 11, 15, 33, 19, 11, 15, 19, 1d, 19, 1d, 1d, 2e, 33, 19, 11, 15, 3a, 15, 05, 11, 09, 02, 0d, 47, 09, 02, 14, 01, 22, 01, 01, 09, 28, 02, 02, 01, 08, 00, 4b, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 30, 0d, 09, 02, 00, 00, 00, 0d, 00, 4b, 05, 00, 10, 00, 11, 28, 00, 02, 00, 10, 00, 16, 30, 11, 3a, 01, 00, 02, 00, 10, 00, 11, 3a, 00, 15, 00, 16, 30, 15, 36, 02, 00, 00, 00, 15, 00, 16, 33, 00, 1c, 00, 1d, 28, 01, 02, 00, 1c, 00, 22, 30, 19, 2e, 01, 02, 00, 00, 1c, 00, 1d, 19, 00, 21, 00, 22, 30, 26, 1d, 02, 00, 00, 00, 21, 00, 22, 26, 00, 25, 00, 29, 2b, 00, 33, 00, 38, 36, 00, 44, 00, 49, 0d, 00, 4c, 02, 06, 47, 02, 0c, 02, 06, 43, 03, 01, 00, 02] Number of files: 1 - file 0 => global file 1 @@ -166,7 +166,7 @@ Number of file 0 mappings: 20 - Code(Expression(16, Add)) at (prev + 3, 1) to (start + 0, 2) = (c3 + (c2 + (c0 - c1))) -Function name: mcdc_nested_if::nested_single_condition_decision +Function name: nested_if::nested_single_condition_decision Raw bytes (85): 0x[01, 01, 06, 01, 05, 05, 11, 05, 11, 09, 02, 0d, 17, 09, 02, 0b, 01, 17, 01, 04, 09, 28, 00, 02, 04, 08, 00, 29, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 30, 0d, 09, 02, 00, 00, 00, 0d, 00, 29, 05, 00, 10, 00, 11, 20, 11, 0a, 00, 10, 00, 11, 11, 00, 14, 00, 19, 0a, 00, 23, 00, 27, 0d, 00, 2a, 02, 06, 17, 02, 0c, 02, 06, 13, 03, 01, 00, 02] Number of files: 1 - file 0 => global file 1 diff --git a/tests/coverage/mcdc_nested_if.coverage b/tests/coverage/mcdc/nested_if.coverage similarity index 100% rename from tests/coverage/mcdc_nested_if.coverage rename to tests/coverage/mcdc/nested_if.coverage diff --git a/tests/coverage/mcdc_nested_if.rs b/tests/coverage/mcdc/nested_if.rs similarity index 100% rename from tests/coverage/mcdc_nested_if.rs rename to tests/coverage/mcdc/nested_if.rs diff --git a/tests/coverage/mcdc_non_control_flow.cov-map b/tests/coverage/mcdc/non_control_flow.cov-map similarity index 97% rename from tests/coverage/mcdc_non_control_flow.cov-map rename to tests/coverage/mcdc/non_control_flow.cov-map index 937c36e1f16c4..f8576831e75f1 100644 --- a/tests/coverage/mcdc_non_control_flow.cov-map +++ b/tests/coverage/mcdc/non_control_flow.cov-map @@ -1,4 +1,4 @@ -Function name: mcdc_non_control_flow::assign_3 +Function name: non_control_flow::assign_3 Raw bytes (89): 0x[01, 01, 09, 05, 07, 0b, 11, 09, 0d, 01, 05, 01, 05, 22, 11, 01, 05, 22, 11, 01, 05, 0a, 01, 16, 01, 00, 28, 03, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 28, 00, 03, 00, 0d, 00, 18, 30, 05, 22, 01, 00, 02, 00, 0d, 00, 0e, 22, 00, 12, 00, 13, 30, 1e, 11, 02, 03, 00, 00, 12, 00, 13, 1e, 00, 17, 00, 18, 30, 09, 0d, 03, 00, 00, 00, 17, 00, 18, 03, 01, 05, 01, 02] Number of files: 1 - file 0 => global file 1 @@ -34,7 +34,7 @@ Number of file 0 mappings: 10 - Code(Expression(0, Add)) at (prev + 1, 5) to (start + 1, 2) = (c1 + ((c2 + c3) + c4)) -Function name: mcdc_non_control_flow::assign_3_bis +Function name: non_control_flow::assign_3_bis Raw bytes (85): 0x[01, 01, 07, 07, 11, 09, 0d, 01, 05, 05, 09, 16, 1a, 05, 09, 01, 05, 0a, 01, 1b, 01, 00, 2c, 03, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 28, 00, 03, 00, 0d, 00, 18, 30, 05, 1a, 01, 03, 02, 00, 0d, 00, 0e, 05, 00, 12, 00, 13, 30, 09, 16, 03, 00, 02, 00, 12, 00, 13, 13, 00, 17, 00, 18, 30, 0d, 11, 02, 00, 00, 00, 17, 00, 18, 03, 01, 05, 01, 02] Number of files: 1 - file 0 => global file 1 @@ -67,7 +67,7 @@ Number of file 0 mappings: 10 - Code(Expression(0, Add)) at (prev + 1, 5) to (start + 1, 2) = ((c2 + c3) + c4) -Function name: mcdc_non_control_flow::assign_and +Function name: non_control_flow::assign_and Raw bytes (64): 0x[01, 01, 04, 07, 0e, 09, 0d, 01, 05, 01, 05, 08, 01, 0c, 01, 00, 21, 03, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 28, 00, 02, 00, 0d, 00, 13, 30, 05, 0e, 01, 02, 00, 00, 0d, 00, 0e, 05, 00, 12, 00, 13, 30, 09, 0d, 02, 00, 00, 00, 12, 00, 13, 03, 01, 05, 01, 02] Number of files: 1 - file 0 => global file 1 @@ -92,7 +92,7 @@ Number of file 0 mappings: 8 - Code(Expression(0, Add)) at (prev + 1, 5) to (start + 1, 2) = ((c2 + c3) + (c0 - c1)) -Function name: mcdc_non_control_flow::assign_or +Function name: non_control_flow::assign_or Raw bytes (64): 0x[01, 01, 04, 07, 0d, 05, 09, 01, 05, 01, 05, 08, 01, 11, 01, 00, 20, 03, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 28, 00, 02, 00, 0d, 00, 13, 30, 05, 0e, 01, 00, 02, 00, 0d, 00, 0e, 0e, 00, 12, 00, 13, 30, 09, 0d, 02, 00, 00, 00, 12, 00, 13, 03, 01, 05, 01, 02] Number of files: 1 - file 0 => global file 1 @@ -118,7 +118,7 @@ Number of file 0 mappings: 8 - Code(Expression(0, Add)) at (prev + 1, 5) to (start + 1, 2) = ((c1 + c2) + c3) -Function name: mcdc_non_control_flow::foo +Function name: non_control_flow::foo Raw bytes (9): 0x[01, 01, 00, 01, 01, 25, 01, 02, 02] Number of files: 1 - file 0 => global file 1 @@ -126,7 +126,7 @@ Number of expressions: 0 Number of file 0 mappings: 1 - Code(Counter(0)) at (prev + 37, 1) to (start + 2, 2) -Function name: mcdc_non_control_flow::func_call +Function name: non_control_flow::func_call Raw bytes (52): 0x[01, 01, 03, 01, 05, 0b, 02, 09, 0d, 06, 01, 29, 01, 01, 0a, 28, 00, 02, 01, 09, 00, 0f, 30, 05, 02, 01, 02, 00, 00, 09, 00, 0a, 05, 00, 0e, 00, 0f, 30, 09, 0d, 02, 00, 00, 00, 0e, 00, 0f, 07, 01, 01, 00, 02] Number of files: 1 - file 0 => global file 1 @@ -147,7 +147,7 @@ Number of file 0 mappings: 6 - Code(Expression(1, Add)) at (prev + 1, 1) to (start + 0, 2) = ((c2 + c3) + (c0 - c1)) -Function name: mcdc_non_control_flow::right_comb_tree +Function name: non_control_flow::right_comb_tree Raw bytes (139): 0x[01, 01, 13, 07, 1a, 0b, 19, 0f, 15, 13, 11, 09, 0d, 01, 05, 01, 05, 05, 19, 05, 19, 4a, 15, 05, 19, 4a, 15, 05, 19, 46, 11, 4a, 15, 05, 19, 46, 11, 4a, 15, 05, 19, 0e, 01, 20, 01, 00, 41, 03, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 28, 00, 05, 00, 0d, 00, 2a, 30, 05, 1a, 01, 02, 00, 00, 0d, 00, 0e, 05, 00, 13, 00, 14, 30, 4a, 19, 02, 03, 00, 00, 13, 00, 14, 4a, 00, 19, 00, 1a, 30, 46, 15, 03, 04, 00, 00, 19, 00, 1a, 46, 00, 1f, 00, 20, 30, 42, 11, 04, 05, 00, 00, 1f, 00, 20, 42, 00, 24, 00, 27, 30, 09, 0d, 05, 00, 00, 00, 24, 00, 27, 03, 01, 05, 01, 02] Number of files: 1 - file 0 => global file 1 diff --git a/tests/coverage/mcdc_non_control_flow.coverage b/tests/coverage/mcdc/non_control_flow.coverage similarity index 100% rename from tests/coverage/mcdc_non_control_flow.coverage rename to tests/coverage/mcdc/non_control_flow.coverage diff --git a/tests/coverage/mcdc_non_control_flow.rs b/tests/coverage/mcdc/non_control_flow.rs similarity index 100% rename from tests/coverage/mcdc_non_control_flow.rs rename to tests/coverage/mcdc/non_control_flow.rs From c77788f011ee04cfc825926d89647af5ac3f6aa5 Mon Sep 17 00:00:00 2001 From: zhuyunxing Date: Tue, 2 Jul 2024 14:24:43 +0800 Subject: [PATCH 847/892] coverage. MCDC tests also report branches coverage --- tests/coverage/mcdc/if.coverage | 28 ++++++++++++++++++- tests/coverage/mcdc/if.rs | 2 +- tests/coverage/mcdc/nested_if.coverage | 25 ++++++++++++++++- tests/coverage/mcdc/nested_if.rs | 2 +- tests/coverage/mcdc/non_control_flow.coverage | 25 ++++++++++++++++- tests/coverage/mcdc/non_control_flow.rs | 2 +- 6 files changed, 78 insertions(+), 6 deletions(-) diff --git a/tests/coverage/mcdc/if.coverage b/tests/coverage/mcdc/if.coverage index c2ed311a5bc2c..91fff073d0cff 100644 --- a/tests/coverage/mcdc/if.coverage +++ b/tests/coverage/mcdc/if.coverage @@ -2,12 +2,15 @@ LL| |//@ edition: 2021 LL| |//@ min-llvm-version: 18 LL| |//@ compile-flags: -Zcoverage-options=mcdc - LL| |//@ llvm-cov-flags: --show-mcdc + LL| |//@ llvm-cov-flags: --show-branches=count --show-mcdc LL| | LL| 2|fn mcdc_check_neither(a: bool, b: bool) { LL| 2| if a && b { ^0 ------------------ + | Branch (LL:8): [True: 0, False: 2] + | Branch (LL:13): [True: 0, False: 0] + ------------------ |---> MC/DC Decision Region (LL:8) to (LL:14) | | Number of Conditions: 2 @@ -34,6 +37,9 @@ LL| 2| if a && b { ^1 ------------------ + | Branch (LL:8): [True: 1, False: 1] + | Branch (LL:13): [True: 1, False: 0] + ------------------ |---> MC/DC Decision Region (LL:8) to (LL:14) | | Number of Conditions: 2 @@ -60,6 +66,9 @@ LL| 2|fn mcdc_check_b(a: bool, b: bool) { LL| 2| if a && b { ------------------ + | Branch (LL:8): [True: 2, False: 0] + | Branch (LL:13): [True: 1, False: 1] + ------------------ |---> MC/DC Decision Region (LL:8) to (LL:14) | | Number of Conditions: 2 @@ -87,6 +96,9 @@ LL| 3| if a && b { ^2 ------------------ + | Branch (LL:8): [True: 2, False: 1] + | Branch (LL:13): [True: 1, False: 1] + ------------------ |---> MC/DC Decision Region (LL:8) to (LL:14) | | Number of Conditions: 2 @@ -117,6 +129,10 @@ LL| 4| if a && (b || c) { ^3 ^2 ------------------ + | Branch (LL:8): [True: 3, False: 1] + | Branch (LL:14): [True: 1, False: 2] + | Branch (LL:19): [True: 1, False: 1] + ------------------ |---> MC/DC Decision Region (LL:8) to (LL:21) | | Number of Conditions: 3 @@ -150,6 +166,10 @@ LL| 4| if (a || b) && c { ^1 ------------------ + | Branch (LL:9): [True: 3, False: 1] + | Branch (LL:14): [True: 1, False: 0] + | Branch (LL:20): [True: 2, False: 2] + ------------------ |---> MC/DC Decision Region (LL:8) to (LL:21) | | Number of Conditions: 3 @@ -180,6 +200,9 @@ LL| 3| if a || b { ^0 ------------------ + | Branch (LL:8): [True: 3, False: 0] + | Branch (LL:13): [True: 0, False: 0] + ------------------ |---> MC/DC Decision Region (LL:8) to (LL:14) | | Number of Conditions: 2 @@ -200,6 +223,9 @@ LL| 3| if b && c { ^2 ------------------ + | Branch (LL:12): [True: 2, False: 1] + | Branch (LL:17): [True: 1, False: 1] + ------------------ |---> MC/DC Decision Region (LL:12) to (LL:18) | | Number of Conditions: 2 diff --git a/tests/coverage/mcdc/if.rs b/tests/coverage/mcdc/if.rs index a85843721c6ce..d8e6b61a9d59d 100644 --- a/tests/coverage/mcdc/if.rs +++ b/tests/coverage/mcdc/if.rs @@ -2,7 +2,7 @@ //@ edition: 2021 //@ min-llvm-version: 18 //@ compile-flags: -Zcoverage-options=mcdc -//@ llvm-cov-flags: --show-mcdc +//@ llvm-cov-flags: --show-branches=count --show-mcdc fn mcdc_check_neither(a: bool, b: bool) { if a && b { diff --git a/tests/coverage/mcdc/nested_if.coverage b/tests/coverage/mcdc/nested_if.coverage index 19529cd6aa432..a273a713a8ab8 100644 --- a/tests/coverage/mcdc/nested_if.coverage +++ b/tests/coverage/mcdc/nested_if.coverage @@ -2,12 +2,17 @@ LL| |//@ edition: 2021 LL| |//@ min-llvm-version: 18 LL| |//@ compile-flags: -Zcoverage-options=mcdc - LL| |//@ llvm-cov-flags: --show-mcdc + LL| |//@ llvm-cov-flags: --show-branches=count --show-mcdc LL| | LL| 4|fn nested_if_in_condition(a: bool, b: bool, c: bool) { LL| 4| if a && if b || c { true } else { false } { ^3 ^2 ^2 ^1 ------------------ + | Branch (LL:8): [True: 3, False: 1] + | Branch (LL:13): [True: 2, False: 1] + | Branch (LL:16): [True: 1, False: 2] + | Branch (LL:21): [True: 1, False: 1] + ------------------ |---> MC/DC Decision Region (LL:8) to (LL:46) | | Number of Conditions: 2 @@ -53,6 +58,13 @@ LL| 4| if a && if b || if c && d { true } else { false } { false } else { true } { ^3 ^2 ^1 ^1 ^1 ^2 ^1 ------------------ + | Branch (LL:8): [True: 3, False: 1] + | Branch (LL:13): [True: 1, False: 2] + | Branch (LL:16): [True: 1, False: 2] + | Branch (LL:21): [True: 1, False: 1] + | Branch (LL:24): [True: 1, False: 1] + | Branch (LL:29): [True: 1, False: 0] + ------------------ |---> MC/DC Decision Region (LL:8) to (LL:78) | | Number of Conditions: 2 @@ -117,6 +129,10 @@ LL| 3| if a && if b { false } else { true } { ^2 ^1 ^1 ------------------ + | Branch (LL:8): [True: 2, False: 1] + | Branch (LL:13): [True: 1, False: 1] + | Branch (LL:16): [True: 1, False: 1] + ------------------ |---> MC/DC Decision Region (LL:8) to (LL:41) | | Number of Conditions: 2 @@ -145,6 +161,13 @@ LL| 7| if a && if b || c { if d && e { true } else { false } } else { false } { ^6 ^5 ^5 ^2 ^1 ^4 ^1 ------------------ + | Branch (LL:8): [True: 6, False: 1] + | Branch (LL:13): [True: 1, False: 5] + | Branch (LL:16): [True: 1, False: 5] + | Branch (LL:21): [True: 4, False: 1] + | Branch (LL:28): [True: 2, False: 3] + | Branch (LL:33): [True: 1, False: 1] + ------------------ |---> MC/DC Decision Region (LL:8) to (LL:75) | | Number of Conditions: 2 diff --git a/tests/coverage/mcdc/nested_if.rs b/tests/coverage/mcdc/nested_if.rs index 3d869771f75b5..f5068b5dcc23f 100644 --- a/tests/coverage/mcdc/nested_if.rs +++ b/tests/coverage/mcdc/nested_if.rs @@ -2,7 +2,7 @@ //@ edition: 2021 //@ min-llvm-version: 18 //@ compile-flags: -Zcoverage-options=mcdc -//@ llvm-cov-flags: --show-mcdc +//@ llvm-cov-flags: --show-branches=count --show-mcdc fn nested_if_in_condition(a: bool, b: bool, c: bool) { if a && if b || c { true } else { false } { diff --git a/tests/coverage/mcdc/non_control_flow.coverage b/tests/coverage/mcdc/non_control_flow.coverage index cd733885a98b6..6ae796e8ed203 100644 --- a/tests/coverage/mcdc/non_control_flow.coverage +++ b/tests/coverage/mcdc/non_control_flow.coverage @@ -2,7 +2,7 @@ LL| |//@ edition: 2021 LL| |//@ min-llvm-version: 18 LL| |//@ compile-flags: -Zcoverage-options=mcdc - LL| |//@ llvm-cov-flags: --show-mcdc + LL| |//@ llvm-cov-flags: --show-branches=count --show-mcdc LL| | LL| |// This test ensures that boolean expressions that are not inside control flow LL| |// decisions are correctly instrumented. @@ -13,6 +13,9 @@ LL| 3| let x = a && b; ^2 ------------------ + | Branch (LL:13): [True: 2, False: 1] + | Branch (LL:18): [True: 1, False: 1] + ------------------ |---> MC/DC Decision Region (LL:13) to (LL:19) | | Number of Conditions: 2 @@ -38,6 +41,9 @@ LL| 3| let x = a || b; ^1 ------------------ + | Branch (LL:13): [True: 2, False: 1] + | Branch (LL:18): [True: 0, False: 1] + ------------------ |---> MC/DC Decision Region (LL:13) to (LL:19) | | Number of Conditions: 2 @@ -62,6 +68,10 @@ LL| 4| let x = a || b && c; ^2 ^1 ------------------ + | Branch (LL:13): [True: 2, False: 2] + | Branch (LL:18): [True: 1, False: 1] + | Branch (LL:23): [True: 1, False: 0] + ------------------ |---> MC/DC Decision Region (LL:13) to (LL:24) | | Number of Conditions: 3 @@ -89,6 +99,10 @@ LL| 4| let x = a && b || c; ^2 ^3 ------------------ + | Branch (LL:13): [True: 2, False: 2] + | Branch (LL:18): [True: 1, False: 1] + | Branch (LL:23): [True: 2, False: 1] + ------------------ |---> MC/DC Decision Region (LL:13) to (LL:24) | | Number of Conditions: 3 @@ -116,6 +130,12 @@ LL| 3| let x = a && (b && (c && (d && (e)))); ^2 ^1 ^1 ^1 ------------------ + | Branch (LL:13): [True: 2, False: 1] + | Branch (LL:19): [True: 1, False: 1] + | Branch (LL:25): [True: 1, False: 0] + | Branch (LL:31): [True: 1, False: 0] + | Branch (LL:36): [True: 1, False: 0] + ------------------ |---> MC/DC Decision Region (LL:13) to (LL:42) | | Number of Conditions: 5 @@ -151,6 +171,9 @@ LL| 3| foo(a && b); ^2 ------------------ + | Branch (LL:9): [True: 2, False: 1] + | Branch (LL:14): [True: 1, False: 1] + ------------------ |---> MC/DC Decision Region (LL:9) to (LL:15) | | Number of Conditions: 2 diff --git a/tests/coverage/mcdc/non_control_flow.rs b/tests/coverage/mcdc/non_control_flow.rs index 85c0a6c6ae58a..77e64e6625b2c 100644 --- a/tests/coverage/mcdc/non_control_flow.rs +++ b/tests/coverage/mcdc/non_control_flow.rs @@ -2,7 +2,7 @@ //@ edition: 2021 //@ min-llvm-version: 18 //@ compile-flags: -Zcoverage-options=mcdc -//@ llvm-cov-flags: --show-mcdc +//@ llvm-cov-flags: --show-branches=count --show-mcdc // This test ensures that boolean expressions that are not inside control flow // decisions are correctly instrumented. From 83fa6b726ad04d5b4e9769c39eae544131fee46c Mon Sep 17 00:00:00 2001 From: zhuyunxing Date: Tue, 2 Jul 2024 18:34:26 +0800 Subject: [PATCH 848/892] coverage. Fix panic when generating mcdc code for inlined functions --- compiler/rustc_mir_transform/src/inline.rs | 6 +++ .../coverage/mcdc/inlined_expressions.cov-map | 21 ++++++++++ .../mcdc/inlined_expressions.coverage | 41 +++++++++++++++++++ tests/coverage/mcdc/inlined_expressions.rs | 17 ++++++++ 4 files changed, 85 insertions(+) create mode 100644 tests/coverage/mcdc/inlined_expressions.cov-map create mode 100644 tests/coverage/mcdc/inlined_expressions.coverage create mode 100644 tests/coverage/mcdc/inlined_expressions.rs diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs index fe73715480f8b..fd9f0fec88ddd 100644 --- a/compiler/rustc_mir_transform/src/inline.rs +++ b/compiler/rustc_mir_transform/src/inline.rs @@ -41,6 +41,12 @@ struct CallSite<'tcx> { impl<'tcx> MirPass<'tcx> for Inline { fn is_enabled(&self, sess: &rustc_session::Session) -> bool { + // FIXME(#127234): Coverage instrumentation currently doesn't handle inlined + // MIR correctly when Modified Condition/Decision Coverage is enabled. + if sess.instrument_coverage_mcdc() { + return false; + } + if let Some(enabled) = sess.opts.unstable_opts.inline_mir { return enabled; } diff --git a/tests/coverage/mcdc/inlined_expressions.cov-map b/tests/coverage/mcdc/inlined_expressions.cov-map new file mode 100644 index 0000000000000..09b7291c96493 --- /dev/null +++ b/tests/coverage/mcdc/inlined_expressions.cov-map @@ -0,0 +1,21 @@ +Function name: inlined_expressions::inlined_instance +Raw bytes (52): 0x[01, 01, 03, 01, 05, 0b, 02, 09, 0d, 06, 01, 08, 01, 01, 06, 28, 00, 02, 01, 05, 00, 0b, 30, 05, 02, 01, 02, 00, 00, 05, 00, 06, 05, 00, 0a, 00, 0b, 30, 09, 0d, 02, 00, 00, 00, 0a, 00, 0b, 07, 01, 01, 00, 02] +Number of files: 1 +- file 0 => global file 1 +Number of expressions: 3 +- expression 0 operands: lhs = Counter(0), rhs = Counter(1) +- expression 1 operands: lhs = Expression(2, Add), rhs = Expression(0, Sub) +- expression 2 operands: lhs = Counter(2), rhs = Counter(3) +Number of file 0 mappings: 6 +- Code(Counter(0)) at (prev + 8, 1) to (start + 1, 6) +- MCDCDecision { bitmap_idx: 0, conditions_num: 2 } at (prev + 1, 5) to (start + 0, 11) +- MCDCBranch { true: Counter(1), false: Expression(0, Sub), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 5) to (start + 0, 6) + true = c1 + false = (c0 - c1) +- Code(Counter(1)) at (prev + 0, 10) to (start + 0, 11) +- MCDCBranch { true: Counter(2), false: Counter(3), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 10) to (start + 0, 11) + true = c2 + false = c3 +- Code(Expression(1, Add)) at (prev + 1, 1) to (start + 0, 2) + = ((c2 + c3) + (c0 - c1)) + diff --git a/tests/coverage/mcdc/inlined_expressions.coverage b/tests/coverage/mcdc/inlined_expressions.coverage new file mode 100644 index 0000000000000..5b083d6218680 --- /dev/null +++ b/tests/coverage/mcdc/inlined_expressions.coverage @@ -0,0 +1,41 @@ + LL| |#![feature(coverage_attribute)] + LL| |//@ edition: 2021 + LL| |//@ min-llvm-version: 18 + LL| |//@ compile-flags: -Zcoverage-options=mcdc -Copt-level=z -Cllvm-args=--inline-threshold=0 + LL| |//@ llvm-cov-flags: --show-branches=count --show-mcdc + LL| | + LL| |#[inline(always)] + LL| 3|fn inlined_instance(a: bool, b: bool) -> bool { + LL| 3| a && b + ^2 + ------------------ + | Branch (LL:5): [True: 2, False: 1] + | Branch (LL:10): [True: 1, False: 1] + ------------------ + |---> MC/DC Decision Region (LL:5) to (LL:11) + | + | Number of Conditions: 2 + | Condition C1 --> (LL:5) + | Condition C2 --> (LL:10) + | + | Executed MC/DC Test Vectors: + | + | C1, C2 Result + | 1 { F, - = F } + | 2 { T, F = F } + | 3 { T, T = T } + | + | C1-Pair: covered: (1,3) + | C2-Pair: covered: (2,3) + | MC/DC Coverage for Decision: 100.00% + | + ------------------ + LL| 3|} + LL| | + LL| |#[coverage(off)] + LL| |fn main() { + LL| | let _ = inlined_instance(true, false); + LL| | let _ = inlined_instance(false, true); + LL| | let _ = inlined_instance(true, true); + LL| |} + diff --git a/tests/coverage/mcdc/inlined_expressions.rs b/tests/coverage/mcdc/inlined_expressions.rs new file mode 100644 index 0000000000000..65f7ee66f3994 --- /dev/null +++ b/tests/coverage/mcdc/inlined_expressions.rs @@ -0,0 +1,17 @@ +#![feature(coverage_attribute)] +//@ edition: 2021 +//@ min-llvm-version: 18 +//@ compile-flags: -Zcoverage-options=mcdc -Copt-level=z -Cllvm-args=--inline-threshold=0 +//@ llvm-cov-flags: --show-branches=count --show-mcdc + +#[inline(always)] +fn inlined_instance(a: bool, b: bool) -> bool { + a && b +} + +#[coverage(off)] +fn main() { + let _ = inlined_instance(true, false); + let _ = inlined_instance(false, true); + let _ = inlined_instance(true, true); +} From 7097dbc50c086b652c37374cfbed6a40bf30efaf Mon Sep 17 00:00:00 2001 From: lcnr Date: Tue, 9 Jul 2024 09:10:19 +0200 Subject: [PATCH 849/892] exhaustively destructure external constraints --- compiler/rustc_next_trait_solver/src/solve/mod.rs | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_next_trait_solver/src/solve/mod.rs b/compiler/rustc_next_trait_solver/src/solve/mod.rs index 24055d6cd832b..c65c5851e9b4f 100644 --- a/compiler/rustc_next_trait_solver/src/solve/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/mod.rs @@ -48,12 +48,20 @@ enum GoalEvaluationKind { Nested, } +// FIXME(trait-system-refactor-initiative#117): we don't detect whether a response +// ended up pulling down any universes. fn has_no_inference_or_external_constraints( response: ty::Canonical>, ) -> bool { - response.value.external_constraints.region_constraints.is_empty() - && response.value.var_values.is_identity() - && response.value.external_constraints.opaque_types.is_empty() + let ExternalConstraintsData { + ref region_constraints, + ref opaque_types, + ref normalization_nested_goals, + } = *response.value.external_constraints; + response.value.var_values.is_identity() + && region_constraints.is_empty() + && opaque_types.is_empty() + && normalization_nested_goals.is_empty() } impl<'a, D, I> EvalCtxt<'a, D> From e38109d7f0e48a995c73a70a084630560bbcbcc0 Mon Sep 17 00:00:00 2001 From: lcnr Date: Tue, 9 Jul 2024 09:22:58 +0200 Subject: [PATCH 850/892] use `update_parent_goal` for lazy updates --- .../src/solve/search_graph.rs | 30 +++++++------------ 1 file changed, 10 insertions(+), 20 deletions(-) diff --git a/compiler/rustc_next_trait_solver/src/solve/search_graph.rs b/compiler/rustc_next_trait_solver/src/solve/search_graph.rs index 2cd3b10f56adb..f8a50913f05f8 100644 --- a/compiler/rustc_next_trait_solver/src/solve/search_graph.rs +++ b/compiler/rustc_next_trait_solver/src/solve/search_graph.rs @@ -139,18 +139,11 @@ impl SearchGraph { self.mode } - /// Pops the highest goal from the stack, lazily updating the - /// the next goal in the stack. - /// - /// Directly popping from the stack instead of using this method - /// would cause us to not track overflow and recursion depth correctly. - fn pop_stack(&mut self) -> StackEntry { - let elem = self.stack.pop().unwrap(); - if let Some(last) = self.stack.raw.last_mut() { - last.reached_depth = last.reached_depth.max(elem.reached_depth); - last.encountered_overflow |= elem.encountered_overflow; + fn update_parent_goal(&mut self, reached_depth: StackDepth, encountered_overflow: bool) { + if let Some(parent) = self.stack.raw.last_mut() { + parent.reached_depth = parent.reached_depth.max(reached_depth); + parent.encountered_overflow |= encountered_overflow; } - elem } pub(super) fn is_empty(&self) -> bool { @@ -364,7 +357,7 @@ impl SearchGraph { } debug!("canonical cycle overflow"); - let current_entry = self.pop_stack(); + let current_entry = self.stack.pop().unwrap(); debug_assert!(current_entry.has_been_used.is_empty()); let result = Self::response_no_constraints(cx, input, Certainty::overflow(false)); (current_entry, result) @@ -372,6 +365,8 @@ impl SearchGraph { let proof_tree = inspect.finalize_canonical_goal_evaluation(cx); + self.update_parent_goal(final_entry.reached_depth, final_entry.encountered_overflow); + // We're now done with this goal. In case this goal is involved in a larger cycle // do not remove it from the provisional cache and update its provisional result. // We only add the root of cycles to the global cache. @@ -441,14 +436,9 @@ impl SearchGraph { } } - // Update the reached depth of the current goal to make sure - // its state is the same regardless of whether we've used the - // global cache or not. + // Adjust the parent goal as if we actually computed this goal. let reached_depth = self.stack.next_index().plus(additional_depth); - if let Some(last) = self.stack.raw.last_mut() { - last.reached_depth = last.reached_depth.max(reached_depth); - last.encountered_overflow |= encountered_overflow; - } + self.update_parent_goal(reached_depth, encountered_overflow); Some(result) } @@ -477,7 +467,7 @@ impl SearchGraph { F: FnMut(&mut Self, &mut ProofTreeBuilder) -> QueryResult, { let result = prove_goal(self, inspect); - let stack_entry = self.pop_stack(); + let stack_entry = self.stack.pop().unwrap(); debug_assert_eq!(stack_entry.input, input); // If the current goal is not the root of a cycle, we are done. From fd9a92542cb85bf8a0d3948f26a8d81fbd16093c Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Fri, 5 Jul 2024 09:16:00 +0000 Subject: [PATCH 851/892] Automatically taint when reporting errors from ItemCtxt --- compiler/rustc_hir_analysis/src/collect.rs | 8 +- .../src/hir_ty_lowering/bounds.rs | 39 +++--- .../src/hir_ty_lowering/errors.rs | 43 +++---- .../src/hir_ty_lowering/generics.rs | 42 +++--- .../src/hir_ty_lowering/lint.rs | 2 +- .../src/hir_ty_lowering/mod.rs | 57 ++++----- .../src/hir_ty_lowering/object_safety.rs | 4 +- .../rustc_hir_typeck/src/fn_ctxt/_impl.rs | 4 +- compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs | 4 + .../rustc_hir_typeck/src/method/confirm.rs | 4 +- .../associated-types-eq-expr-path.rs | 5 +- .../associated-types-eq-expr-path.stderr | 22 +--- .../assoc_const_as_type_argument.rs | 1 - .../assoc_const_as_type_argument.stderr | 18 +-- .../const-arg-in-const-arg.min.stderr | 120 ++++++------------ .../const-generics/const-arg-in-const-arg.rs | 4 - .../issues/issue-62878.min.stderr | 30 +---- tests/ui/const-generics/issues/issue-62878.rs | 2 - ...const-expression-suggest-missing-braces.rs | 1 - ...t-expression-suggest-missing-braces.stderr | 38 ++---- .../min_const_generics/macro-fail.rs | 3 - .../min_const_generics/macro-fail.stderr | 61 ++------- .../const-generics/suggest_const_for_array.rs | 2 - .../suggest_const_for_array.stderr | 31 +---- .../generic-function-item-where-type.rs | 1 - .../generic-function-item-where-type.stderr | 11 +- 26 files changed, 183 insertions(+), 374 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index 843e4d41e001e..f83d74ecd3887 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -18,7 +18,9 @@ use rustc_ast::Recovered; use rustc_data_structures::captures::Captures; use rustc_data_structures::fx::{FxHashSet, FxIndexMap}; use rustc_data_structures::unord::UnordMap; -use rustc_errors::{struct_span_code_err, Applicability, Diag, ErrorGuaranteed, StashKey, E0228}; +use rustc_errors::{ + struct_span_code_err, Applicability, Diag, DiagCtxtHandle, ErrorGuaranteed, StashKey, E0228, +}; use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::intravisit::{self, walk_generics, Visitor}; @@ -370,6 +372,10 @@ impl<'tcx> HirTyLowerer<'tcx> for ItemCtxt<'tcx> { self.tcx } + fn dcx(&self) -> DiagCtxtHandle<'_> { + self.tcx.dcx().taintable_handle(&self.tainted_by_errors) + } + fn item_def_id(&self) -> LocalDefId { self.item_def_id } diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs index 802215b2843ee..a1feef9e15b7e 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs @@ -76,7 +76,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { } if unbounds.len() > 1 { - tcx.dcx().emit_err(errors::MultipleRelaxedDefaultBounds { + self.dcx().emit_err(errors::MultipleRelaxedDefaultBounds { spans: unbounds.iter().map(|ptr| ptr.span).collect(), }); } @@ -90,7 +90,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { continue; } // There was a `?Trait` bound, but it was not `?Sized`; warn. - tcx.dcx().span_warn( + self.dcx().span_warn( unbound.span, "relaxing a default bound only does something for `?Sized`; \ all other traits are not bound by default", @@ -310,7 +310,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { duplicates .entry(assoc_item.def_id) .and_modify(|prev_span| { - tcx.dcx().emit_err(errors::ValueOfAssociatedStructAlreadySpecified { + self.dcx().emit_err(errors::ValueOfAssociatedStructAlreadySpecified { span: constraint.span, prev_span: *prev_span, item_name: constraint.ident, @@ -338,7 +338,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { .into(), ty::GenericParamDefKind::Type { .. } => { let guar = *emitted_bad_param_err.get_or_insert_with(|| { - tcx.dcx().emit_err( + self.dcx().emit_err( crate::errors::ReturnTypeNotationIllegalParam::Type { span: path_span, param_span: tcx.def_span(param.def_id), @@ -349,7 +349,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { } ty::GenericParamDefKind::Const { .. } => { let guar = *emitted_bad_param_err.get_or_insert_with(|| { - tcx.dcx().emit_err( + self.dcx().emit_err( crate::errors::ReturnTypeNotationIllegalParam::Const { span: path_span, param_span: tcx.def_span(param.def_id), @@ -371,7 +371,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { { alias_ty.into() } else { - return Err(tcx.dcx().emit_err(crate::errors::ReturnTypeNotationOnNonRpitit { + return Err(self.dcx().emit_err(crate::errors::ReturnTypeNotationOnNonRpitit { span: constraint.span, ty: tcx.liberate_late_bound_regions(assoc_item.def_id, output), fn_span: tcx.hir().span_if_local(assoc_item.def_id), @@ -417,7 +417,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { let ty = alias_term .map_bound(|alias| tcx.type_of(alias.def_id).instantiate(tcx, alias.args)); let ty = - check_assoc_const_binding_type(tcx, constraint.ident, ty, constraint.hir_id); + check_assoc_const_binding_type(self, constraint.ident, ty, constraint.hir_id); tcx.feed_anon_const_type(anon_const.def_id, ty::EarlyBinder::bind(ty)); } @@ -426,7 +426,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { match constraint.kind { hir::AssocItemConstraintKind::Equality { .. } if let ty::AssocKind::Fn = assoc_kind => { - return Err(tcx.dcx().emit_err(crate::errors::ReturnTypeNotationEqualityBound { + return Err(self.dcx().emit_err(crate::errors::ReturnTypeNotationEqualityBound { span: constraint.span, })); } @@ -462,7 +462,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { late_bound_in_term, |br_name| { struct_span_code_err!( - tcx.dcx(), + self.dcx(), constraint.span, E0582, "binding for associated type `{}` references {}, \ @@ -519,7 +519,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { /// /// [^1]: . fn check_assoc_const_binding_type<'tcx>( - tcx: TyCtxt<'tcx>, + cx: &dyn HirTyLowerer<'tcx>, assoc_const: Ident, ty: ty::Binder<'tcx, Ty<'tcx>>, hir_id: hir::HirId, @@ -536,13 +536,14 @@ fn check_assoc_const_binding_type<'tcx>( } let mut collector = GenericParamAndBoundVarCollector { - tcx, + cx, params: Default::default(), vars: Default::default(), depth: ty::INNERMOST, }; let mut guar = ty.visit_with(&mut collector).break_value(); + let tcx = cx.tcx(); let ty_note = ty .make_suggestable(tcx, false, None) .map(|ty| crate::errors::TyOfAssocConstBindingNote { assoc_const, ty }); @@ -556,7 +557,7 @@ fn check_assoc_const_binding_type<'tcx>( for index in collector.params { let param = generics.param_at(index as _, tcx); let is_self_param = param.name == rustc_span::symbol::kw::SelfUpper; - guar.get_or_insert(tcx.dcx().emit_err(crate::errors::ParamInTyOfAssocConstBinding { + guar.get_or_insert(cx.dcx().emit_err(crate::errors::ParamInTyOfAssocConstBinding { span: assoc_const.span, assoc_const, param_name: param.name, @@ -574,7 +575,7 @@ fn check_assoc_const_binding_type<'tcx>( })); } for (var_def_id, var_name) in collector.vars { - guar.get_or_insert(tcx.dcx().emit_err( + guar.get_or_insert(cx.dcx().emit_err( crate::errors::EscapingBoundVarInTyOfAssocConstBinding { span: assoc_const.span, assoc_const, @@ -590,14 +591,14 @@ fn check_assoc_const_binding_type<'tcx>( Ty::new_error(tcx, guar) } -struct GenericParamAndBoundVarCollector<'tcx> { - tcx: TyCtxt<'tcx>, +struct GenericParamAndBoundVarCollector<'a, 'tcx> { + cx: &'a dyn HirTyLowerer<'tcx>, params: FxIndexSet, vars: FxIndexSet<(DefId, Symbol)>, depth: ty::DebruijnIndex, } -impl<'tcx> TypeVisitor> for GenericParamAndBoundVarCollector<'tcx> { +impl<'tcx> TypeVisitor> for GenericParamAndBoundVarCollector<'_, 'tcx> { type Result = ControlFlow; fn visit_binder>>( @@ -620,7 +621,7 @@ impl<'tcx> TypeVisitor> for GenericParamAndBoundVarCollector<'tcx> ty::BoundTyKind::Param(def_id, name) => (def_id, name), ty::BoundTyKind::Anon => { let reported = self - .tcx + .cx .dcx() .delayed_bug(format!("unexpected anon bound ty: {:?}", bt.var)); return ControlFlow::Break(reported); @@ -643,7 +644,7 @@ impl<'tcx> TypeVisitor> for GenericParamAndBoundVarCollector<'tcx> ty::BrNamed(def_id, name) => (def_id, name), ty::BrAnon | ty::BrEnv => { let guar = self - .tcx + .cx .dcx() .delayed_bug(format!("unexpected bound region kind: {:?}", br.kind)); return ControlFlow::Break(guar); @@ -661,7 +662,7 @@ impl<'tcx> TypeVisitor> for GenericParamAndBoundVarCollector<'tcx> self.params.insert(param.index); } ty::ConstKind::Bound(db, ty::BoundVar { .. }) if db >= self.depth => { - let guar = self.tcx.dcx().delayed_bug("unexpected escaping late-bound const var"); + let guar = self.cx.dcx().delayed_bug("unexpected escaping late-bound const var"); return ControlFlow::Break(guar); } _ if ct.has_param() || ct.has_bound_vars() => return ct.super_visit_with(self), diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs index 2d240699105d6..d8bbe403f1f50 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs @@ -46,7 +46,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { return; } - self.tcx().dcx().emit_err(MissingTypeParams { + self.dcx().emit_err(MissingTypeParams { span, def_span: self.tcx().def_span(def_id), span_snippet: self.tcx().sess.source_map().span_to_snippet(span).ok(), @@ -109,7 +109,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { if is_impl { let trait_name = self.tcx().def_path_str(trait_def_id); - self.tcx().dcx().emit_err(ManualImplementation { span, trait_name }); + self.dcx().emit_err(ManualImplementation { span, trait_name }); } } @@ -156,7 +156,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { if is_dummy { err.label = Some(errors::AssocItemNotFoundLabel::NotFound { span }); - return tcx.dcx().emit_err(err); + return self.dcx().emit_err(err); } let all_candidate_names: Vec<_> = all_candidates() @@ -174,7 +174,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { assoc_kind: assoc_kind_str, suggested_name, }); - return tcx.dcx().emit_err(err); + return self.dcx().emit_err(err); } // If we didn't find a good item in the supertraits (or couldn't get @@ -239,10 +239,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { assoc_kind: assoc_kind_str, suggested_name, }); - return tcx.dcx().emit_err(err); + return self.dcx().emit_err(err); } - let mut err = tcx.dcx().create_err(err); + let mut err = self.dcx().create_err(err); if suggest_constraining_type_param( tcx, generics, @@ -264,7 +264,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { } return err.emit(); } - return tcx.dcx().emit_err(err); + return self.dcx().emit_err(err); } } @@ -291,7 +291,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { err.label = Some(errors::AssocItemNotFoundLabel::NotFound { span: assoc_name.span }); } - tcx.dcx().emit_err(err) + self.dcx().emit_err(err) } fn complain_about_assoc_kind_mismatch( @@ -347,7 +347,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { (ident.span, None, assoc_kind, assoc_item.kind) }; - tcx.dcx().emit_err(errors::AssocKindMismatch { + self.dcx().emit_err(errors::AssocKindMismatch { span, expected: super::assoc_kind_str(expected), got: super::assoc_kind_str(got), @@ -366,8 +366,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { traits: &[String], name: Symbol, ) -> ErrorGuaranteed { - let mut err = - struct_span_code_err!(self.tcx().dcx(), span, E0223, "ambiguous associated type"); + let mut err = struct_span_code_err!(self.dcx(), span, E0223, "ambiguous associated type"); if self .tcx() .resolutions(()) @@ -475,7 +474,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { span: Span, ) -> ErrorGuaranteed { let mut err = struct_span_code_err!( - self.tcx().dcx(), + self.dcx(), name.span, E0034, "multiple applicable items in scope" @@ -576,7 +575,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { }; let mut err = struct_span_code_err!( - tcx.dcx(), + self.dcx(), name.span, E0220, "associated type `{name}` not found for `{self_ty}` in the current scope" @@ -662,7 +661,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { bounds.sort(); bounds.dedup(); - let mut err = tcx.dcx().struct_span_err( + let mut err = self.dcx().struct_span_err( name.span, format!("the associated type `{name}` exists for `{self_ty}`, but its trait bounds were not satisfied") ); @@ -829,7 +828,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { trait_bound_spans.sort(); let mut err = struct_span_code_err!( - tcx.dcx(), + self.dcx(), trait_bound_spans, E0191, "the value of the associated type{} {} must be specified", @@ -1012,7 +1011,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { .next() { let reported = - struct_span_code_err!(tcx.dcx(), span, E0223, "ambiguous associated type") + struct_span_code_err!(self.dcx(), span, E0223, "ambiguous associated type") .with_span_suggestion_verbose( ident2.span.to(ident3.span), format!("there is an associated function with a similar name: `{name}`"), @@ -1120,7 +1119,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { let last_span = *arg_spans.last().unwrap(); let span: MultiSpan = arg_spans.into(); let mut err = struct_span_code_err!( - self.tcx().dcx(), + self.dcx(), span, E0109, "{kind} arguments are not allowed on {this_type}", @@ -1139,11 +1138,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { &self, regular_traits: &Vec>, ) -> ErrorGuaranteed { - let tcx = self.tcx(); let first_trait = ®ular_traits[0]; let additional_trait = ®ular_traits[1]; let mut err = struct_span_code_err!( - tcx.dcx(), + self.dcx(), additional_trait.bottom().1, E0225, "only auto traits can be used as additional traits in a trait object" @@ -1186,7 +1184,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { .find(|&trait_ref| tcx.is_trait_alias(trait_ref)) .map(|trait_ref| tcx.def_span(trait_ref)); let reported = - tcx.dcx().emit_err(TraitObjectDeclaredWithNoTraits { span, trait_alias_span }); + self.dcx().emit_err(TraitObjectDeclaredWithNoTraits { span, trait_alias_span }); self.set_tainted_by_errors(reported); reported } @@ -1194,11 +1192,12 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { /// Emit an error for the given associated item constraint. pub fn prohibit_assoc_item_constraint( - tcx: TyCtxt<'_>, + cx: &dyn HirTyLowerer<'_>, constraint: &hir::AssocItemConstraint<'_>, segment: Option<(DefId, &hir::PathSegment<'_>, Span)>, ) -> ErrorGuaranteed { - let mut err = tcx.dcx().create_err(AssocItemConstraintsNotAllowedHere { + let tcx = cx.tcx(); + let mut err = cx.dcx().create_err(AssocItemConstraintsNotAllowedHere { span: constraint.span, fn_trait_expansion: if let Some((_, segment, span)) = segment && segment.args().parenthesized == hir::GenericArgsParentheses::ParenSugar diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs index 90836f0a54f45..b1c77db9f3700 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs @@ -1,4 +1,4 @@ -use super::IsMethodCall; +use super::{HirTyLowerer, IsMethodCall}; use crate::errors::wrong_number_of_generic_args::{GenericArgsInfo, WrongNumberOfGenericArgs}; use crate::hir_ty_lowering::{ errors::prohibit_assoc_item_constraint, ExplicitLateBound, GenericArgCountMismatch, @@ -13,7 +13,7 @@ use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::DefId; use rustc_hir::GenericArg; use rustc_middle::ty::{ - self, GenericArgsRef, GenericParamDef, GenericParamDefKind, IsSuggestable, Ty, TyCtxt, + self, GenericArgsRef, GenericParamDef, GenericParamDefKind, IsSuggestable, Ty, }; use rustc_session::lint::builtin::LATE_BOUND_LIFETIME_ARGUMENTS; use rustc_span::symbol::{kw, sym}; @@ -22,15 +22,16 @@ use smallvec::SmallVec; /// Report an error that a generic argument did not match the generic parameter that was /// expected. fn generic_arg_mismatch_err( - tcx: TyCtxt<'_>, + cx: &dyn HirTyLowerer<'_>, arg: &GenericArg<'_>, param: &GenericParamDef, possible_ordering_error: bool, help: Option, ) -> ErrorGuaranteed { + let tcx = cx.tcx(); let sess = tcx.sess; let mut err = struct_span_code_err!( - tcx.dcx(), + cx.dcx(), arg.span(), E0747, "{} provided when a {} was expected", @@ -171,7 +172,7 @@ fn generic_arg_mismatch_err( /// - `inferred_kind`: if no parameter was provided, and inference /// is enabled, then creates a suitable inference variable. pub fn lower_generic_args<'tcx: 'a, 'a>( - tcx: TyCtxt<'tcx>, + cx: &dyn HirTyLowerer<'tcx>, def_id: DefId, parent_args: &[ty::GenericArg<'tcx>], has_self: bool, @@ -179,6 +180,7 @@ pub fn lower_generic_args<'tcx: 'a, 'a>( arg_count: &GenericArgCountResult, ctx: &mut impl GenericArgsLowerer<'a, 'tcx>, ) -> GenericArgsRef<'tcx> { + let tcx = cx.tcx(); // Collect the segments of the path; we need to instantiate arguments // for parameters throughout the entire path (wherever there are // generic parameters). @@ -326,7 +328,7 @@ pub fn lower_generic_args<'tcx: 'a, 'a>( param_types_present.dedup(); generic_arg_mismatch_err( - tcx, + cx, arg, param, !args_iter.clone().is_sorted_by_key(|arg| arg.to_ord()), @@ -381,7 +383,7 @@ pub fn lower_generic_args<'tcx: 'a, 'a>( assert_eq!(kind, "lifetime"); let (provided_arg, param) = force_infer_lt.expect("lifetimes ought to have been inferred"); - generic_arg_mismatch_err(tcx, provided_arg, param, false, None); + generic_arg_mismatch_err(cx, provided_arg, param, false, None); } break; @@ -405,7 +407,7 @@ pub fn lower_generic_args<'tcx: 'a, 'a>( /// Checks that the correct number of generic arguments have been provided. /// Used specifically for function calls. pub fn check_generic_arg_count_for_call( - tcx: TyCtxt<'_>, + cx: &dyn HirTyLowerer<'_>, def_id: DefId, generics: &ty::Generics, seg: &hir::PathSegment<'_>, @@ -416,14 +418,14 @@ pub fn check_generic_arg_count_for_call( IsMethodCall::No => GenericArgPosition::Value, }; let has_self = generics.parent.is_none() && generics.has_self; - check_generic_arg_count(tcx, def_id, seg, generics, gen_pos, has_self) + check_generic_arg_count(cx, def_id, seg, generics, gen_pos, has_self) } /// Checks that the correct number of generic arguments have been provided. /// This is used both for datatypes and function calls. -#[instrument(skip(tcx, gen_pos), level = "debug")] +#[instrument(skip(cx, gen_pos), level = "debug")] pub(crate) fn check_generic_arg_count( - tcx: TyCtxt<'_>, + cx: &dyn HirTyLowerer<'_>, def_id: DefId, seg: &hir::PathSegment<'_>, gen_params: &ty::Generics, @@ -456,11 +458,11 @@ pub(crate) fn check_generic_arg_count( if gen_pos != GenericArgPosition::Type && let Some(c) = gen_args.constraints.first() { - prohibit_assoc_item_constraint(tcx, c, None); + prohibit_assoc_item_constraint(cx, c, None); } let explicit_late_bound = - prohibit_explicit_late_bound_lifetimes(tcx, gen_params, gen_args, gen_pos); + prohibit_explicit_late_bound_lifetimes(cx, gen_params, gen_args, gen_pos); let mut invalid_args = vec![]; @@ -486,8 +488,8 @@ pub(crate) fn check_generic_arg_count( GenericArgsInfo::MissingLifetimes { num_missing_args } }; - let reported = tcx.dcx().emit_err(WrongNumberOfGenericArgs::new( - tcx, + let reported = cx.dcx().emit_err(WrongNumberOfGenericArgs::new( + cx.tcx(), gen_args_info, seg, gen_params, @@ -571,9 +573,9 @@ pub(crate) fn check_generic_arg_count( debug!(?gen_args_info); let reported = gen_args.has_err().unwrap_or_else(|| { - tcx.dcx() + cx.dcx() .create_err(WrongNumberOfGenericArgs::new( - tcx, + cx.tcx(), gen_args_info, seg, gen_params, @@ -621,7 +623,7 @@ pub(crate) fn check_generic_arg_count( /// Prohibits explicit lifetime arguments if late-bound lifetime parameters /// are present. This is used both for datatypes and function calls. pub(crate) fn prohibit_explicit_late_bound_lifetimes( - tcx: TyCtxt<'_>, + cx: &dyn HirTyLowerer<'_>, def: &ty::Generics, args: &hir::GenericArgs<'_>, position: GenericArgPosition, @@ -642,13 +644,13 @@ pub(crate) fn prohibit_explicit_late_bound_lifetimes( if position == GenericArgPosition::Value && args.num_lifetime_params() != param_counts.lifetimes { - struct_span_code_err!(tcx.dcx(), span, E0794, "{}", msg) + struct_span_code_err!(cx.dcx(), span, E0794, "{}", msg) .with_span_note(span_late, note) .emit(); } else { let mut multispan = MultiSpan::from_span(span); multispan.push_span_label(span_late, note); - tcx.node_span_lint( + cx.tcx().node_span_lint( LATE_BOUND_LIFETIME_ARGUMENTS, args.args[0].hir_id(), multispan, diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs index 240a749de96a6..1ba45067ec8c9 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs @@ -60,7 +60,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { let msg = "trait objects must include the `dyn` keyword"; let label = "add `dyn` keyword before this trait"; let mut diag = - rustc_errors::struct_span_code_err!(tcx.dcx(), self_ty.span, E0782, "{}", msg); + rustc_errors::struct_span_code_err!(self.dcx(), self_ty.span, E0782, "{}", msg); if self_ty.span.can_be_used_for_suggestions() && !self.maybe_suggest_impl_trait(self_ty, &mut diag) { diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs index 02db0352daafa..e8a4ab103bd2b 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -28,7 +28,8 @@ use crate::require_c_abi_if_c_variadic; use rustc_ast::TraitObjectSyntax; use rustc_data_structures::fx::{FxHashSet, FxIndexMap}; use rustc_errors::{ - codes::*, struct_span_code_err, Applicability, Diag, ErrorGuaranteed, FatalError, + codes::*, struct_span_code_err, Applicability, Diag, DiagCtxtHandle, ErrorGuaranteed, + FatalError, }; use rustc_hir as hir; use rustc_hir::def::{CtorOf, DefKind, Namespace, Res}; @@ -102,6 +103,8 @@ pub enum RegionInferReason<'a> { pub trait HirTyLowerer<'tcx> { fn tcx(&self) -> TyCtxt<'tcx>; + fn dcx(&self) -> DiagCtxtHandle<'_>; + /// Returns the [`LocalDefId`] of the overarching item whose constituents get lowered. fn item_def_id(&self) -> LocalDefId; @@ -323,7 +326,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { ty::BoundConstness::NotConst, ); if let Some(c) = item_segment.args().constraints.first() { - prohibit_assoc_item_constraint(self.tcx(), c, Some((def_id, item_segment, span))); + prohibit_assoc_item_constraint(self, c, Some((def_id, item_segment, span))); } args } @@ -394,7 +397,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { } let mut arg_count = check_generic_arg_count( - tcx, + self, def_id, segment, generics, @@ -562,7 +565,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { && generics.has_self && !tcx.has_attr(def_id, sym::const_trait) { - let reported = tcx.dcx().emit_err(crate::errors::ConstBoundForNonConstTrait { + let reported = self.dcx().emit_err(crate::errors::ConstBoundForNonConstTrait { span, modifier: constness.as_str(), }); @@ -579,7 +582,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { incorrect_args: &arg_count.correct, }; let args = lower_generic_args( - tcx, + self, def_id, parent_args, self_ty.is_some(), @@ -609,7 +612,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { ty::BoundConstness::NotConst, ); if let Some(c) = item_segment.args().constraints.first() { - prohibit_assoc_item_constraint(self.tcx(), c, Some((item_def_id, item_segment, span))); + prohibit_assoc_item_constraint(self, c, Some((item_def_id, item_segment, span))); } args } @@ -715,7 +718,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { // would not be well-formed! if polarity != ty::PredicatePolarity::Positive { assert!( - self.tcx().dcx().has_errors().is_some(), + self.dcx().has_errors().is_some(), "negative trait bounds should not have assoc item constraints", ); continue; @@ -761,11 +764,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { constness, ); if let Some(c) = trait_segment.args().constraints.first() { - prohibit_assoc_item_constraint( - self.tcx(), - c, - Some((trait_def_id, trait_segment, span)), - ); + prohibit_assoc_item_constraint(self, c, Some((trait_def_id, trait_segment, span))); } ty::TraitRef::new_from_args(self.tcx(), trait_def_id, generic_args) } @@ -887,7 +886,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { let assoc_kind_str = assoc_kind_str(assoc_kind); let ty_param_name = &ty_param_name.to_string(); - let mut err = tcx.dcx().create_err(crate::errors::AmbiguousAssocItem { + let mut err = self.dcx().create_err(crate::errors::AmbiguousAssocItem { span, assoc_kind: assoc_kind_str, assoc_name, @@ -1059,7 +1058,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { // trait reference. let Some(trait_ref) = tcx.impl_trait_ref(impl_def_id) else { // A cycle error occurred, most likely. - tcx.dcx().span_bug(span, "expected cycle error"); + self.dcx().span_bug(span, "expected cycle error"); }; self.probe_single_bound_for_assoc_item( @@ -1089,10 +1088,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { let reported = if variant_resolution.is_some() { // Variant in type position let msg = format!("expected type, found variant `{assoc_ident}`"); - tcx.dcx().span_err(span, msg) + self.dcx().span_err(span, msg) } else if qself_ty.is_enum() { let mut err = struct_span_code_err!( - tcx.dcx(), + self.dcx(), assoc_ident.span, E0599, "no variant named `{}` found for enum `{}`", @@ -1133,7 +1132,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { } else if let ty::Alias(ty::Opaque, alias_ty) = qself_ty.kind() { // `::Assoc` makes no sense. struct_span_code_err!( - tcx.dcx(), + self.dcx(), tcx.def_span(alias_ty.def_id), E0667, "`impl Trait` is not allowed in path parameters" @@ -1404,7 +1403,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { let tcx = self.tcx(); if !tcx.visibility(item_def_id).is_accessible_from(scope, tcx) { - let reported = tcx.dcx().emit_err(crate::errors::AssocItemIsPrivate { + let reported = self.dcx().emit_err(crate::errors::AssocItemIsPrivate { span, kind: tcx.def_descr(item_def_id), name: ident, @@ -1564,7 +1563,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { for segment in segments { // Only emit the first error to avoid overloading the user with error messages. if let Some(c) = segment.args().constraints.first() { - return Err(prohibit_assoc_item_constraint(self.tcx(), c, None)); + return Err(prohibit_assoc_item_constraint(self, c, None)); } } @@ -1824,7 +1823,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { // `AlwaysApplicable` impl needs a `T: ?Sized` bound for // this to compile if we were to normalize here. if forbid_generic && ty.has_param() { - let mut err = tcx.dcx().struct_span_err( + let mut err = self.dcx().struct_span_err( path.span, "generic `Self` types are currently not permitted in anonymous constants", ); @@ -1894,7 +1893,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { ); Ty::new_error( self.tcx(), - self.tcx().dcx().span_delayed_bug(span, "incorrect resolution for `Self`"), + self.dcx().span_delayed_bug(span, "incorrect resolution for `Self`"), ) } _ => span_bug!(span, "unexpected resolution: {:?}", path.res), @@ -1967,7 +1966,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { let sig_span = self.tcx().def_span(sig_id); let mut try_emit = |descr| { if emit { - self.tcx().dcx().emit_err(crate::errors::NotSupportedDelegation { + self.dcx().emit_err(crate::errors::NotSupportedDelegation { span, descr, callee_span: sig_span, @@ -2017,7 +2016,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { ) -> Ty<'tcx> { if self.check_delegation_constraints(sig_id, span, idx == hir::InferDelegationKind::Output) { - let e = self.tcx().dcx().span_delayed_bug(span, "not supported delegation case"); + let e = self.dcx().span_delayed_bug(span, "not supported delegation case"); self.set_tainted_by_errors(e); return Ty::new_error(self.tcx(), e); }; @@ -2183,7 +2182,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { let ty = self.lower_ty(ty); let pat_ty = match pat.kind { hir::PatKind::Wild => { - let err = tcx.dcx().emit_err(WildPatTy { span: pat.span }); + let err = self.dcx().emit_err(WildPatTy { span: pat.span }); Ty::new_error(tcx, err) } hir::PatKind::Range(start, end, include_end) => { @@ -2363,7 +2362,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { self.validate_late_bound_regions(late_bound_in_args, late_bound_in_ret, |br_name| { struct_span_code_err!( - tcx.dcx(), + self.dcx(), decl.output.span(), E0581, "return type references {}, which is not constrained by the fn input types", @@ -2414,11 +2413,11 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { } #[instrument(level = "trace", skip(self, generate_err))] - fn validate_late_bound_regions( - &self, + fn validate_late_bound_regions<'cx>( + &'cx self, constrained_regions: FxHashSet, referenced_regions: FxHashSet, - generate_err: impl Fn(&str) -> Diag<'tcx>, + generate_err: impl Fn(&str) -> Diag<'cx>, ) { for br in referenced_regions.difference(&constrained_regions) { let br_name = match *br { @@ -2484,7 +2483,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { // error. let r = derived_region_bounds[0]; if derived_region_bounds[1..].iter().any(|r1| r != *r1) { - self.set_tainted_by_errors(tcx.dcx().emit_err(AmbiguousLifetimeBound { span })); + self.dcx().emit_err(AmbiguousLifetimeBound { span }); } Some(r) } diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/object_safety.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/object_safety.rs index df69c1938dd75..bbb37be5c9f3f 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/object_safety.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/object_safety.rs @@ -236,7 +236,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { Ty::new_misc_error(tcx).into() } else if arg.walk().any(|arg| arg == dummy_self.into()) { references_self = true; - let guar = tcx.dcx().span_delayed_bug( + let guar = self.dcx().span_delayed_bug( span, "trait object trait bounds reference `Self`", ); @@ -263,7 +263,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { if references_self { let def_id = i.bottom().0.def_id(); let reported = struct_span_code_err!( - tcx.dcx(), + self.dcx(), i.bottom().1, E0038, "the {} `{}` cannot be made into an object", diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index 5450243417f7f..f74859e4d9a16 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -1139,7 +1139,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // parameter's value explicitly, so we have to do some error- // checking here. let arg_count = - check_generic_arg_count_for_call(tcx, def_id, generics, seg, IsMethodCall::No); + check_generic_arg_count_for_call(self, def_id, generics, seg, IsMethodCall::No); if let ExplicitLateBound::Yes = arg_count.explicit_late_bound { explicit_late_bound = ExplicitLateBound::Yes; @@ -1375,7 +1375,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let args_raw = self_ctor_args.unwrap_or_else(|| { lower_generic_args( - tcx, + self, def_id, &[], has_self, diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs index da68da029b417..1de2935ecaf73 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs @@ -217,6 +217,10 @@ impl<'tcx> HirTyLowerer<'tcx> for FnCtxt<'_, 'tcx> { self.tcx } + fn dcx(&self) -> DiagCtxtHandle<'_> { + self.root_ctxt.dcx() + } + fn item_def_id(&self) -> LocalDefId { self.body_id } diff --git a/compiler/rustc_hir_typeck/src/method/confirm.rs b/compiler/rustc_hir_typeck/src/method/confirm.rs index 02844bcadac6e..e574fde14fb0a 100644 --- a/compiler/rustc_hir_typeck/src/method/confirm.rs +++ b/compiler/rustc_hir_typeck/src/method/confirm.rs @@ -354,7 +354,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> { let generics = self.tcx.generics_of(pick.item.def_id); let arg_count_correct = check_generic_arg_count_for_call( - self.tcx, + self.fcx, pick.item.def_id, generics, seg, @@ -425,7 +425,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> { } let args = lower_generic_args( - self.tcx, + self.fcx, pick.item.def_id, parent_args, false, diff --git a/tests/ui/associated-types/associated-types-eq-expr-path.rs b/tests/ui/associated-types/associated-types-eq-expr-path.rs index 67831f913039a..3179811274e81 100644 --- a/tests/ui/associated-types/associated-types-eq-expr-path.rs +++ b/tests/ui/associated-types/associated-types-eq-expr-path.rs @@ -7,11 +7,12 @@ trait Foo { impl Foo for isize { type A = usize; - fn bar() -> isize { 42 } + fn bar() -> isize { + 42 + } } pub fn main() { let x: isize = Foo::::bar(); //~^ ERROR associated item constraints are not allowed here - //~| ERROR cannot call } diff --git a/tests/ui/associated-types/associated-types-eq-expr-path.stderr b/tests/ui/associated-types/associated-types-eq-expr-path.stderr index 4f28b3cb2de33..bbe021fbc55f0 100644 --- a/tests/ui/associated-types/associated-types-eq-expr-path.stderr +++ b/tests/ui/associated-types/associated-types-eq-expr-path.stderr @@ -1,25 +1,9 @@ error[E0229]: associated item constraints are not allowed here - --> $DIR/associated-types-eq-expr-path.rs:14:26 + --> $DIR/associated-types-eq-expr-path.rs:16:26 | LL | let x: isize = Foo::::bar(); | ^^^^^^^^^ associated item constraint not allowed here -error[E0790]: cannot call associated function on trait without specifying the corresponding `impl` type - --> $DIR/associated-types-eq-expr-path.rs:14:20 - | -LL | fn bar() -> isize; - | ------------------ `Foo::bar` defined here -... -LL | let x: isize = Foo::::bar(); - | ^^^^^^^^^^^^^^^^^^^^^^^ cannot call associated function of trait - | -help: use the fully-qualified path to the only available implementation - | -LL - let x: isize = Foo::::bar(); -LL + let x: isize = >::bar(); - | - -error: aborting due to 2 previous errors +error: aborting due to 1 previous error -Some errors have detailed explanations: E0229, E0790. -For more information about an error, try `rustc --explain E0229`. +For more information about this error, try `rustc --explain E0229`. diff --git a/tests/ui/const-generics/assoc_const_as_type_argument.rs b/tests/ui/const-generics/assoc_const_as_type_argument.rs index bec6102417c5f..ffc7f116a94ef 100644 --- a/tests/ui/const-generics/assoc_const_as_type_argument.rs +++ b/tests/ui/const-generics/assoc_const_as_type_argument.rs @@ -8,7 +8,6 @@ fn foo() { bar::<::ASSOC>(); //~^ ERROR: expected associated type, found associated constant `Trait::ASSOC` //~| ERROR: unresolved item provided when a constant was expected - //~| ERROR type annotations needed } fn main() {} diff --git a/tests/ui/const-generics/assoc_const_as_type_argument.stderr b/tests/ui/const-generics/assoc_const_as_type_argument.stderr index 53edc19b28ca2..ac00954613506 100644 --- a/tests/ui/const-generics/assoc_const_as_type_argument.stderr +++ b/tests/ui/const-generics/assoc_const_as_type_argument.stderr @@ -15,19 +15,7 @@ help: if this generic argument was intended as a const parameter, surround it wi LL | bar::<{ ::ASSOC }>(); | + + -error[E0284]: type annotations needed - --> $DIR/assoc_const_as_type_argument.rs:8:5 - | -LL | bar::<::ASSOC>(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer the value of the const parameter `N` declared on the function `bar` - | -note: required by a const generic parameter in `bar` - --> $DIR/assoc_const_as_type_argument.rs:5:8 - | -LL | fn bar() {} - | ^^^^^^^^^^^^^^ required by this const generic parameter in `bar` - -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors -Some errors have detailed explanations: E0284, E0575, E0747. -For more information about an error, try `rustc --explain E0284`. +Some errors have detailed explanations: E0575, E0747. +For more information about an error, try `rustc --explain E0575`. diff --git a/tests/ui/const-generics/const-arg-in-const-arg.min.stderr b/tests/ui/const-generics/const-arg-in-const-arg.min.stderr index 2ea9d6b35b451..ce7fce2599360 100644 --- a/tests/ui/const-generics/const-arg-in-const-arg.min.stderr +++ b/tests/ui/const-generics/const-arg-in-const-arg.min.stderr @@ -17,7 +17,7 @@ LL | let _: [u8; bar::()]; = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations - --> $DIR/const-arg-in-const-arg.rs:19:23 + --> $DIR/const-arg-in-const-arg.rs:18:23 | LL | let _: [u8; faz::<'a>(&())]; | ^^ cannot perform const operation using `'a` @@ -26,7 +26,7 @@ LL | let _: [u8; faz::<'a>(&())]; = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations - --> $DIR/const-arg-in-const-arg.rs:21:23 + --> $DIR/const-arg-in-const-arg.rs:20:23 | LL | let _: [u8; baz::<'a>(&())]; | ^^ cannot perform const operation using `'a` @@ -35,7 +35,7 @@ LL | let _: [u8; baz::<'a>(&())]; = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations - --> $DIR/const-arg-in-const-arg.rs:22:23 + --> $DIR/const-arg-in-const-arg.rs:21:23 | LL | let _: [u8; faz::<'b>(&())]; | ^^ cannot perform const operation using `'b` @@ -44,7 +44,7 @@ LL | let _: [u8; faz::<'b>(&())]; = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations - --> $DIR/const-arg-in-const-arg.rs:24:23 + --> $DIR/const-arg-in-const-arg.rs:23:23 | LL | let _: [u8; baz::<'b>(&())]; | ^^ cannot perform const operation using `'b` @@ -53,7 +53,7 @@ LL | let _: [u8; baz::<'b>(&())]; = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations - --> $DIR/const-arg-in-const-arg.rs:27:23 + --> $DIR/const-arg-in-const-arg.rs:26:23 | LL | let _ = [0; bar::()]; | ^ cannot perform const operation using `N` @@ -62,7 +62,7 @@ LL | let _ = [0; bar::()]; = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations - --> $DIR/const-arg-in-const-arg.rs:30:23 + --> $DIR/const-arg-in-const-arg.rs:28:23 | LL | let _ = [0; faz::<'a>(&())]; | ^^ cannot perform const operation using `'a` @@ -71,7 +71,7 @@ LL | let _ = [0; faz::<'a>(&())]; = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations - --> $DIR/const-arg-in-const-arg.rs:32:23 + --> $DIR/const-arg-in-const-arg.rs:30:23 | LL | let _ = [0; baz::<'a>(&())]; | ^^ cannot perform const operation using `'a` @@ -80,7 +80,7 @@ LL | let _ = [0; baz::<'a>(&())]; = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations - --> $DIR/const-arg-in-const-arg.rs:33:23 + --> $DIR/const-arg-in-const-arg.rs:31:23 | LL | let _ = [0; faz::<'b>(&())]; | ^^ cannot perform const operation using `'b` @@ -89,7 +89,7 @@ LL | let _ = [0; faz::<'b>(&())]; = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations - --> $DIR/const-arg-in-const-arg.rs:35:23 + --> $DIR/const-arg-in-const-arg.rs:33:23 | LL | let _ = [0; baz::<'b>(&())]; | ^^ cannot perform const operation using `'b` @@ -98,7 +98,7 @@ LL | let _ = [0; baz::<'b>(&())]; = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations - --> $DIR/const-arg-in-const-arg.rs:36:24 + --> $DIR/const-arg-in-const-arg.rs:34:24 | LL | let _: Foo<{ foo::() }>; | ^ cannot perform const operation using `T` @@ -107,7 +107,7 @@ LL | let _: Foo<{ foo::() }>; = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations - --> $DIR/const-arg-in-const-arg.rs:37:24 + --> $DIR/const-arg-in-const-arg.rs:35:24 | LL | let _: Foo<{ bar::() }>; | ^ cannot perform const operation using `N` @@ -116,7 +116,7 @@ LL | let _: Foo<{ bar::() }>; = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations - --> $DIR/const-arg-in-const-arg.rs:40:24 + --> $DIR/const-arg-in-const-arg.rs:37:24 | LL | let _: Foo<{ faz::<'a>(&()) }>; | ^^ cannot perform const operation using `'a` @@ -125,7 +125,7 @@ LL | let _: Foo<{ faz::<'a>(&()) }>; = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations - --> $DIR/const-arg-in-const-arg.rs:42:24 + --> $DIR/const-arg-in-const-arg.rs:39:24 | LL | let _: Foo<{ baz::<'a>(&()) }>; | ^^ cannot perform const operation using `'a` @@ -134,7 +134,7 @@ LL | let _: Foo<{ baz::<'a>(&()) }>; = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations - --> $DIR/const-arg-in-const-arg.rs:43:24 + --> $DIR/const-arg-in-const-arg.rs:40:24 | LL | let _: Foo<{ faz::<'b>(&()) }>; | ^^ cannot perform const operation using `'b` @@ -143,7 +143,7 @@ LL | let _: Foo<{ faz::<'b>(&()) }>; = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations - --> $DIR/const-arg-in-const-arg.rs:45:24 + --> $DIR/const-arg-in-const-arg.rs:42:24 | LL | let _: Foo<{ baz::<'b>(&()) }>; | ^^ cannot perform const operation using `'b` @@ -152,7 +152,7 @@ LL | let _: Foo<{ baz::<'b>(&()) }>; = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations - --> $DIR/const-arg-in-const-arg.rs:46:27 + --> $DIR/const-arg-in-const-arg.rs:43:27 | LL | let _ = Foo::<{ foo::() }>; | ^ cannot perform const operation using `T` @@ -161,7 +161,7 @@ LL | let _ = Foo::<{ foo::() }>; = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations - --> $DIR/const-arg-in-const-arg.rs:47:27 + --> $DIR/const-arg-in-const-arg.rs:44:27 | LL | let _ = Foo::<{ bar::() }>; | ^ cannot perform const operation using `N` @@ -170,7 +170,7 @@ LL | let _ = Foo::<{ bar::() }>; = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations - --> $DIR/const-arg-in-const-arg.rs:50:27 + --> $DIR/const-arg-in-const-arg.rs:46:27 | LL | let _ = Foo::<{ faz::<'a>(&()) }>; | ^^ cannot perform const operation using `'a` @@ -179,7 +179,7 @@ LL | let _ = Foo::<{ faz::<'a>(&()) }>; = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations - --> $DIR/const-arg-in-const-arg.rs:52:27 + --> $DIR/const-arg-in-const-arg.rs:48:27 | LL | let _ = Foo::<{ baz::<'a>(&()) }>; | ^^ cannot perform const operation using `'a` @@ -188,7 +188,7 @@ LL | let _ = Foo::<{ baz::<'a>(&()) }>; = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations - --> $DIR/const-arg-in-const-arg.rs:53:27 + --> $DIR/const-arg-in-const-arg.rs:49:27 | LL | let _ = Foo::<{ faz::<'b>(&()) }>; | ^^ cannot perform const operation using `'b` @@ -197,7 +197,7 @@ LL | let _ = Foo::<{ faz::<'b>(&()) }>; = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations - --> $DIR/const-arg-in-const-arg.rs:55:27 + --> $DIR/const-arg-in-const-arg.rs:51:27 | LL | let _ = Foo::<{ baz::<'b>(&()) }>; | ^^ cannot perform const operation using `'b` @@ -216,20 +216,8 @@ help: if this generic argument was intended as a const parameter, surround it wi LL | let _: [u8; bar::<{ N }>()]; | + + -error[E0284]: type annotations needed - --> $DIR/const-arg-in-const-arg.rs:16:17 - | -LL | let _: [u8; bar::()]; - | ^^^^^^^^ cannot infer the value of the const parameter `N` declared on the function `bar` - | -note: required by a const generic parameter in `bar` - --> $DIR/const-arg-in-const-arg.rs:9:14 - | -LL | const fn bar() -> usize { N } - | ^^^^^^^^^^^^^^ required by this const generic parameter in `bar` - error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present - --> $DIR/const-arg-in-const-arg.rs:19:23 + --> $DIR/const-arg-in-const-arg.rs:18:23 | LL | let _: [u8; faz::<'a>(&())]; | ^^ @@ -241,7 +229,7 @@ LL | const fn faz<'a>(_: &'a ()) -> usize { 13 } | ^^ error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present - --> $DIR/const-arg-in-const-arg.rs:22:23 + --> $DIR/const-arg-in-const-arg.rs:21:23 | LL | let _: [u8; faz::<'b>(&())]; | ^^ @@ -253,7 +241,7 @@ LL | const fn faz<'a>(_: &'a ()) -> usize { 13 } | ^^ error[E0747]: unresolved item provided when a constant was expected - --> $DIR/const-arg-in-const-arg.rs:37:24 + --> $DIR/const-arg-in-const-arg.rs:35:24 | LL | let _: Foo<{ bar::() }>; | ^ @@ -263,20 +251,8 @@ help: if this generic argument was intended as a const parameter, surround it wi LL | let _: Foo<{ bar::<{ N }>() }>; | + + -error[E0284]: type annotations needed - --> $DIR/const-arg-in-const-arg.rs:37:18 - | -LL | let _: Foo<{ bar::() }>; - | ^^^^^^^^ cannot infer the value of the const parameter `N` declared on the function `bar` - | -note: required by a const generic parameter in `bar` - --> $DIR/const-arg-in-const-arg.rs:9:14 - | -LL | const fn bar() -> usize { N } - | ^^^^^^^^^^^^^^ required by this const generic parameter in `bar` - error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present - --> $DIR/const-arg-in-const-arg.rs:40:24 + --> $DIR/const-arg-in-const-arg.rs:37:24 | LL | let _: Foo<{ faz::<'a>(&()) }>; | ^^ @@ -288,7 +264,7 @@ LL | const fn faz<'a>(_: &'a ()) -> usize { 13 } | ^^ error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present - --> $DIR/const-arg-in-const-arg.rs:43:24 + --> $DIR/const-arg-in-const-arg.rs:40:24 | LL | let _: Foo<{ faz::<'b>(&()) }>; | ^^ @@ -300,7 +276,7 @@ LL | const fn faz<'a>(_: &'a ()) -> usize { 13 } | ^^ error: constant expression depends on a generic parameter - --> $DIR/const-arg-in-const-arg.rs:26:17 + --> $DIR/const-arg-in-const-arg.rs:25:17 | LL | let _ = [0; foo::()]; | ^^^^^^^^^^ @@ -308,7 +284,7 @@ LL | let _ = [0; foo::()]; = note: this may fail depending on what value the parameter takes error[E0747]: unresolved item provided when a constant was expected - --> $DIR/const-arg-in-const-arg.rs:27:23 + --> $DIR/const-arg-in-const-arg.rs:26:23 | LL | let _ = [0; bar::()]; | ^ @@ -318,20 +294,8 @@ help: if this generic argument was intended as a const parameter, surround it wi LL | let _ = [0; bar::<{ N }>()]; | + + -error[E0284]: type annotations needed - --> $DIR/const-arg-in-const-arg.rs:27:17 - | -LL | let _ = [0; bar::()]; - | ^^^^^^^^ cannot infer the value of the const parameter `N` declared on the function `bar` - | -note: required by a const generic parameter in `bar` - --> $DIR/const-arg-in-const-arg.rs:9:14 - | -LL | const fn bar() -> usize { N } - | ^^^^^^^^^^^^^^ required by this const generic parameter in `bar` - error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present - --> $DIR/const-arg-in-const-arg.rs:30:23 + --> $DIR/const-arg-in-const-arg.rs:28:23 | LL | let _ = [0; faz::<'a>(&())]; | ^^ @@ -343,7 +307,7 @@ LL | const fn faz<'a>(_: &'a ()) -> usize { 13 } | ^^ error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present - --> $DIR/const-arg-in-const-arg.rs:33:23 + --> $DIR/const-arg-in-const-arg.rs:31:23 | LL | let _ = [0; faz::<'b>(&())]; | ^^ @@ -355,7 +319,7 @@ LL | const fn faz<'a>(_: &'a ()) -> usize { 13 } | ^^ error[E0747]: unresolved item provided when a constant was expected - --> $DIR/const-arg-in-const-arg.rs:47:27 + --> $DIR/const-arg-in-const-arg.rs:44:27 | LL | let _ = Foo::<{ bar::() }>; | ^ @@ -365,20 +329,8 @@ help: if this generic argument was intended as a const parameter, surround it wi LL | let _ = Foo::<{ bar::<{ N }>() }>; | + + -error[E0284]: type annotations needed - --> $DIR/const-arg-in-const-arg.rs:47:21 - | -LL | let _ = Foo::<{ bar::() }>; - | ^^^^^^^^ cannot infer the value of the const parameter `N` declared on the function `bar` - | -note: required by a const generic parameter in `bar` - --> $DIR/const-arg-in-const-arg.rs:9:14 - | -LL | const fn bar() -> usize { N } - | ^^^^^^^^^^^^^^ required by this const generic parameter in `bar` - error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present - --> $DIR/const-arg-in-const-arg.rs:50:27 + --> $DIR/const-arg-in-const-arg.rs:46:27 | LL | let _ = Foo::<{ faz::<'a>(&()) }>; | ^^ @@ -390,7 +342,7 @@ LL | const fn faz<'a>(_: &'a ()) -> usize { 13 } | ^^ error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present - --> $DIR/const-arg-in-const-arg.rs:53:27 + --> $DIR/const-arg-in-const-arg.rs:49:27 | LL | let _ = Foo::<{ faz::<'b>(&()) }>; | ^^ @@ -401,7 +353,7 @@ note: the late bound lifetime parameter is introduced here LL | const fn faz<'a>(_: &'a ()) -> usize { 13 } | ^^ -error: aborting due to 40 previous errors +error: aborting due to 36 previous errors -Some errors have detailed explanations: E0284, E0747, E0794. -For more information about an error, try `rustc --explain E0284`. +Some errors have detailed explanations: E0747, E0794. +For more information about an error, try `rustc --explain E0747`. diff --git a/tests/ui/const-generics/const-arg-in-const-arg.rs b/tests/ui/const-generics/const-arg-in-const-arg.rs index b95c63309f782..27b74489fe8e0 100644 --- a/tests/ui/const-generics/const-arg-in-const-arg.rs +++ b/tests/ui/const-generics/const-arg-in-const-arg.rs @@ -15,7 +15,6 @@ fn test<'a, 'b, T, const N: usize>() where &'b (): Sized { let _: [u8; foo::()]; //[min]~ ERROR generic parameters may not let _: [u8; bar::()]; //[min]~ ERROR generic parameters may not //[min]~^ ERROR unresolved item provided when a constant was expected - //[min]~| ERROR type annotations needed let _: [u8; faz::<'a>(&())]; //[min]~ ERROR generic parameters may not //[min]~^ ERROR cannot specify lifetime arguments let _: [u8; baz::<'a>(&())]; //[min]~ ERROR generic parameters may not @@ -26,7 +25,6 @@ fn test<'a, 'b, T, const N: usize>() where &'b (): Sized { let _ = [0; foo::()]; //[min]~ ERROR constant expression depends on a generic parameter let _ = [0; bar::()]; //[min]~ ERROR generic parameters may not //[min]~^ ERROR unresolved item provided when a constant was expected - //[min]~| ERROR type annotations needed let _ = [0; faz::<'a>(&())]; //[min]~ ERROR generic parameters may not //[min]~^ ERROR cannot specify lifetime arguments let _ = [0; baz::<'a>(&())]; //[min]~ ERROR generic parameters may not @@ -36,7 +34,6 @@ fn test<'a, 'b, T, const N: usize>() where &'b (): Sized { let _: Foo<{ foo::() }>; //[min]~ ERROR generic parameters may not let _: Foo<{ bar::() }>; //[min]~ ERROR generic parameters may not //[min]~^ ERROR unresolved item provided when a constant was expected - //[min]~| ERROR type annotations needed let _: Foo<{ faz::<'a>(&()) }>; //[min]~ ERROR generic parameters may not //[min]~^ ERROR cannot specify lifetime arguments let _: Foo<{ baz::<'a>(&()) }>; //[min]~ ERROR generic parameters may not @@ -46,7 +43,6 @@ fn test<'a, 'b, T, const N: usize>() where &'b (): Sized { let _ = Foo::<{ foo::() }>; //[min]~ ERROR generic parameters may not let _ = Foo::<{ bar::() }>; //[min]~ ERROR generic parameters may not //[min]~^ ERROR unresolved item provided when a constant was expected - //[min]~| ERROR type annotations needed let _ = Foo::<{ faz::<'a>(&()) }>; //[min]~ ERROR generic parameters may not //[min]~^ ERROR cannot specify lifetime arguments let _ = Foo::<{ baz::<'a>(&()) }>; //[min]~ ERROR generic parameters may not diff --git a/tests/ui/const-generics/issues/issue-62878.min.stderr b/tests/ui/const-generics/issues/issue-62878.min.stderr index 3fd50bbe29803..5205726d73845 100644 --- a/tests/ui/const-generics/issues/issue-62878.min.stderr +++ b/tests/ui/const-generics/issues/issue-62878.min.stderr @@ -30,31 +30,7 @@ help: add `#![feature(generic_arg_infer)]` to the crate attributes to enable LL + #![feature(generic_arg_infer)] | -error[E0284]: type annotations needed - --> $DIR/issue-62878.rs:10:5 - | -LL | foo::<_, { [1] }>(); - | ^^^^^^^^^^^^^^^^^ cannot infer the value of the const parameter `N` declared on the function `foo` - | -note: required by a const generic parameter in `foo` - --> $DIR/issue-62878.rs:5:8 - | -LL | fn foo() {} - | ^^^^^^^^^^^^^^ required by this const generic parameter in `foo` - -error[E0284]: type annotations needed - --> $DIR/issue-62878.rs:10:5 - | -LL | foo::<_, { [1] }>(); - | ^^^^^^^^^^^^^^^^^ cannot infer the value of the const parameter `A` declared on the function `foo` - | -note: required by a const generic parameter in `foo` - --> $DIR/issue-62878.rs:5:24 - | -LL | fn foo() {} - | ^^^^^^^^^^^^^^^^ required by this const generic parameter in `foo` - -error: aborting due to 5 previous errors +error: aborting due to 3 previous errors -Some errors have detailed explanations: E0284, E0747, E0770. -For more information about an error, try `rustc --explain E0284`. +Some errors have detailed explanations: E0747, E0770. +For more information about an error, try `rustc --explain E0747`. diff --git a/tests/ui/const-generics/issues/issue-62878.rs b/tests/ui/const-generics/issues/issue-62878.rs index c784e95edd824..0b5269df85ee1 100644 --- a/tests/ui/const-generics/issues/issue-62878.rs +++ b/tests/ui/const-generics/issues/issue-62878.rs @@ -9,6 +9,4 @@ fn foo() {} fn main() { foo::<_, { [1] }>(); //[min]~^ ERROR: type provided when a constant was expected - //[min]~| ERROR type annotations needed - //[min]~| ERROR type annotations needed } diff --git a/tests/ui/const-generics/min_const_generics/const-expression-suggest-missing-braces.rs b/tests/ui/const-generics/min_const_generics/const-expression-suggest-missing-braces.rs index 497c020bde43e..e12e07a28e763 100644 --- a/tests/ui/const-generics/min_const_generics/const-expression-suggest-missing-braces.rs +++ b/tests/ui/const-generics/min_const_generics/const-expression-suggest-missing-braces.rs @@ -12,7 +12,6 @@ fn b() { //~^ ERROR expected trait, found constant `BAR` //~| ERROR expected trait, found constant `BAR` //~| ERROR type provided when a constant was expected - //~| ERROR type annotations needed } fn c() { foo::<3 + 3>(); //~ ERROR expressions must be enclosed in braces diff --git a/tests/ui/const-generics/min_const_generics/const-expression-suggest-missing-braces.stderr b/tests/ui/const-generics/min_const_generics/const-expression-suggest-missing-braces.stderr index c2ba517f60960..d9bcc523b1fc4 100644 --- a/tests/ui/const-generics/min_const_generics/const-expression-suggest-missing-braces.stderr +++ b/tests/ui/const-generics/min_const_generics/const-expression-suggest-missing-braces.stderr @@ -10,7 +10,7 @@ LL | foo::<{ BAR + 3 }>(); | + + error: expressions must be enclosed in braces to be used as const generic arguments - --> $DIR/const-expression-suggest-missing-braces.rs:18:11 + --> $DIR/const-expression-suggest-missing-braces.rs:17:11 | LL | foo::<3 + 3>(); | ^^^^^ @@ -21,7 +21,7 @@ LL | foo::<{ 3 + 3 }>(); | + + error: expected one of `,` or `>`, found `-` - --> $DIR/const-expression-suggest-missing-braces.rs:21:15 + --> $DIR/const-expression-suggest-missing-braces.rs:20:15 | LL | foo::(); | ^ expected one of `,` or `>` @@ -32,7 +32,7 @@ LL | foo::<{ BAR - 3 }>(); | + + error: expected one of `,` or `>`, found `-` - --> $DIR/const-expression-suggest-missing-braces.rs:24:15 + --> $DIR/const-expression-suggest-missing-braces.rs:23:15 | LL | foo::(); | ^ expected one of `,` or `>` @@ -43,7 +43,7 @@ LL | foo::<{ BAR - BAR }>(); | + + error: expressions must be enclosed in braces to be used as const generic arguments - --> $DIR/const-expression-suggest-missing-braces.rs:27:11 + --> $DIR/const-expression-suggest-missing-braces.rs:26:11 | LL | foo::<100 - BAR>(); | ^^^^^^^^^ @@ -54,7 +54,7 @@ LL | foo::<{ 100 - BAR }>(); | + + error: expected one of `,` or `>`, found `(` - --> $DIR/const-expression-suggest-missing-braces.rs:30:19 + --> $DIR/const-expression-suggest-missing-braces.rs:29:19 | LL | foo::()>(); | ^ expected one of `,` or `>` @@ -65,7 +65,7 @@ LL | foo::<{ bar() }>(); | + + error: expected one of `,` or `>`, found `(` - --> $DIR/const-expression-suggest-missing-braces.rs:33:21 + --> $DIR/const-expression-suggest-missing-braces.rs:32:21 | LL | foo::()>(); | ^ expected one of `,` or `>` @@ -76,7 +76,7 @@ LL | foo::<{ bar::() }>(); | + + error: expected one of `,` or `>`, found `(` - --> $DIR/const-expression-suggest-missing-braces.rs:36:21 + --> $DIR/const-expression-suggest-missing-braces.rs:35:21 | LL | foo::() + BAR>(); | ^ expected one of `,` or `>` @@ -87,7 +87,7 @@ LL | foo::<{ bar::() + BAR }>(); | + + error: expected one of `,` or `>`, found `(` - --> $DIR/const-expression-suggest-missing-braces.rs:39:21 + --> $DIR/const-expression-suggest-missing-braces.rs:38:21 | LL | foo::() - BAR>(); | ^ expected one of `,` or `>` @@ -98,7 +98,7 @@ LL | foo::<{ bar::() - BAR }>(); | + + error: expected one of `,` or `>`, found `-` - --> $DIR/const-expression-suggest-missing-braces.rs:42:15 + --> $DIR/const-expression-suggest-missing-braces.rs:41:15 | LL | foo::()>(); | ^ expected one of `,` or `>` @@ -109,7 +109,7 @@ LL | foo::<{ BAR - bar::() }>(); | + + error: expected one of `,` or `>`, found `-` - --> $DIR/const-expression-suggest-missing-braces.rs:45:15 + --> $DIR/const-expression-suggest-missing-braces.rs:44:15 | LL | foo::()>(); | ^ expected one of `,` or `>` @@ -137,19 +137,7 @@ error[E0747]: type provided when a constant was expected LL | foo::(); | ^^^^^^^^^ -error[E0284]: type annotations needed - --> $DIR/const-expression-suggest-missing-braces.rs:11:5 - | -LL | foo::(); - | ^^^^^^^^^^^^^^^^ cannot infer the value of the const parameter `C` declared on the function `foo` - | -note: required by a const generic parameter in `foo` - --> $DIR/const-expression-suggest-missing-braces.rs:1:8 - | -LL | fn foo() {} - | ^^^^^^^^^^^^^^ required by this const generic parameter in `foo` - -error: aborting due to 15 previous errors +error: aborting due to 14 previous errors -Some errors have detailed explanations: E0284, E0404, E0747. -For more information about an error, try `rustc --explain E0284`. +Some errors have detailed explanations: E0404, E0747. +For more information about an error, try `rustc --explain E0404`. diff --git a/tests/ui/const-generics/min_const_generics/macro-fail.rs b/tests/ui/const-generics/min_const_generics/macro-fail.rs index 25726490c2cca..8cfa5293cc28f 100644 --- a/tests/ui/const-generics/min_const_generics/macro-fail.rs +++ b/tests/ui/const-generics/min_const_generics/macro-fail.rs @@ -16,7 +16,6 @@ fn make_marker() -> impl Marker { //~| ERROR: type provided when a constant was expected Example:: //~^ ERROR: type provided when a constant was expected - //~| ERROR type annotations needed } fn from_marker(_: impl Marker<{ @@ -37,10 +36,8 @@ fn main() { let _fail = Example::; //~^ ERROR: type provided when a constant - //~| ERROR type annotations needed let _fail = Example::; //~^ ERROR unexpected end of macro invocation //~| ERROR: type provided when a constant was expected - //~| ERROR type annotations needed } diff --git a/tests/ui/const-generics/min_const_generics/macro-fail.stderr b/tests/ui/const-generics/min_const_generics/macro-fail.stderr index 4e183fe5b1c55..34764982bb046 100644 --- a/tests/ui/const-generics/min_const_generics/macro-fail.stderr +++ b/tests/ui/const-generics/min_const_generics/macro-fail.stderr @@ -1,5 +1,5 @@ error: expected type, found `{` - --> $DIR/macro-fail.rs:31:27 + --> $DIR/macro-fail.rs:30:27 | LL | fn make_marker() -> impl Marker { | ---------------------- @@ -13,7 +13,7 @@ LL | ($rusty: ident) => {{ let $rusty = 3; *&$rusty }} = note: this error originates in the macro `gimme_a_const` (in Nightly builds, run with -Z macro-backtrace for more info) error: expected type, found `{` - --> $DIR/macro-fail.rs:31:27 + --> $DIR/macro-fail.rs:30:27 | LL | Example:: | ---------------------- @@ -41,7 +41,7 @@ LL | let _fail = Example::; = note: this error originates in the macro `external_macro` (in Nightly builds, run with -Z macro-backtrace for more info) error: unexpected end of macro invocation - --> $DIR/macro-fail.rs:42:25 + --> $DIR/macro-fail.rs:40:25 | LL | macro_rules! gimme_a_const { | -------------------------- when calling this macro @@ -50,7 +50,7 @@ LL | let _fail = Example::; | ^^^^^^^^^^^^^^^^ missing tokens in macro arguments | note: while trying to match meta-variable `$rusty:ident` - --> $DIR/macro-fail.rs:31:8 + --> $DIR/macro-fail.rs:30:8 | LL | ($rusty: ident) => {{ let $rusty = 3; *&$rusty }} | ^^^^^^^^^^^^^ @@ -75,63 +75,18 @@ error[E0747]: type provided when a constant was expected LL | Example:: | ^^^^^^^^^^^^^^^^^^^^^^ -error[E0284]: type annotations needed - --> $DIR/macro-fail.rs:17:3 - | -LL | Example:: - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer the value of the const parameter `N` declared on the struct `Example` - | -note: required by a const generic parameter in `Example` - --> $DIR/macro-fail.rs:1:16 - | -LL | struct Example; - | ^^^^^^^^^^^^^^ required by this const generic parameter in `Example` - error[E0747]: type provided when a constant was expected - --> $DIR/macro-fail.rs:38:25 + --> $DIR/macro-fail.rs:37:25 | LL | let _fail = Example::; | ^^^^^^^^^^^^^^^^^ error[E0747]: type provided when a constant was expected - --> $DIR/macro-fail.rs:42:25 + --> $DIR/macro-fail.rs:40:25 | LL | let _fail = Example::; | ^^^^^^^^^^^^^^^^ -error[E0284]: type annotations needed for `Example<_>` - --> $DIR/macro-fail.rs:38:7 - | -LL | let _fail = Example::; - | ^^^^^ ---------------------------- type must be known at this point - | -note: required by a const generic parameter in `Example` - --> $DIR/macro-fail.rs:1:16 - | -LL | struct Example; - | ^^^^^^^^^^^^^^ required by this const generic parameter in `Example` -help: consider giving `_fail` an explicit type, where the value of const parameter `N` is specified - | -LL | let _fail: Example = Example::; - | ++++++++++++ - -error[E0284]: type annotations needed for `Example<_>` - --> $DIR/macro-fail.rs:42:7 - | -LL | let _fail = Example::; - | ^^^^^ --------------------------- type must be known at this point - | -note: required by a const generic parameter in `Example` - --> $DIR/macro-fail.rs:1:16 - | -LL | struct Example; - | ^^^^^^^^^^^^^^ required by this const generic parameter in `Example` -help: consider giving `_fail` an explicit type, where the value of const parameter `N` is specified - | -LL | let _fail: Example = Example::; - | ++++++++++++ - -error: aborting due to 12 previous errors +error: aborting due to 9 previous errors -Some errors have detailed explanations: E0284, E0747. -For more information about an error, try `rustc --explain E0284`. +For more information about this error, try `rustc --explain E0747`. diff --git a/tests/ui/const-generics/suggest_const_for_array.rs b/tests/ui/const-generics/suggest_const_for_array.rs index 4d29d0693759f..b52fd152f976a 100644 --- a/tests/ui/const-generics/suggest_const_for_array.rs +++ b/tests/ui/const-generics/suggest_const_for_array.rs @@ -5,8 +5,6 @@ fn example() {} fn other() { example::<[usize; 3]>(); //~^ ERROR type provided when a const - //~| ERROR type annotations needed example::<[usize; 4 + 5]>(); //~^ ERROR type provided when a const - //~| ERROR type annotations needed } diff --git a/tests/ui/const-generics/suggest_const_for_array.stderr b/tests/ui/const-generics/suggest_const_for_array.stderr index c867914070bb7..f0ad8368e5d71 100644 --- a/tests/ui/const-generics/suggest_const_for_array.stderr +++ b/tests/ui/const-generics/suggest_const_for_array.stderr @@ -5,36 +5,11 @@ LL | example::<[usize; 3]>(); | ^^^^^^^^^^ help: array type provided where a `usize` was expected, try: `{ 3 }` error[E0747]: type provided when a constant was expected - --> $DIR/suggest_const_for_array.rs:9:15 + --> $DIR/suggest_const_for_array.rs:8:15 | LL | example::<[usize; 4 + 5]>(); | ^^^^^^^^^^^^^^ help: array type provided where a `usize` was expected, try: `{ 4 + 5 }` -error[E0284]: type annotations needed - --> $DIR/suggest_const_for_array.rs:6:5 - | -LL | example::<[usize; 3]>(); - | ^^^^^^^^^^^^^^^^^^^^^ cannot infer the value of the const parameter `N` declared on the function `example` - | -note: required by a const generic parameter in `example` - --> $DIR/suggest_const_for_array.rs:3:12 - | -LL | fn example() {} - | ^^^^^^^^^^^^^^ required by this const generic parameter in `example` - -error[E0284]: type annotations needed - --> $DIR/suggest_const_for_array.rs:9:5 - | -LL | example::<[usize; 4 + 5]>(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer the value of the const parameter `N` declared on the function `example` - | -note: required by a const generic parameter in `example` - --> $DIR/suggest_const_for_array.rs:3:12 - | -LL | fn example() {} - | ^^^^^^^^^^^^^^ required by this const generic parameter in `example` - -error: aborting due to 4 previous errors +error: aborting due to 2 previous errors -Some errors have detailed explanations: E0284, E0747. -For more information about an error, try `rustc --explain E0284`. +For more information about this error, try `rustc --explain E0747`. diff --git a/tests/ui/generics/generic-function-item-where-type.rs b/tests/ui/generics/generic-function-item-where-type.rs index 0e36018389e96..e1b0578cadbe9 100644 --- a/tests/ui/generics/generic-function-item-where-type.rs +++ b/tests/ui/generics/generic-function-item-where-type.rs @@ -3,5 +3,4 @@ fn foo() {} fn main() { foo::

    () //~^ ERROR constant provided when a type was expected - //~| ERROR type annotations needed } diff --git a/tests/ui/generics/generic-function-item-where-type.stderr b/tests/ui/generics/generic-function-item-where-type.stderr index 5b0c9a8ee6df5..00e62843cb4b6 100644 --- a/tests/ui/generics/generic-function-item-where-type.stderr +++ b/tests/ui/generics/generic-function-item-where-type.stderr @@ -7,13 +7,6 @@ LL | foo::
    () = help: `main` is a function item, not a type = help: function item types cannot be named directly -error[E0282]: type annotations needed - --> $DIR/generic-function-item-where-type.rs:4:5 - | -LL | foo::
    () - | ^^^^^^^^^^^ cannot infer type of the type parameter `U` declared on the function `foo` - -error: aborting due to 2 previous errors +error: aborting due to 1 previous error -Some errors have detailed explanations: E0282, E0747. -For more information about an error, try `rustc --explain E0282`. +For more information about this error, try `rustc --explain E0747`. From aece06482ebc7fae6044420e2d98f92101553c6f Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Fri, 5 Jul 2024 10:05:58 +0000 Subject: [PATCH 852/892] Remove HirTyLowerer::set_tainted_by_errors, since it is now redundant --- compiler/rustc_hir_analysis/src/collect.rs | 92 ++++++++++++------- .../rustc_hir_analysis/src/collect/type_of.rs | 27 ++++-- .../src/hir_ty_lowering/errors.rs | 43 +++------ .../src/hir_ty_lowering/mod.rs | 22 +---- .../src/hir_ty_lowering/object_safety.rs | 3 +- compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs | 6 +- 6 files changed, 97 insertions(+), 96 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index f83d74ecd3887..890f5d8a07476 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -163,7 +163,7 @@ pub struct CollectItemTypesVisitor<'tcx> { /// and suggest adding type parameters in the appropriate place, taking into consideration any and /// all already existing generic type parameters to avoid suggesting a name that is already in use. pub(crate) fn placeholder_type_error<'tcx>( - tcx: TyCtxt<'tcx>, + cx: &dyn HirTyLowerer<'tcx>, generics: Option<&hir::Generics<'_>>, placeholder_types: Vec, suggest: bool, @@ -174,21 +174,21 @@ pub(crate) fn placeholder_type_error<'tcx>( return; } - placeholder_type_error_diag(tcx, generics, placeholder_types, vec![], suggest, hir_ty, kind) + placeholder_type_error_diag(cx, generics, placeholder_types, vec![], suggest, hir_ty, kind) .emit(); } -pub(crate) fn placeholder_type_error_diag<'tcx>( - tcx: TyCtxt<'tcx>, +pub(crate) fn placeholder_type_error_diag<'cx, 'tcx>( + cx: &'cx dyn HirTyLowerer<'tcx>, generics: Option<&hir::Generics<'_>>, placeholder_types: Vec, additional_spans: Vec, suggest: bool, hir_ty: Option<&hir::Ty<'_>>, kind: &'static str, -) -> Diag<'tcx> { +) -> Diag<'cx> { if placeholder_types.is_empty() { - return bad_placeholder(tcx, additional_spans, kind); + return bad_placeholder(cx, additional_spans, kind); } let params = generics.map(|g| g.params).unwrap_or_default(); @@ -212,7 +212,7 @@ pub(crate) fn placeholder_type_error_diag<'tcx>( } let mut err = - bad_placeholder(tcx, placeholder_types.into_iter().chain(additional_spans).collect(), kind); + bad_placeholder(cx, placeholder_types.into_iter().chain(additional_spans).collect(), kind); // Suggest, but only if it is not a function in const or static if suggest { @@ -226,7 +226,7 @@ pub(crate) fn placeholder_type_error_diag<'tcx>( // Check if parent is const or static is_const_or_static = matches!( - tcx.parent_hir_node(hir_ty.hir_id), + cx.tcx().parent_hir_node(hir_ty.hir_id), Node::Item(&hir::Item { kind: hir::ItemKind::Const(..) | hir::ItemKind::Static(..), .. @@ -269,7 +269,16 @@ fn reject_placeholder_type_signatures_in_item<'tcx>( let mut visitor = HirPlaceholderCollector::default(); visitor.visit_item(item); - placeholder_type_error(tcx, Some(generics), visitor.0, suggest, None, item.kind.descr()); + let icx = ItemCtxt::new(tcx, item.owner_id.def_id); + + placeholder_type_error( + icx.lowerer(), + Some(generics), + visitor.0, + suggest, + None, + item.kind.descr(), + ); } impl<'tcx> Visitor<'tcx> for CollectItemTypesVisitor<'tcx> { @@ -331,15 +340,15 @@ impl<'tcx> Visitor<'tcx> for CollectItemTypesVisitor<'tcx> { /////////////////////////////////////////////////////////////////////////// // Utility types and common code for the above passes. -fn bad_placeholder<'tcx>( - tcx: TyCtxt<'tcx>, +fn bad_placeholder<'cx, 'tcx>( + cx: &'cx dyn HirTyLowerer<'tcx>, mut spans: Vec, kind: &'static str, -) -> Diag<'tcx> { +) -> Diag<'cx> { let kind = if kind.ends_with('s') { format!("{kind}es") } else { format!("{kind}s") }; spans.sort(); - tcx.dcx().create_err(errors::PlaceholderNotAllowedItemSignatures { spans, kind }) + cx.dcx().create_err(errors::PlaceholderNotAllowedItemSignatures { spans, kind }) } impl<'tcx> ItemCtxt<'tcx> { @@ -383,14 +392,13 @@ impl<'tcx> HirTyLowerer<'tcx> for ItemCtxt<'tcx> { fn re_infer(&self, span: Span, reason: RegionInferReason<'_>) -> ty::Region<'tcx> { if let RegionInferReason::BorrowedObjectLifetimeDefault = reason { let e = struct_span_code_err!( - self.tcx().dcx(), + self.dcx(), span, E0228, "the lifetime bound for this object type cannot be deduced \ from context; please supply an explicit bound" ) .emit(); - self.set_tainted_by_errors(e); ty::Region::new_error(self.tcx(), e) } else { // This indicates an illegal lifetime in a non-assoc-trait position @@ -515,10 +523,6 @@ impl<'tcx> HirTyLowerer<'tcx> for ItemCtxt<'tcx> { None } - fn set_tainted_by_errors(&self, err: ErrorGuaranteed) { - self.tainted_by_errors.set(Some(err)); - } - fn lower_fn_sig( &self, decl: &hir::FnDecl<'tcx>, @@ -576,7 +580,7 @@ impl<'tcx> HirTyLowerer<'tcx> for ItemCtxt<'tcx> { // `ident_span` to not emit an error twice when we have `fn foo(_: fn() -> _)`. let mut diag = crate::collect::placeholder_type_error_diag( - tcx, + self, generics, visitor.0, infer_replacements.iter().map(|(s, _)| *s).collect(), @@ -596,7 +600,7 @@ impl<'tcx> HirTyLowerer<'tcx> for ItemCtxt<'tcx> { ); } - self.set_tainted_by_errors(diag.emit()); + diag.emit(); } (input_tys, output_ty) @@ -645,6 +649,7 @@ fn lower_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) { let it = tcx.hir().item(item_id); debug!(item = %it.ident, id = %it.hir_id()); let def_id = item_id.owner_id.def_id; + let icx = ItemCtxt::new(tcx, def_id); match &it.kind { // These don't define types. @@ -669,7 +674,7 @@ fn lower_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) { let mut visitor = HirPlaceholderCollector::default(); visitor.visit_foreign_item(item); placeholder_type_error( - tcx, + icx.lowerer(), None, visitor.0, false, @@ -748,7 +753,14 @@ fn lower_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) { if !ty.is_suggestable_infer_ty() { let mut visitor = HirPlaceholderCollector::default(); visitor.visit_item(it); - placeholder_type_error(tcx, None, visitor.0, false, None, it.kind.descr()); + placeholder_type_error( + icx.lowerer(), + None, + visitor.0, + false, + None, + it.kind.descr(), + ); } } @@ -766,6 +778,7 @@ fn lower_trait_item(tcx: TyCtxt<'_>, trait_item_id: hir::TraitItemId) { let trait_item = tcx.hir().trait_item(trait_item_id); let def_id = trait_item_id.owner_id; tcx.ensure().generics_of(def_id); + let icx = ItemCtxt::new(tcx, def_id.def_id); match trait_item.kind { hir::TraitItemKind::Fn(..) => { @@ -782,7 +795,14 @@ fn lower_trait_item(tcx: TyCtxt<'_>, trait_item_id: hir::TraitItemId) { // Account for `const C: _;`. let mut visitor = HirPlaceholderCollector::default(); visitor.visit_trait_item(trait_item); - placeholder_type_error(tcx, None, visitor.0, false, None, "associated constant"); + placeholder_type_error( + icx.lowerer(), + None, + visitor.0, + false, + None, + "associated constant", + ); } } @@ -793,7 +813,7 @@ fn lower_trait_item(tcx: TyCtxt<'_>, trait_item_id: hir::TraitItemId) { // Account for `type T = _;`. let mut visitor = HirPlaceholderCollector::default(); visitor.visit_trait_item(trait_item); - placeholder_type_error(tcx, None, visitor.0, false, None, "associated type"); + placeholder_type_error(icx.lowerer(), None, visitor.0, false, None, "associated type"); } hir::TraitItemKind::Type(_, None) => { @@ -804,7 +824,7 @@ fn lower_trait_item(tcx: TyCtxt<'_>, trait_item_id: hir::TraitItemId) { let mut visitor = HirPlaceholderCollector::default(); visitor.visit_trait_item(trait_item); - placeholder_type_error(tcx, None, visitor.0, false, None, "associated type"); + placeholder_type_error(icx.lowerer(), None, visitor.0, false, None, "associated type"); } }; @@ -817,6 +837,7 @@ fn lower_impl_item(tcx: TyCtxt<'_>, impl_item_id: hir::ImplItemId) { tcx.ensure().type_of(def_id); tcx.ensure().predicates_of(def_id); let impl_item = tcx.hir().impl_item(impl_item_id); + let icx = ItemCtxt::new(tcx, def_id.def_id); match impl_item.kind { hir::ImplItemKind::Fn(..) => { tcx.ensure().codegen_fn_attrs(def_id); @@ -827,14 +848,21 @@ fn lower_impl_item(tcx: TyCtxt<'_>, impl_item_id: hir::ImplItemId) { let mut visitor = HirPlaceholderCollector::default(); visitor.visit_impl_item(impl_item); - placeholder_type_error(tcx, None, visitor.0, false, None, "associated type"); + placeholder_type_error(icx.lowerer(), None, visitor.0, false, None, "associated type"); } hir::ImplItemKind::Const(ty, _) => { // Account for `const T: _ = ..;` if !ty.is_suggestable_infer_ty() { let mut visitor = HirPlaceholderCollector::default(); visitor.visit_impl_item(impl_item); - placeholder_type_error(tcx, None, visitor.0, false, None, "associated constant"); + placeholder_type_error( + icx.lowerer(), + None, + visitor.0, + false, + None, + "associated constant", + ); } } } @@ -1385,7 +1413,7 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_, ty::PolyFn .. }) | Item(hir::Item { kind: ItemKind::Fn(sig, generics, _), .. }) => { - infer_return_ty_for_fn_sig(tcx, sig, generics, def_id, &icx) + infer_return_ty_for_fn_sig(sig, generics, def_id, &icx) } ImplItem(hir::ImplItem { kind: ImplItemKind::Fn(sig, _), generics, .. }) => { @@ -1402,7 +1430,7 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_, ty::PolyFn None, ) } else { - infer_return_ty_for_fn_sig(tcx, sig, generics, def_id, &icx) + infer_return_ty_for_fn_sig(sig, generics, def_id, &icx) } } @@ -1455,12 +1483,12 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_, ty::PolyFn } fn infer_return_ty_for_fn_sig<'tcx>( - tcx: TyCtxt<'tcx>, sig: &hir::FnSig<'tcx>, generics: &hir::Generics<'_>, def_id: LocalDefId, icx: &ItemCtxt<'tcx>, ) -> ty::PolyFnSig<'tcx> { + let tcx = icx.tcx; let hir_id = tcx.local_def_id_to_hir_id(def_id); match sig.decl.output.get_infer_ret_ty() { @@ -1492,7 +1520,7 @@ fn infer_return_ty_for_fn_sig<'tcx>( let mut visitor = HirPlaceholderCollector::default(); visitor.visit_ty(ty); - let mut diag = bad_placeholder(tcx, visitor.0, "return type"); + let mut diag = bad_placeholder(icx.lowerer(), visitor.0, "return type"); let ret_ty = fn_sig.output(); // Don't leak types into signatures unless they're nameable! // For example, if a function returns itself, we don't want that diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs index 1e2b0c4323385..974dd415f464c 100644 --- a/compiler/rustc_hir_analysis/src/collect/type_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs @@ -12,6 +12,7 @@ use rustc_span::symbol::Ident; use rustc_span::{Span, DUMMY_SP}; use crate::errors::TypeofReservedKeywordUsed; +use crate::hir_ty_lowering::HirTyLowerer; use super::bad_placeholder; use super::ItemCtxt; @@ -357,7 +358,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_ .and_then(|body_id| { ty.is_suggestable_infer_ty().then(|| { infer_placeholder_type( - tcx, + icx.lowerer(), def_id, body_id, ty.span, @@ -381,7 +382,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_ ImplItemKind::Const(ty, body_id) => { if ty.is_suggestable_infer_ty() { infer_placeholder_type( - tcx, + icx.lowerer(), def_id, body_id, ty.span, @@ -405,7 +406,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_ ItemKind::Static(ty, .., body_id) => { if ty.is_suggestable_infer_ty() { infer_placeholder_type( - tcx, + icx.lowerer(), def_id, body_id, ty.span, @@ -418,7 +419,14 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_ } ItemKind::Const(ty, _, body_id) => { if ty.is_suggestable_infer_ty() { - infer_placeholder_type(tcx, def_id, body_id, ty.span, item.ident, "constant") + infer_placeholder_type( + icx.lowerer(), + def_id, + body_id, + ty.span, + item.ident, + "constant", + ) } else { icx.lower_ty(ty) } @@ -559,21 +567,22 @@ pub(super) fn type_of_opaque( } } -fn infer_placeholder_type<'a>( - tcx: TyCtxt<'a>, +fn infer_placeholder_type<'tcx>( + cx: &dyn HirTyLowerer<'tcx>, def_id: LocalDefId, body_id: hir::BodyId, span: Span, item_ident: Ident, kind: &'static str, -) -> Ty<'a> { +) -> Ty<'tcx> { + let tcx = cx.tcx(); let ty = tcx.diagnostic_only_typeck(def_id).node_type(body_id.hir_id); // If this came from a free `const` or `static mut?` item, // then the user may have written e.g. `const A = 42;`. // In this case, the parser has stashed a diagnostic for // us to improve in typeck so we do that now. - let guar = tcx + let guar = cx .dcx() .try_steal_modify_and_emit_err(span, StashKey::ItemNoType, |err| { if !ty.references_error() { @@ -602,7 +611,7 @@ fn infer_placeholder_type<'a>( } }) .unwrap_or_else(|| { - let mut diag = bad_placeholder(tcx, vec![span], kind); + let mut diag = bad_placeholder(cx, vec![span], kind); if !ty.references_error() { if let Some(ty) = ty.make_suggestable(tcx, false, None) { diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs index d8bbe403f1f50..983924a4b0873 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs @@ -462,9 +462,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { } } } - let reported = err.emit(); - self.set_tainted_by_errors(reported); - reported + err.emit() } pub(crate) fn complain_about_ambiguous_inherent_assoc_ty( @@ -481,9 +479,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { ); err.span_label(name.span, format!("multiple `{name}` found")); self.note_ambiguous_inherent_assoc_ty(&mut err, candidates, span); - let reported = err.emit(); - self.set_tainted_by_errors(reported); - reported + err.emit() } // FIXME(fmease): Heavily adapted from `rustc_hir_typeck::method::suggest`. Deduplicate. @@ -973,7 +969,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { } } - self.set_tainted_by_errors(err.emit()); + err.emit(); } /// On ambiguous associated type, look for an associated function whose name matches the @@ -1010,17 +1006,14 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { .filter_by_name_unhygienic(Symbol::intern(&name)) .next() { - let reported = - struct_span_code_err!(self.dcx(), span, E0223, "ambiguous associated type") - .with_span_suggestion_verbose( - ident2.span.to(ident3.span), - format!("there is an associated function with a similar name: `{name}`"), - name, - Applicability::MaybeIncorrect, - ) - .emit(); - self.set_tainted_by_errors(reported); - Err(reported) + Err(struct_span_code_err!(self.dcx(), span, E0223, "ambiguous associated type") + .with_span_suggestion_verbose( + ident2.span.to(ident3.span), + format!("there is an associated function with a similar name: `{name}`"), + name, + Applicability::MaybeIncorrect, + ) + .emit()) } else { Ok(()) } @@ -1129,9 +1122,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { err.span_label(span, format!("not allowed on {what}")); } generics_args_err_extend(self.tcx(), segments, &mut err, err_extend); - let reported = err.emit(); - self.set_tainted_by_errors(reported); - reported + err.emit() } pub fn report_trait_object_addition_traits_error( @@ -1167,9 +1158,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { for more information on them, visit \ ", ); - let reported = err.emit(); - self.set_tainted_by_errors(reported); - reported + err.emit() } pub fn report_trait_object_with_no_traits_error( @@ -1183,10 +1172,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { .map(|&(trait_ref, _)| trait_ref.def_id()) .find(|&trait_ref| tcx.is_trait_alias(trait_ref)) .map(|trait_ref| tcx.def_span(trait_ref)); - let reported = - self.dcx().emit_err(TraitObjectDeclaredWithNoTraits { span, trait_alias_span }); - self.set_tainted_by_errors(reported); - reported + + self.dcx().emit_err(TraitObjectDeclaredWithNoTraits { span, trait_alias_span }) } } diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs index e8a4ab103bd2b..0482277975cac 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -180,12 +180,6 @@ pub trait HirTyLowerer<'tcx> { /// The inference context of the lowering context if applicable. fn infcx(&self) -> Option<&InferCtxt<'tcx>>; - /// Taint the context with errors. - /// - /// Invoke this when you encounter an error from some prior pass like name resolution. - /// This is used to help suppress derived errors typeck might otherwise report. - fn set_tainted_by_errors(&self, e: ErrorGuaranteed); - /// Convenience method for coercing the lowering context into a trait object type. /// /// Most lowering routines are defined on the trait object type directly @@ -405,10 +399,6 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { self_ty.is_some(), ); - if let Err(err) = &arg_count.correct { - self.set_tainted_by_errors(err.reported); - } - // Skip processing if type has no generic parameters. // Traits always have `Self` as a generic parameter, which means they will not return early // here and so associated item constraints will be handled regardless of whether there are @@ -569,7 +559,6 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { span, modifier: constness.as_str(), }); - self.set_tainted_by_errors(reported); arg_count.correct = Err(GenericArgCountMismatch { reported, invalid_args: vec![] }); } @@ -876,7 +865,6 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { span, constraint, ); - self.set_tainted_by_errors(reported); return Err(reported); }; debug!(?bound); @@ -959,7 +947,6 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { )); } let reported = err.emit(); - self.set_tainted_by_errors(reported); if !where_bounds.is_empty() { return Err(reported); } @@ -1152,7 +1139,6 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { assoc_ident.name, ) }; - self.set_tainted_by_errors(reported); return Err(reported); } }; @@ -1403,13 +1389,12 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { let tcx = self.tcx(); if !tcx.visibility(item_def_id).is_accessible_from(scope, tcx) { - let reported = self.dcx().emit_err(crate::errors::AssocItemIsPrivate { + self.dcx().emit_err(crate::errors::AssocItemIsPrivate { span, kind: tcx.def_descr(item_def_id), name: ident, defined_here_label: tcx.def_span(item_def_id), }); - self.set_tainted_by_errors(reported); } tcx.check_stability(item_def_id, Some(block), span, None); @@ -1835,7 +1820,6 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { err.span_note(impl_.self_ty.span, "not a concrete type"); } let reported = err.emit(); - self.set_tainted_by_errors(reported); Ty::new_error(tcx, reported) } else { ty @@ -1882,7 +1866,6 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { .tcx() .dcx() .span_delayed_bug(path.span, "path with `Res::Err` but no error emitted"); - self.set_tainted_by_errors(e); Ty::new_error(self.tcx(), e) } Res::Def(..) => { @@ -2017,7 +2000,6 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { if self.check_delegation_constraints(sig_id, span, idx == hir::InferDelegationKind::Output) { let e = self.dcx().span_delayed_bug(span, "not supported delegation case"); - self.set_tainted_by_errors(e); return Ty::new_error(self.tcx(), e); }; let sig = self.tcx().fn_sig(sig_id); @@ -2442,7 +2424,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { err.note("consider introducing a named lifetime parameter"); } - self.set_tainted_by_errors(err.emit()); + err.emit(); } } diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/object_safety.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/object_safety.rs index bbb37be5c9f3f..af8fbc9b987d1 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/object_safety.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/object_safety.rs @@ -262,7 +262,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { if references_self { let def_id = i.bottom().0.def_id(); - let reported = struct_span_code_err!( + struct_span_code_err!( self.dcx(), i.bottom().1, E0038, @@ -275,7 +275,6 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { .error_msg(), ) .emit(); - self.set_tainted_by_errors(reported); } ty::ExistentialTraitRef { def_id: trait_ref.def_id, args } diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs index 1de2935ecaf73..b5796fbd48a88 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs @@ -5,7 +5,7 @@ mod checks; mod inspect_obligations; mod suggestions; -use rustc_errors::{DiagCtxtHandle, ErrorGuaranteed}; +use rustc_errors::DiagCtxtHandle; use crate::coercion::DynamicCoerceMany; use crate::fallback::DivergingFallbackBehavior; @@ -342,10 +342,6 @@ impl<'tcx> HirTyLowerer<'tcx> for FnCtxt<'_, 'tcx> { Some(&self.infcx) } - fn set_tainted_by_errors(&self, e: ErrorGuaranteed) { - self.infcx.set_tainted_by_errors(e) - } - fn lower_fn_sig( &self, decl: &rustc_hir::FnDecl<'tcx>, From dd175feb25bc09484a74994a1b80af290eeb6509 Mon Sep 17 00:00:00 2001 From: lcnr Date: Tue, 9 Jul 2024 09:39:13 +0200 Subject: [PATCH 853/892] cycle_participants to nested_goals --- .../src/solve/search_graph.rs | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/compiler/rustc_next_trait_solver/src/solve/search_graph.rs b/compiler/rustc_next_trait_solver/src/solve/search_graph.rs index f8a50913f05f8..69d52dcad7a59 100644 --- a/compiler/rustc_next_trait_solver/src/solve/search_graph.rs +++ b/compiler/rustc_next_trait_solver/src/solve/search_graph.rs @@ -71,7 +71,7 @@ struct StackEntry { /// C :- D /// D :- C /// ``` - cycle_participants: HashSet>, + nested_goals: HashSet>, /// Starts out as `None` and gets set when rerunning this /// goal in case we encounter a cycle. provisional_result: Option>, @@ -215,8 +215,8 @@ impl SearchGraph { let current_cycle_root = &mut stack[current_root.as_usize()]; for entry in cycle_participants { entry.non_root_cycle_participant = entry.non_root_cycle_participant.max(Some(head)); - current_cycle_root.cycle_participants.insert(entry.input); - current_cycle_root.cycle_participants.extend(mem::take(&mut entry.cycle_participants)); + current_cycle_root.nested_goals.insert(entry.input); + current_cycle_root.nested_goals.extend(mem::take(&mut entry.nested_goals)); } } @@ -335,7 +335,7 @@ impl SearchGraph { non_root_cycle_participant: None, encountered_overflow: false, has_been_used: HasBeenUsed::empty(), - cycle_participants: Default::default(), + nested_goals: Default::default(), provisional_result: None, }; assert_eq!(self.stack.push(entry), depth); @@ -389,7 +389,7 @@ impl SearchGraph { // // We must not use the global cache entry of a root goal if a cycle // participant is on the stack. This is necessary to prevent unstable - // results. See the comment of `StackEntry::cycle_participants` for + // results. See the comment of `StackEntry::nested_goals` for // more details. self.global_cache(cx).insert( cx, @@ -397,7 +397,7 @@ impl SearchGraph { proof_tree, reached_depth, final_entry.encountered_overflow, - final_entry.cycle_participants, + final_entry.nested_goals, dep_node, result, ) @@ -544,27 +544,27 @@ impl SearchGraph { non_root_cycle_participant, encountered_overflow: _, has_been_used, - ref cycle_participants, + ref nested_goals, provisional_result, } = *entry; let cache_entry = provisional_cache.get(&entry.input).unwrap(); assert_eq!(cache_entry.stack_depth, Some(depth)); if let Some(head) = non_root_cycle_participant { assert!(head < depth); - assert!(cycle_participants.is_empty()); + assert!(nested_goals.is_empty()); assert_ne!(stack[head].has_been_used, HasBeenUsed::empty()); let mut current_root = head; while let Some(parent) = stack[current_root].non_root_cycle_participant { current_root = parent; } - assert!(stack[current_root].cycle_participants.contains(&input)); + assert!(stack[current_root].nested_goals.contains(&input)); } - if !cycle_participants.is_empty() { + if !nested_goals.is_empty() { assert!(provisional_result.is_some() || !has_been_used.is_empty()); for entry in stack.iter().take(depth.as_usize()) { - assert_eq!(cycle_participants.get(&entry.input), None); + assert_eq!(nested_goals.get(&entry.input), None); } } } From b4b2643c111714b541db1c18c178ad0ce654238b Mon Sep 17 00:00:00 2001 From: Pietro Albini Date: Mon, 8 Jul 2024 17:24:28 +0200 Subject: [PATCH 854/892] set the correct rustc and cargo even for tests invoking parse_inner --- src/bootstrap/src/core/config/config.rs | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs index 882bae8aeb6a1..458120fd2027c 100644 --- a/src/bootstrap/src/core/config/config.rs +++ b/src/bootstrap/src/core/config/config.rs @@ -1189,19 +1189,7 @@ impl Config { pub fn parse(args: &[String]) -> Config { #[cfg(test)] fn get_toml(_: &Path) -> TomlConfig { - let mut default = TomlConfig::default(); - - // When configuring bootstrap for tests, make sure to set the rustc and Cargo to the - // same ones used to call the tests. If we don't do that, bootstrap will use its own - // detection logic to find a suitable rustc and Cargo, which doesn't work when the - // caller is specìfying a custom local rustc or Cargo in their config.toml. - default.build = Some(Build { - rustc: std::env::var_os("RUSTC").map(|v| v.into()), - cargo: std::env::var_os("CARGO").map(|v| v.into()), - ..Build::default() - }); - - default + TomlConfig::default() } #[cfg(not(test))] @@ -1341,6 +1329,17 @@ impl Config { TomlConfig::default() }; + if cfg!(test) { + // When configuring bootstrap for tests, make sure to set the rustc and Cargo to the + // same ones used to call the tests (if custom ones are not defined in the toml). If we + // don't do that, bootstrap will use its own detection logic to find a suitable rustc + // and Cargo, which doesn't work when the caller is specìfying a custom local rustc or + // Cargo in their config.toml. + let build = toml.build.get_or_insert_with(Default::default); + build.rustc = build.rustc.take().or(std::env::var_os("RUSTC").map(|p| p.into())); + build.cargo = build.cargo.take().or(std::env::var_os("CARGO").map(|p| p.into())); + } + if let Some(include) = &toml.profile { // Allows creating alias for profile names, allowing // profiles to be renamed while maintaining back compatibility From 7af825fea4fea17d0b58fcd8c1f2b6fa11638cfb Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 8 Jul 2024 16:23:01 -0400 Subject: [PATCH 855/892] Split out overflow handling into its own module --- .../src/error_reporting/traits/mod.rs | 2 + .../src/error_reporting/traits/overflow.rs | 197 ++++++++++++++++++ .../traits/type_err_ctxt_ext.rs | 182 +--------------- .../src/solve/normalize.rs | 2 +- .../src/traits/fulfill.rs | 2 +- .../src/traits/normalize.rs | 2 +- .../src/traits/query/normalize.rs | 2 +- .../src/traits/select/mod.rs | 2 +- compiler/rustc_traits/src/codegen.rs | 2 +- .../src/normalize_projection_ty.rs | 2 +- 10 files changed, 208 insertions(+), 187 deletions(-) create mode 100644 compiler/rustc_trait_selection/src/error_reporting/traits/overflow.rs diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs index 438b25056c338..7d334d623cc24 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs @@ -3,6 +3,7 @@ pub mod ambiguity; mod infer_ctxt_ext; pub mod on_unimplemented; +mod overflow; pub mod suggestions; mod type_err_ctxt_ext; @@ -17,6 +18,7 @@ use rustc_span::Span; use std::ops::ControlFlow; pub use self::infer_ctxt_ext::*; +pub use self::overflow::*; pub use self::type_err_ctxt_ext::*; // When outputting impl candidates, prefer showing those that are more similar. diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/overflow.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/overflow.rs new file mode 100644 index 0000000000000..061a5a4be2075 --- /dev/null +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/overflow.rs @@ -0,0 +1,197 @@ +use std::fmt; + +use rustc_errors::{ + struct_span_code_err, Diag, EmissionGuarantee, ErrorGuaranteed, FatalError, E0275, +}; +use rustc_hir::def::Namespace; +use rustc_hir::def_id::LOCAL_CRATE; +use rustc_infer::infer::error_reporting::TypeErrCtxt; +use rustc_infer::traits::{Obligation, PredicateObligation}; +use rustc_macros::extension; +use rustc_middle::ty::print::{FmtPrinter, Print}; +use rustc_middle::ty::{self, TyCtxt}; +use rustc_session::Limit; +use rustc_span::Span; +use rustc_type_ir::Upcast; + +use super::InferCtxtPrivExt; +use crate::error_reporting::traits::suggestions::TypeErrCtxtExt; + +pub enum OverflowCause<'tcx> { + DeeplyNormalize(ty::AliasTerm<'tcx>), + TraitSolver(ty::Predicate<'tcx>), +} + +pub fn suggest_new_overflow_limit<'tcx, G: EmissionGuarantee>( + tcx: TyCtxt<'tcx>, + err: &mut Diag<'_, G>, +) { + let suggested_limit = match tcx.recursion_limit() { + Limit(0) => Limit(2), + limit => limit * 2, + }; + err.help(format!( + "consider increasing the recursion limit by adding a \ + `#![recursion_limit = \"{}\"]` attribute to your crate (`{}`)", + suggested_limit, + tcx.crate_name(LOCAL_CRATE), + )); +} + +#[extension(pub trait TypeErrCtxtOverflowExt<'a, 'tcx>)] +impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { + /// Reports that an overflow has occurred and halts compilation. We + /// halt compilation unconditionally because it is important that + /// overflows never be masked -- they basically represent computations + /// whose result could not be truly determined and thus we can't say + /// if the program type checks or not -- and they are unusual + /// occurrences in any case. + fn report_overflow_error( + &self, + cause: OverflowCause<'tcx>, + span: Span, + suggest_increasing_limit: bool, + mutate: impl FnOnce(&mut Diag<'_>), + ) -> ! { + let mut err = self.build_overflow_error(cause, span, suggest_increasing_limit); + mutate(&mut err); + err.emit(); + FatalError.raise(); + } + + fn build_overflow_error( + &self, + cause: OverflowCause<'tcx>, + span: Span, + suggest_increasing_limit: bool, + ) -> Diag<'a> { + fn with_short_path<'tcx, T>(tcx: TyCtxt<'tcx>, value: T) -> String + where + T: fmt::Display + Print<'tcx, FmtPrinter<'tcx, 'tcx>>, + { + let s = value.to_string(); + if s.len() > 50 { + // We don't need to save the type to a file, we will be talking about this type already + // in a separate note when we explain the obligation, so it will be available that way. + let mut cx: FmtPrinter<'_, '_> = + FmtPrinter::new_with_limit(tcx, Namespace::TypeNS, rustc_session::Limit(6)); + value.print(&mut cx).unwrap(); + cx.into_buffer() + } else { + s + } + } + + let mut err = match cause { + OverflowCause::DeeplyNormalize(alias_term) => { + let alias_term = self.resolve_vars_if_possible(alias_term); + let kind = alias_term.kind(self.tcx).descr(); + let alias_str = with_short_path(self.tcx, alias_term); + struct_span_code_err!( + self.dcx(), + span, + E0275, + "overflow normalizing the {kind} `{alias_str}`", + ) + } + OverflowCause::TraitSolver(predicate) => { + let predicate = self.resolve_vars_if_possible(predicate); + match predicate.kind().skip_binder() { + ty::PredicateKind::Subtype(ty::SubtypePredicate { a, b, a_is_expected: _ }) + | ty::PredicateKind::Coerce(ty::CoercePredicate { a, b }) => { + struct_span_code_err!( + self.dcx(), + span, + E0275, + "overflow assigning `{a}` to `{b}`", + ) + } + _ => { + let pred_str = with_short_path(self.tcx, predicate); + struct_span_code_err!( + self.dcx(), + span, + E0275, + "overflow evaluating the requirement `{pred_str}`", + ) + } + } + } + }; + + if suggest_increasing_limit { + suggest_new_overflow_limit(self.tcx, &mut err); + } + + err + } + + /// Reports that an overflow has occurred and halts compilation. We + /// halt compilation unconditionally because it is important that + /// overflows never be masked -- they basically represent computations + /// whose result could not be truly determined and thus we can't say + /// if the program type checks or not -- and they are unusual + /// occurrences in any case. + fn report_overflow_obligation( + &self, + obligation: &Obligation<'tcx, T>, + suggest_increasing_limit: bool, + ) -> ! + where + T: Upcast, ty::Predicate<'tcx>> + Clone, + { + let predicate = obligation.predicate.clone().upcast(self.tcx); + let predicate = self.resolve_vars_if_possible(predicate); + self.report_overflow_error( + OverflowCause::TraitSolver(predicate), + obligation.cause.span, + suggest_increasing_limit, + |err| { + self.note_obligation_cause_code( + obligation.cause.body_id, + err, + predicate, + obligation.param_env, + obligation.cause.code(), + &mut vec![], + &mut Default::default(), + ); + }, + ); + } + + /// Reports that a cycle was detected which led to overflow and halts + /// compilation. This is equivalent to `report_overflow_obligation` except + /// that we can give a more helpful error message (and, in particular, + /// we do not suggest increasing the overflow limit, which is not + /// going to help). + fn report_overflow_obligation_cycle(&self, cycle: &[PredicateObligation<'tcx>]) -> ! { + let cycle = self.resolve_vars_if_possible(cycle.to_owned()); + assert!(!cycle.is_empty()); + + debug!(?cycle, "report_overflow_error_cycle"); + + // The 'deepest' obligation is most likely to have a useful + // cause 'backtrace' + self.report_overflow_obligation( + cycle.iter().max_by_key(|p| p.recursion_depth).unwrap(), + false, + ); + } + + fn report_overflow_no_abort( + &self, + obligation: PredicateObligation<'tcx>, + suggest_increasing_limit: bool, + ) -> ErrorGuaranteed { + let obligation = self.resolve_vars_if_possible(obligation); + let mut err = self.build_overflow_error( + OverflowCause::TraitSolver(obligation.predicate), + obligation.cause.span, + suggest_increasing_limit, + ); + self.note_obligation_cause(&mut err, &obligation); + self.point_at_returns_when_relevant(&mut err, &obligation); + err.emit() + } +} diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/type_err_ctxt_ext.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/type_err_ctxt_ext.rs index 7843a95d9667e..ee5f4f44251c0 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/type_err_ctxt_ext.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/type_err_ctxt_ext.rs @@ -3,6 +3,7 @@ use super::on_unimplemented::{AppendConstMessage, OnUnimplementedNote, TypeErrCtxtExt as _}; use super::suggestions::{get_explanation_based_on_obligation, TypeErrCtxtExt as _}; use crate::error_reporting::traits::infer_ctxt_ext::InferCtxtExt; +use crate::error_reporting::traits::overflow::TypeErrCtxtOverflowExt; use crate::error_reporting::traits::to_pretty_impl_header; use crate::error_reporting::traits::{ambiguity, ambiguity::CandidateSource::*}; use crate::errors::{ @@ -23,7 +24,7 @@ use rustc_data_structures::fx::{FxHashMap, FxIndexMap}; use rustc_data_structures::unord::UnordSet; use rustc_errors::codes::*; use rustc_errors::{pluralize, struct_span_code_err, Applicability, MultiSpan, StringPart}; -use rustc_errors::{Diag, EmissionGuarantee, ErrorGuaranteed, FatalError, StashKey}; +use rustc_errors::{Diag, ErrorGuaranteed, StashKey}; use rustc_hir::def::{DefKind, Namespace, Res}; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::intravisit::Visitor; @@ -46,12 +47,9 @@ use rustc_middle::ty::{ TypeVisitableExt, Upcast, }; use rustc_middle::{bug, span_bug}; -use rustc_session::Limit; -use rustc_span::def_id::LOCAL_CRATE; use rustc_span::symbol::sym; use rustc_span::{BytePos, ExpnKind, Span, Symbol, DUMMY_SP}; use std::borrow::Cow; -use std::fmt; use std::iter; use super::{ @@ -61,27 +59,6 @@ use super::{ pub use rustc_infer::traits::error_reporting::*; -pub enum OverflowCause<'tcx> { - DeeplyNormalize(ty::AliasTerm<'tcx>), - TraitSolver(ty::Predicate<'tcx>), -} - -pub fn suggest_new_overflow_limit<'tcx, G: EmissionGuarantee>( - tcx: TyCtxt<'tcx>, - err: &mut Diag<'_, G>, -) { - let suggested_limit = match tcx.recursion_limit() { - Limit(0) => Limit(2), - limit => limit * 2, - }; - err.help(format!( - "consider increasing the recursion limit by adding a \ - `#![recursion_limit = \"{}\"]` attribute to your crate (`{}`)", - suggested_limit, - tcx.crate_name(LOCAL_CRATE), - )); -} - #[extension(pub trait TypeErrCtxtExt<'a, 'tcx>)] impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { fn report_fulfillment_errors( @@ -204,161 +181,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { reported.unwrap_or_else(|| self.dcx().delayed_bug("failed to report fulfillment errors")) } - /// Reports that an overflow has occurred and halts compilation. We - /// halt compilation unconditionally because it is important that - /// overflows never be masked -- they basically represent computations - /// whose result could not be truly determined and thus we can't say - /// if the program type checks or not -- and they are unusual - /// occurrences in any case. - fn report_overflow_error( - &self, - cause: OverflowCause<'tcx>, - span: Span, - suggest_increasing_limit: bool, - mutate: impl FnOnce(&mut Diag<'_>), - ) -> ! { - let mut err = self.build_overflow_error(cause, span, suggest_increasing_limit); - mutate(&mut err); - err.emit(); - FatalError.raise(); - } - - fn build_overflow_error( - &self, - cause: OverflowCause<'tcx>, - span: Span, - suggest_increasing_limit: bool, - ) -> Diag<'a> { - fn with_short_path<'tcx, T>(tcx: TyCtxt<'tcx>, value: T) -> String - where - T: fmt::Display + Print<'tcx, FmtPrinter<'tcx, 'tcx>>, - { - let s = value.to_string(); - if s.len() > 50 { - // We don't need to save the type to a file, we will be talking about this type already - // in a separate note when we explain the obligation, so it will be available that way. - let mut cx: FmtPrinter<'_, '_> = - FmtPrinter::new_with_limit(tcx, Namespace::TypeNS, rustc_session::Limit(6)); - value.print(&mut cx).unwrap(); - cx.into_buffer() - } else { - s - } - } - - let mut err = match cause { - OverflowCause::DeeplyNormalize(alias_term) => { - let alias_term = self.resolve_vars_if_possible(alias_term); - let kind = alias_term.kind(self.tcx).descr(); - let alias_str = with_short_path(self.tcx, alias_term); - struct_span_code_err!( - self.dcx(), - span, - E0275, - "overflow normalizing the {kind} `{alias_str}`", - ) - } - OverflowCause::TraitSolver(predicate) => { - let predicate = self.resolve_vars_if_possible(predicate); - match predicate.kind().skip_binder() { - ty::PredicateKind::Subtype(ty::SubtypePredicate { a, b, a_is_expected: _ }) - | ty::PredicateKind::Coerce(ty::CoercePredicate { a, b }) => { - struct_span_code_err!( - self.dcx(), - span, - E0275, - "overflow assigning `{a}` to `{b}`", - ) - } - _ => { - let pred_str = with_short_path(self.tcx, predicate); - struct_span_code_err!( - self.dcx(), - span, - E0275, - "overflow evaluating the requirement `{pred_str}`", - ) - } - } - } - }; - - if suggest_increasing_limit { - suggest_new_overflow_limit(self.tcx, &mut err); - } - - err - } - - /// Reports that an overflow has occurred and halts compilation. We - /// halt compilation unconditionally because it is important that - /// overflows never be masked -- they basically represent computations - /// whose result could not be truly determined and thus we can't say - /// if the program type checks or not -- and they are unusual - /// occurrences in any case. - fn report_overflow_obligation( - &self, - obligation: &Obligation<'tcx, T>, - suggest_increasing_limit: bool, - ) -> ! - where - T: Upcast, ty::Predicate<'tcx>> + Clone, - { - let predicate = obligation.predicate.clone().upcast(self.tcx); - let predicate = self.resolve_vars_if_possible(predicate); - self.report_overflow_error( - OverflowCause::TraitSolver(predicate), - obligation.cause.span, - suggest_increasing_limit, - |err| { - self.note_obligation_cause_code( - obligation.cause.body_id, - err, - predicate, - obligation.param_env, - obligation.cause.code(), - &mut vec![], - &mut Default::default(), - ); - }, - ); - } - - /// Reports that a cycle was detected which led to overflow and halts - /// compilation. This is equivalent to `report_overflow_obligation` except - /// that we can give a more helpful error message (and, in particular, - /// we do not suggest increasing the overflow limit, which is not - /// going to help). - fn report_overflow_obligation_cycle(&self, cycle: &[PredicateObligation<'tcx>]) -> ! { - let cycle = self.resolve_vars_if_possible(cycle.to_owned()); - assert!(!cycle.is_empty()); - - debug!(?cycle, "report_overflow_error_cycle"); - - // The 'deepest' obligation is most likely to have a useful - // cause 'backtrace' - self.report_overflow_obligation( - cycle.iter().max_by_key(|p| p.recursion_depth).unwrap(), - false, - ); - } - - fn report_overflow_no_abort( - &self, - obligation: PredicateObligation<'tcx>, - suggest_increasing_limit: bool, - ) -> ErrorGuaranteed { - let obligation = self.resolve_vars_if_possible(obligation); - let mut err = self.build_overflow_error( - OverflowCause::TraitSolver(obligation.predicate), - obligation.cause.span, - suggest_increasing_limit, - ); - self.note_obligation_cause(&mut err, &obligation); - self.point_at_returns_when_relevant(&mut err, &obligation); - err.emit() - } - /// The `root_obligation` parameter should be the `root_obligation` field /// from a `FulfillmentError`. If no `FulfillmentError` is available, /// then it should be the same as `obligation`. diff --git a/compiler/rustc_trait_selection/src/solve/normalize.rs b/compiler/rustc_trait_selection/src/solve/normalize.rs index bda2137fa7368..ca313590265d2 100644 --- a/compiler/rustc_trait_selection/src/solve/normalize.rs +++ b/compiler/rustc_trait_selection/src/solve/normalize.rs @@ -1,7 +1,7 @@ use std::fmt::Debug; use std::marker::PhantomData; -use crate::error_reporting::traits::{OverflowCause, TypeErrCtxtExt}; +use crate::error_reporting::traits::{OverflowCause, TypeErrCtxtOverflowExt}; use crate::traits::query::evaluate_obligation::InferCtxtExt; use crate::traits::{BoundVarReplacer, PlaceholderReplacer, ScrubbedTraitError}; use rustc_data_structures::stack::ensure_sufficient_stack; diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs index 6f7e69798ee92..5597c8be59258 100644 --- a/compiler/rustc_trait_selection/src/traits/fulfill.rs +++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs @@ -1,4 +1,4 @@ -use crate::error_reporting::traits::TypeErrCtxtExt; +use crate::error_reporting::traits::TypeErrCtxtOverflowExt; use crate::infer::{InferCtxt, TyOrConstInferVar}; use crate::traits::normalize::normalize_with_depth_to; use rustc_data_structures::captures::Captures; diff --git a/compiler/rustc_trait_selection/src/traits/normalize.rs b/compiler/rustc_trait_selection/src/traits/normalize.rs index a34fd80446785..dda3aaaf71e82 100644 --- a/compiler/rustc_trait_selection/src/traits/normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/normalize.rs @@ -3,7 +3,7 @@ use super::SelectionContext; use super::{project, with_replaced_escaping_bound_vars, BoundVarReplacer, PlaceholderReplacer}; use crate::error_reporting::traits::OverflowCause; -use crate::error_reporting::traits::TypeErrCtxtExt; +use crate::error_reporting::traits::TypeErrCtxtOverflowExt; use crate::solve::NextSolverError; use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_infer::infer::at::At; diff --git a/compiler/rustc_trait_selection/src/traits/query/normalize.rs b/compiler/rustc_trait_selection/src/traits/query/normalize.rs index da4e4fef3cf78..c11e86abef8a4 100644 --- a/compiler/rustc_trait_selection/src/traits/query/normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/query/normalize.rs @@ -3,7 +3,7 @@ //! `normalize_canonicalized_projection_ty` query when it encounters projections. use crate::error_reporting::traits::OverflowCause; -use crate::error_reporting::traits::TypeErrCtxtExt; +use crate::error_reporting::traits::TypeErrCtxtOverflowExt; use crate::infer::at::At; use crate::infer::canonical::OriginalQueryValues; use crate::infer::{InferCtxt, InferOk}; diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 1e55b2d015003..2c4ffdabf140e 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -18,7 +18,7 @@ use super::{ TraitQueryMode, }; -use crate::error_reporting::traits::TypeErrCtxtExt; +use crate::error_reporting::traits::TypeErrCtxtOverflowExt; use crate::infer::{InferCtxt, InferCtxtExt, InferOk, TypeFreshener}; use crate::solve::InferCtxtSelectExt as _; use crate::traits::normalize::normalize_with_depth; diff --git a/compiler/rustc_traits/src/codegen.rs b/compiler/rustc_traits/src/codegen.rs index 51ac7b2c7ac1b..3ee5fd876ff57 100644 --- a/compiler/rustc_traits/src/codegen.rs +++ b/compiler/rustc_traits/src/codegen.rs @@ -7,7 +7,7 @@ use rustc_infer::infer::TyCtxtInferExt; use rustc_middle::bug; use rustc_middle::traits::CodegenObligationError; use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt}; -use rustc_trait_selection::error_reporting::traits::TypeErrCtxtExt; +use rustc_trait_selection::error_reporting::traits::TypeErrCtxtOverflowExt; use rustc_trait_selection::traits::{ ImplSource, Obligation, ObligationCause, ObligationCtxt, ScrubbedTraitError, SelectionContext, Unimplemented, diff --git a/compiler/rustc_traits/src/normalize_projection_ty.rs b/compiler/rustc_traits/src/normalize_projection_ty.rs index 85d84983d28fa..2d70fdc3935fb 100644 --- a/compiler/rustc_traits/src/normalize_projection_ty.rs +++ b/compiler/rustc_traits/src/normalize_projection_ty.rs @@ -2,7 +2,7 @@ use rustc_infer::infer::canonical::{Canonical, QueryResponse}; use rustc_infer::infer::TyCtxtInferExt; use rustc_middle::query::Providers; use rustc_middle::ty::{ParamEnvAnd, TyCtxt}; -use rustc_trait_selection::error_reporting::traits::TypeErrCtxtExt; +use rustc_trait_selection::error_reporting::traits::TypeErrCtxtOverflowExt; use rustc_trait_selection::infer::InferCtxtBuilderExt; use rustc_trait_selection::traits::query::{ normalize::NormalizationResult, CanonicalAliasGoal, NoSolution, From cd68a28daa460e04875a16b9677117af93046979 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 8 Jul 2024 16:44:00 -0400 Subject: [PATCH 856/892] Move some stuff into the ambiguity and suggestion modules --- .../src/error_reporting/traits/ambiguity.rs | 568 ++++++++++++++- .../src/error_reporting/traits/mod.rs | 58 -- .../src/error_reporting/traits/suggestions.rs | 169 +++++ .../traits/type_err_ctxt_ext.rs | 681 +----------------- 4 files changed, 742 insertions(+), 734 deletions(-) diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs index e6cb28df593af..c301deac6164d 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs @@ -1,10 +1,27 @@ +use std::ops::ControlFlow; + +use rustc_errors::{ + struct_span_code_err, Applicability, Diag, MultiSpan, StashKey, E0283, E0284, E0790, +}; +use rustc_hir as hir; +use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::DefId; +use rustc_hir::intravisit::Visitor as _; +use rustc_hir::LangItem; +use rustc_infer::infer::error_reporting::{TypeAnnotationNeeded, TypeErrCtxt}; use rustc_infer::infer::{BoundRegionConversionTime, InferCtxt}; use rustc_infer::traits::util::elaborate; -use rustc_infer::traits::{Obligation, ObligationCause, PolyTraitObligation}; -use rustc_middle::ty; -use rustc_span::{Span, DUMMY_SP}; +use rustc_infer::traits::{ + Obligation, ObligationCause, ObligationCauseCode, PolyTraitObligation, PredicateObligation, +}; +use rustc_macros::extension; +use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitable as _, TypeVisitableExt as _}; +use rustc_span::{ErrorGuaranteed, Span, DUMMY_SP}; +use crate::error_reporting::traits::suggestions::TypeErrCtxtExt as _; +use crate::error_reporting::traits::{ + to_pretty_impl_header, FindExprBySpan, InferCtxtPrivExt as _, +}; use crate::traits::query::evaluate_obligation::InferCtxtExt; use crate::traits::ObligationCtxt; @@ -134,3 +151,548 @@ pub fn compute_applicable_impls_for_diagnostics<'tcx>( ambiguities } + +#[extension(pub trait TypeErrCtxtAmbiguityExt<'a, 'tcx>)] +impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { + #[instrument(skip(self), level = "debug")] + fn maybe_report_ambiguity(&self, obligation: &PredicateObligation<'tcx>) -> ErrorGuaranteed { + // Unable to successfully determine, probably means + // insufficient type information, but could mean + // ambiguous impls. The latter *ought* to be a + // coherence violation, so we don't report it here. + + let predicate = self.resolve_vars_if_possible(obligation.predicate); + let span = obligation.cause.span; + + debug!(?predicate, obligation.cause.code = ?obligation.cause.code()); + + // Ambiguity errors are often caused as fallout from earlier errors. + // We ignore them if this `infcx` is tainted in some cases below. + + let bound_predicate = predicate.kind(); + let mut err = match bound_predicate.skip_binder() { + ty::PredicateKind::Clause(ty::ClauseKind::Trait(data)) => { + let trait_ref = bound_predicate.rebind(data.trait_ref); + debug!(?trait_ref); + + if let Err(e) = predicate.error_reported() { + return e; + } + + if let Err(guar) = self.tcx.ensure().coherent_trait(trait_ref.def_id()) { + // Avoid bogus "type annotations needed `Foo: Bar`" errors on `impl Bar for Foo` in case + // other `Foo` impls are incoherent. + return guar; + } + + // This is kind of a hack: it frequently happens that some earlier + // error prevents types from being fully inferred, and then we get + // a bunch of uninteresting errors saying something like " doesn't implement Sized". It may even be true that we + // could just skip over all checks where the self-ty is an + // inference variable, but I was afraid that there might be an + // inference variable created, registered as an obligation, and + // then never forced by writeback, and hence by skipping here we'd + // be ignoring the fact that we don't KNOW the type works + // out. Though even that would probably be harmless, given that + // we're only talking about builtin traits, which are known to be + // inhabited. We used to check for `self.tcx.sess.has_errors()` to + // avoid inundating the user with unnecessary errors, but we now + // check upstream for type errors and don't add the obligations to + // begin with in those cases. + if self.tcx.is_lang_item(trait_ref.def_id(), LangItem::Sized) { + match self.tainted_by_errors() { + None => { + let err = self.emit_inference_failure_err( + obligation.cause.body_id, + span, + trait_ref.self_ty().skip_binder().into(), + TypeAnnotationNeeded::E0282, + false, + ); + return err.stash(span, StashKey::MaybeForgetReturn).unwrap(); + } + Some(e) => return e, + } + } + + // Typically, this ambiguity should only happen if + // there are unresolved type inference variables + // (otherwise it would suggest a coherence + // failure). But given #21974 that is not necessarily + // the case -- we can have multiple where clauses that + // are only distinguished by a region, which results + // in an ambiguity even when all types are fully + // known, since we don't dispatch based on region + // relationships. + + // Pick the first generic parameter that still contains inference variables as the one + // we're going to emit an error for. If there are none (see above), fall back to + // a more general error. + let arg = data.trait_ref.args.iter().find(|s| s.has_non_region_infer()); + + let mut err = if let Some(arg) = arg { + self.emit_inference_failure_err( + obligation.cause.body_id, + span, + arg, + TypeAnnotationNeeded::E0283, + true, + ) + } else { + struct_span_code_err!( + self.dcx(), + span, + E0283, + "type annotations needed: cannot satisfy `{}`", + predicate, + ) + }; + + let mut ambiguities = compute_applicable_impls_for_diagnostics( + self.infcx, + &obligation.with(self.tcx, trait_ref), + ); + let has_non_region_infer = + trait_ref.skip_binder().args.types().any(|t| !t.is_ty_or_numeric_infer()); + // It doesn't make sense to talk about applicable impls if there are more than a + // handful of them. If there are a lot of them, but only a few of them have no type + // params, we only show those, as they are more likely to be useful/intended. + if ambiguities.len() > 5 { + let infcx = self.infcx; + if !ambiguities.iter().all(|option| match option { + CandidateSource::DefId(did) => infcx.tcx.generics_of(*did).count() == 0, + CandidateSource::ParamEnv(_) => true, + }) { + // If not all are blanket impls, we filter blanked impls out. + ambiguities.retain(|option| match option { + CandidateSource::DefId(did) => infcx.tcx.generics_of(*did).count() == 0, + CandidateSource::ParamEnv(_) => true, + }); + } + } + if ambiguities.len() > 1 && ambiguities.len() < 10 && has_non_region_infer { + if let Some(e) = self.tainted_by_errors() + && arg.is_none() + { + // If `arg.is_none()`, then this is probably two param-env + // candidates or impl candidates that are equal modulo lifetimes. + // Therefore, if we've already emitted an error, just skip this + // one, since it's not particularly actionable. + err.cancel(); + return e; + } + self.annotate_source_of_ambiguity(&mut err, &ambiguities, predicate); + } else { + if let Some(e) = self.tainted_by_errors() { + err.cancel(); + return e; + } + err.note(format!("cannot satisfy `{predicate}`")); + let impl_candidates = + self.find_similar_impl_candidates(predicate.as_trait_clause().unwrap()); + if impl_candidates.len() < 40 { + self.report_similar_impl_candidates( + impl_candidates.as_slice(), + trait_ref, + obligation.cause.body_id, + &mut err, + false, + obligation.param_env, + ); + } + } + + if let ObligationCauseCode::WhereClause(def_id, _) + | ObligationCauseCode::WhereClauseInExpr(def_id, ..) = *obligation.cause.code() + { + self.suggest_fully_qualified_path(&mut err, def_id, span, trait_ref.def_id()); + } + + if let Some(ty::GenericArgKind::Type(_)) = arg.map(|arg| arg.unpack()) + && let Some(body) = self.tcx.hir().maybe_body_owned_by(obligation.cause.body_id) + { + let mut expr_finder = FindExprBySpan::new(span, self.tcx); + expr_finder.visit_expr(&body.value); + + if let Some(hir::Expr { + kind: + hir::ExprKind::Call( + hir::Expr { + kind: hir::ExprKind::Path(hir::QPath::Resolved(None, path)), + .. + }, + _, + ) + | hir::ExprKind::Path(hir::QPath::Resolved(None, path)), + .. + }) = expr_finder.result + && let [ + .., + trait_path_segment @ hir::PathSegment { + res: Res::Def(DefKind::Trait, trait_id), + .. + }, + hir::PathSegment { + ident: assoc_item_name, + res: Res::Def(_, item_id), + .. + }, + ] = path.segments + && data.trait_ref.def_id == *trait_id + && self.tcx.trait_of_item(*item_id) == Some(*trait_id) + && let None = self.tainted_by_errors() + { + let (verb, noun) = match self.tcx.associated_item(item_id).kind { + ty::AssocKind::Const => ("refer to the", "constant"), + ty::AssocKind::Fn => ("call", "function"), + // This is already covered by E0223, but this following single match + // arm doesn't hurt here. + ty::AssocKind::Type => ("refer to the", "type"), + }; + + // Replace the more general E0283 with a more specific error + err.cancel(); + err = self.dcx().struct_span_err( + span, + format!( + "cannot {verb} associated {noun} on trait without specifying the \ + corresponding `impl` type", + ), + ); + err.code(E0790); + + if let Some(local_def_id) = data.trait_ref.def_id.as_local() + && let hir::Node::Item(hir::Item { + ident: trait_name, + kind: hir::ItemKind::Trait(_, _, _, _, trait_item_refs), + .. + }) = self.tcx.hir_node_by_def_id(local_def_id) + && let Some(method_ref) = trait_item_refs + .iter() + .find(|item_ref| item_ref.ident == *assoc_item_name) + { + err.span_label( + method_ref.span, + format!("`{trait_name}::{assoc_item_name}` defined here"), + ); + } + + err.span_label(span, format!("cannot {verb} associated {noun} of trait")); + + let trait_impls = self.tcx.trait_impls_of(data.trait_ref.def_id); + + if let Some(impl_def_id) = + trait_impls.non_blanket_impls().values().flatten().next() + { + let non_blanket_impl_count = + trait_impls.non_blanket_impls().values().flatten().count(); + // If there is only one implementation of the trait, suggest using it. + // Otherwise, use a placeholder comment for the implementation. + let (message, self_type) = if non_blanket_impl_count == 1 { + ( + "use the fully-qualified path to the only available \ + implementation", + format!( + "{}", + self.tcx.type_of(impl_def_id).instantiate_identity() + ), + ) + } else { + ( + "use a fully-qualified path to a specific available \ + implementation", + "/* self type */".to_string(), + ) + }; + let mut suggestions = + vec![(path.span.shrink_to_lo(), format!("<{self_type} as "))]; + if let Some(generic_arg) = trait_path_segment.args { + let between_span = + trait_path_segment.ident.span.between(generic_arg.span_ext); + // get rid of :: between Trait and + // must be '::' between them, otherwise the parser won't accept the code + suggestions.push((between_span, "".to_string())); + suggestions + .push((generic_arg.span_ext.shrink_to_hi(), ">".to_string())); + } else { + suggestions.push(( + trait_path_segment.ident.span.shrink_to_hi(), + ">".to_string(), + )); + } + err.multipart_suggestion( + message, + suggestions, + Applicability::MaybeIncorrect, + ); + } + } + }; + + err + } + + ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(arg)) => { + // Same hacky approach as above to avoid deluging user + // with error messages. + + if let Err(e) = arg.error_reported() { + return e; + } + if let Some(e) = self.tainted_by_errors() { + return e; + } + + self.emit_inference_failure_err( + obligation.cause.body_id, + span, + arg, + TypeAnnotationNeeded::E0282, + false, + ) + } + + ty::PredicateKind::Subtype(data) => { + if let Err(e) = data.error_reported() { + return e; + } + if let Some(e) = self.tainted_by_errors() { + return e; + } + let ty::SubtypePredicate { a_is_expected: _, a, b } = data; + // both must be type variables, or the other would've been instantiated + assert!(a.is_ty_var() && b.is_ty_var()); + self.emit_inference_failure_err( + obligation.cause.body_id, + span, + a.into(), + TypeAnnotationNeeded::E0282, + true, + ) + } + ty::PredicateKind::Clause(ty::ClauseKind::Projection(data)) => { + if let Err(e) = predicate.error_reported() { + return e; + } + if let Some(e) = self.tainted_by_errors() { + return e; + } + + if let Err(guar) = + self.tcx.ensure().coherent_trait(self.tcx.parent(data.projection_term.def_id)) + { + // Avoid bogus "type annotations needed `Foo: Bar`" errors on `impl Bar for Foo` in case + // other `Foo` impls are incoherent. + return guar; + } + let arg = data + .projection_term + .args + .iter() + .chain(Some(data.term.into_arg())) + .find(|g| g.has_non_region_infer()); + if let Some(arg) = arg { + self.emit_inference_failure_err( + obligation.cause.body_id, + span, + arg, + TypeAnnotationNeeded::E0284, + true, + ) + .with_note(format!("cannot satisfy `{predicate}`")) + } else { + // If we can't find a generic parameter, just print a generic error + struct_span_code_err!( + self.dcx(), + span, + E0284, + "type annotations needed: cannot satisfy `{}`", + predicate, + ) + .with_span_label(span, format!("cannot satisfy `{predicate}`")) + } + } + + ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(data)) => { + if let Err(e) = predicate.error_reported() { + return e; + } + if let Some(e) = self.tainted_by_errors() { + return e; + } + let arg = data.walk().find(|g| g.is_non_region_infer()); + if let Some(arg) = arg { + let err = self.emit_inference_failure_err( + obligation.cause.body_id, + span, + arg, + TypeAnnotationNeeded::E0284, + true, + ); + err + } else { + // If we can't find a generic parameter, just print a generic error + struct_span_code_err!( + self.dcx(), + span, + E0284, + "type annotations needed: cannot satisfy `{}`", + predicate, + ) + .with_span_label(span, format!("cannot satisfy `{predicate}`")) + } + } + + ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(ct, ..)) => self + .emit_inference_failure_err( + obligation.cause.body_id, + span, + ct.into(), + TypeAnnotationNeeded::E0284, + true, + ), + ty::PredicateKind::NormalizesTo(ty::NormalizesTo { alias, term }) + if term.is_infer() => + { + if let Some(e) = self.tainted_by_errors() { + return e; + } + struct_span_code_err!( + self.dcx(), + span, + E0284, + "type annotations needed: cannot normalize `{alias}`", + ) + .with_span_label(span, format!("cannot normalize `{alias}`")) + } + + _ => { + if let Some(e) = self.tainted_by_errors() { + return e; + } + struct_span_code_err!( + self.dcx(), + span, + E0284, + "type annotations needed: cannot satisfy `{}`", + predicate, + ) + .with_span_label(span, format!("cannot satisfy `{predicate}`")) + } + }; + self.note_obligation_cause(&mut err, obligation); + err.emit() + } + + fn annotate_source_of_ambiguity( + &self, + err: &mut Diag<'_>, + ambiguities: &[CandidateSource], + predicate: ty::Predicate<'tcx>, + ) { + let mut spans = vec![]; + let mut crates = vec![]; + let mut post = vec![]; + let mut has_param_env = false; + for ambiguity in ambiguities { + match ambiguity { + CandidateSource::DefId(impl_def_id) => match self.tcx.span_of_impl(*impl_def_id) { + Ok(span) => spans.push(span), + Err(name) => { + crates.push(name); + if let Some(header) = to_pretty_impl_header(self.tcx, *impl_def_id) { + post.push(header); + } + } + }, + CandidateSource::ParamEnv(span) => { + has_param_env = true; + spans.push(*span); + } + } + } + let mut crate_names: Vec<_> = crates.iter().map(|n| format!("`{n}`")).collect(); + crate_names.sort(); + crate_names.dedup(); + post.sort(); + post.dedup(); + + if self.tainted_by_errors().is_some() + && (crate_names.len() == 1 + && spans.len() == 0 + && ["`core`", "`alloc`", "`std`"].contains(&crate_names[0].as_str()) + || predicate.visit_with(&mut HasNumericInferVisitor).is_break()) + { + // Avoid complaining about other inference issues for expressions like + // `42 >> 1`, where the types are still `{integer}`, but we want to + // Do we need `trait_ref.skip_binder().self_ty().is_numeric() &&` too? + // NOTE(eddyb) this was `.cancel()`, but `err` + // is borrowed, so we can't fully defuse it. + err.downgrade_to_delayed_bug(); + return; + } + + let msg = format!( + "multiple `impl`s{} satisfying `{}` found", + if has_param_env { " or `where` clauses" } else { "" }, + predicate + ); + let post = if post.len() > 1 || (post.len() == 1 && post[0].contains('\n')) { + format!(":\n{}", post.iter().map(|p| format!("- {p}")).collect::>().join("\n"),) + } else if post.len() == 1 { + format!(": `{}`", post[0]) + } else { + String::new() + }; + + match (spans.len(), crates.len(), crate_names.len()) { + (0, 0, 0) => { + err.note(format!("cannot satisfy `{predicate}`")); + } + (0, _, 1) => { + err.note(format!("{} in the `{}` crate{}", msg, crates[0], post,)); + } + (0, _, _) => { + err.note(format!( + "{} in the following crates: {}{}", + msg, + crate_names.join(", "), + post, + )); + } + (_, 0, 0) => { + let span: MultiSpan = spans.into(); + err.span_note(span, msg); + } + (_, 1, 1) => { + let span: MultiSpan = spans.into(); + err.span_note(span, msg); + err.note(format!("and another `impl` found in the `{}` crate{}", crates[0], post,)); + } + _ => { + let span: MultiSpan = spans.into(); + err.span_note(span, msg); + err.note(format!( + "and more `impl`s found in the following crates: {}{}", + crate_names.join(", "), + post, + )); + } + } + } +} + +struct HasNumericInferVisitor; + +impl<'tcx> ty::TypeVisitor> for HasNumericInferVisitor { + type Result = ControlFlow<()>; + + fn visit_ty(&mut self, ty: Ty<'tcx>) -> Self::Result { + if matches!(ty.kind(), ty::Infer(ty::FloatVar(_) | ty::IntVar(_))) { + ControlFlow::Break(()) + } else { + ControlFlow::Continue(()) + } + } +} diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs index 7d334d623cc24..e776248e68476 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs @@ -15,7 +15,6 @@ use rustc_infer::traits::{Obligation, ObligationCause, ObligationCauseCode, Pred use rustc_middle::ty::print::PrintTraitRefExt as _; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_span::Span; -use std::ops::ControlFlow; pub use self::infer_ctxt_ext::*; pub use self::overflow::*; @@ -91,49 +90,6 @@ impl<'v> Visitor<'v> for FindExprBySpan<'v> { } } -/// Look for type `param` in an ADT being used only through a reference to confirm that suggesting -/// `param: ?Sized` would be a valid constraint. -struct FindTypeParam { - param: rustc_span::Symbol, - invalid_spans: Vec, - nested: bool, -} - -impl<'v> Visitor<'v> for FindTypeParam { - fn visit_where_predicate(&mut self, _: &'v hir::WherePredicate<'v>) { - // Skip where-clauses, to avoid suggesting indirection for type parameters found there. - } - - fn visit_ty(&mut self, ty: &hir::Ty<'_>) { - // We collect the spans of all uses of the "bare" type param, like in `field: T` or - // `field: (T, T)` where we could make `T: ?Sized` while skipping cases that are known to be - // valid like `field: &'a T` or `field: *mut T` and cases that *might* have further `Sized` - // obligations like `Box` and `Vec`, but we perform no extra analysis for those cases - // and suggest `T: ?Sized` regardless of their obligations. This is fine because the errors - // in that case should make what happened clear enough. - match ty.kind { - hir::TyKind::Ptr(_) | hir::TyKind::Ref(..) | hir::TyKind::TraitObject(..) => {} - hir::TyKind::Path(hir::QPath::Resolved(None, path)) - if path.segments.len() == 1 && path.segments[0].ident.name == self.param => - { - if !self.nested { - debug!(?ty, "FindTypeParam::visit_ty"); - self.invalid_spans.push(ty.span); - } - } - hir::TyKind::Path(_) => { - let prev = self.nested; - self.nested = true; - hir::intravisit::walk_ty(self, ty); - self.nested = prev; - } - _ => { - hir::intravisit::walk_ty(self, ty); - } - } - } -} - /// Summarizes information #[derive(Clone)] pub enum ArgKind { @@ -165,20 +121,6 @@ impl ArgKind { } } -struct HasNumericInferVisitor; - -impl<'tcx> ty::TypeVisitor> for HasNumericInferVisitor { - type Result = ControlFlow<()>; - - fn visit_ty(&mut self, ty: Ty<'tcx>) -> Self::Result { - if matches!(ty.kind(), ty::Infer(ty::FloatVar(_) | ty::IntVar(_))) { - ControlFlow::Break(()) - } else { - ControlFlow::Continue(()) - } - } -} - #[derive(Copy, Clone)] pub enum DefIdOrName { DefId(DefId), diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs index fdc6db4abec0b..11a2b1d323379 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs @@ -4623,6 +4623,132 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { ); } } + + #[instrument(level = "debug", skip_all)] + fn suggest_unsized_bound_if_applicable( + &self, + err: &mut Diag<'_>, + obligation: &PredicateObligation<'tcx>, + ) { + let ty::PredicateKind::Clause(ty::ClauseKind::Trait(pred)) = + obligation.predicate.kind().skip_binder() + else { + return; + }; + let (ObligationCauseCode::WhereClause(item_def_id, span) + | ObligationCauseCode::WhereClauseInExpr(item_def_id, span, ..)) = + *obligation.cause.code().peel_derives() + else { + return; + }; + if span.is_dummy() { + return; + } + debug!(?pred, ?item_def_id, ?span); + + let (Some(node), true) = ( + self.tcx.hir().get_if_local(item_def_id), + self.tcx.is_lang_item(pred.def_id(), LangItem::Sized), + ) else { + return; + }; + + let Some(generics) = node.generics() else { + return; + }; + let sized_trait = self.tcx.lang_items().sized_trait(); + debug!(?generics.params); + debug!(?generics.predicates); + let Some(param) = generics.params.iter().find(|param| param.span == span) else { + return; + }; + // Check that none of the explicit trait bounds is `Sized`. Assume that an explicit + // `Sized` bound is there intentionally and we don't need to suggest relaxing it. + let explicitly_sized = generics + .bounds_for_param(param.def_id) + .flat_map(|bp| bp.bounds) + .any(|bound| bound.trait_ref().and_then(|tr| tr.trait_def_id()) == sized_trait); + if explicitly_sized { + return; + } + debug!(?param); + match node { + hir::Node::Item( + item @ hir::Item { + // Only suggest indirection for uses of type parameters in ADTs. + kind: + hir::ItemKind::Enum(..) | hir::ItemKind::Struct(..) | hir::ItemKind::Union(..), + .. + }, + ) => { + if self.suggest_indirection_for_unsized(err, item, param) { + return; + } + } + _ => {} + }; + + // Didn't add an indirection suggestion, so add a general suggestion to relax `Sized`. + let (span, separator, open_paren_sp) = + if let Some((s, open_paren_sp)) = generics.bounds_span_for_suggestions(param.def_id) { + (s, " +", open_paren_sp) + } else { + (param.name.ident().span.shrink_to_hi(), ":", None) + }; + + let mut suggs = vec![]; + let suggestion = format!("{separator} ?Sized"); + + if let Some(open_paren_sp) = open_paren_sp { + suggs.push((open_paren_sp, "(".to_string())); + suggs.push((span, format!("){suggestion}"))); + } else { + suggs.push((span, suggestion)); + } + + err.multipart_suggestion_verbose( + "consider relaxing the implicit `Sized` restriction", + suggs, + Applicability::MachineApplicable, + ); + } + + fn suggest_indirection_for_unsized( + &self, + err: &mut Diag<'_>, + item: &hir::Item<'tcx>, + param: &hir::GenericParam<'tcx>, + ) -> bool { + // Suggesting `T: ?Sized` is only valid in an ADT if `T` is only used in a + // borrow. `struct S<'a, T: ?Sized>(&'a T);` is valid, `struct S(T);` + // is not. Look for invalid "bare" parameter uses, and suggest using indirection. + let mut visitor = + FindTypeParam { param: param.name.ident().name, invalid_spans: vec![], nested: false }; + visitor.visit_item(item); + if visitor.invalid_spans.is_empty() { + return false; + } + let mut multispan: MultiSpan = param.span.into(); + multispan.push_span_label( + param.span, + format!("this could be changed to `{}: ?Sized`...", param.name.ident()), + ); + for sp in visitor.invalid_spans { + multispan.push_span_label( + sp, + format!("...if indirection were used here: `Box<{}>`", param.name.ident()), + ); + } + err.span_help( + multispan, + format!( + "you could relax the implicit `Sized` bound on `{T}` if it were \ + used through indirection like `&{T}` or `Box<{T}>`", + T = param.name.ident(), + ), + ); + true + } } /// Add a hint to add a missing borrow or remove an unnecessary one. @@ -5126,3 +5252,46 @@ fn get_deref_type_and_refs(mut ty: Ty<'_>) -> (Ty<'_>, Vec) { (ty, refs) } + +/// Look for type `param` in an ADT being used only through a reference to confirm that suggesting +/// `param: ?Sized` would be a valid constraint. +struct FindTypeParam { + param: rustc_span::Symbol, + invalid_spans: Vec, + nested: bool, +} + +impl<'v> Visitor<'v> for FindTypeParam { + fn visit_where_predicate(&mut self, _: &'v hir::WherePredicate<'v>) { + // Skip where-clauses, to avoid suggesting indirection for type parameters found there. + } + + fn visit_ty(&mut self, ty: &hir::Ty<'_>) { + // We collect the spans of all uses of the "bare" type param, like in `field: T` or + // `field: (T, T)` where we could make `T: ?Sized` while skipping cases that are known to be + // valid like `field: &'a T` or `field: *mut T` and cases that *might* have further `Sized` + // obligations like `Box` and `Vec`, but we perform no extra analysis for those cases + // and suggest `T: ?Sized` regardless of their obligations. This is fine because the errors + // in that case should make what happened clear enough. + match ty.kind { + hir::TyKind::Ptr(_) | hir::TyKind::Ref(..) | hir::TyKind::TraitObject(..) => {} + hir::TyKind::Path(hir::QPath::Resolved(None, path)) + if path.segments.len() == 1 && path.segments[0].ident.name == self.param => + { + if !self.nested { + debug!(?ty, "FindTypeParam::visit_ty"); + self.invalid_spans.push(ty.span); + } + } + hir::TyKind::Path(_) => { + let prev = self.nested; + self.nested = true; + hir::intravisit::walk_ty(self, ty); + self.nested = prev; + } + _ => { + hir::intravisit::walk_ty(self, ty); + } + } + } +} diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/type_err_ctxt_ext.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/type_err_ctxt_ext.rs index ee5f4f44251c0..dec3b26420c24 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/type_err_ctxt_ext.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/type_err_ctxt_ext.rs @@ -1,15 +1,12 @@ -// ignore-tidy-filelength :( - +use super::ambiguity::TypeErrCtxtAmbiguityExt as _; use super::on_unimplemented::{AppendConstMessage, OnUnimplementedNote, TypeErrCtxtExt as _}; use super::suggestions::{get_explanation_based_on_obligation, TypeErrCtxtExt as _}; use crate::error_reporting::traits::infer_ctxt_ext::InferCtxtExt; use crate::error_reporting::traits::overflow::TypeErrCtxtOverflowExt; -use crate::error_reporting::traits::to_pretty_impl_header; -use crate::error_reporting::traits::{ambiguity, ambiguity::CandidateSource::*}; use crate::errors::{ AsyncClosureNotFn, ClosureFnMutLabel, ClosureFnOnceLabel, ClosureKindMismatch, }; -use crate::infer::error_reporting::{TyCategory, TypeAnnotationNeeded as ErrorCode}; +use crate::infer::error_reporting::TyCategory; use crate::infer::InferCtxtExt as _; use crate::infer::{self, InferCtxt}; use crate::traits::query::evaluate_obligation::InferCtxtExt as _; @@ -23,13 +20,13 @@ use core::ops::ControlFlow; use rustc_data_structures::fx::{FxHashMap, FxIndexMap}; use rustc_data_structures::unord::UnordSet; use rustc_errors::codes::*; -use rustc_errors::{pluralize, struct_span_code_err, Applicability, MultiSpan, StringPart}; +use rustc_errors::{pluralize, struct_span_code_err, Applicability, StringPart}; use rustc_errors::{Diag, ErrorGuaranteed, StashKey}; -use rustc_hir::def::{DefKind, Namespace, Res}; +use rustc_hir::def::Namespace; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::intravisit::Visitor; +use rustc_hir::Node; use rustc_hir::{self as hir, LangItem}; -use rustc_hir::{GenericParam, Item, Node}; use rustc_infer::infer::error_reporting::TypeErrCtxt; use rustc_infer::infer::{InferOk, TypeTrace}; use rustc_macros::extension; @@ -43,8 +40,7 @@ use rustc_middle::ty::print::{ PrintTraitRefExt as _, }; use rustc_middle::ty::{ - self, SubtypePredicate, ToPolyTraitRef, TraitRef, Ty, TyCtxt, TypeFoldable, TypeVisitable, - TypeVisitableExt, Upcast, + self, ToPolyTraitRef, TraitRef, Ty, TyCtxt, TypeFoldable, TypeVisitableExt, Upcast, }; use rustc_middle::{bug, span_bug}; use rustc_span::symbol::sym; @@ -53,8 +49,7 @@ use std::borrow::Cow; use std::iter; use super::{ - ArgKind, CandidateSimilarity, FindExprBySpan, FindTypeParam, GetSafeTransmuteErrorAndReason, - HasNumericInferVisitor, ImplCandidate, UnsatisfiedConst, + ArgKind, CandidateSimilarity, GetSafeTransmuteErrorAndReason, ImplCandidate, UnsatisfiedConst, }; pub use rustc_infer::traits::error_reporting::*; @@ -956,7 +951,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { } /// When the `E` of the resulting `Result` in an expression `foo().bar().baz()?`, - /// identify thoe method chain sub-expressions that could or could not have been annotated + /// identify those method chain sub-expressions that could or could not have been annotated /// with `?`. fn try_conversion_context( &self, @@ -2172,536 +2167,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { Obligation::new(self.tcx, ObligationCause::dummy(), param_env, trait_pred) } - #[instrument(skip(self), level = "debug")] - fn maybe_report_ambiguity(&self, obligation: &PredicateObligation<'tcx>) -> ErrorGuaranteed { - // Unable to successfully determine, probably means - // insufficient type information, but could mean - // ambiguous impls. The latter *ought* to be a - // coherence violation, so we don't report it here. - - let predicate = self.resolve_vars_if_possible(obligation.predicate); - let span = obligation.cause.span; - - debug!(?predicate, obligation.cause.code = ?obligation.cause.code()); - - // Ambiguity errors are often caused as fallout from earlier errors. - // We ignore them if this `infcx` is tainted in some cases below. - - let bound_predicate = predicate.kind(); - let mut err = match bound_predicate.skip_binder() { - ty::PredicateKind::Clause(ty::ClauseKind::Trait(data)) => { - let trait_ref = bound_predicate.rebind(data.trait_ref); - debug!(?trait_ref); - - if let Err(e) = predicate.error_reported() { - return e; - } - - if let Err(guar) = self.tcx.ensure().coherent_trait(trait_ref.def_id()) { - // Avoid bogus "type annotations needed `Foo: Bar`" errors on `impl Bar for Foo` in case - // other `Foo` impls are incoherent. - return guar; - } - - // This is kind of a hack: it frequently happens that some earlier - // error prevents types from being fully inferred, and then we get - // a bunch of uninteresting errors saying something like " doesn't implement Sized". It may even be true that we - // could just skip over all checks where the self-ty is an - // inference variable, but I was afraid that there might be an - // inference variable created, registered as an obligation, and - // then never forced by writeback, and hence by skipping here we'd - // be ignoring the fact that we don't KNOW the type works - // out. Though even that would probably be harmless, given that - // we're only talking about builtin traits, which are known to be - // inhabited. We used to check for `self.tcx.sess.has_errors()` to - // avoid inundating the user with unnecessary errors, but we now - // check upstream for type errors and don't add the obligations to - // begin with in those cases. - if self.tcx.is_lang_item(trait_ref.def_id(), LangItem::Sized) { - match self.tainted_by_errors() { - None => { - let err = self.emit_inference_failure_err( - obligation.cause.body_id, - span, - trait_ref.self_ty().skip_binder().into(), - ErrorCode::E0282, - false, - ); - return err.stash(span, StashKey::MaybeForgetReturn).unwrap(); - } - Some(e) => return e, - } - } - - // Typically, this ambiguity should only happen if - // there are unresolved type inference variables - // (otherwise it would suggest a coherence - // failure). But given #21974 that is not necessarily - // the case -- we can have multiple where clauses that - // are only distinguished by a region, which results - // in an ambiguity even when all types are fully - // known, since we don't dispatch based on region - // relationships. - - // Pick the first generic parameter that still contains inference variables as the one - // we're going to emit an error for. If there are none (see above), fall back to - // a more general error. - let arg = data.trait_ref.args.iter().find(|s| s.has_non_region_infer()); - - let mut err = if let Some(arg) = arg { - self.emit_inference_failure_err( - obligation.cause.body_id, - span, - arg, - ErrorCode::E0283, - true, - ) - } else { - struct_span_code_err!( - self.dcx(), - span, - E0283, - "type annotations needed: cannot satisfy `{}`", - predicate, - ) - }; - - let mut ambiguities = ambiguity::compute_applicable_impls_for_diagnostics( - self.infcx, - &obligation.with(self.tcx, trait_ref), - ); - let has_non_region_infer = - trait_ref.skip_binder().args.types().any(|t| !t.is_ty_or_numeric_infer()); - // It doesn't make sense to talk about applicable impls if there are more than a - // handful of them. If there are a lot of them, but only a few of them have no type - // params, we only show those, as they are more likely to be useful/intended. - if ambiguities.len() > 5 { - let infcx = self.infcx; - if !ambiguities.iter().all(|option| match option { - DefId(did) => infcx.tcx.generics_of(*did).count() == 0, - ParamEnv(_) => true, - }) { - // If not all are blanket impls, we filter blanked impls out. - ambiguities.retain(|option| match option { - DefId(did) => infcx.tcx.generics_of(*did).count() == 0, - ParamEnv(_) => true, - }); - } - } - if ambiguities.len() > 1 && ambiguities.len() < 10 && has_non_region_infer { - if let Some(e) = self.tainted_by_errors() - && arg.is_none() - { - // If `arg.is_none()`, then this is probably two param-env - // candidates or impl candidates that are equal modulo lifetimes. - // Therefore, if we've already emitted an error, just skip this - // one, since it's not particularly actionable. - err.cancel(); - return e; - } - self.annotate_source_of_ambiguity(&mut err, &ambiguities, predicate); - } else { - if let Some(e) = self.tainted_by_errors() { - err.cancel(); - return e; - } - err.note(format!("cannot satisfy `{predicate}`")); - let impl_candidates = - self.find_similar_impl_candidates(predicate.as_trait_clause().unwrap()); - if impl_candidates.len() < 40 { - self.report_similar_impl_candidates( - impl_candidates.as_slice(), - trait_ref, - obligation.cause.body_id, - &mut err, - false, - obligation.param_env, - ); - } - } - - if let ObligationCauseCode::WhereClause(def_id, _) - | ObligationCauseCode::WhereClauseInExpr(def_id, ..) = *obligation.cause.code() - { - self.suggest_fully_qualified_path(&mut err, def_id, span, trait_ref.def_id()); - } - - if let Some(ty::GenericArgKind::Type(_)) = arg.map(|arg| arg.unpack()) - && let Some(body) = self.tcx.hir().maybe_body_owned_by(obligation.cause.body_id) - { - let mut expr_finder = FindExprBySpan::new(span, self.tcx); - expr_finder.visit_expr(&body.value); - - if let Some(hir::Expr { - kind: - hir::ExprKind::Call( - hir::Expr { - kind: hir::ExprKind::Path(hir::QPath::Resolved(None, path)), - .. - }, - _, - ) - | hir::ExprKind::Path(hir::QPath::Resolved(None, path)), - .. - }) = expr_finder.result - && let [ - .., - trait_path_segment @ hir::PathSegment { - res: Res::Def(DefKind::Trait, trait_id), - .. - }, - hir::PathSegment { - ident: assoc_item_name, - res: Res::Def(_, item_id), - .. - }, - ] = path.segments - && data.trait_ref.def_id == *trait_id - && self.tcx.trait_of_item(*item_id) == Some(*trait_id) - && let None = self.tainted_by_errors() - { - let (verb, noun) = match self.tcx.associated_item(item_id).kind { - ty::AssocKind::Const => ("refer to the", "constant"), - ty::AssocKind::Fn => ("call", "function"), - // This is already covered by E0223, but this following single match - // arm doesn't hurt here. - ty::AssocKind::Type => ("refer to the", "type"), - }; - - // Replace the more general E0283 with a more specific error - err.cancel(); - err = self.dcx().struct_span_err( - span, - format!( - "cannot {verb} associated {noun} on trait without specifying the \ - corresponding `impl` type", - ), - ); - err.code(E0790); - - if let Some(local_def_id) = data.trait_ref.def_id.as_local() - && let hir::Node::Item(hir::Item { - ident: trait_name, - kind: hir::ItemKind::Trait(_, _, _, _, trait_item_refs), - .. - }) = self.tcx.hir_node_by_def_id(local_def_id) - && let Some(method_ref) = trait_item_refs - .iter() - .find(|item_ref| item_ref.ident == *assoc_item_name) - { - err.span_label( - method_ref.span, - format!("`{trait_name}::{assoc_item_name}` defined here"), - ); - } - - err.span_label(span, format!("cannot {verb} associated {noun} of trait")); - - let trait_impls = self.tcx.trait_impls_of(data.trait_ref.def_id); - - if let Some(impl_def_id) = - trait_impls.non_blanket_impls().values().flatten().next() - { - let non_blanket_impl_count = - trait_impls.non_blanket_impls().values().flatten().count(); - // If there is only one implementation of the trait, suggest using it. - // Otherwise, use a placeholder comment for the implementation. - let (message, self_type) = if non_blanket_impl_count == 1 { - ( - "use the fully-qualified path to the only available \ - implementation", - format!( - "{}", - self.tcx.type_of(impl_def_id).instantiate_identity() - ), - ) - } else { - ( - "use a fully-qualified path to a specific available \ - implementation", - "/* self type */".to_string(), - ) - }; - let mut suggestions = - vec![(path.span.shrink_to_lo(), format!("<{self_type} as "))]; - if let Some(generic_arg) = trait_path_segment.args { - let between_span = - trait_path_segment.ident.span.between(generic_arg.span_ext); - // get rid of :: between Trait and - // must be '::' between them, otherwise the parser won't accept the code - suggestions.push((between_span, "".to_string())); - suggestions - .push((generic_arg.span_ext.shrink_to_hi(), ">".to_string())); - } else { - suggestions.push(( - trait_path_segment.ident.span.shrink_to_hi(), - ">".to_string(), - )); - } - err.multipart_suggestion( - message, - suggestions, - Applicability::MaybeIncorrect, - ); - } - } - }; - - err - } - - ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(arg)) => { - // Same hacky approach as above to avoid deluging user - // with error messages. - - if let Err(e) = arg.error_reported() { - return e; - } - if let Some(e) = self.tainted_by_errors() { - return e; - } - - self.emit_inference_failure_err( - obligation.cause.body_id, - span, - arg, - ErrorCode::E0282, - false, - ) - } - - ty::PredicateKind::Subtype(data) => { - if let Err(e) = data.error_reported() { - return e; - } - if let Some(e) = self.tainted_by_errors() { - return e; - } - let SubtypePredicate { a_is_expected: _, a, b } = data; - // both must be type variables, or the other would've been instantiated - assert!(a.is_ty_var() && b.is_ty_var()); - self.emit_inference_failure_err( - obligation.cause.body_id, - span, - a.into(), - ErrorCode::E0282, - true, - ) - } - ty::PredicateKind::Clause(ty::ClauseKind::Projection(data)) => { - if let Err(e) = predicate.error_reported() { - return e; - } - if let Some(e) = self.tainted_by_errors() { - return e; - } - - if let Err(guar) = - self.tcx.ensure().coherent_trait(self.tcx.parent(data.projection_term.def_id)) - { - // Avoid bogus "type annotations needed `Foo: Bar`" errors on `impl Bar for Foo` in case - // other `Foo` impls are incoherent. - return guar; - } - let arg = data - .projection_term - .args - .iter() - .chain(Some(data.term.into_arg())) - .find(|g| g.has_non_region_infer()); - if let Some(arg) = arg { - self.emit_inference_failure_err( - obligation.cause.body_id, - span, - arg, - ErrorCode::E0284, - true, - ) - .with_note(format!("cannot satisfy `{predicate}`")) - } else { - // If we can't find a generic parameter, just print a generic error - struct_span_code_err!( - self.dcx(), - span, - E0284, - "type annotations needed: cannot satisfy `{}`", - predicate, - ) - .with_span_label(span, format!("cannot satisfy `{predicate}`")) - } - } - - ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(data)) => { - if let Err(e) = predicate.error_reported() { - return e; - } - if let Some(e) = self.tainted_by_errors() { - return e; - } - let arg = data.walk().find(|g| g.is_non_region_infer()); - if let Some(arg) = arg { - let err = self.emit_inference_failure_err( - obligation.cause.body_id, - span, - arg, - ErrorCode::E0284, - true, - ); - err - } else { - // If we can't find a generic parameter, just print a generic error - struct_span_code_err!( - self.dcx(), - span, - E0284, - "type annotations needed: cannot satisfy `{}`", - predicate, - ) - .with_span_label(span, format!("cannot satisfy `{predicate}`")) - } - } - - ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(ct, ..)) => self - .emit_inference_failure_err( - obligation.cause.body_id, - span, - ct.into(), - ErrorCode::E0284, - true, - ), - ty::PredicateKind::NormalizesTo(ty::NormalizesTo { alias, term }) - if term.is_infer() => - { - if let Some(e) = self.tainted_by_errors() { - return e; - } - struct_span_code_err!( - self.dcx(), - span, - E0284, - "type annotations needed: cannot normalize `{alias}`", - ) - .with_span_label(span, format!("cannot normalize `{alias}`")) - } - - _ => { - if let Some(e) = self.tainted_by_errors() { - return e; - } - struct_span_code_err!( - self.dcx(), - span, - E0284, - "type annotations needed: cannot satisfy `{}`", - predicate, - ) - .with_span_label(span, format!("cannot satisfy `{predicate}`")) - } - }; - self.note_obligation_cause(&mut err, obligation); - err.emit() - } - - fn annotate_source_of_ambiguity( - &self, - err: &mut Diag<'_>, - ambiguities: &[ambiguity::CandidateSource], - predicate: ty::Predicate<'tcx>, - ) { - let mut spans = vec![]; - let mut crates = vec![]; - let mut post = vec![]; - let mut has_param_env = false; - for ambiguity in ambiguities { - match ambiguity { - ambiguity::CandidateSource::DefId(impl_def_id) => { - match self.tcx.span_of_impl(*impl_def_id) { - Ok(span) => spans.push(span), - Err(name) => { - crates.push(name); - if let Some(header) = to_pretty_impl_header(self.tcx, *impl_def_id) { - post.push(header); - } - } - } - } - ambiguity::CandidateSource::ParamEnv(span) => { - has_param_env = true; - spans.push(*span); - } - } - } - let mut crate_names: Vec<_> = crates.iter().map(|n| format!("`{n}`")).collect(); - crate_names.sort(); - crate_names.dedup(); - post.sort(); - post.dedup(); - - if self.tainted_by_errors().is_some() - && (crate_names.len() == 1 - && spans.len() == 0 - && ["`core`", "`alloc`", "`std`"].contains(&crate_names[0].as_str()) - || predicate.visit_with(&mut HasNumericInferVisitor).is_break()) - { - // Avoid complaining about other inference issues for expressions like - // `42 >> 1`, where the types are still `{integer}`, but we want to - // Do we need `trait_ref.skip_binder().self_ty().is_numeric() &&` too? - // NOTE(eddyb) this was `.cancel()`, but `err` - // is borrowed, so we can't fully defuse it. - err.downgrade_to_delayed_bug(); - return; - } - - let msg = format!( - "multiple `impl`s{} satisfying `{}` found", - if has_param_env { " or `where` clauses" } else { "" }, - predicate - ); - let post = if post.len() > 1 || (post.len() == 1 && post[0].contains('\n')) { - format!(":\n{}", post.iter().map(|p| format!("- {p}")).collect::>().join("\n"),) - } else if post.len() == 1 { - format!(": `{}`", post[0]) - } else { - String::new() - }; - - match (spans.len(), crates.len(), crate_names.len()) { - (0, 0, 0) => { - err.note(format!("cannot satisfy `{predicate}`")); - } - (0, _, 1) => { - err.note(format!("{} in the `{}` crate{}", msg, crates[0], post,)); - } - (0, _, _) => { - err.note(format!( - "{} in the following crates: {}{}", - msg, - crate_names.join(", "), - post, - )); - } - (_, 0, 0) => { - let span: MultiSpan = spans.into(); - err.span_note(span, msg); - } - (_, 1, 1) => { - let span: MultiSpan = spans.into(); - err.span_note(span, msg); - err.note(format!("and another `impl` found in the `{}` crate{}", crates[0], post,)); - } - _ => { - let span: MultiSpan = spans.into(); - err.span_note(span, msg); - err.note(format!( - "and more `impl`s found in the following crates: {}{}", - crate_names.join(", "), - post, - )); - } - } - } - /// Returns `true` if the trait predicate may apply for *some* assignment /// to the type parameters. fn predicate_can_apply( @@ -2769,136 +2234,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { } } - #[instrument(level = "debug", skip_all)] - fn suggest_unsized_bound_if_applicable( - &self, - err: &mut Diag<'_>, - obligation: &PredicateObligation<'tcx>, - ) { - let ty::PredicateKind::Clause(ty::ClauseKind::Trait(pred)) = - obligation.predicate.kind().skip_binder() - else { - return; - }; - let (ObligationCauseCode::WhereClause(item_def_id, span) - | ObligationCauseCode::WhereClauseInExpr(item_def_id, span, ..)) = - *obligation.cause.code().peel_derives() - else { - return; - }; - if span.is_dummy() { - return; - } - debug!(?pred, ?item_def_id, ?span); - - let (Some(node), true) = ( - self.tcx.hir().get_if_local(item_def_id), - self.tcx.is_lang_item(pred.def_id(), LangItem::Sized), - ) else { - return; - }; - self.maybe_suggest_unsized_generics(err, span, node); - } - - #[instrument(level = "debug", skip_all)] - fn maybe_suggest_unsized_generics(&self, err: &mut Diag<'_>, span: Span, node: Node<'tcx>) { - let Some(generics) = node.generics() else { - return; - }; - let sized_trait = self.tcx.lang_items().sized_trait(); - debug!(?generics.params); - debug!(?generics.predicates); - let Some(param) = generics.params.iter().find(|param| param.span == span) else { - return; - }; - // Check that none of the explicit trait bounds is `Sized`. Assume that an explicit - // `Sized` bound is there intentionally and we don't need to suggest relaxing it. - let explicitly_sized = generics - .bounds_for_param(param.def_id) - .flat_map(|bp| bp.bounds) - .any(|bound| bound.trait_ref().and_then(|tr| tr.trait_def_id()) == sized_trait); - if explicitly_sized { - return; - } - debug!(?param); - match node { - hir::Node::Item( - item @ hir::Item { - // Only suggest indirection for uses of type parameters in ADTs. - kind: - hir::ItemKind::Enum(..) | hir::ItemKind::Struct(..) | hir::ItemKind::Union(..), - .. - }, - ) => { - if self.maybe_indirection_for_unsized(err, item, param) { - return; - } - } - _ => {} - }; - - // Didn't add an indirection suggestion, so add a general suggestion to relax `Sized`. - let (span, separator, open_paren_sp) = - if let Some((s, open_paren_sp)) = generics.bounds_span_for_suggestions(param.def_id) { - (s, " +", open_paren_sp) - } else { - (param.name.ident().span.shrink_to_hi(), ":", None) - }; - - let mut suggs = vec![]; - let suggestion = format!("{separator} ?Sized"); - - if let Some(open_paren_sp) = open_paren_sp { - suggs.push((open_paren_sp, "(".to_string())); - suggs.push((span, format!("){suggestion}"))); - } else { - suggs.push((span, suggestion)); - } - - err.multipart_suggestion_verbose( - "consider relaxing the implicit `Sized` restriction", - suggs, - Applicability::MachineApplicable, - ); - } - - fn maybe_indirection_for_unsized( - &self, - err: &mut Diag<'_>, - item: &Item<'tcx>, - param: &GenericParam<'tcx>, - ) -> bool { - // Suggesting `T: ?Sized` is only valid in an ADT if `T` is only used in a - // borrow. `struct S<'a, T: ?Sized>(&'a T);` is valid, `struct S(T);` - // is not. Look for invalid "bare" parameter uses, and suggest using indirection. - let mut visitor = - FindTypeParam { param: param.name.ident().name, invalid_spans: vec![], nested: false }; - visitor.visit_item(item); - if visitor.invalid_spans.is_empty() { - return false; - } - let mut multispan: MultiSpan = param.span.into(); - multispan.push_span_label( - param.span, - format!("this could be changed to `{}: ?Sized`...", param.name.ident()), - ); - for sp in visitor.invalid_spans { - multispan.push_span_label( - sp, - format!("...if indirection were used here: `Box<{}>`", param.name.ident()), - ); - } - err.span_help( - multispan, - format!( - "you could relax the implicit `Sized` bound on `{T}` if it were \ - used through indirection like `&{T}` or `Box<{T}>`", - T = param.name.ident(), - ), - ); - true - } - fn is_recursive_obligation( &self, obligated_types: &mut Vec>, From bbbff806038eeb178a7984820f498a03baff02f1 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 8 Jul 2024 16:58:18 -0400 Subject: [PATCH 857/892] Split out fulfillment error reporting a bit more --- compiler/rustc_hir_typeck/src/coercion.rs | 2 +- ..._err_ctxt_ext.rs => fulfillment_errors.rs} | 204 +---------------- .../error_reporting/traits/infer_ctxt_ext.rs | 4 +- .../src/error_reporting/traits/mod.rs | 215 +++++++++++++++++- .../traits/on_unimplemented.rs | 2 +- .../src/error_reporting/traits/suggestions.rs | 2 +- 6 files changed, 221 insertions(+), 208 deletions(-) rename compiler/rustc_trait_selection/src/error_reporting/traits/{type_err_ctxt_ext.rs => fulfillment_errors.rs} (93%) diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs index d1b99aae25b1d..5e2a68e1f02db 100644 --- a/compiler/rustc_hir_typeck/src/coercion.rs +++ b/compiler/rustc_hir_typeck/src/coercion.rs @@ -59,7 +59,7 @@ use rustc_span::symbol::sym; use rustc_span::{BytePos, DesugaringKind, Span, DUMMY_SP}; use rustc_target::spec::abi::Abi; use rustc_trait_selection::error_reporting::traits::suggestions::TypeErrCtxtExt; -use rustc_trait_selection::error_reporting::traits::TypeErrCtxtExt as _; +use rustc_trait_selection::error_reporting::traits::TypeErrCtxtSelectionErrExt as _; use rustc_trait_selection::infer::InferCtxtExt as _; use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt; use rustc_trait_selection::traits::{ diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/type_err_ctxt_ext.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs similarity index 93% rename from compiler/rustc_trait_selection/src/error_reporting/traits/type_err_ctxt_ext.rs rename to compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs index dec3b26420c24..f7ec5f1ff325f 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/type_err_ctxt_ext.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs @@ -1,8 +1,6 @@ -use super::ambiguity::TypeErrCtxtAmbiguityExt as _; use super::on_unimplemented::{AppendConstMessage, OnUnimplementedNote, TypeErrCtxtExt as _}; use super::suggestions::{get_explanation_based_on_obligation, TypeErrCtxtExt as _}; use crate::error_reporting::traits::infer_ctxt_ext::InferCtxtExt; -use crate::error_reporting::traits::overflow::TypeErrCtxtOverflowExt; use crate::errors::{ AsyncClosureNotFn, ClosureFnMutLabel, ClosureFnOnceLabel, ClosureKindMismatch, }; @@ -12,12 +10,12 @@ use crate::infer::{self, InferCtxt}; use crate::traits::query::evaluate_obligation::InferCtxtExt as _; use crate::traits::NormalizeExt; use crate::traits::{ - elaborate, FulfillmentError, FulfillmentErrorCode, MismatchedProjectionTypes, Obligation, - ObligationCause, ObligationCauseCode, ObligationCtxt, Overflow, PredicateObligation, - SelectionError, SignatureMismatch, TraitNotObjectSafe, + elaborate, MismatchedProjectionTypes, Obligation, ObligationCause, ObligationCauseCode, + ObligationCtxt, Overflow, PredicateObligation, SelectionError, SignatureMismatch, + TraitNotObjectSafe, }; use core::ops::ControlFlow; -use rustc_data_structures::fx::{FxHashMap, FxIndexMap}; +use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::unord::UnordSet; use rustc_errors::codes::*; use rustc_errors::{pluralize, struct_span_code_err, Applicability, StringPart}; @@ -44,9 +42,8 @@ use rustc_middle::ty::{ }; use rustc_middle::{bug, span_bug}; use rustc_span::symbol::sym; -use rustc_span::{BytePos, ExpnKind, Span, Symbol, DUMMY_SP}; +use rustc_span::{BytePos, Span, Symbol, DUMMY_SP}; use std::borrow::Cow; -use std::iter; use super::{ ArgKind, CandidateSimilarity, GetSafeTransmuteErrorAndReason, ImplCandidate, UnsatisfiedConst, @@ -54,128 +51,8 @@ use super::{ pub use rustc_infer::traits::error_reporting::*; -#[extension(pub trait TypeErrCtxtExt<'a, 'tcx>)] +#[extension(pub trait TypeErrCtxtSelectionErrExt<'a, 'tcx>)] impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { - fn report_fulfillment_errors( - &self, - mut errors: Vec>, - ) -> ErrorGuaranteed { - self.sub_relations - .borrow_mut() - .add_constraints(self, errors.iter().map(|e| e.obligation.predicate)); - - #[derive(Debug)] - struct ErrorDescriptor<'tcx> { - predicate: ty::Predicate<'tcx>, - index: Option, // None if this is an old error - } - - let mut error_map: FxIndexMap<_, Vec<_>> = self - .reported_trait_errors - .borrow() - .iter() - .map(|(&span, predicates)| { - ( - span, - predicates - .0 - .iter() - .map(|&predicate| ErrorDescriptor { predicate, index: None }) - .collect(), - ) - }) - .collect(); - - // Ensure `T: Sized` and `T: WF` obligations come last. This lets us display diagnostics - // with more relevant type information and hide redundant E0282 errors. - errors.sort_by_key(|e| match e.obligation.predicate.kind().skip_binder() { - ty::PredicateKind::Clause(ty::ClauseKind::Trait(pred)) - if self.tcx.is_lang_item(pred.def_id(), LangItem::Sized) => - { - 1 - } - ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(_)) => 3, - ty::PredicateKind::Coerce(_) => 2, - _ => 0, - }); - - for (index, error) in errors.iter().enumerate() { - // We want to ignore desugarings here: spans are equivalent even - // if one is the result of a desugaring and the other is not. - let mut span = error.obligation.cause.span; - let expn_data = span.ctxt().outer_expn_data(); - if let ExpnKind::Desugaring(_) = expn_data.kind { - span = expn_data.call_site; - } - - error_map.entry(span).or_default().push(ErrorDescriptor { - predicate: error.obligation.predicate, - index: Some(index), - }); - } - - // We do this in 2 passes because we want to display errors in order, though - // maybe it *is* better to sort errors by span or something. - let mut is_suppressed = vec![false; errors.len()]; - for (_, error_set) in error_map.iter() { - // We want to suppress "duplicate" errors with the same span. - for error in error_set { - if let Some(index) = error.index { - // Suppress errors that are either: - // 1) strictly implied by another error. - // 2) implied by an error with a smaller index. - for error2 in error_set { - if error2.index.is_some_and(|index2| is_suppressed[index2]) { - // Avoid errors being suppressed by already-suppressed - // errors, to prevent all errors from being suppressed - // at once. - continue; - } - - if self.error_implies(error2.predicate, error.predicate) - && !(error2.index >= error.index - && self.error_implies(error.predicate, error2.predicate)) - { - info!("skipping {:?} (implied by {:?})", error, error2); - is_suppressed[index] = true; - break; - } - } - } - } - } - - let mut reported = None; - - for from_expansion in [false, true] { - for (error, suppressed) in iter::zip(&errors, &is_suppressed) { - if !suppressed && error.obligation.cause.span.from_expansion() == from_expansion { - let guar = self.report_fulfillment_error(error); - self.infcx.set_tainted_by_errors(guar); - reported = Some(guar); - // We want to ignore desugarings here: spans are equivalent even - // if one is the result of a desugaring and the other is not. - let mut span = error.obligation.cause.span; - let expn_data = span.ctxt().outer_expn_data(); - if let ExpnKind::Desugaring(_) = expn_data.kind { - span = expn_data.call_site; - } - self.reported_trait_errors - .borrow_mut() - .entry(span) - .or_insert_with(|| (vec![], guar)) - .0 - .push(error.obligation.predicate); - } - } - } - - // It could be that we don't report an error because we have seen an `ErrorReported` from - // another source. We should probably be able to fix most of these, but some are delayed - // bugs that get a proper error after this function. - reported.unwrap_or_else(|| self.dcx().delayed_bug("failed to report fulfillment errors")) - } - /// The `root_obligation` parameter should be the `root_obligation` field /// from a `FulfillmentError`. If no `FulfillmentError` is available, /// then it should be the same as `obligation`. @@ -803,7 +680,10 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { self.point_at_returns_when_relevant(&mut err, &obligation); err.emit() } +} +#[extension(pub(super) trait TypeErrCtxtExt<'a, 'tcx>)] +impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { fn apply_do_not_recommend(&self, obligation: &mut PredicateObligation<'tcx>) -> bool { let mut base_cause = obligation.cause.code().clone(); let mut applied_do_not_recommend = false; @@ -1324,72 +1204,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { } } - #[instrument(skip(self), level = "debug")] - fn report_fulfillment_error(&self, error: &FulfillmentError<'tcx>) -> ErrorGuaranteed { - let mut error = FulfillmentError { - obligation: error.obligation.clone(), - code: error.code.clone(), - root_obligation: error.root_obligation.clone(), - }; - if matches!( - error.code, - FulfillmentErrorCode::Select(crate::traits::SelectionError::Unimplemented) - | FulfillmentErrorCode::Project(_) - ) && self.apply_do_not_recommend(&mut error.obligation) - { - error.code = FulfillmentErrorCode::Select(SelectionError::Unimplemented); - } - - match error.code { - FulfillmentErrorCode::Select(ref selection_error) => self.report_selection_error( - error.obligation.clone(), - &error.root_obligation, - selection_error, - ), - FulfillmentErrorCode::Project(ref e) => { - self.report_projection_error(&error.obligation, e) - } - FulfillmentErrorCode::Ambiguity { overflow: None } => { - self.maybe_report_ambiguity(&error.obligation) - } - FulfillmentErrorCode::Ambiguity { overflow: Some(suggest_increasing_limit) } => { - self.report_overflow_no_abort(error.obligation.clone(), suggest_increasing_limit) - } - FulfillmentErrorCode::Subtype(ref expected_found, ref err) => self - .report_mismatched_types( - &error.obligation.cause, - expected_found.expected, - expected_found.found, - *err, - ) - .emit(), - FulfillmentErrorCode::ConstEquate(ref expected_found, ref err) => { - let mut diag = self.report_mismatched_consts( - &error.obligation.cause, - expected_found.expected, - expected_found.found, - *err, - ); - let code = error.obligation.cause.code().peel_derives().peel_match_impls(); - if let ObligationCauseCode::WhereClause(..) - | ObligationCauseCode::WhereClauseInExpr(..) = code - { - self.note_obligation_cause_code( - error.obligation.cause.body_id, - &mut diag, - error.obligation.predicate, - error.obligation.param_env, - code, - &mut vec![], - &mut Default::default(), - ); - } - diag.emit() - } - FulfillmentErrorCode::Cycle(ref cycle) => self.report_overflow_obligation_cycle(cycle), - } - } - #[instrument(level = "debug", skip_all)] fn report_projection_error( &self, diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/infer_ctxt_ext.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/infer_ctxt_ext.rs index 34da8e576ce86..e8d7e80ac562c 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/infer_ctxt_ext.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/infer_ctxt_ext.rs @@ -1,3 +1,5 @@ +// FIXME(error_reporting): This should be made into private methods on `TypeErrCtxt`. + use crate::infer::InferCtxt; use crate::traits::{Obligation, ObligationCause, ObligationCtxt}; use rustc_errors::{codes::*, pluralize, struct_span_code_err, Applicability, Diag}; @@ -9,8 +11,6 @@ use rustc_span::{Span, DUMMY_SP}; use super::ArgKind; -pub use rustc_infer::traits::error_reporting::*; - #[extension(pub trait InferCtxtExt<'tcx>)] impl<'tcx> InferCtxt<'tcx> { /// Given some node representing a fn-like thing in the HIR map, diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs index e776248e68476..2131e236401ef 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs @@ -1,24 +1,34 @@ -// ignore-tidy-filelength :( - pub mod ambiguity; +mod fulfillment_errors; mod infer_ctxt_ext; pub mod on_unimplemented; mod overflow; pub mod suggestions; -mod type_err_ctxt_ext; -use rustc_data_structures::fx::FxIndexSet; -use rustc_hir as hir; +use std::iter; + +use rustc_data_structures::fx::{FxIndexMap, FxIndexSet}; use rustc_hir::def_id::DefId; use rustc_hir::intravisit::Visitor; -use rustc_infer::traits::{Obligation, ObligationCause, ObligationCauseCode, PredicateObligation}; +use rustc_hir::{self as hir, LangItem}; +use rustc_infer::infer::error_reporting::TypeErrCtxt; +use rustc_infer::traits::{ + Obligation, ObligationCause, ObligationCauseCode, PredicateObligation, SelectionError, +}; +use rustc_macros::extension; use rustc_middle::ty::print::PrintTraitRefExt as _; use rustc_middle::ty::{self, Ty, TyCtxt}; -use rustc_span::Span; +use rustc_span::{ErrorGuaranteed, ExpnKind, Span}; + +use ambiguity::TypeErrCtxtAmbiguityExt as _; +use fulfillment_errors::TypeErrCtxtExt as _; +use suggestions::TypeErrCtxtExt as _; +use crate::traits::{FulfillmentError, FulfillmentErrorCode}; + +pub use self::fulfillment_errors::*; pub use self::infer_ctxt_ext::*; pub use self::overflow::*; -pub use self::type_err_ctxt_ext::*; // When outputting impl candidates, prefer showing those that are more similar. // @@ -127,6 +137,195 @@ pub enum DefIdOrName { Name(&'static str), } +#[extension(pub trait TypeErrCtxtExt<'a, 'tcx>)] +impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { + fn report_fulfillment_errors( + &self, + mut errors: Vec>, + ) -> ErrorGuaranteed { + self.sub_relations + .borrow_mut() + .add_constraints(self, errors.iter().map(|e| e.obligation.predicate)); + + #[derive(Debug)] + struct ErrorDescriptor<'tcx> { + predicate: ty::Predicate<'tcx>, + index: Option, // None if this is an old error + } + + let mut error_map: FxIndexMap<_, Vec<_>> = self + .reported_trait_errors + .borrow() + .iter() + .map(|(&span, predicates)| { + ( + span, + predicates + .0 + .iter() + .map(|&predicate| ErrorDescriptor { predicate, index: None }) + .collect(), + ) + }) + .collect(); + + // Ensure `T: Sized` and `T: WF` obligations come last. This lets us display diagnostics + // with more relevant type information and hide redundant E0282 errors. + errors.sort_by_key(|e| match e.obligation.predicate.kind().skip_binder() { + ty::PredicateKind::Clause(ty::ClauseKind::Trait(pred)) + if self.tcx.is_lang_item(pred.def_id(), LangItem::Sized) => + { + 1 + } + ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(_)) => 3, + ty::PredicateKind::Coerce(_) => 2, + _ => 0, + }); + + for (index, error) in errors.iter().enumerate() { + // We want to ignore desugarings here: spans are equivalent even + // if one is the result of a desugaring and the other is not. + let mut span = error.obligation.cause.span; + let expn_data = span.ctxt().outer_expn_data(); + if let ExpnKind::Desugaring(_) = expn_data.kind { + span = expn_data.call_site; + } + + error_map.entry(span).or_default().push(ErrorDescriptor { + predicate: error.obligation.predicate, + index: Some(index), + }); + } + + // We do this in 2 passes because we want to display errors in order, though + // maybe it *is* better to sort errors by span or something. + let mut is_suppressed = vec![false; errors.len()]; + for (_, error_set) in error_map.iter() { + // We want to suppress "duplicate" errors with the same span. + for error in error_set { + if let Some(index) = error.index { + // Suppress errors that are either: + // 1) strictly implied by another error. + // 2) implied by an error with a smaller index. + for error2 in error_set { + if error2.index.is_some_and(|index2| is_suppressed[index2]) { + // Avoid errors being suppressed by already-suppressed + // errors, to prevent all errors from being suppressed + // at once. + continue; + } + + if self.error_implies(error2.predicate, error.predicate) + && !(error2.index >= error.index + && self.error_implies(error.predicate, error2.predicate)) + { + info!("skipping {:?} (implied by {:?})", error, error2); + is_suppressed[index] = true; + break; + } + } + } + } + } + + let mut reported = None; + + for from_expansion in [false, true] { + for (error, suppressed) in iter::zip(&errors, &is_suppressed) { + if !suppressed && error.obligation.cause.span.from_expansion() == from_expansion { + let guar = self.report_fulfillment_error(error); + self.infcx.set_tainted_by_errors(guar); + reported = Some(guar); + // We want to ignore desugarings here: spans are equivalent even + // if one is the result of a desugaring and the other is not. + let mut span = error.obligation.cause.span; + let expn_data = span.ctxt().outer_expn_data(); + if let ExpnKind::Desugaring(_) = expn_data.kind { + span = expn_data.call_site; + } + self.reported_trait_errors + .borrow_mut() + .entry(span) + .or_insert_with(|| (vec![], guar)) + .0 + .push(error.obligation.predicate); + } + } + } + + // It could be that we don't report an error because we have seen an `ErrorReported` from + // another source. We should probably be able to fix most of these, but some are delayed + // bugs that get a proper error after this function. + reported.unwrap_or_else(|| self.dcx().delayed_bug("failed to report fulfillment errors")) + } + + #[instrument(skip(self), level = "debug")] + fn report_fulfillment_error(&self, error: &FulfillmentError<'tcx>) -> ErrorGuaranteed { + let mut error = FulfillmentError { + obligation: error.obligation.clone(), + code: error.code.clone(), + root_obligation: error.root_obligation.clone(), + }; + if matches!( + error.code, + FulfillmentErrorCode::Select(crate::traits::SelectionError::Unimplemented) + | FulfillmentErrorCode::Project(_) + ) && self.apply_do_not_recommend(&mut error.obligation) + { + error.code = FulfillmentErrorCode::Select(SelectionError::Unimplemented); + } + + match error.code { + FulfillmentErrorCode::Select(ref selection_error) => self.report_selection_error( + error.obligation.clone(), + &error.root_obligation, + selection_error, + ), + FulfillmentErrorCode::Project(ref e) => { + self.report_projection_error(&error.obligation, e) + } + FulfillmentErrorCode::Ambiguity { overflow: None } => { + self.maybe_report_ambiguity(&error.obligation) + } + FulfillmentErrorCode::Ambiguity { overflow: Some(suggest_increasing_limit) } => { + self.report_overflow_no_abort(error.obligation.clone(), suggest_increasing_limit) + } + FulfillmentErrorCode::Subtype(ref expected_found, ref err) => self + .report_mismatched_types( + &error.obligation.cause, + expected_found.expected, + expected_found.found, + *err, + ) + .emit(), + FulfillmentErrorCode::ConstEquate(ref expected_found, ref err) => { + let mut diag = self.report_mismatched_consts( + &error.obligation.cause, + expected_found.expected, + expected_found.found, + *err, + ); + let code = error.obligation.cause.code().peel_derives().peel_match_impls(); + if let ObligationCauseCode::WhereClause(..) + | ObligationCauseCode::WhereClauseInExpr(..) = code + { + self.note_obligation_cause_code( + error.obligation.cause.body_id, + &mut diag, + error.obligation.predicate, + error.obligation.param_env, + code, + &mut vec![], + &mut Default::default(), + ); + } + diag.emit() + } + FulfillmentErrorCode::Cycle(ref cycle) => self.report_overflow_obligation_cycle(cycle), + } + } +} + /// Recovers the "impl X for Y" signature from `impl_def_id` and returns it as a /// string. pub(crate) fn to_pretty_impl_header(tcx: TyCtxt<'_>, impl_def_id: DefId) -> Option { 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 83c6798ba2ed1..e90fe8fb94dd2 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 @@ -1,5 +1,5 @@ use super::{ObligationCauseCode, PredicateObligation}; -use crate::error_reporting::traits::type_err_ctxt_ext::InferCtxtPrivExt; +use crate::error_reporting::traits::fulfillment_errors::InferCtxtPrivExt; use crate::errors::{ EmptyOnClauseInOnUnimplemented, InvalidOnClauseInOnUnimplemented, NoValueInOnUnimplemented, }; diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs index 11a2b1d323379..2cf808f962f08 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs @@ -44,7 +44,7 @@ use std::assert_matches::debug_assert_matches; use std::borrow::Cow; use std::iter; -use crate::error_reporting::traits::type_err_ctxt_ext::InferCtxtPrivExt; +use crate::error_reporting::traits::fulfillment_errors::InferCtxtPrivExt; use crate::infer::InferCtxtExt as _; use crate::traits::query::evaluate_obligation::InferCtxtExt as _; use rustc_middle::ty::print::{ From 4700b5b01f51d2436b0cf1674f22eb6a72bb66c9 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Tue, 9 Jul 2024 12:50:47 -0300 Subject: [PATCH 858/892] Remove spastorino from SMIR --- triagebot.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/triagebot.toml b/triagebot.toml index 8ae454d412a6f..351ae1642f0e0 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -1051,7 +1051,6 @@ project-const-traits = [ project-stable-mir = [ "@celinval", "@oli-obk", - "@spastorino", "@ouz-a", ] From 25637e2c8e69317d61e25acd0bf2129b3507693d Mon Sep 17 00:00:00 2001 From: Vincenzo Palazzo Date: Sat, 25 May 2024 08:44:24 +0000 Subject: [PATCH 859/892] Adds expr_2024 migration lit This is adding a migration lint for the current (in the 2021 edition and previous) to move expr to expr_2021 from expr Co-Developed-by: Eric Holk Signed-off-by: Vincenzo Palazzo --- compiler/rustc_lint/messages.ftl | 3 + compiler/rustc_lint/src/lib.rs | 3 + compiler/rustc_lint/src/lints.rs | 7 + ..._expr_fragment_specifier_2024_migration.rs | 155 ++++++++++++++++++ 4 files changed, 168 insertions(+) create mode 100644 compiler/rustc_lint/src/macro_expr_fragment_specifier_2024_migration.rs diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl index 3e952558d29d3..f048f6fe8ad4b 100644 --- a/compiler/rustc_lint/messages.ftl +++ b/compiler/rustc_lint/messages.ftl @@ -439,6 +439,9 @@ lint_lintpass_by_hand = implementing `LintPass` by hand lint_macro_expanded_macro_exports_accessed_by_absolute_paths = macro-expanded `macro_export` macros from the current crate cannot be referred to by absolute paths .note = the macro is defined here +lint_macro_expr_fragment_specifier_2024_migration = + the `expr` fragment specifier will accept more expressions in the 2024 edition + .suggestion = to keep the existing behavior, use the `expr_2021` fragment specifier lint_macro_is_private = macro `{$ident}` is private lint_macro_rule_never_used = rule #{$n} of macro `{$name}` is never used diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index 17f9d4421aef2..868a44a980a0f 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -60,6 +60,7 @@ mod late; mod let_underscore; mod levels; mod lints; +mod macro_expr_fragment_specifier_2024_migration; mod map_unit_fn; mod methods; mod multiple_supertrait_upcastable; @@ -97,6 +98,7 @@ use impl_trait_overcaptures::ImplTraitOvercaptures; use internal::*; use invalid_from_utf8::*; use let_underscore::*; +use macro_expr_fragment_specifier_2024_migration::*; use map_unit_fn::*; use methods::*; use multiple_supertrait_upcastable::*; @@ -170,6 +172,7 @@ early_lint_methods!( IncompleteInternalFeatures: IncompleteInternalFeatures, RedundantSemicolons: RedundantSemicolons, UnusedDocComment: UnusedDocComment, + Expr2024: Expr2024, ] ] ); diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs index 7c5640f5959a0..54c73710eca6f 100644 --- a/compiler/rustc_lint/src/lints.rs +++ b/compiler/rustc_lint/src/lints.rs @@ -317,6 +317,13 @@ pub struct BuiltinTypeAliasGenericBounds<'a, 'b> { pub sub: Option>, } +#[derive(LintDiagnostic)] +#[diag(lint_macro_expr_fragment_specifier_2024_migration)] +pub struct MacroExprFragment2024 { + #[suggestion(code = "expr_2021", applicability = "machine-applicable")] + pub suggestion: Span, +} + pub struct BuiltinTypeAliasGenericBoundsSuggestion { pub suggestions: Vec<(Span, String)>, } diff --git a/compiler/rustc_lint/src/macro_expr_fragment_specifier_2024_migration.rs b/compiler/rustc_lint/src/macro_expr_fragment_specifier_2024_migration.rs new file mode 100644 index 0000000000000..867e132b1063e --- /dev/null +++ b/compiler/rustc_lint/src/macro_expr_fragment_specifier_2024_migration.rs @@ -0,0 +1,155 @@ +//! Migration code for the `expr_fragment_specifier_2024` +//! rule. +use tracing::debug; + +use rustc_ast::token::Token; +use rustc_ast::token::TokenKind; +use rustc_ast::tokenstream::TokenStream; +use rustc_ast::tokenstream::TokenTree; +use rustc_session::declare_lint; +use rustc_session::declare_lint_pass; +use rustc_session::lint::FutureIncompatibilityReason; +use rustc_span::edition::Edition; +use rustc_span::sym; + +use crate::lints::MacroExprFragment2024; +use crate::EarlyLintPass; + +declare_lint! { + /// The `edition_2024_expr_fragment_specifier` lint detects the use of + /// `expr` fragments in macros during migration to the 2024 edition. + /// + /// The `expr` fragment specifier will accept more expressions in the 2024 + /// edition. To maintain the behavior from the 2021 edition and earlier, use + /// the `expr_2021` fragment specifier. + /// + /// ### Example + /// + /// ```rust,edition2021,compile_fail + /// #![deny(edition_2024_expr_fragment_specifier)] + /// macro_rules! m { + /// ($e:expr) => { + /// $e + /// } + /// } + /// + /// fn main() { + /// m!(1); + /// } + /// ``` + /// + /// {{produces}} + /// + /// ### Explanation + /// + /// Rust [editions] allow the language to evolve without breaking backwards + /// compatibility. This lint catches code that uses [macro matcher fragment + /// specifiers] that have changed meaning in the 2024 edition. If you switch + /// to the new edition without updating the code, your macros may behave + /// differently. + /// + /// In the 2024 edition, the `expr` fragment specifier `expr` will also + /// match `const { ... }` blocks. This means if a macro had a pattern that + /// matched `$e:expr` and another that matches `const { $e: expr }`, for + /// example, that under the 2024 edition the first pattern would match while + /// in the 2021 and earlier editions the second pattern would match. To keep + /// the old behavior, use the `expr_2021` fragment specifier. + /// + /// This lint detects macros whose behavior might change due to the changing + /// meaning of the `expr` fragment specifier. It is "allow" by default + /// because the code is perfectly valid in older editions. The [`cargo fix`] + /// tool with the `--edition` flag will switch this lint to "warn" and + /// automatically apply the suggested fix from the compiler. This provides a + /// completely automated way to update old code for a new edition. + /// + /// Using `cargo fix --edition` with this lint will ensure that your code + /// retains the same behavior. This may not be the desired, as macro authors + /// often will want their macros to use the latest grammar for matching + /// expressions. Be sure to carefully review changes introduced by this lint + /// to ensure the macros implement the desired behavior. + /// + /// [editions]: https://doc.rust-lang.org/edition-guide/ + /// [macro matcher fragment specifiers]: https://doc.rust-lang.org/nightly/edition-guide/rust-2024/macro-fragment-specifiers.html + /// [`cargo fix`]: https://doc.rust-lang.org/cargo/commands/cargo-fix.html + pub EDITION_2024_EXPR_FRAGMENT_SPECIFIER, + Allow, + "The `expr` fragment specifier will accept more expressions in the 2024 edition. \ + To keep the existing behavior, use the `expr_2021` fragment specifier.", + @future_incompatible = FutureIncompatibleInfo { + reason: FutureIncompatibilityReason::EditionSemanticsChange(Edition::Edition2024), + reference: "Migration Guide ", + }; +} + +declare_lint_pass!(Expr2024 => [EDITION_2024_EXPR_FRAGMENT_SPECIFIER,]); + +impl Expr2024 { + fn check_tokens(&mut self, cx: &crate::EarlyContext<'_>, tokens: &TokenStream) { + let mut prev_colon = false; + let mut prev_identifier = false; + let mut prev_dollar = false; + for tt in tokens.trees() { + debug!( + "check_tokens: {:?} - colon {prev_dollar} - ident {prev_identifier} - colon {prev_colon}", + tt + ); + match tt { + TokenTree::Token(token, _) => match token.kind { + TokenKind::Dollar => { + prev_dollar = true; + continue; + } + TokenKind::Ident(..) | TokenKind::NtIdent(..) => { + if prev_colon && prev_identifier && prev_dollar { + self.check_ident_token(cx, token); + } else if prev_dollar { + prev_identifier = true; + continue; + } + } + TokenKind::Colon => { + if prev_dollar && prev_identifier { + prev_colon = true; + continue; + } + } + _ => {} + }, + TokenTree::Delimited(.., tts) => self.check_tokens(cx, tts), + } + prev_colon = false; + prev_identifier = false; + prev_dollar = false; + } + } + + fn check_ident_token(&mut self, cx: &crate::EarlyContext<'_>, token: &Token) { + debug!("check_ident_token: {:?}", token); + let (sym, edition) = match token.kind { + TokenKind::Ident(sym, _) => (sym, Edition::Edition2024), + _ => return, + }; + + debug!("token.span.edition(): {:?}", token.span.edition()); + if token.span.edition() >= edition { + return; + } + + if sym != sym::expr { + return; + } + + debug!("emitting lint"); + cx.builder.emit_span_lint( + &EDITION_2024_EXPR_FRAGMENT_SPECIFIER, + token.span.into(), + MacroExprFragment2024 { suggestion: token.span }, + ); + } +} + +impl EarlyLintPass for Expr2024 { + fn check_mac_def(&mut self, cx: &crate::EarlyContext<'_>, mc: &rustc_ast::MacroDef) { + self.check_tokens(cx, &mc.body.tokens); + } +} From 568e78f36653b6c336a278e252cc08d2088937c0 Mon Sep 17 00:00:00 2001 From: Vincenzo Palazzo Date: Sat, 25 May 2024 10:50:25 +0200 Subject: [PATCH 860/892] tests: adds cargo fix tests Co-Developed-by: Eric Holk Signed-off-by: Vincenzo Palazzo --- .../macros/expr_2021_cargo_fix_edition.fixed | 24 ++++++++++++++ .../ui/macros/expr_2021_cargo_fix_edition.rs | 24 ++++++++++++++ .../macros/expr_2021_cargo_fix_edition.stderr | 33 +++++++++++++++++++ .../expr_2021_inline_const.edi2021.stderr | 4 +-- .../expr_2021_inline_const.edi2024.stderr | 2 +- tests/ui/macros/expr_2021_inline_const.rs | 7 ++++ 6 files changed, 91 insertions(+), 3 deletions(-) create mode 100644 tests/ui/macros/expr_2021_cargo_fix_edition.fixed create mode 100644 tests/ui/macros/expr_2021_cargo_fix_edition.rs create mode 100644 tests/ui/macros/expr_2021_cargo_fix_edition.stderr diff --git a/tests/ui/macros/expr_2021_cargo_fix_edition.fixed b/tests/ui/macros/expr_2021_cargo_fix_edition.fixed new file mode 100644 index 0000000000000..1becd8a92d62e --- /dev/null +++ b/tests/ui/macros/expr_2021_cargo_fix_edition.fixed @@ -0,0 +1,24 @@ +//@ run-rustfix +//@ check-pass +//@ compile-flags: --edition=2021 +#![allow(incomplete_features)] +#![feature(expr_fragment_specifier_2024)] +#![warn(edition_2024_expr_fragment_specifier)] + +macro_rules! m { + ($e:expr_2021) => { //~ WARN: the `expr` fragment specifier will accept more expressions in the 2024 edition + //~^ WARN: this changes meaning in Rust 2024 + $e + }; + ($($i:expr_2021)*) => { }; //~ WARN: the `expr` fragment specifier will accept more expressions in the 2024 edition + //~^ WARN: this changes meaning in Rust 2024 +} + +macro_rules! test { + (expr) => {} +} + +fn main() { + m!(()); + test!(expr); +} diff --git a/tests/ui/macros/expr_2021_cargo_fix_edition.rs b/tests/ui/macros/expr_2021_cargo_fix_edition.rs new file mode 100644 index 0000000000000..ec0b86d2c2332 --- /dev/null +++ b/tests/ui/macros/expr_2021_cargo_fix_edition.rs @@ -0,0 +1,24 @@ +//@ run-rustfix +//@ check-pass +//@ compile-flags: --edition=2021 +#![allow(incomplete_features)] +#![feature(expr_fragment_specifier_2024)] +#![warn(edition_2024_expr_fragment_specifier)] + +macro_rules! m { + ($e:expr) => { //~ WARN: the `expr` fragment specifier will accept more expressions in the 2024 edition + //~^ WARN: this changes meaning in Rust 2024 + $e + }; + ($($i:expr)*) => { }; //~ WARN: the `expr` fragment specifier will accept more expressions in the 2024 edition + //~^ WARN: this changes meaning in Rust 2024 +} + +macro_rules! test { + (expr) => {} +} + +fn main() { + m!(()); + test!(expr); +} diff --git a/tests/ui/macros/expr_2021_cargo_fix_edition.stderr b/tests/ui/macros/expr_2021_cargo_fix_edition.stderr new file mode 100644 index 0000000000000..e8a44fed322f9 --- /dev/null +++ b/tests/ui/macros/expr_2021_cargo_fix_edition.stderr @@ -0,0 +1,33 @@ +warning: the `expr` fragment specifier will accept more expressions in the 2024 edition + --> $DIR/expr_2021_cargo_fix_edition.rs:9:9 + | +LL | ($e:expr) => { + | ^^^^ + | + = warning: this changes meaning in Rust 2024 + = note: for more information, see Migration Guide +note: the lint level is defined here + --> $DIR/expr_2021_cargo_fix_edition.rs:6:9 + | +LL | #![warn(edition_2024_expr_fragment_specifier)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: to keep the existing behavior, use the `expr_2021` fragment specifier + | +LL | ($e:expr_2021) => { + | ~~~~~~~~~ + +warning: the `expr` fragment specifier will accept more expressions in the 2024 edition + --> $DIR/expr_2021_cargo_fix_edition.rs:13:11 + | +LL | ($($i:expr)*) => { }; + | ^^^^ + | + = warning: this changes meaning in Rust 2024 + = note: for more information, see Migration Guide +help: to keep the existing behavior, use the `expr_2021` fragment specifier + | +LL | ($($i:expr_2021)*) => { }; + | ~~~~~~~~~ + +warning: 2 warnings emitted + diff --git a/tests/ui/macros/expr_2021_inline_const.edi2021.stderr b/tests/ui/macros/expr_2021_inline_const.edi2021.stderr index 5e88096445473..b55ae62030c56 100644 --- a/tests/ui/macros/expr_2021_inline_const.edi2021.stderr +++ b/tests/ui/macros/expr_2021_inline_const.edi2021.stderr @@ -1,5 +1,5 @@ error: no rules expected the token `const` - --> $DIR/expr_2021_inline_const.rs:21:12 + --> $DIR/expr_2021_inline_const.rs:26:12 | LL | macro_rules! m2021 { | ------------------ when calling this macro @@ -14,7 +14,7 @@ LL | ($e:expr_2021) => { | ^^^^^^^^^^^^ error: no rules expected the token `const` - --> $DIR/expr_2021_inline_const.rs:22:12 + --> $DIR/expr_2021_inline_const.rs:27:12 | LL | macro_rules! m2024 { | ------------------ when calling this macro diff --git a/tests/ui/macros/expr_2021_inline_const.edi2024.stderr b/tests/ui/macros/expr_2021_inline_const.edi2024.stderr index 237ecb2cc192a..285db53d6c834 100644 --- a/tests/ui/macros/expr_2021_inline_const.edi2024.stderr +++ b/tests/ui/macros/expr_2021_inline_const.edi2024.stderr @@ -1,5 +1,5 @@ error: no rules expected the token `const` - --> $DIR/expr_2021_inline_const.rs:21:12 + --> $DIR/expr_2021_inline_const.rs:26:12 | LL | macro_rules! m2021 { | ------------------ when calling this macro diff --git a/tests/ui/macros/expr_2021_inline_const.rs b/tests/ui/macros/expr_2021_inline_const.rs index ebc5ea3642108..06b74a466d6e2 100644 --- a/tests/ui/macros/expr_2021_inline_const.rs +++ b/tests/ui/macros/expr_2021_inline_const.rs @@ -17,7 +17,14 @@ macro_rules! m2024 { $e }; } + +macro_rules! test { + (expr) => {} +} + fn main() { m2021!(const { 1 }); //~ ERROR: no rules expected the token `const` m2024!(const { 1 }); //[edi2021]~ ERROR: no rules expected the token `const` + + test!(expr); } From d44732120cfd6f49d49bc333ad60c0539aedee19 Mon Sep 17 00:00:00 2001 From: Oneirical Date: Wed, 26 Jun 2024 16:21:58 -0400 Subject: [PATCH 861/892] rewrite symbols-include-type-name to rmake --- .../tidy/src/allowed_run_make_makefiles.txt | 1 - tests/run-make/cdylib-fewer-symbols/rmake.rs | 18 ++++++++---------- tests/run-make/extern-flag-pathless/rmake.rs | 3 +++ .../symbols-include-type-name/Makefile | 9 --------- .../symbols-include-type-name/rmake.rs | 12 ++++++++++++ 5 files changed, 23 insertions(+), 20 deletions(-) delete mode 100644 tests/run-make/symbols-include-type-name/Makefile create mode 100644 tests/run-make/symbols-include-type-name/rmake.rs diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index e9034c631af6f..17f4c5883a7f7 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -170,7 +170,6 @@ run-make/staticlib-dylib-linkage/Makefile run-make/std-core-cycle/Makefile run-make/symbol-mangling-hashed/Makefile run-make/symbol-visibility/Makefile -run-make/symbols-include-type-name/Makefile run-make/sysroot-crates-are-unstable/Makefile run-make/target-cpu-native/Makefile run-make/target-specs/Makefile diff --git a/tests/run-make/cdylib-fewer-symbols/rmake.rs b/tests/run-make/cdylib-fewer-symbols/rmake.rs index 8a8d31e6e49e4..da11f036f7ca4 100644 --- a/tests/run-make/cdylib-fewer-symbols/rmake.rs +++ b/tests/run-make/cdylib-fewer-symbols/rmake.rs @@ -4,20 +4,18 @@ // four such symbols are successfully hidden. // See https://github.com/rust-lang/rust/pull/45710 -//FIXME(Oneirical): try it on windows, restore ignore -// See https://github.com/rust-lang/rust/pull/46207#issuecomment-347561753 -//FIXME(Oneirical): I also removed cross-compile ignore since there is no binary execution +//@ ignore-cross-compile +// Reason: The __rust_ symbol appears during cross-compilation. use run_make_support::{dynamic_lib_name, llvm_readobj, rustc}; fn main() { // Compile a cdylib rustc().input("foo.rs").run(); - let out = llvm_readobj().arg("--symbols").input(dynamic_lib_name("foo")).run().stdout_utf8(); - let out = // All hidden symbols must be removed. - out.lines().filter(|&line| !line.trim().contains("HIDDEN")).collect::>().join("\n"); - assert!(!&out.contains("__rdl_")); - assert!(!&out.contains("__rde_")); - assert!(!&out.contains("__rg_")); - assert!(!&out.contains("__ruse_")); + let out = + llvm_readobj().arg("--dyn-symbols").input(dynamic_lib_name("foo")).run().stdout_utf8(); + assert!(!&out.contains("__rdl_"), "{out}"); + assert!(!&out.contains("__rde_"), "{out}"); + assert!(!&out.contains("__rg_"), "{out}"); + assert!(!&out.contains("__rust_"), "{out}"); } diff --git a/tests/run-make/extern-flag-pathless/rmake.rs b/tests/run-make/extern-flag-pathless/rmake.rs index 2f151136c33c1..9cf828abcb8b4 100644 --- a/tests/run-make/extern-flag-pathless/rmake.rs +++ b/tests/run-make/extern-flag-pathless/rmake.rs @@ -5,6 +5,9 @@ // respected. // See https://github.com/rust-lang/rust/pull/64882 +//@ ignore-cross-compile +// Reason: the compiled binary is executed + use run_make_support::{dynamic_lib_name, fs_wrapper, run, run_fail, rust_lib_name, rustc}; fn main() { diff --git a/tests/run-make/symbols-include-type-name/Makefile b/tests/run-make/symbols-include-type-name/Makefile deleted file mode 100644 index ac26a852e36c1..0000000000000 --- a/tests/run-make/symbols-include-type-name/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -include ../tools.mk - -# Check that symbol names for methods include type names, instead of . - -OUT=$(TMPDIR)/lib.s - -all: - $(RUSTC) --crate-type staticlib --emit asm lib.rs - $(CGREP) Def < $(OUT) diff --git a/tests/run-make/symbols-include-type-name/rmake.rs b/tests/run-make/symbols-include-type-name/rmake.rs new file mode 100644 index 0000000000000..746c7486bf0c0 --- /dev/null +++ b/tests/run-make/symbols-include-type-name/rmake.rs @@ -0,0 +1,12 @@ +// Method names used to be obfuscated when exported into symbols, +// leaving only an obscure ``. After the fix in #30328, +// this test checks that method names are successfully saved in the symbol list. +// See https://github.com/rust-lang/rust/issues/30260 + +use run_make_support::{invalid_utf8_contains, rustc}; + +fn main() { + rustc().crate_type("staticlib").emit("asm").input("lib.rs").run(); + // Check that symbol names for methods include type names, instead of . + invalid_utf8_contains("lib.s", "Def"); +} From dfac6fa5c6b0ca99002f08e99b30c462b72f861d Mon Sep 17 00:00:00 2001 From: simonLeary42 <71396965+simonLeary42@users.noreply.github.com> Date: Tue, 9 Jul 2024 15:23:59 -0400 Subject: [PATCH 862/892] cmake version is from LLVM, link to LLVM docs --- INSTALL.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/INSTALL.md b/INSTALL.md index 9619ec2ce5cfa..1c2cecf8ef9b3 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -48,7 +48,7 @@ If building LLVM from source, you'll need additional tools: [LLVM's documentation](https://llvm.org/docs/GettingStarted.html#host-c-toolchain-both-compiler-and-standard-library) * `ninja`, or GNU `make` 3.81 or later (Ninja is recommended, especially on Windows) -* `cmake` 3.13.4 or later +* `cmake` version listed on [LLVM's documentation](https://llvm.org/docs/GettingStarted.html#software) * `libstdc++-static` may be required on some Linux distributions such as Fedora and Ubuntu From 37599b2072cba572ae9dcf7d1be1445f46f8125c Mon Sep 17 00:00:00 2001 From: Oneirical Date: Tue, 9 Jul 2024 16:13:45 -0400 Subject: [PATCH 863/892] rewrite and rename issue-83112-incr-test-moved-file to rmake --- .../tidy/src/allowed_run_make_makefiles.txt | 1 - .../main.rs | 0 tests/run-make/incr-test-moved-file/rmake.rs | 27 +++++++++++++++++++ .../issue-83112-incr-test-moved-file/Makefile | 25 ----------------- 4 files changed, 27 insertions(+), 26 deletions(-) rename tests/run-make/{issue-83112-incr-test-moved-file => incr-test-moved-file}/main.rs (100%) create mode 100644 tests/run-make/incr-test-moved-file/rmake.rs delete mode 100644 tests/run-make/issue-83112-incr-test-moved-file/Makefile diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index d26d6fe360dc7..f71992cad233f 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -62,7 +62,6 @@ run-make/issue-36710/Makefile run-make/issue-47551/Makefile run-make/issue-69368/Makefile run-make/issue-83045/Makefile -run-make/issue-83112-incr-test-moved-file/Makefile run-make/issue-84395-lto-embed-bitcode/Makefile run-make/issue-85019-moved-src-dir/Makefile run-make/issue-85401-static-mir/Makefile diff --git a/tests/run-make/issue-83112-incr-test-moved-file/main.rs b/tests/run-make/incr-test-moved-file/main.rs similarity index 100% rename from tests/run-make/issue-83112-incr-test-moved-file/main.rs rename to tests/run-make/incr-test-moved-file/main.rs diff --git a/tests/run-make/incr-test-moved-file/rmake.rs b/tests/run-make/incr-test-moved-file/rmake.rs new file mode 100644 index 0000000000000..ae142a0d22e86 --- /dev/null +++ b/tests/run-make/incr-test-moved-file/rmake.rs @@ -0,0 +1,27 @@ +// The generated test harness code contains spans with a dummy location, +// but a non-dummy SyntaxContext. Previously, the incremental cache was encoding +// these spans as a full span (with a source file index), instead of skipping +// the encoding of the location information. If the file gest moved, the hash +// of the span will be unchanged (since it has a dummy location), so the incr +// cache would end up try to load a non-existent file using the previously +// enccoded source file id. +// This test reproduces the steps that used to trigger this bug, and checks +// for successful compilation. +// See https://github.com/rust-lang/rust/issues/83112 + +//@ ignore-none +// Reason: no-std is not supported +//@ ignore-nvptx64-nvidia-cuda +// FIXME: can't find crate for 'std' + +use run_make_support::{fs_wrapper, rust_lib_name, rustc}; + +fn main() { + fs_wrapper::create_dir("incr"); + fs_wrapper::create_dir("src"); + fs_wrapper::create_dir("src/mydir"); + fs_wrapper::copy("main.rs", "src/main.rs"); + rustc().input("src/main.rs").incremental("incr").arg("--test").run(); + fs_wrapper::rename("src/main.rs", "src/mydir/main.rs"); + rustc().input("src/mydir/main.rs").incremental("incr").arg("--test").run(); +} diff --git a/tests/run-make/issue-83112-incr-test-moved-file/Makefile b/tests/run-make/issue-83112-incr-test-moved-file/Makefile deleted file mode 100644 index a00088cd9d61b..0000000000000 --- a/tests/run-make/issue-83112-incr-test-moved-file/Makefile +++ /dev/null @@ -1,25 +0,0 @@ -include ../tools.mk - -# ignore-none no-std is not supported -# ignore-nvptx64-nvidia-cuda FIXME: can't find crate for 'std' - -# Regression test for issue #83112 -# The generated test harness code contains spans with a dummy location, -# but a non-dummy SyntaxContext. Previously, the incremental cache was encoding -# these spans as a full span (with a source file index), instead of skipping -# the encoding of the location information. If the file gest moved, the hash -# of the span will be unchanged (since it has a dummy location), so the incr -# cache would end up try to load a non-existent file using the previously -# enccoded source file id. - -SRC=$(TMPDIR)/src -INCR=$(TMPDIR)/incr - -all: - mkdir $(SRC) - mkdir $(SRC)/mydir - mkdir $(INCR) - cp main.rs $(SRC)/main.rs - $(RUSTC) --test -C incremental=$(INCR) $(SRC)/main.rs --target $(TARGET) - mv $(SRC)/main.rs $(SRC)/mydir/main.rs - $(RUSTC) --test -C incremental=$(INCR) $(SRC)/mydir/main.rs --target $(TARGET) From 80fb4cab4e831f8c2bc735b71c351a198e17c9c9 Mon Sep 17 00:00:00 2001 From: Oneirical Date: Tue, 9 Jul 2024 16:34:22 -0400 Subject: [PATCH 864/892] rewrite type-mismatch-same-crate-name to rmake --- .../tidy/src/allowed_run_make_makefiles.txt | 1 - .../type-mismatch-same-crate-name/Makefile | 19 ------------ .../type-mismatch-same-crate-name/rmake.rs | 29 +++++++++++++++++++ 3 files changed, 29 insertions(+), 20 deletions(-) delete mode 100644 tests/run-make/type-mismatch-same-crate-name/Makefile create mode 100644 tests/run-make/type-mismatch-same-crate-name/rmake.rs diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index f71992cad233f..52410382828ce 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -142,6 +142,5 @@ run-make/test-benches/Makefile run-make/thumb-none-cortex-m/Makefile run-make/thumb-none-qemu/Makefile run-make/translation/Makefile -run-make/type-mismatch-same-crate-name/Makefile run-make/unstable-flag-required/Makefile run-make/x86_64-fortanix-unknown-sgx-lvi/Makefile diff --git a/tests/run-make/type-mismatch-same-crate-name/Makefile b/tests/run-make/type-mismatch-same-crate-name/Makefile deleted file mode 100644 index a2a2a41c7a5a1..0000000000000 --- a/tests/run-make/type-mismatch-same-crate-name/Makefile +++ /dev/null @@ -1,19 +0,0 @@ -include ../tools.mk - -all: - # compile two different versions of crateA - $(RUSTC) --crate-type=rlib crateA.rs -C metadata=-1 -C extra-filename=-1 - $(RUSTC) --crate-type=rlib crateA.rs -C metadata=-2 -C extra-filename=-2 - # make crateB depend on version 1 of crateA - $(RUSTC) --crate-type=rlib crateB.rs --extern crateA=$(TMPDIR)/libcrateA-1.rlib - # make crateC depend on version 2 of crateA - $(RUSTC) crateC.rs --extern crateA=$(TMPDIR)/libcrateA-2.rlib 2>&1 | \ - tr -d '\r\n' | $(CGREP) -e \ - "mismatched types.*\ - crateB::try_foo\(foo2\);.*\ - expected \`crateA::foo::Foo\`, found \`Foo\`.*\ - different versions of crate \`crateA\`.*\ - mismatched types.*\ - crateB::try_bar\(bar2\);.*\ - expected trait \`crateA::bar::Bar\`, found trait \`Bar\`.*\ - different versions of crate \`crateA\`" diff --git a/tests/run-make/type-mismatch-same-crate-name/rmake.rs b/tests/run-make/type-mismatch-same-crate-name/rmake.rs new file mode 100644 index 0000000000000..ecf80d88d51c1 --- /dev/null +++ b/tests/run-make/type-mismatch-same-crate-name/rmake.rs @@ -0,0 +1,29 @@ +// When a compilation failure deals with seemingly identical types, some helpful +// errors should be printed. +// The main use case of this error is when there are two crates +// (generally different versions of the same crate) with the same name +// causing a type mismatch. In this test, one of the crates +// is only introduced as an indirect dependency and the type is accessed via a reexport. +// See https://github.com/rust-lang/rust/pull/42826 + +use run_make_support::{rust_lib_name, rustc}; + +fn main() { + rustc().crate_type("rlib").input("crateA.rs").metadata("-1").extra_filename("-1").run(); + rustc().crate_type("rlib").input("crateA.rs").metadata("-2").extra_filename("-2").run(); + rustc() + .crate_type("rlib") + .input("crateB.rs") + .extern_("crateA", rust_lib_name("crateA-1")) + .run(); + rustc() + .input("crateC.rs") + .extern_("crateA", rust_lib_name("crateA-2")) + .run_fail() + .assert_stderr_contains("mismatched types") + .assert_stderr_contains("crateB::try_foo(foo2);") + .assert_stderr_contains("different versions of crate `crateA`") + .assert_stderr_contains("crateB::try_bar(bar2);") + .assert_stderr_contains("expected trait `crateA::bar::Bar`, found trait `Bar`") + .assert_stderr_contains("different versions of crate `crateA`"); +} From 2adfa147d7cf07810f2d1658b482b8e44bef7e5b Mon Sep 17 00:00:00 2001 From: Oneirical Date: Tue, 9 Jul 2024 16:47:52 -0400 Subject: [PATCH 865/892] rewrite issue-109934-lto-debuginfo as an ui test --- .../tidy/src/allowed_run_make_makefiles.txt | 1 - .../issue-109934-lto-debuginfo/Makefile | 12 ---------- .../issue-109934-lto-debuginfo/lib.rs | 9 -------- tests/ui/lto/debuginfo-lto-alloc.rs | 22 +++++++++++++++++++ 4 files changed, 22 insertions(+), 22 deletions(-) delete mode 100644 tests/run-make/issue-109934-lto-debuginfo/Makefile delete mode 100644 tests/run-make/issue-109934-lto-debuginfo/lib.rs create mode 100644 tests/ui/lto/debuginfo-lto-alloc.rs diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index 52410382828ce..fa41547d060e7 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -48,7 +48,6 @@ run-make/incr-add-rust-src-component/Makefile run-make/incr-foreign-head-span/Makefile run-make/interdependent-c-libraries/Makefile run-make/issue-107094/Makefile -run-make/issue-109934-lto-debuginfo/Makefile run-make/issue-14698/Makefile run-make/issue-15460/Makefile run-make/issue-18943/Makefile diff --git a/tests/run-make/issue-109934-lto-debuginfo/Makefile b/tests/run-make/issue-109934-lto-debuginfo/Makefile deleted file mode 100644 index 3b7a99d3dbc62..0000000000000 --- a/tests/run-make/issue-109934-lto-debuginfo/Makefile +++ /dev/null @@ -1,12 +0,0 @@ -# ignore-cross-compile -include ../tools.mk - -# With the upgrade to LLVM 16, this was getting: -# -# error: Cannot represent a difference across sections -# -# The error stemmed from DI function definitions under type scopes, fixed by -# only declaring in type scope and defining the subprogram elsewhere. - -all: - $(RUSTC) lib.rs --test -C lto=fat -C debuginfo=2 -C incremental=$(TMPDIR)/inc-fat diff --git a/tests/run-make/issue-109934-lto-debuginfo/lib.rs b/tests/run-make/issue-109934-lto-debuginfo/lib.rs deleted file mode 100644 index c405928bd1824..0000000000000 --- a/tests/run-make/issue-109934-lto-debuginfo/lib.rs +++ /dev/null @@ -1,9 +0,0 @@ -extern crate alloc; - -#[cfg(test)] -mod tests { - #[test] - fn something_alloc() { - assert_eq!(Vec::::new(), Vec::::new()); - } -} diff --git a/tests/ui/lto/debuginfo-lto-alloc.rs b/tests/ui/lto/debuginfo-lto-alloc.rs new file mode 100644 index 0000000000000..459103c354c1c --- /dev/null +++ b/tests/ui/lto/debuginfo-lto-alloc.rs @@ -0,0 +1,22 @@ +// With the upgrade to LLVM 16, the following error appeared when using +// link-time-optimization (LTO) alloc and debug compilation mode simultaneously: +// +// error: Cannot represent a difference across sections +// +// The error stemmed from DI function definitions under type scopes, fixed by +// only declaring in type scope and defining the subprogram elsewhere. +// This test reproduces the circumstances that caused the error to appear, and checks +// that compilation is successful. + +//@ check-pass +//@ compile-flags: --test -C debuginfo=2 -C lto=fat -C incremental=inc-fat + +extern crate alloc; + +#[cfg(test)] +mod tests { + #[test] + fn something_alloc() { + assert_eq!(Vec::::new(), Vec::::new()); + } +} From 479b0cdb8957255716fc8158f06a1cb0aba5ad1a Mon Sep 17 00:00:00 2001 From: Charles Celerier Date: Sun, 7 Jul 2024 05:03:59 +0000 Subject: [PATCH 866/892] Ignore fuchsia tests implicitly relying on a signal upon abort Both test-panic-abort-nocapture.rs and test-panic-abort.rs assert the stderr output of the test. On Fuchsia, if a test fails an assertion, this output will contain a line noting the process returned the code -1028 (ZX_TASK_RETCODE_EXCEPTION_KILL). But the asserted stderr output lacks this note. Presumably this is because other platforms implement -Cpanic=abort by killing the process instead of returned a status code. --- tests/ui/test-attrs/test-panic-abort-nocapture.rs | 1 + tests/ui/test-attrs/test-panic-abort-nocapture.run.stderr | 4 ++-- tests/ui/test-attrs/test-panic-abort.rs | 1 + tests/ui/test-attrs/test-panic-abort.run.stdout | 2 +- 4 files changed, 5 insertions(+), 3 deletions(-) diff --git a/tests/ui/test-attrs/test-panic-abort-nocapture.rs b/tests/ui/test-attrs/test-panic-abort-nocapture.rs index 03c175a2a49ff..8c9e222a40d3e 100644 --- a/tests/ui/test-attrs/test-panic-abort-nocapture.rs +++ b/tests/ui/test-attrs/test-panic-abort-nocapture.rs @@ -10,6 +10,7 @@ //@ ignore-wasm no panic or subprocess support //@ ignore-emscripten no panic or subprocess support //@ ignore-sgx no subprocess support +//@ ignore-fuchsia code returned as ZX_TASK_RETCODE_EXCEPTION_KILL, FIXME (#127539) #![cfg(test)] diff --git a/tests/ui/test-attrs/test-panic-abort-nocapture.run.stderr b/tests/ui/test-attrs/test-panic-abort-nocapture.run.stderr index 16001b3eecd4d..4c94518d4d197 100644 --- a/tests/ui/test-attrs/test-panic-abort-nocapture.run.stderr +++ b/tests/ui/test-attrs/test-panic-abort-nocapture.run.stderr @@ -1,9 +1,9 @@ -thread 'main' panicked at $DIR/test-panic-abort-nocapture.rs:34:5: +thread 'main' panicked at $DIR/test-panic-abort-nocapture.rs:35:5: assertion `left == right` failed left: 2 right: 4 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace -thread 'main' panicked at $DIR/test-panic-abort-nocapture.rs:28:5: +thread 'main' panicked at $DIR/test-panic-abort-nocapture.rs:29:5: assertion `left == right` failed left: 2 right: 4 diff --git a/tests/ui/test-attrs/test-panic-abort.rs b/tests/ui/test-attrs/test-panic-abort.rs index 77efaf05bbc0d..c9f6439ef8946 100644 --- a/tests/ui/test-attrs/test-panic-abort.rs +++ b/tests/ui/test-attrs/test-panic-abort.rs @@ -10,6 +10,7 @@ //@ ignore-wasm no panic or subprocess support //@ ignore-emscripten no panic or subprocess support //@ ignore-sgx no subprocess support +//@ ignore-fuchsia code returned as ZX_TASK_RETCODE_EXCEPTION_KILL, FIXME (#127539) #![cfg(test)] #![feature(test)] diff --git a/tests/ui/test-attrs/test-panic-abort.run.stdout b/tests/ui/test-attrs/test-panic-abort.run.stdout index f5d14e77da963..25105f38fcf78 100644 --- a/tests/ui/test-attrs/test-panic-abort.run.stdout +++ b/tests/ui/test-attrs/test-panic-abort.run.stdout @@ -17,7 +17,7 @@ hello, world testing123 ---- it_fails stderr ---- testing321 -thread 'main' panicked at $DIR/test-panic-abort.rs:39:5: +thread 'main' panicked at $DIR/test-panic-abort.rs:40:5: assertion `left == right` failed left: 2 right: 5 From af3aa36d60746f8fac262cd5a3d32f23d60f36ea Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Wed, 10 Jul 2024 01:00:55 +0200 Subject: [PATCH 867/892] do not run test where it cannot run This was seen on Ferrocene, where we have a custom test target that does not have unwind support --- library/alloc/src/slice/tests.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/library/alloc/src/slice/tests.rs b/library/alloc/src/slice/tests.rs index 0156b9928dab4..0b972a13898eb 100644 --- a/library/alloc/src/slice/tests.rs +++ b/library/alloc/src/slice/tests.rs @@ -240,6 +240,7 @@ fn panic_safe() { #[test] #[cfg_attr(miri, ignore)] // Miri is too slow +#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")] fn test_sort() { let mut rng = test_rng(); From 7c88bda1cb9a454ebce2f84ce188e950272a12c0 Mon Sep 17 00:00:00 2001 From: Ashton Hunt Date: Tue, 9 Jul 2024 17:21:31 -0600 Subject: [PATCH 868/892] E0191 suggestion correction, inserts turbofish without dyn (#91997) --- .../src/hir_ty_lowering/errors.rs | 14 ++++++++++- .../dynless-turbofish-e0191-issue-91997.rs | 8 +++++++ ...dynless-turbofish-e0191-issue-91997.stderr | 23 +++++++++++++++++++ tests/ui/issues/issue-23024.stderr | 2 +- tests/ui/issues/issue-28344.stderr | 4 ++-- 5 files changed, 47 insertions(+), 4 deletions(-) create mode 100644 tests/ui/errors/dynless-turbofish-e0191-issue-91997.rs create mode 100644 tests/ui/errors/dynless-turbofish-e0191-issue-91997.stderr diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs index 2d240699105d6..21613a98e219a 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs @@ -12,9 +12,9 @@ use rustc_errors::MultiSpan; use rustc_errors::{ codes::*, pluralize, struct_span_code_err, Applicability, Diag, ErrorGuaranteed, }; -use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{DefId, LocalDefId}; +use rustc_hir::{self as hir, Node}; use rustc_middle::bug; use rustc_middle::query::Key; use rustc_middle::ty::print::{PrintPolyTraitRefExt as _, PrintTraitRefExt as _}; @@ -745,7 +745,15 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { if object_safety_violations { return; } + + // related to issue #91997, turbofishes added only when in an expr or pat + let mut in_expr_or_pat = false; if let ([], [bound]) = (&potential_assoc_types[..], &trait_bounds) { + let grandparent = tcx.parent_hir_node(tcx.parent_hir_id(bound.trait_ref.hir_ref_id)); + in_expr_or_pat = match grandparent { + Node::Expr(_) | Node::Pat(_) => true, + _ => false, + }; match bound.trait_ref.path.segments { // FIXME: `trait_ref.path.span` can point to a full path with multiple // segments, even though `trait_ref.path.segments` is of length `1`. Work @@ -901,6 +909,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { // `Trait<'a, Item = Type>` while accounting for the `<'a>` in the // suggestion. format!("{}, {}>", &snippet[..snippet.len() - 1], types.join(", ")) + } else if in_expr_or_pat { + // The user wrote `Iterator`, so we don't have a type we can suggest, but at + // least we can clue them to the correct syntax `Iterator::`. + format!("{}::<{}>", snippet, types.join(", ")) } else { // The user wrote `Iterator`, so we don't have a type we can suggest, but at // least we can clue them to the correct syntax `Iterator`. diff --git a/tests/ui/errors/dynless-turbofish-e0191-issue-91997.rs b/tests/ui/errors/dynless-turbofish-e0191-issue-91997.rs new file mode 100644 index 0000000000000..69a4c13530bd3 --- /dev/null +++ b/tests/ui/errors/dynless-turbofish-e0191-issue-91997.rs @@ -0,0 +1,8 @@ +trait MyIterator : Iterator {} + +fn main() { + let _ = MyIterator::next; +} +//~^^ ERROR the value of the associated type `Item` in `Iterator` must be specified [E0191] +//~| WARN trait objects without an explicit `dyn` are deprecated [bare_trait_objects] +//~| WARN this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! diff --git a/tests/ui/errors/dynless-turbofish-e0191-issue-91997.stderr b/tests/ui/errors/dynless-turbofish-e0191-issue-91997.stderr new file mode 100644 index 0000000000000..68d8adc5a4013 --- /dev/null +++ b/tests/ui/errors/dynless-turbofish-e0191-issue-91997.stderr @@ -0,0 +1,23 @@ +warning: trait objects without an explicit `dyn` are deprecated + --> $DIR/dynless-turbofish-e0191-issue-91997.rs:4:13 + | +LL | let _ = MyIterator::next; + | ^^^^^^^^^^ + | + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! + = note: for more information, see + = note: `#[warn(bare_trait_objects)]` on by default +help: if this is an object-safe trait, use `dyn` + | +LL | let _ = ::next; + | ++++ + + +error[E0191]: the value of the associated type `Item` in `Iterator` must be specified + --> $DIR/dynless-turbofish-e0191-issue-91997.rs:4:13 + | +LL | let _ = MyIterator::next; + | ^^^^^^^^^^ help: specify the associated type: `MyIterator::` + +error: aborting due to 1 previous error; 1 warning emitted + +For more information about this error, try `rustc --explain E0191`. diff --git a/tests/ui/issues/issue-23024.stderr b/tests/ui/issues/issue-23024.stderr index 1672622d8b723..62278a51be635 100644 --- a/tests/ui/issues/issue-23024.stderr +++ b/tests/ui/issues/issue-23024.stderr @@ -23,7 +23,7 @@ error[E0191]: the value of the associated type `Output` in `FnOnce` must be spec --> $DIR/issue-23024.rs:8:39 | LL | println!("{:?}",(vfnfer[0] as dyn Fn)(3)); - | ^^ help: specify the associated type: `Fn` + | ^^ help: specify the associated type: `Fn::` error: aborting due to 3 previous errors diff --git a/tests/ui/issues/issue-28344.stderr b/tests/ui/issues/issue-28344.stderr index d30fb3cfe58ab..b7e0790f67964 100644 --- a/tests/ui/issues/issue-28344.stderr +++ b/tests/ui/issues/issue-28344.stderr @@ -16,7 +16,7 @@ error[E0191]: the value of the associated type `Output` in `BitXor` must be spec --> $DIR/issue-28344.rs:4:17 | LL | let x: u8 = BitXor::bitor(0 as u8, 0 as u8); - | ^^^^^^ help: specify the associated type: `BitXor` + | ^^^^^^ help: specify the associated type: `BitXor::` error[E0599]: no function or associated item named `bitor` found for trait object `dyn BitXor<_>` in the current scope --> $DIR/issue-28344.rs:4:25 @@ -44,7 +44,7 @@ error[E0191]: the value of the associated type `Output` in `BitXor` must be spec --> $DIR/issue-28344.rs:10:13 | LL | let g = BitXor::bitor; - | ^^^^^^ help: specify the associated type: `BitXor` + | ^^^^^^ help: specify the associated type: `BitXor::` error[E0599]: no function or associated item named `bitor` found for trait object `dyn BitXor<_>` in the current scope --> $DIR/issue-28344.rs:10:21 From 06d76c3156a8245067473fcc62bc5669f468bf4f Mon Sep 17 00:00:00 2001 From: Andres Olivares Date: Wed, 19 Jun 2024 10:15:50 -0400 Subject: [PATCH 869/892] Exposing STARTUPINFOW.wShowWindow in CommandExt (show_window function) to control how a new process should display its window (normal, minimized, maximized, etc) --- library/std/src/os/windows/process.rs | 12 ++++++++++++ library/std/src/sys/pal/windows/process.rs | 10 ++++++++++ 2 files changed, 22 insertions(+) diff --git a/library/std/src/os/windows/process.rs b/library/std/src/os/windows/process.rs index 9cca27fa5dd5b..b5afdf9868f25 100644 --- a/library/std/src/os/windows/process.rs +++ b/library/std/src/os/windows/process.rs @@ -181,6 +181,13 @@ pub trait CommandExt: Sealed { #[stable(feature = "windows_process_extensions", since = "1.16.0")] fn creation_flags(&mut self, flags: u32) -> &mut process::Command; + /// Sets the field [wShowWindow][1] of [STARTUPINFO][2] that is passed to `CreateProcess`. + /// + /// [1]: https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-showwindow + /// [2]: https://learn.microsoft.com/es-es/windows/win32/api/processthreadsapi/ns-processthreadsapi-startupinfow + #[unstable(feature = "windows_process_extensions_show_window", issue = "none")] + fn show_window(&mut self, cmd_show: u16) -> &mut process::Command; + /// Forces all arguments to be wrapped in quote (`"`) characters. /// /// This is useful for passing arguments to [MSYS2/Cygwin][1] based @@ -370,6 +377,11 @@ impl CommandExt for process::Command { self } + fn show_window(&mut self, cmd_show: u16) -> &mut process::Command { + self.as_inner_mut().show_window(Some(cmd_show)); + self + } + fn force_quotes(&mut self, enabled: bool) -> &mut process::Command { self.as_inner_mut().force_quotes(enabled); self diff --git a/library/std/src/sys/pal/windows/process.rs b/library/std/src/sys/pal/windows/process.rs index 2da986a1494ef..c62764696b86b 100644 --- a/library/std/src/sys/pal/windows/process.rs +++ b/library/std/src/sys/pal/windows/process.rs @@ -163,6 +163,7 @@ pub struct Command { env: CommandEnv, cwd: Option, flags: u32, + show_window: Option, detach: bool, // not currently exposed in std::process stdin: Option, stdout: Option, @@ -194,6 +195,7 @@ impl Command { env: Default::default(), cwd: None, flags: 0, + show_window: None, detach: false, stdin: None, stdout: None, @@ -224,6 +226,9 @@ impl Command { pub fn creation_flags(&mut self, flags: u32) { self.flags = flags; } + pub fn show_window(&mut self, cmd_show: Option) { + self.show_window = cmd_show; + } pub fn force_quotes(&mut self, enabled: bool) { self.force_quotes_enabled = enabled; @@ -337,6 +342,11 @@ impl Command { si.hStdError = stderr.as_raw_handle(); } + if let Some(cmd_show) = self.show_window { + si.dwFlags |= c::STARTF_USESHOWWINDOW; + si.wShowWindow = cmd_show; + } + let si_ptr: *mut c::STARTUPINFOW; let mut proc_thread_attribute_list; From e82ad2e62224c66ef0b6c9e11a79e73cf645f1b4 Mon Sep 17 00:00:00 2001 From: Andres Olivares Date: Tue, 9 Jul 2024 20:48:17 -0400 Subject: [PATCH 870/892] Few changes to doc comments. Added tracking issue number. --- library/std/src/os/windows/process.rs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/library/std/src/os/windows/process.rs b/library/std/src/os/windows/process.rs index b5afdf9868f25..a087fb4883014 100644 --- a/library/std/src/os/windows/process.rs +++ b/library/std/src/os/windows/process.rs @@ -181,11 +181,12 @@ pub trait CommandExt: Sealed { #[stable(feature = "windows_process_extensions", since = "1.16.0")] fn creation_flags(&mut self, flags: u32) -> &mut process::Command; - /// Sets the field [wShowWindow][1] of [STARTUPINFO][2] that is passed to `CreateProcess`. + /// Sets the field `wShowWindow` of [STARTUPINFO][1] that is passed to `CreateProcess`. + /// Allowed values are the ones listed in + /// https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-showwindow /// - /// [1]: https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-showwindow - /// [2]: https://learn.microsoft.com/es-es/windows/win32/api/processthreadsapi/ns-processthreadsapi-startupinfow - #[unstable(feature = "windows_process_extensions_show_window", issue = "none")] + /// [1]: https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/ns-processthreadsapi-startupinfow + #[unstable(feature = "windows_process_extensions_show_window", issue = "127544")] fn show_window(&mut self, cmd_show: u16) -> &mut process::Command; /// Forces all arguments to be wrapped in quote (`"`) characters. From b8b6d14de92986e420e782d9a587960f6792c7c2 Mon Sep 17 00:00:00 2001 From: Andres Olivares Date: Tue, 9 Jul 2024 21:46:20 -0400 Subject: [PATCH 871/892] Fixed doc links --- library/std/src/os/windows/process.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/std/src/os/windows/process.rs b/library/std/src/os/windows/process.rs index a087fb4883014..05ffb8925a1f0 100644 --- a/library/std/src/os/windows/process.rs +++ b/library/std/src/os/windows/process.rs @@ -183,9 +183,9 @@ pub trait CommandExt: Sealed { /// Sets the field `wShowWindow` of [STARTUPINFO][1] that is passed to `CreateProcess`. /// Allowed values are the ones listed in - /// https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-showwindow + /// /// - /// [1]: https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/ns-processthreadsapi-startupinfow + /// [1]: #[unstable(feature = "windows_process_extensions_show_window", issue = "127544")] fn show_window(&mut self, cmd_show: u16) -> &mut process::Command; From 9cd1d253a60aca27086da57b68c24b0924277d58 Mon Sep 17 00:00:00 2001 From: Pietro Albini Date: Wed, 10 Jul 2024 09:27:30 +0200 Subject: [PATCH 872/892] use utils::helpers::exe --- src/bootstrap/src/core/config/config.rs | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs index 458120fd2027c..00acd3dabecb3 100644 --- a/src/bootstrap/src/core/config/config.rs +++ b/src/bootstrap/src/core/config/config.rs @@ -1451,11 +1451,6 @@ impl Config { config.out = crate::utils::helpers::absolute(&config.out); } - // Hacky way to determine the executable suffix for the build target. We cannot use - // std::env::consts::EXE_SUFFIX as the build target might not be the target bootstrap was - // compiled with. - let initial_exe_suffix = if config.build.triple.contains("windows") { ".exe" } else { "" }; - config.initial_rustc = if let Some(rustc) = rustc { if !flags.skip_stage0_validation { config.check_stage0_version(&rustc, "rustc"); @@ -1468,7 +1463,7 @@ impl Config { .join(config.build.triple) .join("stage0") .join("bin") - .join(format!("rustc{initial_exe_suffix}")) + .join(exe("rustc", config.build)) }; config.initial_cargo = if let Some(cargo) = cargo { @@ -1483,7 +1478,7 @@ impl Config { .join(config.build.triple) .join("stage0") .join("bin") - .join(format!("cargo{initial_exe_suffix}")) + .join(exe("cargo", config.build)) }; // NOTE: it's important this comes *after* we set `initial_rustc` just above. From 3562ec74cae80cfccda7d388c186609254437426 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Wed, 10 Jul 2024 07:54:17 +0000 Subject: [PATCH 873/892] Make `visit_clobber`'s impl safe --- compiler/rustc_ast/src/mut_visit.rs | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index cbf21317f1a77..1c1163551db5f 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -20,7 +20,7 @@ use rustc_span::symbol::Ident; use rustc_span::Span; use smallvec::{smallvec, Array, SmallVec}; use std::ops::DerefMut; -use std::{panic, ptr}; +use std::panic; use thin_vec::ThinVec; pub trait ExpectOne { @@ -318,19 +318,8 @@ pub trait MutVisitor: Sized { // // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. pub fn visit_clobber(t: &mut T, f: impl FnOnce(T) -> T) { - unsafe { - // Safe because `t` is used in a read-only fashion by `read()` before - // being overwritten by `write()`. - let old_t = ptr::read(t); - let new_t = - panic::catch_unwind(panic::AssertUnwindSafe(|| f(old_t))).unwrap_or_else(|err| { - // Set `t` to some valid but possible meaningless value, - // and pass the fatal error further. - ptr::write(t, T::dummy()); - panic::resume_unwind(err); - }); - ptr::write(t, new_t); - } + let old_t = std::mem::replace(t, T::dummy()); + *t = f(old_t); } // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. From c8e44471b823116fab9849667f80811104e26ef4 Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Wed, 10 Jul 2024 11:56:56 +0200 Subject: [PATCH 874/892] Temporarily remove me from review rotation. --- triagebot.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/triagebot.toml b/triagebot.toml index 8767eb138a192..77b3db8a0109b 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -941,7 +941,6 @@ compiler = [ libs = [ "@cuviper", "@Mark-Simulacrum", - "@m-ou-se", "@Amanieu", "@Nilstrieb", "@workingjubilee", From 541b32c8abffc772ffe58d5ac622a8f956a39d30 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 10 Jul 2024 13:01:59 +0200 Subject: [PATCH 875/892] Update `Cargo.lock` and remove duplicated impl --- compiler/rustc_codegen_gcc/Cargo.lock | 10 ++++++---- compiler/rustc_codegen_gcc/src/builder.rs | 6 ------ 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_codegen_gcc/Cargo.lock b/compiler/rustc_codegen_gcc/Cargo.lock index cd693835ded1d..915229f7e7eef 100644 --- a/compiler/rustc_codegen_gcc/Cargo.lock +++ b/compiler/rustc_codegen_gcc/Cargo.lock @@ -79,16 +79,18 @@ dependencies = [ [[package]] name = "gccjit" -version = "2.0.0" -source = "git+https://github.com/rust-lang/gccjit.rs#328cb1b414f67dfa15162ba7a55ed01931f1b219" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62e0ba949ebee07c5cc21f02cb48f28f2c8db7fcbc15fdc5120476a6c43b4636" dependencies = [ "gccjit_sys", ] [[package]] name = "gccjit_sys" -version = "0.1.0" -source = "git+https://github.com/rust-lang/gccjit.rs#328cb1b414f67dfa15162ba7a55ed01931f1b219" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5bbf85e12c2593772329a9d4e8310271f6706e6045ce4f41b041dd34fba6603" dependencies = [ "libc", ] diff --git a/compiler/rustc_codegen_gcc/src/builder.rs b/compiler/rustc_codegen_gcc/src/builder.rs index b7f62fd09d220..307348f595dc9 100644 --- a/compiler/rustc_codegen_gcc/src/builder.rs +++ b/compiler/rustc_codegen_gcc/src/builder.rs @@ -2369,12 +2369,6 @@ impl<'tcx> HasWasmCAbiOpt for Builder<'_, '_, 'tcx> { } } -impl<'tcx> HasWasmCAbiOpt for Builder<'_, '_, 'tcx> { - fn wasm_c_abi_opt(&self) -> WasmCAbi { - self.cx.wasm_c_abi_opt() - } -} - pub trait ToGccComp { fn to_gcc_comparison(&self) -> ComparisonOp; } From 8bf65c69f7d84a3be4c8278b611dbc1e5a3e2acd Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 10 Jul 2024 13:33:53 +0200 Subject: [PATCH 876/892] Update GCC version --- src/ci/docker/host-x86_64/dist-x86_64-linux/build-gccjit.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ci/docker/host-x86_64/dist-x86_64-linux/build-gccjit.sh b/src/ci/docker/host-x86_64/dist-x86_64-linux/build-gccjit.sh index 5bc6f5cc2169b..4c80e895fd2f8 100755 --- a/src/ci/docker/host-x86_64/dist-x86_64-linux/build-gccjit.sh +++ b/src/ci/docker/host-x86_64/dist-x86_64-linux/build-gccjit.sh @@ -3,7 +3,7 @@ GIT_REPO="https://github.com/rust-lang/gcc" # This commit hash needs to be updated to use a more recent gcc fork version. -GIT_COMMIT="78dc50f0e50e6cd1433149520bd512a4e0eaa1bc" +GIT_COMMIT="341be3b7d7ac6976cfed8ed59da3573c040d0776" set -ex From f77394fdf3f45188d3f110f72f31c4233d4d38eb Mon Sep 17 00:00:00 2001 From: lcnr Date: Wed, 10 Jul 2024 14:13:16 +0200 Subject: [PATCH 877/892] instantiate higher ranked goals in candidate selection reverts #119820 --- .../src/traits/select/mod.rs | 66 ++++--------------- ...didate-from-env-universe-err-1.next.stderr | 23 +++++++ .../candidate-from-env-universe-err-1.rs | 7 +- .../candidate-from-env-universe-err-1.stderr | 26 -------- ...ate-from-env-universe-err-2.current.stderr | 25 ------- ...didate-from-env-universe-err-2.next.stderr | 4 +- ...ndidate-from-env-universe-err-2.old.stderr | 26 -------- .../candidate-from-env-universe-err-2.rs | 3 +- ...om-env-universe-err-project.current.stderr | 26 ++------ ...-from-env-universe-err-project.next.stderr | 8 +-- ...candidate-from-env-universe-err-project.rs | 8 +-- .../leak-check-in-selection-2.next.stderr | 6 +- .../leak-check-in-selection-2.old.stderr | 23 ------- .../leak-check/leak-check-in-selection-2.rs | 3 +- .../leak-check-in-selection-3.old.stderr | 21 +----- .../leak-check/leak-check-in-selection-3.rs | 6 +- ...igher-ranker-supertraits-transitive.stderr | 22 +++++-- .../hrtb-higher-ranker-supertraits.rs | 6 +- .../hrtb-higher-ranker-supertraits.stderr | 59 +++++++---------- tests/ui/implied-bounds/issue-100690.rs | 5 +- tests/ui/implied-bounds/issue-100690.stderr | 47 ++++--------- 21 files changed, 121 insertions(+), 299 deletions(-) create mode 100644 tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-1.next.stderr delete mode 100644 tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-1.stderr delete mode 100644 tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-2.current.stderr delete mode 100644 tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-2.old.stderr delete mode 100644 tests/ui/higher-ranked/leak-check/leak-check-in-selection-2.old.stderr diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 2c4ffdabf140e..7a93f59f16394 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -64,20 +64,6 @@ mod _match; mod candidate_assembly; mod confirmation; -/// Whether to consider the binder of higher ranked goals for the `leak_check` when -/// evaluating higher-ranked goals. See #119820 for more info. -/// -/// While this is a bit hacky, it is necessary to match the behavior of the new solver: -/// We eagerly instantiate binders in the new solver, outside of candidate selection, so -/// the leak check inside of candidates does not consider any bound vars from the higher -/// ranked goal. However, we do exit the binder once we're completely finished with a goal, -/// so the leak-check can be used in evaluate by causing nested higher-ranked goals to fail. -#[derive(Debug, Copy, Clone)] -enum LeakCheckHigherRankedGoal { - No, - Yes, -} - #[derive(Clone, Debug, Eq, PartialEq, Hash)] pub enum IntercrateAmbiguityCause<'tcx> { DownstreamCrate { trait_ref: ty::TraitRef<'tcx>, self_ty: Option> }, @@ -402,10 +388,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let mut no_candidates_apply = true; for c in candidate_set.vec.iter() { - if self - .evaluate_candidate(stack, c, LeakCheckHigherRankedGoal::No)? - .may_apply() - { + if self.evaluate_candidate(stack, c)?.may_apply() { no_candidates_apply = false; break; } @@ -476,7 +459,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // is needed for specialization. Propagate overflow if it occurs. let mut candidates = candidates .into_iter() - .map(|c| match self.evaluate_candidate(stack, &c, LeakCheckHigherRankedGoal::No) { + .map(|c| match self.evaluate_candidate(stack, &c) { Ok(eval) if eval.may_apply() => { Ok(Some(EvaluatedCandidate { candidate: c, evaluation: eval })) } @@ -566,7 +549,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { obligation: &PredicateObligation<'tcx>, ) -> Result { debug_assert!(!self.infcx.next_trait_solver()); - self.evaluation_probe(|this, _outer_universe| { + self.evaluation_probe(|this| { let goal = this.infcx.resolve_vars_if_possible((obligation.predicate, obligation.param_env)); let mut result = this.evaluate_predicate_recursively( @@ -589,11 +572,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { /// `op`, but this can be overwritten if necessary. fn evaluation_probe( &mut self, - op: impl FnOnce(&mut Self, &mut ty::UniverseIndex) -> Result, + op: impl FnOnce(&mut Self) -> Result, ) -> Result { self.infcx.probe(|snapshot| -> Result { - let mut outer_universe = self.infcx.universe(); - let result = op(self, &mut outer_universe)?; + let outer_universe = self.infcx.universe(); + let result = op(self)?; match self.infcx.leak_check(outer_universe, Some(snapshot)) { Ok(()) => {} @@ -1254,7 +1237,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } match self.candidate_from_obligation(stack) { - Ok(Some(c)) => self.evaluate_candidate(stack, &c, LeakCheckHigherRankedGoal::Yes), + Ok(Some(c)) => self.evaluate_candidate(stack, &c), Ok(None) => Ok(EvaluatedToAmbig), Err(Overflow(OverflowError::Canonical)) => Err(OverflowError::Canonical), Err(..) => Ok(EvaluatedToErr), @@ -1279,10 +1262,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { /// Further evaluates `candidate` to decide whether all type parameters match and whether nested /// obligations are met. Returns whether `candidate` remains viable after this further /// scrutiny. - /// - /// Depending on the value of [LeakCheckHigherRankedGoal], we may ignore the binder of the goal - /// when eagerly detecting higher ranked region errors via the `leak_check`. See that enum for - /// more info. #[instrument( level = "debug", skip(self, stack), @@ -1293,25 +1272,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { &mut self, stack: &TraitObligationStack<'o, 'tcx>, candidate: &SelectionCandidate<'tcx>, - leak_check_higher_ranked_goal: LeakCheckHigherRankedGoal, ) -> Result { - let mut result = self.evaluation_probe(|this, outer_universe| { - // We eagerly instantiate higher ranked goals to prevent universe errors - // from impacting candidate selection. This matches the behavior of the new - // solver. This slightly weakens type inference. - // - // In case there are no unresolved type or const variables this - // should still not be necessary to select a unique impl as any overlap - // relying on a universe error from higher ranked goals should have resulted - // in an overlap error in coherence. - let p = self.infcx.enter_forall_and_leak_universe(stack.obligation.predicate); - let obligation = stack.obligation.with(this.tcx(), ty::Binder::dummy(p)); - match leak_check_higher_ranked_goal { - LeakCheckHigherRankedGoal::No => *outer_universe = self.infcx.universe(), - LeakCheckHigherRankedGoal::Yes => {} - } - - match this.confirm_candidate(&obligation, candidate.clone()) { + let mut result = self.evaluation_probe(|this| { + match this.confirm_candidate(stack.obligation, candidate.clone()) { Ok(selection) => { debug!(?selection); this.evaluate_predicates_recursively( @@ -1731,19 +1694,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { }) .map_err(|_| ()) } + fn where_clause_may_apply<'o>( &mut self, stack: &TraitObligationStack<'o, 'tcx>, where_clause_trait_ref: ty::PolyTraitRef<'tcx>, ) -> Result { - self.evaluation_probe(|this, outer_universe| { - // Eagerly instantiate higher ranked goals. - // - // See the comment in `evaluate_candidate` to see why. - let p = self.infcx.enter_forall_and_leak_universe(stack.obligation.predicate); - let obligation = stack.obligation.with(this.tcx(), ty::Binder::dummy(p)); - *outer_universe = self.infcx.universe(); - match this.match_where_clause_trait_ref(&obligation, where_clause_trait_ref) { + self.evaluation_probe(|this| { + match this.match_where_clause_trait_ref(stack.obligation, where_clause_trait_ref) { Ok(obligations) => this.evaluate_predicates_recursively(stack.list(), obligations), Err(()) => Ok(EvaluatedToErr), } diff --git a/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-1.next.stderr b/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-1.next.stderr new file mode 100644 index 0000000000000..90391b7b86b5c --- /dev/null +++ b/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-1.next.stderr @@ -0,0 +1,23 @@ +error[E0277]: the trait bound `for<'a> &'a &T: Trait` is not satisfied + --> $DIR/candidate-from-env-universe-err-1.rs:27:16 + | +LL | hr_bound::<&T>(); + | ^^ the trait `for<'a> Trait` is not implemented for `&'a &T` + | +note: required by a bound in `hr_bound` + --> $DIR/candidate-from-env-universe-err-1.rs:14:20 + | +LL | fn hr_bound() + | -------- required by a bound in this function +LL | where +LL | for<'a> &'a T: Trait, + | ^^^^^ required by this bound in `hr_bound` +help: consider removing the leading `&`-reference + | +LL - hr_bound::<&T>(); +LL + hr_bound::(); + | + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-1.rs b/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-1.rs index b448f0bdc7778..bd251216162db 100644 --- a/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-1.rs +++ b/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-1.rs @@ -1,3 +1,7 @@ +//@ revisions: old next +//@[next] compile-flags: -Znext-solver +//@[old] check-pass + // cc #119820 trait Trait {} @@ -21,8 +25,7 @@ where // the leak check both candidates may apply and we prefer the // `param_env` candidate in winnowing. hr_bound::<&T>(); - //~^ ERROR the parameter type `T` may not live long enough - //~| ERROR implementation of `Trait` is not general enough + //[next]~^ ERROR the trait bound `for<'a> &'a &T: Trait` is not satisfied } fn main() {} diff --git a/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-1.stderr b/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-1.stderr deleted file mode 100644 index febe252d7d1d5..0000000000000 --- a/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-1.stderr +++ /dev/null @@ -1,26 +0,0 @@ -error[E0310]: the parameter type `T` may not live long enough - --> $DIR/candidate-from-env-universe-err-1.rs:23:5 - | -LL | hr_bound::<&T>(); - | ^^^^^^^^^^^^^^ - | | - | 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 | T: Trait + 'static, - | +++++++++ - -error: implementation of `Trait` is not general enough - --> $DIR/candidate-from-env-universe-err-1.rs:23:5 - | -LL | hr_bound::<&T>(); - | ^^^^^^^^^^^^^^ implementation of `Trait` is not general enough - | - = note: `Trait` would have to be implemented for the type `&'0 &T`, for any lifetime `'0`... - = note: ...but `Trait` is actually implemented for the type `&'1 &'1 T`, for some specific lifetime `'1` - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0310`. diff --git a/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-2.current.stderr b/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-2.current.stderr deleted file mode 100644 index 22ce87c024861..0000000000000 --- a/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-2.current.stderr +++ /dev/null @@ -1,25 +0,0 @@ -error: lifetime may not live long enough - --> $DIR/candidate-from-env-universe-err-2.rs:14:5 - | -LL | fn not_hr<'a, T: for<'b> Trait<'a, 'b> + OtherTrait<'static>>() { - | -- lifetime `'a` defined here -LL | impl_hr::(); - | ^^^^^^^^^^^^ requires that `'a` must outlive `'static` - | -note: due to current limitations in the borrow checker, this implies a `'static` lifetime - --> $DIR/candidate-from-env-universe-err-2.rs:11:19 - | -LL | fn impl_hr<'b, T: for<'a> Trait<'a, 'b>>() {} - | ^^^^^^^^^^^^^^^^^^^^^ - -error: implementation of `Trait` is not general enough - --> $DIR/candidate-from-env-universe-err-2.rs:14:5 - | -LL | impl_hr::(); - | ^^^^^^^^^^^^ implementation of `Trait` is not general enough - | - = note: `T` must implement `Trait<'0, '_>`, for any lifetime `'0`... - = note: ...but it actually implements `Trait<'1, '_>`, for some specific lifetime `'1` - -error: aborting due to 2 previous errors - diff --git a/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-2.next.stderr b/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-2.next.stderr index a61bc748bea2d..8771de85c192e 100644 --- a/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-2.next.stderr +++ b/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-2.next.stderr @@ -1,11 +1,11 @@ error[E0277]: the trait bound `for<'a> T: Trait<'a, '_>` is not satisfied - --> $DIR/candidate-from-env-universe-err-2.rs:14:5 + --> $DIR/candidate-from-env-universe-err-2.rs:15:5 | LL | impl_hr::(); | ^^^^^^^^^^^^^^ the trait `for<'a> Trait<'a, '_>` is not implemented for `T` | note: required by a bound in `impl_hr` - --> $DIR/candidate-from-env-universe-err-2.rs:11:19 + --> $DIR/candidate-from-env-universe-err-2.rs:12:19 | LL | fn impl_hr<'b, T: for<'a> Trait<'a, 'b>>() {} | ^^^^^^^^^^^^^^^^^^^^^ required by this bound in `impl_hr` diff --git a/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-2.old.stderr b/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-2.old.stderr deleted file mode 100644 index 29a72b1c1b641..0000000000000 --- a/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-2.old.stderr +++ /dev/null @@ -1,26 +0,0 @@ -error: lifetime may not live long enough - --> $DIR/candidate-from-env-universe-err-2.rs:14:5 - | -LL | fn not_hr<'a, T: for<'b> Trait<'a, 'b> + OtherTrait<'static>>() { - | -- lifetime `'a` defined here -LL | impl_hr::(); - | ^^^^^^^^^^^^ requires that `'a` must outlive `'static` - | -note: due to current limitations in the borrow checker, this implies a `'static` lifetime - --> $DIR/candidate-from-env-universe-err-2.rs:11:19 - | -LL | fn impl_hr<'b, T: for<'a> Trait<'a, 'b>>() {} - | ^^^^^^^^^^^^^^^^^^^^^ - -error[E0308]: mismatched types - --> $DIR/candidate-from-env-universe-err-2.rs:14:5 - | -LL | impl_hr::(); - | ^^^^^^^^^^^^ one type is more general than the other - | - = note: expected trait `for<'a> Trait<'a, '_>` - found trait `for<'b> Trait<'_, 'b>` - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-2.rs b/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-2.rs index 56fa70469ccf8..0132b7db60574 100644 --- a/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-2.rs +++ b/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-2.rs @@ -1,5 +1,6 @@ //@ revisions: current next //@[next] compile-flags: -Znext-solver +//@[current] check-pass // cc #119820 @@ -13,8 +14,6 @@ fn impl_hr<'b, T: for<'a> Trait<'a, 'b>>() {} fn not_hr<'a, T: for<'b> Trait<'a, 'b> + OtherTrait<'static>>() { impl_hr::(); //[next]~^ ERROR the trait bound `for<'a> T: Trait<'a, '_>` is not satisfied - //[current]~^^ERROR lifetime may not live long enough - //[current]~| ERROR implementation of `Trait` is not general enough } fn main() {} diff --git a/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-project.current.stderr b/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-project.current.stderr index bb0b2de788e83..7b9fd6bb4c571 100644 --- a/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-project.current.stderr +++ b/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-project.current.stderr @@ -1,23 +1,5 @@ -error: implementation of `Trait` is not general enough - --> $DIR/candidate-from-env-universe-err-project.rs:28:5 - | -LL | trait_bound::(); - | ^^^^^^^^^^^^^^^^^^ implementation of `Trait` is not general enough - | - = note: `T` must implement `Trait<'0>`, for any lifetime `'0`... - = note: ...but it actually implements `Trait<'static>` - -error: implementation of `Trait` is not general enough - --> $DIR/candidate-from-env-universe-err-project.rs:39:5 - | -LL | projection_bound::(); - | ^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Trait` is not general enough - | - = note: `T` must implement `Trait<'0>`, for any lifetime `'0`... - = note: ...but it actually implements `Trait<'static>` - error[E0308]: mismatched types - --> $DIR/candidate-from-env-universe-err-project.rs:39:5 + --> $DIR/candidate-from-env-universe-err-project.rs:38:5 | LL | projection_bound::(); | ^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other @@ -31,7 +13,7 @@ LL | fn projection_bound Trait<'a, Assoc = usize>>() {} | ^^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/candidate-from-env-universe-err-project.rs:55:30 + --> $DIR/candidate-from-env-universe-err-project.rs:53:30 | LL | let _higher_ranked_norm: for<'a> fn(>::Assoc) = |_| (); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other @@ -40,7 +22,7 @@ LL | let _higher_ranked_norm: for<'a> fn(>::Assoc) = |_| (); found associated type `>::Assoc` error[E0308]: mismatched types - --> $DIR/candidate-from-env-universe-err-project.rs:55:30 + --> $DIR/candidate-from-env-universe-err-project.rs:53:30 | LL | let _higher_ranked_norm: for<'a> fn(>::Assoc) = |_| (); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other @@ -49,6 +31,6 @@ LL | let _higher_ranked_norm: for<'a> fn(>::Assoc) = |_| (); found associated type `>::Assoc` = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error: aborting due to 5 previous errors +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-project.next.stderr b/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-project.next.stderr index 2804d5bbe9408..90df487c07e7f 100644 --- a/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-project.next.stderr +++ b/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-project.next.stderr @@ -15,7 +15,7 @@ LL | fn function1 + for<'a> Trait<'a>>() { | +++++++++++++++++++ error[E0277]: the trait bound `for<'a> T: Trait<'a>` is not satisfied - --> $DIR/candidate-from-env-universe-err-project.rs:39:24 + --> $DIR/candidate-from-env-universe-err-project.rs:38:24 | LL | projection_bound::(); | ^ the trait `for<'a> Trait<'a>` is not implemented for `T` @@ -31,7 +31,7 @@ LL | fn function2 + for<'a> Trait<'a>>() { | +++++++++++++++++++ error[E0271]: type mismatch resolving `>::Assoc == usize` - --> $DIR/candidate-from-env-universe-err-project.rs:39:24 + --> $DIR/candidate-from-env-universe-err-project.rs:38:24 | LL | projection_bound::(); | ^ type mismatch resolving `>::Assoc == usize` @@ -48,13 +48,13 @@ LL | fn projection_bound Trait<'a, Assoc = usize>>() {} | ^^^^^^^^^^^^^ required by this bound in `projection_bound` error: higher-ranked subtype error - --> $DIR/candidate-from-env-universe-err-project.rs:55:30 + --> $DIR/candidate-from-env-universe-err-project.rs:53:30 | LL | let _higher_ranked_norm: for<'a> fn(>::Assoc) = |_| (); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: higher-ranked subtype error - --> $DIR/candidate-from-env-universe-err-project.rs:55:30 + --> $DIR/candidate-from-env-universe-err-project.rs:53:30 | LL | let _higher_ranked_norm: for<'a> fn(>::Assoc) = |_| (); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-project.rs b/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-project.rs index e0d2e44e6e7d8..a77d87f6fa78e 100644 --- a/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-project.rs +++ b/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-project.rs @@ -1,8 +1,8 @@ //@ revisions: next current //@[next] compile-flags: -Znext-solver -// cc #119820 the previous behavior here was inconsistent as we discarded -// the where-bound candidate for trait goals due to the leak check, but did +// cc #119820 the behavior is inconsistent as we discard the where-bound +// candidate for trait goals due to the leak check, but did // not do so for projection candidates and during normalization. // // This results in an inconsistency between `Trait` and `Projection` goals as @@ -27,7 +27,6 @@ fn function1>() { // We prefer env candidates over impl candidatescausing this to succeed. trait_bound::(); //[next]~^ ERROR the trait bound `for<'a> T: Trait<'a>` is not satisfied - //[current]~^^ ERROR implementation of `Trait` is not general enough } fn function2>() { @@ -39,8 +38,7 @@ fn function2>() { projection_bound::(); //[next]~^ ERROR type mismatch resolving `>::Assoc == usize` //[next]~| ERROR the trait bound `for<'a> T: Trait<'a>` is not satisfied - //[current]~^^^ ERROR implementation of `Trait` is not general enough - //[current]~| ERROR mismatched types + //[current]~^^^ ERROR mismatched types } fn function3>() { diff --git a/tests/ui/higher-ranked/leak-check/leak-check-in-selection-2.next.stderr b/tests/ui/higher-ranked/leak-check/leak-check-in-selection-2.next.stderr index a840304e49c1f..cb97bc4b8fc6e 100644 --- a/tests/ui/higher-ranked/leak-check/leak-check-in-selection-2.next.stderr +++ b/tests/ui/higher-ranked/leak-check/leak-check-in-selection-2.next.stderr @@ -1,11 +1,11 @@ error[E0283]: type annotations needed - --> $DIR/leak-check-in-selection-2.rs:16:5 + --> $DIR/leak-check-in-selection-2.rs:17:5 | LL | impls_trait::<(), _>(); | ^^^^^^^^^^^^^^^^^^^^ cannot infer type of the type parameter `U` declared on the function `impls_trait` | note: multiple `impl`s satisfying `for<'a> (): Trait<&'a str, _>` found - --> $DIR/leak-check-in-selection-2.rs:9:1 + --> $DIR/leak-check-in-selection-2.rs:10:1 | LL | impl<'a> Trait<&'a str, &'a str> for () {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -13,7 +13,7 @@ LL | LL | impl<'a> Trait<&'a str, String> for () {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: required by a bound in `impls_trait` - --> $DIR/leak-check-in-selection-2.rs:13:19 + --> $DIR/leak-check-in-selection-2.rs:14:19 | LL | fn impls_trait Trait<&'a str, U>, U>() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `impls_trait` diff --git a/tests/ui/higher-ranked/leak-check/leak-check-in-selection-2.old.stderr b/tests/ui/higher-ranked/leak-check/leak-check-in-selection-2.old.stderr deleted file mode 100644 index a840304e49c1f..0000000000000 --- a/tests/ui/higher-ranked/leak-check/leak-check-in-selection-2.old.stderr +++ /dev/null @@ -1,23 +0,0 @@ -error[E0283]: type annotations needed - --> $DIR/leak-check-in-selection-2.rs:16:5 - | -LL | impls_trait::<(), _>(); - | ^^^^^^^^^^^^^^^^^^^^ cannot infer type of the type parameter `U` declared on the function `impls_trait` - | -note: multiple `impl`s satisfying `for<'a> (): Trait<&'a str, _>` found - --> $DIR/leak-check-in-selection-2.rs:9:1 - | -LL | impl<'a> Trait<&'a str, &'a str> for () {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -LL | -LL | impl<'a> Trait<&'a str, String> for () {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: required by a bound in `impls_trait` - --> $DIR/leak-check-in-selection-2.rs:13:19 - | -LL | fn impls_trait Trait<&'a str, U>, U>() {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `impls_trait` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0283`. diff --git a/tests/ui/higher-ranked/leak-check/leak-check-in-selection-2.rs b/tests/ui/higher-ranked/leak-check/leak-check-in-selection-2.rs index 48dd569f201b9..24e38ec45a2c4 100644 --- a/tests/ui/higher-ranked/leak-check/leak-check-in-selection-2.rs +++ b/tests/ui/higher-ranked/leak-check/leak-check-in-selection-2.rs @@ -1,5 +1,6 @@ //@ revisions: old next //@[next] compile-flags: -Znext-solver +//@[old] check-pass // cc #119820 @@ -14,5 +15,5 @@ fn impls_trait Trait<&'a str, U>, U>() {} fn main() { impls_trait::<(), _>(); - //~^ ERROR type annotations needed + //[next]~^ ERROR type annotations needed } diff --git a/tests/ui/higher-ranked/leak-check/leak-check-in-selection-3.old.stderr b/tests/ui/higher-ranked/leak-check/leak-check-in-selection-3.old.stderr index 662a06537401a..194571dd4a85b 100644 --- a/tests/ui/higher-ranked/leak-check/leak-check-in-selection-3.old.stderr +++ b/tests/ui/higher-ranked/leak-check/leak-check-in-selection-3.old.stderr @@ -1,22 +1,3 @@ -error[E0283]: type annotations needed - --> $DIR/leak-check-in-selection-3.rs:18:5 - | -LL | impls_leak::>(); - | ^^^^^^^^^^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the function `impls_leak` - | -note: multiple `impl`s satisfying `for<'a> Box<_>: Leak<'a>` found - --> $DIR/leak-check-in-selection-3.rs:9:1 - | -LL | impl Leak<'_> for Box {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -LL | impl Leak<'static> for Box {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: required by a bound in `impls_leak` - --> $DIR/leak-check-in-selection-3.rs:12:18 - | -LL | fn impls_leak Leak<'a>>() {} - | ^^^^^^^^^^^^^^^^ required by this bound in `impls_leak` - error[E0283]: type annotations needed --> $DIR/leak-check-in-selection-3.rs:35:5 | @@ -43,6 +24,6 @@ note: required by a bound in `impls_indirect_leak` LL | fn impls_indirect_leak IndirectLeak<'a>>() {} | ^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `impls_indirect_leak` -error: aborting due to 2 previous errors +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0283`. diff --git a/tests/ui/higher-ranked/leak-check/leak-check-in-selection-3.rs b/tests/ui/higher-ranked/leak-check/leak-check-in-selection-3.rs index 9e99b6c527d9d..9aa1be57a4fb2 100644 --- a/tests/ui/higher-ranked/leak-check/leak-check-in-selection-3.rs +++ b/tests/ui/higher-ranked/leak-check/leak-check-in-selection-3.rs @@ -1,9 +1,9 @@ //@ revisions: old next //@[next] compile-flags: -Znext-solver -// cc #119820, the previous behavior here was inconsistent, +// cc #119820, the behavior here is inconsistent, // using the leak check to guide inference for `for<'a> Box<_>: Leak<'a>` -// but not for `for<'a> Box<_>: IndirectLeak<'a>` +// but not for `for<'a> Box<_>: IndirectLeak<'a>`. trait Leak<'a> {} impl Leak<'_> for Box {} @@ -16,7 +16,7 @@ fn direct() { // The `Box` impls fails the leak check, // meaning that we apply the `Box` impl. impls_leak::>(); - //~^ ERROR type annotations needed + //[next]~^ ERROR type annotations needed } trait IndirectLeak<'a> {} diff --git a/tests/ui/higher-ranked/trait-bounds/hrtb-higher-ranker-supertraits-transitive.stderr b/tests/ui/higher-ranked/trait-bounds/hrtb-higher-ranker-supertraits-transitive.stderr index be19bf85bd2f3..e10da26665ebb 100644 --- a/tests/ui/higher-ranked/trait-bounds/hrtb-higher-ranker-supertraits-transitive.stderr +++ b/tests/ui/higher-ranked/trait-bounds/hrtb-higher-ranker-supertraits-transitive.stderr @@ -1,11 +1,23 @@ -error: implementation of `Bar` is not general enough - --> $DIR/hrtb-higher-ranker-supertraits-transitive.rs:47:5 +error[E0277]: the trait bound `for<'ccx> B: Bar<'ccx>` is not satisfied + --> $DIR/hrtb-higher-ranker-supertraits-transitive.rs:47:26 | LL | want_bar_for_any_ccx(b); - | ^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Bar` is not general enough + | -------------------- ^ the trait `for<'ccx> Bar<'ccx>` is not implemented for `B` + | | + | required by a bound introduced by this call | - = note: `B` must implement `Bar<'0>`, for any lifetime `'0`... - = note: ...but it actually implements `Bar<'static>` +note: required by a bound in `want_bar_for_any_ccx` + --> $DIR/hrtb-higher-ranker-supertraits-transitive.rs:32:15 + | +LL | fn want_bar_for_any_ccx(b: &B) + | -------------------- required by a bound in this function +LL | where B : for<'ccx> Bar<'ccx> + | ^^^^^^^^^^^^^^^^^^^ required by this bound in `want_bar_for_any_ccx` +help: consider further restricting this bound + | +LL | where B : Qux + for<'ccx> Bar<'ccx> + | +++++++++++++++++++++ error: aborting due to 1 previous error +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/higher-ranked/trait-bounds/hrtb-higher-ranker-supertraits.rs b/tests/ui/higher-ranked/trait-bounds/hrtb-higher-ranker-supertraits.rs index 70ce580258d43..7e2ecc937bd0d 100644 --- a/tests/ui/higher-ranked/trait-bounds/hrtb-higher-ranker-supertraits.rs +++ b/tests/ui/higher-ranked/trait-bounds/hrtb-higher-ranker-supertraits.rs @@ -12,8 +12,7 @@ trait Bar<'ccx>: for<'tcx> Foo<'tcx> { fn want_foo_for_some_tcx<'x, F: Foo<'x>>(f: &'x F) { want_foo_for_some_tcx(f); want_foo_for_any_tcx(f); - //~^ ERROR lifetime may not live long enough - //~| ERROR implementation of `Foo` is not general enough + //~^ ERROR the trait bound `for<'tcx> F: Foo<'tcx>` is not satisfied } fn want_foo_for_any_tcx Foo<'tcx>>(f: &F) { @@ -27,8 +26,7 @@ fn want_bar_for_some_ccx<'x, B: Bar<'x>>(b: &B) { want_bar_for_some_ccx(b); want_bar_for_any_ccx(b); - //~^ ERROR lifetime may not live long enough - //~| ERROR implementation of `Bar` is not general enough + //~^ ERROR the trait bound `for<'ccx> B: Bar<'ccx>` is not satisfied } fn want_bar_for_any_ccx Bar<'ccx>>(b: &B) { diff --git a/tests/ui/higher-ranked/trait-bounds/hrtb-higher-ranker-supertraits.stderr b/tests/ui/higher-ranked/trait-bounds/hrtb-higher-ranker-supertraits.stderr index dd760926ea117..af76377de8500 100644 --- a/tests/ui/higher-ranked/trait-bounds/hrtb-higher-ranker-supertraits.stderr +++ b/tests/ui/higher-ranked/trait-bounds/hrtb-higher-ranker-supertraits.stderr @@ -1,50 +1,39 @@ -error: lifetime may not live long enough - --> $DIR/hrtb-higher-ranker-supertraits.rs:14:5 +error[E0277]: the trait bound `for<'tcx> F: Foo<'tcx>` is not satisfied + --> $DIR/hrtb-higher-ranker-supertraits.rs:14:26 | -LL | fn want_foo_for_some_tcx<'x, F: Foo<'x>>(f: &'x F) { - | -- lifetime `'x` defined here -LL | want_foo_for_some_tcx(f); LL | want_foo_for_any_tcx(f); - | ^^^^^^^^^^^^^^^^^^^^^^^ requires that `'x` must outlive `'static` + | -------------------- ^ the trait `for<'tcx> Foo<'tcx>` is not implemented for `F` + | | + | required by a bound introduced by this call | -note: due to current limitations in the borrow checker, this implies a `'static` lifetime - --> $DIR/hrtb-higher-ranker-supertraits.rs:19:28 +note: required by a bound in `want_foo_for_any_tcx` + --> $DIR/hrtb-higher-ranker-supertraits.rs:18:28 | LL | fn want_foo_for_any_tcx Foo<'tcx>>(f: &F) { - | ^^^^^^^^^^^^^^^^^^^ - -error: implementation of `Foo` is not general enough - --> $DIR/hrtb-higher-ranker-supertraits.rs:14:5 - | -LL | want_foo_for_any_tcx(f); - | ^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough + | ^^^^^^^^^^^^^^^^^^^ required by this bound in `want_foo_for_any_tcx` +help: consider further restricting this bound | - = note: `F` must implement `Foo<'0>`, for any lifetime `'0`... - = note: ...but it actually implements `Foo<'1>`, for some specific lifetime `'1` +LL | fn want_foo_for_some_tcx<'x, F: Foo<'x> + for<'tcx> Foo<'tcx>>(f: &'x F) { + | +++++++++++++++++++++ -error: lifetime may not live long enough - --> $DIR/hrtb-higher-ranker-supertraits.rs:29:5 +error[E0277]: the trait bound `for<'ccx> B: Bar<'ccx>` is not satisfied + --> $DIR/hrtb-higher-ranker-supertraits.rs:28:26 | -LL | fn want_bar_for_some_ccx<'x, B: Bar<'x>>(b: &B) { - | -- lifetime `'x` defined here -... LL | want_bar_for_any_ccx(b); - | ^^^^^^^^^^^^^^^^^^^^^^^ requires that `'x` must outlive `'static` + | -------------------- ^ the trait `for<'ccx> Bar<'ccx>` is not implemented for `B` + | | + | required by a bound introduced by this call | -note: due to current limitations in the borrow checker, this implies a `'static` lifetime - --> $DIR/hrtb-higher-ranker-supertraits.rs:34:28 +note: required by a bound in `want_bar_for_any_ccx` + --> $DIR/hrtb-higher-ranker-supertraits.rs:32:28 | LL | fn want_bar_for_any_ccx Bar<'ccx>>(b: &B) { - | ^^^^^^^^^^^^^^^^^^^ - -error: implementation of `Bar` is not general enough - --> $DIR/hrtb-higher-ranker-supertraits.rs:29:5 - | -LL | want_bar_for_any_ccx(b); - | ^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Bar` is not general enough + | ^^^^^^^^^^^^^^^^^^^ required by this bound in `want_bar_for_any_ccx` +help: consider further restricting this bound | - = note: `B` must implement `Bar<'0>`, for any lifetime `'0`... - = note: ...but it actually implements `Bar<'1>`, for some specific lifetime `'1` +LL | fn want_bar_for_some_ccx<'x, B: Bar<'x> + for<'ccx> Bar<'ccx>>(b: &B) { + | +++++++++++++++++++++ -error: aborting due to 4 previous errors +error: aborting due to 2 previous errors +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/implied-bounds/issue-100690.rs b/tests/ui/implied-bounds/issue-100690.rs index 041c687ec9430..b0dbf749c4670 100644 --- a/tests/ui/implied-bounds/issue-100690.rs +++ b/tests/ui/implied-bounds/issue-100690.rs @@ -32,10 +32,7 @@ impl<'a, T: 'a> Handle<'a, T, UIView<'a, T>, Result<(), io::Error>> for TUIHandl F: FnOnce(&mut UIView<'a, T>) -> Result<(), io::Error> + Send + 'static, { real_dispatch(f) - //~^ ERROR lifetime may not live long enough - //~| ERROR implementation of `FnOnce` is not general enough - //~| ERROR mismatched types - // + //~^ ERROR expected a `FnOnce(&mut UIView<'_, T>)` closure, found `F` } } diff --git a/tests/ui/implied-bounds/issue-100690.stderr b/tests/ui/implied-bounds/issue-100690.stderr index 2cfd028f2559b..4964dccd551d9 100644 --- a/tests/ui/implied-bounds/issue-100690.stderr +++ b/tests/ui/implied-bounds/issue-100690.stderr @@ -1,41 +1,22 @@ -error: lifetime may not live long enough - --> $DIR/issue-100690.rs:34:9 +error[E0277]: expected a `FnOnce(&mut UIView<'_, T>)` closure, found `F` + --> $DIR/issue-100690.rs:34:23 | -LL | impl<'a, T: 'a> Handle<'a, T, UIView<'a, T>, Result<(), io::Error>> for TUIHandle { - | -- lifetime `'a` defined here -... LL | real_dispatch(f) - | ^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static` + | ------------- ^ expected an `FnOnce(&mut UIView<'_, T>)` closure, found `F` + | | + | required by a bound introduced by this call | -note: due to current limitations in the borrow checker, this implies a `'static` lifetime + = note: expected a closure with arguments `(&mut UIView<'a, _>,)` + found a closure with arguments `(&mut UIView<'_, _>,)` +note: required by a bound in `real_dispatch` --> $DIR/issue-100690.rs:8:8 | +LL | fn real_dispatch(f: F) -> Result<(), io::Error> + | ------------- required by a bound in this function +LL | where LL | F: FnOnce(&mut UIView) -> Result<(), io::Error> + Send + 'static, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `real_dispatch` -error: implementation of `FnOnce` is not general enough - --> $DIR/issue-100690.rs:34:9 - | -LL | real_dispatch(f) - | ^^^^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough - | - = note: `F` must implement `FnOnce<(&mut UIView<'0, T>,)>`, for any lifetime `'0`... - = note: ...but it actually implements `FnOnce<(&mut UIView<'1, T>,)>`, for some specific lifetime `'1` - -error[E0308]: mismatched types - --> $DIR/issue-100690.rs:34:9 - | -LL | real_dispatch(f) - | ^^^^^^^^^^^^^^^^ one type is more general than the other - | - = note: expected associated type `,)>>::Output` - found associated type `,)>>::Output` -note: the lifetime requirement is introduced here - --> $DIR/issue-100690.rs:8:34 - | -LL | F: FnOnce(&mut UIView) -> Result<(), io::Error> + Send + 'static, - | ^^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to 3 previous errors +error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0308`. +For more information about this error, try `rustc --explain E0277`. From e7bd16e6c8f498af99a28e139dc4d74d8d43cbb6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Wed, 10 Jul 2024 14:45:14 +0200 Subject: [PATCH 878/892] Fix local download of Docker caches --- src/ci/docker/run.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ci/docker/run.sh b/src/ci/docker/run.sh index 695b8b4c0d9e1..40f421714118e 100755 --- a/src/ci/docker/run.sh +++ b/src/ci/docker/run.sh @@ -93,7 +93,7 @@ if [ -f "$docker_dir/$image/Dockerfile" ]; then docker --version REGISTRY=ghcr.io - REGISTRY_USERNAME=${GITHUB_REPOSITORY_OWNER} + REGISTRY_USERNAME=${GITHUB_REPOSITORY_OWNER:-rust-lang-ci} # Tag used to push the final Docker image, so that it can be pulled by e.g. rustup IMAGE_TAG=${REGISTRY}/${REGISTRY_USERNAME}/rust-ci:${cksum} # Tag used to cache the Docker build From e00fd781c91bc4b2703f25a75b0b28c775bd51b9 Mon Sep 17 00:00:00 2001 From: lcnr Date: Wed, 10 Jul 2024 14:45:07 +0200 Subject: [PATCH 879/892] simplify and future-proof `needs_normalization` --- .../rustc_trait_selection/src/traits/normalize.rs | 13 +++++-------- compiler/rustc_type_ir/src/flags.rs | 8 ++++---- compiler/rustc_type_ir/src/visit.rs | 2 +- 3 files changed, 10 insertions(+), 13 deletions(-) diff --git a/compiler/rustc_trait_selection/src/traits/normalize.rs b/compiler/rustc_trait_selection/src/traits/normalize.rs index dda3aaaf71e82..3a7481acbafd3 100644 --- a/compiler/rustc_trait_selection/src/traits/normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/normalize.rs @@ -109,16 +109,13 @@ pub(super) fn needs_normalization<'tcx, T: TypeVisitable>>( value: &T, reveal: Reveal, ) -> bool { - // This mirrors `ty::TypeFlags::HAS_ALIASES` except that we take `Reveal` into account. - - let mut flags = ty::TypeFlags::HAS_TY_PROJECTION - | ty::TypeFlags::HAS_TY_WEAK - | ty::TypeFlags::HAS_TY_INHERENT - | ty::TypeFlags::HAS_CT_PROJECTION; + let mut flags = ty::TypeFlags::HAS_ALIAS; + // Opaques are treated as rigid with `Reveal::UserFacing`, + // so we can ignore those. match reveal { - Reveal::UserFacing => {} - Reveal::All => flags |= ty::TypeFlags::HAS_TY_OPAQUE, + Reveal::UserFacing => flags.remove(ty::TypeFlags::HAS_TY_OPAQUE), + Reveal::All => {} } value.has_type_flags(flags) diff --git a/compiler/rustc_type_ir/src/flags.rs b/compiler/rustc_type_ir/src/flags.rs index 6a1ac642b70f7..81aa4a1f19ee0 100644 --- a/compiler/rustc_type_ir/src/flags.rs +++ b/compiler/rustc_type_ir/src/flags.rs @@ -14,7 +14,7 @@ bitflags::bitflags! { /// Does this have `ConstKind::Param`? const HAS_CT_PARAM = 1 << 2; - const HAS_PARAM = TypeFlags::HAS_TY_PARAM.bits() + const HAS_PARAM = TypeFlags::HAS_TY_PARAM.bits() | TypeFlags::HAS_RE_PARAM.bits() | TypeFlags::HAS_CT_PARAM.bits(); @@ -27,7 +27,7 @@ bitflags::bitflags! { /// Does this have inference variables? Used to determine whether /// inference is required. - const HAS_INFER = TypeFlags::HAS_TY_INFER.bits() + const HAS_INFER = TypeFlags::HAS_TY_INFER.bits() | TypeFlags::HAS_RE_INFER.bits() | TypeFlags::HAS_CT_INFER.bits(); @@ -39,7 +39,7 @@ bitflags::bitflags! { const HAS_CT_PLACEHOLDER = 1 << 8; /// Does this have placeholders? - const HAS_PLACEHOLDER = TypeFlags::HAS_TY_PLACEHOLDER.bits() + const HAS_PLACEHOLDER = TypeFlags::HAS_TY_PLACEHOLDER.bits() | TypeFlags::HAS_RE_PLACEHOLDER.bits() | TypeFlags::HAS_CT_PLACEHOLDER.bits(); @@ -81,7 +81,7 @@ bitflags::bitflags! { /// Does this have `Alias` or `ConstKind::Unevaluated`? /// /// Rephrased, could this term be normalized further? - const HAS_ALIASES = TypeFlags::HAS_TY_PROJECTION.bits() + const HAS_ALIAS = TypeFlags::HAS_TY_PROJECTION.bits() | TypeFlags::HAS_TY_WEAK.bits() | TypeFlags::HAS_TY_OPAQUE.bits() | TypeFlags::HAS_TY_INHERENT.bits() diff --git a/compiler/rustc_type_ir/src/visit.rs b/compiler/rustc_type_ir/src/visit.rs index 473a0aa250ffc..25eb56fe3fb51 100644 --- a/compiler/rustc_type_ir/src/visit.rs +++ b/compiler/rustc_type_ir/src/visit.rs @@ -230,7 +230,7 @@ pub trait TypeVisitableExt: TypeVisitable { } fn has_aliases(&self) -> bool { - self.has_type_flags(TypeFlags::HAS_ALIASES) + self.has_type_flags(TypeFlags::HAS_ALIAS) } fn has_inherent_projections(&self) -> bool { From 07e6dd95bd84bd506a0a04f2054ff82c681be928 Mon Sep 17 00:00:00 2001 From: yukang Date: Thu, 11 Jul 2024 00:07:07 +0800 Subject: [PATCH 880/892] report pat no field error no recoverd struct variant --- compiler/rustc_hir_analysis/src/collect.rs | 5 +- compiler/rustc_hir_typeck/src/expr.rs | 11 ++-- compiler/rustc_hir_typeck/src/pat.rs | 7 ++- compiler/rustc_metadata/src/rmeta/decoder.rs | 2 +- compiler/rustc_middle/src/ty/mod.rs | 57 ++++++++++++------- .../struct-parser-recovery-issue-126344.rs | 42 ++++++++++++++ ...struct-parser-recovery-issue-126344.stderr | 18 ++++++ tests/ui/thir-print/thir-tree-match.stdout | 8 +-- .../struct-index-err-ice-issue-126744.rs} | 3 +- .../struct-index-err-ice-issue-126744.stderr | 10 ++++ 10 files changed, 131 insertions(+), 32 deletions(-) create mode 100644 tests/ui/pattern/struct-parser-recovery-issue-126344.rs create mode 100644 tests/ui/pattern/struct-parser-recovery-issue-126344.stderr rename tests/{crashes/126744.rs => ui/typeck/struct-index-err-ice-issue-126744.rs} (56%) create mode 100644 tests/ui/typeck/struct-index-err-ice-issue-126744.stderr diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index 843e4d41e001e..b95ea60e49dbc 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -1091,7 +1091,10 @@ fn lower_variant( vis: tcx.visibility(f.def_id), }) .collect(); - let recovered = matches!(def, hir::VariantData::Struct { recovered: Recovered::Yes(_), .. }); + let recovered = match def { + hir::VariantData::Struct { recovered: Recovered::Yes(guar), .. } => Some(*guar), + _ => None, + }; ty::VariantDef::new( ident.name, variant_did.map(LocalDefId::to_def_id), diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index bd5e5294983d2..0a1294964d0c3 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -2177,10 +2177,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { skip_fields: &[hir::ExprField<'_>], kind_name: &str, ) -> ErrorGuaranteed { - if variant.is_recovered() { - let guar = - self.dcx().span_delayed_bug(expr.span, "parser recovered but no error was emitted"); - self.set_tainted_by_errors(guar); + // we don't care to report errors for a struct if the struct itself is tainted + if let Err(guar) = variant.has_errors() { return guar; } let mut err = self.err_ctxt().type_error_struct_with_diag( @@ -2345,6 +2343,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let mut last_ty = None; let mut nested_fields = Vec::new(); let mut index = None; + + // we don't care to report errors for a struct if the struct itself is tainted + if let Err(guar) = adt_def.non_enum_variant().has_errors() { + return Ty::new_error(self.tcx(), guar); + } while let Some(idx) = self.tcx.find_field((adt_def.did(), ident)) { let &mut first_idx = index.get_or_insert(idx); let field = &adt_def.non_enum_variant().fields[idx]; diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index be526e1c26c4c..6d1e9ff1f9527 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -1531,9 +1531,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .filter(|(_, ident)| !used_fields.contains_key(ident)) .collect::>(); - let inexistent_fields_err = if !(inexistent_fields.is_empty() || variant.is_recovered()) + let inexistent_fields_err = if !inexistent_fields.is_empty() && !inexistent_fields.iter().any(|field| field.ident.name == kw::Underscore) { + // we don't care to report errors for a struct if the struct itself is tainted + variant.has_errors()?; Some(self.error_inexistent_fields( adt.variant_descr(), &inexistent_fields, @@ -1812,6 +1814,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return Ok(()); } + // we don't care to report errors for a struct if the struct itself is tainted + variant.has_errors()?; + let path = rustc_hir_pretty::qpath_to_string(&self.tcx, qpath); let mut err = struct_span_code_err!( self.dcx(), diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index 83b41e0540edf..0ba9b940eed10 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -1133,7 +1133,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { .collect(), adt_kind, parent_did, - false, + None, data.is_non_exhaustive, // FIXME: unnamed fields in crate metadata is unimplemented yet. false, diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 4470db47474cb..48d4d702513d2 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -1159,11 +1159,8 @@ bitflags::bitflags! { const NO_VARIANT_FLAGS = 0; /// Indicates whether the field list of this variant is `#[non_exhaustive]`. const IS_FIELD_LIST_NON_EXHAUSTIVE = 1 << 0; - /// Indicates whether this variant was obtained as part of recovering from - /// a syntactic error. May be incomplete or bogus. - const IS_RECOVERED = 1 << 1; /// Indicates whether this variant has unnamed fields. - const HAS_UNNAMED_FIELDS = 1 << 2; + const HAS_UNNAMED_FIELDS = 1 << 1; } } rustc_data_structures::external_bitflags_debug! { VariantFlags } @@ -1183,6 +1180,8 @@ pub struct VariantDef { pub discr: VariantDiscr, /// Fields of this variant. pub fields: IndexVec, + /// The error guarantees from parser, if any. + tainted: Option, /// Flags of the variant (e.g. is field list non-exhaustive)? flags: VariantFlags, } @@ -1212,7 +1211,7 @@ impl VariantDef { fields: IndexVec, adt_kind: AdtKind, parent_did: DefId, - recovered: bool, + recover_tainted: Option, is_field_list_non_exhaustive: bool, has_unnamed_fields: bool, ) -> Self { @@ -1227,15 +1226,19 @@ impl VariantDef { flags |= VariantFlags::IS_FIELD_LIST_NON_EXHAUSTIVE; } - if recovered { - flags |= VariantFlags::IS_RECOVERED; - } - if has_unnamed_fields { flags |= VariantFlags::HAS_UNNAMED_FIELDS; } - VariantDef { def_id: variant_did.unwrap_or(parent_did), ctor, name, discr, fields, flags } + VariantDef { + def_id: variant_did.unwrap_or(parent_did), + ctor, + name, + discr, + fields, + flags, + tainted: recover_tainted, + } } /// Is this field list non-exhaustive? @@ -1244,12 +1247,6 @@ impl VariantDef { self.flags.intersects(VariantFlags::IS_FIELD_LIST_NON_EXHAUSTIVE) } - /// Was this variant obtained as part of recovering from a syntactic error? - #[inline] - pub fn is_recovered(&self) -> bool { - self.flags.intersects(VariantFlags::IS_RECOVERED) - } - /// Does this variant contains unnamed fields #[inline] pub fn has_unnamed_fields(&self) -> bool { @@ -1261,6 +1258,12 @@ impl VariantDef { Ident::new(self.name, tcx.def_ident_span(self.def_id).unwrap()) } + /// Was this variant obtained as part of recovering from a syntactic error? + #[inline] + pub fn has_errors(&self) -> Result<(), ErrorGuaranteed> { + self.tainted.map_or(Ok(()), Err) + } + #[inline] pub fn ctor_kind(&self) -> Option { self.ctor.map(|(kind, _)| kind) @@ -1308,8 +1311,24 @@ impl PartialEq for VariantDef { // definition of `VariantDef` changes, a compile-error will be produced, // reminding us to revisit this assumption. - let Self { def_id: lhs_def_id, ctor: _, name: _, discr: _, fields: _, flags: _ } = &self; - let Self { def_id: rhs_def_id, ctor: _, name: _, discr: _, fields: _, flags: _ } = other; + let Self { + def_id: lhs_def_id, + ctor: _, + name: _, + discr: _, + fields: _, + flags: _, + tainted: _, + } = &self; + let Self { + def_id: rhs_def_id, + ctor: _, + name: _, + discr: _, + fields: _, + flags: _, + tainted: _, + } = other; let res = lhs_def_id == rhs_def_id; @@ -1339,7 +1358,7 @@ impl Hash for VariantDef { // of `VariantDef` changes, a compile-error will be produced, reminding // us to revisit this assumption. - let Self { def_id, ctor: _, name: _, discr: _, fields: _, flags: _ } = &self; + let Self { def_id, ctor: _, name: _, discr: _, fields: _, flags: _, tainted: _ } = &self; def_id.hash(s) } } diff --git a/tests/ui/pattern/struct-parser-recovery-issue-126344.rs b/tests/ui/pattern/struct-parser-recovery-issue-126344.rs new file mode 100644 index 0000000000000..1e3ce3e025e87 --- /dev/null +++ b/tests/ui/pattern/struct-parser-recovery-issue-126344.rs @@ -0,0 +1,42 @@ +struct Wrong { + x: i32; //~ ERROR struct fields are separated by `,` + y: i32, + z: i32, + h: i32, +} + +fn oops(w: &Wrong) { + w.x; +} + +fn foo(w: &Wrong) { + w.y; +} + +fn haha(w: &Wrong) { + w.z; +} + +struct WrongWithType { + x: 1, //~ ERROR expected type, found `1` + y: i32, + z: i32, + h: i32, +} + +fn oops_type(w: &WrongWithType) { + w.x; +} + +fn foo_type(w: &WrongWithType) { + w.y; +} + +fn haha_type(w: &WrongWithType) { + w.z; +} + +fn main() { + let v = Wrong { x: 1, y: 2, z: 3, h: 4 }; + let x = WrongWithType { x: 1, y: 2, z: 3, h: 4 }; +} diff --git a/tests/ui/pattern/struct-parser-recovery-issue-126344.stderr b/tests/ui/pattern/struct-parser-recovery-issue-126344.stderr new file mode 100644 index 0000000000000..ef7f9c566db37 --- /dev/null +++ b/tests/ui/pattern/struct-parser-recovery-issue-126344.stderr @@ -0,0 +1,18 @@ +error: struct fields are separated by `,` + --> $DIR/struct-parser-recovery-issue-126344.rs:2:11 + | +LL | struct Wrong { + | ----- while parsing this struct +LL | x: i32; + | ^ help: replace `;` with `,` + +error: expected type, found `1` + --> $DIR/struct-parser-recovery-issue-126344.rs:21:8 + | +LL | struct WrongWithType { + | ------------- while parsing this struct +LL | x: 1, + | ^ expected type + +error: aborting due to 2 previous errors + diff --git a/tests/ui/thir-print/thir-tree-match.stdout b/tests/ui/thir-print/thir-tree-match.stdout index 31c46716a006d..b2431698cc645 100644 --- a/tests/ui/thir-print/thir-tree-match.stdout +++ b/tests/ui/thir-print/thir-tree-match.stdout @@ -92,7 +92,7 @@ body: adt_def: AdtDef { did: DefId(0:10 ~ thir_tree_match[fcf8]::Foo) - variants: [VariantDef { def_id: DefId(0:11 ~ thir_tree_match[fcf8]::Foo::FooOne), ctor: Some((Fn, DefId(0:12 ~ thir_tree_match[fcf8]::Foo::FooOne::{constructor#0}))), name: "FooOne", discr: Relative(0), fields: [FieldDef { did: DefId(0:13 ~ thir_tree_match[fcf8]::Foo::FooOne::0), name: "0", vis: Restricted(DefId(0:0 ~ thir_tree_match[fcf8])) }], flags: }, VariantDef { def_id: DefId(0:14 ~ thir_tree_match[fcf8]::Foo::FooTwo), ctor: Some((Const, DefId(0:15 ~ thir_tree_match[fcf8]::Foo::FooTwo::{constructor#0}))), name: "FooTwo", discr: Relative(1), fields: [], flags: }] + variants: [VariantDef { def_id: DefId(0:11 ~ thir_tree_match[fcf8]::Foo::FooOne), ctor: Some((Fn, DefId(0:12 ~ thir_tree_match[fcf8]::Foo::FooOne::{constructor#0}))), name: "FooOne", discr: Relative(0), fields: [FieldDef { did: DefId(0:13 ~ thir_tree_match[fcf8]::Foo::FooOne::0), name: "0", vis: Restricted(DefId(0:0 ~ thir_tree_match[fcf8])) }], tainted: None, flags: }, VariantDef { def_id: DefId(0:14 ~ thir_tree_match[fcf8]::Foo::FooTwo), ctor: Some((Const, DefId(0:15 ~ thir_tree_match[fcf8]::Foo::FooTwo::{constructor#0}))), name: "FooTwo", discr: Relative(1), fields: [], tainted: None, flags: }] flags: IS_ENUM repr: ReprOptions { int: None, align: None, pack: None, flags: , field_shuffle_seed: 3477539199540094892 } args: [] @@ -106,7 +106,7 @@ body: adt_def: AdtDef { did: DefId(0:3 ~ thir_tree_match[fcf8]::Bar) - variants: [VariantDef { def_id: DefId(0:4 ~ thir_tree_match[fcf8]::Bar::First), ctor: Some((Const, DefId(0:5 ~ thir_tree_match[fcf8]::Bar::First::{constructor#0}))), name: "First", discr: Relative(0), fields: [], flags: }, VariantDef { def_id: DefId(0:6 ~ thir_tree_match[fcf8]::Bar::Second), ctor: Some((Const, DefId(0:7 ~ thir_tree_match[fcf8]::Bar::Second::{constructor#0}))), name: "Second", discr: Relative(1), fields: [], flags: }, VariantDef { def_id: DefId(0:8 ~ thir_tree_match[fcf8]::Bar::Third), ctor: Some((Const, DefId(0:9 ~ thir_tree_match[fcf8]::Bar::Third::{constructor#0}))), name: "Third", discr: Relative(2), fields: [], flags: }] + variants: [VariantDef { def_id: DefId(0:4 ~ thir_tree_match[fcf8]::Bar::First), ctor: Some((Const, DefId(0:5 ~ thir_tree_match[fcf8]::Bar::First::{constructor#0}))), name: "First", discr: Relative(0), fields: [], tainted: None, flags: }, VariantDef { def_id: DefId(0:6 ~ thir_tree_match[fcf8]::Bar::Second), ctor: Some((Const, DefId(0:7 ~ thir_tree_match[fcf8]::Bar::Second::{constructor#0}))), name: "Second", discr: Relative(1), fields: [], tainted: None, flags: }, VariantDef { def_id: DefId(0:8 ~ thir_tree_match[fcf8]::Bar::Third), ctor: Some((Const, DefId(0:9 ~ thir_tree_match[fcf8]::Bar::Third::{constructor#0}))), name: "Third", discr: Relative(2), fields: [], tainted: None, flags: }] flags: IS_ENUM repr: ReprOptions { int: None, align: None, pack: None, flags: , field_shuffle_seed: 10333377570083945360 } args: [] @@ -154,7 +154,7 @@ body: adt_def: AdtDef { did: DefId(0:10 ~ thir_tree_match[fcf8]::Foo) - variants: [VariantDef { def_id: DefId(0:11 ~ thir_tree_match[fcf8]::Foo::FooOne), ctor: Some((Fn, DefId(0:12 ~ thir_tree_match[fcf8]::Foo::FooOne::{constructor#0}))), name: "FooOne", discr: Relative(0), fields: [FieldDef { did: DefId(0:13 ~ thir_tree_match[fcf8]::Foo::FooOne::0), name: "0", vis: Restricted(DefId(0:0 ~ thir_tree_match[fcf8])) }], flags: }, VariantDef { def_id: DefId(0:14 ~ thir_tree_match[fcf8]::Foo::FooTwo), ctor: Some((Const, DefId(0:15 ~ thir_tree_match[fcf8]::Foo::FooTwo::{constructor#0}))), name: "FooTwo", discr: Relative(1), fields: [], flags: }] + variants: [VariantDef { def_id: DefId(0:11 ~ thir_tree_match[fcf8]::Foo::FooOne), ctor: Some((Fn, DefId(0:12 ~ thir_tree_match[fcf8]::Foo::FooOne::{constructor#0}))), name: "FooOne", discr: Relative(0), fields: [FieldDef { did: DefId(0:13 ~ thir_tree_match[fcf8]::Foo::FooOne::0), name: "0", vis: Restricted(DefId(0:0 ~ thir_tree_match[fcf8])) }], tainted: None, flags: }, VariantDef { def_id: DefId(0:14 ~ thir_tree_match[fcf8]::Foo::FooTwo), ctor: Some((Const, DefId(0:15 ~ thir_tree_match[fcf8]::Foo::FooTwo::{constructor#0}))), name: "FooTwo", discr: Relative(1), fields: [], tainted: None, flags: }] flags: IS_ENUM repr: ReprOptions { int: None, align: None, pack: None, flags: , field_shuffle_seed: 3477539199540094892 } args: [] @@ -206,7 +206,7 @@ body: adt_def: AdtDef { did: DefId(0:10 ~ thir_tree_match[fcf8]::Foo) - variants: [VariantDef { def_id: DefId(0:11 ~ thir_tree_match[fcf8]::Foo::FooOne), ctor: Some((Fn, DefId(0:12 ~ thir_tree_match[fcf8]::Foo::FooOne::{constructor#0}))), name: "FooOne", discr: Relative(0), fields: [FieldDef { did: DefId(0:13 ~ thir_tree_match[fcf8]::Foo::FooOne::0), name: "0", vis: Restricted(DefId(0:0 ~ thir_tree_match[fcf8])) }], flags: }, VariantDef { def_id: DefId(0:14 ~ thir_tree_match[fcf8]::Foo::FooTwo), ctor: Some((Const, DefId(0:15 ~ thir_tree_match[fcf8]::Foo::FooTwo::{constructor#0}))), name: "FooTwo", discr: Relative(1), fields: [], flags: }] + variants: [VariantDef { def_id: DefId(0:11 ~ thir_tree_match[fcf8]::Foo::FooOne), ctor: Some((Fn, DefId(0:12 ~ thir_tree_match[fcf8]::Foo::FooOne::{constructor#0}))), name: "FooOne", discr: Relative(0), fields: [FieldDef { did: DefId(0:13 ~ thir_tree_match[fcf8]::Foo::FooOne::0), name: "0", vis: Restricted(DefId(0:0 ~ thir_tree_match[fcf8])) }], tainted: None, flags: }, VariantDef { def_id: DefId(0:14 ~ thir_tree_match[fcf8]::Foo::FooTwo), ctor: Some((Const, DefId(0:15 ~ thir_tree_match[fcf8]::Foo::FooTwo::{constructor#0}))), name: "FooTwo", discr: Relative(1), fields: [], tainted: None, flags: }] flags: IS_ENUM repr: ReprOptions { int: None, align: None, pack: None, flags: , field_shuffle_seed: 3477539199540094892 } args: [] diff --git a/tests/crashes/126744.rs b/tests/ui/typeck/struct-index-err-ice-issue-126744.rs similarity index 56% rename from tests/crashes/126744.rs rename to tests/ui/typeck/struct-index-err-ice-issue-126744.rs index ed562c86e61b2..00edc4d8e41e7 100644 --- a/tests/crashes/126744.rs +++ b/tests/ui/typeck/struct-index-err-ice-issue-126744.rs @@ -1,5 +1,4 @@ -//@ known-bug: rust-lang/rust#126744 -struct X {,} +struct X {,} //~ ERROR expected identifier, found `,` fn main() { || { diff --git a/tests/ui/typeck/struct-index-err-ice-issue-126744.stderr b/tests/ui/typeck/struct-index-err-ice-issue-126744.stderr new file mode 100644 index 0000000000000..84a3af9ab0057 --- /dev/null +++ b/tests/ui/typeck/struct-index-err-ice-issue-126744.stderr @@ -0,0 +1,10 @@ +error: expected identifier, found `,` + --> $DIR/struct-index-err-ice-issue-126744.rs:1:11 + | +LL | struct X {,} + | - ^ expected identifier + | | + | while parsing this struct + +error: aborting due to 1 previous error + From 9aaa0c5867d7f68ef38dcaeb73b68085b8c4d731 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Fri, 21 Jun 2024 15:15:36 +1000 Subject: [PATCH 881/892] Always use a colon in `//@ normalize-*:` headers --- tests/rustdoc-ui/doctest/block-doc-comment.rs | 2 +- tests/rustdoc-ui/doctest/cfg-test.rs | 2 +- tests/rustdoc-ui/doctest/check-cfg-test.rs | 2 +- tests/rustdoc-ui/doctest/display-output.rs | 2 +- .../doctest/doc-comment-multi-line-attr.rs | 2 +- .../doc-comment-multi-line-cfg-attr.rs | 2 +- .../doctest/doc-test-doctest-feature.rs | 2 +- .../doctest/doc-test-rustdoc-feature.rs | 2 +- .../doctest-multiline-crate-attribute.rs | 2 +- tests/rustdoc-ui/doctest/doctest-output.rs | 2 +- .../doctest/failed-doctest-compile-fail.rs | 2 +- .../failed-doctest-extra-semicolon-on-item.rs | 2 +- .../doctest/failed-doctest-missing-codes.rs | 2 +- .../doctest/failed-doctest-output-windows.rs | 2 +- .../doctest/failed-doctest-output.rs | 2 +- .../doctest/failed-doctest-should-panic.rs | 2 +- tests/rustdoc-ui/doctest/no-run-flag.rs | 2 +- tests/rustdoc-ui/doctest/nocapture-fail.rs | 2 +- tests/rustdoc-ui/doctest/nocapture.rs | 2 +- .../rustdoc-ui/doctest/non-local-defs-impl.rs | 2 +- tests/rustdoc-ui/doctest/non_local_defs.rs | 2 +- tests/rustdoc-ui/doctest/run-directory.rs | 2 +- tests/rustdoc-ui/doctest/test-no_std.rs | 2 +- tests/rustdoc-ui/doctest/test-type.rs | 2 +- .../doctest/unparseable-doc-test.rs | 2 +- tests/rustdoc-ui/ice-bug-report-url.rs | 12 +++++------ tests/rustdoc-ui/issues/issue-80992.rs | 2 +- .../issues/issue-81662-shortness.rs | 2 +- tests/rustdoc-ui/issues/issue-91134.rs | 2 +- ...remap-path-prefix-failed-doctest-output.rs | 4 ++-- .../remap-path-prefix-invalid-doctest.rs | 2 +- ...remap-path-prefix-passed-doctest-output.rs | 2 +- tests/rustdoc-ui/track-diagnostics.rs | 2 +- tests/ui-fulldeps/fluent-messages/test.rs | 2 +- .../ui-fulldeps/missing-rustc-driver-error.rs | 2 +- .../diagnostic-derive-doc-comment-field.rs | 4 ++-- .../session-diagnostic/diagnostic-derive.rs | 4 ++-- tests/ui/abi/debug.rs | 10 +++++----- tests/ui/attributes/dump-preds.rs | 2 +- tests/ui/attributes/dump_def_parents.rs | 2 +- .../generic_const_exprs/issue-80742.rs | 6 +++--- tests/ui/const-ptr/forbidden_slices.rs | 4 ++-- .../const-eval/const-eval-query-stack.rs | 20 +++++++++---------- .../heap/dealloc_intrinsic_dangling.rs | 6 +++--- tests/ui/consts/const-eval/raw-bytes.rs | 2 +- tests/ui/consts/const-eval/ub-enum.rs | 6 +++--- tests/ui/consts/const-eval/ub-nonnull.rs | 4 ++-- tests/ui/consts/const-eval/ub-ref-ptr.rs | 4 ++-- tests/ui/consts/const-eval/ub-uninhabit.rs | 4 ++-- tests/ui/consts/const-eval/ub-wide-ptr.rs | 8 ++++---- .../mut_ref_in_final_dynamic_check.rs | 6 +++--- tests/ui/consts/const_refs_to_static_fail.rs | 4 ++-- .../const_refs_to_static_fail_invalid.rs | 4 ++-- tests/ui/consts/dangling-alloc-id-ice.rs | 6 +++--- .../consts/dangling-zst-ice-issue-126393.rs | 6 +++--- .../miri_unleashed/const_refers_to_static.rs | 4 ++-- .../const_refers_to_static_cross_crate.rs | 4 ++-- .../miri_unleashed/mutable_references.rs | 4 ++-- .../miri_unleashed/mutable_references_err.rs | 4 ++-- tests/ui/consts/offset_ub.rs | 2 +- tests/ui/consts/overflowing-consts.rs | 4 ++-- .../transmute-size-mismatch-before-typeck.rs | 8 ++++---- tests/ui/consts/validate_never_arrays.rs | 4 ++-- tests/ui/coroutine/static-not-unpin.rs | 2 +- .../debuginfo-type-name-layout-ice-94961-1.rs | 4 ++-- .../debuginfo-type-name-layout-ice-94961-2.rs | 4 ++-- tests/ui/duplicate_entry_error.rs | 2 +- tests/ui/error-codes/E0017.rs | 4 ++-- tests/ui/error-codes/E0152.rs | 2 +- .../extern-C-non-FFI-safe-arg-ice-52334.rs | 4 ++-- tests/ui/hygiene/panic-location.rs | 2 +- tests/ui/hygiene/unpretty-debug.rs | 2 +- tests/ui/hygiene/unpretty-debug.stdout | 2 +- .../impl-trait/erased-regions-in-hidden-ty.rs | 2 +- tests/ui/intrinsics/not-overridden.rs | 6 +++--- .../non-ice-error-on-worker-io-fail.rs | 4 ++-- tests/ui/issues/issue-28625.rs | 2 +- tests/ui/issues/issue-32377.rs | 2 +- tests/ui/lang-items/duplicate.rs | 2 +- tests/ui/layout/debug.rs | 2 +- tests/ui/layout/enum-scalar-pair-int-ptr.rs | 6 +++--- tests/ui/layout/enum.rs | 2 +- ...6158-scalarpair-payload-might-be-uninit.rs | 2 +- .../ui/layout/issue-96185-overaligned-enum.rs | 2 +- tests/ui/layout/struct.rs | 2 +- tests/ui/layout/valid_range_oob.rs | 4 ++-- .../ui/layout/zero-sized-array-enum-niche.rs | 2 +- tests/ui/limits/huge-enum.rs | 4 ++-- tests/ui/limits/huge-struct.rs | 4 ++-- tests/ui/limits/issue-17913.rs | 2 +- tests/ui/limits/issue-55878.rs | 4 ++-- tests/ui/lint/lint-overflowing-ops.rs | 4 ++-- tests/ui/mir/lint/storage-live.rs | 8 ++++---- .../msvc-non-utf8-output.rs | 2 +- tests/ui/packed/packed-struct-transmute.rs | 2 +- tests/ui/panic-handler/panic-handler-std.rs | 2 +- tests/ui/panics/default-backtrace-ice.rs | 12 +++++------ tests/ui/proc-macro/load-panic-backtrace.rs | 4 ++-- tests/ui/proc-macro/meta-macro-hygiene.rs | 6 +++--- tests/ui/proc-macro/meta-macro-hygiene.stdout | 6 +++--- .../proc-macro/nonterminal-token-hygiene.rs | 6 +++--- .../nonterminal-token-hygiene.stdout | 6 +++--- tests/ui/process/println-with-broken-pipe.rs | 2 +- tests/ui/repr/repr-c-dead-variants.rs | 2 +- tests/ui/repr/repr-c-int-dead-variants.rs | 2 +- .../multiple_definitions_attribute_merging.rs | 6 +++--- .../ui/resolve/proc_macro_generated_packed.rs | 6 +++--- .../effects/minicore.rs | 4 ++-- tests/ui/statics/mutable_memory_validation.rs | 4 ++-- tests/ui/test-attrs/terse.rs | 2 +- tests/ui/test-attrs/test-filter-multiple.rs | 2 +- .../test-attrs/test-panic-abort-nocapture.rs | 2 +- tests/ui/test-attrs/test-panic-abort.rs | 2 +- tests/ui/test-attrs/test-passed.rs | 2 +- tests/ui/test-attrs/test-thread-capture.rs | 2 +- tests/ui/test-attrs/test-thread-nocapture.rs | 2 +- tests/ui/test-attrs/test-type.rs | 2 +- tests/ui/track-diagnostics/track.rs | 6 +++--- tests/ui/track-diagnostics/track2.rs | 2 +- tests/ui/track-diagnostics/track3.rs | 2 +- tests/ui/track-diagnostics/track4.rs | 2 +- tests/ui/track-diagnostics/track5.rs | 2 +- tests/ui/track-diagnostics/track6.rs | 2 +- .../illegal-upcast-to-impl-opaque.rs | 8 ++++---- .../ui/transmute/transmute-different-sizes.rs | 2 +- tests/ui/transmute/transmute-fat-pointers.rs | 2 +- tests/ui/transmute/transmute-impl.rs | 2 +- tests/ui/treat-err-as-bug/err.rs | 4 ++-- tests/ui/treat-err-as-bug/span_delayed_bug.rs | 4 ++-- tests/ui/type/pattern_types/range_patterns.rs | 2 +- tests/ui/unknown-llvm-arg.rs | 4 ++-- tests/ui/unpretty/avoid-crash.rs | 2 +- 132 files changed, 228 insertions(+), 228 deletions(-) diff --git a/tests/rustdoc-ui/doctest/block-doc-comment.rs b/tests/rustdoc-ui/doctest/block-doc-comment.rs index fdb500a8bdfac..df953dc49bee4 100644 --- a/tests/rustdoc-ui/doctest/block-doc-comment.rs +++ b/tests/rustdoc-ui/doctest/block-doc-comment.rs @@ -1,6 +1,6 @@ //@ check-pass //@ compile-flags:--test -//@ normalize-stdout-test "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" // This test ensures that no code block is detected in the doc comments. diff --git a/tests/rustdoc-ui/doctest/cfg-test.rs b/tests/rustdoc-ui/doctest/cfg-test.rs index 3b01f8bd0d0ac..573172349acbc 100644 --- a/tests/rustdoc-ui/doctest/cfg-test.rs +++ b/tests/rustdoc-ui/doctest/cfg-test.rs @@ -1,7 +1,7 @@ //@ check-pass //@ compile-flags:--test --test-args --test-threads=1 //@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR" -//@ normalize-stdout-test "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" // Crates like core have doctests gated on `cfg(not(test))` so we need to make // sure `cfg(test)` is not active when running `rustdoc --test`. diff --git a/tests/rustdoc-ui/doctest/check-cfg-test.rs b/tests/rustdoc-ui/doctest/check-cfg-test.rs index c96f0c35333f7..b3bff381d64a1 100644 --- a/tests/rustdoc-ui/doctest/check-cfg-test.rs +++ b/tests/rustdoc-ui/doctest/check-cfg-test.rs @@ -2,7 +2,7 @@ //@ compile-flags: --test --nocapture --check-cfg=cfg(feature,values("test")) -Z unstable-options //@ normalize-stderr-test: "tests/rustdoc-ui/doctest" -> "$$DIR" //@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR" -//@ normalize-stdout-test "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" /// The doctest will produce a warning because feature invalid is unexpected /// ``` diff --git a/tests/rustdoc-ui/doctest/display-output.rs b/tests/rustdoc-ui/doctest/display-output.rs index 080d34398a56c..70d15ea6f8a53 100644 --- a/tests/rustdoc-ui/doctest/display-output.rs +++ b/tests/rustdoc-ui/doctest/display-output.rs @@ -4,7 +4,7 @@ //@ edition:2018 //@ compile-flags:--test --test-args=--show-output //@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR" -//@ normalize-stdout-test "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" /// ``` /// #![warn(unused)] diff --git a/tests/rustdoc-ui/doctest/doc-comment-multi-line-attr.rs b/tests/rustdoc-ui/doctest/doc-comment-multi-line-attr.rs index c09796df6f1d5..f95d6f82933a1 100644 --- a/tests/rustdoc-ui/doctest/doc-comment-multi-line-attr.rs +++ b/tests/rustdoc-ui/doctest/doc-comment-multi-line-attr.rs @@ -1,7 +1,7 @@ // Regression test for #97440: Multiline inner attribute triggers ICE during doctest //@ compile-flags:--test //@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR" -//@ normalize-stdout-test "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" //@ check-pass //! ```rust diff --git a/tests/rustdoc-ui/doctest/doc-comment-multi-line-cfg-attr.rs b/tests/rustdoc-ui/doctest/doc-comment-multi-line-cfg-attr.rs index 832f720ef3f6c..8cafadfdc8293 100644 --- a/tests/rustdoc-ui/doctest/doc-comment-multi-line-cfg-attr.rs +++ b/tests/rustdoc-ui/doctest/doc-comment-multi-line-cfg-attr.rs @@ -1,6 +1,6 @@ //@ compile-flags:--test //@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR" -//@ normalize-stdout-test "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" //@ check-pass /// ``` diff --git a/tests/rustdoc-ui/doctest/doc-test-doctest-feature.rs b/tests/rustdoc-ui/doctest/doc-test-doctest-feature.rs index 2bec9414f1d72..fca1f51ed216c 100644 --- a/tests/rustdoc-ui/doctest/doc-test-doctest-feature.rs +++ b/tests/rustdoc-ui/doctest/doc-test-doctest-feature.rs @@ -1,7 +1,7 @@ //@ check-pass //@ compile-flags:--test //@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR" -//@ normalize-stdout-test "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" // Make sure `cfg(doctest)` is set when finding doctests but not inside // the doctests. diff --git a/tests/rustdoc-ui/doctest/doc-test-rustdoc-feature.rs b/tests/rustdoc-ui/doctest/doc-test-rustdoc-feature.rs index 765bbd244a603..6d12d7af56acc 100644 --- a/tests/rustdoc-ui/doctest/doc-test-rustdoc-feature.rs +++ b/tests/rustdoc-ui/doctest/doc-test-rustdoc-feature.rs @@ -1,7 +1,7 @@ //@ check-pass //@ compile-flags:--test //@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR" -//@ normalize-stdout-test "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" #![feature(doc_cfg)] diff --git a/tests/rustdoc-ui/doctest/doctest-multiline-crate-attribute.rs b/tests/rustdoc-ui/doctest/doctest-multiline-crate-attribute.rs index c626c3b626106..b446492e47244 100644 --- a/tests/rustdoc-ui/doctest/doctest-multiline-crate-attribute.rs +++ b/tests/rustdoc-ui/doctest/doctest-multiline-crate-attribute.rs @@ -1,6 +1,6 @@ //@ compile-flags:--test --test-args=--test-threads=1 //@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR" -//@ normalize-stdout-test "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" //@ check-pass /// ``` diff --git a/tests/rustdoc-ui/doctest/doctest-output.rs b/tests/rustdoc-ui/doctest/doctest-output.rs index 0bd032669f8e4..72394a4bed311 100644 --- a/tests/rustdoc-ui/doctest/doctest-output.rs +++ b/tests/rustdoc-ui/doctest/doctest-output.rs @@ -2,7 +2,7 @@ //@ aux-build:extern_macros.rs //@ compile-flags:--test --test-args=--test-threads=1 //@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR" -//@ normalize-stdout-test "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" //@ check-pass //! ``` diff --git a/tests/rustdoc-ui/doctest/failed-doctest-compile-fail.rs b/tests/rustdoc-ui/doctest/failed-doctest-compile-fail.rs index 5e79ee04687a3..4d0e035f86e07 100644 --- a/tests/rustdoc-ui/doctest/failed-doctest-compile-fail.rs +++ b/tests/rustdoc-ui/doctest/failed-doctest-compile-fail.rs @@ -3,7 +3,7 @@ //@ compile-flags:--test //@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR" -//@ normalize-stdout-test "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" //@ failure-status: 101 /// ```compile_fail diff --git a/tests/rustdoc-ui/doctest/failed-doctest-extra-semicolon-on-item.rs b/tests/rustdoc-ui/doctest/failed-doctest-extra-semicolon-on-item.rs index bedb2ac64dba2..b65ef43270588 100644 --- a/tests/rustdoc-ui/doctest/failed-doctest-extra-semicolon-on-item.rs +++ b/tests/rustdoc-ui/doctest/failed-doctest-extra-semicolon-on-item.rs @@ -3,7 +3,7 @@ //@ compile-flags:--test //@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR" -//@ normalize-stdout-test "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" //@ failure-status: 101 /// diff --git a/tests/rustdoc-ui/doctest/failed-doctest-missing-codes.rs b/tests/rustdoc-ui/doctest/failed-doctest-missing-codes.rs index 70db072f72667..766d948614375 100644 --- a/tests/rustdoc-ui/doctest/failed-doctest-missing-codes.rs +++ b/tests/rustdoc-ui/doctest/failed-doctest-missing-codes.rs @@ -3,7 +3,7 @@ //@ compile-flags:--test //@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR" -//@ normalize-stdout-test "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" //@ failure-status: 101 /// ```compile_fail,E0004 diff --git a/tests/rustdoc-ui/doctest/failed-doctest-output-windows.rs b/tests/rustdoc-ui/doctest/failed-doctest-output-windows.rs index 5e1ecf82f5821..cf0d8b9daa1cc 100644 --- a/tests/rustdoc-ui/doctest/failed-doctest-output-windows.rs +++ b/tests/rustdoc-ui/doctest/failed-doctest-output-windows.rs @@ -8,7 +8,7 @@ //@ compile-flags:--test --test-args --test-threads=1 //@ rustc-env:RUST_BACKTRACE=0 //@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR" -//@ normalize-stdout-test "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" //@ failure-status: 101 // doctest fails at runtime diff --git a/tests/rustdoc-ui/doctest/failed-doctest-output.rs b/tests/rustdoc-ui/doctest/failed-doctest-output.rs index d4d49b73793e6..160796065f333 100644 --- a/tests/rustdoc-ui/doctest/failed-doctest-output.rs +++ b/tests/rustdoc-ui/doctest/failed-doctest-output.rs @@ -8,7 +8,7 @@ //@ compile-flags:--test --test-args --test-threads=1 //@ rustc-env:RUST_BACKTRACE=0 //@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR" -//@ normalize-stdout-test "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" //@ failure-status: 101 // doctest fails at runtime diff --git a/tests/rustdoc-ui/doctest/failed-doctest-should-panic.rs b/tests/rustdoc-ui/doctest/failed-doctest-should-panic.rs index 6426fd353a7f7..b24687993e5dc 100644 --- a/tests/rustdoc-ui/doctest/failed-doctest-should-panic.rs +++ b/tests/rustdoc-ui/doctest/failed-doctest-should-panic.rs @@ -3,7 +3,7 @@ //@ compile-flags:--test //@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR" -//@ normalize-stdout-test "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" //@ failure-status: 101 /// ```should_panic diff --git a/tests/rustdoc-ui/doctest/no-run-flag.rs b/tests/rustdoc-ui/doctest/no-run-flag.rs index bdb977b5504d4..0f7a0a175f124 100644 --- a/tests/rustdoc-ui/doctest/no-run-flag.rs +++ b/tests/rustdoc-ui/doctest/no-run-flag.rs @@ -3,7 +3,7 @@ //@ check-pass //@ compile-flags:-Z unstable-options --test --no-run --test-args=--test-threads=1 //@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR" -//@ normalize-stdout-test "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" /// ``` /// let a = true; diff --git a/tests/rustdoc-ui/doctest/nocapture-fail.rs b/tests/rustdoc-ui/doctest/nocapture-fail.rs index 9c225174270c8..db4062e849410 100644 --- a/tests/rustdoc-ui/doctest/nocapture-fail.rs +++ b/tests/rustdoc-ui/doctest/nocapture-fail.rs @@ -2,7 +2,7 @@ //@ compile-flags:--test -Zunstable-options --nocapture //@ normalize-stderr-test: "tests/rustdoc-ui/doctest" -> "$$DIR" //@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR" -//@ normalize-stdout-test "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" /// ```compile_fail /// fn foo() { diff --git a/tests/rustdoc-ui/doctest/nocapture.rs b/tests/rustdoc-ui/doctest/nocapture.rs index 39785286fb172..3b87dad49f953 100644 --- a/tests/rustdoc-ui/doctest/nocapture.rs +++ b/tests/rustdoc-ui/doctest/nocapture.rs @@ -1,7 +1,7 @@ //@ check-pass //@ compile-flags:--test -Zunstable-options --nocapture //@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR" -//@ normalize-stdout-test "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" /// ``` /// println!("hello!"); diff --git a/tests/rustdoc-ui/doctest/non-local-defs-impl.rs b/tests/rustdoc-ui/doctest/non-local-defs-impl.rs index c984e097c0463..37c80bc1f2728 100644 --- a/tests/rustdoc-ui/doctest/non-local-defs-impl.rs +++ b/tests/rustdoc-ui/doctest/non-local-defs-impl.rs @@ -4,7 +4,7 @@ //@ aux-build:pub_trait.rs //@ compile-flags: --test --test-args --test-threads=1 //@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR" -//@ normalize-stdout-test "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" #![doc(test(attr(deny(non_local_definitions))))] #![doc(test(attr(allow(dead_code))))] diff --git a/tests/rustdoc-ui/doctest/non_local_defs.rs b/tests/rustdoc-ui/doctest/non_local_defs.rs index d8cfe5637ae02..83327eb1e3f49 100644 --- a/tests/rustdoc-ui/doctest/non_local_defs.rs +++ b/tests/rustdoc-ui/doctest/non_local_defs.rs @@ -2,7 +2,7 @@ //@ compile-flags:--test --test-args --test-threads=1 --nocapture -Zunstable-options //@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR" //@ normalize-stderr-test: "tests/rustdoc-ui/doctest" -> "$$DIR" -//@ normalize-stdout-test "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" #![doc(test(attr(warn(non_local_definitions))))] diff --git a/tests/rustdoc-ui/doctest/run-directory.rs b/tests/rustdoc-ui/doctest/run-directory.rs index 2fc18470133c7..0e3a30ba46141 100644 --- a/tests/rustdoc-ui/doctest/run-directory.rs +++ b/tests/rustdoc-ui/doctest/run-directory.rs @@ -5,7 +5,7 @@ //@ [correct]compile-flags:--test --test-run-directory={{src-base}} //@ [incorrect]compile-flags:--test --test-run-directory={{src-base}}/coverage //@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR" -//@ normalize-stdout-test "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" /// ``` /// assert_eq!( diff --git a/tests/rustdoc-ui/doctest/test-no_std.rs b/tests/rustdoc-ui/doctest/test-no_std.rs index 897927f41569b..b8af892552dec 100644 --- a/tests/rustdoc-ui/doctest/test-no_std.rs +++ b/tests/rustdoc-ui/doctest/test-no_std.rs @@ -1,6 +1,6 @@ //@ compile-flags:--test //@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR" -//@ normalize-stdout-test "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" //@ check-pass #![no_std] diff --git a/tests/rustdoc-ui/doctest/test-type.rs b/tests/rustdoc-ui/doctest/test-type.rs index d18143368e86a..846a98a853b56 100644 --- a/tests/rustdoc-ui/doctest/test-type.rs +++ b/tests/rustdoc-ui/doctest/test-type.rs @@ -1,7 +1,7 @@ //@ compile-flags: --test --test-args=--test-threads=1 //@ check-pass //@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR" -//@ normalize-stdout-test "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" /// ``` /// let a = true; diff --git a/tests/rustdoc-ui/doctest/unparseable-doc-test.rs b/tests/rustdoc-ui/doctest/unparseable-doc-test.rs index e96e3b9cd3583..43acfa6de3f95 100644 --- a/tests/rustdoc-ui/doctest/unparseable-doc-test.rs +++ b/tests/rustdoc-ui/doctest/unparseable-doc-test.rs @@ -1,6 +1,6 @@ //@ compile-flags: --test //@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR" -//@ normalize-stdout-test "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" //@ failure-status: 101 //@ rustc-env: RUST_BACKTRACE=0 diff --git a/tests/rustdoc-ui/ice-bug-report-url.rs b/tests/rustdoc-ui/ice-bug-report-url.rs index 7c289b7c0cb6d..f270340e07e8f 100644 --- a/tests/rustdoc-ui/ice-bug-report-url.rs +++ b/tests/rustdoc-ui/ice-bug-report-url.rs @@ -4,12 +4,12 @@ //@ error-pattern: aborting due to //@ error-pattern: we would appreciate a bug report: https://github.com/rust-lang/rust/issues/new?labels=C-bug%2C+I-ICE%2C+T-rustdoc&template=ice.md -//@ normalize-stderr-test "note: compiler flags.*\n\n" -> "" -//@ normalize-stderr-test "note: rustc.*running on.*" -> "note: rustc {version} running on {platform}" -//@ normalize-stderr-test "thread.*panicked at compiler.*" -> "" -//@ normalize-stderr-test " +\d{1,}: .*\n" -> "" -//@ normalize-stderr-test " + at .*\n" -> "" -//@ normalize-stderr-test ".*note: Some details are omitted.*\n" -> "" +//@ normalize-stderr-test: "note: compiler flags.*\n\n" -> "" +//@ normalize-stderr-test: "note: rustc.*running on.*" -> "note: rustc {version} running on {platform}" +//@ normalize-stderr-test: "thread.*panicked at compiler.*" -> "" +//@ normalize-stderr-test: " +\d{1,}: .*\n" -> "" +//@ normalize-stderr-test: " + at .*\n" -> "" +//@ normalize-stderr-test: ".*note: Some details are omitted.*\n" -> "" fn wrong() //~^ ERROR expected one of diff --git a/tests/rustdoc-ui/issues/issue-80992.rs b/tests/rustdoc-ui/issues/issue-80992.rs index 4e112fc925136..31cc8b78ecc4a 100644 --- a/tests/rustdoc-ui/issues/issue-80992.rs +++ b/tests/rustdoc-ui/issues/issue-80992.rs @@ -1,7 +1,7 @@ //@ check-pass //@ compile-flags:--test //@ normalize-stdout-test: "tests/rustdoc-ui/issues" -> "$$DIR" -//@ normalize-stdout-test "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" pub fn test() -> Result<(), ()> { //! ```compile_fail diff --git a/tests/rustdoc-ui/issues/issue-81662-shortness.rs b/tests/rustdoc-ui/issues/issue-81662-shortness.rs index 736ca3c5bad2f..02207d2a736d7 100644 --- a/tests/rustdoc-ui/issues/issue-81662-shortness.rs +++ b/tests/rustdoc-ui/issues/issue-81662-shortness.rs @@ -2,7 +2,7 @@ //@ check-stdout //@ error-pattern:cannot find function `foo` in this scope //@ normalize-stdout-test: "tests/rustdoc-ui/issues" -> "$$DIR" -//@ normalize-stdout-test "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" //@ failure-status: 101 /// ```rust diff --git a/tests/rustdoc-ui/issues/issue-91134.rs b/tests/rustdoc-ui/issues/issue-91134.rs index b80d6539ebe9a..6b1fec957eacf 100644 --- a/tests/rustdoc-ui/issues/issue-91134.rs +++ b/tests/rustdoc-ui/issues/issue-91134.rs @@ -2,7 +2,7 @@ //@ aux-build:empty-fn.rs //@ check-pass //@ normalize-stdout-test: "tests/rustdoc-ui/issues" -> "$$DIR" -//@ normalize-stdout-test "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" //@ edition:2021 /// diff --git a/tests/rustdoc-ui/remap-path-prefix-failed-doctest-output.rs b/tests/rustdoc-ui/remap-path-prefix-failed-doctest-output.rs index 2b220370d77aa..57c0c1af031b2 100644 --- a/tests/rustdoc-ui/remap-path-prefix-failed-doctest-output.rs +++ b/tests/rustdoc-ui/remap-path-prefix-failed-doctest-output.rs @@ -4,8 +4,8 @@ //@ failure-status: 101 //@ compile-flags:--test -Z unstable-options --remap-path-prefix={{src-base}}=remapped_path --test-args --test-threads=1 //@ rustc-env:RUST_BACKTRACE=0 -//@ normalize-stdout-test "finished in \d+\.\d+s" -> "finished in $$TIME" -//@ normalize-stdout-test "exit (status|code): 101" -> "exit status: 101" +//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout-test: "exit (status|code): 101" -> "exit status: 101" // doctest fails at runtime /// ``` diff --git a/tests/rustdoc-ui/remap-path-prefix-invalid-doctest.rs b/tests/rustdoc-ui/remap-path-prefix-invalid-doctest.rs index 2e023e32d7a7b..96a79e85f6be5 100644 --- a/tests/rustdoc-ui/remap-path-prefix-invalid-doctest.rs +++ b/tests/rustdoc-ui/remap-path-prefix-invalid-doctest.rs @@ -4,7 +4,7 @@ //@ failure-status: 101 //@ compile-flags:--test -Z unstable-options --remap-path-prefix={{src-base}}=remapped_path --test-args --test-threads=1 //@ rustc-env:RUST_BACKTRACE=0 -//@ normalize-stdout-test "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" // doctest fails to compile /// ``` diff --git a/tests/rustdoc-ui/remap-path-prefix-passed-doctest-output.rs b/tests/rustdoc-ui/remap-path-prefix-passed-doctest-output.rs index c58f3faeb5323..4c61c43578cdf 100644 --- a/tests/rustdoc-ui/remap-path-prefix-passed-doctest-output.rs +++ b/tests/rustdoc-ui/remap-path-prefix-passed-doctest-output.rs @@ -5,7 +5,7 @@ // adapted to use that, and that normalize line can go away //@ compile-flags:--test -Z unstable-options --remap-path-prefix={{src-base}}=remapped_path --test-args --test-threads=1 -//@ normalize-stdout-test "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" // doctest passes at runtime /// ``` diff --git a/tests/rustdoc-ui/track-diagnostics.rs b/tests/rustdoc-ui/track-diagnostics.rs index 75f2517a408a9..403b8c7891745 100644 --- a/tests/rustdoc-ui/track-diagnostics.rs +++ b/tests/rustdoc-ui/track-diagnostics.rs @@ -3,7 +3,7 @@ // Normalize the emitted location so this doesn't need // updating everytime someone adds or removes a line. -//@ normalize-stderr-test ".rs:\d+:\d+" -> ".rs:LL:CC" +//@ normalize-stderr-test: ".rs:\d+:\d+" -> ".rs:LL:CC" struct A; struct B; diff --git a/tests/ui-fulldeps/fluent-messages/test.rs b/tests/ui-fulldeps/fluent-messages/test.rs index 2cd22b99e8377..7bf1252ccf602 100644 --- a/tests/ui-fulldeps/fluent-messages/test.rs +++ b/tests/ui-fulldeps/fluent-messages/test.rs @@ -1,4 +1,4 @@ -//@ normalize-stderr-test "could not open Fluent resource:.*" -> "could not open Fluent resource: os-specific message" +//@ normalize-stderr-test: "could not open Fluent resource:.*" -> "could not open Fluent resource: os-specific message" #![feature(rustc_private)] #![crate_type = "lib"] diff --git a/tests/ui-fulldeps/missing-rustc-driver-error.rs b/tests/ui-fulldeps/missing-rustc-driver-error.rs index adc3e701cc0e4..23ca39363bcd2 100644 --- a/tests/ui-fulldeps/missing-rustc-driver-error.rs +++ b/tests/ui-fulldeps/missing-rustc-driver-error.rs @@ -1,7 +1,7 @@ // Test that we get the following hint when trying to use a compiler crate without rustc_driver. //@ error-pattern: try adding `extern crate rustc_driver;` at the top level of this crate //@ compile-flags: --emit link -//@ normalize-stderr-test ".*crate .* required.*\n\n" -> "" +//@ normalize-stderr-test: ".*crate .* required.*\n\n" -> "" //@ normalize-stderr-test: "aborting due to [0-9]+" -> "aborting due to NUMBER" #![feature(rustc_private)] diff --git a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive-doc-comment-field.rs b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive-doc-comment-field.rs index 432ede89826f9..7921ede23c573 100644 --- a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive-doc-comment-field.rs +++ b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive-doc-comment-field.rs @@ -1,7 +1,7 @@ //@ check-fail // Tests that a doc comment will not preclude a field from being considered a diagnostic argument -//@ normalize-stderr-test "the following other types implement trait `IntoDiagArg`:(?:.*\n){0,9}\s+and \d+ others" -> "normalized in stderr" -//@ normalize-stderr-test "(COMPILER_DIR/.*\.rs):[0-9]+:[0-9]+" -> "$1:LL:CC" +//@ normalize-stderr-test: "the following other types implement trait `IntoDiagArg`:(?:.*\n){0,9}\s+and \d+ others" -> "normalized in stderr" +//@ normalize-stderr-test: "(COMPILER_DIR/.*\.rs):[0-9]+:[0-9]+" -> "$1:LL:CC" // The proc_macro2 crate handles spans differently when on beta/stable release rather than nightly, // changing the output of this test. Since Subdiagnostic is strictly internal to the compiler diff --git a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.rs b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.rs index 4f50837d5fe49..dc268dfc5caf7 100644 --- a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.rs +++ b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.rs @@ -1,7 +1,7 @@ //@ check-fail // Tests error conditions for specifying diagnostics using #[derive(Diagnostic)] -//@ normalize-stderr-test "the following other types implement trait `IntoDiagArg`:(?:.*\n){0,9}\s+and \d+ others" -> "normalized in stderr" -//@ normalize-stderr-test "(COMPILER_DIR/.*\.rs):[0-9]+:[0-9]+" -> "$1:LL:CC" +//@ normalize-stderr-test: "the following other types implement trait `IntoDiagArg`:(?:.*\n){0,9}\s+and \d+ others" -> "normalized in stderr" +//@ normalize-stderr-test: "(COMPILER_DIR/.*\.rs):[0-9]+:[0-9]+" -> "$1:LL:CC" // The proc_macro2 crate handles spans differently when on beta/stable release rather than nightly, // changing the output of this test. Since Diagnostic is strictly internal to the compiler diff --git a/tests/ui/abi/debug.rs b/tests/ui/abi/debug.rs index ceb88d4e9faa8..16d6160273415 100644 --- a/tests/ui/abi/debug.rs +++ b/tests/ui/abi/debug.rs @@ -1,9 +1,9 @@ -//@ normalize-stderr-test "(abi|pref|unadjusted_abi_align): Align\([1-8] bytes\)" -> "$1: $$SOME_ALIGN" -//@ normalize-stderr-test "(size): Size\([48] bytes\)" -> "$1: $$SOME_SIZE" -//@ normalize-stderr-test "(can_unwind): (true|false)" -> "$1: $$SOME_BOOL" -//@ normalize-stderr-test "(valid_range): 0\.\.=(4294967295|18446744073709551615)" -> "$1: $$FULL" +//@ normalize-stderr-test: "(abi|pref|unadjusted_abi_align): Align\([1-8] bytes\)" -> "$1: $$SOME_ALIGN" +//@ normalize-stderr-test: "(size): Size\([48] bytes\)" -> "$1: $$SOME_SIZE" +//@ normalize-stderr-test: "(can_unwind): (true|false)" -> "$1: $$SOME_BOOL" +//@ normalize-stderr-test: "(valid_range): 0\.\.=(4294967295|18446744073709551615)" -> "$1: $$FULL" // This pattern is prepared for when we account for alignment in the niche. -//@ normalize-stderr-test "(valid_range): [1-9]\.\.=(429496729[0-9]|1844674407370955161[0-9])" -> "$1: $$NON_NULL" +//@ normalize-stderr-test: "(valid_range): [1-9]\.\.=(429496729[0-9]|1844674407370955161[0-9])" -> "$1: $$NON_NULL" // Some attributes are only computed for release builds: //@ compile-flags: -O #![feature(rustc_attrs)] diff --git a/tests/ui/attributes/dump-preds.rs b/tests/ui/attributes/dump-preds.rs index 1e15ff2f9bdb3..ca38e23b237cf 100644 --- a/tests/ui/attributes/dump-preds.rs +++ b/tests/ui/attributes/dump-preds.rs @@ -1,4 +1,4 @@ -//@ normalize-stderr-test "DefId\(.+?\)" -> "DefId(..)" +//@ normalize-stderr-test: "DefId\(.+?\)" -> "DefId(..)" #![feature(rustc_attrs)] diff --git a/tests/ui/attributes/dump_def_parents.rs b/tests/ui/attributes/dump_def_parents.rs index af1c210d2cd18..de0c88bb6c39a 100644 --- a/tests/ui/attributes/dump_def_parents.rs +++ b/tests/ui/attributes/dump_def_parents.rs @@ -1,4 +1,4 @@ -//@ normalize-stderr-test "DefId\(.+?\)" -> "DefId(..)" +//@ normalize-stderr-test: "DefId\(.+?\)" -> "DefId(..)" #![feature(rustc_attrs)] fn bar() { diff --git a/tests/ui/const-generics/generic_const_exprs/issue-80742.rs b/tests/ui/const-generics/generic_const_exprs/issue-80742.rs index ddb7b5f852e45..30851b49cdcae 100644 --- a/tests/ui/const-generics/generic_const_exprs/issue-80742.rs +++ b/tests/ui/const-generics/generic_const_exprs/issue-80742.rs @@ -1,9 +1,9 @@ //@ check-fail //@ known-bug: #97477 //@ failure-status: 101 -//@ normalize-stderr-test "note: .*\n\n" -> "" -//@ normalize-stderr-test "thread 'rustc' panicked.*\n" -> "" -//@ normalize-stderr-test "(error: internal compiler error: [^:]+):\d+:\d+: " -> "$1:LL:CC: " +//@ normalize-stderr-test: "note: .*\n\n" -> "" +//@ normalize-stderr-test: "thread 'rustc' panicked.*\n" -> "" +//@ normalize-stderr-test: "(error: internal compiler error: [^:]+):\d+:\d+: " -> "$1:LL:CC: " //@ rustc-env:RUST_BACKTRACE=0 // This test used to cause an ICE in rustc_mir::interpret::step::eval_rvalue_into_place diff --git a/tests/ui/const-ptr/forbidden_slices.rs b/tests/ui/const-ptr/forbidden_slices.rs index 2550a3a01096b..bc4993466eb10 100644 --- a/tests/ui/const-ptr/forbidden_slices.rs +++ b/tests/ui/const-ptr/forbidden_slices.rs @@ -1,6 +1,6 @@ // Strip out raw byte dumps to make comparison platform-independent: -//@ normalize-stderr-test "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" -//@ normalize-stderr-test "([0-9a-f][0-9a-f] |╾─*A(LLOC)?[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> "HEX_DUMP" +//@ normalize-stderr-test: "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" +//@ normalize-stderr-test: "([0-9a-f][0-9a-f] |╾─*A(LLOC)?[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> "HEX_DUMP" #![feature( slice_from_ptr_range, diff --git a/tests/ui/consts/const-eval/const-eval-query-stack.rs b/tests/ui/consts/const-eval/const-eval-query-stack.rs index 53589bfd2ab2b..c015c5e0c4985 100644 --- a/tests/ui/consts/const-eval/const-eval-query-stack.rs +++ b/tests/ui/consts/const-eval/const-eval-query-stack.rs @@ -1,16 +1,16 @@ //@ compile-flags: -Ztreat-err-as-bug=1 //@ failure-status: 101 //@ rustc-env:RUST_BACKTRACE=1 -//@ normalize-stderr-test "\nerror: .*unexpectedly panicked.*\n\n" -> "" -//@ normalize-stderr-test "note: we would appreciate a bug report.*\n\n" -> "" -//@ normalize-stderr-test "note: compiler flags.*\n\n" -> "" -//@ normalize-stderr-test "note: rustc.*running on.*\n\n" -> "" -//@ normalize-stderr-test "thread.*panicked.*:\n.*\n" -> "" -//@ normalize-stderr-test "stack backtrace:\n" -> "" -//@ normalize-stderr-test "\s\d{1,}: .*\n" -> "" -//@ normalize-stderr-test "\s at .*\n" -> "" -//@ normalize-stderr-test ".*note: Some details.*\n" -> "" -//@ normalize-stderr-test ".*omitted \d{1,} frame.*\n" -> "" +//@ normalize-stderr-test: "\nerror: .*unexpectedly panicked.*\n\n" -> "" +//@ normalize-stderr-test: "note: we would appreciate a bug report.*\n\n" -> "" +//@ normalize-stderr-test: "note: compiler flags.*\n\n" -> "" +//@ normalize-stderr-test: "note: rustc.*running on.*\n\n" -> "" +//@ normalize-stderr-test: "thread.*panicked.*:\n.*\n" -> "" +//@ normalize-stderr-test: "stack backtrace:\n" -> "" +//@ normalize-stderr-test: "\s\d{1,}: .*\n" -> "" +//@ normalize-stderr-test: "\s at .*\n" -> "" +//@ normalize-stderr-test: ".*note: Some details.*\n" -> "" +//@ normalize-stderr-test: ".*omitted \d{1,} frame.*\n" -> "" #![allow(unconditional_panic)] const X: i32 = 1 / 0; //~ERROR constant diff --git a/tests/ui/consts/const-eval/heap/dealloc_intrinsic_dangling.rs b/tests/ui/consts/const-eval/heap/dealloc_intrinsic_dangling.rs index 0f70862b5d9cc..da7ab7f8ba43a 100644 --- a/tests/ui/consts/const-eval/heap/dealloc_intrinsic_dangling.rs +++ b/tests/ui/consts/const-eval/heap/dealloc_intrinsic_dangling.rs @@ -3,9 +3,9 @@ #![feature(const_mut_refs)] // Strip out raw byte dumps to make comparison platform-independent: -//@ normalize-stderr-test "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" -//@ normalize-stderr-test "([0-9a-f][0-9a-f] |╾─*A(LLOC)?[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> "HEX_DUMP" -//@ normalize-stderr-test "HEX_DUMP\s*\n\s*HEX_DUMP" -> "HEX_DUMP" +//@ normalize-stderr-test: "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" +//@ normalize-stderr-test: "([0-9a-f][0-9a-f] |╾─*A(LLOC)?[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> "HEX_DUMP" +//@ normalize-stderr-test: "HEX_DUMP\s*\n\s*HEX_DUMP" -> "HEX_DUMP" use std::intrinsics; diff --git a/tests/ui/consts/const-eval/raw-bytes.rs b/tests/ui/consts/const-eval/raw-bytes.rs index 2fbf135c9975c..1c7ef6f2b0f8e 100644 --- a/tests/ui/consts/const-eval/raw-bytes.rs +++ b/tests/ui/consts/const-eval/raw-bytes.rs @@ -1,7 +1,7 @@ //@ stderr-per-bitwidth //@ ignore-endian-big // ignore-tidy-linelength -//@ normalize-stderr-test "╾─*ALLOC[0-9]+(\+[a-z0-9]+)?()?─*╼" -> "╾ALLOC_ID$1╼" +//@ normalize-stderr-test: "╾─*ALLOC[0-9]+(\+[a-z0-9]+)?()?─*╼" -> "╾ALLOC_ID$1╼" #![allow(invalid_value)] #![feature(never_type, rustc_attrs, ptr_metadata, slice_from_ptr_range, const_slice_from_ptr_range)] diff --git a/tests/ui/consts/const-eval/ub-enum.rs b/tests/ui/consts/const-eval/ub-enum.rs index 71d450c014fc1..728c1666deb61 100644 --- a/tests/ui/consts/const-eval/ub-enum.rs +++ b/tests/ui/consts/const-eval/ub-enum.rs @@ -1,7 +1,7 @@ // Strip out raw byte dumps to make comparison platform-independent: -//@ normalize-stderr-test "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" -//@ normalize-stderr-test "([0-9a-f][0-9a-f] |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> "HEX_DUMP" -//@ normalize-stderr-test "0x0+" -> "0x0" +//@ normalize-stderr-test: "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" +//@ normalize-stderr-test: "([0-9a-f][0-9a-f] |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> "HEX_DUMP" +//@ normalize-stderr-test: "0x0+" -> "0x0" #![feature(never_type)] #![allow(invalid_value)] diff --git a/tests/ui/consts/const-eval/ub-nonnull.rs b/tests/ui/consts/const-eval/ub-nonnull.rs index 10d304436f807..47d3ca97fda7b 100644 --- a/tests/ui/consts/const-eval/ub-nonnull.rs +++ b/tests/ui/consts/const-eval/ub-nonnull.rs @@ -1,6 +1,6 @@ // Strip out raw byte dumps to make comparison platform-independent: -//@ normalize-stderr-test "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" -//@ normalize-stderr-test "([0-9a-f][0-9a-f] |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?─*╼ )+ *│.*" -> "HEX_DUMP" +//@ normalize-stderr-test: "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" +//@ normalize-stderr-test: "([0-9a-f][0-9a-f] |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?─*╼ )+ *│.*" -> "HEX_DUMP" #![allow(invalid_value)] // make sure we cannot allow away the errors tested here #![feature(rustc_attrs, ptr_metadata)] diff --git a/tests/ui/consts/const-eval/ub-ref-ptr.rs b/tests/ui/consts/const-eval/ub-ref-ptr.rs index 78dcd1c1f42e6..44b25a6438ea8 100644 --- a/tests/ui/consts/const-eval/ub-ref-ptr.rs +++ b/tests/ui/consts/const-eval/ub-ref-ptr.rs @@ -1,7 +1,7 @@ // ignore-tidy-linelength // Strip out raw byte dumps to make comparison platform-independent: -//@ normalize-stderr-test "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" -//@ normalize-stderr-test "([0-9a-f][0-9a-f] |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> "HEX_DUMP" +//@ normalize-stderr-test: "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" +//@ normalize-stderr-test: "([0-9a-f][0-9a-f] |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> "HEX_DUMP" #![allow(invalid_value)] use std::mem; diff --git a/tests/ui/consts/const-eval/ub-uninhabit.rs b/tests/ui/consts/const-eval/ub-uninhabit.rs index cd29c22262b67..0167de26e9420 100644 --- a/tests/ui/consts/const-eval/ub-uninhabit.rs +++ b/tests/ui/consts/const-eval/ub-uninhabit.rs @@ -1,6 +1,6 @@ // Strip out raw byte dumps to make comparison platform-independent: -//@ normalize-stderr-test "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" -//@ normalize-stderr-test "([0-9a-f][0-9a-f] |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> "HEX_DUMP" +//@ normalize-stderr-test: "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" +//@ normalize-stderr-test: "([0-9a-f][0-9a-f] |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> "HEX_DUMP" #![feature(core_intrinsics)] #![feature(never_type)] diff --git a/tests/ui/consts/const-eval/ub-wide-ptr.rs b/tests/ui/consts/const-eval/ub-wide-ptr.rs index 53207e43fdf8e..d0d93081738fe 100644 --- a/tests/ui/consts/const-eval/ub-wide-ptr.rs +++ b/tests/ui/consts/const-eval/ub-wide-ptr.rs @@ -5,10 +5,10 @@ use std::{ptr, mem}; // Strip out raw byte dumps to make comparison platform-independent: -//@ normalize-stderr-test "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" -//@ normalize-stderr-test "([0-9a-f][0-9a-f] |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> "HEX_DUMP" -//@ normalize-stderr-test "offset \d+" -> "offset N" -//@ normalize-stderr-test "size \d+" -> "size N" +//@ normalize-stderr-test: "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" +//@ normalize-stderr-test: "([0-9a-f][0-9a-f] |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> "HEX_DUMP" +//@ normalize-stderr-test: "offset \d+" -> "offset N" +//@ normalize-stderr-test: "size \d+" -> "size N" /// A newtype wrapper to prevent MIR generation from inserting reborrows that would affect the error diff --git a/tests/ui/consts/const-mut-refs/mut_ref_in_final_dynamic_check.rs b/tests/ui/consts/const-mut-refs/mut_ref_in_final_dynamic_check.rs index b86846af98813..c12c22447b59c 100644 --- a/tests/ui/consts/const-mut-refs/mut_ref_in_final_dynamic_check.rs +++ b/tests/ui/consts/const-mut-refs/mut_ref_in_final_dynamic_check.rs @@ -1,6 +1,6 @@ -//@ normalize-stderr-test "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" -//@ normalize-stderr-test "( 0x[0-9a-f][0-9a-f] │)? ([0-9a-f][0-9a-f] |__ |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> " HEX_DUMP" -//@ normalize-stderr-test "HEX_DUMP\s*\n\s*HEX_DUMP" -> "HEX_DUMP" +//@ normalize-stderr-test: "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" +//@ normalize-stderr-test: "( 0x[0-9a-f][0-9a-f] │)? ([0-9a-f][0-9a-f] |__ |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> " HEX_DUMP" +//@ normalize-stderr-test: "HEX_DUMP\s*\n\s*HEX_DUMP" -> "HEX_DUMP" #![feature(const_mut_refs, const_refs_to_static)] #![feature(raw_ref_op)] diff --git a/tests/ui/consts/const_refs_to_static_fail.rs b/tests/ui/consts/const_refs_to_static_fail.rs index e001c4d6395bf..806aa5f8f6fba 100644 --- a/tests/ui/consts/const_refs_to_static_fail.rs +++ b/tests/ui/consts/const_refs_to_static_fail.rs @@ -1,5 +1,5 @@ -//@ normalize-stderr-test "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" -//@ normalize-stderr-test "([0-9a-f][0-9a-f] |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> "HEX_DUMP" +//@ normalize-stderr-test: "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" +//@ normalize-stderr-test: "([0-9a-f][0-9a-f] |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> "HEX_DUMP" #![feature(const_refs_to_static, const_mut_refs, sync_unsafe_cell)] use std::cell::SyncUnsafeCell; diff --git a/tests/ui/consts/const_refs_to_static_fail_invalid.rs b/tests/ui/consts/const_refs_to_static_fail_invalid.rs index be1574af588a3..c58606d2ebb5f 100644 --- a/tests/ui/consts/const_refs_to_static_fail_invalid.rs +++ b/tests/ui/consts/const_refs_to_static_fail_invalid.rs @@ -1,5 +1,5 @@ -//@ normalize-stderr-test "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" -//@ normalize-stderr-test "([0-9a-f][0-9a-f] |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> "HEX_DUMP" +//@ normalize-stderr-test: "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" +//@ normalize-stderr-test: "([0-9a-f][0-9a-f] |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> "HEX_DUMP" #![feature(const_refs_to_static)] #![allow(static_mut_refs)] diff --git a/tests/ui/consts/dangling-alloc-id-ice.rs b/tests/ui/consts/dangling-alloc-id-ice.rs index 76d6f33baf34b..da95d4d134760 100644 --- a/tests/ui/consts/dangling-alloc-id-ice.rs +++ b/tests/ui/consts/dangling-alloc-id-ice.rs @@ -1,8 +1,8 @@ // https://github.com/rust-lang/rust/issues/55223 // Strip out raw byte dumps to make comparison platform-independent: -//@ normalize-stderr-test "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" -//@ normalize-stderr-test "([0-9a-f][0-9a-f] |╾─*A(LLOC)?[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> "HEX_DUMP" -//@ normalize-stderr-test "HEX_DUMP\s*\n\s*HEX_DUMP" -> "HEX_DUMP" +//@ normalize-stderr-test: "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" +//@ normalize-stderr-test: "([0-9a-f][0-9a-f] |╾─*A(LLOC)?[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> "HEX_DUMP" +//@ normalize-stderr-test: "HEX_DUMP\s*\n\s*HEX_DUMP" -> "HEX_DUMP" union Foo<'a> { y: &'a (), diff --git a/tests/ui/consts/dangling-zst-ice-issue-126393.rs b/tests/ui/consts/dangling-zst-ice-issue-126393.rs index 917aa0572fc0d..b56fcd235c7db 100644 --- a/tests/ui/consts/dangling-zst-ice-issue-126393.rs +++ b/tests/ui/consts/dangling-zst-ice-issue-126393.rs @@ -1,7 +1,7 @@ // Strip out raw byte dumps to make comparison platform-independent: -//@ normalize-stderr-test "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" -//@ normalize-stderr-test "([0-9a-f][0-9a-f] |╾─*A(LLOC)?[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> "HEX_DUMP" -//@ normalize-stderr-test "HEX_DUMP\s*\n\s*HEX_DUMP" -> "HEX_DUMP" +//@ normalize-stderr-test: "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" +//@ normalize-stderr-test: "([0-9a-f][0-9a-f] |╾─*A(LLOC)?[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> "HEX_DUMP" +//@ normalize-stderr-test: "HEX_DUMP\s*\n\s*HEX_DUMP" -> "HEX_DUMP" pub struct Wrapper; pub static MAGIC_FFI_REF: &'static Wrapper = unsafe { diff --git a/tests/ui/consts/miri_unleashed/const_refers_to_static.rs b/tests/ui/consts/miri_unleashed/const_refers_to_static.rs index 31f89030bb345..5625953257335 100644 --- a/tests/ui/consts/miri_unleashed/const_refers_to_static.rs +++ b/tests/ui/consts/miri_unleashed/const_refers_to_static.rs @@ -1,6 +1,6 @@ //@ compile-flags: -Zunleash-the-miri-inside-of-you -//@ normalize-stderr-test "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" -//@ normalize-stderr-test "([0-9a-f][0-9a-f] |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> "HEX_DUMP" +//@ normalize-stderr-test: "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" +//@ normalize-stderr-test: "([0-9a-f][0-9a-f] |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> "HEX_DUMP" use std::sync::atomic::AtomicUsize; use std::sync::atomic::Ordering; diff --git a/tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.rs b/tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.rs index fa3ca6928e35b..a6d75658c7580 100644 --- a/tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.rs +++ b/tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.rs @@ -1,7 +1,7 @@ //@ compile-flags: -Zunleash-the-miri-inside-of-you //@ aux-build:static_cross_crate.rs -//@ normalize-stderr-test "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" -//@ normalize-stderr-test "([0-9a-f][0-9a-f] |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> "HEX_DUMP" +//@ normalize-stderr-test: "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" +//@ normalize-stderr-test: "([0-9a-f][0-9a-f] |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> "HEX_DUMP" #![feature(half_open_range_patterns_in_slices)] #![allow(static_mut_refs)] diff --git a/tests/ui/consts/miri_unleashed/mutable_references.rs b/tests/ui/consts/miri_unleashed/mutable_references.rs index 07f1d70259f0d..efb346f91aefe 100644 --- a/tests/ui/consts/miri_unleashed/mutable_references.rs +++ b/tests/ui/consts/miri_unleashed/mutable_references.rs @@ -1,6 +1,6 @@ //@ compile-flags: -Zunleash-the-miri-inside-of-you -//@ normalize-stderr-test "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" -//@ normalize-stderr-test "([0-9a-f][0-9a-f] |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> "HEX_DUMP" +//@ normalize-stderr-test: "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" +//@ normalize-stderr-test: "([0-9a-f][0-9a-f] |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> "HEX_DUMP" #![deny(const_eval_mutable_ptr_in_final_value)] use std::cell::UnsafeCell; diff --git a/tests/ui/consts/miri_unleashed/mutable_references_err.rs b/tests/ui/consts/miri_unleashed/mutable_references_err.rs index a3da545846e9d..8398b0758dddd 100644 --- a/tests/ui/consts/miri_unleashed/mutable_references_err.rs +++ b/tests/ui/consts/miri_unleashed/mutable_references_err.rs @@ -1,6 +1,6 @@ //@ compile-flags: -Zunleash-the-miri-inside-of-you -//@ normalize-stderr-test "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" -//@ normalize-stderr-test "([0-9a-f][0-9a-f] |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> "HEX_DUMP" +//@ normalize-stderr-test: "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" +//@ normalize-stderr-test: "([0-9a-f][0-9a-f] |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> "HEX_DUMP" #![allow(invalid_reference_casting, static_mut_refs)] #![deny(const_eval_mutable_ptr_in_final_value)] use std::cell::UnsafeCell; diff --git a/tests/ui/consts/offset_ub.rs b/tests/ui/consts/offset_ub.rs index 36e4ff1281a11..ebc7019a75aa8 100644 --- a/tests/ui/consts/offset_ub.rs +++ b/tests/ui/consts/offset_ub.rs @@ -1,7 +1,7 @@ use std::ptr; -//@ normalize-stderr-test "0x7f+" -> "0x7f..f" +//@ normalize-stderr-test: "0x7f+" -> "0x7f..f" pub const BEFORE_START: *const u8 = unsafe { (&0u8 as *const u8).offset(-1) }; //~NOTE diff --git a/tests/ui/consts/overflowing-consts.rs b/tests/ui/consts/overflowing-consts.rs index 52c0623f2c037..68282750dce2e 100644 --- a/tests/ui/consts/overflowing-consts.rs +++ b/tests/ui/consts/overflowing-consts.rs @@ -6,8 +6,8 @@ //@ [opt]compile-flags: -O //@ [opt_with_overflow_checks]compile-flags: -C overflow-checks=on -O //@ ignore-pass (test tests codegen-time behaviour) -//@ normalize-stderr-test "shift left by `(64|32)_usize`, which" -> "shift left by `%BITS%`, which" -//@ normalize-stderr-test "shift right by `(64|32)_usize`, which" -> "shift right by `%BITS%`, which" +//@ normalize-stderr-test: "shift left by `(64|32)_usize`, which" -> "shift left by `%BITS%`, which" +//@ normalize-stderr-test: "shift right by `(64|32)_usize`, which" -> "shift right by `%BITS%`, which" #[cfg(target_pointer_width = "32")] diff --git a/tests/ui/consts/transmute-size-mismatch-before-typeck.rs b/tests/ui/consts/transmute-size-mismatch-before-typeck.rs index 2ddce483564f7..44eac5b16cc0b 100644 --- a/tests/ui/consts/transmute-size-mismatch-before-typeck.rs +++ b/tests/ui/consts/transmute-size-mismatch-before-typeck.rs @@ -1,7 +1,7 @@ -//@ normalize-stderr-64bit "64 bits" -> "word size" -//@ normalize-stderr-32bit "32 bits" -> "word size" -//@ normalize-stderr-64bit "128 bits" -> "2 * word size" -//@ normalize-stderr-32bit "64 bits" -> "2 * word size" +//@ normalize-stderr-64bit: "64 bits" -> "word size" +//@ normalize-stderr-32bit: "32 bits" -> "word size" +//@ normalize-stderr-64bit: "128 bits" -> "2 * word size" +//@ normalize-stderr-32bit: "64 bits" -> "2 * word size" fn main() { match &b""[..] { diff --git a/tests/ui/consts/validate_never_arrays.rs b/tests/ui/consts/validate_never_arrays.rs index aa5dbdf823357..7585a78a0d353 100644 --- a/tests/ui/consts/validate_never_arrays.rs +++ b/tests/ui/consts/validate_never_arrays.rs @@ -1,6 +1,6 @@ // Strip out raw byte dumps to make comparison platform-independent: -//@ normalize-stderr-test "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" -//@ normalize-stderr-test "([0-9a-f][0-9a-f] |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> "HEX_DUMP" +//@ normalize-stderr-test: "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" +//@ normalize-stderr-test: "([0-9a-f][0-9a-f] |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> "HEX_DUMP" #![feature(never_type)] const _: &[!; 1] = unsafe { &*(1_usize as *const [!; 1]) }; //~ ERROR undefined behavior diff --git a/tests/ui/coroutine/static-not-unpin.rs b/tests/ui/coroutine/static-not-unpin.rs index 2bc25e3796d45..54148368b1392 100644 --- a/tests/ui/coroutine/static-not-unpin.rs +++ b/tests/ui/coroutine/static-not-unpin.rs @@ -4,7 +4,7 @@ #![feature(coroutines, stmt_expr_attributes)] -//@ normalize-stderr-test "std::pin::Unpin" -> "std::marker::Unpin" +//@ normalize-stderr-test: "std::pin::Unpin" -> "std::marker::Unpin" use std::marker::Unpin; diff --git a/tests/ui/debuginfo/debuginfo-type-name-layout-ice-94961-1.rs b/tests/ui/debuginfo/debuginfo-type-name-layout-ice-94961-1.rs index 6d70764b9f761..dc68f6cf71f11 100644 --- a/tests/ui/debuginfo/debuginfo-type-name-layout-ice-94961-1.rs +++ b/tests/ui/debuginfo/debuginfo-type-name-layout-ice-94961-1.rs @@ -4,8 +4,8 @@ //@ compile-flags:-C debuginfo=2 //@ build-fail //@ error-pattern: too big for the current architecture -//@ normalize-stderr-64bit "18446744073709551615" -> "SIZE" -//@ normalize-stderr-32bit "4294967295" -> "SIZE" +//@ normalize-stderr-64bit: "18446744073709551615" -> "SIZE" +//@ normalize-stderr-32bit: "4294967295" -> "SIZE" #![crate_type = "rlib"] diff --git a/tests/ui/debuginfo/debuginfo-type-name-layout-ice-94961-2.rs b/tests/ui/debuginfo/debuginfo-type-name-layout-ice-94961-2.rs index a84dec10abd17..2b6e85362b68c 100644 --- a/tests/ui/debuginfo/debuginfo-type-name-layout-ice-94961-2.rs +++ b/tests/ui/debuginfo/debuginfo-type-name-layout-ice-94961-2.rs @@ -6,8 +6,8 @@ //@ compile-flags:-C debuginfo=2 //@ build-fail //@ error-pattern: too big for the current architecture -//@ normalize-stderr-64bit "18446744073709551615" -> "SIZE" -//@ normalize-stderr-32bit "4294967295" -> "SIZE" +//@ normalize-stderr-64bit: "18446744073709551615" -> "SIZE" +//@ normalize-stderr-32bit: "4294967295" -> "SIZE" #![crate_type = "rlib"] diff --git a/tests/ui/duplicate_entry_error.rs b/tests/ui/duplicate_entry_error.rs index 8e49f57a3df94..e8b905a65f60d 100644 --- a/tests/ui/duplicate_entry_error.rs +++ b/tests/ui/duplicate_entry_error.rs @@ -1,4 +1,4 @@ -//@ normalize-stderr-test "loaded from .*libstd-.*.rlib" -> "loaded from SYSROOT/libstd-*.rlib" +//@ normalize-stderr-test: "loaded from .*libstd-.*.rlib" -> "loaded from SYSROOT/libstd-*.rlib" // note-pattern: first defined in crate `std`. // Test for issue #31788 and E0152 diff --git a/tests/ui/error-codes/E0017.rs b/tests/ui/error-codes/E0017.rs index 6ba5f9c9a2b71..c046f7859fa09 100644 --- a/tests/ui/error-codes/E0017.rs +++ b/tests/ui/error-codes/E0017.rs @@ -1,7 +1,7 @@ #![feature(const_mut_refs)] -//@ normalize-stderr-test "\(size: ., align: .\)" -> "" -//@ normalize-stderr-test " +│ ╾─+╼" -> "" +//@ normalize-stderr-test: "\(size: ., align: .\)" -> "" +//@ normalize-stderr-test: " +│ ╾─+╼" -> "" static X: i32 = 1; const C: i32 = 2; diff --git a/tests/ui/error-codes/E0152.rs b/tests/ui/error-codes/E0152.rs index d56d4e710a405..44d462c27e68f 100644 --- a/tests/ui/error-codes/E0152.rs +++ b/tests/ui/error-codes/E0152.rs @@ -1,4 +1,4 @@ -//@ normalize-stderr-test "loaded from .*liballoc-.*.rlib" -> "loaded from SYSROOT/liballoc-*.rlib" +//@ normalize-stderr-test: "loaded from .*liballoc-.*.rlib" -> "loaded from SYSROOT/liballoc-*.rlib" #![feature(lang_items)] #[lang = "owned_box"] diff --git a/tests/ui/extern/extern-C-non-FFI-safe-arg-ice-52334.rs b/tests/ui/extern/extern-C-non-FFI-safe-arg-ice-52334.rs index bba7190d43da2..bf060b3d16834 100644 --- a/tests/ui/extern/extern-C-non-FFI-safe-arg-ice-52334.rs +++ b/tests/ui/extern/extern-C-non-FFI-safe-arg-ice-52334.rs @@ -1,8 +1,8 @@ // test for ICE when casting extern "C" fn when it has a non-FFI-safe argument // issue: rust-lang/rust#52334 //@ check-pass -//@ normalize-stderr-test "\[i8\]" -> "[i8 or u8 (arch dependant)]" -//@ normalize-stderr-test "\[u8\]" -> "[i8 or u8 (arch dependant)]" +//@ normalize-stderr-test: "\[i8\]" -> "[i8 or u8 (arch dependant)]" +//@ normalize-stderr-test: "\[u8\]" -> "[i8 or u8 (arch dependant)]" type Foo = extern "C" fn(::std::ffi::CStr); //~^ WARN `extern` fn uses type diff --git a/tests/ui/hygiene/panic-location.rs b/tests/ui/hygiene/panic-location.rs index b2f9bfe4f9a7a..7b20f1683a976 100644 --- a/tests/ui/hygiene/panic-location.rs +++ b/tests/ui/hygiene/panic-location.rs @@ -1,7 +1,7 @@ //@ run-fail //@ check-run-results //@ exec-env:RUST_BACKTRACE=0 -//@ normalize-stderr-test ".rs:\d+:\d+" -> ".rs:LL:CC" +//@ normalize-stderr-test: ".rs:\d+:\d+" -> ".rs:LL:CC" // // Regression test for issue #70963 // The captured stderr from this test reports a location diff --git a/tests/ui/hygiene/unpretty-debug.rs b/tests/ui/hygiene/unpretty-debug.rs index 20c909b1cbee7..8e05d60e2184a 100644 --- a/tests/ui/hygiene/unpretty-debug.rs +++ b/tests/ui/hygiene/unpretty-debug.rs @@ -2,7 +2,7 @@ //@ compile-flags: -Zunpretty=expanded,hygiene // Don't break whenever Symbol numbering changes -//@ normalize-stdout-test "\d+#" -> "0#" +//@ normalize-stdout-test: "\d+#" -> "0#" // minimal junk #![feature(no_core)] diff --git a/tests/ui/hygiene/unpretty-debug.stdout b/tests/ui/hygiene/unpretty-debug.stdout index cab3fe2f29b1f..1f620cef239f1 100644 --- a/tests/ui/hygiene/unpretty-debug.stdout +++ b/tests/ui/hygiene/unpretty-debug.stdout @@ -2,7 +2,7 @@ //@ compile-flags: -Zunpretty=expanded,hygiene // Don't break whenever Symbol numbering changes -//@ normalize-stdout-test "\d+#" -> "0#" +//@ normalize-stdout-test: "\d+#" -> "0#" // minimal junk #![feature /* 0#0 */(no_core)] diff --git a/tests/ui/impl-trait/erased-regions-in-hidden-ty.rs b/tests/ui/impl-trait/erased-regions-in-hidden-ty.rs index e60f1badcae0f..294b27e1dc183 100644 --- a/tests/ui/impl-trait/erased-regions-in-hidden-ty.rs +++ b/tests/ui/impl-trait/erased-regions-in-hidden-ty.rs @@ -2,7 +2,7 @@ //@ ignore-compare-mode-next-solver (explicit revisions) //@ compile-flags: -Zverbose-internals //@[next] compile-flags: -Znext-solver -//@ normalize-stderr-test "DefId\([^\)]+\)" -> "DefId(..)" +//@ normalize-stderr-test: "DefId\([^\)]+\)" -> "DefId(..)" #![feature(rustc_attrs)] #![rustc_hidden_type_of_opaques] diff --git a/tests/ui/intrinsics/not-overridden.rs b/tests/ui/intrinsics/not-overridden.rs index 93b408331b862..e1f1bbe095122 100644 --- a/tests/ui/intrinsics/not-overridden.rs +++ b/tests/ui/intrinsics/not-overridden.rs @@ -3,9 +3,9 @@ #![feature(rustc_attrs)] //@ build-fail //@ failure-status:101 -//@ normalize-stderr-test ".*note: .*\n\n" -> "" -//@ normalize-stderr-test "thread 'rustc' panicked.*:\n.*\n" -> "" -//@ normalize-stderr-test "internal compiler error:.*: intrinsic const_deallocate " -> "" +//@ normalize-stderr-test: ".*note: .*\n\n" -> "" +//@ normalize-stderr-test: "thread 'rustc' panicked.*:\n.*\n" -> "" +//@ normalize-stderr-test: "internal compiler error:.*: intrinsic const_deallocate " -> "" //@ rustc-env:RUST_BACKTRACE=0 #[rustc_intrinsic] diff --git a/tests/ui/io-checks/non-ice-error-on-worker-io-fail.rs b/tests/ui/io-checks/non-ice-error-on-worker-io-fail.rs index fab7ec166e6fa..a6deb8bab29cc 100644 --- a/tests/ui/io-checks/non-ice-error-on-worker-io-fail.rs +++ b/tests/ui/io-checks/non-ice-error-on-worker-io-fail.rs @@ -19,10 +19,10 @@ //@ error-pattern: error // On Mac OS X, we get an error like the below -//@ normalize-stderr-test "failed to write bytecode to ./does-not-exist/output.non_ice_error_on_worker_io_fail.*" -> "io error modifying ./does-not-exist/" +//@ normalize-stderr-test: "failed to write bytecode to ./does-not-exist/output.non_ice_error_on_worker_io_fail.*" -> "io error modifying ./does-not-exist/" // On Linux, we get an error like the below -//@ normalize-stderr-test "couldn't create a temp dir.*" -> "io error modifying ./does-not-exist/" +//@ normalize-stderr-test: "couldn't create a temp dir.*" -> "io error modifying ./does-not-exist/" //@ ignore-windows - this is a unix-specific test //@ ignore-emscripten - the file-system issues do not replicate here diff --git a/tests/ui/issues/issue-28625.rs b/tests/ui/issues/issue-28625.rs index 2f25bf8c734ff..23f96d10bf261 100644 --- a/tests/ui/issues/issue-28625.rs +++ b/tests/ui/issues/issue-28625.rs @@ -1,4 +1,4 @@ -//@ normalize-stderr-test "\d+ bits" -> "N bits" +//@ normalize-stderr-test: "\d+ bits" -> "N bits" trait Bar { type Bar; diff --git a/tests/ui/issues/issue-32377.rs b/tests/ui/issues/issue-32377.rs index 6e4a7661a237e..3a4942deb8347 100644 --- a/tests/ui/issues/issue-32377.rs +++ b/tests/ui/issues/issue-32377.rs @@ -1,4 +1,4 @@ -//@ normalize-stderr-test "\d+ bits" -> "N bits" +//@ normalize-stderr-test: "\d+ bits" -> "N bits" use std::mem; use std::marker::PhantomData; diff --git a/tests/ui/lang-items/duplicate.rs b/tests/ui/lang-items/duplicate.rs index 2b68fef87c0a7..3aa7dd2b0bee1 100644 --- a/tests/ui/lang-items/duplicate.rs +++ b/tests/ui/lang-items/duplicate.rs @@ -1,4 +1,4 @@ -//@ normalize-stderr-test "loaded from .*libcore-.*.rlib" -> "loaded from SYSROOT/libcore-*.rlib" +//@ normalize-stderr-test: "loaded from .*libcore-.*.rlib" -> "loaded from SYSROOT/libcore-*.rlib" #![feature(lang_items)] #[lang = "sized"] diff --git a/tests/ui/layout/debug.rs b/tests/ui/layout/debug.rs index b917cceafd507..aeacbc784462d 100644 --- a/tests/ui/layout/debug.rs +++ b/tests/ui/layout/debug.rs @@ -1,4 +1,4 @@ -//@ normalize-stderr-test "pref: Align\([1-8] bytes\)" -> "pref: $$SOME_ALIGN" +//@ normalize-stderr-test: "pref: Align\([1-8] bytes\)" -> "pref: $$SOME_ALIGN" #![feature(never_type, rustc_attrs, type_alias_impl_trait, repr_simd)] #![crate_type = "lib"] diff --git a/tests/ui/layout/enum-scalar-pair-int-ptr.rs b/tests/ui/layout/enum-scalar-pair-int-ptr.rs index a1aec094d8025..885cc3e37dfd6 100644 --- a/tests/ui/layout/enum-scalar-pair-int-ptr.rs +++ b/tests/ui/layout/enum-scalar-pair-int-ptr.rs @@ -1,6 +1,6 @@ -//@ normalize-stderr-test "pref: Align\([1-8] bytes\)" -> "pref: $$PREF_ALIGN" -//@ normalize-stderr-test "Int\(I[0-9]+," -> "Int(I?," -//@ normalize-stderr-test "valid_range: 0..=[0-9]+" -> "valid_range: $$VALID_RANGE" +//@ normalize-stderr-test: "pref: Align\([1-8] bytes\)" -> "pref: $$PREF_ALIGN" +//@ normalize-stderr-test: "Int\(I[0-9]+," -> "Int(I?," +//@ normalize-stderr-test: "valid_range: 0..=[0-9]+" -> "valid_range: $$VALID_RANGE" //! Enum layout tests related to scalar pairs with an int/ptr common primitive. diff --git a/tests/ui/layout/enum.rs b/tests/ui/layout/enum.rs index e0a7fc328df30..b58d390a2eff6 100644 --- a/tests/ui/layout/enum.rs +++ b/tests/ui/layout/enum.rs @@ -1,4 +1,4 @@ -//@ normalize-stderr-test "pref: Align\([1-8] bytes\)" -> "pref: $$PREF_ALIGN" +//@ normalize-stderr-test: "pref: Align\([1-8] bytes\)" -> "pref: $$PREF_ALIGN" //! Various enum layout tests. #![feature(rustc_attrs)] diff --git a/tests/ui/layout/issue-96158-scalarpair-payload-might-be-uninit.rs b/tests/ui/layout/issue-96158-scalarpair-payload-might-be-uninit.rs index 3acacc4559c1b..2c8179a63d807 100644 --- a/tests/ui/layout/issue-96158-scalarpair-payload-might-be-uninit.rs +++ b/tests/ui/layout/issue-96158-scalarpair-payload-might-be-uninit.rs @@ -1,4 +1,4 @@ -//@ normalize-stderr-test "pref: Align\([1-8] bytes\)" -> "pref: $$PREF_ALIGN" +//@ normalize-stderr-test: "pref: Align\([1-8] bytes\)" -> "pref: $$PREF_ALIGN" #![crate_type = "lib"] #![feature(rustc_attrs)] diff --git a/tests/ui/layout/issue-96185-overaligned-enum.rs b/tests/ui/layout/issue-96185-overaligned-enum.rs index 3889a423906ea..88863d14cb7fe 100644 --- a/tests/ui/layout/issue-96185-overaligned-enum.rs +++ b/tests/ui/layout/issue-96185-overaligned-enum.rs @@ -1,4 +1,4 @@ -//@ normalize-stderr-test "pref: Align\([1-8] bytes\)" -> "pref: $$PREF_ALIGN" +//@ normalize-stderr-test: "pref: Align\([1-8] bytes\)" -> "pref: $$PREF_ALIGN" #![crate_type = "lib"] #![feature(rustc_attrs)] diff --git a/tests/ui/layout/struct.rs b/tests/ui/layout/struct.rs index 484490a5f780c..d072d123b0d4a 100644 --- a/tests/ui/layout/struct.rs +++ b/tests/ui/layout/struct.rs @@ -1,4 +1,4 @@ -//@ normalize-stderr-test "pref: Align\([1-8] bytes\)" -> "pref: $$PREF_ALIGN" +//@ normalize-stderr-test: "pref: Align\([1-8] bytes\)" -> "pref: $$PREF_ALIGN" //! Various struct layout tests. #![feature(rustc_attrs)] diff --git a/tests/ui/layout/valid_range_oob.rs b/tests/ui/layout/valid_range_oob.rs index 12f519ff2ca58..38ab5cec7a668 100644 --- a/tests/ui/layout/valid_range_oob.rs +++ b/tests/ui/layout/valid_range_oob.rs @@ -1,6 +1,6 @@ //@ failure-status: 101 -//@ normalize-stderr-test "note: .*\n\n" -> "" -//@ normalize-stderr-test "thread 'rustc' panicked.*\n" -> "" +//@ normalize-stderr-test: "note: .*\n\n" -> "" +//@ normalize-stderr-test: "thread 'rustc' panicked.*\n" -> "" //@ rustc-env:RUST_BACKTRACE=0 #![feature(rustc_attrs)] diff --git a/tests/ui/layout/zero-sized-array-enum-niche.rs b/tests/ui/layout/zero-sized-array-enum-niche.rs index 0c37c0f010e2b..433db46b7a002 100644 --- a/tests/ui/layout/zero-sized-array-enum-niche.rs +++ b/tests/ui/layout/zero-sized-array-enum-niche.rs @@ -1,4 +1,4 @@ -//@ normalize-stderr-test "pref: Align\([1-8] bytes\)" -> "pref: $$PREF_ALIGN" +//@ normalize-stderr-test: "pref: Align\([1-8] bytes\)" -> "pref: $$PREF_ALIGN" #![crate_type = "lib"] #![feature(rustc_attrs)] diff --git a/tests/ui/limits/huge-enum.rs b/tests/ui/limits/huge-enum.rs index a6e6c5b73beea..cf6e637388c7f 100644 --- a/tests/ui/limits/huge-enum.rs +++ b/tests/ui/limits/huge-enum.rs @@ -1,6 +1,6 @@ //@ build-fail -//@ normalize-stderr-test "std::option::Option<\[u32; \d+\]>" -> "TYPE" -//@ normalize-stderr-test "\[u32; \d+\]" -> "TYPE" +//@ normalize-stderr-test: "std::option::Option<\[u32; \d+\]>" -> "TYPE" +//@ normalize-stderr-test: "\[u32; \d+\]" -> "TYPE" #[cfg(target_pointer_width = "32")] type BIG = Option<[u32; (1<<29)-1]>; diff --git a/tests/ui/limits/huge-struct.rs b/tests/ui/limits/huge-struct.rs index c9fd56b3a578a..b9e90b3e9d1ae 100644 --- a/tests/ui/limits/huge-struct.rs +++ b/tests/ui/limits/huge-struct.rs @@ -1,6 +1,6 @@ //@ build-fail -//@ normalize-stderr-test "S32" -> "SXX" -//@ normalize-stderr-test "S1M" -> "SXX" +//@ normalize-stderr-test: "S32" -> "SXX" +//@ normalize-stderr-test: "S1M" -> "SXX" //@ error-pattern: too big for the current struct S32 { diff --git a/tests/ui/limits/issue-17913.rs b/tests/ui/limits/issue-17913.rs index 5df8c48c7ec0c..325923f32f376 100644 --- a/tests/ui/limits/issue-17913.rs +++ b/tests/ui/limits/issue-17913.rs @@ -1,5 +1,5 @@ //@ build-fail -//@ normalize-stderr-test "\[&usize; \d+\]" -> "[&usize; usize::MAX]" +//@ normalize-stderr-test: "\[&usize; \d+\]" -> "[&usize; usize::MAX]" //@ error-pattern: too big for the current architecture #[cfg(target_pointer_width = "64")] diff --git a/tests/ui/limits/issue-55878.rs b/tests/ui/limits/issue-55878.rs index 1372433e11a57..4d91a173240da 100644 --- a/tests/ui/limits/issue-55878.rs +++ b/tests/ui/limits/issue-55878.rs @@ -1,6 +1,6 @@ //@ build-fail -//@ normalize-stderr-64bit "18446744073709551615" -> "SIZE" -//@ normalize-stderr-32bit "4294967295" -> "SIZE" +//@ normalize-stderr-64bit: "18446744073709551615" -> "SIZE" +//@ normalize-stderr-32bit: "4294967295" -> "SIZE" //@ error-pattern: are too big for the current architecture fn main() { diff --git a/tests/ui/lint/lint-overflowing-ops.rs b/tests/ui/lint/lint-overflowing-ops.rs index 3aadf77324377..c5b9f892b0b85 100644 --- a/tests/ui/lint/lint-overflowing-ops.rs +++ b/tests/ui/lint/lint-overflowing-ops.rs @@ -11,8 +11,8 @@ //@ [opt_with_overflow_checks]compile-flags: -C overflow-checks=on -O -Z deduplicate-diagnostics=yes //@ build-fail //@ ignore-pass (test tests codegen-time behaviour) -//@ normalize-stderr-test "shift left by `(64|32)_usize`, which" -> "shift left by `%BITS%`, which" -//@ normalize-stderr-test "shift right by `(64|32)_usize`, which" -> "shift right by `%BITS%`, which" +//@ normalize-stderr-test: "shift left by `(64|32)_usize`, which" -> "shift left by `%BITS%`, which" +//@ normalize-stderr-test: "shift right by `(64|32)_usize`, which" -> "shift right by `%BITS%`, which" #![deny(arithmetic_overflow)] diff --git a/tests/ui/mir/lint/storage-live.rs b/tests/ui/mir/lint/storage-live.rs index d734b773642e9..ded02150342d5 100644 --- a/tests/ui/mir/lint/storage-live.rs +++ b/tests/ui/mir/lint/storage-live.rs @@ -2,10 +2,10 @@ //@ failure-status: 101 //@ error-pattern: broken MIR in //@ error-pattern: StorageLive(_1) which already has storage here -//@ normalize-stderr-test "note: .*\n\n" -> "" -//@ normalize-stderr-test "thread 'rustc' panicked.*\n" -> "" -//@ normalize-stderr-test "storage_live\[....\]" -> "storage_live[HASH]" -//@ normalize-stderr-test "(delayed at [^:]+):\d+:\d+ - " -> "$1:LL:CC - " +//@ normalize-stderr-test: "note: .*\n\n" -> "" +//@ normalize-stderr-test: "thread 'rustc' panicked.*\n" -> "" +//@ normalize-stderr-test: "storage_live\[....\]" -> "storage_live[HASH]" +//@ normalize-stderr-test: "(delayed at [^:]+):\d+:\d+ - " -> "$1:LL:CC - " //@ rustc-env:RUST_BACKTRACE=0 #![feature(custom_mir, core_intrinsics)] diff --git a/tests/ui/native-library-link-flags/msvc-non-utf8-output.rs b/tests/ui/native-library-link-flags/msvc-non-utf8-output.rs index 776e3bf12ad26..659a832247a9b 100644 --- a/tests/ui/native-library-link-flags/msvc-non-utf8-output.rs +++ b/tests/ui/native-library-link-flags/msvc-non-utf8-output.rs @@ -1,5 +1,5 @@ //@ build-fail //@ compile-flags:-C link-arg=⦺ⅈ⽯⭏⽽◃⡽⚞ //@ only-msvc -//@ normalize-stderr-test "(?:.|\n)*(⦺ⅈ⽯⭏⽽◃⡽⚞)(?:.|\n)*" -> "$1" +//@ normalize-stderr-test: "(?:.|\n)*(⦺ⅈ⽯⭏⽽◃⡽⚞)(?:.|\n)*" -> "$1" pub fn main() {} diff --git a/tests/ui/packed/packed-struct-transmute.rs b/tests/ui/packed/packed-struct-transmute.rs index cf7c1f2b7cd55..0a887e3886d59 100644 --- a/tests/ui/packed/packed-struct-transmute.rs +++ b/tests/ui/packed/packed-struct-transmute.rs @@ -3,7 +3,7 @@ // the error points to the start of the file, not the line with the // transmute -//@ normalize-stderr-test "\d+ bits" -> "N bits" +//@ normalize-stderr-test: "\d+ bits" -> "N bits" //@ error-pattern: cannot transmute between types of different sizes, or dependently-sized types use std::mem; diff --git a/tests/ui/panic-handler/panic-handler-std.rs b/tests/ui/panic-handler/panic-handler-std.rs index 051828ec8809f..82e6de43a2ec7 100644 --- a/tests/ui/panic-handler/panic-handler-std.rs +++ b/tests/ui/panic-handler/panic-handler-std.rs @@ -1,4 +1,4 @@ -//@ normalize-stderr-test "loaded from .*libstd-.*.rlib" -> "loaded from SYSROOT/libstd-*.rlib" +//@ normalize-stderr-test: "loaded from .*libstd-.*.rlib" -> "loaded from SYSROOT/libstd-*.rlib" //@ error-pattern: found duplicate lang item `panic_impl` extern crate core; diff --git a/tests/ui/panics/default-backtrace-ice.rs b/tests/ui/panics/default-backtrace-ice.rs index e0e99a0289579..718d1da5bb759 100644 --- a/tests/ui/panics/default-backtrace-ice.rs +++ b/tests/ui/panics/default-backtrace-ice.rs @@ -3,12 +3,12 @@ //@ error-pattern:stack backtrace: //@ failure-status:101 //@ ignore-msvc -//@ normalize-stderr-test "note: .*" -> "" -//@ normalize-stderr-test "thread 'rustc' .*" -> "" -//@ normalize-stderr-test " +\d+:.*__rust_begin_short_backtrace.*" -> "(begin_short_backtrace)" -//@ normalize-stderr-test " +\d+:.*__rust_end_short_backtrace.*" -> "(end_short_backtrace)" -//@ normalize-stderr-test " +\d+:.*\n" -> "" -//@ normalize-stderr-test " +at .*\n" -> "" +//@ normalize-stderr-test: "note: .*" -> "" +//@ normalize-stderr-test: "thread 'rustc' .*" -> "" +//@ normalize-stderr-test: " +\d+:.*__rust_begin_short_backtrace.*" -> "(begin_short_backtrace)" +//@ normalize-stderr-test: " +\d+:.*__rust_end_short_backtrace.*" -> "(end_short_backtrace)" +//@ normalize-stderr-test: " +\d+:.*\n" -> "" +//@ normalize-stderr-test: " +at .*\n" -> "" // // This test makes sure that full backtraces are used for ICEs when // RUST_BACKTRACE is not set. It does this by checking for the presence of diff --git a/tests/ui/proc-macro/load-panic-backtrace.rs b/tests/ui/proc-macro/load-panic-backtrace.rs index 56ef4e9e08841..15badedef973d 100644 --- a/tests/ui/proc-macro/load-panic-backtrace.rs +++ b/tests/ui/proc-macro/load-panic-backtrace.rs @@ -1,8 +1,8 @@ //@ aux-build:test-macros.rs //@ compile-flags: -Z proc-macro-backtrace //@ rustc-env:RUST_BACKTRACE=0 -//@ normalize-stderr-test "thread '.*' panicked " -> "" -//@ normalize-stderr-test "note:.*RUST_BACKTRACE=1.*\n" -> "" +//@ normalize-stderr-test: "thread '.*' panicked " -> "" +//@ normalize-stderr-test: "note:.*RUST_BACKTRACE=1.*\n" -> "" //@ needs-unwind proc macro panics to report errors #[macro_use] diff --git a/tests/ui/proc-macro/meta-macro-hygiene.rs b/tests/ui/proc-macro/meta-macro-hygiene.rs index 9dac1030b9c7f..98496d5a4c609 100644 --- a/tests/ui/proc-macro/meta-macro-hygiene.rs +++ b/tests/ui/proc-macro/meta-macro-hygiene.rs @@ -4,9 +4,9 @@ //@ compile-flags: -Z span-debug -Z macro-backtrace -Z unpretty=expanded,hygiene -Z trim-diagnostic-paths=no //@ check-pass // ignore-tidy-linelength -//@ normalize-stdout-test "\d+#" -> "0#" -//@ normalize-stdout-test "expn\d{3,}" -> "expnNNN" -//@ normalize-stdout-test "extern crate compiler_builtins /\* \d+ \*/" -> "extern crate compiler_builtins /* NNN */" +//@ normalize-stdout-test: "\d+#" -> "0#" +//@ normalize-stdout-test: "expn\d{3,}" -> "expnNNN" +//@ normalize-stdout-test: "extern crate compiler_builtins /\* \d+ \*/" -> "extern crate compiler_builtins /* NNN */" // // We don't care about symbol ids, so we set them all to 0 // in the stdout diff --git a/tests/ui/proc-macro/meta-macro-hygiene.stdout b/tests/ui/proc-macro/meta-macro-hygiene.stdout index 8697ba58a3903..3c6ec6fbdd4ba 100644 --- a/tests/ui/proc-macro/meta-macro-hygiene.stdout +++ b/tests/ui/proc-macro/meta-macro-hygiene.stdout @@ -8,9 +8,9 @@ Respanned: TokenStream [Ident { ident: "$crate", span: $DIR/auxiliary/make-macro //@ compile-flags: -Z span-debug -Z macro-backtrace -Z unpretty=expanded,hygiene -Z trim-diagnostic-paths=no //@ check-pass // ignore-tidy-linelength -//@ normalize-stdout-test "\d+#" -> "0#" -//@ normalize-stdout-test "expn\d{3,}" -> "expnNNN" -//@ normalize-stdout-test "extern crate compiler_builtins /\* \d+ \*/" -> "extern crate compiler_builtins /* NNN */" +//@ normalize-stdout-test: "\d+#" -> "0#" +//@ normalize-stdout-test: "expn\d{3,}" -> "expnNNN" +//@ normalize-stdout-test: "extern crate compiler_builtins /\* \d+ \*/" -> "extern crate compiler_builtins /* NNN */" // // We don't care about symbol ids, so we set them all to 0 // in the stdout diff --git a/tests/ui/proc-macro/nonterminal-token-hygiene.rs b/tests/ui/proc-macro/nonterminal-token-hygiene.rs index d1e42509584b4..6a4406b053d5e 100644 --- a/tests/ui/proc-macro/nonterminal-token-hygiene.rs +++ b/tests/ui/proc-macro/nonterminal-token-hygiene.rs @@ -4,9 +4,9 @@ //@ compile-flags: -Z span-debug -Z macro-backtrace -Z unpretty=expanded,hygiene //@ compile-flags: -Z trim-diagnostic-paths=no // ignore-tidy-linelength -//@ normalize-stdout-test "\d+#" -> "0#" -//@ normalize-stdout-test "expn\d{3,}" -> "expnNNN" -//@ normalize-stdout-test "extern crate compiler_builtins /\* \d+ \*/" -> "extern crate compiler_builtins /* NNN */" +//@ normalize-stdout-test: "\d+#" -> "0#" +//@ normalize-stdout-test: "expn\d{3,}" -> "expnNNN" +//@ normalize-stdout-test: "extern crate compiler_builtins /\* \d+ \*/" -> "extern crate compiler_builtins /* NNN */" //@ aux-build:test-macros.rs #![feature(decl_macro)] diff --git a/tests/ui/proc-macro/nonterminal-token-hygiene.stdout b/tests/ui/proc-macro/nonterminal-token-hygiene.stdout index 2078e59b8b4b0..de3265e928141 100644 --- a/tests/ui/proc-macro/nonterminal-token-hygiene.stdout +++ b/tests/ui/proc-macro/nonterminal-token-hygiene.stdout @@ -28,9 +28,9 @@ PRINT-BANG INPUT (DEBUG): TokenStream [ //@ compile-flags: -Z span-debug -Z macro-backtrace -Z unpretty=expanded,hygiene //@ compile-flags: -Z trim-diagnostic-paths=no // ignore-tidy-linelength -//@ normalize-stdout-test "\d+#" -> "0#" -//@ normalize-stdout-test "expn\d{3,}" -> "expnNNN" -//@ normalize-stdout-test "extern crate compiler_builtins /\* \d+ \*/" -> "extern crate compiler_builtins /* NNN */" +//@ normalize-stdout-test: "\d+#" -> "0#" +//@ normalize-stdout-test: "expn\d{3,}" -> "expnNNN" +//@ normalize-stdout-test: "extern crate compiler_builtins /\* \d+ \*/" -> "extern crate compiler_builtins /* NNN */" //@ aux-build:test-macros.rs #![feature /* 0#0 */(decl_macro)] diff --git a/tests/ui/process/println-with-broken-pipe.rs b/tests/ui/process/println-with-broken-pipe.rs index 798db3c0f8ca4..4ac1f7c98cbd1 100644 --- a/tests/ui/process/println-with-broken-pipe.rs +++ b/tests/ui/process/println-with-broken-pipe.rs @@ -5,7 +5,7 @@ //@ ignore-fuchsia //@ ignore-horizon //@ ignore-android -//@ normalize-stderr-test ".rs:\d+:\d+" -> ".rs:LL:CC" +//@ normalize-stderr-test: ".rs:\d+:\d+" -> ".rs:LL:CC" //@ compile-flags: -Zon-broken-pipe=error // Test what the error message looks like when `println!()` panics because of diff --git a/tests/ui/repr/repr-c-dead-variants.rs b/tests/ui/repr/repr-c-dead-variants.rs index f113588e83fe9..cc080b2e59ad7 100644 --- a/tests/ui/repr/repr-c-dead-variants.rs +++ b/tests/ui/repr/repr-c-dead-variants.rs @@ -6,7 +6,7 @@ // See also: repr-c-int-dead-variants.rs -//@ normalize-stderr-test "pref: Align\([1-8] bytes\)" -> "pref: $$SOME_ALIGN" +//@ normalize-stderr-test: "pref: Align\([1-8] bytes\)" -> "pref: $$SOME_ALIGN" // This test depends on the value of the `c_enum_min_bits` target option. // As there's no way to actually check it from UI test, we only run this test on a subset of archs. diff --git a/tests/ui/repr/repr-c-int-dead-variants.rs b/tests/ui/repr/repr-c-int-dead-variants.rs index 8d2b39bd6486e..ed26174343a48 100644 --- a/tests/ui/repr/repr-c-int-dead-variants.rs +++ b/tests/ui/repr/repr-c-int-dead-variants.rs @@ -3,7 +3,7 @@ // See also: repr-c-dead-variants.rs -//@ normalize-stderr-test "pref: Align\([1-8] bytes\)" -> "pref: $$SOME_ALIGN" +//@ normalize-stderr-test: "pref: Align\([1-8] bytes\)" -> "pref: $$SOME_ALIGN" // A simple uninhabited type. enum Void {} diff --git a/tests/ui/resolve/multiple_definitions_attribute_merging.rs b/tests/ui/resolve/multiple_definitions_attribute_merging.rs index 523717861e1ba..7d649476ad2a4 100644 --- a/tests/ui/resolve/multiple_definitions_attribute_merging.rs +++ b/tests/ui/resolve/multiple_definitions_attribute_merging.rs @@ -4,9 +4,9 @@ //@known-bug: #120873 //@ failure-status: 101 -//@ normalize-stderr-test "note: .*\n\n" -> "" -//@ normalize-stderr-test "thread 'rustc' panicked.*\n" -> "" -//@ normalize-stderr-test "(error: internal compiler error: [^:]+):\d+:\d+: " -> "$1:LL:CC: " +//@ normalize-stderr-test: "note: .*\n\n" -> "" +//@ normalize-stderr-test: "thread 'rustc' panicked.*\n" -> "" +//@ normalize-stderr-test: "(error: internal compiler error: [^:]+):\d+:\d+: " -> "$1:LL:CC: " //@ rustc-env:RUST_BACKTRACE=0 #[repr(packed)] diff --git a/tests/ui/resolve/proc_macro_generated_packed.rs b/tests/ui/resolve/proc_macro_generated_packed.rs index 34a7e4db6030d..e8d04f808d03b 100644 --- a/tests/ui/resolve/proc_macro_generated_packed.rs +++ b/tests/ui/resolve/proc_macro_generated_packed.rs @@ -4,9 +4,9 @@ //@aux-build: proc_macro_generate_packed.rs //@known-bug: #120873 //@ failure-status: 101 -//@ normalize-stderr-test "note: .*\n\n" -> "" -//@ normalize-stderr-test "thread 'rustc' panicked.*\n" -> "" -//@ normalize-stderr-test "(error: internal compiler error: [^:]+):\d+:\d+: " -> "$1:LL:CC: " +//@ normalize-stderr-test: "note: .*\n\n" -> "" +//@ normalize-stderr-test: "thread 'rustc' panicked.*\n" -> "" +//@ normalize-stderr-test: "(error: internal compiler error: [^:]+):\d+:\d+: " -> "$1:LL:CC: " //@ rustc-env:RUST_BACKTRACE=0 extern crate proc_macro_generate_packed; diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/minicore.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/minicore.rs index 63c353c7d6627..3c6d4757fea2a 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/minicore.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/minicore.rs @@ -1,7 +1,7 @@ //@ known-bug: #110395 //@ failure-status: 101 -//@ normalize-stderr-test ".*note: .*\n\n" -> "" -//@ normalize-stderr-test "thread 'rustc' panicked.*:\n.*\n" -> "" +//@ normalize-stderr-test: ".*note: .*\n\n" -> "" +//@ normalize-stderr-test: "thread 'rustc' panicked.*:\n.*\n" -> "" //@ rustc-env:RUST_BACKTRACE=0 // FIXME(effects) check-pass //@ compile-flags: -Znext-solver diff --git a/tests/ui/statics/mutable_memory_validation.rs b/tests/ui/statics/mutable_memory_validation.rs index fcf6ad1627772..470229d5fa7cd 100644 --- a/tests/ui/statics/mutable_memory_validation.rs +++ b/tests/ui/statics/mutable_memory_validation.rs @@ -1,8 +1,8 @@ //issue: rust-lang/rust#122548 // Strip out raw byte dumps to make comparison platform-independent: -//@ normalize-stderr-test "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" -//@ normalize-stderr-test "([0-9a-f][0-9a-f] |╾─*A(LLOC)?[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> "HEX_DUMP" +//@ normalize-stderr-test: "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" +//@ normalize-stderr-test: "([0-9a-f][0-9a-f] |╾─*A(LLOC)?[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> "HEX_DUMP" #![feature(const_mut_refs)] #![feature(const_refs_to_static)] diff --git a/tests/ui/test-attrs/terse.rs b/tests/ui/test-attrs/terse.rs index ab9d5cc19bd6c..74e189158570f 100644 --- a/tests/ui/test-attrs/terse.rs +++ b/tests/ui/test-attrs/terse.rs @@ -3,7 +3,7 @@ //@ run-flags: --test-threads=1 --quiet //@ check-run-results //@ exec-env:RUST_BACKTRACE=0 -//@ normalize-stdout-test "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" //@ ignore-emscripten no threads support //@ needs-unwind diff --git a/tests/ui/test-attrs/test-filter-multiple.rs b/tests/ui/test-attrs/test-filter-multiple.rs index 05fc022834aea..c875929e67242 100644 --- a/tests/ui/test-attrs/test-filter-multiple.rs +++ b/tests/ui/test-attrs/test-filter-multiple.rs @@ -2,7 +2,7 @@ //@ compile-flags: --test //@ run-flags: --test-threads=1 test1 test2 //@ check-run-results -//@ normalize-stdout-test "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" //@ needs-threads #[test] diff --git a/tests/ui/test-attrs/test-panic-abort-nocapture.rs b/tests/ui/test-attrs/test-panic-abort-nocapture.rs index 8c9e222a40d3e..c2c3d6d547d6c 100644 --- a/tests/ui/test-attrs/test-panic-abort-nocapture.rs +++ b/tests/ui/test-attrs/test-panic-abort-nocapture.rs @@ -4,7 +4,7 @@ //@ run-fail //@ check-run-results //@ exec-env:RUST_BACKTRACE=0 -//@ normalize-stdout-test "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" //@ ignore-android #120567 //@ ignore-wasm no panic or subprocess support diff --git a/tests/ui/test-attrs/test-panic-abort.rs b/tests/ui/test-attrs/test-panic-abort.rs index c9f6439ef8946..0c44acaffd77b 100644 --- a/tests/ui/test-attrs/test-panic-abort.rs +++ b/tests/ui/test-attrs/test-panic-abort.rs @@ -4,7 +4,7 @@ //@ run-fail //@ check-run-results //@ exec-env:RUST_BACKTRACE=0 -//@ normalize-stdout-test "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" //@ ignore-android #120567 //@ ignore-wasm no panic or subprocess support diff --git a/tests/ui/test-attrs/test-passed.rs b/tests/ui/test-attrs/test-passed.rs index f43f66a6edf5e..2a3fca7f002e9 100644 --- a/tests/ui/test-attrs/test-passed.rs +++ b/tests/ui/test-attrs/test-passed.rs @@ -3,7 +3,7 @@ //@ run-flags: --test-threads=1 //@ run-pass //@ check-run-results -//@ normalize-stdout-test "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" // Tests the output of the test harness with only passed tests. diff --git a/tests/ui/test-attrs/test-thread-capture.rs b/tests/ui/test-attrs/test-thread-capture.rs index d770964125fba..75ff4e0ece64f 100644 --- a/tests/ui/test-attrs/test-thread-capture.rs +++ b/tests/ui/test-attrs/test-thread-capture.rs @@ -3,7 +3,7 @@ //@ run-flags: --test-threads=1 //@ check-run-results //@ exec-env:RUST_BACKTRACE=0 -//@ normalize-stdout-test "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" //@ ignore-emscripten no threads support //@ needs-unwind diff --git a/tests/ui/test-attrs/test-thread-nocapture.rs b/tests/ui/test-attrs/test-thread-nocapture.rs index 58e5f7e33cb75..6a36ea8d7d196 100644 --- a/tests/ui/test-attrs/test-thread-nocapture.rs +++ b/tests/ui/test-attrs/test-thread-nocapture.rs @@ -3,7 +3,7 @@ //@ run-flags: --test-threads=1 --nocapture //@ check-run-results //@ exec-env:RUST_BACKTRACE=0 -//@ normalize-stdout-test "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" //@ ignore-emscripten no threads support //@ needs-unwind diff --git a/tests/ui/test-attrs/test-type.rs b/tests/ui/test-attrs/test-type.rs index 7db7e31d01daa..1b71ead55b077 100644 --- a/tests/ui/test-attrs/test-type.rs +++ b/tests/ui/test-attrs/test-type.rs @@ -1,7 +1,7 @@ //@ compile-flags: --test -Zpanic-abort-tests //@ run-flags: --test-threads=1 //@ check-run-results -//@ normalize-stdout-test "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" //@ needs-threads //@ run-pass diff --git a/tests/ui/track-diagnostics/track.rs b/tests/ui/track-diagnostics/track.rs index 4b984171480ea..5023f34e4c1b2 100644 --- a/tests/ui/track-diagnostics/track.rs +++ b/tests/ui/track-diagnostics/track.rs @@ -5,13 +5,13 @@ // Normalize the emitted location so this doesn't need // updating everytime someone adds or removes a line. -//@ normalize-stderr-test ".rs:\d+:\d+" -> ".rs:LL:CC" -//@ normalize-stderr-test "note: rustc .+ running on .+" -> "note: rustc $$VERSION running on $$TARGET" +//@ normalize-stderr-test: ".rs:\d+:\d+" -> ".rs:LL:CC" +//@ normalize-stderr-test: "note: rustc .+ running on .+" -> "note: rustc $$VERSION running on $$TARGET" // The test becomes too flaky if we care about exact args. If `-Z ui-testing` // from compiletest and `-Z track-diagnostics` from `// compile-flags` at the // top of this file are present, then assume all args are present. -//@ normalize-stderr-test "note: compiler flags: .*-Z ui-testing.*-Z track-diagnostics" -> "note: compiler flags: ... -Z ui-testing ... -Z track-diagnostics" +//@ normalize-stderr-test: "note: compiler flags: .*-Z ui-testing.*-Z track-diagnostics" -> "note: compiler flags: ... -Z ui-testing ... -Z track-diagnostics" fn main() { break rust diff --git a/tests/ui/track-diagnostics/track2.rs b/tests/ui/track-diagnostics/track2.rs index 00a17ccb2910d..7466e9246ce61 100644 --- a/tests/ui/track-diagnostics/track2.rs +++ b/tests/ui/track-diagnostics/track2.rs @@ -3,7 +3,7 @@ // Normalize the emitted location so this doesn't need // updating everytime someone adds or removes a line. -//@ normalize-stderr-test ".rs:\d+:\d+" -> ".rs:LL:CC" +//@ normalize-stderr-test: ".rs:\d+:\d+" -> ".rs:LL:CC" fn main() { let _moved @ _from = String::from("foo"); diff --git a/tests/ui/track-diagnostics/track3.rs b/tests/ui/track-diagnostics/track3.rs index 2d0efdc839f9b..43ad1dff8b83a 100644 --- a/tests/ui/track-diagnostics/track3.rs +++ b/tests/ui/track-diagnostics/track3.rs @@ -3,7 +3,7 @@ // Normalize the emitted location so this doesn't need // updating everytime someone adds or removes a line. -//@ normalize-stderr-test ".rs:\d+:\d+" -> ".rs:LL:CC" +//@ normalize-stderr-test: ".rs:\d+:\d+" -> ".rs:LL:CC" fn main() { let _unimported = Blah { field: u8 }; diff --git a/tests/ui/track-diagnostics/track4.rs b/tests/ui/track-diagnostics/track4.rs index 788c999e0527a..bc76f6f145171 100644 --- a/tests/ui/track-diagnostics/track4.rs +++ b/tests/ui/track-diagnostics/track4.rs @@ -3,7 +3,7 @@ // Normalize the emitted location so this doesn't need // updating everytime someone adds or removes a line. -//@ normalize-stderr-test ".rs:\d+:\d+" -> ".rs:LL:CC" +//@ normalize-stderr-test: ".rs:\d+:\d+" -> ".rs:LL:CC" pub onion { Owo(u8), diff --git a/tests/ui/track-diagnostics/track5.rs b/tests/ui/track-diagnostics/track5.rs index 28df72915cfb8..bb82e9a62c8bd 100644 --- a/tests/ui/track-diagnostics/track5.rs +++ b/tests/ui/track-diagnostics/track5.rs @@ -3,6 +3,6 @@ // Normalize the emitted location so this doesn't need // updating everytime someone adds or removes a line. -//@ normalize-stderr-test ".rs:\d+:\d+" -> ".rs:LL:CC" +//@ normalize-stderr-test: ".rs:\d+:\d+" -> ".rs:LL:CC" } diff --git a/tests/ui/track-diagnostics/track6.rs b/tests/ui/track-diagnostics/track6.rs index 7b0dd7a37a7a2..fc8df68e6d921 100644 --- a/tests/ui/track-diagnostics/track6.rs +++ b/tests/ui/track-diagnostics/track6.rs @@ -3,7 +3,7 @@ // Normalize the emitted location so this doesn't need // updating everytime someone adds or removes a line. -//@ normalize-stderr-test ".rs:\d+:\d+" -> ".rs:LL:CC" +//@ normalize-stderr-test: ".rs:\d+:\d+" -> ".rs:LL:CC" pub trait Foo { diff --git a/tests/ui/traits/trait-upcasting/illegal-upcast-to-impl-opaque.rs b/tests/ui/traits/trait-upcasting/illegal-upcast-to-impl-opaque.rs index 5820e49a4e52d..ef0a5a7adcaf5 100644 --- a/tests/ui/traits/trait-upcasting/illegal-upcast-to-impl-opaque.rs +++ b/tests/ui/traits/trait-upcasting/illegal-upcast-to-impl-opaque.rs @@ -2,10 +2,10 @@ //@[next] compile-flags: -Znext-solver //@[next] failure-status: 101 //@[next] known-bug: unknown -//@[next] normalize-stderr-test "note: .*\n\n" -> "" -//@[next] normalize-stderr-test "thread 'rustc' panicked.*\n.*\n" -> "" -//@[next] normalize-stderr-test "(error: internal compiler error: [^:]+):\d+:\d+: " -> "$1:LL:CC: " -//@[next] normalize-stderr-test "delayed at .*" -> "" +//@[next] normalize-stderr-test: "note: .*\n\n" -> "" +//@[next] normalize-stderr-test: "thread 'rustc' panicked.*\n.*\n" -> "" +//@[next] normalize-stderr-test: "(error: internal compiler error: [^:]+):\d+:\d+: " -> "$1:LL:CC: " +//@[next] normalize-stderr-test: "delayed at .*" -> "" //@[next] rustc-env:RUST_BACKTRACE=0 //@ check-pass diff --git a/tests/ui/transmute/transmute-different-sizes.rs b/tests/ui/transmute/transmute-different-sizes.rs index ac98eb231dd1c..b7fca2b327831 100644 --- a/tests/ui/transmute/transmute-different-sizes.rs +++ b/tests/ui/transmute/transmute-different-sizes.rs @@ -1,4 +1,4 @@ -//@ normalize-stderr-test "\d+ bits" -> "N bits" +//@ normalize-stderr-test: "\d+ bits" -> "N bits" // Tests that `transmute` cannot be called on types of different size. diff --git a/tests/ui/transmute/transmute-fat-pointers.rs b/tests/ui/transmute/transmute-fat-pointers.rs index 7043e53dbff79..d1340c5e86045 100644 --- a/tests/ui/transmute/transmute-fat-pointers.rs +++ b/tests/ui/transmute/transmute-fat-pointers.rs @@ -1,4 +1,4 @@ -//@ normalize-stderr-test "\d+ bits" -> "N bits" +//@ normalize-stderr-test: "\d+ bits" -> "N bits" // Tests that are conservative around thin/fat pointer mismatches. diff --git a/tests/ui/transmute/transmute-impl.rs b/tests/ui/transmute/transmute-impl.rs index 617e707cda911..15d67483cc8d7 100644 --- a/tests/ui/transmute/transmute-impl.rs +++ b/tests/ui/transmute/transmute-impl.rs @@ -1,4 +1,4 @@ -//@ normalize-stderr-test "\d+ bits" -> "N bits" +//@ normalize-stderr-test: "\d+ bits" -> "N bits" // Tests that are conservative around thin/fat pointer mismatches. diff --git a/tests/ui/treat-err-as-bug/err.rs b/tests/ui/treat-err-as-bug/err.rs index 02eea06049490..82683cdffef69 100644 --- a/tests/ui/treat-err-as-bug/err.rs +++ b/tests/ui/treat-err-as-bug/err.rs @@ -2,8 +2,8 @@ //@ failure-status: 101 //@ error-pattern: aborting due to `-Z treat-err-as-bug=1` //@ error-pattern: [eval_static_initializer] evaluating initializer of static `C` -//@ normalize-stderr-test "note: .*\n\n" -> "" -//@ normalize-stderr-test "thread 'rustc' panicked.*:\n.*\n" -> "" +//@ normalize-stderr-test: "note: .*\n\n" -> "" +//@ normalize-stderr-test: "thread 'rustc' panicked.*:\n.*\n" -> "" //@ rustc-env:RUST_BACKTRACE=0 #![crate_type = "rlib"] diff --git a/tests/ui/treat-err-as-bug/span_delayed_bug.rs b/tests/ui/treat-err-as-bug/span_delayed_bug.rs index 7e5a221b6d85d..97b8e4a3ddac2 100644 --- a/tests/ui/treat-err-as-bug/span_delayed_bug.rs +++ b/tests/ui/treat-err-as-bug/span_delayed_bug.rs @@ -2,8 +2,8 @@ //@ failure-status: 101 //@ error-pattern: aborting due to `-Z treat-err-as-bug=1` //@ error-pattern: [trigger_delayed_bug] triggering a delayed bug for testing incremental -//@ normalize-stderr-test "note: .*\n\n" -> "" -//@ normalize-stderr-test "thread 'rustc' panicked.*:\n.*\n" -> "" +//@ normalize-stderr-test: "note: .*\n\n" -> "" +//@ normalize-stderr-test: "thread 'rustc' panicked.*:\n.*\n" -> "" //@ rustc-env:RUST_BACKTRACE=0 #![feature(rustc_attrs)] diff --git a/tests/ui/type/pattern_types/range_patterns.rs b/tests/ui/type/pattern_types/range_patterns.rs index d1fd055dbab92..9eddc8cab7fe1 100644 --- a/tests/ui/type/pattern_types/range_patterns.rs +++ b/tests/ui/type/pattern_types/range_patterns.rs @@ -3,7 +3,7 @@ #![feature(core_pattern_types)] #![allow(incomplete_features)] -//@ normalize-stderr-test "pref: Align\([1-8] bytes\)" -> "pref: $$SOME_ALIGN" +//@ normalize-stderr-test: "pref: Align\([1-8] bytes\)" -> "pref: $$SOME_ALIGN" use std::pat::pattern_type; diff --git a/tests/ui/unknown-llvm-arg.rs b/tests/ui/unknown-llvm-arg.rs index 935c083dca657..17908d36417c7 100644 --- a/tests/ui/unknown-llvm-arg.rs +++ b/tests/ui/unknown-llvm-arg.rs @@ -1,6 +1,6 @@ //@ compile-flags: -Cllvm-args=-not-a-real-llvm-arg -//@ normalize-stderr-test "--help" -> "-help" -//@ normalize-stderr-test "\n(\n|.)*" -> "" +//@ normalize-stderr-test: "--help" -> "-help" +//@ normalize-stderr-test: "\n(\n|.)*" -> "" // I'm seeing "--help" locally, but "-help" in CI, so I'm normalizing it to just "-help". diff --git a/tests/ui/unpretty/avoid-crash.rs b/tests/ui/unpretty/avoid-crash.rs index 2105068617b1c..e2bde8236220e 100644 --- a/tests/ui/unpretty/avoid-crash.rs +++ b/tests/ui/unpretty/avoid-crash.rs @@ -1,4 +1,4 @@ -//@ normalize-stderr-test "error `.*`" -> "$$ERROR_MESSAGE" +//@ normalize-stderr-test: "error `.*`" -> "$$ERROR_MESSAGE" //@ compile-flags: -o. -Zunpretty=ast-tree fn main() {} From b6773591ee82df4d57157252f5122e280be3786d Mon Sep 17 00:00:00 2001 From: Zalathar Date: Fri, 21 Jun 2024 15:15:58 +1000 Subject: [PATCH 882/892] Require a colon in `//@ normalize-*:` headers --- src/tools/compiletest/src/header.rs | 4 +--- src/tools/compiletest/src/header/tests.rs | 20 ++++++-------------- 2 files changed, 7 insertions(+), 17 deletions(-) diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs index 63d1efd42fae1..7479be90797ee 100644 --- a/src/tools/compiletest/src/header.rs +++ b/src/tools/compiletest/src/header.rs @@ -1121,13 +1121,11 @@ fn expand_variables(mut value: String, config: &Config) -> String { /// normalize-*: "REGEX" -> "REPLACEMENT" /// ``` fn parse_normalize_rule(header: &str) -> Option<(String, String)> { - // FIXME(#126370): A colon after the header name should be mandatory, but - // currently is not, and there are many tests that lack the colon. // FIXME: Support escaped double-quotes in strings. let captures = static_regex!( r#"(?x) # (verbose mode regex) ^ - [^:\s]+:?\s* # (header name followed by optional colon) + [^:\s]+:\s* # (header name followed by colon) "(?[^"]*)" # "REGEX" \s+->\s+ # -> "(?[^"]*)" # "REPLACEMENT" diff --git a/src/tools/compiletest/src/header/tests.rs b/src/tools/compiletest/src/header/tests.rs index 61a85b84ad64c..c790eb18d67c4 100644 --- a/src/tools/compiletest/src/header/tests.rs +++ b/src/tools/compiletest/src/header/tests.rs @@ -33,20 +33,11 @@ fn make_test_description( #[test] fn test_parse_normalize_rule() { - let good_data = &[ - ( - r#"normalize-stderr-32bit: "something (32 bits)" -> "something ($WORD bits)""#, - "something (32 bits)", - "something ($WORD bits)", - ), - // FIXME(#126370): A colon after the header name should be mandatory, - // but currently is not, and there are many tests that lack the colon. - ( - r#"normalize-stderr-32bit "something (32 bits)" -> "something ($WORD bits)""#, - "something (32 bits)", - "something ($WORD bits)", - ), - ]; + let good_data = &[( + r#"normalize-stderr-32bit: "something (32 bits)" -> "something ($WORD bits)""#, + "something (32 bits)", + "something ($WORD bits)", + )]; for &(input, expected_regex, expected_replacement) in good_data { let parsed = parse_normalize_rule(input); @@ -56,6 +47,7 @@ fn test_parse_normalize_rule() { } let bad_data = &[ + r#"normalize-stderr-32bit "something (32 bits)" -> "something ($WORD bits)""#, r#"normalize-stderr-16bit: something (16 bits) -> something ($WORD bits)"#, r#"normalize-stderr-32bit: something (32 bits) -> something ($WORD bits)"#, r#"normalize-stderr-32bit: "something (32 bits) -> something ($WORD bits)"#, From dce98c52ff3e431d9b1358298fe8da9db545a3e2 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Thu, 4 Jul 2024 10:27:00 +0000 Subject: [PATCH 883/892] Avoid follow-up errors and ICEs after missing lifetime errors on data structures --- .gitignore | 1 + compiler/rustc_infer/src/infer/mod.rs | 3 +++ tests/crashes/124083.rs | 9 -------- tests/crashes/124262.rs | 5 ---- tests/crashes/125155.rs | 17 -------------- tests/crashes/125888.rs | 17 -------------- tests/crashes/125992.rs | 19 --------------- tests/crashes/126648.rs | 8 ------- tests/crashes/126666.rs | 18 --------------- tests/crashes/127266.rs | 17 -------------- tests/crashes/127304.rs | 20 ---------------- tests/rustdoc-ui/unable-fulfill-trait.rs | 1 - tests/rustdoc-ui/unable-fulfill-trait.stderr | 23 +++---------------- .../issues/issue-71381.full.stderr | 18 +++------------ .../issues/issue-71381.min.stderr | 20 ++++------------ tests/ui/const-generics/issues/issue-71381.rs | 1 - tests/ui/impl-trait/issue-72911.rs | 1 - tests/ui/impl-trait/issue-72911.stderr | 13 ++--------- .../issue-74918-missing-lifetime.rs | 1 - .../issue-74918-missing-lifetime.stderr | 16 +------------ tests/ui/statics/missing_lifetime.rs | 9 ++++++++ tests/ui/statics/missing_lifetime.stderr | 11 +++++++++ 22 files changed, 37 insertions(+), 211 deletions(-) delete mode 100644 tests/crashes/124083.rs delete mode 100644 tests/crashes/124262.rs delete mode 100644 tests/crashes/125155.rs delete mode 100644 tests/crashes/125888.rs delete mode 100644 tests/crashes/125992.rs delete mode 100644 tests/crashes/126648.rs delete mode 100644 tests/crashes/126666.rs delete mode 100644 tests/crashes/127266.rs delete mode 100644 tests/crashes/127304.rs create mode 100644 tests/ui/statics/missing_lifetime.rs create mode 100644 tests/ui/statics/missing_lifetime.stderr diff --git a/.gitignore b/.gitignore index 87d02563ed048..f1ca6a79b5c5c 100644 --- a/.gitignore +++ b/.gitignore @@ -50,6 +50,7 @@ build/ /target /src/bootstrap/target /src/tools/x/target +/inc-fat/ # Created by default with `src/ci/docker/run.sh` /obj/ /rustc-ice* diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index 9f55939c165e0..a0be545d46fed 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -1264,6 +1264,9 @@ impl<'tcx> InferCtxt<'tcx> { where T: TypeFoldable>, { + if let Err(guar) = value.error_reported() { + self.set_tainted_by_errors(guar); + } if !value.has_non_region_infer() { return value; } diff --git a/tests/crashes/124083.rs b/tests/crashes/124083.rs deleted file mode 100644 index e9cbf3f708614..0000000000000 --- a/tests/crashes/124083.rs +++ /dev/null @@ -1,9 +0,0 @@ -//@ known-bug: #124083 - -struct Outest(&'a ()); - -fn make() -> Outest {} - -fn main() { - if let Outest("foo") = make() {} -} diff --git a/tests/crashes/124262.rs b/tests/crashes/124262.rs deleted file mode 100644 index b9dac5eca2276..0000000000000 --- a/tests/crashes/124262.rs +++ /dev/null @@ -1,5 +0,0 @@ -//@ known-bug: #124262 -//@ edition:2021 - -struct Foo(<&[fn()] as ::core::ops::Deref>::Target); -const _: *const Foo = 0 as _; diff --git a/tests/crashes/125155.rs b/tests/crashes/125155.rs deleted file mode 100644 index 165061d4b5296..0000000000000 --- a/tests/crashes/125155.rs +++ /dev/null @@ -1,17 +0,0 @@ -//@ known-bug: rust-lang/rust#125155 - -enum NestedEnum { - First, - Second, - Third -} -enum Enum { - Variant2(Option<*mut &'a &'b ()>) -} - - -fn foo(x: Enum) -> isize { - match x { - Enum::Variant2(NestedEnum::Third) => 4, - } -} diff --git a/tests/crashes/125888.rs b/tests/crashes/125888.rs deleted file mode 100644 index ae8f2d6576b74..0000000000000 --- a/tests/crashes/125888.rs +++ /dev/null @@ -1,17 +0,0 @@ -//@ known-bug: rust-lang/rust#125888 -enum NestedEnum { - First, - Second, -} - -enum Enum { - Variant(*const &'a ()), -} - -fn foo(x: Enum) { - match x { - Enum::Variant(NestedEnum::Second) => {} - } -} - -fn main() {} diff --git a/tests/crashes/125992.rs b/tests/crashes/125992.rs deleted file mode 100644 index d78f28ce6de41..0000000000000 --- a/tests/crashes/125992.rs +++ /dev/null @@ -1,19 +0,0 @@ -//@ known-bug: rust-lang/rust#125992 -//@ compile-flags: -Zpolonius=next - -#![feature(inherent_associated_types)] - -type Function = for<'a> fn(&'a i32) -> S<'a>::P; - -struct S<'a>(&'a ()); - -impl<'a> S { - type P = &'a i32; -} - -fn ret_ref_local<'e>() -> &'e i32 { - let f: Function = |x| x; - - let local = 0; - f(&local) -} diff --git a/tests/crashes/126648.rs b/tests/crashes/126648.rs deleted file mode 100644 index 1cf3e44bba9bc..0000000000000 --- a/tests/crashes/126648.rs +++ /dev/null @@ -1,8 +0,0 @@ -//@ known-bug: rust-lang/rust#126648 -struct Outest(*const &'a ()); - -fn make() -> Outest {} - -fn main() { - if let Outest("foo") = make() {} -} diff --git a/tests/crashes/126666.rs b/tests/crashes/126666.rs deleted file mode 100644 index 58526707c9ab4..0000000000000 --- a/tests/crashes/126666.rs +++ /dev/null @@ -1,18 +0,0 @@ -//@ known-bug: rust-lang/rust#126666 -#![feature(const_mut_refs)] -#![feature(const_refs_to_static)] -#![feature(object_safe_for_dispatch)] - -struct Meh { - x: &'static dyn UnsafeCell, -} - -const MUH: Meh = Meh { - x: &mut *(&READONLY as *const _ as *mut _), -}; - -static READONLY: i32 = 0; - -trait UnsafeCell<'a> {} - -pub fn main() {} diff --git a/tests/crashes/127266.rs b/tests/crashes/127266.rs deleted file mode 100644 index 2bdbe03e373a9..0000000000000 --- a/tests/crashes/127266.rs +++ /dev/null @@ -1,17 +0,0 @@ -//@ known-bug: rust-lang/rust#127266 -#![feature(const_mut_refs)] -#![feature(const_refs_to_static)] - -struct Meh { - x: &'static dyn UnsafeCell, -} - -const MUH: Meh = Meh { - x: &mut *(READONLY as *mut _), -}; - -static READONLY: i32 = 0; - -trait UnsafeCell<'a> {} - -pub fn main() {} diff --git a/tests/crashes/127304.rs b/tests/crashes/127304.rs deleted file mode 100644 index 2975fc27f6766..0000000000000 --- a/tests/crashes/127304.rs +++ /dev/null @@ -1,20 +0,0 @@ -//@ known-bug: rust-lang/rust #127304 -#![feature(adt_const_params)] - -trait Trait {} -impl Trait for () {} - -struct MyStr(str); -impl std::marker::ConstParamTy for MyStr {} - -fn function_with_my_str() -> &'static MyStr { - S -} - -impl MyStr { - const fn new(s: &Trait str) -> &'static MyStr {} -} - -pub fn main() { - let f = function_with_my_str::<{ MyStr::new("hello") }>(); -} diff --git a/tests/rustdoc-ui/unable-fulfill-trait.rs b/tests/rustdoc-ui/unable-fulfill-trait.rs index f3b6256346f0c..4edc7ab76c198 100644 --- a/tests/rustdoc-ui/unable-fulfill-trait.rs +++ b/tests/rustdoc-ui/unable-fulfill-trait.rs @@ -4,7 +4,6 @@ pub struct Foo<'a, 'b, T> { field1: dyn Bar<'a, 'b>, //~^ ERROR //~| ERROR - //~| ERROR } pub trait Bar<'x, 's, U> diff --git a/tests/rustdoc-ui/unable-fulfill-trait.stderr b/tests/rustdoc-ui/unable-fulfill-trait.stderr index 40d103f2a62e7..12e53546cdacc 100644 --- a/tests/rustdoc-ui/unable-fulfill-trait.stderr +++ b/tests/rustdoc-ui/unable-fulfill-trait.stderr @@ -5,7 +5,7 @@ LL | field1: dyn Bar<'a, 'b>, | ^^^ expected 1 generic argument | note: trait defined here, with 1 generic parameter: `U` - --> $DIR/unable-fulfill-trait.rs:10:11 + --> $DIR/unable-fulfill-trait.rs:9:11 | LL | pub trait Bar<'x, 's, U> | ^^^ - @@ -20,24 +20,7 @@ error[E0227]: ambiguous lifetime bound, explicit lifetime bound required LL | field1: dyn Bar<'a, 'b>, | ^^^^^^^^^^^^^^^ -error[E0478]: lifetime bound not satisfied - --> $DIR/unable-fulfill-trait.rs:4:13 - | -LL | field1: dyn Bar<'a, 'b>, - | ^^^^^^^^^^^^^^^ - | -note: lifetime parameter instantiated with the lifetime `'b` as defined here - --> $DIR/unable-fulfill-trait.rs:3:20 - | -LL | pub struct Foo<'a, 'b, T> { - | ^^ -note: but lifetime parameter must outlive the lifetime `'a` as defined here - --> $DIR/unable-fulfill-trait.rs:3:16 - | -LL | pub struct Foo<'a, 'b, T> { - | ^^ - -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors -Some errors have detailed explanations: E0107, E0227, E0478. +Some errors have detailed explanations: E0107, E0227. For more information about an error, try `rustc --explain E0107`. diff --git a/tests/ui/const-generics/issues/issue-71381.full.stderr b/tests/ui/const-generics/issues/issue-71381.full.stderr index 05e847cf4c841..b6460e0017fa5 100644 --- a/tests/ui/const-generics/issues/issue-71381.full.stderr +++ b/tests/ui/const-generics/issues/issue-71381.full.stderr @@ -7,25 +7,13 @@ LL | pub fn call_me $DIR/issue-71381.rs:24:40 + --> $DIR/issue-71381.rs:23:40 | LL | const FN: unsafe extern "C" fn(Args), | ^^^^ the type must not depend on the parameter `Args` | = note: type parameters may not be used in the type of const parameters -error[E0594]: cannot assign to `self.0`, which is behind a `&` reference - --> $DIR/issue-71381.rs:17:9 - | -LL | self.0 = Self::trampiline:: as _ - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `self` is a `&` reference, so the data it refers to cannot be written - | -help: consider changing this to be a mutable reference - | -LL | pub fn call_me(&mut self) { - | ~~~~~~~~~ - -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors -Some errors have detailed explanations: E0594, E0770. -For more information about an error, try `rustc --explain E0594`. +For more information about this error, try `rustc --explain E0770`. diff --git a/tests/ui/const-generics/issues/issue-71381.min.stderr b/tests/ui/const-generics/issues/issue-71381.min.stderr index 1c30e885d1b7d..e16d3b7a8a469 100644 --- a/tests/ui/const-generics/issues/issue-71381.min.stderr +++ b/tests/ui/const-generics/issues/issue-71381.min.stderr @@ -7,7 +7,7 @@ LL | pub fn call_me $DIR/issue-71381.rs:24:40 + --> $DIR/issue-71381.rs:23:40 | LL | const FN: unsafe extern "C" fn(Args), | ^^^^ the type must not depend on the parameter `Args` @@ -23,25 +23,13 @@ LL | pub fn call_me $DIR/issue-71381.rs:24:19 + --> $DIR/issue-71381.rs:23:19 | LL | const FN: unsafe extern "C" fn(Args), | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: the only supported types are integers, `bool` and `char` -error[E0594]: cannot assign to `self.0`, which is behind a `&` reference - --> $DIR/issue-71381.rs:17:9 - | -LL | self.0 = Self::trampiline:: as _ - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `self` is a `&` reference, so the data it refers to cannot be written - | -help: consider changing this to be a mutable reference - | -LL | pub fn call_me(&mut self) { - | ~~~~~~~~~ - -error: aborting due to 5 previous errors +error: aborting due to 4 previous errors -Some errors have detailed explanations: E0594, E0770. -For more information about an error, try `rustc --explain E0594`. +For more information about this error, try `rustc --explain E0770`. diff --git a/tests/ui/const-generics/issues/issue-71381.rs b/tests/ui/const-generics/issues/issue-71381.rs index 166b724a7a33a..e472ef31fcdd3 100644 --- a/tests/ui/const-generics/issues/issue-71381.rs +++ b/tests/ui/const-generics/issues/issue-71381.rs @@ -15,7 +15,6 @@ impl Test { //~^ ERROR: the type of const parameters must not depend on other generic parameters //[min]~^^ ERROR: using function pointers as const generic parameters is forbidden self.0 = Self::trampiline:: as _ - //~^ ERROR: cannot assign to `self.0` } unsafe extern "C" fn trampiline< diff --git a/tests/ui/impl-trait/issue-72911.rs b/tests/ui/impl-trait/issue-72911.rs index 7ba8579e24fb1..63f4898f4306b 100644 --- a/tests/ui/impl-trait/issue-72911.rs +++ b/tests/ui/impl-trait/issue-72911.rs @@ -15,7 +15,6 @@ fn gather_from_file(dir_entry: &foo::MissingItem) -> impl Iterator fn lint_files() -> impl Iterator { //~^ ERROR: failed to resolve - //~| ERROR: `()` is not an iterator unimplemented!() } diff --git a/tests/ui/impl-trait/issue-72911.stderr b/tests/ui/impl-trait/issue-72911.stderr index 44c20a7be53df..0e86561aa2779 100644 --- a/tests/ui/impl-trait/issue-72911.stderr +++ b/tests/ui/impl-trait/issue-72911.stderr @@ -1,11 +1,3 @@ -error[E0277]: `()` is not an iterator - --> $DIR/issue-72911.rs:16:20 - | -LL | fn lint_files() -> impl Iterator { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `()` is not an iterator - | - = help: the trait `Iterator` is not implemented for `()` - error[E0433]: failed to resolve: use of undeclared crate or module `foo` --> $DIR/issue-72911.rs:11:33 | @@ -18,7 +10,6 @@ error[E0433]: failed to resolve: use of undeclared crate or module `foo` LL | fn lint_files() -> impl Iterator { | ^^^ use of undeclared crate or module `foo` -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors -Some errors have detailed explanations: E0277, E0433. -For more information about an error, try `rustc --explain E0277`. +For more information about this error, try `rustc --explain E0433`. diff --git a/tests/ui/mismatched_types/issue-74918-missing-lifetime.rs b/tests/ui/mismatched_types/issue-74918-missing-lifetime.rs index c7842667dc614..6aa34354a7ad9 100644 --- a/tests/ui/mismatched_types/issue-74918-missing-lifetime.rs +++ b/tests/ui/mismatched_types/issue-74918-missing-lifetime.rs @@ -9,7 +9,6 @@ impl> Iterator for ChunkingIterator { type Item = IteratorChunk; //~ ERROR missing lifetime fn next(&mut self) -> Option> { - //~^ ERROR `impl` item signature doesn't match `trait` item signature todo!() } } diff --git a/tests/ui/mismatched_types/issue-74918-missing-lifetime.stderr b/tests/ui/mismatched_types/issue-74918-missing-lifetime.stderr index b523182309959..5020395eb6aea 100644 --- a/tests/ui/mismatched_types/issue-74918-missing-lifetime.stderr +++ b/tests/ui/mismatched_types/issue-74918-missing-lifetime.stderr @@ -9,20 +9,6 @@ help: consider introducing a named lifetime parameter LL | type Item<'a> = IteratorChunk<'a, T, S>; | ++++ +++ -error: `impl` item signature doesn't match `trait` item signature - --> $DIR/issue-74918-missing-lifetime.rs:11:5 - | -LL | fn next(&mut self) -> Option> { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ found `fn(&'1 mut ChunkingIterator) -> Option>` - --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL - | - = note: expected `fn(&'1 mut ChunkingIterator) -> Option>` - | - = note: expected signature `fn(&'1 mut ChunkingIterator) -> Option>` - found signature `fn(&'1 mut ChunkingIterator) -> Option>` - = help: the lifetime requirements from the `impl` do not correspond to the requirements in the `trait` - = help: verify the lifetime relationships in the `trait` and `impl` between the `self` argument, the other inputs and its output - -error: aborting due to 2 previous errors +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0106`. diff --git a/tests/ui/statics/missing_lifetime.rs b/tests/ui/statics/missing_lifetime.rs new file mode 100644 index 0000000000000..e6a63ef221c6a --- /dev/null +++ b/tests/ui/statics/missing_lifetime.rs @@ -0,0 +1,9 @@ +//! This test checks that we taint typeck results when there are +//! error lifetimes, even though typeck doesn't actually care about lifetimes. + +struct Slice(&'reborrow [&'static [u8]]); +//~^ ERROR undeclared lifetime + +static MAP: Slice = Slice(&[b"" as &'static [u8]]); + +fn main() {} diff --git a/tests/ui/statics/missing_lifetime.stderr b/tests/ui/statics/missing_lifetime.stderr new file mode 100644 index 0000000000000..e23b27f7a6a6d --- /dev/null +++ b/tests/ui/statics/missing_lifetime.stderr @@ -0,0 +1,11 @@ +error[E0261]: use of undeclared lifetime name `'reborrow` + --> $DIR/missing_lifetime.rs:4:15 + | +LL | struct Slice(&'reborrow [&'static [u8]]); + | - ^^^^^^^^^ undeclared lifetime + | | + | help: consider introducing lifetime `'reborrow` here: `<'reborrow>` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0261`. From 86f8aae11d1119b575c30aaca2a05c81f507c7a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Fri, 21 Jun 2024 22:15:05 +0000 Subject: [PATCH 884/892] Remove redundancy in resolve error between main message and primary label ``` error[E0576]: cannot find method or associated constant `BAR` --> $DIR/issue-87638.rs:20:27 | LL | let _ = ::BAR; | ^^^ not found in trait `Trait` ``` instead of ``` error[E0576]: cannot find method or associated constant `BAR` in trait `Trait` --> $DIR/issue-87638.rs:20:27 | LL | let _ = ::BAR; | ^^^ not found in `Trait` ``` The general rule is that the primary span label should work well on its own (suitable to be shown in editors), while the main message provides additional context of the general case. When using `--error-format=short`, we concatenate the main message and the primary labels, so they should be complementary. --- .../rustc_resolve/src/late/diagnostics.rs | 4 +- .../clippy/tests/ui/crashes/ice-6252.stderr | 4 +- .../ui/option_map_unit_fn_unfixable.stderr | 8 ++-- .../failed-doctest-output-windows.stdout | 2 +- .../doctest/failed-doctest-output.stdout | 2 +- tests/rustdoc-ui/impl-fn-nesting.rs | 18 +++---- tests/rustdoc-ui/impl-fn-nesting.stderr | 18 +++---- .../issues/issue-81662-shortness.rs | 2 +- .../issues/issue-81662-shortness.stdout | 2 +- .../session-diagnostic/diagnostic-derive.rs | 4 +- .../diagnostic-derive.stderr | 6 +-- .../subdiagnostic-derive.rs | 8 ++-- .../subdiagnostic-derive.stderr | 6 +-- tests/ui/annotate-snippet/missing-type.rs | 2 +- tests/ui/annotate-snippet/missing-type.stderr | 2 +- .../extern-fn-arg-names.rs | 2 +- .../extern-fn-arg-names.stderr | 2 +- .../argument-suggestions/issue-109831.stderr | 4 +- .../suggest-better-removing-issue-126246.rs | 10 ++-- ...uggest-better-removing-issue-126246.stderr | 10 ++-- .../slice-pat-type-mismatches.rs | 4 +- .../slice-pat-type-mismatches.stderr | 2 +- tests/ui/asm/issue-113788.rs | 2 +- tests/ui/asm/issue-113788.stderr | 2 +- tests/ui/associated-consts/issue-93835.rs | 4 +- tests/ui/associated-consts/issue-93835.stderr | 6 +-- tests/ui/associated-item/issue-87638.fixed | 4 +- tests/ui/associated-item/issue-87638.rs | 4 +- tests/ui/associated-item/issue-87638.stderr | 8 ++-- tests/ui/associated-path-shl.rs | 10 ++-- tests/ui/associated-path-shl.stderr | 10 ++-- .../missing-trait-bound-for-assoc-fails.rs | 2 +- ...missing-trait-bound-for-assoc-fails.stderr | 2 +- .../associated-types/associated-types-eq-1.rs | 2 +- .../associated-types-eq-1.stderr | 2 +- tests/ui/associated-types/issue-19883.rs | 2 +- tests/ui/associated-types/issue-19883.stderr | 4 +- tests/ui/associated-types/issue-22037.rs | 2 +- tests/ui/associated-types/issue-22037.stderr | 4 +- .../async-closures/tainted-body.rs | 2 +- .../async-closures/tainted-body.stderr | 2 +- tests/ui/async-await/async-fn/not-a-trait.rs | 2 +- .../async-await/async-fn/not-a-trait.stderr | 2 +- .../drop-order-locals-are-hidden.rs | 8 ++-- .../drop-order-locals-are-hidden.stderr | 8 ++-- .../in-trait/return-not-existing-pair.rs | 2 +- .../in-trait/return-not-existing-pair.stderr | 2 +- ...eturn-not-existing-type-wrapping-rpitit.rs | 2 +- ...n-not-existing-type-wrapping-rpitit.stderr | 2 +- .../issue-72590-type-error-sized.stderr | 4 +- tests/ui/attributes/issue-90873.rs | 4 +- .../attributes/key-value-expansion-scope.rs | 34 ++++++------- tests/ui/attributes/main-removed-1.rs | 2 +- tests/ui/attributes/obsolete-attr.rs | 4 +- tests/ui/attributes/unknown-attr.rs | 6 +-- .../unsafe/double-unsafe-attributes.rs | 2 +- tests/ui/attributes/unused-item-in-attr.rs | 2 +- tests/ui/c-variadic/issue-86053-1.rs | 2 +- tests/ui/c-variadic/issue-86053-1.stderr | 2 +- tests/ui/cast/cast-errors-issue-43825.stderr | 2 +- tests/ui/cast/casts-issue-46365.stderr | 2 +- .../cast/ice-cast-type-with-error-124848.rs | 2 +- .../ice-cast-type-with-error-124848.stderr | 2 +- tests/ui/cfg/diagnostics-cross-crate.rs | 8 ++-- tests/ui/cfg/diagnostics-cross-crate.stderr | 16 +++---- tests/ui/cfg/diagnostics-not-a-def.stderr | 4 +- tests/ui/cfg/diagnostics-reexport.rs | 2 +- tests/ui/cfg/diagnostics-reexport.stderr | 4 +- tests/ui/cfg/diagnostics-same-crate.rs | 10 ++-- tests/ui/cfg/diagnostics-same-crate.stderr | 12 ++--- tests/ui/closures/issue-78720.rs | 2 +- tests/ui/closures/issue-78720.stderr | 2 +- tests/ui/closures/issue-90871.rs | 2 +- tests/ui/closures/issue-90871.stderr | 2 +- tests/ui/codemap_tests/tab.stderr | 2 +- tests/ui/codemap_tests/unicode_2.stderr | 2 +- tests/ui/coercion/type-errors.rs | 6 +-- tests/ui/coercion/type-errors.stderr | 6 +-- .../coherence-error-suppression.stderr | 2 +- .../coherence/illegal-copy-bad-projection.rs | 2 +- .../illegal-copy-bad-projection.stderr | 2 +- .../ui-testing-optout.stderr | 6 +-- ...-attr-unknown-attribute-macro-expansion.rs | 2 +- .../cfg-generic-params.rs | 10 ++-- .../cfg_accessible.stderr | 6 +-- tests/ui/conditional-compilation/test-cfg.rs | 2 +- .../conditional-compilation/test-cfg.stderr | 2 +- .../early/invalid-const-arguments.stderr | 4 +- .../generic_const_exprs/error_in_ty.rs | 2 +- .../generic_const_exprs/error_in_ty.stderr | 2 +- ...to-be-a-closure-or-coroutine-ice-113776.rs | 2 +- ...e-a-closure-or-coroutine-ice-113776.stderr | 2 +- ...icates-of-no-entry-found-for-key-119275.rs | 2 +- ...es-of-no-entry-found-for-key-119275.stderr | 2 +- .../generic_const_exprs/issue-109141.rs | 2 +- .../generic_const_exprs/issue-109141.stderr | 2 +- .../unevaluated-const-ice-119731.rs | 10 ++-- .../unevaluated-const-ice-119731.stderr | 10 ++-- .../const-generics/not_wf_param_in_rpitit.rs | 2 +- .../not_wf_param_in_rpitit.stderr | 2 +- .../const-generics/type_not_in_scope.stderr | 2 +- tests/ui/const-generics/unknown_adt.stderr | 2 +- .../ice-type-mismatch-when-copying-112824.rs | 2 +- ...e-type-mismatch-when-copying-112824.stderr | 2 +- .../const-eval/ice-unhandled-type-122191.rs | 2 +- .../ice-unhandled-type-122191.stderr | 2 +- .../erroneous_type_in_const_return_value.rs | 2 +- ...rroneous_type_in_const_return_value.stderr | 2 +- tests/ui/consts/erroneous_type_in_promoted.rs | 2 +- .../consts/erroneous_type_in_promoted.stderr | 2 +- .../ice-bad-input-type-for-cast-83056.rs | 2 +- .../ice-bad-input-type-for-cast-83056.stderr | 2 +- tests/ui/consts/issue-104609.rs | 2 +- tests/ui/consts/issue-104609.stderr | 2 +- tests/ui/consts/issue-116186.rs | 2 +- tests/ui/consts/issue-116186.stderr | 2 +- tests/ui/consts/issue-90878-2.rs | 2 +- tests/ui/consts/issue-91434.rs | 2 +- tests/ui/consts/issue-91434.stderr | 2 +- tests/ui/coroutine/gen_block.none.stderr | 6 +-- tests/ui/coroutine/layout-error.rs | 2 +- tests/ui/coroutine/layout-error.stderr | 2 +- tests/ui/custom_attribute.rs | 6 +-- tests/ui/deduplicate-diagnostics.rs | 4 +- tests/ui/delegation/bad-resolve.rs | 4 +- tests/ui/delegation/bad-resolve.stderr | 4 +- tests/ui/delegation/explicit-paths.rs | 8 ++-- tests/ui/delegation/explicit-paths.stderr | 8 ++-- tests/ui/delegation/ice-issue-124342.rs | 4 +- tests/ui/delegation/ice-issue-124342.stderr | 6 +-- tests/ui/delegation/target-expr.rs | 2 +- tests/ui/delegation/target-expr.stderr | 2 +- tests/ui/derived-errors/issue-31997.rs | 2 +- tests/ui/derived-errors/issue-31997.stderr | 2 +- tests/ui/derives/deriving-bounds.rs | 8 ++-- .../ui/derives/deriving-meta-unknown-trait.rs | 4 +- tests/ui/derives/deriving-primitive.rs | 4 +- .../ui/diagnostic_namespace/requires_path.rs | 2 +- tests/ui/did_you_mean/issue-103909.rs | 2 +- tests/ui/did_you_mean/issue-103909.stderr | 2 +- .../issue-56028-there-is-an-enum-variant.rs | 4 +- ...ssue-56028-there-is-an-enum-variant.stderr | 4 +- tests/ui/did_you_mean/println-typo.rs | 2 +- tests/ui/dropck/drop-on-non-struct.stderr | 2 +- tests/ui/editions/async-block-2015.rs | 2 +- tests/ui/editions/async-block-2015.stderr | 2 +- tests/ui/enum/suggest-default-attribute.rs | 2 +- tests/ui/error-codes/E0405.stderr | 2 +- tests/ui/error-codes/E0411.stderr | 2 +- tests/ui/error-codes/E0412.stderr | 2 +- tests/ui/error-codes/E0425.stderr | 2 +- tests/ui/error-festival.stderr | 2 +- .../ui/errors/remap-path-prefix.normal.stderr | 2 +- ...p-path-prefix.with-diagnostic-scope.stderr | 2 +- ...ath-prefix.without-diagnostic-scope.stderr | 2 +- tests/ui/expr/if/bad-if-let-suggestion.rs | 10 ++-- tests/ui/expr/if/bad-if-let-suggestion.stderr | 10 ++-- .../malformed_closure/ruby_style_closure.rs | 2 +- .../ruby_style_closure.stderr | 2 +- tests/ui/extern/extern-with-type-bounds.rs | 2 +- .../ui/extern/extern-with-type-bounds.stderr | 2 +- ...363-extern-item-where-clauses-debug-ice.rs | 4 +- ...extern-item-where-clauses-debug-ice.stderr | 4 +- tests/ui/extern/issue-80074.rs | 4 +- .../feature-gate-concat_idents2.rs | 2 +- .../feature-gate-concat_idents2.stderr | 2 +- .../feature-gate-custom_attribute.rs | 20 ++++---- .../feature-gate-custom_attribute2.rs | 34 ++++++------- .../feature-gate-gen_blocks.none.stderr | 2 +- .../feature-gates/feature-gate-rustc-attrs.rs | 2 +- .../issue-43106-gating-of-derive-2.rs | 12 ++--- .../fmt/format-args-capture-issue-102057.rs | 14 +++--- .../format-args-capture-issue-102057.stderr | 14 +++--- .../ui/fmt/format-args-capture-issue-94010.rs | 4 +- .../format-args-capture-issue-94010.stderr | 4 +- .../format-args-capture-missing-variables.rs | 12 ++--- ...rmat-args-capture-missing-variables.stderr | 12 ++--- tests/ui/fmt/ifmt-bad-arg.rs | 10 ++-- tests/ui/fmt/ifmt-bad-arg.stderr | 10 ++-- tests/ui/fmt/unicode-escape-spans.stderr | 20 ++++---- tests/ui/for/for-expn.rs | 2 +- tests/ui/for/for-expn.stderr | 2 +- ...n-help-with-err-generic-is-not-function.rs | 8 ++-- ...lp-with-err-generic-is-not-function.stderr | 4 +- .../ui/functions-closures/fn-help-with-err.rs | 2 +- .../fn-help-with-err.stderr | 2 +- .../equality-bound.rs | 12 ++--- .../equality-bound.stderr | 12 ++--- tests/ui/generics/issue-106694.rs | 6 +-- tests/ui/generics/issue-106694.stderr | 6 +-- tests/ui/hygiene/arguments.rs | 2 +- tests/ui/hygiene/arguments.stderr | 2 +- tests/ui/hygiene/cross-crate-glob-hygiene.rs | 2 +- .../hygiene/cross-crate-glob-hygiene.stderr | 2 +- tests/ui/hygiene/cross-crate-name-hiding-2.rs | 2 +- .../hygiene/cross-crate-name-hiding-2.stderr | 2 +- tests/ui/hygiene/cross-crate-name-hiding.rs | 2 +- .../ui/hygiene/cross-crate-name-hiding.stderr | 2 +- tests/ui/hygiene/for-loop.rs | 2 +- tests/ui/hygiene/for-loop.stderr | 2 +- tests/ui/hygiene/generate-mod.rs | 12 ++--- tests/ui/hygiene/generate-mod.stderr | 12 ++--- tests/ui/hygiene/globs.rs | 8 ++-- tests/ui/hygiene/globs.stderr | 8 ++-- tests/ui/hygiene/no_implicit_prelude-2018.rs | 2 +- tests/ui/hygiene/pattern-macro.rs | 2 +- tests/ui/hygiene/pattern-macro.stderr | 2 +- tests/ui/hygiene/rustc-macro-transparency.rs | 2 +- .../hygiene/rustc-macro-transparency.stderr | 2 +- ...ure-rpitits-are-created-before-freezing.rs | 2 +- ...rpitits-are-created-before-freezing.stderr | 2 +- .../rpitit-shadowed-by-missing-adt.rs | 2 +- .../rpitit-shadowed-by-missing-adt.stderr | 2 +- tests/ui/impl-trait/issue-103181-2.rs | 2 +- tests/ui/impl-trait/issue-103181-2.stderr | 2 +- tests/ui/impl-trait/issue-54966.rs | 2 +- tests/ui/impl-trait/issue-54966.stderr | 2 +- tests/ui/impl-trait/issues/issue-82139.rs | 2 +- tests/ui/impl-trait/issues/issue-82139.stderr | 2 +- .../opaque-used-in-extraneous-argument.stderr | 4 +- .../precise-capturing/bad-params.rs | 4 +- .../precise-capturing/bad-params.stderr | 4 +- .../precise-capturing/bound-modifiers.rs | 8 ++-- .../precise-capturing/bound-modifiers.stderr | 8 ++-- tests/ui/implied-bounds/references-err.rs | 2 +- tests/ui/implied-bounds/references-err.stderr | 2 +- .../ui/imports/glob-conflict-cross-crate-1.rs | 4 +- .../glob-conflict-cross-crate-1.stderr | 8 ++-- .../ui/imports/glob-conflict-cross-crate-2.rs | 2 +- .../glob-conflict-cross-crate-2.stderr | 2 +- tests/ui/imports/glob-resolve1.rs | 14 +++--- tests/ui/imports/glob-resolve1.stderr | 14 +++--- ...port-alias-issue-121168.edition2015.stderr | 2 +- ...port-alias-issue-121168.edition2018.stderr | 2 +- ...port-alias-issue-121168.edition2021.stderr | 2 +- tests/ui/imports/import-alias-issue-121168.rs | 2 +- tests/ui/imports/import-glob-0.rs | 2 +- tests/ui/imports/import-glob-0.stderr | 2 +- tests/ui/imports/import-glob-circular.rs | 2 +- tests/ui/imports/import-glob-circular.stderr | 2 +- tests/ui/imports/inaccessible_type_aliases.rs | 4 +- .../imports/inaccessible_type_aliases.stderr | 4 +- tests/ui/imports/issue-4366-2.rs | 2 +- tests/ui/imports/issue-4366-2.stderr | 2 +- tests/ui/imports/issue-4366.rs | 2 +- tests/ui/imports/issue-4366.stderr | 2 +- tests/ui/imports/issue-59764.rs | 2 +- tests/ui/imports/issue-59764.stderr | 2 +- tests/ui/issues-71798.rs | 2 +- tests/ui/issues-71798.stderr | 2 +- tests/ui/issues/issue-15167.rs | 8 ++-- tests/ui/issues/issue-15167.stderr | 8 ++-- tests/ui/issues/issue-18058.rs | 2 +- tests/ui/issues/issue-18058.stderr | 2 +- tests/ui/issues/issue-19734.rs | 2 +- tests/ui/issues/issue-2281-part1.rs | 2 +- tests/ui/issues/issue-2281-part1.stderr | 2 +- tests/ui/issues/issue-30589.rs | 2 +- tests/ui/issues/issue-30589.stderr | 2 +- tests/ui/issues/issue-32655.rs | 4 +- tests/ui/issues/issue-32950.rs | 2 +- tests/ui/issues/issue-32950.stderr | 2 +- tests/ui/issues/issue-33525.stderr | 2 +- tests/ui/issues/issue-33571.rs | 4 +- tests/ui/issues/issue-36836.rs | 2 +- tests/ui/issues/issue-36836.stderr | 2 +- tests/ui/issues/issue-40845.rs | 4 +- tests/ui/issues/issue-46332.rs | 2 +- tests/ui/issues/issue-46332.stderr | 2 +- tests/ui/issues/issue-53300.rs | 2 +- tests/ui/issues/issue-53300.stderr | 2 +- tests/ui/issues/issue-58712.rs | 4 +- tests/ui/issues/issue-58712.stderr | 4 +- .../issues/issue-72839-error-overflow.stderr | 2 +- tests/ui/issues/issue-77919.rs | 4 +- tests/ui/issues/issue-77919.stderr | 4 +- tests/ui/issues/issue-86756.rs | 2 +- tests/ui/issues/issue-86756.stderr | 2 +- tests/ui/issues/issue-8767.rs | 2 +- tests/ui/issues/issue-8767.stderr | 2 +- .../ui/keyword/keyword-self-as-identifier.rs | 2 +- .../keyword/keyword-self-as-identifier.stderr | 2 +- tests/ui/label/label_misspelled.rs | 16 +++---- tests/ui/label/label_misspelled.stderr | 16 +++---- tests/ui/label/label_misspelled_2.rs | 4 +- tests/ui/label/label_misspelled_2.stderr | 4 +- tests/ui/lang-items/issue-83471.stderr | 2 +- .../cannot-transmute-unnormalizable-type.rs | 2 +- ...annot-transmute-unnormalizable-type.stderr | 2 +- tests/ui/layout/issue-84108.rs | 4 +- tests/ui/layout/issue-84108.stderr | 4 +- .../layout/malformed-unsized-type-in-union.rs | 2 +- .../malformed-unsized-type-in-union.stderr | 2 +- tests/ui/layout/transmute-to-tail-with-err.rs | 2 +- .../layout/transmute-to-tail-with-err.stderr | 2 +- tests/ui/let-else/let-else-scope.rs | 2 +- tests/ui/let-else/let-else-scope.stderr | 2 +- .../issue-83907-invalid-fn-like-path.stderr | 2 +- .../lint/internal/trivial-diagnostics.stderr | 4 +- tests/ui/lint/issue-35075.rs | 4 +- tests/ui/lint/issue-35075.stderr | 4 +- tests/ui/lint/recommend-literal.rs | 18 +++---- tests/ui/lint/recommend-literal.stderr | 18 +++---- tests/ui/lint/use_suggestion_json.stderr | 4 +- tests/ui/loops/loop-break-value.rs | 2 +- tests/ui/loops/loop-break-value.stderr | 2 +- tests/ui/lowering/span-bug-issue-121431.rs | 2 +- .../ui/lowering/span-bug-issue-121431.stderr | 2 +- .../ui/macros/defined-later-issue-121061-2.rs | 2 +- tests/ui/macros/defined-later-issue-121061.rs | 2 +- tests/ui/macros/expand-full-no-resolution.rs | 4 +- tests/ui/macros/issue-100199.rs | 2 +- tests/ui/macros/issue-100199.stderr | 2 +- tests/ui/macros/issue-11692-1.rs | 2 +- tests/ui/macros/issue-11692-2.rs | 2 +- tests/ui/macros/issue-118786.rs | 2 +- tests/ui/macros/macro-backtrace-nested.stderr | 4 +- tests/ui/macros/macro-context.rs | 4 +- tests/ui/macros/macro-context.stderr | 4 +- .../macro-expand-within-generics-in-path.rs | 2 +- .../macro-metavar-expr-concat/hygiene.rs | 2 +- .../macro-metavar-expr-concat/hygiene.stderr | 2 +- tests/ui/macros/macro-outer-attributes.rs | 2 +- tests/ui/macros/macro-outer-attributes.stderr | 4 +- tests/ui/macros/macro-parameter-span.rs | 2 +- tests/ui/macros/macro-parameter-span.stderr | 2 +- tests/ui/macros/macro-path-prelude-fail-3.rs | 2 +- tests/ui/macros/macro-reexport-removed.rs | 2 +- .../rfc-3086-metavar-expr/syntax-errors.rs | 12 ++--- .../syntax-errors.stderr | 12 ++--- tests/ui/match/expr_before_ident_pat.rs | 2 +- tests/ui/match/expr_before_ident_pat.stderr | 2 +- tests/ui/match/issue-82866.rs | 4 +- tests/ui/match/issue-82866.stderr | 4 +- tests/ui/match/issue-92100.rs | 2 +- tests/ui/match/issue-92100.stderr | 2 +- tests/ui/match/match-join.rs | 2 +- tests/ui/match/match-join.stderr | 2 +- ...ggest-method-on-call-for-ambig-receiver.rs | 2 +- ...t-method-on-call-for-ambig-receiver.stderr | 2 +- .../suggest-method-on-call-with-macro-rcvr.rs | 2 +- ...gest-method-on-call-with-macro-rcvr.stderr | 2 +- .../issue-83499-input-output-iteration-ice.rs | 2 +- ...ue-83499-input-output-iteration-ice.stderr | 2 +- ...build-2021-closure-capture-ice-110453-1.rs | 2 +- ...d-2021-closure-capture-ice-110453-1.stderr | 2 +- ...build-2021-closure-capture-ice-110453-2.rs | 2 +- ...d-2021-closure-capture-ice-110453-2.stderr | 2 +- tests/ui/mir/validate/error-body.rs | 2 +- tests/ui/mir/validate/error-body.stderr | 2 +- .../missing-items/missing-const-parameter.rs | 10 ++-- .../missing-const-parameter.stderr | 10 ++-- .../missing-items/missing-type-parameter2.rs | 10 ++-- .../missing-type-parameter2.stderr | 10 ++-- tests/ui/missing/missing-macro-use.rs | 2 +- .../mod_file_correct_spans.rs | 2 +- .../mod_file_correct_spans.stderr | 4 +- ...spaced-enum-glob-import-no-impls-xcrate.rs | 8 ++-- ...ed-enum-glob-import-no-impls-xcrate.stderr | 12 ++--- .../namespaced-enum-glob-import-no-impls.rs | 8 ++-- ...amespaced-enum-glob-import-no-impls.stderr | 12 ++--- tests/ui/nested-cfg-attrs.rs | 2 +- tests/ui/nested-cfg-attrs.stderr | 2 +- .../avoid-ice-on-warning.new.stderr | 2 +- .../avoid-ice-on-warning.old.stderr | 2 +- .../ui/object-safety/avoid-ice-on-warning.rs | 2 +- tests/ui/object-safety/erroneous_signature.rs | 4 +- .../object-safety/erroneous_signature.stderr | 4 +- tests/ui/offset-of/offset-of-enum.rs | 2 +- tests/ui/offset-of/offset-of-enum.stderr | 2 +- tests/ui/offset-of/offset-of-self.rs | 4 +- tests/ui/offset-of/offset-of-self.stderr | 6 +-- tests/ui/panics/default-backtrace-ice.stderr | 2 +- .../multiple-tail-expr-behind-cfg.rs | 2 +- tests/ui/parser/circular_modules_main.stderr | 4 +- ...onst-param-decl-on-type-instead-of-impl.rs | 2 +- ...-param-decl-on-type-instead-of-impl.stderr | 2 +- tests/ui/parser/default-unmatched-assoc.rs | 4 +- tests/ui/parser/default-unmatched-extern.rs | 2 +- tests/ui/parser/dyn-trait-compatibility.rs | 14 +++--- .../ui/parser/dyn-trait-compatibility.stderr | 14 +++--- tests/ui/parser/emoji-identifiers.rs | 2 +- tests/ui/parser/emoji-identifiers.stderr | 2 +- tests/ui/parser/fn-field-parse-error-ice.rs | 2 +- .../ui/parser/fn-field-parse-error-ice.stderr | 2 +- tests/ui/parser/issues/issue-103143.rs | 2 +- tests/ui/parser/issues/issue-103143.stderr | 2 +- .../issues/issue-103748-ICE-wrong-braces.rs | 2 +- .../issue-103748-ICE-wrong-braces.stderr | 2 +- tests/ui/parser/issues/issue-112458.rs | 2 +- tests/ui/parser/issues/issue-112458.stderr | 2 +- tests/ui/parser/issues/issue-118531-ice.rs | 2 +- tests/ui/parser/issues/issue-32505.rs | 2 +- tests/ui/parser/issues/issue-32505.stderr | 2 +- .../issue-65122-mac-invoc-in-mut-patterns.rs | 4 +- tests/ui/parser/kw-in-trait-bounds.rs | 8 ++-- tests/ui/parser/kw-in-trait-bounds.stderr | 8 ++-- ...ultibyte-char-use-seperator-issue-80134.rs | 4 +- ...byte-char-use-seperator-issue-80134.stderr | 4 +- tests/ui/parser/not-a-pred.rs | 2 +- tests/ui/parser/not-a-pred.stderr | 2 +- tests/ui/parser/pat-lt-bracket-5.rs | 2 +- tests/ui/parser/pat-lt-bracket-5.stderr | 2 +- tests/ui/parser/raw/raw-literal-keywords.rs | 6 +-- .../ui/parser/raw/raw-literal-keywords.stderr | 6 +-- .../recover/recover-fn-ptr-with-generics.rs | 4 +- .../recover-fn-ptr-with-generics.stderr | 4 +- .../ui/parser/recover/recover-ref-dyn-mut.rs | 2 +- .../parser/recover/recover-ref-dyn-mut.stderr | 2 +- .../recover/recover-unticked-labels.fixed | 2 +- .../parser/recover/recover-unticked-labels.rs | 2 +- .../recover/recover-unticked-labels.stderr | 2 +- .../parser/trailing-question-in-macro-type.rs | 2 +- .../trailing-question-in-macro-type.stderr | 2 +- tests/ui/parser/unmatched-langle-1.rs | 4 +- tests/ui/parser/unmatched-langle-1.stderr | 4 +- tests/ui/parser/where_with_bound.rs | 2 +- tests/ui/parser/where_with_bound.stderr | 2 +- ...-pattern-meant-to-be-slice-rest-pattern.rs | 12 ++--- ...tern-meant-to-be-slice-rest-pattern.stderr | 12 ++--- .../issue-119493-type-error-ice.stderr | 4 +- .../issue-119778-type-error-ice.stderr | 4 +- tests/ui/privacy/privacy-ns1.rs | 4 +- tests/ui/privacy/privacy-ns1.stderr | 4 +- .../ambiguous-builtin-attrs-test.rs | 2 +- .../ambiguous-builtin-attrs-test.stderr | 2 +- .../ui/proc-macro/ambiguous-builtin-attrs.rs | 2 +- .../proc-macro/ambiguous-builtin-attrs.stderr | 2 +- .../proc-macro/attributes-on-modules-fail.rs | 4 +- .../attributes-on-modules-fail.stderr | 4 +- tests/ui/proc-macro/break-token-spans.stderr | 2 +- .../proc-macro/derive-helper-legacy-limits.rs | 2 +- .../derive-helper-legacy-spurious.rs | 4 +- .../ui/proc-macro/derive-helper-shadowing.rs | 4 +- tests/ui/proc-macro/derive-still-gated.rs | 2 +- .../ui/proc-macro/disappearing-resolution.rs | 2 +- tests/ui/proc-macro/empty-where-clause.stderr | 6 +-- .../ui/proc-macro/gen-macro-rules-hygiene.rs | 4 +- .../proc-macro/gen-macro-rules-hygiene.stderr | 4 +- tests/ui/proc-macro/generate-mod.rs | 16 +++---- tests/ui/proc-macro/generate-mod.stderr | 8 ++-- .../issue-118455-skip-err-builtin.rs | 2 +- tests/ui/proc-macro/issue-38586.stderr | 2 +- tests/ui/proc-macro/issue-83510.rs | 4 +- tests/ui/proc-macro/issue-83510.stderr | 4 +- tests/ui/proc-macro/keep-expr-tokens.stderr | 4 +- tests/ui/proc-macro/lints_in_proc_macros.rs | 2 +- .../ui/proc-macro/lints_in_proc_macros.stderr | 2 +- .../proc-macro/macro-namespace-reserved-2.rs | 10 ++-- tests/ui/proc-macro/macro-rules-derive.stderr | 2 +- tests/ui/proc-macro/mixed-site-span.rs | 6 +-- tests/ui/proc-macro/mixed-site-span.stderr | 8 ++-- tests/ui/proc-macro/parent-source-spans.rs | 6 +-- .../ui/proc-macro/parent-source-spans.stderr | 6 +-- tests/ui/proc-macro/proc-macro-attributes.rs | 2 +- tests/ui/proc-macro/resolve-error.rs | 4 +- .../ui/proc-macro/span-from-proc-macro.stderr | 6 +-- tests/ui/proc-macro/weird-hygiene.stderr | 4 +- tests/ui/query-system/issue-83479.rs | 4 +- tests/ui/query-system/issue-83479.stderr | 4 +- tests/ui/recursion/recursive-reexports.rs | 2 +- tests/ui/recursion/recursive-reexports.stderr | 4 +- tests/ui/regions/outlives-with-missing.rs | 2 +- tests/ui/regions/outlives-with-missing.stderr | 2 +- tests/ui/reserved/reserved-attr-on-macro.rs | 2 +- .../resolve/associated-fn-called-as-fn.stderr | 4 +- tests/ui/resolve/bad-env-capture.stderr | 4 +- tests/ui/resolve/bad-env-capture2.stderr | 4 +- tests/ui/resolve/bad-env-capture3.stderr | 4 +- tests/ui/resolve/bad-expr-path.rs | 6 +-- tests/ui/resolve/bad-expr-path.stderr | 8 ++-- tests/ui/resolve/bad-expr-path2.rs | 4 +- tests/ui/resolve/bad-expr-path2.stderr | 4 +- tests/ui/resolve/crate-called-as-function.rs | 2 +- .../resolve/crate-called-as-function.stderr | 2 +- tests/ui/resolve/crate-in-paths.rs | 2 +- tests/ui/resolve/crate-in-paths.stderr | 2 +- tests/ui/resolve/editions-crate-root-2015.rs | 4 +- .../resolve/editions-crate-root-2015.stderr | 4 +- tests/ui/resolve/editions-crate-root-2018.rs | 8 ++-- .../resolve/editions-crate-root-2018.stderr | 4 +- .../ui/resolve/enums-are-namespaced-xc.stderr | 12 ++--- tests/ui/resolve/enums-pats-not-idents.rs | 2 +- tests/ui/resolve/enums-pats-not-idents.stderr | 2 +- ...ethod-in-self-not-available-in-assoc-fn.rs | 6 +-- ...d-in-self-not-available-in-assoc-fn.stderr | 6 +-- tests/ui/resolve/filter-intrinsics.stderr | 4 +- tests/ui/resolve/issue-102946.rs | 2 +- tests/ui/resolve/issue-102946.stderr | 2 +- tests/ui/resolve/issue-103474.rs | 6 +-- tests/ui/resolve/issue-103474.stderr | 6 +-- .../resolve/issue-104700-inner_scope.stderr | 4 +- tests/ui/resolve/issue-116164.rs | 2 +- tests/ui/resolve/issue-116164.stderr | 2 +- tests/ui/resolve/issue-118295.rs | 2 +- tests/ui/resolve/issue-14254.stderr | 48 +++++++++---------- tests/ui/resolve/issue-17518.stderr | 2 +- tests/ui/resolve/issue-21221-1.stderr | 8 ++-- tests/ui/resolve/issue-21221-2.stderr | 2 +- tests/ui/resolve/issue-21221-3.stderr | 2 +- tests/ui/resolve/issue-21221-4.stderr | 2 +- tests/ui/resolve/issue-2356.rs | 2 +- tests/ui/resolve/issue-2356.stderr | 30 ++++++------ tests/ui/resolve/issue-24968.stderr | 10 ++-- tests/ui/resolve/issue-26545.rs | 2 +- tests/ui/resolve/issue-26545.stderr | 2 +- tests/ui/resolve/issue-31845.rs | 2 +- tests/ui/resolve/issue-31845.stderr | 2 +- tests/ui/resolve/issue-35675.rs | 8 ++-- tests/ui/resolve/issue-35675.stderr | 8 ++-- tests/ui/resolve/issue-42944.rs | 2 +- tests/ui/resolve/issue-42944.stderr | 2 +- tests/ui/resolve/issue-49074.rs | 4 +- tests/ui/resolve/issue-50599.stderr | 4 +- tests/ui/resolve/issue-5099.rs | 6 +-- tests/ui/resolve/issue-5099.stderr | 6 +-- tests/ui/resolve/issue-5927.rs | 4 +- tests/ui/resolve/issue-5927.stderr | 4 +- tests/ui/resolve/issue-60057.rs | 4 +- tests/ui/resolve/issue-60057.stderr | 4 +- .../issue-69401-trait-fn-no-body-ty-local.rs | 2 +- ...sue-69401-trait-fn-no-body-ty-local.stderr | 2 +- tests/ui/resolve/issue-80079.rs | 2 +- tests/ui/resolve/issue-80079.stderr | 2 +- tests/ui/resolve/issue-85348.rs | 2 +- tests/ui/resolve/issue-85348.stderr | 2 +- tests/ui/resolve/issue-88472.rs | 8 ++-- tests/ui/resolve/issue-88472.stderr | 4 +- tests/ui/resolve/issue-90113.rs | 2 +- tests/ui/resolve/issue-90113.stderr | 2 +- tests/ui/resolve/levenshtein.stderr | 16 +++---- .../ui/resolve/no-implicit-prelude-nested.rs | 30 ++++++------ .../resolve/no-implicit-prelude-nested.stderr | 30 ++++++------ tests/ui/resolve/no-implicit-prelude.rs | 10 ++-- tests/ui/resolve/no-implicit-prelude.stderr | 10 ++-- tests/ui/resolve/privacy-enum-ctor.rs | 8 ++-- tests/ui/resolve/privacy-enum-ctor.stderr | 8 ++-- tests/ui/resolve/raw-ident-in-path.rs | 2 +- tests/ui/resolve/raw-ident-in-path.stderr | 2 +- .../resolve/resolve-assoc-suggestions.stderr | 18 +++---- .../ui/resolve/resolve-primitive-fallback.rs | 2 +- .../resolve/resolve-primitive-fallback.stderr | 2 +- tests/ui/resolve/resolve-self-in-impl-2.rs | 2 +- .../ui/resolve/resolve-self-in-impl-2.stderr | 2 +- .../resolve-speculative-adjustment.stderr | 8 ++-- tests/ui/resolve/resolve-unknown-trait.rs | 6 +-- tests/ui/resolve/resolve-unknown-trait.stderr | 6 +-- ...gest-import-without-clobbering-attrs.fixed | 2 +- ...suggest-import-without-clobbering-attrs.rs | 2 +- ...est-import-without-clobbering-attrs.stderr | 2 +- ...iable-with-name-similar-to-struct-field.rs | 10 ++-- ...e-with-name-similar-to-struct-field.stderr | 14 +++--- .../typo-suggestion-named-underscore.rs | 4 +- .../typo-suggestion-named-underscore.stderr | 4 +- ...xed-closure-sugar-nonexistent-trait.stderr | 2 +- .../resolve/unresolved_static_type_field.rs | 2 +- .../unresolved_static_type_field.stderr | 2 +- tests/ui/resolve/use_suggestion.stderr | 4 +- .../resolve/use_suggestion_placement.stderr | 6 +-- tests/ui/resolve/visibility-indeterminate.rs | 2 +- .../rfc-2294-if-let-guard/bindings.stderr | 4 +- .../ice-120503-async-const-method.stderr | 2 +- tests/ui/rmeta/rmeta.rs | 2 +- tests/ui/rmeta/rmeta.stderr | 2 +- .../rust-2018/issue-52202-use-suggestions.rs | 2 +- .../issue-52202-use-suggestions.stderr | 2 +- tests/ui/rustdoc/cfg-rustdoc.stderr | 2 +- tests/ui/self/class-missing-self.rs | 4 +- tests/ui/self/class-missing-self.stderr | 4 +- tests/ui/self/elision/nested-item.rs | 2 +- tests/ui/self/elision/nested-item.stderr | 2 +- tests/ui/self/self_type_keyword-2.rs | 6 +-- tests/ui/self/self_type_keyword-2.stderr | 6 +-- tests/ui/self/self_type_keyword.rs | 2 +- tests/ui/self/self_type_keyword.stderr | 2 +- tests/ui/self/suggest-self-2.rs | 8 ++-- tests/ui/self/suggest-self-2.stderr | 8 ++-- tests/ui/self/suggest-self.rs | 6 +-- tests/ui/self/suggest-self.stderr | 6 +-- ...dings-in-pattern-with-ty-err-doesnt-ice.rs | 2 +- ...s-in-pattern-with-ty-err-doesnt-ice.stderr | 2 +- ...021-incompatible-closure-captures-96258.rs | 2 +- ...incompatible-closure-captures-96258.stderr | 2 +- tests/ui/span/suggestion-raw-68962.stderr | 4 +- tests/ui/span/typo-suggestion.stderr | 4 +- .../issue-68830-spurious-diagnostics.rs | 2 +- .../issue-68830-spurious-diagnostics.stderr | 2 +- .../min_specialization/impl-on-nonexisting.rs | 2 +- .../impl-on-nonexisting.stderr | 2 +- tests/ui/stability-attribute/issue-109177.rs | 2 +- .../stability-attribute/issue-109177.stderr | 2 +- .../unresolved_stability_lint.rs | 2 +- .../unresolved_stability_lint.stderr | 2 +- .../ice-struct-tail-normalization-113272.rs | 2 +- ...ce-struct-tail-normalization-113272.stderr | 2 +- .../struct-fields-shorthand-unresolved.rs | 2 +- .../struct-fields-shorthand-unresolved.stderr | 2 +- .../ui/structs/unresolved-struct-with-fru.rs | 2 +- .../structs/unresolved-struct-with-fru.stderr | 2 +- .../suggestions/assoc-const-without-self.rs | 2 +- .../assoc-const-without-self.stderr | 2 +- .../assoc-type-in-method-return.rs | 2 +- .../assoc-type-in-method-return.stderr | 2 +- tests/ui/suggestions/assoc_fn_without_self.rs | 16 +++---- .../suggestions/assoc_fn_without_self.stderr | 16 +++---- tests/ui/suggestions/attribute-typos.rs | 6 +-- tests/ui/suggestions/bool_typo_err_suggest.rs | 4 +- .../suggestions/bool_typo_err_suggest.stderr | 4 +- .../dont-suggest-foreign-doc-hidden.rs | 4 +- .../dont-suggest-foreign-doc-hidden.stderr | 4 +- .../suggestions/fn-to-method-deeply-nested.rs | 12 ++--- .../fn-to-method-deeply-nested.stderr | 12 ++--- tests/ui/suggestions/fn-to-method.rs | 6 +-- tests/ui/suggestions/fn-to-method.stderr | 6 +-- .../ice-unwrap-probe-many-result-125876.rs | 2 +- ...ice-unwrap-probe-many-result-125876.stderr | 2 +- tests/ui/suggestions/if-let-typo.rs | 4 +- tests/ui/suggestions/if-let-typo.stderr | 4 +- .../suggestions/issue-104086-suggest-let.rs | 34 ++++++------- .../issue-104086-suggest-let.stderr | 34 ++++++------- tests/ui/suggestions/issue-104287.rs | 2 +- tests/ui/suggestions/issue-104287.stderr | 2 +- .../issue-66968-suggest-sorted-words.stderr | 2 +- ...method-access-to-range-literal-typo.stderr | 2 +- .../no-extern-crate-in-type.stderr | 2 +- tests/ui/suggestions/non_ascii_ident.rs | 4 +- tests/ui/suggestions/non_ascii_ident.stderr | 4 +- .../ui/suggestions/raw-name-use-suggestion.rs | 2 +- .../raw-name-use-suggestion.stderr | 2 +- .../suggestions/silenced-binding-typo.stderr | 2 +- .../suggest-let-for-assignment.fixed | 22 ++++----- .../suggestions/suggest-let-for-assignment.rs | 22 ++++----- .../suggest-let-for-assignment.stderr | 22 ++++----- .../suggestions/suggest_print_over_printf.rs | 2 +- .../suggest_print_over_printf.stderr | 2 +- ...type-ascription-instead-of-path-in-type.rs | 2 +- ...-ascription-instead-of-path-in-type.stderr | 2 +- .../type-not-found-in-adt-field.rs | 8 ++-- .../type-not-found-in-adt-field.stderr | 4 +- tests/ui/suggestions/while-let-typo.rs | 4 +- tests/ui/suggestions/while-let-typo.stderr | 4 +- .../tool-attributes-misplaced-1.rs | 8 ++-- tests/ui/track-diagnostics/track.stderr | 2 +- tests/ui/track-diagnostics/track3.stderr | 2 +- .../ice-unsized-struct-arg-issue-121612.rs | 4 +- ...ice-unsized-struct-arg-issue-121612.stderr | 4 +- .../ice-unsized-tuple-const-issue-121443.rs | 2 +- ...ce-unsized-tuple-const-issue-121443.stderr | 2 +- .../impl-bound-with-references-error.rs | 2 +- .../impl-bound-with-references-error.stderr | 2 +- ...owed-path-in-trait-bound-suggestion.stderr | 2 +- .../assoc_type_bound_with_struct.rs | 2 +- .../assoc_type_bound_with_struct.stderr | 2 +- .../dont-autoderef-ty-with-escaping-var.rs | 2 +- ...dont-autoderef-ty-with-escaping-var.stderr | 2 +- ...alller-supplied-obligation-issue-121941.rs | 2 +- ...er-supplied-obligation-issue-121941.stderr | 2 +- tests/ui/traits/ignore-err-impls.rs | 2 +- tests/ui/traits/ignore-err-impls.stderr | 2 +- tests/ui/traits/issue-22384.rs | 2 +- tests/ui/traits/issue-22384.stderr | 4 +- tests/ui/traits/issue-50480.rs | 12 ++--- tests/ui/traits/issue-50480.stderr | 12 ++--- tests/ui/traits/issue-75627.stderr | 2 +- tests/ui/traits/issue-78372.rs | 6 +-- tests/ui/traits/issue-78372.stderr | 6 +-- .../dont-normalize-proj-with-error.rs | 2 +- .../dont-normalize-proj-with-error.stderr | 2 +- .../next-solver/issue-118950-root-region.rs | 2 +- .../issue-118950-root-region.stderr | 2 +- tests/ui/traits/no-fallback-multiple-impls.rs | 2 +- .../traits/no-fallback-multiple-impls.stderr | 2 +- .../binder-defaults-112547.rs | 2 +- .../binder-defaults-112547.stderr | 2 +- .../binder-defaults-118697.rs | 2 +- .../binder-defaults-118697.stderr | 2 +- tests/ui/traits/trait-selection-ice-84727.rs | 8 ++-- .../traits/trait-selection-ice-84727.stderr | 8 ++-- tests/ui/transmutability/issue-101739-1.rs | 2 +- .../ui/transmutability/issue-101739-1.stderr | 2 +- .../unknown_dst.stderr | 2 +- .../unknown_src.stderr | 2 +- .../unknown_src_field.stderr | 2 +- tests/ui/tuple/tuple-struct-fields/test.rs | 2 +- .../ui/tuple/tuple-struct-fields/test.stderr | 2 +- tests/ui/tuple/tuple-struct-fields/test2.rs | 4 +- .../ui/tuple/tuple-struct-fields/test2.stderr | 4 +- tests/ui/tuple/tuple-struct-fields/test3.rs | 4 +- .../ui/tuple/tuple-struct-fields/test3.stderr | 4 +- .../nested-impl-trait-in-tait.rs | 2 +- .../nested-impl-trait-in-tait.stderr | 2 +- .../ui/type-alias/issue-62364-self-ty-arg.rs | 2 +- .../type-alias/issue-62364-self-ty-arg.stderr | 2 +- tests/ui/type/issue-7607-1.rs | 2 +- tests/ui/type/issue-7607-1.stderr | 2 +- tests/ui/type/type-path-err-node-types.rs | 2 +- tests/ui/type/type-path-err-node-types.stderr | 8 ++-- .../ui/typeck/apit-with-error-type-in-sig.rs | 2 +- .../typeck/apit-with-error-type-in-sig.stderr | 2 +- .../typeck/autoderef-with-param-env-error.rs | 2 +- .../autoderef-with-param-env-error.stderr | 2 +- tests/ui/typeck/check-args-on-fn-err-2.rs | 2 +- tests/ui/typeck/check-args-on-fn-err-2.stderr | 2 +- tests/ui/typeck/check-args-on-fn-err.rs | 2 +- tests/ui/typeck/check-args-on-fn-err.stderr | 2 +- tests/ui/typeck/issue-104510-ice.rs | 2 +- tests/ui/typeck/issue-104510-ice.stderr | 2 +- tests/ui/typeck/issue-104513-ice.rs | 2 +- tests/ui/typeck/issue-104513-ice.stderr | 2 +- tests/ui/typeck/issue-105946.rs | 2 +- tests/ui/typeck/issue-105946.stderr | 2 +- tests/ui/typeck/issue-106929.rs | 2 +- tests/ui/typeck/issue-106929.stderr | 2 +- ...sue-114423-ice-regression-in-suggestion.rs | 6 +-- ...114423-ice-regression-in-suggestion.stderr | 6 +-- tests/ui/typeck/issue-83693.rs | 6 +-- tests/ui/typeck/issue-83693.stderr | 6 +-- tests/ui/typeck/issue-88844.rs | 2 +- tests/ui/typeck/issue-88844.stderr | 2 +- tests/ui/typeck/issue-90319.rs | 2 +- tests/ui/typeck/issue-90319.stderr | 2 +- tests/ui/typeck/issue-91267.rs | 2 +- tests/ui/typeck/issue-91267.stderr | 2 +- .../typeck/nonexistent-field-not-ambiguous.rs | 2 +- .../nonexistent-field-not-ambiguous.stderr | 2 +- tests/ui/typeck/quiet-type-err-let-binding.rs | 2 +- .../typeck/quiet-type-err-let-binding.stderr | 2 +- tests/ui/ufcs/ufcs-partially-resolved.rs | 20 ++++---- tests/ui/ufcs/ufcs-partially-resolved.stderr | 28 +++++------ ...mismatch-closure-from-another-scope.stderr | 4 +- tests/ui/union/unresolved-field-isnt-copy.rs | 2 +- .../union/unresolved-field-isnt-copy.stderr | 2 +- tests/ui/unresolved/unresolved-candidates.rs | 2 +- .../unresolved/unresolved-candidates.stderr | 2 +- ...ce-hir-wf-check-anon-const-issue-122199.rs | 4 +- ...ir-wf-check-anon-const-issue-122199.stderr | 4 +- tests/ui/wf/issue-110157.rs | 4 +- tests/ui/wf/issue-110157.stderr | 4 +- tests/ui/where-clauses/ignore-err-clauses.rs | 2 +- .../where-clauses/ignore-err-clauses.stderr | 2 +- .../normalization-of-unknown-type.stderr | 2 +- 741 files changed, 1593 insertions(+), 1593 deletions(-) diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 941fb6436df92..6cbf5fce1786f 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -347,11 +347,11 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { } else { suggestion }; - (format!("not found in {mod_str}"), override_suggestion) + (format!("not found in {mod_prefix}{mod_str}"), override_suggestion) }; BaseError { - msg: format!("cannot find {expected} `{item_str}` in {mod_prefix}{mod_str}"), + msg: format!("cannot find {expected} `{item_str}`"), fallback_label, span: item_span, span_label, diff --git a/src/tools/clippy/tests/ui/crashes/ice-6252.stderr b/src/tools/clippy/tests/ui/crashes/ice-6252.stderr index cd2031af1c6da..067809c7cd6f6 100644 --- a/src/tools/clippy/tests/ui/crashes/ice-6252.stderr +++ b/src/tools/clippy/tests/ui/crashes/ice-6252.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `PhantomData` in this scope +error[E0412]: cannot find type `PhantomData` --> tests/ui/crashes/ice-6252.rs:9:9 | LL | _n: PhantomData, @@ -9,7 +9,7 @@ help: consider importing this struct LL + use std::marker::PhantomData; | -error[E0412]: cannot find type `VAL` in this scope +error[E0412]: cannot find type `VAL` --> tests/ui/crashes/ice-6252.rs:11:63 | LL | impl TypeVal for Multiply where N: TypeVal {} diff --git a/src/tools/clippy/tests/ui/option_map_unit_fn_unfixable.stderr b/src/tools/clippy/tests/ui/option_map_unit_fn_unfixable.stderr index 66271036113ca..b49d182b64567 100644 --- a/src/tools/clippy/tests/ui/option_map_unit_fn_unfixable.stderr +++ b/src/tools/clippy/tests/ui/option_map_unit_fn_unfixable.stderr @@ -1,22 +1,22 @@ -error[E0425]: cannot find value `x` in this scope +error[E0425]: cannot find value `x` --> tests/ui/option_map_unit_fn_unfixable.rs:17:5 | LL | x.field.map(|value| { do_nothing(value); do_nothing(value) }); | ^ not found in this scope -error[E0425]: cannot find value `x` in this scope +error[E0425]: cannot find value `x` --> tests/ui/option_map_unit_fn_unfixable.rs:19:5 | LL | x.field.map(|value| if value > 0 { do_nothing(value); do_nothing(value) }); | ^ not found in this scope -error[E0425]: cannot find value `x` in this scope +error[E0425]: cannot find value `x` --> tests/ui/option_map_unit_fn_unfixable.rs:23:5 | LL | x.field.map(|value| { | ^ not found in this scope -error[E0425]: cannot find value `x` in this scope +error[E0425]: cannot find value `x` --> tests/ui/option_map_unit_fn_unfixable.rs:27:5 | LL | x.field.map(|value| { do_nothing(value); do_nothing(value); }); diff --git a/tests/rustdoc-ui/doctest/failed-doctest-output-windows.stdout b/tests/rustdoc-ui/doctest/failed-doctest-output-windows.stdout index 1b37249dd60f9..b9d0614821ca3 100644 --- a/tests/rustdoc-ui/doctest/failed-doctest-output-windows.stdout +++ b/tests/rustdoc-ui/doctest/failed-doctest-output-windows.stdout @@ -6,7 +6,7 @@ test $DIR/failed-doctest-output-windows.rs - SomeStruct (line 15) ... FAILED failures: ---- $DIR/failed-doctest-output-windows.rs - OtherStruct (line 25) stdout ---- -error[E0425]: cannot find value `no` in this scope +error[E0425]: cannot find value `no` --> $DIR/failed-doctest-output-windows.rs:26:1 | LL | no diff --git a/tests/rustdoc-ui/doctest/failed-doctest-output.stdout b/tests/rustdoc-ui/doctest/failed-doctest-output.stdout index 7b0cf9a432d4c..4c7233a296060 100644 --- a/tests/rustdoc-ui/doctest/failed-doctest-output.stdout +++ b/tests/rustdoc-ui/doctest/failed-doctest-output.stdout @@ -6,7 +6,7 @@ test $DIR/failed-doctest-output.rs - SomeStruct (line 15) ... FAILED failures: ---- $DIR/failed-doctest-output.rs - OtherStruct (line 25) stdout ---- -error[E0425]: cannot find value `no` in this scope +error[E0425]: cannot find value `no` --> $DIR/failed-doctest-output.rs:26:1 | LL | no diff --git a/tests/rustdoc-ui/impl-fn-nesting.rs b/tests/rustdoc-ui/impl-fn-nesting.rs index a927f6bd79976..38275ebcc6c32 100644 --- a/tests/rustdoc-ui/impl-fn-nesting.rs +++ b/tests/rustdoc-ui/impl-fn-nesting.rs @@ -9,28 +9,28 @@ pub trait NeedsBody { /// This function has docs pub fn f(a: UnknownType, b: B) { -//~^ ERROR cannot find trait `UnknownBound` in this scope -//~| ERROR cannot find type `UnknownType` in this scope +//~^ ERROR cannot find trait `UnknownBound` +//~| ERROR cannot find type `UnknownType` impl UnknownTrait for ValidType {} //~ ERROR cannot find trait `UnknownTrait` impl UnknownTrait for T {} - //~^ ERROR cannot find trait `UnknownBound` in this scope - //~| ERROR cannot find trait `UnknownTrait` in this scope + //~^ ERROR cannot find trait `UnknownBound` + //~| ERROR cannot find trait `UnknownTrait` impl ValidTrait for UnknownType {} - //~^ ERROR cannot find type `UnknownType` in this scope + //~^ ERROR cannot find type `UnknownType` impl ValidTrait for ValidType where ValidTrait: UnknownBound {} - //~^ ERROR cannot find trait `UnknownBound` in this scope + //~^ ERROR cannot find trait `UnknownBound` /// This impl has documentation impl NeedsBody for ValidType { type Item = UnknownType; - //~^ ERROR cannot find type `UnknownType` in this scope + //~^ ERROR cannot find type `UnknownType` /// This function has documentation fn f() { ::a(); content::shouldnt::matter(); unknown_macro!(); - //~^ ERROR cannot find macro `unknown_macro` in this scope + //~^ ERROR cannot find macro `unknown_macro` /// This is documentation for a macro macro_rules! can_define_macros_here_too { @@ -42,7 +42,7 @@ pub fn f(a: UnknownType, b: B) { /// This also is documented. pub fn doubly_nested(c: UnknownType) { - //~^ ERROR cannot find type `UnknownType` in this scope + //~^ ERROR cannot find type `UnknownType` } } } diff --git a/tests/rustdoc-ui/impl-fn-nesting.stderr b/tests/rustdoc-ui/impl-fn-nesting.stderr index 75e6b4ed217dd..8723380894f29 100644 --- a/tests/rustdoc-ui/impl-fn-nesting.stderr +++ b/tests/rustdoc-ui/impl-fn-nesting.stderr @@ -4,55 +4,55 @@ error: cannot find macro `unknown_macro` in this scope LL | unknown_macro!(); | ^^^^^^^^^^^^^ -error[E0405]: cannot find trait `UnknownBound` in this scope +error[E0405]: cannot find trait `UnknownBound` --> $DIR/impl-fn-nesting.rs:11:13 | LL | pub fn f(a: UnknownType, b: B) { | ^^^^^^^^^^^^ not found in this scope -error[E0412]: cannot find type `UnknownType` in this scope +error[E0412]: cannot find type `UnknownType` --> $DIR/impl-fn-nesting.rs:11:30 | LL | pub fn f(a: UnknownType, b: B) { | ^^^^^^^^^^^ not found in this scope -error[E0405]: cannot find trait `UnknownTrait` in this scope +error[E0405]: cannot find trait `UnknownTrait` --> $DIR/impl-fn-nesting.rs:14:10 | LL | impl UnknownTrait for ValidType {} | ^^^^^^^^^^^^ not found in this scope -error[E0405]: cannot find trait `UnknownTrait` in this scope +error[E0405]: cannot find trait `UnknownTrait` --> $DIR/impl-fn-nesting.rs:15:27 | LL | impl UnknownTrait for T {} | ^^^^^^^^^^^^ not found in this scope -error[E0405]: cannot find trait `UnknownBound` in this scope +error[E0405]: cannot find trait `UnknownBound` --> $DIR/impl-fn-nesting.rs:15:13 | LL | impl UnknownTrait for T {} | ^^^^^^^^^^^^ not found in this scope -error[E0412]: cannot find type `UnknownType` in this scope +error[E0412]: cannot find type `UnknownType` --> $DIR/impl-fn-nesting.rs:18:25 | LL | impl ValidTrait for UnknownType {} | ^^^^^^^^^^^ not found in this scope -error[E0405]: cannot find trait `UnknownBound` in this scope +error[E0405]: cannot find trait `UnknownBound` --> $DIR/impl-fn-nesting.rs:20:53 | LL | impl ValidTrait for ValidType where ValidTrait: UnknownBound {} | ^^^^^^^^^^^^ not found in this scope -error[E0412]: cannot find type `UnknownType` in this scope +error[E0412]: cannot find type `UnknownType` --> $DIR/impl-fn-nesting.rs:25:21 | LL | type Item = UnknownType; | ^^^^^^^^^^^ not found in this scope -error[E0412]: cannot find type `UnknownType` in this scope +error[E0412]: cannot find type `UnknownType` --> $DIR/impl-fn-nesting.rs:44:37 | LL | pub fn doubly_nested(c: UnknownType) { diff --git a/tests/rustdoc-ui/issues/issue-81662-shortness.rs b/tests/rustdoc-ui/issues/issue-81662-shortness.rs index 02207d2a736d7..7df63261ce7ee 100644 --- a/tests/rustdoc-ui/issues/issue-81662-shortness.rs +++ b/tests/rustdoc-ui/issues/issue-81662-shortness.rs @@ -1,6 +1,6 @@ //@ compile-flags:--test --error-format=short //@ check-stdout -//@ error-pattern:cannot find function `foo` in this scope +//@ error-pattern:cannot find function `foo` //@ normalize-stdout-test: "tests/rustdoc-ui/issues" -> "$$DIR" //@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" //@ failure-status: 101 diff --git a/tests/rustdoc-ui/issues/issue-81662-shortness.stdout b/tests/rustdoc-ui/issues/issue-81662-shortness.stdout index f32f51e12f2c3..754396380116d 100644 --- a/tests/rustdoc-ui/issues/issue-81662-shortness.stdout +++ b/tests/rustdoc-ui/issues/issue-81662-shortness.stdout @@ -5,7 +5,7 @@ test $DIR/issue-81662-shortness.rs - foo (line 8) ... FAILED failures: ---- $DIR/issue-81662-shortness.rs - foo (line 8) stdout ---- -$DIR/issue-81662-shortness.rs:9:1: error[E0425]: cannot find function `foo` in this scope +$DIR/issue-81662-shortness.rs:9:1: error[E0425]: cannot find function `foo` error: aborting due to 1 previous error Couldn't compile the test. diff --git a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.rs b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.rs index dc268dfc5caf7..803cd10155e65 100644 --- a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.rs +++ b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.rs @@ -73,7 +73,7 @@ struct InvalidLitNestedAttr {} #[derive(Diagnostic)] #[diag(nonsense, code = E0123)] -//~^ ERROR cannot find value `nonsense` in module `crate::fluent_generated` +//~^ ERROR cannot find value `nonsense` struct InvalidNestedStructAttr {} #[derive(Diagnostic)] @@ -805,7 +805,7 @@ struct SuggestionsInvalidItem { sub: Span, } -#[derive(Diagnostic)] //~ ERROR cannot find value `__code_34` in this scope +#[derive(Diagnostic)] //~ ERROR cannot find value `__code_34` #[diag(no_crate_example)] struct SuggestionsInvalidLiteral { #[suggestion(code = 3)] diff --git a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr index e36c6852d3b20..b2f5ba4093a5c 100644 --- a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr +++ b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr @@ -596,13 +596,13 @@ error: cannot find attribute `multipart_suggestion` in this scope LL | #[multipart_suggestion(no_crate_suggestion)] | ^^^^^^^^^^^^^^^^^^^^ -error[E0425]: cannot find value `nonsense` in module `crate::fluent_generated` +error[E0425]: cannot find value `nonsense` --> $DIR/diagnostic-derive.rs:75:8 | LL | #[diag(nonsense, code = E0123)] - | ^^^^^^^^ not found in `crate::fluent_generated` + | ^^^^^^^^ not found in module `crate::fluent_generated` -error[E0425]: cannot find value `__code_34` in this scope +error[E0425]: cannot find value `__code_34` --> $DIR/diagnostic-derive.rs:808:10 | LL | #[derive(Diagnostic)] diff --git a/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive.rs b/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive.rs index 659ae54f7a3be..43deef7d8caf6 100644 --- a/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive.rs +++ b/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive.rs @@ -66,7 +66,7 @@ struct D { #[derive(Subdiagnostic)] #[foo] //~^ ERROR `#[foo]` is not a valid attribute -//~^^ ERROR cannot find attribute `foo` in this scope +//~^^ ERROR cannot find attribute `foo` struct E { #[primary_span] span: Span, @@ -124,8 +124,8 @@ struct K { #[derive(Subdiagnostic)] #[label(slug)] -//~^ ERROR cannot find value `slug` in module `crate::fluent_generated` -//~^^ NOTE not found in `crate::fluent_generated` +//~^ ERROR cannot find value `slug` +//~^^ NOTE not found in module `crate::fluent_generated` struct L { #[primary_span] span: Span, @@ -712,7 +712,7 @@ struct BP { } #[derive(Subdiagnostic)] -//~^ ERROR cannot find value `__code_29` in this scope +//~^ ERROR cannot find value `__code_29` //~| NOTE in this expansion //~| NOTE not found in this scope #[multipart_suggestion(no_crate_example)] diff --git a/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive.stderr b/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive.stderr index fccf3757dbec6..ce99ad6533299 100644 --- a/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive.stderr +++ b/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive.stderr @@ -553,13 +553,13 @@ error: cannot find attribute `bar` in this scope LL | #[bar("...")] | ^^^ -error[E0425]: cannot find value `slug` in module `crate::fluent_generated` +error[E0425]: cannot find value `slug` --> $DIR/subdiagnostic-derive.rs:126:9 | LL | #[label(slug)] - | ^^^^ not found in `crate::fluent_generated` + | ^^^^ not found in module `crate::fluent_generated` -error[E0425]: cannot find value `__code_29` in this scope +error[E0425]: cannot find value `__code_29` --> $DIR/subdiagnostic-derive.rs:714:10 | LL | #[derive(Subdiagnostic)] diff --git a/tests/ui/annotate-snippet/missing-type.rs b/tests/ui/annotate-snippet/missing-type.rs index ea1c2521103e8..29834d2028ed7 100644 --- a/tests/ui/annotate-snippet/missing-type.rs +++ b/tests/ui/annotate-snippet/missing-type.rs @@ -1,5 +1,5 @@ //@ compile-flags: --error-format human-annotate-rs -Z unstable-options -//@ error-pattern:cannot find type `Iter` in this scope +//@ error-pattern:cannot find type `Iter` pub fn main() { let x: Iter; diff --git a/tests/ui/annotate-snippet/missing-type.stderr b/tests/ui/annotate-snippet/missing-type.stderr index 89ce19c182f52..c6c5c1d258ed2 100644 --- a/tests/ui/annotate-snippet/missing-type.stderr +++ b/tests/ui/annotate-snippet/missing-type.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `Iter` in this scope +error[E0412]: cannot find type `Iter` --> $DIR/missing-type.rs:5:12 | LL | let x: Iter; diff --git a/tests/ui/argument-suggestions/extern-fn-arg-names.rs b/tests/ui/argument-suggestions/extern-fn-arg-names.rs index df2fd6624cd0c..ed9697d7e5c52 100644 --- a/tests/ui/argument-suggestions/extern-fn-arg-names.rs +++ b/tests/ui/argument-suggestions/extern-fn-arg-names.rs @@ -1,6 +1,6 @@ extern "Rust" { fn dstfn(src: i32, dst: err); - //~^ ERROR cannot find type `err` in this scope + //~^ ERROR cannot find type `err` } fn main() { diff --git a/tests/ui/argument-suggestions/extern-fn-arg-names.stderr b/tests/ui/argument-suggestions/extern-fn-arg-names.stderr index f6bc84c1203ad..265c0ad477b39 100644 --- a/tests/ui/argument-suggestions/extern-fn-arg-names.stderr +++ b/tests/ui/argument-suggestions/extern-fn-arg-names.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `err` in this scope +error[E0412]: cannot find type `err` --> $DIR/extern-fn-arg-names.rs:2:29 | LL | fn dstfn(src: i32, dst: err); diff --git a/tests/ui/argument-suggestions/issue-109831.stderr b/tests/ui/argument-suggestions/issue-109831.stderr index 7b9a3c9ef2c6c..2962e10aebbe6 100644 --- a/tests/ui/argument-suggestions/issue-109831.stderr +++ b/tests/ui/argument-suggestions/issue-109831.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `C` in this scope +error[E0412]: cannot find type `C` --> $DIR/issue-109831.rs:4:24 | LL | struct A; @@ -16,7 +16,7 @@ help: you might be missing a type parameter LL | fn f(b1: B, b2: B, a2: C) {} | +++ -error[E0425]: cannot find value `C` in this scope +error[E0425]: cannot find value `C` --> $DIR/issue-109831.rs:7:16 | LL | struct A; diff --git a/tests/ui/argument-suggestions/suggest-better-removing-issue-126246.rs b/tests/ui/argument-suggestions/suggest-better-removing-issue-126246.rs index fa1802283c39c..bdd91fdf6938d 100644 --- a/tests/ui/argument-suggestions/suggest-better-removing-issue-126246.rs +++ b/tests/ui/argument-suggestions/suggest-better-removing-issue-126246.rs @@ -8,14 +8,14 @@ fn add_two(x: i32, y: i32) -> i32 { fn main() { add_one(2, 2); //~ ERROR this function takes 1 argument but 2 arguments were supplied - add_one(no_such_local, 10); //~ ERROR cannot find value `no_such_local` in this scope + add_one(no_such_local, 10); //~ ERROR cannot find value `no_such_local` //~| ERROR this function takes 1 argument but 2 arguments were supplied - add_one(10, no_such_local); //~ ERROR cannot find value `no_such_local` in this scope + add_one(10, no_such_local); //~ ERROR cannot find value `no_such_local` //~| ERROR this function takes 1 argument but 2 arguments were supplied - add_two(10, no_such_local, 10); //~ ERROR cannot find value `no_such_local` in this scope + add_two(10, no_such_local, 10); //~ ERROR cannot find value `no_such_local` //~| ERROR this function takes 2 arguments but 3 arguments were supplied - add_two(no_such_local, 10, 10); //~ ERROR cannot find value `no_such_local` in this scope + add_two(no_such_local, 10, 10); //~ ERROR cannot find value `no_such_local` //~| ERROR this function takes 2 arguments but 3 arguments were supplied - add_two(10, 10, no_such_local); //~ ERROR cannot find value `no_such_local` in this scope + add_two(10, 10, no_such_local); //~ ERROR cannot find value `no_such_local` //~| ERROR this function takes 2 arguments but 3 arguments were supplied } diff --git a/tests/ui/argument-suggestions/suggest-better-removing-issue-126246.stderr b/tests/ui/argument-suggestions/suggest-better-removing-issue-126246.stderr index dc293945eb600..23e074d79ffb2 100644 --- a/tests/ui/argument-suggestions/suggest-better-removing-issue-126246.stderr +++ b/tests/ui/argument-suggestions/suggest-better-removing-issue-126246.stderr @@ -1,28 +1,28 @@ -error[E0425]: cannot find value `no_such_local` in this scope +error[E0425]: cannot find value `no_such_local` --> $DIR/suggest-better-removing-issue-126246.rs:11:13 | LL | add_one(no_such_local, 10); | ^^^^^^^^^^^^^ not found in this scope -error[E0425]: cannot find value `no_such_local` in this scope +error[E0425]: cannot find value `no_such_local` --> $DIR/suggest-better-removing-issue-126246.rs:13:17 | LL | add_one(10, no_such_local); | ^^^^^^^^^^^^^ not found in this scope -error[E0425]: cannot find value `no_such_local` in this scope +error[E0425]: cannot find value `no_such_local` --> $DIR/suggest-better-removing-issue-126246.rs:15:17 | LL | add_two(10, no_such_local, 10); | ^^^^^^^^^^^^^ not found in this scope -error[E0425]: cannot find value `no_such_local` in this scope +error[E0425]: cannot find value `no_such_local` --> $DIR/suggest-better-removing-issue-126246.rs:17:13 | LL | add_two(no_such_local, 10, 10); | ^^^^^^^^^^^^^ not found in this scope -error[E0425]: cannot find value `no_such_local` in this scope +error[E0425]: cannot find value `no_such_local` --> $DIR/suggest-better-removing-issue-126246.rs:19:21 | LL | add_two(10, 10, no_such_local); diff --git a/tests/ui/array-slice-vec/slice-pat-type-mismatches.rs b/tests/ui/array-slice-vec/slice-pat-type-mismatches.rs index 03a1876fdc5a5..ea4141b27664e 100644 --- a/tests/ui/array-slice-vec/slice-pat-type-mismatches.rs +++ b/tests/ui/array-slice-vec/slice-pat-type-mismatches.rs @@ -24,8 +24,8 @@ fn main() { }; match does_not_exist { - //~^ ERROR cannot find value `does_not_exist` in this scope - [] => {} // ERROR cannot find value `does_not_exist` in this scope + //~^ ERROR cannot find value `does_not_exist` + [] => {} // ERROR cannot find value `does_not_exist` }; } diff --git a/tests/ui/array-slice-vec/slice-pat-type-mismatches.stderr b/tests/ui/array-slice-vec/slice-pat-type-mismatches.stderr index d1d042c477681..f48c1564babd4 100644 --- a/tests/ui/array-slice-vec/slice-pat-type-mismatches.stderr +++ b/tests/ui/array-slice-vec/slice-pat-type-mismatches.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `does_not_exist` in this scope +error[E0425]: cannot find value `does_not_exist` --> $DIR/slice-pat-type-mismatches.rs:26:11 | LL | match does_not_exist { diff --git a/tests/ui/asm/issue-113788.rs b/tests/ui/asm/issue-113788.rs index 3b11e253eda27..1d63cb309ef73 100644 --- a/tests/ui/asm/issue-113788.rs +++ b/tests/ui/asm/issue-113788.rs @@ -2,6 +2,6 @@ //@ needs-asm-support //@ only-x86_64 fn main() { - let peb: *const PEB; //~ ERROR cannot find type `PEB` in this scope [E0412] + let peb: *const PEB; //~ ERROR cannot find type `PEB` [E0412] unsafe { std::arch::asm!("mov {0}, fs:[0x30]", out(reg) peb); } } diff --git a/tests/ui/asm/issue-113788.stderr b/tests/ui/asm/issue-113788.stderr index c44ba3c91d91a..ba27c8b101fb1 100644 --- a/tests/ui/asm/issue-113788.stderr +++ b/tests/ui/asm/issue-113788.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `PEB` in this scope +error[E0412]: cannot find type `PEB` --> $DIR/issue-113788.rs:5:21 | LL | let peb: *const PEB; diff --git a/tests/ui/associated-consts/issue-93835.rs b/tests/ui/associated-consts/issue-93835.rs index 9cc33d53f9cd5..cf458b11135eb 100644 --- a/tests/ui/associated-consts/issue-93835.rs +++ b/tests/ui/associated-consts/issue-93835.rs @@ -2,10 +2,10 @@ fn e() { type_ascribe!(p, a>); - //~^ ERROR cannot find type `a` in this scope + //~^ ERROR cannot find type `a` //~| ERROR cannot find value //~| ERROR associated const equality - //~| ERROR cannot find trait `p` in this scope + //~| ERROR cannot find trait `p` } fn main() {} diff --git a/tests/ui/associated-consts/issue-93835.stderr b/tests/ui/associated-consts/issue-93835.stderr index dfe78b3d1f380..8de7c04530f54 100644 --- a/tests/ui/associated-consts/issue-93835.stderr +++ b/tests/ui/associated-consts/issue-93835.stderr @@ -1,16 +1,16 @@ -error[E0425]: cannot find value `p` in this scope +error[E0425]: cannot find value `p` --> $DIR/issue-93835.rs:4:19 | LL | type_ascribe!(p, a>); | ^ not found in this scope -error[E0412]: cannot find type `a` in this scope +error[E0412]: cannot find type `a` --> $DIR/issue-93835.rs:4:22 | LL | type_ascribe!(p, a>); | ^ not found in this scope -error[E0405]: cannot find trait `p` in this scope +error[E0405]: cannot find trait `p` --> $DIR/issue-93835.rs:4:26 | LL | type_ascribe!(p, a>); diff --git a/tests/ui/associated-item/issue-87638.fixed b/tests/ui/associated-item/issue-87638.fixed index 36184e7862557..a923dec25ade6 100644 --- a/tests/ui/associated-item/issue-87638.fixed +++ b/tests/ui/associated-item/issue-87638.fixed @@ -14,9 +14,9 @@ impl Trait for S { } fn main() { - let _: ::Target; //~ ERROR cannot find associated type `Output` in trait `Trait` + let _: ::Target; //~ ERROR cannot find associated type `Output` //~^ HELP maybe you meant this associated type - let _ = ::FOO; //~ ERROR cannot find method or associated constant `BAR` in trait `Trait` + let _ = ::FOO; //~ ERROR cannot find method or associated constant `BAR` //~^ HELP maybe you meant this associated constant } diff --git a/tests/ui/associated-item/issue-87638.rs b/tests/ui/associated-item/issue-87638.rs index 30187625ff3da..9ccd44aa43b43 100644 --- a/tests/ui/associated-item/issue-87638.rs +++ b/tests/ui/associated-item/issue-87638.rs @@ -14,9 +14,9 @@ impl Trait for S { } fn main() { - let _: ::Output; //~ ERROR cannot find associated type `Output` in trait `Trait` + let _: ::Output; //~ ERROR cannot find associated type `Output` //~^ HELP maybe you meant this associated type - let _ = ::BAR; //~ ERROR cannot find method or associated constant `BAR` in trait `Trait` + let _ = ::BAR; //~ ERROR cannot find method or associated constant `BAR` //~^ HELP maybe you meant this associated constant } diff --git a/tests/ui/associated-item/issue-87638.stderr b/tests/ui/associated-item/issue-87638.stderr index cf6083444b0e6..ce13a4eac4b3b 100644 --- a/tests/ui/associated-item/issue-87638.stderr +++ b/tests/ui/associated-item/issue-87638.stderr @@ -1,4 +1,4 @@ -error[E0576]: cannot find associated type `Output` in trait `Trait` +error[E0576]: cannot find associated type `Output` --> $DIR/issue-87638.rs:17:26 | LL | type Target; @@ -7,10 +7,10 @@ LL | type Target; LL | let _: ::Output; | ^^^^^^ | | - | not found in `Trait` + | not found in trait `Trait` | help: maybe you meant this associated type: `Target` -error[E0576]: cannot find method or associated constant `BAR` in trait `Trait` +error[E0576]: cannot find method or associated constant `BAR` --> $DIR/issue-87638.rs:20:27 | LL | const FOO: usize; @@ -19,7 +19,7 @@ LL | const FOO: usize; LL | let _ = ::BAR; | ^^^ | | - | not found in `Trait` + | not found in trait `Trait` | help: maybe you meant this associated constant: `FOO` error: aborting due to 2 previous errors diff --git a/tests/ui/associated-path-shl.rs b/tests/ui/associated-path-shl.rs index 20a6fd83faa32..a9639063ee824 100644 --- a/tests/ui/associated-path-shl.rs +++ b/tests/ui/associated-path-shl.rs @@ -1,9 +1,9 @@ // Check that associated paths starting with `<<` are successfully parsed. fn main() { - let _: <::B>::C; //~ ERROR cannot find type `A` in this scope - let _ = <::B>::C; //~ ERROR cannot find type `A` in this scope - let <::B>::C; //~ ERROR cannot find type `A` in this scope - let 0 ..= <::B>::C; //~ ERROR cannot find type `A` in this scope - <::B>::C; //~ ERROR cannot find type `A` in this scope + let _: <::B>::C; //~ ERROR cannot find type `A` + let _ = <::B>::C; //~ ERROR cannot find type `A` + let <::B>::C; //~ ERROR cannot find type `A` + let 0 ..= <::B>::C; //~ ERROR cannot find type `A` + <::B>::C; //~ ERROR cannot find type `A` } diff --git a/tests/ui/associated-path-shl.stderr b/tests/ui/associated-path-shl.stderr index 71ee93f4835fb..330a304919c2b 100644 --- a/tests/ui/associated-path-shl.stderr +++ b/tests/ui/associated-path-shl.stderr @@ -1,28 +1,28 @@ -error[E0412]: cannot find type `A` in this scope +error[E0412]: cannot find type `A` --> $DIR/associated-path-shl.rs:4:14 | LL | let _: <::B>::C; | ^ not found in this scope -error[E0412]: cannot find type `A` in this scope +error[E0412]: cannot find type `A` --> $DIR/associated-path-shl.rs:5:15 | LL | let _ = <::B>::C; | ^ not found in this scope -error[E0412]: cannot find type `A` in this scope +error[E0412]: cannot find type `A` --> $DIR/associated-path-shl.rs:6:11 | LL | let <::B>::C; | ^ not found in this scope -error[E0412]: cannot find type `A` in this scope +error[E0412]: cannot find type `A` --> $DIR/associated-path-shl.rs:7:17 | LL | let 0 ..= <::B>::C; | ^ not found in this scope -error[E0412]: cannot find type `A` in this scope +error[E0412]: cannot find type `A` --> $DIR/associated-path-shl.rs:8:7 | LL | <::B>::C; diff --git a/tests/ui/associated-type-bounds/missing-trait-bound-for-assoc-fails.rs b/tests/ui/associated-type-bounds/missing-trait-bound-for-assoc-fails.rs index 07d0f8f8769e5..93c7203f14710 100644 --- a/tests/ui/associated-type-bounds/missing-trait-bound-for-assoc-fails.rs +++ b/tests/ui/associated-type-bounds/missing-trait-bound-for-assoc-fails.rs @@ -2,7 +2,7 @@ fn foo(_m: M) where M::Item: Temp, - //~^ ERROR cannot find trait `Temp` in this scope [E0405] + //~^ ERROR cannot find trait `Temp` [E0405] //~| ERROR associated type `Item` not found for `M` [E0220] { } diff --git a/tests/ui/associated-type-bounds/missing-trait-bound-for-assoc-fails.stderr b/tests/ui/associated-type-bounds/missing-trait-bound-for-assoc-fails.stderr index bc2807b03961c..65c37ecf5bbc0 100644 --- a/tests/ui/associated-type-bounds/missing-trait-bound-for-assoc-fails.stderr +++ b/tests/ui/associated-type-bounds/missing-trait-bound-for-assoc-fails.stderr @@ -1,4 +1,4 @@ -error[E0405]: cannot find trait `Temp` in this scope +error[E0405]: cannot find trait `Temp` --> $DIR/missing-trait-bound-for-assoc-fails.rs:4:14 | LL | M::Item: Temp, diff --git a/tests/ui/associated-types/associated-types-eq-1.rs b/tests/ui/associated-types/associated-types-eq-1.rs index c371138ff45b1..f672f83d260a2 100644 --- a/tests/ui/associated-types/associated-types-eq-1.rs +++ b/tests/ui/associated-types/associated-types-eq-1.rs @@ -7,7 +7,7 @@ pub trait Foo { } fn foo2(x: I) { - let _: A = x.boo(); //~ ERROR cannot find type `A` in this scope + let _: A = x.boo(); //~ ERROR cannot find type `A` } pub fn main() {} diff --git a/tests/ui/associated-types/associated-types-eq-1.stderr b/tests/ui/associated-types/associated-types-eq-1.stderr index 14ef36876740b..a9267d07265dd 100644 --- a/tests/ui/associated-types/associated-types-eq-1.stderr +++ b/tests/ui/associated-types/associated-types-eq-1.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `A` in this scope +error[E0412]: cannot find type `A` --> $DIR/associated-types-eq-1.rs:10:12 | LL | fn foo2(x: I) { diff --git a/tests/ui/associated-types/issue-19883.rs b/tests/ui/associated-types/issue-19883.rs index 5cf422043a585..ad63ea57e1ad0 100644 --- a/tests/ui/associated-types/issue-19883.rs +++ b/tests/ui/associated-types/issue-19883.rs @@ -7,7 +7,7 @@ trait From { trait To: Sized { fn to>(self) -> >::Dst - //~^ ERROR cannot find associated type `Dst` in trait `From` + //~^ ERROR cannot find associated type `Dst` { From::from(self) } diff --git a/tests/ui/associated-types/issue-19883.stderr b/tests/ui/associated-types/issue-19883.stderr index 35184e852cfe1..03a4bdf38c388 100644 --- a/tests/ui/associated-types/issue-19883.stderr +++ b/tests/ui/associated-types/issue-19883.stderr @@ -1,4 +1,4 @@ -error[E0576]: cannot find associated type `Dst` in trait `From` +error[E0576]: cannot find associated type `Dst` --> $DIR/issue-19883.rs:9:30 | LL | type Output; @@ -7,7 +7,7 @@ LL | type Output; LL | >::Dst | ^^^ | | - | not found in `From` + | not found in trait `From` | help: maybe you meant this associated type: `Output` error: aborting due to 1 previous error diff --git a/tests/ui/associated-types/issue-22037.rs b/tests/ui/associated-types/issue-22037.rs index b9eb41b6ea6e5..83c17132e7a31 100644 --- a/tests/ui/associated-types/issue-22037.rs +++ b/tests/ui/associated-types/issue-22037.rs @@ -1,7 +1,7 @@ trait A { type Output; fn a(&self) -> ::X; - //~^ ERROR cannot find associated type `X` in trait `A` + //~^ ERROR cannot find associated type `X` } impl A for u32 { diff --git a/tests/ui/associated-types/issue-22037.stderr b/tests/ui/associated-types/issue-22037.stderr index b02dad97d354e..135f228bfad48 100644 --- a/tests/ui/associated-types/issue-22037.stderr +++ b/tests/ui/associated-types/issue-22037.stderr @@ -1,4 +1,4 @@ -error[E0576]: cannot find associated type `X` in trait `A` +error[E0576]: cannot find associated type `X` --> $DIR/issue-22037.rs:3:33 | LL | type Output; @@ -6,7 +6,7 @@ LL | type Output; LL | fn a(&self) -> ::X; | ^ | | - | not found in `A` + | not found in trait `A` | help: maybe you meant this associated type: `Output` error: aborting due to 1 previous error diff --git a/tests/ui/async-await/async-closures/tainted-body.rs b/tests/ui/async-await/async-closures/tainted-body.rs index e42d9d6e36ade..8ea499de9c7a4 100644 --- a/tests/ui/async-await/async-closures/tainted-body.rs +++ b/tests/ui/async-await/async-closures/tainted-body.rs @@ -7,7 +7,7 @@ fn main() { let _ = async || { used_fn(); - //~^ ERROR cannot find function `used_fn` in this scope + //~^ ERROR cannot find function `used_fn` 0 }; } diff --git a/tests/ui/async-await/async-closures/tainted-body.stderr b/tests/ui/async-await/async-closures/tainted-body.stderr index b06a896b81f52..f8ae0d1558809 100644 --- a/tests/ui/async-await/async-closures/tainted-body.stderr +++ b/tests/ui/async-await/async-closures/tainted-body.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find function `used_fn` in this scope +error[E0425]: cannot find function `used_fn` --> $DIR/tainted-body.rs:9:9 | LL | used_fn(); diff --git a/tests/ui/async-await/async-fn/not-a-trait.rs b/tests/ui/async-await/async-fn/not-a-trait.rs index 0d22cbd2c0730..663bdcdaefc89 100644 --- a/tests/ui/async-await/async-fn/not-a-trait.rs +++ b/tests/ui/async-await/async-fn/not-a-trait.rs @@ -8,6 +8,6 @@ fn test(x: impl async S) {} //~^ ERROR expected trait, found struct `S` fn missing(x: impl async Missing) {} -//~^ ERROR cannot find trait `Missing` in this scope +//~^ ERROR cannot find trait `Missing` fn main() {} diff --git a/tests/ui/async-await/async-fn/not-a-trait.stderr b/tests/ui/async-await/async-fn/not-a-trait.stderr index d49f7d7d2fc16..b9a07a0b04cc1 100644 --- a/tests/ui/async-await/async-fn/not-a-trait.stderr +++ b/tests/ui/async-await/async-fn/not-a-trait.stderr @@ -4,7 +4,7 @@ error[E0404]: expected trait, found struct `S` LL | fn test(x: impl async S) {} | ^ not a trait -error[E0405]: cannot find trait `Missing` in this scope +error[E0405]: cannot find trait `Missing` --> $DIR/not-a-trait.rs:10:26 | LL | fn missing(x: impl async Missing) {} diff --git a/tests/ui/async-await/drop-order/drop-order-locals-are-hidden.rs b/tests/ui/async-await/drop-order/drop-order-locals-are-hidden.rs index d4897a1caf39d..cb9c70ff665ed 100644 --- a/tests/ui/async-await/drop-order/drop-order-locals-are-hidden.rs +++ b/tests/ui/async-await/drop-order/drop-order-locals-are-hidden.rs @@ -1,13 +1,13 @@ //@ edition:2018 async fn foobar_async(x: u32, (a, _, _c): (u32, u32, u32), _: u32, _y: u32) { - assert_eq!(__arg1, (1, 2, 3)); //~ ERROR cannot find value `__arg1` in this scope [E0425] - assert_eq!(__arg2, 4); //~ ERROR cannot find value `__arg2` in this scope [E0425] + assert_eq!(__arg1, (1, 2, 3)); //~ ERROR cannot find value `__arg1` [E0425] + assert_eq!(__arg2, 4); //~ ERROR cannot find value `__arg2` [E0425] } async fn baz_async(ref mut x: u32, ref y: u32) { - assert_eq!(__arg0, 1); //~ ERROR cannot find value `__arg0` in this scope [E0425] - assert_eq!(__arg1, 2); //~ ERROR cannot find value `__arg1` in this scope [E0425] + assert_eq!(__arg0, 1); //~ ERROR cannot find value `__arg0` [E0425] + assert_eq!(__arg1, 2); //~ ERROR cannot find value `__arg1` [E0425] } fn main() {} diff --git a/tests/ui/async-await/drop-order/drop-order-locals-are-hidden.stderr b/tests/ui/async-await/drop-order/drop-order-locals-are-hidden.stderr index aa04a613f47c1..01460b1a9751e 100644 --- a/tests/ui/async-await/drop-order/drop-order-locals-are-hidden.stderr +++ b/tests/ui/async-await/drop-order/drop-order-locals-are-hidden.stderr @@ -1,22 +1,22 @@ -error[E0425]: cannot find value `__arg1` in this scope +error[E0425]: cannot find value `__arg1` --> $DIR/drop-order-locals-are-hidden.rs:4:16 | LL | assert_eq!(__arg1, (1, 2, 3)); | ^^^^^^ not found in this scope -error[E0425]: cannot find value `__arg2` in this scope +error[E0425]: cannot find value `__arg2` --> $DIR/drop-order-locals-are-hidden.rs:5:16 | LL | assert_eq!(__arg2, 4); | ^^^^^^ not found in this scope -error[E0425]: cannot find value `__arg0` in this scope +error[E0425]: cannot find value `__arg0` --> $DIR/drop-order-locals-are-hidden.rs:9:16 | LL | assert_eq!(__arg0, 1); | ^^^^^^ not found in this scope -error[E0425]: cannot find value `__arg1` in this scope +error[E0425]: cannot find value `__arg1` --> $DIR/drop-order-locals-are-hidden.rs:10:16 | LL | assert_eq!(__arg1, 2); diff --git a/tests/ui/async-await/in-trait/return-not-existing-pair.rs b/tests/ui/async-await/in-trait/return-not-existing-pair.rs index 3889efe1f2a3c..e72c8d8e93783 100644 --- a/tests/ui/async-await/in-trait/return-not-existing-pair.rs +++ b/tests/ui/async-await/in-trait/return-not-existing-pair.rs @@ -3,7 +3,7 @@ trait MyTrait<'a, 'b, T> { async fn foo(&'a self, key: &'b T) -> (&'a ConnImpl, &'b T); - //~^ ERROR: cannot find type `ConnImpl` in this scope [E0412] + //~^ ERROR: cannot find type `ConnImpl` [E0412] } impl<'a, 'b, T, U> MyTrait for U { diff --git a/tests/ui/async-await/in-trait/return-not-existing-pair.stderr b/tests/ui/async-await/in-trait/return-not-existing-pair.stderr index 13d3606abba78..bfa1cf1ddecf0 100644 --- a/tests/ui/async-await/in-trait/return-not-existing-pair.stderr +++ b/tests/ui/async-await/in-trait/return-not-existing-pair.stderr @@ -9,7 +9,7 @@ help: indicate the anonymous lifetimes LL | impl<'a, 'b, T, U> MyTrait<'_, '_, T> for U { | +++++++ -error[E0412]: cannot find type `ConnImpl` in this scope +error[E0412]: cannot find type `ConnImpl` --> $DIR/return-not-existing-pair.rs:5:48 | LL | async fn foo(&'a self, key: &'b T) -> (&'a ConnImpl, &'b T); diff --git a/tests/ui/async-await/in-trait/return-not-existing-type-wrapping-rpitit.rs b/tests/ui/async-await/in-trait/return-not-existing-type-wrapping-rpitit.rs index e45fca6de770f..e485a19a41523 100644 --- a/tests/ui/async-await/in-trait/return-not-existing-type-wrapping-rpitit.rs +++ b/tests/ui/async-await/in-trait/return-not-existing-type-wrapping-rpitit.rs @@ -5,7 +5,7 @@ struct Wrapper(T); trait Foo { fn bar() -> Wrapper>; - //~^ ERROR: cannot find type `Missing` in this scope [E0412] + //~^ ERROR: cannot find type `Missing` [E0412] } impl Foo for () { diff --git a/tests/ui/async-await/in-trait/return-not-existing-type-wrapping-rpitit.stderr b/tests/ui/async-await/in-trait/return-not-existing-type-wrapping-rpitit.stderr index 84e0a643485f7..58773c066b884 100644 --- a/tests/ui/async-await/in-trait/return-not-existing-type-wrapping-rpitit.stderr +++ b/tests/ui/async-await/in-trait/return-not-existing-type-wrapping-rpitit.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `Missing` in this scope +error[E0412]: cannot find type `Missing` --> $DIR/return-not-existing-type-wrapping-rpitit.rs:7:25 | LL | fn bar() -> Wrapper>; diff --git a/tests/ui/async-await/issue-72590-type-error-sized.stderr b/tests/ui/async-await/issue-72590-type-error-sized.stderr index 1b822234d80cc..557b29472bfe5 100644 --- a/tests/ui/async-await/issue-72590-type-error-sized.stderr +++ b/tests/ui/async-await/issue-72590-type-error-sized.stderr @@ -1,10 +1,10 @@ -error[E0412]: cannot find type `Nonexistent` in this scope +error[E0412]: cannot find type `Nonexistent` --> $DIR/issue-72590-type-error-sized.rs:6:10 | LL | foo: Nonexistent, | ^^^^^^^^^^^ not found in this scope -error[E0412]: cannot find type `Missing` in this scope +error[E0412]: cannot find type `Missing` --> $DIR/issue-72590-type-error-sized.rs:11:11 | LL | test: Missing diff --git a/tests/ui/attributes/issue-90873.rs b/tests/ui/attributes/issue-90873.rs index 53339ce7e28fb..47643c52fd2d3 100644 --- a/tests/ui/attributes/issue-90873.rs +++ b/tests/ui/attributes/issue-90873.rs @@ -1,9 +1,9 @@ #![u=||{static d=||1;}] //~^ attribute value must be a literal -//~| cannot find attribute `u` in this scope +//~| cannot find attribute `u` //~| missing type for `static` item #![a={impl std::ops::Neg for i8 {}}] //~^ ERROR attribute value must be a literal -//~| ERROR cannot find attribute `a` in this scope +//~| ERROR cannot find attribute `a` //~| ERROR `main` function not found in crate `issue_90873` diff --git a/tests/ui/attributes/key-value-expansion-scope.rs b/tests/ui/attributes/key-value-expansion-scope.rs index b6eab1571d490..15da8228cc02c 100644 --- a/tests/ui/attributes/key-value-expansion-scope.rs +++ b/tests/ui/attributes/key-value-expansion-scope.rs @@ -1,19 +1,19 @@ -#![doc = in_root!()] //~ WARN cannot find macro `in_root` in this scope +#![doc = in_root!()] //~ WARN cannot find macro `in_root` //~| WARN this was previously accepted by the compiler -#![doc = in_mod!()] //~ ERROR cannot find macro `in_mod` in this scope -#![doc = in_mod_escape!()] //~ WARN cannot find macro `in_mod_escape` in this scope +#![doc = in_mod!()] //~ ERROR cannot find macro `in_mod` +#![doc = in_mod_escape!()] //~ WARN cannot find macro `in_mod_escape` //~| WARN this was previously accepted by the compiler -#![doc = in_block!()] //~ ERROR cannot find macro `in_block` in this scope +#![doc = in_block!()] //~ ERROR cannot find macro `in_block` -#[doc = in_root!()] //~ ERROR cannot find macro `in_root` in this scope -#[doc = in_mod!()] //~ ERROR cannot find macro `in_mod` in this scope -#[doc = in_mod_escape!()] //~ ERROR cannot find macro `in_mod_escape` in this scope -#[doc = in_block!()] //~ ERROR cannot find macro `in_block` in this scope +#[doc = in_root!()] //~ ERROR cannot find macro `in_root` +#[doc = in_mod!()] //~ ERROR cannot find macro `in_mod` +#[doc = in_mod_escape!()] //~ ERROR cannot find macro `in_mod_escape` +#[doc = in_block!()] //~ ERROR cannot find macro `in_block` fn before() { - #![doc = in_root!()] //~ ERROR cannot find macro `in_root` in this scope - #![doc = in_mod!()] //~ ERROR cannot find macro `in_mod` in this scope - #![doc = in_mod_escape!()] //~ ERROR cannot find macro `in_mod_escape` in this scope - #![doc = in_block!()] //~ ERROR cannot find macro `in_block` in this scope + #![doc = in_root!()] //~ ERROR cannot find macro `in_root` + #![doc = in_mod!()] //~ ERROR cannot find macro `in_mod` + #![doc = in_mod_escape!()] //~ ERROR cannot find macro `in_mod_escape` + #![doc = in_block!()] //~ ERROR cannot find macro `in_block` } macro_rules! in_root { () => { "" } } @@ -49,7 +49,7 @@ mod macros_escape { #[doc = in_block!()] //~ ERROR cannot find macro `in_block` in this scope fn block() { - #![doc = in_block!()] //~ ERROR cannot find macro `in_block` in this scope + #![doc = in_block!()] //~ ERROR cannot find macro `in_block` macro_rules! in_block { () => { "" } } @@ -60,14 +60,14 @@ fn block() { } #[doc = in_root!()] // OK -#[doc = in_mod!()] //~ ERROR cannot find macro `in_mod` in this scope +#[doc = in_mod!()] //~ ERROR cannot find macro `in_mod` #[doc = in_mod_escape!()] // OK -#[doc = in_block!()] //~ ERROR cannot find macro `in_block` in this scope +#[doc = in_block!()] //~ ERROR cannot find macro `in_block` fn after() { #![doc = in_root!()] // OK - #![doc = in_mod!()] //~ ERROR cannot find macro `in_mod` in this scope + #![doc = in_mod!()] //~ ERROR cannot find macro `in_mod` #![doc = in_mod_escape!()] // OK - #![doc = in_block!()] //~ ERROR cannot find macro `in_block` in this scope + #![doc = in_block!()] //~ ERROR cannot find macro `in_block` } fn main() {} diff --git a/tests/ui/attributes/main-removed-1.rs b/tests/ui/attributes/main-removed-1.rs index 0e887469d4466..36cec5c6d958f 100644 --- a/tests/ui/attributes/main-removed-1.rs +++ b/tests/ui/attributes/main-removed-1.rs @@ -1,2 +1,2 @@ -#[main] //~ ERROR cannot find attribute `main` in this scope +#[main] //~ ERROR cannot find attribute `main` fn main() {} diff --git a/tests/ui/attributes/obsolete-attr.rs b/tests/ui/attributes/obsolete-attr.rs index 7019abcaffbae..ae048eda531dd 100644 --- a/tests/ui/attributes/obsolete-attr.rs +++ b/tests/ui/attributes/obsolete-attr.rs @@ -1,9 +1,9 @@ // Obsolete attributes fall back to unstable custom attributes. #[ab_isize = "stdcall"] extern "C" {} -//~^ ERROR cannot find attribute `ab_isize` in this scope +//~^ ERROR cannot find attribute `ab_isize` #[fixed_stack_segment] fn f() {} -//~^ ERROR cannot find attribute `fixed_stack_segment` in this scope +//~^ ERROR cannot find attribute `fixed_stack_segment` fn main() {} diff --git a/tests/ui/attributes/unknown-attr.rs b/tests/ui/attributes/unknown-attr.rs index 70fef04e95c67..ff6969c2426b4 100644 --- a/tests/ui/attributes/unknown-attr.rs +++ b/tests/ui/attributes/unknown-attr.rs @@ -3,10 +3,10 @@ #![feature(custom_inner_attributes)] #![mutable_doc] -//~^ ERROR cannot find attribute `mutable_doc` in this scope +//~^ ERROR cannot find attribute `mutable_doc` #[dance] mod a {} -//~^ ERROR cannot find attribute `dance` in this scope +//~^ ERROR cannot find attribute `dance` #[dance] fn main() {} -//~^ ERROR cannot find attribute `dance` in this scope +//~^ ERROR cannot find attribute `dance` diff --git a/tests/ui/attributes/unsafe/double-unsafe-attributes.rs b/tests/ui/attributes/unsafe/double-unsafe-attributes.rs index a6c0ea578f25a..de94328ba7320 100644 --- a/tests/ui/attributes/unsafe/double-unsafe-attributes.rs +++ b/tests/ui/attributes/unsafe/double-unsafe-attributes.rs @@ -2,7 +2,7 @@ #[unsafe(unsafe(no_mangle))] //~^ ERROR expected identifier, found keyword `unsafe` -//~| ERROR cannot find attribute `r#unsafe` in this scope +//~| ERROR cannot find attribute `r#unsafe` //~| ERROR `r#unsafe` is not an unsafe attribute fn a() {} diff --git a/tests/ui/attributes/unused-item-in-attr.rs b/tests/ui/attributes/unused-item-in-attr.rs index fda0a5d6a3f16..460e85569865c 100644 --- a/tests/ui/attributes/unused-item-in-attr.rs +++ b/tests/ui/attributes/unused-item-in-attr.rs @@ -1,6 +1,6 @@ #[w = { extern crate alloc; }] //~^ ERROR attribute value must be a literal -//~| ERROR cannot find attribute `w` in this scope +//~| ERROR cannot find attribute `w` fn f() {} fn main() {} diff --git a/tests/ui/c-variadic/issue-86053-1.rs b/tests/ui/c-variadic/issue-86053-1.rs index f952235be9811..ce80375dbd51a 100644 --- a/tests/ui/c-variadic/issue-86053-1.rs +++ b/tests/ui/c-variadic/issue-86053-1.rs @@ -1,7 +1,7 @@ // Regression test for the ICE described in issue #86053. //@ error-pattern:unexpected `self` parameter in function //@ error-pattern:`...` must be the last argument of a C-variadic function -//@ error-pattern:cannot find type `F` in this scope +//@ error-pattern:cannot find type `F` #![feature(c_variadic)] diff --git a/tests/ui/c-variadic/issue-86053-1.stderr b/tests/ui/c-variadic/issue-86053-1.stderr index 67a619e46d57d..9c34766d87ce7 100644 --- a/tests/ui/c-variadic/issue-86053-1.stderr +++ b/tests/ui/c-variadic/issue-86053-1.stderr @@ -52,7 +52,7 @@ error: only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` function LL | self , ... , self , self , ... ) where F : FnOnce ( & 'a & 'b usize ) { | ^^^ ^^^ -error[E0412]: cannot find type `F` in this scope +error[E0412]: cannot find type `F` --> $DIR/issue-86053-1.rs:11:48 | LL | self , ... , self , self , ... ) where F : FnOnce ( & 'a & 'b usize ) { diff --git a/tests/ui/cast/cast-errors-issue-43825.stderr b/tests/ui/cast/cast-errors-issue-43825.stderr index 658d5ddbb611c..5ed78fd04cf74 100644 --- a/tests/ui/cast/cast-errors-issue-43825.stderr +++ b/tests/ui/cast/cast-errors-issue-43825.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `error` in this scope +error[E0425]: cannot find value `error` --> $DIR/cast-errors-issue-43825.rs:2:17 | LL | let error = error; diff --git a/tests/ui/cast/casts-issue-46365.stderr b/tests/ui/cast/casts-issue-46365.stderr index 84bc73a9b7862..68e46618a621e 100644 --- a/tests/ui/cast/casts-issue-46365.stderr +++ b/tests/ui/cast/casts-issue-46365.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `Ipsum` in this scope +error[E0412]: cannot find type `Ipsum` --> $DIR/casts-issue-46365.rs:2:12 | LL | ipsum: Ipsum diff --git a/tests/ui/cast/ice-cast-type-with-error-124848.rs b/tests/ui/cast/ice-cast-type-with-error-124848.rs index 9b3732b02db43..e8b99e5878e2a 100644 --- a/tests/ui/cast/ice-cast-type-with-error-124848.rs +++ b/tests/ui/cast/ice-cast-type-with-error-124848.rs @@ -6,7 +6,7 @@ use std::cell::Cell; struct MyType<'a>(Cell>>, Pin); //~^ ERROR use of undeclared lifetime name `'unpinned` -//~| ERROR cannot find type `Pin` in this scope +//~| ERROR cannot find type `Pin` fn main() { let mut unpinned = MyType(Cell::new(None)); diff --git a/tests/ui/cast/ice-cast-type-with-error-124848.stderr b/tests/ui/cast/ice-cast-type-with-error-124848.stderr index 2d86bf76d1102..60a4eb21bfd16 100644 --- a/tests/ui/cast/ice-cast-type-with-error-124848.stderr +++ b/tests/ui/cast/ice-cast-type-with-error-124848.stderr @@ -24,7 +24,7 @@ LL | fn main() { LL | let bad_addr = &unpinned as *const Cell>> as usize; | ^^ undeclared lifetime -error[E0412]: cannot find type `Pin` in this scope +error[E0412]: cannot find type `Pin` --> $DIR/ice-cast-type-with-error-124848.rs:7:60 | LL | struct MyType<'a>(Cell>>, Pin); diff --git a/tests/ui/cfg/diagnostics-cross-crate.rs b/tests/ui/cfg/diagnostics-cross-crate.rs index 77dd91d6c2823..e5d7e02afe374 100644 --- a/tests/ui/cfg/diagnostics-cross-crate.rs +++ b/tests/ui/cfg/diagnostics-cross-crate.rs @@ -5,12 +5,12 @@ extern crate cfged_out; fn main() { // There is no uwu at this path - no diagnostic. cfged_out::uwu(); //~ ERROR cannot find function - //~^ NOTE not found in `cfged_out` + //~^ NOTE not found in crate `cfged_out` // It does exist here - diagnostic. cfged_out::inner::uwu(); //~ ERROR cannot find function //~^ NOTE found an item that was configured out - //~| NOTE not found in `cfged_out::inner` + //~| NOTE not found in module `cfged_out::inner` // The module isn't found - we would like to get a diagnostic, but currently don't due to // the awkward way the resolver diagnostics are currently implemented. @@ -21,11 +21,11 @@ fn main() { // It should find the one in the right module, not the wrong one. cfged_out::inner::right::meow(); //~ ERROR cannot find function //~^ NOTE found an item that was configured out - //~| NOTE not found in `cfged_out::inner::right + //~| NOTE not found in module `cfged_out::inner::right //~| NOTE the item is gated behind the `what-a-cool-feature` feature // Exists in the crate root - diagnostic. cfged_out::vanished(); //~ ERROR cannot find function //~^ NOTE found an item that was configured out - //~| NOTE not found in `cfged_out` + //~| NOTE not found in crate `cfged_out` } diff --git a/tests/ui/cfg/diagnostics-cross-crate.stderr b/tests/ui/cfg/diagnostics-cross-crate.stderr index 8a238f3640445..a01b1a47ef8d1 100644 --- a/tests/ui/cfg/diagnostics-cross-crate.stderr +++ b/tests/ui/cfg/diagnostics-cross-crate.stderr @@ -10,17 +10,17 @@ note: found an item that was configured out LL | pub mod doesnt_exist { | ^^^^^^^^^^^^ -error[E0425]: cannot find function `uwu` in crate `cfged_out` +error[E0425]: cannot find function `uwu` --> $DIR/diagnostics-cross-crate.rs:7:16 | LL | cfged_out::uwu(); - | ^^^ not found in `cfged_out` + | ^^^ not found in crate `cfged_out` -error[E0425]: cannot find function `uwu` in module `cfged_out::inner` +error[E0425]: cannot find function `uwu` --> $DIR/diagnostics-cross-crate.rs:11:23 | LL | cfged_out::inner::uwu(); - | ^^^ not found in `cfged_out::inner` + | ^^^ not found in module `cfged_out::inner` | note: found an item that was configured out --> $DIR/auxiliary/cfged_out.rs:3:12 @@ -28,11 +28,11 @@ note: found an item that was configured out LL | pub fn uwu() {} | ^^^ -error[E0425]: cannot find function `meow` in module `cfged_out::inner::right` +error[E0425]: cannot find function `meow` --> $DIR/diagnostics-cross-crate.rs:22:30 | LL | cfged_out::inner::right::meow(); - | ^^^^ not found in `cfged_out::inner::right` + | ^^^^ not found in module `cfged_out::inner::right` | note: found an item that was configured out --> $DIR/auxiliary/cfged_out.rs:17:16 @@ -41,11 +41,11 @@ LL | pub fn meow() {} | ^^^^ = note: the item is gated behind the `what-a-cool-feature` feature -error[E0425]: cannot find function `vanished` in crate `cfged_out` +error[E0425]: cannot find function `vanished` --> $DIR/diagnostics-cross-crate.rs:28:16 | LL | cfged_out::vanished(); - | ^^^^^^^^ not found in `cfged_out` + | ^^^^^^^^ not found in crate `cfged_out` | note: found an item that was configured out --> $DIR/auxiliary/cfged_out.rs:22:8 diff --git a/tests/ui/cfg/diagnostics-not-a-def.stderr b/tests/ui/cfg/diagnostics-not-a-def.stderr index 51c1c03640f68..e987bc7060596 100644 --- a/tests/ui/cfg/diagnostics-not-a-def.stderr +++ b/tests/ui/cfg/diagnostics-not-a-def.stderr @@ -1,8 +1,8 @@ -error[E0425]: cannot find function `i_am_not` in module `inner` +error[E0425]: cannot find function `i_am_not` --> $DIR/diagnostics-not-a-def.rs:12:12 | LL | inner::i_am_not(); - | ^^^^^^^^ not found in `inner` + | ^^^^^^^^ not found in module `inner` error: aborting due to 1 previous error diff --git a/tests/ui/cfg/diagnostics-reexport.rs b/tests/ui/cfg/diagnostics-reexport.rs index 9b3208cb87cf9..71ded444bc41c 100644 --- a/tests/ui/cfg/diagnostics-reexport.rs +++ b/tests/ui/cfg/diagnostics-reexport.rs @@ -36,5 +36,5 @@ mod b { fn main() { // There is no uwu at this path - no diagnostic. inner::uwu(); //~ ERROR cannot find function - //~^ NOTE not found in `inner` + //~^ NOTE not found in module `inner` } diff --git a/tests/ui/cfg/diagnostics-reexport.stderr b/tests/ui/cfg/diagnostics-reexport.stderr index e25b7cf86e210..c64179a741bb7 100644 --- a/tests/ui/cfg/diagnostics-reexport.stderr +++ b/tests/ui/cfg/diagnostics-reexport.stderr @@ -29,11 +29,11 @@ note: found an item that was configured out LL | pub fn y() {} | ^ -error[E0425]: cannot find function `uwu` in module `inner` +error[E0425]: cannot find function `uwu` --> $DIR/diagnostics-reexport.rs:38:12 | LL | inner::uwu(); - | ^^^ not found in `inner` + | ^^^ not found in module `inner` | note: found an item that was configured out --> $DIR/diagnostics-reexport.rs:8:20 diff --git a/tests/ui/cfg/diagnostics-same-crate.rs b/tests/ui/cfg/diagnostics-same-crate.rs index b2a0fb58dd6b5..f31b08d3ad901 100644 --- a/tests/ui/cfg/diagnostics-same-crate.rs +++ b/tests/ui/cfg/diagnostics-same-crate.rs @@ -32,7 +32,7 @@ mod placeholder { //~| NOTE no `doesnt_exist` in `inner` use super::inner::doesnt_exist::hi; //~^ ERROR unresolved import `super::inner::doesnt_exist` - //~| NOTE could not find `doesnt_exist` in `inner` + //~| NOTE could not find `doesnt_exist` } #[cfg(i_dont_exist_and_you_can_do_nothing_about_it)] @@ -41,11 +41,11 @@ pub fn vanished() {} fn main() { // There is no uwu at this path - no diagnostic. uwu(); //~ ERROR cannot find function - //~^ NOTE not found in this scope + //~^ NOTE not found // It does exist here - diagnostic. inner::uwu(); //~ ERROR cannot find function - //~| NOTE not found in `inner` + //~| NOTE not found in module `inner` // The module isn't found - we would like to get a diagnostic, but currently don't due to // the awkward way the resolver diagnostics are currently implemented. @@ -54,12 +54,12 @@ fn main() { // It should find the one in the right module, not the wrong one. inner::right::meow(); //~ ERROR cannot find function - //~| NOTE not found in `inner::right + //~| NOTE not found in module `inner::right //~| NOTE the item is gated behind the `what-a-cool-feature` feature // Exists in the crate root - we would generally want a diagnostic, // but currently don't have one. // Not that it matters much though, this is highly unlikely to confuse anyone. vanished(); //~ ERROR cannot find function - //~^ NOTE not found in this scope + //~^ NOTE not found } diff --git a/tests/ui/cfg/diagnostics-same-crate.stderr b/tests/ui/cfg/diagnostics-same-crate.stderr index 86421736b8c60..f215738469249 100644 --- a/tests/ui/cfg/diagnostics-same-crate.stderr +++ b/tests/ui/cfg/diagnostics-same-crate.stderr @@ -34,11 +34,11 @@ note: found an item that was configured out LL | pub mod doesnt_exist { | ^^^^^^^^^^^^ -error[E0425]: cannot find function `uwu` in module `inner` +error[E0425]: cannot find function `uwu` --> $DIR/diagnostics-same-crate.rs:47:12 | LL | inner::uwu(); - | ^^^ not found in `inner` + | ^^^ not found in module `inner` | note: found an item that was configured out --> $DIR/diagnostics-same-crate.rs:5:12 @@ -46,11 +46,11 @@ note: found an item that was configured out LL | pub fn uwu() {} | ^^^ -error[E0425]: cannot find function `meow` in module `inner::right` +error[E0425]: cannot find function `meow` --> $DIR/diagnostics-same-crate.rs:56:19 | LL | inner::right::meow(); - | ^^^^ not found in `inner::right` + | ^^^^ not found in module `inner::right` | note: found an item that was configured out --> $DIR/diagnostics-same-crate.rs:24:16 @@ -59,13 +59,13 @@ LL | pub fn meow() {} | ^^^^ = note: the item is gated behind the `what-a-cool-feature` feature -error[E0425]: cannot find function `uwu` in this scope +error[E0425]: cannot find function `uwu` --> $DIR/diagnostics-same-crate.rs:43:5 | LL | uwu(); | ^^^ not found in this scope -error[E0425]: cannot find function `vanished` in this scope +error[E0425]: cannot find function `vanished` --> $DIR/diagnostics-same-crate.rs:63:5 | LL | vanished(); diff --git a/tests/ui/closures/issue-78720.rs b/tests/ui/closures/issue-78720.rs index 81af030fe5568..5fa9d805774d1 100644 --- a/tests/ui/closures/issue-78720.rs +++ b/tests/ui/closures/issue-78720.rs @@ -11,7 +11,7 @@ trait FilterBase2 { struct Map2 { _func: F, - //~^ ERROR cannot find type `F` in this scope + //~^ ERROR cannot find type `F` } impl FilterBase2 for F {} diff --git a/tests/ui/closures/issue-78720.stderr b/tests/ui/closures/issue-78720.stderr index 5d65c87b0fd61..09b115b07e153 100644 --- a/tests/ui/closures/issue-78720.stderr +++ b/tests/ui/closures/issue-78720.stderr @@ -4,7 +4,7 @@ error: at least one trait must be specified LL | fn server() -> impl { | ^^^^ -error[E0412]: cannot find type `F` in this scope +error[E0412]: cannot find type `F` --> $DIR/issue-78720.rs:13:12 | LL | _func: F, diff --git a/tests/ui/closures/issue-90871.rs b/tests/ui/closures/issue-90871.rs index 7ce061cd388c9..e8b57a3e76883 100644 --- a/tests/ui/closures/issue-90871.rs +++ b/tests/ui/closures/issue-90871.rs @@ -2,6 +2,6 @@ fn main() { type_ascribe!(2, n([u8; || 1])) - //~^ ERROR cannot find type `n` in this scope + //~^ ERROR cannot find type `n` //~| ERROR mismatched types } diff --git a/tests/ui/closures/issue-90871.stderr b/tests/ui/closures/issue-90871.stderr index ef1cb213f73be..4a607b5b66a84 100644 --- a/tests/ui/closures/issue-90871.stderr +++ b/tests/ui/closures/issue-90871.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `n` in this scope +error[E0412]: cannot find type `n` --> $DIR/issue-90871.rs:4:22 | LL | type_ascribe!(2, n([u8; || 1])) diff --git a/tests/ui/codemap_tests/tab.stderr b/tests/ui/codemap_tests/tab.stderr index d2de7486557f7..51f68358873d5 100644 --- a/tests/ui/codemap_tests/tab.stderr +++ b/tests/ui/codemap_tests/tab.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `bar` in this scope +error[E0425]: cannot find value `bar` --> $DIR/tab.rs:4:2 | LL | bar; diff --git a/tests/ui/codemap_tests/unicode_2.stderr b/tests/ui/codemap_tests/unicode_2.stderr index 19aae1d3c9511..c0acaa95d2127 100644 --- a/tests/ui/codemap_tests/unicode_2.stderr +++ b/tests/ui/codemap_tests/unicode_2.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `a̐é` in this scope +error[E0425]: cannot find value `a̐é` --> $DIR/unicode_2.rs:4:13 | LL | let _ = a̐é; diff --git a/tests/ui/coercion/type-errors.rs b/tests/ui/coercion/type-errors.rs index a86789907a055..4d1f6fec30bcb 100644 --- a/tests/ui/coercion/type-errors.rs +++ b/tests/ui/coercion/type-errors.rs @@ -3,7 +3,7 @@ // shortcutting and returning success, because we need the adjustments for building the MIR. pub fn has_error() -> TypeError {} -//~^ ERROR cannot find type `TypeError` in this scope +//~^ ERROR cannot find type `TypeError` // https://github.com/rust-lang/rust/issues/120884 // Casting a function item to a data pointer in valid in HIR, but invalid in MIR. @@ -16,11 +16,11 @@ pub fn cast() -> *const u8 { // https://github.com/rust-lang/rust/issues/120945 // This one ICEd, because we skipped the builtin deref from `&TypeError` to `TypeError`. pub fn autoderef_source(e: &TypeError) { - //~^ ERROR cannot find type `TypeError` in this scope + //~^ ERROR cannot find type `TypeError` autoderef_target(e) } pub fn autoderef_target(_: &TypeError) {} -//~^ ERROR cannot find type `TypeError` in this scope +//~^ ERROR cannot find type `TypeError` fn main() {} diff --git a/tests/ui/coercion/type-errors.stderr b/tests/ui/coercion/type-errors.stderr index 14deb785f75aa..dd0fe6a5660af 100644 --- a/tests/ui/coercion/type-errors.stderr +++ b/tests/ui/coercion/type-errors.stderr @@ -1,16 +1,16 @@ -error[E0412]: cannot find type `TypeError` in this scope +error[E0412]: cannot find type `TypeError` --> $DIR/type-errors.rs:5:23 | LL | pub fn has_error() -> TypeError {} | ^^^^^^^^^ not found in this scope -error[E0412]: cannot find type `TypeError` in this scope +error[E0412]: cannot find type `TypeError` --> $DIR/type-errors.rs:18:29 | LL | pub fn autoderef_source(e: &TypeError) { | ^^^^^^^^^ not found in this scope -error[E0412]: cannot find type `TypeError` in this scope +error[E0412]: cannot find type `TypeError` --> $DIR/type-errors.rs:23:29 | LL | pub fn autoderef_target(_: &TypeError) {} diff --git a/tests/ui/coherence/coherence-error-suppression.stderr b/tests/ui/coherence/coherence-error-suppression.stderr index fcaa510c632a8..0e96bee2e9ba5 100644 --- a/tests/ui/coherence/coherence-error-suppression.stderr +++ b/tests/ui/coherence/coherence-error-suppression.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `DoesNotExist` in this scope +error[E0412]: cannot find type `DoesNotExist` --> $DIR/coherence-error-suppression.rs:9:14 | LL | impl Foo for DoesNotExist {} diff --git a/tests/ui/coherence/illegal-copy-bad-projection.rs b/tests/ui/coherence/illegal-copy-bad-projection.rs index 797443a0abe5a..bd8a00ef06455 100644 --- a/tests/ui/coherence/illegal-copy-bad-projection.rs +++ b/tests/ui/coherence/illegal-copy-bad-projection.rs @@ -4,7 +4,7 @@ trait AsPtr { impl AsPtr for () { type Ptr = *const void; - //~^ ERROR cannot find type `void` in this scope + //~^ ERROR cannot find type `void` } #[derive(Copy, Clone)] diff --git a/tests/ui/coherence/illegal-copy-bad-projection.stderr b/tests/ui/coherence/illegal-copy-bad-projection.stderr index 2a74cb5a9b8b1..be778e6f488bd 100644 --- a/tests/ui/coherence/illegal-copy-bad-projection.stderr +++ b/tests/ui/coherence/illegal-copy-bad-projection.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `void` in this scope +error[E0412]: cannot find type `void` --> $DIR/illegal-copy-bad-projection.rs:6:23 | LL | type Ptr = *const void; diff --git a/tests/ui/compiletest-self-test/ui-testing-optout.stderr b/tests/ui/compiletest-self-test/ui-testing-optout.stderr index 652c472c0bcfe..e789b56f5f7ae 100644 --- a/tests/ui/compiletest-self-test/ui-testing-optout.stderr +++ b/tests/ui/compiletest-self-test/ui-testing-optout.stderr @@ -1,10 +1,10 @@ -error[E0412]: cannot find type `B` in this scope +error[E0412]: cannot find type `B` --> $DIR/ui-testing-optout.rs:4:10 | 4 | type A = B; | ^ not found in this scope -error[E0412]: cannot find type `D` in this scope +error[E0412]: cannot find type `D` --> $DIR/ui-testing-optout.rs:7:10 | 4 | type A = B; @@ -13,7 +13,7 @@ error[E0412]: cannot find type `D` in this scope 7 | type C = D; | ^ help: a type alias with a similar name exists: `A` -error[E0412]: cannot find type `F` in this scope +error[E0412]: cannot find type `F` --> $DIR/ui-testing-optout.rs:92:10 | 4 | type A = B; diff --git a/tests/ui/conditional-compilation/cfg-attr-unknown-attribute-macro-expansion.rs b/tests/ui/conditional-compilation/cfg-attr-unknown-attribute-macro-expansion.rs index 45b757e928302..14fa0ad847e24 100644 --- a/tests/ui/conditional-compilation/cfg-attr-unknown-attribute-macro-expansion.rs +++ b/tests/ui/conditional-compilation/cfg-attr-unknown-attribute-macro-expansion.rs @@ -1,7 +1,7 @@ macro_rules! foo { () => { #[cfg_attr(all(), unknown)] - //~^ ERROR cannot find attribute `unknown` in this scope + //~^ ERROR cannot find attribute `unknown` fn foo() {} } } diff --git a/tests/ui/conditional-compilation/cfg-generic-params.rs b/tests/ui/conditional-compilation/cfg-generic-params.rs index 4bb8f8ae94f69..dccd9380eb468 100644 --- a/tests/ui/conditional-compilation/cfg-generic-params.rs +++ b/tests/ui/conditional-compilation/cfg-generic-params.rs @@ -17,22 +17,22 @@ struct WhereBad where for<#[cfg(FALSE)] 'a, #[cfg(yes)] T> u8: Copy; fn f_lt_no<#[cfg_attr(FALSE, unknown)] 'a>() {} // OK fn f_lt_yes<#[cfg_attr(yes, unknown)] 'a>() {} -//~^ ERROR cannot find attribute `unknown` in this scope +//~^ ERROR cannot find attribute `unknown` fn f_ty_no<#[cfg_attr(FALSE, unknown)] T>() {} // OK fn f_ty_yes<#[cfg_attr(yes, unknown)] T>() {} -//~^ ERROR cannot find attribute `unknown` in this scope +//~^ ERROR cannot find attribute `unknown` type FnNo = for<#[cfg_attr(FALSE, unknown)] 'a> fn(); // OK type FnYes = for<#[cfg_attr(yes, unknown)] 'a> fn(); -//~^ ERROR cannot find attribute `unknown` in this scope +//~^ ERROR cannot find attribute `unknown` type PolyNo = dyn for<#[cfg_attr(FALSE, unknown)] 'a> Copy; // OK type PolyYes = dyn for<#[cfg_attr(yes, unknown)] 'a> Copy; -//~^ ERROR cannot find attribute `unknown` in this scope +//~^ ERROR cannot find attribute `unknown` struct WhereNo where for<#[cfg_attr(FALSE, unknown)] 'a> u8: Copy; // OK struct WhereYes where for<#[cfg_attr(yes, unknown)] 'a> u8: Copy; -//~^ ERROR cannot find attribute `unknown` in this scope +//~^ ERROR cannot find attribute `unknown` fn main() { f_lt::<'static>(); diff --git a/tests/ui/conditional-compilation/cfg_accessible.stderr b/tests/ui/conditional-compilation/cfg_accessible.stderr index e3731a1ad7128..a2a7b1a9f66e9 100644 --- a/tests/ui/conditional-compilation/cfg_accessible.stderr +++ b/tests/ui/conditional-compilation/cfg_accessible.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `ExistingPrivate` in this scope +error[E0425]: cannot find value `ExistingPrivate` --> $DIR/cfg_accessible.rs:52:5 | LL | ExistingPrivate; @@ -10,13 +10,13 @@ note: unit struct `m::ExistingPrivate` exists but is inaccessible LL | struct ExistingPrivate; | ^^^^^^^^^^^^^^^^^^^^^^^ not accessible -error[E0425]: cannot find value `NonExistingPrivate` in this scope +error[E0425]: cannot find value `NonExistingPrivate` --> $DIR/cfg_accessible.rs:53:5 | LL | NonExistingPrivate; | ^^^^^^^^^^^^^^^^^^ not found in this scope -error[E0425]: cannot find value `NonExistingTraitAlias` in this scope +error[E0425]: cannot find value `NonExistingTraitAlias` --> $DIR/cfg_accessible.rs:54:5 | LL | NonExistingTraitAlias; diff --git a/tests/ui/conditional-compilation/test-cfg.rs b/tests/ui/conditional-compilation/test-cfg.rs index adbbc309be447..700fb3954c40b 100644 --- a/tests/ui/conditional-compilation/test-cfg.rs +++ b/tests/ui/conditional-compilation/test-cfg.rs @@ -4,5 +4,5 @@ fn foo() {} fn main() { - foo(); //~ ERROR cannot find function `foo` in this scope + foo(); //~ ERROR cannot find function `foo` } diff --git a/tests/ui/conditional-compilation/test-cfg.stderr b/tests/ui/conditional-compilation/test-cfg.stderr index 9715f16acc20c..62bca67db729f 100644 --- a/tests/ui/conditional-compilation/test-cfg.stderr +++ b/tests/ui/conditional-compilation/test-cfg.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find function `foo` in this scope +error[E0425]: cannot find function `foo` --> $DIR/test-cfg.rs:7:5 | LL | foo(); diff --git a/tests/ui/const-generics/early/invalid-const-arguments.stderr b/tests/ui/const-generics/early/invalid-const-arguments.stderr index cee34e3b71593..3472a4c40ca48 100644 --- a/tests/ui/const-generics/early/invalid-const-arguments.stderr +++ b/tests/ui/const-generics/early/invalid-const-arguments.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `N` in this scope +error[E0412]: cannot find type `N` --> $DIR/invalid-const-arguments.rs:5:16 | LL | struct A; @@ -16,7 +16,7 @@ help: you might be missing a type parameter LL | impl Foo for A {} | +++ -error[E0412]: cannot find type `T` in this scope +error[E0412]: cannot find type `T` --> $DIR/invalid-const-arguments.rs:14:32 | LL | struct A; diff --git a/tests/ui/const-generics/generic_const_exprs/error_in_ty.rs b/tests/ui/const-generics/generic_const_exprs/error_in_ty.rs index 29ad935c0149c..76f0ce033a07a 100644 --- a/tests/ui/const-generics/generic_const_exprs/error_in_ty.rs +++ b/tests/ui/const-generics/generic_const_exprs/error_in_ty.rs @@ -4,7 +4,7 @@ #![allow(incomplete_features)] pub struct A {} -//~^ ERROR: cannot find value `x` in this scope +//~^ ERROR: cannot find value `x` //~| ERROR: `[usize; x]` is forbidden as the type of a const generic parameter impl A<2> { diff --git a/tests/ui/const-generics/generic_const_exprs/error_in_ty.stderr b/tests/ui/const-generics/generic_const_exprs/error_in_ty.stderr index 0e40255bcf59b..45fd2e1121db8 100644 --- a/tests/ui/const-generics/generic_const_exprs/error_in_ty.stderr +++ b/tests/ui/const-generics/generic_const_exprs/error_in_ty.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `x` in this scope +error[E0425]: cannot find value `x` --> $DIR/error_in_ty.rs:6:31 | LL | pub struct A {} diff --git a/tests/ui/const-generics/generic_const_exprs/expected-type-of-closure-body-to-be-a-closure-or-coroutine-ice-113776.rs b/tests/ui/const-generics/generic_const_exprs/expected-type-of-closure-body-to-be-a-closure-or-coroutine-ice-113776.rs index 4bea3ad87f5ed..0ca496880b346 100644 --- a/tests/ui/const-generics/generic_const_exprs/expected-type-of-closure-body-to-be-a-closure-or-coroutine-ice-113776.rs +++ b/tests/ui/const-generics/generic_const_exprs/expected-type-of-closure-body-to-be-a-closure-or-coroutine-ice-113776.rs @@ -9,7 +9,7 @@ use core::ops::SubAssign; fn f( data: &[(); { let f: F = async { 1 }; - //~^ ERROR cannot find type `F` in this scope + //~^ ERROR cannot find type `F` 1 }], diff --git a/tests/ui/const-generics/generic_const_exprs/expected-type-of-closure-body-to-be-a-closure-or-coroutine-ice-113776.stderr b/tests/ui/const-generics/generic_const_exprs/expected-type-of-closure-body-to-be-a-closure-or-coroutine-ice-113776.stderr index 416a938112424..a7633068d2973 100644 --- a/tests/ui/const-generics/generic_const_exprs/expected-type-of-closure-body-to-be-a-closure-or-coroutine-ice-113776.stderr +++ b/tests/ui/const-generics/generic_const_exprs/expected-type-of-closure-body-to-be-a-closure-or-coroutine-ice-113776.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `F` in this scope +error[E0412]: cannot find type `F` --> $DIR/expected-type-of-closure-body-to-be-a-closure-or-coroutine-ice-113776.rs:11:17 | LL | let f: F = async { 1 }; diff --git a/tests/ui/const-generics/generic_const_exprs/ice-predicates-of-no-entry-found-for-key-119275.rs b/tests/ui/const-generics/generic_const_exprs/ice-predicates-of-no-entry-found-for-key-119275.rs index 4ba696f4ae080..9a04e1bc3391d 100644 --- a/tests/ui/const-generics/generic_const_exprs/ice-predicates-of-no-entry-found-for-key-119275.rs +++ b/tests/ui/const-generics/generic_const_exprs/ice-predicates-of-no-entry-found-for-key-119275.rs @@ -5,7 +5,7 @@ fn bug(&self) //~^ ERROR `self` parameter is only allowed in associated functions -//~^^ ERROR cannot find type `Nat` in this scope +//~^^ ERROR cannot find type `Nat` where for [(); COT::BYTES]:, //~^ ERROR only lifetime parameters can be used in this context diff --git a/tests/ui/const-generics/generic_const_exprs/ice-predicates-of-no-entry-found-for-key-119275.stderr b/tests/ui/const-generics/generic_const_exprs/ice-predicates-of-no-entry-found-for-key-119275.stderr index ee0ec38ab0631..7a2a5ade7fea1 100644 --- a/tests/ui/const-generics/generic_const_exprs/ice-predicates-of-no-entry-found-for-key-119275.stderr +++ b/tests/ui/const-generics/generic_const_exprs/ice-predicates-of-no-entry-found-for-key-119275.stderr @@ -6,7 +6,7 @@ LL | fn bug(&self) | = note: associated functions are those in `impl` or `trait` definitions -error[E0412]: cannot find type `Nat` in this scope +error[E0412]: cannot find type `Nat` --> $DIR/ice-predicates-of-no-entry-found-for-key-119275.rs:6:17 | LL | fn bug(&self) diff --git a/tests/ui/const-generics/generic_const_exprs/issue-109141.rs b/tests/ui/const-generics/generic_const_exprs/issue-109141.rs index c6dd981cced00..c7d3de8b8c375 100644 --- a/tests/ui/const-generics/generic_const_exprs/issue-109141.rs +++ b/tests/ui/const-generics/generic_const_exprs/issue-109141.rs @@ -9,6 +9,6 @@ impl EntriesBuffer { } struct EntriesBuffer(Box<[[u8; HashesEntryLEN]; 5]>); -//~^ ERROR: cannot find value `HashesEntryLEN` in this scope +//~^ ERROR: cannot find value `HashesEntryLEN` fn main() {} diff --git a/tests/ui/const-generics/generic_const_exprs/issue-109141.stderr b/tests/ui/const-generics/generic_const_exprs/issue-109141.stderr index 7a9572d000d5a..0068873f08721 100644 --- a/tests/ui/const-generics/generic_const_exprs/issue-109141.stderr +++ b/tests/ui/const-generics/generic_const_exprs/issue-109141.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `HashesEntryLEN` in this scope +error[E0425]: cannot find value `HashesEntryLEN` --> $DIR/issue-109141.rs:11:32 | LL | struct EntriesBuffer(Box<[[u8; HashesEntryLEN]; 5]>); diff --git a/tests/ui/const-generics/generic_const_exprs/unevaluated-const-ice-119731.rs b/tests/ui/const-generics/generic_const_exprs/unevaluated-const-ice-119731.rs index 51cae20df84d4..1bf05041477b2 100644 --- a/tests/ui/const-generics/generic_const_exprs/unevaluated-const-ice-119731.rs +++ b/tests/ui/const-generics/generic_const_exprs/unevaluated-const-ice-119731.rs @@ -11,8 +11,8 @@ mod v20 { const v2: v11 = [[256; v4]; v4]; const v0: [[usize; v4]; v4] = v6(v8); - //~^ ERROR cannot find value `v8` in this scope - //~| ERROR cannot find function `v6` in this scope + //~^ ERROR cannot find value `v8` + //~| ERROR cannot find function `v6` pub struct v17 { //~^ WARN type `v17` should have an upper camel case name //~| ERROR `[[usize; v4]; v4]` is forbidden as the type of a const generic parameter @@ -21,16 +21,16 @@ mod v20 { impl v17<512, v0> { pub const fn v21() -> v18 {} - //~^ ERROR cannot find type `v18` in this scope + //~^ ERROR cannot find type `v18` } impl v17 { //~^ ERROR maximum number of nodes exceeded in constant v20::v17::::{constant#1} //~| ERROR maximum number of nodes exceeded in constant v20::v17::::{constant#1} pub const fn v21() -> v18 { - //~^ ERROR cannot find type `v18` in this scope + //~^ ERROR cannot find type `v18` v18 { _p: () } - //~^ ERROR cannot find struct, variant or union type `v18` in this scope + //~^ ERROR cannot find struct, variant or union type `v18` } } } diff --git a/tests/ui/const-generics/generic_const_exprs/unevaluated-const-ice-119731.stderr b/tests/ui/const-generics/generic_const_exprs/unevaluated-const-ice-119731.stderr index 39f022fbee9db..dfba4fab25874 100644 --- a/tests/ui/const-generics/generic_const_exprs/unevaluated-const-ice-119731.stderr +++ b/tests/ui/const-generics/generic_const_exprs/unevaluated-const-ice-119731.stderr @@ -7,13 +7,13 @@ LL | pub use v20::{v13, v17}; | no `v13` in `v20` | help: a similar name exists in the module: `v11` -error[E0425]: cannot find value `v8` in this scope +error[E0425]: cannot find value `v8` --> $DIR/unevaluated-const-ice-119731.rs:13:38 | LL | const v0: [[usize; v4]; v4] = v6(v8); | ^^ not found in this scope -error[E0412]: cannot find type `v18` in this scope +error[E0412]: cannot find type `v18` --> $DIR/unevaluated-const-ice-119731.rs:23:31 | LL | pub type v11 = [[usize; v4]; v4]; @@ -22,7 +22,7 @@ LL | pub type v11 = [[usize; v4]; v4]; LL | pub const fn v21() -> v18 {} | ^^^ help: a type alias with a similar name exists: `v11` -error[E0412]: cannot find type `v18` in this scope +error[E0412]: cannot find type `v18` --> $DIR/unevaluated-const-ice-119731.rs:30:31 | LL | pub type v11 = [[usize; v4]; v4]; @@ -31,7 +31,7 @@ LL | pub type v11 = [[usize; v4]; v4]; LL | pub const fn v21() -> v18 { | ^^^ help: a type alias with a similar name exists: `v11` -error[E0422]: cannot find struct, variant or union type `v18` in this scope +error[E0422]: cannot find struct, variant or union type `v18` --> $DIR/unevaluated-const-ice-119731.rs:32:13 | LL | pub type v11 = [[usize; v4]; v4]; @@ -54,7 +54,7 @@ warning: type `v17` should have an upper camel case name LL | pub struct v17 { | ^^^ help: convert the identifier to upper camel case (notice the capitalization): `V17` -error[E0425]: cannot find function `v6` in this scope +error[E0425]: cannot find function `v6` --> $DIR/unevaluated-const-ice-119731.rs:13:35 | LL | const v0: [[usize; v4]; v4] = v6(v8); diff --git a/tests/ui/const-generics/not_wf_param_in_rpitit.rs b/tests/ui/const-generics/not_wf_param_in_rpitit.rs index 5471dc9022f90..9e8a822c9c5e2 100644 --- a/tests/ui/const-generics/not_wf_param_in_rpitit.rs +++ b/tests/ui/const-generics/not_wf_param_in_rpitit.rs @@ -1,7 +1,7 @@ //@ edition:2021 trait Trait { - //~^ ERROR: cannot find value `bar` in this scope + //~^ ERROR: cannot find value `bar` //~| ERROR: cycle detected when computing type of `Trait::N` //~| ERROR: the trait `Trait` cannot be made into an object //~| ERROR: the trait `Trait` cannot be made into an object diff --git a/tests/ui/const-generics/not_wf_param_in_rpitit.stderr b/tests/ui/const-generics/not_wf_param_in_rpitit.stderr index 9095948d22b8a..d15c244ae5120 100644 --- a/tests/ui/const-generics/not_wf_param_in_rpitit.stderr +++ b/tests/ui/const-generics/not_wf_param_in_rpitit.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `bar` in this scope +error[E0425]: cannot find value `bar` --> $DIR/not_wf_param_in_rpitit.rs:3:30 | LL | trait Trait { diff --git a/tests/ui/const-generics/type_not_in_scope.stderr b/tests/ui/const-generics/type_not_in_scope.stderr index 5f45550a62796..55fa5b9cfc365 100644 --- a/tests/ui/const-generics/type_not_in_scope.stderr +++ b/tests/ui/const-generics/type_not_in_scope.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `X` in this scope +error[E0412]: cannot find type `X` --> $DIR/type_not_in_scope.rs:1:6 | LL | impl X { diff --git a/tests/ui/const-generics/unknown_adt.stderr b/tests/ui/const-generics/unknown_adt.stderr index 2e8210772e94a..d27314275c591 100644 --- a/tests/ui/const-generics/unknown_adt.stderr +++ b/tests/ui/const-generics/unknown_adt.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `UnknownStruct` in this scope +error[E0412]: cannot find type `UnknownStruct` --> $DIR/unknown_adt.rs:2:12 | LL | let _: UnknownStruct<7>; diff --git a/tests/ui/const_prop/ice-type-mismatch-when-copying-112824.rs b/tests/ui/const_prop/ice-type-mismatch-when-copying-112824.rs index 09f7e2ba5b1dd..69251b301a2a7 100644 --- a/tests/ui/const_prop/ice-type-mismatch-when-copying-112824.rs +++ b/tests/ui/const_prop/ice-type-mismatch-when-copying-112824.rs @@ -4,7 +4,7 @@ pub struct Opcode(pub u8); pub struct Opcode2(&'a S); //~^ ERROR use of undeclared lifetime name `'a` -//~^^ ERROR cannot find type `S` in this scope +//~^^ ERROR cannot find type `S` impl Opcode2 { pub const OP2: Opcode2 = Opcode2(Opcode(0x1)); diff --git a/tests/ui/const_prop/ice-type-mismatch-when-copying-112824.stderr b/tests/ui/const_prop/ice-type-mismatch-when-copying-112824.stderr index 9442eac0cf54a..9d2cd64fb5a66 100644 --- a/tests/ui/const_prop/ice-type-mismatch-when-copying-112824.stderr +++ b/tests/ui/const_prop/ice-type-mismatch-when-copying-112824.stderr @@ -6,7 +6,7 @@ LL | pub struct Opcode2(&'a S); | | | help: consider introducing lifetime `'a` here: `<'a>` -error[E0412]: cannot find type `S` in this scope +error[E0412]: cannot find type `S` --> $DIR/ice-type-mismatch-when-copying-112824.rs:5:24 | LL | pub struct Opcode2(&'a S); diff --git a/tests/ui/consts/const-eval/ice-unhandled-type-122191.rs b/tests/ui/consts/const-eval/ice-unhandled-type-122191.rs index a92b99976e262..376de119481cb 100644 --- a/tests/ui/consts/const-eval/ice-unhandled-type-122191.rs +++ b/tests/ui/consts/const-eval/ice-unhandled-type-122191.rs @@ -4,7 +4,7 @@ type Foo = impl Send; struct A; const VALUE: Foo = value(); -//~^ ERROR cannot find function `value` in this scope +//~^ ERROR cannot find function `value` fn test() { match VALUE { diff --git a/tests/ui/consts/const-eval/ice-unhandled-type-122191.stderr b/tests/ui/consts/const-eval/ice-unhandled-type-122191.stderr index daf0ccaa776ca..fcba6c45a35e4 100644 --- a/tests/ui/consts/const-eval/ice-unhandled-type-122191.stderr +++ b/tests/ui/consts/const-eval/ice-unhandled-type-122191.stderr @@ -8,7 +8,7 @@ LL | type Foo = impl Send; = help: add `#![feature(type_alias_impl_trait)]` 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[E0425]: cannot find function `value` in this scope +error[E0425]: cannot find function `value` --> $DIR/ice-unhandled-type-122191.rs:6:20 | LL | const VALUE: Foo = value(); diff --git a/tests/ui/consts/erroneous_type_in_const_return_value.rs b/tests/ui/consts/erroneous_type_in_const_return_value.rs index 304211f77da72..69a907d89d0fe 100644 --- a/tests/ui/consts/erroneous_type_in_const_return_value.rs +++ b/tests/ui/consts/erroneous_type_in_const_return_value.rs @@ -4,7 +4,7 @@ enum Eek { TheConst, UnusedByTheConst(Sum), - //~^ ERROR cannot find type `Sum` in this scope + //~^ ERROR cannot find type `Sum` } const EEK_ZERO: &[Eek] = &[]; diff --git a/tests/ui/consts/erroneous_type_in_const_return_value.stderr b/tests/ui/consts/erroneous_type_in_const_return_value.stderr index 453f5b640973f..390c8e5151ad9 100644 --- a/tests/ui/consts/erroneous_type_in_const_return_value.stderr +++ b/tests/ui/consts/erroneous_type_in_const_return_value.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `Sum` in this scope +error[E0412]: cannot find type `Sum` --> $DIR/erroneous_type_in_const_return_value.rs:6:22 | LL | UnusedByTheConst(Sum), diff --git a/tests/ui/consts/erroneous_type_in_promoted.rs b/tests/ui/consts/erroneous_type_in_promoted.rs index 32e33c2030fbb..6e34618bdbaf3 100644 --- a/tests/ui/consts/erroneous_type_in_promoted.rs +++ b/tests/ui/consts/erroneous_type_in_promoted.rs @@ -4,7 +4,7 @@ enum Eek { TheConst, UnusedByTheConst(Sum), - //~^ ERROR cannot find type `Sum` in this scope + //~^ ERROR cannot find type `Sum` } const fn foo() { diff --git a/tests/ui/consts/erroneous_type_in_promoted.stderr b/tests/ui/consts/erroneous_type_in_promoted.stderr index 0601fc9ebe7fb..f70404b2f5797 100644 --- a/tests/ui/consts/erroneous_type_in_promoted.stderr +++ b/tests/ui/consts/erroneous_type_in_promoted.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `Sum` in this scope +error[E0412]: cannot find type `Sum` --> $DIR/erroneous_type_in_promoted.rs:6:22 | LL | UnusedByTheConst(Sum), diff --git a/tests/ui/consts/ice-bad-input-type-for-cast-83056.rs b/tests/ui/consts/ice-bad-input-type-for-cast-83056.rs index 1a22dc2b5495a..1e5e9007c415a 100644 --- a/tests/ui/consts/ice-bad-input-type-for-cast-83056.rs +++ b/tests/ui/consts/ice-bad-input-type-for-cast-83056.rs @@ -3,5 +3,5 @@ struct S([bool; f as usize]); fn f() -> T {} -//~^ ERROR cannot find type `T` in this scope +//~^ ERROR cannot find type `T` pub fn main() {} diff --git a/tests/ui/consts/ice-bad-input-type-for-cast-83056.stderr b/tests/ui/consts/ice-bad-input-type-for-cast-83056.stderr index 115f168852058..374bf6cc8d8a5 100644 --- a/tests/ui/consts/ice-bad-input-type-for-cast-83056.stderr +++ b/tests/ui/consts/ice-bad-input-type-for-cast-83056.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `T` in this scope +error[E0412]: cannot find type `T` --> $DIR/ice-bad-input-type-for-cast-83056.rs:5:11 | LL | struct S([bool; f as usize]); diff --git a/tests/ui/consts/issue-104609.rs b/tests/ui/consts/issue-104609.rs index 9ee83b409c16f..b769569857daa 100644 --- a/tests/ui/consts/issue-104609.rs +++ b/tests/ui/consts/issue-104609.rs @@ -1,6 +1,6 @@ fn foo() { oops; - //~^ ERROR: cannot find value `oops` in this scope + //~^ ERROR: cannot find value `oops` } unsafe fn bar() { diff --git a/tests/ui/consts/issue-104609.stderr b/tests/ui/consts/issue-104609.stderr index fe84d83725fd2..408c0c242a7fd 100644 --- a/tests/ui/consts/issue-104609.stderr +++ b/tests/ui/consts/issue-104609.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `oops` in this scope +error[E0425]: cannot find value `oops` --> $DIR/issue-104609.rs:2:5 | LL | oops; diff --git a/tests/ui/consts/issue-116186.rs b/tests/ui/consts/issue-116186.rs index a77c38c64dc57..8a8d3e0747917 100644 --- a/tests/ui/consts/issue-116186.rs +++ b/tests/ui/consts/issue-116186.rs @@ -2,7 +2,7 @@ #![feature(generic_const_exprs)] fn something(path: [usize; N]) -> impl Clone { - //~^ ERROR cannot find value `N` in this scope + //~^ ERROR cannot find value `N` match path { [] => 0, //~ ERROR cannot pattern-match on an array without a fixed length _ => 1, diff --git a/tests/ui/consts/issue-116186.stderr b/tests/ui/consts/issue-116186.stderr index e6eae2d9f55ef..2e8c2dc4d3d78 100644 --- a/tests/ui/consts/issue-116186.stderr +++ b/tests/ui/consts/issue-116186.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `N` in this scope +error[E0425]: cannot find value `N` --> $DIR/issue-116186.rs:4:28 | LL | fn something(path: [usize; N]) -> impl Clone { diff --git a/tests/ui/consts/issue-90878-2.rs b/tests/ui/consts/issue-90878-2.rs index 0e61c65305fbe..0a5cb98c8206a 100644 --- a/tests/ui/consts/issue-90878-2.rs +++ b/tests/ui/consts/issue-90878-2.rs @@ -1,5 +1,5 @@ #![l=|x|[b;x ]] //~ ERROR attribute value must be a literal -//~^ ERROR cannot find attribute `l` in this scope +//~^ ERROR cannot find attribute `l` // notice the space at the start, // we can't attach any attributes to this file because it needs to be at the start diff --git a/tests/ui/consts/issue-91434.rs b/tests/ui/consts/issue-91434.rs index 001dc708f8932..9131b16ec4df5 100644 --- a/tests/ui/consts/issue-91434.rs +++ b/tests/ui/consts/issue-91434.rs @@ -1,5 +1,5 @@ fn main() { [9; [[9E; h]]]; //~^ ERROR: expected at least one digit in exponent - //~| ERROR: cannot find value `h` in this scope [E0425] + //~| ERROR: cannot find value `h` [E0425] } diff --git a/tests/ui/consts/issue-91434.stderr b/tests/ui/consts/issue-91434.stderr index 08d3ad77053d5..3123a12e77cb6 100644 --- a/tests/ui/consts/issue-91434.stderr +++ b/tests/ui/consts/issue-91434.stderr @@ -4,7 +4,7 @@ error: expected at least one digit in exponent LL | [9; [[9E; h]]]; | ^^ -error[E0425]: cannot find value `h` in this scope +error[E0425]: cannot find value `h` --> $DIR/issue-91434.rs:2:15 | LL | [9; [[9E; h]]]; diff --git a/tests/ui/coroutine/gen_block.none.stderr b/tests/ui/coroutine/gen_block.none.stderr index 64fa2be003de5..781434ad05ab9 100644 --- a/tests/ui/coroutine/gen_block.none.stderr +++ b/tests/ui/coroutine/gen_block.none.stderr @@ -6,19 +6,19 @@ LL | let y = gen { yield 42 }; | | | while parsing this struct -error[E0422]: cannot find struct, variant or union type `gen` in this scope +error[E0422]: cannot find struct, variant or union type `gen` --> $DIR/gen_block.rs:7:13 | LL | let x = gen {}; | ^^^ not found in this scope -error[E0422]: cannot find struct, variant or union type `gen` in this scope +error[E0422]: cannot find struct, variant or union type `gen` --> $DIR/gen_block.rs:10:13 | LL | let y = gen { yield 42 }; | ^^^ not found in this scope -error[E0422]: cannot find struct, variant or union type `gen` in this scope +error[E0422]: cannot find struct, variant or union type `gen` --> $DIR/gen_block.rs:13:5 | LL | gen {}; diff --git a/tests/ui/coroutine/layout-error.rs b/tests/ui/coroutine/layout-error.rs index 3e26cf17d29ec..f4d7b16326095 100644 --- a/tests/ui/coroutine/layout-error.rs +++ b/tests/ui/coroutine/layout-error.rs @@ -24,7 +24,7 @@ mod helper { F:, { async fn cb() { - let a = Foo; //~ ERROR cannot find value `Foo` in this scope + let a = Foo; //~ ERROR cannot find value `Foo` } Task::spawn(&POOL, || cb()); diff --git a/tests/ui/coroutine/layout-error.stderr b/tests/ui/coroutine/layout-error.stderr index ceadb62c99988..bb7d32d3ea025 100644 --- a/tests/ui/coroutine/layout-error.stderr +++ b/tests/ui/coroutine/layout-error.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `Foo` in this scope +error[E0425]: cannot find value `Foo` --> $DIR/layout-error.rs:27:21 | LL | let a = Foo; diff --git a/tests/ui/custom_attribute.rs b/tests/ui/custom_attribute.rs index 4957184229da0..6bbe272d0b642 100644 --- a/tests/ui/custom_attribute.rs +++ b/tests/ui/custom_attribute.rs @@ -1,9 +1,9 @@ #![feature(stmt_expr_attributes)] -#[foo] //~ ERROR cannot find attribute `foo` in this scope +#[foo] //~ ERROR cannot find attribute `foo` fn main() { - #[foo] //~ ERROR cannot find attribute `foo` in this scope + #[foo] //~ ERROR cannot find attribute `foo` let x = (); - #[foo] //~ ERROR cannot find attribute `foo` in this scope + #[foo] //~ ERROR cannot find attribute `foo` x } diff --git a/tests/ui/deduplicate-diagnostics.rs b/tests/ui/deduplicate-diagnostics.rs index 54bd5dd5098c1..c36175426bc0a 100644 --- a/tests/ui/deduplicate-diagnostics.rs +++ b/tests/ui/deduplicate-diagnostics.rs @@ -1,8 +1,8 @@ //@ revisions: duplicate deduplicate //@[deduplicate] compile-flags: -Z deduplicate-diagnostics=yes -#[derive(Unresolved)] //~ ERROR cannot find derive macro `Unresolved` in this scope - //[duplicate]~| ERROR cannot find derive macro `Unresolved` in this scope +#[derive(Unresolved)] //~ ERROR cannot find derive macro `Unresolved` + //[duplicate]~| ERROR cannot find derive macro `Unresolved` struct S; #[deny("literal")] //~ ERROR malformed lint attribute input diff --git a/tests/ui/delegation/bad-resolve.rs b/tests/ui/delegation/bad-resolve.rs index f378e05304b29..184ec20bb5d86 100644 --- a/tests/ui/delegation/bad-resolve.rs +++ b/tests/ui/delegation/bad-resolve.rs @@ -29,11 +29,11 @@ impl Trait for S { //~| ERROR expected method or associated constant, found associated type `Trait::Type` reuse ::baz; //~^ ERROR method `baz` is not a member of trait `Trait` - //~| ERROR cannot find method or associated constant `baz` in trait `Trait` + //~| ERROR cannot find method or associated constant `baz` reuse ::bar; reuse foo { &self.0 } - //~^ ERROR cannot find function `foo` in this scope + //~^ ERROR cannot find function `foo` } mod prefix {} diff --git a/tests/ui/delegation/bad-resolve.stderr b/tests/ui/delegation/bad-resolve.stderr index 883ff523bcfea..8dd883e68be2c 100644 --- a/tests/ui/delegation/bad-resolve.stderr +++ b/tests/ui/delegation/bad-resolve.stderr @@ -39,7 +39,7 @@ LL | reuse ::Type; | = note: can't use a type alias as a constructor -error[E0576]: cannot find method or associated constant `baz` in trait `Trait` +error[E0576]: cannot find method or associated constant `baz` --> $DIR/bad-resolve.rs:30:25 | LL | fn bar() {} @@ -48,7 +48,7 @@ LL | fn bar() {} LL | reuse ::baz; | ^^^ help: an associated function with a similar name exists: `bar` -error[E0425]: cannot find function `foo` in this scope +error[E0425]: cannot find function `foo` --> $DIR/bad-resolve.rs:35:11 | LL | reuse foo { &self.0 } diff --git a/tests/ui/delegation/explicit-paths.rs b/tests/ui/delegation/explicit-paths.rs index a91ca4cb931ed..11637dda16102 100644 --- a/tests/ui/delegation/explicit-paths.rs +++ b/tests/ui/delegation/explicit-paths.rs @@ -27,7 +27,7 @@ mod fn_to_other { //~^ ERROR delegation to a trait method from a free function is not supported yet reuse to_reuse::foo3; reuse S::foo4; - //~^ ERROR cannot find function `foo4` in `S` + //~^ ERROR cannot find function `foo4` } mod inherent_impl_assoc_fn_to_other { @@ -38,7 +38,7 @@ mod inherent_impl_assoc_fn_to_other { reuse ::foo2; reuse to_reuse::foo3; reuse F::foo4 { &self.0 } - //~^ ERROR cannot find function `foo4` in `F` + //~^ ERROR cannot find function `foo4` } } @@ -52,7 +52,7 @@ mod trait_impl_assoc_fn_to_other { //~^ ERROR method `foo3` is not a member of trait `Trait` reuse F::foo4 { &self.0 } //~^ ERROR method `foo4` is not a member of trait `Trait` - //~| ERROR cannot find function `foo4` in `F` + //~| ERROR cannot find function `foo4` } } @@ -65,7 +65,7 @@ mod trait_assoc_fn_to_other { reuse ::foo2; reuse to_reuse::foo3; reuse F::foo4 { &F } - //~^ ERROR cannot find function `foo4` in `F` + //~^ ERROR cannot find function `foo4` } } diff --git a/tests/ui/delegation/explicit-paths.stderr b/tests/ui/delegation/explicit-paths.stderr index d33c5da4377b1..833c6d5974175 100644 --- a/tests/ui/delegation/explicit-paths.stderr +++ b/tests/ui/delegation/explicit-paths.stderr @@ -16,13 +16,13 @@ LL | reuse F::foo4 { &self.0 } | | help: there is an associated function with a similar name: `foo1` | not a member of trait `Trait` -error[E0425]: cannot find function `foo4` in `S` +error[E0425]: cannot find function `foo4` --> $DIR/explicit-paths.rs:29:14 | LL | reuse S::foo4; | ^^^^ not found in `S` -error[E0425]: cannot find function `foo4` in `F` +error[E0425]: cannot find function `foo4` --> $DIR/explicit-paths.rs:40:18 | LL | reuse F::foo4 { &self.0 } @@ -34,7 +34,7 @@ note: function `fn_to_other::foo4` exists but is inaccessible LL | reuse S::foo4; | ^^^^^^^^^^^^^^ not accessible -error[E0425]: cannot find function `foo4` in `F` +error[E0425]: cannot find function `foo4` --> $DIR/explicit-paths.rs:53:18 | LL | reuse F::foo4 { &self.0 } @@ -46,7 +46,7 @@ note: function `fn_to_other::foo4` exists but is inaccessible LL | reuse S::foo4; | ^^^^^^^^^^^^^^ not accessible -error[E0425]: cannot find function `foo4` in `F` +error[E0425]: cannot find function `foo4` --> $DIR/explicit-paths.rs:67:18 | LL | reuse F::foo4 { &F } diff --git a/tests/ui/delegation/ice-issue-124342.rs b/tests/ui/delegation/ice-issue-124342.rs index ad62f6bd54af9..d1acee5135c39 100644 --- a/tests/ui/delegation/ice-issue-124342.rs +++ b/tests/ui/delegation/ice-issue-124342.rs @@ -5,8 +5,8 @@ mod to_reuse {} trait Trait { reuse to_reuse::foo { foo } - //~^ ERROR cannot find function `foo` in module `to_reuse` - //~| ERROR cannot find value `foo` in this scope + //~^ ERROR cannot find function `foo` + //~| ERROR cannot find value `foo` } fn main() {} diff --git a/tests/ui/delegation/ice-issue-124342.stderr b/tests/ui/delegation/ice-issue-124342.stderr index f9a3684d64932..d6cd20827be64 100644 --- a/tests/ui/delegation/ice-issue-124342.stderr +++ b/tests/ui/delegation/ice-issue-124342.stderr @@ -1,10 +1,10 @@ -error[E0425]: cannot find function `foo` in module `to_reuse` +error[E0425]: cannot find function `foo` --> $DIR/ice-issue-124342.rs:7:21 | LL | reuse to_reuse::foo { foo } - | ^^^ not found in `to_reuse` + | ^^^ not found in module `to_reuse` -error[E0425]: cannot find value `foo` in this scope +error[E0425]: cannot find value `foo` --> $DIR/ice-issue-124342.rs:7:27 | LL | reuse to_reuse::foo { foo } diff --git a/tests/ui/delegation/target-expr.rs b/tests/ui/delegation/target-expr.rs index fd7ea943b9d5e..889cb8d3daff8 100644 --- a/tests/ui/delegation/target-expr.rs +++ b/tests/ui/delegation/target-expr.rs @@ -36,5 +36,5 @@ fn main() { self.0; //~^ ERROR expected value, found module `self` let z = x; - //~^ ERROR cannot find value `x` in this scope + //~^ ERROR cannot find value `x` } diff --git a/tests/ui/delegation/target-expr.stderr b/tests/ui/delegation/target-expr.stderr index b30f0c474c68b..f5858d99620a7 100644 --- a/tests/ui/delegation/target-expr.stderr +++ b/tests/ui/delegation/target-expr.stderr @@ -26,7 +26,7 @@ LL | fn main() { LL | self.0; | ^^^^ `self` value is a keyword only available in methods with a `self` parameter -error[E0425]: cannot find value `x` in this scope +error[E0425]: cannot find value `x` --> $DIR/target-expr.rs:38:13 | LL | let z = x; diff --git a/tests/ui/derived-errors/issue-31997.rs b/tests/ui/derived-errors/issue-31997.rs index ff619313afb5b..a4cbf2c46df89 100644 --- a/tests/ui/derived-errors/issue-31997.rs +++ b/tests/ui/derived-errors/issue-31997.rs @@ -11,7 +11,7 @@ fn closure(x: F) -> Result } fn foo() -> Result<(), ()> { - try!(closure(|| bar(core::ptr::null_mut()))); //~ ERROR cannot find function `bar` in this scope + try!(closure(|| bar(core::ptr::null_mut()))); //~ ERROR cannot find function `bar` Ok(()) } diff --git a/tests/ui/derived-errors/issue-31997.stderr b/tests/ui/derived-errors/issue-31997.stderr index 7d6415fef83c1..0c765fad72b40 100644 --- a/tests/ui/derived-errors/issue-31997.stderr +++ b/tests/ui/derived-errors/issue-31997.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find function `bar` in this scope +error[E0425]: cannot find function `bar` --> $DIR/issue-31997.rs:14:21 | LL | try!(closure(|| bar(core::ptr::null_mut()))); diff --git a/tests/ui/derives/deriving-bounds.rs b/tests/ui/derives/deriving-bounds.rs index 95d440420b065..ed54eb0e64856 100644 --- a/tests/ui/derives/deriving-bounds.rs +++ b/tests/ui/derives/deriving-bounds.rs @@ -1,11 +1,11 @@ #[derive(Send)] -//~^ ERROR cannot find derive macro `Send` in this scope -//~| ERROR cannot find derive macro `Send` in this scope +//~^ ERROR cannot find derive macro `Send` +//~| ERROR cannot find derive macro `Send` struct Test; #[derive(Sync)] -//~^ ERROR cannot find derive macro `Sync` in this scope -//~| ERROR cannot find derive macro `Sync` in this scope +//~^ ERROR cannot find derive macro `Sync` +//~| ERROR cannot find derive macro `Sync` struct Test1; pub fn main() {} diff --git a/tests/ui/derives/deriving-meta-unknown-trait.rs b/tests/ui/derives/deriving-meta-unknown-trait.rs index 6463a7664de93..d2f92120cb297 100644 --- a/tests/ui/derives/deriving-meta-unknown-trait.rs +++ b/tests/ui/derives/deriving-meta-unknown-trait.rs @@ -1,6 +1,6 @@ #[derive(Eqr)] -//~^ ERROR cannot find derive macro `Eqr` in this scope -//~| ERROR cannot find derive macro `Eqr` in this scope +//~^ ERROR cannot find derive macro `Eqr` +//~| ERROR cannot find derive macro `Eqr` struct Foo; pub fn main() {} diff --git a/tests/ui/derives/deriving-primitive.rs b/tests/ui/derives/deriving-primitive.rs index 1173eca640fc3..a6de175c9cbc4 100644 --- a/tests/ui/derives/deriving-primitive.rs +++ b/tests/ui/derives/deriving-primitive.rs @@ -1,5 +1,5 @@ -#[derive(FromPrimitive)] //~ ERROR cannot find derive macro `FromPrimitive` in this scope - //~| ERROR cannot find derive macro `FromPrimitive` in this scope +#[derive(FromPrimitive)] //~ ERROR cannot find derive macro `FromPrimitive` + //~| ERROR cannot find derive macro `FromPrimitive` enum Foo {} fn main() {} diff --git a/tests/ui/diagnostic_namespace/requires_path.rs b/tests/ui/diagnostic_namespace/requires_path.rs index 4f3a1319cafff..8c0cdc0f89af0 100644 --- a/tests/ui/diagnostic_namespace/requires_path.rs +++ b/tests/ui/diagnostic_namespace/requires_path.rs @@ -1,5 +1,5 @@ #[diagnostic] -//~^ERROR cannot find attribute `diagnostic` in this scope +//~^ERROR cannot find attribute `diagnostic` pub struct Bar; diff --git a/tests/ui/did_you_mean/issue-103909.rs b/tests/ui/did_you_mean/issue-103909.rs index 20b67cd102d70..b7d5c32e5e087 100644 --- a/tests/ui/did_you_mean/issue-103909.rs +++ b/tests/ui/did_you_mean/issue-103909.rs @@ -3,7 +3,7 @@ use std::fs::File; fn main() { if Err(err) = File::open("hello.txt") { - //~^ ERROR: cannot find value `err` in this scope + //~^ ERROR: cannot find value `err` //~| ERROR: mismatched types } } diff --git a/tests/ui/did_you_mean/issue-103909.stderr b/tests/ui/did_you_mean/issue-103909.stderr index 8641017470ba0..a684a29ad62d9 100644 --- a/tests/ui/did_you_mean/issue-103909.stderr +++ b/tests/ui/did_you_mean/issue-103909.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `err` in this scope +error[E0425]: cannot find value `err` --> $DIR/issue-103909.rs:5:12 | LL | if Err(err) = File::open("hello.txt") { diff --git a/tests/ui/did_you_mean/issue-56028-there-is-an-enum-variant.rs b/tests/ui/did_you_mean/issue-56028-there-is-an-enum-variant.rs index 264cfa449942c..fa4f0bd8a95e2 100644 --- a/tests/ui/did_you_mean/issue-56028-there-is-an-enum-variant.rs +++ b/tests/ui/did_you_mean/issue-56028-there-is-an-enum-variant.rs @@ -7,8 +7,8 @@ enum Solidify { Set } enum UnorderedCollection { Set } fn setup() -> Set { Set } -//~^ ERROR cannot find type `Set` in this scope -//~| ERROR cannot find value `Set` in this scope +//~^ ERROR cannot find type `Set` +//~| ERROR cannot find value `Set` fn main() { setup(); diff --git a/tests/ui/did_you_mean/issue-56028-there-is-an-enum-variant.stderr b/tests/ui/did_you_mean/issue-56028-there-is-an-enum-variant.stderr index b1a15b8594a0a..65990ec80c35b 100644 --- a/tests/ui/did_you_mean/issue-56028-there-is-an-enum-variant.stderr +++ b/tests/ui/did_you_mean/issue-56028-there-is-an-enum-variant.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `Set` in this scope +error[E0412]: cannot find type `Set` --> $DIR/issue-56028-there-is-an-enum-variant.rs:9:15 | LL | fn setup() -> Set { Set } @@ -16,7 +16,7 @@ LL | fn setup() -> PutDown { Set } | ~~~~~~~ and 3 other candidates -error[E0425]: cannot find value `Set` in this scope +error[E0425]: cannot find value `Set` --> $DIR/issue-56028-there-is-an-enum-variant.rs:9:21 | LL | fn setup() -> Set { Set } diff --git a/tests/ui/did_you_mean/println-typo.rs b/tests/ui/did_you_mean/println-typo.rs index 685b5e1f28403..679fda3719332 100644 --- a/tests/ui/did_you_mean/println-typo.rs +++ b/tests/ui/did_you_mean/println-typo.rs @@ -1,6 +1,6 @@ // https://internals.rust-lang.org/t/18227 fn main() { - prinltn!(); //~ ERROR cannot find macro `prinltn` in this scope + prinltn!(); //~ ERROR cannot find macro `prinltn` //^ a macro with a similar name exists: `println` } diff --git a/tests/ui/dropck/drop-on-non-struct.stderr b/tests/ui/dropck/drop-on-non-struct.stderr index e8fbe5e972642..06c7c6c0d75e4 100644 --- a/tests/ui/dropck/drop-on-non-struct.stderr +++ b/tests/ui/dropck/drop-on-non-struct.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `Nonexistent` in this scope +error[E0412]: cannot find type `Nonexistent` --> $DIR/drop-on-non-struct.rs:9:15 | LL | impl Drop for Nonexistent { diff --git a/tests/ui/editions/async-block-2015.rs b/tests/ui/editions/async-block-2015.rs index 3daf4930c5b4b..3364eee59e8ef 100644 --- a/tests/ui/editions/async-block-2015.rs +++ b/tests/ui/editions/async-block-2015.rs @@ -5,7 +5,7 @@ async fn foo() { //~| NOTE for more on editions, read https://doc.rust-lang.org/edition-guide let x = async {}; - //~^ ERROR cannot find struct, variant or union type `async` in this scope + //~^ ERROR cannot find struct, variant or union type `async` //~| NOTE `async` blocks are only allowed in Rust 2018 or later let y = async { //~ NOTE `async` blocks are only allowed in Rust 2018 or later let x = 42; diff --git a/tests/ui/editions/async-block-2015.stderr b/tests/ui/editions/async-block-2015.stderr index b792b8c1e0dd8..93962ceff3e2b 100644 --- a/tests/ui/editions/async-block-2015.stderr +++ b/tests/ui/editions/async-block-2015.stderr @@ -29,7 +29,7 @@ LL | 42 = help: pass `--edition 2021` to `rustc` = note: for more on editions, read https://doc.rust-lang.org/edition-guide -error[E0422]: cannot find struct, variant or union type `async` in this scope +error[E0422]: cannot find struct, variant or union type `async` --> $DIR/async-block-2015.rs:7:13 | LL | let x = async {}; diff --git a/tests/ui/enum/suggest-default-attribute.rs b/tests/ui/enum/suggest-default-attribute.rs index 1d7567e60a57c..6dbc263e0a7a3 100644 --- a/tests/ui/enum/suggest-default-attribute.rs +++ b/tests/ui/enum/suggest-default-attribute.rs @@ -1,6 +1,6 @@ pub enum Test { //~ HELP consider adding a derive #[default] - //~^ ERROR cannot find attribute `default` in this scope + //~^ ERROR cannot find attribute `default` First, Second, } diff --git a/tests/ui/error-codes/E0405.stderr b/tests/ui/error-codes/E0405.stderr index 1fb115c9e999b..f264ad58ec07a 100644 --- a/tests/ui/error-codes/E0405.stderr +++ b/tests/ui/error-codes/E0405.stderr @@ -1,4 +1,4 @@ -error[E0405]: cannot find trait `SomeTrait` in this scope +error[E0405]: cannot find trait `SomeTrait` --> $DIR/E0405.rs:3:6 | LL | impl SomeTrait for Foo {} diff --git a/tests/ui/error-codes/E0411.stderr b/tests/ui/error-codes/E0411.stderr index 16da10348a28f..3a2977d011d56 100644 --- a/tests/ui/error-codes/E0411.stderr +++ b/tests/ui/error-codes/E0411.stderr @@ -1,4 +1,4 @@ -error[E0411]: cannot find type `Self` in this scope +error[E0411]: cannot find type `Self` --> $DIR/E0411.rs:2:6 | LL | fn main() { diff --git a/tests/ui/error-codes/E0412.stderr b/tests/ui/error-codes/E0412.stderr index 7c1172642faff..105a36b30d316 100644 --- a/tests/ui/error-codes/E0412.stderr +++ b/tests/ui/error-codes/E0412.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `Something` in this scope +error[E0412]: cannot find type `Something` --> $DIR/E0412.rs:1:6 | LL | impl Something {} diff --git a/tests/ui/error-codes/E0425.stderr b/tests/ui/error-codes/E0425.stderr index db78dc3f7abe3..fb21ca3302474 100644 --- a/tests/ui/error-codes/E0425.stderr +++ b/tests/ui/error-codes/E0425.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `elf` in this scope +error[E0425]: cannot find value `elf` --> $DIR/E0425.rs:3:9 | LL | elf; diff --git a/tests/ui/error-festival.stderr b/tests/ui/error-festival.stderr index 9d75671c4e6b4..b0983fbb6bf88 100644 --- a/tests/ui/error-festival.stderr +++ b/tests/ui/error-festival.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `y` in this scope +error[E0425]: cannot find value `y` --> $DIR/error-festival.rs:14:5 | LL | y = 2; diff --git a/tests/ui/errors/remap-path-prefix.normal.stderr b/tests/ui/errors/remap-path-prefix.normal.stderr index 46d33d26052cb..32029becfa86e 100644 --- a/tests/ui/errors/remap-path-prefix.normal.stderr +++ b/tests/ui/errors/remap-path-prefix.normal.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `ferris` in this scope +error[E0425]: cannot find value `ferris` --> remapped/errors/remap-path-prefix.rs:19:5 | LL | ferris diff --git a/tests/ui/errors/remap-path-prefix.with-diagnostic-scope.stderr b/tests/ui/errors/remap-path-prefix.with-diagnostic-scope.stderr index 46d33d26052cb..32029becfa86e 100644 --- a/tests/ui/errors/remap-path-prefix.with-diagnostic-scope.stderr +++ b/tests/ui/errors/remap-path-prefix.with-diagnostic-scope.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `ferris` in this scope +error[E0425]: cannot find value `ferris` --> remapped/errors/remap-path-prefix.rs:19:5 | LL | ferris diff --git a/tests/ui/errors/remap-path-prefix.without-diagnostic-scope.stderr b/tests/ui/errors/remap-path-prefix.without-diagnostic-scope.stderr index 0badea6e27bf3..02131f934d312 100644 --- a/tests/ui/errors/remap-path-prefix.without-diagnostic-scope.stderr +++ b/tests/ui/errors/remap-path-prefix.without-diagnostic-scope.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `ferris` in this scope +error[E0425]: cannot find value `ferris` --> $DIR/remap-path-prefix.rs:19:5 | LL | ferris diff --git a/tests/ui/expr/if/bad-if-let-suggestion.rs b/tests/ui/expr/if/bad-if-let-suggestion.rs index b0d0676e1ea75..823013fd39c13 100644 --- a/tests/ui/expr/if/bad-if-let-suggestion.rs +++ b/tests/ui/expr/if/bad-if-let-suggestion.rs @@ -1,20 +1,20 @@ fn a() { if let x = 1 && i = 2 {} - //~^ ERROR cannot find value `i` in this scope + //~^ ERROR cannot find value `i` //~| ERROR mismatched types //~| ERROR expected expression, found `let` statement } fn b() { if (i + j) = i {} - //~^ ERROR cannot find value `i` in this scope - //~| ERROR cannot find value `i` in this scope - //~| ERROR cannot find value `j` in this scope + //~^ ERROR cannot find value `i` + //~| ERROR cannot find value `i` + //~| ERROR cannot find value `j` } fn c() { if x[0] = 1 {} - //~^ ERROR cannot find value `x` in this scope + //~^ ERROR cannot find value `x` } fn main() {} diff --git a/tests/ui/expr/if/bad-if-let-suggestion.stderr b/tests/ui/expr/if/bad-if-let-suggestion.stderr index 0d1f895bd82bf..0c9b53c2ce48d 100644 --- a/tests/ui/expr/if/bad-if-let-suggestion.stderr +++ b/tests/ui/expr/if/bad-if-let-suggestion.stderr @@ -14,13 +14,13 @@ help: you might have meant to compare for equality LL | if let x = 1 && i == 2 {} | + -error[E0425]: cannot find value `i` in this scope +error[E0425]: cannot find value `i` --> $DIR/bad-if-let-suggestion.rs:2:21 | LL | if let x = 1 && i = 2 {} | ^ not found in this scope -error[E0425]: cannot find value `i` in this scope +error[E0425]: cannot find value `i` --> $DIR/bad-if-let-suggestion.rs:9:9 | LL | fn a() { @@ -29,7 +29,7 @@ LL | fn a() { LL | if (i + j) = i {} | ^ help: a function with a similar name exists: `a` -error[E0425]: cannot find value `j` in this scope +error[E0425]: cannot find value `j` --> $DIR/bad-if-let-suggestion.rs:9:13 | LL | fn a() { @@ -38,7 +38,7 @@ LL | fn a() { LL | if (i + j) = i {} | ^ help: a function with a similar name exists: `a` -error[E0425]: cannot find value `i` in this scope +error[E0425]: cannot find value `i` --> $DIR/bad-if-let-suggestion.rs:9:18 | LL | fn a() { @@ -47,7 +47,7 @@ LL | fn a() { LL | if (i + j) = i {} | ^ help: a function with a similar name exists: `a` -error[E0425]: cannot find value `x` in this scope +error[E0425]: cannot find value `x` --> $DIR/bad-if-let-suggestion.rs:16:8 | LL | fn a() { diff --git a/tests/ui/expr/malformed_closure/ruby_style_closure.rs b/tests/ui/expr/malformed_closure/ruby_style_closure.rs index fdec072b8a864..7f99d0bcc23c9 100644 --- a/tests/ui/expr/malformed_closure/ruby_style_closure.rs +++ b/tests/ui/expr/malformed_closure/ruby_style_closure.rs @@ -10,6 +10,6 @@ fn main() { let p = Some(45).and_then({ |x| println!("doubling {}", x); Some(x * 2) - //~^ ERROR: cannot find value `x` in this scope + //~^ ERROR: cannot find value `x` }); } diff --git a/tests/ui/expr/malformed_closure/ruby_style_closure.stderr b/tests/ui/expr/malformed_closure/ruby_style_closure.stderr index b1607bbacc926..deff78a926edc 100644 --- a/tests/ui/expr/malformed_closure/ruby_style_closure.stderr +++ b/tests/ui/expr/malformed_closure/ruby_style_closure.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `x` in this scope +error[E0425]: cannot find value `x` --> $DIR/ruby_style_closure.rs:12:14 | LL | Some(x * 2) diff --git a/tests/ui/extern/extern-with-type-bounds.rs b/tests/ui/extern/extern-with-type-bounds.rs index 99e9801fd4010..63856e4effbe9 100644 --- a/tests/ui/extern/extern-with-type-bounds.rs +++ b/tests/ui/extern/extern-with-type-bounds.rs @@ -16,7 +16,7 @@ extern "rust-intrinsic" { // Unresolved bounds should still error. fn align_of() -> usize; - //~^ ERROR cannot find trait `NoSuchTrait` in this scope + //~^ ERROR cannot find trait `NoSuchTrait` } fn main() {} diff --git a/tests/ui/extern/extern-with-type-bounds.stderr b/tests/ui/extern/extern-with-type-bounds.stderr index 42448d9e9246d..266b67cabeb91 100644 --- a/tests/ui/extern/extern-with-type-bounds.stderr +++ b/tests/ui/extern/extern-with-type-bounds.stderr @@ -1,4 +1,4 @@ -error[E0405]: cannot find trait `NoSuchTrait` in this scope +error[E0405]: cannot find trait `NoSuchTrait` --> $DIR/extern-with-type-bounds.rs:18:20 | LL | fn align_of() -> usize; diff --git a/tests/ui/extern/issue-112363-extern-item-where-clauses-debug-ice.rs b/tests/ui/extern/issue-112363-extern-item-where-clauses-debug-ice.rs index 17e08f511d71f..e25c9ea285ece 100644 --- a/tests/ui/extern/issue-112363-extern-item-where-clauses-debug-ice.rs +++ b/tests/ui/extern/issue-112363-extern-item-where-clauses-debug-ice.rs @@ -2,8 +2,8 @@ extern "C" { type Item = [T] where [T]: Sized; //~^ incorrect `type` inside `extern` block //~| `type`s inside `extern` blocks cannot have `where` clauses - //~| cannot find type `T` in this scope - //~| cannot find type `T` in this scope + //~| cannot find type `T` + //~| cannot find type `T` //~| extern types are experimental } diff --git a/tests/ui/extern/issue-112363-extern-item-where-clauses-debug-ice.stderr b/tests/ui/extern/issue-112363-extern-item-where-clauses-debug-ice.stderr index 039e50b5e12da..3064d24c4462c 100644 --- a/tests/ui/extern/issue-112363-extern-item-where-clauses-debug-ice.stderr +++ b/tests/ui/extern/issue-112363-extern-item-where-clauses-debug-ice.stderr @@ -20,13 +20,13 @@ LL | type Item = [T] where [T]: Sized; | = note: for more information, visit https://doc.rust-lang.org/std/keyword.extern.html -error[E0412]: cannot find type `T` in this scope +error[E0412]: cannot find type `T` --> $DIR/issue-112363-extern-item-where-clauses-debug-ice.rs:2:28 | LL | type Item = [T] where [T]: Sized; | ^ not found in this scope -error[E0412]: cannot find type `T` in this scope +error[E0412]: cannot find type `T` --> $DIR/issue-112363-extern-item-where-clauses-debug-ice.rs:2:18 | LL | type Item = [T] where [T]: Sized; diff --git a/tests/ui/extern/issue-80074.rs b/tests/ui/extern/issue-80074.rs index ba7b55a450f51..4d84f551beaf3 100644 --- a/tests/ui/extern/issue-80074.rs +++ b/tests/ui/extern/issue-80074.rs @@ -14,7 +14,7 @@ fn main() { //~^ WARN: macro `foo` is private //~| WARN: it will become a hard error in a future release! bar!(); - //~^ ERROR: cannot find macro `bar` in this scope + //~^ ERROR: cannot find macro `bar` m!(); - //~^ ERROR: cannot find macro `m` in this scope + //~^ ERROR: cannot find macro `m` } diff --git a/tests/ui/feature-gates/feature-gate-concat_idents2.rs b/tests/ui/feature-gates/feature-gate-concat_idents2.rs index 9660ffeafa518..0da02c72e5216 100644 --- a/tests/ui/feature-gates/feature-gate-concat_idents2.rs +++ b/tests/ui/feature-gates/feature-gate-concat_idents2.rs @@ -1,4 +1,4 @@ fn main() { concat_idents!(a, b); //~ ERROR `concat_idents` is not stable enough - //~| ERROR cannot find value `ab` in this scope + //~| ERROR cannot find value `ab` } diff --git a/tests/ui/feature-gates/feature-gate-concat_idents2.stderr b/tests/ui/feature-gates/feature-gate-concat_idents2.stderr index 2fe786ff4063d..261b3661ac7a5 100644 --- a/tests/ui/feature-gates/feature-gate-concat_idents2.stderr +++ b/tests/ui/feature-gates/feature-gate-concat_idents2.stderr @@ -8,7 +8,7 @@ LL | concat_idents!(a, b); = help: add `#![feature(concat_idents)]` 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[E0425]: cannot find value `ab` in this scope +error[E0425]: cannot find value `ab` --> $DIR/feature-gate-concat_idents2.rs:2:5 | LL | concat_idents!(a, b); diff --git a/tests/ui/feature-gates/feature-gate-custom_attribute.rs b/tests/ui/feature-gates/feature-gate-custom_attribute.rs index 936cab268d2c9..08acffe414614 100644 --- a/tests/ui/feature-gates/feature-gate-custom_attribute.rs +++ b/tests/ui/feature-gates/feature-gate-custom_attribute.rs @@ -1,18 +1,18 @@ // Check that literals in attributes parse just fine. -#[fake_attr] //~ ERROR cannot find attribute `fake_attr` in this scope -#[fake_attr(100)] //~ ERROR cannot find attribute `fake_attr` in this scope -#[fake_attr(1, 2, 3)] //~ ERROR cannot find attribute `fake_attr` in this scope -#[fake_attr("hello")] //~ ERROR cannot find attribute `fake_attr` in this scope -#[fake_attr(name = "hello")] //~ ERROR cannot find attribute `fake_attr` in this scope +#[fake_attr] //~ ERROR cannot find attribute `fake_attr` +#[fake_attr(100)] //~ ERROR cannot find attribute `fake_attr` +#[fake_attr(1, 2, 3)] //~ ERROR cannot find attribute `fake_attr` +#[fake_attr("hello")] //~ ERROR cannot find attribute `fake_attr` +#[fake_attr(name = "hello")] //~ ERROR cannot find attribute `fake_attr` #[fake_attr(1, "hi", key = 12, true, false)] //~ ERROR cannot find attribute `fake_attr` in th #[fake_attr(key = "hello", val = 10)] //~ ERROR cannot find attribute `fake_attr` in this scop -#[fake_attr(key("hello"), val(10))] //~ ERROR cannot find attribute `fake_attr` in this scope +#[fake_attr(key("hello"), val(10))] //~ ERROR cannot find attribute `fake_attr` #[fake_attr(enabled = true, disabled = false)] //~ ERROR cannot find attribute `fake_attr` in -#[fake_attr(true)] //~ ERROR cannot find attribute `fake_attr` in this scope -#[fake_attr(pi = 3.14159)] //~ ERROR cannot find attribute `fake_attr` in this scope -#[fake_attr(b"hi")] //~ ERROR cannot find attribute `fake_attr` in this scope -#[fake_doc(r"doc")] //~ ERROR cannot find attribute `fake_doc` in this scope +#[fake_attr(true)] //~ ERROR cannot find attribute `fake_attr` +#[fake_attr(pi = 3.14159)] //~ ERROR cannot find attribute `fake_attr` +#[fake_attr(b"hi")] //~ ERROR cannot find attribute `fake_attr` +#[fake_doc(r"doc")] //~ ERROR cannot find attribute `fake_doc` struct Q {} fn main() {} diff --git a/tests/ui/feature-gates/feature-gate-custom_attribute2.rs b/tests/ui/feature-gates/feature-gate-custom_attribute2.rs index 724e53debeb01..3b1dcdd697da9 100644 --- a/tests/ui/feature-gates/feature-gate-custom_attribute2.rs +++ b/tests/ui/feature-gates/feature-gate-custom_attribute2.rs @@ -2,54 +2,54 @@ // lists are included when we are checking for unstable attributes. struct StLt<#[lt_struct] 'a>(&'a u32); -//~^ ERROR cannot find attribute `lt_struct` in this scope +//~^ ERROR cannot find attribute `lt_struct` struct StTy<#[ty_struct] I>(I); -//~^ ERROR cannot find attribute `ty_struct` in this scope +//~^ ERROR cannot find attribute `ty_struct` enum EnLt<#[lt_enum] 'b> { A(&'b u32), B } -//~^ ERROR cannot find attribute `lt_enum` in this scope +//~^ ERROR cannot find attribute `lt_enum` enum EnTy<#[ty_enum] J> { A(J), B } -//~^ ERROR cannot find attribute `ty_enum` in this scope +//~^ ERROR cannot find attribute `ty_enum` trait TrLt<#[lt_trait] 'c> { fn foo(&self, _: &'c [u32]) -> &'c u32; } -//~^ ERROR cannot find attribute `lt_trait` in this scope +//~^ ERROR cannot find attribute `lt_trait` trait TrTy<#[ty_trait] K> { fn foo(&self, _: K); } -//~^ ERROR cannot find attribute `ty_trait` in this scope +//~^ ERROR cannot find attribute `ty_trait` type TyLt<#[lt_type] 'd> = &'d u32; -//~^ ERROR cannot find attribute `lt_type` in this scope +//~^ ERROR cannot find attribute `lt_type` type TyTy<#[ty_type] L> = (L, ); -//~^ ERROR cannot find attribute `ty_type` in this scope +//~^ ERROR cannot find attribute `ty_type` impl<#[lt_inherent] 'e> StLt<'e> { } -//~^ ERROR cannot find attribute `lt_inherent` in this scope +//~^ ERROR cannot find attribute `lt_inherent` impl<#[ty_inherent] M> StTy { } -//~^ ERROR cannot find attribute `ty_inherent` in this scope +//~^ ERROR cannot find attribute `ty_inherent` impl<#[lt_impl_for] 'f> TrLt<'f> for StLt<'f> { - //~^ ERROR cannot find attribute `lt_impl_for` in this scope + //~^ ERROR cannot find attribute `lt_impl_for` fn foo(&self, _: &'f [u32]) -> &'f u32 { loop { } } } impl<#[ty_impl_for] N> TrTy for StTy { - //~^ ERROR cannot find attribute `ty_impl_for` in this scope + //~^ ERROR cannot find attribute `ty_impl_for` fn foo(&self, _: N) { } } fn f_lt<#[lt_fn] 'g>(_: &'g [u32]) -> &'g u32 { loop { } } -//~^ ERROR cannot find attribute `lt_fn` in this scope +//~^ ERROR cannot find attribute `lt_fn` fn f_ty<#[ty_fn] O>(_: O) { } -//~^ ERROR cannot find attribute `ty_fn` in this scope +//~^ ERROR cannot find attribute `ty_fn` impl StTy { fn m_lt<#[lt_meth] 'h>(_: &'h [u32]) -> &'h u32 { loop { } } - //~^ ERROR cannot find attribute `lt_meth` in this scope + //~^ ERROR cannot find attribute `lt_meth` fn m_ty<#[ty_meth] P>(_: P) { } - //~^ ERROR cannot find attribute `ty_meth` in this scope + //~^ ERROR cannot find attribute `ty_meth` } fn hof_lt(_: Q) where Q: for <#[lt_hof] 'i> Fn(&'i [u32]) -> &'i u32 - //~^ ERROR cannot find attribute `lt_hof` in this scope + //~^ ERROR cannot find attribute `lt_hof` { } diff --git a/tests/ui/feature-gates/feature-gate-gen_blocks.none.stderr b/tests/ui/feature-gates/feature-gate-gen_blocks.none.stderr index b4b37f0e63847..bc4c6f5e1235e 100644 --- a/tests/ui/feature-gates/feature-gate-gen_blocks.none.stderr +++ b/tests/ui/feature-gates/feature-gate-gen_blocks.none.stderr @@ -10,7 +10,7 @@ error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found LL | async gen {}; | ^^^ expected one of 8 possible tokens -error[E0422]: cannot find struct, variant or union type `gen` in this scope +error[E0422]: cannot find struct, variant or union type `gen` --> $DIR/feature-gate-gen_blocks.rs:5:5 | LL | gen {}; diff --git a/tests/ui/feature-gates/feature-gate-rustc-attrs.rs b/tests/ui/feature-gates/feature-gate-rustc-attrs.rs index c985298a30aed..a1d2b00831f41 100644 --- a/tests/ui/feature-gates/feature-gate-rustc-attrs.rs +++ b/tests/ui/feature-gates/feature-gate-rustc-attrs.rs @@ -19,5 +19,5 @@ fn g() {} //~^ ERROR the `#[rustc_dummy]` attribute is just used for rustc unit tests #[rustc_unknown] //~^ ERROR attributes starting with `rustc` are reserved for use by the `rustc` compiler -//~| ERROR cannot find attribute `rustc_unknown` in this scope +//~| ERROR cannot find attribute `rustc_unknown` fn main() {} diff --git a/tests/ui/feature-gates/issue-43106-gating-of-derive-2.rs b/tests/ui/feature-gates/issue-43106-gating-of-derive-2.rs index 3276309f745c2..0d9a6ea876d84 100644 --- a/tests/ui/feature-gates/issue-43106-gating-of-derive-2.rs +++ b/tests/ui/feature-gates/issue-43106-gating-of-derive-2.rs @@ -2,18 +2,18 @@ mod derive { #[derive(x3300)] - //~^ ERROR cannot find derive macro `x3300` in this scope - //~| ERROR cannot find derive macro `x3300` in this scope + //~^ ERROR cannot find derive macro `x3300` + //~| ERROR cannot find derive macro `x3300` union U { f: i32 } #[derive(x3300)] - //~^ ERROR cannot find derive macro `x3300` in this scope - //~| ERROR cannot find derive macro `x3300` in this scope + //~^ ERROR cannot find derive macro `x3300` + //~| ERROR cannot find derive macro `x3300` enum E { } #[derive(x3300)] - //~^ ERROR cannot find derive macro `x3300` in this scope - //~| ERROR cannot find derive macro `x3300` in this scope + //~^ ERROR cannot find derive macro `x3300` + //~| ERROR cannot find derive macro `x3300` struct S; } diff --git a/tests/ui/fmt/format-args-capture-issue-102057.rs b/tests/ui/fmt/format-args-capture-issue-102057.rs index b8089d49bcb3b..6e51afc643043 100644 --- a/tests/ui/fmt/format-args-capture-issue-102057.rs +++ b/tests/ui/fmt/format-args-capture-issue-102057.rs @@ -1,19 +1,19 @@ fn main() { format!("\x7Ba}"); - //~^ ERROR cannot find value `a` in this scope + //~^ ERROR cannot find value `a` format!("\x7Ba\x7D"); - //~^ ERROR cannot find value `a` in this scope + //~^ ERROR cannot find value `a` let a = 0; format!("\x7Ba} {b}"); - //~^ ERROR cannot find value `b` in this scope + //~^ ERROR cannot find value `b` format!("\x7Ba\x7D {b}"); - //~^ ERROR cannot find value `b` in this scope + //~^ ERROR cannot find value `b` format!("\x7Ba} \x7Bb}"); - //~^ ERROR cannot find value `b` in this scope + //~^ ERROR cannot find value `b` format!("\x7Ba\x7D \x7Bb}"); - //~^ ERROR cannot find value `b` in this scope + //~^ ERROR cannot find value `b` format!("\x7Ba\x7D \x7Bb\x7D"); - //~^ ERROR cannot find value `b` in this scope + //~^ ERROR cannot find value `b` } diff --git a/tests/ui/fmt/format-args-capture-issue-102057.stderr b/tests/ui/fmt/format-args-capture-issue-102057.stderr index f2d625e7f8dc8..339c66c4990c5 100644 --- a/tests/ui/fmt/format-args-capture-issue-102057.stderr +++ b/tests/ui/fmt/format-args-capture-issue-102057.stderr @@ -1,40 +1,40 @@ -error[E0425]: cannot find value `a` in this scope +error[E0425]: cannot find value `a` --> $DIR/format-args-capture-issue-102057.rs:2:18 | LL | format!("\x7Ba}"); | ^ not found in this scope -error[E0425]: cannot find value `a` in this scope +error[E0425]: cannot find value `a` --> $DIR/format-args-capture-issue-102057.rs:4:18 | LL | format!("\x7Ba\x7D"); | ^ not found in this scope -error[E0425]: cannot find value `b` in this scope +error[E0425]: cannot find value `b` --> $DIR/format-args-capture-issue-102057.rs:9:22 | LL | format!("\x7Ba} {b}"); | ^ help: a local variable with a similar name exists: `a` -error[E0425]: cannot find value `b` in this scope +error[E0425]: cannot find value `b` --> $DIR/format-args-capture-issue-102057.rs:11:25 | LL | format!("\x7Ba\x7D {b}"); | ^ help: a local variable with a similar name exists: `a` -error[E0425]: cannot find value `b` in this scope +error[E0425]: cannot find value `b` --> $DIR/format-args-capture-issue-102057.rs:13:25 | LL | format!("\x7Ba} \x7Bb}"); | ^ help: a local variable with a similar name exists: `a` -error[E0425]: cannot find value `b` in this scope +error[E0425]: cannot find value `b` --> $DIR/format-args-capture-issue-102057.rs:15:28 | LL | format!("\x7Ba\x7D \x7Bb}"); | ^ help: a local variable with a similar name exists: `a` -error[E0425]: cannot find value `b` in this scope +error[E0425]: cannot find value `b` --> $DIR/format-args-capture-issue-102057.rs:17:28 | LL | format!("\x7Ba\x7D \x7Bb\x7D"); diff --git a/tests/ui/fmt/format-args-capture-issue-94010.rs b/tests/ui/fmt/format-args-capture-issue-94010.rs index bd03e9c93ae2a..2e925df188ebb 100644 --- a/tests/ui/fmt/format-args-capture-issue-94010.rs +++ b/tests/ui/fmt/format-args-capture-issue-94010.rs @@ -1,7 +1,7 @@ fn main() { const FOO: i32 = 123; println!("{foo:X}"); - //~^ ERROR: cannot find value `foo` in this scope + //~^ ERROR: cannot find value `foo` println!("{:.foo$}", 0); - //~^ ERROR: cannot find value `foo` in this scope + //~^ ERROR: cannot find value `foo` } diff --git a/tests/ui/fmt/format-args-capture-issue-94010.stderr b/tests/ui/fmt/format-args-capture-issue-94010.stderr index ed90dc855360a..852957edd57b2 100644 --- a/tests/ui/fmt/format-args-capture-issue-94010.stderr +++ b/tests/ui/fmt/format-args-capture-issue-94010.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `foo` in this scope +error[E0425]: cannot find value `foo` --> $DIR/format-args-capture-issue-94010.rs:3:16 | LL | const FOO: i32 = 123; @@ -6,7 +6,7 @@ LL | const FOO: i32 = 123; LL | println!("{foo:X}"); | ^^^ help: a constant with a similar name exists (notice the capitalization): `FOO` -error[E0425]: cannot find value `foo` in this scope +error[E0425]: cannot find value `foo` --> $DIR/format-args-capture-issue-94010.rs:5:18 | LL | const FOO: i32 = 123; diff --git a/tests/ui/fmt/format-args-capture-missing-variables.rs b/tests/ui/fmt/format-args-capture-missing-variables.rs index 46fc083cb7301..d1222c1d33447 100644 --- a/tests/ui/fmt/format-args-capture-missing-variables.rs +++ b/tests/ui/fmt/format-args-capture-missing-variables.rs @@ -1,12 +1,12 @@ fn main() { format!("{} {foo} {} {bar} {}", 1, 2, 3); - //~^ ERROR: cannot find value `foo` in this scope - //~^^ ERROR: cannot find value `bar` in this scope + //~^ ERROR: cannot find value `foo` + //~^^ ERROR: cannot find value `bar` - format!("{foo}"); //~ ERROR: cannot find value `foo` in this scope + format!("{foo}"); //~ ERROR: cannot find value `foo` format!("{valuea} {valueb}", valuea=5, valuec=7); - //~^ ERROR cannot find value `valueb` in this scope + //~^ ERROR cannot find value `valueb` //~^^ ERROR named argument never used format!(r##" @@ -14,7 +14,7 @@ fn main() { {foo} "##); - //~^^^ ERROR: cannot find value `foo` in this scope + //~^^^ ERROR: cannot find value `foo` - panic!("{foo} {bar}", bar=1); //~ ERROR: cannot find value `foo` in this scope + panic!("{foo} {bar}", bar=1); //~ ERROR: cannot find value `foo` } diff --git a/tests/ui/fmt/format-args-capture-missing-variables.stderr b/tests/ui/fmt/format-args-capture-missing-variables.stderr index d980e7be273e8..ed75fd54f20e7 100644 --- a/tests/ui/fmt/format-args-capture-missing-variables.stderr +++ b/tests/ui/fmt/format-args-capture-missing-variables.stderr @@ -6,37 +6,37 @@ LL | format!("{valuea} {valueb}", valuea=5, valuec=7); | | | formatting specifier missing -error[E0425]: cannot find value `foo` in this scope +error[E0425]: cannot find value `foo` --> $DIR/format-args-capture-missing-variables.rs:2:18 | LL | format!("{} {foo} {} {bar} {}", 1, 2, 3); | ^^^ not found in this scope -error[E0425]: cannot find value `bar` in this scope +error[E0425]: cannot find value `bar` --> $DIR/format-args-capture-missing-variables.rs:2:27 | LL | format!("{} {foo} {} {bar} {}", 1, 2, 3); | ^^^ not found in this scope -error[E0425]: cannot find value `foo` in this scope +error[E0425]: cannot find value `foo` --> $DIR/format-args-capture-missing-variables.rs:6:15 | LL | format!("{foo}"); | ^^^ not found in this scope -error[E0425]: cannot find value `valueb` in this scope +error[E0425]: cannot find value `valueb` --> $DIR/format-args-capture-missing-variables.rs:8:24 | LL | format!("{valuea} {valueb}", valuea=5, valuec=7); | ^^^^^^ not found in this scope -error[E0425]: cannot find value `foo` in this scope +error[E0425]: cannot find value `foo` --> $DIR/format-args-capture-missing-variables.rs:14:10 | LL | {foo} | ^^^ not found in this scope -error[E0425]: cannot find value `foo` in this scope +error[E0425]: cannot find value `foo` --> $DIR/format-args-capture-missing-variables.rs:19:14 | LL | panic!("{foo} {bar}", bar=1); diff --git a/tests/ui/fmt/ifmt-bad-arg.rs b/tests/ui/fmt/ifmt-bad-arg.rs index 68861d7bf3faf..7ca30cab494af 100644 --- a/tests/ui/fmt/ifmt-bad-arg.rs +++ b/tests/ui/fmt/ifmt-bad-arg.rs @@ -25,10 +25,10 @@ fn main() { //~^ ERROR: 6 positional arguments in format string, but there are 3 arguments format!("{} {foo} {} {bar} {}", 1, 2, 3); - //~^ ERROR: cannot find value `foo` in this scope - //~^^ ERROR: cannot find value `bar` in this scope + //~^ ERROR: cannot find value `foo` + //~^^ ERROR: cannot find value `bar` - format!("{foo}"); //~ ERROR: cannot find value `foo` in this scope + format!("{foo}"); //~ ERROR: cannot find value `foo` format!("", 1, 2); //~ ERROR: multiple unused formatting arguments format!("{}", 1, 2); //~ ERROR: argument never used format!("{1}", 1, 2); //~ ERROR: argument never used @@ -43,7 +43,7 @@ fn main() { // bad named arguments, #35082 format!("{valuea} {valueb}", valuea=5, valuec=7); - //~^ ERROR cannot find value `valueb` in this scope + //~^ ERROR cannot find value `valueb` //~^^ ERROR named argument never used // bad syntax of the format string @@ -60,7 +60,7 @@ fn main() { {foo} "##); - //~^^^ ERROR: cannot find value `foo` in this scope + //~^^^ ERROR: cannot find value `foo` // bad syntax in format string with multiple newlines, #53836 format!("first number: {} diff --git a/tests/ui/fmt/ifmt-bad-arg.stderr b/tests/ui/fmt/ifmt-bad-arg.stderr index 09ce3dca4117e..c51b7efc89337 100644 --- a/tests/ui/fmt/ifmt-bad-arg.stderr +++ b/tests/ui/fmt/ifmt-bad-arg.stderr @@ -266,31 +266,31 @@ LL | println!("{:.0$}"); = note: positional arguments are zero-based = note: for information about formatting flags, visit https://doc.rust-lang.org/std/fmt/index.html -error[E0425]: cannot find value `foo` in this scope +error[E0425]: cannot find value `foo` --> $DIR/ifmt-bad-arg.rs:27:18 | LL | format!("{} {foo} {} {bar} {}", 1, 2, 3); | ^^^ not found in this scope -error[E0425]: cannot find value `bar` in this scope +error[E0425]: cannot find value `bar` --> $DIR/ifmt-bad-arg.rs:27:27 | LL | format!("{} {foo} {} {bar} {}", 1, 2, 3); | ^^^ not found in this scope -error[E0425]: cannot find value `foo` in this scope +error[E0425]: cannot find value `foo` --> $DIR/ifmt-bad-arg.rs:31:15 | LL | format!("{foo}"); | ^^^ not found in this scope -error[E0425]: cannot find value `valueb` in this scope +error[E0425]: cannot find value `valueb` --> $DIR/ifmt-bad-arg.rs:45:24 | LL | format!("{valuea} {valueb}", valuea=5, valuec=7); | ^^^^^^ not found in this scope -error[E0425]: cannot find value `foo` in this scope +error[E0425]: cannot find value `foo` --> $DIR/ifmt-bad-arg.rs:60:10 | LL | {foo} diff --git a/tests/ui/fmt/unicode-escape-spans.stderr b/tests/ui/fmt/unicode-escape-spans.stderr index 1d8473f01b822..11e4979a49825 100644 --- a/tests/ui/fmt/unicode-escape-spans.stderr +++ b/tests/ui/fmt/unicode-escape-spans.stderr @@ -1,58 +1,58 @@ -error[E0425]: cannot find value `a` in this scope +error[E0425]: cannot find value `a` --> $DIR/unicode-escape-spans.rs:3:25 | LL | format!("\u{000041}{a}"); | ^ not found in this scope -error[E0425]: cannot find value `a` in this scope +error[E0425]: cannot find value `a` --> $DIR/unicode-escape-spans.rs:4:23 | LL | format!("\u{0041}{a}"); | ^ not found in this scope -error[E0425]: cannot find value `a` in this scope +error[E0425]: cannot find value `a` --> $DIR/unicode-escape-spans.rs:5:21 | LL | format!("\u{41}{a}"); | ^ not found in this scope -error[E0425]: cannot find value `a` in this scope +error[E0425]: cannot find value `a` --> $DIR/unicode-escape-spans.rs:6:20 | LL | format!("\u{0}{a}"); | ^ not found in this scope -error[E0425]: cannot find value `a` in this scope +error[E0425]: cannot find value `a` --> $DIR/unicode-escape-spans.rs:9:22 | LL | format!("\u{0df}{a}"); | ^ not found in this scope -error[E0425]: cannot find value `a` in this scope +error[E0425]: cannot find value `a` --> $DIR/unicode-escape-spans.rs:10:21 | LL | format!("\u{df}{a}"); | ^ not found in this scope -error[E0425]: cannot find value `a` in this scope +error[E0425]: cannot find value `a` --> $DIR/unicode-escape-spans.rs:13:25 | LL | format!("\u{00211d}{a}"); | ^ not found in this scope -error[E0425]: cannot find value `a` in this scope +error[E0425]: cannot find value `a` --> $DIR/unicode-escape-spans.rs:14:23 | LL | format!("\u{211d}{a}"); | ^ not found in this scope -error[E0425]: cannot find value `a` in this scope +error[E0425]: cannot find value `a` --> $DIR/unicode-escape-spans.rs:17:24 | LL | format!("\u{1f4a3}{a}"); | ^ not found in this scope -error[E0425]: cannot find value `a` in this scope +error[E0425]: cannot find value `a` --> $DIR/unicode-escape-spans.rs:18:25 | LL | format!("\u{10ffff}{a}"); diff --git a/tests/ui/for/for-expn.rs b/tests/ui/for/for-expn.rs index b9c4bbedac9f7..d5cf2aa33994d 100644 --- a/tests/ui/for/for-expn.rs +++ b/tests/ui/for/for-expn.rs @@ -3,7 +3,7 @@ fn main() { // Odd formatting to make sure we get the right span. for t in & - foo //~ ERROR cannot find value `foo` in this scope + foo //~ ERROR cannot find value `foo` { } } diff --git a/tests/ui/for/for-expn.stderr b/tests/ui/for/for-expn.stderr index 00822324039f0..f4d5e7e3eb7ea 100644 --- a/tests/ui/for/for-expn.stderr +++ b/tests/ui/for/for-expn.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `foo` in this scope +error[E0425]: cannot find value `foo` --> $DIR/for-expn.rs:6:7 | LL | foo diff --git a/tests/ui/functions-closures/fn-help-with-err-generic-is-not-function.rs b/tests/ui/functions-closures/fn-help-with-err-generic-is-not-function.rs index e48ab4aa96fb9..b9bb7f53b51ac 100644 --- a/tests/ui/functions-closures/fn-help-with-err-generic-is-not-function.rs +++ b/tests/ui/functions-closures/fn-help-with-err-generic-is-not-function.rs @@ -1,12 +1,12 @@ struct Struct(T); impl Struct -//~^ ERROR cannot find type `T` in this scope -//~| NOTE not found in this scope +//~^ ERROR cannot find type `T` +//~| NOTE not found //~| HELP you might be missing a type parameter where T: Copy, - //~^ ERROR cannot find type `T` in this scope - //~| NOTE not found in this scope + //~^ ERROR cannot find type `T` + //~| NOTE not found { fn method(v: Vec) { v.len(); } } diff --git a/tests/ui/functions-closures/fn-help-with-err-generic-is-not-function.stderr b/tests/ui/functions-closures/fn-help-with-err-generic-is-not-function.stderr index 9d4ea01152cc9..eef18f68084ed 100644 --- a/tests/ui/functions-closures/fn-help-with-err-generic-is-not-function.stderr +++ b/tests/ui/functions-closures/fn-help-with-err-generic-is-not-function.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `T` in this scope +error[E0412]: cannot find type `T` --> $DIR/fn-help-with-err-generic-is-not-function.rs:2:13 | LL | impl Struct @@ -9,7 +9,7 @@ help: you might be missing a type parameter LL | impl Struct | +++ -error[E0412]: cannot find type `T` in this scope +error[E0412]: cannot find type `T` --> $DIR/fn-help-with-err-generic-is-not-function.rs:7:5 | LL | T: Copy, diff --git a/tests/ui/functions-closures/fn-help-with-err.rs b/tests/ui/functions-closures/fn-help-with-err.rs index 612fe1b841918..01232d044339d 100644 --- a/tests/ui/functions-closures/fn-help-with-err.rs +++ b/tests/ui/functions-closures/fn-help-with-err.rs @@ -11,7 +11,7 @@ impl Bar for Foo {} fn main() { let arc = std::sync::Arc::new(oops); - //~^ ERROR cannot find value `oops` in this scope + //~^ ERROR cannot find value `oops` //~| NOTE not found arc.bar(); diff --git a/tests/ui/functions-closures/fn-help-with-err.stderr b/tests/ui/functions-closures/fn-help-with-err.stderr index e5fe4611434ea..91de164b013dd 100644 --- a/tests/ui/functions-closures/fn-help-with-err.stderr +++ b/tests/ui/functions-closures/fn-help-with-err.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `oops` in this scope +error[E0425]: cannot find value `oops` --> $DIR/fn-help-with-err.rs:13:35 | LL | let arc = std::sync::Arc::new(oops); diff --git a/tests/ui/generic-associated-types/equality-bound.rs b/tests/ui/generic-associated-types/equality-bound.rs index be05181f5d09e..facf838b99b3a 100644 --- a/tests/ui/generic-associated-types/equality-bound.rs +++ b/tests/ui/generic-associated-types/equality-bound.rs @@ -19,7 +19,7 @@ struct X {} impl FromIterator for X { fn from_iter(_: T) -> Self where T: IntoIterator, IntoIterator::Item = A, //~^ ERROR equality constraints are not yet supported in `where` clauses - //~| ERROR cannot find type `A` in this scope + //~| ERROR cannot find type `A` { todo!() } @@ -30,7 +30,7 @@ struct Y {} impl FromIterator for Y { fn from_iter(_: T) -> Self where T: IntoIterator, T::Item = A, //~^ ERROR equality constraints are not yet supported in `where` clauses - //~| ERROR cannot find type `A` in this scope + //~| ERROR cannot find type `A` { todo!() } @@ -41,7 +41,7 @@ struct Z {} impl FromIterator for Z { fn from_iter(_: T) -> Self where IntoIterator::Item = A, //~^ ERROR equality constraints are not yet supported in `where` clauses - //~| ERROR cannot find type `A` in this scope + //~| ERROR cannot find type `A` { todo!() } @@ -52,7 +52,7 @@ struct K {} impl FromIterator for K { fn from_iter(_: T) -> Self where T::Item = A, //~^ ERROR equality constraints are not yet supported in `where` clauses - //~| ERROR cannot find type `A` in this scope + //~| ERROR cannot find type `A` { todo!() } @@ -63,7 +63,7 @@ struct L {} impl FromIterator for L { fn from_iter(_: T) -> Self where IntoIterator::Item = A, T: IntoIterator, //~^ ERROR equality constraints are not yet supported in `where` clauses - //~| ERROR cannot find type `A` in this scope + //~| ERROR cannot find type `A` { todo!() } @@ -74,7 +74,7 @@ struct M {} impl FromIterator for M { fn from_iter(_: T) -> Self where T::Item = A, T: IntoIterator, //~^ ERROR equality constraints are not yet supported in `where` clauses - //~| ERROR cannot find type `A` in this scope + //~| ERROR cannot find type `A` { todo!() } diff --git a/tests/ui/generic-associated-types/equality-bound.stderr b/tests/ui/generic-associated-types/equality-bound.stderr index a054c06caebde..72200c462ac8f 100644 --- a/tests/ui/generic-associated-types/equality-bound.stderr +++ b/tests/ui/generic-associated-types/equality-bound.stderr @@ -110,7 +110,7 @@ LL - fn from_iter(_: T) -> Self where T::Item = A, T: IntoIterator, LL + fn from_iter(_: T) -> Self where T: IntoIterator, | -error[E0412]: cannot find type `A` in this scope +error[E0412]: cannot find type `A` --> $DIR/equality-bound.rs:20:79 | LL | fn from_iter(_: T) -> Self where T: IntoIterator, IntoIterator::Item = A, @@ -119,7 +119,7 @@ LL | fn from_iter(_: T) -> Self where T: IntoIterator, IntoIterator::Item LL | struct K {} | -------- similarly named struct `K` defined here -error[E0412]: cannot find type `A` in this scope +error[E0412]: cannot find type `A` --> $DIR/equality-bound.rs:31:68 | LL | fn from_iter(_: T) -> Self where T: IntoIterator, T::Item = A, @@ -128,7 +128,7 @@ LL | fn from_iter(_: T) -> Self where T: IntoIterator, T::Item = A, LL | struct K {} | -------- similarly named struct `K` defined here -error[E0412]: cannot find type `A` in this scope +error[E0412]: cannot find type `A` --> $DIR/equality-bound.rs:42:76 | LL | fn from_iter(_: T) -> Self where IntoIterator::Item = A, @@ -137,7 +137,7 @@ LL | fn from_iter(_: T) -> Self where IntoIterator::Item = LL | struct K {} | -------- similarly named struct `K` defined here -error[E0412]: cannot find type `A` in this scope +error[E0412]: cannot find type `A` --> $DIR/equality-bound.rs:53:65 | LL | struct K {} @@ -146,7 +146,7 @@ LL | struct K {} LL | fn from_iter(_: T) -> Self where T::Item = A, | ^ help: a struct with a similar name exists: `K` -error[E0412]: cannot find type `A` in this scope +error[E0412]: cannot find type `A` --> $DIR/equality-bound.rs:64:62 | LL | struct K {} @@ -155,7 +155,7 @@ LL | struct K {} LL | fn from_iter(_: T) -> Self where IntoIterator::Item = A, T: IntoIterator, | ^ help: a struct with a similar name exists: `K` -error[E0412]: cannot find type `A` in this scope +error[E0412]: cannot find type `A` --> $DIR/equality-bound.rs:75:51 | LL | struct K {} diff --git a/tests/ui/generics/issue-106694.rs b/tests/ui/generics/issue-106694.rs index c4b02ee81ec8f..5daa947bd466e 100644 --- a/tests/ui/generics/issue-106694.rs +++ b/tests/ui/generics/issue-106694.rs @@ -11,14 +11,14 @@ fn partially_correct_impl(_: impl &*const &Trait + Copy) {} fn foo_bad(_: impl &BadTrait) {} //~^ ERROR expected a trait, found type -//~^^ ERROR cannot find trait `BadTrait` in this scope +//~^^ ERROR cannot find trait `BadTrait` fn bar_bad(_: T) {} //~^ ERROR expected a trait, found type -//~^^ ERROR cannot find trait `BadTrait` in this scope +//~^^ ERROR cannot find trait `BadTrait` fn partially_correct_impl_bad(_: impl &*const &BadTrait + Copy) {} //~^ ERROR expected a trait, found type -//~^^ ERROR cannot find trait `BadTrait` in this scope +//~^^ ERROR cannot find trait `BadTrait` fn main() {} diff --git a/tests/ui/generics/issue-106694.stderr b/tests/ui/generics/issue-106694.stderr index 235b8982a99c6..435b05938c822 100644 --- a/tests/ui/generics/issue-106694.stderr +++ b/tests/ui/generics/issue-106694.stderr @@ -70,19 +70,19 @@ LL - fn partially_correct_impl_bad(_: impl &*const &BadTrait + Copy) {} LL + fn partially_correct_impl_bad(_: impl BadTrait + Copy) {} | -error[E0405]: cannot find trait `BadTrait` in this scope +error[E0405]: cannot find trait `BadTrait` --> $DIR/issue-106694.rs:12:21 | LL | fn foo_bad(_: impl &BadTrait) {} | ^^^^^^^^ not found in this scope -error[E0405]: cannot find trait `BadTrait` in this scope +error[E0405]: cannot find trait `BadTrait` --> $DIR/issue-106694.rs:16:16 | LL | fn bar_bad(_: T) {} | ^^^^^^^^ not found in this scope -error[E0405]: cannot find trait `BadTrait` in this scope +error[E0405]: cannot find trait `BadTrait` --> $DIR/issue-106694.rs:20:48 | LL | fn partially_correct_impl_bad(_: impl &*const &BadTrait + Copy) {} diff --git a/tests/ui/hygiene/arguments.rs b/tests/ui/hygiene/arguments.rs index ab58301d468b0..7490bda535157 100644 --- a/tests/ui/hygiene/arguments.rs +++ b/tests/ui/hygiene/arguments.rs @@ -11,5 +11,5 @@ macro m($t:ty, $e:expr) { fn main() { struct S; - m!(S, S); //~ ERROR cannot find type `S` in this scope + m!(S, S); //~ ERROR cannot find type `S` } diff --git a/tests/ui/hygiene/arguments.stderr b/tests/ui/hygiene/arguments.stderr index 0d8d652b6f33d..e13adaabfe809 100644 --- a/tests/ui/hygiene/arguments.stderr +++ b/tests/ui/hygiene/arguments.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `S` in this scope +error[E0412]: cannot find type `S` --> $DIR/arguments.rs:14:8 | LL | m!(S, S); diff --git a/tests/ui/hygiene/cross-crate-glob-hygiene.rs b/tests/ui/hygiene/cross-crate-glob-hygiene.rs index 81cc6927c1d28..f97010fbf8caf 100644 --- a/tests/ui/hygiene/cross-crate-glob-hygiene.rs +++ b/tests/ui/hygiene/cross-crate-glob-hygiene.rs @@ -19,5 +19,5 @@ use m::*; fn main() { let x = my_struct!(create); - //~^ ERROR cannot find struct, variant or union type `MyStruct` in this scope + //~^ ERROR cannot find struct, variant or union type `MyStruct` } diff --git a/tests/ui/hygiene/cross-crate-glob-hygiene.stderr b/tests/ui/hygiene/cross-crate-glob-hygiene.stderr index 1abc739fc362d..e0612da5bd710 100644 --- a/tests/ui/hygiene/cross-crate-glob-hygiene.stderr +++ b/tests/ui/hygiene/cross-crate-glob-hygiene.stderr @@ -1,4 +1,4 @@ -error[E0422]: cannot find struct, variant or union type `MyStruct` in this scope +error[E0422]: cannot find struct, variant or union type `MyStruct` --> $DIR/cross-crate-glob-hygiene.rs:21:13 | LL | let x = my_struct!(create); diff --git a/tests/ui/hygiene/cross-crate-name-hiding-2.rs b/tests/ui/hygiene/cross-crate-name-hiding-2.rs index 2eae000b045e2..06019c5dd2bb9 100644 --- a/tests/ui/hygiene/cross-crate-name-hiding-2.rs +++ b/tests/ui/hygiene/cross-crate-name-hiding-2.rs @@ -11,5 +11,5 @@ my_struct!(define); fn main() { let x = MyStruct {}; - //~^ ERROR cannot find struct, variant or union type `MyStruct` in this scope + //~^ ERROR cannot find struct, variant or union type `MyStruct` } diff --git a/tests/ui/hygiene/cross-crate-name-hiding-2.stderr b/tests/ui/hygiene/cross-crate-name-hiding-2.stderr index a5d509fab996f..bede1625a0857 100644 --- a/tests/ui/hygiene/cross-crate-name-hiding-2.stderr +++ b/tests/ui/hygiene/cross-crate-name-hiding-2.stderr @@ -1,4 +1,4 @@ -error[E0422]: cannot find struct, variant or union type `MyStruct` in this scope +error[E0422]: cannot find struct, variant or union type `MyStruct` --> $DIR/cross-crate-name-hiding-2.rs:13:13 | LL | let x = MyStruct {}; diff --git a/tests/ui/hygiene/cross-crate-name-hiding.rs b/tests/ui/hygiene/cross-crate-name-hiding.rs index 586e7647df74c..38cc83805cbd7 100644 --- a/tests/ui/hygiene/cross-crate-name-hiding.rs +++ b/tests/ui/hygiene/cross-crate-name-hiding.rs @@ -9,5 +9,5 @@ use pub_hygiene::*; fn main() { let x = MyStruct {}; - //~^ ERROR cannot find struct, variant or union type `MyStruct` in this scope + //~^ ERROR cannot find struct, variant or union type `MyStruct` } diff --git a/tests/ui/hygiene/cross-crate-name-hiding.stderr b/tests/ui/hygiene/cross-crate-name-hiding.stderr index 4abd14f935581..f1947a2c1803b 100644 --- a/tests/ui/hygiene/cross-crate-name-hiding.stderr +++ b/tests/ui/hygiene/cross-crate-name-hiding.stderr @@ -1,4 +1,4 @@ -error[E0422]: cannot find struct, variant or union type `MyStruct` in this scope +error[E0422]: cannot find struct, variant or union type `MyStruct` --> $DIR/cross-crate-name-hiding.rs:11:13 | LL | let x = MyStruct {}; diff --git a/tests/ui/hygiene/for-loop.rs b/tests/ui/hygiene/for-loop.rs index 2e5ae43a9ce47..40a3d2fb433ca 100644 --- a/tests/ui/hygiene/for-loop.rs +++ b/tests/ui/hygiene/for-loop.rs @@ -3,6 +3,6 @@ fn main() { for _ in 0..10 { - iter.next(); //~ ERROR cannot find value `iter` in this scope + iter.next(); //~ ERROR cannot find value `iter` } } diff --git a/tests/ui/hygiene/for-loop.stderr b/tests/ui/hygiene/for-loop.stderr index 5f334fd89603c..62195b7ce8e1f 100644 --- a/tests/ui/hygiene/for-loop.stderr +++ b/tests/ui/hygiene/for-loop.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `iter` in this scope +error[E0425]: cannot find value `iter` --> $DIR/for-loop.rs:6:9 | LL | iter.next(); diff --git a/tests/ui/hygiene/generate-mod.rs b/tests/ui/hygiene/generate-mod.rs index 8826293542c97..d7c9d41b20c7c 100644 --- a/tests/ui/hygiene/generate-mod.rs +++ b/tests/ui/hygiene/generate-mod.rs @@ -16,8 +16,8 @@ macro genmod_transparent() { type A = FromOutside; struct Outer; mod inner { - type A = FromOutside; //~ ERROR cannot find type `FromOutside` in this scope - type Inner = Outer; //~ ERROR cannot find type `Outer` in this scope + type A = FromOutside; //~ ERROR cannot find type `FromOutside` + type Inner = Outer; //~ ERROR cannot find type `Outer` } } @@ -25,15 +25,15 @@ macro_rules! genmod_legacy { () => { type A = FromOutside; struct Outer; mod inner { - type A = FromOutside; //~ ERROR cannot find type `FromOutside` in this scope - type Inner = Outer; //~ ERROR cannot find type `Outer` in this scope + type A = FromOutside; //~ ERROR cannot find type `FromOutside` + type Inner = Outer; //~ ERROR cannot find type `Outer` } }} fn check() { struct FromOutside; - genmod!(FromOutside, Outer); //~ ERROR cannot find type `FromOutside` in this scope - //~| ERROR cannot find type `Outer` in this scope + genmod!(FromOutside, Outer); //~ ERROR cannot find type `FromOutside` + //~| ERROR cannot find type `Outer` } fn check_transparent() { diff --git a/tests/ui/hygiene/generate-mod.stderr b/tests/ui/hygiene/generate-mod.stderr index 32a2e145ca942..d090cc12dc93f 100644 --- a/tests/ui/hygiene/generate-mod.stderr +++ b/tests/ui/hygiene/generate-mod.stderr @@ -1,16 +1,16 @@ -error[E0412]: cannot find type `FromOutside` in this scope +error[E0412]: cannot find type `FromOutside` --> $DIR/generate-mod.rs:35:13 | LL | genmod!(FromOutside, Outer); | ^^^^^^^^^^^ not found in this scope -error[E0412]: cannot find type `Outer` in this scope +error[E0412]: cannot find type `Outer` --> $DIR/generate-mod.rs:35:26 | LL | genmod!(FromOutside, Outer); | ^^^^^ not found in this scope -error[E0412]: cannot find type `FromOutside` in this scope +error[E0412]: cannot find type `FromOutside` --> $DIR/generate-mod.rs:19:18 | LL | type A = FromOutside; @@ -21,7 +21,7 @@ LL | genmod_transparent!(); | = note: this error originates in the macro `genmod_transparent` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0412]: cannot find type `Outer` in this scope +error[E0412]: cannot find type `Outer` --> $DIR/generate-mod.rs:20:22 | LL | type Inner = Outer; @@ -32,7 +32,7 @@ LL | genmod_transparent!(); | = note: this error originates in the macro `genmod_transparent` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0412]: cannot find type `FromOutside` in this scope +error[E0412]: cannot find type `FromOutside` --> $DIR/generate-mod.rs:28:18 | LL | type A = FromOutside; @@ -43,7 +43,7 @@ LL | genmod_legacy!(); | = note: this error originates in the macro `genmod_legacy` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0412]: cannot find type `Outer` in this scope +error[E0412]: cannot find type `Outer` --> $DIR/generate-mod.rs:29:22 | LL | type Inner = Outer; diff --git a/tests/ui/hygiene/globs.rs b/tests/ui/hygiene/globs.rs index a3f466ef435d3..507ec03ee9e97 100644 --- a/tests/ui/hygiene/globs.rs +++ b/tests/ui/hygiene/globs.rs @@ -12,14 +12,14 @@ macro m($($t:tt)*) { $($t)* use foo::*; f(); - g(); //~ ERROR cannot find function `g` in this scope + g(); //~ ERROR cannot find function `g` } fn main() { m! { use bar::*; g(); - f(); //~ ERROR cannot find function `f` in this scope + f(); //~ ERROR cannot find function `f` } } @@ -58,11 +58,11 @@ macro n($i:ident) { } } - n!(f); //~ ERROR cannot find function `f` in this scope + n!(f); //~ ERROR cannot find function `f` n_with_super!(f); mod test2 { super::n! { - f //~ ERROR cannot find function `f` in this scope + f //~ ERROR cannot find function `f` } super::n_with_super! { f diff --git a/tests/ui/hygiene/globs.stderr b/tests/ui/hygiene/globs.stderr index 180172644402b..3b6e74009e087 100644 --- a/tests/ui/hygiene/globs.stderr +++ b/tests/ui/hygiene/globs.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find function `f` in this scope +error[E0425]: cannot find function `f` --> $DIR/globs.rs:22:9 | LL | pub fn g() {} @@ -16,7 +16,7 @@ help: consider importing this function LL + use foo::f; | -error[E0425]: cannot find function `g` in this scope +error[E0425]: cannot find function `g` --> $DIR/globs.rs:15:5 | LL | pub fn f() {} @@ -42,7 +42,7 @@ help: consider importing this function LL + use bar::g; | -error[E0425]: cannot find function `f` in this scope +error[E0425]: cannot find function `f` --> $DIR/globs.rs:61:12 | LL | n!(f); @@ -55,7 +55,7 @@ LL | n!(f); foo::f = note: this error originates in the macro `n` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0425]: cannot find function `f` in this scope +error[E0425]: cannot find function `f` --> $DIR/globs.rs:65:17 | LL | n!(f); diff --git a/tests/ui/hygiene/no_implicit_prelude-2018.rs b/tests/ui/hygiene/no_implicit_prelude-2018.rs index 015bff870908e..598b3a3dad200 100644 --- a/tests/ui/hygiene/no_implicit_prelude-2018.rs +++ b/tests/ui/hygiene/no_implicit_prelude-2018.rs @@ -4,7 +4,7 @@ mod bar { fn f() { ::std::print!(""); // OK - print!(); //~ ERROR cannot find macro `print` in this scope + print!(); //~ ERROR cannot find macro `print` } } diff --git a/tests/ui/hygiene/pattern-macro.rs b/tests/ui/hygiene/pattern-macro.rs index e5d6a3aa1a0e6..e83287ec89d8c 100644 --- a/tests/ui/hygiene/pattern-macro.rs +++ b/tests/ui/hygiene/pattern-macro.rs @@ -2,5 +2,5 @@ macro_rules! foo { () => ( x ) } fn main() { let foo!() = 2; - x + 1; //~ ERROR cannot find value `x` in this scope + x + 1; //~ ERROR cannot find value `x` } diff --git a/tests/ui/hygiene/pattern-macro.stderr b/tests/ui/hygiene/pattern-macro.stderr index a9764cea49e59..cb9b743432b5c 100644 --- a/tests/ui/hygiene/pattern-macro.stderr +++ b/tests/ui/hygiene/pattern-macro.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `x` in this scope +error[E0425]: cannot find value `x` --> $DIR/pattern-macro.rs:5:5 | LL | x + 1; diff --git a/tests/ui/hygiene/rustc-macro-transparency.rs b/tests/ui/hygiene/rustc-macro-transparency.rs index 5f36993af2f30..59c2faec40590 100644 --- a/tests/ui/hygiene/rustc-macro-transparency.rs +++ b/tests/ui/hygiene/rustc-macro-transparency.rs @@ -23,7 +23,7 @@ fn main() { Transparent; // OK SemiTransparent; // OK - Opaque; //~ ERROR cannot find value `Opaque` in this scope + Opaque; //~ ERROR cannot find value `Opaque` transparent; // OK semitransparent; //~ ERROR expected value, found macro `semitransparent` diff --git a/tests/ui/hygiene/rustc-macro-transparency.stderr b/tests/ui/hygiene/rustc-macro-transparency.stderr index 1d2a1e1249864..9b23bbb360a0d 100644 --- a/tests/ui/hygiene/rustc-macro-transparency.stderr +++ b/tests/ui/hygiene/rustc-macro-transparency.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `Opaque` in this scope +error[E0425]: cannot find value `Opaque` --> $DIR/rustc-macro-transparency.rs:26:5 | LL | Opaque; diff --git a/tests/ui/impl-trait/in-trait/ensure-rpitits-are-created-before-freezing.rs b/tests/ui/impl-trait/in-trait/ensure-rpitits-are-created-before-freezing.rs index 35a6acca52c7d..279b7f7a8b3d1 100644 --- a/tests/ui/impl-trait/in-trait/ensure-rpitits-are-created-before-freezing.rs +++ b/tests/ui/impl-trait/in-trait/ensure-rpitits-are-created-before-freezing.rs @@ -6,7 +6,7 @@ trait Iterable { // `ty::Error` in a trait ref will silence any missing item errors, but will also // prevent the `associated_items` query from being called before def ids are frozen. impl Iterable for Missing { -//~^ ERROR cannot find type `Missing` in this scope +//~^ ERROR cannot find type `Missing` fn iter(&self) -> Self::Item {} } diff --git a/tests/ui/impl-trait/in-trait/ensure-rpitits-are-created-before-freezing.stderr b/tests/ui/impl-trait/in-trait/ensure-rpitits-are-created-before-freezing.stderr index c172787e6ef21..86ec30da61830 100644 --- a/tests/ui/impl-trait/in-trait/ensure-rpitits-are-created-before-freezing.stderr +++ b/tests/ui/impl-trait/in-trait/ensure-rpitits-are-created-before-freezing.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `Missing` in this scope +error[E0412]: cannot find type `Missing` --> $DIR/ensure-rpitits-are-created-before-freezing.rs:8:19 | LL | impl Iterable for Missing { diff --git a/tests/ui/impl-trait/in-trait/rpitit-shadowed-by-missing-adt.rs b/tests/ui/impl-trait/in-trait/rpitit-shadowed-by-missing-adt.rs index 4e46b7114c1a2..19225d527ffde 100644 --- a/tests/ui/impl-trait/in-trait/rpitit-shadowed-by-missing-adt.rs +++ b/tests/ui/impl-trait/in-trait/rpitit-shadowed-by-missing-adt.rs @@ -4,7 +4,7 @@ use std::ops::Deref; pub trait Tr { fn w() -> impl Deref>; - //~^ ERROR cannot find type `Missing` in this scope + //~^ ERROR cannot find type `Missing` } impl Tr for () { diff --git a/tests/ui/impl-trait/in-trait/rpitit-shadowed-by-missing-adt.stderr b/tests/ui/impl-trait/in-trait/rpitit-shadowed-by-missing-adt.stderr index e7d38f2240642..66353b8601f6d 100644 --- a/tests/ui/impl-trait/in-trait/rpitit-shadowed-by-missing-adt.stderr +++ b/tests/ui/impl-trait/in-trait/rpitit-shadowed-by-missing-adt.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `Missing` in this scope +error[E0412]: cannot find type `Missing` --> $DIR/rpitit-shadowed-by-missing-adt.rs:6:35 | LL | fn w() -> impl Deref>; diff --git a/tests/ui/impl-trait/issue-103181-2.rs b/tests/ui/impl-trait/issue-103181-2.rs index 72729e851e36b..08a014b788f56 100644 --- a/tests/ui/impl-trait/issue-103181-2.rs +++ b/tests/ui/impl-trait/issue-103181-2.rs @@ -10,7 +10,7 @@ impl SendFuture for Fut { async fn broken_fut() { ident_error; - //~^ ERROR cannot find value `ident_error` in this scope + //~^ ERROR cannot find value `ident_error` } // triggers normalization of `::Output`, diff --git a/tests/ui/impl-trait/issue-103181-2.stderr b/tests/ui/impl-trait/issue-103181-2.stderr index cef4449dbb986..eef4df16b59ef 100644 --- a/tests/ui/impl-trait/issue-103181-2.stderr +++ b/tests/ui/impl-trait/issue-103181-2.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `ident_error` in this scope +error[E0425]: cannot find value `ident_error` --> $DIR/issue-103181-2.rs:12:5 | LL | ident_error; diff --git a/tests/ui/impl-trait/issue-54966.rs b/tests/ui/impl-trait/issue-54966.rs index 0ed3c4b3ca945..f25f929084bb4 100644 --- a/tests/ui/impl-trait/issue-54966.rs +++ b/tests/ui/impl-trait/issue-54966.rs @@ -1,6 +1,6 @@ // issue-54966: ICE returning an unknown type with impl FnMut fn generate_duration() -> Oper {} -//~^ ERROR cannot find type `Oper` in this scope +//~^ ERROR cannot find type `Oper` fn main() {} diff --git a/tests/ui/impl-trait/issue-54966.stderr b/tests/ui/impl-trait/issue-54966.stderr index 4024c5afa80b6..9b936c25d78a4 100644 --- a/tests/ui/impl-trait/issue-54966.stderr +++ b/tests/ui/impl-trait/issue-54966.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `Oper` in this scope +error[E0412]: cannot find type `Oper` --> $DIR/issue-54966.rs:3:27 | LL | fn generate_duration() -> Oper {} diff --git a/tests/ui/impl-trait/issues/issue-82139.rs b/tests/ui/impl-trait/issues/issue-82139.rs index 3f0b0f1a8dee0..056402e242860 100644 --- a/tests/ui/impl-trait/issues/issue-82139.rs +++ b/tests/ui/impl-trait/issues/issue-82139.rs @@ -12,7 +12,7 @@ impl Trait for Struct { type Associated = impl Bound; fn func() -> Self::Associated { - Some(42).map(|_| j) //~ ERROR cannot find value `j` in this scope + Some(42).map(|_| j) //~ ERROR cannot find value `j` } } diff --git a/tests/ui/impl-trait/issues/issue-82139.stderr b/tests/ui/impl-trait/issues/issue-82139.stderr index b87084433120b..4c0c997bef1e0 100644 --- a/tests/ui/impl-trait/issues/issue-82139.stderr +++ b/tests/ui/impl-trait/issues/issue-82139.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `j` in this scope +error[E0425]: cannot find value `j` --> $DIR/issue-82139.rs:15:26 | LL | Some(42).map(|_| j) diff --git a/tests/ui/impl-trait/opaque-used-in-extraneous-argument.stderr b/tests/ui/impl-trait/opaque-used-in-extraneous-argument.stderr index caaac5434c56a..f03665d192a54 100644 --- a/tests/ui/impl-trait/opaque-used-in-extraneous-argument.stderr +++ b/tests/ui/impl-trait/opaque-used-in-extraneous-argument.stderr @@ -10,7 +10,7 @@ help: consider using the `'static` lifetime, but this is uncommon unless you're LL | fn frob() -> impl Fn + 'static {} | ~~~~~~~ -error[E0412]: cannot find type `P` in this scope +error[E0412]: cannot find type `P` --> $DIR/opaque-used-in-extraneous-argument.rs:5:22 | LL | fn frob() -> impl Fn + '_ {} @@ -21,7 +21,7 @@ help: you might be missing a type parameter LL | fn frob

    () -> impl Fn + '_ {} | +++ -error[E0412]: cannot find type `T` +error[E0412]: cannot find type `T` in this scope --> $DIR/opaque-used-in-extraneous-argument.rs:5:34 | LL | fn frob() -> impl Fn + '_ {} diff --git a/tests/ui/impl-trait/precise-capturing/bad-params.stderr b/tests/ui/impl-trait/precise-capturing/bad-params.stderr index bc1fc2e2d5879..e104f115aa3f2 100644 --- a/tests/ui/impl-trait/precise-capturing/bad-params.stderr +++ b/tests/ui/impl-trait/precise-capturing/bad-params.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `T` +error[E0412]: cannot find type `T` in this scope --> $DIR/bad-params.rs:3:34 | LL | fn missing() -> impl Sized + use {} @@ -9,7 +9,7 @@ help: you might be missing a type parameter LL | fn missing() -> impl Sized + use {} | +++ -error[E0411]: cannot find type `Self` +error[E0411]: cannot find type `Self` in this scope --> $DIR/bad-params.rs:6:39 | LL | fn missing_self() -> impl Sized + use {} diff --git a/tests/ui/impl-trait/precise-capturing/bound-modifiers.stderr b/tests/ui/impl-trait/precise-capturing/bound-modifiers.stderr index 33ccfd1f89b2a..4602225e7b922 100644 --- a/tests/ui/impl-trait/precise-capturing/bound-modifiers.stderr +++ b/tests/ui/impl-trait/precise-capturing/bound-modifiers.stderr @@ -22,25 +22,25 @@ error: expected identifier, found keyword `use` LL | fn binder() -> impl Sized + for<'a> use<> {} | ^^^ expected identifier, found keyword -error[E0405]: cannot find trait `r#use` +error[E0405]: cannot find trait `r#use` in this scope --> $DIR/bound-modifiers.rs:5:32 | LL | fn polarity() -> impl Sized + ?use<> {} | ^^^ not found in this scope -error[E0405]: cannot find trait `r#use` +error[E0405]: cannot find trait `r#use` in this scope --> $DIR/bound-modifiers.rs:11:38 | LL | fn asyncness() -> impl Sized + async use<> {} | ^^^ not found in this scope -error[E0405]: cannot find trait `r#use` +error[E0405]: cannot find trait `r#use` in this scope --> $DIR/bound-modifiers.rs:16:38 | LL | fn constness() -> impl Sized + const use<> {} | ^^^ not found in this scope -error[E0405]: cannot find trait `r#use` +error[E0405]: cannot find trait `r#use` in this scope --> $DIR/bound-modifiers.rs:21:37 | LL | fn binder() -> impl Sized + for<'a> use<> {} diff --git a/tests/ui/implied-bounds/references-err.stderr b/tests/ui/implied-bounds/references-err.stderr index f350bd781be95..df83fce3bdef7 100644 --- a/tests/ui/implied-bounds/references-err.stderr +++ b/tests/ui/implied-bounds/references-err.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `DoesNotExist` +error[E0412]: cannot find type `DoesNotExist` in this scope --> $DIR/references-err.rs:14:18 | LL | type Assoc = DoesNotExist; diff --git a/tests/ui/imports/glob-conflict-cross-crate-1.stderr b/tests/ui/imports/glob-conflict-cross-crate-1.stderr index c3187af772e30..83969fc70846e 100644 --- a/tests/ui/imports/glob-conflict-cross-crate-1.stderr +++ b/tests/ui/imports/glob-conflict-cross-crate-1.stderr @@ -1,10 +1,10 @@ -error[E0425]: cannot find function `f` +error[E0425]: cannot find function `f` in crate `glob_conflict` --> $DIR/glob-conflict-cross-crate-1.rs:6:20 | LL | glob_conflict::f(); | ^ not found in crate `glob_conflict` -error[E0425]: cannot find function `f` +error[E0425]: cannot find function `f` in module `glob_conflict::glob` --> $DIR/glob-conflict-cross-crate-1.rs:9:26 | LL | glob_conflict::glob::f(); diff --git a/tests/ui/imports/glob-conflict-cross-crate-2.stderr b/tests/ui/imports/glob-conflict-cross-crate-2.stderr index ceaa0ba80fa13..aebb2d59d063a 100644 --- a/tests/ui/imports/glob-conflict-cross-crate-2.stderr +++ b/tests/ui/imports/glob-conflict-cross-crate-2.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `C` +error[E0412]: cannot find type `C` in this scope --> $DIR/glob-conflict-cross-crate-2.rs:8:13 | LL | let _a: C = 1; diff --git a/tests/ui/imports/glob-resolve1.stderr b/tests/ui/imports/glob-resolve1.stderr index 8ed155860c049..4401ef58732e8 100644 --- a/tests/ui/imports/glob-resolve1.stderr +++ b/tests/ui/imports/glob-resolve1.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find function `fpriv` +error[E0425]: cannot find function `fpriv` in this scope --> $DIR/glob-resolve1.rs:26:5 | LL | fpriv(); @@ -10,7 +10,7 @@ note: function `bar::fpriv` exists but is inaccessible LL | fn fpriv() {} | ^^^^^^^^^^ not accessible -error[E0425]: cannot find function `epriv` +error[E0425]: cannot find function `epriv` in this scope --> $DIR/glob-resolve1.rs:27:5 | LL | epriv(); @@ -40,7 +40,7 @@ help: you might have meant to use the following enum variant LL | B::B1; | ~~~~~ -error[E0425]: cannot find value `C` +error[E0425]: cannot find value `C` in this scope --> $DIR/glob-resolve1.rs:29:5 | LL | C; @@ -52,7 +52,7 @@ note: unit struct `bar::C` exists but is inaccessible LL | struct C; | ^^^^^^^^^ not accessible -error[E0425]: cannot find function `import` +error[E0425]: cannot find function `import` in this scope --> $DIR/glob-resolve1.rs:30:5 | LL | import(); @@ -63,7 +63,7 @@ help: consider importing this function LL + use other::import; | -error[E0412]: cannot find type `A` +error[E0412]: cannot find type `A` in this scope --> $DIR/glob-resolve1.rs:32:11 | LL | pub enum B { @@ -78,7 +78,7 @@ note: enum `bar::A` exists but is inaccessible LL | enum A { | ^^^^^^ not accessible -error[E0412]: cannot find type `C` +error[E0412]: cannot find type `C` in this scope --> $DIR/glob-resolve1.rs:33:11 | LL | pub enum B { @@ -93,7 +93,7 @@ note: struct `bar::C` exists but is inaccessible LL | struct C; | ^^^^^^^^^ not accessible -error[E0412]: cannot find type `D` +error[E0412]: cannot find type `D` in this scope --> $DIR/glob-resolve1.rs:34:11 | LL | pub enum B { diff --git a/tests/ui/imports/import-alias-issue-121168.edition2015.stderr b/tests/ui/imports/import-alias-issue-121168.edition2015.stderr index a93dc203e691b..47001fc1a5291 100644 --- a/tests/ui/imports/import-alias-issue-121168.edition2015.stderr +++ b/tests/ui/imports/import-alias-issue-121168.edition2015.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `Foo` +error[E0412]: cannot find type `Foo` in this scope --> $DIR/import-alias-issue-121168.rs:11:12 | LL | let _: Foo = todo!(); diff --git a/tests/ui/imports/import-alias-issue-121168.edition2018.stderr b/tests/ui/imports/import-alias-issue-121168.edition2018.stderr index a8317fcbb5f92..e14e700c33d81 100644 --- a/tests/ui/imports/import-alias-issue-121168.edition2018.stderr +++ b/tests/ui/imports/import-alias-issue-121168.edition2018.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `Foo` +error[E0412]: cannot find type `Foo` in this scope --> $DIR/import-alias-issue-121168.rs:11:12 | LL | let _: Foo = todo!(); diff --git a/tests/ui/imports/import-alias-issue-121168.edition2021.stderr b/tests/ui/imports/import-alias-issue-121168.edition2021.stderr index a8317fcbb5f92..e14e700c33d81 100644 --- a/tests/ui/imports/import-alias-issue-121168.edition2021.stderr +++ b/tests/ui/imports/import-alias-issue-121168.edition2021.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `Foo` +error[E0412]: cannot find type `Foo` in this scope --> $DIR/import-alias-issue-121168.rs:11:12 | LL | let _: Foo = todo!(); diff --git a/tests/ui/imports/import-glob-0.stderr b/tests/ui/imports/import-glob-0.stderr index 9e86ace214d08..6a2837e770dc5 100644 --- a/tests/ui/imports/import-glob-0.stderr +++ b/tests/ui/imports/import-glob-0.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find function `f999` +error[E0425]: cannot find function `f999` in this scope --> $DIR/import-glob-0.rs:14:5 | LL | f999(); diff --git a/tests/ui/imports/import-glob-circular.stderr b/tests/ui/imports/import-glob-circular.stderr index 31c752a1cd96f..2eb268813d0f2 100644 --- a/tests/ui/imports/import-glob-circular.stderr +++ b/tests/ui/imports/import-glob-circular.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find function `f1066` +error[E0425]: cannot find function `f1066` in this scope --> $DIR/import-glob-circular.rs:16:17 | LL | fn test() { f1066(); } diff --git a/tests/ui/imports/inaccessible_type_aliases.stderr b/tests/ui/imports/inaccessible_type_aliases.stderr index d131f5def62c7..ef224246061d9 100644 --- a/tests/ui/imports/inaccessible_type_aliases.stderr +++ b/tests/ui/imports/inaccessible_type_aliases.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `Foo` +error[E0412]: cannot find type `Foo` in this scope --> $DIR/inaccessible_type_aliases.rs:11:12 | LL | let x: Foo = 100; @@ -13,7 +13,7 @@ LL | type Foo = u64; LL | type Foo = u64; | ^^^^^^^^^^^^^^^ `b::Foo`: not accessible -error[E0412]: cannot find type `Bar` +error[E0412]: cannot find type `Bar` in this scope --> $DIR/inaccessible_type_aliases.rs:12:12 | LL | let y: Bar = 100; diff --git a/tests/ui/imports/issue-4366-2.stderr b/tests/ui/imports/issue-4366-2.stderr index e96ff76d2c667..412423f4d595e 100644 --- a/tests/ui/imports/issue-4366-2.stderr +++ b/tests/ui/imports/issue-4366-2.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `Bar` +error[E0412]: cannot find type `Bar` in this scope --> $DIR/issue-4366-2.rs:15:21 | LL | fn sub() -> Bar { 1 } diff --git a/tests/ui/imports/issue-4366.stderr b/tests/ui/imports/issue-4366.stderr index 35e5055d2d89c..e63399d554ee3 100644 --- a/tests/ui/imports/issue-4366.stderr +++ b/tests/ui/imports/issue-4366.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find function `foo` +error[E0425]: cannot find function `foo` in this scope --> $DIR/issue-4366.rs:18:29 | LL | fn sub() -> isize { foo(); 1 } diff --git a/tests/ui/imports/issue-59764.rs b/tests/ui/imports/issue-59764.rs index 12232eeef852d..fb976792b9799 100644 --- a/tests/ui/imports/issue-59764.rs +++ b/tests/ui/imports/issue-59764.rs @@ -131,5 +131,5 @@ makro!(bar); fn main() { bar(); - //~^ ERROR cannot find function `bar` [E0425] + //~^ ERROR cannot find function `bar` } diff --git a/tests/ui/imports/issue-59764.stderr b/tests/ui/imports/issue-59764.stderr index d8549980a57bb..74525c9c88f5a 100644 --- a/tests/ui/imports/issue-59764.stderr +++ b/tests/ui/imports/issue-59764.stderr @@ -226,7 +226,7 @@ help: a macro with this name exists at the root of the crate LL | use issue_59764::makro; | ~~~~~~~~~~~~~~~~~~ -error[E0425]: cannot find function `bar` +error[E0425]: cannot find function `bar` in this scope --> $DIR/issue-59764.rs:133:5 | LL | bar(); diff --git a/tests/ui/issues-71798.stderr b/tests/ui/issues-71798.stderr index 7911a0e039d0a..52dd14ccb0a14 100644 --- a/tests/ui/issues-71798.stderr +++ b/tests/ui/issues-71798.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `u` +error[E0425]: cannot find value `u` in this scope --> $DIR/issues-71798.rs:7:24 | LL | let _ = test_ref & u; diff --git a/tests/ui/issues/issue-15167.stderr b/tests/ui/issues/issue-15167.stderr index 88a9649b0bc99..53082ea0ec6bb 100644 --- a/tests/ui/issues/issue-15167.stderr +++ b/tests/ui/issues/issue-15167.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `n` +error[E0425]: cannot find value `n` in this scope --> $DIR/issue-15167.rs:3:25 | LL | macro_rules! f { () => (n) } @@ -9,7 +9,7 @@ LL | println!("{}", f!()); | = note: this error originates in the macro `f` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0425]: cannot find value `n` +error[E0425]: cannot find value `n` in this scope --> $DIR/issue-15167.rs:3:25 | LL | macro_rules! f { () => (n) } @@ -20,7 +20,7 @@ LL | println!("{}", f!()); | = note: this error originates in the macro `f` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0425]: cannot find value `n` +error[E0425]: cannot find value `n` in this scope --> $DIR/issue-15167.rs:3:25 | LL | macro_rules! f { () => (n) } @@ -31,7 +31,7 @@ LL | println!("{}", f!()); | = note: this error originates in the macro `f` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0425]: cannot find value `n` +error[E0425]: cannot find value `n` in this scope --> $DIR/issue-15167.rs:3:25 | LL | macro_rules! f { () => (n) } diff --git a/tests/ui/issues/issue-18058.stderr b/tests/ui/issues/issue-18058.stderr index 2415ca371b7ed..c880bb0029192 100644 --- a/tests/ui/issues/issue-18058.stderr +++ b/tests/ui/issues/issue-18058.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `Undefined` +error[E0412]: cannot find type `Undefined` in this scope --> $DIR/issue-18058.rs:1:6 | LL | impl Undefined {} diff --git a/tests/ui/issues/issue-19734.stderr b/tests/ui/issues/issue-19734.stderr index 9c5dba3fc67a4..6023045e98360 100644 --- a/tests/ui/issues/issue-19734.stderr +++ b/tests/ui/issues/issue-19734.stderr @@ -1,4 +1,4 @@ -error: cannot find macro `undef` +error: cannot find macro `undef` in this scope --> $DIR/issue-19734.rs:6:5 | LL | undef!(); diff --git a/tests/ui/issues/issue-2281-part1.stderr b/tests/ui/issues/issue-2281-part1.stderr index ae1a6289b0bc0..47a1ef8cc0277 100644 --- a/tests/ui/issues/issue-2281-part1.stderr +++ b/tests/ui/issues/issue-2281-part1.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `foobar` +error[E0425]: cannot find value `foobar` in this scope --> $DIR/issue-2281-part1.rs:1:28 | LL | fn main() { println!("{}", foobar); } diff --git a/tests/ui/issues/issue-30589.stderr b/tests/ui/issues/issue-30589.stderr index fc74ec29ee5ef..6f97a189cead9 100644 --- a/tests/ui/issues/issue-30589.stderr +++ b/tests/ui/issues/issue-30589.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `DecoderError` +error[E0412]: cannot find type `DecoderError` in this scope --> $DIR/issue-30589.rs:3:23 | LL | impl fmt::Display for DecoderError { diff --git a/tests/ui/issues/issue-32655.stderr b/tests/ui/issues/issue-32655.stderr index 215e2f7c69bcc..2b4240b2d9b50 100644 --- a/tests/ui/issues/issue-32655.stderr +++ b/tests/ui/issues/issue-32655.stderr @@ -1,4 +1,4 @@ -error: cannot find attribute `derive_Clone` +error: cannot find attribute `derive_Clone` in this scope --> $DIR/issue-32655.rs:3:11 | LL | #[derive_Clone] @@ -15,7 +15,7 @@ LL | foo!(); | = note: this error originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info) -error: cannot find attribute `derive_Clone` +error: cannot find attribute `derive_Clone` in this scope --> $DIR/issue-32655.rs:15:7 | LL | #[derive_Clone] diff --git a/tests/ui/issues/issue-32950.stderr b/tests/ui/issues/issue-32950.stderr index eb4d79cd0d645..f6635d982e4ec 100644 --- a/tests/ui/issues/issue-32950.stderr +++ b/tests/ui/issues/issue-32950.stderr @@ -4,7 +4,7 @@ error: `derive` cannot be used on items with type macros LL | concat_idents!(Foo, Bar) | ^^^^^^^^^^^^^^^^^^^^^^^^ -error[E0412]: cannot find type `FooBar` +error[E0412]: cannot find type `FooBar` in this scope --> $DIR/issue-32950.rs:5:5 | LL | concat_idents!(Foo, Bar) diff --git a/tests/ui/issues/issue-33525.stderr b/tests/ui/issues/issue-33525.stderr index 5112acf81fcf2..ee9f4d4c3016d 100644 --- a/tests/ui/issues/issue-33525.stderr +++ b/tests/ui/issues/issue-33525.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `a` +error[E0425]: cannot find value `a` in this scope --> $DIR/issue-33525.rs:2:5 | LL | a; diff --git a/tests/ui/issues/issue-33571.stderr b/tests/ui/issues/issue-33571.stderr index 3f9bf3acb09ee..06fe0d5ae270a 100644 --- a/tests/ui/issues/issue-33571.stderr +++ b/tests/ui/issues/issue-33571.stderr @@ -1,4 +1,4 @@ -error: cannot find derive macro `Sync` +error: cannot find derive macro `Sync` in this scope --> $DIR/issue-33571.rs:2:10 | LL | Sync, @@ -10,7 +10,7 @@ note: unsafe traits like `Sync` should be implemented explicitly LL | Sync, | ^^^^ -error: cannot find derive macro `Sync` +error: cannot find derive macro `Sync` in this scope --> $DIR/issue-33571.rs:2:10 | LL | Sync, diff --git a/tests/ui/issues/issue-36836.stderr b/tests/ui/issues/issue-36836.stderr index 54b06df601228..e5c943c7c3d82 100644 --- a/tests/ui/issues/issue-36836.stderr +++ b/tests/ui/issues/issue-36836.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `Bar` +error[E0412]: cannot find type `Bar` in this scope --> $DIR/issue-36836.rs:13:17 | LL | impl Foo for Bar {} diff --git a/tests/ui/issues/issue-40845.stderr b/tests/ui/issues/issue-40845.stderr index d0811cbe846ea..18d62d9eb5ad3 100644 --- a/tests/ui/issues/issue-40845.stderr +++ b/tests/ui/issues/issue-40845.stderr @@ -1,10 +1,10 @@ -error: cannot find macro `m` +error: cannot find macro `m` in this scope --> $DIR/issue-40845.rs:1:11 | LL | trait T { m!(); } | ^ not found in this scope -error: cannot find macro `m` +error: cannot find macro `m` in this scope --> $DIR/issue-40845.rs:4:10 | LL | impl S { m!(); } diff --git a/tests/ui/issues/issue-46332.stderr b/tests/ui/issues/issue-46332.stderr index 6ea4d49df0232..8c0c1dfa6ee86 100644 --- a/tests/ui/issues/issue-46332.stderr +++ b/tests/ui/issues/issue-46332.stderr @@ -1,4 +1,4 @@ -error[E0422]: cannot find struct, variant or union type `TyUInt` +error[E0422]: cannot find struct, variant or union type `TyUInt` in this scope --> $DIR/issue-46332.rs:9:5 | LL | struct TyUint {} diff --git a/tests/ui/issues/issue-53300.rs b/tests/ui/issues/issue-53300.rs index 39f746dc676e5..cc63356fc76ef 100644 --- a/tests/ui/issues/issue-53300.rs +++ b/tests/ui/issues/issue-53300.rs @@ -5,7 +5,7 @@ pub trait A { } fn addition() -> Wrapper {} -//~^ ERROR cannot find type `Wrapper` [E0412] +//~^ ERROR cannot find type `Wrapper` fn main() { let res = addition(); diff --git a/tests/ui/issues/issue-53300.stderr b/tests/ui/issues/issue-53300.stderr index ae35822dd9bdb..293465ecb8140 100644 --- a/tests/ui/issues/issue-53300.stderr +++ b/tests/ui/issues/issue-53300.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `Wrapper` +error[E0412]: cannot find type `Wrapper` in this scope --> $DIR/issue-53300.rs:7:18 | LL | fn addition() -> Wrapper {} diff --git a/tests/ui/issues/issue-58712.stderr b/tests/ui/issues/issue-58712.stderr index 79615510afb78..f4bd4d1e826a0 100644 --- a/tests/ui/issues/issue-58712.stderr +++ b/tests/ui/issues/issue-58712.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `DeviceId` +error[E0412]: cannot find type `DeviceId` in this scope --> $DIR/issue-58712.rs:6:20 | LL | impl AddrVec { @@ -9,7 +9,7 @@ help: you might be missing a type parameter LL | impl AddrVec { | ++++++++++ -error[E0412]: cannot find type `DeviceId` +error[E0412]: cannot find type `DeviceId` in this scope --> $DIR/issue-58712.rs:8:29 | LL | pub fn device(&self) -> DeviceId { diff --git a/tests/ui/issues/issue-72839-error-overflow.stderr b/tests/ui/issues/issue-72839-error-overflow.stderr index fa6801086d3a4..35be632f57975 100644 --- a/tests/ui/issues/issue-72839-error-overflow.stderr +++ b/tests/ui/issues/issue-72839-error-overflow.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `missing_var` +error[E0425]: cannot find value `missing_var` in this scope --> $DIR/issue-72839-error-overflow.rs:18:8 | LL | if missing_var % 8 == 0 {} diff --git a/tests/ui/issues/issue-77919.stderr b/tests/ui/issues/issue-77919.stderr index a3e8fddec6372..dbbe70ff06990 100644 --- a/tests/ui/issues/issue-77919.stderr +++ b/tests/ui/issues/issue-77919.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `PhantomData` +error[E0412]: cannot find type `PhantomData` in this scope --> $DIR/issue-77919.rs:9:9 | LL | _n: PhantomData, @@ -9,7 +9,7 @@ help: consider importing this struct LL + use std::marker::PhantomData; | -error[E0412]: cannot find type `VAL` +error[E0412]: cannot find type `VAL` in this scope --> $DIR/issue-77919.rs:11:63 | LL | impl TypeVal for Multiply where N: TypeVal {} diff --git a/tests/ui/issues/issue-86756.stderr b/tests/ui/issues/issue-86756.stderr index 8556dc37b5215..d0906a6fa74f4 100644 --- a/tests/ui/issues/issue-86756.stderr +++ b/tests/ui/issues/issue-86756.stderr @@ -6,7 +6,7 @@ LL | trait Foo {} | | | first use of `T` -error[E0412]: cannot find type `dyn` +error[E0412]: cannot find type `dyn` in this scope --> $DIR/issue-86756.rs:5:10 | LL | eq:: diff --git a/tests/ui/issues/issue-8767.stderr b/tests/ui/issues/issue-8767.stderr index 95058e03d8b47..66141628e28d2 100644 --- a/tests/ui/issues/issue-8767.stderr +++ b/tests/ui/issues/issue-8767.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `B` +error[E0412]: cannot find type `B` in this scope --> $DIR/issue-8767.rs:1:6 | LL | impl B { diff --git a/tests/ui/keyword/keyword-self-as-identifier.stderr b/tests/ui/keyword/keyword-self-as-identifier.stderr index 12bfa6121fb04..098ef8d82a04f 100644 --- a/tests/ui/keyword/keyword-self-as-identifier.stderr +++ b/tests/ui/keyword/keyword-self-as-identifier.stderr @@ -1,4 +1,4 @@ -error[E0531]: cannot find unit struct, unit variant or constant `Self` +error[E0531]: cannot find unit struct, unit variant or constant `Self` in this scope --> $DIR/keyword-self-as-identifier.rs:2:9 | LL | let Self = 22; diff --git a/tests/ui/label/label_misspelled.stderr b/tests/ui/label/label_misspelled.stderr index 0e0b3174bc379..4b5b9e92ca09a 100644 --- a/tests/ui/label/label_misspelled.stderr +++ b/tests/ui/label/label_misspelled.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `while_loop` +error[E0425]: cannot find value `while_loop` in this scope --> $DIR/label_misspelled.rs:6:9 | LL | 'while_loop: while true { @@ -7,7 +7,7 @@ LL | LL | while_loop; | ^^^^^^^^^^ not found in this scope -error[E0425]: cannot find value `while_let` +error[E0425]: cannot find value `while_let` in this scope --> $DIR/label_misspelled.rs:11:9 | LL | 'while_let: while let Some(_) = Some(()) { @@ -16,7 +16,7 @@ LL | LL | while_let; | ^^^^^^^^^ not found in this scope -error[E0425]: cannot find value `for_loop` +error[E0425]: cannot find value `for_loop` in this scope --> $DIR/label_misspelled.rs:16:9 | LL | 'for_loop: for _ in 0..3 { @@ -25,7 +25,7 @@ LL | LL | for_loop; | ^^^^^^^^ not found in this scope -error[E0425]: cannot find value `LOOP` +error[E0425]: cannot find value `LOOP` in this scope --> $DIR/label_misspelled.rs:21:9 | LL | 'LOOP: loop { @@ -34,7 +34,7 @@ LL | LL | LOOP; | ^^^^ not found in this scope -error[E0425]: cannot find value `LOOP` +error[E0425]: cannot find value `LOOP` in this scope --> $DIR/label_misspelled.rs:28:15 | LL | 'LOOP: loop { @@ -45,7 +45,7 @@ LL | break LOOP; | not found in this scope | help: use the similarly named label: `'LOOP` -error[E0425]: cannot find value `while_loop` +error[E0425]: cannot find value `while_loop` in this scope --> $DIR/label_misspelled.rs:32:15 | LL | 'while_loop: while true { @@ -56,7 +56,7 @@ LL | break while_loop; | not found in this scope | help: use the similarly named label: `'while_loop` -error[E0425]: cannot find value `while_let` +error[E0425]: cannot find value `while_let` in this scope --> $DIR/label_misspelled.rs:36:15 | LL | 'while_let: while let Some(_) = Some(()) { @@ -67,7 +67,7 @@ LL | break while_let; | not found in this scope | help: use the similarly named label: `'while_let` -error[E0425]: cannot find value `for_loop` +error[E0425]: cannot find value `for_loop` in this scope --> $DIR/label_misspelled.rs:40:15 | LL | 'for_loop: for _ in 0..3 { diff --git a/tests/ui/label/label_misspelled_2.stderr b/tests/ui/label/label_misspelled_2.stderr index cf0e5cf4f93ac..960646d9894d1 100644 --- a/tests/ui/label/label_misspelled_2.stderr +++ b/tests/ui/label/label_misspelled_2.stderr @@ -10,7 +10,7 @@ error: malformed loop label LL | d: for _ in 0..1 { | ^ help: use the correct loop label format: `'d` -error[E0425]: cannot find value `b` +error[E0425]: cannot find value `b` in this scope --> $DIR/label_misspelled_2.rs:8:15 | LL | 'b: for _ in 0..1 { @@ -21,7 +21,7 @@ LL | break b; | not found in this scope | help: use the similarly named label: `'b` -error[E0425]: cannot find value `d` +error[E0425]: cannot find value `d` in this scope --> $DIR/label_misspelled_2.rs:14:15 | LL | d: for _ in 0..1 { diff --git a/tests/ui/lang-items/issue-83471.stderr b/tests/ui/lang-items/issue-83471.stderr index 99e0f37e82499..244b2efeaf1e0 100644 --- a/tests/ui/lang-items/issue-83471.stderr +++ b/tests/ui/lang-items/issue-83471.stderr @@ -41,7 +41,7 @@ LL | #[lang = "fn"] LL | trait Fn { | - this trait has 0 generic arguments -error[E0425]: cannot find function `a` +error[E0425]: cannot find function `a` in this scope --> $DIR/issue-83471.rs:21:5 | LL | a() diff --git a/tests/ui/layout/cannot-transmute-unnormalizable-type.stderr b/tests/ui/layout/cannot-transmute-unnormalizable-type.stderr index d562a588afc02..dd5119318ff4b 100644 --- a/tests/ui/layout/cannot-transmute-unnormalizable-type.stderr +++ b/tests/ui/layout/cannot-transmute-unnormalizable-type.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `Missing` +error[E0412]: cannot find type `Missing` in this scope --> $DIR/cannot-transmute-unnormalizable-type.rs:7:5 | LL | Missing: Trait, diff --git a/tests/ui/layout/issue-84108.stderr b/tests/ui/layout/issue-84108.stderr index 07bdc6db686b1..8ddce285e23f8 100644 --- a/tests/ui/layout/issue-84108.stderr +++ b/tests/ui/layout/issue-84108.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `OsStr` +error[E0412]: cannot find type `OsStr` in this scope --> $DIR/issue-84108.rs:6:24 | LL | static FOO: (dyn AsRef, u8) = ("hello", 42); @@ -9,7 +9,7 @@ help: consider importing this struct LL + use std::ffi::OsStr; | -error[E0412]: cannot find type `Path` +error[E0412]: cannot find type `Path` in this scope --> $DIR/issue-84108.rs:9:14 | LL | const BAR: (&Path, [u8], usize) = ("hello", [], 42); diff --git a/tests/ui/layout/malformed-unsized-type-in-union.stderr b/tests/ui/layout/malformed-unsized-type-in-union.stderr index a2adb38cc1501..ad4f0cda19e5c 100644 --- a/tests/ui/layout/malformed-unsized-type-in-union.stderr +++ b/tests/ui/layout/malformed-unsized-type-in-union.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `Missing` +error[E0412]: cannot find type `Missing` in this scope --> $DIR/malformed-unsized-type-in-union.rs:3:34 | LL | union W { s: dyn Iterator } diff --git a/tests/ui/layout/transmute-to-tail-with-err.stderr b/tests/ui/layout/transmute-to-tail-with-err.stderr index aeb47186eb1db..433c6b38d0b42 100644 --- a/tests/ui/layout/transmute-to-tail-with-err.stderr +++ b/tests/ui/layout/transmute-to-tail-with-err.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `T` +error[E0412]: cannot find type `T` in this scope --> $DIR/transmute-to-tail-with-err.rs:3:26 | LL | struct Bar(Box>); diff --git a/tests/ui/let-else/let-else-scope.stderr b/tests/ui/let-else/let-else-scope.stderr index 2f8a99ddabb64..335ee3dfb1ea7 100644 --- a/tests/ui/let-else/let-else-scope.stderr +++ b/tests/ui/let-else/let-else-scope.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `x` +error[E0425]: cannot find value `x` in this scope --> $DIR/let-else-scope.rs:3:22 | LL | panic!("{}", x); diff --git a/tests/ui/lifetimes/issue-83907-invalid-fn-like-path.stderr b/tests/ui/lifetimes/issue-83907-invalid-fn-like-path.stderr index bdeb4a62ed9d3..e57933da558fd 100644 --- a/tests/ui/lifetimes/issue-83907-invalid-fn-like-path.stderr +++ b/tests/ui/lifetimes/issue-83907-invalid-fn-like-path.stderr @@ -6,7 +6,7 @@ LL | static STATIC_VAR_FIVE: &One(); | | | help: provide a definition for the static: `= ;` -error[E0412]: cannot find type `One` +error[E0412]: cannot find type `One` in this scope --> $DIR/issue-83907-invalid-fn-like-path.rs:3:26 | LL | static STATIC_VAR_FIVE: &One(); diff --git a/tests/ui/lint/internal/trivial-diagnostics.stderr b/tests/ui/lint/internal/trivial-diagnostics.stderr index 233d24c49e806..d47a7dae023e2 100644 --- a/tests/ui/lint/internal/trivial-diagnostics.stderr +++ b/tests/ui/lint/internal/trivial-diagnostics.stderr @@ -1,10 +1,10 @@ -error[E0425]: cannot find value `msg` +error[E0425]: cannot find value `msg` in this scope --> $DIR/trivial-diagnostics.rs:4:21 | LL | struct_span_err(msg).emit(); | ^^^ not found in this scope -error[E0425]: cannot find function `struct_span_err` +error[E0425]: cannot find function `struct_span_err` in this scope --> $DIR/trivial-diagnostics.rs:4:5 | LL | struct_span_err(msg).emit(); diff --git a/tests/ui/lint/issue-35075.stderr b/tests/ui/lint/issue-35075.stderr index 1fe6a0efa99a3..08bdaa728583d 100644 --- a/tests/ui/lint/issue-35075.stderr +++ b/tests/ui/lint/issue-35075.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `Foo` +error[E0412]: cannot find type `Foo` in this scope --> $DIR/issue-35075.rs:2:12 | LL | inner: Foo @@ -9,7 +9,7 @@ help: there is an enum variant `Baz::Foo`; try using the variant's enum LL | inner: Baz | ~~~ -error[E0412]: cannot find type `Foo` +error[E0412]: cannot find type `Foo` in this scope --> $DIR/issue-35075.rs:6:9 | LL | Foo(Foo) diff --git a/tests/ui/lint/recommend-literal.rs b/tests/ui/lint/recommend-literal.rs index da79ff9c38adf..0c2003a52426b 100644 --- a/tests/ui/lint/recommend-literal.rs +++ b/tests/ui/lint/recommend-literal.rs @@ -8,10 +8,10 @@ fn main() { //~^ ERROR cannot find type `long` //~| HELP perhaps you intended to use this type let v1: Boolean = true; - //~^ ERROR: cannot find type `Boolean` [E0412] + //~^ ERROR: cannot find type `Boolean` //~| HELP perhaps you intended to use this type let v2: Bool = true; - //~^ ERROR: cannot find type `Bool` [E0412] + //~^ ERROR: cannot find type `Bool` //~| HELP a builtin type with a similar name exists //~| HELP perhaps you intended to use this type } diff --git a/tests/ui/lint/recommend-literal.stderr b/tests/ui/lint/recommend-literal.stderr index 185298f21e321..424ecadd4b8cc 100644 --- a/tests/ui/lint/recommend-literal.stderr +++ b/tests/ui/lint/recommend-literal.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `double` +error[E0412]: cannot find type `double` in this scope --> $DIR/recommend-literal.rs:1:13 | LL | type Real = double; @@ -7,7 +7,7 @@ LL | type Real = double; | not found in this scope | help: perhaps you intended to use this type: `f64` -error[E0412]: cannot find type `long` +error[E0412]: cannot find type `long` in this scope --> $DIR/recommend-literal.rs:7:12 | LL | let y: long = 74802374902374923; @@ -16,7 +16,7 @@ LL | let y: long = 74802374902374923; | not found in this scope | help: perhaps you intended to use this type: `i64` -error[E0412]: cannot find type `Boolean` +error[E0412]: cannot find type `Boolean` in this scope --> $DIR/recommend-literal.rs:10:13 | LL | let v1: Boolean = true; @@ -25,7 +25,7 @@ LL | let v1: Boolean = true; | not found in this scope | help: perhaps you intended to use this type: `bool` -error[E0412]: cannot find type `Bool` +error[E0412]: cannot find type `Bool` in this scope --> $DIR/recommend-literal.rs:13:13 | LL | let v2: Bool = true; @@ -40,7 +40,7 @@ help: perhaps you intended to use this type LL | let v2: bool = true; | ~~~~ -error[E0412]: cannot find type `boolean` +error[E0412]: cannot find type `boolean` in this scope --> $DIR/recommend-literal.rs:19:9 | LL | fn z(a: boolean) { @@ -49,7 +49,7 @@ LL | fn z(a: boolean) { | not found in this scope | help: perhaps you intended to use this type: `bool` -error[E0412]: cannot find type `byte` +error[E0412]: cannot find type `byte` in this scope --> $DIR/recommend-literal.rs:24:11 | LL | fn a() -> byte { @@ -58,7 +58,7 @@ LL | fn a() -> byte { | not found in this scope | help: perhaps you intended to use this type: `u8` -error[E0412]: cannot find type `float` +error[E0412]: cannot find type `float` in this scope --> $DIR/recommend-literal.rs:31:12 | LL | width: float, @@ -67,7 +67,7 @@ LL | width: float, | not found in this scope | help: perhaps you intended to use this type: `f32` -error[E0412]: cannot find type `int` +error[E0412]: cannot find type `int` in this scope --> $DIR/recommend-literal.rs:34:19 | LL | depth: Option, @@ -82,7 +82,7 @@ help: you might be missing a type parameter LL | struct Data { | +++++ -error[E0412]: cannot find type `short` +error[E0412]: cannot find type `short` in this scope --> $DIR/recommend-literal.rs:40:16 | LL | impl Stuff for short {} diff --git a/tests/ui/lint/use_suggestion_json.stderr b/tests/ui/lint/use_suggestion_json.stderr index 6ab129e287a8d..4683e5dd8f3c2 100644 --- a/tests/ui/lint/use_suggestion_json.stderr +++ b/tests/ui/lint/use_suggestion_json.stderr @@ -1,6 +1,6 @@ { "$message_type": "diagnostic", - "message": "cannot find type `Iter`", + "message": "cannot find type `Iter` in this scope", "code": { "code": "E0412", "explanation": "A used type name is not in scope. @@ -380,7 +380,7 @@ mod foo { "rendered": null } ], - "rendered": "\u001b[0m\u001b[1m\u001b[38;5;9merror[E0412]\u001b[0m\u001b[0m\u001b[1m: cannot find type `Iter`\u001b[0m + "rendered": "\u001b[0m\u001b[1m\u001b[38;5;9merror[E0412]\u001b[0m\u001b[0m\u001b[1m: cannot find type `Iter` in this scope\u001b[0m \u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m--> \u001b[0m\u001b[0m$DIR/use_suggestion_json.rs:12:12\u001b[0m \u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m \u001b[0m\u001b[1m\u001b[38;5;12mLL\u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m\u001b[0m \u001b[0m\u001b[0m let x: Iter;\u001b[0m diff --git a/tests/ui/loops/loop-break-value.stderr b/tests/ui/loops/loop-break-value.stderr index f5a8c38a0bedb..0912bdbb221ec 100644 --- a/tests/ui/loops/loop-break-value.stderr +++ b/tests/ui/loops/loop-break-value.stderr @@ -16,7 +16,7 @@ LL | break; LL | let _ = 'a: loop { | ^^ label `'a` already in scope -error[E0425]: cannot find value `LOOP` +error[E0425]: cannot find value `LOOP` in this scope --> $DIR/loop-break-value.rs:99:15 | LL | 'LOOP: for _ in 0 .. 9 { diff --git a/tests/ui/lowering/span-bug-issue-121431.stderr b/tests/ui/lowering/span-bug-issue-121431.stderr index adbe09b2d55b0..595500b580640 100644 --- a/tests/ui/lowering/span-bug-issue-121431.stderr +++ b/tests/ui/lowering/span-bug-issue-121431.stderr @@ -1,4 +1,4 @@ -error[E0405]: cannot find trait `CallbackMarker` +error[E0405]: cannot find trait `CallbackMarker` in this scope --> $DIR/span-bug-issue-121431.rs:1:21 | LL | fn bug() -> impl CallbackMarker< Item = [(); { |_: &mut ()| 3; 4 }] > {} diff --git a/tests/ui/macros/defined-later-issue-121061-2.stderr b/tests/ui/macros/defined-later-issue-121061-2.stderr index 78c6d5f90f5a2..e2da60f35d591 100644 --- a/tests/ui/macros/defined-later-issue-121061-2.stderr +++ b/tests/ui/macros/defined-later-issue-121061-2.stderr @@ -1,4 +1,4 @@ -error: cannot find macro `something_later` +error: cannot find macro `something_later` in this scope --> $DIR/defined-later-issue-121061-2.rs:3:9 | LL | something_later!(); diff --git a/tests/ui/macros/defined-later-issue-121061.stderr b/tests/ui/macros/defined-later-issue-121061.stderr index bbaf3055b366b..fd835902f397d 100644 --- a/tests/ui/macros/defined-later-issue-121061.stderr +++ b/tests/ui/macros/defined-later-issue-121061.stderr @@ -1,4 +1,4 @@ -error: cannot find macro `something_later` +error: cannot find macro `something_later` in this scope --> $DIR/defined-later-issue-121061.rs:2:5 | LL | something_later!(); diff --git a/tests/ui/macros/expand-full-no-resolution.stderr b/tests/ui/macros/expand-full-no-resolution.stderr index 8680eccd8669e..0e8747390e344 100644 --- a/tests/ui/macros/expand-full-no-resolution.stderr +++ b/tests/ui/macros/expand-full-no-resolution.stderr @@ -1,4 +1,4 @@ -error: cannot find macro `a` +error: cannot find macro `a` in this scope --> $DIR/expand-full-no-resolution.rs:18:18 | LL | macro_rules! _a { @@ -12,7 +12,7 @@ help: the leading underscore in `_a` marks it as unused, consider renaming it to LL | macro_rules! a { | ~ -error: cannot find macro `a` +error: cannot find macro `a` in this scope --> $DIR/expand-full-no-resolution.rs:19:10 | LL | macro_rules! _a { diff --git a/tests/ui/macros/issue-100199.stderr b/tests/ui/macros/issue-100199.stderr index 170bd0cf0f017..89c634ce4f0b5 100644 --- a/tests/ui/macros/issue-100199.stderr +++ b/tests/ui/macros/issue-100199.stderr @@ -1,4 +1,4 @@ -error[E0405]: cannot find trait `MyTrait` +error[E0405]: cannot find trait `MyTrait` in the crate root --> $DIR/issue-100199.rs:1:1 | LL | #[issue_100199::struct_with_bound] diff --git a/tests/ui/macros/issue-11692-1.stderr b/tests/ui/macros/issue-11692-1.stderr index 8fb713beaa349..54dd6f5574ab9 100644 --- a/tests/ui/macros/issue-11692-1.stderr +++ b/tests/ui/macros/issue-11692-1.stderr @@ -1,4 +1,4 @@ -error: cannot find macro `testo` +error: cannot find macro `testo` in this scope --> $DIR/issue-11692-1.rs:2:12 | LL | print!(testo!()); diff --git a/tests/ui/macros/issue-11692-2.stderr b/tests/ui/macros/issue-11692-2.stderr index 0d17f857f962e..948d688518269 100644 --- a/tests/ui/macros/issue-11692-2.stderr +++ b/tests/ui/macros/issue-11692-2.stderr @@ -1,4 +1,4 @@ -error: cannot find macro `test` +error: cannot find macro `test` in this scope --> $DIR/issue-11692-2.rs:2:13 | LL | concat!(test!()); diff --git a/tests/ui/macros/issue-118786.stderr b/tests/ui/macros/issue-118786.stderr index cb5ef0d1febd0..58342386b78b2 100644 --- a/tests/ui/macros/issue-118786.stderr +++ b/tests/ui/macros/issue-118786.stderr @@ -24,7 +24,7 @@ LL | make_macro!((meow)); | = note: the usage of `make_macro!` is likely invalid in item context -error: cannot find macro `macro_rules` +error: cannot find macro `macro_rules` in this scope --> $DIR/issue-118786.rs:7:9 | LL | macro_rules! $macro_name { diff --git a/tests/ui/macros/issue-88206.stderr b/tests/ui/macros/issue-88206.stderr index aefa7793d6965..b109001b0c96d 100644 --- a/tests/ui/macros/issue-88206.stderr +++ b/tests/ui/macros/issue-88206.stderr @@ -1,4 +1,4 @@ -error: cannot find macro `X` +error: cannot find macro `X` in this scope --> $DIR/issue-88206.rs:74:5 | LL | X!(); @@ -10,7 +10,7 @@ note: `X` is imported here, but it is a struct, not a macro LL | use hey::{Serialize, Deserialize, X}; | ^ -error: cannot find macro `test` +error: cannot find macro `test` in this scope --> $DIR/issue-88206.rs:69:5 | LL | test!(); @@ -18,7 +18,7 @@ LL | test!(); | = note: `test` is in scope, but it is an attribute: `#[test]` -error: cannot find macro `Copy` +error: cannot find macro `Copy` in this scope --> $DIR/issue-88206.rs:64:5 | LL | Copy!(); @@ -26,7 +26,7 @@ LL | Copy!(); | = note: `Copy` is in scope, but it is a derive macro: `#[derive(Copy)]` -error: cannot find macro `Box` +error: cannot find macro `Box` in this scope --> $DIR/issue-88206.rs:59:5 | LL | Box!(); @@ -34,7 +34,7 @@ LL | Box!(); | = note: `Box` is in scope, but it is a struct, not a macro -error: cannot find macro `from_utf8` +error: cannot find macro `from_utf8` in this scope --> $DIR/issue-88206.rs:55:5 | LL | from_utf8!(); @@ -46,7 +46,7 @@ note: `from_utf8` is imported here, but it is a function, not a macro LL | use std::str::*; | ^^^^^^^^^^^ -error: cannot find attribute `println` +error: cannot find attribute `println` in this scope --> $DIR/issue-88206.rs:48:3 | LL | #[println] @@ -54,7 +54,7 @@ LL | #[println] | = note: `println` is in scope, but it is a function-like macro -error: cannot find attribute `from_utf8_unchecked` +error: cannot find attribute `from_utf8_unchecked` in this scope --> $DIR/issue-88206.rs:43:3 | LL | #[from_utf8_unchecked] @@ -66,7 +66,7 @@ note: `from_utf8_unchecked` is imported here, but it is a function, not an attri LL | use std::str::*; | ^^^^^^^^^^^ -error: cannot find attribute `Deserialize` +error: cannot find attribute `Deserialize` in this scope --> $DIR/issue-88206.rs:38:3 | LL | #[Deserialize] @@ -78,7 +78,7 @@ note: `Deserialize` is imported here, but it is a trait, not an attribute LL | use hey::{Serialize, Deserialize, X}; | ^^^^^^^^^^^ -error: cannot find derive macro `println` +error: cannot find derive macro `println` in this scope --> $DIR/issue-88206.rs:32:10 | LL | #[derive(println)] @@ -86,7 +86,7 @@ LL | #[derive(println)] | = note: `println` is in scope, but it is a function-like macro -error: cannot find derive macro `from_utf8_mut` +error: cannot find derive macro `from_utf8_mut` in this scope --> $DIR/issue-88206.rs:27:10 | LL | #[derive(from_utf8_mut)] @@ -98,7 +98,7 @@ note: `from_utf8_mut` is imported here, but it is a function, not a derive macro LL | use std::str::*; | ^^^^^^^^^^^ -error: cannot find derive macro `Serialize` +error: cannot find derive macro `Serialize` in this scope --> $DIR/issue-88206.rs:22:10 | LL | #[derive(Serialize)] diff --git a/tests/ui/macros/issue-88228.stderr b/tests/ui/macros/issue-88228.stderr index 328799dd5b121..32b430b82590e 100644 --- a/tests/ui/macros/issue-88228.stderr +++ b/tests/ui/macros/issue-88228.stderr @@ -1,4 +1,4 @@ -error: cannot find macro `bla` +error: cannot find macro `bla` in this scope --> $DIR/issue-88228.rs:20:5 | LL | bla!(); @@ -9,7 +9,7 @@ help: consider importing this macro through its public re-export LL + use crate::hey::bla; | -error: cannot find derive macro `println` +error: cannot find derive macro `println` in this scope --> $DIR/issue-88228.rs:14:10 | LL | #[derive(println)] @@ -17,7 +17,7 @@ LL | #[derive(println)] | = note: `println` is in scope, but it is a function-like macro -error: cannot find derive macro `Bla` +error: cannot find derive macro `Bla` in this scope --> $DIR/issue-88228.rs:10:10 | LL | #[derive(Bla)] diff --git a/tests/ui/macros/macro-backtrace-nested.stderr b/tests/ui/macros/macro-backtrace-nested.stderr index f50b02e5cf259..dadedfbe8f671 100644 --- a/tests/ui/macros/macro-backtrace-nested.stderr +++ b/tests/ui/macros/macro-backtrace-nested.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `fake` +error[E0425]: cannot find value `fake` in this scope --> $DIR/macro-backtrace-nested.rs:5:12 | LL | () => (fake) @@ -9,7 +9,7 @@ LL | 1 + call_nested_expr!(); | = note: this error originates in the macro `nested_expr` which comes from the expansion of the macro `call_nested_expr` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0425]: cannot find value `fake` +error[E0425]: cannot find value `fake` in this scope --> $DIR/macro-backtrace-nested.rs:5:12 | LL | () => (fake) diff --git a/tests/ui/macros/macro-context.stderr b/tests/ui/macros/macro-context.stderr index 5ebdf2af93841..7785f41594627 100644 --- a/tests/ui/macros/macro-context.stderr +++ b/tests/ui/macros/macro-context.stderr @@ -42,7 +42,7 @@ LL | m!(); | = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0412]: cannot find type `i` +error[E0412]: cannot find type `i` in this scope --> $DIR/macro-context.rs:3:13 | LL | () => ( i ; typeof ); @@ -53,7 +53,7 @@ LL | let a: m!(); | = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0425]: cannot find value `i` +error[E0425]: cannot find value `i` in this scope --> $DIR/macro-context.rs:3:13 | LL | () => ( i ; typeof ); diff --git a/tests/ui/macros/macro-expand-within-generics-in-path.stderr b/tests/ui/macros/macro-expand-within-generics-in-path.stderr index fd4fbcdc60a46..7e5a08fe4d3b3 100644 --- a/tests/ui/macros/macro-expand-within-generics-in-path.stderr +++ b/tests/ui/macros/macro-expand-within-generics-in-path.stderr @@ -4,7 +4,7 @@ error: unexpected generic arguments in path LL | m!(generic); | ^^^^^^ -error: cannot find attribute `generic` +error: cannot find attribute `generic` in this scope --> $DIR/macro-expand-within-generics-in-path.rs:15:4 | LL | m!(generic); diff --git a/tests/ui/macros/macro-expansion-tests.stderr b/tests/ui/macros/macro-expansion-tests.stderr index 39cee66c3df55..01f6d12cadd2e 100644 --- a/tests/ui/macros/macro-expansion-tests.stderr +++ b/tests/ui/macros/macro-expansion-tests.stderr @@ -1,4 +1,4 @@ -error: cannot find macro `m` +error: cannot find macro `m` in this scope --> $DIR/macro-expansion-tests.rs:7:21 | LL | fn g() -> i32 { m!() } @@ -6,7 +6,7 @@ LL | fn g() -> i32 { m!() } | = help: have you added the `#[macro_use]` on the module/import? -error: cannot find macro `m` +error: cannot find macro `m` in this scope --> $DIR/macro-expansion-tests.rs:15:21 | LL | fn g() -> i32 { m!() } diff --git a/tests/ui/macros/macro-metavar-expr-concat/hygiene.stderr b/tests/ui/macros/macro-metavar-expr-concat/hygiene.stderr index 99229927502c9..ef2326dce857f 100644 --- a/tests/ui/macros/macro-metavar-expr-concat/hygiene.stderr +++ b/tests/ui/macros/macro-metavar-expr-concat/hygiene.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `abcdef` +error[E0425]: cannot find value `abcdef` in this scope --> $DIR/hygiene.rs:5:10 | LL | ${concat($lhs, $rhs)} diff --git a/tests/ui/macros/macro-name-typo.stderr b/tests/ui/macros/macro-name-typo.stderr index 283c1b6d252bd..8ec855c7f4865 100644 --- a/tests/ui/macros/macro-name-typo.stderr +++ b/tests/ui/macros/macro-name-typo.stderr @@ -1,4 +1,4 @@ -error: cannot find macro `printlx` +error: cannot find macro `printlx` in this scope --> $DIR/macro-name-typo.rs:2:5 | LL | printlx!("oh noes!"); diff --git a/tests/ui/macros/macro-outer-attributes.stderr b/tests/ui/macros/macro-outer-attributes.stderr index db79d98f1fef2..14f621029ca83 100644 --- a/tests/ui/macros/macro-outer-attributes.stderr +++ b/tests/ui/macros/macro-outer-attributes.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find function `bar` +error[E0425]: cannot find function `bar` in module `a` --> $DIR/macro-outer-attributes.rs:18:8 | LL | a::bar(); diff --git a/tests/ui/macros/macro-parameter-span.stderr b/tests/ui/macros/macro-parameter-span.stderr index ed61ede88bf75..247750a8ad705 100644 --- a/tests/ui/macros/macro-parameter-span.stderr +++ b/tests/ui/macros/macro-parameter-span.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `x` +error[E0425]: cannot find value `x` in this scope --> $DIR/macro-parameter-span.rs:11:9 | LL | x diff --git a/tests/ui/macros/macro-path-prelude-fail-3.stderr b/tests/ui/macros/macro-path-prelude-fail-3.stderr index ac888a3957411..99292289f9233 100644 --- a/tests/ui/macros/macro-path-prelude-fail-3.stderr +++ b/tests/ui/macros/macro-path-prelude-fail-3.stderr @@ -1,4 +1,4 @@ -error: cannot find macro `inline` +error: cannot find macro `inline` in this scope --> $DIR/macro-path-prelude-fail-3.rs:2:5 | LL | inline!(); diff --git a/tests/ui/macros/macro-reexport-removed.stderr b/tests/ui/macros/macro-reexport-removed.stderr index f6ebad65a8099..d05c9c848c47e 100644 --- a/tests/ui/macros/macro-reexport-removed.stderr +++ b/tests/ui/macros/macro-reexport-removed.stderr @@ -6,7 +6,7 @@ LL | #![feature(macro_reexport)] | = note: subsumed by `pub use` -error: cannot find attribute `macro_reexport` +error: cannot find attribute `macro_reexport` in this scope --> $DIR/macro-reexport-removed.rs:5:3 | LL | #[macro_reexport(macro_one)] diff --git a/tests/ui/macros/macro-use-wrong-name.stderr b/tests/ui/macros/macro-use-wrong-name.stderr index 62948823cf85c..2db09f1e2226c 100644 --- a/tests/ui/macros/macro-use-wrong-name.stderr +++ b/tests/ui/macros/macro-use-wrong-name.stderr @@ -1,4 +1,4 @@ -error: cannot find macro `macro_two` +error: cannot find macro `macro_two` in this scope --> $DIR/macro-use-wrong-name.rs:7:5 | LL | macro_two!(); diff --git a/tests/ui/macros/macro_undefined.stderr b/tests/ui/macros/macro_undefined.stderr index 44155da0e933d..dccdd754606f2 100644 --- a/tests/ui/macros/macro_undefined.stderr +++ b/tests/ui/macros/macro_undefined.stderr @@ -1,4 +1,4 @@ -error: cannot find macro `k` +error: cannot find macro `k` in this scope --> $DIR/macro_undefined.rs:11:5 | LL | macro_rules! kl { diff --git a/tests/ui/macros/macros-nonfatal-errors.stderr b/tests/ui/macros/macros-nonfatal-errors.stderr index cbec314323aa4..0ab29a20525d4 100644 --- a/tests/ui/macros/macros-nonfatal-errors.stderr +++ b/tests/ui/macros/macros-nonfatal-errors.stderr @@ -238,7 +238,7 @@ LL | Foo, | = help: consider a manual implementation of `Default` -error: cannot find macro `llvm_asm` +error: cannot find macro `llvm_asm` in this scope --> $DIR/macros-nonfatal-errors.rs:99:5 | LL | llvm_asm!(invalid); diff --git a/tests/ui/macros/rfc-3086-metavar-expr/syntax-errors.stderr b/tests/ui/macros/rfc-3086-metavar-expr/syntax-errors.stderr index 1554fdbce0bed..2c44ad2e0a4ad 100644 --- a/tests/ui/macros/rfc-3086-metavar-expr/syntax-errors.stderr +++ b/tests/ui/macros/rfc-3086-metavar-expr/syntax-errors.stderr @@ -313,7 +313,7 @@ LL | unknown_metavar!(a); | = note: this error originates in the macro `unknown_metavar` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0425]: cannot find value `i` +error[E0425]: cannot find value `i` in this scope --> $DIR/syntax-errors.rs:23:36 | LL | ( $( $i:ident ),* ) => { count(i) }; @@ -324,7 +324,7 @@ LL | no_curly__no_rhs_dollar__round!(a, b, c); | = note: this error originates in the macro `no_curly__no_rhs_dollar__round` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0425]: cannot find value `i` +error[E0425]: cannot find value `i` in this scope --> $DIR/syntax-errors.rs:30:29 | LL | ( $i:ident ) => { count(i) }; @@ -335,13 +335,13 @@ LL | no_curly__no_rhs_dollar__no_round!(a); | = note: this error originates in the macro `no_curly__no_rhs_dollar__no_round` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0425]: cannot find value `a` +error[E0425]: cannot find value `a` in this scope --> $DIR/syntax-errors.rs:152:37 | LL | no_curly__rhs_dollar__no_round!(a); | ^ not found in this scope -error[E0425]: cannot find function `count` +error[E0425]: cannot find function `count` in this scope --> $DIR/syntax-errors.rs:23:30 | LL | ( $( $i:ident ),* ) => { count(i) }; @@ -352,7 +352,7 @@ LL | no_curly__no_rhs_dollar__round!(a, b, c); | = note: this error originates in the macro `no_curly__no_rhs_dollar__round` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0425]: cannot find function `count` +error[E0425]: cannot find function `count` in this scope --> $DIR/syntax-errors.rs:30:23 | LL | ( $i:ident ) => { count(i) }; @@ -363,7 +363,7 @@ LL | no_curly__no_rhs_dollar__no_round!(a); | = note: this error originates in the macro `no_curly__no_rhs_dollar__no_round` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0425]: cannot find function `count` +error[E0425]: cannot find function `count` in this scope --> $DIR/syntax-errors.rs:43:23 | LL | ( $i:ident ) => { count($i) }; diff --git a/tests/ui/match/expr_before_ident_pat.stderr b/tests/ui/match/expr_before_ident_pat.stderr index 20382c70c5dea..1657c51545cb2 100644 --- a/tests/ui/match/expr_before_ident_pat.stderr +++ b/tests/ui/match/expr_before_ident_pat.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `a` +error[E0425]: cannot find value `a` in this scope --> $DIR/expr_before_ident_pat.rs:10:12 | LL | funny!(a, a); diff --git a/tests/ui/match/issue-82866.stderr b/tests/ui/match/issue-82866.stderr index 09d69408d3cdf..f9e3360a525ff 100644 --- a/tests/ui/match/issue-82866.stderr +++ b/tests/ui/match/issue-82866.stderr @@ -1,10 +1,10 @@ -error[E0425]: cannot find value `x` +error[E0425]: cannot find value `x` in this scope --> $DIR/issue-82866.rs:2:11 | LL | match x { | ^ not found in this scope -error[E0412]: cannot find type `v` +error[E0412]: cannot find type `v` in this scope --> $DIR/issue-82866.rs:4:16 | LL | Some::(v) => (), diff --git a/tests/ui/match/issue-92100.stderr b/tests/ui/match/issue-92100.stderr index 0a18f0d1e9baa..eb9f4ba1ad698 100644 --- a/tests/ui/match/issue-92100.stderr +++ b/tests/ui/match/issue-92100.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `a` +error[E0425]: cannot find value `a` in this scope --> $DIR/issue-92100.rs:5:10 | LL | [a.., a] => {} diff --git a/tests/ui/match/match-join.stderr b/tests/ui/match/match-join.stderr index b5cf1201217ac..4feb1bef9ad59 100644 --- a/tests/ui/match/match-join.stderr +++ b/tests/ui/match/match-join.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `x` +error[E0425]: cannot find value `x` in this scope --> $DIR/match-join.rs:9:20 | LL | println!("{}", x); diff --git a/tests/ui/methods/suggest-method-on-call-for-ambig-receiver.stderr b/tests/ui/methods/suggest-method-on-call-for-ambig-receiver.stderr index cefa5a4808fcf..40d8301c24e5c 100644 --- a/tests/ui/methods/suggest-method-on-call-for-ambig-receiver.stderr +++ b/tests/ui/methods/suggest-method-on-call-for-ambig-receiver.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find function `consume` +error[E0425]: cannot find function `consume` in this scope --> $DIR/suggest-method-on-call-for-ambig-receiver.rs:10:13 | LL | consume(right); diff --git a/tests/ui/methods/suggest-method-on-call-with-macro-rcvr.stderr b/tests/ui/methods/suggest-method-on-call-with-macro-rcvr.stderr index 2d3918bdeada7..86c2f6431d1b8 100644 --- a/tests/ui/methods/suggest-method-on-call-with-macro-rcvr.stderr +++ b/tests/ui/methods/suggest-method-on-call-with-macro-rcvr.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find function `len` +error[E0425]: cannot find function `len` in this scope --> $DIR/suggest-method-on-call-with-macro-rcvr.rs:4:17 | LL | let hello = len(vec![]); diff --git a/tests/ui/mir/issue-83499-input-output-iteration-ice.stderr b/tests/ui/mir/issue-83499-input-output-iteration-ice.stderr index 9467f1ced14d1..80a8a94aea400 100644 --- a/tests/ui/mir/issue-83499-input-output-iteration-ice.stderr +++ b/tests/ui/mir/issue-83499-input-output-iteration-ice.stderr @@ -10,7 +10,7 @@ error: at least one trait must be specified LL | fn foo(_: Bar, ...) -> impl {} | ^^^^ -error[E0412]: cannot find type `Bar` +error[E0412]: cannot find type `Bar` in this scope --> $DIR/issue-83499-input-output-iteration-ice.rs:7:11 | LL | fn foo(_: Bar, ...) -> impl {} diff --git a/tests/ui/mir/mir-build-2021-closure-capture-ice-110453-1.stderr b/tests/ui/mir/mir-build-2021-closure-capture-ice-110453-1.stderr index feb80778b3bb0..468da0227d3d0 100644 --- a/tests/ui/mir/mir-build-2021-closure-capture-ice-110453-1.stderr +++ b/tests/ui/mir/mir-build-2021-closure-capture-ice-110453-1.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `B` +error[E0412]: cannot find type `B` in this scope --> $DIR/mir-build-2021-closure-capture-ice-110453-1.rs:12:18 | LL | pub struct C(B); diff --git a/tests/ui/mir/mir-build-2021-closure-capture-ice-110453-2.stderr b/tests/ui/mir/mir-build-2021-closure-capture-ice-110453-2.stderr index 5479e6b5fee8b..8fe4981eb3f24 100644 --- a/tests/ui/mir/mir-build-2021-closure-capture-ice-110453-2.stderr +++ b/tests/ui/mir/mir-build-2021-closure-capture-ice-110453-2.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `as_str` +error[E0412]: cannot find type `as_str` in this scope --> $DIR/mir-build-2021-closure-capture-ice-110453-2.rs:8:47 | LL | pub fn dup(f: impl Fn(i32) -> i32) -> impl Fn(as_str) -> i32 { diff --git a/tests/ui/mir/validate/error-body.stderr b/tests/ui/mir/validate/error-body.stderr index a7536238bbd9f..1dfeaf0b7e2cb 100644 --- a/tests/ui/mir/validate/error-body.stderr +++ b/tests/ui/mir/validate/error-body.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find function `missing` +error[E0425]: cannot find function `missing` in this scope --> $DIR/error-body.rs:5:5 | LL | missing(); diff --git a/tests/ui/missing/missing-items/missing-const-parameter.stderr b/tests/ui/missing/missing-items/missing-const-parameter.stderr index 0b9c674f3ec15..d9fea1306514c 100644 --- a/tests/ui/missing/missing-items/missing-const-parameter.stderr +++ b/tests/ui/missing/missing-items/missing-const-parameter.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `N` +error[E0425]: cannot find value `N` in this scope --> $DIR/missing-const-parameter.rs:3:15 | LL | impl Struct<{ N }> {} @@ -9,7 +9,7 @@ help: you might be missing a const parameter LL | impl Struct<{ N }> {} | +++++++++++++++++++++ -error[E0425]: cannot find value `N` +error[E0425]: cannot find value `N` in this scope --> $DIR/missing-const-parameter.rs:7:22 | LL | fn func0(_: Struct<{ N }>) {} @@ -20,7 +20,7 @@ help: you might be missing a const parameter LL | fn func0(_: Struct<{ N }>) {} | +++++++++++++++++++++ -error[E0425]: cannot find value `N` +error[E0425]: cannot find value `N` in this scope --> $DIR/missing-const-parameter.rs:11:18 | LL | fn func1(_: [u8; N]) {} @@ -31,7 +31,7 @@ help: you might be missing a const parameter LL | fn func1(_: [u8; N]) {} | +++++++++++++++++++++ -error[E0425]: cannot find value `N` +error[E0425]: cannot find value `N` in this scope --> $DIR/missing-const-parameter.rs:15:20 | LL | fn func2(_: [T; N]) {} @@ -42,7 +42,7 @@ help: you might be missing a const parameter LL | fn func2(_: [T; N]) {} | +++++++++++++++++++++ -error[E0425]: cannot find value `C` +error[E0425]: cannot find value `C` in this scope --> $DIR/missing-const-parameter.rs:19:37 | LL | struct Image([[u32; C]; R]); diff --git a/tests/ui/missing/missing-items/missing-type-parameter2.stderr b/tests/ui/missing/missing-items/missing-type-parameter2.stderr index 073bb9c9a9eee..f33951c98bfb3 100644 --- a/tests/ui/missing/missing-items/missing-type-parameter2.stderr +++ b/tests/ui/missing/missing-items/missing-type-parameter2.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `N` +error[E0412]: cannot find type `N` in this scope --> $DIR/missing-type-parameter2.rs:3:8 | LL | struct X(); @@ -16,7 +16,7 @@ help: you might be missing a type parameter LL | impl X {} | +++ -error[E0412]: cannot find type `N` +error[E0412]: cannot find type `N` in this scope --> $DIR/missing-type-parameter2.rs:6:28 | LL | impl X {} @@ -33,7 +33,7 @@ help: you might be missing a type parameter LL | impl X {} | +++ -error[E0412]: cannot find type `T` +error[E0412]: cannot find type `T` in this scope --> $DIR/missing-type-parameter2.rs:11:20 | LL | struct X(); @@ -51,7 +51,7 @@ help: you might be missing a type parameter LL | fn foo(_: T) where T: Send {} | +++ -error[E0412]: cannot find type `T` +error[E0412]: cannot find type `T` in this scope --> $DIR/missing-type-parameter2.rs:11:11 | LL | struct X(); @@ -69,7 +69,7 @@ help: you might be missing a type parameter LL | fn foo(_: T) where T: Send {} | +++ -error[E0412]: cannot find type `A` +error[E0412]: cannot find type `A` in this scope --> $DIR/missing-type-parameter2.rs:15:24 | LL | struct X(); diff --git a/tests/ui/missing/missing-macro-use.stderr b/tests/ui/missing/missing-macro-use.stderr index f4a3f2c231f29..d83c0680571c5 100644 --- a/tests/ui/missing/missing-macro-use.stderr +++ b/tests/ui/missing/missing-macro-use.stderr @@ -1,4 +1,4 @@ -error: cannot find macro `macro_two` +error: cannot find macro `macro_two` in this scope --> $DIR/missing-macro-use.rs:6:5 | LL | macro_two!(); diff --git a/tests/ui/modules_and_files_visibility/mod_file_correct_spans.stderr b/tests/ui/modules_and_files_visibility/mod_file_correct_spans.stderr index 889f88df42c0f..1d368e94baa23 100644 --- a/tests/ui/modules_and_files_visibility/mod_file_correct_spans.stderr +++ b/tests/ui/modules_and_files_visibility/mod_file_correct_spans.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find function `bar` +error[E0425]: cannot find function `bar` in module `mod_file_aux` --> $DIR/mod_file_correct_spans.rs:6:27 | LL | assert!(mod_file_aux::bar() == 10); diff --git a/tests/ui/namespace/namespaced-enum-glob-import-no-impls-xcrate.stderr b/tests/ui/namespace/namespaced-enum-glob-import-no-impls-xcrate.stderr index 5a325b6870f50..5425a76bd4b7d 100644 --- a/tests/ui/namespace/namespaced-enum-glob-import-no-impls-xcrate.stderr +++ b/tests/ui/namespace/namespaced-enum-glob-import-no-impls-xcrate.stderr @@ -1,22 +1,22 @@ -error[E0425]: cannot find function `foo` +error[E0425]: cannot find function `foo` in module `m` --> $DIR/namespaced-enum-glob-import-no-impls-xcrate.rs:12:8 | LL | m::foo(); | ^^^ not found in module `m` -error[E0425]: cannot find function `bar` +error[E0425]: cannot find function `bar` in module `m` --> $DIR/namespaced-enum-glob-import-no-impls-xcrate.rs:14:8 | LL | m::bar(); | ^^^ not found in module `m` -error[E0425]: cannot find function `foo` +error[E0425]: cannot find function `foo` in this scope --> $DIR/namespaced-enum-glob-import-no-impls-xcrate.rs:11:5 | LL | foo(); | ^^^ not found in this scope -error[E0425]: cannot find function `bar` +error[E0425]: cannot find function `bar` in this scope --> $DIR/namespaced-enum-glob-import-no-impls-xcrate.rs:13:5 | LL | bar(); diff --git a/tests/ui/namespace/namespaced-enum-glob-import-no-impls.stderr b/tests/ui/namespace/namespaced-enum-glob-import-no-impls.stderr index 66436d134a95a..7b9a2ed6c33a0 100644 --- a/tests/ui/namespace/namespaced-enum-glob-import-no-impls.stderr +++ b/tests/ui/namespace/namespaced-enum-glob-import-no-impls.stderr @@ -1,22 +1,22 @@ -error[E0425]: cannot find function `foo` +error[E0425]: cannot find function `foo` in module `m` --> $DIR/namespaced-enum-glob-import-no-impls.rs:22:8 | LL | m::foo(); | ^^^ not found in module `m` -error[E0425]: cannot find function `bar` +error[E0425]: cannot find function `bar` in module `m` --> $DIR/namespaced-enum-glob-import-no-impls.rs:24:8 | LL | m::bar(); | ^^^ not found in module `m` -error[E0425]: cannot find function `foo` +error[E0425]: cannot find function `foo` in this scope --> $DIR/namespaced-enum-glob-import-no-impls.rs:21:5 | LL | foo(); | ^^^ not found in this scope -error[E0425]: cannot find function `bar` +error[E0425]: cannot find function `bar` in this scope --> $DIR/namespaced-enum-glob-import-no-impls.rs:23:5 | LL | bar(); diff --git a/tests/ui/nested-cfg-attrs.stderr b/tests/ui/nested-cfg-attrs.stderr index d91cbe5ccb009..16c2930714353 100644 --- a/tests/ui/nested-cfg-attrs.stderr +++ b/tests/ui/nested-cfg-attrs.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find function `f` +error[E0425]: cannot find function `f` in this scope --> $DIR/nested-cfg-attrs.rs:4:13 | LL | fn main() { f() } diff --git a/tests/ui/object-safety/avoid-ice-on-warning.new.stderr b/tests/ui/object-safety/avoid-ice-on-warning.new.stderr index 160a1e7218501..517f910080de7 100644 --- a/tests/ui/object-safety/avoid-ice-on-warning.new.stderr +++ b/tests/ui/object-safety/avoid-ice-on-warning.new.stderr @@ -4,7 +4,7 @@ error: return types are denoted using `->` LL | fn call_this(f: F) : Fn(&str) + call_that {} | ^ help: use `->` instead -error[E0405]: cannot find trait `call_that` +error[E0405]: cannot find trait `call_that` in this scope --> $DIR/avoid-ice-on-warning.rs:4:36 | LL | fn call_this(f: F) : Fn(&str) + call_that {} diff --git a/tests/ui/object-safety/avoid-ice-on-warning.old.stderr b/tests/ui/object-safety/avoid-ice-on-warning.old.stderr index 094fab336e7d7..3939c06eabe5b 100644 --- a/tests/ui/object-safety/avoid-ice-on-warning.old.stderr +++ b/tests/ui/object-safety/avoid-ice-on-warning.old.stderr @@ -4,7 +4,7 @@ error: return types are denoted using `->` LL | fn call_this(f: F) : Fn(&str) + call_that {} | ^ help: use `->` instead -error[E0405]: cannot find trait `call_that` +error[E0405]: cannot find trait `call_that` in this scope --> $DIR/avoid-ice-on-warning.rs:4:36 | LL | fn call_this(f: F) : Fn(&str) + call_that {} diff --git a/tests/ui/object-safety/erroneous_signature.stderr b/tests/ui/object-safety/erroneous_signature.stderr index e682e265ba2c4..f3b14ffe34c3b 100644 --- a/tests/ui/object-safety/erroneous_signature.stderr +++ b/tests/ui/object-safety/erroneous_signature.stderr @@ -1,10 +1,10 @@ -error[E0412]: cannot find type `MissingType` +error[E0412]: cannot find type `MissingType` in this scope --> $DIR/erroneous_signature.rs:2:22 | LL | fn err(&self) -> MissingType; | ^^^^^^^^^^^ not found in this scope -error[E0412]: cannot find type `MissingType` +error[E0412]: cannot find type `MissingType` in this scope --> $DIR/erroneous_signature.rs:7:22 | LL | fn err(&self) -> MissingType { diff --git a/tests/ui/offset-of/offset-of-enum.stderr b/tests/ui/offset-of/offset-of-enum.stderr index b8040fd23b2c6..7e7ad41f5b6a9 100644 --- a/tests/ui/offset-of/offset-of-enum.stderr +++ b/tests/ui/offset-of/offset-of-enum.stderr @@ -7,7 +7,7 @@ LL | offset_of!(Alpha::One, 0); | not a type | help: try using the variant's enum: `Alpha` -error[E0412]: cannot find type `Beta` +error[E0412]: cannot find type `Beta` in this scope --> $DIR/offset-of-enum.rs:17:16 | LL | offset_of!(Beta, One); diff --git a/tests/ui/offset-of/offset-of-self.stderr b/tests/ui/offset-of/offset-of-self.stderr index ed293f98bd6bc..89bec86a2a96c 100644 --- a/tests/ui/offset-of/offset-of-self.stderr +++ b/tests/ui/offset-of/offset-of-self.stderr @@ -4,7 +4,7 @@ error: offset_of expects dot-separated field and variant names LL | offset_of!(Self, Self::v); | ^^^^^^^ -error[E0412]: cannot find type `S` +error[E0412]: cannot find type `S` in module `self` --> $DIR/offset-of-self.rs:34:26 | LL | offset_of!(self::S, v); @@ -20,7 +20,7 @@ LL - offset_of!(self::S, v); LL + offset_of!(S, v); | -error[E0411]: cannot find type `Self` +error[E0411]: cannot find type `Self` in this scope --> $DIR/offset-of-self.rs:51:16 | LL | fn main() { diff --git a/tests/ui/panics/default-backtrace-ice.stderr b/tests/ui/panics/default-backtrace-ice.stderr index 3499d745ff417..23b863568bc74 100644 --- a/tests/ui/panics/default-backtrace-ice.stderr +++ b/tests/ui/panics/default-backtrace-ice.stderr @@ -1,4 +1,4 @@ -error: internal compiler error[E0425]: cannot find value `missing_ident` +error: internal compiler error[E0425]: cannot find value `missing_ident` in this scope --> $DIR/default-backtrace-ice.rs:21:13 | LL | fn main() { missing_ident; } diff --git a/tests/ui/parser/attribute/multiple-tail-expr-behind-cfg.stderr b/tests/ui/parser/attribute/multiple-tail-expr-behind-cfg.stderr index 982fa63de391a..79a34a887c8e3 100644 --- a/tests/ui/parser/attribute/multiple-tail-expr-behind-cfg.stderr +++ b/tests/ui/parser/attribute/multiple-tail-expr-behind-cfg.stderr @@ -44,7 +44,7 @@ help: alternatively, consider surrounding the expression with a block LL | { [1, 2, 3].iter().map(|c| c.to_string()).collect::() } | + + -error: cannot find attribute `attr` +error: cannot find attribute `attr` in this scope --> $DIR/multiple-tail-expr-behind-cfg.rs:13:7 | LL | #[attr] diff --git a/tests/ui/parser/circular_modules_main.stderr b/tests/ui/parser/circular_modules_main.stderr index 2b5481c32a019..7310a71d6ee85 100644 --- a/tests/ui/parser/circular_modules_main.stderr +++ b/tests/ui/parser/circular_modules_main.stderr @@ -4,7 +4,7 @@ error: circular modules: $DIR/circular_modules_main.rs -> $DIR/circular_modules_ LL | mod circular_modules_main; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -error[E0425]: cannot find function `hi_str` +error[E0425]: cannot find function `hi_str` in module `circular_modules_main` --> $DIR/circular_modules_hello.rs:7:43 | LL | println!("{}", circular_modules_main::hi_str()); diff --git a/tests/ui/parser/const-param-decl-on-type-instead-of-impl.stderr b/tests/ui/parser/const-param-decl-on-type-instead-of-impl.stderr index 85c39027698c1..96885d11ee07f 100644 --- a/tests/ui/parser/const-param-decl-on-type-instead-of-impl.stderr +++ b/tests/ui/parser/const-param-decl-on-type-instead-of-impl.stderr @@ -27,7 +27,7 @@ error[E0433]: failed to resolve: use of undeclared crate or module `path` LL | path::path::Struct::() | ^^^^ use of undeclared crate or module `path` -error[E0412]: cannot find type `T` +error[E0412]: cannot find type `T` in this scope --> $DIR/const-param-decl-on-type-instead-of-impl.rs:8:15 | LL | fn banana(a: >::BAR) {} diff --git a/tests/ui/parser/default-unmatched-assoc.stderr b/tests/ui/parser/default-unmatched-assoc.stderr index 88b6d14681016..fe904e9a13631 100644 --- a/tests/ui/parser/default-unmatched-assoc.stderr +++ b/tests/ui/parser/default-unmatched-assoc.stderr @@ -38,13 +38,13 @@ LL | default do LL | } | - item list ends here -error: cannot find macro `default` +error: cannot find macro `default` in this scope --> $DIR/default-unmatched-assoc.rs:4:5 | LL | default!(); | ^^^^^^^ not found in this scope -error: cannot find macro `default` +error: cannot find macro `default` in this scope --> $DIR/default-unmatched-assoc.rs:12:5 | LL | default!(); diff --git a/tests/ui/parser/default-unmatched-extern.stderr b/tests/ui/parser/default-unmatched-extern.stderr index 1e6b7ac269faf..5333621163ffd 100644 --- a/tests/ui/parser/default-unmatched-extern.stderr +++ b/tests/ui/parser/default-unmatched-extern.stderr @@ -18,7 +18,7 @@ LL | default do LL | } | - item list ends here -error: cannot find macro `default` +error: cannot find macro `default` in this scope --> $DIR/default-unmatched-extern.rs:4:5 | LL | default!(); diff --git a/tests/ui/parser/dyn-trait-compatibility.stderr b/tests/ui/parser/dyn-trait-compatibility.stderr index 3a12c7be756d2..e34d855a9d4f9 100644 --- a/tests/ui/parser/dyn-trait-compatibility.stderr +++ b/tests/ui/parser/dyn-trait-compatibility.stderr @@ -1,40 +1,40 @@ -error[E0412]: cannot find type `dyn` +error[E0412]: cannot find type `dyn` in this scope --> $DIR/dyn-trait-compatibility.rs:1:11 | LL | type A0 = dyn; | ^^^ not found in this scope -error[E0412]: cannot find type `dyn` +error[E0412]: cannot find type `dyn` in this scope --> $DIR/dyn-trait-compatibility.rs:5:11 | LL | type A2 = dyn; | ^^^ not found in this scope -error[E0412]: cannot find type `dyn` +error[E0412]: cannot find type `dyn` in this scope --> $DIR/dyn-trait-compatibility.rs:5:15 | LL | type A2 = dyn; | ^^^ not found in this scope -error[E0412]: cannot find type `dyn` +error[E0412]: cannot find type `dyn` in this scope --> $DIR/dyn-trait-compatibility.rs:5:20 | LL | type A2 = dyn; | ^^^ not found in this scope -error[E0412]: cannot find type `dyn` +error[E0412]: cannot find type `dyn` in this scope --> $DIR/dyn-trait-compatibility.rs:9:11 | LL | type A3 = dyn<::dyn>; | ^^^ not found in this scope -error[E0405]: cannot find trait `dyn` +error[E0405]: cannot find trait `dyn` in this scope --> $DIR/dyn-trait-compatibility.rs:9:23 | LL | type A3 = dyn<::dyn>; | ^^^ not found in this scope -error[E0412]: cannot find type `dyn` +error[E0412]: cannot find type `dyn` in this scope --> $DIR/dyn-trait-compatibility.rs:9:16 | LL | type A3 = dyn<::dyn>; diff --git a/tests/ui/parser/emoji-identifiers.stderr b/tests/ui/parser/emoji-identifiers.stderr index ab66692bcf64e..536afc53f0ceb 100644 --- a/tests/ui/parser/emoji-identifiers.stderr +++ b/tests/ui/parser/emoji-identifiers.stderr @@ -83,7 +83,7 @@ help: there is an associated function `full_of_✨` with a similar name LL | 👀::full_of_✨() | ~~~~~~~~~~ -error[E0425]: cannot find function `i_like_to_😄_a_lot` +error[E0425]: cannot find function `i_like_to_😄_a_lot` in this scope --> $DIR/emoji-identifiers.rs:13:13 | LL | fn i_like_to_😅_a_lot() -> 👀 { diff --git a/tests/ui/parser/fn-field-parse-error-ice.stderr b/tests/ui/parser/fn-field-parse-error-ice.stderr index 8c3903afd6ab6..3bf68e8cc04fe 100644 --- a/tests/ui/parser/fn-field-parse-error-ice.stderr +++ b/tests/ui/parser/fn-field-parse-error-ice.stderr @@ -17,7 +17,7 @@ help: escape `fn` to use it as an identifier LL | inner : dyn r#fn () | ++ -error[E0412]: cannot find type `dyn` +error[E0412]: cannot find type `dyn` in this scope --> $DIR/fn-field-parse-error-ice.rs:4:13 | LL | inner : dyn fn () diff --git a/tests/ui/parser/issues/issue-103143.stderr b/tests/ui/parser/issues/issue-103143.stderr index c59dd3240796b..4035c69afa712 100644 --- a/tests/ui/parser/issues/issue-103143.stderr +++ b/tests/ui/parser/issues/issue-103143.stderr @@ -9,7 +9,7 @@ help: expressions must be enclosed in braces to be used as const generic argumen LL | x::<#[a]{ y:: }> | + + -error[E0425]: cannot find value `x` +error[E0425]: cannot find value `x` in this scope --> $DIR/issue-103143.rs:2:5 | LL | x::<#[a]y::> diff --git a/tests/ui/parser/issues/issue-103748-ICE-wrong-braces.rs b/tests/ui/parser/issues/issue-103748-ICE-wrong-braces.rs index 5e5c1cfa59ece..88df8d77c9cb9 100644 --- a/tests/ui/parser/issues/issue-103748-ICE-wrong-braces.rs +++ b/tests/ui/parser/issues/issue-103748-ICE-wrong-braces.rs @@ -3,6 +3,6 @@ struct Apple((Apple, Option(Banana ? Citron))); //~^ ERROR invalid `?` in type //~| ERROR expected one of `)` or `,`, found `Citron` -//~| ERROR cannot find type `Citron` [E0412] +//~| ERROR cannot find type `Citron` //~| ERROR parenthesized type parameters may only be used with a `Fn` trait [E0214] //~| ERROR `Apple` has infinite size diff --git a/tests/ui/parser/issues/issue-103748-ICE-wrong-braces.stderr b/tests/ui/parser/issues/issue-103748-ICE-wrong-braces.stderr index 63b07f26dda1e..b0d8b03ae08c3 100644 --- a/tests/ui/parser/issues/issue-103748-ICE-wrong-braces.stderr +++ b/tests/ui/parser/issues/issue-103748-ICE-wrong-braces.stderr @@ -17,7 +17,7 @@ LL | struct Apple((Apple, Option(Banana ? Citron))); | | | help: missing `,` -error[E0412]: cannot find type `Citron` +error[E0412]: cannot find type `Citron` in this scope --> $DIR/issue-103748-ICE-wrong-braces.rs:3:38 | LL | struct Apple((Apple, Option(Banana ? Citron))); diff --git a/tests/ui/parser/issues/issue-112458.stderr b/tests/ui/parser/issues/issue-112458.stderr index 05d0e18470f25..54a8f1d03b02a 100644 --- a/tests/ui/parser/issues/issue-112458.stderr +++ b/tests/ui/parser/issues/issue-112458.stderr @@ -4,7 +4,7 @@ error: unexpected token: `)` LL | println!("{}", x.); | ^ -error[E0425]: cannot find value `x` +error[E0425]: cannot find value `x` in this scope --> $DIR/issue-112458.rs:2:20 | LL | println!("{}", x.); diff --git a/tests/ui/parser/issues/issue-118531-ice.stderr b/tests/ui/parser/issues/issue-118531-ice.stderr index ca5638a2c99b4..adf883274ecb6 100644 --- a/tests/ui/parser/issues/issue-118531-ice.stderr +++ b/tests/ui/parser/issues/issue-118531-ice.stderr @@ -28,7 +28,7 @@ LL | #[attr] = help: add `#![feature(stmt_expr_attributes)]` 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: cannot find attribute `attr` +error: cannot find attribute `attr` in this scope --> $DIR/issue-118531-ice.rs:5:7 | LL | #[attr] diff --git a/tests/ui/parser/issues/issue-32505.stderr b/tests/ui/parser/issues/issue-32505.stderr index 6e2065dbce7ba..0eaa5efd525fc 100644 --- a/tests/ui/parser/issues/issue-32505.stderr +++ b/tests/ui/parser/issues/issue-32505.stderr @@ -11,7 +11,7 @@ help: you might have meant to open the body of the closure LL | foo(|_| {}) | ++ -error[E0425]: cannot find function `foo` +error[E0425]: cannot find function `foo` in this scope --> $DIR/issue-32505.rs:2:5 | LL | foo(|_|) diff --git a/tests/ui/parser/issues/issue-65122-mac-invoc-in-mut-patterns.stderr b/tests/ui/parser/issues/issue-65122-mac-invoc-in-mut-patterns.stderr index 3c2a57c3c57f6..908b4f75833e1 100644 --- a/tests/ui/parser/issues/issue-65122-mac-invoc-in-mut-patterns.stderr +++ b/tests/ui/parser/issues/issue-65122-mac-invoc-in-mut-patterns.stderr @@ -33,13 +33,13 @@ LL | mac2! { does_not_exist!() } = note: `mut` may be followed by `variable` and `variable @ pattern` = note: this error originates in the macro `mac2` (in Nightly builds, run with -Z macro-backtrace for more info) -error: cannot find macro `does_not_exist` +error: cannot find macro `does_not_exist` in this scope --> $DIR/issue-65122-mac-invoc-in-mut-patterns.rs:22:13 | LL | mac2! { does_not_exist!() } | ^^^^^^^^^^^^^^ not found in this scope -error: cannot find macro `does_not_exist` +error: cannot find macro `does_not_exist` in this scope --> $DIR/issue-65122-mac-invoc-in-mut-patterns.rs:20:13 | LL | mac1! { does_not_exist!() } diff --git a/tests/ui/parser/kw-in-trait-bounds.stderr b/tests/ui/parser/kw-in-trait-bounds.stderr index 5527d4f3c8bcf..3c54e03195031 100644 --- a/tests/ui/parser/kw-in-trait-bounds.stderr +++ b/tests/ui/parser/kw-in-trait-bounds.stderr @@ -86,7 +86,7 @@ help: escape `struct` to use it as an identifier LL | B: r#struct, | ++ -error[E0405]: cannot find trait `r#struct` +error[E0405]: cannot find trait `r#struct` in this scope --> $DIR/kw-in-trait-bounds.rs:16:10 | LL | fn _g(_: impl struct, _: &dyn struct) @@ -95,7 +95,7 @@ LL | fn _g(_: impl struct, _: &dyn struct) LL | trait Struct {} | ------------ similarly named trait `Struct` defined here -error[E0405]: cannot find trait `r#struct` +error[E0405]: cannot find trait `r#struct` in this scope --> $DIR/kw-in-trait-bounds.rs:30:8 | LL | B: struct, @@ -104,7 +104,7 @@ LL | B: struct, LL | trait Struct {} | ------------ similarly named trait `Struct` defined here -error[E0405]: cannot find trait `r#struct` +error[E0405]: cannot find trait `r#struct` in this scope --> $DIR/kw-in-trait-bounds.rs:16:29 | LL | fn _g(_: impl struct, _: &dyn struct) @@ -113,7 +113,7 @@ LL | fn _g(_: impl struct, _: &dyn struct) LL | trait Struct {} | ------------ similarly named trait `Struct` defined here -error[E0405]: cannot find trait `r#struct` +error[E0405]: cannot find trait `r#struct` in this scope --> $DIR/kw-in-trait-bounds.rs:16:45 | LL | fn _g(_: impl struct, _: &dyn struct) diff --git a/tests/ui/parser/multibyte-char-use-seperator-issue-80134.stderr b/tests/ui/parser/multibyte-char-use-seperator-issue-80134.stderr index 518707fecbf40..21e71aa121560 100644 --- a/tests/ui/parser/multibyte-char-use-seperator-issue-80134.stderr +++ b/tests/ui/parser/multibyte-char-use-seperator-issue-80134.stderr @@ -16,13 +16,13 @@ LL | (()氷); | expected one of `)`, `,`, `.`, `?`, or an operator | help: missing `,` -error[E0425]: cannot find value `é` +error[E0425]: cannot find value `é` in this scope --> $DIR/multibyte-char-use-seperator-issue-80134.rs:4:8 | LL | (()é); | ^ not found in this scope -error[E0425]: cannot find value `氷` +error[E0425]: cannot find value `氷` in this scope --> $DIR/multibyte-char-use-seperator-issue-80134.rs:7:8 | LL | (()氷); diff --git a/tests/ui/parser/not-a-pred.rs b/tests/ui/parser/not-a-pred.rs index 09c6778f14c8b..15cb1c805ede4 100644 --- a/tests/ui/parser/not-a-pred.rs +++ b/tests/ui/parser/not-a-pred.rs @@ -10,6 +10,6 @@ fn main() { let a: isize = 10; let b: isize = 23; check (lt(a, b)); - //~^ ERROR cannot find function `check` [E0425] + //~^ ERROR cannot find function `check` f(a, b); } diff --git a/tests/ui/parser/not-a-pred.stderr b/tests/ui/parser/not-a-pred.stderr index fb27131f0f70b..bcc64a687fd0c 100644 --- a/tests/ui/parser/not-a-pred.stderr +++ b/tests/ui/parser/not-a-pred.stderr @@ -22,7 +22,7 @@ error[E0573]: expected type, found local variable `b` LL | fn f(a: isize, b: isize) : lt(a, b) { } | ^ not a type -error[E0425]: cannot find function `check` +error[E0425]: cannot find function `check` in this scope --> $DIR/not-a-pred.rs:12:5 | LL | check (lt(a, b)); diff --git a/tests/ui/parser/pat-lt-bracket-5.stderr b/tests/ui/parser/pat-lt-bracket-5.stderr index 6331a1602a5b8..18cf2df028216 100644 --- a/tests/ui/parser/pat-lt-bracket-5.stderr +++ b/tests/ui/parser/pat-lt-bracket-5.stderr @@ -4,7 +4,7 @@ error: expected a pattern, found an expression LL | let v[0] = v[1]; | ^^^^ arbitrary expressions are not allowed in patterns -error[E0425]: cannot find value `v` +error[E0425]: cannot find value `v` in this scope --> $DIR/pat-lt-bracket-5.rs:2:16 | LL | let v[0] = v[1]; diff --git a/tests/ui/parser/raw/raw-literal-keywords.stderr b/tests/ui/parser/raw/raw-literal-keywords.stderr index 718b3016ce87b..f7b6c894a90fe 100644 --- a/tests/ui/parser/raw/raw-literal-keywords.stderr +++ b/tests/ui/parser/raw/raw-literal-keywords.stderr @@ -16,19 +16,19 @@ error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found LL | r#union Test; | ^^^^ expected one of 8 possible tokens -error[E0425]: cannot find value `r#if` +error[E0425]: cannot find value `r#if` in this scope --> $DIR/raw-literal-keywords.rs:14:13 | LL | let _ = r#if; | ^^^^ not found in this scope -error[E0425]: cannot find value `r#struct` +error[E0425]: cannot find value `r#struct` in this scope --> $DIR/raw-literal-keywords.rs:18:13 | LL | let _ = r#struct; | ^^^^^^^^ not found in this scope -error[E0425]: cannot find value `union` +error[E0425]: cannot find value `union` in this scope --> $DIR/raw-literal-keywords.rs:22:13 | LL | let _ = r#union; diff --git a/tests/ui/parser/recover/recover-fn-ptr-with-generics.stderr b/tests/ui/parser/recover/recover-fn-ptr-with-generics.stderr index 8156185828786..6b6cb2d6bdde7 100644 --- a/tests/ui/parser/recover/recover-fn-ptr-with-generics.stderr +++ b/tests/ui/parser/recover/recover-fn-ptr-with-generics.stderr @@ -88,13 +88,13 @@ error: expected identifier, found `>` LL | type QuiteBroken = fn(); | ^ expected identifier -error[E0412]: cannot find type `T` +error[E0412]: cannot find type `T` in this scope --> $DIR/recover-fn-ptr-with-generics.rs:5:27 | LL | type Identity = fn(T) -> T; | ^ not found in this scope -error[E0412]: cannot find type `T` +error[E0412]: cannot find type `T` in this scope --> $DIR/recover-fn-ptr-with-generics.rs:5:33 | LL | type Identity = fn(T) -> T; diff --git a/tests/ui/parser/recover/recover-ref-dyn-mut.rs b/tests/ui/parser/recover/recover-ref-dyn-mut.rs index e9067c3fe3662..820b6d1ef9631 100644 --- a/tests/ui/parser/recover/recover-ref-dyn-mut.rs +++ b/tests/ui/parser/recover/recover-ref-dyn-mut.rs @@ -5,5 +5,5 @@ fn main() { let r: &dyn mut Trait; //~^ ERROR: `mut` must precede `dyn` //~| HELP: place `mut` before `dyn` - //~| ERROR: cannot find trait `Trait` [E0405] + //~| ERROR: cannot find trait `Trait` } diff --git a/tests/ui/parser/recover/recover-ref-dyn-mut.stderr b/tests/ui/parser/recover/recover-ref-dyn-mut.stderr index 378b69a08c2f1..c048c8ea1b0dd 100644 --- a/tests/ui/parser/recover/recover-ref-dyn-mut.stderr +++ b/tests/ui/parser/recover/recover-ref-dyn-mut.stderr @@ -4,7 +4,7 @@ error: `mut` must precede `dyn` LL | let r: &dyn mut Trait; | ^^^^^^^^ help: place `mut` before `dyn`: `&mut dyn` -error[E0405]: cannot find trait `Trait` +error[E0405]: cannot find trait `Trait` in this scope --> $DIR/recover-ref-dyn-mut.rs:5:21 | LL | let r: &dyn mut Trait; diff --git a/tests/ui/parser/recover/recover-unticked-labels.stderr b/tests/ui/parser/recover/recover-unticked-labels.stderr index 6314c19fe7d72..fbd108ca613c7 100644 --- a/tests/ui/parser/recover/recover-unticked-labels.stderr +++ b/tests/ui/parser/recover/recover-unticked-labels.stderr @@ -14,7 +14,7 @@ LL | 'label: loop { continue label }; | | | help: labels start with a tick -error[E0425]: cannot find value `label` +error[E0425]: cannot find value `label` in this scope --> $DIR/recover-unticked-labels.rs:4:26 | LL | 'label: loop { break label }; diff --git a/tests/ui/parser/trailing-question-in-macro-type.stderr b/tests/ui/parser/trailing-question-in-macro-type.stderr index 361014b7c3d16..e3d33bf251d66 100644 --- a/tests/ui/parser/trailing-question-in-macro-type.stderr +++ b/tests/ui/parser/trailing-question-in-macro-type.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `o` +error[E0425]: cannot find value `o` in this scope --> $DIR/trailing-question-in-macro-type.rs:12:15 | LL | fn_expr!{ o?.when(|&i| i > 0)?.when(|&i| i%2 == 0) }; diff --git a/tests/ui/parser/unmatched-langle-1.rs b/tests/ui/parser/unmatched-langle-1.rs index 16dc8943023fe..489b20dd7b4e6 100644 --- a/tests/ui/parser/unmatched-langle-1.rs +++ b/tests/ui/parser/unmatched-langle-1.rs @@ -4,6 +4,6 @@ fn main() { foo::<<<>(); //~^ ERROR: unmatched angle brackets - //~| ERROR: cannot find function `foo` [E0425] - //~| ERROR: cannot find type `Ty` [E0412] + //~| ERROR: cannot find function `foo` + //~| ERROR: cannot find type `Ty` } diff --git a/tests/ui/parser/unmatched-langle-1.stderr b/tests/ui/parser/unmatched-langle-1.stderr index 45edd1bd60491..cdf74bdedc2e1 100644 --- a/tests/ui/parser/unmatched-langle-1.stderr +++ b/tests/ui/parser/unmatched-langle-1.stderr @@ -4,13 +4,13 @@ error: unmatched angle brackets LL | foo::<<<>(); | ^^^ help: remove extra angle brackets -error[E0412]: cannot find type `Ty` +error[E0412]: cannot find type `Ty` in this scope --> $DIR/unmatched-langle-1.rs:5:14 | LL | foo::<<<>(); | ^^ not found in this scope -error[E0425]: cannot find function `foo` +error[E0425]: cannot find function `foo` in this scope --> $DIR/unmatched-langle-1.rs:5:5 | LL | foo::<<<>(); diff --git a/tests/ui/parser/where_with_bound.stderr b/tests/ui/parser/where_with_bound.stderr index 73b7a5b3d60f9..ff98b3f5fed61 100644 --- a/tests/ui/parser/where_with_bound.stderr +++ b/tests/ui/parser/where_with_bound.stderr @@ -4,7 +4,7 @@ error: generic parameters on `where` clauses are reserved for future use LL | fn foo() where ::Item: ToString, T: Iterator { } | ^^^ currently unsupported -error[E0412]: cannot find type `Item` +error[E0412]: cannot find type `Item` in the crate root --> $DIR/where_with_bound.rs:1:24 | LL | fn foo() where ::Item: ToString, T: Iterator { } diff --git a/tests/ui/pattern/range-pattern-meant-to-be-slice-rest-pattern.stderr b/tests/ui/pattern/range-pattern-meant-to-be-slice-rest-pattern.stderr index 283babbbef6fd..37c02eb6ada9c 100644 --- a/tests/ui/pattern/range-pattern-meant-to-be-slice-rest-pattern.stderr +++ b/tests/ui/pattern/range-pattern-meant-to-be-slice-rest-pattern.stderr @@ -4,7 +4,7 @@ error: range-to patterns with `...` are not allowed LL | [_, ...tail] => println!("{tail}"), | ^^^ help: use `..=` instead -error[E0425]: cannot find value `rest` +error[E0425]: cannot find value `rest` in this scope --> $DIR/range-pattern-meant-to-be-slice-rest-pattern.rs:3:13 | LL | [1, rest..] => println!("{rest}"), @@ -15,13 +15,13 @@ help: if you meant to collect the rest of the slice in `rest`, use the at operat LL | [1, rest @ ..] => println!("{rest}"), | + -error[E0425]: cannot find value `rest` +error[E0425]: cannot find value `rest` in this scope --> $DIR/range-pattern-meant-to-be-slice-rest-pattern.rs:3:35 | LL | [1, rest..] => println!("{rest}"), | ^^^^ not found in this scope -error[E0425]: cannot find value `tail` +error[E0425]: cannot find value `tail` in this scope --> $DIR/range-pattern-meant-to-be-slice-rest-pattern.rs:11:15 | LL | [_, ..tail] => println!("{tail}"), @@ -32,13 +32,13 @@ help: if you meant to collect the rest of the slice in `tail`, use the at operat LL | [_, tail @ ..] => println!("{tail}"), | ~~~~~~~~~ -error[E0425]: cannot find value `tail` +error[E0425]: cannot find value `tail` in this scope --> $DIR/range-pattern-meant-to-be-slice-rest-pattern.rs:11:35 | LL | [_, ..tail] => println!("{tail}"), | ^^^^ not found in this scope -error[E0425]: cannot find value `tail` +error[E0425]: cannot find value `tail` in this scope --> $DIR/range-pattern-meant-to-be-slice-rest-pattern.rs:17:16 | LL | [_, ...tail] => println!("{tail}"), @@ -49,7 +49,7 @@ help: if you meant to collect the rest of the slice in `tail`, use the at operat LL | [_, tail @ ..] => println!("{tail}"), | ~~~~~~~~~ -error[E0425]: cannot find value `tail` +error[E0425]: cannot find value `tail` in this scope --> $DIR/range-pattern-meant-to-be-slice-rest-pattern.rs:17:36 | LL | [_, ...tail] => println!("{tail}"), diff --git a/tests/ui/pattern/usefulness/issue-119493-type-error-ice.stderr b/tests/ui/pattern/usefulness/issue-119493-type-error-ice.stderr index cf827eb569aec..1c560aa2ca813 100644 --- a/tests/ui/pattern/usefulness/issue-119493-type-error-ice.stderr +++ b/tests/ui/pattern/usefulness/issue-119493-type-error-ice.stderr @@ -1,10 +1,10 @@ -error[E0412]: cannot find type `NonExistent` +error[E0412]: cannot find type `NonExistent` in this scope --> $DIR/issue-119493-type-error-ice.rs:5:16 | LL | struct Foo(NonExistent); | ^^^^^^^^^^^ not found in this scope -error[E0412]: cannot find type `NonExistent` +error[E0412]: cannot find type `NonExistent` in this scope --> $DIR/issue-119493-type-error-ice.rs:5:16 | LL | struct Foo(NonExistent); diff --git a/tests/ui/pattern/usefulness/issue-119778-type-error-ice.stderr b/tests/ui/pattern/usefulness/issue-119778-type-error-ice.stderr index affbd6f317ac0..7da384d613efb 100644 --- a/tests/ui/pattern/usefulness/issue-119778-type-error-ice.stderr +++ b/tests/ui/pattern/usefulness/issue-119778-type-error-ice.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `S` +error[E0425]: cannot find value `S` in this scope --> $DIR/issue-119778-type-error-ice.rs:5:21 | LL | struct Foo([u8; S]); @@ -9,7 +9,7 @@ help: you might be missing a const parameter LL | struct Foo([u8; S]); | +++++++++++++++++++++ -error[E0425]: cannot find value `S` +error[E0425]: cannot find value `S` in this scope --> $DIR/issue-119778-type-error-ice.rs:5:21 | LL | struct Foo([u8; S]); diff --git a/tests/ui/privacy/privacy-ns1.stderr b/tests/ui/privacy/privacy-ns1.stderr index 20152f35f81d4..9710cc48637bc 100644 --- a/tests/ui/privacy/privacy-ns1.stderr +++ b/tests/ui/privacy/privacy-ns1.stderr @@ -16,7 +16,7 @@ help: consider importing this function instead LL + use foo2::Bar; | -error[E0425]: cannot find function, tuple struct or tuple variant `Bar` +error[E0425]: cannot find function, tuple struct or tuple variant `Bar` in this scope --> $DIR/privacy-ns1.rs:51:5 | LL | pub struct Baz; @@ -34,7 +34,7 @@ help: consider importing this function LL + use foo2::Bar; | -error[E0412]: cannot find type `Bar` +error[E0412]: cannot find type `Bar` in this scope --> $DIR/privacy-ns1.rs:52:17 | LL | pub struct Baz; diff --git a/tests/ui/proc-macro/ambiguous-builtin-attrs-test.stderr b/tests/ui/proc-macro/ambiguous-builtin-attrs-test.stderr index 80f7e5e37ac2f..346cebf639d17 100644 --- a/tests/ui/proc-macro/ambiguous-builtin-attrs-test.stderr +++ b/tests/ui/proc-macro/ambiguous-builtin-attrs-test.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `NonExistent` +error[E0425]: cannot find value `NonExistent` in this scope --> $DIR/ambiguous-builtin-attrs-test.rs:19:5 | LL | NonExistent; diff --git a/tests/ui/proc-macro/ambiguous-builtin-attrs.stderr b/tests/ui/proc-macro/ambiguous-builtin-attrs.stderr index b4432d50a6410..0f4ddc065a742 100644 --- a/tests/ui/proc-macro/ambiguous-builtin-attrs.stderr +++ b/tests/ui/proc-macro/ambiguous-builtin-attrs.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `NonExistent` +error[E0425]: cannot find value `NonExistent` in this scope --> $DIR/ambiguous-builtin-attrs.rs:34:5 | LL | NonExistent; diff --git a/tests/ui/proc-macro/attributes-on-modules-fail.stderr b/tests/ui/proc-macro/attributes-on-modules-fail.stderr index 8f37ea2915ac3..e69ab78723861 100644 --- a/tests/ui/proc-macro/attributes-on-modules-fail.stderr +++ b/tests/ui/proc-macro/attributes-on-modules-fail.stderr @@ -46,7 +46,7 @@ LL | mod inner; = help: add `#![feature(proc_macro_hygiene)]` 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[E0412]: cannot find type `Y` +error[E0412]: cannot find type `Y` in this scope --> $DIR/attributes-on-modules-fail.rs:10:14 | LL | type A = Y; @@ -57,7 +57,7 @@ help: consider importing this struct LL + use Y; | -error[E0412]: cannot find type `X` +error[E0412]: cannot find type `X` in this scope --> $DIR/attributes-on-modules-fail.rs:14:10 | LL | type A = X; diff --git a/tests/ui/proc-macro/break-token-spans.stderr b/tests/ui/proc-macro/break-token-spans.stderr index 17d2f63ef93ec..e69cc3b8cf598 100644 --- a/tests/ui/proc-macro/break-token-spans.stderr +++ b/tests/ui/proc-macro/break-token-spans.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find function `f` +error[E0425]: cannot find function `f` in this scope --> $DIR/break-token-spans.rs:13:5 | LL | f :: < Vec < _ > > ( ) ; diff --git a/tests/ui/proc-macro/derive-helper-legacy-limits.stderr b/tests/ui/proc-macro/derive-helper-legacy-limits.stderr index c209e1cc0d8c2..28924782ae912 100644 --- a/tests/ui/proc-macro/derive-helper-legacy-limits.stderr +++ b/tests/ui/proc-macro/derive-helper-legacy-limits.stderr @@ -1,4 +1,4 @@ -error: cannot find attribute `empty_helper` +error: cannot find attribute `empty_helper` in this scope --> $DIR/derive-helper-legacy-limits.rs:17:3 | LL | #[empty_helper] diff --git a/tests/ui/proc-macro/derive-helper-legacy-spurious.stderr b/tests/ui/proc-macro/derive-helper-legacy-spurious.stderr index f23eb9aa6256e..4f857573e27d5 100644 --- a/tests/ui/proc-macro/derive-helper-legacy-spurious.stderr +++ b/tests/ui/proc-macro/derive-helper-legacy-spurious.stderr @@ -1,10 +1,10 @@ -error: cannot find attribute `dummy` +error: cannot find attribute `dummy` in this scope --> $DIR/derive-helper-legacy-spurious.rs:3:4 | LL | #![dummy] | ^^^^^ not found in this scope -error: cannot find attribute `empty_helper` +error: cannot find attribute `empty_helper` in this scope --> $DIR/derive-helper-legacy-spurious.rs:9:3 | LL | #[empty_helper] diff --git a/tests/ui/proc-macro/derive-helper-shadowing.stderr b/tests/ui/proc-macro/derive-helper-shadowing.stderr index bf929eef2cb0b..b264348e74297 100644 --- a/tests/ui/proc-macro/derive-helper-shadowing.stderr +++ b/tests/ui/proc-macro/derive-helper-shadowing.stderr @@ -10,7 +10,7 @@ note: the derive helper attribute imported here LL | use empty_helper as renamed; | ^^^^^^^^^^^^^^^^^^^^^^^ -error: cannot find attribute `empty_helper` +error: cannot find attribute `empty_helper` in this scope --> $DIR/derive-helper-shadowing.rs:38:22 | LL | #[derive(GenHelperUse)] @@ -22,7 +22,7 @@ help: consider importing this attribute macro through its public re-export LL + use empty_helper; | -error: cannot find attribute `empty_helper` +error: cannot find attribute `empty_helper` in this scope --> $DIR/derive-helper-shadowing.rs:14:11 | LL | #[empty_helper] diff --git a/tests/ui/proc-macro/derive-still-gated.stderr b/tests/ui/proc-macro/derive-still-gated.stderr index f51cb5073aeba..aa7cb951e1030 100644 --- a/tests/ui/proc-macro/derive-still-gated.stderr +++ b/tests/ui/proc-macro/derive-still-gated.stderr @@ -1,4 +1,4 @@ -error: cannot find attribute `derive_Empty` +error: cannot find attribute `derive_Empty` in this scope --> $DIR/derive-still-gated.rs:6:3 | LL | #[derive_Empty] diff --git a/tests/ui/proc-macro/disappearing-resolution.stderr b/tests/ui/proc-macro/disappearing-resolution.stderr index 25c5ccdd57b8d..c5a217d8e5bc3 100644 --- a/tests/ui/proc-macro/disappearing-resolution.stderr +++ b/tests/ui/proc-macro/disappearing-resolution.stderr @@ -1,4 +1,4 @@ -error: cannot find attribute `empty_helper` +error: cannot find attribute `empty_helper` in this scope --> $DIR/disappearing-resolution.rs:18:3 | LL | #[empty_helper] diff --git a/tests/ui/proc-macro/empty-where-clause.stderr b/tests/ui/proc-macro/empty-where-clause.stderr index 8ef47abcd2e8b..192a2b30f0dcd 100644 --- a/tests/ui/proc-macro/empty-where-clause.stderr +++ b/tests/ui/proc-macro/empty-where-clause.stderr @@ -1,16 +1,16 @@ -error[E0412]: cannot find type `MissingType1` +error[E0412]: cannot find type `MissingType1` in this scope --> $DIR/empty-where-clause.rs:8:12 | LL | field: MissingType1 | ^^^^^^^^^^^^ not found in this scope -error[E0412]: cannot find type `MissingType2` +error[E0412]: cannot find type `MissingType2` in this scope --> $DIR/empty-where-clause.rs:12:20 | LL | struct TupleStruct(MissingType2) where; | ^^^^^^^^^^^^ not found in this scope -error[E0412]: cannot find type `MissingType3` +error[E0412]: cannot find type `MissingType3` in this scope --> $DIR/empty-where-clause.rs:15:13 | LL | Variant(MissingType3) diff --git a/tests/ui/proc-macro/gen-macro-rules-hygiene.stderr b/tests/ui/proc-macro/gen-macro-rules-hygiene.stderr index ac16658ebca2b..df7c4f72eb0b6 100644 --- a/tests/ui/proc-macro/gen-macro-rules-hygiene.stderr +++ b/tests/ui/proc-macro/gen-macro-rules-hygiene.stderr @@ -9,7 +9,7 @@ LL | generated!(); | = note: this error originates in the macro `generated` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0425]: cannot find value `local_use` +error[E0425]: cannot find value `local_use` in this scope --> $DIR/gen-macro-rules-hygiene.rs:12:1 | LL | gen_macro_rules!(); @@ -20,7 +20,7 @@ LL | generated!(); | = note: this error originates in the macro `generated` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0425]: cannot find value `local_def` +error[E0425]: cannot find value `local_def` in this scope --> $DIR/gen-macro-rules-hygiene.rs:21:9 | LL | local_def; diff --git a/tests/ui/proc-macro/generate-mod.stderr b/tests/ui/proc-macro/generate-mod.stderr index fac7d422f7305..cbe6b14ca9af5 100644 --- a/tests/ui/proc-macro/generate-mod.stderr +++ b/tests/ui/proc-macro/generate-mod.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `FromOutside` +error[E0412]: cannot find type `FromOutside` in this scope --> $DIR/generate-mod.rs:9:1 | LL | generate_mod::check!(); @@ -8,7 +8,7 @@ LL | generate_mod::check!(); FromOutside = note: this error originates in the macro `generate_mod::check` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0412]: cannot find type `Outer` +error[E0412]: cannot find type `Outer` in this scope --> $DIR/generate-mod.rs:9:1 | LL | generate_mod::check!(); @@ -18,7 +18,7 @@ LL | generate_mod::check!(); Outer = note: this error originates in the macro `generate_mod::check` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0412]: cannot find type `FromOutside` +error[E0412]: cannot find type `FromOutside` in this scope --> $DIR/generate-mod.rs:12:1 | LL | #[generate_mod::check_attr] @@ -28,7 +28,7 @@ LL | #[generate_mod::check_attr] FromOutside = note: this error originates in the attribute macro `generate_mod::check_attr` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0412]: cannot find type `OuterAttr` +error[E0412]: cannot find type `OuterAttr` in this scope --> $DIR/generate-mod.rs:12:1 | LL | #[generate_mod::check_attr] @@ -38,7 +38,7 @@ LL | #[generate_mod::check_attr] OuterAttr = note: this error originates in the attribute macro `generate_mod::check_attr` (in Nightly builds, run with -Z macro-backtrace for more info) -error: cannot find type `FromOutside` +error: cannot find type `FromOutside` in this scope --> $DIR/generate-mod.rs:16:10 | LL | #[derive(generate_mod::CheckDerive)] @@ -49,7 +49,7 @@ LL | #[derive(generate_mod::CheckDerive)] = note: `#[deny(proc_macro_derive_resolution_fallback)]` on by default = note: this error originates in the derive macro `generate_mod::CheckDerive` (in Nightly builds, run with -Z macro-backtrace for more info) -error: cannot find type `OuterDerive` +error: cannot find type `OuterDerive` in this scope --> $DIR/generate-mod.rs:16:10 | LL | #[derive(generate_mod::CheckDerive)] @@ -59,7 +59,7 @@ LL | #[derive(generate_mod::CheckDerive)] = note: for more information, see issue #83583 = note: this error originates in the derive macro `generate_mod::CheckDerive` (in Nightly builds, run with -Z macro-backtrace for more info) -error: cannot find type `FromOutside` +error: cannot find type `FromOutside` in this scope --> $DIR/generate-mod.rs:23:14 | LL | #[derive(generate_mod::CheckDerive)] @@ -69,7 +69,7 @@ LL | #[derive(generate_mod::CheckDerive)] = note: for more information, see issue #83583 = note: this error originates in the derive macro `generate_mod::CheckDerive` (in Nightly builds, run with -Z macro-backtrace for more info) -error: cannot find type `OuterDerive` +error: cannot find type `OuterDerive` in this scope --> $DIR/generate-mod.rs:23:14 | LL | #[derive(generate_mod::CheckDerive)] @@ -83,7 +83,7 @@ error: aborting due to 8 previous errors For more information about this error, try `rustc --explain E0412`. Future incompatibility report: Future breakage diagnostic: -error: cannot find type `FromOutside` +error: cannot find type `FromOutside` in this scope --> $DIR/generate-mod.rs:16:10 | LL | #[derive(generate_mod::CheckDerive)] @@ -95,7 +95,7 @@ LL | #[derive(generate_mod::CheckDerive)] = note: this error originates in the derive macro `generate_mod::CheckDerive` (in Nightly builds, run with -Z macro-backtrace for more info) Future breakage diagnostic: -error: cannot find type `OuterDerive` +error: cannot find type `OuterDerive` in this scope --> $DIR/generate-mod.rs:16:10 | LL | #[derive(generate_mod::CheckDerive)] @@ -107,7 +107,7 @@ LL | #[derive(generate_mod::CheckDerive)] = note: this error originates in the derive macro `generate_mod::CheckDerive` (in Nightly builds, run with -Z macro-backtrace for more info) Future breakage diagnostic: -error: cannot find type `FromOutside` +error: cannot find type `FromOutside` in this scope --> $DIR/generate-mod.rs:23:14 | LL | #[derive(generate_mod::CheckDerive)] @@ -119,7 +119,7 @@ LL | #[derive(generate_mod::CheckDerive)] = note: this error originates in the derive macro `generate_mod::CheckDerive` (in Nightly builds, run with -Z macro-backtrace for more info) Future breakage diagnostic: -error: cannot find type `OuterDerive` +error: cannot find type `OuterDerive` in this scope --> $DIR/generate-mod.rs:23:14 | LL | #[derive(generate_mod::CheckDerive)] @@ -131,7 +131,7 @@ LL | #[derive(generate_mod::CheckDerive)] = note: this error originates in the derive macro `generate_mod::CheckDerive` (in Nightly builds, run with -Z macro-backtrace for more info) Future breakage diagnostic: -warning: cannot find type `FromOutside` +warning: cannot find type `FromOutside` in this scope --> $DIR/generate-mod.rs:30:10 | LL | #[derive(generate_mod::CheckDeriveLint)] // OK, lint is suppressed @@ -142,7 +142,7 @@ LL | #[derive(generate_mod::CheckDeriveLint)] // OK, lint is suppressed = note: this warning originates in the derive macro `generate_mod::CheckDeriveLint` (in Nightly builds, run with -Z macro-backtrace for more info) Future breakage diagnostic: -warning: cannot find type `OuterDeriveLint` +warning: cannot find type `OuterDeriveLint` in this scope --> $DIR/generate-mod.rs:30:10 | LL | #[derive(generate_mod::CheckDeriveLint)] // OK, lint is suppressed diff --git a/tests/ui/proc-macro/issue-118455-skip-err-builtin.stderr b/tests/ui/proc-macro/issue-118455-skip-err-builtin.stderr index ebaa407daaf2f..0f4310e8e9db1 100644 --- a/tests/ui/proc-macro/issue-118455-skip-err-builtin.stderr +++ b/tests/ui/proc-macro/issue-118455-skip-err-builtin.stderr @@ -1,4 +1,4 @@ -error: cannot find attribute `some_nonexistent_attribute` +error: cannot find attribute `some_nonexistent_attribute` in this scope --> $DIR/issue-118455-skip-err-builtin.rs:1:4 | LL | #![some_nonexistent_attribute] diff --git a/tests/ui/proc-macro/issue-38586.stderr b/tests/ui/proc-macro/issue-38586.stderr index 9c448ce569d06..0049155645078 100644 --- a/tests/ui/proc-macro/issue-38586.stderr +++ b/tests/ui/proc-macro/issue-38586.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `foo` +error[E0425]: cannot find value `foo` in this scope --> $DIR/issue-38586.rs:6:10 | LL | #[derive(A)] diff --git a/tests/ui/proc-macro/issue-83510.stderr b/tests/ui/proc-macro/issue-83510.stderr index ca748dfca857c..e59b77af3dc39 100644 --- a/tests/ui/proc-macro/issue-83510.stderr +++ b/tests/ui/proc-macro/issue-83510.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `Foo` +error[E0412]: cannot find type `Foo` in this scope --> $DIR/issue-83510.rs:5:1 | LL | issue_83510::dance_like_you_want_to_ice!(); @@ -14,7 +14,7 @@ LL | issue_83510::dance_like_you_want_to_ice!(); | = note: this error originates in the macro `issue_83510::dance_like_you_want_to_ice` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0405]: cannot find trait `Baz` +error[E0405]: cannot find trait `Baz` in this scope --> $DIR/issue-83510.rs:5:1 | LL | issue_83510::dance_like_you_want_to_ice!(); diff --git a/tests/ui/proc-macro/keep-expr-tokens.stderr b/tests/ui/proc-macro/keep-expr-tokens.stderr index d67799de8222a..1a1f83cc1569b 100644 --- a/tests/ui/proc-macro/keep-expr-tokens.stderr +++ b/tests/ui/proc-macro/keep-expr-tokens.stderr @@ -1,10 +1,10 @@ -error[E0425]: cannot find value `bad` +error[E0425]: cannot find value `bad` in this scope --> $DIR/keep-expr-tokens.rs:19:62 | LL | (#[recollect_attr] #[recollect_attr] ((#[recollect_attr] bad))); | ^^^ not found in this scope -error[E0425]: cannot find function `missing_fn` +error[E0425]: cannot find function `missing_fn` in this scope --> $DIR/keep-expr-tokens.rs:17:17 | LL | for item in missing_fn() {} diff --git a/tests/ui/proc-macro/lints_in_proc_macros.stderr b/tests/ui/proc-macro/lints_in_proc_macros.stderr index fba9f32e3f622..244d218608be7 100644 --- a/tests/ui/proc-macro/lints_in_proc_macros.stderr +++ b/tests/ui/proc-macro/lints_in_proc_macros.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `foobar2` +error[E0425]: cannot find value `foobar2` in this scope --> $DIR/lints_in_proc_macros.rs:9:5 | LL | bang_proc_macro2!(); diff --git a/tests/ui/proc-macro/macro-namespace-reserved-2.stderr b/tests/ui/proc-macro/macro-namespace-reserved-2.stderr index 5a05d44e3b97b..2f8451cbfb35b 100644 --- a/tests/ui/proc-macro/macro-namespace-reserved-2.stderr +++ b/tests/ui/proc-macro/macro-namespace-reserved-2.stderr @@ -104,7 +104,7 @@ LL | #[derive(crate::my_macro)] = help: add as non-Derive macro `#[crate::my_macro]` -error: cannot find macro `my_macro_attr` +error: cannot find macro `my_macro_attr` in this scope --> $DIR/macro-namespace-reserved-2.rs:28:5 | LL | my_macro_attr!(); @@ -112,7 +112,7 @@ LL | my_macro_attr!(); | = note: `my_macro_attr` is in scope, but it is an attribute: `#[my_macro_attr]` -error: cannot find macro `MyTrait` +error: cannot find macro `MyTrait` in this scope --> $DIR/macro-namespace-reserved-2.rs:33:5 | LL | MyTrait!(); @@ -120,7 +120,7 @@ LL | MyTrait!(); | = note: `MyTrait` is in scope, but it is a derive macro: `#[derive(MyTrait)]` -error: cannot find attribute `my_macro` +error: cannot find attribute `my_macro` in this scope --> $DIR/macro-namespace-reserved-2.rs:38:3 | LL | #[my_macro] @@ -128,7 +128,7 @@ LL | #[my_macro] | = note: `my_macro` is in scope, but it is a function-like macro -error: cannot find derive macro `my_macro` +error: cannot find derive macro `my_macro` in this scope --> $DIR/macro-namespace-reserved-2.rs:48:10 | LL | #[derive(my_macro)] @@ -136,7 +136,7 @@ LL | #[derive(my_macro)] | = note: `my_macro` is in scope, but it is a function-like macro -error: cannot find derive macro `my_macro` +error: cannot find derive macro `my_macro` in this scope --> $DIR/macro-namespace-reserved-2.rs:48:10 | LL | #[derive(my_macro)] diff --git a/tests/ui/proc-macro/macro-rules-derive.stderr b/tests/ui/proc-macro/macro-rules-derive.stderr index 6457e84a514cb..e7cd4474618fe 100644 --- a/tests/ui/proc-macro/macro-rules-derive.stderr +++ b/tests/ui/proc-macro/macro-rules-derive.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `MissingType` +error[E0412]: cannot find type `MissingType` in this scope --> $DIR/macro-rules-derive.rs:10:20 | LL | field: MissingType diff --git a/tests/ui/proc-macro/mixed-site-span.stderr b/tests/ui/proc-macro/mixed-site-span.stderr index 3df298a4ec59a..b8c2524cac68a 100644 --- a/tests/ui/proc-macro/mixed-site-span.stderr +++ b/tests/ui/proc-macro/mixed-site-span.stderr @@ -6,7 +6,7 @@ LL | proc_macro_rules!(); | = note: this error originates in the macro `proc_macro_rules` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0425]: cannot find value `local_use` +error[E0425]: cannot find value `local_use` in this scope --> $DIR/mixed-site-span.rs:13:9 | LL | proc_macro_rules!(); @@ -14,13 +14,13 @@ LL | proc_macro_rules!(); | = note: this error originates in the macro `proc_macro_rules` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0425]: cannot find value `local_def` +error[E0425]: cannot find value `local_def` in this scope --> $DIR/mixed-site-span.rs:17:9 | LL | local_def; | ^^^^^^^^^ help: a local variable with a similar name exists: `local_use` -error[E0412]: cannot find type `ItemUse` +error[E0412]: cannot find type `ItemUse` in crate `$crate` --> $DIR/mixed-site-span.rs:24:1 | LL | pass_dollar_crate!(); diff --git a/tests/ui/proc-macro/parent-source-spans.stderr b/tests/ui/proc-macro/parent-source-spans.stderr index b50142bc83bb3..a3b27fd7bcc1b 100644 --- a/tests/ui/proc-macro/parent-source-spans.stderr +++ b/tests/ui/proc-macro/parent-source-spans.stderr @@ -136,7 +136,7 @@ error: second source: "hop" LL | three!("hip", "hop"); | ^^^^^ -error[E0425]: cannot find value `ok` +error[E0425]: cannot find value `ok` in this scope --> $DIR/parent-source-spans.rs:29:5 | LL | parent_source_spans!($($tokens)*); @@ -150,7 +150,7 @@ LL | one!("hello", "world"); | = note: this error originates in the macro `parent_source_spans` which comes from the expansion of the macro `one` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0425]: cannot find value `ok` +error[E0425]: cannot find value `ok` in this scope --> $DIR/parent-source-spans.rs:29:5 | LL | parent_source_spans!($($tokens)*); @@ -164,7 +164,7 @@ LL | two!("yay", "rust"); | = note: this error originates in the macro `parent_source_spans` which comes from the expansion of the macro `two` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0425]: cannot find value `ok` +error[E0425]: cannot find value `ok` in this scope --> $DIR/parent-source-spans.rs:29:5 | LL | parent_source_spans!($($tokens)*); diff --git a/tests/ui/proc-macro/proc-macro-attributes.stderr b/tests/ui/proc-macro/proc-macro-attributes.stderr index 1721f038fadd3..4c2097700f933 100644 --- a/tests/ui/proc-macro/proc-macro-attributes.stderr +++ b/tests/ui/proc-macro/proc-macro-attributes.stderr @@ -1,4 +1,4 @@ -error: cannot find attribute `C` +error: cannot find attribute `C` in this scope --> $DIR/proc-macro-attributes.rs:9:3 | LL | #[C] diff --git a/tests/ui/proc-macro/resolve-error.stderr b/tests/ui/proc-macro/resolve-error.stderr index cf8253664ac8e..56700e4dc4cee 100644 --- a/tests/ui/proc-macro/resolve-error.stderr +++ b/tests/ui/proc-macro/resolve-error.stderr @@ -1,4 +1,4 @@ -error: cannot find macro `bang_proc_macrp` +error: cannot find macro `bang_proc_macrp` in this scope --> $DIR/resolve-error.rs:60:5 | LL | bang_proc_macrp!(); @@ -12,13 +12,13 @@ LL | bang_proc_macrp!(); LL | pub fn empty(_: TokenStream) -> TokenStream { | ------------------------------------------- similarly named macro `bang_proc_macro` defined here -error: cannot find macro `Dlona` +error: cannot find macro `Dlona` in this scope --> $DIR/resolve-error.rs:57:5 | LL | Dlona!(); | ^^^^^ not found in this scope -error: cannot find macro `attr_proc_macra` +error: cannot find macro `attr_proc_macra` in this scope --> $DIR/resolve-error.rs:54:5 | LL | macro_rules! attr_proc_mac { @@ -30,7 +30,7 @@ LL | attr_proc_macra!(); | not found in this scope | help: a macro with a similar name exists: `attr_proc_mac` -error: cannot find macro `FooWithLongNama` +error: cannot find macro `FooWithLongNama` in this scope --> $DIR/resolve-error.rs:51:5 | LL | macro_rules! FooWithLongNam { @@ -42,13 +42,13 @@ LL | FooWithLongNama!(); | not found in this scope | help: a macro with a similar name exists: `FooWithLongNam` -error: cannot find derive macro `attr_proc_macra` +error: cannot find derive macro `attr_proc_macra` in this scope --> $DIR/resolve-error.rs:45:10 | LL | #[derive(attr_proc_macra)] | ^^^^^^^^^^^^^^^ not found in this scope -error: cannot find derive macro `attr_proc_macra` +error: cannot find derive macro `attr_proc_macra` in this scope --> $DIR/resolve-error.rs:45:10 | LL | #[derive(attr_proc_macra)] @@ -56,7 +56,7 @@ LL | #[derive(attr_proc_macra)] | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error: cannot find derive macro `Dlona` +error: cannot find derive macro `Dlona` in this scope --> $DIR/resolve-error.rs:40:10 | LL | #[derive(Dlona)] @@ -70,7 +70,7 @@ LL | #[derive(Dlona)] LL | pub fn derive_clonea(input: TokenStream) -> TokenStream { | ------------------------------------------------------- similarly named derive macro `Clona` defined here -error: cannot find derive macro `Dlona` +error: cannot find derive macro `Dlona` in this scope --> $DIR/resolve-error.rs:40:10 | LL | #[derive(Dlona)] @@ -86,7 +86,7 @@ LL | pub fn derive_clonea(input: TokenStream) -> TokenStream { | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error: cannot find derive macro `Dlone` +error: cannot find derive macro `Dlone` in this scope --> $DIR/resolve-error.rs:35:10 | LL | #[derive(Dlone)] @@ -98,7 +98,7 @@ LL | #[derive(Dlone)] | = note: similarly named derive macro `Clone` defined here -error: cannot find derive macro `Dlone` +error: cannot find derive macro `Dlone` in this scope --> $DIR/resolve-error.rs:35:10 | LL | #[derive(Dlone)] @@ -112,13 +112,13 @@ LL | #[derive(Dlone)] | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error: cannot find attribute `FooWithLongNan` +error: cannot find attribute `FooWithLongNan` in this scope --> $DIR/resolve-error.rs:32:3 | LL | #[FooWithLongNan] | ^^^^^^^^^^^^^^ not found in this scope -error: cannot find attribute `attr_proc_macra` +error: cannot find attribute `attr_proc_macra` in this scope --> $DIR/resolve-error.rs:28:3 | LL | #[attr_proc_macra] @@ -132,7 +132,7 @@ LL | #[attr_proc_macra] LL | pub fn empty_attr(_: TokenStream, _: TokenStream) -> TokenStream { | ---------------------------------------------------------------- similarly named attribute macro `attr_proc_macro` defined here -error: cannot find derive macro `FooWithLongNan` +error: cannot find derive macro `FooWithLongNan` in this scope --> $DIR/resolve-error.rs:22:10 | LL | #[derive(FooWithLongNan)] @@ -146,7 +146,7 @@ LL | #[derive(FooWithLongNan)] LL | pub fn derive_foo(input: TokenStream) -> TokenStream { | ---------------------------------------------------- similarly named derive macro `FooWithLongName` defined here -error: cannot find derive macro `FooWithLongNan` +error: cannot find derive macro `FooWithLongNan` in this scope --> $DIR/resolve-error.rs:22:10 | LL | #[derive(FooWithLongNan)] diff --git a/tests/ui/proc-macro/span-from-proc-macro.stderr b/tests/ui/proc-macro/span-from-proc-macro.stderr index 43af9280a8132..7beed505a7efa 100644 --- a/tests/ui/proc-macro/span-from-proc-macro.stderr +++ b/tests/ui/proc-macro/span-from-proc-macro.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `MissingType` +error[E0412]: cannot find type `MissingType` in this scope --> $DIR/auxiliary/span-from-proc-macro.rs:37:20 | LL | pub fn error_from_attribute(_args: TokenStream, _input: TokenStream) -> TokenStream { @@ -12,7 +12,7 @@ LL | field: MissingType LL | #[error_from_attribute] | ----------------------- in this procedural macro expansion -error[E0412]: cannot find type `OtherMissingType` +error[E0412]: cannot find type `OtherMissingType` in this scope --> $DIR/auxiliary/span-from-proc-macro.rs:46:21 | LL | pub fn error_from_derive(_input: TokenStream) -> TokenStream { @@ -26,7 +26,7 @@ LL | Variant(OtherMissingType) LL | #[derive(ErrorFromDerive)] | --------------- in this derive macro expansion -error[E0425]: cannot find value `my_ident` +error[E0425]: cannot find value `my_ident` in this scope --> $DIR/auxiliary/span-from-proc-macro.rs:29:9 | LL | pub fn other_error_from_bang(_input: TokenStream) -> TokenStream { diff --git a/tests/ui/proc-macro/weird-hygiene.stderr b/tests/ui/proc-macro/weird-hygiene.stderr index d5d693b264b42..256e68e8970e6 100644 --- a/tests/ui/proc-macro/weird-hygiene.stderr +++ b/tests/ui/proc-macro/weird-hygiene.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `hidden_ident` +error[E0425]: cannot find value `hidden_ident` in this scope --> $DIR/weird-hygiene.rs:23:43 | LL | Value = (stringify!($tokens + hidden_ident), 1).1 @@ -9,7 +9,7 @@ LL | other!(50); | = note: this error originates in the macro `inner` which comes from the expansion of the macro `other` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0425]: cannot find value `hidden_ident` +error[E0425]: cannot find value `hidden_ident` in this scope --> $DIR/weird-hygiene.rs:34:13 | LL | hidden_ident diff --git a/tests/ui/query-system/issue-83479.stderr b/tests/ui/query-system/issue-83479.stderr index dd0bac2bc47a7..7cb41f5cbe51c 100644 --- a/tests/ui/query-system/issue-83479.stderr +++ b/tests/ui/query-system/issue-83479.stderr @@ -27,13 +27,13 @@ LL | static FOO: usize; | | | help: provide a definition for the static: `= ;` -error[E0405]: cannot find trait `Trait` +error[E0405]: cannot find trait `Trait` in this scope --> $DIR/issue-83479.rs:3:24 | LL | type PairCoupledTypes: Trait< | ^^^^^ not found in this scope -error[E0405]: cannot find trait `Trait` +error[E0405]: cannot find trait `Trait` in this scope --> $DIR/issue-83479.rs:9:10 | LL | > = impl Trait< diff --git a/tests/ui/recursion/recursive-reexports.stderr b/tests/ui/recursion/recursive-reexports.stderr index 01176b83572d5..cfa245ea69ff7 100644 --- a/tests/ui/recursion/recursive-reexports.stderr +++ b/tests/ui/recursion/recursive-reexports.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `S` +error[E0412]: cannot find type `S` in crate `recursive_reexports` --> $DIR/recursive-reexports.rs:5:32 | LL | fn f() -> recursive_reexports::S {} diff --git a/tests/ui/regions/outlives-with-missing.stderr b/tests/ui/regions/outlives-with-missing.stderr index 4a06373e5c6d8..0e3aaaf5fdbd0 100644 --- a/tests/ui/regions/outlives-with-missing.stderr +++ b/tests/ui/regions/outlives-with-missing.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `T` +error[E0412]: cannot find type `T` in this scope --> $DIR/outlives-with-missing.rs:10:9 | LL | impl HandlerWrapper { diff --git a/tests/ui/reserved/reserved-attr-on-macro.stderr b/tests/ui/reserved/reserved-attr-on-macro.stderr index 591f9b3f47ef0..c0d4c29390caa 100644 --- a/tests/ui/reserved/reserved-attr-on-macro.stderr +++ b/tests/ui/reserved/reserved-attr-on-macro.stderr @@ -4,7 +4,7 @@ error: attributes starting with `rustc` are reserved for use by the `rustc` comp LL | #[rustc_attribute_should_be_reserved] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: cannot find attribute `rustc_attribute_should_be_reserved` +error: cannot find attribute `rustc_attribute_should_be_reserved` in this scope --> $DIR/reserved-attr-on-macro.rs:1:3 | LL | #[rustc_attribute_should_be_reserved] diff --git a/tests/ui/resolve/associated-fn-called-as-fn.stderr b/tests/ui/resolve/associated-fn-called-as-fn.stderr index 577492ee14f93..7d28b959a1a48 100644 --- a/tests/ui/resolve/associated-fn-called-as-fn.stderr +++ b/tests/ui/resolve/associated-fn-called-as-fn.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find function `collect_primary` +error[E0425]: cannot find function `collect_primary` in this scope --> $DIR/associated-fn-called-as-fn.rs:6:30 | LL | '0'..='9' => collect_primary(&c), @@ -9,7 +9,7 @@ help: you might have meant to call the associated function LL | '0'..='9' => Self::collect_primary(&c), | ++++++ -error[E0425]: cannot find function `collect_primary` +error[E0425]: cannot find function `collect_primary` in this scope --> $DIR/associated-fn-called-as-fn.rs:23:30 | LL | '0'..='9' => collect_primary(&c), diff --git a/tests/ui/resolve/bad-env-capture.stderr b/tests/ui/resolve/bad-env-capture.stderr index 05d8ef748b531..59b1fabfd7c46 100644 --- a/tests/ui/resolve/bad-env-capture.stderr +++ b/tests/ui/resolve/bad-env-capture.stderr @@ -6,13 +6,13 @@ LL | fn bar() { log(debug, x); } | = help: use the `|| { ... }` closure form instead -error[E0425]: cannot find value `debug` +error[E0425]: cannot find value `debug` in this scope --> $DIR/bad-env-capture.rs:4:20 | LL | fn bar() { log(debug, x); } | ^^^^^ not found in this scope -error[E0425]: cannot find function `log` +error[E0425]: cannot find function `log` in this scope --> $DIR/bad-env-capture.rs:4:16 | LL | fn bar() { log(debug, x); } diff --git a/tests/ui/resolve/bad-env-capture2.stderr b/tests/ui/resolve/bad-env-capture2.stderr index e6e750d6c023e..811c259de6bd6 100644 --- a/tests/ui/resolve/bad-env-capture2.stderr +++ b/tests/ui/resolve/bad-env-capture2.stderr @@ -6,13 +6,13 @@ LL | fn bar() { log(debug, x); } | = help: use the `|| { ... }` closure form instead -error[E0425]: cannot find value `debug` +error[E0425]: cannot find value `debug` in this scope --> $DIR/bad-env-capture2.rs:3:20 | LL | fn bar() { log(debug, x); } | ^^^^^ not found in this scope -error[E0425]: cannot find function `log` +error[E0425]: cannot find function `log` in this scope --> $DIR/bad-env-capture2.rs:3:16 | LL | fn bar() { log(debug, x); } diff --git a/tests/ui/resolve/bad-env-capture3.stderr b/tests/ui/resolve/bad-env-capture3.stderr index bdcf19f717c60..eab37fde96e4c 100644 --- a/tests/ui/resolve/bad-env-capture3.stderr +++ b/tests/ui/resolve/bad-env-capture3.stderr @@ -6,13 +6,13 @@ LL | fn bar() { log(debug, x); } | = help: use the `|| { ... }` closure form instead -error[E0425]: cannot find value `debug` +error[E0425]: cannot find value `debug` in this scope --> $DIR/bad-env-capture3.rs:4:24 | LL | fn bar() { log(debug, x); } | ^^^^^ not found in this scope -error[E0425]: cannot find function `log` +error[E0425]: cannot find function `log` in this scope --> $DIR/bad-env-capture3.rs:4:20 | LL | fn bar() { log(debug, x); } diff --git a/tests/ui/resolve/bad-expr-path.stderr b/tests/ui/resolve/bad-expr-path.stderr index 44da9ae9bc3b0..ea13b8a05e61c 100644 --- a/tests/ui/resolve/bad-expr-path.stderr +++ b/tests/ui/resolve/bad-expr-path.stderr @@ -1,10 +1,10 @@ -error[E0425]: cannot find value `debug` +error[E0425]: cannot find value `debug` in this scope --> $DIR/bad-expr-path.rs:4:9 | LL | log(debug, m1::arguments); | ^^^^^ not found in this scope -error[E0425]: cannot find value `arguments` +error[E0425]: cannot find value `arguments` in module `m1` --> $DIR/bad-expr-path.rs:4:20 | LL | log(debug, m1::arguments); @@ -19,7 +19,7 @@ LL | fn main(arguments: Vec) { = note: expected signature `fn()` found signature `fn(Vec)` -error[E0425]: cannot find function `log` +error[E0425]: cannot find function `log` in this scope --> $DIR/bad-expr-path.rs:4:5 | LL | log(debug, m1::arguments); diff --git a/tests/ui/resolve/bad-expr-path2.stderr b/tests/ui/resolve/bad-expr-path2.stderr index c74efcd036b27..9238b1f7023e5 100644 --- a/tests/ui/resolve/bad-expr-path2.stderr +++ b/tests/ui/resolve/bad-expr-path2.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `debug` +error[E0425]: cannot find value `debug` in this scope --> $DIR/bad-expr-path2.rs:6:9 | LL | log(debug, m1::arguments); @@ -19,7 +19,7 @@ LL | fn main(arguments: Vec) { = note: expected signature `fn()` found signature `fn(Vec)` -error[E0425]: cannot find function `log` +error[E0425]: cannot find function `log` in this scope --> $DIR/bad-expr-path2.rs:6:5 | LL | log(debug, m1::arguments); diff --git a/tests/ui/resolve/crate-called-as-function.stderr b/tests/ui/resolve/crate-called-as-function.stderr index ccfd9ff830418..1d6eb8ad6f5e0 100644 --- a/tests/ui/resolve/crate-called-as-function.stderr +++ b/tests/ui/resolve/crate-called-as-function.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find external crate `foo` +error[E0425]: cannot find external crate `foo` in the crate root --> $DIR/crate-called-as-function.rs:2:7 | LL | ::foo() diff --git a/tests/ui/resolve/crate-in-paths.rs b/tests/ui/resolve/crate-in-paths.rs index 1cbcfb7458c58..6d27f82450699 100644 --- a/tests/ui/resolve/crate-in-paths.rs +++ b/tests/ui/resolve/crate-in-paths.rs @@ -6,5 +6,5 @@ mod bar { fn main() { Foo; - //~^ ERROR cannot find value `Foo` [E0425] + //~^ ERROR cannot find value `Foo` } diff --git a/tests/ui/resolve/crate-in-paths.stderr b/tests/ui/resolve/crate-in-paths.stderr index b16a2e30d03de..9eb735a3aab53 100644 --- a/tests/ui/resolve/crate-in-paths.stderr +++ b/tests/ui/resolve/crate-in-paths.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `Foo` +error[E0425]: cannot find value `Foo` in this scope --> $DIR/crate-in-paths.rs:8:5 | LL | Foo; diff --git a/tests/ui/resolve/editions-crate-root-2015.stderr b/tests/ui/resolve/editions-crate-root-2015.stderr index 785528d20cce4..00cdd0c58f4ec 100644 --- a/tests/ui/resolve/editions-crate-root-2015.stderr +++ b/tests/ui/resolve/editions-crate-root-2015.stderr @@ -14,13 +14,13 @@ LL | fn crate_inner(_: crate::nonexistant::Foo) { | = help: consider adding `extern crate nonexistant` to use the `nonexistant` crate -error[E0412]: cannot find type `nonexistant` +error[E0412]: cannot find type `nonexistant` in the crate root --> $DIR/editions-crate-root-2015.rs:11:25 | LL | fn bare_global(_: ::nonexistant) { | ^^^^^^^^^^^ not found in the crate root -error[E0412]: cannot find type `nonexistant` +error[E0412]: cannot find type `nonexistant` in the crate root --> $DIR/editions-crate-root-2015.rs:14:29 | LL | fn bare_crate(_: crate::nonexistant) { diff --git a/tests/ui/resolve/editions-crate-root-2018.stderr b/tests/ui/resolve/editions-crate-root-2018.stderr index a51440f69359b..967a5a2fca155 100644 --- a/tests/ui/resolve/editions-crate-root-2018.stderr +++ b/tests/ui/resolve/editions-crate-root-2018.stderr @@ -10,13 +10,13 @@ error[E0433]: failed to resolve: could not find `nonexistant` in the crate root LL | fn crate_inner(_: crate::nonexistant::Foo) { | ^^^^^^^^^^^ could not find `nonexistant` in the crate root -error[E0412]: cannot find crate `nonexistant` +error[E0412]: cannot find crate `nonexistant` in the list of imported crates --> $DIR/editions-crate-root-2018.rs:11:25 | LL | fn bare_global(_: ::nonexistant) { | ^^^^^^^^^^^ not found in the list of imported crates -error[E0412]: cannot find type `nonexistant` +error[E0412]: cannot find type `nonexistant` in the crate root --> $DIR/editions-crate-root-2018.rs:14:29 | LL | fn bare_crate(_: crate::nonexistant) { diff --git a/tests/ui/resolve/enums-are-namespaced-xc.stderr b/tests/ui/resolve/enums-are-namespaced-xc.stderr index ce9df1779ede5..71978055afa1a 100644 --- a/tests/ui/resolve/enums-are-namespaced-xc.stderr +++ b/tests/ui/resolve/enums-are-namespaced-xc.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `A` +error[E0425]: cannot find value `A` in crate `namespaced_enums` --> $DIR/enums-are-namespaced-xc.rs:5:31 | LL | let _ = namespaced_enums::A; @@ -14,7 +14,7 @@ LL - let _ = namespaced_enums::A; LL + let _ = A; | -error[E0425]: cannot find function, tuple struct or tuple variant `B` +error[E0425]: cannot find function, tuple struct or tuple variant `B` in crate `namespaced_enums` --> $DIR/enums-are-namespaced-xc.rs:7:31 | LL | let _ = namespaced_enums::B(10); @@ -30,7 +30,7 @@ LL - let _ = namespaced_enums::B(10); LL + let _ = B(10); | -error[E0422]: cannot find struct, variant or union type `C` +error[E0422]: cannot find struct, variant or union type `C` in crate `namespaced_enums` --> $DIR/enums-are-namespaced-xc.rs:9:31 | LL | let _ = namespaced_enums::C { a: 10 }; diff --git a/tests/ui/resolve/enums-pats-not-idents.stderr b/tests/ui/resolve/enums-pats-not-idents.stderr index 267792918de22..6bb6e152c800c 100644 --- a/tests/ui/resolve/enums-pats-not-idents.stderr +++ b/tests/ui/resolve/enums-pats-not-idents.stderr @@ -1,4 +1,4 @@ -error[E0531]: cannot find tuple struct or tuple variant `a` +error[E0531]: cannot find tuple struct or tuple variant `a` in this scope --> $DIR/enums-pats-not-idents.rs:2:9 | LL | let a(1) = 13; diff --git a/tests/ui/resolve/field-and-method-in-self-not-available-in-assoc-fn.stderr b/tests/ui/resolve/field-and-method-in-self-not-available-in-assoc-fn.stderr index d323696f580ab..2f624f24804c8 100644 --- a/tests/ui/resolve/field-and-method-in-self-not-available-in-assoc-fn.stderr +++ b/tests/ui/resolve/field-and-method-in-self-not-available-in-assoc-fn.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `field` +error[E0425]: cannot find value `field` in this scope --> $DIR/field-and-method-in-self-not-available-in-assoc-fn.rs:11:9 | LL | field: u32, @@ -10,7 +10,7 @@ LL | fn field(&self) -> u32 { LL | field; | ^^^^^ -error[E0425]: cannot find value `field` +error[E0425]: cannot find value `field` in this scope --> $DIR/field-and-method-in-self-not-available-in-assoc-fn.rs:12:15 | LL | field: u32, @@ -22,7 +22,7 @@ LL | fn field(&self) -> u32 { LL | Foo { field } | ^^^^^ -error[E0425]: cannot find value `field` +error[E0425]: cannot find value `field` in this scope --> $DIR/field-and-method-in-self-not-available-in-assoc-fn.rs:15:15 | LL | fn field(&self) -> u32 { diff --git a/tests/ui/resolve/filter-intrinsics.stderr b/tests/ui/resolve/filter-intrinsics.stderr index 20d5c01be8fa1..9c9e92f6d4f83 100644 --- a/tests/ui/resolve/filter-intrinsics.stderr +++ b/tests/ui/resolve/filter-intrinsics.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find function `transmute` +error[E0425]: cannot find function `transmute` in this scope --> $DIR/filter-intrinsics.rs:3:13 | LL | let _ = transmute::(); @@ -9,7 +9,7 @@ help: consider importing this function LL + use std::mem::transmute; | -error[E0425]: cannot find function `fabsf64` +error[E0425]: cannot find function `fabsf64` in this scope --> $DIR/filter-intrinsics.rs:8:13 | LL | let _ = fabsf64(1.0); diff --git a/tests/ui/resolve/issue-102946.stderr b/tests/ui/resolve/issue-102946.stderr index 7ad1bbcc831b0..b2cdcb25c3f96 100644 --- a/tests/ui/resolve/issue-102946.stderr +++ b/tests/ui/resolve/issue-102946.stderr @@ -1,4 +1,4 @@ -error[E0405]: cannot find trait `Error` +error[E0405]: cannot find trait `Error` in this scope --> $DIR/issue-102946.rs:1:6 | LL | impl Error for str::Utf8Error { diff --git a/tests/ui/resolve/issue-103474.stderr b/tests/ui/resolve/issue-103474.stderr index 88503b5f8aad7..e48fb31eccc9a 100644 --- a/tests/ui/resolve/issue-103474.stderr +++ b/tests/ui/resolve/issue-103474.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `this` +error[E0425]: cannot find value `this` in this scope --> $DIR/issue-103474.rs:23:9 | LL | this.i @@ -13,7 +13,7 @@ help: if you meant to use `self`, you are also missing a `self` receiver argumen LL | fn needs_self(&self) { | +++++ -error[E0425]: cannot find function `first` +error[E0425]: cannot find function `first` in this scope --> $DIR/issue-103474.rs:6:9 | LL | first() @@ -24,7 +24,7 @@ help: consider using the method on `Self` LL | self.first() | +++++ -error[E0425]: cannot find function `no_method_err` +error[E0425]: cannot find function `no_method_err` in this scope --> $DIR/issue-103474.rs:11:9 | LL | no_method_err() diff --git a/tests/ui/resolve/issue-104700-inner_scope.stderr b/tests/ui/resolve/issue-104700-inner_scope.stderr index 5b17e0b7dbc90..051b234fc72d8 100644 --- a/tests/ui/resolve/issue-104700-inner_scope.stderr +++ b/tests/ui/resolve/issue-104700-inner_scope.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `bar` +error[E0425]: cannot find value `bar` in this scope --> $DIR/issue-104700-inner_scope.rs:7:8 | LL | if bar == 2 { @@ -10,7 +10,7 @@ help: the binding `bar` is available in a different scope in the same function LL | let bar = 2; | ^^^ -error[E0425]: cannot find function `test_func` +error[E0425]: cannot find function `test_func` in this scope --> $DIR/issue-104700-inner_scope.rs:10:5 | LL | test_func(1); diff --git a/tests/ui/resolve/issue-116164.stderr b/tests/ui/resolve/issue-116164.stderr index fc54cae01f96c..8880242c19561 100644 --- a/tests/ui/resolve/issue-116164.stderr +++ b/tests/ui/resolve/issue-116164.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `ExOne` +error[E0425]: cannot find value `ExOne` in this scope --> $DIR/issue-116164.rs:17:5 | LL | ExOne; diff --git a/tests/ui/resolve/issue-118295.stderr b/tests/ui/resolve/issue-118295.stderr index 43a56d6e25a32..fecd1ad1a595a 100644 --- a/tests/ui/resolve/issue-118295.stderr +++ b/tests/ui/resolve/issue-118295.stderr @@ -1,4 +1,4 @@ -error: cannot find macro `macro_rules` +error: cannot find macro `macro_rules` in this scope --> $DIR/issue-118295.rs:1:1 | LL | macro_rules! {} diff --git a/tests/ui/resolve/issue-14254.stderr b/tests/ui/resolve/issue-14254.stderr index 5246e0f2a1c77..9284b4babc50f 100644 --- a/tests/ui/resolve/issue-14254.stderr +++ b/tests/ui/resolve/issue-14254.stderr @@ -1,10 +1,10 @@ -error[E0425]: cannot find value `a` +error[E0425]: cannot find value `a` in this scope --> $DIR/issue-14254.rs:21:9 | LL | a; | ^ not found in this scope -error[E0425]: cannot find value `x` +error[E0425]: cannot find value `x` in this scope --> $DIR/issue-14254.rs:30:9 | LL | x; @@ -15,7 +15,7 @@ help: you might have meant to use the available field LL | self.x; | +++++ -error[E0425]: cannot find value `y` +error[E0425]: cannot find value `y` in this scope --> $DIR/issue-14254.rs:32:9 | LL | y; @@ -26,13 +26,13 @@ help: you might have meant to use the available field LL | self.y; | +++++ -error[E0425]: cannot find value `a` +error[E0425]: cannot find value `a` in this scope --> $DIR/issue-14254.rs:34:9 | LL | a; | ^ not found in this scope -error[E0425]: cannot find value `bah` +error[E0425]: cannot find value `bah` in this scope --> $DIR/issue-14254.rs:36:9 | LL | bah; @@ -43,13 +43,13 @@ help: you might have meant to refer to the associated function LL | Self::bah; | ++++++ -error[E0425]: cannot find value `b` +error[E0425]: cannot find value `b` in this scope --> $DIR/issue-14254.rs:38:9 | LL | b; | ^ not found in this scope -error[E0425]: cannot find value `x` +error[E0425]: cannot find value `x` in this scope --> $DIR/issue-14254.rs:47:9 | LL | x; @@ -60,7 +60,7 @@ help: you might have meant to use the available field LL | self.x; | +++++ -error[E0425]: cannot find value `y` +error[E0425]: cannot find value `y` in this scope --> $DIR/issue-14254.rs:49:9 | LL | y; @@ -71,13 +71,13 @@ help: you might have meant to use the available field LL | self.y; | +++++ -error[E0425]: cannot find value `a` +error[E0425]: cannot find value `a` in this scope --> $DIR/issue-14254.rs:51:9 | LL | a; | ^ not found in this scope -error[E0425]: cannot find value `bah` +error[E0425]: cannot find value `bah` in this scope --> $DIR/issue-14254.rs:53:9 | LL | bah; @@ -88,13 +88,13 @@ help: you might have meant to refer to the associated function LL | Self::bah; | ++++++ -error[E0425]: cannot find value `b` +error[E0425]: cannot find value `b` in this scope --> $DIR/issue-14254.rs:55:9 | LL | b; | ^ not found in this scope -error[E0425]: cannot find value `bah` +error[E0425]: cannot find value `bah` in this scope --> $DIR/issue-14254.rs:64:9 | LL | bah; @@ -105,7 +105,7 @@ help: you might have meant to refer to the associated function LL | Self::bah; | ++++++ -error[E0425]: cannot find value `bah` +error[E0425]: cannot find value `bah` in this scope --> $DIR/issue-14254.rs:73:9 | LL | bah; @@ -116,7 +116,7 @@ help: you might have meant to refer to the associated function LL | Self::bah; | ++++++ -error[E0425]: cannot find value `bah` +error[E0425]: cannot find value `bah` in this scope --> $DIR/issue-14254.rs:82:9 | LL | bah; @@ -127,7 +127,7 @@ help: you might have meant to refer to the associated function LL | Self::bah; | ++++++ -error[E0425]: cannot find value `bah` +error[E0425]: cannot find value `bah` in this scope --> $DIR/issue-14254.rs:91:9 | LL | bah; @@ -138,7 +138,7 @@ help: you might have meant to refer to the associated function LL | Self::bah; | ++++++ -error[E0425]: cannot find value `bah` +error[E0425]: cannot find value `bah` in this scope --> $DIR/issue-14254.rs:100:9 | LL | bah; @@ -149,7 +149,7 @@ help: you might have meant to refer to the associated function LL | Self::bah; | ++++++ -error[E0425]: cannot find function `baz` +error[E0425]: cannot find function `baz` in this scope --> $DIR/issue-14254.rs:19:9 | LL | baz(); @@ -160,7 +160,7 @@ help: you might have meant to call the method LL | self.baz(); | +++++ -error[E0425]: cannot find function `baz` +error[E0425]: cannot find function `baz` in this scope --> $DIR/issue-14254.rs:28:9 | LL | baz(); @@ -171,7 +171,7 @@ help: you might have meant to call the method LL | self.baz(); | +++++ -error[E0425]: cannot find function `baz` +error[E0425]: cannot find function `baz` in this scope --> $DIR/issue-14254.rs:45:9 | LL | baz(); @@ -182,7 +182,7 @@ help: you might have meant to call the method LL | self.baz(); | +++++ -error[E0425]: cannot find function `baz` +error[E0425]: cannot find function `baz` in this scope --> $DIR/issue-14254.rs:62:9 | LL | baz(); @@ -193,7 +193,7 @@ help: you might have meant to call the method LL | self.baz(); | +++++ -error[E0425]: cannot find function `baz` +error[E0425]: cannot find function `baz` in this scope --> $DIR/issue-14254.rs:71:9 | LL | baz(); @@ -204,7 +204,7 @@ help: you might have meant to call the method LL | self.baz(); | +++++ -error[E0425]: cannot find function `baz` +error[E0425]: cannot find function `baz` in this scope --> $DIR/issue-14254.rs:80:9 | LL | baz(); @@ -215,7 +215,7 @@ help: you might have meant to call the method LL | self.baz(); | +++++ -error[E0425]: cannot find function `baz` +error[E0425]: cannot find function `baz` in this scope --> $DIR/issue-14254.rs:89:9 | LL | baz(); @@ -226,7 +226,7 @@ help: you might have meant to call the method LL | self.baz(); | +++++ -error[E0425]: cannot find function `baz` +error[E0425]: cannot find function `baz` in this scope --> $DIR/issue-14254.rs:98:9 | LL | baz(); diff --git a/tests/ui/resolve/issue-17518.stderr b/tests/ui/resolve/issue-17518.stderr index 97760f23ad928..3eba715188b40 100644 --- a/tests/ui/resolve/issue-17518.stderr +++ b/tests/ui/resolve/issue-17518.stderr @@ -1,4 +1,4 @@ -error[E0422]: cannot find struct, variant or union type `E` +error[E0422]: cannot find struct, variant or union type `E` in this scope --> $DIR/issue-17518.rs:6:5 | LL | E { name: "foobar" }; diff --git a/tests/ui/resolve/issue-21221-1.stderr b/tests/ui/resolve/issue-21221-1.stderr index 2a7482ce6f043..ccf03afaa19fe 100644 --- a/tests/ui/resolve/issue-21221-1.stderr +++ b/tests/ui/resolve/issue-21221-1.stderr @@ -1,4 +1,4 @@ -error[E0405]: cannot find trait `Mul` +error[E0405]: cannot find trait `Mul` in this scope --> $DIR/issue-21221-1.rs:43:6 | LL | impl Mul for Foo { @@ -13,7 +13,7 @@ LL + use mul1::Mul; LL + use mul2::Mul; | -error[E0412]: cannot find type `Mul` +error[E0412]: cannot find type `Mul` in this scope --> $DIR/issue-21221-1.rs:58:16 | LL | fn getMul() -> Mul { @@ -28,13 +28,13 @@ LL + use mul1::Mul; LL + use mul2::Mul; | -error[E0405]: cannot find trait `ThisTraitReallyDoesntExistInAnyModuleReally` +error[E0405]: cannot find trait `ThisTraitReallyDoesntExistInAnyModuleReally` in this scope --> $DIR/issue-21221-1.rs:63:6 | LL | impl ThisTraitReallyDoesntExistInAnyModuleReally for Foo { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not found in this scope -error[E0405]: cannot find trait `Div` +error[E0405]: cannot find trait `Div` in this scope --> $DIR/issue-21221-1.rs:68:6 | LL | impl Div for Foo { diff --git a/tests/ui/resolve/issue-21221-2.stderr b/tests/ui/resolve/issue-21221-2.stderr index e1983dbb7bc9a..5db327955eb10 100644 --- a/tests/ui/resolve/issue-21221-2.stderr +++ b/tests/ui/resolve/issue-21221-2.stderr @@ -1,4 +1,4 @@ -error[E0405]: cannot find trait `T` +error[E0405]: cannot find trait `T` in this scope --> $DIR/issue-21221-2.rs:18:6 | LL | impl T for Foo { } diff --git a/tests/ui/resolve/issue-21221-3.stderr b/tests/ui/resolve/issue-21221-3.stderr index 6328bbb542697..ed3eb2dfb237f 100644 --- a/tests/ui/resolve/issue-21221-3.stderr +++ b/tests/ui/resolve/issue-21221-3.stderr @@ -1,4 +1,4 @@ -error[E0405]: cannot find trait `OuterTrait` +error[E0405]: cannot find trait `OuterTrait` in this scope --> $DIR/issue-21221-3.rs:15:6 | LL | impl OuterTrait for Foo {} diff --git a/tests/ui/resolve/issue-21221-4.stderr b/tests/ui/resolve/issue-21221-4.stderr index 1e1e06b2ef7ac..482a3bd54a33e 100644 --- a/tests/ui/resolve/issue-21221-4.stderr +++ b/tests/ui/resolve/issue-21221-4.stderr @@ -1,4 +1,4 @@ -error[E0405]: cannot find trait `T` +error[E0405]: cannot find trait `T` in this scope --> $DIR/issue-21221-4.rs:10:6 | LL | impl T for Foo {} diff --git a/tests/ui/resolve/issue-2356.rs b/tests/ui/resolve/issue-2356.rs index 6def92ba7d067..f7b2dd13dcb64 100644 --- a/tests/ui/resolve/issue-2356.rs +++ b/tests/ui/resolve/issue-2356.rs @@ -29,7 +29,7 @@ impl Clone for Cat { impl Default for Cat { fn default() -> Self { default(); - //~^ ERROR cannot find function `default` [E0425] + //~^ ERROR cannot find function `default` loop {} } } diff --git a/tests/ui/resolve/issue-2356.stderr b/tests/ui/resolve/issue-2356.stderr index 6ba8979efe8df..74a2c9268a2f9 100644 --- a/tests/ui/resolve/issue-2356.stderr +++ b/tests/ui/resolve/issue-2356.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `whiskers` +error[E0425]: cannot find value `whiskers` in this scope --> $DIR/issue-2356.rs:39:5 | LL | whiskers: isize, @@ -20,7 +20,7 @@ help: add a `self` receiver parameter to make the associated `fn` a method LL | fn meow(&self) { | +++++ -error[E0425]: cannot find value `whiskers` +error[E0425]: cannot find value `whiskers` in this scope --> $DIR/issue-2356.rs:79:5 | LL | whiskers = 0; @@ -31,7 +31,7 @@ help: you might have meant to use the available field LL | self.whiskers = 0; | +++++ -error[E0425]: cannot find value `whiskers` +error[E0425]: cannot find value `whiskers` in this scope --> $DIR/issue-2356.rs:84:5 | LL | whiskers: isize, @@ -48,13 +48,13 @@ LL | fn main() { LL | self += 1; | ^^^^ `self` value is a keyword only available in methods with a `self` parameter -error[E0425]: cannot find function `shave` +error[E0425]: cannot find function `shave` in this scope --> $DIR/issue-2356.rs:17:5 | LL | shave(); | ^^^^^ not found in this scope -error[E0425]: cannot find function `clone` +error[E0425]: cannot find function `clone` in this scope --> $DIR/issue-2356.rs:24:5 | LL | clone(); @@ -65,7 +65,7 @@ help: you might have meant to call the method LL | self.clone(); | +++++ -error[E0425]: cannot find function `default` +error[E0425]: cannot find function `default` in this scope --> $DIR/issue-2356.rs:31:5 | LL | default(); @@ -76,7 +76,7 @@ help: you might have meant to call the associated function LL | Self::default(); | ++++++ -error[E0425]: cannot find function `shave` +error[E0425]: cannot find function `shave` in this scope --> $DIR/issue-2356.rs:41:5 | LL | shave(4); @@ -87,13 +87,13 @@ help: you might have meant to call the associated function LL | Self::shave(4); | ++++++ -error[E0425]: cannot find function `purr` +error[E0425]: cannot find function `purr` in this scope --> $DIR/issue-2356.rs:43:5 | LL | purr(); | ^^^^ not found in this scope -error[E0425]: cannot find function `static_method` +error[E0425]: cannot find function `static_method` in this scope --> $DIR/issue-2356.rs:52:9 | LL | static_method(); @@ -104,25 +104,25 @@ help: consider using the associated function on `Self` LL | Self::static_method(); | ++++++ -error[E0425]: cannot find function `purr` +error[E0425]: cannot find function `purr` in this scope --> $DIR/issue-2356.rs:54:9 | LL | purr(); | ^^^^ not found in this scope -error[E0425]: cannot find function `purr` +error[E0425]: cannot find function `purr` in this scope --> $DIR/issue-2356.rs:56:9 | LL | purr(); | ^^^^ not found in this scope -error[E0425]: cannot find function `purr` +error[E0425]: cannot find function `purr` in this scope --> $DIR/issue-2356.rs:58:9 | LL | purr(); | ^^^^ not found in this scope -error[E0425]: cannot find function `grow_older` +error[E0425]: cannot find function `grow_older` in this scope --> $DIR/issue-2356.rs:72:5 | LL | grow_older(); @@ -133,13 +133,13 @@ help: consider using the associated function on `Self` LL | Self::grow_older(); | ++++++ -error[E0425]: cannot find function `shave` +error[E0425]: cannot find function `shave` in this scope --> $DIR/issue-2356.rs:74:5 | LL | shave(); | ^^^^^ not found in this scope -error[E0425]: cannot find function `purr_louder` +error[E0425]: cannot find function `purr_louder` in this scope --> $DIR/issue-2356.rs:86:5 | LL | purr_louder(); diff --git a/tests/ui/resolve/issue-24968.stderr b/tests/ui/resolve/issue-24968.stderr index 2bf6c063c0b23..82f5a1d5b57b3 100644 --- a/tests/ui/resolve/issue-24968.stderr +++ b/tests/ui/resolve/issue-24968.stderr @@ -1,4 +1,4 @@ -error[E0411]: cannot find type `Self` +error[E0411]: cannot find type `Self` in this scope --> $DIR/issue-24968.rs:3:11 | LL | fn foo(_: Self) { @@ -6,7 +6,7 @@ LL | fn foo(_: Self) { | | | `Self` not allowed in a function -error[E0411]: cannot find type `Self` +error[E0411]: cannot find type `Self` in this scope --> $DIR/issue-24968.rs:8:12 | LL | fn foo2() { @@ -14,7 +14,7 @@ LL | fn foo2() { LL | let x: Self; | ^^^^ `Self` is only available in impls, traits, and type definitions -error[E0411]: cannot find type `Self` +error[E0411]: cannot find type `Self` in this scope --> $DIR/issue-24968.rs:14:5 | LL | type Foo @@ -23,7 +23,7 @@ LL | where LL | Self: Clone, | ^^^^ `Self` is only available in impls, traits, and type definitions -error[E0411]: cannot find type `Self` +error[E0411]: cannot find type `Self` in this scope --> $DIR/issue-24968.rs:18:12 | LL | const FOO: Self = 0; @@ -31,7 +31,7 @@ LL | const FOO: Self = 0; | | | `Self` not allowed in a constant item -error[E0411]: cannot find type `Self` +error[E0411]: cannot find type `Self` in this scope --> $DIR/issue-24968.rs:24:15 | LL | static FOO_S: Self = 0; diff --git a/tests/ui/resolve/issue-26545.rs b/tests/ui/resolve/issue-26545.rs index 436cf0e7d906e..72a171475066c 100644 --- a/tests/ui/resolve/issue-26545.rs +++ b/tests/ui/resolve/issue-26545.rs @@ -5,7 +5,7 @@ mod foo { mod baz { fn foo() { B(()); - //~^ ERROR cannot find function, tuple struct or tuple variant `B` [E0425] + //~^ ERROR cannot find function, tuple struct or tuple variant `B` } } diff --git a/tests/ui/resolve/issue-26545.stderr b/tests/ui/resolve/issue-26545.stderr index 128e031bc8ae6..ced19ea1819cd 100644 --- a/tests/ui/resolve/issue-26545.stderr +++ b/tests/ui/resolve/issue-26545.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find function, tuple struct or tuple variant `B` +error[E0425]: cannot find function, tuple struct or tuple variant `B` in this scope --> $DIR/issue-26545.rs:7:9 | LL | B(()); diff --git a/tests/ui/resolve/issue-31845.stderr b/tests/ui/resolve/issue-31845.stderr index 5dc098cadb758..e65b911151f07 100644 --- a/tests/ui/resolve/issue-31845.stderr +++ b/tests/ui/resolve/issue-31845.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find function `g` +error[E0425]: cannot find function `g` in this scope --> $DIR/issue-31845.rs:7:12 | LL | g(); diff --git a/tests/ui/resolve/issue-35675.stderr b/tests/ui/resolve/issue-35675.stderr index 353dc93b8af12..44af65b0768a8 100644 --- a/tests/ui/resolve/issue-35675.stderr +++ b/tests/ui/resolve/issue-35675.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `Apple` +error[E0412]: cannot find type `Apple` in this scope --> $DIR/issue-35675.rs:7:29 | LL | fn should_return_fruit() -> Apple { @@ -9,7 +9,7 @@ help: there is an enum variant `Fruit::Apple`; try using the variant's enum LL | fn should_return_fruit() -> Fruit { | ~~~~~ -error[E0425]: cannot find function, tuple struct or tuple variant `Apple` +error[E0425]: cannot find function, tuple struct or tuple variant `Apple` in this scope --> $DIR/issue-35675.rs:9:5 | LL | Apple(5) @@ -29,7 +29,7 @@ LL | fn should_return_fruit_too() -> Fruit::Apple { | not a type | help: try using the variant's enum: `Fruit` -error[E0425]: cannot find function, tuple struct or tuple variant `Apple` +error[E0425]: cannot find function, tuple struct or tuple variant `Apple` in this scope --> $DIR/issue-35675.rs:15:5 | LL | Apple(5) @@ -49,7 +49,7 @@ LL | fn foo() -> Ok { | not a type | help: try using the variant's enum: `std::result::Result` -error[E0412]: cannot find type `Variant3` +error[E0412]: cannot find type `Variant3` in this scope --> $DIR/issue-35675.rs:24:13 | LL | fn bar() -> Variant3 { diff --git a/tests/ui/resolve/issue-42944.rs b/tests/ui/resolve/issue-42944.rs index 75b69735e5b97..d5bd7bba95a36 100644 --- a/tests/ui/resolve/issue-42944.rs +++ b/tests/ui/resolve/issue-42944.rs @@ -14,7 +14,7 @@ mod bar { mod baz { fn foo() { Bx(()); - //~^ ERROR cannot find function, tuple struct or tuple variant `Bx` [E0425] + //~^ ERROR cannot find function, tuple struct or tuple variant `Bx` } } diff --git a/tests/ui/resolve/issue-42944.stderr b/tests/ui/resolve/issue-42944.stderr index 8ee3179d85d10..4ffa9402c667e 100644 --- a/tests/ui/resolve/issue-42944.stderr +++ b/tests/ui/resolve/issue-42944.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find function, tuple struct or tuple variant `Bx` +error[E0425]: cannot find function, tuple struct or tuple variant `Bx` in this scope --> $DIR/issue-42944.rs:16:9 | LL | Bx(()); diff --git a/tests/ui/resolve/issue-49074.stderr b/tests/ui/resolve/issue-49074.stderr index 0ded4d9eab2cc..0cae266c9a9fb 100644 --- a/tests/ui/resolve/issue-49074.stderr +++ b/tests/ui/resolve/issue-49074.stderr @@ -1,4 +1,4 @@ -error: cannot find macro `bar` +error: cannot find macro `bar` in this scope --> $DIR/issue-49074.rs:12:4 | LL | bar!(); @@ -6,7 +6,7 @@ LL | bar!(); | = help: have you added the `#[macro_use]` on the module/import? -error: cannot find attribute `marco_use` +error: cannot find attribute `marco_use` in this scope --> $DIR/issue-49074.rs:3:3 | LL | #[marco_use] // typo diff --git a/tests/ui/resolve/issue-50599.stderr b/tests/ui/resolve/issue-50599.stderr index 29265bca44724..250db65ab08d7 100644 --- a/tests/ui/resolve/issue-50599.stderr +++ b/tests/ui/resolve/issue-50599.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `LOG10_2` +error[E0425]: cannot find value `LOG10_2` in module `std::f64` --> $DIR/issue-50599.rs:3:48 | LL | const M: usize = (f64::from(N) * std::f64::LOG10_2) as usize; diff --git a/tests/ui/resolve/issue-5099.stderr b/tests/ui/resolve/issue-5099.stderr index 62b02b3f6f152..e9b2a9c4d4844 100644 --- a/tests/ui/resolve/issue-5099.stderr +++ b/tests/ui/resolve/issue-5099.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `this` +error[E0425]: cannot find value `this` in this scope --> $DIR/issue-5099.rs:3:9 | LL | this.a @@ -13,7 +13,7 @@ help: if you meant to use `self`, you are also missing a `self` receiver argumen LL | fn a(&self) -> A { | +++++ -error[E0425]: cannot find value `this` +error[E0425]: cannot find value `this` in this scope --> $DIR/issue-5099.rs:6:9 | LL | this.b(x); @@ -28,7 +28,7 @@ help: if you meant to use `self`, you are also missing a `self` receiver argumen LL | fn b(&self, x: i32) { | ++++++ -error[E0425]: cannot find value `this` +error[E0425]: cannot find value `this` in this scope --> $DIR/issue-5099.rs:9:20 | LL | let _ = || this.a; diff --git a/tests/ui/resolve/issue-5927.stderr b/tests/ui/resolve/issue-5927.stderr index 131f94d6d6427..d6cd6853dbdb5 100644 --- a/tests/ui/resolve/issue-5927.stderr +++ b/tests/ui/resolve/issue-5927.stderr @@ -1,10 +1,10 @@ -error[E0531]: cannot find tuple struct or tuple variant `x` +error[E0531]: cannot find tuple struct or tuple variant `x` in this scope --> $DIR/issue-5927.rs:3:9 | LL | x(1) => x(1) | ^ not found in this scope -error[E0425]: cannot find function `x` +error[E0425]: cannot find function `x` in this scope --> $DIR/issue-5927.rs:3:17 | LL | x(1) => x(1) diff --git a/tests/ui/resolve/issue-60057.stderr b/tests/ui/resolve/issue-60057.stderr index dd90d34054bdb..8737cf770015f 100644 --- a/tests/ui/resolve/issue-60057.stderr +++ b/tests/ui/resolve/issue-60057.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `banana` +error[E0425]: cannot find value `banana` in this scope --> $DIR/issue-60057.rs:8:21 | LL | banana: u8, @@ -7,7 +7,7 @@ LL | banana: u8, LL | banana: banana | ^^^^^^ -error[E0425]: cannot find value `banana` +error[E0425]: cannot find value `banana` in this scope --> $DIR/issue-60057.rs:14:21 | LL | banana: banana diff --git a/tests/ui/resolve/issue-69401-trait-fn-no-body-ty-local.rs b/tests/ui/resolve/issue-69401-trait-fn-no-body-ty-local.rs index bbc96c875c66e..0fb2fdb76768e 100644 --- a/tests/ui/resolve/issue-69401-trait-fn-no-body-ty-local.rs +++ b/tests/ui/resolve/issue-69401-trait-fn-no-body-ty-local.rs @@ -2,5 +2,5 @@ fn main() {} trait Foo { fn fn_with_type_named_same_as_local_in_param(b: b); - //~^ ERROR cannot find type `b` [E0412] + //~^ ERROR cannot find type `b` } diff --git a/tests/ui/resolve/issue-69401-trait-fn-no-body-ty-local.stderr b/tests/ui/resolve/issue-69401-trait-fn-no-body-ty-local.stderr index 78e47163ebfd2..60ef13551a17c 100644 --- a/tests/ui/resolve/issue-69401-trait-fn-no-body-ty-local.stderr +++ b/tests/ui/resolve/issue-69401-trait-fn-no-body-ty-local.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `b` +error[E0412]: cannot find type `b` in this scope --> $DIR/issue-69401-trait-fn-no-body-ty-local.rs:4:53 | LL | fn fn_with_type_named_same_as_local_in_param(b: b); diff --git a/tests/ui/resolve/issue-80079.stderr b/tests/ui/resolve/issue-80079.stderr index 4f344d7f5ec98..e300ee964bee7 100644 --- a/tests/ui/resolve/issue-80079.stderr +++ b/tests/ui/resolve/issue-80079.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `Foo` +error[E0425]: cannot find value `Foo` in this scope --> $DIR/issue-80079.rs:11:13 | LL | let _ = Foo; diff --git a/tests/ui/resolve/issue-85348.rs b/tests/ui/resolve/issue-85348.rs index a23793a4fdb90..4639c41f0dfe2 100644 --- a/tests/ui/resolve/issue-85348.rs +++ b/tests/ui/resolve/issue-85348.rs @@ -1,7 +1,7 @@ // Checks whether shadowing a const parameter leads to an ICE (#85348). impl ArrayWindowsExample { -//~^ ERROR: cannot find type `ArrayWindowsExample` [E0412] +//~^ ERROR: cannot find type `ArrayWindowsExample` fn next() { let mut N; //~^ ERROR: let bindings cannot shadow const parameters [E0530] diff --git a/tests/ui/resolve/issue-85348.stderr b/tests/ui/resolve/issue-85348.stderr index ce2fc48922d68..42b43f825d10c 100644 --- a/tests/ui/resolve/issue-85348.stderr +++ b/tests/ui/resolve/issue-85348.stderr @@ -7,7 +7,7 @@ LL | impl ArrayWindowsExample { LL | let mut N; | ^ cannot be named the same as a const parameter -error[E0412]: cannot find type `ArrayWindowsExample` +error[E0412]: cannot find type `ArrayWindowsExample` in this scope --> $DIR/issue-85348.rs:3:22 | LL | impl ArrayWindowsExample { diff --git a/tests/ui/resolve/issue-88472.rs b/tests/ui/resolve/issue-88472.rs index 4eff15d941c27..6b62f413bc49b 100644 --- a/tests/ui/resolve/issue-88472.rs +++ b/tests/ui/resolve/issue-88472.rs @@ -14,7 +14,7 @@ mod b { use crate::a::*; //~^ WARNING: unused import type Bar = Foo; - //~^ ERROR: cannot find type `Foo` [E0412] + //~^ ERROR: cannot find type `Foo` //~| NOTE: not found } @@ -31,7 +31,7 @@ mod c { mod e { type Baz = Eee; - //~^ ERROR: cannot find type `Eee` [E0412] + //~^ ERROR: cannot find type `Eee` //~| NOTE: not found } diff --git a/tests/ui/resolve/issue-88472.stderr b/tests/ui/resolve/issue-88472.stderr index dbb0daa06363b..8431fc97766f7 100644 --- a/tests/ui/resolve/issue-88472.stderr +++ b/tests/ui/resolve/issue-88472.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `Foo` +error[E0412]: cannot find type `Foo` in this scope --> $DIR/issue-88472.rs:16:16 | LL | type Bar = Foo; @@ -10,7 +10,7 @@ note: struct `a::Foo` exists but is inaccessible LL | struct Foo; | ^^^^^^^^^^^ not accessible -error[E0412]: cannot find type `Eee` +error[E0412]: cannot find type `Eee` in this scope --> $DIR/issue-88472.rs:33:16 | LL | type Baz = Eee; diff --git a/tests/ui/resolve/issue-90113.stderr b/tests/ui/resolve/issue-90113.stderr index 6f36be4a18670..d25c67825e3a1 100644 --- a/tests/ui/resolve/issue-90113.stderr +++ b/tests/ui/resolve/issue-90113.stderr @@ -1,4 +1,4 @@ -error[E0531]: cannot find tuple struct or tuple variant `Cons` +error[E0531]: cannot find tuple struct or tuple variant `Cons` in this scope --> $DIR/issue-90113.rs:17:9 | LL | Cons(..) => {} diff --git a/tests/ui/resolve/levenshtein.stderr b/tests/ui/resolve/levenshtein.stderr index 140d269ab84bc..cf478210132ed 100644 --- a/tests/ui/resolve/levenshtein.stderr +++ b/tests/ui/resolve/levenshtein.stderr @@ -1,10 +1,10 @@ -error[E0412]: cannot find type `esize` +error[E0412]: cannot find type `esize` in this scope --> $DIR/levenshtein.rs:5:11 | LL | fn foo(c: esize) {} // Misspelled primitive type name. | ^^^^^ help: a builtin type with a similar name exists: `isize` -error[E0412]: cannot find type `Baz` +error[E0412]: cannot find type `Baz` in this scope --> $DIR/levenshtein.rs:10:10 | LL | enum Bar { } @@ -13,7 +13,7 @@ LL | LL | type A = Baz; // Misspelled type name. | ^^^ help: an enum with a similar name exists: `Bar` -error[E0412]: cannot find type `Opiton` +error[E0412]: cannot find type `Opiton` in this scope --> $DIR/levenshtein.rs:12:10 | LL | type B = Opiton; // Misspelled type name from the prelude. @@ -22,13 +22,13 @@ LL | type B = Opiton; // Misspelled type name from the prelude. | = note: similarly named enum `Option` defined here -error[E0412]: cannot find type `Baz` +error[E0412]: cannot find type `Baz` in this scope --> $DIR/levenshtein.rs:16:14 | LL | type A = Baz; // No suggestion here, Bar is not visible | ^^^ not found in this scope -error[E0425]: cannot find value `MAXITEM` +error[E0425]: cannot find value `MAXITEM` in this scope --> $DIR/levenshtein.rs:24:20 | LL | const MAX_ITEM: usize = 10; @@ -37,7 +37,7 @@ LL | const MAX_ITEM: usize = 10; LL | let v = [0u32; MAXITEM]; // Misspelled constant name. | ^^^^^^^ help: a constant with a similar name exists: `MAX_ITEM` -error[E0412]: cannot find type `first` +error[E0412]: cannot find type `first` in module `m` --> $DIR/levenshtein.rs:28:15 | LL | pub struct First; @@ -46,7 +46,7 @@ LL | pub struct First; LL | let b: m::first = m::second; // Misspelled item in module. | ^^^^^ help: a struct with a similar name exists (notice the capitalization): `First` -error[E0425]: cannot find value `second` +error[E0425]: cannot find value `second` in module `m` --> $DIR/levenshtein.rs:28:26 | LL | pub struct Second; @@ -55,7 +55,7 @@ LL | pub struct Second; LL | let b: m::first = m::second; // Misspelled item in module. | ^^^^^^ help: a unit struct with a similar name exists (notice the capitalization): `Second` -error[E0425]: cannot find function `foobar` +error[E0425]: cannot find function `foobar` in this scope --> $DIR/levenshtein.rs:26:5 | LL | fn foo_bar() {} diff --git a/tests/ui/resolve/no-implicit-prelude-nested.stderr b/tests/ui/resolve/no-implicit-prelude-nested.stderr index e3e338cae9e73..49cf72bfee2d6 100644 --- a/tests/ui/resolve/no-implicit-prelude-nested.stderr +++ b/tests/ui/resolve/no-implicit-prelude-nested.stderr @@ -1,4 +1,4 @@ -error[E0405]: cannot find trait `Add` +error[E0405]: cannot find trait `Add` in this scope --> $DIR/no-implicit-prelude-nested.rs:11:14 | LL | impl Add for Test {} @@ -20,7 +20,7 @@ help: consider importing this trait instead LL + use std::clone::Clone; | -error[E0405]: cannot find trait `Iterator` +error[E0405]: cannot find trait `Iterator` in this scope --> $DIR/no-implicit-prelude-nested.rs:13:14 | LL | impl Iterator for Test {} @@ -31,7 +31,7 @@ help: consider importing this trait LL + use std::iter::Iterator; | -error[E0405]: cannot find trait `ToString` +error[E0405]: cannot find trait `ToString` in this scope --> $DIR/no-implicit-prelude-nested.rs:14:14 | LL | impl ToString for Test {} @@ -42,13 +42,13 @@ help: consider importing this trait LL + use std::string::ToString; | -error[E0405]: cannot find trait `Writer` +error[E0405]: cannot find trait `Writer` in this scope --> $DIR/no-implicit-prelude-nested.rs:15:14 | LL | impl Writer for Test {} | ^^^^^^ not found in this scope -error[E0425]: cannot find function `drop` +error[E0425]: cannot find function `drop` in this scope --> $DIR/no-implicit-prelude-nested.rs:18:13 | LL | drop(2) @@ -59,7 +59,7 @@ help: consider importing this function LL + use std::mem::drop; | -error[E0405]: cannot find trait `Add` +error[E0405]: cannot find trait `Add` in this scope --> $DIR/no-implicit-prelude-nested.rs:23:10 | LL | impl Add for Test {} @@ -81,7 +81,7 @@ help: consider importing this trait instead LL + use std::clone::Clone; | -error[E0405]: cannot find trait `Iterator` +error[E0405]: cannot find trait `Iterator` in this scope --> $DIR/no-implicit-prelude-nested.rs:25:10 | LL | impl Iterator for Test {} @@ -92,7 +92,7 @@ help: consider importing this trait LL + use std::iter::Iterator; | -error[E0405]: cannot find trait `ToString` +error[E0405]: cannot find trait `ToString` in this scope --> $DIR/no-implicit-prelude-nested.rs:26:10 | LL | impl ToString for Test {} @@ -103,13 +103,13 @@ help: consider importing this trait LL + use std::string::ToString; | -error[E0405]: cannot find trait `Writer` +error[E0405]: cannot find trait `Writer` in this scope --> $DIR/no-implicit-prelude-nested.rs:27:10 | LL | impl Writer for Test {} | ^^^^^^ not found in this scope -error[E0425]: cannot find function `drop` +error[E0425]: cannot find function `drop` in this scope --> $DIR/no-implicit-prelude-nested.rs:30:9 | LL | drop(2) @@ -120,7 +120,7 @@ help: consider importing this function LL + use std::mem::drop; | -error[E0405]: cannot find trait `Add` +error[E0405]: cannot find trait `Add` in this scope --> $DIR/no-implicit-prelude-nested.rs:38:14 | LL | impl Add for Test {} @@ -142,7 +142,7 @@ help: consider importing this trait instead LL + use std::clone::Clone; | -error[E0405]: cannot find trait `Iterator` +error[E0405]: cannot find trait `Iterator` in this scope --> $DIR/no-implicit-prelude-nested.rs:40:14 | LL | impl Iterator for Test {} @@ -153,7 +153,7 @@ help: consider importing this trait LL + use std::iter::Iterator; | -error[E0405]: cannot find trait `ToString` +error[E0405]: cannot find trait `ToString` in this scope --> $DIR/no-implicit-prelude-nested.rs:41:14 | LL | impl ToString for Test {} @@ -164,13 +164,13 @@ help: consider importing this trait LL + use std::string::ToString; | -error[E0405]: cannot find trait `Writer` +error[E0405]: cannot find trait `Writer` in this scope --> $DIR/no-implicit-prelude-nested.rs:42:14 | LL | impl Writer for Test {} | ^^^^^^ not found in this scope -error[E0425]: cannot find function `drop` +error[E0425]: cannot find function `drop` in this scope --> $DIR/no-implicit-prelude-nested.rs:45:13 | LL | drop(2) diff --git a/tests/ui/resolve/no-implicit-prelude.stderr b/tests/ui/resolve/no-implicit-prelude.stderr index ee933ae2dd60a..5a759743f7258 100644 --- a/tests/ui/resolve/no-implicit-prelude.stderr +++ b/tests/ui/resolve/no-implicit-prelude.stderr @@ -1,4 +1,4 @@ -error[E0405]: cannot find trait `Add` +error[E0405]: cannot find trait `Add` in this scope --> $DIR/no-implicit-prelude.rs:10:6 | LL | impl Add for Test {} @@ -20,7 +20,7 @@ help: consider importing this trait instead LL + use std::clone::Clone; | -error[E0405]: cannot find trait `Iterator` +error[E0405]: cannot find trait `Iterator` in this scope --> $DIR/no-implicit-prelude.rs:12:6 | LL | impl Iterator for Test {} @@ -31,7 +31,7 @@ help: consider importing this trait LL + use std::iter::Iterator; | -error[E0405]: cannot find trait `ToString` +error[E0405]: cannot find trait `ToString` in this scope --> $DIR/no-implicit-prelude.rs:13:6 | LL | impl ToString for Test {} @@ -42,13 +42,13 @@ help: consider importing this trait LL + use std::string::ToString; | -error[E0405]: cannot find trait `Writer` +error[E0405]: cannot find trait `Writer` in this scope --> $DIR/no-implicit-prelude.rs:14:6 | LL | impl Writer for Test {} | ^^^^^^ not found in this scope -error[E0425]: cannot find function `drop` +error[E0425]: cannot find function `drop` in this scope --> $DIR/no-implicit-prelude.rs:17:5 | LL | drop(2) diff --git a/tests/ui/resolve/path-attr-in-const-block.stderr b/tests/ui/resolve/path-attr-in-const-block.stderr index a3ad87f0ddcfb..8231757ec62a2 100644 --- a/tests/ui/resolve/path-attr-in-const-block.stderr +++ b/tests/ui/resolve/path-attr-in-const-block.stderr @@ -1,4 +1,4 @@ -error: cannot find macro `foo` +error: cannot find macro `foo` in this scope --> $DIR/path-attr-in-const-block.rs:6:19 | LL | #![path = foo!()] diff --git a/tests/ui/resolve/privacy-enum-ctor.stderr b/tests/ui/resolve/privacy-enum-ctor.stderr index ea0e99b90e4cc..ee3aecddcc342 100644 --- a/tests/ui/resolve/privacy-enum-ctor.stderr +++ b/tests/ui/resolve/privacy-enum-ctor.stderr @@ -134,7 +134,7 @@ LL + use std::f32::consts::E; LL + use std::f64::consts::E; | -error[E0412]: cannot find type `Z` +error[E0412]: cannot find type `Z` in this scope --> $DIR/privacy-enum-ctor.rs:57:12 | LL | pub enum E { @@ -175,7 +175,7 @@ help: alternatively, the following enum variant is available LL | let _: Z = (m::Z::Fn(/* fields */)); | ~~~~~~~~~~~~~~~~~~~~~~~~ -error[E0412]: cannot find type `Z` +error[E0412]: cannot find type `Z` in this scope --> $DIR/privacy-enum-ctor.rs:61:12 | LL | pub enum E { @@ -190,7 +190,7 @@ note: enum `m::Z` exists but is inaccessible LL | pub(in m) enum Z { | ^^^^^^^^^^^^^^^^ not accessible -error[E0412]: cannot find type `Z` +error[E0412]: cannot find type `Z` in this scope --> $DIR/privacy-enum-ctor.rs:64:12 | LL | pub enum E { @@ -205,7 +205,7 @@ note: enum `m::Z` exists but is inaccessible LL | pub(in m) enum Z { | ^^^^^^^^^^^^^^^^ not accessible -error[E0412]: cannot find type `Z` +error[E0412]: cannot find type `Z` in this scope --> $DIR/privacy-enum-ctor.rs:68:12 | LL | pub enum E { diff --git a/tests/ui/resolve/raw-ident-in-path.stderr b/tests/ui/resolve/raw-ident-in-path.stderr index d1bad7ea1844f..7d2aa69113638 100644 --- a/tests/ui/resolve/raw-ident-in-path.stderr +++ b/tests/ui/resolve/raw-ident-in-path.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `r#break` +error[E0412]: cannot find type `r#break` in the crate root --> $DIR/raw-ident-in-path.rs:3:17 | LL | type A = crate::r#break; diff --git a/tests/ui/resolve/resolve-assoc-suggestions.stderr b/tests/ui/resolve/resolve-assoc-suggestions.stderr index 401d7dc5beb54..3d9d4ffaa10c8 100644 --- a/tests/ui/resolve/resolve-assoc-suggestions.stderr +++ b/tests/ui/resolve/resolve-assoc-suggestions.stderr @@ -1,16 +1,16 @@ -error[E0412]: cannot find type `field` +error[E0412]: cannot find type `field` in this scope --> $DIR/resolve-assoc-suggestions.rs:16:16 | LL | let _: field; | ^^^^^ not found in this scope -error[E0531]: cannot find tuple struct or tuple variant `field` +error[E0531]: cannot find tuple struct or tuple variant `field` in this scope --> $DIR/resolve-assoc-suggestions.rs:18:13 | LL | let field(..); | ^^^^^ not found in this scope -error[E0425]: cannot find value `field` +error[E0425]: cannot find value `field` in this scope --> $DIR/resolve-assoc-suggestions.rs:20:9 | LL | field; @@ -21,7 +21,7 @@ help: you might have meant to use the available field LL | self.field; | +++++ -error[E0412]: cannot find type `Type` +error[E0412]: cannot find type `Type` in this scope --> $DIR/resolve-assoc-suggestions.rs:23:16 | LL | let _: Type; @@ -32,31 +32,31 @@ help: you might have meant to use the associated type LL | let _: Self::Type; | ++++++ -error[E0531]: cannot find tuple struct or tuple variant `Type` +error[E0531]: cannot find tuple struct or tuple variant `Type` in this scope --> $DIR/resolve-assoc-suggestions.rs:25:13 | LL | let Type(..); | ^^^^ not found in this scope -error[E0425]: cannot find value `Type` +error[E0425]: cannot find value `Type` in this scope --> $DIR/resolve-assoc-suggestions.rs:27:9 | LL | Type; | ^^^^ not found in this scope -error[E0412]: cannot find type `method` +error[E0412]: cannot find type `method` in this scope --> $DIR/resolve-assoc-suggestions.rs:30:16 | LL | let _: method; | ^^^^^^ not found in this scope -error[E0531]: cannot find tuple struct or tuple variant `method` +error[E0531]: cannot find tuple struct or tuple variant `method` in this scope --> $DIR/resolve-assoc-suggestions.rs:32:13 | LL | let method(..); | ^^^^^^ not found in this scope -error[E0425]: cannot find value `method` +error[E0425]: cannot find value `method` in this scope --> $DIR/resolve-assoc-suggestions.rs:34:9 | LL | method; diff --git a/tests/ui/resolve/resolve-primitive-fallback.stderr b/tests/ui/resolve/resolve-primitive-fallback.stderr index e2a982880e7bb..d0583966459be 100644 --- a/tests/ui/resolve/resolve-primitive-fallback.stderr +++ b/tests/ui/resolve/resolve-primitive-fallback.stderr @@ -4,7 +4,7 @@ error[E0423]: expected value, found builtin type `u16` LL | std::mem::size_of(u16); | ^^^ not a value -error[E0412]: cannot find type `u8` +error[E0412]: cannot find type `u8` in the crate root --> $DIR/resolve-primitive-fallback.rs:8:14 | LL | let _: ::u8; diff --git a/tests/ui/resolve/resolve-self-in-impl-2.stderr b/tests/ui/resolve/resolve-self-in-impl-2.stderr index 3627bf1d45227..3791fe90a6bae 100644 --- a/tests/ui/resolve/resolve-self-in-impl-2.stderr +++ b/tests/ui/resolve/resolve-self-in-impl-2.stderr @@ -4,7 +4,7 @@ error[E0411]: expected trait, found self type `Self` LL | impl Self for S {} | ^^^^ `Self` is only available in impls, traits, and type definitions -error[E0405]: cannot find trait `N` +error[E0405]: cannot find trait `N` in `Self` --> $DIR/resolve-self-in-impl-2.rs:5:12 | LL | impl Self::N for S {} diff --git a/tests/ui/resolve/resolve-speculative-adjustment.stderr b/tests/ui/resolve/resolve-speculative-adjustment.stderr index bea202013863b..fb15472bdae8d 100644 --- a/tests/ui/resolve/resolve-speculative-adjustment.stderr +++ b/tests/ui/resolve/resolve-speculative-adjustment.stderr @@ -1,10 +1,10 @@ -error[E0425]: cannot find value `field` +error[E0425]: cannot find value `field` in this scope --> $DIR/resolve-speculative-adjustment.rs:17:13 | LL | field; | ^^^^^ not found in this scope -error[E0425]: cannot find value `field` +error[E0425]: cannot find value `field` in this scope --> $DIR/resolve-speculative-adjustment.rs:23:9 | LL | field; @@ -15,7 +15,7 @@ help: you might have meant to use the available field LL | self.field; | +++++ -error[E0425]: cannot find function `method` +error[E0425]: cannot find function `method` in this scope --> $DIR/resolve-speculative-adjustment.rs:25:9 | LL | method(); @@ -26,7 +26,7 @@ help: you might have meant to call the method LL | self.method(); | +++++ -error[E0425]: cannot find function `method` +error[E0425]: cannot find function `method` in this scope --> $DIR/resolve-speculative-adjustment.rs:19:13 | LL | method(); diff --git a/tests/ui/resolve/resolve-unknown-trait.stderr b/tests/ui/resolve/resolve-unknown-trait.stderr index e27b954efbcd6..e19cfe617d4f2 100644 --- a/tests/ui/resolve/resolve-unknown-trait.stderr +++ b/tests/ui/resolve/resolve-unknown-trait.stderr @@ -1,16 +1,16 @@ -error[E0405]: cannot find trait `SomeNonExistentTrait` +error[E0405]: cannot find trait `SomeNonExistentTrait` in this scope --> $DIR/resolve-unknown-trait.rs:1:18 | LL | trait NewTrait : SomeNonExistentTrait {} | ^^^^^^^^^^^^^^^^^^^^ not found in this scope -error[E0405]: cannot find trait `SomeNonExistentTrait` +error[E0405]: cannot find trait `SomeNonExistentTrait` in this scope --> $DIR/resolve-unknown-trait.rs:4:6 | LL | impl SomeNonExistentTrait for isize {} | ^^^^^^^^^^^^^^^^^^^^ not found in this scope -error[E0405]: cannot find trait `SomeNonExistentTrait` +error[E0405]: cannot find trait `SomeNonExistentTrait` in this scope --> $DIR/resolve-unknown-trait.rs:7:8 | LL | fn f() {} diff --git a/tests/ui/resolve/suggest-import-without-clobbering-attrs.stderr b/tests/ui/resolve/suggest-import-without-clobbering-attrs.stderr index ce457c6c7247d..de65d695dd23d 100644 --- a/tests/ui/resolve/suggest-import-without-clobbering-attrs.stderr +++ b/tests/ui/resolve/suggest-import-without-clobbering-attrs.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find function `z` +error[E0425]: cannot find function `z` in this scope --> $DIR/suggest-import-without-clobbering-attrs.rs:13:5 | LL | z(); diff --git a/tests/ui/resolve/typo-suggestion-for-variable-with-name-similar-to-struct-field.stderr b/tests/ui/resolve/typo-suggestion-for-variable-with-name-similar-to-struct-field.stderr index 8b4881c1618cc..5662021a2d523 100644 --- a/tests/ui/resolve/typo-suggestion-for-variable-with-name-similar-to-struct-field.stderr +++ b/tests/ui/resolve/typo-suggestion-for-variable-with-name-similar-to-struct-field.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `config` +error[E0425]: cannot find value `config` in this scope --> $DIR/typo-suggestion-for-variable-with-name-similar-to-struct-field.rs:7:16 | LL | config: String, @@ -7,7 +7,7 @@ LL | config: String, LL | Self { config } | ^^^^^^ help: a local variable with a similar name exists: `cofig` -error[E0425]: cannot find value `config` +error[E0425]: cannot find value `config` in this scope --> $DIR/typo-suggestion-for-variable-with-name-similar-to-struct-field.rs:11:20 | LL | config: String, @@ -16,7 +16,7 @@ LL | config: String, LL | println!("{config}"); | ^^^^^^ help: a local variable with a similar name exists: `cofig` -error[E0425]: cannot find value `config` +error[E0425]: cannot find value `config` in this scope --> $DIR/typo-suggestion-for-variable-with-name-similar-to-struct-field.rs:15:20 | LL | println!("{config}"); @@ -31,7 +31,7 @@ help: a local variable with a similar name exists LL | println!("{cofig}"); | ~~~~~ -error[E0425]: cannot find value `bah` +error[E0425]: cannot find value `bah` in this scope --> $DIR/typo-suggestion-for-variable-with-name-similar-to-struct-field.rs:33:9 | LL | bah; @@ -49,7 +49,7 @@ help: a function with a similar name exists LL | ba; | ~~ -error[E0425]: cannot find value `BAR` +error[E0425]: cannot find value `BAR` in this scope --> $DIR/typo-suggestion-for-variable-with-name-similar-to-struct-field.rs:35:9 | LL | BAR; @@ -67,7 +67,7 @@ help: a constant with a similar name exists LL | BARR; | ~~~~ -error[E0412]: cannot find type `Baz` +error[E0412]: cannot find type `Baz` in this scope --> $DIR/typo-suggestion-for-variable-with-name-similar-to-struct-field.rs:37:18 | LL | let foo: Baz = "".to_string(); @@ -85,7 +85,7 @@ help: a type alias with a similar name exists LL | let foo: Bar = "".to_string(); | ~~~ -error[E0425]: cannot find function `baz` +error[E0425]: cannot find function `baz` in this scope --> $DIR/typo-suggestion-for-variable-with-name-similar-to-struct-field.rs:31:9 | LL | baz(); diff --git a/tests/ui/resolve/typo-suggestion-named-underscore.stderr b/tests/ui/resolve/typo-suggestion-named-underscore.stderr index ed7fb40d1196d..65d1b084a3a7b 100644 --- a/tests/ui/resolve/typo-suggestion-named-underscore.stderr +++ b/tests/ui/resolve/typo-suggestion-named-underscore.stderr @@ -1,10 +1,10 @@ -error[E0425]: cannot find value `a` +error[E0425]: cannot find value `a` in this scope --> $DIR/typo-suggestion-named-underscore.rs:4:5 | LL | a // Shouldn't suggest underscore | ^ not found in this scope -error[E0405]: cannot find trait `A` +error[E0405]: cannot find trait `A` in this scope --> $DIR/typo-suggestion-named-underscore.rs:13:11 | LL | fn foo(x: T) {} // Shouldn't suggest underscore diff --git a/tests/ui/resolve/unboxed-closure-sugar-nonexistent-trait.stderr b/tests/ui/resolve/unboxed-closure-sugar-nonexistent-trait.stderr index 2d2d0fd4b8e0b..8addc0303fb91 100644 --- a/tests/ui/resolve/unboxed-closure-sugar-nonexistent-trait.stderr +++ b/tests/ui/resolve/unboxed-closure-sugar-nonexistent-trait.stderr @@ -1,4 +1,4 @@ -error[E0405]: cannot find trait `Nonexist` +error[E0405]: cannot find trait `Nonexist` in this scope --> $DIR/unboxed-closure-sugar-nonexistent-trait.rs:1:8 | LL | fn f isize>(x: F) {} diff --git a/tests/ui/resolve/unresolved_static_type_field.stderr b/tests/ui/resolve/unresolved_static_type_field.stderr index 9bcf3af02c0e4..f039eef2e06b9 100644 --- a/tests/ui/resolve/unresolved_static_type_field.stderr +++ b/tests/ui/resolve/unresolved_static_type_field.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `cx` +error[E0425]: cannot find value `cx` in this scope --> $DIR/unresolved_static_type_field.rs:9:11 | LL | cx: bool, diff --git a/tests/ui/resolve/use_suggestion.stderr b/tests/ui/resolve/use_suggestion.stderr index 1d8acaf67fac9..1155f5caa1739 100644 --- a/tests/ui/resolve/use_suggestion.stderr +++ b/tests/ui/resolve/use_suggestion.stderr @@ -9,7 +9,7 @@ help: consider importing this struct LL + use std::collections::HashMap; | -error[E0412]: cannot find type `HashMap` +error[E0412]: cannot find type `HashMap` in this scope --> $DIR/use_suggestion.rs:5:13 | LL | let y1: HashMap; @@ -20,7 +20,7 @@ help: consider importing this struct LL + use std::collections::HashMap; | -error[E0412]: cannot find type `GooMap` +error[E0412]: cannot find type `GooMap` in this scope --> $DIR/use_suggestion.rs:6:13 | LL | let y2: GooMap; diff --git a/tests/ui/resolve/use_suggestion_placement.stderr b/tests/ui/resolve/use_suggestion_placement.stderr index 08bd4269649ed..3611f9ae6b4ed 100644 --- a/tests/ui/resolve/use_suggestion_placement.stderr +++ b/tests/ui/resolve/use_suggestion_placement.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `Path` +error[E0412]: cannot find type `Path` in this scope --> $DIR/use_suggestion_placement.rs:18:16 | LL | type Bar = Path; @@ -9,7 +9,7 @@ help: consider importing this struct LL + use std::path::Path; | -error[E0425]: cannot find value `A` +error[E0425]: cannot find value `A` in this scope --> $DIR/use_suggestion_placement.rs:23:13 | LL | let _ = A; @@ -20,7 +20,7 @@ help: consider importing this constant LL + use m::A; | -error[E0412]: cannot find type `HashMap` +error[E0412]: cannot find type `HashMap` in this scope --> $DIR/use_suggestion_placement.rs:28:23 | LL | type Dict = HashMap; diff --git a/tests/ui/resolve/visibility-indeterminate.stderr b/tests/ui/resolve/visibility-indeterminate.stderr index c74c4f67d61e1..b4ca10a0a84af 100644 --- a/tests/ui/resolve/visibility-indeterminate.stderr +++ b/tests/ui/resolve/visibility-indeterminate.stderr @@ -4,7 +4,7 @@ error[E0578]: cannot determine resolution for the visibility LL | pub(in ::bar) struct Baz {} | ^^^^^ -error: cannot find macro `foo` +error: cannot find macro `foo` in this scope --> $DIR/visibility-indeterminate.rs:3:1 | LL | foo!(); diff --git a/tests/ui/rfcs/rfc-2294-if-let-guard/bindings.stderr b/tests/ui/rfcs/rfc-2294-if-let-guard/bindings.stderr index 5aa1888f8cc5d..2463b7f3eacc7 100644 --- a/tests/ui/rfcs/rfc-2294-if-let-guard/bindings.stderr +++ b/tests/ui/rfcs/rfc-2294-if-let-guard/bindings.stderr @@ -1,10 +1,10 @@ -error[E0425]: cannot find value `y` +error[E0425]: cannot find value `y` in this scope --> $DIR/bindings.rs:6:14 | LL | _ => y, | ^ not found in this scope -error[E0425]: cannot find value `y` +error[E0425]: cannot find value `y` in this scope --> $DIR/bindings.rs:8:5 | LL | y diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-120503-async-const-method.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-120503-async-const-method.stderr index 460797c6fd020..1f309e1e85446 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-120503-async-const-method.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-120503-async-const-method.stderr @@ -60,7 +60,7 @@ error: using `#![feature(effects)]` without enabling next trait solver globally = note: the next trait solver must be enabled globally for the effects feature to work correctly = help: use `-Znext-solver` to enable -error[E0425]: cannot find function `main8` +error[E0425]: cannot find function `main8` in this scope --> $DIR/ice-120503-async-const-method.rs:13:9 | LL | main8().await; diff --git a/tests/ui/rmeta/rmeta.stderr b/tests/ui/rmeta/rmeta.stderr index 14048dc899826..85452ea41d313 100644 --- a/tests/ui/rmeta/rmeta.stderr +++ b/tests/ui/rmeta/rmeta.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `Foo` +error[E0425]: cannot find value `Foo` in this scope --> $DIR/rmeta.rs:7:13 | LL | let _ = Foo; diff --git a/tests/ui/rust-2018/issue-52202-use-suggestions.stderr b/tests/ui/rust-2018/issue-52202-use-suggestions.stderr index c6a600de55233..ee1a336ea98f6 100644 --- a/tests/ui/rust-2018/issue-52202-use-suggestions.stderr +++ b/tests/ui/rust-2018/issue-52202-use-suggestions.stderr @@ -1,4 +1,4 @@ -error[E0422]: cannot find struct, variant or union type `Drain` +error[E0422]: cannot find struct, variant or union type `Drain` in this scope --> $DIR/issue-52202-use-suggestions.rs:11:14 | LL | let _d = Drain {}; diff --git a/tests/ui/rustdoc/cfg-rustdoc.stderr b/tests/ui/rustdoc/cfg-rustdoc.stderr index 42c388dcb6d64..340a8e22482ce 100644 --- a/tests/ui/rustdoc/cfg-rustdoc.stderr +++ b/tests/ui/rustdoc/cfg-rustdoc.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `Foo` +error[E0425]: cannot find value `Foo` in this scope --> $DIR/cfg-rustdoc.rs:5:13 | LL | let f = Foo; diff --git a/tests/ui/self/class-missing-self.stderr b/tests/ui/self/class-missing-self.stderr index 0caf630bfc021..ca7a896200fc3 100644 --- a/tests/ui/self/class-missing-self.stderr +++ b/tests/ui/self/class-missing-self.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `meows` +error[E0425]: cannot find value `meows` in this scope --> $DIR/class-missing-self.rs:9:7 | LL | meows += 1; @@ -9,7 +9,7 @@ help: you might have meant to use the available field LL | self.meows += 1; | +++++ -error[E0425]: cannot find function `sleep` +error[E0425]: cannot find function `sleep` in this scope --> $DIR/class-missing-self.rs:10:7 | LL | sleep(); diff --git a/tests/ui/self/elision/nested-item.stderr b/tests/ui/self/elision/nested-item.stderr index feeb560d995cc..7bad26fa13303 100644 --- a/tests/ui/self/elision/nested-item.stderr +++ b/tests/ui/self/elision/nested-item.stderr @@ -35,7 +35,7 @@ LL - fn wrap(self: Wrap<{ fn bar(&self) {} }>) -> &() { LL + fn wrap(self: Wrap<{ fn bar(&self) {} }>) -> () { | -error[E0412]: cannot find type `Wrap` +error[E0412]: cannot find type `Wrap` in this scope --> $DIR/nested-item.rs:5:15 | LL | fn wrap(self: Wrap<{ fn bar(&self) {} }>) -> &() { diff --git a/tests/ui/self/self_type_keyword-2.stderr b/tests/ui/self/self_type_keyword-2.stderr index 7e96bcc89eebf..4e931f91f70c4 100644 --- a/tests/ui/self/self_type_keyword-2.stderr +++ b/tests/ui/self/self_type_keyword-2.stderr @@ -4,19 +4,19 @@ error[E0432]: unresolved import `self::Self` LL | use self::Self as Foo; | ^^^^^^^^^^^^^^^^^ no `Self` in the root -error[E0531]: cannot find unit struct, unit variant or constant `Self` +error[E0531]: cannot find unit struct, unit variant or constant `Self` in this scope --> $DIR/self_type_keyword-2.rs:4:9 | LL | let Self = 5; | ^^^^ not found in this scope -error[E0531]: cannot find unit struct, unit variant or constant `Self` +error[E0531]: cannot find unit struct, unit variant or constant `Self` in this scope --> $DIR/self_type_keyword-2.rs:8:9 | LL | Self => (), | ^^^^ not found in this scope -error[E0531]: cannot find unit struct, unit variant or constant `Self` +error[E0531]: cannot find unit struct, unit variant or constant `Self` in this scope --> $DIR/self_type_keyword-2.rs:10:18 | LL | Foo { x: Self } => (), diff --git a/tests/ui/self/self_type_keyword.stderr b/tests/ui/self/self_type_keyword.stderr index b69a40b335e9d..1275158cba88a 100644 --- a/tests/ui/self/self_type_keyword.stderr +++ b/tests/ui/self/self_type_keyword.stderr @@ -54,13 +54,13 @@ error: lifetimes cannot use keyword names LL | struct Bar<'Self>; | ^^^^^ -error: cannot find macro `Self` +error: cannot find macro `Self` in this scope --> $DIR/self_type_keyword.rs:21:9 | LL | Self!() => (), | ^^^^ not found in this scope -error[E0531]: cannot find unit struct, unit variant or constant `Self` +error[E0531]: cannot find unit struct, unit variant or constant `Self` in this scope --> $DIR/self_type_keyword.rs:16:13 | LL | mut Self => (), diff --git a/tests/ui/self/suggest-self-2.stderr b/tests/ui/self/suggest-self-2.stderr index dbb3c2ab9235d..4bd025ea07630 100644 --- a/tests/ui/self/suggest-self-2.stderr +++ b/tests/ui/self/suggest-self-2.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find function `bar` +error[E0425]: cannot find function `bar` in this scope --> $DIR/suggest-self-2.rs:5:9 | LL | bar(self); @@ -6,7 +6,7 @@ LL | bar(self); | | | help: try calling `bar` as a method: `self.bar()` -error[E0425]: cannot find function `bar` +error[E0425]: cannot find function `bar` in this scope --> $DIR/suggest-self-2.rs:9:9 | LL | bar(&&self, 102); @@ -14,7 +14,7 @@ LL | bar(&&self, 102); | | | help: try calling `bar` as a method: `self.bar(102)` -error[E0425]: cannot find function `bar` +error[E0425]: cannot find function `bar` in this scope --> $DIR/suggest-self-2.rs:13:9 | LL | bar(&mut self, 102, &"str"); @@ -22,7 +22,7 @@ LL | bar(&mut self, 102, &"str"); | | | help: try calling `bar` as a method: `self.bar(102, &"str")` -error[E0425]: cannot find function `bar` +error[E0425]: cannot find function `bar` in this scope --> $DIR/suggest-self-2.rs:17:9 | LL | bar(); diff --git a/tests/ui/self/suggest-self.stderr b/tests/ui/self/suggest-self.stderr index 8625a83694698..0d38b9d87c5e8 100644 --- a/tests/ui/self/suggest-self.stderr +++ b/tests/ui/self/suggest-self.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `this` +error[E0425]: cannot find value `this` in this scope --> $DIR/suggest-self.rs:21:9 | LL | this.x @@ -7,7 +7,7 @@ LL | this.x | not found in this scope | help: you might have meant to use `self` here instead -error[E0425]: cannot find value `this` +error[E0425]: cannot find value `this` in this scope --> $DIR/suggest-self.rs:26:9 | LL | this.foo() @@ -16,7 +16,7 @@ LL | this.foo() | not found in this scope | help: you might have meant to use `self` here instead -error[E0425]: cannot find value `my` +error[E0425]: cannot find value `my` in this scope --> $DIR/suggest-self.rs:31:9 | LL | my.bar() diff --git a/tests/ui/sized/ensure-overriding-bindings-in-pattern-with-ty-err-doesnt-ice.stderr b/tests/ui/sized/ensure-overriding-bindings-in-pattern-with-ty-err-doesnt-ice.stderr index 1b3c6641e194d..fc431eb14127f 100644 --- a/tests/ui/sized/ensure-overriding-bindings-in-pattern-with-ty-err-doesnt-ice.stderr +++ b/tests/ui/sized/ensure-overriding-bindings-in-pattern-with-ty-err-doesnt-ice.stderr @@ -4,7 +4,7 @@ error: expected a pattern, found an expression LL | let str::<{fn str() { let str::T>>::as_bytes; }}, T>::as_bytes; | ^^^^^^^^^^^^^^^^^^ arbitrary expressions are not allowed in patterns -error[E0412]: cannot find type `T` +error[E0412]: cannot find type `T` in this scope --> $DIR/ensure-overriding-bindings-in-pattern-with-ty-err-doesnt-ice.rs:2:55 | LL | let str::<{fn str() { let str::T>>::as_bytes; }}, T>::as_bytes; diff --git a/tests/ui/span/drop-location-span-error-rust-2021-incompatible-closure-captures-96258.stderr b/tests/ui/span/drop-location-span-error-rust-2021-incompatible-closure-captures-96258.stderr index bf8191e5fb425..60433e1c28467 100644 --- a/tests/ui/span/drop-location-span-error-rust-2021-incompatible-closure-captures-96258.stderr +++ b/tests/ui/span/drop-location-span-error-rust-2021-incompatible-closure-captures-96258.stderr @@ -7,7 +7,7 @@ LL | pub(crate) async fn new( = help: pass `--edition 2021` to `rustc` = note: for more on editions, read https://doc.rust-lang.org/edition-guide -error[E0412]: cannot find type `Duration` +error[E0412]: cannot find type `Duration` in this scope --> $DIR/drop-location-span-error-rust-2021-incompatible-closure-captures-96258.rs:10:19 | LL | interval: Duration, diff --git a/tests/ui/span/suggestion-raw-68962.stderr b/tests/ui/span/suggestion-raw-68962.stderr index 2a76514405770..2e25f5cbdf58d 100644 --- a/tests/ui/span/suggestion-raw-68962.stderr +++ b/tests/ui/span/suggestion-raw-68962.stderr @@ -1,10 +1,10 @@ -error[E0425]: cannot find value `fina` +error[E0425]: cannot find value `fina` in this scope --> $DIR/suggestion-raw-68962.rs:7:5 | LL | fina; | ^^^^ help: a local variable with a similar name exists: `r#final` -error[E0425]: cannot find function `f` +error[E0425]: cannot find function `f` in this scope --> $DIR/suggestion-raw-68962.rs:10:5 | LL | fn r#fn() {} diff --git a/tests/ui/span/typo-suggestion.stderr b/tests/ui/span/typo-suggestion.stderr index 5d7c41319a7e4..61d4e06119c4f 100644 --- a/tests/ui/span/typo-suggestion.stderr +++ b/tests/ui/span/typo-suggestion.stderr @@ -1,10 +1,10 @@ -error[E0425]: cannot find value `bar` +error[E0425]: cannot find value `bar` in this scope --> $DIR/typo-suggestion.rs:5:26 | LL | println!("Hello {}", bar); | ^^^ not found in this scope -error[E0425]: cannot find value `fob` +error[E0425]: cannot find value `fob` in this scope --> $DIR/typo-suggestion.rs:8:26 | LL | println!("Hello {}", fob); diff --git a/tests/ui/specialization/issue-68830-spurious-diagnostics.stderr b/tests/ui/specialization/issue-68830-spurious-diagnostics.stderr index dff73f6f09d1c..13f6ae0805dad 100644 --- a/tests/ui/specialization/issue-68830-spurious-diagnostics.stderr +++ b/tests/ui/specialization/issue-68830-spurious-diagnostics.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `MissingType` +error[E0412]: cannot find type `MissingType` in this scope --> $DIR/issue-68830-spurious-diagnostics.rs:8:10 | LL | err: MissingType diff --git a/tests/ui/specialization/min_specialization/impl-on-nonexisting.stderr b/tests/ui/specialization/min_specialization/impl-on-nonexisting.stderr index 934a502091972..85b492c0503b2 100644 --- a/tests/ui/specialization/min_specialization/impl-on-nonexisting.stderr +++ b/tests/ui/specialization/min_specialization/impl-on-nonexisting.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `NonExistent` +error[E0412]: cannot find type `NonExistent` in this scope --> $DIR/impl-on-nonexisting.rs:4:16 | LL | impl Trait for NonExistent {} diff --git a/tests/ui/stability-attribute/issue-109177.rs b/tests/ui/stability-attribute/issue-109177.rs index f7d4afd256ee6..8bfa030fce099 100644 --- a/tests/ui/stability-attribute/issue-109177.rs +++ b/tests/ui/stability-attribute/issue-109177.rs @@ -5,7 +5,7 @@ extern crate similar_unstable_method; fn main() { // FIXME: this function should not suggest the `foo` function. similar_unstable_method::foo1(); - //~^ ERROR cannot find function `foo1` [E0425] + //~^ ERROR cannot find function `foo1` let foo = similar_unstable_method::Foo; foo.foo1(); diff --git a/tests/ui/stability-attribute/issue-109177.stderr b/tests/ui/stability-attribute/issue-109177.stderr index d0ed578887197..9c2ac591ace05 100644 --- a/tests/ui/stability-attribute/issue-109177.stderr +++ b/tests/ui/stability-attribute/issue-109177.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find function `foo1` +error[E0425]: cannot find function `foo1` in crate `similar_unstable_method` --> $DIR/issue-109177.rs:7:30 | LL | similar_unstable_method::foo1(); diff --git a/tests/ui/stability-attribute/unresolved_stability_lint.stderr b/tests/ui/stability-attribute/unresolved_stability_lint.stderr index f7c29495f7f44..51780d2088099 100644 --- a/tests/ui/stability-attribute/unresolved_stability_lint.stderr +++ b/tests/ui/stability-attribute/unresolved_stability_lint.stderr @@ -1,4 +1,4 @@ -error[E0405]: cannot find trait `Foo` +error[E0405]: cannot find trait `Foo` in this scope --> $DIR/unresolved_stability_lint.rs:5:6 | LL | impl Foo for () {} diff --git a/tests/ui/structs/ice-struct-tail-normalization-113272.stderr b/tests/ui/structs/ice-struct-tail-normalization-113272.stderr index be8be757ef753..a205eb80f5c0a 100644 --- a/tests/ui/structs/ice-struct-tail-normalization-113272.stderr +++ b/tests/ui/structs/ice-struct-tail-normalization-113272.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `Missing` +error[E0412]: cannot find type `Missing` in this scope --> $DIR/ice-struct-tail-normalization-113272.rs:5:25 | LL | impl Trait for () where Missing: Trait {} diff --git a/tests/ui/structs/struct-fields-shorthand-unresolved.stderr b/tests/ui/structs/struct-fields-shorthand-unresolved.stderr index e99312f77ec40..b485c17c1b270 100644 --- a/tests/ui/structs/struct-fields-shorthand-unresolved.stderr +++ b/tests/ui/structs/struct-fields-shorthand-unresolved.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `y` +error[E0425]: cannot find value `y` in this scope --> $DIR/struct-fields-shorthand-unresolved.rs:10:9 | LL | y diff --git a/tests/ui/structs/unresolved-struct-with-fru.stderr b/tests/ui/structs/unresolved-struct-with-fru.stderr index df44538bbddda..9902c3ed35711 100644 --- a/tests/ui/structs/unresolved-struct-with-fru.stderr +++ b/tests/ui/structs/unresolved-struct-with-fru.stderr @@ -1,4 +1,4 @@ -error[E0422]: cannot find struct, variant or union type `Oops` +error[E0422]: cannot find struct, variant or union type `Oops` in this scope --> $DIR/unresolved-struct-with-fru.rs:9:18 | LL | let s2 = Oops { a: 2, ..s1 }; diff --git a/tests/ui/suggestions/assoc-const-without-self.stderr b/tests/ui/suggestions/assoc-const-without-self.stderr index b31ea8c6b1ef1..5a9fba8a0e47b 100644 --- a/tests/ui/suggestions/assoc-const-without-self.stderr +++ b/tests/ui/suggestions/assoc-const-without-self.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `A_CONST` +error[E0425]: cannot find value `A_CONST` in this scope --> $DIR/assoc-const-without-self.rs:7:9 | LL | A_CONST diff --git a/tests/ui/suggestions/assoc-type-in-method-return.stderr b/tests/ui/suggestions/assoc-type-in-method-return.stderr index 5a53eeb8d6134..f83da79097009 100644 --- a/tests/ui/suggestions/assoc-type-in-method-return.stderr +++ b/tests/ui/suggestions/assoc-type-in-method-return.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `Bla` +error[E0412]: cannot find type `Bla` in this scope --> $DIR/assoc-type-in-method-return.rs:3:25 | LL | fn to_bla(&self) -> Bla; diff --git a/tests/ui/suggestions/assoc_fn_without_self.stderr b/tests/ui/suggestions/assoc_fn_without_self.stderr index ba6dea8f7deb5..9cee7c7ee5ee8 100644 --- a/tests/ui/suggestions/assoc_fn_without_self.stderr +++ b/tests/ui/suggestions/assoc_fn_without_self.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find function `foo` +error[E0425]: cannot find function `foo` in this scope --> $DIR/assoc_fn_without_self.rs:16:9 | LL | foo(); @@ -9,7 +9,7 @@ help: consider using the associated function on `Self` LL | Self::foo(); | ++++++ -error[E0425]: cannot find function `bar` +error[E0425]: cannot find function `bar` in this scope --> $DIR/assoc_fn_without_self.rs:17:9 | LL | fn bar(&self) {} @@ -18,7 +18,7 @@ LL | fn bar(&self) {} LL | bar(); | ^^^ not found in this scope -error[E0425]: cannot find function `baz` +error[E0425]: cannot find function `baz` in this scope --> $DIR/assoc_fn_without_self.rs:18:9 | LL | baz(2, 3); @@ -29,13 +29,13 @@ help: consider using the associated function on `Self` LL | Self::baz(2, 3); | ++++++ -error[E0425]: cannot find function `foo` +error[E0425]: cannot find function `foo` in this scope --> $DIR/assoc_fn_without_self.rs:14:13 | LL | foo(); | ^^^ not found in this scope -error[E0425]: cannot find function `foo` +error[E0425]: cannot find function `foo` in this scope --> $DIR/assoc_fn_without_self.rs:24:9 | LL | foo(); @@ -46,7 +46,7 @@ help: consider using the associated function on `Self` LL | Self::foo(); | ++++++ -error[E0425]: cannot find function `bar` +error[E0425]: cannot find function `bar` in this scope --> $DIR/assoc_fn_without_self.rs:25:9 | LL | bar(); @@ -57,7 +57,7 @@ help: consider using the method on `Self` LL | self.bar(); | +++++ -error[E0425]: cannot find function `baz` +error[E0425]: cannot find function `baz` in this scope --> $DIR/assoc_fn_without_self.rs:26:9 | LL | baz(2, 3); @@ -68,7 +68,7 @@ help: consider using the associated function on `Self` LL | Self::baz(2, 3); | ++++++ -error[E0425]: cannot find function `foo` +error[E0425]: cannot find function `foo` in this scope --> $DIR/assoc_fn_without_self.rs:22:13 | LL | foo(); diff --git a/tests/ui/suggestions/attribute-typos.stderr b/tests/ui/suggestions/attribute-typos.stderr index 23566efcf84ac..1791d8c7ff4bb 100644 --- a/tests/ui/suggestions/attribute-typos.stderr +++ b/tests/ui/suggestions/attribute-typos.stderr @@ -4,7 +4,7 @@ error: attributes starting with `rustc` are reserved for use by the `rustc` comp LL | #[rustc_err] | ^^^^^^^^^ -error: cannot find attribute `rustc_err` +error: cannot find attribute `rustc_err` in this scope --> $DIR/attribute-typos.rs:7:3 | LL | #[rustc_err] @@ -13,7 +13,7 @@ LL | #[rustc_err] | not found in this scope | help: a built-in attribute with a similar name exists: `rustc_error` -error: cannot find attribute `tests` +error: cannot find attribute `tests` in this scope --> $DIR/attribute-typos.rs:4:3 | LL | #[tests] @@ -25,7 +25,7 @@ LL | #[tests] | = note: similarly named attribute macro `test` defined here -error: cannot find attribute `deprcated` +error: cannot find attribute `deprcated` in this scope --> $DIR/attribute-typos.rs:1:3 | LL | #[deprcated] diff --git a/tests/ui/suggestions/bool_typo_err_suggest.stderr b/tests/ui/suggestions/bool_typo_err_suggest.stderr index 0c41080e7c07b..8d59ed63e5432 100644 --- a/tests/ui/suggestions/bool_typo_err_suggest.stderr +++ b/tests/ui/suggestions/bool_typo_err_suggest.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `True` +error[E0425]: cannot find value `True` in this scope --> $DIR/bool_typo_err_suggest.rs:5:13 | LL | let x = True; @@ -9,7 +9,7 @@ help: you may want to use a bool value instead LL | let x = true; | ~~~~ -error[E0425]: cannot find value `False` +error[E0425]: cannot find value `False` in this scope --> $DIR/bool_typo_err_suggest.rs:9:13 | LL | let y = False; diff --git a/tests/ui/suggestions/dont-suggest-foreign-doc-hidden.stderr b/tests/ui/suggestions/dont-suggest-foreign-doc-hidden.stderr index 071d17c614763..7fb4d95ff9bf5 100644 --- a/tests/ui/suggestions/dont-suggest-foreign-doc-hidden.stderr +++ b/tests/ui/suggestions/dont-suggest-foreign-doc-hidden.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `Foo` +error[E0412]: cannot find type `Foo` in this scope --> $DIR/dont-suggest-foreign-doc-hidden.rs:11:16 | LL | pub fn test(_: Foo) {} @@ -9,7 +9,7 @@ help: consider importing this struct LL + use local::Foo; | -error[E0412]: cannot find type `Bar` +error[E0412]: cannot find type `Bar` in this scope --> $DIR/dont-suggest-foreign-doc-hidden.rs:14:17 | LL | pub fn test2(_: Bar) {} diff --git a/tests/ui/suggestions/fn-to-method-deeply-nested.stderr b/tests/ui/suggestions/fn-to-method-deeply-nested.stderr index 9c7850a7e497c..ce813ea7abae8 100644 --- a/tests/ui/suggestions/fn-to-method-deeply-nested.stderr +++ b/tests/ui/suggestions/fn-to-method-deeply-nested.stderr @@ -1,34 +1,34 @@ -error[E0425]: cannot find value `z` +error[E0425]: cannot find value `z` in this scope --> $DIR/fn-to-method-deeply-nested.rs:8:9 | LL | z???????????????????????????????????????????????????????????????????????????????????????? | ^ not found in this scope -error[E0425]: cannot find function `e` +error[E0425]: cannot find function `e` in this scope --> $DIR/fn-to-method-deeply-nested.rs:2:13 | LL | a(b(c(d(e( | ^ not found in this scope -error[E0425]: cannot find function `d` +error[E0425]: cannot find function `d` in this scope --> $DIR/fn-to-method-deeply-nested.rs:2:11 | LL | a(b(c(d(e( | ^ not found in this scope -error[E0425]: cannot find function `c` +error[E0425]: cannot find function `c` in this scope --> $DIR/fn-to-method-deeply-nested.rs:2:9 | LL | a(b(c(d(e( | ^ not found in this scope -error[E0425]: cannot find function `b` +error[E0425]: cannot find function `b` in this scope --> $DIR/fn-to-method-deeply-nested.rs:2:7 | LL | a(b(c(d(e( | ^ not found in this scope -error[E0425]: cannot find function `a` +error[E0425]: cannot find function `a` in this scope --> $DIR/fn-to-method-deeply-nested.rs:2:5 | LL | a(b(c(d(e( diff --git a/tests/ui/suggestions/fn-to-method.stderr b/tests/ui/suggestions/fn-to-method.stderr index 1a29cf163ae00..36c17e60d3572 100644 --- a/tests/ui/suggestions/fn-to-method.stderr +++ b/tests/ui/suggestions/fn-to-method.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find function `cmp` +error[E0425]: cannot find function `cmp` in this scope --> $DIR/fn-to-method.rs:8:13 | LL | let x = cmp(&1, &2); @@ -9,7 +9,7 @@ help: use the `.` operator to call the method `Ord::cmp` on `&{integer}` LL | let x = (&1).cmp(&2); | ~ ~~~~~~~~~ -error[E0425]: cannot find function `len` +error[E0425]: cannot find function `len` in this scope --> $DIR/fn-to-method.rs:12:13 | LL | let y = len([1, 2, 3]); @@ -21,7 +21,7 @@ LL - let y = len([1, 2, 3]); LL + let y = [1, 2, 3].len(); | -error[E0425]: cannot find function `bar` +error[E0425]: cannot find function `bar` in this scope --> $DIR/fn-to-method.rs:16:13 | LL | let z = bar(Foo); diff --git a/tests/ui/suggestions/ice-unwrap-probe-many-result-125876.stderr b/tests/ui/suggestions/ice-unwrap-probe-many-result-125876.stderr index ea0f50d4df22f..d610a3b7cadd2 100644 --- a/tests/ui/suggestions/ice-unwrap-probe-many-result-125876.stderr +++ b/tests/ui/suggestions/ice-unwrap-probe-many-result-125876.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `num` +error[E0425]: cannot find value `num` in this scope --> $DIR/ice-unwrap-probe-many-result-125876.rs:4:24 | LL | std::ptr::from_ref(num).cast_mut().as_deref(); diff --git a/tests/ui/suggestions/if-let-typo.stderr b/tests/ui/suggestions/if-let-typo.stderr index cc73bfd187735..02148b7f7adfd 100644 --- a/tests/ui/suggestions/if-let-typo.stderr +++ b/tests/ui/suggestions/if-let-typo.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `x` +error[E0425]: cannot find value `x` in this scope --> $DIR/if-let-typo.rs:4:13 | LL | if Some(x) = foo {} @@ -9,7 +9,7 @@ help: you might have meant to use pattern matching LL | if let Some(x) = foo {} | +++ -error[E0425]: cannot find value `x` +error[E0425]: cannot find value `x` in this scope --> $DIR/if-let-typo.rs:10:8 | LL | if x = 5 {} diff --git a/tests/ui/suggestions/issue-104086-suggest-let.stderr b/tests/ui/suggestions/issue-104086-suggest-let.stderr index ca54d93b1b424..fb4ea3121ac67 100644 --- a/tests/ui/suggestions/issue-104086-suggest-let.stderr +++ b/tests/ui/suggestions/issue-104086-suggest-let.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `x` +error[E0425]: cannot find value `x` in this scope --> $DIR/issue-104086-suggest-let.rs:2:5 | LL | x = x = x; @@ -9,19 +9,19 @@ help: you might have meant to introduce a new binding LL | let x = x = x; | +++ -error[E0425]: cannot find value `x` +error[E0425]: cannot find value `x` in this scope --> $DIR/issue-104086-suggest-let.rs:2:9 | LL | x = x = x; | ^ not found in this scope -error[E0425]: cannot find value `x` +error[E0425]: cannot find value `x` in this scope --> $DIR/issue-104086-suggest-let.rs:2:13 | LL | x = x = x; | ^ not found in this scope -error[E0425]: cannot find value `x` +error[E0425]: cannot find value `x` in this scope --> $DIR/issue-104086-suggest-let.rs:7:5 | LL | x = y = y = y; @@ -32,25 +32,25 @@ help: you might have meant to introduce a new binding LL | let x = y = y = y; | +++ -error[E0425]: cannot find value `y` +error[E0425]: cannot find value `y` in this scope --> $DIR/issue-104086-suggest-let.rs:7:9 | LL | x = y = y = y; | ^ not found in this scope -error[E0425]: cannot find value `y` +error[E0425]: cannot find value `y` in this scope --> $DIR/issue-104086-suggest-let.rs:7:13 | LL | x = y = y = y; | ^ not found in this scope -error[E0425]: cannot find value `y` +error[E0425]: cannot find value `y` in this scope --> $DIR/issue-104086-suggest-let.rs:7:17 | LL | x = y = y = y; | ^ not found in this scope -error[E0425]: cannot find value `x` +error[E0425]: cannot find value `x` in this scope --> $DIR/issue-104086-suggest-let.rs:13:5 | LL | x = y = y; @@ -61,19 +61,19 @@ help: you might have meant to introduce a new binding LL | let x = y = y; | +++ -error[E0425]: cannot find value `y` +error[E0425]: cannot find value `y` in this scope --> $DIR/issue-104086-suggest-let.rs:13:9 | LL | x = y = y; | ^ not found in this scope -error[E0425]: cannot find value `y` +error[E0425]: cannot find value `y` in this scope --> $DIR/issue-104086-suggest-let.rs:13:13 | LL | x = y = y; | ^ not found in this scope -error[E0425]: cannot find value `x` +error[E0425]: cannot find value `x` in this scope --> $DIR/issue-104086-suggest-let.rs:18:5 | LL | x = x = y; @@ -84,19 +84,19 @@ help: you might have meant to introduce a new binding LL | let x = x = y; | +++ -error[E0425]: cannot find value `x` +error[E0425]: cannot find value `x` in this scope --> $DIR/issue-104086-suggest-let.rs:18:9 | LL | x = x = y; | ^ not found in this scope -error[E0425]: cannot find value `y` +error[E0425]: cannot find value `y` in this scope --> $DIR/issue-104086-suggest-let.rs:18:13 | LL | x = x = y; | ^ not found in this scope -error[E0425]: cannot find value `x` +error[E0425]: cannot find value `x` in this scope --> $DIR/issue-104086-suggest-let.rs:23:5 | LL | x = x; // will suggest add `let` @@ -107,13 +107,13 @@ help: you might have meant to introduce a new binding LL | let x = x; // will suggest add `let` | +++ -error[E0425]: cannot find value `x` +error[E0425]: cannot find value `x` in this scope --> $DIR/issue-104086-suggest-let.rs:23:9 | LL | x = x; // will suggest add `let` | ^ not found in this scope -error[E0425]: cannot find value `x` +error[E0425]: cannot find value `x` in this scope --> $DIR/issue-104086-suggest-let.rs:27:5 | LL | x = y // will suggest add `let` @@ -124,7 +124,7 @@ help: you might have meant to introduce a new binding LL | let x = y // will suggest add `let` | +++ -error[E0425]: cannot find value `y` +error[E0425]: cannot find value `y` in this scope --> $DIR/issue-104086-suggest-let.rs:27:9 | LL | x = y // will suggest add `let` diff --git a/tests/ui/suggestions/issue-104287.stderr b/tests/ui/suggestions/issue-104287.stderr index 7696b0dd7f569..ed59b2e7a2d3b 100644 --- a/tests/ui/suggestions/issue-104287.stderr +++ b/tests/ui/suggestions/issue-104287.stderr @@ -12,7 +12,7 @@ note: method defined here, with 0 generic parameters LL | fn foo(&self) {} | ^^^ -error[E0425]: cannot find function `foo` +error[E0425]: cannot find function `foo` in this scope --> $DIR/issue-104287.rs:10:5 | LL | foo::<()>(x); diff --git a/tests/ui/suggestions/issue-66968-suggest-sorted-words.stderr b/tests/ui/suggestions/issue-66968-suggest-sorted-words.stderr index fd88444e8f9f9..ce0087fbfcbab 100644 --- a/tests/ui/suggestions/issue-66968-suggest-sorted-words.stderr +++ b/tests/ui/suggestions/issue-66968-suggest-sorted-words.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `a_variable_longer_name` +error[E0425]: cannot find value `a_variable_longer_name` in this scope --> $DIR/issue-66968-suggest-sorted-words.rs:3:20 | LL | println!("{}", a_variable_longer_name); diff --git a/tests/ui/suggestions/method-access-to-range-literal-typo.stderr b/tests/ui/suggestions/method-access-to-range-literal-typo.stderr index 28ae1a6b57f16..b1fb0254cd9cf 100644 --- a/tests/ui/suggestions/method-access-to-range-literal-typo.stderr +++ b/tests/ui/suggestions/method-access-to-range-literal-typo.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find function `foo` +error[E0425]: cannot find function `foo` in this scope --> $DIR/method-access-to-range-literal-typo.rs:26:22 | LL | self.option..foo().get(0) diff --git a/tests/ui/suggestions/no-extern-crate-in-type.stderr b/tests/ui/suggestions/no-extern-crate-in-type.stderr index 8dce68802f55d..384b17d1e2b48 100644 --- a/tests/ui/suggestions/no-extern-crate-in-type.stderr +++ b/tests/ui/suggestions/no-extern-crate-in-type.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `Foo` +error[E0412]: cannot find type `Foo` in this scope --> $DIR/no-extern-crate-in-type.rs:5:22 | LL | type Output = Option; diff --git a/tests/ui/suggestions/non_ascii_ident.stderr b/tests/ui/suggestions/non_ascii_ident.stderr index f084eba3afc84..fdcc64aef3681 100644 --- a/tests/ui/suggestions/non_ascii_ident.stderr +++ b/tests/ui/suggestions/non_ascii_ident.stderr @@ -1,10 +1,10 @@ -error[E0425]: cannot find value `读文` +error[E0425]: cannot find value `读文` in this scope --> $DIR/non_ascii_ident.rs:3:13 | LL | let _ = 读文; | ^^^^ not found in this scope -error[E0425]: cannot find function `读文` +error[E0425]: cannot find function `读文` in this scope --> $DIR/non_ascii_ident.rs:6:5 | LL | 读文(f); diff --git a/tests/ui/suggestions/raw-name-use-suggestion.stderr b/tests/ui/suggestions/raw-name-use-suggestion.stderr index 2ebfc27a9e3ba..fb070ffc33230 100644 --- a/tests/ui/suggestions/raw-name-use-suggestion.stderr +++ b/tests/ui/suggestions/raw-name-use-suggestion.stderr @@ -20,7 +20,7 @@ help: escape `let` to use it as an identifier LL | foo::r#let(); | ++ -error[E0425]: cannot find function `r#break` +error[E0425]: cannot find function `r#break` in this scope --> $DIR/raw-name-use-suggestion.rs:8:5 | LL | r#break(); diff --git a/tests/ui/suggestions/silenced-binding-typo.stderr b/tests/ui/suggestions/silenced-binding-typo.stderr index d57909036d70d..a1e8b9e30d4b7 100644 --- a/tests/ui/suggestions/silenced-binding-typo.stderr +++ b/tests/ui/suggestions/silenced-binding-typo.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `x` +error[E0425]: cannot find value `x` in this scope --> $DIR/silenced-binding-typo.rs:4:14 | LL | let _x = 42; diff --git a/tests/ui/suggestions/suggest-let-for-assignment.stderr b/tests/ui/suggestions/suggest-let-for-assignment.stderr index 9dbb02b8afda5..8d97dbeb14a7a 100644 --- a/tests/ui/suggestions/suggest-let-for-assignment.stderr +++ b/tests/ui/suggestions/suggest-let-for-assignment.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `demo` +error[E0425]: cannot find value `demo` in this scope --> $DIR/suggest-let-for-assignment.rs:4:5 | LL | demo = 1; @@ -9,13 +9,13 @@ help: you might have meant to introduce a new binding LL | let demo = 1; | +++ -error[E0425]: cannot find value `demo` +error[E0425]: cannot find value `demo` in this scope --> $DIR/suggest-let-for-assignment.rs:5:10 | LL | dbg!(demo); | ^^^^ not found in this scope -error[E0425]: cannot find value `x` +error[E0425]: cannot find value `x` in this scope --> $DIR/suggest-let-for-assignment.rs:7:5 | LL | x = "x"; @@ -26,13 +26,13 @@ help: you might have meant to introduce a new binding LL | let x = "x"; | +++ -error[E0425]: cannot find value `x` +error[E0425]: cannot find value `x` in this scope --> $DIR/suggest-let-for-assignment.rs:8:23 | LL | println!("x: {}", x); | ^ not found in this scope -error[E0425]: cannot find value `let_some_variable` +error[E0425]: cannot find value `let_some_variable` in this scope --> $DIR/suggest-let-for-assignment.rs:10:5 | LL | let_some_variable = 6; @@ -43,13 +43,13 @@ help: you might have meant to introduce a new binding LL | let some_variable = 6; | ~~~~~~~~~~~~~~~~~ -error[E0425]: cannot find value `some_variable` +error[E0425]: cannot find value `some_variable` in this scope --> $DIR/suggest-let-for-assignment.rs:11:35 | LL | println!("some_variable: {}", some_variable); | ^^^^^^^^^^^^^ not found in this scope -error[E0425]: cannot find value `letother_variable` +error[E0425]: cannot find value `letother_variable` in this scope --> $DIR/suggest-let-for-assignment.rs:13:5 | LL | letother_variable = 6; @@ -60,19 +60,19 @@ help: you might have meant to introduce a new binding LL | let other_variable = 6; | ~~~~~~~~~~~~~~~~~~ -error[E0425]: cannot find value `other_variable` +error[E0425]: cannot find value `other_variable` in this scope --> $DIR/suggest-let-for-assignment.rs:14:36 | LL | println!("other_variable: {}", other_variable); | ^^^^^^^^^^^^^^ not found in this scope -error[E0425]: cannot find value `x` +error[E0425]: cannot find value `x` in this scope --> $DIR/suggest-let-for-assignment.rs:16:8 | LL | if x == "x" { | ^ not found in this scope -error[E0425]: cannot find value `y` +error[E0425]: cannot find value `y` in this scope --> $DIR/suggest-let-for-assignment.rs:21:5 | LL | y = 1 + 2; @@ -83,7 +83,7 @@ help: you might have meant to introduce a new binding LL | let y = 1 + 2; | +++ -error[E0425]: cannot find value `y` +error[E0425]: cannot find value `y` in this scope --> $DIR/suggest-let-for-assignment.rs:22:23 | LL | println!("y: {}", y); diff --git a/tests/ui/suggestions/suggest_print_over_printf.stderr b/tests/ui/suggestions/suggest_print_over_printf.stderr index b81fc80599ec4..8a79745133c93 100644 --- a/tests/ui/suggestions/suggest_print_over_printf.stderr +++ b/tests/ui/suggestions/suggest_print_over_printf.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find function `printf` +error[E0425]: cannot find function `printf` in this scope --> $DIR/suggest_print_over_printf.rs:5:5 | LL | printf("%d", x); diff --git a/tests/ui/suggestions/type-ascription-instead-of-path-in-type.stderr b/tests/ui/suggestions/type-ascription-instead-of-path-in-type.stderr index c675f98c51033..56b6a69a283f4 100644 --- a/tests/ui/suggestions/type-ascription-instead-of-path-in-type.stderr +++ b/tests/ui/suggestions/type-ascription-instead-of-path-in-type.stderr @@ -1,4 +1,4 @@ -error[E0405]: cannot find trait `B` +error[E0405]: cannot find trait `B` in this scope --> $DIR/type-ascription-instead-of-path-in-type.rs:6:18 | LL | let _: Vec = A::B; diff --git a/tests/ui/suggestions/type-not-found-in-adt-field.stderr b/tests/ui/suggestions/type-not-found-in-adt-field.stderr index 77c4c5b73d757..934ba87bbaa88 100644 --- a/tests/ui/suggestions/type-not-found-in-adt-field.stderr +++ b/tests/ui/suggestions/type-not-found-in-adt-field.stderr @@ -1,10 +1,10 @@ -error[E0412]: cannot find type `Someunknownname` +error[E0412]: cannot find type `Someunknownname` in this scope --> $DIR/type-not-found-in-adt-field.rs:2:12 | LL | m: Vec>, | ^^^^^^^^^^^^^^^ not found in this scope -error[E0412]: cannot find type `K` +error[E0412]: cannot find type `K` in this scope --> $DIR/type-not-found-in-adt-field.rs:6:8 | LL | m: K, diff --git a/tests/ui/suggestions/while-let-typo.stderr b/tests/ui/suggestions/while-let-typo.stderr index abc9fe2c5045c..69a7e5761d421 100644 --- a/tests/ui/suggestions/while-let-typo.stderr +++ b/tests/ui/suggestions/while-let-typo.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `x` +error[E0425]: cannot find value `x` in this scope --> $DIR/while-let-typo.rs:4:16 | LL | while Some(x) = foo {} @@ -9,7 +9,7 @@ help: you might have meant to use pattern matching LL | while let Some(x) = foo {} | +++ -error[E0425]: cannot find value `x` +error[E0425]: cannot find value `x` in this scope --> $DIR/while-let-typo.rs:8:11 | LL | while x = 5 {} diff --git a/tests/ui/tool-attributes/tool-attributes-misplaced-1.stderr b/tests/ui/tool-attributes/tool-attributes-misplaced-1.stderr index 39c7d04ced3e6..c7ccf370915fd 100644 --- a/tests/ui/tool-attributes/tool-attributes-misplaced-1.stderr +++ b/tests/ui/tool-attributes/tool-attributes-misplaced-1.stderr @@ -1,10 +1,10 @@ -error: cannot find derive macro `rustfmt` +error: cannot find derive macro `rustfmt` in this scope --> $DIR/tool-attributes-misplaced-1.rs:4:10 | LL | #[derive(rustfmt)] | ^^^^^^^ not found in this scope -error: cannot find derive macro `rustfmt` +error: cannot find derive macro `rustfmt` in this scope --> $DIR/tool-attributes-misplaced-1.rs:4:10 | LL | #[derive(rustfmt)] @@ -12,13 +12,13 @@ LL | #[derive(rustfmt)] | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error: cannot find attribute `rustfmt` +error: cannot find attribute `rustfmt` in this scope --> $DIR/tool-attributes-misplaced-1.rs:9:3 | LL | #[rustfmt] | ^^^^^^^ not found in this scope -error: cannot find macro `rustfmt` +error: cannot find macro `rustfmt` in this scope --> $DIR/tool-attributes-misplaced-1.rs:15:5 | LL | rustfmt!(); diff --git a/tests/ui/track-diagnostics/track.stderr b/tests/ui/track-diagnostics/track.stderr index 462c741d41897..436f9ecf93dec 100644 --- a/tests/ui/track-diagnostics/track.stderr +++ b/tests/ui/track-diagnostics/track.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `rust` +error[E0425]: cannot find value `rust` in this scope --> $DIR/track.rs:LL:CC | LL | break rust diff --git a/tests/ui/track-diagnostics/track3.stderr b/tests/ui/track-diagnostics/track3.stderr index f7c451365279d..dc468d7e8eeb1 100644 --- a/tests/ui/track-diagnostics/track3.stderr +++ b/tests/ui/track-diagnostics/track3.stderr @@ -1,4 +1,4 @@ -error[E0422]: cannot find struct, variant or union type `Blah` +error[E0422]: cannot find struct, variant or union type `Blah` in this scope --> $DIR/track3.rs:LL:CC | LL | let _unimported = Blah { field: u8 }; diff --git a/tests/ui/trait-bounds/ice-unsized-struct-arg-issue-121612.stderr b/tests/ui/trait-bounds/ice-unsized-struct-arg-issue-121612.stderr index 29e77d55b5869..0be80e9479f0b 100644 --- a/tests/ui/trait-bounds/ice-unsized-struct-arg-issue-121612.stderr +++ b/tests/ui/trait-bounds/ice-unsized-struct-arg-issue-121612.stderr @@ -1,10 +1,10 @@ -error[E0412]: cannot find type `Idx` +error[E0412]: cannot find type `Idx` in this scope --> $DIR/ice-unsized-struct-arg-issue-121612.rs:5:30 | LL | struct MySlice Idx>(bool, T); | ^^^ not found in this scope -error[E0412]: cannot find type `Idx` +error[E0412]: cannot find type `Idx` in this scope --> $DIR/ice-unsized-struct-arg-issue-121612.rs:5:38 | LL | struct MySlice Idx>(bool, T); diff --git a/tests/ui/trait-bounds/ice-unsized-tuple-const-issue-121443.stderr b/tests/ui/trait-bounds/ice-unsized-tuple-const-issue-121443.stderr index a6db24897dc50..0e92979ccd507 100644 --- a/tests/ui/trait-bounds/ice-unsized-tuple-const-issue-121443.stderr +++ b/tests/ui/trait-bounds/ice-unsized-tuple-const-issue-121443.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `some_fn` +error[E0425]: cannot find value `some_fn` in this scope --> $DIR/ice-unsized-tuple-const-issue-121443.rs:8:18 | LL | const TEST: Fn = some_fn; diff --git a/tests/ui/trait-bounds/impl-bound-with-references-error.rs b/tests/ui/trait-bounds/impl-bound-with-references-error.rs index 1eb4360cbb5a6..b6a532297e5c1 100644 --- a/tests/ui/trait-bounds/impl-bound-with-references-error.rs +++ b/tests/ui/trait-bounds/impl-bound-with-references-error.rs @@ -10,7 +10,7 @@ impl From for LabelText //~^ ERROR conflicting implementations of trait `From` for type `LabelText` [E0119] where T: Into>, - //~^ ERROR cannot find type `Cow` [E0412] + //~^ ERROR cannot find type `Cow` { fn from(text: T) -> Self { LabelText::Plain(text.into()) //~ ERROR expected function, found `LabelText` diff --git a/tests/ui/trait-bounds/impl-bound-with-references-error.stderr b/tests/ui/trait-bounds/impl-bound-with-references-error.stderr index ed2da8268a04a..b3ac5544e38f5 100644 --- a/tests/ui/trait-bounds/impl-bound-with-references-error.stderr +++ b/tests/ui/trait-bounds/impl-bound-with-references-error.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `Cow` +error[E0412]: cannot find type `Cow` in this scope --> $DIR/impl-bound-with-references-error.rs:12:13 | LL | T: Into>, diff --git a/tests/ui/trait-bounds/shadowed-path-in-trait-bound-suggestion.stderr b/tests/ui/trait-bounds/shadowed-path-in-trait-bound-suggestion.stderr index c076219d9631d..e2a72697501f2 100644 --- a/tests/ui/trait-bounds/shadowed-path-in-trait-bound-suggestion.stderr +++ b/tests/ui/trait-bounds/shadowed-path-in-trait-bound-suggestion.stderr @@ -1,4 +1,4 @@ -error[E0405]: cannot find trait `Trait` +error[E0405]: cannot find trait `Trait` in `A` --> $DIR/shadowed-path-in-trait-bound-suggestion.rs:9:24 | LL | pub struct A(pub H); diff --git a/tests/ui/traits/associated_type_bound/assoc_type_bound_with_struct.stderr b/tests/ui/traits/associated_type_bound/assoc_type_bound_with_struct.stderr index f5503f5c09044..0020f9e416df2 100644 --- a/tests/ui/traits/associated_type_bound/assoc_type_bound_with_struct.stderr +++ b/tests/ui/traits/associated_type_bound/assoc_type_bound_with_struct.stderr @@ -70,7 +70,7 @@ help: a trait with a similar name exists LL | fn qux<'a, T: Bar>(_: &'a T) where <&'a T as Bar>::Baz: ToString { | ~~~~~~~~ -error[E0405]: cannot find trait `Unresolved` +error[E0405]: cannot find trait `Unresolved` in this scope --> $DIR/assoc_type_bound_with_struct.rs:19:31 | LL | fn issue_95327() where ::Assoc: String {} diff --git a/tests/ui/traits/dont-autoderef-ty-with-escaping-var.stderr b/tests/ui/traits/dont-autoderef-ty-with-escaping-var.stderr index 5d1d3671e194f..fecb05cade758 100644 --- a/tests/ui/traits/dont-autoderef-ty-with-escaping-var.stderr +++ b/tests/ui/traits/dont-autoderef-ty-with-escaping-var.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `unknown` +error[E0425]: cannot find value `unknown` in this scope --> $DIR/dont-autoderef-ty-with-escaping-var.rs:17:35 | LL | >::ref_foo(unknown); diff --git a/tests/ui/traits/dont-match-error-ty-with-calller-supplied-obligation-issue-121941.rs b/tests/ui/traits/dont-match-error-ty-with-calller-supplied-obligation-issue-121941.rs index f5d76683e6ab5..38daa0a576691 100644 --- a/tests/ui/traits/dont-match-error-ty-with-calller-supplied-obligation-issue-121941.rs +++ b/tests/ui/traits/dont-match-error-ty-with-calller-supplied-obligation-issue-121941.rs @@ -1,5 +1,5 @@ fn function() { - foo == 2; //~ ERROR cannot find value `foo` [E0425] + foo == 2; //~ ERROR cannot find value `foo` } fn main() {} diff --git a/tests/ui/traits/dont-match-error-ty-with-calller-supplied-obligation-issue-121941.stderr b/tests/ui/traits/dont-match-error-ty-with-calller-supplied-obligation-issue-121941.stderr index 09d593b03916e..2da731dcc4b14 100644 --- a/tests/ui/traits/dont-match-error-ty-with-calller-supplied-obligation-issue-121941.stderr +++ b/tests/ui/traits/dont-match-error-ty-with-calller-supplied-obligation-issue-121941.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `foo` +error[E0425]: cannot find value `foo` in this scope --> $DIR/dont-match-error-ty-with-calller-supplied-obligation-issue-121941.rs:2:5 | LL | foo == 2; diff --git a/tests/ui/traits/ignore-err-impls.stderr b/tests/ui/traits/ignore-err-impls.stderr index fa8899d4d6731..955e2d7804981 100644 --- a/tests/ui/traits/ignore-err-impls.stderr +++ b/tests/ui/traits/ignore-err-impls.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `Type` +error[E0412]: cannot find type `Type` in this scope --> $DIR/ignore-err-impls.rs:6:14 | LL | impl Generic for S {} diff --git a/tests/ui/traits/issue-22384.stderr b/tests/ui/traits/issue-22384.stderr index 4cc4dc71e6e04..36ea54d27c63b 100644 --- a/tests/ui/traits/issue-22384.stderr +++ b/tests/ui/traits/issue-22384.stderr @@ -1,4 +1,4 @@ -error[E0576]: cannot find associated type `foobar` +error[E0576]: cannot find associated type `foobar` in trait `Copy` --> $DIR/issue-22384.rs:6:21 | LL | <::foobar as Trait>::foo(); diff --git a/tests/ui/traits/issue-50480.stderr b/tests/ui/traits/issue-50480.stderr index b9fd86dd2f574..330b23b5755d7 100644 --- a/tests/ui/traits/issue-50480.stderr +++ b/tests/ui/traits/issue-50480.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `N` +error[E0412]: cannot find type `N` in this scope --> $DIR/issue-50480.rs:3:12 | LL | struct Foo(N, NotDefined, ::Item, Vec, String); @@ -9,13 +9,13 @@ help: you might be missing a type parameter LL | struct Foo(N, NotDefined, ::Item, Vec, String); | +++ -error[E0412]: cannot find type `NotDefined` +error[E0412]: cannot find type `NotDefined` in this scope --> $DIR/issue-50480.rs:3:15 | LL | struct Foo(N, NotDefined, ::Item, Vec, String); | ^^^^^^^^^^ not found in this scope -error[E0412]: cannot find type `N` +error[E0412]: cannot find type `N` in this scope --> $DIR/issue-50480.rs:3:12 | LL | struct Foo(N, NotDefined, ::Item, Vec, String); @@ -26,7 +26,7 @@ help: you might be missing a type parameter LL | struct Foo(N, NotDefined, ::Item, Vec, String); | +++ -error[E0412]: cannot find type `NotDefined` +error[E0412]: cannot find type `NotDefined` in this scope --> $DIR/issue-50480.rs:3:15 | LL | struct Foo(N, NotDefined, ::Item, Vec, String); @@ -37,7 +37,7 @@ help: you might be missing a type parameter LL | struct Foo(N, NotDefined, ::Item, Vec, String); | ++++++++++++ -error[E0412]: cannot find type `N` +error[E0412]: cannot find type `N` in this scope --> $DIR/issue-50480.rs:14:18 | LL | struct Bar(T, N, NotDefined, ::Item, Vec, String); @@ -54,7 +54,7 @@ help: you might be missing a type parameter LL | struct Bar(T, N, NotDefined, ::Item, Vec, String); | +++ -error[E0412]: cannot find type `NotDefined` +error[E0412]: cannot find type `NotDefined` in this scope --> $DIR/issue-50480.rs:14:21 | LL | struct Bar(T, N, NotDefined, ::Item, Vec, String); diff --git a/tests/ui/traits/issue-75627.stderr b/tests/ui/traits/issue-75627.stderr index 82ad7b4e1b3da..137985ee04641 100644 --- a/tests/ui/traits/issue-75627.stderr +++ b/tests/ui/traits/issue-75627.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `T` +error[E0412]: cannot find type `T` in this scope --> $DIR/issue-75627.rs:3:26 | LL | unsafe impl Send for Foo {} diff --git a/tests/ui/traits/issue-78372.stderr b/tests/ui/traits/issue-78372.stderr index 5daf86367ba7d..cdcb0cdf2593d 100644 --- a/tests/ui/traits/issue-78372.stderr +++ b/tests/ui/traits/issue-78372.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `PhantomData` +error[E0412]: cannot find type `PhantomData` in this scope --> $DIR/issue-78372.rs:2:23 | LL | struct Smaht(PhantomData); @@ -9,7 +9,7 @@ help: consider importing this struct LL + use std::marker::PhantomData; | -error[E0412]: cannot find type `U` +error[E0412]: cannot find type `U` in this scope --> $DIR/issue-78372.rs:3:31 | LL | impl DispatchFromDyn> for T {} @@ -26,7 +26,7 @@ help: you might be missing a type parameter LL | impl DispatchFromDyn> for T {} | +++ -error[E0412]: cannot find type `MISC` +error[E0412]: cannot find type `MISC` in this scope --> $DIR/issue-78372.rs:3:34 | LL | impl DispatchFromDyn> for T {} diff --git a/tests/ui/traits/next-solver/dont-normalize-proj-with-error.stderr b/tests/ui/traits/next-solver/dont-normalize-proj-with-error.stderr index dc5628392ce7a..576ede52aff2d 100644 --- a/tests/ui/traits/next-solver/dont-normalize-proj-with-error.stderr +++ b/tests/ui/traits/next-solver/dont-normalize-proj-with-error.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `TypeError` +error[E0412]: cannot find type `TypeError` in this scope --> $DIR/dont-normalize-proj-with-error.rs:17:20 | LL | fn type_error() -> TypeError { todo!() } diff --git a/tests/ui/traits/next-solver/issue-118950-root-region.stderr b/tests/ui/traits/next-solver/issue-118950-root-region.stderr index 2af6db20ddcf3..17da1f5247963 100644 --- a/tests/ui/traits/next-solver/issue-118950-root-region.stderr +++ b/tests/ui/traits/next-solver/issue-118950-root-region.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `Missing` +error[E0412]: cannot find type `Missing` in this scope --> $DIR/issue-118950-root-region.rs:19:55 | LL | impl Overlap fn(Assoc<'a, T>)> for T where Missing: Overlap {} diff --git a/tests/ui/traits/no-fallback-multiple-impls.stderr b/tests/ui/traits/no-fallback-multiple-impls.stderr index c2eae3e91a043..e38c432ca98c8 100644 --- a/tests/ui/traits/no-fallback-multiple-impls.stderr +++ b/tests/ui/traits/no-fallback-multiple-impls.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find function `missing` +error[E0425]: cannot find function `missing` in this scope --> $DIR/no-fallback-multiple-impls.rs:12:5 | LL | missing(); diff --git a/tests/ui/traits/non_lifetime_binders/binder-defaults-112547.stderr b/tests/ui/traits/non_lifetime_binders/binder-defaults-112547.stderr index 48a5126eedd39..edc55a3c8e68f 100644 --- a/tests/ui/traits/non_lifetime_binders/binder-defaults-112547.stderr +++ b/tests/ui/traits/non_lifetime_binders/binder-defaults-112547.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `V` +error[E0412]: cannot find type `V` in this scope --> $DIR/binder-defaults-112547.rs:8:4 | LL | }> V: IntoIterator diff --git a/tests/ui/traits/non_lifetime_binders/binder-defaults-118697.stderr b/tests/ui/traits/non_lifetime_binders/binder-defaults-118697.stderr index d0369eda5935e..6b93f52dbfcaa 100644 --- a/tests/ui/traits/non_lifetime_binders/binder-defaults-118697.stderr +++ b/tests/ui/traits/non_lifetime_binders/binder-defaults-118697.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `A` +error[E0412]: cannot find type `A` in this scope --> $DIR/binder-defaults-118697.rs:4:22 | LL | type T = dyn for Fn(()); diff --git a/tests/ui/traits/trait-selection-ice-84727.stderr b/tests/ui/traits/trait-selection-ice-84727.stderr index bfd4c1689d5d6..d4bc4163897c4 100644 --- a/tests/ui/traits/trait-selection-ice-84727.stderr +++ b/tests/ui/traits/trait-selection-ice-84727.stderr @@ -1,22 +1,22 @@ -error[E0412]: cannot find type `Color` +error[E0412]: cannot find type `Color` in this scope --> $DIR/trait-selection-ice-84727.rs:5:17 | LL | foreground: Color, | ^^^^^ not found in this scope -error[E0412]: cannot find type `Color` +error[E0412]: cannot find type `Color` in this scope --> $DIR/trait-selection-ice-84727.rs:7:17 | LL | background: Color, | ^^^^^ not found in this scope -error[E0412]: cannot find type `Color` +error[E0412]: cannot find type `Color` in this scope --> $DIR/trait-selection-ice-84727.rs:18:16 | LL | Self: Over, Cell>, | ^^^^^ not found in this scope -error[E0412]: cannot find type `NewBg` +error[E0412]: cannot find type `NewBg` in this scope --> $DIR/trait-selection-ice-84727.rs:32:27 | LL | fn over(self) -> Cell { diff --git a/tests/ui/transmutability/issue-101739-1.stderr b/tests/ui/transmutability/issue-101739-1.stderr index e587848c2a5c8..6f79bf7b42468 100644 --- a/tests/ui/transmutability/issue-101739-1.stderr +++ b/tests/ui/transmutability/issue-101739-1.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `Dst` +error[E0412]: cannot find type `Dst` in this scope --> $DIR/issue-101739-1.rs:8:9 | LL | Dst: BikeshedIntrinsicFrom, diff --git a/tests/ui/transmutability/malformed-program-gracefulness/unknown_dst.stderr b/tests/ui/transmutability/malformed-program-gracefulness/unknown_dst.stderr index d58974efb143d..9fa376bf4332b 100644 --- a/tests/ui/transmutability/malformed-program-gracefulness/unknown_dst.stderr +++ b/tests/ui/transmutability/malformed-program-gracefulness/unknown_dst.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `Dst` +error[E0412]: cannot find type `Dst` in this scope --> $DIR/unknown_dst.rs:18:36 | LL | assert::is_transmutable::(); diff --git a/tests/ui/transmutability/malformed-program-gracefulness/unknown_src.stderr b/tests/ui/transmutability/malformed-program-gracefulness/unknown_src.stderr index 685220e5ce80b..f2c7d9e1bcc15 100644 --- a/tests/ui/transmutability/malformed-program-gracefulness/unknown_src.stderr +++ b/tests/ui/transmutability/malformed-program-gracefulness/unknown_src.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `Src` +error[E0412]: cannot find type `Src` in this scope --> $DIR/unknown_src.rs:18:31 | LL | assert::is_transmutable::(); diff --git a/tests/ui/transmutability/malformed-program-gracefulness/unknown_src_field.stderr b/tests/ui/transmutability/malformed-program-gracefulness/unknown_src_field.stderr index c1995bfb02a1b..cabc7bcfef762 100644 --- a/tests/ui/transmutability/malformed-program-gracefulness/unknown_src_field.stderr +++ b/tests/ui/transmutability/malformed-program-gracefulness/unknown_src_field.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `Missing` +error[E0412]: cannot find type `Missing` in this scope --> $DIR/unknown_src_field.rs:18:27 | LL | #[repr(C)] struct Dst(Missing); diff --git a/tests/ui/tuple/tuple-struct-fields/test.stderr b/tests/ui/tuple/tuple-struct-fields/test.stderr index b5cce9a480924..bfa0b32fd458a 100644 --- a/tests/ui/tuple/tuple-struct-fields/test.stderr +++ b/tests/ui/tuple/tuple-struct-fields/test.stderr @@ -6,7 +6,7 @@ LL | struct S2(pub((foo)) ()); | | | help: missing `,` -error[E0412]: cannot find type `foo` +error[E0412]: cannot find type `foo` in this scope --> $DIR/test.rs:4:20 | LL | struct S2(pub((foo)) ()); diff --git a/tests/ui/tuple/tuple-struct-fields/test2.stderr b/tests/ui/tuple/tuple-struct-fields/test2.stderr index 97e67307d849b..784411aba8f8a 100644 --- a/tests/ui/tuple/tuple-struct-fields/test2.stderr +++ b/tests/ui/tuple/tuple-struct-fields/test2.stderr @@ -11,13 +11,13 @@ LL | define_struct! { (foo) } | = note: this error originates in the macro `define_struct` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0412]: cannot find type `foo` +error[E0412]: cannot find type `foo` in this scope --> $DIR/test2.rs:11:23 | LL | define_struct! { (foo) } | ^^^ not found in this scope -error[E0412]: cannot find type `foo` +error[E0412]: cannot find type `foo` in this scope --> $DIR/test2.rs:11:23 | LL | define_struct! { (foo) } diff --git a/tests/ui/tuple/tuple-struct-fields/test3.stderr b/tests/ui/tuple/tuple-struct-fields/test3.stderr index 6c0a05be33a5e..00b07c0315292 100644 --- a/tests/ui/tuple/tuple-struct-fields/test3.stderr +++ b/tests/ui/tuple/tuple-struct-fields/test3.stderr @@ -11,13 +11,13 @@ LL | define_struct! { foo } | = note: this error originates in the macro `define_struct` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0412]: cannot find type `foo` +error[E0412]: cannot find type `foo` in this scope --> $DIR/test3.rs:11:22 | LL | define_struct! { foo } | ^^^ not found in this scope -error[E0412]: cannot find type `foo` +error[E0412]: cannot find type `foo` in this scope --> $DIR/test3.rs:11:22 | LL | define_struct! { foo } diff --git a/tests/ui/type-alias-impl-trait/nested-impl-trait-in-tait.stderr b/tests/ui/type-alias-impl-trait/nested-impl-trait-in-tait.stderr index eca7205add50d..ca15b134a9947 100644 --- a/tests/ui/type-alias-impl-trait/nested-impl-trait-in-tait.stderr +++ b/tests/ui/type-alias-impl-trait/nested-impl-trait-in-tait.stderr @@ -14,7 +14,7 @@ help: consider introducing lifetime `'db` here LL | pub type Tait<'db> = impl Iterator; | +++++ -error[E0412]: cannot find type `LocalKey` +error[E0412]: cannot find type `LocalKey` in this scope --> $DIR/nested-impl-trait-in-tait.rs:3:44 | LL | pub type Tait = impl Iterator; diff --git a/tests/ui/type-alias/issue-62364-self-ty-arg.rs b/tests/ui/type-alias/issue-62364-self-ty-arg.rs index ec7b6baff49b3..0d5c7373e58f3 100644 --- a/tests/ui/type-alias/issue-62364-self-ty-arg.rs +++ b/tests/ui/type-alias/issue-62364-self-ty-arg.rs @@ -3,6 +3,6 @@ struct Struct { } type Alias<'a> = Struct<&'a Self>; -//~^ ERROR cannot find type `Self` [E0411] +//~^ ERROR cannot find type `Self` fn main() {} diff --git a/tests/ui/type-alias/issue-62364-self-ty-arg.stderr b/tests/ui/type-alias/issue-62364-self-ty-arg.stderr index 3389dfe27c414..26d93dcc27276 100644 --- a/tests/ui/type-alias/issue-62364-self-ty-arg.stderr +++ b/tests/ui/type-alias/issue-62364-self-ty-arg.stderr @@ -1,4 +1,4 @@ -error[E0411]: cannot find type `Self` +error[E0411]: cannot find type `Self` in this scope --> $DIR/issue-62364-self-ty-arg.rs:5:29 | LL | type Alias<'a> = Struct<&'a Self>; diff --git a/tests/ui/type/issue-7607-1.stderr b/tests/ui/type/issue-7607-1.stderr index 1b4fb5077b534..db4c8f25dbc43 100644 --- a/tests/ui/type/issue-7607-1.stderr +++ b/tests/ui/type/issue-7607-1.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `Fo` +error[E0412]: cannot find type `Fo` in this scope --> $DIR/issue-7607-1.rs:5:6 | LL | impl Fo { diff --git a/tests/ui/type/type-path-err-node-types.stderr b/tests/ui/type/type-path-err-node-types.stderr index 9a56eda807706..bd5c5e20c245c 100644 --- a/tests/ui/type/type-path-err-node-types.stderr +++ b/tests/ui/type/type-path-err-node-types.stderr @@ -1,16 +1,16 @@ -error[E0412]: cannot find type `Nonexistent` +error[E0412]: cannot find type `Nonexistent` in this scope --> $DIR/type-path-err-node-types.rs:7:12 | LL | let _: Nonexistent; | ^^^^^^^^^^^ not found in this scope -error[E0576]: cannot find method or associated constant `nonexistent` +error[E0576]: cannot find method or associated constant `nonexistent` in trait `Tr` --> $DIR/type-path-err-node-types.rs:11:21 | LL | >::nonexistent(); | ^^^^^^^^^^^ not found in trait `Tr` -error[E0425]: cannot find value `nonexistent` +error[E0425]: cannot find value `nonexistent` in this scope --> $DIR/type-path-err-node-types.rs:19:5 | LL | nonexistent.nonexistent::(); diff --git a/tests/ui/typeck/apit-with-error-type-in-sig.stderr b/tests/ui/typeck/apit-with-error-type-in-sig.stderr index d470891413eb8..6ed9b1f9b8cba 100644 --- a/tests/ui/typeck/apit-with-error-type-in-sig.stderr +++ b/tests/ui/typeck/apit-with-error-type-in-sig.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `Bar` +error[E0412]: cannot find type `Bar` in this scope --> $DIR/apit-with-error-type-in-sig.rs:1:12 | LL | type Foo = Bar; diff --git a/tests/ui/typeck/autoderef-with-param-env-error.stderr b/tests/ui/typeck/autoderef-with-param-env-error.stderr index bf07ba74c6a39..e06be398aa07a 100644 --- a/tests/ui/typeck/autoderef-with-param-env-error.stderr +++ b/tests/ui/typeck/autoderef-with-param-env-error.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `T` +error[E0412]: cannot find type `T` in this scope --> $DIR/autoderef-with-param-env-error.rs:3:5 | LL | T: Send, diff --git a/tests/ui/typeck/check-args-on-fn-err-2.stderr b/tests/ui/typeck/check-args-on-fn-err-2.stderr index 6f85cc7ef3365..301bb88dbacf6 100644 --- a/tests/ui/typeck/check-args-on-fn-err-2.stderr +++ b/tests/ui/typeck/check-args-on-fn-err-2.stderr @@ -11,7 +11,7 @@ help: change the type of the numeric literal from `u32` to `i32` LL | a((), 1i32 == 2i32); | ~~~ -error[E0425]: cannot find function `a` +error[E0425]: cannot find function `a` in this scope --> $DIR/check-args-on-fn-err-2.rs:2:5 | LL | a((), 1i32 == 2u32); diff --git a/tests/ui/typeck/check-args-on-fn-err.stderr b/tests/ui/typeck/check-args-on-fn-err.stderr index 3c4689877b6af..be0798ab107c0 100644 --- a/tests/ui/typeck/check-args-on-fn-err.stderr +++ b/tests/ui/typeck/check-args-on-fn-err.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find function `unknown` +error[E0425]: cannot find function `unknown` in this scope --> $DIR/check-args-on-fn-err.rs:2:5 | LL | unknown(1, |glyf| { diff --git a/tests/ui/typeck/issue-104510-ice.stderr b/tests/ui/typeck/issue-104510-ice.stderr index bfbc8dd5ff227..143139b2c089c 100644 --- a/tests/ui/typeck/issue-104510-ice.stderr +++ b/tests/ui/typeck/issue-104510-ice.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `Oops` +error[E0412]: cannot find type `Oops` in this scope --> $DIR/issue-104510-ice.rs:4:21 | LL | struct W(Oops); diff --git a/tests/ui/typeck/issue-104513-ice.stderr b/tests/ui/typeck/issue-104513-ice.stderr index 80a0168e08f27..37d38a76a4034 100644 --- a/tests/ui/typeck/issue-104513-ice.stderr +++ b/tests/ui/typeck/issue-104513-ice.stderr @@ -1,4 +1,4 @@ -error[E0405]: cannot find trait `Oops` +error[E0405]: cannot find trait `Oops` in this scope --> $DIR/issue-104513-ice.rs:3:19 | LL | let _: S = S; diff --git a/tests/ui/typeck/issue-105946.rs b/tests/ui/typeck/issue-105946.rs index 305f524e18521..3d0b192e4ced6 100644 --- a/tests/ui/typeck/issue-105946.rs +++ b/tests/ui/typeck/issue-105946.rs @@ -4,7 +4,7 @@ fn digit() -> str { } fn main() { let [_y..] = [Box::new(1), Box::new(2)]; - //~^ ERROR: cannot find value `_y` [E0425] + //~^ ERROR: cannot find value `_y` //~| ERROR: `X..` patterns in slices are experimental [E0658] //~| ERROR: pattern requires 1 element but array has 2 [E0527] } diff --git a/tests/ui/typeck/issue-105946.stderr b/tests/ui/typeck/issue-105946.stderr index 6c6d4c456bb66..33d4e0b141ab3 100644 --- a/tests/ui/typeck/issue-105946.stderr +++ b/tests/ui/typeck/issue-105946.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `_y` +error[E0425]: cannot find value `_y` in this scope --> $DIR/issue-105946.rs:6:10 | LL | let [_y..] = [Box::new(1), Box::new(2)]; diff --git a/tests/ui/typeck/issue-106929.stderr b/tests/ui/typeck/issue-106929.stderr index 34ce63bb604ef..375c9372ec288 100644 --- a/tests/ui/typeck/issue-106929.stderr +++ b/tests/ui/typeck/issue-106929.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find function `post` +error[E0425]: cannot find function `post` in this scope --> $DIR/issue-106929.rs:9:5 | LL | post(c, ()); diff --git a/tests/ui/typeck/issue-114423-ice-regression-in-suggestion.stderr b/tests/ui/typeck/issue-114423-ice-regression-in-suggestion.stderr index 0e4d79fe958c8..4ccfacfb00521 100644 --- a/tests/ui/typeck/issue-114423-ice-regression-in-suggestion.stderr +++ b/tests/ui/typeck/issue-114423-ice-regression-in-suggestion.stderr @@ -1,16 +1,16 @@ -error[E0425]: cannot find value `e` +error[E0425]: cannot find value `e` in this scope --> $DIR/issue-114423-ice-regression-in-suggestion.rs:7:51 | LL | let (r, alone_in_path, b): (f32, f32, f32) = (e.clone(), e.clone()); | ^ not found in this scope -error[E0425]: cannot find value `e` +error[E0425]: cannot find value `e` in this scope --> $DIR/issue-114423-ice-regression-in-suggestion.rs:7:62 | LL | let (r, alone_in_path, b): (f32, f32, f32) = (e.clone(), e.clone()); | ^ not found in this scope -error[E0425]: cannot find value `g` +error[E0425]: cannot find value `g` in this scope --> $DIR/issue-114423-ice-regression-in-suggestion.rs:11:22 | LL | let _ = RGB { r, g, b }; diff --git a/tests/ui/typeck/issue-83693.rs b/tests/ui/typeck/issue-83693.rs index ec23cc58cd7e7..5bb3d7ec8c358 100644 --- a/tests/ui/typeck/issue-83693.rs +++ b/tests/ui/typeck/issue-83693.rs @@ -4,16 +4,16 @@ #![crate_type="lib"] impl F { -//~^ ERROR: cannot find type `F` [E0412] +//~^ ERROR: cannot find type `F` fn call() { ::call - //~^ ERROR: cannot find type `TestResult` [E0412] + //~^ ERROR: cannot find type `TestResult` //~| associated item constraints are not allowed here [E0229] } } fn call() { ::call - //~^ ERROR: cannot find type `x` [E0412] + //~^ ERROR: cannot find type `x` //~| ERROR: associated item constraints are not allowed here [E0229] } diff --git a/tests/ui/typeck/issue-83693.stderr b/tests/ui/typeck/issue-83693.stderr index ff0f90929d55d..34bca426116e5 100644 --- a/tests/ui/typeck/issue-83693.stderr +++ b/tests/ui/typeck/issue-83693.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `F` +error[E0412]: cannot find type `F` in this scope --> $DIR/issue-83693.rs:6:6 | LL | impl F { @@ -7,13 +7,13 @@ LL | impl F { | = note: similarly named trait `Fn` defined here -error[E0412]: cannot find type `TestResult` +error[E0412]: cannot find type `TestResult` in this scope --> $DIR/issue-83693.rs:9:22 | LL | ::call | ^^^^^^^^^^ not found in this scope -error[E0412]: cannot find type `x` +error[E0412]: cannot find type `x` in this scope --> $DIR/issue-83693.rs:16:6 | LL | ::call diff --git a/tests/ui/typeck/issue-88844.rs b/tests/ui/typeck/issue-88844.rs index 34e6d254091de..57049818aff13 100644 --- a/tests/ui/typeck/issue-88844.rs +++ b/tests/ui/typeck/issue-88844.rs @@ -4,7 +4,7 @@ struct Struct { value: i32 } //~^ NOTE: similarly named struct `Struct` defined here impl Stuct { -//~^ ERROR: cannot find type `Stuct` [E0412] +//~^ ERROR: cannot find type `Stuct` //~| HELP: a struct with a similar name exists fn new() -> Self { Self { value: 42 } diff --git a/tests/ui/typeck/issue-88844.stderr b/tests/ui/typeck/issue-88844.stderr index 5c62e428fe7ac..68473f65dcf53 100644 --- a/tests/ui/typeck/issue-88844.stderr +++ b/tests/ui/typeck/issue-88844.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `Stuct` +error[E0412]: cannot find type `Stuct` in this scope --> $DIR/issue-88844.rs:6:6 | LL | struct Struct { value: i32 } diff --git a/tests/ui/typeck/issue-90319.rs b/tests/ui/typeck/issue-90319.rs index 3140bb519a6ed..db2572b862d3d 100644 --- a/tests/ui/typeck/issue-90319.rs +++ b/tests/ui/typeck/issue-90319.rs @@ -11,7 +11,7 @@ fn get() -> T { } fn main() { - let thing = get::();//~ERROR cannot find type `Thing` [E0412] + let thing = get::();//~ERROR cannot find type `Thing` let wrapper = Wrapper(thing); Trait::method(&wrapper); } diff --git a/tests/ui/typeck/issue-90319.stderr b/tests/ui/typeck/issue-90319.stderr index 20ef8811b8921..fa18056e802d4 100644 --- a/tests/ui/typeck/issue-90319.stderr +++ b/tests/ui/typeck/issue-90319.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `Thing` +error[E0412]: cannot find type `Thing` in this scope --> $DIR/issue-90319.rs:14:23 | LL | let thing = get::(); diff --git a/tests/ui/typeck/issue-91267.rs b/tests/ui/typeck/issue-91267.rs index c4f3f7b30dabd..b63800e10d6d9 100644 --- a/tests/ui/typeck/issue-91267.rs +++ b/tests/ui/typeck/issue-91267.rs @@ -2,7 +2,7 @@ fn main() { type_ascribe!(0, u8=e>) - //~^ ERROR: cannot find type `e` [E0412] + //~^ ERROR: cannot find type `e` //~| ERROR: associated item constraints are not allowed here [E0229] //~| ERROR: mismatched types [E0308] } diff --git a/tests/ui/typeck/issue-91267.stderr b/tests/ui/typeck/issue-91267.stderr index 5363e47c9e03a..d16b1997e9f7d 100644 --- a/tests/ui/typeck/issue-91267.stderr +++ b/tests/ui/typeck/issue-91267.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `e` +error[E0412]: cannot find type `e` in this scope --> $DIR/issue-91267.rs:4:30 | LL | type_ascribe!(0, u8=e>) diff --git a/tests/ui/typeck/nonexistent-field-not-ambiguous.stderr b/tests/ui/typeck/nonexistent-field-not-ambiguous.stderr index 36c33db44faea..82207a731b962 100644 --- a/tests/ui/typeck/nonexistent-field-not-ambiguous.stderr +++ b/tests/ui/typeck/nonexistent-field-not-ambiguous.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `MissingType` +error[E0412]: cannot find type `MissingType` in this scope --> $DIR/nonexistent-field-not-ambiguous.rs:2:10 | LL | val: MissingType, diff --git a/tests/ui/typeck/quiet-type-err-let-binding.stderr b/tests/ui/typeck/quiet-type-err-let-binding.stderr index 0eba3448cabcf..f27ca1dd58206 100644 --- a/tests/ui/typeck/quiet-type-err-let-binding.stderr +++ b/tests/ui/typeck/quiet-type-err-let-binding.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find function `foo` +error[E0425]: cannot find function `foo` in this scope --> $DIR/quiet-type-err-let-binding.rs:14:13 | LL | let x = foo(); diff --git a/tests/ui/ufcs/ufcs-partially-resolved.stderr b/tests/ui/ufcs/ufcs-partially-resolved.stderr index 82d472ead7b73..3b6b1b81ef152 100644 --- a/tests/ui/ufcs/ufcs-partially-resolved.stderr +++ b/tests/ui/ufcs/ufcs-partially-resolved.stderr @@ -1,4 +1,4 @@ -error[E0576]: cannot find associated type `N` +error[E0576]: cannot find associated type `N` in trait `Tr` --> $DIR/ufcs-partially-resolved.rs:19:24 | LL | type Y = u16; @@ -27,7 +27,7 @@ help: you might have meant to use `#![feature(trait_alias)]` instead of a `type` LL | trait A = u32; | -error[E0576]: cannot find method or associated constant `N` +error[E0576]: cannot find method or associated constant `N` in trait `Tr` --> $DIR/ufcs-partially-resolved.rs:22:17 | LL | fn Y() {} @@ -74,7 +74,7 @@ LL | ::Y; | = note: similarly named trait `Eq` defined here -error[E0576]: cannot find associated type `N` +error[E0576]: cannot find associated type `N` in trait `Tr` --> $DIR/ufcs-partially-resolved.rs:30:24 | LL | type Y = u16; @@ -103,7 +103,7 @@ help: you might have meant to use `#![feature(trait_alias)]` instead of a `type` LL | trait A = u32; | -error[E0576]: cannot find associated type `N` +error[E0576]: cannot find associated type `N` in trait `Tr` --> $DIR/ufcs-partially-resolved.rs:33:17 | LL | type Y = u16; @@ -150,37 +150,37 @@ LL | ::Y::NN; | = note: similarly named trait `Eq` defined here -error[E0405]: cannot find trait `N` +error[E0405]: cannot find trait `N` in trait `Tr` --> $DIR/ufcs-partially-resolved.rs:41:23 | LL | let _: ::NN; | ^ not found in trait `Tr` -error[E0405]: cannot find trait `N` +error[E0405]: cannot find trait `N` in enum `E` --> $DIR/ufcs-partially-resolved.rs:42:22 | LL | let _: ::NN; | ^ not found in enum `E` -error[E0405]: cannot find trait `N` +error[E0405]: cannot find trait `N` in `A` --> $DIR/ufcs-partially-resolved.rs:43:22 | LL | let _: ::NN; | ^ not found in `A` -error[E0405]: cannot find trait `N` +error[E0405]: cannot find trait `N` in trait `Tr` --> $DIR/ufcs-partially-resolved.rs:44:16 | LL | ::NN; | ^ not found in trait `Tr` -error[E0405]: cannot find trait `N` +error[E0405]: cannot find trait `N` in enum `E` --> $DIR/ufcs-partially-resolved.rs:45:15 | LL | ::NN; | ^ not found in enum `E` -error[E0405]: cannot find trait `N` +error[E0405]: cannot find trait `N` in `A` --> $DIR/ufcs-partially-resolved.rs:46:15 | LL | ::NN; diff --git a/tests/ui/unboxed-closures/unboxed-closures-type-mismatch-closure-from-another-scope.stderr b/tests/ui/unboxed-closures/unboxed-closures-type-mismatch-closure-from-another-scope.stderr index 7ed432240bc8a..5f22c781345ff 100644 --- a/tests/ui/unboxed-closures/unboxed-closures-type-mismatch-closure-from-another-scope.stderr +++ b/tests/ui/unboxed-closures/unboxed-closures-type-mismatch-closure-from-another-scope.stderr @@ -1,10 +1,10 @@ -error[E0425]: cannot find value `x` +error[E0425]: cannot find value `x` in this scope --> $DIR/unboxed-closures-type-mismatch-closure-from-another-scope.rs:2:21 | LL | let x = match **x { | ^ not found in this scope -error[E0425]: cannot find value `y` +error[E0425]: cannot find value `y` in this scope --> $DIR/unboxed-closures-type-mismatch-closure-from-another-scope.rs:9:26 | LL | closure(&mut p, &y); diff --git a/tests/ui/union/unresolved-field-isnt-copy.stderr b/tests/ui/union/unresolved-field-isnt-copy.stderr index 26d207104be9f..ee5d1e37b141c 100644 --- a/tests/ui/union/unresolved-field-isnt-copy.stderr +++ b/tests/ui/union/unresolved-field-isnt-copy.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `Missing` +error[E0412]: cannot find type `Missing` in this scope --> $DIR/unresolved-field-isnt-copy.rs:4:15 | LL | x: *const Missing, diff --git a/tests/ui/unresolved/unresolved-candidates.stderr b/tests/ui/unresolved/unresolved-candidates.stderr index 03b13e7b92ade..7ef2f6b1a2922 100644 --- a/tests/ui/unresolved/unresolved-candidates.stderr +++ b/tests/ui/unresolved/unresolved-candidates.stderr @@ -9,7 +9,7 @@ help: consider importing this trait instead LL | use a::Trait; | ~~~~~~~~ -error[E0405]: cannot find trait `Trait` +error[E0405]: cannot find trait `Trait` in this scope --> $DIR/unresolved-candidates.rs:10:10 | LL | impl Trait for () {} diff --git a/tests/ui/wf/ice-hir-wf-check-anon-const-issue-122199.stderr b/tests/ui/wf/ice-hir-wf-check-anon-const-issue-122199.stderr index 9f9984ad1c075..f2456f99e6233 100644 --- a/tests/ui/wf/ice-hir-wf-check-anon-const-issue-122199.stderr +++ b/tests/ui/wf/ice-hir-wf-check-anon-const-issue-122199.stderr @@ -7,7 +7,7 @@ LL | trait Trait { LL | fn fnc(&self) -> Trait { | ^ already used -error[E0425]: cannot find value `bar` +error[E0425]: cannot find value `bar` in this scope --> $DIR/ice-hir-wf-check-anon-const-issue-122199.rs:1:30 | LL | trait Trait { @@ -19,7 +19,7 @@ error[E0423]: expected value, found builtin type `u32` LL | fn fnc(&self) -> Trait { | ^^^ not a value -error[E0425]: cannot find value `bar` +error[E0425]: cannot find value `bar` in this scope --> $DIR/ice-hir-wf-check-anon-const-issue-122199.rs:25:9 | LL | bar diff --git a/tests/ui/wf/issue-110157.stderr b/tests/ui/wf/issue-110157.stderr index 0785a10306cc4..e750ea47d515c 100644 --- a/tests/ui/wf/issue-110157.stderr +++ b/tests/ui/wf/issue-110157.stderr @@ -1,10 +1,10 @@ -error[E0412]: cannot find type `Missing` +error[E0412]: cannot find type `Missing` in this scope --> $DIR/issue-110157.rs:6:12 | LL | F: Fn(&Missing) -> Result, | ^^^^^^^ not found in this scope -error[E0412]: cannot find type `Missing` +error[E0412]: cannot find type `Missing` in this scope --> $DIR/issue-110157.rs:8:24 | LL | I: Iterator, diff --git a/tests/ui/where-clauses/ignore-err-clauses.stderr b/tests/ui/where-clauses/ignore-err-clauses.stderr index 146915f991580..4cf553da4c5fc 100644 --- a/tests/ui/where-clauses/ignore-err-clauses.stderr +++ b/tests/ui/where-clauses/ignore-err-clauses.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `UUU` +error[E0412]: cannot find type `UUU` in this scope --> $DIR/ignore-err-clauses.rs:6:5 | LL | UUU: Copy, diff --git a/tests/ui/where-clauses/normalization-of-unknown-type.stderr b/tests/ui/where-clauses/normalization-of-unknown-type.stderr index 69690e16f31b1..11b83224352b8 100644 --- a/tests/ui/where-clauses/normalization-of-unknown-type.stderr +++ b/tests/ui/where-clauses/normalization-of-unknown-type.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `Foo` +error[E0412]: cannot find type `Foo` in this scope --> $DIR/normalization-of-unknown-type.rs:24:5 | LL | Foo: Filter, From ec83028cf4591f34403a2378377903eab0f6b79b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Mon, 1 Jul 2024 23:31:29 +0000 Subject: [PATCH 887/892] More accurate description of unresolved imported item State when the element that couldn't be found was expected to be a module, a generic item, a value or a macro. State what scope the E0433 the item couldn't be found in, when available. --- .../rustc_resolve/src/build_reduced_graph.rs | 12 +- compiler/rustc_resolve/src/diagnostics.rs | 53 +++- compiler/rustc_resolve/src/ident.rs | 96 +++++--- compiler/rustc_resolve/src/imports.rs | 4 +- compiler/rustc_resolve/src/late.rs | 4 +- compiler/rustc_resolve/src/lib.rs | 8 +- compiler/rustc_resolve/src/macros.rs | 70 +++--- .../crashes/unreachable-array-or-slice.stderr | 2 +- src/tools/miri/tests/fail/rustc-error2.stderr | 2 +- .../intra-doc/unresolved-import-recovery.rs | 2 +- .../unresolved-import-recovery.stderr | 4 +- tests/rustdoc-ui/issues/issue-61732.rs | 2 +- tests/rustdoc-ui/issues/issue-61732.stderr | 6 +- .../session-diagnostic/diagnostic-derive.rs | 6 +- .../diagnostic-derive.stderr | 43 ++-- .../subdiagnostic-derive.rs | 59 +++-- .../subdiagnostic-derive.stderr | 228 +++++++++--------- .../field-attributes-vis-unresolved.rs | 4 +- .../field-attributes-vis-unresolved.stderr | 8 +- ...T-struct-pattern-box-pattern-ice-121463.rs | 4 +- ...ruct-pattern-box-pattern-ice-121463.stderr | 4 +- tests/ui/cfg/diagnostics-cross-crate.rs | 2 +- tests/ui/cfg/diagnostics-cross-crate.stderr | 2 +- tests/ui/cfg/diagnostics-same-crate.rs | 2 +- tests/ui/cfg/diagnostics-same-crate.stderr | 2 +- .../ui/coherence/conflicting-impl-with-err.rs | 4 +- .../conflicting-impl-with-err.stderr | 4 +- ...icates-of-no-entry-found-for-key-119275.rs | 2 +- ...es-of-no-entry-found-for-key-119275.stderr | 2 +- tests/ui/const-generics/issues/issue-82956.rs | 2 +- .../const-generics/issues/issue-82956.stderr | 2 +- .../consts/const_refs_to_static-ice-121413.rs | 2 +- .../const_refs_to_static-ice-121413.stderr | 2 +- tests/ui/custom-attribute-multisegment.rs | 2 +- tests/ui/custom-attribute-multisegment.stderr | 2 +- tests/ui/delegation/bad-resolve.rs | 4 +- tests/ui/delegation/bad-resolve.stderr | 4 +- tests/ui/delegation/glob-bad-path.rs | 2 +- tests/ui/delegation/glob-bad-path.stderr | 2 +- tests/ui/derived-errors/issue-31997-1.stderr | 2 +- .../dollar-crate/dollar-crate-is-keyword-2.rs | 4 +- .../dollar-crate-is-keyword-2.stderr | 4 +- tests/ui/error-codes/E0432.stderr | 2 +- tests/ui/error-codes/E0433.stderr | 2 +- tests/ui/extern-flag/multiple-opts.rs | 2 +- tests/ui/extern-flag/multiple-opts.stderr | 2 +- tests/ui/extern-flag/noprelude.rs | 2 +- tests/ui/extern-flag/noprelude.stderr | 2 +- tests/ui/extern/extern-macro.rs | 2 +- tests/ui/extern/extern-macro.stderr | 2 +- .../feature-gate-extern_absolute_paths.rs | 2 +- .../feature-gate-extern_absolute_paths.stderr | 6 +- tests/ui/foreign/stashed-issue-121451.rs | 2 +- tests/ui/foreign/stashed-issue-121451.stderr | 2 +- .../equality-bound.rs | 2 +- .../equality-bound.stderr | 2 +- .../extern-prelude-from-opaque-fail-2018.rs | 4 +- ...xtern-prelude-from-opaque-fail-2018.stderr | 4 +- .../extern-prelude-from-opaque-fail.rs | 4 +- .../extern-prelude-from-opaque-fail.stderr | 4 +- tests/ui/hygiene/no_implicit_prelude.rs | 2 +- tests/ui/hygiene/no_implicit_prelude.stderr | 2 +- tests/ui/impl-trait/issue-72911.rs | 4 +- tests/ui/impl-trait/issue-72911.stderr | 4 +- .../impl-trait/stashed-diag-issue-121504.rs | 2 +- .../stashed-diag-issue-121504.stderr | 2 +- .../absolute-paths-in-nested-use-groups.rs | 9 +- ...absolute-paths-in-nested-use-groups.stderr | 10 +- .../extern-prelude-extern-crate-fail.rs | 2 +- .../extern-prelude-extern-crate-fail.stderr | 2 +- .../imports/import-from-missing-star-2.stderr | 2 +- .../imports/import-from-missing-star-3.stderr | 4 +- .../imports/import-from-missing-star.stderr | 2 +- tests/ui/imports/import3.stderr | 2 +- tests/ui/imports/issue-109343.stderr | 2 +- tests/ui/imports/issue-1697.rs | 2 +- tests/ui/imports/issue-1697.stderr | 2 +- tests/ui/imports/issue-33464.stderr | 6 +- tests/ui/imports/issue-36881.stderr | 2 +- tests/ui/imports/issue-37887.stderr | 2 +- tests/ui/imports/issue-53269.stderr | 2 +- tests/ui/imports/issue-55457.stderr | 2 +- tests/ui/imports/issue-81413.stderr | 2 +- .../ui/imports/suggest-import-issue-120074.rs | 2 +- .../suggest-import-issue-120074.stderr | 2 +- tests/ui/imports/tool-mod-child.rs | 4 +- tests/ui/imports/tool-mod-child.stderr | 12 +- .../ui/imports/unresolved-imports-used.stderr | 8 +- tests/ui/issues/issue-33293.rs | 2 +- tests/ui/issues/issue-33293.stderr | 2 +- tests/ui/issues/issue-38857.rs | 2 +- tests/ui/issues/issue-38857.stderr | 2 +- tests/ui/issues/issue-46101.rs | 4 +- tests/ui/issues/issue-46101.stderr | 4 +- tests/ui/issues/issue-71406.rs | 3 +- tests/ui/issues/issue-71406.stderr | 2 +- .../keyword-extern-as-identifier-use.stderr | 4 +- .../ui/keyword/keyword-super-as-identifier.rs | 2 +- .../keyword-super-as-identifier.stderr | 9 +- tests/ui/keyword/keyword-super.rs | 2 +- tests/ui/keyword/keyword-super.stderr | 9 +- tests/ui/lifetimes/issue-97194.rs | 2 +- tests/ui/lifetimes/issue-97194.stderr | 2 +- .../ice-array-into-iter-lint-issue-121532.rs | 2 +- ...e-array-into-iter-lint-issue-121532.stderr | 2 +- .../ui/macros/builtin-prelude-no-accidents.rs | 6 +- .../builtin-prelude-no-accidents.stderr | 6 +- tests/ui/macros/builtin-std-paths-fail.rs | 32 +-- tests/ui/macros/builtin-std-paths-fail.stderr | 32 +-- tests/ui/macros/macro-inner-attributes.rs | 2 +- tests/ui/macros/macro-inner-attributes.stderr | 2 +- tests/ui/macros/macro-path-prelude-fail-1.rs | 4 +- .../macros/macro-path-prelude-fail-1.stderr | 4 +- tests/ui/macros/macro-path-prelude-fail-2.rs | 2 +- .../macros/macro-path-prelude-fail-2.stderr | 2 +- .../ui/macros/macro_path_as_generic_bound.rs | 2 +- .../macros/macro_path_as_generic_bound.stderr | 2 +- tests/ui/macros/meta-item-absolute-path.rs | 4 +- .../ui/macros/meta-item-absolute-path.stderr | 8 +- tests/ui/mir/issue-121103.rs | 4 +- tests/ui/mir/issue-121103.stderr | 4 +- .../mod_file_disambig.rs | 2 +- .../mod_file_disambig.stderr | 2 +- ...onst-param-decl-on-type-instead-of-impl.rs | 2 +- ...-param-decl-on-type-instead-of-impl.stderr | 2 +- tests/ui/parser/dyn-trait-compatibility.rs | 2 +- .../ui/parser/dyn-trait-compatibility.stderr | 2 +- tests/ui/parser/mod_file_not_exist.rs | 2 +- tests/ui/parser/mod_file_not_exist.stderr | 2 +- tests/ui/parser/mod_file_not_exist_windows.rs | 2 +- .../parser/mod_file_not_exist_windows.stderr | 2 +- tests/ui/pattern/pattern-error-continue.rs | 2 +- .../ui/pattern/pattern-error-continue.stderr | 2 +- tests/ui/privacy/restricted/test.rs | 2 +- tests/ui/privacy/restricted/test.stderr | 4 +- tests/ui/privacy/unreachable-issue-121455.rs | 2 +- .../privacy/unreachable-issue-121455.stderr | 2 +- tests/ui/proc-macro/amputate-span.stderr | 4 +- tests/ui/resolve/112590-2.fixed | 10 +- tests/ui/resolve/112590-2.rs | 10 +- tests/ui/resolve/112590-2.stderr | 10 +- tests/ui/resolve/bad-module.rs | 4 +- tests/ui/resolve/bad-module.stderr | 4 +- tests/ui/resolve/editions-crate-root-2015.rs | 4 +- .../resolve/editions-crate-root-2015.stderr | 8 +- tests/ui/resolve/editions-crate-root-2018.rs | 4 +- .../resolve/editions-crate-root-2018.stderr | 4 +- .../ui/resolve/export-fully-qualified-2018.rs | 2 +- .../export-fully-qualified-2018.stderr | 2 +- tests/ui/resolve/export-fully-qualified.rs | 2 +- .../ui/resolve/export-fully-qualified.stderr | 2 +- tests/ui/resolve/extern-prelude-fail.rs | 2 +- tests/ui/resolve/extern-prelude-fail.stderr | 6 +- tests/ui/resolve/impl-items-vis-unresolved.rs | 2 +- .../resolve/impl-items-vis-unresolved.stderr | 4 +- tests/ui/resolve/issue-101749-2.rs | 2 +- tests/ui/resolve/issue-101749-2.stderr | 2 +- tests/ui/resolve/issue-101749.fixed | 2 +- tests/ui/resolve/issue-101749.rs | 2 +- tests/ui/resolve/issue-101749.stderr | 2 +- tests/ui/resolve/issue-109250.rs | 2 +- tests/ui/resolve/issue-109250.stderr | 2 +- tests/ui/resolve/issue-117920.rs | 2 +- tests/ui/resolve/issue-117920.stderr | 4 +- tests/ui/resolve/issue-24968.rs | 4 +- tests/ui/resolve/issue-24968.stderr | 4 +- tests/ui/resolve/issue-81508.rs | 4 +- tests/ui/resolve/issue-81508.stderr | 4 +- tests/ui/resolve/issue-82156.rs | 2 +- tests/ui/resolve/issue-82156.stderr | 9 +- tests/ui/resolve/issue-82865.rs | 2 +- tests/ui/resolve/issue-82865.stderr | 4 +- tests/ui/resolve/missing-in-namespace.rs | 2 +- tests/ui/resolve/missing-in-namespace.stderr | 2 +- tests/ui/resolve/resolve-bad-visibility.rs | 4 +- .../ui/resolve/resolve-bad-visibility.stderr | 8 +- .../ui/resolve/resolve-variant-assoc-item.rs | 4 +- .../resolve/resolve-variant-assoc-item.stderr | 4 +- tests/ui/resolve/tool-import.rs | 3 +- tests/ui/resolve/tool-import.stderr | 2 +- .../typo-suggestion-mistyped-in-path.rs | 8 +- .../typo-suggestion-mistyped-in-path.stderr | 8 +- .../resolve/unresolved-segments-visibility.rs | 2 +- .../unresolved-segments-visibility.stderr | 2 +- tests/ui/resolve/use_suggestion.rs | 4 +- tests/ui/resolve/use_suggestion.stderr | 4 +- .../crate-path-non-absolute.rs | 4 +- .../crate-path-non-absolute.stderr | 4 +- .../non-existent-2.rs | 2 +- .../non-existent-2.stderr | 2 +- .../issue-102156.stderr | 8 +- .../portable-intrinsics-arent-exposed.stderr | 4 +- tests/ui/span/visibility-ty-params.rs | 2 +- tests/ui/span/visibility-ty-params.stderr | 2 +- ...-std-import-order-issue-83564.no_std.fixed | 2 +- ...std-import-order-issue-83564.no_std.stderr | 2 +- .../core-std-import-order-issue-83564.rs | 2 +- ...ore-std-import-order-issue-83564.std.fixed | 2 +- ...re-std-import-order-issue-83564.std.stderr | 2 +- tests/ui/suggestions/crate-or-module-typo.rs | 6 +- .../suggestions/crate-or-module-typo.stderr | 6 +- tests/ui/suggestions/issue-103112.rs | 2 +- tests/ui/suggestions/issue-103112.stderr | 2 +- .../issue-112590-suggest-import.rs | 6 +- .../issue-112590-suggest-import.stderr | 6 +- .../suggest-tryinto-edition-change.rs | 8 +- .../suggest-tryinto-edition-change.stderr | 6 +- .../ui/suggestions/undeclared-module-alloc.rs | 2 +- .../undeclared-module-alloc.stderr | 2 +- tests/ui/super-at-top-level.rs | 3 +- tests/ui/super-at-top-level.stderr | 4 +- .../tool-attributes-shadowing.rs | 2 +- .../tool-attributes-shadowing.stderr | 2 +- tests/ui/tool-attributes/unknown-tool-name.rs | 2 +- .../tool-attributes/unknown-tool-name.stderr | 2 +- .../ui/type-alias/issue-62263-self-in-atb.rs | 2 +- .../type-alias/issue-62263-self-in-atb.stderr | 2 +- .../type-alias/issue-62305-self-assoc-ty.rs | 2 +- .../issue-62305-self-assoc-ty.stderr | 2 +- tests/ui/type/type-path-err-node-types.rs | 2 +- tests/ui/type/type-path-err-node-types.stderr | 2 +- tests/ui/typeck/issue-120856.rs | 6 +- tests/ui/typeck/issue-120856.stderr | 4 +- .../path-to-method-sugg-unresolved-expr.rs | 3 +- ...path-to-method-sugg-unresolved-expr.stderr | 2 +- .../ui/underscore-imports/issue-110164.stderr | 8 +- .../unresolved-asterisk-imports.stderr | 2 +- tests/ui/unresolved/unresolved-import.rs | 2 +- tests/ui/unresolved/unresolved-import.stderr | 2 +- tests/ui/use/use-self-type.rs | 2 +- tests/ui/use/use-self-type.stderr | 2 +- tests/ui/use/use-super-global-path.rs | 10 +- tests/ui/use/use-super-global-path.stderr | 8 +- 233 files changed, 760 insertions(+), 623 deletions(-) diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs index 92cf73870ff13..bbc9535fc3052 100644 --- a/compiler/rustc_resolve/src/build_reduced_graph.rs +++ b/compiler/rustc_resolve/src/build_reduced_graph.rs @@ -307,9 +307,15 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> { PathResult::NonModule(partial_res) => { expected_found_error(partial_res.expect_full_res()) } - PathResult::Failed { span, label, suggestion, .. } => { - Err(VisResolutionError::FailedToResolve(span, label, suggestion)) - } + PathResult::Failed { + span, label, suggestion, segment_name, item_type, .. + } => Err(VisResolutionError::FailedToResolve( + span, + segment_name, + label, + suggestion, + item_type, + )), PathResult::Indeterminate => Err(VisResolutionError::Indeterminate(path.span)), } } diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index ffd495aa9857e..d00189929946f 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -794,9 +794,32 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { ResolutionError::SelfImportOnlyInImportListWithNonEmptyPrefix => { self.dcx().create_err(errs::SelfImportOnlyInImportListWithNonEmptyPrefix { span }) } - ResolutionError::FailedToResolve { segment, label, suggestion, module } => { - let mut err = - struct_span_code_err!(self.dcx(), span, E0433, "failed to resolve: {}", &label); + ResolutionError::FailedToResolve { segment, label, suggestion, module, item_type } => { + let mut err = struct_span_code_err!( + self.dcx(), + span, + E0433, + "cannot find {item_type} `{segment}` in {}", + match module { + Some(ModuleOrUniformRoot::CurrentScope) | None => "this scope".to_string(), + Some(ModuleOrUniformRoot::Module(module)) => { + match module.kind { + ModuleKind::Def(_, _, name) if name == kw::Empty => { + "the crate root".to_string() + } + ModuleKind::Def(kind, def_id, name) => { + format!("{} `{name}`", kind.descr(def_id)) + } + ModuleKind::Block => "this scope".to_string(), + } + } + Some(ModuleOrUniformRoot::CrateRootAndExternPrelude) => { + "the crate root or the list of imported crates".to_string() + } + Some(ModuleOrUniformRoot::ExternPrelude) => + "the list of imported crates".to_string(), + }, + ); err.span_label(span, label); if let Some((suggestions, msg, applicability)) = suggestion { @@ -809,7 +832,6 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { if let Some(ModuleOrUniformRoot::Module(module)) = module && let Some(module) = module.opt_def_id() - && let Some(segment) = segment { self.find_cfg_stripped(&mut err, &segment, module); } @@ -989,10 +1011,18 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { VisResolutionError::AncestorOnly(span) => { self.dcx().create_err(errs::AncestorOnly(span)) } - VisResolutionError::FailedToResolve(span, label, suggestion) => self.into_struct_error( - span, - ResolutionError::FailedToResolve { segment: None, label, suggestion, module: None }, - ), + VisResolutionError::FailedToResolve(span, segment, label, suggestion, item_type) => { + self.into_struct_error( + span, + ResolutionError::FailedToResolve { + segment, + label, + suggestion, + module: None, + item_type, + }, + ) + } VisResolutionError::ExpectedFound(span, path_str, res) => { self.dcx().create_err(errs::ExpectedModuleFound { span, res, path_str }) } @@ -2003,16 +2033,19 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { ) } else if ident.name == sym::core { ( - format!("maybe a missing crate `{ident}`?"), + format!("you might be missing a crate named `{ident}`"), Some(( vec![(ident.span, "std".to_string())], "try using `std` instead of `core`".to_string(), Applicability::MaybeIncorrect, )), ) + } else if ident.is_raw_guess() { + // We're unlikely to have a crate called `r#super`, don't suggest anything. + ("unresolved import".to_string(), None) } else if self.tcx.sess.is_rust_2015() { ( - format!("maybe a missing crate `{ident}`?"), + format!("you might be missing a crate named `{ident}`"), Some(( vec![], format!( diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs index 7d531385e2120..a026432a8eb2d 100644 --- a/compiler/rustc_resolve/src/ident.rs +++ b/compiler/rustc_resolve/src/ident.rs @@ -1,5 +1,5 @@ use rustc_ast::{self as ast, NodeId}; -use rustc_errors::ErrorGuaranteed; +use rustc_errors::{Applicability, ErrorGuaranteed}; use rustc_hir::def::{DefKind, Namespace, NonMacroAttrKind, PartialRes, PerNS}; use rustc_middle::bug; use rustc_middle::ty; @@ -1463,9 +1463,28 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { continue; } } - return PathResult::failed(ident, false, finalize.is_some(), module, || { - ("there are too many leading `super` keywords".to_string(), None) - }); + let mut item_type = "module"; + let mut suggestion = None; + let label = if path.len() == 1 + && let Some(ribs) = ribs + && let RibKind::Normal = ribs[ValueNS][ribs[ValueNS].len() - 1].kind + { + item_type = "item"; + suggestion = Some((vec![(ident.span.shrink_to_lo(), "r#".to_string())], "if you still want to call your identifier `super`, use the raw identifier format".to_string(), Applicability::MachineApplicable)); + "can't use `super` as an identifier" + } else if segment_idx == 0 { + "can't use `super` on the crate root, there are no further modules to go \"up\" to" + } else { + "there are too many leading `super` keywords" + }; + return PathResult::failed( + ident, + false, + finalize.is_some(), + module, + || (label.to_string(), suggestion), + item_type, + ); } if segment_idx == 0 { if name == kw::SelfLower { @@ -1497,19 +1516,26 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { // Report special messages for path segment keywords in wrong positions. if ident.is_path_segment_keyword() && segment_idx != 0 { - return PathResult::failed(ident, false, finalize.is_some(), module, || { - let name_str = if name == kw::PathRoot { - "crate root".to_string() - } else { - format!("`{name}`") - }; - let label = if segment_idx == 1 && path[0].ident.name == kw::PathRoot { - format!("global paths cannot start with {name_str}") - } else { - format!("{name_str} in paths can only be used in start position") - }; - (label, None) - }); + return PathResult::failed( + ident, + false, + finalize.is_some(), + module, + || { + let name_str = if name == kw::PathRoot { + "crate root".to_string() + } else { + format!("`{name}`") + }; + let label = if segment_idx == 1 && path[0].ident.name == kw::PathRoot { + format!("global paths cannot start with {name_str}") + } else { + format!("{name_str} in paths can only be used in start position") + }; + (label, None) + }, + "module", + ); } let binding = if let Some(module) = module { @@ -1605,6 +1631,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { ); (label, None) }, + "module", ); } } @@ -1619,18 +1646,29 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { } } - return PathResult::failed(ident, is_last, finalize.is_some(), module, || { - self.report_path_resolution_error( - path, - opt_ns, - parent_scope, - ribs, - ignore_binding, - module, - segment_idx, - ident, - ) - }); + return PathResult::failed( + ident, + is_last, + finalize.is_some(), + module, + || { + self.report_path_resolution_error( + path, + opt_ns, + parent_scope, + ribs, + ignore_binding, + module, + segment_idx, + ident, + ) + }, + match opt_ns { + Some(ValueNS) if path.len() == 1 => "item or value", + Some(ns) if path.len() - 1 == segment_idx => ns.descr(), + Some(_) | None => "item", + }, + ); } } } diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs index 3896fe4c4fa64..a7b25b8f0804f 100644 --- a/compiler/rustc_resolve/src/imports.rs +++ b/compiler/rustc_resolve/src/imports.rs @@ -900,16 +900,18 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { label, suggestion, module, + item_type, } => { if no_ambiguity { assert!(import.imported_module.get().is_none()); self.report_error( span, ResolutionError::FailedToResolve { - segment: Some(segment_name), + segment: segment_name, label, suggestion, module, + item_type, }, ); } diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 1d37264f96a3c..dae42983d80d8 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -4274,14 +4274,16 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { suggestion, module, segment_name, + item_type, } => { return Err(respan( span, ResolutionError::FailedToResolve { - segment: Some(segment_name), + segment: segment_name, label, suggestion, module, + item_type, }, )); } diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 7cb5a3fb2fd15..c920ac17847a0 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -228,10 +228,11 @@ enum ResolutionError<'a> { SelfImportOnlyInImportListWithNonEmptyPrefix, /// Error E0433: failed to resolve. FailedToResolve { - segment: Option, + segment: Symbol, label: String, suggestion: Option, module: Option>, + item_type: &'static str, }, /// Error E0434: can't capture dynamic environment in a fn item. CannotCaptureDynamicEnvironmentInFnItem, @@ -287,7 +288,7 @@ enum ResolutionError<'a> { enum VisResolutionError<'a> { Relative2018(Span, &'a ast::Path), AncestorOnly(Span), - FailedToResolve(Span, String, Option), + FailedToResolve(Span, Symbol, String, Option, &'static str), ExpectedFound(Span, String, Res), Indeterminate(Span), ModuleOnly(Span), @@ -429,6 +430,7 @@ enum PathResult<'a> { module: Option>, /// The segment name of target segment_name: Symbol, + item_type: &'static str, }, } @@ -439,6 +441,7 @@ impl<'a> PathResult<'a> { finalize: bool, module: Option>, label_and_suggestion: impl FnOnce() -> (String, Option), + item_type: &'static str, ) -> PathResult<'a> { let (label, suggestion) = if finalize { label_and_suggestion() } else { (String::new(), None) }; @@ -449,6 +452,7 @@ impl<'a> PathResult<'a> { suggestion, is_error_from_last_segment, module, + item_type, } } } diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs index a6c56743bfe77..3e4d17f9a0085 100644 --- a/compiler/rustc_resolve/src/macros.rs +++ b/compiler/rustc_resolve/src/macros.rs @@ -862,44 +862,54 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { ), path_res @ (PathResult::NonModule(..) | PathResult::Failed { .. }) => { let mut suggestion = None; - let (span, label, module) = - if let PathResult::Failed { span, label, module, .. } = path_res { - // try to suggest if it's not a macro, maybe a function - if let PathResult::NonModule(partial_res) = - self.maybe_resolve_path(&path, Some(ValueNS), &parent_scope) - && partial_res.unresolved_segments() == 0 - { - let sm = self.tcx.sess.source_map(); - let exclamation_span = sm.next_point(span); - suggestion = Some(( - vec![(exclamation_span, "".to_string())], - format!( - "{} is not a macro, but a {}, try to remove `!`", - Segment::names_to_string(&path), - partial_res.base_res().descr() - ), - Applicability::MaybeIncorrect, - )); - } - (span, label, module) - } else { - ( - path_span, + let (span, label, module, segment, item_type) = if let PathResult::Failed { + span, + label, + module, + segment_name, + item_type, + .. + } = path_res + { + // try to suggest if it's not a macro, maybe a function + if let PathResult::NonModule(partial_res) = + self.maybe_resolve_path(&path, Some(ValueNS), &parent_scope) + && partial_res.unresolved_segments() == 0 + { + let sm = self.tcx.sess.source_map(); + let exclamation_span = sm.next_point(span); + suggestion = Some(( + vec![(exclamation_span, "".to_string())], format!( - "partially resolved path in {} {}", - kind.article(), - kind.descr() + "{} is not a macro, but a {}, try to remove `!`", + Segment::names_to_string(&path), + partial_res.base_res().descr() ), - None, - ) - }; + Applicability::MaybeIncorrect, + )); + } + (span, label, module, segment_name, item_type) + } else { + ( + path_span, + format!( + "partially resolved path in {} {}", + kind.article(), + kind.descr() + ), + None, + path.last().map(|segment| segment.ident.name).unwrap(), + "item", + ) + }; self.report_error( span, ResolutionError::FailedToResolve { - segment: path.last().map(|segment| segment.ident.name), + segment, label, suggestion, module, + item_type, }, ); } diff --git a/src/tools/clippy/tests/ui/crashes/unreachable-array-or-slice.stderr b/src/tools/clippy/tests/ui/crashes/unreachable-array-or-slice.stderr index 9e0d3b934b80f..5420e611728f0 100644 --- a/src/tools/clippy/tests/ui/crashes/unreachable-array-or-slice.stderr +++ b/src/tools/clippy/tests/ui/crashes/unreachable-array-or-slice.stderr @@ -1,4 +1,4 @@ -error[E0433]: failed to resolve: `Self` is only available in impls, traits, and type definitions +error[E0433]: cannot find item `Self` in this scope --> tests/ui/crashes/unreachable-array-or-slice.rs:4:9 | LL | let Self::anything_here_kills_it(a, b, ..) = Foo(5, 5, 5, 5); diff --git a/src/tools/miri/tests/fail/rustc-error2.stderr b/src/tools/miri/tests/fail/rustc-error2.stderr index de2861a019c69..29c86f41f2833 100644 --- a/src/tools/miri/tests/fail/rustc-error2.stderr +++ b/src/tools/miri/tests/fail/rustc-error2.stderr @@ -1,4 +1,4 @@ -error[E0433]: failed to resolve: use of undeclared crate or module `assert_mem_uninitialized_valid` +error[E0433]: cannot find item `assert_mem_uninitialized_valid` --> $DIR/rustc-error2.rs:LL:CC | LL | fn deref(&self) -> &assert_mem_uninitialized_valid::Target { diff --git a/tests/rustdoc-ui/intra-doc/unresolved-import-recovery.rs b/tests/rustdoc-ui/intra-doc/unresolved-import-recovery.rs index c71e5bee12ead..504151c341ee8 100644 --- a/tests/rustdoc-ui/intra-doc/unresolved-import-recovery.rs +++ b/tests/rustdoc-ui/intra-doc/unresolved-import-recovery.rs @@ -1,6 +1,6 @@ // Regression test for issue #95879. -use unresolved_crate::module::Name; //~ ERROR failed to resolve +use unresolved_crate::module::Name; //~ ERROR cannot find item /// [Name] pub struct S; diff --git a/tests/rustdoc-ui/intra-doc/unresolved-import-recovery.stderr b/tests/rustdoc-ui/intra-doc/unresolved-import-recovery.stderr index 8315c73a639f8..c9de7231f0383 100644 --- a/tests/rustdoc-ui/intra-doc/unresolved-import-recovery.stderr +++ b/tests/rustdoc-ui/intra-doc/unresolved-import-recovery.stderr @@ -1,8 +1,8 @@ -error[E0433]: failed to resolve: maybe a missing crate `unresolved_crate`? +error[E0433]: cannot find item `unresolved_crate` in the crate root --> $DIR/unresolved-import-recovery.rs:3:5 | LL | use unresolved_crate::module::Name; - | ^^^^^^^^^^^^^^^^ maybe a missing crate `unresolved_crate`? + | ^^^^^^^^^^^^^^^^ you might be missing a crate named `unresolved_crate` | = help: consider adding `extern crate unresolved_crate` to use the `unresolved_crate` crate diff --git a/tests/rustdoc-ui/issues/issue-61732.rs b/tests/rustdoc-ui/issues/issue-61732.rs index 4bd8efeaa3b97..938cbc316eb71 100644 --- a/tests/rustdoc-ui/issues/issue-61732.rs +++ b/tests/rustdoc-ui/issues/issue-61732.rs @@ -1,4 +1,4 @@ // This previously triggered an ICE. pub(in crate::r#mod) fn main() {} -//~^ ERROR failed to resolve: maybe a missing crate `r#mod` +//~^ ERROR cannot find item `mod` in this scope diff --git a/tests/rustdoc-ui/issues/issue-61732.stderr b/tests/rustdoc-ui/issues/issue-61732.stderr index f351f52d1e15c..437f6618d1062 100644 --- a/tests/rustdoc-ui/issues/issue-61732.stderr +++ b/tests/rustdoc-ui/issues/issue-61732.stderr @@ -1,10 +1,8 @@ -error[E0433]: failed to resolve: maybe a missing crate `r#mod`? +error[E0433]: cannot find item `mod` in this scope --> $DIR/issue-61732.rs:3:15 | LL | pub(in crate::r#mod) fn main() {} - | ^^^^^ maybe a missing crate `r#mod`? - | - = help: consider adding `extern crate r#mod` to use the `r#mod` crate + | ^^^^^ unresolved import error: aborting due to 1 previous error diff --git a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.rs b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.rs index af3f7e5a6f11c..07796b139cf6a 100644 --- a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.rs +++ b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.rs @@ -56,7 +56,7 @@ enum DiagnosticOnEnum { #[derive(Diagnostic)] #[diag(no_crate_example, code = E0123)] #[diag = "E0123"] -//~^ ERROR failed to resolve: maybe a missing crate `core` +//~^ ERROR cannot find item `core` struct WrongStructAttrStyle {} #[derive(Diagnostic)] @@ -801,7 +801,7 @@ struct SuggestionsNoItem { struct SuggestionsInvalidItem { #[suggestion(code(foo))] //~^ ERROR `code(...)` must contain only string literals - //~| ERROR failed to resolve: maybe a missing crate `core` + //~| ERROR cannot find item `core` sub: Span, } @@ -809,7 +809,7 @@ struct SuggestionsInvalidItem { #[diag(no_crate_example)] struct SuggestionsInvalidLiteral { #[suggestion(code = 3)] - //~^ ERROR failed to resolve: maybe a missing crate `core` + //~^ ERROR cannot find item `core` sub: Span, } diff --git a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr index b2f5ba4093a5c..ac5baf6dd6758 100644 --- a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr +++ b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr @@ -524,85 +524,94 @@ LL | #[suggestion(no_crate_suggestion, code = "")] = help: to show a suggestion consisting of multiple parts, use a `Subdiagnostic` annotated with `#[multipart_suggestion(...)]` = help: to show a variable set of suggestions, use a `Vec` of `Subdiagnostic`s annotated with `#[suggestion(...)]` -error[E0433]: failed to resolve: maybe a missing crate `core`? +error[E0433]: cannot find item `core` in the crate root --> $DIR/diagnostic-derive.rs:58:8 | LL | #[diag = "E0123"] - | ^ maybe a missing crate `core`? + | ^ you might be missing a crate named `core` -error[E0433]: failed to resolve: maybe a missing crate `core`? +error[E0433]: cannot find item `core` in the crate root --> $DIR/diagnostic-derive.rs:802:23 | LL | #[suggestion(code(foo))] - | ^^^ maybe a missing crate `core`? + | ^^^ you might be missing a crate named `core` -error[E0433]: failed to resolve: maybe a missing crate `core`? +error[E0433]: cannot find item `core` in the crate root --> $DIR/diagnostic-derive.rs:811:25 | LL | #[suggestion(code = 3)] - | ^ maybe a missing crate `core`? + | ^ you might be missing a crate named `core` error: cannot find attribute `nonsense` in this scope --> $DIR/diagnostic-derive.rs:63:3 | LL | #[nonsense(no_crate_example, code = E0123)] - | ^^^^^^^^ + | ^^^^^^^^ not found in this scope error: cannot find attribute `nonsense` in this scope --> $DIR/diagnostic-derive.rs:150:7 | LL | #[nonsense] - | ^^^^^^^^ + | ^^^^^^^^ not found in this scope error: cannot find attribute `error` in this scope --> $DIR/diagnostic-derive.rs:583:3 | LL | #[error(no_crate_example, code = E0123)] - | ^^^^^ + | ^^^^^ not found in this scope error: cannot find attribute `warn_` in this scope --> $DIR/diagnostic-derive.rs:590:3 | LL | #[warn_(no_crate_example, code = E0123)] - | ^^^^^ help: a built-in attribute with a similar name exists: `warn` + | ^^^^^ + | | + | not found in this scope + | help: a built-in attribute with a similar name exists: `warn` error: cannot find attribute `lint` in this scope --> $DIR/diagnostic-derive.rs:597:3 | LL | #[lint(no_crate_example, code = E0123)] - | ^^^^ help: a built-in attribute with a similar name exists: `link` + | ^^^^ + | | + | not found in this scope + | help: a built-in attribute with a similar name exists: `link` error: cannot find attribute `lint` in this scope --> $DIR/diagnostic-derive.rs:604:3 | LL | #[lint(no_crate_example, code = E0123)] - | ^^^^ help: a built-in attribute with a similar name exists: `link` + | ^^^^ + | | + | not found in this scope + | help: a built-in attribute with a similar name exists: `link` error: cannot find attribute `multipart_suggestion` in this scope --> $DIR/diagnostic-derive.rs:644:3 | LL | #[multipart_suggestion(no_crate_suggestion)] - | ^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^ not found in this scope error: cannot find attribute `multipart_suggestion` in this scope --> $DIR/diagnostic-derive.rs:647:3 | LL | #[multipart_suggestion()] - | ^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^ not found in this scope error: cannot find attribute `multipart_suggestion` in this scope --> $DIR/diagnostic-derive.rs:651:7 | LL | #[multipart_suggestion(no_crate_suggestion)] - | ^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^ not found in this scope -error[E0425]: cannot find value `nonsense` +error[E0425]: cannot find value `nonsense` in module `crate::fluent_generated` --> $DIR/diagnostic-derive.rs:75:8 | LL | #[diag(nonsense, code = E0123)] | ^^^^^^^^ not found in module `crate::fluent_generated` -error[E0425]: cannot find value `__code_34` +error[E0425]: cannot find value `__code_34` in this scope --> $DIR/diagnostic-derive.rs:808:10 | LL | #[derive(Diagnostic)] diff --git a/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive.rs b/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive.rs index c02434e3a8a39..2758cfaa54265 100644 --- a/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive.rs +++ b/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive.rs @@ -66,7 +66,8 @@ struct D { #[derive(Subdiagnostic)] #[foo] //~^ ERROR `#[foo]` is not a valid attribute -//~^^ ERROR cannot find attribute `foo` +//~| ERROR cannot find attribute `foo` +//~| NOTE not found in this scope struct E { #[primary_span] span: Span, @@ -94,8 +95,8 @@ struct G { #[derive(Subdiagnostic)] #[label("...")] -//~^ ERROR failed to resolve: maybe a missing crate `core`? -//~| NOTE maybe a missing crate `core`? +//~^ ERROR cannot find item `core` +//~| NOTE you might be missing a crate named `core` struct H { #[primary_span] span: Span, @@ -162,7 +163,8 @@ struct O { #[derive(Subdiagnostic)] #[foo] //~^ ERROR cannot find attribute `foo` -//~^^ ERROR unsupported type attribute for subdiagnostic enum +//~| ERROR unsupported type attribute for subdiagnostic enum +//~| NOTE not found in this scope enum P { #[label(no_crate_example)] A { @@ -176,7 +178,8 @@ enum P { enum Q { #[bar] //~^ ERROR `#[bar]` is not a valid attribute - //~^^ ERROR cannot find attribute `bar` + //~| ERROR cannot find attribute `bar` + //~| NOTE not found in this scope A { #[primary_span] span: Span, @@ -188,7 +191,8 @@ enum Q { enum R { #[bar = "..."] //~^ ERROR `#[bar = ...]` is not a valid attribute - //~^^ ERROR cannot find attribute `bar` + //~| ERROR cannot find attribute `bar` + //~| NOTE not found in this scope A { #[primary_span] span: Span, @@ -200,7 +204,8 @@ enum R { enum S { #[bar = 4] //~^ ERROR `#[bar = ...]` is not a valid attribute - //~^^ ERROR cannot find attribute `bar` + //~| ERROR cannot find attribute `bar` + //~| NOTE not found in this scope A { #[primary_span] span: Span, @@ -212,7 +217,8 @@ enum S { enum T { #[bar("...")] //~^ ERROR `#[bar(...)]` is not a valid attribute - //~^^ ERROR cannot find attribute `bar` + //~| ERROR cannot find attribute `bar` + //~| NOTE not found in this scope A { #[primary_span] span: Span, @@ -273,7 +279,8 @@ struct Y { span: Span, #[bar] //~^ ERROR `#[bar]` is not a valid attribute - //~^^ ERROR cannot find attribute `bar` + //~| ERROR cannot find attribute `bar` + //~| NOTE not found in this scope bar: String, } @@ -284,7 +291,8 @@ struct Z { span: Span, #[bar = "..."] //~^ ERROR `#[bar = ...]` is not a valid attribute - //~^^ ERROR cannot find attribute `bar` + //~| ERROR cannot find attribute `bar` + //~| NOTE not found in this scope bar: String, } @@ -295,7 +303,8 @@ struct AA { span: Span, #[bar("...")] //~^ ERROR `#[bar(...)]` is not a valid attribute - //~^^ ERROR cannot find attribute `bar` + //~| ERROR cannot find attribute `bar` + //~| NOTE not found in this scope bar: String, } @@ -310,8 +319,8 @@ struct AB { #[derive(Subdiagnostic)] union AC { - //~^ ERROR failed to resolve: maybe a missing crate `core`? - //~| NOTE maybe a missing crate `core`? + //~^ ERROR cannot find item `core` + //~| NOTE you might be missing a crate named `core` span: u32, b: u64, } @@ -581,8 +590,8 @@ struct BD { span2: Span, #[suggestion_part(foo = "bar")] //~^ ERROR `code` is the only valid nested attribute - //~| ERROR failed to resolve: maybe a missing crate `core`? - //~| NOTE maybe a missing crate `core`? + //~| ERROR cannot find item `core` + //~| NOTE you might be missing a crate named `core` span4: Span, #[suggestion_part(code = "...")] //~^ ERROR the `#[suggestion_part(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan` @@ -674,8 +683,8 @@ enum BL { struct BM { #[suggestion_part(code("foo"))] //~^ ERROR expected exactly one string literal for `code = ...` - //~| ERROR failed to resolve: maybe a missing crate `core`? - //~| NOTE maybe a missing crate `core`? + //~| ERROR cannot find item `core` + //~| NOTE you might be missing a crate named `core` span: Span, r#type: String, } @@ -685,8 +694,8 @@ struct BM { struct BN { #[suggestion_part(code("foo", "bar"))] //~^ ERROR expected exactly one string literal for `code = ...` - //~| ERROR failed to resolve: maybe a missing crate `core`? - //~| NOTE maybe a missing crate `core`? + //~| ERROR cannot find item `core` + //~| NOTE you might be missing a crate named `core` span: Span, r#type: String, } @@ -696,8 +705,8 @@ struct BN { struct BO { #[suggestion_part(code(3))] //~^ ERROR expected exactly one string literal for `code = ...` - //~| ERROR failed to resolve: maybe a missing crate `core`? - //~| NOTE maybe a missing crate `core`? + //~| ERROR cannot find item `core` + //~| NOTE you might be missing a crate named `core` span: Span, r#type: String, } @@ -718,8 +727,8 @@ struct BP { #[multipart_suggestion(no_crate_example)] struct BQ { #[suggestion_part(code = 3)] - //~^ ERROR failed to resolve: maybe a missing crate `core`? - //~| NOTE maybe a missing crate `core`? + //~^ ERROR cannot find item `core` + //~| NOTE you might be missing a crate named `core` span: Span, r#type: String, } @@ -811,8 +820,8 @@ struct SuggestionStyleInvalid3 { #[derive(Subdiagnostic)] #[suggestion(no_crate_example, code = "", style("foo"))] //~^ ERROR expected `= "xxx"` -//~| ERROR failed to resolve: maybe a missing crate `core`? -//~| NOTE maybe a missing crate `core`? +//~| ERROR cannot find item `core` +//~| NOTE you might be missing a crate named `core` struct SuggestionStyleInvalid4 { #[primary_span] sub: Span, diff --git a/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive.stderr b/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive.stderr index ce99ad6533299..72ae8c198f1f8 100644 --- a/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive.stderr +++ b/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive.stderr @@ -17,127 +17,127 @@ LL | #[foo] | ^ error: `#[label = ...]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:77:1 + --> $DIR/subdiagnostic-derive.rs:78:1 | LL | #[label = "..."] | ^ error: only `no_span` is a valid nested attribute - --> $DIR/subdiagnostic-derive.rs:86:9 + --> $DIR/subdiagnostic-derive.rs:87:9 | LL | #[label(bug = "...")] | ^^^ error: diagnostic slug must be first argument of a `#[label(...)]` attribute - --> $DIR/subdiagnostic-derive.rs:86:1 + --> $DIR/subdiagnostic-derive.rs:87:1 | LL | #[label(bug = "...")] | ^ error: only `no_span` is a valid nested attribute - --> $DIR/subdiagnostic-derive.rs:106:9 + --> $DIR/subdiagnostic-derive.rs:107:9 | LL | #[label(slug = 4)] | ^^^^ error: diagnostic slug must be first argument of a `#[label(...)]` attribute - --> $DIR/subdiagnostic-derive.rs:106:1 + --> $DIR/subdiagnostic-derive.rs:107:1 | LL | #[label(slug = 4)] | ^ error: only `no_span` is a valid nested attribute - --> $DIR/subdiagnostic-derive.rs:116:9 + --> $DIR/subdiagnostic-derive.rs:117:9 | LL | #[label(slug("..."))] | ^^^^ error: diagnostic slug must be first argument of a `#[label(...)]` attribute - --> $DIR/subdiagnostic-derive.rs:116:1 + --> $DIR/subdiagnostic-derive.rs:117:1 | LL | #[label(slug("..."))] | ^ error: diagnostic slug must be first argument of a `#[label(...)]` attribute - --> $DIR/subdiagnostic-derive.rs:136:1 + --> $DIR/subdiagnostic-derive.rs:137:1 | LL | #[label()] | ^ error: only `no_span` is a valid nested attribute - --> $DIR/subdiagnostic-derive.rs:145:27 + --> $DIR/subdiagnostic-derive.rs:146:27 | LL | #[label(no_crate_example, code = "...")] | ^^^^ error: only `no_span` is a valid nested attribute - --> $DIR/subdiagnostic-derive.rs:154:27 + --> $DIR/subdiagnostic-derive.rs:155:27 | LL | #[label(no_crate_example, applicability = "machine-applicable")] | ^^^^^^^^^^^^^ error: unsupported type attribute for subdiagnostic enum - --> $DIR/subdiagnostic-derive.rs:163:1 + --> $DIR/subdiagnostic-derive.rs:164:1 | LL | #[foo] | ^ error: `#[bar]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:177:5 + --> $DIR/subdiagnostic-derive.rs:179:5 | LL | #[bar] | ^ error: `#[bar = ...]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:189:5 + --> $DIR/subdiagnostic-derive.rs:192:5 | LL | #[bar = "..."] | ^ error: `#[bar = ...]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:201:5 + --> $DIR/subdiagnostic-derive.rs:205:5 | LL | #[bar = 4] | ^ error: `#[bar(...)]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:213:5 + --> $DIR/subdiagnostic-derive.rs:218:5 | LL | #[bar("...")] | ^ error: only `no_span` is a valid nested attribute - --> $DIR/subdiagnostic-derive.rs:225:13 + --> $DIR/subdiagnostic-derive.rs:231:13 | LL | #[label(code = "...")] | ^^^^ error: diagnostic slug must be first argument of a `#[label(...)]` attribute - --> $DIR/subdiagnostic-derive.rs:225:5 + --> $DIR/subdiagnostic-derive.rs:231:5 | LL | #[label(code = "...")] | ^ error: the `#[primary_span]` attribute can only be applied to fields of type `Span` or `MultiSpan` - --> $DIR/subdiagnostic-derive.rs:254:5 + --> $DIR/subdiagnostic-derive.rs:260:5 | LL | #[primary_span] | ^ error: label without `#[primary_span]` field - --> $DIR/subdiagnostic-derive.rs:251:1 + --> $DIR/subdiagnostic-derive.rs:257:1 | LL | #[label(no_crate_example)] | ^ error: `#[applicability]` is only valid on suggestions - --> $DIR/subdiagnostic-derive.rs:264:5 + --> $DIR/subdiagnostic-derive.rs:270:5 | LL | #[applicability] | ^ error: `#[bar]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:274:5 + --> $DIR/subdiagnostic-derive.rs:280:5 | LL | #[bar] | ^ @@ -145,13 +145,13 @@ LL | #[bar] = help: only `primary_span`, `applicability` and `skip_arg` are valid field attributes error: `#[bar = ...]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:285:5 + --> $DIR/subdiagnostic-derive.rs:292:5 | LL | #[bar = "..."] | ^ error: `#[bar(...)]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:296:5 + --> $DIR/subdiagnostic-derive.rs:304:5 | LL | #[bar("...")] | ^ @@ -159,97 +159,97 @@ LL | #[bar("...")] = help: only `primary_span`, `applicability` and `skip_arg` are valid field attributes error: a diagnostic slug must be the first argument to the attribute - --> $DIR/subdiagnostic-derive.rs:328:44 + --> $DIR/subdiagnostic-derive.rs:337:44 | LL | #[label(no_crate_example, no_crate::example)] | ^ error: specified multiple times - --> $DIR/subdiagnostic-derive.rs:341:5 + --> $DIR/subdiagnostic-derive.rs:350:5 | LL | #[primary_span] | ^ | note: previously specified here - --> $DIR/subdiagnostic-derive.rs:338:5 + --> $DIR/subdiagnostic-derive.rs:347:5 | LL | #[primary_span] | ^ error: subdiagnostic kind not specified - --> $DIR/subdiagnostic-derive.rs:347:8 + --> $DIR/subdiagnostic-derive.rs:356:8 | LL | struct AG { | ^^ error: specified multiple times - --> $DIR/subdiagnostic-derive.rs:384:46 + --> $DIR/subdiagnostic-derive.rs:393:46 | LL | #[suggestion(no_crate_example, code = "...", code = "...")] | ^^^^ | note: previously specified here - --> $DIR/subdiagnostic-derive.rs:384:32 + --> $DIR/subdiagnostic-derive.rs:393:32 | LL | #[suggestion(no_crate_example, code = "...", code = "...")] | ^^^^ error: specified multiple times - --> $DIR/subdiagnostic-derive.rs:402:5 + --> $DIR/subdiagnostic-derive.rs:411:5 | LL | #[applicability] | ^ | note: previously specified here - --> $DIR/subdiagnostic-derive.rs:399:5 + --> $DIR/subdiagnostic-derive.rs:408:5 | LL | #[applicability] | ^ error: the `#[applicability]` attribute can only be applied to fields of type `Applicability` - --> $DIR/subdiagnostic-derive.rs:412:5 + --> $DIR/subdiagnostic-derive.rs:421:5 | LL | #[applicability] | ^ error: suggestion without `code = "..."` - --> $DIR/subdiagnostic-derive.rs:425:1 + --> $DIR/subdiagnostic-derive.rs:434:1 | LL | #[suggestion(no_crate_example)] | ^ error: invalid applicability - --> $DIR/subdiagnostic-derive.rs:435:62 + --> $DIR/subdiagnostic-derive.rs:444:62 | LL | #[suggestion(no_crate_example, code = "...", applicability = "foo")] | ^^^^^ error: suggestion without `#[primary_span]` field - --> $DIR/subdiagnostic-derive.rs:453:1 + --> $DIR/subdiagnostic-derive.rs:462:1 | LL | #[suggestion(no_crate_example, code = "...")] | ^ error: unsupported type attribute for subdiagnostic enum - --> $DIR/subdiagnostic-derive.rs:467:1 + --> $DIR/subdiagnostic-derive.rs:476:1 | LL | #[label] | ^ error: `var` doesn't refer to a field on this type - --> $DIR/subdiagnostic-derive.rs:487:39 + --> $DIR/subdiagnostic-derive.rs:496:39 | LL | #[suggestion(no_crate_example, code = "{var}", applicability = "machine-applicable")] | ^^^^^^^ error: `var` doesn't refer to a field on this type - --> $DIR/subdiagnostic-derive.rs:506:43 + --> $DIR/subdiagnostic-derive.rs:515:43 | LL | #[suggestion(no_crate_example, code = "{var}", applicability = "machine-applicable")] | ^^^^^^^ error: `#[suggestion_part]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:529:5 + --> $DIR/subdiagnostic-derive.rs:538:5 | LL | #[suggestion_part] | ^ @@ -257,7 +257,7 @@ LL | #[suggestion_part] = help: `#[suggestion_part(...)]` is only valid in multipart suggestions, use `#[primary_span]` instead error: `#[suggestion_part(...)]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:532:5 + --> $DIR/subdiagnostic-derive.rs:541:5 | LL | #[suggestion_part(code = "...")] | ^ @@ -265,13 +265,13 @@ LL | #[suggestion_part(code = "...")] = help: `#[suggestion_part(...)]` is only valid in multipart suggestions error: suggestion without `#[primary_span]` field - --> $DIR/subdiagnostic-derive.rs:526:1 + --> $DIR/subdiagnostic-derive.rs:535:1 | LL | #[suggestion(no_crate_example, code = "...")] | ^ error: invalid nested attribute - --> $DIR/subdiagnostic-derive.rs:541:42 + --> $DIR/subdiagnostic-derive.rs:550:42 | LL | #[multipart_suggestion(no_crate_example, code = "...", applicability = "machine-applicable")] | ^^^^ @@ -279,25 +279,25 @@ LL | #[multipart_suggestion(no_crate_example, code = "...", applicability = "mac = help: only `no_span`, `style` and `applicability` are valid nested attributes error: multipart suggestion without any `#[suggestion_part(...)]` fields - --> $DIR/subdiagnostic-derive.rs:541:1 + --> $DIR/subdiagnostic-derive.rs:550:1 | LL | #[multipart_suggestion(no_crate_example, code = "...", applicability = "machine-applicable")] | ^ error: `#[suggestion_part(...)]` attribute without `code = "..."` - --> $DIR/subdiagnostic-derive.rs:551:5 + --> $DIR/subdiagnostic-derive.rs:560:5 | LL | #[suggestion_part] | ^ error: `#[suggestion_part(...)]` attribute without `code = "..."` - --> $DIR/subdiagnostic-derive.rs:559:5 + --> $DIR/subdiagnostic-derive.rs:568:5 | LL | #[suggestion_part()] | ^ error: `#[primary_span]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:568:5 + --> $DIR/subdiagnostic-derive.rs:577:5 | LL | #[primary_span] | ^ @@ -305,97 +305,97 @@ LL | #[primary_span] = help: multipart suggestions use one or more `#[suggestion_part]`s rather than one `#[primary_span]` error: multipart suggestion without any `#[suggestion_part(...)]` fields - --> $DIR/subdiagnostic-derive.rs:565:1 + --> $DIR/subdiagnostic-derive.rs:574:1 | LL | #[multipart_suggestion(no_crate_example)] | ^ error: `#[suggestion_part(...)]` attribute without `code = "..."` - --> $DIR/subdiagnostic-derive.rs:576:5 + --> $DIR/subdiagnostic-derive.rs:585:5 | LL | #[suggestion_part] | ^ error: `#[suggestion_part(...)]` attribute without `code = "..."` - --> $DIR/subdiagnostic-derive.rs:579:5 + --> $DIR/subdiagnostic-derive.rs:588:5 | LL | #[suggestion_part()] | ^ error: `code` is the only valid nested attribute - --> $DIR/subdiagnostic-derive.rs:582:23 + --> $DIR/subdiagnostic-derive.rs:591:23 | LL | #[suggestion_part(foo = "bar")] | ^^^ error: the `#[suggestion_part(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan` - --> $DIR/subdiagnostic-derive.rs:587:5 + --> $DIR/subdiagnostic-derive.rs:596:5 | LL | #[suggestion_part(code = "...")] | ^ error: the `#[suggestion_part(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan` - --> $DIR/subdiagnostic-derive.rs:590:5 + --> $DIR/subdiagnostic-derive.rs:599:5 | LL | #[suggestion_part()] | ^ error: specified multiple times - --> $DIR/subdiagnostic-derive.rs:598:37 + --> $DIR/subdiagnostic-derive.rs:607:37 | LL | #[suggestion_part(code = "...", code = ",,,")] | ^^^^ | note: previously specified here - --> $DIR/subdiagnostic-derive.rs:598:23 + --> $DIR/subdiagnostic-derive.rs:607:23 | LL | #[suggestion_part(code = "...", code = ",,,")] | ^^^^ error: `#[applicability]` has no effect if all `#[suggestion]`/`#[multipart_suggestion]` attributes have a static `applicability = "..."` - --> $DIR/subdiagnostic-derive.rs:627:5 + --> $DIR/subdiagnostic-derive.rs:636:5 | LL | #[applicability] | ^ error: expected exactly one string literal for `code = ...` - --> $DIR/subdiagnostic-derive.rs:675:34 + --> $DIR/subdiagnostic-derive.rs:684:34 | LL | #[suggestion_part(code("foo"))] | ^ error: expected exactly one string literal for `code = ...` - --> $DIR/subdiagnostic-derive.rs:686:41 + --> $DIR/subdiagnostic-derive.rs:695:41 | LL | #[suggestion_part(code("foo", "bar"))] | ^ error: expected exactly one string literal for `code = ...` - --> $DIR/subdiagnostic-derive.rs:697:30 + --> $DIR/subdiagnostic-derive.rs:706:30 | LL | #[suggestion_part(code(3))] | ^ error: expected exactly one string literal for `code = ...` - --> $DIR/subdiagnostic-derive.rs:708:29 + --> $DIR/subdiagnostic-derive.rs:717:29 | LL | #[suggestion_part(code())] | ^ error: specified multiple times - --> $DIR/subdiagnostic-derive.rs:763:1 + --> $DIR/subdiagnostic-derive.rs:772:1 | LL | #[suggestion(no_crate_example, code = "", style = "hidden", style = "normal")] | ^ | note: previously specified here - --> $DIR/subdiagnostic-derive.rs:763:1 + --> $DIR/subdiagnostic-derive.rs:772:1 | LL | #[suggestion(no_crate_example, code = "", style = "hidden", style = "normal")] | ^ error: `#[suggestion_hidden(...)]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:772:1 + --> $DIR/subdiagnostic-derive.rs:781:1 | LL | #[suggestion_hidden(no_crate_example, code = "")] | ^ @@ -403,7 +403,7 @@ LL | #[suggestion_hidden(no_crate_example, code = "")] = help: Use `#[suggestion(..., style = "hidden")]` instead error: `#[suggestion_hidden(...)]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:780:1 + --> $DIR/subdiagnostic-derive.rs:789:1 | LL | #[suggestion_hidden(no_crate_example, code = "", style = "normal")] | ^ @@ -411,7 +411,7 @@ LL | #[suggestion_hidden(no_crate_example, code = "", style = "normal")] = help: Use `#[suggestion(..., style = "hidden")]` instead error: invalid suggestion style - --> $DIR/subdiagnostic-derive.rs:788:51 + --> $DIR/subdiagnostic-derive.rs:797:51 | LL | #[suggestion(no_crate_example, code = "", style = "foo")] | ^^^^^ @@ -419,25 +419,25 @@ LL | #[suggestion(no_crate_example, code = "", style = "foo")] = help: valid styles are `normal`, `short`, `hidden`, `verbose` and `tool-only` error: expected `= "xxx"` - --> $DIR/subdiagnostic-derive.rs:796:49 + --> $DIR/subdiagnostic-derive.rs:805:49 | LL | #[suggestion(no_crate_example, code = "", style = 42)] | ^ error: a diagnostic slug must be the first argument to the attribute - --> $DIR/subdiagnostic-derive.rs:804:48 + --> $DIR/subdiagnostic-derive.rs:813:48 | LL | #[suggestion(no_crate_example, code = "", style)] | ^ error: expected `= "xxx"` - --> $DIR/subdiagnostic-derive.rs:812:48 + --> $DIR/subdiagnostic-derive.rs:821:48 | LL | #[suggestion(no_crate_example, code = "", style("foo"))] | ^ error: `#[primary_span]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:825:5 + --> $DIR/subdiagnostic-derive.rs:834:5 | LL | #[primary_span] | ^ @@ -446,121 +446,121 @@ LL | #[primary_span] = help: to create a suggestion with multiple spans, use `#[multipart_suggestion]` instead error: suggestion without `#[primary_span]` field - --> $DIR/subdiagnostic-derive.rs:822:1 + --> $DIR/subdiagnostic-derive.rs:831:1 | LL | #[suggestion(no_crate_example, code = "")] | ^ -error[E0433]: failed to resolve: maybe a missing crate `core`? - --> $DIR/subdiagnostic-derive.rs:96:9 +error[E0433]: cannot find item `core` in the crate root + --> $DIR/subdiagnostic-derive.rs:97:9 | LL | #[label("...")] - | ^^^^^ maybe a missing crate `core`? + | ^^^^^ you might be missing a crate named `core` -error[E0433]: failed to resolve: maybe a missing crate `core`? - --> $DIR/subdiagnostic-derive.rs:312:1 +error[E0433]: cannot find item `core` in the crate root + --> $DIR/subdiagnostic-derive.rs:321:1 | LL | union AC { - | ^^^^^ maybe a missing crate `core`? + | ^^^^^ you might be missing a crate named `core` -error[E0433]: failed to resolve: maybe a missing crate `core`? - --> $DIR/subdiagnostic-derive.rs:582:27 +error[E0433]: cannot find item `core` in the crate root + --> $DIR/subdiagnostic-derive.rs:591:27 | LL | #[suggestion_part(foo = "bar")] - | ^ maybe a missing crate `core`? + | ^ you might be missing a crate named `core` -error[E0433]: failed to resolve: maybe a missing crate `core`? - --> $DIR/subdiagnostic-derive.rs:675:28 +error[E0433]: cannot find item `core` in the crate root + --> $DIR/subdiagnostic-derive.rs:684:28 | LL | #[suggestion_part(code("foo"))] - | ^^^^^ maybe a missing crate `core`? + | ^^^^^ you might be missing a crate named `core` -error[E0433]: failed to resolve: maybe a missing crate `core`? - --> $DIR/subdiagnostic-derive.rs:686:28 +error[E0433]: cannot find item `core` in the crate root + --> $DIR/subdiagnostic-derive.rs:695:28 | LL | #[suggestion_part(code("foo", "bar"))] - | ^^^^^ maybe a missing crate `core`? + | ^^^^^ you might be missing a crate named `core` -error[E0433]: failed to resolve: maybe a missing crate `core`? - --> $DIR/subdiagnostic-derive.rs:697:28 +error[E0433]: cannot find item `core` in the crate root + --> $DIR/subdiagnostic-derive.rs:706:28 | LL | #[suggestion_part(code(3))] - | ^ maybe a missing crate `core`? + | ^ you might be missing a crate named `core` -error[E0433]: failed to resolve: maybe a missing crate `core`? - --> $DIR/subdiagnostic-derive.rs:720:30 +error[E0433]: cannot find item `core` in the crate root + --> $DIR/subdiagnostic-derive.rs:729:30 | LL | #[suggestion_part(code = 3)] - | ^ maybe a missing crate `core`? + | ^ you might be missing a crate named `core` -error[E0433]: failed to resolve: maybe a missing crate `core`? - --> $DIR/subdiagnostic-derive.rs:812:48 +error[E0433]: cannot find item `core` in the crate root + --> $DIR/subdiagnostic-derive.rs:821:48 | LL | #[suggestion(no_crate_example, code = "", style("foo"))] - | ^ maybe a missing crate `core`? + | ^ you might be missing a crate named `core` error: cannot find attribute `foo` in this scope --> $DIR/subdiagnostic-derive.rs:67:3 | LL | #[foo] - | ^^^ + | ^^^ not found in this scope error: cannot find attribute `foo` in this scope - --> $DIR/subdiagnostic-derive.rs:163:3 + --> $DIR/subdiagnostic-derive.rs:164:3 | LL | #[foo] - | ^^^ + | ^^^ not found in this scope error: cannot find attribute `bar` in this scope - --> $DIR/subdiagnostic-derive.rs:177:7 + --> $DIR/subdiagnostic-derive.rs:179:7 | LL | #[bar] - | ^^^ + | ^^^ not found in this scope error: cannot find attribute `bar` in this scope - --> $DIR/subdiagnostic-derive.rs:189:7 + --> $DIR/subdiagnostic-derive.rs:192:7 | LL | #[bar = "..."] - | ^^^ + | ^^^ not found in this scope error: cannot find attribute `bar` in this scope - --> $DIR/subdiagnostic-derive.rs:201:7 + --> $DIR/subdiagnostic-derive.rs:205:7 | LL | #[bar = 4] - | ^^^ + | ^^^ not found in this scope error: cannot find attribute `bar` in this scope - --> $DIR/subdiagnostic-derive.rs:213:7 + --> $DIR/subdiagnostic-derive.rs:218:7 | LL | #[bar("...")] - | ^^^ + | ^^^ not found in this scope error: cannot find attribute `bar` in this scope - --> $DIR/subdiagnostic-derive.rs:274:7 + --> $DIR/subdiagnostic-derive.rs:280:7 | LL | #[bar] - | ^^^ + | ^^^ not found in this scope error: cannot find attribute `bar` in this scope - --> $DIR/subdiagnostic-derive.rs:285:7 + --> $DIR/subdiagnostic-derive.rs:292:7 | LL | #[bar = "..."] - | ^^^ + | ^^^ not found in this scope error: cannot find attribute `bar` in this scope - --> $DIR/subdiagnostic-derive.rs:296:7 + --> $DIR/subdiagnostic-derive.rs:304:7 | LL | #[bar("...")] - | ^^^ + | ^^^ not found in this scope -error[E0425]: cannot find value `slug` - --> $DIR/subdiagnostic-derive.rs:126:9 +error[E0425]: cannot find value `slug` in module `crate::fluent_generated` + --> $DIR/subdiagnostic-derive.rs:127:9 | LL | #[label(slug)] | ^^^^ not found in module `crate::fluent_generated` -error[E0425]: cannot find value `__code_29` - --> $DIR/subdiagnostic-derive.rs:714:10 +error[E0425]: cannot find value `__code_29` in this scope + --> $DIR/subdiagnostic-derive.rs:723:10 | LL | #[derive(Subdiagnostic)] | ^^^^^^^^^^^^^ not found in this scope diff --git a/tests/ui/attributes/field-attributes-vis-unresolved.rs b/tests/ui/attributes/field-attributes-vis-unresolved.rs index d1bd2a1e72724..04ed4283d294d 100644 --- a/tests/ui/attributes/field-attributes-vis-unresolved.rs +++ b/tests/ui/attributes/field-attributes-vis-unresolved.rs @@ -14,12 +14,12 @@ mod internal { struct S { #[rustfmt::skip] - pub(in nonexistent) field: u8 //~ ERROR failed to resolve + pub(in nonexistent) field: u8 //~ ERROR cannot find item `nonexistent` } struct Z( #[rustfmt::skip] - pub(in nonexistent) u8 //~ ERROR failed to resolve + pub(in nonexistent) u8 //~ ERROR cannot find item `nonexistent` ); fn main() {} diff --git a/tests/ui/attributes/field-attributes-vis-unresolved.stderr b/tests/ui/attributes/field-attributes-vis-unresolved.stderr index 439762546381e..edd019ae3b8e7 100644 --- a/tests/ui/attributes/field-attributes-vis-unresolved.stderr +++ b/tests/ui/attributes/field-attributes-vis-unresolved.stderr @@ -1,16 +1,16 @@ -error[E0433]: failed to resolve: maybe a missing crate `nonexistent`? +error[E0433]: cannot find item `nonexistent` in this scope --> $DIR/field-attributes-vis-unresolved.rs:17:12 | LL | pub(in nonexistent) field: u8 - | ^^^^^^^^^^^ maybe a missing crate `nonexistent`? + | ^^^^^^^^^^^ you might be missing a crate named `nonexistent` | = help: consider adding `extern crate nonexistent` to use the `nonexistent` crate -error[E0433]: failed to resolve: maybe a missing crate `nonexistent`? +error[E0433]: cannot find item `nonexistent` in this scope --> $DIR/field-attributes-vis-unresolved.rs:22:12 | LL | pub(in nonexistent) u8 - | ^^^^^^^^^^^ maybe a missing crate `nonexistent`? + | ^^^^^^^^^^^ you might be missing a crate named `nonexistent` | = help: consider adding `extern crate nonexistent` to use the `nonexistent` crate diff --git a/tests/ui/borrowck/non-ADT-struct-pattern-box-pattern-ice-121463.rs b/tests/ui/borrowck/non-ADT-struct-pattern-box-pattern-ice-121463.rs index cf927e34fb418..6d11af54ec49f 100644 --- a/tests/ui/borrowck/non-ADT-struct-pattern-box-pattern-ice-121463.rs +++ b/tests/ui/borrowck/non-ADT-struct-pattern-box-pattern-ice-121463.rs @@ -4,9 +4,9 @@ fn main() { let mut a = E::StructVar { boxed: Box::new(5_i32) }; - //~^ ERROR failed to resolve: use of undeclared type `E` + //~^ ERROR cannot find item `E` match a { E::StructVar { box boxed } => { } - //~^ ERROR failed to resolve: use of undeclared type `E` + //~^ ERROR cannot find item `E` } } diff --git a/tests/ui/borrowck/non-ADT-struct-pattern-box-pattern-ice-121463.stderr b/tests/ui/borrowck/non-ADT-struct-pattern-box-pattern-ice-121463.stderr index 349546606a57e..3b7b60895680c 100644 --- a/tests/ui/borrowck/non-ADT-struct-pattern-box-pattern-ice-121463.stderr +++ b/tests/ui/borrowck/non-ADT-struct-pattern-box-pattern-ice-121463.stderr @@ -1,4 +1,4 @@ -error[E0433]: failed to resolve: use of undeclared type `E` +error[E0433]: cannot find item `E` in this scope --> $DIR/non-ADT-struct-pattern-box-pattern-ice-121463.rs:6:17 | LL | let mut a = E::StructVar { boxed: Box::new(5_i32) }; @@ -7,7 +7,7 @@ LL | let mut a = E::StructVar { boxed: Box::new(5_i32) }; | use of undeclared type `E` | help: a trait with a similar name exists: `Eq` -error[E0433]: failed to resolve: use of undeclared type `E` +error[E0433]: cannot find item `E` in this scope --> $DIR/non-ADT-struct-pattern-box-pattern-ice-121463.rs:9:9 | LL | E::StructVar { box boxed } => { } diff --git a/tests/ui/cfg/diagnostics-cross-crate.rs b/tests/ui/cfg/diagnostics-cross-crate.rs index e5d7e02afe374..2a2c6d0ef33e8 100644 --- a/tests/ui/cfg/diagnostics-cross-crate.rs +++ b/tests/ui/cfg/diagnostics-cross-crate.rs @@ -14,7 +14,7 @@ fn main() { // The module isn't found - we would like to get a diagnostic, but currently don't due to // the awkward way the resolver diagnostics are currently implemented. - cfged_out::inner::doesnt_exist::hello(); //~ ERROR failed to resolve + cfged_out::inner::doesnt_exist::hello(); //~ ERROR cannot find item `doesnt_exist` //~^ NOTE could not find `doesnt_exist` in `inner` //~| NOTE found an item that was configured out diff --git a/tests/ui/cfg/diagnostics-cross-crate.stderr b/tests/ui/cfg/diagnostics-cross-crate.stderr index 73598df060b67..ff4327f7dd634 100644 --- a/tests/ui/cfg/diagnostics-cross-crate.stderr +++ b/tests/ui/cfg/diagnostics-cross-crate.stderr @@ -1,4 +1,4 @@ -error[E0433]: failed to resolve: could not find `doesnt_exist` in `inner` +error[E0433]: cannot find item `doesnt_exist` in module `inner` --> $DIR/diagnostics-cross-crate.rs:17:23 | LL | cfged_out::inner::doesnt_exist::hello(); diff --git a/tests/ui/cfg/diagnostics-same-crate.rs b/tests/ui/cfg/diagnostics-same-crate.rs index f31b08d3ad901..2304fa5350a18 100644 --- a/tests/ui/cfg/diagnostics-same-crate.rs +++ b/tests/ui/cfg/diagnostics-same-crate.rs @@ -49,7 +49,7 @@ fn main() { // The module isn't found - we would like to get a diagnostic, but currently don't due to // the awkward way the resolver diagnostics are currently implemented. - inner::doesnt_exist::hello(); //~ ERROR failed to resolve + inner::doesnt_exist::hello(); //~ ERROR cannot find item `doesnt_exist` //~| NOTE could not find `doesnt_exist` in `inner` // It should find the one in the right module, not the wrong one. diff --git a/tests/ui/cfg/diagnostics-same-crate.stderr b/tests/ui/cfg/diagnostics-same-crate.stderr index f98fdcf4b61c3..1f15d087f59cb 100644 --- a/tests/ui/cfg/diagnostics-same-crate.stderr +++ b/tests/ui/cfg/diagnostics-same-crate.stderr @@ -22,7 +22,7 @@ note: found an item that was configured out LL | pub mod doesnt_exist { | ^^^^^^^^^^^^ -error[E0433]: failed to resolve: could not find `doesnt_exist` in `inner` +error[E0433]: cannot find item `doesnt_exist` in module `inner` --> $DIR/diagnostics-same-crate.rs:52:12 | LL | inner::doesnt_exist::hello(); diff --git a/tests/ui/coherence/conflicting-impl-with-err.rs b/tests/ui/coherence/conflicting-impl-with-err.rs index 3e0234b874d7b..940827119d3c1 100644 --- a/tests/ui/coherence/conflicting-impl-with-err.rs +++ b/tests/ui/coherence/conflicting-impl-with-err.rs @@ -1,8 +1,8 @@ struct ErrorKind; struct Error(ErrorKind); -impl From for Error { //~ ERROR failed to resolve - fn from(_: nope::Thing) -> Self { //~ ERROR failed to resolve +impl From for Error { //~ ERROR cannot find item `nope` + fn from(_: nope::Thing) -> Self { //~ ERROR cannot find item `nope` unimplemented!() } } diff --git a/tests/ui/coherence/conflicting-impl-with-err.stderr b/tests/ui/coherence/conflicting-impl-with-err.stderr index 3009b452dc7a0..7eef802ca67eb 100644 --- a/tests/ui/coherence/conflicting-impl-with-err.stderr +++ b/tests/ui/coherence/conflicting-impl-with-err.stderr @@ -1,10 +1,10 @@ -error[E0433]: failed to resolve: use of undeclared crate or module `nope` +error[E0433]: cannot find item `nope` in this scope --> $DIR/conflicting-impl-with-err.rs:4:11 | LL | impl From for Error { | ^^^^ use of undeclared crate or module `nope` -error[E0433]: failed to resolve: use of undeclared crate or module `nope` +error[E0433]: cannot find item `nope` in this scope --> $DIR/conflicting-impl-with-err.rs:5:16 | LL | fn from(_: nope::Thing) -> Self { diff --git a/tests/ui/const-generics/generic_const_exprs/ice-predicates-of-no-entry-found-for-key-119275.rs b/tests/ui/const-generics/generic_const_exprs/ice-predicates-of-no-entry-found-for-key-119275.rs index 9a04e1bc3391d..8550bf7d19f16 100644 --- a/tests/ui/const-generics/generic_const_exprs/ice-predicates-of-no-entry-found-for-key-119275.rs +++ b/tests/ui/const-generics/generic_const_exprs/ice-predicates-of-no-entry-found-for-key-119275.rs @@ -11,7 +11,7 @@ where //~^ ERROR only lifetime parameters can be used in this context //~^^ ERROR defaults for generic parameters are not allowed in `for<...>` binders //~^^^ ERROR defaults for generic parameters are not allowed in `for<...>` binders - //~^^^^ ERROR failed to resolve: use of undeclared type `COT` + //~^^^^ ERROR cannot find item `COT` { } diff --git a/tests/ui/const-generics/generic_const_exprs/ice-predicates-of-no-entry-found-for-key-119275.stderr b/tests/ui/const-generics/generic_const_exprs/ice-predicates-of-no-entry-found-for-key-119275.stderr index ee0ec38ab0631..52260fec4654a 100644 --- a/tests/ui/const-generics/generic_const_exprs/ice-predicates-of-no-entry-found-for-key-119275.stderr +++ b/tests/ui/const-generics/generic_const_exprs/ice-predicates-of-no-entry-found-for-key-119275.stderr @@ -34,7 +34,7 @@ error: defaults for generic parameters are not allowed in `for<...>` binders LL | for [(); COT::BYTES]:, | ^^^^^^^ -error[E0433]: failed to resolve: use of undeclared type `COT` +error[E0433]: cannot find item `COT` in this scope --> $DIR/ice-predicates-of-no-entry-found-for-key-119275.rs:10:43 | LL | for [(); COT::BYTES]:, diff --git a/tests/ui/const-generics/issues/issue-82956.rs b/tests/ui/const-generics/issues/issue-82956.rs index 3539e9b966c86..c154cb63045ba 100644 --- a/tests/ui/const-generics/issues/issue-82956.rs +++ b/tests/ui/const-generics/issues/issue-82956.rs @@ -23,7 +23,7 @@ where fn pop(self) -> (Self::Newlen, Self::Output) { let mut iter = IntoIter::new(self); - //~^ ERROR: failed to resolve: use of undeclared type `IntoIter` + //~^ ERROR: cannot find item `IntoIter` let end = iter.next_back().unwrap(); let new = [(); N - 1].map(move |()| iter.next().unwrap()); (new, end) diff --git a/tests/ui/const-generics/issues/issue-82956.stderr b/tests/ui/const-generics/issues/issue-82956.stderr index a956fc741f4d4..e3b34f18f5f9e 100644 --- a/tests/ui/const-generics/issues/issue-82956.stderr +++ b/tests/ui/const-generics/issues/issue-82956.stderr @@ -1,4 +1,4 @@ -error[E0433]: failed to resolve: use of undeclared type `IntoIter` +error[E0433]: cannot find item `IntoIter` in this scope --> $DIR/issue-82956.rs:25:24 | LL | let mut iter = IntoIter::new(self); diff --git a/tests/ui/consts/const_refs_to_static-ice-121413.rs b/tests/ui/consts/const_refs_to_static-ice-121413.rs index 8fc3912efd08e..24c2e0650b887 100644 --- a/tests/ui/consts/const_refs_to_static-ice-121413.rs +++ b/tests/ui/consts/const_refs_to_static-ice-121413.rs @@ -7,7 +7,7 @@ const REF_INTERIOR_MUT: &usize = { //~^ HELP consider importing this struct static FOO: Sync = AtomicUsize::new(0); - //~^ ERROR failed to resolve: use of undeclared type `AtomicUsize` + //~^ ERROR cannot find item `AtomicUsize` //~| WARN trait objects without an explicit `dyn` are deprecated //~| ERROR the size for values of type `(dyn Sync + 'static)` cannot be known at compilation time //~| ERROR the size for values of type `(dyn Sync + 'static)` cannot be known at compilation time diff --git a/tests/ui/consts/const_refs_to_static-ice-121413.stderr b/tests/ui/consts/const_refs_to_static-ice-121413.stderr index fbe32a70293aa..abd476009ce86 100644 --- a/tests/ui/consts/const_refs_to_static-ice-121413.stderr +++ b/tests/ui/consts/const_refs_to_static-ice-121413.stderr @@ -1,4 +1,4 @@ -error[E0433]: failed to resolve: use of undeclared type `AtomicUsize` +error[E0433]: cannot find item `AtomicUsize` in this scope --> $DIR/const_refs_to_static-ice-121413.rs:9:24 | LL | static FOO: Sync = AtomicUsize::new(0); diff --git a/tests/ui/custom-attribute-multisegment.rs b/tests/ui/custom-attribute-multisegment.rs index 2434921390245..a9f309b1a5e8c 100644 --- a/tests/ui/custom-attribute-multisegment.rs +++ b/tests/ui/custom-attribute-multisegment.rs @@ -2,5 +2,5 @@ mod existent {} -#[existent::nonexistent] //~ ERROR failed to resolve: could not find `nonexistent` in `existent` +#[existent::nonexistent] //~ ERROR cannot find macro `nonexistent` fn main() {} diff --git a/tests/ui/custom-attribute-multisegment.stderr b/tests/ui/custom-attribute-multisegment.stderr index 90ebe27793911..28723fd9b33c0 100644 --- a/tests/ui/custom-attribute-multisegment.stderr +++ b/tests/ui/custom-attribute-multisegment.stderr @@ -1,4 +1,4 @@ -error[E0433]: failed to resolve: could not find `nonexistent` in `existent` +error[E0433]: cannot find macro `nonexistent` in module `existent` --> $DIR/custom-attribute-multisegment.rs:5:13 | LL | #[existent::nonexistent] diff --git a/tests/ui/delegation/bad-resolve.rs b/tests/ui/delegation/bad-resolve.rs index 184ec20bb5d86..e2287299bc5d7 100644 --- a/tests/ui/delegation/bad-resolve.rs +++ b/tests/ui/delegation/bad-resolve.rs @@ -37,7 +37,7 @@ impl Trait for S { } mod prefix {} -reuse unresolved_prefix::{a, b, c}; //~ ERROR use of undeclared crate or module `unresolved_prefix` -reuse prefix::{self, super, crate}; //~ ERROR `crate` in paths can only be used in start position +reuse unresolved_prefix::{a, b, c}; //~ ERROR cannot find item `unresolved_prefix` +reuse prefix::{self, super, crate}; //~ ERROR cannot find module `crate` fn main() {} diff --git a/tests/ui/delegation/bad-resolve.stderr b/tests/ui/delegation/bad-resolve.stderr index 883ff523bcfea..faf0e19f66474 100644 --- a/tests/ui/delegation/bad-resolve.stderr +++ b/tests/ui/delegation/bad-resolve.stderr @@ -63,13 +63,13 @@ LL | type Type; LL | impl Trait for S { | ^^^^^^^^^^^^^^^^ missing `Type` in implementation -error[E0433]: failed to resolve: use of undeclared crate or module `unresolved_prefix` +error[E0433]: cannot find item `unresolved_prefix` in this scope --> $DIR/bad-resolve.rs:40:7 | LL | reuse unresolved_prefix::{a, b, c}; | ^^^^^^^^^^^^^^^^^ use of undeclared crate or module `unresolved_prefix` -error[E0433]: failed to resolve: `crate` in paths can only be used in start position +error[E0433]: cannot find module `crate` in module `prefix` --> $DIR/bad-resolve.rs:41:29 | LL | reuse prefix::{self, super, crate}; diff --git a/tests/ui/delegation/glob-bad-path.rs b/tests/ui/delegation/glob-bad-path.rs index 7bc4f0153a308..f16569282e018 100644 --- a/tests/ui/delegation/glob-bad-path.rs +++ b/tests/ui/delegation/glob-bad-path.rs @@ -5,7 +5,7 @@ trait Trait {} struct S; impl Trait for u8 { - reuse unresolved::*; //~ ERROR failed to resolve: use of undeclared crate or module `unresolved` + reuse unresolved::*; //~ ERROR cannot find type `unresolved` reuse S::*; //~ ERROR expected trait, found struct `S` } diff --git a/tests/ui/delegation/glob-bad-path.stderr b/tests/ui/delegation/glob-bad-path.stderr index 0c06364b3f0ab..3ab1c29f1abef 100644 --- a/tests/ui/delegation/glob-bad-path.stderr +++ b/tests/ui/delegation/glob-bad-path.stderr @@ -4,7 +4,7 @@ error: expected trait, found struct `S` LL | reuse S::*; | ^ not a trait -error[E0433]: failed to resolve: use of undeclared crate or module `unresolved` +error[E0433]: cannot find type `unresolved` in this scope --> $DIR/glob-bad-path.rs:8:11 | LL | reuse unresolved::*; diff --git a/tests/ui/derived-errors/issue-31997-1.stderr b/tests/ui/derived-errors/issue-31997-1.stderr index 40485027a660c..ccb62a6db55f4 100644 --- a/tests/ui/derived-errors/issue-31997-1.stderr +++ b/tests/ui/derived-errors/issue-31997-1.stderr @@ -1,4 +1,4 @@ -error[E0433]: failed to resolve: use of undeclared type `HashMap` +error[E0433]: cannot find item `HashMap` in this scope --> $DIR/issue-31997-1.rs:20:19 | LL | let mut map = HashMap::new(); diff --git a/tests/ui/dollar-crate/dollar-crate-is-keyword-2.rs b/tests/ui/dollar-crate/dollar-crate-is-keyword-2.rs index bbab6f8774876..dc66ce5240732 100644 --- a/tests/ui/dollar-crate/dollar-crate-is-keyword-2.rs +++ b/tests/ui/dollar-crate/dollar-crate-is-keyword-2.rs @@ -3,8 +3,8 @@ mod a {} macro_rules! m { () => { use a::$crate; //~ ERROR unresolved import `a::$crate` - use a::$crate::b; //~ ERROR `$crate` in paths can only be used in start position - type A = a::$crate; //~ ERROR `$crate` in paths can only be used in start position + use a::$crate::b; //~ ERROR cannot find module `$crate` + type A = a::$crate; //~ ERROR cannot find module `$crate` } } diff --git a/tests/ui/dollar-crate/dollar-crate-is-keyword-2.stderr b/tests/ui/dollar-crate/dollar-crate-is-keyword-2.stderr index d46029710d6f7..8fedb484f5ecf 100644 --- a/tests/ui/dollar-crate/dollar-crate-is-keyword-2.stderr +++ b/tests/ui/dollar-crate/dollar-crate-is-keyword-2.stderr @@ -1,4 +1,4 @@ -error[E0433]: failed to resolve: `$crate` in paths can only be used in start position +error[E0433]: cannot find module `$crate` in module `a` --> $DIR/dollar-crate-is-keyword-2.rs:6:16 | LL | use a::$crate::b; @@ -20,7 +20,7 @@ LL | m!(); | = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0433]: failed to resolve: `$crate` in paths can only be used in start position +error[E0433]: cannot find module `$crate` in module `a` --> $DIR/dollar-crate-is-keyword-2.rs:7:21 | LL | type A = a::$crate; diff --git a/tests/ui/error-codes/E0432.stderr b/tests/ui/error-codes/E0432.stderr index 473e82f863437..17b07eac8d0af 100644 --- a/tests/ui/error-codes/E0432.stderr +++ b/tests/ui/error-codes/E0432.stderr @@ -2,7 +2,7 @@ error[E0432]: unresolved import `something` --> $DIR/E0432.rs:1:5 | LL | use something::Foo; - | ^^^^^^^^^ maybe a missing crate `something`? + | ^^^^^^^^^ you might be missing a crate named `something` | = help: consider adding `extern crate something` to use the `something` crate diff --git a/tests/ui/error-codes/E0433.stderr b/tests/ui/error-codes/E0433.stderr index 1ac8c3ebc4d40..04f7b41320cd9 100644 --- a/tests/ui/error-codes/E0433.stderr +++ b/tests/ui/error-codes/E0433.stderr @@ -1,4 +1,4 @@ -error[E0433]: failed to resolve: use of undeclared type `NonExistingMap` +error[E0433]: cannot find item `NonExistingMap` in this scope --> $DIR/E0433.rs:2:15 | LL | let map = NonExistingMap::new(); diff --git a/tests/ui/extern-flag/multiple-opts.rs b/tests/ui/extern-flag/multiple-opts.rs index 091064a070c37..2f49c88a68f59 100644 --- a/tests/ui/extern-flag/multiple-opts.rs +++ b/tests/ui/extern-flag/multiple-opts.rs @@ -16,5 +16,5 @@ pub mod m { } fn main() { - somedep::somefun(); //~ ERROR failed to resolve + somedep::somefun(); //~ ERROR cannot find item `somedep` } diff --git a/tests/ui/extern-flag/multiple-opts.stderr b/tests/ui/extern-flag/multiple-opts.stderr index 0aaca5ee253e4..9b402eea7b844 100644 --- a/tests/ui/extern-flag/multiple-opts.stderr +++ b/tests/ui/extern-flag/multiple-opts.stderr @@ -1,4 +1,4 @@ -error[E0433]: failed to resolve: use of undeclared crate or module `somedep` +error[E0433]: cannot find item `somedep` in this scope --> $DIR/multiple-opts.rs:19:5 | LL | somedep::somefun(); diff --git a/tests/ui/extern-flag/noprelude.rs b/tests/ui/extern-flag/noprelude.rs index 4af617a1d628b..de492408d7c9e 100644 --- a/tests/ui/extern-flag/noprelude.rs +++ b/tests/ui/extern-flag/noprelude.rs @@ -3,5 +3,5 @@ //@ edition:2018 fn main() { - somedep::somefun(); //~ ERROR failed to resolve + somedep::somefun(); //~ ERROR cannot find item `somedep` } diff --git a/tests/ui/extern-flag/noprelude.stderr b/tests/ui/extern-flag/noprelude.stderr index 23b9b2fd94b27..0445cda144098 100644 --- a/tests/ui/extern-flag/noprelude.stderr +++ b/tests/ui/extern-flag/noprelude.stderr @@ -1,4 +1,4 @@ -error[E0433]: failed to resolve: use of undeclared crate or module `somedep` +error[E0433]: cannot find item `somedep` in this scope --> $DIR/noprelude.rs:6:5 | LL | somedep::somefun(); diff --git a/tests/ui/extern/extern-macro.rs b/tests/ui/extern/extern-macro.rs index ab974e628ff19..9b9ccfa066ef6 100644 --- a/tests/ui/extern/extern-macro.rs +++ b/tests/ui/extern/extern-macro.rs @@ -2,5 +2,5 @@ fn main() { enum Foo {} - let _ = Foo::bar!(); //~ ERROR failed to resolve: partially resolved path in a macro + let _ = Foo::bar!(); //~ ERROR cannot find item `bar` } diff --git a/tests/ui/extern/extern-macro.stderr b/tests/ui/extern/extern-macro.stderr index e4d767f0e8644..01060f4e51fa7 100644 --- a/tests/ui/extern/extern-macro.stderr +++ b/tests/ui/extern/extern-macro.stderr @@ -1,4 +1,4 @@ -error[E0433]: failed to resolve: partially resolved path in a macro +error[E0433]: cannot find item `bar` in this scope --> $DIR/extern-macro.rs:5:13 | LL | let _ = Foo::bar!(); diff --git a/tests/ui/feature-gates/feature-gate-extern_absolute_paths.rs b/tests/ui/feature-gates/feature-gate-extern_absolute_paths.rs index cff273ce2c55a..07e9235039be5 100644 --- a/tests/ui/feature-gates/feature-gate-extern_absolute_paths.rs +++ b/tests/ui/feature-gates/feature-gate-extern_absolute_paths.rs @@ -1,5 +1,5 @@ use core::default; //~ ERROR unresolved import `core` fn main() { - let _: u8 = ::core::default::Default(); //~ ERROR failed to resolve + let _: u8 = ::core::default::Default(); //~ ERROR cannot find item `core` } diff --git a/tests/ui/feature-gates/feature-gate-extern_absolute_paths.stderr b/tests/ui/feature-gates/feature-gate-extern_absolute_paths.stderr index 2fcad98be9f73..d4a53f75c0868 100644 --- a/tests/ui/feature-gates/feature-gate-extern_absolute_paths.stderr +++ b/tests/ui/feature-gates/feature-gate-extern_absolute_paths.stderr @@ -4,14 +4,14 @@ error[E0432]: unresolved import `core` LL | use core::default; | ^^^^ | | - | maybe a missing crate `core`? + | you might be missing a crate named `core` | help: try using `std` instead of `core`: `std` -error[E0433]: failed to resolve: maybe a missing crate `core`? +error[E0433]: cannot find item `core` in the crate root --> $DIR/feature-gate-extern_absolute_paths.rs:4:19 | LL | let _: u8 = ::core::default::Default(); - | ^^^^ maybe a missing crate `core`? + | ^^^^ you might be missing a crate named `core` | help: try using `std` instead of `core` | diff --git a/tests/ui/foreign/stashed-issue-121451.rs b/tests/ui/foreign/stashed-issue-121451.rs index 97a4af374758d..5735af9030105 100644 --- a/tests/ui/foreign/stashed-issue-121451.rs +++ b/tests/ui/foreign/stashed-issue-121451.rs @@ -1,4 +1,4 @@ extern "C" fn _f() -> libc::uintptr_t {} -//~^ ERROR failed to resolve: use of undeclared crate or module `libc` +//~^ ERROR cannot find item `libc` fn main() {} diff --git a/tests/ui/foreign/stashed-issue-121451.stderr b/tests/ui/foreign/stashed-issue-121451.stderr index 440d98d6f460d..c40665a97f2cd 100644 --- a/tests/ui/foreign/stashed-issue-121451.stderr +++ b/tests/ui/foreign/stashed-issue-121451.stderr @@ -1,4 +1,4 @@ -error[E0433]: failed to resolve: use of undeclared crate or module `libc` +error[E0433]: cannot find item `libc` in this scope --> $DIR/stashed-issue-121451.rs:1:23 | LL | extern "C" fn _f() -> libc::uintptr_t {} diff --git a/tests/ui/generic-associated-types/equality-bound.rs b/tests/ui/generic-associated-types/equality-bound.rs index facf838b99b3a..5ae4e435f8929 100644 --- a/tests/ui/generic-associated-types/equality-bound.rs +++ b/tests/ui/generic-associated-types/equality-bound.rs @@ -8,7 +8,7 @@ fn sum2(i: I) -> i32 where I::Item = i32 { } fn sum3(i: J) -> i32 where I::Item = i32 { //~^ ERROR equality constraints are not yet supported in `where` clauses -//~| ERROR failed to resolve: use of undeclared type `I` +//~| ERROR cannot find item `I` panic!() } diff --git a/tests/ui/generic-associated-types/equality-bound.stderr b/tests/ui/generic-associated-types/equality-bound.stderr index a054c06caebde..194786cb482d0 100644 --- a/tests/ui/generic-associated-types/equality-bound.stderr +++ b/tests/ui/generic-associated-types/equality-bound.stderr @@ -164,7 +164,7 @@ LL | struct K {} LL | fn from_iter(_: T) -> Self where T::Item = A, T: IntoIterator, | ^ help: a struct with a similar name exists: `K` -error[E0433]: failed to resolve: use of undeclared type `I` +error[E0433]: cannot find item `I` in this scope --> $DIR/equality-bound.rs:9:41 | LL | fn sum3(i: J) -> i32 where I::Item = i32 { diff --git a/tests/ui/hygiene/extern-prelude-from-opaque-fail-2018.rs b/tests/ui/hygiene/extern-prelude-from-opaque-fail-2018.rs index aaf831d1983e4..d66565074b1c6 100644 --- a/tests/ui/hygiene/extern-prelude-from-opaque-fail-2018.rs +++ b/tests/ui/hygiene/extern-prelude-from-opaque-fail-2018.rs @@ -10,7 +10,7 @@ macro a() { mod u { // Late resolution. fn f() { my_core::mem::drop(0); } - //~^ ERROR failed to resolve: use of undeclared crate or module `my_core` + //~^ ERROR cannot find item `my_core` } } @@ -23,7 +23,7 @@ mod v { mod u { // Late resolution. fn f() { my_core::mem::drop(0); } - //~^ ERROR failed to resolve: use of undeclared crate or module `my_core` + //~^ ERROR cannot find item `my_core` } fn main() {} diff --git a/tests/ui/hygiene/extern-prelude-from-opaque-fail-2018.stderr b/tests/ui/hygiene/extern-prelude-from-opaque-fail-2018.stderr index cc229764ad3fb..3514eaad27613 100644 --- a/tests/ui/hygiene/extern-prelude-from-opaque-fail-2018.stderr +++ b/tests/ui/hygiene/extern-prelude-from-opaque-fail-2018.stderr @@ -15,7 +15,7 @@ LL | a!(); | = note: this error originates in the macro `a` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0433]: failed to resolve: use of undeclared crate or module `my_core` +error[E0433]: cannot find item `my_core` in this scope --> $DIR/extern-prelude-from-opaque-fail-2018.rs:12:18 | LL | fn f() { my_core::mem::drop(0); } @@ -28,7 +28,7 @@ LL | a!(); std::mem = note: this error originates in the macro `a` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0433]: failed to resolve: use of undeclared crate or module `my_core` +error[E0433]: cannot find item `my_core` in this scope --> $DIR/extern-prelude-from-opaque-fail-2018.rs:25:14 | LL | fn f() { my_core::mem::drop(0); } diff --git a/tests/ui/hygiene/extern-prelude-from-opaque-fail.rs b/tests/ui/hygiene/extern-prelude-from-opaque-fail.rs index be3102aeab07f..d42d5ca5485f3 100644 --- a/tests/ui/hygiene/extern-prelude-from-opaque-fail.rs +++ b/tests/ui/hygiene/extern-prelude-from-opaque-fail.rs @@ -10,7 +10,7 @@ macro a() { mod u { // Late resolution. fn f() { my_core::mem::drop(0); } - //~^ ERROR failed to resolve: use of undeclared crate or module `my_core` + //~^ ERROR cannot find item `my_core` } } @@ -23,7 +23,7 @@ mod v { mod u { // Late resolution. fn f() { my_core::mem::drop(0); } - //~^ ERROR failed to resolve: use of undeclared crate or module `my_core` + //~^ ERROR cannot find item `my_core` } fn main() {} diff --git a/tests/ui/hygiene/extern-prelude-from-opaque-fail.stderr b/tests/ui/hygiene/extern-prelude-from-opaque-fail.stderr index 13b2827ef39b8..7b0ac9f31cfd5 100644 --- a/tests/ui/hygiene/extern-prelude-from-opaque-fail.stderr +++ b/tests/ui/hygiene/extern-prelude-from-opaque-fail.stderr @@ -15,7 +15,7 @@ LL | a!(); | = note: this error originates in the macro `a` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0433]: failed to resolve: use of undeclared crate or module `my_core` +error[E0433]: cannot find item `my_core` in this scope --> $DIR/extern-prelude-from-opaque-fail.rs:12:18 | LL | fn f() { my_core::mem::drop(0); } @@ -28,7 +28,7 @@ LL | a!(); my_core::mem = note: this error originates in the macro `a` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0433]: failed to resolve: use of undeclared crate or module `my_core` +error[E0433]: cannot find item `my_core` in this scope --> $DIR/extern-prelude-from-opaque-fail.rs:25:14 | LL | fn f() { my_core::mem::drop(0); } diff --git a/tests/ui/hygiene/no_implicit_prelude.rs b/tests/ui/hygiene/no_implicit_prelude.rs index e23826e9d4ef6..b1cdf081539a8 100644 --- a/tests/ui/hygiene/no_implicit_prelude.rs +++ b/tests/ui/hygiene/no_implicit_prelude.rs @@ -8,7 +8,7 @@ mod foo { #[no_implicit_prelude] mod bar { pub macro m() { - Vec::new(); //~ ERROR failed to resolve + Vec::new(); //~ ERROR cannot find item `Vec` ().clone() //~ ERROR no method named `clone` found } fn f() { diff --git a/tests/ui/hygiene/no_implicit_prelude.stderr b/tests/ui/hygiene/no_implicit_prelude.stderr index 5de6e3db327b1..461b2b7bc6f85 100644 --- a/tests/ui/hygiene/no_implicit_prelude.stderr +++ b/tests/ui/hygiene/no_implicit_prelude.stderr @@ -1,4 +1,4 @@ -error[E0433]: failed to resolve: use of undeclared type `Vec` +error[E0433]: cannot find item `Vec` in this scope --> $DIR/no_implicit_prelude.rs:11:9 | LL | fn f() { ::bar::m!(); } diff --git a/tests/ui/impl-trait/issue-72911.rs b/tests/ui/impl-trait/issue-72911.rs index 63f4898f4306b..e1e22e2d9f4f5 100644 --- a/tests/ui/impl-trait/issue-72911.rs +++ b/tests/ui/impl-trait/issue-72911.rs @@ -9,12 +9,12 @@ pub fn gather_all() -> impl Iterator { } fn gather_from_file(dir_entry: &foo::MissingItem) -> impl Iterator { - //~^ ERROR: failed to resolve + //~^ ERROR: cannot find item `foo` unimplemented!() } fn lint_files() -> impl Iterator { - //~^ ERROR: failed to resolve + //~^ ERROR: cannot find item `foo` unimplemented!() } diff --git a/tests/ui/impl-trait/issue-72911.stderr b/tests/ui/impl-trait/issue-72911.stderr index 0e86561aa2779..2b879c26ce731 100644 --- a/tests/ui/impl-trait/issue-72911.stderr +++ b/tests/ui/impl-trait/issue-72911.stderr @@ -1,10 +1,10 @@ -error[E0433]: failed to resolve: use of undeclared crate or module `foo` +error[E0433]: cannot find item `foo` in this scope --> $DIR/issue-72911.rs:11:33 | LL | fn gather_from_file(dir_entry: &foo::MissingItem) -> impl Iterator { | ^^^ use of undeclared crate or module `foo` -error[E0433]: failed to resolve: use of undeclared crate or module `foo` +error[E0433]: cannot find item `foo` in this scope --> $DIR/issue-72911.rs:16:41 | LL | fn lint_files() -> impl Iterator { diff --git a/tests/ui/impl-trait/stashed-diag-issue-121504.rs b/tests/ui/impl-trait/stashed-diag-issue-121504.rs index 4ac8ffe8931c6..ec95ce89fad8f 100644 --- a/tests/ui/impl-trait/stashed-diag-issue-121504.rs +++ b/tests/ui/impl-trait/stashed-diag-issue-121504.rs @@ -4,7 +4,7 @@ trait MyTrait { async fn foo(self) -> (Self, i32); } -impl MyTrait for xyz::T { //~ ERROR failed to resolve: use of undeclared crate or module `xyz` +impl MyTrait for xyz::T { //~ ERROR cannot find item `xyz` async fn foo(self, key: i32) -> (u32, i32) { (self, key) } diff --git a/tests/ui/impl-trait/stashed-diag-issue-121504.stderr b/tests/ui/impl-trait/stashed-diag-issue-121504.stderr index 6a881dc7f9fbd..aa013b0d75371 100644 --- a/tests/ui/impl-trait/stashed-diag-issue-121504.stderr +++ b/tests/ui/impl-trait/stashed-diag-issue-121504.stderr @@ -1,4 +1,4 @@ -error[E0433]: failed to resolve: use of undeclared crate or module `xyz` +error[E0433]: cannot find item `xyz` in this scope --> $DIR/stashed-diag-issue-121504.rs:7:18 | LL | impl MyTrait for xyz::T { diff --git a/tests/ui/imports/absolute-paths-in-nested-use-groups.rs b/tests/ui/imports/absolute-paths-in-nested-use-groups.rs index 96b5131674c75..1c1f8fb359946 100644 --- a/tests/ui/imports/absolute-paths-in-nested-use-groups.rs +++ b/tests/ui/imports/absolute-paths-in-nested-use-groups.rs @@ -3,9 +3,12 @@ mod foo {} use foo::{ - ::bar, //~ ERROR crate root in paths can only be used in start position - super::bar, //~ ERROR `super` in paths can only be used in start position - self::bar, //~ ERROR `self` in paths can only be used in start position + ::bar, //~ ERROR cannot find module `{{root}}` + //~^ NOTE crate root in paths can only be used in start position + super::bar, //~ ERROR cannot find module `super` + //~^ NOTE `super` in paths can only be used in start position + self::bar, //~ ERROR cannot find module `self` + //~^ NOTE `self` in paths can only be used in start position }; fn main() {} diff --git a/tests/ui/imports/absolute-paths-in-nested-use-groups.stderr b/tests/ui/imports/absolute-paths-in-nested-use-groups.stderr index e41590ac45eed..7245f414c7ef2 100644 --- a/tests/ui/imports/absolute-paths-in-nested-use-groups.stderr +++ b/tests/ui/imports/absolute-paths-in-nested-use-groups.stderr @@ -1,17 +1,17 @@ -error[E0433]: failed to resolve: crate root in paths can only be used in start position +error[E0433]: cannot find module `{{root}}` in module `foo` --> $DIR/absolute-paths-in-nested-use-groups.rs:6:5 | LL | ::bar, | ^ crate root in paths can only be used in start position -error[E0433]: failed to resolve: `super` in paths can only be used in start position - --> $DIR/absolute-paths-in-nested-use-groups.rs:7:5 +error[E0433]: cannot find module `super` in module `foo` + --> $DIR/absolute-paths-in-nested-use-groups.rs:8:5 | LL | super::bar, | ^^^^^ `super` in paths can only be used in start position -error[E0433]: failed to resolve: `self` in paths can only be used in start position - --> $DIR/absolute-paths-in-nested-use-groups.rs:8:5 +error[E0433]: cannot find module `self` in module `foo` + --> $DIR/absolute-paths-in-nested-use-groups.rs:10:5 | LL | self::bar, | ^^^^ `self` in paths can only be used in start position diff --git a/tests/ui/imports/extern-prelude-extern-crate-fail.rs b/tests/ui/imports/extern-prelude-extern-crate-fail.rs index 2f018851d1936..5a73685ea7514 100644 --- a/tests/ui/imports/extern-prelude-extern-crate-fail.rs +++ b/tests/ui/imports/extern-prelude-extern-crate-fail.rs @@ -7,7 +7,7 @@ mod n { mod m { fn check() { - two_macros::m!(); //~ ERROR failed to resolve: use of undeclared crate or module `two_macros` + two_macros::m!(); //~ ERROR cannot find item `two_macros` } } diff --git a/tests/ui/imports/extern-prelude-extern-crate-fail.stderr b/tests/ui/imports/extern-prelude-extern-crate-fail.stderr index f7e37449eebe5..0887f5be77975 100644 --- a/tests/ui/imports/extern-prelude-extern-crate-fail.stderr +++ b/tests/ui/imports/extern-prelude-extern-crate-fail.stderr @@ -9,7 +9,7 @@ LL | define_std_as_non_existent!(); | = note: this error originates in the macro `define_std_as_non_existent` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0433]: failed to resolve: use of undeclared crate or module `two_macros` +error[E0433]: cannot find item `two_macros` in this scope --> $DIR/extern-prelude-extern-crate-fail.rs:10:9 | LL | two_macros::m!(); diff --git a/tests/ui/imports/import-from-missing-star-2.stderr b/tests/ui/imports/import-from-missing-star-2.stderr index ea3876248c93f..06f6c854c6953 100644 --- a/tests/ui/imports/import-from-missing-star-2.stderr +++ b/tests/ui/imports/import-from-missing-star-2.stderr @@ -2,7 +2,7 @@ error[E0432]: unresolved import `spam` --> $DIR/import-from-missing-star-2.rs:2:9 | LL | use spam::*; - | ^^^^ maybe a missing crate `spam`? + | ^^^^ you might be missing a crate named `spam` | = help: consider adding `extern crate spam` to use the `spam` crate diff --git a/tests/ui/imports/import-from-missing-star-3.stderr b/tests/ui/imports/import-from-missing-star-3.stderr index 1fe5d4f19a97d..46b677c008af2 100644 --- a/tests/ui/imports/import-from-missing-star-3.stderr +++ b/tests/ui/imports/import-from-missing-star-3.stderr @@ -2,7 +2,7 @@ error[E0432]: unresolved import `spam` --> $DIR/import-from-missing-star-3.rs:2:9 | LL | use spam::*; - | ^^^^ maybe a missing crate `spam`? + | ^^^^ you might be missing a crate named `spam` | = help: consider adding `extern crate spam` to use the `spam` crate @@ -10,7 +10,7 @@ error[E0432]: unresolved import `spam` --> $DIR/import-from-missing-star-3.rs:27:13 | LL | use spam::*; - | ^^^^ maybe a missing crate `spam`? + | ^^^^ you might be missing a crate named `spam` | = help: consider adding `extern crate spam` to use the `spam` crate diff --git a/tests/ui/imports/import-from-missing-star.stderr b/tests/ui/imports/import-from-missing-star.stderr index f8e295078047f..c341ec81608b7 100644 --- a/tests/ui/imports/import-from-missing-star.stderr +++ b/tests/ui/imports/import-from-missing-star.stderr @@ -2,7 +2,7 @@ error[E0432]: unresolved import `spam` --> $DIR/import-from-missing-star.rs:1:5 | LL | use spam::*; - | ^^^^ maybe a missing crate `spam`? + | ^^^^ you might be missing a crate named `spam` | = help: consider adding `extern crate spam` to use the `spam` crate diff --git a/tests/ui/imports/import3.stderr b/tests/ui/imports/import3.stderr index 80b0a7f061994..9fdc191e3c299 100644 --- a/tests/ui/imports/import3.stderr +++ b/tests/ui/imports/import3.stderr @@ -2,7 +2,7 @@ error[E0432]: unresolved import `main` --> $DIR/import3.rs:2:5 | LL | use main::bar; - | ^^^^ maybe a missing crate `main`? + | ^^^^ you might be missing a crate named `main` | = help: consider adding `extern crate main` to use the `main` crate diff --git a/tests/ui/imports/issue-109343.stderr b/tests/ui/imports/issue-109343.stderr index 1b95fcf55679f..a61d4af7848e4 100644 --- a/tests/ui/imports/issue-109343.stderr +++ b/tests/ui/imports/issue-109343.stderr @@ -2,7 +2,7 @@ error[E0432]: unresolved import `unresolved` --> $DIR/issue-109343.rs:4:9 | LL | pub use unresolved::f; - | ^^^^^^^^^^ maybe a missing crate `unresolved`? + | ^^^^^^^^^^ you might be missing a crate named `unresolved` | = help: consider adding `extern crate unresolved` to use the `unresolved` crate diff --git a/tests/ui/imports/issue-1697.rs b/tests/ui/imports/issue-1697.rs index 5cd76d21f91cf..5f7ef582c1aba 100644 --- a/tests/ui/imports/issue-1697.rs +++ b/tests/ui/imports/issue-1697.rs @@ -1,6 +1,6 @@ // Testing that we don't fail abnormally after hitting the errors use unresolved::*; //~ ERROR unresolved import `unresolved` [E0432] - //~^ maybe a missing crate `unresolved`? + //~^ you might be missing a crate named `unresolved` fn main() {} diff --git a/tests/ui/imports/issue-1697.stderr b/tests/ui/imports/issue-1697.stderr index 840608ca2a14d..1d3d8c3a92f77 100644 --- a/tests/ui/imports/issue-1697.stderr +++ b/tests/ui/imports/issue-1697.stderr @@ -2,7 +2,7 @@ error[E0432]: unresolved import `unresolved` --> $DIR/issue-1697.rs:3:5 | LL | use unresolved::*; - | ^^^^^^^^^^ maybe a missing crate `unresolved`? + | ^^^^^^^^^^ you might be missing a crate named `unresolved` | = help: consider adding `extern crate unresolved` to use the `unresolved` crate diff --git a/tests/ui/imports/issue-33464.stderr b/tests/ui/imports/issue-33464.stderr index c4e5c55589914..a51e27916c3d7 100644 --- a/tests/ui/imports/issue-33464.stderr +++ b/tests/ui/imports/issue-33464.stderr @@ -2,7 +2,7 @@ error[E0432]: unresolved import `abc` --> $DIR/issue-33464.rs:3:5 | LL | use abc::one_el; - | ^^^ maybe a missing crate `abc`? + | ^^^ you might be missing a crate named `abc` | = help: consider adding `extern crate abc` to use the `abc` crate @@ -10,7 +10,7 @@ error[E0432]: unresolved import `abc` --> $DIR/issue-33464.rs:5:5 | LL | use abc::{a, bbb, cccccc}; - | ^^^ maybe a missing crate `abc`? + | ^^^ you might be missing a crate named `abc` | = help: consider adding `extern crate abc` to use the `abc` crate @@ -18,7 +18,7 @@ error[E0432]: unresolved import `a_very_long_name` --> $DIR/issue-33464.rs:7:5 | LL | use a_very_long_name::{el, el2}; - | ^^^^^^^^^^^^^^^^ maybe a missing crate `a_very_long_name`? + | ^^^^^^^^^^^^^^^^ you might be missing a crate named `a_very_long_name` | = help: consider adding `extern crate a_very_long_name` to use the `a_very_long_name` crate diff --git a/tests/ui/imports/issue-36881.stderr b/tests/ui/imports/issue-36881.stderr index e9b632d2718ce..fef0efe3d0f49 100644 --- a/tests/ui/imports/issue-36881.stderr +++ b/tests/ui/imports/issue-36881.stderr @@ -2,7 +2,7 @@ error[E0432]: unresolved import `issue_36881_aux` --> $DIR/issue-36881.rs:5:9 | LL | use issue_36881_aux::Foo; - | ^^^^^^^^^^^^^^^ maybe a missing crate `issue_36881_aux`? + | ^^^^^^^^^^^^^^^ you might be missing a crate named `issue_36881_aux` | = help: consider adding `extern crate issue_36881_aux` to use the `issue_36881_aux` crate diff --git a/tests/ui/imports/issue-37887.stderr b/tests/ui/imports/issue-37887.stderr index e7792ac0d159b..b06f71a916311 100644 --- a/tests/ui/imports/issue-37887.stderr +++ b/tests/ui/imports/issue-37887.stderr @@ -2,7 +2,7 @@ error[E0432]: unresolved import `test` --> $DIR/issue-37887.rs:3:9 | LL | use test::*; - | ^^^^ maybe a missing crate `test`? + | ^^^^ you might be missing a crate named `test` | = help: consider adding `extern crate test` to use the `test` crate diff --git a/tests/ui/imports/issue-53269.stderr b/tests/ui/imports/issue-53269.stderr index 29c7556dac432..67559f691b66a 100644 --- a/tests/ui/imports/issue-53269.stderr +++ b/tests/ui/imports/issue-53269.stderr @@ -2,7 +2,7 @@ error[E0432]: unresolved import `nonexistent_module` --> $DIR/issue-53269.rs:6:9 | LL | use nonexistent_module::mac; - | ^^^^^^^^^^^^^^^^^^ maybe a missing crate `nonexistent_module`? + | ^^^^^^^^^^^^^^^^^^ you might be missing a crate named `nonexistent_module` | = help: consider adding `extern crate nonexistent_module` to use the `nonexistent_module` crate diff --git a/tests/ui/imports/issue-55457.stderr b/tests/ui/imports/issue-55457.stderr index 09bb13a060478..0ca61b6160948 100644 --- a/tests/ui/imports/issue-55457.stderr +++ b/tests/ui/imports/issue-55457.stderr @@ -11,7 +11,7 @@ error[E0432]: unresolved import `non_existent` --> $DIR/issue-55457.rs:2:5 | LL | use non_existent::non_existent; - | ^^^^^^^^^^^^ maybe a missing crate `non_existent`? + | ^^^^^^^^^^^^ you might be missing a crate named `non_existent` | = help: consider adding `extern crate non_existent` to use the `non_existent` crate diff --git a/tests/ui/imports/issue-81413.stderr b/tests/ui/imports/issue-81413.stderr index c2a3212501181..b884f4807097e 100644 --- a/tests/ui/imports/issue-81413.stderr +++ b/tests/ui/imports/issue-81413.stderr @@ -2,7 +2,7 @@ error[E0432]: unresolved import `doesnt_exist` --> $DIR/issue-81413.rs:7:9 | LL | pub use doesnt_exist::*; - | ^^^^^^^^^^^^ maybe a missing crate `doesnt_exist`? + | ^^^^^^^^^^^^ you might be missing a crate named `doesnt_exist` | = help: consider adding `extern crate doesnt_exist` to use the `doesnt_exist` crate diff --git a/tests/ui/imports/suggest-import-issue-120074.rs b/tests/ui/imports/suggest-import-issue-120074.rs index a798e9eeeb809..feecc30e1db73 100644 --- a/tests/ui/imports/suggest-import-issue-120074.rs +++ b/tests/ui/imports/suggest-import-issue-120074.rs @@ -7,5 +7,5 @@ pub mod foo { } fn main() { - println!("Hello, {}!", crate::bar::do_the_thing); //~ ERROR failed to resolve: unresolved import + println!("Hello, {}!", crate::bar::do_the_thing); //~ ERROR cannot find item `bar` } diff --git a/tests/ui/imports/suggest-import-issue-120074.stderr b/tests/ui/imports/suggest-import-issue-120074.stderr index c1dff93bbdbff..3f8128e958ad7 100644 --- a/tests/ui/imports/suggest-import-issue-120074.stderr +++ b/tests/ui/imports/suggest-import-issue-120074.stderr @@ -1,4 +1,4 @@ -error[E0433]: failed to resolve: unresolved import +error[E0433]: cannot find item `bar` in the crate root --> $DIR/suggest-import-issue-120074.rs:10:35 | LL | println!("Hello, {}!", crate::bar::do_the_thing); diff --git a/tests/ui/imports/tool-mod-child.rs b/tests/ui/imports/tool-mod-child.rs index 4581dc2e2ad88..7b72a30606350 100644 --- a/tests/ui/imports/tool-mod-child.rs +++ b/tests/ui/imports/tool-mod-child.rs @@ -1,7 +1,7 @@ use clippy::a; //~ ERROR unresolved import `clippy` -use clippy::a::b; //~ ERROR failed to resolve: maybe a missing crate `clippy`? +use clippy::a::b; //~ ERROR cannot find item `clippy` use rustdoc::a; //~ ERROR unresolved import `rustdoc` -use rustdoc::a::b; //~ ERROR failed to resolve: maybe a missing crate `rustdoc`? +use rustdoc::a::b; //~ ERROR cannot find item `rustdoc` fn main() {} diff --git a/tests/ui/imports/tool-mod-child.stderr b/tests/ui/imports/tool-mod-child.stderr index 6caf15bc72401..015a08005d2d2 100644 --- a/tests/ui/imports/tool-mod-child.stderr +++ b/tests/ui/imports/tool-mod-child.stderr @@ -1,8 +1,8 @@ -error[E0433]: failed to resolve: maybe a missing crate `clippy`? +error[E0433]: cannot find item `clippy` in the crate root --> $DIR/tool-mod-child.rs:2:5 | LL | use clippy::a::b; - | ^^^^^^ maybe a missing crate `clippy`? + | ^^^^^^ you might be missing a crate named `clippy` | = help: consider adding `extern crate clippy` to use the `clippy` crate @@ -10,15 +10,15 @@ error[E0432]: unresolved import `clippy` --> $DIR/tool-mod-child.rs:1:5 | LL | use clippy::a; - | ^^^^^^ maybe a missing crate `clippy`? + | ^^^^^^ you might be missing a crate named `clippy` | = help: consider adding `extern crate clippy` to use the `clippy` crate -error[E0433]: failed to resolve: maybe a missing crate `rustdoc`? +error[E0433]: cannot find item `rustdoc` in the crate root --> $DIR/tool-mod-child.rs:5:5 | LL | use rustdoc::a::b; - | ^^^^^^^ maybe a missing crate `rustdoc`? + | ^^^^^^^ you might be missing a crate named `rustdoc` | = help: consider adding `extern crate rustdoc` to use the `rustdoc` crate @@ -26,7 +26,7 @@ error[E0432]: unresolved import `rustdoc` --> $DIR/tool-mod-child.rs:4:5 | LL | use rustdoc::a; - | ^^^^^^^ maybe a missing crate `rustdoc`? + | ^^^^^^^ you might be missing a crate named `rustdoc` | = help: consider adding `extern crate rustdoc` to use the `rustdoc` crate diff --git a/tests/ui/imports/unresolved-imports-used.stderr b/tests/ui/imports/unresolved-imports-used.stderr index 73f9d1bfb6c61..a791efd715d3e 100644 --- a/tests/ui/imports/unresolved-imports-used.stderr +++ b/tests/ui/imports/unresolved-imports-used.stderr @@ -14,7 +14,7 @@ error[E0432]: unresolved import `foo` --> $DIR/unresolved-imports-used.rs:11:5 | LL | use foo::bar; - | ^^^ maybe a missing crate `foo`? + | ^^^ you might be missing a crate named `foo` | = help: consider adding `extern crate foo` to use the `foo` crate @@ -22,7 +22,7 @@ error[E0432]: unresolved import `baz` --> $DIR/unresolved-imports-used.rs:12:5 | LL | use baz::*; - | ^^^ maybe a missing crate `baz`? + | ^^^ you might be missing a crate named `baz` | = help: consider adding `extern crate baz` to use the `baz` crate @@ -30,7 +30,7 @@ error[E0432]: unresolved import `foo2` --> $DIR/unresolved-imports-used.rs:14:5 | LL | use foo2::bar2; - | ^^^^ maybe a missing crate `foo2`? + | ^^^^ you might be missing a crate named `foo2` | = help: consider adding `extern crate foo2` to use the `foo2` crate @@ -38,7 +38,7 @@ error[E0432]: unresolved import `baz2` --> $DIR/unresolved-imports-used.rs:15:5 | LL | use baz2::*; - | ^^^^ maybe a missing crate `baz2`? + | ^^^^ you might be missing a crate named `baz2` | = help: consider adding `extern crate baz2` to use the `baz2` crate diff --git a/tests/ui/issues/issue-33293.rs b/tests/ui/issues/issue-33293.rs index a6ef007d51fb5..16bcc640a17e3 100644 --- a/tests/ui/issues/issue-33293.rs +++ b/tests/ui/issues/issue-33293.rs @@ -1,6 +1,6 @@ fn main() { match 0 { aaa::bbb(_) => () - //~^ ERROR failed to resolve: use of undeclared crate or module `aaa` + //~^ ERROR cannot find item `aaa` }; } diff --git a/tests/ui/issues/issue-33293.stderr b/tests/ui/issues/issue-33293.stderr index 5badaa153f2b1..38aa29949edb0 100644 --- a/tests/ui/issues/issue-33293.stderr +++ b/tests/ui/issues/issue-33293.stderr @@ -1,4 +1,4 @@ -error[E0433]: failed to resolve: use of undeclared crate or module `aaa` +error[E0433]: cannot find item `aaa` in this scope --> $DIR/issue-33293.rs:3:9 | LL | aaa::bbb(_) => () diff --git a/tests/ui/issues/issue-38857.rs b/tests/ui/issues/issue-38857.rs index 81d881c100bb6..b2cc88515658c 100644 --- a/tests/ui/issues/issue-38857.rs +++ b/tests/ui/issues/issue-38857.rs @@ -1,5 +1,5 @@ fn main() { let a = std::sys::imp::process::process_common::StdioPipes { ..panic!() }; - //~^ ERROR failed to resolve: could not find `imp` in `sys` [E0433] + //~^ ERROR cannot find item `imp` //~^^ ERROR module `sys` is private [E0603] } diff --git a/tests/ui/issues/issue-38857.stderr b/tests/ui/issues/issue-38857.stderr index 4d505784b8654..d7b2d0af95fb6 100644 --- a/tests/ui/issues/issue-38857.stderr +++ b/tests/ui/issues/issue-38857.stderr @@ -1,4 +1,4 @@ -error[E0433]: failed to resolve: could not find `imp` in `sys` +error[E0433]: cannot find item `imp` in module `sys` --> $DIR/issue-38857.rs:2:23 | LL | let a = std::sys::imp::process::process_common::StdioPipes { ..panic!() }; diff --git a/tests/ui/issues/issue-46101.rs b/tests/ui/issues/issue-46101.rs index ab3d30d401f06..9c93683a82016 100644 --- a/tests/ui/issues/issue-46101.rs +++ b/tests/ui/issues/issue-46101.rs @@ -1,6 +1,6 @@ trait Foo {} -#[derive(Foo::Anything)] //~ ERROR failed to resolve: partially resolved path in a derive macro - //~| ERROR failed to resolve: partially resolved path in a derive macro +#[derive(Foo::Anything)] //~ ERROR cannot find item `Anything` + //~| ERROR cannot find item `Anything` struct S; fn main() {} diff --git a/tests/ui/issues/issue-46101.stderr b/tests/ui/issues/issue-46101.stderr index a0cdd5d5f0532..952c265ea50f0 100644 --- a/tests/ui/issues/issue-46101.stderr +++ b/tests/ui/issues/issue-46101.stderr @@ -1,10 +1,10 @@ -error[E0433]: failed to resolve: partially resolved path in a derive macro +error[E0433]: cannot find item `Anything` in this scope --> $DIR/issue-46101.rs:2:10 | LL | #[derive(Foo::Anything)] | ^^^^^^^^^^^^^ partially resolved path in a derive macro -error[E0433]: failed to resolve: partially resolved path in a derive macro +error[E0433]: cannot find item `Anything` in this scope --> $DIR/issue-46101.rs:2:10 | LL | #[derive(Foo::Anything)] diff --git a/tests/ui/issues/issue-71406.rs b/tests/ui/issues/issue-71406.rs index 6266112c3a86c..d5a0165a69569 100644 --- a/tests/ui/issues/issue-71406.rs +++ b/tests/ui/issues/issue-71406.rs @@ -2,5 +2,6 @@ use std::sync::mpsc; fn main() { let (tx, rx) = mpsc::channel::new(1); - //~^ ERROR expected type, found function `channel` in `mpsc` + //~^ ERROR cannot find item `channel` + //~| NOTE expected type, found function `channel` in `mpsc` } diff --git a/tests/ui/issues/issue-71406.stderr b/tests/ui/issues/issue-71406.stderr index cd7921f550e5d..dd61b7882aac5 100644 --- a/tests/ui/issues/issue-71406.stderr +++ b/tests/ui/issues/issue-71406.stderr @@ -1,4 +1,4 @@ -error[E0433]: failed to resolve: expected type, found function `channel` in `mpsc` +error[E0433]: cannot find item `channel` in module `mpsc` --> $DIR/issue-71406.rs:4:26 | LL | let (tx, rx) = mpsc::channel::new(1); diff --git a/tests/ui/keyword/extern/keyword-extern-as-identifier-use.stderr b/tests/ui/keyword/extern/keyword-extern-as-identifier-use.stderr index 54ee45c28679a..8693616535e06 100644 --- a/tests/ui/keyword/extern/keyword-extern-as-identifier-use.stderr +++ b/tests/ui/keyword/extern/keyword-extern-as-identifier-use.stderr @@ -13,9 +13,7 @@ error[E0432]: unresolved import `r#extern` --> $DIR/keyword-extern-as-identifier-use.rs:1:5 | LL | use extern::foo; - | ^^^^^^ maybe a missing crate `r#extern`? - | - = help: consider adding `extern crate r#extern` to use the `r#extern` crate + | ^^^^^^ unresolved import error: aborting due to 2 previous errors diff --git a/tests/ui/keyword/keyword-super-as-identifier.rs b/tests/ui/keyword/keyword-super-as-identifier.rs index 02c1b27b08a96..a28d99deedc0b 100644 --- a/tests/ui/keyword/keyword-super-as-identifier.rs +++ b/tests/ui/keyword/keyword-super-as-identifier.rs @@ -1,3 +1,3 @@ fn main() { - let super = 22; //~ ERROR failed to resolve: there are too many leading `super` keywords + let super = 22; //~ ERROR cannot find item `super` } diff --git a/tests/ui/keyword/keyword-super-as-identifier.stderr b/tests/ui/keyword/keyword-super-as-identifier.stderr index bfb27c143ff79..1e80dd5012423 100644 --- a/tests/ui/keyword/keyword-super-as-identifier.stderr +++ b/tests/ui/keyword/keyword-super-as-identifier.stderr @@ -1,8 +1,13 @@ -error[E0433]: failed to resolve: there are too many leading `super` keywords +error[E0433]: cannot find item `super` in this scope --> $DIR/keyword-super-as-identifier.rs:2:9 | LL | let super = 22; - | ^^^^^ there are too many leading `super` keywords + | ^^^^^ can't use `super` as an identifier + | +help: if you still want to call your identifier `super`, use the raw identifier format + | +LL | let r#super = 22; + | ++ error: aborting due to 1 previous error diff --git a/tests/ui/keyword/keyword-super.rs b/tests/ui/keyword/keyword-super.rs index c121a6c1050ea..4ddff441cfbb7 100644 --- a/tests/ui/keyword/keyword-super.rs +++ b/tests/ui/keyword/keyword-super.rs @@ -1,3 +1,3 @@ fn main() { - let super: isize; //~ ERROR failed to resolve: there are too many leading `super` keywords + let super: isize; //~ ERROR cannot find item `super` } diff --git a/tests/ui/keyword/keyword-super.stderr b/tests/ui/keyword/keyword-super.stderr index bf595442c3b8b..766a47a184b9c 100644 --- a/tests/ui/keyword/keyword-super.stderr +++ b/tests/ui/keyword/keyword-super.stderr @@ -1,8 +1,13 @@ -error[E0433]: failed to resolve: there are too many leading `super` keywords +error[E0433]: cannot find item `super` in this scope --> $DIR/keyword-super.rs:2:9 | LL | let super: isize; - | ^^^^^ there are too many leading `super` keywords + | ^^^^^ can't use `super` as an identifier + | +help: if you still want to call your identifier `super`, use the raw identifier format + | +LL | let r#super: isize; + | ++ error: aborting due to 1 previous error diff --git a/tests/ui/lifetimes/issue-97194.rs b/tests/ui/lifetimes/issue-97194.rs index 5f3560dbe946e..23518a2519626 100644 --- a/tests/ui/lifetimes/issue-97194.rs +++ b/tests/ui/lifetimes/issue-97194.rs @@ -2,7 +2,7 @@ extern "C" { fn bget(&self, index: [usize; Self::DIM]) -> bool { //~^ ERROR incorrect function inside `extern` block //~| ERROR `self` parameter is only allowed in associated functions - //~| ERROR failed to resolve: `Self` + //~| ERROR cannot find item `Self` type T<'a> = &'a str; } } diff --git a/tests/ui/lifetimes/issue-97194.stderr b/tests/ui/lifetimes/issue-97194.stderr index 93bde285a9901..29ee76b92c9a4 100644 --- a/tests/ui/lifetimes/issue-97194.stderr +++ b/tests/ui/lifetimes/issue-97194.stderr @@ -25,7 +25,7 @@ LL | fn bget(&self, index: [usize; Self::DIM]) -> bool { | = note: associated functions are those in `impl` or `trait` definitions -error[E0433]: failed to resolve: `Self` is only available in impls, traits, and type definitions +error[E0433]: cannot find item `Self` in this scope --> $DIR/issue-97194.rs:2:35 | LL | fn bget(&self, index: [usize; Self::DIM]) -> bool { diff --git a/tests/ui/lint/ice-array-into-iter-lint-issue-121532.rs b/tests/ui/lint/ice-array-into-iter-lint-issue-121532.rs index 92cab01fe48c8..7fae9223868a3 100644 --- a/tests/ui/lint/ice-array-into-iter-lint-issue-121532.rs +++ b/tests/ui/lint/ice-array-into-iter-lint-issue-121532.rs @@ -4,7 +4,7 @@ // Typeck fails for the arg type as // `Self` makes no sense here -fn func(a: Self::ItemsIterator) { //~ ERROR failed to resolve: `Self` is only available in impls, traits, and type definitions +fn func(a: Self::ItemsIterator) { //~ ERROR cannot find item `Self` a.into_iter(); } diff --git a/tests/ui/lint/ice-array-into-iter-lint-issue-121532.stderr b/tests/ui/lint/ice-array-into-iter-lint-issue-121532.stderr index 73ceddae940b2..bfa5e36aad3d2 100644 --- a/tests/ui/lint/ice-array-into-iter-lint-issue-121532.stderr +++ b/tests/ui/lint/ice-array-into-iter-lint-issue-121532.stderr @@ -1,4 +1,4 @@ -error[E0433]: failed to resolve: `Self` is only available in impls, traits, and type definitions +error[E0433]: cannot find item `Self` in this scope --> $DIR/ice-array-into-iter-lint-issue-121532.rs:7:12 | LL | fn func(a: Self::ItemsIterator) { diff --git a/tests/ui/macros/builtin-prelude-no-accidents.rs b/tests/ui/macros/builtin-prelude-no-accidents.rs index 01691a82dd772..c806b68400943 100644 --- a/tests/ui/macros/builtin-prelude-no-accidents.rs +++ b/tests/ui/macros/builtin-prelude-no-accidents.rs @@ -2,7 +2,7 @@ // because macros with the same names are in prelude. fn main() { - env::current_dir; //~ ERROR use of undeclared crate or module `env` - type A = panic::PanicInfo; //~ ERROR use of undeclared crate or module `panic` - type B = vec::Vec; //~ ERROR use of undeclared crate or module `vec` + env::current_dir; //~ ERROR cannot find item `env` + type A = panic::PanicInfo; //~ ERROR cannot find item `panic` + type B = vec::Vec; //~ ERROR cannot find item `vec` } diff --git a/tests/ui/macros/builtin-prelude-no-accidents.stderr b/tests/ui/macros/builtin-prelude-no-accidents.stderr index c1054230bc9a5..6e576ecefdca3 100644 --- a/tests/ui/macros/builtin-prelude-no-accidents.stderr +++ b/tests/ui/macros/builtin-prelude-no-accidents.stderr @@ -1,4 +1,4 @@ -error[E0433]: failed to resolve: use of undeclared crate or module `env` +error[E0433]: cannot find item `env` in this scope --> $DIR/builtin-prelude-no-accidents.rs:5:5 | LL | env::current_dir; @@ -9,7 +9,7 @@ help: consider importing this module LL + use std::env; | -error[E0433]: failed to resolve: use of undeclared crate or module `panic` +error[E0433]: cannot find item `panic` in this scope --> $DIR/builtin-prelude-no-accidents.rs:6:14 | LL | type A = panic::PanicInfo; @@ -20,7 +20,7 @@ help: consider importing this module LL + use std::panic; | -error[E0433]: failed to resolve: use of undeclared crate or module `vec` +error[E0433]: cannot find item `vec` in this scope --> $DIR/builtin-prelude-no-accidents.rs:7:14 | LL | type B = vec::Vec; diff --git a/tests/ui/macros/builtin-std-paths-fail.rs b/tests/ui/macros/builtin-std-paths-fail.rs index c1a4e32a6dcbc..087d5a1bf075a 100644 --- a/tests/ui/macros/builtin-std-paths-fail.rs +++ b/tests/ui/macros/builtin-std-paths-fail.rs @@ -1,25 +1,25 @@ #[derive( - core::RustcDecodable, //~ ERROR could not find `RustcDecodable` in `core` - //~| ERROR could not find `RustcDecodable` in `core` - core::RustcDecodable, //~ ERROR could not find `RustcDecodable` in `core` - //~| ERROR could not find `RustcDecodable` in `core` + core::RustcDecodable, //~ ERROR cannot find macro `RustcDecodable` + //~| ERROR cannot find macro `RustcDecodable` + core::RustcDecodable, //~ ERROR cannot find macro `RustcDecodable` + //~| ERROR cannot find macro `RustcDecodable` )] -#[core::bench] //~ ERROR could not find `bench` in `core` -#[core::global_allocator] //~ ERROR could not find `global_allocator` in `core` -#[core::test_case] //~ ERROR could not find `test_case` in `core` -#[core::test] //~ ERROR could not find `test` in `core` +#[core::bench] //~ ERROR cannot find macro `bench` +#[core::global_allocator] //~ ERROR cannot find macro `global_allocator` +#[core::test_case] //~ ERROR cannot find macro `test_case` +#[core::test] //~ ERROR cannot find macro `test` struct Core; #[derive( - std::RustcDecodable, //~ ERROR could not find `RustcDecodable` in `std` - //~| ERROR could not find `RustcDecodable` in `std` - std::RustcDecodable, //~ ERROR could not find `RustcDecodable` in `std` - //~| ERROR could not find `RustcDecodable` in `std` + std::RustcDecodable, //~ ERROR cannot find macro `RustcDecodable` + //~| ERROR cannot find macro `RustcDecodable` + std::RustcDecodable, //~ ERROR cannot find macro `RustcDecodable` + //~| ERROR cannot find macro `RustcDecodable` )] -#[std::bench] //~ ERROR could not find `bench` in `std` -#[std::global_allocator] //~ ERROR could not find `global_allocator` in `std` -#[std::test_case] //~ ERROR could not find `test_case` in `std` -#[std::test] //~ ERROR could not find `test` in `std` +#[std::bench] //~ ERROR cannot find macro `bench` +#[std::global_allocator] //~ ERROR cannot find macro `global_allocator` +#[std::test_case] //~ ERROR cannot find macro `test_case` +#[std::test] //~ ERROR cannot find macro `test` struct Std; fn main() {} diff --git a/tests/ui/macros/builtin-std-paths-fail.stderr b/tests/ui/macros/builtin-std-paths-fail.stderr index 331943843c02a..8bc929debcdc3 100644 --- a/tests/ui/macros/builtin-std-paths-fail.stderr +++ b/tests/ui/macros/builtin-std-paths-fail.stderr @@ -1,16 +1,16 @@ -error[E0433]: failed to resolve: could not find `RustcDecodable` in `core` +error[E0433]: cannot find macro `RustcDecodable` in crate `core` --> $DIR/builtin-std-paths-fail.rs:2:11 | LL | core::RustcDecodable, | ^^^^^^^^^^^^^^ could not find `RustcDecodable` in `core` -error[E0433]: failed to resolve: could not find `RustcDecodable` in `core` +error[E0433]: cannot find macro `RustcDecodable` in crate `core` --> $DIR/builtin-std-paths-fail.rs:4:11 | LL | core::RustcDecodable, | ^^^^^^^^^^^^^^ could not find `RustcDecodable` in `core` -error[E0433]: failed to resolve: could not find `RustcDecodable` in `core` +error[E0433]: cannot find macro `RustcDecodable` in crate `core` --> $DIR/builtin-std-paths-fail.rs:2:11 | LL | core::RustcDecodable, @@ -18,7 +18,7 @@ LL | core::RustcDecodable, | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error[E0433]: failed to resolve: could not find `RustcDecodable` in `core` +error[E0433]: cannot find macro `RustcDecodable` in crate `core` --> $DIR/builtin-std-paths-fail.rs:4:11 | LL | core::RustcDecodable, @@ -26,43 +26,43 @@ LL | core::RustcDecodable, | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error[E0433]: failed to resolve: could not find `bench` in `core` +error[E0433]: cannot find macro `bench` in crate `core` --> $DIR/builtin-std-paths-fail.rs:7:9 | LL | #[core::bench] | ^^^^^ could not find `bench` in `core` -error[E0433]: failed to resolve: could not find `global_allocator` in `core` +error[E0433]: cannot find macro `global_allocator` in crate `core` --> $DIR/builtin-std-paths-fail.rs:8:9 | LL | #[core::global_allocator] | ^^^^^^^^^^^^^^^^ could not find `global_allocator` in `core` -error[E0433]: failed to resolve: could not find `test_case` in `core` +error[E0433]: cannot find macro `test_case` in crate `core` --> $DIR/builtin-std-paths-fail.rs:9:9 | LL | #[core::test_case] | ^^^^^^^^^ could not find `test_case` in `core` -error[E0433]: failed to resolve: could not find `test` in `core` +error[E0433]: cannot find macro `test` in crate `core` --> $DIR/builtin-std-paths-fail.rs:10:9 | LL | #[core::test] | ^^^^ could not find `test` in `core` -error[E0433]: failed to resolve: could not find `RustcDecodable` in `std` +error[E0433]: cannot find macro `RustcDecodable` in crate `std` --> $DIR/builtin-std-paths-fail.rs:14:10 | LL | std::RustcDecodable, | ^^^^^^^^^^^^^^ could not find `RustcDecodable` in `std` -error[E0433]: failed to resolve: could not find `RustcDecodable` in `std` +error[E0433]: cannot find macro `RustcDecodable` in crate `std` --> $DIR/builtin-std-paths-fail.rs:16:10 | LL | std::RustcDecodable, | ^^^^^^^^^^^^^^ could not find `RustcDecodable` in `std` -error[E0433]: failed to resolve: could not find `RustcDecodable` in `std` +error[E0433]: cannot find macro `RustcDecodable` in crate `std` --> $DIR/builtin-std-paths-fail.rs:14:10 | LL | std::RustcDecodable, @@ -70,7 +70,7 @@ LL | std::RustcDecodable, | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error[E0433]: failed to resolve: could not find `RustcDecodable` in `std` +error[E0433]: cannot find macro `RustcDecodable` in crate `std` --> $DIR/builtin-std-paths-fail.rs:16:10 | LL | std::RustcDecodable, @@ -78,25 +78,25 @@ LL | std::RustcDecodable, | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error[E0433]: failed to resolve: could not find `bench` in `std` +error[E0433]: cannot find macro `bench` in crate `std` --> $DIR/builtin-std-paths-fail.rs:19:8 | LL | #[std::bench] | ^^^^^ could not find `bench` in `std` -error[E0433]: failed to resolve: could not find `global_allocator` in `std` +error[E0433]: cannot find macro `global_allocator` in crate `std` --> $DIR/builtin-std-paths-fail.rs:20:8 | LL | #[std::global_allocator] | ^^^^^^^^^^^^^^^^ could not find `global_allocator` in `std` -error[E0433]: failed to resolve: could not find `test_case` in `std` +error[E0433]: cannot find macro `test_case` in crate `std` --> $DIR/builtin-std-paths-fail.rs:21:8 | LL | #[std::test_case] | ^^^^^^^^^ could not find `test_case` in `std` -error[E0433]: failed to resolve: could not find `test` in `std` +error[E0433]: cannot find macro `test` in crate `std` --> $DIR/builtin-std-paths-fail.rs:22:8 | LL | #[std::test] diff --git a/tests/ui/macros/macro-inner-attributes.rs b/tests/ui/macros/macro-inner-attributes.rs index 6dbfce2135989..8cfc73f5928d5 100644 --- a/tests/ui/macros/macro-inner-attributes.rs +++ b/tests/ui/macros/macro-inner-attributes.rs @@ -15,6 +15,6 @@ test!(b, #[rustc_dummy] fn main() { a::bar(); - //~^ ERROR failed to resolve: use of undeclared crate or module `a` + //~^ ERROR cannot find item `a` b::bar(); } diff --git a/tests/ui/macros/macro-inner-attributes.stderr b/tests/ui/macros/macro-inner-attributes.stderr index b6e10f45e3810..39944b949b8a9 100644 --- a/tests/ui/macros/macro-inner-attributes.stderr +++ b/tests/ui/macros/macro-inner-attributes.stderr @@ -1,4 +1,4 @@ -error[E0433]: failed to resolve: use of undeclared crate or module `a` +error[E0433]: cannot find item `a` in this scope --> $DIR/macro-inner-attributes.rs:17:5 | LL | a::bar(); diff --git a/tests/ui/macros/macro-path-prelude-fail-1.rs b/tests/ui/macros/macro-path-prelude-fail-1.rs index d93792bdfe38d..a47f7cda0e19e 100644 --- a/tests/ui/macros/macro-path-prelude-fail-1.rs +++ b/tests/ui/macros/macro-path-prelude-fail-1.rs @@ -1,7 +1,7 @@ mod m { fn check() { - Vec::clone!(); //~ ERROR failed to resolve: `Vec` is a struct, not a module - u8::clone!(); //~ ERROR failed to resolve: `u8` is a builtin type, not a module + Vec::clone!(); //~ ERROR cannot find module `Vec` + u8::clone!(); //~ ERROR cannot find module `u8` } } diff --git a/tests/ui/macros/macro-path-prelude-fail-1.stderr b/tests/ui/macros/macro-path-prelude-fail-1.stderr index f8377ffb35556..b8ace6d631551 100644 --- a/tests/ui/macros/macro-path-prelude-fail-1.stderr +++ b/tests/ui/macros/macro-path-prelude-fail-1.stderr @@ -1,10 +1,10 @@ -error[E0433]: failed to resolve: `Vec` is a struct, not a module +error[E0433]: cannot find module `Vec` in this scope --> $DIR/macro-path-prelude-fail-1.rs:3:9 | LL | Vec::clone!(); | ^^^ `Vec` is a struct, not a module -error[E0433]: failed to resolve: `u8` is a builtin type, not a module +error[E0433]: cannot find module `u8` in this scope --> $DIR/macro-path-prelude-fail-1.rs:4:9 | LL | u8::clone!(); diff --git a/tests/ui/macros/macro-path-prelude-fail-2.rs b/tests/ui/macros/macro-path-prelude-fail-2.rs index 816a3c4ccc004..42b60bdc934d3 100644 --- a/tests/ui/macros/macro-path-prelude-fail-2.rs +++ b/tests/ui/macros/macro-path-prelude-fail-2.rs @@ -1,6 +1,6 @@ mod m { fn check() { - Result::Ok!(); //~ ERROR failed to resolve: partially resolved path in a macro + Result::Ok!(); //~ ERROR cannot find item `Ok` } } diff --git a/tests/ui/macros/macro-path-prelude-fail-2.stderr b/tests/ui/macros/macro-path-prelude-fail-2.stderr index 87646031cdb82..8ba338f33253b 100644 --- a/tests/ui/macros/macro-path-prelude-fail-2.stderr +++ b/tests/ui/macros/macro-path-prelude-fail-2.stderr @@ -1,4 +1,4 @@ -error[E0433]: failed to resolve: partially resolved path in a macro +error[E0433]: cannot find item `Ok` in this scope --> $DIR/macro-path-prelude-fail-2.rs:3:9 | LL | Result::Ok!(); diff --git a/tests/ui/macros/macro_path_as_generic_bound.rs b/tests/ui/macros/macro_path_as_generic_bound.rs index 663f85688ec9a..b1a07d3dfdde0 100644 --- a/tests/ui/macros/macro_path_as_generic_bound.rs +++ b/tests/ui/macros/macro_path_as_generic_bound.rs @@ -4,6 +4,6 @@ macro_rules! foo(($t:path) => { impl Foo for T {} }); -foo!(m::m2::A); //~ ERROR failed to resolve +foo!(m::m2::A); //~ ERROR cannot find item `m` fn main() {} diff --git a/tests/ui/macros/macro_path_as_generic_bound.stderr b/tests/ui/macros/macro_path_as_generic_bound.stderr index e25ff57e57f36..3b469b5166a1d 100644 --- a/tests/ui/macros/macro_path_as_generic_bound.stderr +++ b/tests/ui/macros/macro_path_as_generic_bound.stderr @@ -1,4 +1,4 @@ -error[E0433]: failed to resolve: use of undeclared crate or module `m` +error[E0433]: cannot find item `m` in this scope --> $DIR/macro_path_as_generic_bound.rs:7:6 | LL | foo!(m::m2::A); diff --git a/tests/ui/macros/meta-item-absolute-path.rs b/tests/ui/macros/meta-item-absolute-path.rs index 8ed911cbca718..04a52fa791c7b 100644 --- a/tests/ui/macros/meta-item-absolute-path.rs +++ b/tests/ui/macros/meta-item-absolute-path.rs @@ -1,5 +1,5 @@ -#[derive(::Absolute)] //~ ERROR failed to resolve - //~| ERROR failed to resolve +#[derive(::Absolute)] //~ ERROR cannot find macro `Absolute` + //~| ERROR cannot find macro `Absolute` struct S; fn main() {} diff --git a/tests/ui/macros/meta-item-absolute-path.stderr b/tests/ui/macros/meta-item-absolute-path.stderr index f0d763d7abbaa..d6786e88d233b 100644 --- a/tests/ui/macros/meta-item-absolute-path.stderr +++ b/tests/ui/macros/meta-item-absolute-path.stderr @@ -1,14 +1,14 @@ -error[E0433]: failed to resolve: maybe a missing crate `Absolute`? +error[E0433]: cannot find macro `Absolute` in the crate root --> $DIR/meta-item-absolute-path.rs:1:12 | LL | #[derive(::Absolute)] - | ^^^^^^^^ maybe a missing crate `Absolute`? + | ^^^^^^^^ you might be missing a crate named `Absolute` -error[E0433]: failed to resolve: maybe a missing crate `Absolute`? +error[E0433]: cannot find macro `Absolute` in the crate root --> $DIR/meta-item-absolute-path.rs:1:12 | LL | #[derive(::Absolute)] - | ^^^^^^^^ maybe a missing crate `Absolute`? + | ^^^^^^^^ you might be missing a crate named `Absolute` | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` diff --git a/tests/ui/mir/issue-121103.rs b/tests/ui/mir/issue-121103.rs index e06361a6964c0..879ec31c2ae2b 100644 --- a/tests/ui/mir/issue-121103.rs +++ b/tests/ui/mir/issue-121103.rs @@ -1,3 +1,3 @@ fn main(_: as lib2::TypeFn>::Output) {} -//~^ ERROR failed to resolve: use of undeclared crate or module `lib2` -//~| ERROR failed to resolve: use of undeclared crate or module `lib2` +//~^ ERROR cannot find item `lib2` +//~| ERROR cannot find item `lib2` diff --git a/tests/ui/mir/issue-121103.stderr b/tests/ui/mir/issue-121103.stderr index 913eee9e0c503..1e58a15f26e5e 100644 --- a/tests/ui/mir/issue-121103.stderr +++ b/tests/ui/mir/issue-121103.stderr @@ -1,10 +1,10 @@ -error[E0433]: failed to resolve: use of undeclared crate or module `lib2` +error[E0433]: cannot find item `lib2` in this scope --> $DIR/issue-121103.rs:1:38 | LL | fn main(_: as lib2::TypeFn>::Output) {} | ^^^^ use of undeclared crate or module `lib2` -error[E0433]: failed to resolve: use of undeclared crate or module `lib2` +error[E0433]: cannot find item `lib2` in this scope --> $DIR/issue-121103.rs:1:13 | LL | fn main(_: as lib2::TypeFn>::Output) {} diff --git a/tests/ui/modules_and_files_visibility/mod_file_disambig.rs b/tests/ui/modules_and_files_visibility/mod_file_disambig.rs index e5958af173b66..8478004486b3a 100644 --- a/tests/ui/modules_and_files_visibility/mod_file_disambig.rs +++ b/tests/ui/modules_and_files_visibility/mod_file_disambig.rs @@ -2,5 +2,5 @@ mod mod_file_disambig_aux; //~ ERROR file for module `mod_file_disambig_aux` fou fn main() { assert_eq!(mod_file_aux::bar(), 10); - //~^ ERROR failed to resolve: use of undeclared crate or module `mod_file_aux` + //~^ ERROR cannot find item `mod_file_aux` } diff --git a/tests/ui/modules_and_files_visibility/mod_file_disambig.stderr b/tests/ui/modules_and_files_visibility/mod_file_disambig.stderr index a2c99396987ef..0d319be52dd7c 100644 --- a/tests/ui/modules_and_files_visibility/mod_file_disambig.stderr +++ b/tests/ui/modules_and_files_visibility/mod_file_disambig.stderr @@ -6,7 +6,7 @@ LL | mod mod_file_disambig_aux; | = help: delete or rename one of them to remove the ambiguity -error[E0433]: failed to resolve: use of undeclared crate or module `mod_file_aux` +error[E0433]: cannot find item `mod_file_aux` in this scope --> $DIR/mod_file_disambig.rs:4:16 | LL | assert_eq!(mod_file_aux::bar(), 10); diff --git a/tests/ui/parser/const-param-decl-on-type-instead-of-impl.rs b/tests/ui/parser/const-param-decl-on-type-instead-of-impl.rs index 949c7b1db6fee..4549f9a7d1353 100644 --- a/tests/ui/parser/const-param-decl-on-type-instead-of-impl.rs +++ b/tests/ui/parser/const-param-decl-on-type-instead-of-impl.rs @@ -11,5 +11,5 @@ fn banana(a: >::BAR) {} fn chaenomeles() { path::path::Struct::() //~^ ERROR unexpected `const` parameter declaration - //~| ERROR failed to resolve: use of undeclared crate or module `path` + //~| ERROR cannot find item `path` } diff --git a/tests/ui/parser/const-param-decl-on-type-instead-of-impl.stderr b/tests/ui/parser/const-param-decl-on-type-instead-of-impl.stderr index 96885d11ee07f..f96779e4969ac 100644 --- a/tests/ui/parser/const-param-decl-on-type-instead-of-impl.stderr +++ b/tests/ui/parser/const-param-decl-on-type-instead-of-impl.stderr @@ -21,7 +21,7 @@ error: unexpected `const` parameter declaration LL | path::path::Struct::() | ^^^^^^^^^^^^^^ expected a `const` expression, not a parameter declaration -error[E0433]: failed to resolve: use of undeclared crate or module `path` +error[E0433]: cannot find item `path` in this scope --> $DIR/const-param-decl-on-type-instead-of-impl.rs:12:5 | LL | path::path::Struct::() diff --git a/tests/ui/parser/dyn-trait-compatibility.rs b/tests/ui/parser/dyn-trait-compatibility.rs index 56e77201ba15d..3cecad46be6db 100644 --- a/tests/ui/parser/dyn-trait-compatibility.rs +++ b/tests/ui/parser/dyn-trait-compatibility.rs @@ -1,7 +1,7 @@ type A0 = dyn; //~^ ERROR cannot find type `dyn` type A1 = dyn::dyn; -//~^ ERROR use of undeclared crate or module `dyn` +//~^ ERROR cannot find item `dyn` type A2 = dyn; //~^ ERROR cannot find type `dyn` //~| ERROR cannot find type `dyn` diff --git a/tests/ui/parser/dyn-trait-compatibility.stderr b/tests/ui/parser/dyn-trait-compatibility.stderr index e34d855a9d4f9..9a3d3d98337f4 100644 --- a/tests/ui/parser/dyn-trait-compatibility.stderr +++ b/tests/ui/parser/dyn-trait-compatibility.stderr @@ -40,7 +40,7 @@ error[E0412]: cannot find type `dyn` in this scope LL | type A3 = dyn<::dyn>; | ^^^ not found in this scope -error[E0433]: failed to resolve: use of undeclared crate or module `dyn` +error[E0433]: cannot find item `dyn` in this scope --> $DIR/dyn-trait-compatibility.rs:3:11 | LL | type A1 = dyn::dyn; diff --git a/tests/ui/parser/mod_file_not_exist.rs b/tests/ui/parser/mod_file_not_exist.rs index 80a17163087c9..57363c2d1ea74 100644 --- a/tests/ui/parser/mod_file_not_exist.rs +++ b/tests/ui/parser/mod_file_not_exist.rs @@ -5,5 +5,5 @@ mod not_a_real_file; //~ ERROR file not found for module `not_a_real_file` fn main() { assert_eq!(mod_file_aux::bar(), 10); - //~^ ERROR failed to resolve: use of undeclared crate or module `mod_file_aux` + //~^ ERROR cannot find item `mod_file_aux` } diff --git a/tests/ui/parser/mod_file_not_exist.stderr b/tests/ui/parser/mod_file_not_exist.stderr index c2f9d30d9ec40..5ca938e913abe 100644 --- a/tests/ui/parser/mod_file_not_exist.stderr +++ b/tests/ui/parser/mod_file_not_exist.stderr @@ -7,7 +7,7 @@ LL | mod not_a_real_file; = help: to create the module `not_a_real_file`, create file "$DIR/not_a_real_file.rs" or "$DIR/not_a_real_file/mod.rs" = note: if there is a `mod not_a_real_file` elsewhere in the crate already, import it with `use crate::...` instead -error[E0433]: failed to resolve: use of undeclared crate or module `mod_file_aux` +error[E0433]: cannot find item `mod_file_aux` in this scope --> $DIR/mod_file_not_exist.rs:7:16 | LL | assert_eq!(mod_file_aux::bar(), 10); diff --git a/tests/ui/parser/mod_file_not_exist_windows.rs b/tests/ui/parser/mod_file_not_exist_windows.rs index 88780c0c24e94..f193d46dedbea 100644 --- a/tests/ui/parser/mod_file_not_exist_windows.rs +++ b/tests/ui/parser/mod_file_not_exist_windows.rs @@ -5,5 +5,5 @@ mod not_a_real_file; //~ ERROR file not found for module `not_a_real_file` fn main() { assert_eq!(mod_file_aux::bar(), 10); - //~^ ERROR failed to resolve: use of undeclared crate or module `mod_file_aux` + //~^ ERROR cannot find item `mod_file_aux` } diff --git a/tests/ui/parser/mod_file_not_exist_windows.stderr b/tests/ui/parser/mod_file_not_exist_windows.stderr index 53b09d8ca53a0..da1e43f21f744 100644 --- a/tests/ui/parser/mod_file_not_exist_windows.stderr +++ b/tests/ui/parser/mod_file_not_exist_windows.stderr @@ -7,7 +7,7 @@ LL | mod not_a_real_file; = help: to create the module `not_a_real_file`, create file "$DIR/not_a_real_file.rs" or "$DIR/not_a_real_file/mod.rs" = note: if there is a `mod not_a_real_file` elsewhere in the crate already, import it with `use crate::...` instead -error[E0433]: failed to resolve: use of undeclared crate or module `mod_file_aux` +error[E0433]: cannot find item `mod_file_aux` --> $DIR/mod_file_not_exist_windows.rs:7:16 | LL | assert_eq!(mod_file_aux::bar(), 10); diff --git a/tests/ui/pattern/pattern-error-continue.rs b/tests/ui/pattern/pattern-error-continue.rs index bed949439237a..80da1b6699283 100644 --- a/tests/ui/pattern/pattern-error-continue.rs +++ b/tests/ui/pattern/pattern-error-continue.rs @@ -30,6 +30,6 @@ fn main() { //~| expected `char`, found `bool` match () { - E::V => {} //~ ERROR failed to resolve: use of undeclared type `E` + E::V => {} //~ ERROR cannot find item `E` } } diff --git a/tests/ui/pattern/pattern-error-continue.stderr b/tests/ui/pattern/pattern-error-continue.stderr index 10fcccb030162..f07dd399c154b 100644 --- a/tests/ui/pattern/pattern-error-continue.stderr +++ b/tests/ui/pattern/pattern-error-continue.stderr @@ -50,7 +50,7 @@ note: function defined here LL | fn f(_c: char) {} | ^ -------- -error[E0433]: failed to resolve: use of undeclared type `E` +error[E0433]: cannot find item `E` in this scope --> $DIR/pattern-error-continue.rs:33:9 | LL | E::V => {} diff --git a/tests/ui/privacy/restricted/test.rs b/tests/ui/privacy/restricted/test.rs index e1d87cfcd88c8..b459057777177 100644 --- a/tests/ui/privacy/restricted/test.rs +++ b/tests/ui/privacy/restricted/test.rs @@ -47,6 +47,6 @@ fn main() { } mod pathological { - pub(in bad::path) mod m1 {} //~ ERROR failed to resolve: maybe a missing crate `bad`? + pub(in bad::path) mod m1 {} //~ ERROR cannot find item `bad` pub(in foo) mod m2 {} //~ ERROR visibilities can only be restricted to ancestor modules } diff --git a/tests/ui/privacy/restricted/test.stderr b/tests/ui/privacy/restricted/test.stderr index 76f19525df532..6e8d6a5843b5a 100644 --- a/tests/ui/privacy/restricted/test.stderr +++ b/tests/ui/privacy/restricted/test.stderr @@ -1,8 +1,8 @@ -error[E0433]: failed to resolve: maybe a missing crate `bad`? +error[E0433]: cannot find item `bad` in this scope --> $DIR/test.rs:50:12 | LL | pub(in bad::path) mod m1 {} - | ^^^ maybe a missing crate `bad`? + | ^^^ you might be missing a crate named `bad` | = help: consider adding `extern crate bad` to use the `bad` crate diff --git a/tests/ui/privacy/unreachable-issue-121455.rs b/tests/ui/privacy/unreachable-issue-121455.rs index 5da30d6ed6397..05fcacc73d2d0 100644 --- a/tests/ui/privacy/unreachable-issue-121455.rs +++ b/tests/ui/privacy/unreachable-issue-121455.rs @@ -1,5 +1,5 @@ fn test(s: &Self::Id) { -//~^ ERROR failed to resolve: `Self` is only available in impls, traits, and type definitions +//~^ ERROR cannot find item `Self` match &s[0..3] {} } diff --git a/tests/ui/privacy/unreachable-issue-121455.stderr b/tests/ui/privacy/unreachable-issue-121455.stderr index 864e950a98eb2..c371f793bf2b0 100644 --- a/tests/ui/privacy/unreachable-issue-121455.stderr +++ b/tests/ui/privacy/unreachable-issue-121455.stderr @@ -1,4 +1,4 @@ -error[E0433]: failed to resolve: `Self` is only available in impls, traits, and type definitions +error[E0433]: cannot find item `Self` in this scope --> $DIR/unreachable-issue-121455.rs:1:13 | LL | fn test(s: &Self::Id) { diff --git a/tests/ui/proc-macro/amputate-span.stderr b/tests/ui/proc-macro/amputate-span.stderr index aa797339be467..d21a6413b87d0 100644 --- a/tests/ui/proc-macro/amputate-span.stderr +++ b/tests/ui/proc-macro/amputate-span.stderr @@ -1,4 +1,4 @@ -error[E0433]: failed to resolve: use of undeclared type `Command` +error[E0433]: cannot find item `Command` in this scope --> $DIR/amputate-span.rs:49:5 | LL | Command::new("git"); @@ -9,7 +9,7 @@ help: consider importing this struct LL + use std::process::Command; | -error[E0433]: failed to resolve: use of undeclared type `Command` +error[E0433]: cannot find item `Command` in this scope --> $DIR/amputate-span.rs:63:9 | LL | Command::new("git"); diff --git a/tests/ui/resolve/112590-2.fixed b/tests/ui/resolve/112590-2.fixed index d88bc4b47e204..f72faeeb51992 100644 --- a/tests/ui/resolve/112590-2.fixed +++ b/tests/ui/resolve/112590-2.fixed @@ -15,7 +15,7 @@ mod u { use foo::bar::baz::MyVec; fn _a() { - let _: Vec = MyVec::new(); //~ ERROR failed to resolve + let _: Vec = MyVec::new(); //~ ERROR cannot find item } } @@ -23,12 +23,12 @@ mod v { use foo::bar::baz::MyVec; fn _b() { - let _: Vec = MyVec::new(); //~ ERROR failed to resolve + let _: Vec = MyVec::new(); //~ ERROR cannot find item } } fn main() { - let _t: Vec = Vec::new(); //~ ERROR failed to resolve - type _B = vec::Vec::; //~ ERROR failed to resolve - let _t = AtomicBool::new(true); //~ ERROR failed to resolve + let _t: Vec = Vec::new(); //~ ERROR cannot find item + type _B = vec::Vec::; //~ ERROR cannot find item + let _t = AtomicBool::new(true); //~ ERROR cannot find item } diff --git a/tests/ui/resolve/112590-2.rs b/tests/ui/resolve/112590-2.rs index d8aaa5a6cc121..532ee55e782c3 100644 --- a/tests/ui/resolve/112590-2.rs +++ b/tests/ui/resolve/112590-2.rs @@ -9,18 +9,18 @@ mod foo { mod u { fn _a() { - let _: Vec = super::foo::baf::baz::MyVec::new(); //~ ERROR failed to resolve + let _: Vec = super::foo::baf::baz::MyVec::new(); //~ ERROR cannot find item } } mod v { fn _b() { - let _: Vec = fox::bar::baz::MyVec::new(); //~ ERROR failed to resolve + let _: Vec = fox::bar::baz::MyVec::new(); //~ ERROR cannot find item } } fn main() { - let _t: Vec = vec::new(); //~ ERROR failed to resolve - type _B = vec::Vec::; //~ ERROR failed to resolve - let _t = std::sync_error::atomic::AtomicBool::new(true); //~ ERROR failed to resolve + let _t: Vec = vec::new(); //~ ERROR cannot find item + type _B = vec::Vec::; //~ ERROR cannot find item + let _t = std::sync_error::atomic::AtomicBool::new(true); //~ ERROR cannot find item } diff --git a/tests/ui/resolve/112590-2.stderr b/tests/ui/resolve/112590-2.stderr index 0db20249d27f5..7492b7bf52723 100644 --- a/tests/ui/resolve/112590-2.stderr +++ b/tests/ui/resolve/112590-2.stderr @@ -1,4 +1,4 @@ -error[E0433]: failed to resolve: could not find `baf` in `foo` +error[E0433]: cannot find item `baf` in module `foo` --> $DIR/112590-2.rs:12:39 | LL | let _: Vec = super::foo::baf::baz::MyVec::new(); @@ -14,7 +14,7 @@ LL - let _: Vec = super::foo::baf::baz::MyVec::new(); LL + let _: Vec = MyVec::new(); | -error[E0433]: failed to resolve: use of undeclared crate or module `fox` +error[E0433]: cannot find item `fox` in this scope --> $DIR/112590-2.rs:18:27 | LL | let _: Vec = fox::bar::baz::MyVec::new(); @@ -30,7 +30,7 @@ LL - let _: Vec = fox::bar::baz::MyVec::new(); LL + let _: Vec = MyVec::new(); | -error[E0433]: failed to resolve: use of undeclared crate or module `vec` +error[E0433]: cannot find item `vec` in this scope --> $DIR/112590-2.rs:24:15 | LL | type _B = vec::Vec::; @@ -41,7 +41,7 @@ help: consider importing this module LL + use std::vec; | -error[E0433]: failed to resolve: could not find `sync_error` in `std` +error[E0433]: cannot find item `sync_error` in crate `std` --> $DIR/112590-2.rs:25:19 | LL | let _t = std::sync_error::atomic::AtomicBool::new(true); @@ -57,7 +57,7 @@ LL - let _t = std::sync_error::atomic::AtomicBool::new(true); LL + let _t = AtomicBool::new(true); | -error[E0433]: failed to resolve: use of undeclared crate or module `vec` +error[E0433]: cannot find item `vec` in this scope --> $DIR/112590-2.rs:23:24 | LL | let _t: Vec = vec::new(); diff --git a/tests/ui/resolve/bad-module.rs b/tests/ui/resolve/bad-module.rs index b23e97c2cf6bc..90a4b6531aff0 100644 --- a/tests/ui/resolve/bad-module.rs +++ b/tests/ui/resolve/bad-module.rs @@ -1,7 +1,7 @@ fn main() { let foo = thing::len(Vec::new()); - //~^ ERROR failed to resolve: use of undeclared crate or module `thing` + //~^ ERROR cannot find item `thing` let foo = foo::bar::baz(); - //~^ ERROR failed to resolve: use of undeclared crate or module `foo` + //~^ ERROR cannot find item `foo` } diff --git a/tests/ui/resolve/bad-module.stderr b/tests/ui/resolve/bad-module.stderr index 558760c6793ab..da41a80f79c15 100644 --- a/tests/ui/resolve/bad-module.stderr +++ b/tests/ui/resolve/bad-module.stderr @@ -1,10 +1,10 @@ -error[E0433]: failed to resolve: use of undeclared crate or module `foo` +error[E0433]: cannot find item `foo` in this scope --> $DIR/bad-module.rs:5:15 | LL | let foo = foo::bar::baz(); | ^^^ use of undeclared crate or module `foo` -error[E0433]: failed to resolve: use of undeclared crate or module `thing` +error[E0433]: cannot find item `thing` in this scope --> $DIR/bad-module.rs:2:15 | LL | let foo = thing::len(Vec::new()); diff --git a/tests/ui/resolve/editions-crate-root-2015.rs b/tests/ui/resolve/editions-crate-root-2015.rs index 06e716c8245ac..0d7e0aa3db8f5 100644 --- a/tests/ui/resolve/editions-crate-root-2015.rs +++ b/tests/ui/resolve/editions-crate-root-2015.rs @@ -2,10 +2,10 @@ mod inner { fn global_inner(_: ::nonexistant::Foo) { - //~^ ERROR failed to resolve: maybe a missing crate `nonexistant`? + //~^ ERROR cannot find item `nonexistant` } fn crate_inner(_: crate::nonexistant::Foo) { - //~^ ERROR failed to resolve: maybe a missing crate `nonexistant`? + //~^ ERROR cannot find item `nonexistant` } fn bare_global(_: ::nonexistant) { diff --git a/tests/ui/resolve/editions-crate-root-2015.stderr b/tests/ui/resolve/editions-crate-root-2015.stderr index 00cdd0c58f4ec..08c6fcfeaba4e 100644 --- a/tests/ui/resolve/editions-crate-root-2015.stderr +++ b/tests/ui/resolve/editions-crate-root-2015.stderr @@ -1,16 +1,16 @@ -error[E0433]: failed to resolve: maybe a missing crate `nonexistant`? +error[E0433]: cannot find item `nonexistant` in the crate root --> $DIR/editions-crate-root-2015.rs:4:26 | LL | fn global_inner(_: ::nonexistant::Foo) { - | ^^^^^^^^^^^ maybe a missing crate `nonexistant`? + | ^^^^^^^^^^^ you might be missing a crate named `nonexistant` | = help: consider adding `extern crate nonexistant` to use the `nonexistant` crate -error[E0433]: failed to resolve: maybe a missing crate `nonexistant`? +error[E0433]: cannot find item `nonexistant` in the crate root --> $DIR/editions-crate-root-2015.rs:7:30 | LL | fn crate_inner(_: crate::nonexistant::Foo) { - | ^^^^^^^^^^^ maybe a missing crate `nonexistant`? + | ^^^^^^^^^^^ you might be missing a crate named `nonexistant` | = help: consider adding `extern crate nonexistant` to use the `nonexistant` crate diff --git a/tests/ui/resolve/editions-crate-root-2018.rs b/tests/ui/resolve/editions-crate-root-2018.rs index 6888cefa18a48..4333e718fab00 100644 --- a/tests/ui/resolve/editions-crate-root-2018.rs +++ b/tests/ui/resolve/editions-crate-root-2018.rs @@ -2,10 +2,10 @@ mod inner { fn global_inner(_: ::nonexistant::Foo) { - //~^ ERROR failed to resolve: could not find `nonexistant` + //~^ ERROR cannot find item `nonexistant` } fn crate_inner(_: crate::nonexistant::Foo) { - //~^ ERROR failed to resolve: could not find `nonexistant` + //~^ ERROR cannot find item `nonexistant` } fn bare_global(_: ::nonexistant) { diff --git a/tests/ui/resolve/editions-crate-root-2018.stderr b/tests/ui/resolve/editions-crate-root-2018.stderr index 967a5a2fca155..3c974bb2cb850 100644 --- a/tests/ui/resolve/editions-crate-root-2018.stderr +++ b/tests/ui/resolve/editions-crate-root-2018.stderr @@ -1,10 +1,10 @@ -error[E0433]: failed to resolve: could not find `nonexistant` in the list of imported crates +error[E0433]: cannot find item `nonexistant` in the list of imported crates --> $DIR/editions-crate-root-2018.rs:4:26 | LL | fn global_inner(_: ::nonexistant::Foo) { | ^^^^^^^^^^^ could not find `nonexistant` in the list of imported crates -error[E0433]: failed to resolve: could not find `nonexistant` in the crate root +error[E0433]: cannot find item `nonexistant` in the crate root --> $DIR/editions-crate-root-2018.rs:7:30 | LL | fn crate_inner(_: crate::nonexistant::Foo) { diff --git a/tests/ui/resolve/export-fully-qualified-2018.rs b/tests/ui/resolve/export-fully-qualified-2018.rs index 26e3044d8df0e..1c0e2aa1f6b68 100644 --- a/tests/ui/resolve/export-fully-qualified-2018.rs +++ b/tests/ui/resolve/export-fully-qualified-2018.rs @@ -5,7 +5,7 @@ // want to change eventually. mod foo { - pub fn bar() { foo::baz(); } //~ ERROR failed to resolve: use of undeclared crate or module `foo` + pub fn bar() { foo::baz(); } //~ ERROR cannot find item `foo` fn baz() { } } diff --git a/tests/ui/resolve/export-fully-qualified-2018.stderr b/tests/ui/resolve/export-fully-qualified-2018.stderr index 378d9832a657a..2713c5ef4f102 100644 --- a/tests/ui/resolve/export-fully-qualified-2018.stderr +++ b/tests/ui/resolve/export-fully-qualified-2018.stderr @@ -1,4 +1,4 @@ -error[E0433]: failed to resolve: use of undeclared crate or module `foo` +error[E0433]: cannot find item `foo` in this scope --> $DIR/export-fully-qualified-2018.rs:8:20 | LL | pub fn bar() { foo::baz(); } diff --git a/tests/ui/resolve/export-fully-qualified.rs b/tests/ui/resolve/export-fully-qualified.rs index 6de33b7e1915f..85f773644f071 100644 --- a/tests/ui/resolve/export-fully-qualified.rs +++ b/tests/ui/resolve/export-fully-qualified.rs @@ -5,7 +5,7 @@ // want to change eventually. mod foo { - pub fn bar() { foo::baz(); } //~ ERROR failed to resolve: use of undeclared crate or module `foo` + pub fn bar() { foo::baz(); } //~ ERROR cannot find item `foo` fn baz() { } } diff --git a/tests/ui/resolve/export-fully-qualified.stderr b/tests/ui/resolve/export-fully-qualified.stderr index 869149d8d3c65..1c14514328364 100644 --- a/tests/ui/resolve/export-fully-qualified.stderr +++ b/tests/ui/resolve/export-fully-qualified.stderr @@ -1,4 +1,4 @@ -error[E0433]: failed to resolve: use of undeclared crate or module `foo` +error[E0433]: cannot find item `foo` in this scope --> $DIR/export-fully-qualified.rs:8:20 | LL | pub fn bar() { foo::baz(); } diff --git a/tests/ui/resolve/extern-prelude-fail.rs b/tests/ui/resolve/extern-prelude-fail.rs index c0716f1ebf566..8fcf7f2262435 100644 --- a/tests/ui/resolve/extern-prelude-fail.rs +++ b/tests/ui/resolve/extern-prelude-fail.rs @@ -5,5 +5,5 @@ fn main() { use extern_prelude::S; //~ ERROR unresolved import `extern_prelude` - let s = ::extern_prelude::S; //~ ERROR failed to resolve + let s = ::extern_prelude::S; //~ ERROR cannot find item `extern_prelude` } diff --git a/tests/ui/resolve/extern-prelude-fail.stderr b/tests/ui/resolve/extern-prelude-fail.stderr index a1591914b4d29..030c4834dc7b8 100644 --- a/tests/ui/resolve/extern-prelude-fail.stderr +++ b/tests/ui/resolve/extern-prelude-fail.stderr @@ -2,15 +2,15 @@ error[E0432]: unresolved import `extern_prelude` --> $DIR/extern-prelude-fail.rs:7:9 | LL | use extern_prelude::S; - | ^^^^^^^^^^^^^^ maybe a missing crate `extern_prelude`? + | ^^^^^^^^^^^^^^ you might be missing a crate named `extern_prelude` | = help: consider adding `extern crate extern_prelude` to use the `extern_prelude` crate -error[E0433]: failed to resolve: maybe a missing crate `extern_prelude`? +error[E0433]: cannot find item `extern_prelude` in the crate root --> $DIR/extern-prelude-fail.rs:8:15 | LL | let s = ::extern_prelude::S; - | ^^^^^^^^^^^^^^ maybe a missing crate `extern_prelude`? + | ^^^^^^^^^^^^^^ you might be missing a crate named `extern_prelude` | = help: consider adding `extern crate extern_prelude` to use the `extern_prelude` crate diff --git a/tests/ui/resolve/impl-items-vis-unresolved.rs b/tests/ui/resolve/impl-items-vis-unresolved.rs index 1494c1cf96800..5c0c151c57cef 100644 --- a/tests/ui/resolve/impl-items-vis-unresolved.rs +++ b/tests/ui/resolve/impl-items-vis-unresolved.rs @@ -19,7 +19,7 @@ pub struct RawFloatState; impl RawFloatState { perftools_inline! { pub(super) fn new() {} - //~^ ERROR failed to resolve: there are too many leading `super` keywords + //~^ ERROR cannot find module `super` } } diff --git a/tests/ui/resolve/impl-items-vis-unresolved.stderr b/tests/ui/resolve/impl-items-vis-unresolved.stderr index cccffdcbf541b..af0b7e6f50bab 100644 --- a/tests/ui/resolve/impl-items-vis-unresolved.stderr +++ b/tests/ui/resolve/impl-items-vis-unresolved.stderr @@ -1,8 +1,8 @@ -error[E0433]: failed to resolve: there are too many leading `super` keywords +error[E0433]: cannot find module `super` in this scope --> $DIR/impl-items-vis-unresolved.rs:21:13 | LL | pub(super) fn new() {} - | ^^^^^ there are too many leading `super` keywords + | ^^^^^ can't use `super` on the crate root, there are no further modules to go "up" to error: aborting due to 1 previous error diff --git a/tests/ui/resolve/issue-101749-2.rs b/tests/ui/resolve/issue-101749-2.rs index 4d3d469447c2b..9afcc4deef2fc 100644 --- a/tests/ui/resolve/issue-101749-2.rs +++ b/tests/ui/resolve/issue-101749-2.rs @@ -12,5 +12,5 @@ fn main() { let rect = Rectangle::new(3, 4); // `area` is not implemented for `Rectangle`, so this should not suggest let _ = rect::area(); - //~^ ERROR failed to resolve: use of undeclared crate or module `rect` + //~^ ERROR cannot find item `rect` } diff --git a/tests/ui/resolve/issue-101749-2.stderr b/tests/ui/resolve/issue-101749-2.stderr index 300aaf26cb7d8..14e35593781a4 100644 --- a/tests/ui/resolve/issue-101749-2.stderr +++ b/tests/ui/resolve/issue-101749-2.stderr @@ -1,4 +1,4 @@ -error[E0433]: failed to resolve: use of undeclared crate or module `rect` +error[E0433]: cannot find item `rect` in this scope --> $DIR/issue-101749-2.rs:14:13 | LL | let _ = rect::area(); diff --git a/tests/ui/resolve/issue-101749.fixed b/tests/ui/resolve/issue-101749.fixed index 97815793d298e..4a532d7a0a44b 100644 --- a/tests/ui/resolve/issue-101749.fixed +++ b/tests/ui/resolve/issue-101749.fixed @@ -15,5 +15,5 @@ impl Rectangle { fn main() { let rect = Rectangle::new(3, 4); let _ = rect.area(); - //~^ ERROR failed to resolve: use of undeclared crate or module `rect` + //~^ ERROR cannot find item `rect` } diff --git a/tests/ui/resolve/issue-101749.rs b/tests/ui/resolve/issue-101749.rs index 994fc86778e08..13c122f721e85 100644 --- a/tests/ui/resolve/issue-101749.rs +++ b/tests/ui/resolve/issue-101749.rs @@ -15,5 +15,5 @@ impl Rectangle { fn main() { let rect = Rectangle::new(3, 4); let _ = rect::area(); - //~^ ERROR failed to resolve: use of undeclared crate or module `rect` + //~^ ERROR cannot find item `rect` } diff --git a/tests/ui/resolve/issue-101749.stderr b/tests/ui/resolve/issue-101749.stderr index 05515b1b46052..d64eb03376e92 100644 --- a/tests/ui/resolve/issue-101749.stderr +++ b/tests/ui/resolve/issue-101749.stderr @@ -1,4 +1,4 @@ -error[E0433]: failed to resolve: use of undeclared crate or module `rect` +error[E0433]: cannot find item `rect` in this scope --> $DIR/issue-101749.rs:17:13 | LL | let _ = rect::area(); diff --git a/tests/ui/resolve/issue-109250.rs b/tests/ui/resolve/issue-109250.rs index 68e33f693cef1..736ad81e3174d 100644 --- a/tests/ui/resolve/issue-109250.rs +++ b/tests/ui/resolve/issue-109250.rs @@ -1,3 +1,3 @@ fn main() { //~ HELP consider importing - HashMap::new; //~ ERROR failed to resolve: use of undeclared type `HashMap` + HashMap::new; //~ ERROR cannot find item `HashMap` } diff --git a/tests/ui/resolve/issue-109250.stderr b/tests/ui/resolve/issue-109250.stderr index ad6cc6986229a..4692e8f43f9a3 100644 --- a/tests/ui/resolve/issue-109250.stderr +++ b/tests/ui/resolve/issue-109250.stderr @@ -1,4 +1,4 @@ -error[E0433]: failed to resolve: use of undeclared type `HashMap` +error[E0433]: cannot find item `HashMap` in this scope --> $DIR/issue-109250.rs:2:5 | LL | HashMap::new; diff --git a/tests/ui/resolve/issue-117920.rs b/tests/ui/resolve/issue-117920.rs index 928f194c59c3f..25a57ae3b9047 100644 --- a/tests/ui/resolve/issue-117920.rs +++ b/tests/ui/resolve/issue-117920.rs @@ -1,6 +1,6 @@ #![crate_type = "lib"] -use super::A; //~ ERROR failed to resolve +use super::A; //~ ERROR cannot find mod b { pub trait A {} diff --git a/tests/ui/resolve/issue-117920.stderr b/tests/ui/resolve/issue-117920.stderr index c4528d467e9f5..53b45c981f7e9 100644 --- a/tests/ui/resolve/issue-117920.stderr +++ b/tests/ui/resolve/issue-117920.stderr @@ -1,8 +1,8 @@ -error[E0433]: failed to resolve: there are too many leading `super` keywords +error[E0433]: cannot find module `super` in this scope --> $DIR/issue-117920.rs:3:5 | LL | use super::A; - | ^^^^^ there are too many leading `super` keywords + | ^^^^^ can't use `super` on the crate root, there are no further modules to go "up" to error: aborting due to 1 previous error diff --git a/tests/ui/resolve/issue-24968.rs b/tests/ui/resolve/issue-24968.rs index 19e16abcee3cb..63e3d19a25ff6 100644 --- a/tests/ui/resolve/issue-24968.rs +++ b/tests/ui/resolve/issue-24968.rs @@ -19,12 +19,12 @@ const FOO: Self = 0; //~^ ERROR cannot find type `Self` const FOO2: u32 = Self::bar(); -//~^ ERROR failed to resolve: `Self` +//~^ ERROR cannot find item `Self` static FOO_S: Self = 0; //~^ ERROR cannot find type `Self` static FOO_S2: u32 = Self::bar(); -//~^ ERROR failed to resolve: `Self` +//~^ ERROR cannot find item `Self` fn main() {} diff --git a/tests/ui/resolve/issue-24968.stderr b/tests/ui/resolve/issue-24968.stderr index 82f5a1d5b57b3..75c4059d7c267 100644 --- a/tests/ui/resolve/issue-24968.stderr +++ b/tests/ui/resolve/issue-24968.stderr @@ -39,13 +39,13 @@ LL | static FOO_S: Self = 0; | | | `Self` not allowed in a static item -error[E0433]: failed to resolve: `Self` is only available in impls, traits, and type definitions +error[E0433]: cannot find item `Self` in this scope --> $DIR/issue-24968.rs:21:19 | LL | const FOO2: u32 = Self::bar(); | ^^^^ `Self` is only available in impls, traits, and type definitions -error[E0433]: failed to resolve: `Self` is only available in impls, traits, and type definitions +error[E0433]: cannot find item `Self` in this scope --> $DIR/issue-24968.rs:27:22 | LL | static FOO_S2: u32 = Self::bar(); diff --git a/tests/ui/resolve/issue-81508.rs b/tests/ui/resolve/issue-81508.rs index 23605cd2fd91d..c0cbb966fb96e 100644 --- a/tests/ui/resolve/issue-81508.rs +++ b/tests/ui/resolve/issue-81508.rs @@ -8,7 +8,7 @@ fn main() { let Baz: &str = ""; - println!("{}", Baz::Bar); //~ ERROR: failed to resolve: use of undeclared type `Baz` + println!("{}", Baz::Bar); //~ ERROR: cannot find item `Baz` } #[allow(non_upper_case_globals)] @@ -17,6 +17,6 @@ pub const Foo: &str = ""; mod submod { use super::Foo; fn function() { - println!("{}", Foo::Bar); //~ ERROR: failed to resolve: use of undeclared type `Foo` + println!("{}", Foo::Bar); //~ ERROR: cannot find item `Foo` } } diff --git a/tests/ui/resolve/issue-81508.stderr b/tests/ui/resolve/issue-81508.stderr index 7258174ba89b3..0e06ab5dd7bd6 100644 --- a/tests/ui/resolve/issue-81508.stderr +++ b/tests/ui/resolve/issue-81508.stderr @@ -1,4 +1,4 @@ -error[E0433]: failed to resolve: use of undeclared type `Baz` +error[E0433]: cannot find item `Baz` in this scope --> $DIR/issue-81508.rs:11:20 | LL | let Baz: &str = ""; @@ -7,7 +7,7 @@ LL | LL | println!("{}", Baz::Bar); | ^^^ use of undeclared type `Baz` -error[E0433]: failed to resolve: use of undeclared type `Foo` +error[E0433]: cannot find item `Foo` in this scope --> $DIR/issue-81508.rs:20:24 | LL | use super::Foo; diff --git a/tests/ui/resolve/issue-82156.rs b/tests/ui/resolve/issue-82156.rs index 6215259e48657..f1c6fffff11ef 100644 --- a/tests/ui/resolve/issue-82156.rs +++ b/tests/ui/resolve/issue-82156.rs @@ -1,3 +1,3 @@ fn main() { - super(); //~ ERROR failed to resolve: there are too many leading `super` keywords + super(); //~ ERROR cannot find item `super` } diff --git a/tests/ui/resolve/issue-82156.stderr b/tests/ui/resolve/issue-82156.stderr index 3894b9573a45c..3649c775d8553 100644 --- a/tests/ui/resolve/issue-82156.stderr +++ b/tests/ui/resolve/issue-82156.stderr @@ -1,8 +1,13 @@ -error[E0433]: failed to resolve: there are too many leading `super` keywords +error[E0433]: cannot find item `super` in this scope --> $DIR/issue-82156.rs:2:5 | LL | super(); - | ^^^^^ there are too many leading `super` keywords + | ^^^^^ can't use `super` as an identifier + | +help: if you still want to call your identifier `super`, use the raw identifier format + | +LL | r#super(); + | ++ error: aborting due to 1 previous error diff --git a/tests/ui/resolve/issue-82865.rs b/tests/ui/resolve/issue-82865.rs index 07d88c413bfa8..6a358ea60864c 100644 --- a/tests/ui/resolve/issue-82865.rs +++ b/tests/ui/resolve/issue-82865.rs @@ -2,7 +2,7 @@ #![feature(decl_macro)] -use x::y::z; //~ ERROR: failed to resolve: maybe a missing crate `x`? +use x::y::z; //~ ERROR: cannot find item `x` macro mac () { Box::z //~ ERROR: no function or associated item diff --git a/tests/ui/resolve/issue-82865.stderr b/tests/ui/resolve/issue-82865.stderr index 730fd6d602645..667d7bcc4b9c6 100644 --- a/tests/ui/resolve/issue-82865.stderr +++ b/tests/ui/resolve/issue-82865.stderr @@ -1,8 +1,8 @@ -error[E0433]: failed to resolve: maybe a missing crate `x`? +error[E0433]: cannot find item `x` in the crate root --> $DIR/issue-82865.rs:5:5 | LL | use x::y::z; - | ^ maybe a missing crate `x`? + | ^ you might be missing a crate named `x` | = help: consider adding `extern crate x` to use the `x` crate diff --git a/tests/ui/resolve/missing-in-namespace.rs b/tests/ui/resolve/missing-in-namespace.rs index e1dedb072b77b..e884ec82dae33 100644 --- a/tests/ui/resolve/missing-in-namespace.rs +++ b/tests/ui/resolve/missing-in-namespace.rs @@ -1,4 +1,4 @@ fn main() { let _map = std::hahmap::HashMap::new(); - //~^ ERROR failed to resolve: could not find `hahmap` in `std + //~^ ERROR cannot find item `hahmap` } diff --git a/tests/ui/resolve/missing-in-namespace.stderr b/tests/ui/resolve/missing-in-namespace.stderr index 35585e4240a2b..d53c191f70c88 100644 --- a/tests/ui/resolve/missing-in-namespace.stderr +++ b/tests/ui/resolve/missing-in-namespace.stderr @@ -1,4 +1,4 @@ -error[E0433]: failed to resolve: could not find `hahmap` in `std` +error[E0433]: cannot find item `hahmap` in crate `std` --> $DIR/missing-in-namespace.rs:2:21 | LL | let _map = std::hahmap::HashMap::new(); diff --git a/tests/ui/resolve/resolve-bad-visibility.rs b/tests/ui/resolve/resolve-bad-visibility.rs index 7d48bb97b106e..d2cbb2973349f 100644 --- a/tests/ui/resolve/resolve-bad-visibility.rs +++ b/tests/ui/resolve/resolve-bad-visibility.rs @@ -4,8 +4,8 @@ trait Tr {} pub(in E) struct S; //~ ERROR expected module, found enum `E` pub(in Tr) struct Z; //~ ERROR expected module, found trait `Tr` pub(in std::vec) struct F; //~ ERROR visibilities can only be restricted to ancestor modules -pub(in nonexistent) struct G; //~ ERROR failed to resolve -pub(in too_soon) struct H; //~ ERROR failed to resolve +pub(in nonexistent) struct G; //~ ERROR cannot find +pub(in too_soon) struct H; //~ ERROR cannot find // Visibilities are resolved eagerly without waiting for modules becoming fully populated. // Visibilities can only use ancestor modules legally which are always available in time, diff --git a/tests/ui/resolve/resolve-bad-visibility.stderr b/tests/ui/resolve/resolve-bad-visibility.stderr index 2ac41b87562e1..ff7e1f58bdce1 100644 --- a/tests/ui/resolve/resolve-bad-visibility.stderr +++ b/tests/ui/resolve/resolve-bad-visibility.stderr @@ -16,19 +16,19 @@ error[E0742]: visibilities can only be restricted to ancestor modules LL | pub(in std::vec) struct F; | ^^^^^^^^ -error[E0433]: failed to resolve: maybe a missing crate `nonexistent`? +error[E0433]: cannot find item `nonexistent` in this scope --> $DIR/resolve-bad-visibility.rs:7:8 | LL | pub(in nonexistent) struct G; - | ^^^^^^^^^^^ maybe a missing crate `nonexistent`? + | ^^^^^^^^^^^ you might be missing a crate named `nonexistent` | = help: consider adding `extern crate nonexistent` to use the `nonexistent` crate -error[E0433]: failed to resolve: maybe a missing crate `too_soon`? +error[E0433]: cannot find item `too_soon` in this scope --> $DIR/resolve-bad-visibility.rs:8:8 | LL | pub(in too_soon) struct H; - | ^^^^^^^^ maybe a missing crate `too_soon`? + | ^^^^^^^^ you might be missing a crate named `too_soon` | = help: consider adding `extern crate too_soon` to use the `too_soon` crate diff --git a/tests/ui/resolve/resolve-variant-assoc-item.rs b/tests/ui/resolve/resolve-variant-assoc-item.rs index db4fedfb0bdf8..8bc294a7f4b7d 100644 --- a/tests/ui/resolve/resolve-variant-assoc-item.rs +++ b/tests/ui/resolve/resolve-variant-assoc-item.rs @@ -2,6 +2,6 @@ enum E { V } use E::V; fn main() { - E::V::associated_item; //~ ERROR failed to resolve: `V` is a variant, not a module - V::associated_item; //~ ERROR failed to resolve: `V` is a variant, not a module + E::V::associated_item; //~ ERROR cannot find module `V` + V::associated_item; //~ ERROR cannot find module `V` } diff --git a/tests/ui/resolve/resolve-variant-assoc-item.stderr b/tests/ui/resolve/resolve-variant-assoc-item.stderr index ed157197d17e1..9508c7412ff2b 100644 --- a/tests/ui/resolve/resolve-variant-assoc-item.stderr +++ b/tests/ui/resolve/resolve-variant-assoc-item.stderr @@ -1,4 +1,4 @@ -error[E0433]: failed to resolve: `V` is a variant, not a module +error[E0433]: cannot find module `V` in enum `E` --> $DIR/resolve-variant-assoc-item.rs:5:8 | LL | E::V::associated_item; @@ -9,7 +9,7 @@ help: there is an enum variant `E::V`; try using the variant's enum LL | E; | ~ -error[E0433]: failed to resolve: `V` is a variant, not a module +error[E0433]: cannot find module `V` in this scope --> $DIR/resolve-variant-assoc-item.rs:6:5 | LL | V::associated_item; diff --git a/tests/ui/resolve/tool-import.rs b/tests/ui/resolve/tool-import.rs index bde375a2c490e..fadb963682fb9 100644 --- a/tests/ui/resolve/tool-import.rs +++ b/tests/ui/resolve/tool-import.rs @@ -1,7 +1,8 @@ //@ edition: 2018 use clippy::time::Instant; -//~^ `clippy` is a tool module +//~^ ERROR cannot find module `clippy` +//~| NOTE `clippy` is a tool module fn main() { Instant::now(); diff --git a/tests/ui/resolve/tool-import.stderr b/tests/ui/resolve/tool-import.stderr index b070439d72b77..02e4432fd9e56 100644 --- a/tests/ui/resolve/tool-import.stderr +++ b/tests/ui/resolve/tool-import.stderr @@ -1,4 +1,4 @@ -error[E0433]: failed to resolve: `clippy` is a tool module, not a module +error[E0433]: cannot find module `clippy` in this scope --> $DIR/tool-import.rs:3:5 | LL | use clippy::time::Instant; diff --git a/tests/ui/resolve/typo-suggestion-mistyped-in-path.rs b/tests/ui/resolve/typo-suggestion-mistyped-in-path.rs index 3ce17a14f146b..bede336f1216f 100644 --- a/tests/ui/resolve/typo-suggestion-mistyped-in-path.rs +++ b/tests/ui/resolve/typo-suggestion-mistyped-in-path.rs @@ -25,18 +25,18 @@ fn main() { //~| NOTE function or associated item not found in `Struct` Struc::foo(); - //~^ ERROR failed to resolve: use of undeclared type `Struc` + //~^ ERROR cannot find item `Struc` //~| NOTE use of undeclared type `Struc` modul::foo(); - //~^ ERROR failed to resolve: use of undeclared crate or module `modul` + //~^ ERROR cannot find item `modul` //~| NOTE use of undeclared crate or module `modul` module::Struc::foo(); - //~^ ERROR failed to resolve: could not find `Struc` in `module` + //~^ ERROR cannot find item `Struc` //~| NOTE could not find `Struc` in `module` Trai::foo(); - //~^ ERROR failed to resolve: use of undeclared type `Trai` + //~^ ERROR cannot find item `Trai` //~| NOTE use of undeclared type `Trai` } diff --git a/tests/ui/resolve/typo-suggestion-mistyped-in-path.stderr b/tests/ui/resolve/typo-suggestion-mistyped-in-path.stderr index f4fb7fd955f2b..d54450e769525 100644 --- a/tests/ui/resolve/typo-suggestion-mistyped-in-path.stderr +++ b/tests/ui/resolve/typo-suggestion-mistyped-in-path.stderr @@ -1,4 +1,4 @@ -error[E0433]: failed to resolve: could not find `Struc` in `module` +error[E0433]: cannot find item `Struc` in module `module` --> $DIR/typo-suggestion-mistyped-in-path.rs:35:13 | LL | module::Struc::foo(); @@ -21,7 +21,7 @@ help: there is an associated function `foo` with a similar name LL | Struct::foo(); | ~~~ -error[E0433]: failed to resolve: use of undeclared type `Struc` +error[E0433]: cannot find item `Struc` in this scope --> $DIR/typo-suggestion-mistyped-in-path.rs:27:5 | LL | Struc::foo(); @@ -30,7 +30,7 @@ LL | Struc::foo(); | use of undeclared type `Struc` | help: a struct with a similar name exists: `Struct` -error[E0433]: failed to resolve: use of undeclared crate or module `modul` +error[E0433]: cannot find item `modul` in this scope --> $DIR/typo-suggestion-mistyped-in-path.rs:31:5 | LL | modul::foo(); @@ -41,7 +41,7 @@ help: there is a crate or module with a similar name LL | module::foo(); | ~~~~~~ -error[E0433]: failed to resolve: use of undeclared type `Trai` +error[E0433]: cannot find item `Trai` in this scope --> $DIR/typo-suggestion-mistyped-in-path.rs:39:5 | LL | Trai::foo(); diff --git a/tests/ui/resolve/unresolved-segments-visibility.rs b/tests/ui/resolve/unresolved-segments-visibility.rs index c26171f75d2ca..3c6b5a52da588 100644 --- a/tests/ui/resolve/unresolved-segments-visibility.rs +++ b/tests/ui/resolve/unresolved-segments-visibility.rs @@ -6,6 +6,6 @@ extern crate alloc as b; mod foo { mod bar { pub(in b::string::String::newy) extern crate alloc as e; - //~^ ERROR failed to resolve: `String` is a struct, not a module [E0433] + //~^ ERROR cannot find module `String` } } diff --git a/tests/ui/resolve/unresolved-segments-visibility.stderr b/tests/ui/resolve/unresolved-segments-visibility.stderr index 09f3c50258d93..065c9a13e0e40 100644 --- a/tests/ui/resolve/unresolved-segments-visibility.stderr +++ b/tests/ui/resolve/unresolved-segments-visibility.stderr @@ -1,4 +1,4 @@ -error[E0433]: failed to resolve: `String` is a struct, not a module +error[E0433]: cannot find module `String` in this scope --> $DIR/unresolved-segments-visibility.rs:8:27 | LL | pub(in b::string::String::newy) extern crate alloc as e; diff --git a/tests/ui/resolve/use_suggestion.rs b/tests/ui/resolve/use_suggestion.rs index 8c9bc6d76b8b2..9a513d08ba49b 100644 --- a/tests/ui/resolve/use_suggestion.rs +++ b/tests/ui/resolve/use_suggestion.rs @@ -1,6 +1,6 @@ fn main() { - let x1 = HashMap::new(); //~ ERROR failed to resolve - let x2 = GooMap::new(); //~ ERROR failed to resolve + let x1 = HashMap::new(); //~ ERROR cannot find item `HashMap` + let x2 = GooMap::new(); //~ ERROR cannot find item `GooMap` let y1: HashMap; //~ ERROR cannot find type let y2: GooMap; //~ ERROR cannot find type diff --git a/tests/ui/resolve/use_suggestion.stderr b/tests/ui/resolve/use_suggestion.stderr index 1155f5caa1739..811f53e763fdd 100644 --- a/tests/ui/resolve/use_suggestion.stderr +++ b/tests/ui/resolve/use_suggestion.stderr @@ -1,4 +1,4 @@ -error[E0433]: failed to resolve: use of undeclared type `HashMap` +error[E0433]: cannot find item `HashMap` in this scope --> $DIR/use_suggestion.rs:2:14 | LL | let x1 = HashMap::new(); @@ -26,7 +26,7 @@ error[E0412]: cannot find type `GooMap` in this scope LL | let y2: GooMap; | ^^^^^^ not found in this scope -error[E0433]: failed to resolve: use of undeclared type `GooMap` +error[E0433]: cannot find item `GooMap` in this scope --> $DIR/use_suggestion.rs:3:14 | LL | let x2 = GooMap::new(); diff --git a/tests/ui/rfcs/rfc-2126-crate-paths/crate-path-non-absolute.rs b/tests/ui/rfcs/rfc-2126-crate-paths/crate-path-non-absolute.rs index 79f6b0dfe34ee..a307781f0baee 100644 --- a/tests/ui/rfcs/rfc-2126-crate-paths/crate-path-non-absolute.rs +++ b/tests/ui/rfcs/rfc-2126-crate-paths/crate-path-non-absolute.rs @@ -2,8 +2,8 @@ struct S; pub mod m { fn f() { - let s = ::m::crate::S; //~ ERROR failed to resolve - let s1 = ::crate::S; //~ ERROR failed to resolve + let s = ::m::crate::S; //~ ERROR cannot find module `crate` + let s1 = ::crate::S; //~ ERROR cannot find module `crate` let s2 = crate::S; // no error } } diff --git a/tests/ui/rfcs/rfc-2126-crate-paths/crate-path-non-absolute.stderr b/tests/ui/rfcs/rfc-2126-crate-paths/crate-path-non-absolute.stderr index 7e7ee3ce03d77..8f44a98aecea5 100644 --- a/tests/ui/rfcs/rfc-2126-crate-paths/crate-path-non-absolute.stderr +++ b/tests/ui/rfcs/rfc-2126-crate-paths/crate-path-non-absolute.stderr @@ -1,10 +1,10 @@ -error[E0433]: failed to resolve: `crate` in paths can only be used in start position +error[E0433]: cannot find module `crate` in module `m` --> $DIR/crate-path-non-absolute.rs:5:22 | LL | let s = ::m::crate::S; | ^^^^^ `crate` in paths can only be used in start position -error[E0433]: failed to resolve: global paths cannot start with `crate` +error[E0433]: cannot find module `crate` in the crate root --> $DIR/crate-path-non-absolute.rs:6:20 | LL | let s1 = ::crate::S; diff --git a/tests/ui/rfcs/rfc-2126-extern-absolute-paths/non-existent-2.rs b/tests/ui/rfcs/rfc-2126-extern-absolute-paths/non-existent-2.rs index 6bbfb69800e11..13fc896a4d7fa 100644 --- a/tests/ui/rfcs/rfc-2126-extern-absolute-paths/non-existent-2.rs +++ b/tests/ui/rfcs/rfc-2126-extern-absolute-paths/non-existent-2.rs @@ -2,5 +2,5 @@ fn main() { let s = ::xcrate::S; - //~^ ERROR failed to resolve: could not find `xcrate` in the list of imported crates + //~^ ERROR cannot find item `xcrate` } diff --git a/tests/ui/rfcs/rfc-2126-extern-absolute-paths/non-existent-2.stderr b/tests/ui/rfcs/rfc-2126-extern-absolute-paths/non-existent-2.stderr index e3875fd843b62..cc0cf75b32d69 100644 --- a/tests/ui/rfcs/rfc-2126-extern-absolute-paths/non-existent-2.stderr +++ b/tests/ui/rfcs/rfc-2126-extern-absolute-paths/non-existent-2.stderr @@ -1,4 +1,4 @@ -error[E0433]: failed to resolve: could not find `xcrate` in the list of imported crates +error[E0433]: cannot find item `xcrate` in the list of imported crates --> $DIR/non-existent-2.rs:4:15 | LL | let s = ::xcrate::S; diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-102156.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-102156.stderr index c331236a4601c..1892394d7f959 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-102156.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-102156.stderr @@ -1,19 +1,19 @@ -error[E0433]: failed to resolve: maybe a missing crate `core`? +error[E0433]: cannot find item `core` in the crate root --> $DIR/issue-102156.rs:4:5 | LL | use core::convert::{From, TryFrom}; | ^^^^ | | - | maybe a missing crate `core`? + | you might be missing a crate named `core` | help: try using `std` instead of `core`: `std` -error[E0433]: failed to resolve: maybe a missing crate `core`? +error[E0433]: cannot find item `core` in the crate root --> $DIR/issue-102156.rs:4:5 | LL | use core::convert::{From, TryFrom}; | ^^^^ | | - | maybe a missing crate `core`? + | you might be missing a crate named `core` | help: try using `std` instead of `core`: `std` | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` diff --git a/tests/ui/simd/portable-intrinsics-arent-exposed.stderr b/tests/ui/simd/portable-intrinsics-arent-exposed.stderr index a6f27af428b51..113d64792407d 100644 --- a/tests/ui/simd/portable-intrinsics-arent-exposed.stderr +++ b/tests/ui/simd/portable-intrinsics-arent-exposed.stderr @@ -1,10 +1,10 @@ -error[E0433]: failed to resolve: maybe a missing crate `core`? +error[E0433]: cannot find item `core` in the crate root --> $DIR/portable-intrinsics-arent-exposed.rs:4:5 | LL | use core::simd::intrinsics; | ^^^^ | | - | maybe a missing crate `core`? + | you might be missing a crate named `core` | help: try using `std` instead of `core`: `std` error[E0432]: unresolved import `std::simd::intrinsics` diff --git a/tests/ui/span/visibility-ty-params.rs b/tests/ui/span/visibility-ty-params.rs index 11c2cf44cb459..22e786a3169cf 100644 --- a/tests/ui/span/visibility-ty-params.rs +++ b/tests/ui/span/visibility-ty-params.rs @@ -4,7 +4,7 @@ macro_rules! m { struct S(T); m!{ S } //~ ERROR unexpected generic arguments in path - //~| ERROR failed to resolve: `S` is a struct, not a module [E0433] + //~| ERROR cannot find module `S` mod m { m!{ m<> } //~ ERROR unexpected generic arguments in path diff --git a/tests/ui/span/visibility-ty-params.stderr b/tests/ui/span/visibility-ty-params.stderr index 97d05c4644e82..abd171f80a443 100644 --- a/tests/ui/span/visibility-ty-params.stderr +++ b/tests/ui/span/visibility-ty-params.stderr @@ -4,7 +4,7 @@ error: unexpected generic arguments in path LL | m!{ S } | ^^^^ -error[E0433]: failed to resolve: `S` is a struct, not a module +error[E0433]: cannot find module `S` in this scope --> $DIR/visibility-ty-params.rs:6:5 | LL | m!{ S } diff --git a/tests/ui/suggestions/core-std-import-order-issue-83564.no_std.fixed b/tests/ui/suggestions/core-std-import-order-issue-83564.no_std.fixed index 02d667d984421..559ea90f6dd0d 100644 --- a/tests/ui/suggestions/core-std-import-order-issue-83564.no_std.fixed +++ b/tests/ui/suggestions/core-std-import-order-issue-83564.no_std.fixed @@ -12,7 +12,7 @@ use core::num::NonZero; fn main() { //~^ HELP consider importing this struct let _x = NonZero::new(5u32).unwrap(); - //~^ ERROR failed to resolve: use of undeclared type `NonZero` + //~^ ERROR cannot find item `NonZero` } #[allow(dead_code)] diff --git a/tests/ui/suggestions/core-std-import-order-issue-83564.no_std.stderr b/tests/ui/suggestions/core-std-import-order-issue-83564.no_std.stderr index d73f613bf9c8a..2d14a483e9446 100644 --- a/tests/ui/suggestions/core-std-import-order-issue-83564.no_std.stderr +++ b/tests/ui/suggestions/core-std-import-order-issue-83564.no_std.stderr @@ -1,4 +1,4 @@ -error[E0433]: failed to resolve: use of undeclared type `NonZero` +error[E0433]: cannot find item `NonZero` in this scope --> $DIR/core-std-import-order-issue-83564.rs:12:14 | LL | let _x = NonZero::new(5u32).unwrap(); diff --git a/tests/ui/suggestions/core-std-import-order-issue-83564.rs b/tests/ui/suggestions/core-std-import-order-issue-83564.rs index 5bb5bfe176ba8..7da0f1a275f79 100644 --- a/tests/ui/suggestions/core-std-import-order-issue-83564.rs +++ b/tests/ui/suggestions/core-std-import-order-issue-83564.rs @@ -10,7 +10,7 @@ fn main() { //~^ HELP consider importing this struct let _x = NonZero::new(5u32).unwrap(); - //~^ ERROR failed to resolve: use of undeclared type `NonZero` + //~^ ERROR cannot find item `NonZero` } #[allow(dead_code)] diff --git a/tests/ui/suggestions/core-std-import-order-issue-83564.std.fixed b/tests/ui/suggestions/core-std-import-order-issue-83564.std.fixed index 3492b42c685f9..020382c396b33 100644 --- a/tests/ui/suggestions/core-std-import-order-issue-83564.std.fixed +++ b/tests/ui/suggestions/core-std-import-order-issue-83564.std.fixed @@ -12,7 +12,7 @@ use std::num::NonZero; fn main() { //~^ HELP consider importing this struct let _x = NonZero::new(5u32).unwrap(); - //~^ ERROR failed to resolve: use of undeclared type `NonZero` + //~^ ERROR cannot find item `NonZero` } #[allow(dead_code)] diff --git a/tests/ui/suggestions/core-std-import-order-issue-83564.std.stderr b/tests/ui/suggestions/core-std-import-order-issue-83564.std.stderr index ebfe197b45d69..8b299321042f3 100644 --- a/tests/ui/suggestions/core-std-import-order-issue-83564.std.stderr +++ b/tests/ui/suggestions/core-std-import-order-issue-83564.std.stderr @@ -1,4 +1,4 @@ -error[E0433]: failed to resolve: use of undeclared type `NonZero` +error[E0433]: cannot find item `NonZero` in this scope --> $DIR/core-std-import-order-issue-83564.rs:12:14 | LL | let _x = NonZero::new(5u32).unwrap(); diff --git a/tests/ui/suggestions/crate-or-module-typo.rs b/tests/ui/suggestions/crate-or-module-typo.rs index dbc0605c76bce..eb8f95ebe3927 100644 --- a/tests/ui/suggestions/crate-or-module-typo.rs +++ b/tests/ui/suggestions/crate-or-module-typo.rs @@ -1,9 +1,9 @@ //@ edition:2018 -use st::cell::Cell; //~ ERROR failed to resolve: use of undeclared crate or module `st` +use st::cell::Cell; //~ ERROR cannot find item `st` mod bar { - pub fn bar() { bar::baz(); } //~ ERROR failed to resolve: function `bar` is not a crate or module + pub fn bar() { bar::baz(); } //~ ERROR cannot find item `bar` fn baz() {} } @@ -11,7 +11,7 @@ mod bar { use bas::bar; //~ ERROR unresolved import `bas` struct Foo { - bar: st::cell::Cell //~ ERROR failed to resolve: use of undeclared crate or module `st` + bar: st::cell::Cell //~ ERROR cannot find item `st` } fn main() {} diff --git a/tests/ui/suggestions/crate-or-module-typo.stderr b/tests/ui/suggestions/crate-or-module-typo.stderr index 084d0408a8e7d..109fc79d8793e 100644 --- a/tests/ui/suggestions/crate-or-module-typo.stderr +++ b/tests/ui/suggestions/crate-or-module-typo.stderr @@ -1,4 +1,4 @@ -error[E0433]: failed to resolve: use of undeclared crate or module `st` +error[E0433]: cannot find item `st` in this scope --> $DIR/crate-or-module-typo.rs:3:5 | LL | use st::cell::Cell; @@ -20,7 +20,7 @@ help: there is a crate or module with a similar name LL | use bar::bar; | ~~~ -error[E0433]: failed to resolve: use of undeclared crate or module `st` +error[E0433]: cannot find item `st` in this scope --> $DIR/crate-or-module-typo.rs:14:10 | LL | bar: st::cell::Cell @@ -40,7 +40,7 @@ LL - bar: st::cell::Cell LL + bar: cell::Cell | -error[E0433]: failed to resolve: function `bar` is not a crate or module +error[E0433]: cannot find item `bar` in this scope --> $DIR/crate-or-module-typo.rs:6:20 | LL | pub fn bar() { bar::baz(); } diff --git a/tests/ui/suggestions/issue-103112.rs b/tests/ui/suggestions/issue-103112.rs index 111ae7c73080d..906e7332d11cc 100644 --- a/tests/ui/suggestions/issue-103112.rs +++ b/tests/ui/suggestions/issue-103112.rs @@ -1,4 +1,4 @@ fn main() { std::process::abort!(); - //~^ ERROR: failed to resolve + //~^ ERROR: cannot find macro `abort` } diff --git a/tests/ui/suggestions/issue-103112.stderr b/tests/ui/suggestions/issue-103112.stderr index b7de57bfd90ed..b0b2beaf545f8 100644 --- a/tests/ui/suggestions/issue-103112.stderr +++ b/tests/ui/suggestions/issue-103112.stderr @@ -1,4 +1,4 @@ -error[E0433]: failed to resolve: could not find `abort` in `process` +error[E0433]: cannot find macro `abort` in module `process` --> $DIR/issue-103112.rs:2:19 | LL | std::process::abort!(); diff --git a/tests/ui/suggestions/issue-112590-suggest-import.rs b/tests/ui/suggestions/issue-112590-suggest-import.rs index 0938814c55985..6dfb785275576 100644 --- a/tests/ui/suggestions/issue-112590-suggest-import.rs +++ b/tests/ui/suggestions/issue-112590-suggest-import.rs @@ -1,8 +1,8 @@ pub struct S; -impl fmt::Debug for S { //~ ERROR failed to resolve: use of undeclared crate or module `fmt` - fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result { //~ ERROR failed to resolve: use of undeclared crate or module `fmt` - //~^ ERROR failed to resolve: use of undeclared crate or module `fmt` +impl fmt::Debug for S { //~ ERROR cannot find item `fmt` + fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result { //~ ERROR cannot find item `fmt` + //~^ ERROR cannot find item `fmt` Ok(()) } } diff --git a/tests/ui/suggestions/issue-112590-suggest-import.stderr b/tests/ui/suggestions/issue-112590-suggest-import.stderr index aeac18c16f047..4c9022d313bfa 100644 --- a/tests/ui/suggestions/issue-112590-suggest-import.stderr +++ b/tests/ui/suggestions/issue-112590-suggest-import.stderr @@ -1,4 +1,4 @@ -error[E0433]: failed to resolve: use of undeclared crate or module `fmt` +error[E0433]: cannot find item `fmt` in this scope --> $DIR/issue-112590-suggest-import.rs:3:6 | LL | impl fmt::Debug for S { @@ -9,7 +9,7 @@ help: consider importing this module LL + use std::fmt; | -error[E0433]: failed to resolve: use of undeclared crate or module `fmt` +error[E0433]: cannot find item `fmt` in this scope --> $DIR/issue-112590-suggest-import.rs:4:28 | LL | fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result { @@ -20,7 +20,7 @@ help: consider importing this module LL + use std::fmt; | -error[E0433]: failed to resolve: use of undeclared crate or module `fmt` +error[E0433]: cannot find item `fmt` in this scope --> $DIR/issue-112590-suggest-import.rs:4:51 | LL | fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result { diff --git a/tests/ui/suggestions/suggest-tryinto-edition-change.rs b/tests/ui/suggestions/suggest-tryinto-edition-change.rs index f45670ae7c1e2..2ea224ced3c89 100644 --- a/tests/ui/suggestions/suggest-tryinto-edition-change.rs +++ b/tests/ui/suggestions/suggest-tryinto-edition-change.rs @@ -4,21 +4,21 @@ fn test() { let _i: i16 = 0_i32.try_into().unwrap(); - //~^ ERROR no method named `try_into` found for type `i32` in the current scope + // //~^ ERROR no method named `try_into` found for type `i32` in the current scope //~| NOTE 'std::convert::TryInto' is included in the prelude starting in Edition 2021 let _i: i16 = TryFrom::try_from(0_i32).unwrap(); - //~^ ERROR failed to resolve: use of undeclared type + //~^ ERROR cannot find item `TryFrom` //~| NOTE use of undeclared type //~| NOTE 'std::convert::TryFrom' is included in the prelude starting in Edition 2021 let _i: i16 = TryInto::try_into(0_i32).unwrap(); - //~^ ERROR failed to resolve: use of undeclared type + //~^ ERROR cannot find item `TryInto` //~| NOTE use of undeclared type //~| NOTE 'std::convert::TryInto' is included in the prelude starting in Edition 2021 let _v: Vec<_> = FromIterator::from_iter(&[1]); - //~^ ERROR failed to resolve: use of undeclared type + //~^ ERROR cannot find item `FromIterator` //~| NOTE use of undeclared type //~| NOTE 'std::iter::FromIterator' is included in the prelude starting in Edition 2021 } diff --git a/tests/ui/suggestions/suggest-tryinto-edition-change.stderr b/tests/ui/suggestions/suggest-tryinto-edition-change.stderr index 5be55f75cd15d..396fd1f4e5492 100644 --- a/tests/ui/suggestions/suggest-tryinto-edition-change.stderr +++ b/tests/ui/suggestions/suggest-tryinto-edition-change.stderr @@ -1,4 +1,4 @@ -error[E0433]: failed to resolve: use of undeclared type `TryFrom` +error[E0433]: cannot find item `TryFrom` in this scope --> $DIR/suggest-tryinto-edition-change.rs:10:19 | LL | let _i: i16 = TryFrom::try_from(0_i32).unwrap(); @@ -10,7 +10,7 @@ help: consider importing this trait LL + use std::convert::TryFrom; | -error[E0433]: failed to resolve: use of undeclared type `TryInto` +error[E0433]: cannot find item `TryInto` in this scope --> $DIR/suggest-tryinto-edition-change.rs:15:19 | LL | let _i: i16 = TryInto::try_into(0_i32).unwrap(); @@ -22,7 +22,7 @@ help: consider importing this trait LL + use std::convert::TryInto; | -error[E0433]: failed to resolve: use of undeclared type `FromIterator` +error[E0433]: cannot find item `FromIterator` in this scope --> $DIR/suggest-tryinto-edition-change.rs:20:22 | LL | let _v: Vec<_> = FromIterator::from_iter(&[1]); diff --git a/tests/ui/suggestions/undeclared-module-alloc.rs b/tests/ui/suggestions/undeclared-module-alloc.rs index e5f22369b941a..84c5fc491bffc 100644 --- a/tests/ui/suggestions/undeclared-module-alloc.rs +++ b/tests/ui/suggestions/undeclared-module-alloc.rs @@ -1,5 +1,5 @@ //@ edition:2018 -use alloc::rc::Rc; //~ ERROR failed to resolve: use of undeclared crate or module `alloc` +use alloc::rc::Rc; //~ ERROR cannot find item `alloc` fn main() {} diff --git a/tests/ui/suggestions/undeclared-module-alloc.stderr b/tests/ui/suggestions/undeclared-module-alloc.stderr index a439546492b5f..2acb4f412b47e 100644 --- a/tests/ui/suggestions/undeclared-module-alloc.stderr +++ b/tests/ui/suggestions/undeclared-module-alloc.stderr @@ -1,4 +1,4 @@ -error[E0433]: failed to resolve: use of undeclared crate or module `alloc` +error[E0433]: cannot find item `alloc` in this scope --> $DIR/undeclared-module-alloc.rs:3:5 | LL | use alloc::rc::Rc; diff --git a/tests/ui/super-at-top-level.rs b/tests/ui/super-at-top-level.rs index e4d587bc9effa..ae1e70050a5c7 100644 --- a/tests/ui/super-at-top-level.rs +++ b/tests/ui/super-at-top-level.rs @@ -1,4 +1,5 @@ -use super::f; //~ ERROR there are too many leading `super` keywords +use super::f; //~ ERROR cannot find module `super` + //~| NOTE can't use `super` on the crate root fn main() { } diff --git a/tests/ui/super-at-top-level.stderr b/tests/ui/super-at-top-level.stderr index 4dce81fbef43f..e86e973990612 100644 --- a/tests/ui/super-at-top-level.stderr +++ b/tests/ui/super-at-top-level.stderr @@ -1,8 +1,8 @@ -error[E0433]: failed to resolve: there are too many leading `super` keywords +error[E0433]: cannot find module `super` in this scope --> $DIR/super-at-top-level.rs:1:5 | LL | use super::f; - | ^^^^^ there are too many leading `super` keywords + | ^^^^^ can't use `super` on the crate root, there are no further modules to go "up" to error: aborting due to 1 previous error diff --git a/tests/ui/tool-attributes/tool-attributes-shadowing.rs b/tests/ui/tool-attributes/tool-attributes-shadowing.rs index 21bbaa3a7105d..1353edaa60165 100644 --- a/tests/ui/tool-attributes/tool-attributes-shadowing.rs +++ b/tests/ui/tool-attributes/tool-attributes-shadowing.rs @@ -1,4 +1,4 @@ mod rustfmt {} -#[rustfmt::skip] //~ ERROR failed to resolve: could not find `skip` in `rustfmt` +#[rustfmt::skip] //~ ERROR cannot find macro `skip` fn main() {} diff --git a/tests/ui/tool-attributes/tool-attributes-shadowing.stderr b/tests/ui/tool-attributes/tool-attributes-shadowing.stderr index f2da617272288..9314d42158da6 100644 --- a/tests/ui/tool-attributes/tool-attributes-shadowing.stderr +++ b/tests/ui/tool-attributes/tool-attributes-shadowing.stderr @@ -1,4 +1,4 @@ -error[E0433]: failed to resolve: could not find `skip` in `rustfmt` +error[E0433]: cannot find macro `skip` in module `rustfmt` --> $DIR/tool-attributes-shadowing.rs:3:12 | LL | #[rustfmt::skip] diff --git a/tests/ui/tool-attributes/unknown-tool-name.rs b/tests/ui/tool-attributes/unknown-tool-name.rs index 73fca61c65d1b..05b3b05593712 100644 --- a/tests/ui/tool-attributes/unknown-tool-name.rs +++ b/tests/ui/tool-attributes/unknown-tool-name.rs @@ -1,2 +1,2 @@ -#[foo::bar] //~ ERROR failed to resolve: use of undeclared crate or module `foo` +#[foo::bar] //~ ERROR cannot find item `foo` fn main() {} diff --git a/tests/ui/tool-attributes/unknown-tool-name.stderr b/tests/ui/tool-attributes/unknown-tool-name.stderr index 361d359a10e47..e113aed48d04d 100644 --- a/tests/ui/tool-attributes/unknown-tool-name.stderr +++ b/tests/ui/tool-attributes/unknown-tool-name.stderr @@ -1,4 +1,4 @@ -error[E0433]: failed to resolve: use of undeclared crate or module `foo` +error[E0433]: cannot find item `foo` in this scope --> $DIR/unknown-tool-name.rs:1:3 | LL | #[foo::bar] diff --git a/tests/ui/type-alias/issue-62263-self-in-atb.rs b/tests/ui/type-alias/issue-62263-self-in-atb.rs index 91522d8912f79..6af8670c1ac95 100644 --- a/tests/ui/type-alias/issue-62263-self-in-atb.rs +++ b/tests/ui/type-alias/issue-62263-self-in-atb.rs @@ -3,6 +3,6 @@ pub trait Trait { } pub type Alias = dyn Trait; -//~^ ERROR failed to resolve: `Self` +//~^ ERROR cannot find item `Self` fn main() {} diff --git a/tests/ui/type-alias/issue-62263-self-in-atb.stderr b/tests/ui/type-alias/issue-62263-self-in-atb.stderr index 18c8bc1a1b361..f983a5abc2e73 100644 --- a/tests/ui/type-alias/issue-62263-self-in-atb.stderr +++ b/tests/ui/type-alias/issue-62263-self-in-atb.stderr @@ -1,4 +1,4 @@ -error[E0433]: failed to resolve: `Self` is only available in impls, traits, and type definitions +error[E0433]: cannot find item `Self` in this scope --> $DIR/issue-62263-self-in-atb.rs:5:32 | LL | pub type Alias = dyn Trait; diff --git a/tests/ui/type-alias/issue-62305-self-assoc-ty.rs b/tests/ui/type-alias/issue-62305-self-assoc-ty.rs index a4d9a285485e7..56a81f1cdc409 100644 --- a/tests/ui/type-alias/issue-62305-self-assoc-ty.rs +++ b/tests/ui/type-alias/issue-62305-self-assoc-ty.rs @@ -1,4 +1,4 @@ type Alias = Self::Target; -//~^ ERROR failed to resolve: `Self` +//~^ ERROR cannot find item `Self` fn main() {} diff --git a/tests/ui/type-alias/issue-62305-self-assoc-ty.stderr b/tests/ui/type-alias/issue-62305-self-assoc-ty.stderr index a35e644d3aa89..471076336f59d 100644 --- a/tests/ui/type-alias/issue-62305-self-assoc-ty.stderr +++ b/tests/ui/type-alias/issue-62305-self-assoc-ty.stderr @@ -1,4 +1,4 @@ -error[E0433]: failed to resolve: `Self` is only available in impls, traits, and type definitions +error[E0433]: cannot find item `Self` in this scope --> $DIR/issue-62305-self-assoc-ty.rs:1:14 | LL | type Alias = Self::Target; diff --git a/tests/ui/type/type-path-err-node-types.rs b/tests/ui/type/type-path-err-node-types.rs index c3a61b1ceda56..84eb0d7401b2c 100644 --- a/tests/ui/type/type-path-err-node-types.rs +++ b/tests/ui/type/type-path-err-node-types.rs @@ -12,7 +12,7 @@ fn ufcs_trait() { } fn ufcs_item() { - NonExistent::Assoc::; //~ ERROR undeclared type `NonExistent` + NonExistent::Assoc::; //~ ERROR cannot find item `NonExistent` } fn method() { diff --git a/tests/ui/type/type-path-err-node-types.stderr b/tests/ui/type/type-path-err-node-types.stderr index bd5c5e20c245c..2b7f75c8f35dc 100644 --- a/tests/ui/type/type-path-err-node-types.stderr +++ b/tests/ui/type/type-path-err-node-types.stderr @@ -16,7 +16,7 @@ error[E0425]: cannot find value `nonexistent` in this scope LL | nonexistent.nonexistent::(); | ^^^^^^^^^^^ not found in this scope -error[E0433]: failed to resolve: use of undeclared type `NonExistent` +error[E0433]: cannot find item `NonExistent` in this scope --> $DIR/type-path-err-node-types.rs:15:5 | LL | NonExistent::Assoc::; diff --git a/tests/ui/typeck/issue-120856.rs b/tests/ui/typeck/issue-120856.rs index e435a0f9d8e89..9900a5191ae0b 100644 --- a/tests/ui/typeck/issue-120856.rs +++ b/tests/ui/typeck/issue-120856.rs @@ -1,5 +1,7 @@ pub type Archived = ::Archived; -//~^ ERROR failed to resolve: use of undeclared crate or module `m` -//~| ERROR failed to resolve: use of undeclared crate or module `n` +//~^ ERROR cannot find item `m` +//~| NOTE use of undeclared crate or module `m` +//~| ERROR cannot find item `n` +//~| NOTE use of undeclared crate or module `n` fn main() {} diff --git a/tests/ui/typeck/issue-120856.stderr b/tests/ui/typeck/issue-120856.stderr index 1fc8b20047355..7ce04c96221a8 100644 --- a/tests/ui/typeck/issue-120856.stderr +++ b/tests/ui/typeck/issue-120856.stderr @@ -1,4 +1,4 @@ -error[E0433]: failed to resolve: use of undeclared crate or module `n` +error[E0433]: cannot find item `n` in this scope --> $DIR/issue-120856.rs:1:37 | LL | pub type Archived = ::Archived; @@ -7,7 +7,7 @@ LL | pub type Archived = ::Archived; | use of undeclared crate or module `n` | help: a trait with a similar name exists: `Fn` -error[E0433]: failed to resolve: use of undeclared crate or module `m` +error[E0433]: cannot find item `m` in this scope --> $DIR/issue-120856.rs:1:25 | LL | pub type Archived = ::Archived; diff --git a/tests/ui/typeck/path-to-method-sugg-unresolved-expr.rs b/tests/ui/typeck/path-to-method-sugg-unresolved-expr.rs index fb56b394493dc..f355accfcffe9 100644 --- a/tests/ui/typeck/path-to-method-sugg-unresolved-expr.rs +++ b/tests/ui/typeck/path-to-method-sugg-unresolved-expr.rs @@ -1,4 +1,5 @@ fn main() { let page_size = page_size::get(); - //~^ ERROR failed to resolve: use of undeclared crate or module `page_size` + //~^ ERROR cannot find item `page_size` + //~| NOTE use of undeclared crate or module `page_size` } diff --git a/tests/ui/typeck/path-to-method-sugg-unresolved-expr.stderr b/tests/ui/typeck/path-to-method-sugg-unresolved-expr.stderr index 3e03c17f3b1c3..e61520f981a80 100644 --- a/tests/ui/typeck/path-to-method-sugg-unresolved-expr.stderr +++ b/tests/ui/typeck/path-to-method-sugg-unresolved-expr.stderr @@ -1,4 +1,4 @@ -error[E0433]: failed to resolve: use of undeclared crate or module `page_size` +error[E0433]: cannot find item `page_size` in this scope --> $DIR/path-to-method-sugg-unresolved-expr.rs:2:21 | LL | let page_size = page_size::get(); diff --git a/tests/ui/underscore-imports/issue-110164.stderr b/tests/ui/underscore-imports/issue-110164.stderr index 5016c41e8a579..c6fe13b901f6e 100644 --- a/tests/ui/underscore-imports/issue-110164.stderr +++ b/tests/ui/underscore-imports/issue-110164.stderr @@ -38,7 +38,7 @@ error[E0432]: unresolved import `_` --> $DIR/issue-110164.rs:8:5 | LL | use _::*; - | ^ maybe a missing crate `_`? + | ^ you might be missing a crate named `_` | = help: consider adding `extern crate _` to use the `_` crate @@ -46,7 +46,7 @@ error[E0432]: unresolved import `_` --> $DIR/issue-110164.rs:5:5 | LL | use _::a; - | ^ maybe a missing crate `_`? + | ^ you might be missing a crate named `_` | = help: consider adding `extern crate _` to use the `_` crate @@ -54,7 +54,7 @@ error[E0432]: unresolved import `_` --> $DIR/issue-110164.rs:13:9 | LL | use _::a; - | ^ maybe a missing crate `_`? + | ^ you might be missing a crate named `_` | = help: consider adding `extern crate _` to use the `_` crate @@ -62,7 +62,7 @@ error[E0432]: unresolved import `_` --> $DIR/issue-110164.rs:16:9 | LL | use _::*; - | ^ maybe a missing crate `_`? + | ^ you might be missing a crate named `_` | = help: consider adding `extern crate _` to use the `_` crate diff --git a/tests/ui/unresolved/unresolved-asterisk-imports.stderr b/tests/ui/unresolved/unresolved-asterisk-imports.stderr index 24ac2f8e6213a..4e3b46d56df0c 100644 --- a/tests/ui/unresolved/unresolved-asterisk-imports.stderr +++ b/tests/ui/unresolved/unresolved-asterisk-imports.stderr @@ -2,7 +2,7 @@ error[E0432]: unresolved import `not_existing_crate` --> $DIR/unresolved-asterisk-imports.rs:1:5 | LL | use not_existing_crate::*; - | ^^^^^^^^^^^^^^^^^^ maybe a missing crate `not_existing_crate`? + | ^^^^^^^^^^^^^^^^^^ you might be missing a crate named `not_existing_crate` | = help: consider adding `extern crate not_existing_crate` to use the `not_existing_crate` crate diff --git a/tests/ui/unresolved/unresolved-import.rs b/tests/ui/unresolved/unresolved-import.rs index 4125c593c747f..fd1a4f180ea5e 100644 --- a/tests/ui/unresolved/unresolved-import.rs +++ b/tests/ui/unresolved/unresolved-import.rs @@ -1,5 +1,5 @@ use foo::bar; //~ ERROR unresolved import `foo` [E0432] - //~^ maybe a missing crate `foo`? + //~^ you might be missing a crate named `foo` //~| HELP consider adding `extern crate foo` to use the `foo` crate use bar::Baz as x; //~ ERROR unresolved import `bar::Baz` [E0432] diff --git a/tests/ui/unresolved/unresolved-import.stderr b/tests/ui/unresolved/unresolved-import.stderr index 0dd928c8b6ffd..37553e32c3c3d 100644 --- a/tests/ui/unresolved/unresolved-import.stderr +++ b/tests/ui/unresolved/unresolved-import.stderr @@ -2,7 +2,7 @@ error[E0432]: unresolved import `foo` --> $DIR/unresolved-import.rs:1:5 | LL | use foo::bar; - | ^^^ maybe a missing crate `foo`? + | ^^^ you might be missing a crate named `foo` | = help: consider adding `extern crate foo` to use the `foo` crate diff --git a/tests/ui/use/use-self-type.rs b/tests/ui/use/use-self-type.rs index 3b4ce42970197..447e6aa42dc79 100644 --- a/tests/ui/use/use-self-type.rs +++ b/tests/ui/use/use-self-type.rs @@ -4,7 +4,7 @@ impl S { fn f() {} fn g() { use Self::f; //~ ERROR unresolved import - pub(in Self::f) struct Z; //~ ERROR failed to resolve: `Self` + pub(in Self::f) struct Z; //~ ERROR cannot find item `Self` } } diff --git a/tests/ui/use/use-self-type.stderr b/tests/ui/use/use-self-type.stderr index 498df34fe325e..cf8ba12f41e6e 100644 --- a/tests/ui/use/use-self-type.stderr +++ b/tests/ui/use/use-self-type.stderr @@ -1,4 +1,4 @@ -error[E0433]: failed to resolve: `Self` cannot be used in imports +error[E0433]: cannot find item `Self` in this scope --> $DIR/use-self-type.rs:7:16 | LL | pub(in Self::f) struct Z; diff --git a/tests/ui/use/use-super-global-path.rs b/tests/ui/use/use-super-global-path.rs index 64bfd14b7e7da..56dfd6ddfe540 100644 --- a/tests/ui/use/use-super-global-path.rs +++ b/tests/ui/use/use-super-global-path.rs @@ -4,11 +4,15 @@ struct S; struct Z; mod foo { - use ::super::{S, Z}; //~ ERROR global paths cannot start with `super` - //~| ERROR global paths cannot start with `super` + use ::super::{S, Z}; //~ ERROR cannot find module `super` + //~| ERROR cannot find module `super` + //~| NOTE global paths cannot start with `super` + //~| NOTE global paths cannot start with `super` + //~| NOTE duplicate diagnostic pub fn g() { - use ::super::main; //~ ERROR global paths cannot start with `super` + use ::super::main; //~ ERROR cannot find module `super` + //~| NOTE global paths cannot start with `super` main(); } } diff --git a/tests/ui/use/use-super-global-path.stderr b/tests/ui/use/use-super-global-path.stderr index 00d172f4799ae..e6b2ac7764484 100644 --- a/tests/ui/use/use-super-global-path.stderr +++ b/tests/ui/use/use-super-global-path.stderr @@ -1,10 +1,10 @@ -error[E0433]: failed to resolve: global paths cannot start with `super` +error[E0433]: cannot find module `super` in the crate root --> $DIR/use-super-global-path.rs:7:11 | LL | use ::super::{S, Z}; | ^^^^^ global paths cannot start with `super` -error[E0433]: failed to resolve: global paths cannot start with `super` +error[E0433]: cannot find module `super` in the crate root --> $DIR/use-super-global-path.rs:7:11 | LL | use ::super::{S, Z}; @@ -12,8 +12,8 @@ LL | use ::super::{S, Z}; | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error[E0433]: failed to resolve: global paths cannot start with `super` - --> $DIR/use-super-global-path.rs:11:15 +error[E0433]: cannot find module `super` in the crate root + --> $DIR/use-super-global-path.rs:14:15 | LL | use ::super::main; | ^^^^^ global paths cannot start with `super` From de92cd4cb59380af215c44526bfdaf694f4672b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 2 Jul 2024 00:58:06 +0000 Subject: [PATCH 888/892] Account for `_` in import paths --- compiler/rustc_resolve/src/diagnostics.rs | 2 ++ tests/ui/underscore-imports/issue-110164.stderr | 16 ++++------------ 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index d00189929946f..a21869af7f6e7 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -2031,6 +2031,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { Applicability::MaybeIncorrect, )), ) + } else if ident.is_special() { + (format!("`{ident}` is not a valid item name"), None) } else if ident.name == sym::core { ( format!("you might be missing a crate named `{ident}`"), diff --git a/tests/ui/underscore-imports/issue-110164.stderr b/tests/ui/underscore-imports/issue-110164.stderr index c6fe13b901f6e..4540cdc96531a 100644 --- a/tests/ui/underscore-imports/issue-110164.stderr +++ b/tests/ui/underscore-imports/issue-110164.stderr @@ -38,33 +38,25 @@ error[E0432]: unresolved import `_` --> $DIR/issue-110164.rs:8:5 | LL | use _::*; - | ^ you might be missing a crate named `_` - | - = help: consider adding `extern crate _` to use the `_` crate + | ^ `_` is not a valid item name error[E0432]: unresolved import `_` --> $DIR/issue-110164.rs:5:5 | LL | use _::a; - | ^ you might be missing a crate named `_` - | - = help: consider adding `extern crate _` to use the `_` crate + | ^ `_` is not a valid item name error[E0432]: unresolved import `_` --> $DIR/issue-110164.rs:13:9 | LL | use _::a; - | ^ you might be missing a crate named `_` - | - = help: consider adding `extern crate _` to use the `_` crate + | ^ `_` is not a valid item name error[E0432]: unresolved import `_` --> $DIR/issue-110164.rs:16:9 | LL | use _::*; - | ^ you might be missing a crate named `_` - | - = help: consider adding `extern crate _` to use the `_` crate + | ^ `_` is not a valid item name error: aborting due to 10 previous errors From 045e8dd5bf45013730f471003c7156f3056b52f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 2 Jul 2024 01:09:53 +0000 Subject: [PATCH 889/892] Fix miri test --- src/tools/miri/tests/fail/rustc-error2.rs | 2 +- src/tools/miri/tests/fail/rustc-error2.stderr | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tools/miri/tests/fail/rustc-error2.rs b/src/tools/miri/tests/fail/rustc-error2.rs index fd2c53933856d..6d9cd9544b3e4 100644 --- a/src/tools/miri/tests/fail/rustc-error2.rs +++ b/src/tools/miri/tests/fail/rustc-error2.rs @@ -4,7 +4,7 @@ struct Struct(T); impl std::ops::Deref for Struct { type Target = dyn Fn(T); fn deref(&self) -> &assert_mem_uninitialized_valid::Target { - //~^ERROR: undeclared crate or module + //~^ ERROR: cannot find item `assert_mem_uninitialized_valid` unimplemented!() } } diff --git a/src/tools/miri/tests/fail/rustc-error2.stderr b/src/tools/miri/tests/fail/rustc-error2.stderr index 29c86f41f2833..59919adb42de5 100644 --- a/src/tools/miri/tests/fail/rustc-error2.stderr +++ b/src/tools/miri/tests/fail/rustc-error2.stderr @@ -1,4 +1,4 @@ -error[E0433]: cannot find item `assert_mem_uninitialized_valid` +error[E0433]: cannot find item `assert_mem_uninitialized_valid` in this scope --> $DIR/rustc-error2.rs:LL:CC | LL | fn deref(&self) -> &assert_mem_uninitialized_valid::Target { From a9fe7c8eb4251611d79c37b8c9497519b030bca2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 2 Jul 2024 01:13:27 +0000 Subject: [PATCH 890/892] fix windows test --- tests/rustdoc-ui/doctest/failed-doctest-output-windows.stdout | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/rustdoc-ui/doctest/failed-doctest-output-windows.stdout b/tests/rustdoc-ui/doctest/failed-doctest-output-windows.stdout index b9d0614821ca3..1b37249dd60f9 100644 --- a/tests/rustdoc-ui/doctest/failed-doctest-output-windows.stdout +++ b/tests/rustdoc-ui/doctest/failed-doctest-output-windows.stdout @@ -6,7 +6,7 @@ test $DIR/failed-doctest-output-windows.rs - SomeStruct (line 15) ... FAILED failures: ---- $DIR/failed-doctest-output-windows.rs - OtherStruct (line 25) stdout ---- -error[E0425]: cannot find value `no` +error[E0425]: cannot find value `no` in this scope --> $DIR/failed-doctest-output-windows.rs:26:1 | LL | no From f0d9e3fed4c9b5140ba780cae046a72d9f062c2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 2 Jul 2024 02:51:16 +0000 Subject: [PATCH 891/892] Add scope context to unresolved macros --- compiler/rustc_lint/messages.ftl | 4 +- .../rustc_lint/src/context/diagnostics.rs | 4 +- compiler/rustc_lint/src/lints.rs | 1 + compiler/rustc_lint_defs/src/lib.rs | 1 + compiler/rustc_resolve/messages.ftl | 4 +- compiler/rustc_resolve/src/errors.rs | 1 + compiler/rustc_resolve/src/macros.rs | 19 +++- tests/ui/attributes/issue-90873.stderr | 8 +- .../key-value-expansion-scope.stderr | 88 +++++++++---------- tests/ui/attributes/main-removed-1.stderr | 4 +- tests/ui/attributes/obsolete-attr.stderr | 8 +- tests/ui/attributes/unknown-attr.stderr | 12 +-- .../unsafe/double-unsafe-attributes.stderr | 4 +- .../ui/attributes/unused-item-in-attr.stderr | 4 +- ...r-unknown-attribute-macro-expansion.stderr | 4 +- .../cfg-generic-params.stderr | 20 ++--- tests/ui/consts/issue-90878-2.stderr | 4 +- tests/ui/custom_attribute.stderr | 4 +- ...deduplicate-diagnostics.deduplicate.stderr | 4 +- .../deduplicate-diagnostics.duplicate.stderr | 8 +- tests/ui/derives/deriving-bounds.stderr | 16 ++-- .../deriving-meta-unknown-trait.stderr | 8 +- tests/ui/derives/deriving-primitive.stderr | 8 +- .../diagnostic_namespace/requires_path.stderr | 4 +- .../ui/enum/suggest-default-attribute.stderr | 4 +- .../feature-gate-custom_attribute.stderr | 52 +++++------ .../feature-gate-custom_attribute2.stderr | 68 +++++++------- .../feature-gate-rustc-attrs.stderr | 4 +- .../issue-43106-gating-of-derive-2.stderr | 24 ++--- tests/ui/issues/issue-19734.stderr | 4 +- tests/ui/issues/issue-32655.stderr | 8 +- tests/ui/issues/issue-33571.stderr | 8 +- tests/ui/issues/issue-40845.stderr | 8 +- tests/ui/macros/issue-118786.stderr | 4 +- tests/ui/macros/issue-88206.rs | 22 ++--- tests/ui/macros/issue-88206.stderr | 24 ++--- tests/ui/macros/issue-88228.stderr | 8 +- ...acro-expand-within-generics-in-path.stderr | 4 +- tests/ui/macros/macro-expansion-tests.stderr | 8 +- tests/ui/macros/macro-reexport-removed.stderr | 4 +- .../multiple-tail-expr-behind-cfg.stderr | 4 +- .../ui/parser/default-unmatched-assoc.stderr | 8 +- .../ui/parser/default-unmatched-extern.stderr | 4 +- .../ui/parser/issues/issue-118531-ice.stderr | 4 +- .../derive-helper-legacy-limits.stderr | 4 +- .../derive-helper-legacy-spurious.stderr | 8 +- .../proc-macro/derive-helper-shadowing.stderr | 8 +- tests/ui/proc-macro/derive-still-gated.stderr | 4 +- .../proc-macro/disappearing-resolution.stderr | 4 +- .../issue-118455-skip-err-builtin.stderr | 4 +- .../macro-namespace-reserved-2.stderr | 12 +-- .../proc-macro/proc-macro-attributes.stderr | 4 +- tests/ui/proc-macro/resolve-error.stderr | 40 ++++----- .../ui/reserved/reserved-attr-on-macro.stderr | 4 +- tests/ui/resolve/issue-118295.rs | 2 +- tests/ui/resolve/issue-118295.stderr | 4 +- tests/ui/resolve/issue-49074.stderr | 4 +- .../resolve/path-attr-in-const-block.stderr | 4 +- .../resolve/visibility-indeterminate.stderr | 4 +- tests/ui/self/self_type_keyword.stderr | 4 +- tests/ui/suggestions/attribute-typos.stderr | 12 +-- .../tool-attributes-misplaced-1.stderr | 12 +-- 62 files changed, 337 insertions(+), 317 deletions(-) diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl index 5921492160e24..283d580f203da 100644 --- a/compiler/rustc_lint/messages.ftl +++ b/compiler/rustc_lint/messages.ftl @@ -609,8 +609,8 @@ lint_opaque_hidden_inferred_bound_sugg = add this bound lint_or_patterns_back_compat = the meaning of the `pat` fragment specifier is changing in Rust 2021, which may affect this macro .suggestion = use pat_param to preserve semantics -lint_out_of_scope_macro_calls = cannot find macro `{$path}` in this scope - .label = not found in this scope +lint_out_of_scope_macro_calls = cannot find macro `{$path}` in {$scope} + .label = not found in {$scope} .help = import `macro_rules` with `use` to make it callable above its definition lint_overflowing_bin_hex = literal out of range for `{$ty}` diff --git a/compiler/rustc_lint/src/context/diagnostics.rs b/compiler/rustc_lint/src/context/diagnostics.rs index 99e1c7f29289a..a388bc8d3ae82 100644 --- a/compiler/rustc_lint/src/context/diagnostics.rs +++ b/compiler/rustc_lint/src/context/diagnostics.rs @@ -434,8 +434,8 @@ pub(super) fn decorate_lint(sess: &Session, diagnostic: BuiltinLintDiag, diag: & lints::InnerAttributeUnstable::CustomInnerAttribute } .decorate_lint(diag), - BuiltinLintDiag::OutOfScopeMacroCalls { span, path } => { - lints::OutOfScopeMacroCalls { span, path }.decorate_lint(diag) + BuiltinLintDiag::OutOfScopeMacroCalls { span, path, scope } => { + lints::OutOfScopeMacroCalls { span, path, scope }.decorate_lint(diag) } } } diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs index 1dcc561a32ed2..ba0833a921d05 100644 --- a/compiler/rustc_lint/src/lints.rs +++ b/compiler/rustc_lint/src/lints.rs @@ -2920,4 +2920,5 @@ pub struct OutOfScopeMacroCalls { #[label] pub span: Span, pub path: String, + pub scope: String, } diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs index 1e67b0bf68a73..e27868a405dee 100644 --- a/compiler/rustc_lint_defs/src/lib.rs +++ b/compiler/rustc_lint_defs/src/lib.rs @@ -747,6 +747,7 @@ pub enum BuiltinLintDiag { OutOfScopeMacroCalls { span: Span, path: String, + scope: String, }, } diff --git a/compiler/rustc_resolve/messages.ftl b/compiler/rustc_resolve/messages.ftl index 2e9d36b80133d..0016a588e9a35 100644 --- a/compiler/rustc_resolve/messages.ftl +++ b/compiler/rustc_resolve/messages.ftl @@ -80,8 +80,8 @@ resolve_cannot_determine_macro_resolution = resolve_cannot_find_builtin_macro_with_name = cannot find a built-in macro with name `{$ident}` -resolve_cannot_find_ident_in_this_scope = cannot find {$expected} `{$ident}` in this scope - .label = not found in this scope +resolve_cannot_find_ident_in_this_scope = cannot find {$expected} `{$ident}` in {$scope} + .label = not found in {$scope} resolve_cannot_glob_import_possible_crates = cannot glob-import all possible crates diff --git a/compiler/rustc_resolve/src/errors.rs b/compiler/rustc_resolve/src/errors.rs index 03ad245d128f0..15d0fd0ffa01f 100644 --- a/compiler/rustc_resolve/src/errors.rs +++ b/compiler/rustc_resolve/src/errors.rs @@ -638,6 +638,7 @@ pub(crate) struct CannotFindIdentInThisScope<'a> { #[label] pub(crate) span: Span, pub(crate) expected: &'a str, + pub(crate) scope: &'a str, pub(crate) ident: Ident, } diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs index 3e4d17f9a0085..c767586d920ed 100644 --- a/compiler/rustc_resolve/src/macros.rs +++ b/compiler/rustc_resolve/src/macros.rs @@ -950,10 +950,17 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { } Err(..) => { let expected = kind.descr_expected(); - + let scope = match parent_scope.module.kind { + ModuleKind::Def(_, _, name) if name == kw::Empty => "the crate root", + ModuleKind::Def(kind, def_id, name) => { + &format!("{} `{name}`", kind.descr(def_id)) + } + ModuleKind::Block => "this scope", + }; let mut err = self.dcx().create_err(CannotFindIdentInThisScope { span: ident.span, expected, + scope, ident, }); self.unresolved_macro_suggestions(&mut err, kind, &parent_scope, ident, krate); @@ -1077,6 +1084,15 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { None, ); if fallback_binding.ok().and_then(|b| b.res().opt_def_id()) != Some(def_id) { + let scope = match parent_scope.module.kind { + ModuleKind::Def(_, _, name) if name == kw::Empty => { + "the crate root".to_string() + } + ModuleKind::Def(kind, def_id, name) => { + format!("{} `{name}`", kind.descr(def_id)) + } + ModuleKind::Block => "this scope".to_string(), + }; self.tcx.sess.psess.buffer_lint( OUT_OF_SCOPE_MACRO_CALLS, path.span, @@ -1084,6 +1100,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { BuiltinLintDiag::OutOfScopeMacroCalls { span: path.span, path: pprust::path_to_string(path), + scope, }, ); } diff --git a/tests/ui/attributes/issue-90873.stderr b/tests/ui/attributes/issue-90873.stderr index 313ecb8cf25e8..a43d2bd93a5ca 100644 --- a/tests/ui/attributes/issue-90873.stderr +++ b/tests/ui/attributes/issue-90873.stderr @@ -10,17 +10,17 @@ error: attribute value must be a literal LL | #![a={impl std::ops::Neg for i8 {}}] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: cannot find attribute `u` in this scope +error: cannot find attribute `u` in the crate root --> $DIR/issue-90873.rs:1:4 | LL | #![u=||{static d=||1;}] - | ^ not found in this scope + | ^ not found in the crate root -error: cannot find attribute `a` in this scope +error: cannot find attribute `a` in the crate root --> $DIR/issue-90873.rs:6:4 | LL | #![a={impl std::ops::Neg for i8 {}}] - | ^ not found in this scope + | ^ not found in the crate root error[E0601]: `main` function not found in crate `issue_90873` --> $DIR/issue-90873.rs:6:37 diff --git a/tests/ui/attributes/key-value-expansion-scope.stderr b/tests/ui/attributes/key-value-expansion-scope.stderr index 19948c4c283ac..2f80503dccdda 100644 --- a/tests/ui/attributes/key-value-expansion-scope.stderr +++ b/tests/ui/attributes/key-value-expansion-scope.stderr @@ -1,187 +1,187 @@ -error: cannot find macro `in_mod` in this scope +error: cannot find macro `in_mod` in the crate root --> $DIR/key-value-expansion-scope.rs:3:10 | LL | #![doc = in_mod!()] - | ^^^^^^ not found in this scope + | ^^^^^^ not found in the crate root | = help: have you added the `#[macro_use]` on the module/import? -error: cannot find macro `in_block` in this scope +error: cannot find macro `in_block` in the crate root --> $DIR/key-value-expansion-scope.rs:6:10 | LL | #![doc = in_block!()] - | ^^^^^^^^ not found in this scope + | ^^^^^^^^ not found in the crate root | = help: have you added the `#[macro_use]` on the module/import? -error: cannot find macro `in_root` in this scope +error: cannot find macro `in_root` in the crate root --> $DIR/key-value-expansion-scope.rs:8:9 | LL | #[doc = in_root!()] - | ^^^^^^^ not found in this scope + | ^^^^^^^ not found in the crate root | = help: have you added the `#[macro_use]` on the module/import? -error: cannot find macro `in_mod` in this scope +error: cannot find macro `in_mod` in the crate root --> $DIR/key-value-expansion-scope.rs:9:9 | LL | #[doc = in_mod!()] - | ^^^^^^ not found in this scope + | ^^^^^^ not found in the crate root | = help: have you added the `#[macro_use]` on the module/import? -error: cannot find macro `in_mod_escape` in this scope +error: cannot find macro `in_mod_escape` in the crate root --> $DIR/key-value-expansion-scope.rs:10:9 | LL | #[doc = in_mod_escape!()] - | ^^^^^^^^^^^^^ not found in this scope + | ^^^^^^^^^^^^^ not found in the crate root | = help: have you added the `#[macro_use]` on the module/import? -error: cannot find macro `in_block` in this scope +error: cannot find macro `in_block` in the crate root --> $DIR/key-value-expansion-scope.rs:11:9 | LL | #[doc = in_block!()] - | ^^^^^^^^ not found in this scope + | ^^^^^^^^ not found in the crate root | = help: have you added the `#[macro_use]` on the module/import? -error: cannot find macro `in_root` in this scope +error: cannot find macro `in_root` in the crate root --> $DIR/key-value-expansion-scope.rs:13:14 | LL | #![doc = in_root!()] - | ^^^^^^^ not found in this scope + | ^^^^^^^ not found in the crate root | = help: have you added the `#[macro_use]` on the module/import? -error: cannot find macro `in_mod` in this scope +error: cannot find macro `in_mod` in the crate root --> $DIR/key-value-expansion-scope.rs:14:14 | LL | #![doc = in_mod!()] - | ^^^^^^ not found in this scope + | ^^^^^^ not found in the crate root | = help: have you added the `#[macro_use]` on the module/import? -error: cannot find macro `in_mod_escape` in this scope +error: cannot find macro `in_mod_escape` in the crate root --> $DIR/key-value-expansion-scope.rs:15:14 | LL | #![doc = in_mod_escape!()] - | ^^^^^^^^^^^^^ not found in this scope + | ^^^^^^^^^^^^^ not found in the crate root | = help: have you added the `#[macro_use]` on the module/import? -error: cannot find macro `in_block` in this scope +error: cannot find macro `in_block` in the crate root --> $DIR/key-value-expansion-scope.rs:16:14 | LL | #![doc = in_block!()] - | ^^^^^^^^ not found in this scope + | ^^^^^^^^ not found in the crate root | = help: have you added the `#[macro_use]` on the module/import? -error: cannot find macro `in_block` in this scope +error: cannot find macro `in_block` in the crate root --> $DIR/key-value-expansion-scope.rs:50:9 | LL | #[doc = in_block!()] - | ^^^^^^^^ not found in this scope + | ^^^^^^^^ not found in the crate root | = help: have you added the `#[macro_use]` on the module/import? -error: cannot find macro `in_block` in this scope +error: cannot find macro `in_block` in the crate root --> $DIR/key-value-expansion-scope.rs:52:14 | LL | #![doc = in_block!()] - | ^^^^^^^^ not found in this scope + | ^^^^^^^^ not found in the crate root | = help: have you added the `#[macro_use]` on the module/import? -error: cannot find macro `in_mod` in this scope +error: cannot find macro `in_mod` in the crate root --> $DIR/key-value-expansion-scope.rs:63:9 | LL | #[doc = in_mod!()] - | ^^^^^^ not found in this scope + | ^^^^^^ not found in the crate root | = help: have you added the `#[macro_use]` on the module/import? -error: cannot find macro `in_block` in this scope +error: cannot find macro `in_block` in the crate root --> $DIR/key-value-expansion-scope.rs:65:9 | LL | #[doc = in_block!()] - | ^^^^^^^^ not found in this scope + | ^^^^^^^^ not found in the crate root | = help: have you added the `#[macro_use]` on the module/import? -error: cannot find macro `in_mod` in this scope +error: cannot find macro `in_mod` in the crate root --> $DIR/key-value-expansion-scope.rs:68:14 | LL | #![doc = in_mod!()] - | ^^^^^^ not found in this scope + | ^^^^^^ not found in the crate root | = help: have you added the `#[macro_use]` on the module/import? -error: cannot find macro `in_block` in this scope +error: cannot find macro `in_block` in the crate root --> $DIR/key-value-expansion-scope.rs:70:14 | LL | #![doc = in_block!()] - | ^^^^^^^^ not found in this scope + | ^^^^^^^^ not found in the crate root | = help: have you added the `#[macro_use]` on the module/import? -warning: cannot find macro `in_root` in this scope +warning: cannot find macro `in_root` in the crate root --> $DIR/key-value-expansion-scope.rs:1:10 | LL | #![doc = in_root!()] - | ^^^^^^^ not found in this scope + | ^^^^^^^ not found in the crate root | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #124535 = help: import `macro_rules` with `use` to make it callable above its definition = note: `#[warn(out_of_scope_macro_calls)]` on by default -warning: cannot find macro `in_mod_escape` in this scope +warning: cannot find macro `in_mod_escape` in the crate root --> $DIR/key-value-expansion-scope.rs:4:10 | LL | #![doc = in_mod_escape!()] - | ^^^^^^^^^^^^^ not found in this scope + | ^^^^^^^^^^^^^ not found in the crate root | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #124535 = help: import `macro_rules` with `use` to make it callable above its definition -warning: cannot find macro `in_mod` in this scope +warning: cannot find macro `in_mod` in module `macros_stay` --> $DIR/key-value-expansion-scope.rs:21:9 | LL | #[doc = in_mod!()] - | ^^^^^^ not found in this scope + | ^^^^^^ not found in module `macros_stay` | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #124535 = help: import `macro_rules` with `use` to make it callable above its definition -warning: cannot find macro `in_mod` in this scope +warning: cannot find macro `in_mod` in module `macros_stay` --> $DIR/key-value-expansion-scope.rs:24:14 | LL | #![doc = in_mod!()] - | ^^^^^^ not found in this scope + | ^^^^^^ not found in module `macros_stay` | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #124535 = help: import `macro_rules` with `use` to make it callable above its definition -warning: cannot find macro `in_mod_escape` in this scope +warning: cannot find macro `in_mod_escape` in module `macros_escape` --> $DIR/key-value-expansion-scope.rs:36:9 | LL | #[doc = in_mod_escape!()] - | ^^^^^^^^^^^^^ not found in this scope + | ^^^^^^^^^^^^^ not found in module `macros_escape` | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #124535 = help: import `macro_rules` with `use` to make it callable above its definition -warning: cannot find macro `in_mod_escape` in this scope +warning: cannot find macro `in_mod_escape` in module `macros_escape` --> $DIR/key-value-expansion-scope.rs:39:14 | LL | #![doc = in_mod_escape!()] - | ^^^^^^^^^^^^^ not found in this scope + | ^^^^^^^^^^^^^ not found in module `macros_escape` | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #124535 diff --git a/tests/ui/attributes/main-removed-1.stderr b/tests/ui/attributes/main-removed-1.stderr index ad6b60a212cc8..96e061403ecbe 100644 --- a/tests/ui/attributes/main-removed-1.stderr +++ b/tests/ui/attributes/main-removed-1.stderr @@ -1,8 +1,8 @@ -error: cannot find attribute `main` in this scope +error: cannot find attribute `main` in the crate root --> $DIR/main-removed-1.rs:1:3 | LL | #[main] - | ^^^^ not found in this scope + | ^^^^ not found in the crate root | = note: `main` is in scope, but it is a function, not an attribute diff --git a/tests/ui/attributes/obsolete-attr.stderr b/tests/ui/attributes/obsolete-attr.stderr index e3ab0ecfbd2bf..a97b9bcfb693d 100644 --- a/tests/ui/attributes/obsolete-attr.stderr +++ b/tests/ui/attributes/obsolete-attr.stderr @@ -1,14 +1,14 @@ -error: cannot find attribute `fixed_stack_segment` in this scope +error: cannot find attribute `fixed_stack_segment` in the crate root --> $DIR/obsolete-attr.rs:6:3 | LL | #[fixed_stack_segment] fn f() {} - | ^^^^^^^^^^^^^^^^^^^ not found in this scope + | ^^^^^^^^^^^^^^^^^^^ not found in the crate root -error: cannot find attribute `ab_isize` in this scope +error: cannot find attribute `ab_isize` in the crate root --> $DIR/obsolete-attr.rs:3:3 | LL | #[ab_isize = "stdcall"] extern "C" {} - | ^^^^^^^^ not found in this scope + | ^^^^^^^^ not found in the crate root error: aborting due to 2 previous errors diff --git a/tests/ui/attributes/unknown-attr.stderr b/tests/ui/attributes/unknown-attr.stderr index acd8b93a78e99..a934737a2a4fe 100644 --- a/tests/ui/attributes/unknown-attr.stderr +++ b/tests/ui/attributes/unknown-attr.stderr @@ -1,20 +1,20 @@ -error: cannot find attribute `mutable_doc` in this scope +error: cannot find attribute `mutable_doc` in the crate root --> $DIR/unknown-attr.rs:5:4 | LL | #![mutable_doc] - | ^^^^^^^^^^^ not found in this scope + | ^^^^^^^^^^^ not found in the crate root -error: cannot find attribute `dance` in this scope +error: cannot find attribute `dance` in the crate root --> $DIR/unknown-attr.rs:8:3 | LL | #[dance] mod a {} - | ^^^^^ not found in this scope + | ^^^^^ not found in the crate root -error: cannot find attribute `dance` in this scope +error: cannot find attribute `dance` in the crate root --> $DIR/unknown-attr.rs:11:3 | LL | #[dance] fn main() {} - | ^^^^^ not found in this scope + | ^^^^^ not found in the crate root error: aborting due to 3 previous errors diff --git a/tests/ui/attributes/unsafe/double-unsafe-attributes.stderr b/tests/ui/attributes/unsafe/double-unsafe-attributes.stderr index 9f9a4e2f214c1..c359567fd1d3b 100644 --- a/tests/ui/attributes/unsafe/double-unsafe-attributes.stderr +++ b/tests/ui/attributes/unsafe/double-unsafe-attributes.stderr @@ -17,11 +17,11 @@ LL | #[unsafe(unsafe(no_mangle))] | = note: extraneous unsafe is not allowed in attributes -error: cannot find attribute `r#unsafe` in this scope +error: cannot find attribute `r#unsafe` in the crate root --> $DIR/double-unsafe-attributes.rs:3:10 | LL | #[unsafe(unsafe(no_mangle))] - | ^^^^^^ not found in this scope + | ^^^^^^ not found in the crate root error: aborting due to 3 previous errors diff --git a/tests/ui/attributes/unused-item-in-attr.stderr b/tests/ui/attributes/unused-item-in-attr.stderr index 3b2f196b468c3..b5d58103d07ef 100644 --- a/tests/ui/attributes/unused-item-in-attr.stderr +++ b/tests/ui/attributes/unused-item-in-attr.stderr @@ -4,11 +4,11 @@ error: attribute value must be a literal LL | #[w = { extern crate alloc; }] | ^^^^^^^^^^^^^^^^^^^^^^^ -error: cannot find attribute `w` in this scope +error: cannot find attribute `w` in the crate root --> $DIR/unused-item-in-attr.rs:1:3 | LL | #[w = { extern crate alloc; }] - | ^ not found in this scope + | ^ not found in the crate root error: aborting due to 2 previous errors diff --git a/tests/ui/conditional-compilation/cfg-attr-unknown-attribute-macro-expansion.stderr b/tests/ui/conditional-compilation/cfg-attr-unknown-attribute-macro-expansion.stderr index 775349f8fb11c..8ee90293522ee 100644 --- a/tests/ui/conditional-compilation/cfg-attr-unknown-attribute-macro-expansion.stderr +++ b/tests/ui/conditional-compilation/cfg-attr-unknown-attribute-macro-expansion.stderr @@ -1,8 +1,8 @@ -error: cannot find attribute `unknown` in this scope +error: cannot find attribute `unknown` in the crate root --> $DIR/cfg-attr-unknown-attribute-macro-expansion.rs:3:27 | LL | #[cfg_attr(all(), unknown)] - | ^^^^^^^ not found in this scope + | ^^^^^^^ not found in the crate root ... LL | foo!(); | ------ in this macro invocation diff --git a/tests/ui/conditional-compilation/cfg-generic-params.stderr b/tests/ui/conditional-compilation/cfg-generic-params.stderr index 7ddfb445f7324..aef384ed88e0a 100644 --- a/tests/ui/conditional-compilation/cfg-generic-params.stderr +++ b/tests/ui/conditional-compilation/cfg-generic-params.stderr @@ -1,32 +1,32 @@ -error: cannot find attribute `unknown` in this scope +error: cannot find attribute `unknown` in the crate root --> $DIR/cfg-generic-params.rs:19:29 | LL | fn f_lt_yes<#[cfg_attr(yes, unknown)] 'a>() {} - | ^^^^^^^ not found in this scope + | ^^^^^^^ not found in the crate root -error: cannot find attribute `unknown` in this scope +error: cannot find attribute `unknown` in the crate root --> $DIR/cfg-generic-params.rs:22:29 | LL | fn f_ty_yes<#[cfg_attr(yes, unknown)] T>() {} - | ^^^^^^^ not found in this scope + | ^^^^^^^ not found in the crate root -error: cannot find attribute `unknown` in this scope +error: cannot find attribute `unknown` in the crate root --> $DIR/cfg-generic-params.rs:26:34 | LL | type FnYes = for<#[cfg_attr(yes, unknown)] 'a> fn(); - | ^^^^^^^ not found in this scope + | ^^^^^^^ not found in the crate root -error: cannot find attribute `unknown` in this scope +error: cannot find attribute `unknown` in the crate root --> $DIR/cfg-generic-params.rs:30:40 | LL | type PolyYes = dyn for<#[cfg_attr(yes, unknown)] 'a> Copy; - | ^^^^^^^ not found in this scope + | ^^^^^^^ not found in the crate root -error: cannot find attribute `unknown` in this scope +error: cannot find attribute `unknown` in the crate root --> $DIR/cfg-generic-params.rs:34:43 | LL | struct WhereYes where for<#[cfg_attr(yes, unknown)] 'a> u8: Copy; - | ^^^^^^^ not found in this scope + | ^^^^^^^ not found in the crate root error[E0658]: only lifetime parameters can be used in this context --> $DIR/cfg-generic-params.rs:7:48 diff --git a/tests/ui/consts/issue-90878-2.stderr b/tests/ui/consts/issue-90878-2.stderr index 20e3b50baae8d..45d1cf053b03b 100644 --- a/tests/ui/consts/issue-90878-2.stderr +++ b/tests/ui/consts/issue-90878-2.stderr @@ -4,11 +4,11 @@ error: attribute value must be a literal LL | #![l=|x|[b;x ]] | ^^^^^^^^^ -error: cannot find attribute `l` in this scope +error: cannot find attribute `l` in the crate root --> $DIR/issue-90878-2.rs:1:5 | LL | #![l=|x|[b;x ]] - | ^ not found in this scope + | ^ not found in the crate root error: aborting due to 2 previous errors diff --git a/tests/ui/custom_attribute.stderr b/tests/ui/custom_attribute.stderr index ba29951323862..37dcb4211ecc0 100644 --- a/tests/ui/custom_attribute.stderr +++ b/tests/ui/custom_attribute.stderr @@ -1,8 +1,8 @@ -error: cannot find attribute `foo` in this scope +error: cannot find attribute `foo` in the crate root --> $DIR/custom_attribute.rs:3:3 | LL | #[foo] - | ^^^ not found in this scope + | ^^^ not found in the crate root error: cannot find attribute `foo` in this scope --> $DIR/custom_attribute.rs:5:7 diff --git a/tests/ui/deduplicate-diagnostics.deduplicate.stderr b/tests/ui/deduplicate-diagnostics.deduplicate.stderr index f441c71771507..2d6820da7f8af 100644 --- a/tests/ui/deduplicate-diagnostics.deduplicate.stderr +++ b/tests/ui/deduplicate-diagnostics.deduplicate.stderr @@ -4,11 +4,11 @@ error[E0452]: malformed lint attribute input LL | #[deny("literal")] | ^^^^^^^^^ bad attribute argument -error: cannot find derive macro `Unresolved` in this scope +error: cannot find derive macro `Unresolved` in the crate root --> $DIR/deduplicate-diagnostics.rs:4:10 | LL | #[derive(Unresolved)] - | ^^^^^^^^^^ not found in this scope + | ^^^^^^^^^^ not found in the crate root error: aborting due to 2 previous errors diff --git a/tests/ui/deduplicate-diagnostics.duplicate.stderr b/tests/ui/deduplicate-diagnostics.duplicate.stderr index 69217fa810bd6..ff6bfa753ddef 100644 --- a/tests/ui/deduplicate-diagnostics.duplicate.stderr +++ b/tests/ui/deduplicate-diagnostics.duplicate.stderr @@ -4,17 +4,17 @@ error[E0452]: malformed lint attribute input LL | #[deny("literal")] | ^^^^^^^^^ bad attribute argument -error: cannot find derive macro `Unresolved` in this scope +error: cannot find derive macro `Unresolved` in the crate root --> $DIR/deduplicate-diagnostics.rs:4:10 | LL | #[derive(Unresolved)] - | ^^^^^^^^^^ not found in this scope + | ^^^^^^^^^^ not found in the crate root -error: cannot find derive macro `Unresolved` in this scope +error: cannot find derive macro `Unresolved` in the crate root --> $DIR/deduplicate-diagnostics.rs:4:10 | LL | #[derive(Unresolved)] - | ^^^^^^^^^^ not found in this scope + | ^^^^^^^^^^ not found in the crate root | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` diff --git a/tests/ui/derives/deriving-bounds.stderr b/tests/ui/derives/deriving-bounds.stderr index f3ddbffe4f55e..8337ab21a8343 100644 --- a/tests/ui/derives/deriving-bounds.stderr +++ b/tests/ui/derives/deriving-bounds.stderr @@ -1,8 +1,8 @@ -error: cannot find derive macro `Sync` in this scope +error: cannot find derive macro `Sync` in the crate root --> $DIR/deriving-bounds.rs:6:10 | LL | #[derive(Sync)] - | ^^^^ not found in this scope + | ^^^^ not found in the crate root | note: unsafe traits like `Sync` should be implemented explicitly --> $DIR/deriving-bounds.rs:6:10 @@ -10,11 +10,11 @@ note: unsafe traits like `Sync` should be implemented explicitly LL | #[derive(Sync)] | ^^^^ -error: cannot find derive macro `Sync` in this scope +error: cannot find derive macro `Sync` in the crate root --> $DIR/deriving-bounds.rs:6:10 | LL | #[derive(Sync)] - | ^^^^ not found in this scope + | ^^^^ not found in the crate root | note: unsafe traits like `Sync` should be implemented explicitly --> $DIR/deriving-bounds.rs:6:10 @@ -23,11 +23,11 @@ LL | #[derive(Sync)] | ^^^^ = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error: cannot find derive macro `Send` in this scope +error: cannot find derive macro `Send` in the crate root --> $DIR/deriving-bounds.rs:1:10 | LL | #[derive(Send)] - | ^^^^ not found in this scope + | ^^^^ not found in the crate root | note: unsafe traits like `Send` should be implemented explicitly --> $DIR/deriving-bounds.rs:1:10 @@ -35,11 +35,11 @@ note: unsafe traits like `Send` should be implemented explicitly LL | #[derive(Send)] | ^^^^ -error: cannot find derive macro `Send` in this scope +error: cannot find derive macro `Send` in the crate root --> $DIR/deriving-bounds.rs:1:10 | LL | #[derive(Send)] - | ^^^^ not found in this scope + | ^^^^ not found in the crate root | note: unsafe traits like `Send` should be implemented explicitly --> $DIR/deriving-bounds.rs:1:10 diff --git a/tests/ui/derives/deriving-meta-unknown-trait.stderr b/tests/ui/derives/deriving-meta-unknown-trait.stderr index 77fcacaa7a206..cd408668ba0fa 100644 --- a/tests/ui/derives/deriving-meta-unknown-trait.stderr +++ b/tests/ui/derives/deriving-meta-unknown-trait.stderr @@ -1,22 +1,22 @@ -error: cannot find derive macro `Eqr` in this scope +error: cannot find derive macro `Eqr` in the crate root --> $DIR/deriving-meta-unknown-trait.rs:1:10 | LL | #[derive(Eqr)] | ^^^ | | - | not found in this scope + | not found in the crate root | help: a derive macro with a similar name exists: `Eq` --> $SRC_DIR/core/src/cmp.rs:LL:COL | = note: similarly named derive macro `Eq` defined here -error: cannot find derive macro `Eqr` in this scope +error: cannot find derive macro `Eqr` in the crate root --> $DIR/deriving-meta-unknown-trait.rs:1:10 | LL | #[derive(Eqr)] | ^^^ | | - | not found in this scope + | not found in the crate root | help: a derive macro with a similar name exists: `Eq` --> $SRC_DIR/core/src/cmp.rs:LL:COL | diff --git a/tests/ui/derives/deriving-primitive.stderr b/tests/ui/derives/deriving-primitive.stderr index 27a13f517daf9..a6c3c0d80e2e4 100644 --- a/tests/ui/derives/deriving-primitive.stderr +++ b/tests/ui/derives/deriving-primitive.stderr @@ -1,14 +1,14 @@ -error: cannot find derive macro `FromPrimitive` in this scope +error: cannot find derive macro `FromPrimitive` in the crate root --> $DIR/deriving-primitive.rs:1:10 | LL | #[derive(FromPrimitive)] - | ^^^^^^^^^^^^^ not found in this scope + | ^^^^^^^^^^^^^ not found in the crate root -error: cannot find derive macro `FromPrimitive` in this scope +error: cannot find derive macro `FromPrimitive` in the crate root --> $DIR/deriving-primitive.rs:1:10 | LL | #[derive(FromPrimitive)] - | ^^^^^^^^^^^^^ not found in this scope + | ^^^^^^^^^^^^^ not found in the crate root | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` diff --git a/tests/ui/diagnostic_namespace/requires_path.stderr b/tests/ui/diagnostic_namespace/requires_path.stderr index 7f7162a861135..beb7f5cbf31d0 100644 --- a/tests/ui/diagnostic_namespace/requires_path.stderr +++ b/tests/ui/diagnostic_namespace/requires_path.stderr @@ -1,8 +1,8 @@ -error: cannot find attribute `diagnostic` in this scope +error: cannot find attribute `diagnostic` in the crate root --> $DIR/requires_path.rs:1:3 | LL | #[diagnostic] - | ^^^^^^^^^^ not found in this scope + | ^^^^^^^^^^ not found in the crate root error: aborting due to 1 previous error diff --git a/tests/ui/enum/suggest-default-attribute.stderr b/tests/ui/enum/suggest-default-attribute.stderr index 217d971a0cc9d..aa65a2ec8f8c4 100644 --- a/tests/ui/enum/suggest-default-attribute.stderr +++ b/tests/ui/enum/suggest-default-attribute.stderr @@ -1,8 +1,8 @@ -error: cannot find attribute `default` in this scope +error: cannot find attribute `default` in enum `Test` --> $DIR/suggest-default-attribute.rs:2:7 | LL | #[default] - | ^^^^^^^ not found in this scope + | ^^^^^^^ not found in enum `Test` | help: consider adding a derive | diff --git a/tests/ui/feature-gates/feature-gate-custom_attribute.stderr b/tests/ui/feature-gates/feature-gate-custom_attribute.stderr index 9901dff87ec16..c628a7bf72c26 100644 --- a/tests/ui/feature-gates/feature-gate-custom_attribute.stderr +++ b/tests/ui/feature-gates/feature-gate-custom_attribute.stderr @@ -1,80 +1,80 @@ -error: cannot find attribute `fake_attr` in this scope +error: cannot find attribute `fake_attr` in the crate root --> $DIR/feature-gate-custom_attribute.rs:3:3 | LL | #[fake_attr] - | ^^^^^^^^^ not found in this scope + | ^^^^^^^^^ not found in the crate root -error: cannot find attribute `fake_attr` in this scope +error: cannot find attribute `fake_attr` in the crate root --> $DIR/feature-gate-custom_attribute.rs:4:3 | LL | #[fake_attr(100)] - | ^^^^^^^^^ not found in this scope + | ^^^^^^^^^ not found in the crate root -error: cannot find attribute `fake_attr` in this scope +error: cannot find attribute `fake_attr` in the crate root --> $DIR/feature-gate-custom_attribute.rs:5:3 | LL | #[fake_attr(1, 2, 3)] - | ^^^^^^^^^ not found in this scope + | ^^^^^^^^^ not found in the crate root -error: cannot find attribute `fake_attr` in this scope +error: cannot find attribute `fake_attr` in the crate root --> $DIR/feature-gate-custom_attribute.rs:6:3 | LL | #[fake_attr("hello")] - | ^^^^^^^^^ not found in this scope + | ^^^^^^^^^ not found in the crate root -error: cannot find attribute `fake_attr` in this scope +error: cannot find attribute `fake_attr` in the crate root --> $DIR/feature-gate-custom_attribute.rs:7:3 | LL | #[fake_attr(name = "hello")] - | ^^^^^^^^^ not found in this scope + | ^^^^^^^^^ not found in the crate root -error: cannot find attribute `fake_attr` in this scope +error: cannot find attribute `fake_attr` in the crate root --> $DIR/feature-gate-custom_attribute.rs:8:3 | LL | #[fake_attr(1, "hi", key = 12, true, false)] - | ^^^^^^^^^ not found in this scope + | ^^^^^^^^^ not found in the crate root -error: cannot find attribute `fake_attr` in this scope +error: cannot find attribute `fake_attr` in the crate root --> $DIR/feature-gate-custom_attribute.rs:9:3 | LL | #[fake_attr(key = "hello", val = 10)] - | ^^^^^^^^^ not found in this scope + | ^^^^^^^^^ not found in the crate root -error: cannot find attribute `fake_attr` in this scope +error: cannot find attribute `fake_attr` in the crate root --> $DIR/feature-gate-custom_attribute.rs:10:3 | LL | #[fake_attr(key("hello"), val(10))] - | ^^^^^^^^^ not found in this scope + | ^^^^^^^^^ not found in the crate root -error: cannot find attribute `fake_attr` in this scope +error: cannot find attribute `fake_attr` in the crate root --> $DIR/feature-gate-custom_attribute.rs:11:3 | LL | #[fake_attr(enabled = true, disabled = false)] - | ^^^^^^^^^ not found in this scope + | ^^^^^^^^^ not found in the crate root -error: cannot find attribute `fake_attr` in this scope +error: cannot find attribute `fake_attr` in the crate root --> $DIR/feature-gate-custom_attribute.rs:12:3 | LL | #[fake_attr(true)] - | ^^^^^^^^^ not found in this scope + | ^^^^^^^^^ not found in the crate root -error: cannot find attribute `fake_attr` in this scope +error: cannot find attribute `fake_attr` in the crate root --> $DIR/feature-gate-custom_attribute.rs:13:3 | LL | #[fake_attr(pi = 3.14159)] - | ^^^^^^^^^ not found in this scope + | ^^^^^^^^^ not found in the crate root -error: cannot find attribute `fake_attr` in this scope +error: cannot find attribute `fake_attr` in the crate root --> $DIR/feature-gate-custom_attribute.rs:14:3 | LL | #[fake_attr(b"hi")] - | ^^^^^^^^^ not found in this scope + | ^^^^^^^^^ not found in the crate root -error: cannot find attribute `fake_doc` in this scope +error: cannot find attribute `fake_doc` in the crate root --> $DIR/feature-gate-custom_attribute.rs:15:3 | LL | #[fake_doc(r"doc")] - | ^^^^^^^^ not found in this scope + | ^^^^^^^^ not found in the crate root error: aborting due to 13 previous errors diff --git a/tests/ui/feature-gates/feature-gate-custom_attribute2.stderr b/tests/ui/feature-gates/feature-gate-custom_attribute2.stderr index 64c2f5dcbd1e7..3014af59cfe71 100644 --- a/tests/ui/feature-gates/feature-gate-custom_attribute2.stderr +++ b/tests/ui/feature-gates/feature-gate-custom_attribute2.stderr @@ -1,104 +1,104 @@ -error: cannot find attribute `lt_struct` in this scope +error: cannot find attribute `lt_struct` in the crate root --> $DIR/feature-gate-custom_attribute2.rs:4:15 | LL | struct StLt<#[lt_struct] 'a>(&'a u32); - | ^^^^^^^^^ not found in this scope + | ^^^^^^^^^ not found in the crate root -error: cannot find attribute `ty_struct` in this scope +error: cannot find attribute `ty_struct` in the crate root --> $DIR/feature-gate-custom_attribute2.rs:6:15 | LL | struct StTy<#[ty_struct] I>(I); - | ^^^^^^^^^ not found in this scope + | ^^^^^^^^^ not found in the crate root -error: cannot find attribute `lt_enum` in this scope +error: cannot find attribute `lt_enum` in enum `EnLt` --> $DIR/feature-gate-custom_attribute2.rs:9:13 | LL | enum EnLt<#[lt_enum] 'b> { A(&'b u32), B } - | ^^^^^^^ not found in this scope + | ^^^^^^^ not found in enum `EnLt` -error: cannot find attribute `ty_enum` in this scope +error: cannot find attribute `ty_enum` in enum `EnTy` --> $DIR/feature-gate-custom_attribute2.rs:11:13 | LL | enum EnTy<#[ty_enum] J> { A(J), B } - | ^^^^^^^ not found in this scope + | ^^^^^^^ not found in enum `EnTy` -error: cannot find attribute `lt_trait` in this scope +error: cannot find attribute `lt_trait` in trait `TrLt` --> $DIR/feature-gate-custom_attribute2.rs:14:14 | LL | trait TrLt<#[lt_trait] 'c> { fn foo(&self, _: &'c [u32]) -> &'c u32; } - | ^^^^^^^^ not found in this scope + | ^^^^^^^^ not found in trait `TrLt` -error: cannot find attribute `ty_trait` in this scope +error: cannot find attribute `ty_trait` in trait `TrTy` --> $DIR/feature-gate-custom_attribute2.rs:16:14 | LL | trait TrTy<#[ty_trait] K> { fn foo(&self, _: K); } - | ^^^^^^^^ not found in this scope + | ^^^^^^^^ not found in trait `TrTy` -error: cannot find attribute `lt_type` in this scope +error: cannot find attribute `lt_type` in the crate root --> $DIR/feature-gate-custom_attribute2.rs:19:13 | LL | type TyLt<#[lt_type] 'd> = &'d u32; - | ^^^^^^^ not found in this scope + | ^^^^^^^ not found in the crate root -error: cannot find attribute `ty_type` in this scope +error: cannot find attribute `ty_type` in the crate root --> $DIR/feature-gate-custom_attribute2.rs:21:13 | LL | type TyTy<#[ty_type] L> = (L, ); - | ^^^^^^^ not found in this scope + | ^^^^^^^ not found in the crate root -error: cannot find attribute `lt_inherent` in this scope +error: cannot find attribute `lt_inherent` in the crate root --> $DIR/feature-gate-custom_attribute2.rs:24:8 | LL | impl<#[lt_inherent] 'e> StLt<'e> { } - | ^^^^^^^^^^^ not found in this scope + | ^^^^^^^^^^^ not found in the crate root -error: cannot find attribute `ty_inherent` in this scope +error: cannot find attribute `ty_inherent` in the crate root --> $DIR/feature-gate-custom_attribute2.rs:26:8 | LL | impl<#[ty_inherent] M> StTy { } - | ^^^^^^^^^^^ not found in this scope + | ^^^^^^^^^^^ not found in the crate root -error: cannot find attribute `lt_impl_for` in this scope +error: cannot find attribute `lt_impl_for` in the crate root --> $DIR/feature-gate-custom_attribute2.rs:29:8 | LL | impl<#[lt_impl_for] 'f> TrLt<'f> for StLt<'f> { - | ^^^^^^^^^^^ not found in this scope + | ^^^^^^^^^^^ not found in the crate root -error: cannot find attribute `ty_impl_for` in this scope +error: cannot find attribute `ty_impl_for` in the crate root --> $DIR/feature-gate-custom_attribute2.rs:33:8 | LL | impl<#[ty_impl_for] N> TrTy for StTy { - | ^^^^^^^^^^^ not found in this scope + | ^^^^^^^^^^^ not found in the crate root -error: cannot find attribute `lt_fn` in this scope +error: cannot find attribute `lt_fn` in the crate root --> $DIR/feature-gate-custom_attribute2.rs:38:11 | LL | fn f_lt<#[lt_fn] 'g>(_: &'g [u32]) -> &'g u32 { loop { } } - | ^^^^^ not found in this scope + | ^^^^^ not found in the crate root -error: cannot find attribute `ty_fn` in this scope +error: cannot find attribute `ty_fn` in the crate root --> $DIR/feature-gate-custom_attribute2.rs:40:11 | LL | fn f_ty<#[ty_fn] O>(_: O) { } - | ^^^^^ not found in this scope + | ^^^^^ not found in the crate root -error: cannot find attribute `lt_meth` in this scope +error: cannot find attribute `lt_meth` in the crate root --> $DIR/feature-gate-custom_attribute2.rs:44:15 | LL | fn m_lt<#[lt_meth] 'h>(_: &'h [u32]) -> &'h u32 { loop { } } - | ^^^^^^^ not found in this scope + | ^^^^^^^ not found in the crate root -error: cannot find attribute `ty_meth` in this scope +error: cannot find attribute `ty_meth` in the crate root --> $DIR/feature-gate-custom_attribute2.rs:46:15 | LL | fn m_ty<#[ty_meth] P>(_: P) { } - | ^^^^^^^ not found in this scope + | ^^^^^^^ not found in the crate root -error: cannot find attribute `lt_hof` in this scope +error: cannot find attribute `lt_hof` in the crate root --> $DIR/feature-gate-custom_attribute2.rs:51:21 | LL | where Q: for <#[lt_hof] 'i> Fn(&'i [u32]) -> &'i u32 - | ^^^^^^ not found in this scope + | ^^^^^^ not found in the crate root error: aborting due to 17 previous errors diff --git a/tests/ui/feature-gates/feature-gate-rustc-attrs.stderr b/tests/ui/feature-gates/feature-gate-rustc-attrs.stderr index b49d299d522de..4aaa657822e3f 100644 --- a/tests/ui/feature-gates/feature-gate-rustc-attrs.stderr +++ b/tests/ui/feature-gates/feature-gate-rustc-attrs.stderr @@ -28,11 +28,11 @@ error: attributes starting with `rustc` are reserved for use by the `rustc` comp LL | #[rustc_unknown] | ^^^^^^^^^^^^^ -error: cannot find attribute `rustc_unknown` in this scope +error: cannot find attribute `rustc_unknown` in the crate root --> $DIR/feature-gate-rustc-attrs.rs:20:3 | LL | #[rustc_unknown] - | ^^^^^^^^^^^^^ not found in this scope + | ^^^^^^^^^^^^^ not found in the crate root error[E0658]: the `#[rustc_dummy]` attribute is just used for rustc unit tests and will never be stable --> $DIR/feature-gate-rustc-attrs.rs:18:1 diff --git a/tests/ui/feature-gates/issue-43106-gating-of-derive-2.stderr b/tests/ui/feature-gates/issue-43106-gating-of-derive-2.stderr index 97f7fbaeaee26..f7f5114c11f01 100644 --- a/tests/ui/feature-gates/issue-43106-gating-of-derive-2.stderr +++ b/tests/ui/feature-gates/issue-43106-gating-of-derive-2.stderr @@ -1,42 +1,42 @@ -error: cannot find derive macro `x3300` in this scope +error: cannot find derive macro `x3300` in module `derive` --> $DIR/issue-43106-gating-of-derive-2.rs:14:14 | LL | #[derive(x3300)] - | ^^^^^ not found in this scope + | ^^^^^ not found in module `derive` -error: cannot find derive macro `x3300` in this scope +error: cannot find derive macro `x3300` in module `derive` --> $DIR/issue-43106-gating-of-derive-2.rs:14:14 | LL | #[derive(x3300)] - | ^^^^^ not found in this scope + | ^^^^^ not found in module `derive` | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error: cannot find derive macro `x3300` in this scope +error: cannot find derive macro `x3300` in module `derive` --> $DIR/issue-43106-gating-of-derive-2.rs:9:14 | LL | #[derive(x3300)] - | ^^^^^ not found in this scope + | ^^^^^ not found in module `derive` -error: cannot find derive macro `x3300` in this scope +error: cannot find derive macro `x3300` in module `derive` --> $DIR/issue-43106-gating-of-derive-2.rs:9:14 | LL | #[derive(x3300)] - | ^^^^^ not found in this scope + | ^^^^^ not found in module `derive` | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error: cannot find derive macro `x3300` in this scope +error: cannot find derive macro `x3300` in module `derive` --> $DIR/issue-43106-gating-of-derive-2.rs:4:14 | LL | #[derive(x3300)] - | ^^^^^ not found in this scope + | ^^^^^ not found in module `derive` -error: cannot find derive macro `x3300` in this scope +error: cannot find derive macro `x3300` in module `derive` --> $DIR/issue-43106-gating-of-derive-2.rs:4:14 | LL | #[derive(x3300)] - | ^^^^^ not found in this scope + | ^^^^^ not found in module `derive` | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` diff --git a/tests/ui/issues/issue-19734.stderr b/tests/ui/issues/issue-19734.stderr index 6023045e98360..0b79d04ee349a 100644 --- a/tests/ui/issues/issue-19734.stderr +++ b/tests/ui/issues/issue-19734.stderr @@ -1,8 +1,8 @@ -error: cannot find macro `undef` in this scope +error: cannot find macro `undef` in the crate root --> $DIR/issue-19734.rs:6:5 | LL | undef!(); - | ^^^^^ not found in this scope + | ^^^^^ not found in the crate root error: aborting due to 1 previous error diff --git a/tests/ui/issues/issue-32655.stderr b/tests/ui/issues/issue-32655.stderr index 2b4240b2d9b50..fff7a9c687930 100644 --- a/tests/ui/issues/issue-32655.stderr +++ b/tests/ui/issues/issue-32655.stderr @@ -1,10 +1,10 @@ -error: cannot find attribute `derive_Clone` in this scope +error: cannot find attribute `derive_Clone` in the crate root --> $DIR/issue-32655.rs:3:11 | LL | #[derive_Clone] | ^^^^^^^^^^^^ | | - | not found in this scope + | not found in the crate root | help: an attribute macro with a similar name exists: `derive_const` ... LL | foo!(); @@ -15,13 +15,13 @@ LL | foo!(); | = note: this error originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info) -error: cannot find attribute `derive_Clone` in this scope +error: cannot find attribute `derive_Clone` in the crate root --> $DIR/issue-32655.rs:15:7 | LL | #[derive_Clone] | ^^^^^^^^^^^^ | | - | not found in this scope + | not found in the crate root | help: an attribute macro with a similar name exists: `derive_const` --> $SRC_DIR/core/src/macros/mod.rs:LL:COL | diff --git a/tests/ui/issues/issue-33571.stderr b/tests/ui/issues/issue-33571.stderr index 06fe0d5ae270a..b97dd30d34037 100644 --- a/tests/ui/issues/issue-33571.stderr +++ b/tests/ui/issues/issue-33571.stderr @@ -1,8 +1,8 @@ -error: cannot find derive macro `Sync` in this scope +error: cannot find derive macro `Sync` in the crate root --> $DIR/issue-33571.rs:2:10 | LL | Sync, - | ^^^^ not found in this scope + | ^^^^ not found in the crate root | note: unsafe traits like `Sync` should be implemented explicitly --> $DIR/issue-33571.rs:2:10 @@ -10,11 +10,11 @@ note: unsafe traits like `Sync` should be implemented explicitly LL | Sync, | ^^^^ -error: cannot find derive macro `Sync` in this scope +error: cannot find derive macro `Sync` in the crate root --> $DIR/issue-33571.rs:2:10 | LL | Sync, - | ^^^^ not found in this scope + | ^^^^ not found in the crate root | note: unsafe traits like `Sync` should be implemented explicitly --> $DIR/issue-33571.rs:2:10 diff --git a/tests/ui/issues/issue-40845.stderr b/tests/ui/issues/issue-40845.stderr index 18d62d9eb5ad3..9a01e749f6479 100644 --- a/tests/ui/issues/issue-40845.stderr +++ b/tests/ui/issues/issue-40845.stderr @@ -1,14 +1,14 @@ -error: cannot find macro `m` in this scope +error: cannot find macro `m` in trait `T` --> $DIR/issue-40845.rs:1:11 | LL | trait T { m!(); } - | ^ not found in this scope + | ^ not found in trait `T` -error: cannot find macro `m` in this scope +error: cannot find macro `m` in the crate root --> $DIR/issue-40845.rs:4:10 | LL | impl S { m!(); } - | ^ not found in this scope + | ^ not found in the crate root error: aborting due to 2 previous errors diff --git a/tests/ui/macros/issue-118786.stderr b/tests/ui/macros/issue-118786.stderr index 58342386b78b2..0b0e1ae563d08 100644 --- a/tests/ui/macros/issue-118786.stderr +++ b/tests/ui/macros/issue-118786.stderr @@ -24,11 +24,11 @@ LL | make_macro!((meow)); | = note: the usage of `make_macro!` is likely invalid in item context -error: cannot find macro `macro_rules` in this scope +error: cannot find macro `macro_rules` in the crate root --> $DIR/issue-118786.rs:7:9 | LL | macro_rules! $macro_name { - | ^^^^^^^^^^^ not found in this scope + | ^^^^^^^^^^^ not found in the crate root ... LL | make_macro!((meow)); | ------------------- in this macro invocation diff --git a/tests/ui/macros/issue-88206.rs b/tests/ui/macros/issue-88206.rs index 89995296a388f..3da5f1b4a971a 100644 --- a/tests/ui/macros/issue-88206.rs +++ b/tests/ui/macros/issue-88206.rs @@ -21,57 +21,57 @@ use hey::{Serialize, Deserialize, X}; #[derive(Serialize)] //~^ ERROR cannot find derive macro `Serialize` -//~| NOTE not found in this scope +//~| NOTE not found struct A; #[derive(from_utf8_mut)] //~^ ERROR cannot find derive macro `from_utf8_mut` -//~| NOTE not found in this scope +//~| NOTE not found struct B; #[derive(println)] //~^ ERROR cannot find derive macro `println` //~| NOTE `println` is in scope, but it is a function-like macro -//~| NOTE not found in this scope +//~| NOTE not found struct C; #[Deserialize] //~^ ERROR cannot find attribute `Deserialize` -//~| NOTE not found in this scope +//~| NOTE not found struct D; #[from_utf8_unchecked] //~^ ERROR cannot find attribute `from_utf8_unchecked` -//~| NOTE not found in this scope +//~| NOTE not found struct E; #[println] //~^ ERROR cannot find attribute `println` //~| NOTE `println` is in scope, but it is a function-like macro -//~| NOTE not found in this scope +//~| NOTE not found struct F; fn main() { from_utf8!(); //~^ ERROR cannot find macro `from_utf8` - //~| NOTE not found in this scope + //~| NOTE not found Box!(); //~^ ERROR cannot find macro `Box` //~| NOTE `Box` is in scope, but it is a struct - //~| NOTE not found in this scope + //~| NOTE not found Copy!(); //~^ ERROR cannot find macro `Copy` //~| NOTE `Copy` is in scope, but it is a derive macro - //~| NOTE not found in this scope + //~| NOTE not found test!(); //~^ ERROR cannot find macro `test` //~| NOTE `test` is in scope, but it is an attribute - //~| NOTE not found in this scope + //~| NOTE not found X!(); //~^ ERROR cannot find macro `X` - //~| NOTE not found in this scope + //~| NOTE not found } diff --git a/tests/ui/macros/issue-88206.stderr b/tests/ui/macros/issue-88206.stderr index b109001b0c96d..f5ed308ca59ac 100644 --- a/tests/ui/macros/issue-88206.stderr +++ b/tests/ui/macros/issue-88206.stderr @@ -46,19 +46,19 @@ note: `from_utf8` is imported here, but it is a function, not a macro LL | use std::str::*; | ^^^^^^^^^^^ -error: cannot find attribute `println` in this scope +error: cannot find attribute `println` in the crate root --> $DIR/issue-88206.rs:48:3 | LL | #[println] - | ^^^^^^^ not found in this scope + | ^^^^^^^ not found in the crate root | = note: `println` is in scope, but it is a function-like macro -error: cannot find attribute `from_utf8_unchecked` in this scope +error: cannot find attribute `from_utf8_unchecked` in the crate root --> $DIR/issue-88206.rs:43:3 | LL | #[from_utf8_unchecked] - | ^^^^^^^^^^^^^^^^^^^ not found in this scope + | ^^^^^^^^^^^^^^^^^^^ not found in the crate root | note: `from_utf8_unchecked` is imported here, but it is a function, not an attribute --> $DIR/issue-88206.rs:5:5 @@ -66,11 +66,11 @@ note: `from_utf8_unchecked` is imported here, but it is a function, not an attri LL | use std::str::*; | ^^^^^^^^^^^ -error: cannot find attribute `Deserialize` in this scope +error: cannot find attribute `Deserialize` in the crate root --> $DIR/issue-88206.rs:38:3 | LL | #[Deserialize] - | ^^^^^^^^^^^ not found in this scope + | ^^^^^^^^^^^ not found in the crate root | note: `Deserialize` is imported here, but it is a trait, not an attribute --> $DIR/issue-88206.rs:17:22 @@ -78,19 +78,19 @@ note: `Deserialize` is imported here, but it is a trait, not an attribute LL | use hey::{Serialize, Deserialize, X}; | ^^^^^^^^^^^ -error: cannot find derive macro `println` in this scope +error: cannot find derive macro `println` in the crate root --> $DIR/issue-88206.rs:32:10 | LL | #[derive(println)] - | ^^^^^^^ not found in this scope + | ^^^^^^^ not found in the crate root | = note: `println` is in scope, but it is a function-like macro -error: cannot find derive macro `from_utf8_mut` in this scope +error: cannot find derive macro `from_utf8_mut` in the crate root --> $DIR/issue-88206.rs:27:10 | LL | #[derive(from_utf8_mut)] - | ^^^^^^^^^^^^^ not found in this scope + | ^^^^^^^^^^^^^ not found in the crate root | note: `from_utf8_mut` is imported here, but it is a function, not a derive macro --> $DIR/issue-88206.rs:5:5 @@ -98,11 +98,11 @@ note: `from_utf8_mut` is imported here, but it is a function, not a derive macro LL | use std::str::*; | ^^^^^^^^^^^ -error: cannot find derive macro `Serialize` in this scope +error: cannot find derive macro `Serialize` in the crate root --> $DIR/issue-88206.rs:22:10 | LL | #[derive(Serialize)] - | ^^^^^^^^^ not found in this scope + | ^^^^^^^^^ not found in the crate root | note: `Serialize` is imported here, but it is only a trait, without a derive macro --> $DIR/issue-88206.rs:17:11 diff --git a/tests/ui/macros/issue-88228.stderr b/tests/ui/macros/issue-88228.stderr index 32b430b82590e..2b2a181d5b554 100644 --- a/tests/ui/macros/issue-88228.stderr +++ b/tests/ui/macros/issue-88228.stderr @@ -9,19 +9,19 @@ help: consider importing this macro through its public re-export LL + use crate::hey::bla; | -error: cannot find derive macro `println` in this scope +error: cannot find derive macro `println` in the crate root --> $DIR/issue-88228.rs:14:10 | LL | #[derive(println)] - | ^^^^^^^ not found in this scope + | ^^^^^^^ not found in the crate root | = note: `println` is in scope, but it is a function-like macro -error: cannot find derive macro `Bla` in this scope +error: cannot find derive macro `Bla` in the crate root --> $DIR/issue-88228.rs:10:10 | LL | #[derive(Bla)] - | ^^^ not found in this scope + | ^^^ not found in the crate root | help: consider importing this derive macro through its public re-export | diff --git a/tests/ui/macros/macro-expand-within-generics-in-path.stderr b/tests/ui/macros/macro-expand-within-generics-in-path.stderr index 7e5a08fe4d3b3..70801fd8077ea 100644 --- a/tests/ui/macros/macro-expand-within-generics-in-path.stderr +++ b/tests/ui/macros/macro-expand-within-generics-in-path.stderr @@ -4,11 +4,11 @@ error: unexpected generic arguments in path LL | m!(generic); | ^^^^^^ -error: cannot find attribute `generic` in this scope +error: cannot find attribute `generic` in the crate root --> $DIR/macro-expand-within-generics-in-path.rs:15:4 | LL | m!(generic); - | ^^^^^^^ not found in this scope + | ^^^^^^^ not found in the crate root error: aborting due to 2 previous errors diff --git a/tests/ui/macros/macro-expansion-tests.stderr b/tests/ui/macros/macro-expansion-tests.stderr index 01f6d12cadd2e..dea12de8774cc 100644 --- a/tests/ui/macros/macro-expansion-tests.stderr +++ b/tests/ui/macros/macro-expansion-tests.stderr @@ -1,16 +1,16 @@ -error: cannot find macro `m` in this scope +error: cannot find macro `m` in module `macros_cant_escape_fns` --> $DIR/macro-expansion-tests.rs:7:21 | LL | fn g() -> i32 { m!() } - | ^ not found in this scope + | ^ not found in module `macros_cant_escape_fns` | = help: have you added the `#[macro_use]` on the module/import? -error: cannot find macro `m` in this scope +error: cannot find macro `m` in module `macros_cant_escape_mods` --> $DIR/macro-expansion-tests.rs:15:21 | LL | fn g() -> i32 { m!() } - | ^ not found in this scope + | ^ not found in module `macros_cant_escape_mods` | = help: have you added the `#[macro_use]` on the module/import? diff --git a/tests/ui/macros/macro-reexport-removed.stderr b/tests/ui/macros/macro-reexport-removed.stderr index d05c9c848c47e..918fde10cc134 100644 --- a/tests/ui/macros/macro-reexport-removed.stderr +++ b/tests/ui/macros/macro-reexport-removed.stderr @@ -6,13 +6,13 @@ LL | #![feature(macro_reexport)] | = note: subsumed by `pub use` -error: cannot find attribute `macro_reexport` in this scope +error: cannot find attribute `macro_reexport` in the crate root --> $DIR/macro-reexport-removed.rs:5:3 | LL | #[macro_reexport(macro_one)] | ^^^^^^^^^^^^^^ | | - | not found in this scope + | not found in the crate root | help: a built-in attribute with a similar name exists: `macro_export` error: aborting due to 2 previous errors diff --git a/tests/ui/parser/attribute/multiple-tail-expr-behind-cfg.stderr b/tests/ui/parser/attribute/multiple-tail-expr-behind-cfg.stderr index 79a34a887c8e3..70f3c1de199c0 100644 --- a/tests/ui/parser/attribute/multiple-tail-expr-behind-cfg.stderr +++ b/tests/ui/parser/attribute/multiple-tail-expr-behind-cfg.stderr @@ -44,11 +44,11 @@ help: alternatively, consider surrounding the expression with a block LL | { [1, 2, 3].iter().map(|c| c.to_string()).collect::() } | + + -error: cannot find attribute `attr` in this scope +error: cannot find attribute `attr` in the crate root --> $DIR/multiple-tail-expr-behind-cfg.rs:13:7 | LL | #[attr] - | ^^^^ not found in this scope + | ^^^^ not found in the crate root error: aborting due to 3 previous errors diff --git a/tests/ui/parser/default-unmatched-assoc.stderr b/tests/ui/parser/default-unmatched-assoc.stderr index fe904e9a13631..511371555a954 100644 --- a/tests/ui/parser/default-unmatched-assoc.stderr +++ b/tests/ui/parser/default-unmatched-assoc.stderr @@ -38,17 +38,17 @@ LL | default do LL | } | - item list ends here -error: cannot find macro `default` in this scope +error: cannot find macro `default` in trait `Foo` --> $DIR/default-unmatched-assoc.rs:4:5 | LL | default!(); - | ^^^^^^^ not found in this scope + | ^^^^^^^ not found in trait `Foo` -error: cannot find macro `default` in this scope +error: cannot find macro `default` in the crate root --> $DIR/default-unmatched-assoc.rs:12:5 | LL | default!(); - | ^^^^^^^ not found in this scope + | ^^^^^^^ not found in the crate root error: aborting due to 6 previous errors diff --git a/tests/ui/parser/default-unmatched-extern.stderr b/tests/ui/parser/default-unmatched-extern.stderr index 5333621163ffd..9a01a80b9a1fe 100644 --- a/tests/ui/parser/default-unmatched-extern.stderr +++ b/tests/ui/parser/default-unmatched-extern.stderr @@ -18,11 +18,11 @@ LL | default do LL | } | - item list ends here -error: cannot find macro `default` in this scope +error: cannot find macro `default` in the crate root --> $DIR/default-unmatched-extern.rs:4:5 | LL | default!(); - | ^^^^^^^ not found in this scope + | ^^^^^^^ not found in the crate root error: aborting due to 3 previous errors diff --git a/tests/ui/parser/issues/issue-118531-ice.stderr b/tests/ui/parser/issues/issue-118531-ice.stderr index adf883274ecb6..b838cb031201e 100644 --- a/tests/ui/parser/issues/issue-118531-ice.stderr +++ b/tests/ui/parser/issues/issue-118531-ice.stderr @@ -28,11 +28,11 @@ LL | #[attr] = help: add `#![feature(stmt_expr_attributes)]` 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: cannot find attribute `attr` in this scope +error: cannot find attribute `attr` in the crate root --> $DIR/issue-118531-ice.rs:5:7 | LL | #[attr] - | ^^^^ not found in this scope + | ^^^^ not found in the crate root error: aborting due to 3 previous errors diff --git a/tests/ui/proc-macro/derive-helper-legacy-limits.stderr b/tests/ui/proc-macro/derive-helper-legacy-limits.stderr index 28924782ae912..aaf9ef1d34291 100644 --- a/tests/ui/proc-macro/derive-helper-legacy-limits.stderr +++ b/tests/ui/proc-macro/derive-helper-legacy-limits.stderr @@ -1,8 +1,8 @@ -error: cannot find attribute `empty_helper` in this scope +error: cannot find attribute `empty_helper` in the crate root --> $DIR/derive-helper-legacy-limits.rs:17:3 | LL | #[empty_helper] - | ^^^^^^^^^^^^ not found in this scope + | ^^^^^^^^^^^^ not found in the crate root error: aborting due to 1 previous error diff --git a/tests/ui/proc-macro/derive-helper-legacy-spurious.stderr b/tests/ui/proc-macro/derive-helper-legacy-spurious.stderr index 4f857573e27d5..58e47eb8cb170 100644 --- a/tests/ui/proc-macro/derive-helper-legacy-spurious.stderr +++ b/tests/ui/proc-macro/derive-helper-legacy-spurious.stderr @@ -1,14 +1,14 @@ -error: cannot find attribute `dummy` in this scope +error: cannot find attribute `dummy` in the crate root --> $DIR/derive-helper-legacy-spurious.rs:3:4 | LL | #![dummy] - | ^^^^^ not found in this scope + | ^^^^^ not found in the crate root -error: cannot find attribute `empty_helper` in this scope +error: cannot find attribute `empty_helper` in the crate root --> $DIR/derive-helper-legacy-spurious.rs:9:3 | LL | #[empty_helper] - | ^^^^^^^^^^^^ not found in this scope + | ^^^^^^^^^^^^ not found in the crate root error: aborting due to 2 previous errors diff --git a/tests/ui/proc-macro/derive-helper-shadowing.stderr b/tests/ui/proc-macro/derive-helper-shadowing.stderr index b264348e74297..a7d5feb95b6f2 100644 --- a/tests/ui/proc-macro/derive-helper-shadowing.stderr +++ b/tests/ui/proc-macro/derive-helper-shadowing.stderr @@ -10,11 +10,11 @@ note: the derive helper attribute imported here LL | use empty_helper as renamed; | ^^^^^^^^^^^^^^^^^^^^^^^ -error: cannot find attribute `empty_helper` in this scope +error: cannot find attribute `empty_helper` in module `inner` --> $DIR/derive-helper-shadowing.rs:38:22 | LL | #[derive(GenHelperUse)] - | ^^^^^^^^^^^^ not found in this scope + | ^^^^^^^^^^^^ not found in module `inner` | = note: this error originates in the derive macro `GenHelperUse` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider importing this attribute macro through its public re-export @@ -22,11 +22,11 @@ help: consider importing this attribute macro through its public re-export LL + use empty_helper; | -error: cannot find attribute `empty_helper` in this scope +error: cannot find attribute `empty_helper` in module `inner` --> $DIR/derive-helper-shadowing.rs:14:11 | LL | #[empty_helper] - | ^^^^^^^^^^^^ not found in this scope + | ^^^^^^^^^^^^ not found in module `inner` ... LL | gen_helper_use!(); | ----------------- in this macro invocation diff --git a/tests/ui/proc-macro/derive-still-gated.stderr b/tests/ui/proc-macro/derive-still-gated.stderr index aa7cb951e1030..604cd6e1b1fed 100644 --- a/tests/ui/proc-macro/derive-still-gated.stderr +++ b/tests/ui/proc-macro/derive-still-gated.stderr @@ -1,8 +1,8 @@ -error: cannot find attribute `derive_Empty` in this scope +error: cannot find attribute `derive_Empty` in the crate root --> $DIR/derive-still-gated.rs:6:3 | LL | #[derive_Empty] - | ^^^^^^^^^^^^ not found in this scope + | ^^^^^^^^^^^^ not found in the crate root error: aborting due to 1 previous error diff --git a/tests/ui/proc-macro/disappearing-resolution.stderr b/tests/ui/proc-macro/disappearing-resolution.stderr index c5a217d8e5bc3..c767a9b29fc37 100644 --- a/tests/ui/proc-macro/disappearing-resolution.stderr +++ b/tests/ui/proc-macro/disappearing-resolution.stderr @@ -1,8 +1,8 @@ -error: cannot find attribute `empty_helper` in this scope +error: cannot find attribute `empty_helper` in the crate root --> $DIR/disappearing-resolution.rs:18:3 | LL | #[empty_helper] - | ^^^^^^^^^^^^ not found in this scope + | ^^^^^^^^^^^^ not found in the crate root error[E0603]: derive macro import `Empty` is private --> $DIR/disappearing-resolution.rs:11:8 diff --git a/tests/ui/proc-macro/issue-118455-skip-err-builtin.stderr b/tests/ui/proc-macro/issue-118455-skip-err-builtin.stderr index 0f4310e8e9db1..bec20f824d127 100644 --- a/tests/ui/proc-macro/issue-118455-skip-err-builtin.stderr +++ b/tests/ui/proc-macro/issue-118455-skip-err-builtin.stderr @@ -1,8 +1,8 @@ -error: cannot find attribute `some_nonexistent_attribute` in this scope +error: cannot find attribute `some_nonexistent_attribute` in the crate root --> $DIR/issue-118455-skip-err-builtin.rs:1:4 | LL | #![some_nonexistent_attribute] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ not found in this scope + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ not found in the crate root error: aborting due to 1 previous error diff --git a/tests/ui/proc-macro/macro-namespace-reserved-2.stderr b/tests/ui/proc-macro/macro-namespace-reserved-2.stderr index 2f8451cbfb35b..50f7e58ad8dcd 100644 --- a/tests/ui/proc-macro/macro-namespace-reserved-2.stderr +++ b/tests/ui/proc-macro/macro-namespace-reserved-2.stderr @@ -120,27 +120,27 @@ LL | MyTrait!(); | = note: `MyTrait` is in scope, but it is a derive macro: `#[derive(MyTrait)]` -error: cannot find attribute `my_macro` in this scope +error: cannot find attribute `my_macro` in the crate root --> $DIR/macro-namespace-reserved-2.rs:38:3 | LL | #[my_macro] - | ^^^^^^^^ not found in this scope + | ^^^^^^^^ not found in the crate root | = note: `my_macro` is in scope, but it is a function-like macro -error: cannot find derive macro `my_macro` in this scope +error: cannot find derive macro `my_macro` in the crate root --> $DIR/macro-namespace-reserved-2.rs:48:10 | LL | #[derive(my_macro)] - | ^^^^^^^^ not found in this scope + | ^^^^^^^^ not found in the crate root | = note: `my_macro` is in scope, but it is a function-like macro -error: cannot find derive macro `my_macro` in this scope +error: cannot find derive macro `my_macro` in the crate root --> $DIR/macro-namespace-reserved-2.rs:48:10 | LL | #[derive(my_macro)] - | ^^^^^^^^ not found in this scope + | ^^^^^^^^ not found in the crate root | = note: `my_macro` is in scope, but it is a function-like macro = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` diff --git a/tests/ui/proc-macro/proc-macro-attributes.stderr b/tests/ui/proc-macro/proc-macro-attributes.stderr index 4c2097700f933..f7342d6f79315 100644 --- a/tests/ui/proc-macro/proc-macro-attributes.stderr +++ b/tests/ui/proc-macro/proc-macro-attributes.stderr @@ -1,10 +1,10 @@ -error: cannot find attribute `C` in this scope +error: cannot find attribute `C` in the crate root --> $DIR/proc-macro-attributes.rs:9:3 | LL | #[C] | ^ | | - | not found in this scope + | not found in the crate root | help: a derive helper attribute with a similar name exists: `B` error[E0659]: `B` is ambiguous diff --git a/tests/ui/proc-macro/resolve-error.stderr b/tests/ui/proc-macro/resolve-error.stderr index 56700e4dc4cee..c21a6a98941ea 100644 --- a/tests/ui/proc-macro/resolve-error.stderr +++ b/tests/ui/proc-macro/resolve-error.stderr @@ -42,27 +42,27 @@ LL | FooWithLongNama!(); | not found in this scope | help: a macro with a similar name exists: `FooWithLongNam` -error: cannot find derive macro `attr_proc_macra` in this scope +error: cannot find derive macro `attr_proc_macra` in the crate root --> $DIR/resolve-error.rs:45:10 | LL | #[derive(attr_proc_macra)] - | ^^^^^^^^^^^^^^^ not found in this scope + | ^^^^^^^^^^^^^^^ not found in the crate root -error: cannot find derive macro `attr_proc_macra` in this scope +error: cannot find derive macro `attr_proc_macra` in the crate root --> $DIR/resolve-error.rs:45:10 | LL | #[derive(attr_proc_macra)] - | ^^^^^^^^^^^^^^^ not found in this scope + | ^^^^^^^^^^^^^^^ not found in the crate root | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error: cannot find derive macro `Dlona` in this scope +error: cannot find derive macro `Dlona` in the crate root --> $DIR/resolve-error.rs:40:10 | LL | #[derive(Dlona)] | ^^^^^ | | - | not found in this scope + | not found in the crate root | help: a derive macro with a similar name exists: `Clona` | ::: $DIR/auxiliary/derive-clona.rs:11:1 @@ -70,13 +70,13 @@ LL | #[derive(Dlona)] LL | pub fn derive_clonea(input: TokenStream) -> TokenStream { | ------------------------------------------------------- similarly named derive macro `Clona` defined here -error: cannot find derive macro `Dlona` in this scope +error: cannot find derive macro `Dlona` in the crate root --> $DIR/resolve-error.rs:40:10 | LL | #[derive(Dlona)] | ^^^^^ | | - | not found in this scope + | not found in the crate root | help: a derive macro with a similar name exists: `Clona` | ::: $DIR/auxiliary/derive-clona.rs:11:1 @@ -86,25 +86,25 @@ LL | pub fn derive_clonea(input: TokenStream) -> TokenStream { | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error: cannot find derive macro `Dlone` in this scope +error: cannot find derive macro `Dlone` in the crate root --> $DIR/resolve-error.rs:35:10 | LL | #[derive(Dlone)] | ^^^^^ | | - | not found in this scope + | not found in the crate root | help: a derive macro with a similar name exists: `Clone` --> $SRC_DIR/core/src/clone.rs:LL:COL | = note: similarly named derive macro `Clone` defined here -error: cannot find derive macro `Dlone` in this scope +error: cannot find derive macro `Dlone` in the crate root --> $DIR/resolve-error.rs:35:10 | LL | #[derive(Dlone)] | ^^^^^ | | - | not found in this scope + | not found in the crate root | help: a derive macro with a similar name exists: `Clone` --> $SRC_DIR/core/src/clone.rs:LL:COL | @@ -112,19 +112,19 @@ LL | #[derive(Dlone)] | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error: cannot find attribute `FooWithLongNan` in this scope +error: cannot find attribute `FooWithLongNan` in the crate root --> $DIR/resolve-error.rs:32:3 | LL | #[FooWithLongNan] - | ^^^^^^^^^^^^^^ not found in this scope + | ^^^^^^^^^^^^^^ not found in the crate root -error: cannot find attribute `attr_proc_macra` in this scope +error: cannot find attribute `attr_proc_macra` in the crate root --> $DIR/resolve-error.rs:28:3 | LL | #[attr_proc_macra] | ^^^^^^^^^^^^^^^ | | - | not found in this scope + | not found in the crate root | help: an attribute macro with a similar name exists: `attr_proc_macro` | ::: $DIR/auxiliary/test-macros.rs:20:1 @@ -132,13 +132,13 @@ LL | #[attr_proc_macra] LL | pub fn empty_attr(_: TokenStream, _: TokenStream) -> TokenStream { | ---------------------------------------------------------------- similarly named attribute macro `attr_proc_macro` defined here -error: cannot find derive macro `FooWithLongNan` in this scope +error: cannot find derive macro `FooWithLongNan` in the crate root --> $DIR/resolve-error.rs:22:10 | LL | #[derive(FooWithLongNan)] | ^^^^^^^^^^^^^^ | | - | not found in this scope + | not found in the crate root | help: a derive macro with a similar name exists: `FooWithLongName` | ::: $DIR/auxiliary/derive-foo.rs:11:1 @@ -146,13 +146,13 @@ LL | #[derive(FooWithLongNan)] LL | pub fn derive_foo(input: TokenStream) -> TokenStream { | ---------------------------------------------------- similarly named derive macro `FooWithLongName` defined here -error: cannot find derive macro `FooWithLongNan` in this scope +error: cannot find derive macro `FooWithLongNan` in the crate root --> $DIR/resolve-error.rs:22:10 | LL | #[derive(FooWithLongNan)] | ^^^^^^^^^^^^^^ | | - | not found in this scope + | not found in the crate root | help: a derive macro with a similar name exists: `FooWithLongName` | ::: $DIR/auxiliary/derive-foo.rs:11:1 diff --git a/tests/ui/reserved/reserved-attr-on-macro.stderr b/tests/ui/reserved/reserved-attr-on-macro.stderr index c0d4c29390caa..8e371c28bee9c 100644 --- a/tests/ui/reserved/reserved-attr-on-macro.stderr +++ b/tests/ui/reserved/reserved-attr-on-macro.stderr @@ -4,11 +4,11 @@ error: attributes starting with `rustc` are reserved for use by the `rustc` comp LL | #[rustc_attribute_should_be_reserved] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: cannot find attribute `rustc_attribute_should_be_reserved` in this scope +error: cannot find attribute `rustc_attribute_should_be_reserved` in the crate root --> $DIR/reserved-attr-on-macro.rs:1:3 | LL | #[rustc_attribute_should_be_reserved] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not found in this scope + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not found in the crate root error: aborting due to 2 previous errors diff --git a/tests/ui/resolve/issue-118295.rs b/tests/ui/resolve/issue-118295.rs index 31dba3381e49d..892e061d207d9 100644 --- a/tests/ui/resolve/issue-118295.rs +++ b/tests/ui/resolve/issue-118295.rs @@ -1,6 +1,6 @@ macro_rules! {} //~^ ERROR cannot find macro `macro_rules` -//~| NOTE not found in this scope +//~| NOTE not found in //~| NOTE maybe you have forgotten to define a name for this `macro_rules!` fn main() {} diff --git a/tests/ui/resolve/issue-118295.stderr b/tests/ui/resolve/issue-118295.stderr index fecd1ad1a595a..edee27c77f19d 100644 --- a/tests/ui/resolve/issue-118295.stderr +++ b/tests/ui/resolve/issue-118295.stderr @@ -1,8 +1,8 @@ -error: cannot find macro `macro_rules` in this scope +error: cannot find macro `macro_rules` in the crate root --> $DIR/issue-118295.rs:1:1 | LL | macro_rules! {} - | ^^^^^^^^^^^ not found in this scope + | ^^^^^^^^^^^ not found in the crate root | note: maybe you have forgotten to define a name for this `macro_rules!` --> $DIR/issue-118295.rs:1:1 diff --git a/tests/ui/resolve/issue-49074.stderr b/tests/ui/resolve/issue-49074.stderr index 0cae266c9a9fb..c8154b4844544 100644 --- a/tests/ui/resolve/issue-49074.stderr +++ b/tests/ui/resolve/issue-49074.stderr @@ -6,13 +6,13 @@ LL | bar!(); | = help: have you added the `#[macro_use]` on the module/import? -error: cannot find attribute `marco_use` in this scope +error: cannot find attribute `marco_use` in the crate root --> $DIR/issue-49074.rs:3:3 | LL | #[marco_use] // typo | ^^^^^^^^^ | | - | not found in this scope + | not found in the crate root | help: a built-in attribute with a similar name exists: `macro_use` error: aborting due to 2 previous errors diff --git a/tests/ui/resolve/path-attr-in-const-block.stderr b/tests/ui/resolve/path-attr-in-const-block.stderr index 8231757ec62a2..dfb89a04ca152 100644 --- a/tests/ui/resolve/path-attr-in-const-block.stderr +++ b/tests/ui/resolve/path-attr-in-const-block.stderr @@ -1,8 +1,8 @@ -error: cannot find macro `foo` in this scope +error: cannot find macro `foo` in the crate root --> $DIR/path-attr-in-const-block.rs:6:19 | LL | #![path = foo!()] - | ^^^ not found in this scope + | ^^^ not found in the crate root error: aborting due to 1 previous error diff --git a/tests/ui/resolve/visibility-indeterminate.stderr b/tests/ui/resolve/visibility-indeterminate.stderr index b4ca10a0a84af..d3ba907147f7d 100644 --- a/tests/ui/resolve/visibility-indeterminate.stderr +++ b/tests/ui/resolve/visibility-indeterminate.stderr @@ -4,11 +4,11 @@ error[E0578]: cannot determine resolution for the visibility LL | pub(in ::bar) struct Baz {} | ^^^^^ -error: cannot find macro `foo` in this scope +error: cannot find macro `foo` in the crate root --> $DIR/visibility-indeterminate.rs:3:1 | LL | foo!(); - | ^^^ not found in this scope + | ^^^ not found in the crate root error: aborting due to 2 previous errors diff --git a/tests/ui/self/self_type_keyword.stderr b/tests/ui/self/self_type_keyword.stderr index 1275158cba88a..a2dd8869bcd06 100644 --- a/tests/ui/self/self_type_keyword.stderr +++ b/tests/ui/self/self_type_keyword.stderr @@ -54,11 +54,11 @@ error: lifetimes cannot use keyword names LL | struct Bar<'Self>; | ^^^^^ -error: cannot find macro `Self` in this scope +error: cannot find macro `Self` in the crate root --> $DIR/self_type_keyword.rs:21:9 | LL | Self!() => (), - | ^^^^ not found in this scope + | ^^^^ not found in the crate root error[E0531]: cannot find unit struct, unit variant or constant `Self` in this scope --> $DIR/self_type_keyword.rs:16:13 diff --git a/tests/ui/suggestions/attribute-typos.stderr b/tests/ui/suggestions/attribute-typos.stderr index 1791d8c7ff4bb..44814ec1244a3 100644 --- a/tests/ui/suggestions/attribute-typos.stderr +++ b/tests/ui/suggestions/attribute-typos.stderr @@ -4,34 +4,34 @@ error: attributes starting with `rustc` are reserved for use by the `rustc` comp LL | #[rustc_err] | ^^^^^^^^^ -error: cannot find attribute `rustc_err` in this scope +error: cannot find attribute `rustc_err` in the crate root --> $DIR/attribute-typos.rs:7:3 | LL | #[rustc_err] | ^^^^^^^^^ | | - | not found in this scope + | not found in the crate root | help: a built-in attribute with a similar name exists: `rustc_error` -error: cannot find attribute `tests` in this scope +error: cannot find attribute `tests` in the crate root --> $DIR/attribute-typos.rs:4:3 | LL | #[tests] | ^^^^^ | | - | not found in this scope + | not found in the crate root | help: an attribute macro with a similar name exists: `test` --> $SRC_DIR/core/src/macros/mod.rs:LL:COL | = note: similarly named attribute macro `test` defined here -error: cannot find attribute `deprcated` in this scope +error: cannot find attribute `deprcated` in the crate root --> $DIR/attribute-typos.rs:1:3 | LL | #[deprcated] | ^^^^^^^^^ | | - | not found in this scope + | not found in the crate root | help: a built-in attribute with a similar name exists: `deprecated` error: aborting due to 4 previous errors diff --git a/tests/ui/tool-attributes/tool-attributes-misplaced-1.stderr b/tests/ui/tool-attributes/tool-attributes-misplaced-1.stderr index c7ccf370915fd..0efbae23bc0d5 100644 --- a/tests/ui/tool-attributes/tool-attributes-misplaced-1.stderr +++ b/tests/ui/tool-attributes/tool-attributes-misplaced-1.stderr @@ -1,22 +1,22 @@ -error: cannot find derive macro `rustfmt` in this scope +error: cannot find derive macro `rustfmt` in the crate root --> $DIR/tool-attributes-misplaced-1.rs:4:10 | LL | #[derive(rustfmt)] - | ^^^^^^^ not found in this scope + | ^^^^^^^ not found in the crate root -error: cannot find derive macro `rustfmt` in this scope +error: cannot find derive macro `rustfmt` in the crate root --> $DIR/tool-attributes-misplaced-1.rs:4:10 | LL | #[derive(rustfmt)] - | ^^^^^^^ not found in this scope + | ^^^^^^^ not found in the crate root | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error: cannot find attribute `rustfmt` in this scope +error: cannot find attribute `rustfmt` in the crate root --> $DIR/tool-attributes-misplaced-1.rs:9:3 | LL | #[rustfmt] - | ^^^^^^^ not found in this scope + | ^^^^^^^ not found in the crate root error: cannot find macro `rustfmt` in this scope --> $DIR/tool-attributes-misplaced-1.rs:15:5 From e1fed5fabcdf4e3b13a28223fe848044ce794539 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 2 Jul 2024 15:53:43 +0000 Subject: [PATCH 892/892] Fix ui-fulldeps test --- .../diagnostic-derive.stderr | 36 +++++++++---------- .../subdiagnostic-derive.rs | 20 +++++------ .../subdiagnostic-derive.stderr | 36 +++++++++---------- 3 files changed, 46 insertions(+), 46 deletions(-) diff --git a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr index ac5baf6dd6758..1268a99e95c6f 100644 --- a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr +++ b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr @@ -542,68 +542,68 @@ error[E0433]: cannot find item `core` in the crate root LL | #[suggestion(code = 3)] | ^ you might be missing a crate named `core` -error: cannot find attribute `nonsense` in this scope +error: cannot find attribute `nonsense` in the crate root --> $DIR/diagnostic-derive.rs:63:3 | LL | #[nonsense(no_crate_example, code = E0123)] - | ^^^^^^^^ not found in this scope + | ^^^^^^^^ not found in the crate root -error: cannot find attribute `nonsense` in this scope +error: cannot find attribute `nonsense` in the crate root --> $DIR/diagnostic-derive.rs:150:7 | LL | #[nonsense] - | ^^^^^^^^ not found in this scope + | ^^^^^^^^ not found in the crate root -error: cannot find attribute `error` in this scope +error: cannot find attribute `error` in the crate root --> $DIR/diagnostic-derive.rs:583:3 | LL | #[error(no_crate_example, code = E0123)] - | ^^^^^ not found in this scope + | ^^^^^ not found in the crate root -error: cannot find attribute `warn_` in this scope +error: cannot find attribute `warn_` in the crate root --> $DIR/diagnostic-derive.rs:590:3 | LL | #[warn_(no_crate_example, code = E0123)] | ^^^^^ | | - | not found in this scope + | not found in the crate root | help: a built-in attribute with a similar name exists: `warn` -error: cannot find attribute `lint` in this scope +error: cannot find attribute `lint` in the crate root --> $DIR/diagnostic-derive.rs:597:3 | LL | #[lint(no_crate_example, code = E0123)] | ^^^^ | | - | not found in this scope + | not found in the crate root | help: a built-in attribute with a similar name exists: `link` -error: cannot find attribute `lint` in this scope +error: cannot find attribute `lint` in the crate root --> $DIR/diagnostic-derive.rs:604:3 | LL | #[lint(no_crate_example, code = E0123)] | ^^^^ | | - | not found in this scope + | not found in the crate root | help: a built-in attribute with a similar name exists: `link` -error: cannot find attribute `multipart_suggestion` in this scope +error: cannot find attribute `multipart_suggestion` in the crate root --> $DIR/diagnostic-derive.rs:644:3 | LL | #[multipart_suggestion(no_crate_suggestion)] - | ^^^^^^^^^^^^^^^^^^^^ not found in this scope + | ^^^^^^^^^^^^^^^^^^^^ not found in the crate root -error: cannot find attribute `multipart_suggestion` in this scope +error: cannot find attribute `multipart_suggestion` in the crate root --> $DIR/diagnostic-derive.rs:647:3 | LL | #[multipart_suggestion()] - | ^^^^^^^^^^^^^^^^^^^^ not found in this scope + | ^^^^^^^^^^^^^^^^^^^^ not found in the crate root -error: cannot find attribute `multipart_suggestion` in this scope +error: cannot find attribute `multipart_suggestion` in the crate root --> $DIR/diagnostic-derive.rs:651:7 | LL | #[multipart_suggestion(no_crate_suggestion)] - | ^^^^^^^^^^^^^^^^^^^^ not found in this scope + | ^^^^^^^^^^^^^^^^^^^^ not found in the crate root error[E0425]: cannot find value `nonsense` in module `crate::fluent_generated` --> $DIR/diagnostic-derive.rs:75:8 diff --git a/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive.rs b/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive.rs index 2758cfaa54265..3e78c1f65b98f 100644 --- a/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive.rs +++ b/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive.rs @@ -67,7 +67,7 @@ struct D { #[foo] //~^ ERROR `#[foo]` is not a valid attribute //~| ERROR cannot find attribute `foo` -//~| NOTE not found in this scope +//~| NOTE not found in struct E { #[primary_span] span: Span, @@ -164,7 +164,7 @@ struct O { #[foo] //~^ ERROR cannot find attribute `foo` //~| ERROR unsupported type attribute for subdiagnostic enum -//~| NOTE not found in this scope +//~| NOTE not found in enum P { #[label(no_crate_example)] A { @@ -179,7 +179,7 @@ enum Q { #[bar] //~^ ERROR `#[bar]` is not a valid attribute //~| ERROR cannot find attribute `bar` - //~| NOTE not found in this scope + //~| NOTE not found in A { #[primary_span] span: Span, @@ -192,7 +192,7 @@ enum R { #[bar = "..."] //~^ ERROR `#[bar = ...]` is not a valid attribute //~| ERROR cannot find attribute `bar` - //~| NOTE not found in this scope + //~| NOTE not found in A { #[primary_span] span: Span, @@ -205,7 +205,7 @@ enum S { #[bar = 4] //~^ ERROR `#[bar = ...]` is not a valid attribute //~| ERROR cannot find attribute `bar` - //~| NOTE not found in this scope + //~| NOTE not found in A { #[primary_span] span: Span, @@ -218,7 +218,7 @@ enum T { #[bar("...")] //~^ ERROR `#[bar(...)]` is not a valid attribute //~| ERROR cannot find attribute `bar` - //~| NOTE not found in this scope + //~| NOTE not found in A { #[primary_span] span: Span, @@ -280,7 +280,7 @@ struct Y { #[bar] //~^ ERROR `#[bar]` is not a valid attribute //~| ERROR cannot find attribute `bar` - //~| NOTE not found in this scope + //~| NOTE not found in bar: String, } @@ -292,7 +292,7 @@ struct Z { #[bar = "..."] //~^ ERROR `#[bar = ...]` is not a valid attribute //~| ERROR cannot find attribute `bar` - //~| NOTE not found in this scope + //~| NOTE not found in bar: String, } @@ -304,7 +304,7 @@ struct AA { #[bar("...")] //~^ ERROR `#[bar(...)]` is not a valid attribute //~| ERROR cannot find attribute `bar` - //~| NOTE not found in this scope + //~| NOTE not found in bar: String, } @@ -723,7 +723,7 @@ struct BP { #[derive(Subdiagnostic)] //~^ ERROR cannot find value `__code_29` //~| NOTE in this expansion -//~| NOTE not found in this scope +//~| NOTE not found in #[multipart_suggestion(no_crate_example)] struct BQ { #[suggestion_part(code = 3)] diff --git a/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive.stderr b/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive.stderr index 72ae8c198f1f8..ef9ed4c511d0a 100644 --- a/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive.stderr +++ b/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive.stderr @@ -499,59 +499,59 @@ error[E0433]: cannot find item `core` in the crate root LL | #[suggestion(no_crate_example, code = "", style("foo"))] | ^ you might be missing a crate named `core` -error: cannot find attribute `foo` in this scope +error: cannot find attribute `foo` in the crate root --> $DIR/subdiagnostic-derive.rs:67:3 | LL | #[foo] - | ^^^ not found in this scope + | ^^^ not found in the crate root -error: cannot find attribute `foo` in this scope +error: cannot find attribute `foo` in the crate root --> $DIR/subdiagnostic-derive.rs:164:3 | LL | #[foo] - | ^^^ not found in this scope + | ^^^ not found in the crate root -error: cannot find attribute `bar` in this scope +error: cannot find attribute `bar` in enum `Q` --> $DIR/subdiagnostic-derive.rs:179:7 | LL | #[bar] - | ^^^ not found in this scope + | ^^^ not found in enum `Q` -error: cannot find attribute `bar` in this scope +error: cannot find attribute `bar` in enum `R` --> $DIR/subdiagnostic-derive.rs:192:7 | LL | #[bar = "..."] - | ^^^ not found in this scope + | ^^^ not found in enum `R` -error: cannot find attribute `bar` in this scope +error: cannot find attribute `bar` in enum `S` --> $DIR/subdiagnostic-derive.rs:205:7 | LL | #[bar = 4] - | ^^^ not found in this scope + | ^^^ not found in enum `S` -error: cannot find attribute `bar` in this scope +error: cannot find attribute `bar` in enum `T` --> $DIR/subdiagnostic-derive.rs:218:7 | LL | #[bar("...")] - | ^^^ not found in this scope + | ^^^ not found in enum `T` -error: cannot find attribute `bar` in this scope +error: cannot find attribute `bar` in the crate root --> $DIR/subdiagnostic-derive.rs:280:7 | LL | #[bar] - | ^^^ not found in this scope + | ^^^ not found in the crate root -error: cannot find attribute `bar` in this scope +error: cannot find attribute `bar` in the crate root --> $DIR/subdiagnostic-derive.rs:292:7 | LL | #[bar = "..."] - | ^^^ not found in this scope + | ^^^ not found in the crate root -error: cannot find attribute `bar` in this scope +error: cannot find attribute `bar` in the crate root --> $DIR/subdiagnostic-derive.rs:304:7 | LL | #[bar("...")] - | ^^^ not found in this scope + | ^^^ not found in the crate root error[E0425]: cannot find value `slug` in module `crate::fluent_generated` --> $DIR/subdiagnostic-derive.rs:127:9

    () -> impl Fn + '_ {} | +++ -error[E0412]: cannot find type `T` in this scope +error[E0412]: cannot find type `T` --> $DIR/opaque-used-in-extraneous-argument.rs:5:34 | LL | fn frob() -> impl Fn + '_ {} diff --git a/tests/ui/impl-trait/precise-capturing/bad-params.rs b/tests/ui/impl-trait/precise-capturing/bad-params.rs index 08eee67c0e579..cbd6ec3ef5506 100644 --- a/tests/ui/impl-trait/precise-capturing/bad-params.rs +++ b/tests/ui/impl-trait/precise-capturing/bad-params.rs @@ -1,10 +1,10 @@ #![feature(precise_capturing)] fn missing() -> impl Sized + use {} -//~^ ERROR cannot find type `T` in this scope +//~^ ERROR cannot find type `T` fn missing_self() -> impl Sized + use {} -//~^ ERROR cannot find type `Self` in this scope +//~^ ERROR cannot find type `Self` struct MyType; impl MyType { diff --git a/tests/ui/impl-trait/precise-capturing/bad-params.stderr b/tests/ui/impl-trait/precise-capturing/bad-params.stderr index e104f115aa3f2..bc1fc2e2d5879 100644 --- a/tests/ui/impl-trait/precise-capturing/bad-params.stderr +++ b/tests/ui/impl-trait/precise-capturing/bad-params.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `T` in this scope +error[E0412]: cannot find type `T` --> $DIR/bad-params.rs:3:34 | LL | fn missing() -> impl Sized + use {} @@ -9,7 +9,7 @@ help: you might be missing a type parameter LL | fn missing() -> impl Sized + use {} | +++ -error[E0411]: cannot find type `Self` in this scope +error[E0411]: cannot find type `Self` --> $DIR/bad-params.rs:6:39 | LL | fn missing_self() -> impl Sized + use {} diff --git a/tests/ui/impl-trait/precise-capturing/bound-modifiers.rs b/tests/ui/impl-trait/precise-capturing/bound-modifiers.rs index 15f2188262869..e0158626d587c 100644 --- a/tests/ui/impl-trait/precise-capturing/bound-modifiers.rs +++ b/tests/ui/impl-trait/precise-capturing/bound-modifiers.rs @@ -4,22 +4,22 @@ fn polarity() -> impl Sized + ?use<> {} //~^ ERROR expected identifier, found keyword `use` -//~| ERROR cannot find trait `r#use` in this scope +//~| ERROR cannot find trait `r#use` //~| WARN relaxing a default bound only does something for `?Sized` //~| WARN relaxing a default bound only does something for `?Sized` fn asyncness() -> impl Sized + async use<> {} //~^ ERROR expected identifier, found keyword `use` -//~| ERROR cannot find trait `r#use` in this scope +//~| ERROR cannot find trait `r#use` //~| ERROR async closures are unstable fn constness() -> impl Sized + const use<> {} //~^ ERROR expected identifier, found keyword `use` -//~| ERROR cannot find trait `r#use` in this scope +//~| ERROR cannot find trait `r#use` //~| ERROR const trait impls are experimental fn binder() -> impl Sized + for<'a> use<> {} //~^ ERROR expected identifier, found keyword `use` -//~| ERROR cannot find trait `r#use` in this scope +//~| ERROR cannot find trait `r#use` fn main() {} diff --git a/tests/ui/impl-trait/precise-capturing/bound-modifiers.stderr b/tests/ui/impl-trait/precise-capturing/bound-modifiers.stderr index 4602225e7b922..33ccfd1f89b2a 100644 --- a/tests/ui/impl-trait/precise-capturing/bound-modifiers.stderr +++ b/tests/ui/impl-trait/precise-capturing/bound-modifiers.stderr @@ -22,25 +22,25 @@ error: expected identifier, found keyword `use` LL | fn binder() -> impl Sized + for<'a> use<> {} | ^^^ expected identifier, found keyword -error[E0405]: cannot find trait `r#use` in this scope +error[E0405]: cannot find trait `r#use` --> $DIR/bound-modifiers.rs:5:32 | LL | fn polarity() -> impl Sized + ?use<> {} | ^^^ not found in this scope -error[E0405]: cannot find trait `r#use` in this scope +error[E0405]: cannot find trait `r#use` --> $DIR/bound-modifiers.rs:11:38 | LL | fn asyncness() -> impl Sized + async use<> {} | ^^^ not found in this scope -error[E0405]: cannot find trait `r#use` in this scope +error[E0405]: cannot find trait `r#use` --> $DIR/bound-modifiers.rs:16:38 | LL | fn constness() -> impl Sized + const use<> {} | ^^^ not found in this scope -error[E0405]: cannot find trait `r#use` in this scope +error[E0405]: cannot find trait `r#use` --> $DIR/bound-modifiers.rs:21:37 | LL | fn binder() -> impl Sized + for<'a> use<> {} diff --git a/tests/ui/implied-bounds/references-err.rs b/tests/ui/implied-bounds/references-err.rs index 203d512e39812..e059c2285eb89 100644 --- a/tests/ui/implied-bounds/references-err.rs +++ b/tests/ui/implied-bounds/references-err.rs @@ -12,7 +12,7 @@ trait Trait { impl Trait for () { type Assoc = DoesNotExist; - //~^ ERROR cannot find type `DoesNotExist` in this scope + //~^ ERROR cannot find type `DoesNotExist` fn tokenize(&self) -> ::Identity { unimplemented!() diff --git a/tests/ui/implied-bounds/references-err.stderr b/tests/ui/implied-bounds/references-err.stderr index df83fce3bdef7..f350bd781be95 100644 --- a/tests/ui/implied-bounds/references-err.stderr +++ b/tests/ui/implied-bounds/references-err.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `DoesNotExist` in this scope +error[E0412]: cannot find type `DoesNotExist` --> $DIR/references-err.rs:14:18 | LL | type Assoc = DoesNotExist; diff --git a/tests/ui/imports/glob-conflict-cross-crate-1.rs b/tests/ui/imports/glob-conflict-cross-crate-1.rs index 5f0433d13fcfd..4ff05a0fb0bab 100644 --- a/tests/ui/imports/glob-conflict-cross-crate-1.rs +++ b/tests/ui/imports/glob-conflict-cross-crate-1.rs @@ -3,10 +3,10 @@ extern crate glob_conflict; fn main() { - glob_conflict::f(); //~ ERROR cannot find function `f` in crate `glob_conflict` + glob_conflict::f(); //~ ERROR cannot find function `f` //^ FIXME: `glob_conflict::f` should raise an // ambiguity error instead of a not found error. - glob_conflict::glob::f(); //~ ERROR cannot find function `f` in module `glob_conflict::glob` + glob_conflict::glob::f(); //~ ERROR cannot find function `f` //^ FIXME: `glob_conflict::glob::f` should raise an // ambiguity error instead of a not found error. } diff --git a/tests/ui/imports/glob-conflict-cross-crate-1.stderr b/tests/ui/imports/glob-conflict-cross-crate-1.stderr index 758087107f397..c3187af772e30 100644 --- a/tests/ui/imports/glob-conflict-cross-crate-1.stderr +++ b/tests/ui/imports/glob-conflict-cross-crate-1.stderr @@ -1,14 +1,14 @@ -error[E0425]: cannot find function `f` in crate `glob_conflict` +error[E0425]: cannot find function `f` --> $DIR/glob-conflict-cross-crate-1.rs:6:20 | LL | glob_conflict::f(); - | ^ not found in `glob_conflict` + | ^ not found in crate `glob_conflict` -error[E0425]: cannot find function `f` in module `glob_conflict::glob` +error[E0425]: cannot find function `f` --> $DIR/glob-conflict-cross-crate-1.rs:9:26 | LL | glob_conflict::glob::f(); - | ^ not found in `glob_conflict::glob` + | ^ not found in module `glob_conflict::glob` error: aborting due to 2 previous errors diff --git a/tests/ui/imports/glob-conflict-cross-crate-2.rs b/tests/ui/imports/glob-conflict-cross-crate-2.rs index b764685dd5796..304fede3a6474 100644 --- a/tests/ui/imports/glob-conflict-cross-crate-2.rs +++ b/tests/ui/imports/glob-conflict-cross-crate-2.rs @@ -5,6 +5,6 @@ extern crate glob_conflict_cross_crate_2_extern; use glob_conflict_cross_crate_2_extern::*; fn main() { - let _a: C = 1; //~ ERROR cannot find type `C` in this scope + let _a: C = 1; //~ ERROR cannot find type `C` //^ FIXME: `C` should be identified as an ambiguous item. } diff --git a/tests/ui/imports/glob-conflict-cross-crate-2.stderr b/tests/ui/imports/glob-conflict-cross-crate-2.stderr index aebb2d59d063a..ceaa0ba80fa13 100644 --- a/tests/ui/imports/glob-conflict-cross-crate-2.stderr +++ b/tests/ui/imports/glob-conflict-cross-crate-2.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `C` in this scope +error[E0412]: cannot find type `C` --> $DIR/glob-conflict-cross-crate-2.rs:8:13 | LL | let _a: C = 1; diff --git a/tests/ui/imports/glob-resolve1.rs b/tests/ui/imports/glob-resolve1.rs index 904b77117dafc..79067bd9cfc7a 100644 --- a/tests/ui/imports/glob-resolve1.rs +++ b/tests/ui/imports/glob-resolve1.rs @@ -23,15 +23,15 @@ mod bar { fn foo() {} fn main() { - fpriv(); //~ ERROR cannot find function `fpriv` in this scope - epriv(); //~ ERROR cannot find function `epriv` in this scope + fpriv(); //~ ERROR cannot find function `fpriv` + epriv(); //~ ERROR cannot find function `epriv` B; //~ ERROR expected value, found enum `B` - C; //~ ERROR cannot find value `C` in this scope - import(); //~ ERROR: cannot find function `import` in this scope + C; //~ ERROR cannot find value `C` + import(); //~ ERROR: cannot find function `import` - foo::(); //~ ERROR: cannot find type `A` in this scope - foo::(); //~ ERROR: cannot find type `C` in this scope - foo::(); //~ ERROR: cannot find type `D` in this scope + foo::(); //~ ERROR: cannot find type `A` + foo::(); //~ ERROR: cannot find type `C` + foo::(); //~ ERROR: cannot find type `D` } mod other { diff --git a/tests/ui/imports/glob-resolve1.stderr b/tests/ui/imports/glob-resolve1.stderr index 4401ef58732e8..8ed155860c049 100644 --- a/tests/ui/imports/glob-resolve1.stderr +++ b/tests/ui/imports/glob-resolve1.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find function `fpriv` in this scope +error[E0425]: cannot find function `fpriv` --> $DIR/glob-resolve1.rs:26:5 | LL | fpriv(); @@ -10,7 +10,7 @@ note: function `bar::fpriv` exists but is inaccessible LL | fn fpriv() {} | ^^^^^^^^^^ not accessible -error[E0425]: cannot find function `epriv` in this scope +error[E0425]: cannot find function `epriv` --> $DIR/glob-resolve1.rs:27:5 | LL | epriv(); @@ -40,7 +40,7 @@ help: you might have meant to use the following enum variant LL | B::B1; | ~~~~~ -error[E0425]: cannot find value `C` in this scope +error[E0425]: cannot find value `C` --> $DIR/glob-resolve1.rs:29:5 | LL | C; @@ -52,7 +52,7 @@ note: unit struct `bar::C` exists but is inaccessible LL | struct C; | ^^^^^^^^^ not accessible -error[E0425]: cannot find function `import` in this scope +error[E0425]: cannot find function `import` --> $DIR/glob-resolve1.rs:30:5 | LL | import(); @@ -63,7 +63,7 @@ help: consider importing this function LL + use other::import; | -error[E0412]: cannot find type `A` in this scope +error[E0412]: cannot find type `A` --> $DIR/glob-resolve1.rs:32:11 | LL | pub enum B { @@ -78,7 +78,7 @@ note: enum `bar::A` exists but is inaccessible LL | enum A { | ^^^^^^ not accessible -error[E0412]: cannot find type `C` in this scope +error[E0412]: cannot find type `C` --> $DIR/glob-resolve1.rs:33:11 | LL | pub enum B { @@ -93,7 +93,7 @@ note: struct `bar::C` exists but is inaccessible LL | struct C; | ^^^^^^^^^ not accessible -error[E0412]: cannot find type `D` in this scope +error[E0412]: cannot find type `D` --> $DIR/glob-resolve1.rs:34:11 | LL | pub enum B { diff --git a/tests/ui/imports/import-alias-issue-121168.edition2015.stderr b/tests/ui/imports/import-alias-issue-121168.edition2015.stderr index 47001fc1a5291..a93dc203e691b 100644 --- a/tests/ui/imports/import-alias-issue-121168.edition2015.stderr +++ b/tests/ui/imports/import-alias-issue-121168.edition2015.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `Foo` in this scope +error[E0412]: cannot find type `Foo` --> $DIR/import-alias-issue-121168.rs:11:12 | LL | let _: Foo = todo!(); diff --git a/tests/ui/imports/import-alias-issue-121168.edition2018.stderr b/tests/ui/imports/import-alias-issue-121168.edition2018.stderr index e14e700c33d81..a8317fcbb5f92 100644 --- a/tests/ui/imports/import-alias-issue-121168.edition2018.stderr +++ b/tests/ui/imports/import-alias-issue-121168.edition2018.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `Foo` in this scope +error[E0412]: cannot find type `Foo` --> $DIR/import-alias-issue-121168.rs:11:12 | LL | let _: Foo = todo!(); diff --git a/tests/ui/imports/import-alias-issue-121168.edition2021.stderr b/tests/ui/imports/import-alias-issue-121168.edition2021.stderr index e14e700c33d81..a8317fcbb5f92 100644 --- a/tests/ui/imports/import-alias-issue-121168.edition2021.stderr +++ b/tests/ui/imports/import-alias-issue-121168.edition2021.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `Foo` in this scope +error[E0412]: cannot find type `Foo` --> $DIR/import-alias-issue-121168.rs:11:12 | LL | let _: Foo = todo!(); diff --git a/tests/ui/imports/import-alias-issue-121168.rs b/tests/ui/imports/import-alias-issue-121168.rs index 826a6765b0399..393b83f0943a2 100644 --- a/tests/ui/imports/import-alias-issue-121168.rs +++ b/tests/ui/imports/import-alias-issue-121168.rs @@ -8,7 +8,7 @@ extern crate import_alias_issue_121168_extern as nice_crate_name; fn use_foo_from_another_crate_without_importing_it_first() { - let _: Foo = todo!(); //~ ERROR cannot find type `Foo` in this scope + let _: Foo = todo!(); //~ ERROR cannot find type `Foo` } fn main() {} diff --git a/tests/ui/imports/import-glob-0.rs b/tests/ui/imports/import-glob-0.rs index 37a0d15456c67..36d8b2a221999 100644 --- a/tests/ui/imports/import-glob-0.rs +++ b/tests/ui/imports/import-glob-0.rs @@ -11,6 +11,6 @@ mod module_of_many_things { fn main() { f1(); f2(); - f999(); //~ ERROR cannot find function `f999` in this scope + f999(); //~ ERROR cannot find function `f999` f4(); } diff --git a/tests/ui/imports/import-glob-0.stderr b/tests/ui/imports/import-glob-0.stderr index 6a2837e770dc5..9e86ace214d08 100644 --- a/tests/ui/imports/import-glob-0.stderr +++ b/tests/ui/imports/import-glob-0.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find function `f999` in this scope +error[E0425]: cannot find function `f999` --> $DIR/import-glob-0.rs:14:5 | LL | f999(); diff --git a/tests/ui/imports/import-glob-circular.rs b/tests/ui/imports/import-glob-circular.rs index e47fa870c0639..4dc45389e67c4 100644 --- a/tests/ui/imports/import-glob-circular.rs +++ b/tests/ui/imports/import-glob-circular.rs @@ -13,7 +13,7 @@ mod circ2 { mod test { use circ1::*; - fn test() { f1066(); } //~ ERROR cannot find function `f1066` in this scope + fn test() { f1066(); } //~ ERROR cannot find function `f1066` } fn main() {} diff --git a/tests/ui/imports/import-glob-circular.stderr b/tests/ui/imports/import-glob-circular.stderr index 2eb268813d0f2..31c752a1cd96f 100644 --- a/tests/ui/imports/import-glob-circular.stderr +++ b/tests/ui/imports/import-glob-circular.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find function `f1066` in this scope +error[E0425]: cannot find function `f1066` --> $DIR/import-glob-circular.rs:16:17 | LL | fn test() { f1066(); } diff --git a/tests/ui/imports/inaccessible_type_aliases.rs b/tests/ui/imports/inaccessible_type_aliases.rs index c3d4214e282d7..5adf459a448f7 100644 --- a/tests/ui/imports/inaccessible_type_aliases.rs +++ b/tests/ui/imports/inaccessible_type_aliases.rs @@ -8,7 +8,7 @@ mod b { } fn main() { - let x: Foo = 100; //~ ERROR: cannot find type `Foo` in this scope - let y: Bar = 100; //~ ERROR: cannot find type `Bar` in this scope + let x: Foo = 100; //~ ERROR: cannot find type `Foo` + let y: Bar = 100; //~ ERROR: cannot find type `Bar` println!("x: {}, y: {}", x, y); } diff --git a/tests/ui/imports/inaccessible_type_aliases.stderr b/tests/ui/imports/inaccessible_type_aliases.stderr index ef224246061d9..d131f5def62c7 100644 --- a/tests/ui/imports/inaccessible_type_aliases.stderr +++ b/tests/ui/imports/inaccessible_type_aliases.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `Foo` in this scope +error[E0412]: cannot find type `Foo` --> $DIR/inaccessible_type_aliases.rs:11:12 | LL | let x: Foo = 100; @@ -13,7 +13,7 @@ LL | type Foo = u64; LL | type Foo = u64; | ^^^^^^^^^^^^^^^ `b::Foo`: not accessible -error[E0412]: cannot find type `Bar` in this scope +error[E0412]: cannot find type `Bar` --> $DIR/inaccessible_type_aliases.rs:12:12 | LL | let y: Bar = 100; diff --git a/tests/ui/imports/issue-4366-2.rs b/tests/ui/imports/issue-4366-2.rs index c777b750252c2..9f243d879c327 100644 --- a/tests/ui/imports/issue-4366-2.rs +++ b/tests/ui/imports/issue-4366-2.rs @@ -13,7 +13,7 @@ mod a { pub mod sub { use a::b::*; fn sub() -> Bar { 1 } - //~^ ERROR cannot find type `Bar` in this scope + //~^ ERROR cannot find type `Bar` } } diff --git a/tests/ui/imports/issue-4366-2.stderr b/tests/ui/imports/issue-4366-2.stderr index 412423f4d595e..e96ff76d2c667 100644 --- a/tests/ui/imports/issue-4366-2.stderr +++ b/tests/ui/imports/issue-4366-2.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `Bar` in this scope +error[E0412]: cannot find type `Bar` --> $DIR/issue-4366-2.rs:15:21 | LL | fn sub() -> Bar { 1 } diff --git a/tests/ui/imports/issue-4366.rs b/tests/ui/imports/issue-4366.rs index 9ec2e58ecadcb..aaec6c599d977 100644 --- a/tests/ui/imports/issue-4366.rs +++ b/tests/ui/imports/issue-4366.rs @@ -15,7 +15,7 @@ mod a { } pub mod sub { use a::b::*; - fn sub() -> isize { foo(); 1 } //~ ERROR cannot find function `foo` in this scope + fn sub() -> isize { foo(); 1 } //~ ERROR cannot find function `foo` } } diff --git a/tests/ui/imports/issue-4366.stderr b/tests/ui/imports/issue-4366.stderr index e63399d554ee3..35e5055d2d89c 100644 --- a/tests/ui/imports/issue-4366.stderr +++ b/tests/ui/imports/issue-4366.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find function `foo` in this scope +error[E0425]: cannot find function `foo` --> $DIR/issue-4366.rs:18:29 | LL | fn sub() -> isize { foo(); 1 } diff --git a/tests/ui/imports/issue-59764.rs b/tests/ui/imports/issue-59764.rs index 5f7a496117a6a..12232eeef852d 100644 --- a/tests/ui/imports/issue-59764.rs +++ b/tests/ui/imports/issue-59764.rs @@ -131,5 +131,5 @@ makro!(bar); fn main() { bar(); - //~^ ERROR cannot find function `bar` in this scope [E0425] + //~^ ERROR cannot find function `bar` [E0425] } diff --git a/tests/ui/imports/issue-59764.stderr b/tests/ui/imports/issue-59764.stderr index 74525c9c88f5a..d8549980a57bb 100644 --- a/tests/ui/imports/issue-59764.stderr +++ b/tests/ui/imports/issue-59764.stderr @@ -226,7 +226,7 @@ help: a macro with this name exists at the root of the crate LL | use issue_59764::makro; | ~~~~~~~~~~~~~~~~~~ -error[E0425]: cannot find function `bar` in this scope +error[E0425]: cannot find function `bar` --> $DIR/issue-59764.rs:133:5 | LL | bar(); diff --git a/tests/ui/issues-71798.rs b/tests/ui/issues-71798.rs index 14b6c0f35812f..500d137c3b85f 100644 --- a/tests/ui/issues-71798.rs +++ b/tests/ui/issues-71798.rs @@ -4,5 +4,5 @@ fn test_ref(x: &u32) -> impl std::future::Future + '_ { } fn main() { - let _ = test_ref & u; //~ ERROR cannot find value `u` in this scope + let _ = test_ref & u; //~ ERROR cannot find value `u` } diff --git a/tests/ui/issues-71798.stderr b/tests/ui/issues-71798.stderr index 52dd14ccb0a14..7911a0e039d0a 100644 --- a/tests/ui/issues-71798.stderr +++ b/tests/ui/issues-71798.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `u` in this scope +error[E0425]: cannot find value `u` --> $DIR/issues-71798.rs:7:24 | LL | let _ = test_ref & u; diff --git a/tests/ui/issues/issue-15167.rs b/tests/ui/issues/issue-15167.rs index a2653c10ea4f7..64828cc8cab2f 100644 --- a/tests/ui/issues/issue-15167.rs +++ b/tests/ui/issues/issue-15167.rs @@ -1,10 +1,10 @@ // macro f should not be able to inject a reference to 'n'. macro_rules! f { () => (n) } -//~^ ERROR cannot find value `n` in this scope -//~| ERROR cannot find value `n` in this scope -//~| ERROR cannot find value `n` in this scope -//~| ERROR cannot find value `n` in this scope +//~^ ERROR cannot find value `n` +//~| ERROR cannot find value `n` +//~| ERROR cannot find value `n` +//~| ERROR cannot find value `n` fn main() -> (){ for n in 0..1 { diff --git a/tests/ui/issues/issue-15167.stderr b/tests/ui/issues/issue-15167.stderr index 53082ea0ec6bb..88a9649b0bc99 100644 --- a/tests/ui/issues/issue-15167.stderr +++ b/tests/ui/issues/issue-15167.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `n` in this scope +error[E0425]: cannot find value `n` --> $DIR/issue-15167.rs:3:25 | LL | macro_rules! f { () => (n) } @@ -9,7 +9,7 @@ LL | println!("{}", f!()); | = note: this error originates in the macro `f` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0425]: cannot find value `n` in this scope +error[E0425]: cannot find value `n` --> $DIR/issue-15167.rs:3:25 | LL | macro_rules! f { () => (n) } @@ -20,7 +20,7 @@ LL | println!("{}", f!()); | = note: this error originates in the macro `f` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0425]: cannot find value `n` in this scope +error[E0425]: cannot find value `n` --> $DIR/issue-15167.rs:3:25 | LL | macro_rules! f { () => (n) } @@ -31,7 +31,7 @@ LL | println!("{}", f!()); | = note: this error originates in the macro `f` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0425]: cannot find value `n` in this scope +error[E0425]: cannot find value `n` --> $DIR/issue-15167.rs:3:25 | LL | macro_rules! f { () => (n) } diff --git a/tests/ui/issues/issue-18058.rs b/tests/ui/issues/issue-18058.rs index cced66717e1bf..959359c7ccd6c 100644 --- a/tests/ui/issues/issue-18058.rs +++ b/tests/ui/issues/issue-18058.rs @@ -1,4 +1,4 @@ impl Undefined {} -//~^ ERROR cannot find type `Undefined` in this scope +//~^ ERROR cannot find type `Undefined` fn main() {} diff --git a/tests/ui/issues/issue-18058.stderr b/tests/ui/issues/issue-18058.stderr index c880bb0029192..2415ca371b7ed 100644 --- a/tests/ui/issues/issue-18058.stderr +++ b/tests/ui/issues/issue-18058.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `Undefined` in this scope +error[E0412]: cannot find type `Undefined` --> $DIR/issue-18058.rs:1:6 | LL | impl Undefined {} diff --git a/tests/ui/issues/issue-19734.rs b/tests/ui/issues/issue-19734.rs index fe4a327aef49c..7b8394982290e 100644 --- a/tests/ui/issues/issue-19734.rs +++ b/tests/ui/issues/issue-19734.rs @@ -4,5 +4,5 @@ struct Type; impl Type { undef!(); - //~^ ERROR cannot find macro `undef` in this scope + //~^ ERROR cannot find macro `undef` } diff --git a/tests/ui/issues/issue-2281-part1.rs b/tests/ui/issues/issue-2281-part1.rs index 8340ade2239d1..a44fabaf47996 100644 --- a/tests/ui/issues/issue-2281-part1.rs +++ b/tests/ui/issues/issue-2281-part1.rs @@ -1 +1 @@ -fn main() { println!("{}", foobar); } //~ ERROR cannot find value `foobar` in this scope +fn main() { println!("{}", foobar); } //~ ERROR cannot find value `foobar` diff --git a/tests/ui/issues/issue-2281-part1.stderr b/tests/ui/issues/issue-2281-part1.stderr index 47a1ef8cc0277..ae1a6289b0bc0 100644 --- a/tests/ui/issues/issue-2281-part1.stderr +++ b/tests/ui/issues/issue-2281-part1.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `foobar` in this scope +error[E0425]: cannot find value `foobar` --> $DIR/issue-2281-part1.rs:1:28 | LL | fn main() { println!("{}", foobar); } diff --git a/tests/ui/issues/issue-30589.rs b/tests/ui/issues/issue-30589.rs index 94eb5839958af..eb89925901ab6 100644 --- a/tests/ui/issues/issue-30589.rs +++ b/tests/ui/issues/issue-30589.rs @@ -1,6 +1,6 @@ use std::fmt; -impl fmt::Display for DecoderError { //~ ERROR cannot find type `DecoderError` in this scope +impl fmt::Display for DecoderError { //~ ERROR cannot find type `DecoderError` fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "Missing data: {}", self.0) } diff --git a/tests/ui/issues/issue-30589.stderr b/tests/ui/issues/issue-30589.stderr index 6f97a189cead9..fc74ec29ee5ef 100644 --- a/tests/ui/issues/issue-30589.stderr +++ b/tests/ui/issues/issue-30589.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `DecoderError` in this scope +error[E0412]: cannot find type `DecoderError` --> $DIR/issue-30589.rs:3:23 | LL | impl fmt::Display for DecoderError { diff --git a/tests/ui/issues/issue-32655.rs b/tests/ui/issues/issue-32655.rs index f52e092312968..f6b631d721ae1 100644 --- a/tests/ui/issues/issue-32655.rs +++ b/tests/ui/issues/issue-32655.rs @@ -1,6 +1,6 @@ macro_rules! foo ( () => ( - #[derive_Clone] //~ ERROR cannot find attribute `derive_Clone` in this scope + #[derive_Clone] //~ ERROR cannot find attribute `derive_Clone` struct T; ); ); @@ -12,7 +12,7 @@ macro_rules! bar ( foo!(); bar!( - #[derive_Clone] //~ ERROR cannot find attribute `derive_Clone` in this scope + #[derive_Clone] //~ ERROR cannot find attribute `derive_Clone` struct S; ); diff --git a/tests/ui/issues/issue-32950.rs b/tests/ui/issues/issue-32950.rs index 27d68a11c1f16..18b45ca632bc1 100644 --- a/tests/ui/issues/issue-32950.rs +++ b/tests/ui/issues/issue-32950.rs @@ -3,7 +3,7 @@ #[derive(Debug)] struct Baz( concat_idents!(Foo, Bar) //~ ERROR `derive` cannot be used on items with type macros - //~^ ERROR cannot find type `FooBar` in this scope + //~^ ERROR cannot find type `FooBar` ); fn main() {} diff --git a/tests/ui/issues/issue-32950.stderr b/tests/ui/issues/issue-32950.stderr index f6635d982e4ec..eb4d79cd0d645 100644 --- a/tests/ui/issues/issue-32950.stderr +++ b/tests/ui/issues/issue-32950.stderr @@ -4,7 +4,7 @@ error: `derive` cannot be used on items with type macros LL | concat_idents!(Foo, Bar) | ^^^^^^^^^^^^^^^^^^^^^^^^ -error[E0412]: cannot find type `FooBar` in this scope +error[E0412]: cannot find type `FooBar` --> $DIR/issue-32950.rs:5:5 | LL | concat_idents!(Foo, Bar) diff --git a/tests/ui/issues/issue-33525.stderr b/tests/ui/issues/issue-33525.stderr index ee9f4d4c3016d..5112acf81fcf2 100644 --- a/tests/ui/issues/issue-33525.stderr +++ b/tests/ui/issues/issue-33525.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `a` in this scope +error[E0425]: cannot find value `a` --> $DIR/issue-33525.rs:2:5 | LL | a; diff --git a/tests/ui/issues/issue-33571.rs b/tests/ui/issues/issue-33571.rs index 2713f47ad2ff6..c452b14e98616 100644 --- a/tests/ui/issues/issue-33571.rs +++ b/tests/ui/issues/issue-33571.rs @@ -1,6 +1,6 @@ #[derive(Clone, - Sync, //~ ERROR cannot find derive macro `Sync` in this scope - //~| ERROR cannot find derive macro `Sync` in this scope + Sync, //~ ERROR cannot find derive macro `Sync` + //~| ERROR cannot find derive macro `Sync` Copy)] enum Foo {} diff --git a/tests/ui/issues/issue-36836.rs b/tests/ui/issues/issue-36836.rs index 99c56213153e4..67597a779d052 100644 --- a/tests/ui/issues/issue-36836.rs +++ b/tests/ui/issues/issue-36836.rs @@ -10,6 +10,6 @@ trait Foo {} -impl Foo for Bar {} //~ ERROR cannot find type `Bar` in this scope +impl Foo for Bar {} //~ ERROR cannot find type `Bar` fn main() {} diff --git a/tests/ui/issues/issue-36836.stderr b/tests/ui/issues/issue-36836.stderr index e5c943c7c3d82..54b06df601228 100644 --- a/tests/ui/issues/issue-36836.stderr +++ b/tests/ui/issues/issue-36836.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `Bar` in this scope +error[E0412]: cannot find type `Bar` --> $DIR/issue-36836.rs:13:17 | LL | impl Foo for Bar {} diff --git a/tests/ui/issues/issue-40845.rs b/tests/ui/issues/issue-40845.rs index a4ede6adfa3c2..76bbcca621001 100644 --- a/tests/ui/issues/issue-40845.rs +++ b/tests/ui/issues/issue-40845.rs @@ -1,6 +1,6 @@ -trait T { m!(); } //~ ERROR cannot find macro `m` in this scope +trait T { m!(); } //~ ERROR cannot find macro `m` struct S; -impl S { m!(); } //~ ERROR cannot find macro `m` in this scope +impl S { m!(); } //~ ERROR cannot find macro `m` fn main() {} diff --git a/tests/ui/issues/issue-46332.rs b/tests/ui/issues/issue-46332.rs index bed74e3138a66..c4af03438ed82 100644 --- a/tests/ui/issues/issue-46332.rs +++ b/tests/ui/issues/issue-46332.rs @@ -7,5 +7,5 @@ struct TyInt {} fn main() { TyUInt {}; - //~^ ERROR cannot find struct, variant or union type `TyUInt` in this scope + //~^ ERROR cannot find struct, variant or union type `TyUInt` } diff --git a/tests/ui/issues/issue-46332.stderr b/tests/ui/issues/issue-46332.stderr index 8c0c1dfa6ee86..6ea4d49df0232 100644 --- a/tests/ui/issues/issue-46332.stderr +++ b/tests/ui/issues/issue-46332.stderr @@ -1,4 +1,4 @@ -error[E0422]: cannot find struct, variant or union type `TyUInt` in this scope +error[E0422]: cannot find struct, variant or union type `TyUInt` --> $DIR/issue-46332.rs:9:5 | LL | struct TyUint {} diff --git a/tests/ui/issues/issue-53300.rs b/tests/ui/issues/issue-53300.rs index 09f0fe9d93553..39f746dc676e5 100644 --- a/tests/ui/issues/issue-53300.rs +++ b/tests/ui/issues/issue-53300.rs @@ -5,7 +5,7 @@ pub trait A { } fn addition() -> Wrapper {} -//~^ ERROR cannot find type `Wrapper` in this scope [E0412] +//~^ ERROR cannot find type `Wrapper` [E0412] fn main() { let res = addition(); diff --git a/tests/ui/issues/issue-53300.stderr b/tests/ui/issues/issue-53300.stderr index 293465ecb8140..ae35822dd9bdb 100644 --- a/tests/ui/issues/issue-53300.stderr +++ b/tests/ui/issues/issue-53300.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `Wrapper` in this scope +error[E0412]: cannot find type `Wrapper` --> $DIR/issue-53300.rs:7:18 | LL | fn addition() -> Wrapper {} diff --git a/tests/ui/issues/issue-58712.rs b/tests/ui/issues/issue-58712.rs index 930bec6889bce..1ec787819d893 100644 --- a/tests/ui/issues/issue-58712.rs +++ b/tests/ui/issues/issue-58712.rs @@ -4,9 +4,9 @@ struct AddrVec { } impl AddrVec { - //~^ ERROR cannot find type `DeviceId` in this scope + //~^ ERROR cannot find type `DeviceId` pub fn device(&self) -> DeviceId { - //~^ ERROR cannot find type `DeviceId` in this scope + //~^ ERROR cannot find type `DeviceId` self.tail() } } diff --git a/tests/ui/issues/issue-58712.stderr b/tests/ui/issues/issue-58712.stderr index f4bd4d1e826a0..79615510afb78 100644 --- a/tests/ui/issues/issue-58712.stderr +++ b/tests/ui/issues/issue-58712.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `DeviceId` in this scope +error[E0412]: cannot find type `DeviceId` --> $DIR/issue-58712.rs:6:20 | LL | impl AddrVec { @@ -9,7 +9,7 @@ help: you might be missing a type parameter LL | impl AddrVec { | ++++++++++ -error[E0412]: cannot find type `DeviceId` in this scope +error[E0412]: cannot find type `DeviceId` --> $DIR/issue-58712.rs:8:29 | LL | pub fn device(&self) -> DeviceId { diff --git a/tests/ui/issues/issue-72839-error-overflow.stderr b/tests/ui/issues/issue-72839-error-overflow.stderr index 35be632f57975..fa6801086d3a4 100644 --- a/tests/ui/issues/issue-72839-error-overflow.stderr +++ b/tests/ui/issues/issue-72839-error-overflow.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `missing_var` in this scope +error[E0425]: cannot find value `missing_var` --> $DIR/issue-72839-error-overflow.rs:18:8 | LL | if missing_var % 8 == 0 {} diff --git a/tests/ui/issues/issue-77919.rs b/tests/ui/issues/issue-77919.rs index bf603314977f9..1fbf5418f45a3 100644 --- a/tests/ui/issues/issue-77919.rs +++ b/tests/ui/issues/issue-77919.rs @@ -6,8 +6,8 @@ trait TypeVal { } struct Five; struct Multiply { - _n: PhantomData, //~ ERROR cannot find type `PhantomData` in this scope + _n: PhantomData, //~ ERROR cannot find type `PhantomData` } impl TypeVal for Multiply where N: TypeVal {} -//~^ ERROR cannot find type `VAL` in this scope +//~^ ERROR cannot find type `VAL` //~| ERROR not all trait items implemented diff --git a/tests/ui/issues/issue-77919.stderr b/tests/ui/issues/issue-77919.stderr index dbbe70ff06990..a3e8fddec6372 100644 --- a/tests/ui/issues/issue-77919.stderr +++ b/tests/ui/issues/issue-77919.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `PhantomData` in this scope +error[E0412]: cannot find type `PhantomData` --> $DIR/issue-77919.rs:9:9 | LL | _n: PhantomData, @@ -9,7 +9,7 @@ help: consider importing this struct LL + use std::marker::PhantomData; | -error[E0412]: cannot find type `VAL` in this scope +error[E0412]: cannot find type `VAL` --> $DIR/issue-77919.rs:11:63 | LL | impl TypeVal for Multiply where N: TypeVal {} diff --git a/tests/ui/issues/issue-86756.rs b/tests/ui/issues/issue-86756.rs index 7f864eb285074..1a181754f8e64 100644 --- a/tests/ui/issues/issue-86756.rs +++ b/tests/ui/issues/issue-86756.rs @@ -3,7 +3,7 @@ trait Foo {} fn eq() { eq:: - //~^ ERROR cannot find type `dyn` in this scope + //~^ ERROR cannot find type `dyn` //~| ERROR missing generics for trait `Foo` //~| WARN trait objects without an explicit `dyn` are deprecated //~| WARN this is accepted in the current edition diff --git a/tests/ui/issues/issue-86756.stderr b/tests/ui/issues/issue-86756.stderr index d0906a6fa74f4..8556dc37b5215 100644 --- a/tests/ui/issues/issue-86756.stderr +++ b/tests/ui/issues/issue-86756.stderr @@ -6,7 +6,7 @@ LL | trait Foo {} | | | first use of `T` -error[E0412]: cannot find type `dyn` in this scope +error[E0412]: cannot find type `dyn` --> $DIR/issue-86756.rs:5:10 | LL | eq:: diff --git a/tests/ui/issues/issue-8767.rs b/tests/ui/issues/issue-8767.rs index 972101a0bc3ee..806e8e7213243 100644 --- a/tests/ui/issues/issue-8767.rs +++ b/tests/ui/issues/issue-8767.rs @@ -1,4 +1,4 @@ -impl B { //~ ERROR cannot find type `B` in this scope +impl B { //~ ERROR cannot find type `B` } fn main() { diff --git a/tests/ui/issues/issue-8767.stderr b/tests/ui/issues/issue-8767.stderr index 66141628e28d2..95058e03d8b47 100644 --- a/tests/ui/issues/issue-8767.stderr +++ b/tests/ui/issues/issue-8767.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `B` in this scope +error[E0412]: cannot find type `B` --> $DIR/issue-8767.rs:1:6 | LL | impl B { diff --git a/tests/ui/keyword/keyword-self-as-identifier.rs b/tests/ui/keyword/keyword-self-as-identifier.rs index 72e4f01e21edd..712d0b462b24b 100644 --- a/tests/ui/keyword/keyword-self-as-identifier.rs +++ b/tests/ui/keyword/keyword-self-as-identifier.rs @@ -1,3 +1,3 @@ fn main() { - let Self = 22; //~ ERROR cannot find unit struct, unit variant or constant `Self` in this scope + let Self = 22; //~ ERROR cannot find unit struct, unit variant or constant `Self` } diff --git a/tests/ui/keyword/keyword-self-as-identifier.stderr b/tests/ui/keyword/keyword-self-as-identifier.stderr index 098ef8d82a04f..12bfa6121fb04 100644 --- a/tests/ui/keyword/keyword-self-as-identifier.stderr +++ b/tests/ui/keyword/keyword-self-as-identifier.stderr @@ -1,4 +1,4 @@ -error[E0531]: cannot find unit struct, unit variant or constant `Self` in this scope +error[E0531]: cannot find unit struct, unit variant or constant `Self` --> $DIR/keyword-self-as-identifier.rs:2:9 | LL | let Self = 22; diff --git a/tests/ui/label/label_misspelled.rs b/tests/ui/label/label_misspelled.rs index e3180b06ecb2b..2134d9bfe6751 100644 --- a/tests/ui/label/label_misspelled.rs +++ b/tests/ui/label/label_misspelled.rs @@ -4,41 +4,41 @@ fn main() { 'while_loop: while true { //~ WARN denote infinite loops with //~^ WARN unused label while_loop; - //~^ ERROR cannot find value `while_loop` in this scope + //~^ ERROR cannot find value `while_loop` }; 'while_let: while let Some(_) = Some(()) { //~^ WARN unused label while_let; - //~^ ERROR cannot find value `while_let` in this scope + //~^ ERROR cannot find value `while_let` } 'for_loop: for _ in 0..3 { //~^ WARN unused label for_loop; - //~^ ERROR cannot find value `for_loop` in this scope + //~^ ERROR cannot find value `for_loop` }; 'LOOP: loop { //~^ WARN unused label LOOP; - //~^ ERROR cannot find value `LOOP` in this scope + //~^ ERROR cannot find value `LOOP` }; } fn foo() { 'LOOP: loop { break LOOP; - //~^ ERROR cannot find value `LOOP` in this scope + //~^ ERROR cannot find value `LOOP` }; 'while_loop: while true { //~ WARN denote infinite loops with break while_loop; - //~^ ERROR cannot find value `while_loop` in this scope + //~^ ERROR cannot find value `while_loop` }; 'while_let: while let Some(_) = Some(()) { break while_let; - //~^ ERROR cannot find value `while_let` in this scope + //~^ ERROR cannot find value `while_let` } 'for_loop: for _ in 0..3 { break for_loop; - //~^ ERROR cannot find value `for_loop` in this scope + //~^ ERROR cannot find value `for_loop` }; } diff --git a/tests/ui/label/label_misspelled.stderr b/tests/ui/label/label_misspelled.stderr index 4b5b9e92ca09a..0e0b3174bc379 100644 --- a/tests/ui/label/label_misspelled.stderr +++ b/tests/ui/label/label_misspelled.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `while_loop` in this scope +error[E0425]: cannot find value `while_loop` --> $DIR/label_misspelled.rs:6:9 | LL | 'while_loop: while true { @@ -7,7 +7,7 @@ LL | LL | while_loop; | ^^^^^^^^^^ not found in this scope -error[E0425]: cannot find value `while_let` in this scope +error[E0425]: cannot find value `while_let` --> $DIR/label_misspelled.rs:11:9 | LL | 'while_let: while let Some(_) = Some(()) { @@ -16,7 +16,7 @@ LL | LL | while_let; | ^^^^^^^^^ not found in this scope -error[E0425]: cannot find value `for_loop` in this scope +error[E0425]: cannot find value `for_loop` --> $DIR/label_misspelled.rs:16:9 | LL | 'for_loop: for _ in 0..3 { @@ -25,7 +25,7 @@ LL | LL | for_loop; | ^^^^^^^^ not found in this scope -error[E0425]: cannot find value `LOOP` in this scope +error[E0425]: cannot find value `LOOP` --> $DIR/label_misspelled.rs:21:9 | LL | 'LOOP: loop { @@ -34,7 +34,7 @@ LL | LL | LOOP; | ^^^^ not found in this scope -error[E0425]: cannot find value `LOOP` in this scope +error[E0425]: cannot find value `LOOP` --> $DIR/label_misspelled.rs:28:15 | LL | 'LOOP: loop { @@ -45,7 +45,7 @@ LL | break LOOP; | not found in this scope | help: use the similarly named label: `'LOOP` -error[E0425]: cannot find value `while_loop` in this scope +error[E0425]: cannot find value `while_loop` --> $DIR/label_misspelled.rs:32:15 | LL | 'while_loop: while true { @@ -56,7 +56,7 @@ LL | break while_loop; | not found in this scope | help: use the similarly named label: `'while_loop` -error[E0425]: cannot find value `while_let` in this scope +error[E0425]: cannot find value `while_let` --> $DIR/label_misspelled.rs:36:15 | LL | 'while_let: while let Some(_) = Some(()) { @@ -67,7 +67,7 @@ LL | break while_let; | not found in this scope | help: use the similarly named label: `'while_let` -error[E0425]: cannot find value `for_loop` in this scope +error[E0425]: cannot find value `for_loop` --> $DIR/label_misspelled.rs:40:15 | LL | 'for_loop: for _ in 0..3 { diff --git a/tests/ui/label/label_misspelled_2.rs b/tests/ui/label/label_misspelled_2.rs index 55bbe6b30a593..92e2ad9df6c1f 100644 --- a/tests/ui/label/label_misspelled_2.rs +++ b/tests/ui/label/label_misspelled_2.rs @@ -5,12 +5,12 @@ fn main() { break 'a; } 'b: for _ in 0..1 { - break b; //~ ERROR cannot find value `b` in this scope + break b; //~ ERROR cannot find value `b` } c: for _ in 0..1 { //~ ERROR malformed loop label break 'c; } d: for _ in 0..1 { //~ ERROR malformed loop label - break d; //~ ERROR cannot find value `d` in this scope + break d; //~ ERROR cannot find value `d` } } diff --git a/tests/ui/label/label_misspelled_2.stderr b/tests/ui/label/label_misspelled_2.stderr index 960646d9894d1..cf0e5cf4f93ac 100644 --- a/tests/ui/label/label_misspelled_2.stderr +++ b/tests/ui/label/label_misspelled_2.stderr @@ -10,7 +10,7 @@ error: malformed loop label LL | d: for _ in 0..1 { | ^ help: use the correct loop label format: `'d` -error[E0425]: cannot find value `b` in this scope +error[E0425]: cannot find value `b` --> $DIR/label_misspelled_2.rs:8:15 | LL | 'b: for _ in 0..1 { @@ -21,7 +21,7 @@ LL | break b; | not found in this scope | help: use the similarly named label: `'b` -error[E0425]: cannot find value `d` in this scope +error[E0425]: cannot find value `d` --> $DIR/label_misspelled_2.rs:14:15 | LL | d: for _ in 0..1 { diff --git a/tests/ui/lang-items/issue-83471.stderr b/tests/ui/lang-items/issue-83471.stderr index 244b2efeaf1e0..99e0f37e82499 100644 --- a/tests/ui/lang-items/issue-83471.stderr +++ b/tests/ui/lang-items/issue-83471.stderr @@ -41,7 +41,7 @@ LL | #[lang = "fn"] LL | trait Fn { | - this trait has 0 generic arguments -error[E0425]: cannot find function `a` in this scope +error[E0425]: cannot find function `a` --> $DIR/issue-83471.rs:21:5 | LL | a() diff --git a/tests/ui/layout/cannot-transmute-unnormalizable-type.rs b/tests/ui/layout/cannot-transmute-unnormalizable-type.rs index d2b6e1d8eba66..f7215dff2dd24 100644 --- a/tests/ui/layout/cannot-transmute-unnormalizable-type.rs +++ b/tests/ui/layout/cannot-transmute-unnormalizable-type.rs @@ -5,7 +5,7 @@ trait Trait { impl Trait for () where Missing: Trait, - //~^ ERROR cannot find type `Missing` in this scope + //~^ ERROR cannot find type `Missing` { type RefTarget = (); } diff --git a/tests/ui/layout/cannot-transmute-unnormalizable-type.stderr b/tests/ui/layout/cannot-transmute-unnormalizable-type.stderr index dd5119318ff4b..d562a588afc02 100644 --- a/tests/ui/layout/cannot-transmute-unnormalizable-type.stderr +++ b/tests/ui/layout/cannot-transmute-unnormalizable-type.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `Missing` in this scope +error[E0412]: cannot find type `Missing` --> $DIR/cannot-transmute-unnormalizable-type.rs:7:5 | LL | Missing: Trait, diff --git a/tests/ui/layout/issue-84108.rs b/tests/ui/layout/issue-84108.rs index 974d5310f6bb8..6b086df248f8d 100644 --- a/tests/ui/layout/issue-84108.rs +++ b/tests/ui/layout/issue-84108.rs @@ -4,10 +4,10 @@ #![crate_type = "lib"] static FOO: (dyn AsRef, u8) = ("hello", 42); -//~^ ERROR cannot find type `OsStr` in this scope +//~^ ERROR cannot find type `OsStr` const BAR: (&Path, [u8], usize) = ("hello", [], 42); -//~^ ERROR cannot find type `Path` in this scope +//~^ ERROR cannot find type `Path` //~| ERROR the size for values of type `[u8]` cannot be known at compilation time //~| ERROR the size for values of type `[u8]` cannot be known at compilation time //~| ERROR mismatched types diff --git a/tests/ui/layout/issue-84108.stderr b/tests/ui/layout/issue-84108.stderr index 8ddce285e23f8..07bdc6db686b1 100644 --- a/tests/ui/layout/issue-84108.stderr +++ b/tests/ui/layout/issue-84108.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `OsStr` in this scope +error[E0412]: cannot find type `OsStr` --> $DIR/issue-84108.rs:6:24 | LL | static FOO: (dyn AsRef, u8) = ("hello", 42); @@ -9,7 +9,7 @@ help: consider importing this struct LL + use std::ffi::OsStr; | -error[E0412]: cannot find type `Path` in this scope +error[E0412]: cannot find type `Path` --> $DIR/issue-84108.rs:9:14 | LL | const BAR: (&Path, [u8], usize) = ("hello", [], 42); diff --git a/tests/ui/layout/malformed-unsized-type-in-union.rs b/tests/ui/layout/malformed-unsized-type-in-union.rs index 5d8ec576cf01b..2f04f74e5acac 100644 --- a/tests/ui/layout/malformed-unsized-type-in-union.rs +++ b/tests/ui/layout/malformed-unsized-type-in-union.rs @@ -1,7 +1,7 @@ // issue: 113760 union W { s: dyn Iterator } -//~^ ERROR cannot find type `Missing` in this scope +//~^ ERROR cannot find type `Missing` static ONCE: W = todo!(); diff --git a/tests/ui/layout/malformed-unsized-type-in-union.stderr b/tests/ui/layout/malformed-unsized-type-in-union.stderr index ad4f0cda19e5c..a2adb38cc1501 100644 --- a/tests/ui/layout/malformed-unsized-type-in-union.stderr +++ b/tests/ui/layout/malformed-unsized-type-in-union.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `Missing` in this scope +error[E0412]: cannot find type `Missing` --> $DIR/malformed-unsized-type-in-union.rs:3:34 | LL | union W { s: dyn Iterator } diff --git a/tests/ui/layout/transmute-to-tail-with-err.rs b/tests/ui/layout/transmute-to-tail-with-err.rs index 6753ce15ed158..41f0f1d4cde0e 100644 --- a/tests/ui/layout/transmute-to-tail-with-err.rs +++ b/tests/ui/layout/transmute-to-tail-with-err.rs @@ -1,7 +1,7 @@ trait Trait {} struct Bar(Box>); -//~^ ERROR cannot find type `T` in this scope +//~^ ERROR cannot find type `T` fn main() { let x: Bar = unsafe { std::mem::transmute(()) }; diff --git a/tests/ui/layout/transmute-to-tail-with-err.stderr b/tests/ui/layout/transmute-to-tail-with-err.stderr index 433c6b38d0b42..aeb47186eb1db 100644 --- a/tests/ui/layout/transmute-to-tail-with-err.stderr +++ b/tests/ui/layout/transmute-to-tail-with-err.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `T` in this scope +error[E0412]: cannot find type `T` --> $DIR/transmute-to-tail-with-err.rs:3:26 | LL | struct Bar(Box>); diff --git a/tests/ui/let-else/let-else-scope.rs b/tests/ui/let-else/let-else-scope.rs index 78a67769ef284..40d7d35e01b9c 100644 --- a/tests/ui/let-else/let-else-scope.rs +++ b/tests/ui/let-else/let-else-scope.rs @@ -1,5 +1,5 @@ fn main() { let Some(x) = Some(2) else { - panic!("{}", x); //~ ERROR cannot find value `x` in this scope + panic!("{}", x); //~ ERROR cannot find value `x` }; } diff --git a/tests/ui/let-else/let-else-scope.stderr b/tests/ui/let-else/let-else-scope.stderr index 335ee3dfb1ea7..2f8a99ddabb64 100644 --- a/tests/ui/let-else/let-else-scope.stderr +++ b/tests/ui/let-else/let-else-scope.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `x` in this scope +error[E0425]: cannot find value `x` --> $DIR/let-else-scope.rs:3:22 | LL | panic!("{}", x); diff --git a/tests/ui/lifetimes/issue-83907-invalid-fn-like-path.stderr b/tests/ui/lifetimes/issue-83907-invalid-fn-like-path.stderr index e57933da558fd..bdeb4a62ed9d3 100644 --- a/tests/ui/lifetimes/issue-83907-invalid-fn-like-path.stderr +++ b/tests/ui/lifetimes/issue-83907-invalid-fn-like-path.stderr @@ -6,7 +6,7 @@ LL | static STATIC_VAR_FIVE: &One(); | | | help: provide a definition for the static: `= ;` -error[E0412]: cannot find type `One` in this scope +error[E0412]: cannot find type `One` --> $DIR/issue-83907-invalid-fn-like-path.rs:3:26 | LL | static STATIC_VAR_FIVE: &One(); diff --git a/tests/ui/lint/internal/trivial-diagnostics.stderr b/tests/ui/lint/internal/trivial-diagnostics.stderr index d47a7dae023e2..233d24c49e806 100644 --- a/tests/ui/lint/internal/trivial-diagnostics.stderr +++ b/tests/ui/lint/internal/trivial-diagnostics.stderr @@ -1,10 +1,10 @@ -error[E0425]: cannot find value `msg` in this scope +error[E0425]: cannot find value `msg` --> $DIR/trivial-diagnostics.rs:4:21 | LL | struct_span_err(msg).emit(); | ^^^ not found in this scope -error[E0425]: cannot find function `struct_span_err` in this scope +error[E0425]: cannot find function `struct_span_err` --> $DIR/trivial-diagnostics.rs:4:5 | LL | struct_span_err(msg).emit(); diff --git a/tests/ui/lint/issue-35075.rs b/tests/ui/lint/issue-35075.rs index 0e54131c24560..c1b2b0c3a8018 100644 --- a/tests/ui/lint/issue-35075.rs +++ b/tests/ui/lint/issue-35075.rs @@ -1,9 +1,9 @@ struct Bar { - inner: Foo //~ ERROR cannot find type `Foo` in this scope + inner: Foo //~ ERROR cannot find type `Foo` } enum Baz { - Foo(Foo) //~ ERROR cannot find type `Foo` in this scope + Foo(Foo) //~ ERROR cannot find type `Foo` } fn main() {} diff --git a/tests/ui/lint/issue-35075.stderr b/tests/ui/lint/issue-35075.stderr index 08bdaa728583d..1fe6a0efa99a3 100644 --- a/tests/ui/lint/issue-35075.stderr +++ b/tests/ui/lint/issue-35075.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `Foo` in this scope +error[E0412]: cannot find type `Foo` --> $DIR/issue-35075.rs:2:12 | LL | inner: Foo @@ -9,7 +9,7 @@ help: there is an enum variant `Baz::Foo`; try using the variant's enum LL | inner: Baz | ~~~ -error[E0412]: cannot find type `Foo` in this scope +error[E0412]: cannot find type `Foo` --> $DIR/issue-35075.rs:6:9 | LL | Foo(Foo) diff --git a/tests/ui/lint/recommend-literal.rs b/tests/ui/lint/recommend-literal.rs index 453cbf28569e9..da79ff9c38adf 100644 --- a/tests/ui/lint/recommend-literal.rs +++ b/tests/ui/lint/recommend-literal.rs @@ -1,42 +1,42 @@ type Real = double; -//~^ ERROR cannot find type `double` in this scope +//~^ ERROR cannot find type `double` //~| HELP perhaps you intended to use this type fn main() { let x: Real = 3.5; let y: long = 74802374902374923; - //~^ ERROR cannot find type `long` in this scope + //~^ ERROR cannot find type `long` //~| HELP perhaps you intended to use this type let v1: Boolean = true; - //~^ ERROR: cannot find type `Boolean` in this scope [E0412] + //~^ ERROR: cannot find type `Boolean` [E0412] //~| HELP perhaps you intended to use this type let v2: Bool = true; - //~^ ERROR: cannot find type `Bool` in this scope [E0412] + //~^ ERROR: cannot find type `Bool` [E0412] //~| HELP a builtin type with a similar name exists //~| HELP perhaps you intended to use this type } fn z(a: boolean) { - //~^ ERROR cannot find type `boolean` in this scope + //~^ ERROR cannot find type `boolean` //~| HELP perhaps you intended to use this type } fn a() -> byte { -//~^ ERROR cannot find type `byte` in this scope +//~^ ERROR cannot find type `byte` //~| HELP perhaps you intended to use this type 3 } struct Data { //~ HELP you might be missing a type parameter width: float, - //~^ ERROR cannot find type `float` in this scope + //~^ ERROR cannot find type `float` //~| HELP perhaps you intended to use this type depth: Option, - //~^ ERROR cannot find type `int` in this scope + //~^ ERROR cannot find type `int` //~| HELP perhaps you intended to use this type } trait Stuff {} impl Stuff for short {} -//~^ ERROR cannot find type `short` in this scope +//~^ ERROR cannot find type `short` //~| HELP perhaps you intended to use this type diff --git a/tests/ui/lint/recommend-literal.stderr b/tests/ui/lint/recommend-literal.stderr index 424ecadd4b8cc..185298f21e321 100644 --- a/tests/ui/lint/recommend-literal.stderr +++ b/tests/ui/lint/recommend-literal.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `double` in this scope +error[E0412]: cannot find type `double` --> $DIR/recommend-literal.rs:1:13 | LL | type Real = double; @@ -7,7 +7,7 @@ LL | type Real = double; | not found in this scope | help: perhaps you intended to use this type: `f64` -error[E0412]: cannot find type `long` in this scope +error[E0412]: cannot find type `long` --> $DIR/recommend-literal.rs:7:12 | LL | let y: long = 74802374902374923; @@ -16,7 +16,7 @@ LL | let y: long = 74802374902374923; | not found in this scope | help: perhaps you intended to use this type: `i64` -error[E0412]: cannot find type `Boolean` in this scope +error[E0412]: cannot find type `Boolean` --> $DIR/recommend-literal.rs:10:13 | LL | let v1: Boolean = true; @@ -25,7 +25,7 @@ LL | let v1: Boolean = true; | not found in this scope | help: perhaps you intended to use this type: `bool` -error[E0412]: cannot find type `Bool` in this scope +error[E0412]: cannot find type `Bool` --> $DIR/recommend-literal.rs:13:13 | LL | let v2: Bool = true; @@ -40,7 +40,7 @@ help: perhaps you intended to use this type LL | let v2: bool = true; | ~~~~ -error[E0412]: cannot find type `boolean` in this scope +error[E0412]: cannot find type `boolean` --> $DIR/recommend-literal.rs:19:9 | LL | fn z(a: boolean) { @@ -49,7 +49,7 @@ LL | fn z(a: boolean) { | not found in this scope | help: perhaps you intended to use this type: `bool` -error[E0412]: cannot find type `byte` in this scope +error[E0412]: cannot find type `byte` --> $DIR/recommend-literal.rs:24:11 | LL | fn a() -> byte { @@ -58,7 +58,7 @@ LL | fn a() -> byte { | not found in this scope | help: perhaps you intended to use this type: `u8` -error[E0412]: cannot find type `float` in this scope +error[E0412]: cannot find type `float` --> $DIR/recommend-literal.rs:31:12 | LL | width: float, @@ -67,7 +67,7 @@ LL | width: float, | not found in this scope | help: perhaps you intended to use this type: `f32` -error[E0412]: cannot find type `int` in this scope +error[E0412]: cannot find type `int` --> $DIR/recommend-literal.rs:34:19 | LL | depth: Option, @@ -82,7 +82,7 @@ help: you might be missing a type parameter LL | struct Data { | +++++ -error[E0412]: cannot find type `short` in this scope +error[E0412]: cannot find type `short` --> $DIR/recommend-literal.rs:40:16 | LL | impl Stuff for short {} diff --git a/tests/ui/lint/use_suggestion_json.stderr b/tests/ui/lint/use_suggestion_json.stderr index 4683e5dd8f3c2..6ab129e287a8d 100644 --- a/tests/ui/lint/use_suggestion_json.stderr +++ b/tests/ui/lint/use_suggestion_json.stderr @@ -1,6 +1,6 @@ { "$message_type": "diagnostic", - "message": "cannot find type `Iter` in this scope", + "message": "cannot find type `Iter`", "code": { "code": "E0412", "explanation": "A used type name is not in scope. @@ -380,7 +380,7 @@ mod foo { "rendered": null } ], - "rendered": "\u001b[0m\u001b[1m\u001b[38;5;9merror[E0412]\u001b[0m\u001b[0m\u001b[1m: cannot find type `Iter` in this scope\u001b[0m + "rendered": "\u001b[0m\u001b[1m\u001b[38;5;9merror[E0412]\u001b[0m\u001b[0m\u001b[1m: cannot find type `Iter`\u001b[0m \u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m--> \u001b[0m\u001b[0m$DIR/use_suggestion_json.rs:12:12\u001b[0m \u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m \u001b[0m\u001b[1m\u001b[38;5;12mLL\u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m\u001b[0m \u001b[0m\u001b[0m let x: Iter;\u001b[0m diff --git a/tests/ui/loops/loop-break-value.rs b/tests/ui/loops/loop-break-value.rs index d509fc1657054..ad7e943159ba6 100644 --- a/tests/ui/loops/loop-break-value.rs +++ b/tests/ui/loops/loop-break-value.rs @@ -97,7 +97,7 @@ fn main() { 'LOOP: for _ in 0 .. 9 { break LOOP; - //~^ ERROR cannot find value `LOOP` in this scope + //~^ ERROR cannot find value `LOOP` } let _ = 'a: loop { diff --git a/tests/ui/loops/loop-break-value.stderr b/tests/ui/loops/loop-break-value.stderr index 0912bdbb221ec..f5a8c38a0bedb 100644 --- a/tests/ui/loops/loop-break-value.stderr +++ b/tests/ui/loops/loop-break-value.stderr @@ -16,7 +16,7 @@ LL | break; LL | let _ = 'a: loop { | ^^ label `'a` already in scope -error[E0425]: cannot find value `LOOP` in this scope +error[E0425]: cannot find value `LOOP` --> $DIR/loop-break-value.rs:99:15 | LL | 'LOOP: for _ in 0 .. 9 { diff --git a/tests/ui/lowering/span-bug-issue-121431.rs b/tests/ui/lowering/span-bug-issue-121431.rs index b855577bcfbff..0a54b523be720 100644 --- a/tests/ui/lowering/span-bug-issue-121431.rs +++ b/tests/ui/lowering/span-bug-issue-121431.rs @@ -1,4 +1,4 @@ fn bug() -> impl CallbackMarker< Item = [(); { |_: &mut ()| 3; 4 }] > {} -//~^ ERROR cannot find trait `CallbackMarker` in this scope +//~^ ERROR cannot find trait `CallbackMarker` fn main() {} diff --git a/tests/ui/lowering/span-bug-issue-121431.stderr b/tests/ui/lowering/span-bug-issue-121431.stderr index 595500b580640..adbe09b2d55b0 100644 --- a/tests/ui/lowering/span-bug-issue-121431.stderr +++ b/tests/ui/lowering/span-bug-issue-121431.stderr @@ -1,4 +1,4 @@ -error[E0405]: cannot find trait `CallbackMarker` in this scope +error[E0405]: cannot find trait `CallbackMarker` --> $DIR/span-bug-issue-121431.rs:1:21 | LL | fn bug() -> impl CallbackMarker< Item = [(); { |_: &mut ()| 3; 4 }] > {} diff --git a/tests/ui/macros/defined-later-issue-121061-2.rs b/tests/ui/macros/defined-later-issue-121061-2.rs index 3db76c281ec87..cde369a47491d 100644 --- a/tests/ui/macros/defined-later-issue-121061-2.rs +++ b/tests/ui/macros/defined-later-issue-121061-2.rs @@ -1,6 +1,6 @@ mod demo { fn hello() { - something_later!(); //~ ERROR cannot find macro `something_later` in this scope + something_later!(); //~ ERROR cannot find macro `something_later` } macro_rules! something_later { diff --git a/tests/ui/macros/defined-later-issue-121061.rs b/tests/ui/macros/defined-later-issue-121061.rs index 07c6d406f03c5..1b0a39f457606 100644 --- a/tests/ui/macros/defined-later-issue-121061.rs +++ b/tests/ui/macros/defined-later-issue-121061.rs @@ -1,5 +1,5 @@ fn main() { - something_later!(); //~ ERROR cannot find macro `something_later` in this scope + something_later!(); //~ ERROR cannot find macro `something_later` } macro_rules! something_later { diff --git a/tests/ui/macros/expand-full-no-resolution.rs b/tests/ui/macros/expand-full-no-resolution.rs index 4d90b8e2a531a..caa223f03a9e6 100644 --- a/tests/ui/macros/expand-full-no-resolution.rs +++ b/tests/ui/macros/expand-full-no-resolution.rs @@ -15,6 +15,6 @@ macro_rules! wrap { wrap!(); fn main() { - format_args!(a!()); //~ ERROR: cannot find macro `a` in this scope - env!(a!()); //~ ERROR: cannot find macro `a` in this scope + format_args!(a!()); //~ ERROR: cannot find macro `a` + env!(a!()); //~ ERROR: cannot find macro `a` } diff --git a/tests/ui/macros/issue-100199.rs b/tests/ui/macros/issue-100199.rs index b1bcc535d74af..a43af3db4f274 100644 --- a/tests/ui/macros/issue-100199.rs +++ b/tests/ui/macros/issue-100199.rs @@ -1,4 +1,4 @@ -#[issue_100199::struct_with_bound] //~ ERROR cannot find trait `MyTrait` in the crate root +#[issue_100199::struct_with_bound] //~ ERROR cannot find trait `MyTrait` struct Foo {} // The above must be on the first line so that it's span points to pos 0. // This used to trigger an ICE because the diagnostic emitter would get diff --git a/tests/ui/macros/issue-100199.stderr b/tests/ui/macros/issue-100199.stderr index 89c634ce4f0b5..170bd0cf0f017 100644 --- a/tests/ui/macros/issue-100199.stderr +++ b/tests/ui/macros/issue-100199.stderr @@ -1,4 +1,4 @@ -error[E0405]: cannot find trait `MyTrait` in the crate root +error[E0405]: cannot find trait `MyTrait` --> $DIR/issue-100199.rs:1:1 | LL | #[issue_100199::struct_with_bound] diff --git a/tests/ui/macros/issue-11692-1.rs b/tests/ui/macros/issue-11692-1.rs index b6f3bb8ef0549..5b1ec3e5650e2 100644 --- a/tests/ui/macros/issue-11692-1.rs +++ b/tests/ui/macros/issue-11692-1.rs @@ -1,3 +1,3 @@ fn main() { - print!(testo!()); //~ ERROR cannot find macro `testo` in this scope + print!(testo!()); //~ ERROR cannot find macro `testo` } diff --git a/tests/ui/macros/issue-11692-2.rs b/tests/ui/macros/issue-11692-2.rs index 5957ed338f4e7..71591974c1d97 100644 --- a/tests/ui/macros/issue-11692-2.rs +++ b/tests/ui/macros/issue-11692-2.rs @@ -1,3 +1,3 @@ fn main() { - concat!(test!()); //~ ERROR cannot find macro `test` in this scope + concat!(test!()); //~ ERROR cannot find macro `test` } diff --git a/tests/ui/macros/issue-118786.rs b/tests/ui/macros/issue-118786.rs index 97454c9de0798..ba48cbb68e7ac 100644 --- a/tests/ui/macros/issue-118786.rs +++ b/tests/ui/macros/issue-118786.rs @@ -6,7 +6,7 @@ macro_rules! make_macro { ($macro_name:tt) => { macro_rules! $macro_name { //~^ ERROR macro expansion ignores token `{` and any following - //~| ERROR cannot find macro `macro_rules` in this scope + //~| ERROR cannot find macro `macro_rules` () => {} } } diff --git a/tests/ui/macros/macro-backtrace-nested.stderr b/tests/ui/macros/macro-backtrace-nested.stderr index dadedfbe8f671..f50b02e5cf259 100644 --- a/tests/ui/macros/macro-backtrace-nested.stderr +++ b/tests/ui/macros/macro-backtrace-nested.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `fake` in this scope +error[E0425]: cannot find value `fake` --> $DIR/macro-backtrace-nested.rs:5:12 | LL | () => (fake) @@ -9,7 +9,7 @@ LL | 1 + call_nested_expr!(); | = note: this error originates in the macro `nested_expr` which comes from the expansion of the macro `call_nested_expr` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0425]: cannot find value `fake` in this scope +error[E0425]: cannot find value `fake` --> $DIR/macro-backtrace-nested.rs:5:12 | LL | () => (fake) diff --git a/tests/ui/macros/macro-context.rs b/tests/ui/macros/macro-context.rs index d09fdf118e6f4..766da567eff7a 100644 --- a/tests/ui/macros/macro-context.rs +++ b/tests/ui/macros/macro-context.rs @@ -4,8 +4,8 @@ macro_rules! m { //~| ERROR macro expansion ignores token `typeof` //~| ERROR macro expansion ignores token `;` //~| ERROR macro expansion ignores token `;` - //~| ERROR cannot find type `i` in this scope - //~| ERROR cannot find value `i` in this scope + //~| ERROR cannot find type `i` + //~| ERROR cannot find value `i` //~| WARN trailing semicolon in macro //~| WARN this was previously } diff --git a/tests/ui/macros/macro-context.stderr b/tests/ui/macros/macro-context.stderr index 7785f41594627..5ebdf2af93841 100644 --- a/tests/ui/macros/macro-context.stderr +++ b/tests/ui/macros/macro-context.stderr @@ -42,7 +42,7 @@ LL | m!(); | = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0412]: cannot find type `i` in this scope +error[E0412]: cannot find type `i` --> $DIR/macro-context.rs:3:13 | LL | () => ( i ; typeof ); @@ -53,7 +53,7 @@ LL | let a: m!(); | = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0425]: cannot find value `i` in this scope +error[E0425]: cannot find value `i` --> $DIR/macro-context.rs:3:13 | LL | () => ( i ; typeof ); diff --git a/tests/ui/macros/macro-expand-within-generics-in-path.rs b/tests/ui/macros/macro-expand-within-generics-in-path.rs index 017d5152221bf..1ba32afee5c5f 100644 --- a/tests/ui/macros/macro-expand-within-generics-in-path.rs +++ b/tests/ui/macros/macro-expand-within-generics-in-path.rs @@ -14,6 +14,6 @@ macro_rules! p { m!(generic); //~^ ERROR: unexpected generic arguments in path -//~| ERROR: cannot find attribute `generic` in this scope +//~| ERROR: cannot find attribute `generic` fn main() {} diff --git a/tests/ui/macros/macro-metavar-expr-concat/hygiene.rs b/tests/ui/macros/macro-metavar-expr-concat/hygiene.rs index 24b0e36498a3e..17397dc3a3e89 100644 --- a/tests/ui/macros/macro-metavar-expr-concat/hygiene.rs +++ b/tests/ui/macros/macro-metavar-expr-concat/hygiene.rs @@ -3,7 +3,7 @@ macro_rules! join { ($lhs:ident, $rhs:ident) => { ${concat($lhs, $rhs)} - //~^ ERROR cannot find value `abcdef` in this scope + //~^ ERROR cannot find value `abcdef` }; } diff --git a/tests/ui/macros/macro-metavar-expr-concat/hygiene.stderr b/tests/ui/macros/macro-metavar-expr-concat/hygiene.stderr index ef2326dce857f..99229927502c9 100644 --- a/tests/ui/macros/macro-metavar-expr-concat/hygiene.stderr +++ b/tests/ui/macros/macro-metavar-expr-concat/hygiene.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `abcdef` in this scope +error[E0425]: cannot find value `abcdef` --> $DIR/hygiene.rs:5:10 | LL | ${concat($lhs, $rhs)} diff --git a/tests/ui/macros/macro-outer-attributes.rs b/tests/ui/macros/macro-outer-attributes.rs index 8c79683f49a96..186353f133f9b 100644 --- a/tests/ui/macros/macro-outer-attributes.rs +++ b/tests/ui/macros/macro-outer-attributes.rs @@ -15,6 +15,6 @@ test!(b, // test1!(#[bar]) #[rustc_dummy] fn main() { - a::bar(); //~ ERROR cannot find function `bar` in module `a` + a::bar(); //~ ERROR cannot find function `bar` b::bar(); } diff --git a/tests/ui/macros/macro-outer-attributes.stderr b/tests/ui/macros/macro-outer-attributes.stderr index 87c0655a422d6..db79d98f1fef2 100644 --- a/tests/ui/macros/macro-outer-attributes.stderr +++ b/tests/ui/macros/macro-outer-attributes.stderr @@ -1,8 +1,8 @@ -error[E0425]: cannot find function `bar` in module `a` +error[E0425]: cannot find function `bar` --> $DIR/macro-outer-attributes.rs:18:8 | LL | a::bar(); - | ^^^ not found in `a` + | ^^^ not found in module `a` | note: found an item that was configured out --> $DIR/macro-outer-attributes.rs:9:14 diff --git a/tests/ui/macros/macro-parameter-span.rs b/tests/ui/macros/macro-parameter-span.rs index 5609f84e141b6..8aa9b405aa35e 100644 --- a/tests/ui/macros/macro-parameter-span.rs +++ b/tests/ui/macros/macro-parameter-span.rs @@ -8,6 +8,6 @@ macro_rules! foo { // not to the macro variable '$id' fn main() { foo!( - x //~ ERROR cannot find value `x` in this scope + x //~ ERROR cannot find value `x` ); } diff --git a/tests/ui/macros/macro-parameter-span.stderr b/tests/ui/macros/macro-parameter-span.stderr index 247750a8ad705..ed61ede88bf75 100644 --- a/tests/ui/macros/macro-parameter-span.stderr +++ b/tests/ui/macros/macro-parameter-span.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `x` in this scope +error[E0425]: cannot find value `x` --> $DIR/macro-parameter-span.rs:11:9 | LL | x diff --git a/tests/ui/macros/macro-path-prelude-fail-3.rs b/tests/ui/macros/macro-path-prelude-fail-3.rs index 68eb350a95614..959a0286fbbd9 100644 --- a/tests/ui/macros/macro-path-prelude-fail-3.rs +++ b/tests/ui/macros/macro-path-prelude-fail-3.rs @@ -1,3 +1,3 @@ fn main() { - inline!(); //~ ERROR cannot find macro `inline` in this scope + inline!(); //~ ERROR cannot find macro `inline` } diff --git a/tests/ui/macros/macro-reexport-removed.rs b/tests/ui/macros/macro-reexport-removed.rs index 4a054686d7767..e9e1c52da3749 100644 --- a/tests/ui/macros/macro-reexport-removed.rs +++ b/tests/ui/macros/macro-reexport-removed.rs @@ -2,7 +2,7 @@ #![feature(macro_reexport)] //~ ERROR feature has been removed -#[macro_reexport(macro_one)] //~ ERROR cannot find attribute `macro_reexport` in this scope +#[macro_reexport(macro_one)] //~ ERROR cannot find attribute `macro_reexport` extern crate two_macros; fn main() {} diff --git a/tests/ui/macros/rfc-3086-metavar-expr/syntax-errors.rs b/tests/ui/macros/rfc-3086-metavar-expr/syntax-errors.rs index 1eda5f5bb6bc3..89acf6ffdddf5 100644 --- a/tests/ui/macros/rfc-3086-metavar-expr/syntax-errors.rs +++ b/tests/ui/macros/rfc-3086-metavar-expr/syntax-errors.rs @@ -21,15 +21,15 @@ macro_rules! curly__rhs_dollar__no_round { #[rustfmt::skip] // autoformatters can break a few of the error traces macro_rules! no_curly__no_rhs_dollar__round { ( $( $i:ident ),* ) => { count(i) }; - //~^ ERROR cannot find function `count` in this scope - //~| ERROR cannot find value `i` in this scope + //~^ ERROR cannot find function `count` + //~| ERROR cannot find value `i` } #[rustfmt::skip] // autoformatters can break a few of the error traces macro_rules! no_curly__no_rhs_dollar__no_round { ( $i:ident ) => { count(i) }; - //~^ ERROR cannot find function `count` in this scope - //~| ERROR cannot find value `i` in this scope + //~^ ERROR cannot find function `count` + //~| ERROR cannot find value `i` } #[rustfmt::skip] // autoformatters can break a few of the error traces @@ -41,7 +41,7 @@ macro_rules! no_curly__rhs_dollar__round { #[rustfmt::skip] // autoformatters can break a few of the error traces macro_rules! no_curly__rhs_dollar__no_round { ( $i:ident ) => { count($i) }; - //~^ ERROR cannot find function `count` in this scope + //~^ ERROR cannot find function `count` } // Other scenarios @@ -150,7 +150,7 @@ fn main() { no_curly__no_rhs_dollar__no_round!(a); no_curly__rhs_dollar__round!(a, b, c); no_curly__rhs_dollar__no_round!(a); - //~^ ERROR cannot find value `a` in this scope + //~^ ERROR cannot find value `a` extra_garbage_after_metavar!(a); metavar_depth_is_not_literal!(a); diff --git a/tests/ui/macros/rfc-3086-metavar-expr/syntax-errors.stderr b/tests/ui/macros/rfc-3086-metavar-expr/syntax-errors.stderr index 2c44ad2e0a4ad..1554fdbce0bed 100644 --- a/tests/ui/macros/rfc-3086-metavar-expr/syntax-errors.stderr +++ b/tests/ui/macros/rfc-3086-metavar-expr/syntax-errors.stderr @@ -313,7 +313,7 @@ LL | unknown_metavar!(a); | = note: this error originates in the macro `unknown_metavar` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0425]: cannot find value `i` in this scope +error[E0425]: cannot find value `i` --> $DIR/syntax-errors.rs:23:36 | LL | ( $( $i:ident ),* ) => { count(i) }; @@ -324,7 +324,7 @@ LL | no_curly__no_rhs_dollar__round!(a, b, c); | = note: this error originates in the macro `no_curly__no_rhs_dollar__round` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0425]: cannot find value `i` in this scope +error[E0425]: cannot find value `i` --> $DIR/syntax-errors.rs:30:29 | LL | ( $i:ident ) => { count(i) }; @@ -335,13 +335,13 @@ LL | no_curly__no_rhs_dollar__no_round!(a); | = note: this error originates in the macro `no_curly__no_rhs_dollar__no_round` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0425]: cannot find value `a` in this scope +error[E0425]: cannot find value `a` --> $DIR/syntax-errors.rs:152:37 | LL | no_curly__rhs_dollar__no_round!(a); | ^ not found in this scope -error[E0425]: cannot find function `count` in this scope +error[E0425]: cannot find function `count` --> $DIR/syntax-errors.rs:23:30 | LL | ( $( $i:ident ),* ) => { count(i) }; @@ -352,7 +352,7 @@ LL | no_curly__no_rhs_dollar__round!(a, b, c); | = note: this error originates in the macro `no_curly__no_rhs_dollar__round` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0425]: cannot find function `count` in this scope +error[E0425]: cannot find function `count` --> $DIR/syntax-errors.rs:30:23 | LL | ( $i:ident ) => { count(i) }; @@ -363,7 +363,7 @@ LL | no_curly__no_rhs_dollar__no_round!(a); | = note: this error originates in the macro `no_curly__no_rhs_dollar__no_round` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0425]: cannot find function `count` in this scope +error[E0425]: cannot find function `count` --> $DIR/syntax-errors.rs:43:23 | LL | ( $i:ident ) => { count($i) }; diff --git a/tests/ui/match/expr_before_ident_pat.rs b/tests/ui/match/expr_before_ident_pat.rs index 27ef3d05a2954..02f053a05bc70 100644 --- a/tests/ui/match/expr_before_ident_pat.rs +++ b/tests/ui/match/expr_before_ident_pat.rs @@ -8,6 +8,6 @@ macro_rules! funny { fn main() { funny!(a, a); - //~^ ERROR cannot find value `a` in this scope + //~^ ERROR cannot find value `a` //~| ERROR arbitrary expressions aren't allowed in patterns } diff --git a/tests/ui/match/expr_before_ident_pat.stderr b/tests/ui/match/expr_before_ident_pat.stderr index 1657c51545cb2..20382c70c5dea 100644 --- a/tests/ui/match/expr_before_ident_pat.stderr +++ b/tests/ui/match/expr_before_ident_pat.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `a` in this scope +error[E0425]: cannot find value `a` --> $DIR/expr_before_ident_pat.rs:10:12 | LL | funny!(a, a); diff --git a/tests/ui/match/issue-82866.rs b/tests/ui/match/issue-82866.rs index 95cd62261f109..042a2611c0880 100644 --- a/tests/ui/match/issue-82866.rs +++ b/tests/ui/match/issue-82866.rs @@ -1,7 +1,7 @@ fn main() { match x { - //~^ ERROR cannot find value `x` in this scope + //~^ ERROR cannot find value `x` Some::(v) => (), - //~^ ERROR cannot find type `v` in this scope + //~^ ERROR cannot find type `v` } } diff --git a/tests/ui/match/issue-82866.stderr b/tests/ui/match/issue-82866.stderr index f9e3360a525ff..09d69408d3cdf 100644 --- a/tests/ui/match/issue-82866.stderr +++ b/tests/ui/match/issue-82866.stderr @@ -1,10 +1,10 @@ -error[E0425]: cannot find value `x` in this scope +error[E0425]: cannot find value `x` --> $DIR/issue-82866.rs:2:11 | LL | match x { | ^ not found in this scope -error[E0412]: cannot find type `v` in this scope +error[E0412]: cannot find type `v` --> $DIR/issue-82866.rs:4:16 | LL | Some::(v) => (), diff --git a/tests/ui/match/issue-92100.rs b/tests/ui/match/issue-92100.rs index baac570dd8a9d..1fb151d2895d9 100644 --- a/tests/ui/match/issue-92100.rs +++ b/tests/ui/match/issue-92100.rs @@ -2,6 +2,6 @@ fn main() { match [1, 2] { - [a.., a] => {} //~ ERROR cannot find value `a` in this scope + [a.., a] => {} //~ ERROR cannot find value `a` } } diff --git a/tests/ui/match/issue-92100.stderr b/tests/ui/match/issue-92100.stderr index eb9f4ba1ad698..0a18f0d1e9baa 100644 --- a/tests/ui/match/issue-92100.stderr +++ b/tests/ui/match/issue-92100.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `a` in this scope +error[E0425]: cannot find value `a` --> $DIR/issue-92100.rs:5:10 | LL | [a.., a] => {} diff --git a/tests/ui/match/match-join.rs b/tests/ui/match/match-join.rs index b0f2593c85364..3ba7b3363fd21 100644 --- a/tests/ui/match/match-join.rs +++ b/tests/ui/match/match-join.rs @@ -6,6 +6,6 @@ fn my_panic() -> ! { panic!(); } fn main() { match true { false => { my_panic(); } true => { } } - println!("{}", x); //~ ERROR cannot find value `x` in this scope + println!("{}", x); //~ ERROR cannot find value `x` let x: isize; } diff --git a/tests/ui/match/match-join.stderr b/tests/ui/match/match-join.stderr index 4feb1bef9ad59..b5cf1201217ac 100644 --- a/tests/ui/match/match-join.stderr +++ b/tests/ui/match/match-join.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `x` in this scope +error[E0425]: cannot find value `x` --> $DIR/match-join.rs:9:20 | LL | println!("{}", x); diff --git a/tests/ui/methods/suggest-method-on-call-for-ambig-receiver.rs b/tests/ui/methods/suggest-method-on-call-for-ambig-receiver.rs index fc2c15ee8c66d..58ba6d8f261a1 100644 --- a/tests/ui/methods/suggest-method-on-call-for-ambig-receiver.rs +++ b/tests/ui/methods/suggest-method-on-call-for-ambig-receiver.rs @@ -8,7 +8,7 @@ fn separate_arms() { } Some(right) => { consume(right); - //~^ ERROR cannot find function `consume` in this scope + //~^ ERROR cannot find function `consume` } } } diff --git a/tests/ui/methods/suggest-method-on-call-for-ambig-receiver.stderr b/tests/ui/methods/suggest-method-on-call-for-ambig-receiver.stderr index 40d8301c24e5c..cefa5a4808fcf 100644 --- a/tests/ui/methods/suggest-method-on-call-for-ambig-receiver.stderr +++ b/tests/ui/methods/suggest-method-on-call-for-ambig-receiver.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find function `consume` in this scope +error[E0425]: cannot find function `consume` --> $DIR/suggest-method-on-call-for-ambig-receiver.rs:10:13 | LL | consume(right); diff --git a/tests/ui/methods/suggest-method-on-call-with-macro-rcvr.rs b/tests/ui/methods/suggest-method-on-call-with-macro-rcvr.rs index 93b7ddf5e9e09..eb5812bce53b0 100644 --- a/tests/ui/methods/suggest-method-on-call-with-macro-rcvr.rs +++ b/tests/ui/methods/suggest-method-on-call-with-macro-rcvr.rs @@ -2,5 +2,5 @@ fn main() { let hello = len(vec![]); - //~^ ERROR cannot find function `len` in this scope + //~^ ERROR cannot find function `len` } diff --git a/tests/ui/methods/suggest-method-on-call-with-macro-rcvr.stderr b/tests/ui/methods/suggest-method-on-call-with-macro-rcvr.stderr index 86c2f6431d1b8..2d3918bdeada7 100644 --- a/tests/ui/methods/suggest-method-on-call-with-macro-rcvr.stderr +++ b/tests/ui/methods/suggest-method-on-call-with-macro-rcvr.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find function `len` in this scope +error[E0425]: cannot find function `len` --> $DIR/suggest-method-on-call-with-macro-rcvr.rs:4:17 | LL | let hello = len(vec![]); diff --git a/tests/ui/mir/issue-83499-input-output-iteration-ice.rs b/tests/ui/mir/issue-83499-input-output-iteration-ice.rs index 78e5c96180285..7a298ad7a2f6a 100644 --- a/tests/ui/mir/issue-83499-input-output-iteration-ice.rs +++ b/tests/ui/mir/issue-83499-input-output-iteration-ice.rs @@ -6,5 +6,5 @@ fn main() {} fn foo(_: Bar, ...) -> impl {} //~^ ERROR only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg -//~| ERROR cannot find type `Bar` in this scope +//~| ERROR cannot find type `Bar` //~| ERROR at least one trait must be specified diff --git a/tests/ui/mir/issue-83499-input-output-iteration-ice.stderr b/tests/ui/mir/issue-83499-input-output-iteration-ice.stderr index 80a8a94aea400..9467f1ced14d1 100644 --- a/tests/ui/mir/issue-83499-input-output-iteration-ice.stderr +++ b/tests/ui/mir/issue-83499-input-output-iteration-ice.stderr @@ -10,7 +10,7 @@ error: at least one trait must be specified LL | fn foo(_: Bar, ...) -> impl {} | ^^^^ -error[E0412]: cannot find type `Bar` in this scope +error[E0412]: cannot find type `Bar` --> $DIR/issue-83499-input-output-iteration-ice.rs:7:11 | LL | fn foo(_: Bar, ...) -> impl {} diff --git a/tests/ui/mir/mir-build-2021-closure-capture-ice-110453-1.rs b/tests/ui/mir/mir-build-2021-closure-capture-ice-110453-1.rs index 0b2e63bfcf772..311dc77e1db7b 100644 --- a/tests/ui/mir/mir-build-2021-closure-capture-ice-110453-1.rs +++ b/tests/ui/mir/mir-build-2021-closure-capture-ice-110453-1.rs @@ -10,7 +10,7 @@ pub fn a() -> B { B } mod handlers { pub struct C(B); - //~^ ERROR cannot find type `B` in this scope + //~^ ERROR cannot find type `B` pub fn c() -> impl Fn() -> C { let a1 = (); || C((crate::a(), a1).into()) diff --git a/tests/ui/mir/mir-build-2021-closure-capture-ice-110453-1.stderr b/tests/ui/mir/mir-build-2021-closure-capture-ice-110453-1.stderr index 468da0227d3d0..feb80778b3bb0 100644 --- a/tests/ui/mir/mir-build-2021-closure-capture-ice-110453-1.stderr +++ b/tests/ui/mir/mir-build-2021-closure-capture-ice-110453-1.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `B` in this scope +error[E0412]: cannot find type `B` --> $DIR/mir-build-2021-closure-capture-ice-110453-1.rs:12:18 | LL | pub struct C(B); diff --git a/tests/ui/mir/mir-build-2021-closure-capture-ice-110453-2.rs b/tests/ui/mir/mir-build-2021-closure-capture-ice-110453-2.rs index d63ccc6651c7b..4e45d1eabc6c9 100644 --- a/tests/ui/mir/mir-build-2021-closure-capture-ice-110453-2.rs +++ b/tests/ui/mir/mir-build-2021-closure-capture-ice-110453-2.rs @@ -6,6 +6,6 @@ #![crate_type="lib"] pub fn dup(f: impl Fn(i32) -> i32) -> impl Fn(as_str) -> i32 { -//~^ ERROR cannot find type `as_str` in this scope +//~^ ERROR cannot find type `as_str` move |a| f(a * 2) } diff --git a/tests/ui/mir/mir-build-2021-closure-capture-ice-110453-2.stderr b/tests/ui/mir/mir-build-2021-closure-capture-ice-110453-2.stderr index 8fe4981eb3f24..5479e6b5fee8b 100644 --- a/tests/ui/mir/mir-build-2021-closure-capture-ice-110453-2.stderr +++ b/tests/ui/mir/mir-build-2021-closure-capture-ice-110453-2.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `as_str` in this scope +error[E0412]: cannot find type `as_str` --> $DIR/mir-build-2021-closure-capture-ice-110453-2.rs:8:47 | LL | pub fn dup(f: impl Fn(i32) -> i32) -> impl Fn(as_str) -> i32 { diff --git a/tests/ui/mir/validate/error-body.rs b/tests/ui/mir/validate/error-body.rs index e77867ddfd421..4025d048afd03 100644 --- a/tests/ui/mir/validate/error-body.rs +++ b/tests/ui/mir/validate/error-body.rs @@ -3,7 +3,7 @@ fn _test() { let x = || 45; missing(); - //~^ ERROR cannot find function `missing` in this scope + //~^ ERROR cannot find function `missing` } fn main() {} diff --git a/tests/ui/mir/validate/error-body.stderr b/tests/ui/mir/validate/error-body.stderr index 1dfeaf0b7e2cb..a7536238bbd9f 100644 --- a/tests/ui/mir/validate/error-body.stderr +++ b/tests/ui/mir/validate/error-body.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find function `missing` in this scope +error[E0425]: cannot find function `missing` --> $DIR/error-body.rs:5:5 | LL | missing(); diff --git a/tests/ui/missing/missing-items/missing-const-parameter.rs b/tests/ui/missing/missing-items/missing-const-parameter.rs index a3af88f263331..c688a7ddb77e9 100644 --- a/tests/ui/missing/missing-items/missing-const-parameter.rs +++ b/tests/ui/missing/missing-items/missing-const-parameter.rs @@ -1,23 +1,23 @@ struct Struct; impl Struct<{ N }> {} -//~^ ERROR cannot find value `N` in this scope +//~^ ERROR cannot find value `N` //~| HELP you might be missing a const parameter fn func0(_: Struct<{ N }>) {} -//~^ ERROR cannot find value `N` in this scope +//~^ ERROR cannot find value `N` //~| HELP you might be missing a const parameter fn func1(_: [u8; N]) {} -//~^ ERROR cannot find value `N` in this scope +//~^ ERROR cannot find value `N` //~| HELP you might be missing a const parameter fn func2(_: [T; N]) {} -//~^ ERROR cannot find value `N` in this scope +//~^ ERROR cannot find value `N` //~| HELP you might be missing a const parameter struct Image([[u32; C]; R]); -//~^ ERROR cannot find value `C` in this scope +//~^ ERROR cannot find value `C` //~| HELP a const parameter with a similar name exists //~| HELP you might be missing a const parameter diff --git a/tests/ui/missing/missing-items/missing-const-parameter.stderr b/tests/ui/missing/missing-items/missing-const-parameter.stderr index d9fea1306514c..0b9c674f3ec15 100644 --- a/tests/ui/missing/missing-items/missing-const-parameter.stderr +++ b/tests/ui/missing/missing-items/missing-const-parameter.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `N` in this scope +error[E0425]: cannot find value `N` --> $DIR/missing-const-parameter.rs:3:15 | LL | impl Struct<{ N }> {} @@ -9,7 +9,7 @@ help: you might be missing a const parameter LL | impl Struct<{ N }> {} | +++++++++++++++++++++ -error[E0425]: cannot find value `N` in this scope +error[E0425]: cannot find value `N` --> $DIR/missing-const-parameter.rs:7:22 | LL | fn func0(_: Struct<{ N }>) {} @@ -20,7 +20,7 @@ help: you might be missing a const parameter LL | fn func0(_: Struct<{ N }>) {} | +++++++++++++++++++++ -error[E0425]: cannot find value `N` in this scope +error[E0425]: cannot find value `N` --> $DIR/missing-const-parameter.rs:11:18 | LL | fn func1(_: [u8; N]) {} @@ -31,7 +31,7 @@ help: you might be missing a const parameter LL | fn func1(_: [u8; N]) {} | +++++++++++++++++++++ -error[E0425]: cannot find value `N` in this scope +error[E0425]: cannot find value `N` --> $DIR/missing-const-parameter.rs:15:20 | LL | fn func2(_: [T; N]) {} @@ -42,7 +42,7 @@ help: you might be missing a const parameter LL | fn func2(_: [T; N]) {} | +++++++++++++++++++++ -error[E0425]: cannot find value `C` in this scope +error[E0425]: cannot find value `C` --> $DIR/missing-const-parameter.rs:19:37 | LL | struct Image([[u32; C]; R]); diff --git a/tests/ui/missing/missing-items/missing-type-parameter2.rs b/tests/ui/missing/missing-items/missing-type-parameter2.rs index e9b32fb7198d4..7c302127a5d54 100644 --- a/tests/ui/missing/missing-items/missing-type-parameter2.rs +++ b/tests/ui/missing/missing-items/missing-type-parameter2.rs @@ -1,19 +1,19 @@ struct X(); impl X {} -//~^ ERROR cannot find type `N` in this scope +//~^ ERROR cannot find type `N` //~| ERROR unresolved item provided when a constant was expected impl X {} -//~^ ERROR cannot find type `N` in this scope +//~^ ERROR cannot find type `N` //~| ERROR defaults for const parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions //~| ERROR unresolved item provided when a constant was expected fn foo(_: T) where T: Send {} -//~^ ERROR cannot find type `T` in this scope -//~| ERROR cannot find type `T` in this scope +//~^ ERROR cannot find type `T` +//~| ERROR cannot find type `T` fn bar(_: A) {} -//~^ ERROR cannot find type `A` in this scope +//~^ ERROR cannot find type `A` fn main() { } diff --git a/tests/ui/missing/missing-items/missing-type-parameter2.stderr b/tests/ui/missing/missing-items/missing-type-parameter2.stderr index f33951c98bfb3..073bb9c9a9eee 100644 --- a/tests/ui/missing/missing-items/missing-type-parameter2.stderr +++ b/tests/ui/missing/missing-items/missing-type-parameter2.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `N` in this scope +error[E0412]: cannot find type `N` --> $DIR/missing-type-parameter2.rs:3:8 | LL | struct X(); @@ -16,7 +16,7 @@ help: you might be missing a type parameter LL | impl X {} | +++ -error[E0412]: cannot find type `N` in this scope +error[E0412]: cannot find type `N` --> $DIR/missing-type-parameter2.rs:6:28 | LL | impl X {} @@ -33,7 +33,7 @@ help: you might be missing a type parameter LL | impl X {} | +++ -error[E0412]: cannot find type `T` in this scope +error[E0412]: cannot find type `T` --> $DIR/missing-type-parameter2.rs:11:20 | LL | struct X(); @@ -51,7 +51,7 @@ help: you might be missing a type parameter LL | fn foo(_: T) where T: Send {} | +++ -error[E0412]: cannot find type `T` in this scope +error[E0412]: cannot find type `T` --> $DIR/missing-type-parameter2.rs:11:11 | LL | struct X(); @@ -69,7 +69,7 @@ help: you might be missing a type parameter LL | fn foo(_: T) where T: Send {} | +++ -error[E0412]: cannot find type `A` in this scope +error[E0412]: cannot find type `A` --> $DIR/missing-type-parameter2.rs:15:24 | LL | struct X(); diff --git a/tests/ui/missing/missing-macro-use.rs b/tests/ui/missing/missing-macro-use.rs index a761c9a5ffd27..d7ddda7332852 100644 --- a/tests/ui/missing/missing-macro-use.rs +++ b/tests/ui/missing/missing-macro-use.rs @@ -4,5 +4,5 @@ extern crate two_macros; pub fn main() { macro_two!(); - //~^ ERROR cannot find macro `macro_two` in this scope + //~^ ERROR cannot find macro `macro_two` } diff --git a/tests/ui/modules_and_files_visibility/mod_file_correct_spans.rs b/tests/ui/modules_and_files_visibility/mod_file_correct_spans.rs index c42d2eaa7bd6d..1e00523abc20b 100644 --- a/tests/ui/modules_and_files_visibility/mod_file_correct_spans.rs +++ b/tests/ui/modules_and_files_visibility/mod_file_correct_spans.rs @@ -4,5 +4,5 @@ mod mod_file_aux; fn main() { assert!(mod_file_aux::bar() == 10); - //~^ ERROR cannot find function `bar` in module `mod_file_aux` + //~^ ERROR cannot find function `bar` } diff --git a/tests/ui/modules_and_files_visibility/mod_file_correct_spans.stderr b/tests/ui/modules_and_files_visibility/mod_file_correct_spans.stderr index 3426505cd1105..889f88df42c0f 100644 --- a/tests/ui/modules_and_files_visibility/mod_file_correct_spans.stderr +++ b/tests/ui/modules_and_files_visibility/mod_file_correct_spans.stderr @@ -1,8 +1,8 @@ -error[E0425]: cannot find function `bar` in module `mod_file_aux` +error[E0425]: cannot find function `bar` --> $DIR/mod_file_correct_spans.rs:6:27 | LL | assert!(mod_file_aux::bar() == 10); - | ^^^ not found in `mod_file_aux` + | ^^^ not found in module `mod_file_aux` error: aborting due to 1 previous error diff --git a/tests/ui/namespace/namespaced-enum-glob-import-no-impls-xcrate.rs b/tests/ui/namespace/namespaced-enum-glob-import-no-impls-xcrate.rs index 6b92f4101948a..32ce8fbeafcfb 100644 --- a/tests/ui/namespace/namespaced-enum-glob-import-no-impls-xcrate.rs +++ b/tests/ui/namespace/namespaced-enum-glob-import-no-impls-xcrate.rs @@ -8,8 +8,8 @@ mod m { pub fn main() { use namespaced_enums::Foo::*; - foo(); //~ ERROR cannot find function `foo` in this scope - m::foo(); //~ ERROR cannot find function `foo` in module `m` - bar(); //~ ERROR cannot find function `bar` in this scope - m::bar(); //~ ERROR cannot find function `bar` in module `m` + foo(); //~ ERROR cannot find function `foo` + m::foo(); //~ ERROR cannot find function `foo` + bar(); //~ ERROR cannot find function `bar` + m::bar(); //~ ERROR cannot find function `bar` } diff --git a/tests/ui/namespace/namespaced-enum-glob-import-no-impls-xcrate.stderr b/tests/ui/namespace/namespaced-enum-glob-import-no-impls-xcrate.stderr index 227d30282b1ea..5a325b6870f50 100644 --- a/tests/ui/namespace/namespaced-enum-glob-import-no-impls-xcrate.stderr +++ b/tests/ui/namespace/namespaced-enum-glob-import-no-impls-xcrate.stderr @@ -1,22 +1,22 @@ -error[E0425]: cannot find function `foo` in module `m` +error[E0425]: cannot find function `foo` --> $DIR/namespaced-enum-glob-import-no-impls-xcrate.rs:12:8 | LL | m::foo(); - | ^^^ not found in `m` + | ^^^ not found in module `m` -error[E0425]: cannot find function `bar` in module `m` +error[E0425]: cannot find function `bar` --> $DIR/namespaced-enum-glob-import-no-impls-xcrate.rs:14:8 | LL | m::bar(); - | ^^^ not found in `m` + | ^^^ not found in module `m` -error[E0425]: cannot find function `foo` in this scope +error[E0425]: cannot find function `foo` --> $DIR/namespaced-enum-glob-import-no-impls-xcrate.rs:11:5 | LL | foo(); | ^^^ not found in this scope -error[E0425]: cannot find function `bar` in this scope +error[E0425]: cannot find function `bar` --> $DIR/namespaced-enum-glob-import-no-impls-xcrate.rs:13:5 | LL | bar(); diff --git a/tests/ui/namespace/namespaced-enum-glob-import-no-impls.rs b/tests/ui/namespace/namespaced-enum-glob-import-no-impls.rs index ab24f36f9a156..368c261b23ab8 100644 --- a/tests/ui/namespace/namespaced-enum-glob-import-no-impls.rs +++ b/tests/ui/namespace/namespaced-enum-glob-import-no-impls.rs @@ -18,8 +18,8 @@ mod m { pub fn main() { use m2::Foo::*; - foo(); //~ ERROR cannot find function `foo` in this scope - m::foo(); //~ ERROR cannot find function `foo` in module `m` - bar(); //~ ERROR cannot find function `bar` in this scope - m::bar(); //~ ERROR cannot find function `bar` in module `m` + foo(); //~ ERROR cannot find function `foo` + m::foo(); //~ ERROR cannot find function `foo` + bar(); //~ ERROR cannot find function `bar` + m::bar(); //~ ERROR cannot find function `bar` } diff --git a/tests/ui/namespace/namespaced-enum-glob-import-no-impls.stderr b/tests/ui/namespace/namespaced-enum-glob-import-no-impls.stderr index 111ac7ab0f0bb..66436d134a95a 100644 --- a/tests/ui/namespace/namespaced-enum-glob-import-no-impls.stderr +++ b/tests/ui/namespace/namespaced-enum-glob-import-no-impls.stderr @@ -1,22 +1,22 @@ -error[E0425]: cannot find function `foo` in module `m` +error[E0425]: cannot find function `foo` --> $DIR/namespaced-enum-glob-import-no-impls.rs:22:8 | LL | m::foo(); - | ^^^ not found in `m` + | ^^^ not found in module `m` -error[E0425]: cannot find function `bar` in module `m` +error[E0425]: cannot find function `bar` --> $DIR/namespaced-enum-glob-import-no-impls.rs:24:8 | LL | m::bar(); - | ^^^ not found in `m` + | ^^^ not found in module `m` -error[E0425]: cannot find function `foo` in this scope +error[E0425]: cannot find function `foo` --> $DIR/namespaced-enum-glob-import-no-impls.rs:21:5 | LL | foo(); | ^^^ not found in this scope -error[E0425]: cannot find function `bar` in this scope +error[E0425]: cannot find function `bar` --> $DIR/namespaced-enum-glob-import-no-impls.rs:23:5 | LL | bar(); diff --git a/tests/ui/nested-cfg-attrs.rs b/tests/ui/nested-cfg-attrs.rs index 0af28fc3d8ec6..05570dd9862a8 100644 --- a/tests/ui/nested-cfg-attrs.rs +++ b/tests/ui/nested-cfg-attrs.rs @@ -1,4 +1,4 @@ #[cfg_attr(all(), cfg_attr(all(), cfg(FALSE)))] fn f() {} -fn main() { f() } //~ ERROR cannot find function `f` in this scope +fn main() { f() } //~ ERROR cannot find function `f` diff --git a/tests/ui/nested-cfg-attrs.stderr b/tests/ui/nested-cfg-attrs.stderr index 16c2930714353..d91cbe5ccb009 100644 --- a/tests/ui/nested-cfg-attrs.stderr +++ b/tests/ui/nested-cfg-attrs.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find function `f` in this scope +error[E0425]: cannot find function `f` --> $DIR/nested-cfg-attrs.rs:4:13 | LL | fn main() { f() } diff --git a/tests/ui/object-safety/avoid-ice-on-warning.new.stderr b/tests/ui/object-safety/avoid-ice-on-warning.new.stderr index 517f910080de7..160a1e7218501 100644 --- a/tests/ui/object-safety/avoid-ice-on-warning.new.stderr +++ b/tests/ui/object-safety/avoid-ice-on-warning.new.stderr @@ -4,7 +4,7 @@ error: return types are denoted using `->` LL | fn call_this(f: F) : Fn(&str) + call_that {} | ^ help: use `->` instead -error[E0405]: cannot find trait `call_that` in this scope +error[E0405]: cannot find trait `call_that` --> $DIR/avoid-ice-on-warning.rs:4:36 | LL | fn call_this(f: F) : Fn(&str) + call_that {} diff --git a/tests/ui/object-safety/avoid-ice-on-warning.old.stderr b/tests/ui/object-safety/avoid-ice-on-warning.old.stderr index 3939c06eabe5b..094fab336e7d7 100644 --- a/tests/ui/object-safety/avoid-ice-on-warning.old.stderr +++ b/tests/ui/object-safety/avoid-ice-on-warning.old.stderr @@ -4,7 +4,7 @@ error: return types are denoted using `->` LL | fn call_this(f: F) : Fn(&str) + call_that {} | ^ help: use `->` instead -error[E0405]: cannot find trait `call_that` in this scope +error[E0405]: cannot find trait `call_that` --> $DIR/avoid-ice-on-warning.rs:4:36 | LL | fn call_this(f: F) : Fn(&str) + call_that {} diff --git a/tests/ui/object-safety/avoid-ice-on-warning.rs b/tests/ui/object-safety/avoid-ice-on-warning.rs index b90d8911d500b..468bced514cbe 100644 --- a/tests/ui/object-safety/avoid-ice-on-warning.rs +++ b/tests/ui/object-safety/avoid-ice-on-warning.rs @@ -3,7 +3,7 @@ //@[new] edition:2021 fn call_this(f: F) : Fn(&str) + call_that {} //~^ ERROR return types are denoted using `->` -//~| ERROR cannot find trait `call_that` in this scope +//~| ERROR cannot find trait `call_that` //[old]~| WARN trait objects without an explicit `dyn` are deprecated //[old]~| WARN this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! fn main() {} diff --git a/tests/ui/object-safety/erroneous_signature.rs b/tests/ui/object-safety/erroneous_signature.rs index cc1841cc4b2a1..cf98df869c2a0 100644 --- a/tests/ui/object-safety/erroneous_signature.rs +++ b/tests/ui/object-safety/erroneous_signature.rs @@ -1,11 +1,11 @@ trait Foo { fn err(&self) -> MissingType; - //~^ ERROR cannot find type `MissingType` in this scope + //~^ ERROR cannot find type `MissingType` } impl Foo for i32 { fn err(&self) -> MissingType { - //~^ ERROR cannot find type `MissingType` in this scope + //~^ ERROR cannot find type `MissingType` 0 } } diff --git a/tests/ui/object-safety/erroneous_signature.stderr b/tests/ui/object-safety/erroneous_signature.stderr index f3b14ffe34c3b..e682e265ba2c4 100644 --- a/tests/ui/object-safety/erroneous_signature.stderr +++ b/tests/ui/object-safety/erroneous_signature.stderr @@ -1,10 +1,10 @@ -error[E0412]: cannot find type `MissingType` in this scope +error[E0412]: cannot find type `MissingType` --> $DIR/erroneous_signature.rs:2:22 | LL | fn err(&self) -> MissingType; | ^^^^^^^^^^^ not found in this scope -error[E0412]: cannot find type `MissingType` in this scope +error[E0412]: cannot find type `MissingType` --> $DIR/erroneous_signature.rs:7:22 | LL | fn err(&self) -> MissingType { diff --git a/tests/ui/offset-of/offset-of-enum.rs b/tests/ui/offset-of/offset-of-enum.rs index cb2f04786ac5c..6a20d0dfaa2ef 100644 --- a/tests/ui/offset-of/offset-of-enum.rs +++ b/tests/ui/offset-of/offset-of-enum.rs @@ -14,5 +14,5 @@ fn main() { offset_of!(Alpha, Two.1); //~ ERROR no field named `1` on enum variant `Alpha::Two` offset_of!(Alpha, Two.foo); //~ ERROR no field named `foo` on enum variant `Alpha::Two` offset_of!(Alpha, NonExistent); //~ ERROR no variant named `NonExistent` found for enum `Alpha` - offset_of!(Beta, One); //~ ERROR cannot find type `Beta` in this scope + offset_of!(Beta, One); //~ ERROR cannot find type `Beta` } diff --git a/tests/ui/offset-of/offset-of-enum.stderr b/tests/ui/offset-of/offset-of-enum.stderr index 7e7ad41f5b6a9..b8040fd23b2c6 100644 --- a/tests/ui/offset-of/offset-of-enum.stderr +++ b/tests/ui/offset-of/offset-of-enum.stderr @@ -7,7 +7,7 @@ LL | offset_of!(Alpha::One, 0); | not a type | help: try using the variant's enum: `Alpha` -error[E0412]: cannot find type `Beta` in this scope +error[E0412]: cannot find type `Beta` --> $DIR/offset-of-enum.rs:17:16 | LL | offset_of!(Beta, One); diff --git a/tests/ui/offset-of/offset-of-self.rs b/tests/ui/offset-of/offset-of-self.rs index 1558e13b53095..1396f0de07c42 100644 --- a/tests/ui/offset-of/offset-of-self.rs +++ b/tests/ui/offset-of/offset-of-self.rs @@ -31,7 +31,7 @@ impl S { mod m { use std::mem::offset_of; fn off() { - offset_of!(self::S, v); //~ ERROR cannot find type `S` in module + offset_of!(self::S, v); //~ ERROR cannot find type `S` offset_of!(super::S, v); offset_of!(crate::S, v); } @@ -48,7 +48,7 @@ mod n { fn main() { offset_of!(self::S, v); - offset_of!(Self, v); //~ ERROR cannot find type `Self` in this scope + offset_of!(Self, v); //~ ERROR cannot find type `Self` offset_of!(S, self); //~ no field `self` on type `S` offset_of!(S, v.self); //~ no field `self` on type `u8` diff --git a/tests/ui/offset-of/offset-of-self.stderr b/tests/ui/offset-of/offset-of-self.stderr index 7c7576e066b6f..ed293f98bd6bc 100644 --- a/tests/ui/offset-of/offset-of-self.stderr +++ b/tests/ui/offset-of/offset-of-self.stderr @@ -4,11 +4,11 @@ error: offset_of expects dot-separated field and variant names LL | offset_of!(Self, Self::v); | ^^^^^^^ -error[E0412]: cannot find type `S` in module `self` +error[E0412]: cannot find type `S` --> $DIR/offset-of-self.rs:34:26 | LL | offset_of!(self::S, v); - | ^ not found in `self` + | ^ not found in module `self` | help: consider importing this struct | @@ -20,7 +20,7 @@ LL - offset_of!(self::S, v); LL + offset_of!(S, v); | -error[E0411]: cannot find type `Self` in this scope +error[E0411]: cannot find type `Self` --> $DIR/offset-of-self.rs:51:16 | LL | fn main() { diff --git a/tests/ui/panics/default-backtrace-ice.stderr b/tests/ui/panics/default-backtrace-ice.stderr index 23b863568bc74..3499d745ff417 100644 --- a/tests/ui/panics/default-backtrace-ice.stderr +++ b/tests/ui/panics/default-backtrace-ice.stderr @@ -1,4 +1,4 @@ -error: internal compiler error[E0425]: cannot find value `missing_ident` in this scope +error: internal compiler error[E0425]: cannot find value `missing_ident` --> $DIR/default-backtrace-ice.rs:21:13 | LL | fn main() { missing_ident; } diff --git a/tests/ui/parser/attribute/multiple-tail-expr-behind-cfg.rs b/tests/ui/parser/attribute/multiple-tail-expr-behind-cfg.rs index 33671df949280..e31b6bf527563 100644 --- a/tests/ui/parser/attribute/multiple-tail-expr-behind-cfg.rs +++ b/tests/ui/parser/attribute/multiple-tail-expr-behind-cfg.rs @@ -10,7 +10,7 @@ fn foo() -> String { fn bar() -> String { #[attr] [1, 2, 3].iter().map(|c| c.to_string()).collect::() //~ ERROR expected `;`, found `#` - #[attr] //~ ERROR cannot find attribute `attr` in this scope + #[attr] //~ ERROR cannot find attribute `attr` String::new() } diff --git a/tests/ui/parser/circular_modules_main.stderr b/tests/ui/parser/circular_modules_main.stderr index 2de70789358b0..2b5481c32a019 100644 --- a/tests/ui/parser/circular_modules_main.stderr +++ b/tests/ui/parser/circular_modules_main.stderr @@ -4,11 +4,11 @@ error: circular modules: $DIR/circular_modules_main.rs -> $DIR/circular_modules_ LL | mod circular_modules_main; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -error[E0425]: cannot find function `hi_str` in module `circular_modules_main` +error[E0425]: cannot find function `hi_str` --> $DIR/circular_modules_hello.rs:7:43 | LL | println!("{}", circular_modules_main::hi_str()); - | ^^^^^^ not found in `circular_modules_main` + | ^^^^^^ not found in module `circular_modules_main` | help: consider importing this function | diff --git a/tests/ui/parser/const-param-decl-on-type-instead-of-impl.rs b/tests/ui/parser/const-param-decl-on-type-instead-of-impl.rs index 53e3c6f960500..949c7b1db6fee 100644 --- a/tests/ui/parser/const-param-decl-on-type-instead-of-impl.rs +++ b/tests/ui/parser/const-param-decl-on-type-instead-of-impl.rs @@ -7,7 +7,7 @@ fn main() { fn banana(a: >::BAR) {} //~^ ERROR unexpected `const` parameter declaration -//~| ERROR cannot find type `T` in this scope +//~| ERROR cannot find type `T` fn chaenomeles() { path::path::Struct::() //~^ ERROR unexpected `const` parameter declaration diff --git a/tests/ui/parser/const-param-decl-on-type-instead-of-impl.stderr b/tests/ui/parser/const-param-decl-on-type-instead-of-impl.stderr index 96885d11ee07f..85c39027698c1 100644 --- a/tests/ui/parser/const-param-decl-on-type-instead-of-impl.stderr +++ b/tests/ui/parser/const-param-decl-on-type-instead-of-impl.stderr @@ -27,7 +27,7 @@ error[E0433]: failed to resolve: use of undeclared crate or module `path` LL | path::path::Struct::() | ^^^^ use of undeclared crate or module `path` -error[E0412]: cannot find type `T` in this scope +error[E0412]: cannot find type `T` --> $DIR/const-param-decl-on-type-instead-of-impl.rs:8:15 | LL | fn banana(a: >::BAR) {} diff --git a/tests/ui/parser/default-unmatched-assoc.rs b/tests/ui/parser/default-unmatched-assoc.rs index 168ea3e76f648..81c966e0beee8 100644 --- a/tests/ui/parser/default-unmatched-assoc.rs +++ b/tests/ui/parser/default-unmatched-assoc.rs @@ -1,7 +1,7 @@ fn main() {} trait Foo { - default!(); //~ ERROR cannot find macro `default` in this scope + default!(); //~ ERROR cannot find macro `default` default do //~^ ERROR `default` is not followed by an item //~| ERROR non-item in item list @@ -9,7 +9,7 @@ trait Foo { struct S; impl S { - default!(); //~ ERROR cannot find macro `default` in this scope + default!(); //~ ERROR cannot find macro `default` default do //~^ ERROR `default` is not followed by an item //~| ERROR non-item in item list diff --git a/tests/ui/parser/default-unmatched-extern.rs b/tests/ui/parser/default-unmatched-extern.rs index 8d0ea590f573f..d1527bba9caa2 100644 --- a/tests/ui/parser/default-unmatched-extern.rs +++ b/tests/ui/parser/default-unmatched-extern.rs @@ -1,7 +1,7 @@ fn main() {} extern "C" { - default!(); //~ ERROR cannot find macro `default` in this scope + default!(); //~ ERROR cannot find macro `default` default do //~^ ERROR `default` is not followed by an item //~| ERROR non-item in item list diff --git a/tests/ui/parser/dyn-trait-compatibility.rs b/tests/ui/parser/dyn-trait-compatibility.rs index 6341e05327754..56e77201ba15d 100644 --- a/tests/ui/parser/dyn-trait-compatibility.rs +++ b/tests/ui/parser/dyn-trait-compatibility.rs @@ -1,14 +1,14 @@ type A0 = dyn; -//~^ ERROR cannot find type `dyn` in this scope +//~^ ERROR cannot find type `dyn` type A1 = dyn::dyn; //~^ ERROR use of undeclared crate or module `dyn` type A2 = dyn; -//~^ ERROR cannot find type `dyn` in this scope -//~| ERROR cannot find type `dyn` in this scope -//~| ERROR cannot find type `dyn` in this scope +//~^ ERROR cannot find type `dyn` +//~| ERROR cannot find type `dyn` +//~| ERROR cannot find type `dyn` type A3 = dyn<::dyn>; -//~^ ERROR cannot find type `dyn` in this scope -//~| ERROR cannot find type `dyn` in this scope -//~| ERROR cannot find trait `dyn` in this scope +//~^ ERROR cannot find type `dyn` +//~| ERROR cannot find type `dyn` +//~| ERROR cannot find trait `dyn` fn main() {} diff --git a/tests/ui/parser/dyn-trait-compatibility.stderr b/tests/ui/parser/dyn-trait-compatibility.stderr index e34d855a9d4f9..3a12c7be756d2 100644 --- a/tests/ui/parser/dyn-trait-compatibility.stderr +++ b/tests/ui/parser/dyn-trait-compatibility.stderr @@ -1,40 +1,40 @@ -error[E0412]: cannot find type `dyn` in this scope +error[E0412]: cannot find type `dyn` --> $DIR/dyn-trait-compatibility.rs:1:11 | LL | type A0 = dyn; | ^^^ not found in this scope -error[E0412]: cannot find type `dyn` in this scope +error[E0412]: cannot find type `dyn` --> $DIR/dyn-trait-compatibility.rs:5:11 | LL | type A2 = dyn; | ^^^ not found in this scope -error[E0412]: cannot find type `dyn` in this scope +error[E0412]: cannot find type `dyn` --> $DIR/dyn-trait-compatibility.rs:5:15 | LL | type A2 = dyn; | ^^^ not found in this scope -error[E0412]: cannot find type `dyn` in this scope +error[E0412]: cannot find type `dyn` --> $DIR/dyn-trait-compatibility.rs:5:20 | LL | type A2 = dyn; | ^^^ not found in this scope -error[E0412]: cannot find type `dyn` in this scope +error[E0412]: cannot find type `dyn` --> $DIR/dyn-trait-compatibility.rs:9:11 | LL | type A3 = dyn<::dyn>; | ^^^ not found in this scope -error[E0405]: cannot find trait `dyn` in this scope +error[E0405]: cannot find trait `dyn` --> $DIR/dyn-trait-compatibility.rs:9:23 | LL | type A3 = dyn<::dyn>; | ^^^ not found in this scope -error[E0412]: cannot find type `dyn` in this scope +error[E0412]: cannot find type `dyn` --> $DIR/dyn-trait-compatibility.rs:9:16 | LL | type A3 = dyn<::dyn>; diff --git a/tests/ui/parser/emoji-identifiers.rs b/tests/ui/parser/emoji-identifiers.rs index b50c046bcb204..faabab8a3c749 100644 --- a/tests/ui/parser/emoji-identifiers.rs +++ b/tests/ui/parser/emoji-identifiers.rs @@ -10,7 +10,7 @@ fn i_like_to_😅_a_lot() -> 👀 { //~ ERROR identifiers cannot contain emoji //~^ ERROR identifiers cannot contain emoji } fn main() { - let _ = i_like_to_😄_a_lot() ➖ 4; //~ ERROR cannot find function `i_like_to_😄_a_lot` in this scope + let _ = i_like_to_😄_a_lot() ➖ 4; //~ ERROR cannot find function `i_like_to_😄_a_lot` //~^ ERROR identifiers cannot contain emoji //~| ERROR unknown start of token: \u{2796} diff --git a/tests/ui/parser/emoji-identifiers.stderr b/tests/ui/parser/emoji-identifiers.stderr index 536afc53f0ceb..ab66692bcf64e 100644 --- a/tests/ui/parser/emoji-identifiers.stderr +++ b/tests/ui/parser/emoji-identifiers.stderr @@ -83,7 +83,7 @@ help: there is an associated function `full_of_✨` with a similar name LL | 👀::full_of_✨() | ~~~~~~~~~~ -error[E0425]: cannot find function `i_like_to_😄_a_lot` in this scope +error[E0425]: cannot find function `i_like_to_😄_a_lot` --> $DIR/emoji-identifiers.rs:13:13 | LL | fn i_like_to_😅_a_lot() -> 👀 { diff --git a/tests/ui/parser/fn-field-parse-error-ice.rs b/tests/ui/parser/fn-field-parse-error-ice.rs index 188257ea53a31..d5a2b37ace118 100644 --- a/tests/ui/parser/fn-field-parse-error-ice.rs +++ b/tests/ui/parser/fn-field-parse-error-ice.rs @@ -4,7 +4,7 @@ struct Baz { inner : dyn fn () //~^ ERROR expected `,`, or `}`, found keyword `fn` //~| ERROR expected identifier, found keyword `fn` - //~| ERROR cannot find type `dyn` in this scope + //~| ERROR cannot find type `dyn` } fn main() {} diff --git a/tests/ui/parser/fn-field-parse-error-ice.stderr b/tests/ui/parser/fn-field-parse-error-ice.stderr index 3bf68e8cc04fe..8c3903afd6ab6 100644 --- a/tests/ui/parser/fn-field-parse-error-ice.stderr +++ b/tests/ui/parser/fn-field-parse-error-ice.stderr @@ -17,7 +17,7 @@ help: escape `fn` to use it as an identifier LL | inner : dyn r#fn () | ++ -error[E0412]: cannot find type `dyn` in this scope +error[E0412]: cannot find type `dyn` --> $DIR/fn-field-parse-error-ice.rs:4:13 | LL | inner : dyn fn () diff --git a/tests/ui/parser/issues/issue-103143.rs b/tests/ui/parser/issues/issue-103143.rs index a584274c40514..e7b04df05fd94 100644 --- a/tests/ui/parser/issues/issue-103143.rs +++ b/tests/ui/parser/issues/issue-103143.rs @@ -1,5 +1,5 @@ fn main() { x::<#[a]y::> //~^ ERROR invalid const generic expression - //~| ERROR cannot find value `x` in this scope + //~| ERROR cannot find value `x` } diff --git a/tests/ui/parser/issues/issue-103143.stderr b/tests/ui/parser/issues/issue-103143.stderr index 4035c69afa712..c59dd3240796b 100644 --- a/tests/ui/parser/issues/issue-103143.stderr +++ b/tests/ui/parser/issues/issue-103143.stderr @@ -9,7 +9,7 @@ help: expressions must be enclosed in braces to be used as const generic argumen LL | x::<#[a]{ y:: }> | + + -error[E0425]: cannot find value `x` in this scope +error[E0425]: cannot find value `x` --> $DIR/issue-103143.rs:2:5 | LL | x::<#[a]y::> diff --git a/tests/ui/parser/issues/issue-103748-ICE-wrong-braces.rs b/tests/ui/parser/issues/issue-103748-ICE-wrong-braces.rs index 1c28c0632fa84..5e5c1cfa59ece 100644 --- a/tests/ui/parser/issues/issue-103748-ICE-wrong-braces.rs +++ b/tests/ui/parser/issues/issue-103748-ICE-wrong-braces.rs @@ -3,6 +3,6 @@ struct Apple((Apple, Option(Banana ? Citron))); //~^ ERROR invalid `?` in type //~| ERROR expected one of `)` or `,`, found `Citron` -//~| ERROR cannot find type `Citron` in this scope [E0412] +//~| ERROR cannot find type `Citron` [E0412] //~| ERROR parenthesized type parameters may only be used with a `Fn` trait [E0214] //~| ERROR `Apple` has infinite size diff --git a/tests/ui/parser/issues/issue-103748-ICE-wrong-braces.stderr b/tests/ui/parser/issues/issue-103748-ICE-wrong-braces.stderr index b0d8b03ae08c3..63b07f26dda1e 100644 --- a/tests/ui/parser/issues/issue-103748-ICE-wrong-braces.stderr +++ b/tests/ui/parser/issues/issue-103748-ICE-wrong-braces.stderr @@ -17,7 +17,7 @@ LL | struct Apple((Apple, Option(Banana ? Citron))); | | | help: missing `,` -error[E0412]: cannot find type `Citron` in this scope +error[E0412]: cannot find type `Citron` --> $DIR/issue-103748-ICE-wrong-braces.rs:3:38 | LL | struct Apple((Apple, Option(Banana ? Citron))); diff --git a/tests/ui/parser/issues/issue-112458.rs b/tests/ui/parser/issues/issue-112458.rs index 36895450cd94f..bc6cf32a90db4 100644 --- a/tests/ui/parser/issues/issue-112458.rs +++ b/tests/ui/parser/issues/issue-112458.rs @@ -1,4 +1,4 @@ fn main() { println!("{}", x.); //~ ERROR unexpected token: `)` - //~^ ERROR cannot find value `x` in this scope + //~^ ERROR cannot find value `x` } diff --git a/tests/ui/parser/issues/issue-112458.stderr b/tests/ui/parser/issues/issue-112458.stderr index 54a8f1d03b02a..05d0e18470f25 100644 --- a/tests/ui/parser/issues/issue-112458.stderr +++ b/tests/ui/parser/issues/issue-112458.stderr @@ -4,7 +4,7 @@ error: unexpected token: `)` LL | println!("{}", x.); | ^ -error[E0425]: cannot find value `x` in this scope +error[E0425]: cannot find value `x` --> $DIR/issue-112458.rs:2:20 | LL | println!("{}", x.); diff --git a/tests/ui/parser/issues/issue-118531-ice.rs b/tests/ui/parser/issues/issue-118531-ice.rs index 24794f06052c9..eeed679027b70 100644 --- a/tests/ui/parser/issues/issue-118531-ice.rs +++ b/tests/ui/parser/issues/issue-118531-ice.rs @@ -3,7 +3,7 @@ fn bar() -> String { [1, 2, 3].iter().map().collect::() //~ ERROR expected `;`, found `#` #[attr] //~ ERROR attributes on expressions are experimental [E0658] - //~^ ERROR cannot find attribute `attr` in this scope + //~^ ERROR cannot find attribute `attr` String::new() } diff --git a/tests/ui/parser/issues/issue-32505.rs b/tests/ui/parser/issues/issue-32505.rs index d95e7dc7d9eff..b91a95f376595 100644 --- a/tests/ui/parser/issues/issue-32505.rs +++ b/tests/ui/parser/issues/issue-32505.rs @@ -1,6 +1,6 @@ pub fn test() { foo(|_|) //~ ERROR expected expression, found `)` - //~^ ERROR cannot find function `foo` in this scope + //~^ ERROR cannot find function `foo` } fn main() { } diff --git a/tests/ui/parser/issues/issue-32505.stderr b/tests/ui/parser/issues/issue-32505.stderr index 0eaa5efd525fc..6e2065dbce7ba 100644 --- a/tests/ui/parser/issues/issue-32505.stderr +++ b/tests/ui/parser/issues/issue-32505.stderr @@ -11,7 +11,7 @@ help: you might have meant to open the body of the closure LL | foo(|_| {}) | ++ -error[E0425]: cannot find function `foo` in this scope +error[E0425]: cannot find function `foo` --> $DIR/issue-32505.rs:2:5 | LL | foo(|_|) diff --git a/tests/ui/parser/issues/issue-65122-mac-invoc-in-mut-patterns.rs b/tests/ui/parser/issues/issue-65122-mac-invoc-in-mut-patterns.rs index 30f3781bf7743..ef61d902f2644 100644 --- a/tests/ui/parser/issues/issue-65122-mac-invoc-in-mut-patterns.rs +++ b/tests/ui/parser/issues/issue-65122-mac-invoc-in-mut-patterns.rs @@ -18,9 +18,9 @@ macro_rules! mac2 { fn foo() { mac1! { does_not_exist!() } - //~^ ERROR cannot find macro `does_not_exist` in this scope + //~^ ERROR cannot find macro `does_not_exist` mac2! { does_not_exist!() } - //~^ ERROR cannot find macro `does_not_exist` in this scope + //~^ ERROR cannot find macro `does_not_exist` } fn main() {} diff --git a/tests/ui/parser/kw-in-trait-bounds.rs b/tests/ui/parser/kw-in-trait-bounds.rs index 16d23672ca3c6..0baf0a45a4876 100644 --- a/tests/ui/parser/kw-in-trait-bounds.rs +++ b/tests/ui/parser/kw-in-trait-bounds.rs @@ -17,9 +17,9 @@ fn _g(_: impl struct, _: &dyn struct) //~^ ERROR expected identifier, found keyword `struct` //~| ERROR expected identifier, found keyword `struct` //~| ERROR expected identifier, found keyword `struct` -//~| ERROR cannot find trait `r#struct` in this scope -//~| ERROR cannot find trait `r#struct` in this scope -//~| ERROR cannot find trait `r#struct` in this scope +//~| ERROR cannot find trait `r#struct` +//~| ERROR cannot find trait `r#struct` +//~| ERROR cannot find trait `r#struct` //~| HELP a trait with a similar name exists //~| HELP a trait with a similar name exists //~| HELP a trait with a similar name exists @@ -29,7 +29,7 @@ fn _g(_: impl struct, _: &dyn struct) where B: struct, //~^ ERROR expected identifier, found keyword `struct` - //~| ERROR cannot find trait `r#struct` in this scope + //~| ERROR cannot find trait `r#struct` //~| HELP a trait with a similar name exists //~| HELP escape `struct` to use it as an identifier {} diff --git a/tests/ui/parser/kw-in-trait-bounds.stderr b/tests/ui/parser/kw-in-trait-bounds.stderr index 3c54e03195031..5527d4f3c8bcf 100644 --- a/tests/ui/parser/kw-in-trait-bounds.stderr +++ b/tests/ui/parser/kw-in-trait-bounds.stderr @@ -86,7 +86,7 @@ help: escape `struct` to use it as an identifier LL | B: r#struct, | ++ -error[E0405]: cannot find trait `r#struct` in this scope +error[E0405]: cannot find trait `r#struct` --> $DIR/kw-in-trait-bounds.rs:16:10 | LL | fn _g(_: impl struct, _: &dyn struct) @@ -95,7 +95,7 @@ LL | fn _g(_: impl struct, _: &dyn struct) LL | trait Struct {} | ------------ similarly named trait `Struct` defined here -error[E0405]: cannot find trait `r#struct` in this scope +error[E0405]: cannot find trait `r#struct` --> $DIR/kw-in-trait-bounds.rs:30:8 | LL | B: struct, @@ -104,7 +104,7 @@ LL | B: struct, LL | trait Struct {} | ------------ similarly named trait `Struct` defined here -error[E0405]: cannot find trait `r#struct` in this scope +error[E0405]: cannot find trait `r#struct` --> $DIR/kw-in-trait-bounds.rs:16:29 | LL | fn _g(_: impl struct, _: &dyn struct) @@ -113,7 +113,7 @@ LL | fn _g(_: impl struct, _: &dyn struct) LL | trait Struct {} | ------------ similarly named trait `Struct` defined here -error[E0405]: cannot find trait `r#struct` in this scope +error[E0405]: cannot find trait `r#struct` --> $DIR/kw-in-trait-bounds.rs:16:45 | LL | fn _g(_: impl struct, _: &dyn struct) diff --git a/tests/ui/parser/multibyte-char-use-seperator-issue-80134.rs b/tests/ui/parser/multibyte-char-use-seperator-issue-80134.rs index 7e7995d6724eb..09ec6a6b08bcc 100644 --- a/tests/ui/parser/multibyte-char-use-seperator-issue-80134.rs +++ b/tests/ui/parser/multibyte-char-use-seperator-issue-80134.rs @@ -3,8 +3,8 @@ fn main() { (()é); //~^ ERROR: expected one of `)`, `,`, `.`, `?`, or an operator - //~| ERROR: cannot find value `é` in this scope + //~| ERROR: cannot find value `é` (()氷); //~^ ERROR: expected one of `)`, `,`, `.`, `?`, or an operator - //~| ERROR: cannot find value `氷` in this scope + //~| ERROR: cannot find value `氷` } diff --git a/tests/ui/parser/multibyte-char-use-seperator-issue-80134.stderr b/tests/ui/parser/multibyte-char-use-seperator-issue-80134.stderr index 21e71aa121560..518707fecbf40 100644 --- a/tests/ui/parser/multibyte-char-use-seperator-issue-80134.stderr +++ b/tests/ui/parser/multibyte-char-use-seperator-issue-80134.stderr @@ -16,13 +16,13 @@ LL | (()氷); | expected one of `)`, `,`, `.`, `?`, or an operator | help: missing `,` -error[E0425]: cannot find value `é` in this scope +error[E0425]: cannot find value `é` --> $DIR/multibyte-char-use-seperator-issue-80134.rs:4:8 | LL | (()é); | ^ not found in this scope -error[E0425]: cannot find value `氷` in this scope +error[E0425]: cannot find value `氷` --> $DIR/multibyte-char-use-seperator-issue-80134.rs:7:8 | LL | (()氷); diff --git a/tests/ui/parser/not-a-pred.rs b/tests/ui/parser/not-a-pred.rs index 5518b554d8e53..09c6778f14c8b 100644 --- a/tests/ui/parser/not-a-pred.rs +++ b/tests/ui/parser/not-a-pred.rs @@ -10,6 +10,6 @@ fn main() { let a: isize = 10; let b: isize = 23; check (lt(a, b)); - //~^ ERROR cannot find function `check` in this scope [E0425] + //~^ ERROR cannot find function `check` [E0425] f(a, b); } diff --git a/tests/ui/parser/not-a-pred.stderr b/tests/ui/parser/not-a-pred.stderr index bcc64a687fd0c..fb27131f0f70b 100644 --- a/tests/ui/parser/not-a-pred.stderr +++ b/tests/ui/parser/not-a-pred.stderr @@ -22,7 +22,7 @@ error[E0573]: expected type, found local variable `b` LL | fn f(a: isize, b: isize) : lt(a, b) { } | ^ not a type -error[E0425]: cannot find function `check` in this scope +error[E0425]: cannot find function `check` --> $DIR/not-a-pred.rs:12:5 | LL | check (lt(a, b)); diff --git a/tests/ui/parser/pat-lt-bracket-5.rs b/tests/ui/parser/pat-lt-bracket-5.rs index 6d784494d56a3..1972752386430 100644 --- a/tests/ui/parser/pat-lt-bracket-5.rs +++ b/tests/ui/parser/pat-lt-bracket-5.rs @@ -1,5 +1,5 @@ fn main() { let v[0] = v[1]; //~^ error: expected a pattern, found an expression - //~| error: cannot find value `v` in this scope + //~| error: cannot find value `v` } diff --git a/tests/ui/parser/pat-lt-bracket-5.stderr b/tests/ui/parser/pat-lt-bracket-5.stderr index 18cf2df028216..6331a1602a5b8 100644 --- a/tests/ui/parser/pat-lt-bracket-5.stderr +++ b/tests/ui/parser/pat-lt-bracket-5.stderr @@ -4,7 +4,7 @@ error: expected a pattern, found an expression LL | let v[0] = v[1]; | ^^^^ arbitrary expressions are not allowed in patterns -error[E0425]: cannot find value `v` in this scope +error[E0425]: cannot find value `v` --> $DIR/pat-lt-bracket-5.rs:2:16 | LL | let v[0] = v[1]; diff --git a/tests/ui/parser/raw/raw-literal-keywords.rs b/tests/ui/parser/raw/raw-literal-keywords.rs index a986980fab97b..4679526a3e06a 100644 --- a/tests/ui/parser/raw/raw-literal-keywords.rs +++ b/tests/ui/parser/raw/raw-literal-keywords.rs @@ -11,15 +11,15 @@ fn test_union() { } fn test_if_2() { - let _ = r#if; //~ ERROR cannot find value `r#if` in this scope + let _ = r#if; //~ ERROR cannot find value `r#if` } fn test_struct_2() { - let _ = r#struct; //~ ERROR cannot find value `r#struct` in this scope + let _ = r#struct; //~ ERROR cannot find value `r#struct` } fn test_union_2() { - let _ = r#union; //~ ERROR cannot find value `union` in this scope + let _ = r#union; //~ ERROR cannot find value `union` } fn main() {} diff --git a/tests/ui/parser/raw/raw-literal-keywords.stderr b/tests/ui/parser/raw/raw-literal-keywords.stderr index f7b6c894a90fe..718b3016ce87b 100644 --- a/tests/ui/parser/raw/raw-literal-keywords.stderr +++ b/tests/ui/parser/raw/raw-literal-keywords.stderr @@ -16,19 +16,19 @@ error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found LL | r#union Test; | ^^^^ expected one of 8 possible tokens -error[E0425]: cannot find value `r#if` in this scope +error[E0425]: cannot find value `r#if` --> $DIR/raw-literal-keywords.rs:14:13 | LL | let _ = r#if; | ^^^^ not found in this scope -error[E0425]: cannot find value `r#struct` in this scope +error[E0425]: cannot find value `r#struct` --> $DIR/raw-literal-keywords.rs:18:13 | LL | let _ = r#struct; | ^^^^^^^^ not found in this scope -error[E0425]: cannot find value `union` in this scope +error[E0425]: cannot find value `union` --> $DIR/raw-literal-keywords.rs:22:13 | LL | let _ = r#union; diff --git a/tests/ui/parser/recover/recover-fn-ptr-with-generics.rs b/tests/ui/parser/recover/recover-fn-ptr-with-generics.rs index 76c56a715d2a4..64bb0f973b4a6 100644 --- a/tests/ui/parser/recover/recover-fn-ptr-with-generics.rs +++ b/tests/ui/parser/recover/recover-fn-ptr-with-generics.rs @@ -4,8 +4,8 @@ fn main() { type Identity = fn(T) -> T; //~^ ERROR function pointer types may not have generic parameters - //~| ERROR cannot find type `T` in this scope - //~| ERROR cannot find type `T` in this scope + //~| ERROR cannot find type `T` + //~| ERROR cannot find type `T` let _: fn(); //~^ ERROR function pointer types may not have generic parameters diff --git a/tests/ui/parser/recover/recover-fn-ptr-with-generics.stderr b/tests/ui/parser/recover/recover-fn-ptr-with-generics.stderr index 6b6cb2d6bdde7..8156185828786 100644 --- a/tests/ui/parser/recover/recover-fn-ptr-with-generics.stderr +++ b/tests/ui/parser/recover/recover-fn-ptr-with-generics.stderr @@ -88,13 +88,13 @@ error: expected identifier, found `>` LL | type QuiteBroken = fn(); | ^ expected identifier -error[E0412]: cannot find type `T` in this scope +error[E0412]: cannot find type `T` --> $DIR/recover-fn-ptr-with-generics.rs:5:27 | LL | type Identity = fn(T) -> T; | ^ not found in this scope -error[E0412]: cannot find type `T` in this scope +error[E0412]: cannot find type `T` --> $DIR/recover-fn-ptr-with-generics.rs:5:33 | LL | type Identity = fn(T) -> T; diff --git a/tests/ui/parser/recover/recover-ref-dyn-mut.rs b/tests/ui/parser/recover/recover-ref-dyn-mut.rs index 3016275cc0fd2..e9067c3fe3662 100644 --- a/tests/ui/parser/recover/recover-ref-dyn-mut.rs +++ b/tests/ui/parser/recover/recover-ref-dyn-mut.rs @@ -5,5 +5,5 @@ fn main() { let r: &dyn mut Trait; //~^ ERROR: `mut` must precede `dyn` //~| HELP: place `mut` before `dyn` - //~| ERROR: cannot find trait `Trait` in this scope [E0405] + //~| ERROR: cannot find trait `Trait` [E0405] } diff --git a/tests/ui/parser/recover/recover-ref-dyn-mut.stderr b/tests/ui/parser/recover/recover-ref-dyn-mut.stderr index c048c8ea1b0dd..378b69a08c2f1 100644 --- a/tests/ui/parser/recover/recover-ref-dyn-mut.stderr +++ b/tests/ui/parser/recover/recover-ref-dyn-mut.stderr @@ -4,7 +4,7 @@ error: `mut` must precede `dyn` LL | let r: &dyn mut Trait; | ^^^^^^^^ help: place `mut` before `dyn`: `&mut dyn` -error[E0405]: cannot find trait `Trait` in this scope +error[E0405]: cannot find trait `Trait` --> $DIR/recover-ref-dyn-mut.rs:5:21 | LL | let r: &dyn mut Trait; diff --git a/tests/ui/parser/recover/recover-unticked-labels.fixed b/tests/ui/parser/recover/recover-unticked-labels.fixed index f003550cbc222..074b047db91f6 100644 --- a/tests/ui/parser/recover/recover-unticked-labels.fixed +++ b/tests/ui/parser/recover/recover-unticked-labels.fixed @@ -1,7 +1,7 @@ //@ run-rustfix fn main() { - 'label: loop { break 'label }; //~ error: cannot find value `label` in this scope + 'label: loop { break 'label }; //~ error: cannot find value `label` 'label: loop { break 'label 0 }; //~ error: expected a label, found an identifier 'label: loop { continue 'label }; //~ error: expected a label, found an identifier } diff --git a/tests/ui/parser/recover/recover-unticked-labels.rs b/tests/ui/parser/recover/recover-unticked-labels.rs index 2b864f16b8412..629cc31509b35 100644 --- a/tests/ui/parser/recover/recover-unticked-labels.rs +++ b/tests/ui/parser/recover/recover-unticked-labels.rs @@ -1,7 +1,7 @@ //@ run-rustfix fn main() { - 'label: loop { break label }; //~ error: cannot find value `label` in this scope + 'label: loop { break label }; //~ error: cannot find value `label` 'label: loop { break label 0 }; //~ error: expected a label, found an identifier 'label: loop { continue label }; //~ error: expected a label, found an identifier } diff --git a/tests/ui/parser/recover/recover-unticked-labels.stderr b/tests/ui/parser/recover/recover-unticked-labels.stderr index fbd108ca613c7..6314c19fe7d72 100644 --- a/tests/ui/parser/recover/recover-unticked-labels.stderr +++ b/tests/ui/parser/recover/recover-unticked-labels.stderr @@ -14,7 +14,7 @@ LL | 'label: loop { continue label }; | | | help: labels start with a tick -error[E0425]: cannot find value `label` in this scope +error[E0425]: cannot find value `label` --> $DIR/recover-unticked-labels.rs:4:26 | LL | 'label: loop { break label }; diff --git a/tests/ui/parser/trailing-question-in-macro-type.rs b/tests/ui/parser/trailing-question-in-macro-type.rs index e2a681ddd1115..eb1f47d7df972 100644 --- a/tests/ui/parser/trailing-question-in-macro-type.rs +++ b/tests/ui/parser/trailing-question-in-macro-type.rs @@ -10,5 +10,5 @@ macro_rules! fn_expr { fn main() { fn_expr!{ o?.when(|&i| i > 0)?.when(|&i| i%2 == 0) }; - //~^ ERROR cannot find value `o` in this scope + //~^ ERROR cannot find value `o` } diff --git a/tests/ui/parser/trailing-question-in-macro-type.stderr b/tests/ui/parser/trailing-question-in-macro-type.stderr index e3d33bf251d66..361014b7c3d16 100644 --- a/tests/ui/parser/trailing-question-in-macro-type.stderr +++ b/tests/ui/parser/trailing-question-in-macro-type.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `o` in this scope +error[E0425]: cannot find value `o` --> $DIR/trailing-question-in-macro-type.rs:12:15 | LL | fn_expr!{ o?.when(|&i| i > 0)?.when(|&i| i%2 == 0) }; diff --git a/tests/ui/parser/unmatched-langle-1.rs b/tests/ui/parser/unmatched-langle-1.rs index fdf2ae398014b..16dc8943023fe 100644 --- a/tests/ui/parser/unmatched-langle-1.rs +++ b/tests/ui/parser/unmatched-langle-1.rs @@ -4,6 +4,6 @@ fn main() { foo::<<<>(); //~^ ERROR: unmatched angle brackets - //~| ERROR: cannot find function `foo` in this scope [E0425] - //~| ERROR: cannot find type `Ty` in this scope [E0412] + //~| ERROR: cannot find function `foo` [E0425] + //~| ERROR: cannot find type `Ty` [E0412] } diff --git a/tests/ui/parser/unmatched-langle-1.stderr b/tests/ui/parser/unmatched-langle-1.stderr index cdf74bdedc2e1..45edd1bd60491 100644 --- a/tests/ui/parser/unmatched-langle-1.stderr +++ b/tests/ui/parser/unmatched-langle-1.stderr @@ -4,13 +4,13 @@ error: unmatched angle brackets LL | foo::<<<>(); | ^^^ help: remove extra angle brackets -error[E0412]: cannot find type `Ty` in this scope +error[E0412]: cannot find type `Ty` --> $DIR/unmatched-langle-1.rs:5:14 | LL | foo::<<<>(); | ^^ not found in this scope -error[E0425]: cannot find function `foo` in this scope +error[E0425]: cannot find function `foo` --> $DIR/unmatched-langle-1.rs:5:5 | LL | foo::<<<>(); diff --git a/tests/ui/parser/where_with_bound.rs b/tests/ui/parser/where_with_bound.rs index 3ca45f1889c9c..c5a00a1001701 100644 --- a/tests/ui/parser/where_with_bound.rs +++ b/tests/ui/parser/where_with_bound.rs @@ -1,5 +1,5 @@ fn foo() where ::Item: ToString, T: Iterator { } //~^ ERROR generic parameters on `where` clauses are reserved for future use -//~| ERROR cannot find type `Item` in the crate root +//~| ERROR cannot find type `Item` fn main() {} diff --git a/tests/ui/parser/where_with_bound.stderr b/tests/ui/parser/where_with_bound.stderr index ff98b3f5fed61..73b7a5b3d60f9 100644 --- a/tests/ui/parser/where_with_bound.stderr +++ b/tests/ui/parser/where_with_bound.stderr @@ -4,7 +4,7 @@ error: generic parameters on `where` clauses are reserved for future use LL | fn foo() where ::Item: ToString, T: Iterator { } | ^^^ currently unsupported -error[E0412]: cannot find type `Item` in the crate root +error[E0412]: cannot find type `Item` --> $DIR/where_with_bound.rs:1:24 | LL | fn foo() where ::Item: ToString, T: Iterator { } diff --git a/tests/ui/pattern/range-pattern-meant-to-be-slice-rest-pattern.rs b/tests/ui/pattern/range-pattern-meant-to-be-slice-rest-pattern.rs index fe7655c2c4e1c..32c0e858fd296 100644 --- a/tests/ui/pattern/range-pattern-meant-to-be-slice-rest-pattern.rs +++ b/tests/ui/pattern/range-pattern-meant-to-be-slice-rest-pattern.rs @@ -1,22 +1,22 @@ fn main() { match &[1, 2, 3][..] { [1, rest..] => println!("{rest}"), - //~^ ERROR cannot find value `rest` in this scope - //~| ERROR cannot find value `rest` in this scope + //~^ ERROR cannot find value `rest` + //~| ERROR cannot find value `rest` //~| ERROR `X..` patterns in slices are experimental _ => {} } match &[4, 5, 6][..] { [] => {} [_, ..tail] => println!("{tail}"), - //~^ ERROR cannot find value `tail` in this scope - //~| ERROR cannot find value `tail` in this scope + //~^ ERROR cannot find value `tail` + //~| ERROR cannot find value `tail` } match &[7, 8, 9][..] { [] => {} [_, ...tail] => println!("{tail}"), - //~^ ERROR cannot find value `tail` in this scope - //~| ERROR cannot find value `tail` in this scope + //~^ ERROR cannot find value `tail` + //~| ERROR cannot find value `tail` //~| ERROR range-to patterns with `...` are not allowed } } diff --git a/tests/ui/pattern/range-pattern-meant-to-be-slice-rest-pattern.stderr b/tests/ui/pattern/range-pattern-meant-to-be-slice-rest-pattern.stderr index 37c02eb6ada9c..283babbbef6fd 100644 --- a/tests/ui/pattern/range-pattern-meant-to-be-slice-rest-pattern.stderr +++ b/tests/ui/pattern/range-pattern-meant-to-be-slice-rest-pattern.stderr @@ -4,7 +4,7 @@ error: range-to patterns with `...` are not allowed LL | [_, ...tail] => println!("{tail}"), | ^^^ help: use `..=` instead -error[E0425]: cannot find value `rest` in this scope +error[E0425]: cannot find value `rest` --> $DIR/range-pattern-meant-to-be-slice-rest-pattern.rs:3:13 | LL | [1, rest..] => println!("{rest}"), @@ -15,13 +15,13 @@ help: if you meant to collect the rest of the slice in `rest`, use the at operat LL | [1, rest @ ..] => println!("{rest}"), | + -error[E0425]: cannot find value `rest` in this scope +error[E0425]: cannot find value `rest` --> $DIR/range-pattern-meant-to-be-slice-rest-pattern.rs:3:35 | LL | [1, rest..] => println!("{rest}"), | ^^^^ not found in this scope -error[E0425]: cannot find value `tail` in this scope +error[E0425]: cannot find value `tail` --> $DIR/range-pattern-meant-to-be-slice-rest-pattern.rs:11:15 | LL | [_, ..tail] => println!("{tail}"), @@ -32,13 +32,13 @@ help: if you meant to collect the rest of the slice in `tail`, use the at operat LL | [_, tail @ ..] => println!("{tail}"), | ~~~~~~~~~ -error[E0425]: cannot find value `tail` in this scope +error[E0425]: cannot find value `tail` --> $DIR/range-pattern-meant-to-be-slice-rest-pattern.rs:11:35 | LL | [_, ..tail] => println!("{tail}"), | ^^^^ not found in this scope -error[E0425]: cannot find value `tail` in this scope +error[E0425]: cannot find value `tail` --> $DIR/range-pattern-meant-to-be-slice-rest-pattern.rs:17:16 | LL | [_, ...tail] => println!("{tail}"), @@ -49,7 +49,7 @@ help: if you meant to collect the rest of the slice in `tail`, use the at operat LL | [_, tail @ ..] => println!("{tail}"), | ~~~~~~~~~ -error[E0425]: cannot find value `tail` in this scope +error[E0425]: cannot find value `tail` --> $DIR/range-pattern-meant-to-be-slice-rest-pattern.rs:17:36 | LL | [_, ...tail] => println!("{tail}"), diff --git a/tests/ui/pattern/usefulness/issue-119493-type-error-ice.stderr b/tests/ui/pattern/usefulness/issue-119493-type-error-ice.stderr index 1c560aa2ca813..cf827eb569aec 100644 --- a/tests/ui/pattern/usefulness/issue-119493-type-error-ice.stderr +++ b/tests/ui/pattern/usefulness/issue-119493-type-error-ice.stderr @@ -1,10 +1,10 @@ -error[E0412]: cannot find type `NonExistent` in this scope +error[E0412]: cannot find type `NonExistent` --> $DIR/issue-119493-type-error-ice.rs:5:16 | LL | struct Foo(NonExistent); | ^^^^^^^^^^^ not found in this scope -error[E0412]: cannot find type `NonExistent` in this scope +error[E0412]: cannot find type `NonExistent` --> $DIR/issue-119493-type-error-ice.rs:5:16 | LL | struct Foo(NonExistent); diff --git a/tests/ui/pattern/usefulness/issue-119778-type-error-ice.stderr b/tests/ui/pattern/usefulness/issue-119778-type-error-ice.stderr index 7da384d613efb..affbd6f317ac0 100644 --- a/tests/ui/pattern/usefulness/issue-119778-type-error-ice.stderr +++ b/tests/ui/pattern/usefulness/issue-119778-type-error-ice.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `S` in this scope +error[E0425]: cannot find value `S` --> $DIR/issue-119778-type-error-ice.rs:5:21 | LL | struct Foo([u8; S]); @@ -9,7 +9,7 @@ help: you might be missing a const parameter LL | struct Foo([u8; S]); | +++++++++++++++++++++ -error[E0425]: cannot find value `S` in this scope +error[E0425]: cannot find value `S` --> $DIR/issue-119778-type-error-ice.rs:5:21 | LL | struct Foo([u8; S]); diff --git a/tests/ui/privacy/privacy-ns1.rs b/tests/ui/privacy/privacy-ns1.rs index 1af5b857e9df6..4ef1ba5c1f52a 100644 --- a/tests/ui/privacy/privacy-ns1.rs +++ b/tests/ui/privacy/privacy-ns1.rs @@ -48,8 +48,8 @@ pub mod foo3 { fn test_glob3() { use foo3::*; - Bar(); //~ ERROR cannot find function, tuple struct or tuple variant `Bar` in this scope - let _x: Box; //~ ERROR cannot find type `Bar` in this scope + Bar(); //~ ERROR cannot find function, tuple struct or tuple variant `Bar` + let _x: Box; //~ ERROR cannot find type `Bar` } fn main() { diff --git a/tests/ui/privacy/privacy-ns1.stderr b/tests/ui/privacy/privacy-ns1.stderr index 9710cc48637bc..20152f35f81d4 100644 --- a/tests/ui/privacy/privacy-ns1.stderr +++ b/tests/ui/privacy/privacy-ns1.stderr @@ -16,7 +16,7 @@ help: consider importing this function instead LL + use foo2::Bar; | -error[E0425]: cannot find function, tuple struct or tuple variant `Bar` in this scope +error[E0425]: cannot find function, tuple struct or tuple variant `Bar` --> $DIR/privacy-ns1.rs:51:5 | LL | pub struct Baz; @@ -34,7 +34,7 @@ help: consider importing this function LL + use foo2::Bar; | -error[E0412]: cannot find type `Bar` in this scope +error[E0412]: cannot find type `Bar` --> $DIR/privacy-ns1.rs:52:17 | LL | pub struct Baz; diff --git a/tests/ui/proc-macro/ambiguous-builtin-attrs-test.rs b/tests/ui/proc-macro/ambiguous-builtin-attrs-test.rs index 3f191cba74583..19fd4cdac9d04 100644 --- a/tests/ui/proc-macro/ambiguous-builtin-attrs-test.rs +++ b/tests/ui/proc-macro/ambiguous-builtin-attrs-test.rs @@ -16,5 +16,5 @@ fn bench(b: &mut test::Bencher) {} fn not_main() { Test; Bench; - NonExistent; //~ ERROR cannot find value `NonExistent` in this scope + NonExistent; //~ ERROR cannot find value `NonExistent` } diff --git a/tests/ui/proc-macro/ambiguous-builtin-attrs-test.stderr b/tests/ui/proc-macro/ambiguous-builtin-attrs-test.stderr index 346cebf639d17..80f7e5e37ac2f 100644 --- a/tests/ui/proc-macro/ambiguous-builtin-attrs-test.stderr +++ b/tests/ui/proc-macro/ambiguous-builtin-attrs-test.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `NonExistent` in this scope +error[E0425]: cannot find value `NonExistent` --> $DIR/ambiguous-builtin-attrs-test.rs:19:5 | LL | NonExistent; diff --git a/tests/ui/proc-macro/ambiguous-builtin-attrs.rs b/tests/ui/proc-macro/ambiguous-builtin-attrs.rs index c82663541a795..2917bff9e2181 100644 --- a/tests/ui/proc-macro/ambiguous-builtin-attrs.rs +++ b/tests/ui/proc-macro/ambiguous-builtin-attrs.rs @@ -31,7 +31,7 @@ fn non_macro_expanded_location<#[repr(C)] T>() { fn main() { Test; Bench; - NonExistent; //~ ERROR cannot find value `NonExistent` in this scope + NonExistent; //~ ERROR cannot find value `NonExistent` } use deny as allow; diff --git a/tests/ui/proc-macro/ambiguous-builtin-attrs.stderr b/tests/ui/proc-macro/ambiguous-builtin-attrs.stderr index 0f4ddc065a742..b4432d50a6410 100644 --- a/tests/ui/proc-macro/ambiguous-builtin-attrs.stderr +++ b/tests/ui/proc-macro/ambiguous-builtin-attrs.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `NonExistent` in this scope +error[E0425]: cannot find value `NonExistent` --> $DIR/ambiguous-builtin-attrs.rs:34:5 | LL | NonExistent; diff --git a/tests/ui/proc-macro/attributes-on-modules-fail.rs b/tests/ui/proc-macro/attributes-on-modules-fail.rs index 9b2eb703eacca..a68a7911f6108 100644 --- a/tests/ui/proc-macro/attributes-on-modules-fail.rs +++ b/tests/ui/proc-macro/attributes-on-modules-fail.rs @@ -7,11 +7,11 @@ extern crate test_macros; mod m { pub struct X; - type A = Y; //~ ERROR cannot find type `Y` in this scope + type A = Y; //~ ERROR cannot find type `Y` } struct Y; -type A = X; //~ ERROR cannot find type `X` in this scope +type A = X; //~ ERROR cannot find type `X` #[derive(Copy)] //~ ERROR `derive` may only be applied to `struct`s, `enum`s and `union`s mod n {} diff --git a/tests/ui/proc-macro/attributes-on-modules-fail.stderr b/tests/ui/proc-macro/attributes-on-modules-fail.stderr index e69ab78723861..8f37ea2915ac3 100644 --- a/tests/ui/proc-macro/attributes-on-modules-fail.stderr +++ b/tests/ui/proc-macro/attributes-on-modules-fail.stderr @@ -46,7 +46,7 @@ LL | mod inner; = help: add `#![feature(proc_macro_hygiene)]` 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[E0412]: cannot find type `Y` in this scope +error[E0412]: cannot find type `Y` --> $DIR/attributes-on-modules-fail.rs:10:14 | LL | type A = Y; @@ -57,7 +57,7 @@ help: consider importing this struct LL + use Y; | -error[E0412]: cannot find type `X` in this scope +error[E0412]: cannot find type `X` --> $DIR/attributes-on-modules-fail.rs:14:10 | LL | type A = X; diff --git a/tests/ui/proc-macro/break-token-spans.stderr b/tests/ui/proc-macro/break-token-spans.stderr index e69cc3b8cf598..17d2f63ef93ec 100644 --- a/tests/ui/proc-macro/break-token-spans.stderr +++ b/tests/ui/proc-macro/break-token-spans.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find function `f` in this scope +error[E0425]: cannot find function `f` --> $DIR/break-token-spans.rs:13:5 | LL | f :: < Vec < _ > > ( ) ; diff --git a/tests/ui/proc-macro/derive-helper-legacy-limits.rs b/tests/ui/proc-macro/derive-helper-legacy-limits.rs index ff09095a60f9d..ce8bdf8c245db 100644 --- a/tests/ui/proc-macro/derive-helper-legacy-limits.rs +++ b/tests/ui/proc-macro/derive-helper-legacy-limits.rs @@ -14,7 +14,7 @@ use derive as my_derive; struct S1; // Legacy helper detection doesn't see through `derive` renaming. -#[empty_helper] //~ ERROR cannot find attribute `empty_helper` in this scope +#[empty_helper] //~ ERROR cannot find attribute `empty_helper` #[my_derive(Empty)] struct S2; diff --git a/tests/ui/proc-macro/derive-helper-legacy-spurious.rs b/tests/ui/proc-macro/derive-helper-legacy-spurious.rs index 2b5bb905e8302..1d20ac5004f60 100644 --- a/tests/ui/proc-macro/derive-helper-legacy-spurious.rs +++ b/tests/ui/proc-macro/derive-helper-legacy-spurious.rs @@ -1,12 +1,12 @@ //@ aux-build:test-macros.rs -#![dummy] //~ ERROR cannot find attribute `dummy` in this scope +#![dummy] //~ ERROR cannot find attribute `dummy` #[macro_use] extern crate test_macros; #[derive(Empty)] -#[empty_helper] //~ ERROR cannot find attribute `empty_helper` in this scope +#[empty_helper] //~ ERROR cannot find attribute `empty_helper` struct Foo {} fn main() {} diff --git a/tests/ui/proc-macro/derive-helper-shadowing.rs b/tests/ui/proc-macro/derive-helper-shadowing.rs index 1c66a60b294b8..f1b7b13583ecf 100644 --- a/tests/ui/proc-macro/derive-helper-shadowing.rs +++ b/tests/ui/proc-macro/derive-helper-shadowing.rs @@ -11,7 +11,7 @@ use test_macros::empty_attr as empty_helper; macro_rules! gen_helper_use { () => { - #[empty_helper] //~ ERROR cannot find attribute `empty_helper` in this scope + #[empty_helper] //~ ERROR cannot find attribute `empty_helper` struct W; } } @@ -35,7 +35,7 @@ struct S { gen_helper_use!(); - #[derive(GenHelperUse)] //~ ERROR cannot find attribute `empty_helper` in this scope + #[derive(GenHelperUse)] //~ ERROR cannot find attribute `empty_helper` struct Owo; use empty_helper as renamed; diff --git a/tests/ui/proc-macro/derive-still-gated.rs b/tests/ui/proc-macro/derive-still-gated.rs index bce7badeffe1d..b08dd2ef932bc 100644 --- a/tests/ui/proc-macro/derive-still-gated.rs +++ b/tests/ui/proc-macro/derive-still-gated.rs @@ -3,7 +3,7 @@ #[macro_use] extern crate test_macros; -#[derive_Empty] //~ ERROR cannot find attribute `derive_Empty` in this scope +#[derive_Empty] //~ ERROR cannot find attribute `derive_Empty` struct A; fn main() {} diff --git a/tests/ui/proc-macro/disappearing-resolution.rs b/tests/ui/proc-macro/disappearing-resolution.rs index b8bc2953576a6..3d700f44175df 100644 --- a/tests/ui/proc-macro/disappearing-resolution.rs +++ b/tests/ui/proc-macro/disappearing-resolution.rs @@ -15,7 +15,7 @@ use m::Empty; //~ ERROR derive macro import `Empty` is private // successfully resolve `Empty` from there, and then resolve `empty_helper` as its helper. // During validation `use m::Empty` introduces a `Res::Err` stub, so `Empty` resolves to it, // and `empty_helper` can no longer be resolved. -#[empty_helper] //~ ERROR cannot find attribute `empty_helper` in this scope +#[empty_helper] //~ ERROR cannot find attribute `empty_helper` #[derive(Empty)] struct S; diff --git a/tests/ui/proc-macro/empty-where-clause.stderr b/tests/ui/proc-macro/empty-where-clause.stderr index 192a2b30f0dcd..8ef47abcd2e8b 100644 --- a/tests/ui/proc-macro/empty-where-clause.stderr +++ b/tests/ui/proc-macro/empty-where-clause.stderr @@ -1,16 +1,16 @@ -error[E0412]: cannot find type `MissingType1` in this scope +error[E0412]: cannot find type `MissingType1` --> $DIR/empty-where-clause.rs:8:12 | LL | field: MissingType1 | ^^^^^^^^^^^^ not found in this scope -error[E0412]: cannot find type `MissingType2` in this scope +error[E0412]: cannot find type `MissingType2` --> $DIR/empty-where-clause.rs:12:20 | LL | struct TupleStruct(MissingType2) where; | ^^^^^^^^^^^^ not found in this scope -error[E0412]: cannot find type `MissingType3` in this scope +error[E0412]: cannot find type `MissingType3` --> $DIR/empty-where-clause.rs:15:13 | LL | Variant(MissingType3) diff --git a/tests/ui/proc-macro/gen-macro-rules-hygiene.rs b/tests/ui/proc-macro/gen-macro-rules-hygiene.rs index 2bfbf9dcccaaf..8d52f7f3dd9fd 100644 --- a/tests/ui/proc-macro/gen-macro-rules-hygiene.rs +++ b/tests/ui/proc-macro/gen-macro-rules-hygiene.rs @@ -11,13 +11,13 @@ struct ItemUse; gen_macro_rules!(); //~^ ERROR use of undeclared label `'label_use` -//~| ERROR cannot find value `local_use` in this scope +//~| ERROR cannot find value `local_use` fn main() { 'label_use: loop { let local_use = 1; generated!(); ItemDef; // OK - local_def; //~ ERROR cannot find value `local_def` in this scope + local_def; //~ ERROR cannot find value `local_def` } } diff --git a/tests/ui/proc-macro/gen-macro-rules-hygiene.stderr b/tests/ui/proc-macro/gen-macro-rules-hygiene.stderr index df7c4f72eb0b6..ac16658ebca2b 100644 --- a/tests/ui/proc-macro/gen-macro-rules-hygiene.stderr +++ b/tests/ui/proc-macro/gen-macro-rules-hygiene.stderr @@ -9,7 +9,7 @@ LL | generated!(); | = note: this error originates in the macro `generated` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0425]: cannot find value `local_use` in this scope +error[E0425]: cannot find value `local_use` --> $DIR/gen-macro-rules-hygiene.rs:12:1 | LL | gen_macro_rules!(); @@ -20,7 +20,7 @@ LL | generated!(); | = note: this error originates in the macro `generated` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0425]: cannot find value `local_def` in this scope +error[E0425]: cannot find value `local_def` --> $DIR/gen-macro-rules-hygiene.rs:21:9 | LL | local_def; diff --git a/tests/ui/proc-macro/generate-mod.rs b/tests/ui/proc-macro/generate-mod.rs index ab93666f28af1..b77ea3d8ffe1a 100644 --- a/tests/ui/proc-macro/generate-mod.rs +++ b/tests/ui/proc-macro/generate-mod.rs @@ -6,22 +6,22 @@ extern crate generate_mod; struct FromOutside; -generate_mod::check!(); //~ ERROR cannot find type `FromOutside` in this scope - //~| ERROR cannot find type `Outer` in this scope +generate_mod::check!(); //~ ERROR cannot find type `FromOutside` + //~| ERROR cannot find type `Outer` -#[generate_mod::check_attr] //~ ERROR cannot find type `FromOutside` in this scope - //~| ERROR cannot find type `OuterAttr` in this scope +#[generate_mod::check_attr] //~ ERROR cannot find type `FromOutside` + //~| ERROR cannot find type `OuterAttr` struct S; -#[derive(generate_mod::CheckDerive)] //~ ERROR cannot find type `FromOutside` in this scope - //~| ERROR cannot find type `OuterDerive` in this scope +#[derive(generate_mod::CheckDerive)] //~ ERROR cannot find type `FromOutside` + //~| ERROR cannot find type `OuterDerive` //~| WARN this was previously accepted //~| WARN this was previously accepted struct Z; fn inner_block() { - #[derive(generate_mod::CheckDerive)] //~ ERROR cannot find type `FromOutside` in this scope - //~| ERROR cannot find type `OuterDerive` in this scope + #[derive(generate_mod::CheckDerive)] //~ ERROR cannot find type `FromOutside` + //~| ERROR cannot find type `OuterDerive` //~| WARN this was previously accepted //~| WARN this was previously accepted struct InnerZ; diff --git a/tests/ui/proc-macro/generate-mod.stderr b/tests/ui/proc-macro/generate-mod.stderr index cbe6b14ca9af5..528ec6558e43e 100644 --- a/tests/ui/proc-macro/generate-mod.stderr +++ b/tests/ui/proc-macro/generate-mod.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `FromOutside` in this scope +error[E0412]: cannot find type `FromOutside` --> $DIR/generate-mod.rs:9:1 | LL | generate_mod::check!(); @@ -8,7 +8,7 @@ LL | generate_mod::check!(); FromOutside = note: this error originates in the macro `generate_mod::check` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0412]: cannot find type `Outer` in this scope +error[E0412]: cannot find type `Outer` --> $DIR/generate-mod.rs:9:1 | LL | generate_mod::check!(); @@ -18,7 +18,7 @@ LL | generate_mod::check!(); Outer = note: this error originates in the macro `generate_mod::check` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0412]: cannot find type `FromOutside` in this scope +error[E0412]: cannot find type `FromOutside` --> $DIR/generate-mod.rs:12:1 | LL | #[generate_mod::check_attr] @@ -28,7 +28,7 @@ LL | #[generate_mod::check_attr] FromOutside = note: this error originates in the attribute macro `generate_mod::check_attr` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0412]: cannot find type `OuterAttr` in this scope +error[E0412]: cannot find type `OuterAttr` --> $DIR/generate-mod.rs:12:1 | LL | #[generate_mod::check_attr] diff --git a/tests/ui/proc-macro/issue-118455-skip-err-builtin.rs b/tests/ui/proc-macro/issue-118455-skip-err-builtin.rs index baef020612891..75bdc4b111ea7 100644 --- a/tests/ui/proc-macro/issue-118455-skip-err-builtin.rs +++ b/tests/ui/proc-macro/issue-118455-skip-err-builtin.rs @@ -1,5 +1,5 @@ #![some_nonexistent_attribute] -//~^ ERROR cannot find attribute `some_nonexistent_attribute` in this scope +//~^ ERROR cannot find attribute `some_nonexistent_attribute` #[derive(Debug)] pub struct SomeUserCode; diff --git a/tests/ui/proc-macro/issue-38586.stderr b/tests/ui/proc-macro/issue-38586.stderr index 0049155645078..9c448ce569d06 100644 --- a/tests/ui/proc-macro/issue-38586.stderr +++ b/tests/ui/proc-macro/issue-38586.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `foo` in this scope +error[E0425]: cannot find value `foo` --> $DIR/issue-38586.rs:6:10 | LL | #[derive(A)] diff --git a/tests/ui/proc-macro/issue-83510.rs b/tests/ui/proc-macro/issue-83510.rs index ea8a334f57c55..3e32e7b16bbba 100644 --- a/tests/ui/proc-macro/issue-83510.rs +++ b/tests/ui/proc-macro/issue-83510.rs @@ -3,9 +3,9 @@ extern crate issue_83510; issue_83510::dance_like_you_want_to_ice!(); -//~^ ERROR: cannot find type `Foo` in this scope +//~^ ERROR: cannot find type `Foo` //~| ERROR: expected trait, found struct `Box` -//~| ERROR: cannot find trait `Baz` in this scope +//~| ERROR: cannot find trait `Baz` //~| ERROR: inherent associated types are unstable fn main() {} diff --git a/tests/ui/proc-macro/issue-83510.stderr b/tests/ui/proc-macro/issue-83510.stderr index e59b77af3dc39..ca748dfca857c 100644 --- a/tests/ui/proc-macro/issue-83510.stderr +++ b/tests/ui/proc-macro/issue-83510.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `Foo` in this scope +error[E0412]: cannot find type `Foo` --> $DIR/issue-83510.rs:5:1 | LL | issue_83510::dance_like_you_want_to_ice!(); @@ -14,7 +14,7 @@ LL | issue_83510::dance_like_you_want_to_ice!(); | = note: this error originates in the macro `issue_83510::dance_like_you_want_to_ice` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0405]: cannot find trait `Baz` in this scope +error[E0405]: cannot find trait `Baz` --> $DIR/issue-83510.rs:5:1 | LL | issue_83510::dance_like_you_want_to_ice!(); diff --git a/tests/ui/proc-macro/keep-expr-tokens.stderr b/tests/ui/proc-macro/keep-expr-tokens.stderr index 1a1f83cc1569b..d67799de8222a 100644 --- a/tests/ui/proc-macro/keep-expr-tokens.stderr +++ b/tests/ui/proc-macro/keep-expr-tokens.stderr @@ -1,10 +1,10 @@ -error[E0425]: cannot find value `bad` in this scope +error[E0425]: cannot find value `bad` --> $DIR/keep-expr-tokens.rs:19:62 | LL | (#[recollect_attr] #[recollect_attr] ((#[recollect_attr] bad))); | ^^^ not found in this scope -error[E0425]: cannot find function `missing_fn` in this scope +error[E0425]: cannot find function `missing_fn` --> $DIR/keep-expr-tokens.rs:17:17 | LL | for item in missing_fn() {} diff --git a/tests/ui/proc-macro/lints_in_proc_macros.rs b/tests/ui/proc-macro/lints_in_proc_macros.rs index 13ae7239a143d..22ebf4d66c172 100644 --- a/tests/ui/proc-macro/lints_in_proc_macros.rs +++ b/tests/ui/proc-macro/lints_in_proc_macros.rs @@ -7,7 +7,7 @@ use bang_proc_macro2::bang_proc_macro2; fn main() { let foobar = 42; bang_proc_macro2!(); - //~^ ERROR cannot find value `foobar2` in this scope + //~^ ERROR cannot find value `foobar2` //~| HELP a local variable with a similar name exists //~| SUGGESTION foobar println!("{}", x); diff --git a/tests/ui/proc-macro/lints_in_proc_macros.stderr b/tests/ui/proc-macro/lints_in_proc_macros.stderr index 244d218608be7..fba9f32e3f622 100644 --- a/tests/ui/proc-macro/lints_in_proc_macros.stderr +++ b/tests/ui/proc-macro/lints_in_proc_macros.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `foobar2` in this scope +error[E0425]: cannot find value `foobar2` --> $DIR/lints_in_proc_macros.rs:9:5 | LL | bang_proc_macro2!(); diff --git a/tests/ui/proc-macro/macro-namespace-reserved-2.rs b/tests/ui/proc-macro/macro-namespace-reserved-2.rs index 79f591d8cb61e..929cb46ae98c9 100644 --- a/tests/ui/proc-macro/macro-namespace-reserved-2.rs +++ b/tests/ui/proc-macro/macro-namespace-reserved-2.rs @@ -25,17 +25,17 @@ fn check_bang1() { my_macro!(); //~ ERROR can't use a procedural macro from the same crate that defines it } fn check_bang2() { - my_macro_attr!(); //~ ERROR cannot find macro `my_macro_attr` in this scope + my_macro_attr!(); //~ ERROR cannot find macro `my_macro_attr` crate::my_macro_attr!(); //~ ERROR can't use a procedural macro from the same crate that defines //~| ERROR expected macro, found attribute macro `crate::my_macro_attr` } fn check_bang3() { - MyTrait!(); //~ ERROR cannot find macro `MyTrait` in this scope + MyTrait!(); //~ ERROR cannot find macro `MyTrait` crate::MyTrait!(); //~ ERROR can't use a procedural macro from the same crate that defines it //~| ERROR expected macro, found derive macro `crate::MyTrait` } -#[my_macro] //~ ERROR cannot find attribute `my_macro` in this scope +#[my_macro] //~ ERROR cannot find attribute `my_macro` #[crate::my_macro] //~ ERROR can't use a procedural macro from the same crate that defines it //~| ERROR expected attribute, found macro `crate::my_macro` fn check_attr1() {} @@ -45,8 +45,8 @@ fn check_attr2() {} //~| ERROR expected attribute, found derive macro `MyTrait` fn check_attr3() {} -#[derive(my_macro)] //~ ERROR cannot find derive macro `my_macro` in this scope - //~| ERROR cannot find derive macro `my_macro` in this scope +#[derive(my_macro)] //~ ERROR cannot find derive macro `my_macro` + //~| ERROR cannot find derive macro `my_macro` #[derive(crate::my_macro)] //~ ERROR can't use a procedural macro from the same crate that defines //~| ERROR expected derive macro, found macro `crate::my_macro` struct CheckDerive1; diff --git a/tests/ui/proc-macro/macro-rules-derive.stderr b/tests/ui/proc-macro/macro-rules-derive.stderr index e7cd4474618fe..6457e84a514cb 100644 --- a/tests/ui/proc-macro/macro-rules-derive.stderr +++ b/tests/ui/proc-macro/macro-rules-derive.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `MissingType` in this scope +error[E0412]: cannot find type `MissingType` --> $DIR/macro-rules-derive.rs:10:20 | LL | field: MissingType diff --git a/tests/ui/proc-macro/mixed-site-span.rs b/tests/ui/proc-macro/mixed-site-span.rs index bab76a8c43319..005c7b31ab705 100644 --- a/tests/ui/proc-macro/mixed-site-span.rs +++ b/tests/ui/proc-macro/mixed-site-span.rs @@ -12,13 +12,13 @@ fn main() { let local_use = 1; proc_macro_rules!(); //~^ ERROR use of undeclared label `'label_use` - //~| ERROR cannot find value `local_use` in this scope + //~| ERROR cannot find value `local_use` ItemDef; // OK - local_def; //~ ERROR cannot find value `local_def` in this scope + local_def; //~ ERROR cannot find value `local_def` } } macro_rules! pass_dollar_crate { - () => (proc_macro_rules!($crate);) //~ ERROR cannot find type `ItemUse` in crate `$crate` + () => (proc_macro_rules!($crate);) //~ ERROR cannot find type `ItemUse` } pass_dollar_crate!(); diff --git a/tests/ui/proc-macro/mixed-site-span.stderr b/tests/ui/proc-macro/mixed-site-span.stderr index 1378608012464..3df298a4ec59a 100644 --- a/tests/ui/proc-macro/mixed-site-span.stderr +++ b/tests/ui/proc-macro/mixed-site-span.stderr @@ -6,7 +6,7 @@ LL | proc_macro_rules!(); | = note: this error originates in the macro `proc_macro_rules` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0425]: cannot find value `local_use` in this scope +error[E0425]: cannot find value `local_use` --> $DIR/mixed-site-span.rs:13:9 | LL | proc_macro_rules!(); @@ -14,17 +14,17 @@ LL | proc_macro_rules!(); | = note: this error originates in the macro `proc_macro_rules` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0425]: cannot find value `local_def` in this scope +error[E0425]: cannot find value `local_def` --> $DIR/mixed-site-span.rs:17:9 | LL | local_def; | ^^^^^^^^^ help: a local variable with a similar name exists: `local_use` -error[E0412]: cannot find type `ItemUse` in crate `$crate` +error[E0412]: cannot find type `ItemUse` --> $DIR/mixed-site-span.rs:24:1 | LL | pass_dollar_crate!(); - | ^^^^^^^^^^^^^^^^^^^^ not found in `$crate` + | ^^^^^^^^^^^^^^^^^^^^ not found in crate `$crate` | = note: this error originates in the macro `proc_macro_rules` which comes from the expansion of the macro `pass_dollar_crate` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/proc-macro/parent-source-spans.rs b/tests/ui/proc-macro/parent-source-spans.rs index 12a1ab1a43d57..84f6c57d4aef7 100644 --- a/tests/ui/proc-macro/parent-source-spans.rs +++ b/tests/ui/proc-macro/parent-source-spans.rs @@ -27,9 +27,9 @@ macro three($($tokens:tt)*) { macro four($($tokens:tt)*) { parent_source_spans!($($tokens)*); - //~^ ERROR cannot find value `ok` in this scope - //~| ERROR cannot find value `ok` in this scope - //~| ERROR cannot find value `ok` in this scope + //~^ ERROR cannot find value `ok` + //~| ERROR cannot find value `ok` + //~| ERROR cannot find value `ok` } fn main() { diff --git a/tests/ui/proc-macro/parent-source-spans.stderr b/tests/ui/proc-macro/parent-source-spans.stderr index a3b27fd7bcc1b..b50142bc83bb3 100644 --- a/tests/ui/proc-macro/parent-source-spans.stderr +++ b/tests/ui/proc-macro/parent-source-spans.stderr @@ -136,7 +136,7 @@ error: second source: "hop" LL | three!("hip", "hop"); | ^^^^^ -error[E0425]: cannot find value `ok` in this scope +error[E0425]: cannot find value `ok` --> $DIR/parent-source-spans.rs:29:5 | LL | parent_source_spans!($($tokens)*); @@ -150,7 +150,7 @@ LL | one!("hello", "world"); | = note: this error originates in the macro `parent_source_spans` which comes from the expansion of the macro `one` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0425]: cannot find value `ok` in this scope +error[E0425]: cannot find value `ok` --> $DIR/parent-source-spans.rs:29:5 | LL | parent_source_spans!($($tokens)*); @@ -164,7 +164,7 @@ LL | two!("yay", "rust"); | = note: this error originates in the macro `parent_source_spans` which comes from the expansion of the macro `two` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0425]: cannot find value `ok` in this scope +error[E0425]: cannot find value `ok` --> $DIR/parent-source-spans.rs:29:5 | LL | parent_source_spans!($($tokens)*); diff --git a/tests/ui/proc-macro/proc-macro-attributes.rs b/tests/ui/proc-macro/proc-macro-attributes.rs index 6d5e7b67c782e..e7f6e83cd640e 100644 --- a/tests/ui/proc-macro/proc-macro-attributes.rs +++ b/tests/ui/proc-macro/proc-macro-attributes.rs @@ -6,7 +6,7 @@ extern crate derive_b; #[B] //~ ERROR `B` is ambiguous //~| WARN derive helper attribute is used before it is introduced //~| WARN this was previously accepted -#[C] //~ ERROR cannot find attribute `C` in this scope +#[C] //~ ERROR cannot find attribute `C` #[B(D)] //~ ERROR `B` is ambiguous //~| WARN derive helper attribute is used before it is introduced //~| WARN this was previously accepted diff --git a/tests/ui/proc-macro/resolve-error.rs b/tests/ui/proc-macro/resolve-error.rs index 2670d8884ae72..f4e9677ccebab 100644 --- a/tests/ui/proc-macro/resolve-error.rs +++ b/tests/ui/proc-macro/resolve-error.rs @@ -25,11 +25,11 @@ macro_rules! attr_proc_mac { struct Foo; // Interpreted as an unstable custom attribute -#[attr_proc_macra] //~ ERROR cannot find attribute `attr_proc_macra` in this scope +#[attr_proc_macra] //~ ERROR cannot find attribute `attr_proc_macra` struct Bar; // Interpreted as an unstable custom attribute -#[FooWithLongNan] //~ ERROR cannot find attribute `FooWithLongNan` in this scope +#[FooWithLongNan] //~ ERROR cannot find attribute `FooWithLongNan` struct Asdf; #[derive(Dlone)] diff --git a/tests/ui/proc-macro/span-from-proc-macro.stderr b/tests/ui/proc-macro/span-from-proc-macro.stderr index 7beed505a7efa..43af9280a8132 100644 --- a/tests/ui/proc-macro/span-from-proc-macro.stderr +++ b/tests/ui/proc-macro/span-from-proc-macro.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `MissingType` in this scope +error[E0412]: cannot find type `MissingType` --> $DIR/auxiliary/span-from-proc-macro.rs:37:20 | LL | pub fn error_from_attribute(_args: TokenStream, _input: TokenStream) -> TokenStream { @@ -12,7 +12,7 @@ LL | field: MissingType LL | #[error_from_attribute] | ----------------------- in this procedural macro expansion -error[E0412]: cannot find type `OtherMissingType` in this scope +error[E0412]: cannot find type `OtherMissingType` --> $DIR/auxiliary/span-from-proc-macro.rs:46:21 | LL | pub fn error_from_derive(_input: TokenStream) -> TokenStream { @@ -26,7 +26,7 @@ LL | Variant(OtherMissingType) LL | #[derive(ErrorFromDerive)] | --------------- in this derive macro expansion -error[E0425]: cannot find value `my_ident` in this scope +error[E0425]: cannot find value `my_ident` --> $DIR/auxiliary/span-from-proc-macro.rs:29:9 | LL | pub fn other_error_from_bang(_input: TokenStream) -> TokenStream { diff --git a/tests/ui/proc-macro/weird-hygiene.stderr b/tests/ui/proc-macro/weird-hygiene.stderr index 256e68e8970e6..d5d693b264b42 100644 --- a/tests/ui/proc-macro/weird-hygiene.stderr +++ b/tests/ui/proc-macro/weird-hygiene.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `hidden_ident` in this scope +error[E0425]: cannot find value `hidden_ident` --> $DIR/weird-hygiene.rs:23:43 | LL | Value = (stringify!($tokens + hidden_ident), 1).1 @@ -9,7 +9,7 @@ LL | other!(50); | = note: this error originates in the macro `inner` which comes from the expansion of the macro `other` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0425]: cannot find value `hidden_ident` in this scope +error[E0425]: cannot find value `hidden_ident` --> $DIR/weird-hygiene.rs:34:13 | LL | hidden_ident diff --git a/tests/ui/query-system/issue-83479.rs b/tests/ui/query-system/issue-83479.rs index 32676dfe9c8fa..b71c5b11adec1 100644 --- a/tests/ui/query-system/issue-83479.rs +++ b/tests/ui/query-system/issue-83479.rs @@ -2,12 +2,12 @@ type PairCoupledTypes: Trait< //~^ ERROR: bounds on `type`s in this context have no effect - //~| ERROR: cannot find trait `Trait` in this scope + //~| ERROR: cannot find trait `Trait` [u32; { static FOO: usize; //~ ERROR: free static item without body }], > = impl Trait< - //~^ ERROR: cannot find trait `Trait` in this scope + //~^ ERROR: cannot find trait `Trait` [u32; { static FOO: usize; //~ ERROR: free static item without body }], diff --git a/tests/ui/query-system/issue-83479.stderr b/tests/ui/query-system/issue-83479.stderr index 7cb41f5cbe51c..dd0bac2bc47a7 100644 --- a/tests/ui/query-system/issue-83479.stderr +++ b/tests/ui/query-system/issue-83479.stderr @@ -27,13 +27,13 @@ LL | static FOO: usize; | | | help: provide a definition for the static: `= ;` -error[E0405]: cannot find trait `Trait` in this scope +error[E0405]: cannot find trait `Trait` --> $DIR/issue-83479.rs:3:24 | LL | type PairCoupledTypes: Trait< | ^^^^^ not found in this scope -error[E0405]: cannot find trait `Trait` in this scope +error[E0405]: cannot find trait `Trait` --> $DIR/issue-83479.rs:9:10 | LL | > = impl Trait< diff --git a/tests/ui/recursion/recursive-reexports.rs b/tests/ui/recursion/recursive-reexports.rs index 26d15fb04734b..ef3992fe25069 100644 --- a/tests/ui/recursion/recursive-reexports.rs +++ b/tests/ui/recursion/recursive-reexports.rs @@ -2,6 +2,6 @@ extern crate recursive_reexports; -fn f() -> recursive_reexports::S {} //~ ERROR cannot find type `S` in crate `recursive_reexports` +fn f() -> recursive_reexports::S {} //~ ERROR cannot find type `S` fn main() {} diff --git a/tests/ui/recursion/recursive-reexports.stderr b/tests/ui/recursion/recursive-reexports.stderr index 71653d26a18d7..01176b83572d5 100644 --- a/tests/ui/recursion/recursive-reexports.stderr +++ b/tests/ui/recursion/recursive-reexports.stderr @@ -1,8 +1,8 @@ -error[E0412]: cannot find type `S` in crate `recursive_reexports` +error[E0412]: cannot find type `S` --> $DIR/recursive-reexports.rs:5:32 | LL | fn f() -> recursive_reexports::S {} - | ^ not found in `recursive_reexports` + | ^ not found in crate `recursive_reexports` error: aborting due to 1 previous error diff --git a/tests/ui/regions/outlives-with-missing.rs b/tests/ui/regions/outlives-with-missing.rs index 29d89718b5867..0d012fa6019ce 100644 --- a/tests/ui/regions/outlives-with-missing.rs +++ b/tests/ui/regions/outlives-with-missing.rs @@ -8,7 +8,7 @@ impl HandlerWrapper { pub fn set_handler(&self, handler: &H::Target) where T: Send + Sync + 'static, - //~^ ERROR cannot find type `T` in this scope + //~^ ERROR cannot find type `T` { } } diff --git a/tests/ui/regions/outlives-with-missing.stderr b/tests/ui/regions/outlives-with-missing.stderr index 0e3aaaf5fdbd0..4a06373e5c6d8 100644 --- a/tests/ui/regions/outlives-with-missing.stderr +++ b/tests/ui/regions/outlives-with-missing.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `T` in this scope +error[E0412]: cannot find type `T` --> $DIR/outlives-with-missing.rs:10:9 | LL | impl HandlerWrapper { diff --git a/tests/ui/reserved/reserved-attr-on-macro.rs b/tests/ui/reserved/reserved-attr-on-macro.rs index 5c4657e0ec2e1..8c0f77176aa6c 100644 --- a/tests/ui/reserved/reserved-attr-on-macro.rs +++ b/tests/ui/reserved/reserved-attr-on-macro.rs @@ -1,5 +1,5 @@ #[rustc_attribute_should_be_reserved] -//~^ ERROR cannot find attribute `rustc_attribute_should_be_reserved` in this scope +//~^ ERROR cannot find attribute `rustc_attribute_should_be_reserved` //~| ERROR attributes starting with `rustc` are reserved for use by the `rustc` compiler macro_rules! foo { diff --git a/tests/ui/resolve/associated-fn-called-as-fn.stderr b/tests/ui/resolve/associated-fn-called-as-fn.stderr index 7d28b959a1a48..577492ee14f93 100644 --- a/tests/ui/resolve/associated-fn-called-as-fn.stderr +++ b/tests/ui/resolve/associated-fn-called-as-fn.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find function `collect_primary` in this scope +error[E0425]: cannot find function `collect_primary` --> $DIR/associated-fn-called-as-fn.rs:6:30 | LL | '0'..='9' => collect_primary(&c), @@ -9,7 +9,7 @@ help: you might have meant to call the associated function LL | '0'..='9' => Self::collect_primary(&c), | ++++++ -error[E0425]: cannot find function `collect_primary` in this scope +error[E0425]: cannot find function `collect_primary` --> $DIR/associated-fn-called-as-fn.rs:23:30 | LL | '0'..='9' => collect_primary(&c), diff --git a/tests/ui/resolve/bad-env-capture.stderr b/tests/ui/resolve/bad-env-capture.stderr index 59b1fabfd7c46..05d8ef748b531 100644 --- a/tests/ui/resolve/bad-env-capture.stderr +++ b/tests/ui/resolve/bad-env-capture.stderr @@ -6,13 +6,13 @@ LL | fn bar() { log(debug, x); } | = help: use the `|| { ... }` closure form instead -error[E0425]: cannot find value `debug` in this scope +error[E0425]: cannot find value `debug` --> $DIR/bad-env-capture.rs:4:20 | LL | fn bar() { log(debug, x); } | ^^^^^ not found in this scope -error[E0425]: cannot find function `log` in this scope +error[E0425]: cannot find function `log` --> $DIR/bad-env-capture.rs:4:16 | LL | fn bar() { log(debug, x); } diff --git a/tests/ui/resolve/bad-env-capture2.stderr b/tests/ui/resolve/bad-env-capture2.stderr index 811c259de6bd6..e6e750d6c023e 100644 --- a/tests/ui/resolve/bad-env-capture2.stderr +++ b/tests/ui/resolve/bad-env-capture2.stderr @@ -6,13 +6,13 @@ LL | fn bar() { log(debug, x); } | = help: use the `|| { ... }` closure form instead -error[E0425]: cannot find value `debug` in this scope +error[E0425]: cannot find value `debug` --> $DIR/bad-env-capture2.rs:3:20 | LL | fn bar() { log(debug, x); } | ^^^^^ not found in this scope -error[E0425]: cannot find function `log` in this scope +error[E0425]: cannot find function `log` --> $DIR/bad-env-capture2.rs:3:16 | LL | fn bar() { log(debug, x); } diff --git a/tests/ui/resolve/bad-env-capture3.stderr b/tests/ui/resolve/bad-env-capture3.stderr index eab37fde96e4c..bdcf19f717c60 100644 --- a/tests/ui/resolve/bad-env-capture3.stderr +++ b/tests/ui/resolve/bad-env-capture3.stderr @@ -6,13 +6,13 @@ LL | fn bar() { log(debug, x); } | = help: use the `|| { ... }` closure form instead -error[E0425]: cannot find value `debug` in this scope +error[E0425]: cannot find value `debug` --> $DIR/bad-env-capture3.rs:4:24 | LL | fn bar() { log(debug, x); } | ^^^^^ not found in this scope -error[E0425]: cannot find function `log` in this scope +error[E0425]: cannot find function `log` --> $DIR/bad-env-capture3.rs:4:20 | LL | fn bar() { log(debug, x); } diff --git a/tests/ui/resolve/bad-expr-path.rs b/tests/ui/resolve/bad-expr-path.rs index 31fc9cf2cb575..f4dff83330d94 100644 --- a/tests/ui/resolve/bad-expr-path.rs +++ b/tests/ui/resolve/bad-expr-path.rs @@ -2,7 +2,7 @@ mod m1 {} fn main(arguments: Vec) { //~ ERROR `main` function has wrong type log(debug, m1::arguments); - //~^ ERROR cannot find function `log` in this scope - //~| ERROR cannot find value `debug` in this scope - //~| ERROR cannot find value `arguments` in module `m1` + //~^ ERROR cannot find function `log` + //~| ERROR cannot find value `debug` + //~| ERROR cannot find value `arguments` } diff --git a/tests/ui/resolve/bad-expr-path.stderr b/tests/ui/resolve/bad-expr-path.stderr index 0392c1fa23993..44da9ae9bc3b0 100644 --- a/tests/ui/resolve/bad-expr-path.stderr +++ b/tests/ui/resolve/bad-expr-path.stderr @@ -1,14 +1,14 @@ -error[E0425]: cannot find value `debug` in this scope +error[E0425]: cannot find value `debug` --> $DIR/bad-expr-path.rs:4:9 | LL | log(debug, m1::arguments); | ^^^^^ not found in this scope -error[E0425]: cannot find value `arguments` in module `m1` +error[E0425]: cannot find value `arguments` --> $DIR/bad-expr-path.rs:4:20 | LL | log(debug, m1::arguments); - | ^^^^^^^^^ not found in `m1` + | ^^^^^^^^^ not found in module `m1` error[E0580]: `main` function has wrong type --> $DIR/bad-expr-path.rs:3:1 @@ -19,7 +19,7 @@ LL | fn main(arguments: Vec) { = note: expected signature `fn()` found signature `fn(Vec)` -error[E0425]: cannot find function `log` in this scope +error[E0425]: cannot find function `log` --> $DIR/bad-expr-path.rs:4:5 | LL | log(debug, m1::arguments); diff --git a/tests/ui/resolve/bad-expr-path2.rs b/tests/ui/resolve/bad-expr-path2.rs index eb88edb9071ef..952949fbb43d5 100644 --- a/tests/ui/resolve/bad-expr-path2.rs +++ b/tests/ui/resolve/bad-expr-path2.rs @@ -4,7 +4,7 @@ mod m1 { fn main(arguments: Vec) { //~ ERROR `main` function has wrong type log(debug, m1::arguments); - //~^ ERROR cannot find function `log` in this scope - //~| ERROR cannot find value `debug` in this scope + //~^ ERROR cannot find function `log` + //~| ERROR cannot find value `debug` //~| ERROR expected value, found module `m1::arguments` } diff --git a/tests/ui/resolve/bad-expr-path2.stderr b/tests/ui/resolve/bad-expr-path2.stderr index 9238b1f7023e5..c74efcd036b27 100644 --- a/tests/ui/resolve/bad-expr-path2.stderr +++ b/tests/ui/resolve/bad-expr-path2.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `debug` in this scope +error[E0425]: cannot find value `debug` --> $DIR/bad-expr-path2.rs:6:9 | LL | log(debug, m1::arguments); @@ -19,7 +19,7 @@ LL | fn main(arguments: Vec) { = note: expected signature `fn()` found signature `fn(Vec)` -error[E0425]: cannot find function `log` in this scope +error[E0425]: cannot find function `log` --> $DIR/bad-expr-path2.rs:6:5 | LL | log(debug, m1::arguments); diff --git a/tests/ui/resolve/crate-called-as-function.rs b/tests/ui/resolve/crate-called-as-function.rs index e8f52c0c029aa..3e70c6029b606 100644 --- a/tests/ui/resolve/crate-called-as-function.rs +++ b/tests/ui/resolve/crate-called-as-function.rs @@ -1,3 +1,3 @@ fn main() { - ::foo() //~ cannot find external crate `foo` in the crate root + ::foo() //~ cannot find external crate `foo` } diff --git a/tests/ui/resolve/crate-called-as-function.stderr b/tests/ui/resolve/crate-called-as-function.stderr index 1d6eb8ad6f5e0..ccfd9ff830418 100644 --- a/tests/ui/resolve/crate-called-as-function.stderr +++ b/tests/ui/resolve/crate-called-as-function.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find external crate `foo` in the crate root +error[E0425]: cannot find external crate `foo` --> $DIR/crate-called-as-function.rs:2:7 | LL | ::foo() diff --git a/tests/ui/resolve/crate-in-paths.rs b/tests/ui/resolve/crate-in-paths.rs index fad1add40afa9..1cbcfb7458c58 100644 --- a/tests/ui/resolve/crate-in-paths.rs +++ b/tests/ui/resolve/crate-in-paths.rs @@ -6,5 +6,5 @@ mod bar { fn main() { Foo; - //~^ ERROR cannot find value `Foo` in this scope [E0425] + //~^ ERROR cannot find value `Foo` [E0425] } diff --git a/tests/ui/resolve/crate-in-paths.stderr b/tests/ui/resolve/crate-in-paths.stderr index 9eb735a3aab53..b16a2e30d03de 100644 --- a/tests/ui/resolve/crate-in-paths.stderr +++ b/tests/ui/resolve/crate-in-paths.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `Foo` in this scope +error[E0425]: cannot find value `Foo` --> $DIR/crate-in-paths.rs:8:5 | LL | Foo; diff --git a/tests/ui/resolve/editions-crate-root-2015.rs b/tests/ui/resolve/editions-crate-root-2015.rs index 5f764d3ceef81..06e716c8245ac 100644 --- a/tests/ui/resolve/editions-crate-root-2015.rs +++ b/tests/ui/resolve/editions-crate-root-2015.rs @@ -9,10 +9,10 @@ mod inner { } fn bare_global(_: ::nonexistant) { - //~^ ERROR cannot find type `nonexistant` in the crate root + //~^ ERROR cannot find type `nonexistant` } fn bare_crate(_: crate::nonexistant) { - //~^ ERROR cannot find type `nonexistant` in the crate root + //~^ ERROR cannot find type `nonexistant` } } diff --git a/tests/ui/resolve/editions-crate-root-2015.stderr b/tests/ui/resolve/editions-crate-root-2015.stderr index 00cdd0c58f4ec..785528d20cce4 100644 --- a/tests/ui/resolve/editions-crate-root-2015.stderr +++ b/tests/ui/resolve/editions-crate-root-2015.stderr @@ -14,13 +14,13 @@ LL | fn crate_inner(_: crate::nonexistant::Foo) { | = help: consider adding `extern crate nonexistant` to use the `nonexistant` crate -error[E0412]: cannot find type `nonexistant` in the crate root +error[E0412]: cannot find type `nonexistant` --> $DIR/editions-crate-root-2015.rs:11:25 | LL | fn bare_global(_: ::nonexistant) { | ^^^^^^^^^^^ not found in the crate root -error[E0412]: cannot find type `nonexistant` in the crate root +error[E0412]: cannot find type `nonexistant` --> $DIR/editions-crate-root-2015.rs:14:29 | LL | fn bare_crate(_: crate::nonexistant) { diff --git a/tests/ui/resolve/editions-crate-root-2018.rs b/tests/ui/resolve/editions-crate-root-2018.rs index 0e964d20f9c0e..6888cefa18a48 100644 --- a/tests/ui/resolve/editions-crate-root-2018.rs +++ b/tests/ui/resolve/editions-crate-root-2018.rs @@ -2,17 +2,17 @@ mod inner { fn global_inner(_: ::nonexistant::Foo) { - //~^ ERROR failed to resolve: could not find `nonexistant` in the list of imported crates + //~^ ERROR failed to resolve: could not find `nonexistant` } fn crate_inner(_: crate::nonexistant::Foo) { - //~^ ERROR failed to resolve: could not find `nonexistant` in the crate root + //~^ ERROR failed to resolve: could not find `nonexistant` } fn bare_global(_: ::nonexistant) { - //~^ ERROR cannot find crate `nonexistant` in the list of imported crates + //~^ ERROR cannot find crate `nonexistant` } fn bare_crate(_: crate::nonexistant) { - //~^ ERROR cannot find type `nonexistant` in the crate root + //~^ ERROR cannot find type `nonexistant` } } diff --git a/tests/ui/resolve/editions-crate-root-2018.stderr b/tests/ui/resolve/editions-crate-root-2018.stderr index 967a5a2fca155..a51440f69359b 100644 --- a/tests/ui/resolve/editions-crate-root-2018.stderr +++ b/tests/ui/resolve/editions-crate-root-2018.stderr @@ -10,13 +10,13 @@ error[E0433]: failed to resolve: could not find `nonexistant` in the crate root LL | fn crate_inner(_: crate::nonexistant::Foo) { | ^^^^^^^^^^^ could not find `nonexistant` in the crate root -error[E0412]: cannot find crate `nonexistant` in the list of imported crates +error[E0412]: cannot find crate `nonexistant` --> $DIR/editions-crate-root-2018.rs:11:25 | LL | fn bare_global(_: ::nonexistant) { | ^^^^^^^^^^^ not found in the list of imported crates -error[E0412]: cannot find type `nonexistant` in the crate root +error[E0412]: cannot find type `nonexistant` --> $DIR/editions-crate-root-2018.rs:14:29 | LL | fn bare_crate(_: crate::nonexistant) { diff --git a/tests/ui/resolve/enums-are-namespaced-xc.stderr b/tests/ui/resolve/enums-are-namespaced-xc.stderr index 5af6cb04275b8..ce9df1779ede5 100644 --- a/tests/ui/resolve/enums-are-namespaced-xc.stderr +++ b/tests/ui/resolve/enums-are-namespaced-xc.stderr @@ -1,8 +1,8 @@ -error[E0425]: cannot find value `A` in crate `namespaced_enums` +error[E0425]: cannot find value `A` --> $DIR/enums-are-namespaced-xc.rs:5:31 | LL | let _ = namespaced_enums::A; - | ^ not found in `namespaced_enums` + | ^ not found in crate `namespaced_enums` | help: consider importing this unit variant | @@ -14,11 +14,11 @@ LL - let _ = namespaced_enums::A; LL + let _ = A; | -error[E0425]: cannot find function, tuple struct or tuple variant `B` in crate `namespaced_enums` +error[E0425]: cannot find function, tuple struct or tuple variant `B` --> $DIR/enums-are-namespaced-xc.rs:7:31 | LL | let _ = namespaced_enums::B(10); - | ^ not found in `namespaced_enums` + | ^ not found in crate `namespaced_enums` | help: consider importing this tuple variant | @@ -30,11 +30,11 @@ LL - let _ = namespaced_enums::B(10); LL + let _ = B(10); | -error[E0422]: cannot find struct, variant or union type `C` in crate `namespaced_enums` +error[E0422]: cannot find struct, variant or union type `C` --> $DIR/enums-are-namespaced-xc.rs:9:31 | LL | let _ = namespaced_enums::C { a: 10 }; - | ^ not found in `namespaced_enums` + | ^ not found in crate `namespaced_enums` | help: consider importing this variant | diff --git a/tests/ui/resolve/enums-pats-not-idents.rs b/tests/ui/resolve/enums-pats-not-idents.rs index 5b918eef6d65b..64e63309146f0 100644 --- a/tests/ui/resolve/enums-pats-not-idents.rs +++ b/tests/ui/resolve/enums-pats-not-idents.rs @@ -1,3 +1,3 @@ fn main() { - let a(1) = 13; //~ ERROR cannot find tuple struct or tuple variant `a` in this scope + let a(1) = 13; //~ ERROR cannot find tuple struct or tuple variant `a` } diff --git a/tests/ui/resolve/enums-pats-not-idents.stderr b/tests/ui/resolve/enums-pats-not-idents.stderr index 6bb6e152c800c..267792918de22 100644 --- a/tests/ui/resolve/enums-pats-not-idents.stderr +++ b/tests/ui/resolve/enums-pats-not-idents.stderr @@ -1,4 +1,4 @@ -error[E0531]: cannot find tuple struct or tuple variant `a` in this scope +error[E0531]: cannot find tuple struct or tuple variant `a` --> $DIR/enums-pats-not-idents.rs:2:9 | LL | let a(1) = 13; diff --git a/tests/ui/resolve/field-and-method-in-self-not-available-in-assoc-fn.rs b/tests/ui/resolve/field-and-method-in-self-not-available-in-assoc-fn.rs index b5f13959081b8..1f074aec25bc6 100644 --- a/tests/ui/resolve/field-and-method-in-self-not-available-in-assoc-fn.rs +++ b/tests/ui/resolve/field-and-method-in-self-not-available-in-assoc-fn.rs @@ -8,11 +8,11 @@ impl Foo { } fn new() -> Foo { - field; //~ ERROR cannot find value `field` in this scope - Foo { field } //~ ERROR cannot find value `field` in this scope + field; //~ ERROR cannot find value `field` + Foo { field } //~ ERROR cannot find value `field` } fn clone(&self) -> Foo { - Foo { field } //~ ERROR cannot find value `field` in this scope + Foo { field } //~ ERROR cannot find value `field` } } fn main() {} diff --git a/tests/ui/resolve/field-and-method-in-self-not-available-in-assoc-fn.stderr b/tests/ui/resolve/field-and-method-in-self-not-available-in-assoc-fn.stderr index 2f624f24804c8..d323696f580ab 100644 --- a/tests/ui/resolve/field-and-method-in-self-not-available-in-assoc-fn.stderr +++ b/tests/ui/resolve/field-and-method-in-self-not-available-in-assoc-fn.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `field` in this scope +error[E0425]: cannot find value `field` --> $DIR/field-and-method-in-self-not-available-in-assoc-fn.rs:11:9 | LL | field: u32, @@ -10,7 +10,7 @@ LL | fn field(&self) -> u32 { LL | field; | ^^^^^ -error[E0425]: cannot find value `field` in this scope +error[E0425]: cannot find value `field` --> $DIR/field-and-method-in-self-not-available-in-assoc-fn.rs:12:15 | LL | field: u32, @@ -22,7 +22,7 @@ LL | fn field(&self) -> u32 { LL | Foo { field } | ^^^^^ -error[E0425]: cannot find value `field` in this scope +error[E0425]: cannot find value `field` --> $DIR/field-and-method-in-self-not-available-in-assoc-fn.rs:15:15 | LL | fn field(&self) -> u32 { diff --git a/tests/ui/resolve/filter-intrinsics.stderr b/tests/ui/resolve/filter-intrinsics.stderr index 9c9e92f6d4f83..20d5c01be8fa1 100644 --- a/tests/ui/resolve/filter-intrinsics.stderr +++ b/tests/ui/resolve/filter-intrinsics.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find function `transmute` in this scope +error[E0425]: cannot find function `transmute` --> $DIR/filter-intrinsics.rs:3:13 | LL | let _ = transmute::(); @@ -9,7 +9,7 @@ help: consider importing this function LL + use std::mem::transmute; | -error[E0425]: cannot find function `fabsf64` in this scope +error[E0425]: cannot find function `fabsf64` --> $DIR/filter-intrinsics.rs:8:13 | LL | let _ = fabsf64(1.0); diff --git a/tests/ui/resolve/issue-102946.rs b/tests/ui/resolve/issue-102946.rs index c6feca6f32f60..01d044b3f1a7e 100644 --- a/tests/ui/resolve/issue-102946.rs +++ b/tests/ui/resolve/issue-102946.rs @@ -1,5 +1,5 @@ impl Error for str::Utf8Error { - //~^ ERROR cannot find trait `Error` in this scope + //~^ ERROR cannot find trait `Error` //~| ERROR ambiguous associated type fn description(&self) {} } diff --git a/tests/ui/resolve/issue-102946.stderr b/tests/ui/resolve/issue-102946.stderr index b2cdcb25c3f96..7ad1bbcc831b0 100644 --- a/tests/ui/resolve/issue-102946.stderr +++ b/tests/ui/resolve/issue-102946.stderr @@ -1,4 +1,4 @@ -error[E0405]: cannot find trait `Error` in this scope +error[E0405]: cannot find trait `Error` --> $DIR/issue-102946.rs:1:6 | LL | impl Error for str::Utf8Error { diff --git a/tests/ui/resolve/issue-103474.rs b/tests/ui/resolve/issue-103474.rs index 14f2259e1d4e8..ae13e2cedd549 100644 --- a/tests/ui/resolve/issue-103474.rs +++ b/tests/ui/resolve/issue-103474.rs @@ -4,12 +4,12 @@ impl S { fn second(&self) { first() - //~^ ERROR cannot find function `first` in this scope + //~^ ERROR cannot find function `first` } fn third(&self) { no_method_err() - //~^ ERROR cannot find function `no_method_err` in this scope + //~^ ERROR cannot find function `no_method_err` } } @@ -21,7 +21,7 @@ struct Foo { impl Foo { fn needs_self() { this.i - //~^ ERROR cannot find value `this` in this scope + //~^ ERROR cannot find value `this` } } diff --git a/tests/ui/resolve/issue-103474.stderr b/tests/ui/resolve/issue-103474.stderr index e48fb31eccc9a..88503b5f8aad7 100644 --- a/tests/ui/resolve/issue-103474.stderr +++ b/tests/ui/resolve/issue-103474.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `this` in this scope +error[E0425]: cannot find value `this` --> $DIR/issue-103474.rs:23:9 | LL | this.i @@ -13,7 +13,7 @@ help: if you meant to use `self`, you are also missing a `self` receiver argumen LL | fn needs_self(&self) { | +++++ -error[E0425]: cannot find function `first` in this scope +error[E0425]: cannot find function `first` --> $DIR/issue-103474.rs:6:9 | LL | first() @@ -24,7 +24,7 @@ help: consider using the method on `Self` LL | self.first() | +++++ -error[E0425]: cannot find function `no_method_err` in this scope +error[E0425]: cannot find function `no_method_err` --> $DIR/issue-103474.rs:11:9 | LL | no_method_err() diff --git a/tests/ui/resolve/issue-104700-inner_scope.stderr b/tests/ui/resolve/issue-104700-inner_scope.stderr index 051b234fc72d8..5b17e0b7dbc90 100644 --- a/tests/ui/resolve/issue-104700-inner_scope.stderr +++ b/tests/ui/resolve/issue-104700-inner_scope.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `bar` in this scope +error[E0425]: cannot find value `bar` --> $DIR/issue-104700-inner_scope.rs:7:8 | LL | if bar == 2 { @@ -10,7 +10,7 @@ help: the binding `bar` is available in a different scope in the same function LL | let bar = 2; | ^^^ -error[E0425]: cannot find function `test_func` in this scope +error[E0425]: cannot find function `test_func` --> $DIR/issue-104700-inner_scope.rs:10:5 | LL | test_func(1); diff --git a/tests/ui/resolve/issue-116164.rs b/tests/ui/resolve/issue-116164.rs index d30c8f514b3d6..66bf5a984f857 100644 --- a/tests/ui/resolve/issue-116164.rs +++ b/tests/ui/resolve/issue-116164.rs @@ -15,5 +15,5 @@ use crate::reexports::*; fn main() { ExOne; - //~^ ERROR: cannot find value `ExOne` in this scope + //~^ ERROR: cannot find value `ExOne` } diff --git a/tests/ui/resolve/issue-116164.stderr b/tests/ui/resolve/issue-116164.stderr index 8880242c19561..fc54cae01f96c 100644 --- a/tests/ui/resolve/issue-116164.stderr +++ b/tests/ui/resolve/issue-116164.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `ExOne` in this scope +error[E0425]: cannot find value `ExOne` --> $DIR/issue-116164.rs:17:5 | LL | ExOne; diff --git a/tests/ui/resolve/issue-118295.rs b/tests/ui/resolve/issue-118295.rs index b97681d956341..314d7d9aa4fe0 100644 --- a/tests/ui/resolve/issue-118295.rs +++ b/tests/ui/resolve/issue-118295.rs @@ -1,5 +1,5 @@ macro_rules! {} -//~^ ERROR cannot find macro `macro_rules` in this scope +//~^ ERROR cannot find macro `macro_rules` //~| NOTE maybe you have forgotten to define a name for this `macro_rules!` fn main() {} diff --git a/tests/ui/resolve/issue-14254.stderr b/tests/ui/resolve/issue-14254.stderr index 9284b4babc50f..5246e0f2a1c77 100644 --- a/tests/ui/resolve/issue-14254.stderr +++ b/tests/ui/resolve/issue-14254.stderr @@ -1,10 +1,10 @@ -error[E0425]: cannot find value `a` in this scope +error[E0425]: cannot find value `a` --> $DIR/issue-14254.rs:21:9 | LL | a; | ^ not found in this scope -error[E0425]: cannot find value `x` in this scope +error[E0425]: cannot find value `x` --> $DIR/issue-14254.rs:30:9 | LL | x; @@ -15,7 +15,7 @@ help: you might have meant to use the available field LL | self.x; | +++++ -error[E0425]: cannot find value `y` in this scope +error[E0425]: cannot find value `y` --> $DIR/issue-14254.rs:32:9 | LL | y; @@ -26,13 +26,13 @@ help: you might have meant to use the available field LL | self.y; | +++++ -error[E0425]: cannot find value `a` in this scope +error[E0425]: cannot find value `a` --> $DIR/issue-14254.rs:34:9 | LL | a; | ^ not found in this scope -error[E0425]: cannot find value `bah` in this scope +error[E0425]: cannot find value `bah` --> $DIR/issue-14254.rs:36:9 | LL | bah; @@ -43,13 +43,13 @@ help: you might have meant to refer to the associated function LL | Self::bah; | ++++++ -error[E0425]: cannot find value `b` in this scope +error[E0425]: cannot find value `b` --> $DIR/issue-14254.rs:38:9 | LL | b; | ^ not found in this scope -error[E0425]: cannot find value `x` in this scope +error[E0425]: cannot find value `x` --> $DIR/issue-14254.rs:47:9 | LL | x; @@ -60,7 +60,7 @@ help: you might have meant to use the available field LL | self.x; | +++++ -error[E0425]: cannot find value `y` in this scope +error[E0425]: cannot find value `y` --> $DIR/issue-14254.rs:49:9 | LL | y; @@ -71,13 +71,13 @@ help: you might have meant to use the available field LL | self.y; | +++++ -error[E0425]: cannot find value `a` in this scope +error[E0425]: cannot find value `a` --> $DIR/issue-14254.rs:51:9 | LL | a; | ^ not found in this scope -error[E0425]: cannot find value `bah` in this scope +error[E0425]: cannot find value `bah` --> $DIR/issue-14254.rs:53:9 | LL | bah; @@ -88,13 +88,13 @@ help: you might have meant to refer to the associated function LL | Self::bah; | ++++++ -error[E0425]: cannot find value `b` in this scope +error[E0425]: cannot find value `b` --> $DIR/issue-14254.rs:55:9 | LL | b; | ^ not found in this scope -error[E0425]: cannot find value `bah` in this scope +error[E0425]: cannot find value `bah` --> $DIR/issue-14254.rs:64:9 | LL | bah; @@ -105,7 +105,7 @@ help: you might have meant to refer to the associated function LL | Self::bah; | ++++++ -error[E0425]: cannot find value `bah` in this scope +error[E0425]: cannot find value `bah` --> $DIR/issue-14254.rs:73:9 | LL | bah; @@ -116,7 +116,7 @@ help: you might have meant to refer to the associated function LL | Self::bah; | ++++++ -error[E0425]: cannot find value `bah` in this scope +error[E0425]: cannot find value `bah` --> $DIR/issue-14254.rs:82:9 | LL | bah; @@ -127,7 +127,7 @@ help: you might have meant to refer to the associated function LL | Self::bah; | ++++++ -error[E0425]: cannot find value `bah` in this scope +error[E0425]: cannot find value `bah` --> $DIR/issue-14254.rs:91:9 | LL | bah; @@ -138,7 +138,7 @@ help: you might have meant to refer to the associated function LL | Self::bah; | ++++++ -error[E0425]: cannot find value `bah` in this scope +error[E0425]: cannot find value `bah` --> $DIR/issue-14254.rs:100:9 | LL | bah; @@ -149,7 +149,7 @@ help: you might have meant to refer to the associated function LL | Self::bah; | ++++++ -error[E0425]: cannot find function `baz` in this scope +error[E0425]: cannot find function `baz` --> $DIR/issue-14254.rs:19:9 | LL | baz(); @@ -160,7 +160,7 @@ help: you might have meant to call the method LL | self.baz(); | +++++ -error[E0425]: cannot find function `baz` in this scope +error[E0425]: cannot find function `baz` --> $DIR/issue-14254.rs:28:9 | LL | baz(); @@ -171,7 +171,7 @@ help: you might have meant to call the method LL | self.baz(); | +++++ -error[E0425]: cannot find function `baz` in this scope +error[E0425]: cannot find function `baz` --> $DIR/issue-14254.rs:45:9 | LL | baz(); @@ -182,7 +182,7 @@ help: you might have meant to call the method LL | self.baz(); | +++++ -error[E0425]: cannot find function `baz` in this scope +error[E0425]: cannot find function `baz` --> $DIR/issue-14254.rs:62:9 | LL | baz(); @@ -193,7 +193,7 @@ help: you might have meant to call the method LL | self.baz(); | +++++ -error[E0425]: cannot find function `baz` in this scope +error[E0425]: cannot find function `baz` --> $DIR/issue-14254.rs:71:9 | LL | baz(); @@ -204,7 +204,7 @@ help: you might have meant to call the method LL | self.baz(); | +++++ -error[E0425]: cannot find function `baz` in this scope +error[E0425]: cannot find function `baz` --> $DIR/issue-14254.rs:80:9 | LL | baz(); @@ -215,7 +215,7 @@ help: you might have meant to call the method LL | self.baz(); | +++++ -error[E0425]: cannot find function `baz` in this scope +error[E0425]: cannot find function `baz` --> $DIR/issue-14254.rs:89:9 | LL | baz(); @@ -226,7 +226,7 @@ help: you might have meant to call the method LL | self.baz(); | +++++ -error[E0425]: cannot find function `baz` in this scope +error[E0425]: cannot find function `baz` --> $DIR/issue-14254.rs:98:9 | LL | baz(); diff --git a/tests/ui/resolve/issue-17518.stderr b/tests/ui/resolve/issue-17518.stderr index 3eba715188b40..97760f23ad928 100644 --- a/tests/ui/resolve/issue-17518.stderr +++ b/tests/ui/resolve/issue-17518.stderr @@ -1,4 +1,4 @@ -error[E0422]: cannot find struct, variant or union type `E` in this scope +error[E0422]: cannot find struct, variant or union type `E` --> $DIR/issue-17518.rs:6:5 | LL | E { name: "foobar" }; diff --git a/tests/ui/resolve/issue-21221-1.stderr b/tests/ui/resolve/issue-21221-1.stderr index ccf03afaa19fe..2a7482ce6f043 100644 --- a/tests/ui/resolve/issue-21221-1.stderr +++ b/tests/ui/resolve/issue-21221-1.stderr @@ -1,4 +1,4 @@ -error[E0405]: cannot find trait `Mul` in this scope +error[E0405]: cannot find trait `Mul` --> $DIR/issue-21221-1.rs:43:6 | LL | impl Mul for Foo { @@ -13,7 +13,7 @@ LL + use mul1::Mul; LL + use mul2::Mul; | -error[E0412]: cannot find type `Mul` in this scope +error[E0412]: cannot find type `Mul` --> $DIR/issue-21221-1.rs:58:16 | LL | fn getMul() -> Mul { @@ -28,13 +28,13 @@ LL + use mul1::Mul; LL + use mul2::Mul; | -error[E0405]: cannot find trait `ThisTraitReallyDoesntExistInAnyModuleReally` in this scope +error[E0405]: cannot find trait `ThisTraitReallyDoesntExistInAnyModuleReally` --> $DIR/issue-21221-1.rs:63:6 | LL | impl ThisTraitReallyDoesntExistInAnyModuleReally for Foo { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not found in this scope -error[E0405]: cannot find trait `Div` in this scope +error[E0405]: cannot find trait `Div` --> $DIR/issue-21221-1.rs:68:6 | LL | impl Div for Foo { diff --git a/tests/ui/resolve/issue-21221-2.stderr b/tests/ui/resolve/issue-21221-2.stderr index 5db327955eb10..e1983dbb7bc9a 100644 --- a/tests/ui/resolve/issue-21221-2.stderr +++ b/tests/ui/resolve/issue-21221-2.stderr @@ -1,4 +1,4 @@ -error[E0405]: cannot find trait `T` in this scope +error[E0405]: cannot find trait `T` --> $DIR/issue-21221-2.rs:18:6 | LL | impl T for Foo { } diff --git a/tests/ui/resolve/issue-21221-3.stderr b/tests/ui/resolve/issue-21221-3.stderr index ed3eb2dfb237f..6328bbb542697 100644 --- a/tests/ui/resolve/issue-21221-3.stderr +++ b/tests/ui/resolve/issue-21221-3.stderr @@ -1,4 +1,4 @@ -error[E0405]: cannot find trait `OuterTrait` in this scope +error[E0405]: cannot find trait `OuterTrait` --> $DIR/issue-21221-3.rs:15:6 | LL | impl OuterTrait for Foo {} diff --git a/tests/ui/resolve/issue-21221-4.stderr b/tests/ui/resolve/issue-21221-4.stderr index 482a3bd54a33e..1e1e06b2ef7ac 100644 --- a/tests/ui/resolve/issue-21221-4.stderr +++ b/tests/ui/resolve/issue-21221-4.stderr @@ -1,4 +1,4 @@ -error[E0405]: cannot find trait `T` in this scope +error[E0405]: cannot find trait `T` --> $DIR/issue-21221-4.rs:10:6 | LL | impl T for Foo {} diff --git a/tests/ui/resolve/issue-2356.rs b/tests/ui/resolve/issue-2356.rs index fe9bf4d443e72..6def92ba7d067 100644 --- a/tests/ui/resolve/issue-2356.rs +++ b/tests/ui/resolve/issue-2356.rs @@ -29,7 +29,7 @@ impl Clone for Cat { impl Default for Cat { fn default() -> Self { default(); - //~^ ERROR cannot find function `default` in this scope [E0425] + //~^ ERROR cannot find function `default` [E0425] loop {} } } diff --git a/tests/ui/resolve/issue-2356.stderr b/tests/ui/resolve/issue-2356.stderr index 74a2c9268a2f9..6ba8979efe8df 100644 --- a/tests/ui/resolve/issue-2356.stderr +++ b/tests/ui/resolve/issue-2356.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `whiskers` in this scope +error[E0425]: cannot find value `whiskers` --> $DIR/issue-2356.rs:39:5 | LL | whiskers: isize, @@ -20,7 +20,7 @@ help: add a `self` receiver parameter to make the associated `fn` a method LL | fn meow(&self) { | +++++ -error[E0425]: cannot find value `whiskers` in this scope +error[E0425]: cannot find value `whiskers` --> $DIR/issue-2356.rs:79:5 | LL | whiskers = 0; @@ -31,7 +31,7 @@ help: you might have meant to use the available field LL | self.whiskers = 0; | +++++ -error[E0425]: cannot find value `whiskers` in this scope +error[E0425]: cannot find value `whiskers` --> $DIR/issue-2356.rs:84:5 | LL | whiskers: isize, @@ -48,13 +48,13 @@ LL | fn main() { LL | self += 1; | ^^^^ `self` value is a keyword only available in methods with a `self` parameter -error[E0425]: cannot find function `shave` in this scope +error[E0425]: cannot find function `shave` --> $DIR/issue-2356.rs:17:5 | LL | shave(); | ^^^^^ not found in this scope -error[E0425]: cannot find function `clone` in this scope +error[E0425]: cannot find function `clone` --> $DIR/issue-2356.rs:24:5 | LL | clone(); @@ -65,7 +65,7 @@ help: you might have meant to call the method LL | self.clone(); | +++++ -error[E0425]: cannot find function `default` in this scope +error[E0425]: cannot find function `default` --> $DIR/issue-2356.rs:31:5 | LL | default(); @@ -76,7 +76,7 @@ help: you might have meant to call the associated function LL | Self::default(); | ++++++ -error[E0425]: cannot find function `shave` in this scope +error[E0425]: cannot find function `shave` --> $DIR/issue-2356.rs:41:5 | LL | shave(4); @@ -87,13 +87,13 @@ help: you might have meant to call the associated function LL | Self::shave(4); | ++++++ -error[E0425]: cannot find function `purr` in this scope +error[E0425]: cannot find function `purr` --> $DIR/issue-2356.rs:43:5 | LL | purr(); | ^^^^ not found in this scope -error[E0425]: cannot find function `static_method` in this scope +error[E0425]: cannot find function `static_method` --> $DIR/issue-2356.rs:52:9 | LL | static_method(); @@ -104,25 +104,25 @@ help: consider using the associated function on `Self` LL | Self::static_method(); | ++++++ -error[E0425]: cannot find function `purr` in this scope +error[E0425]: cannot find function `purr` --> $DIR/issue-2356.rs:54:9 | LL | purr(); | ^^^^ not found in this scope -error[E0425]: cannot find function `purr` in this scope +error[E0425]: cannot find function `purr` --> $DIR/issue-2356.rs:56:9 | LL | purr(); | ^^^^ not found in this scope -error[E0425]: cannot find function `purr` in this scope +error[E0425]: cannot find function `purr` --> $DIR/issue-2356.rs:58:9 | LL | purr(); | ^^^^ not found in this scope -error[E0425]: cannot find function `grow_older` in this scope +error[E0425]: cannot find function `grow_older` --> $DIR/issue-2356.rs:72:5 | LL | grow_older(); @@ -133,13 +133,13 @@ help: consider using the associated function on `Self` LL | Self::grow_older(); | ++++++ -error[E0425]: cannot find function `shave` in this scope +error[E0425]: cannot find function `shave` --> $DIR/issue-2356.rs:74:5 | LL | shave(); | ^^^^^ not found in this scope -error[E0425]: cannot find function `purr_louder` in this scope +error[E0425]: cannot find function `purr_louder` --> $DIR/issue-2356.rs:86:5 | LL | purr_louder(); diff --git a/tests/ui/resolve/issue-24968.stderr b/tests/ui/resolve/issue-24968.stderr index 82f5a1d5b57b3..2bf6c063c0b23 100644 --- a/tests/ui/resolve/issue-24968.stderr +++ b/tests/ui/resolve/issue-24968.stderr @@ -1,4 +1,4 @@ -error[E0411]: cannot find type `Self` in this scope +error[E0411]: cannot find type `Self` --> $DIR/issue-24968.rs:3:11 | LL | fn foo(_: Self) { @@ -6,7 +6,7 @@ LL | fn foo(_: Self) { | | | `Self` not allowed in a function -error[E0411]: cannot find type `Self` in this scope +error[E0411]: cannot find type `Self` --> $DIR/issue-24968.rs:8:12 | LL | fn foo2() { @@ -14,7 +14,7 @@ LL | fn foo2() { LL | let x: Self; | ^^^^ `Self` is only available in impls, traits, and type definitions -error[E0411]: cannot find type `Self` in this scope +error[E0411]: cannot find type `Self` --> $DIR/issue-24968.rs:14:5 | LL | type Foo @@ -23,7 +23,7 @@ LL | where LL | Self: Clone, | ^^^^ `Self` is only available in impls, traits, and type definitions -error[E0411]: cannot find type `Self` in this scope +error[E0411]: cannot find type `Self` --> $DIR/issue-24968.rs:18:12 | LL | const FOO: Self = 0; @@ -31,7 +31,7 @@ LL | const FOO: Self = 0; | | | `Self` not allowed in a constant item -error[E0411]: cannot find type `Self` in this scope +error[E0411]: cannot find type `Self` --> $DIR/issue-24968.rs:24:15 | LL | static FOO_S: Self = 0; diff --git a/tests/ui/resolve/issue-26545.rs b/tests/ui/resolve/issue-26545.rs index 5652ee7470605..436cf0e7d906e 100644 --- a/tests/ui/resolve/issue-26545.rs +++ b/tests/ui/resolve/issue-26545.rs @@ -5,7 +5,7 @@ mod foo { mod baz { fn foo() { B(()); - //~^ ERROR cannot find function, tuple struct or tuple variant `B` in this scope [E0425] + //~^ ERROR cannot find function, tuple struct or tuple variant `B` [E0425] } } diff --git a/tests/ui/resolve/issue-26545.stderr b/tests/ui/resolve/issue-26545.stderr index ced19ea1819cd..128e031bc8ae6 100644 --- a/tests/ui/resolve/issue-26545.stderr +++ b/tests/ui/resolve/issue-26545.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find function, tuple struct or tuple variant `B` in this scope +error[E0425]: cannot find function, tuple struct or tuple variant `B` --> $DIR/issue-26545.rs:7:9 | LL | B(()); diff --git a/tests/ui/resolve/issue-31845.rs b/tests/ui/resolve/issue-31845.rs index f6dc11502ba18..33c1711375cf2 100644 --- a/tests/ui/resolve/issue-31845.rs +++ b/tests/ui/resolve/issue-31845.rs @@ -4,7 +4,7 @@ fn f() { fn g() {} mod foo { fn h() { - g(); //~ ERROR cannot find function `g` in this scope + g(); //~ ERROR cannot find function `g` } } } diff --git a/tests/ui/resolve/issue-31845.stderr b/tests/ui/resolve/issue-31845.stderr index e65b911151f07..5dc098cadb758 100644 --- a/tests/ui/resolve/issue-31845.stderr +++ b/tests/ui/resolve/issue-31845.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find function `g` in this scope +error[E0425]: cannot find function `g` --> $DIR/issue-31845.rs:7:12 | LL | g(); diff --git a/tests/ui/resolve/issue-35675.rs b/tests/ui/resolve/issue-35675.rs index 683761667d40a..682089a21a1fb 100644 --- a/tests/ui/resolve/issue-35675.rs +++ b/tests/ui/resolve/issue-35675.rs @@ -5,15 +5,15 @@ enum Fruit { } fn should_return_fruit() -> Apple { - //~^ ERROR cannot find type `Apple` in this scope + //~^ ERROR cannot find type `Apple` Apple(5) - //~^ ERROR cannot find function, tuple struct or tuple variant `Apple` in this scope + //~^ ERROR cannot find function, tuple struct or tuple variant `Apple` } fn should_return_fruit_too() -> Fruit::Apple { //~^ ERROR expected type, found variant `Fruit::Apple` Apple(5) - //~^ ERROR cannot find function, tuple struct or tuple variant `Apple` in this scope + //~^ ERROR cannot find function, tuple struct or tuple variant `Apple` } fn foo() -> Ok { @@ -22,7 +22,7 @@ fn foo() -> Ok { } fn bar() -> Variant3 { - //~^ ERROR cannot find type `Variant3` in this scope + //~^ ERROR cannot find type `Variant3` } fn qux() -> Some { diff --git a/tests/ui/resolve/issue-35675.stderr b/tests/ui/resolve/issue-35675.stderr index 44af65b0768a8..353dc93b8af12 100644 --- a/tests/ui/resolve/issue-35675.stderr +++ b/tests/ui/resolve/issue-35675.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `Apple` in this scope +error[E0412]: cannot find type `Apple` --> $DIR/issue-35675.rs:7:29 | LL | fn should_return_fruit() -> Apple { @@ -9,7 +9,7 @@ help: there is an enum variant `Fruit::Apple`; try using the variant's enum LL | fn should_return_fruit() -> Fruit { | ~~~~~ -error[E0425]: cannot find function, tuple struct or tuple variant `Apple` in this scope +error[E0425]: cannot find function, tuple struct or tuple variant `Apple` --> $DIR/issue-35675.rs:9:5 | LL | Apple(5) @@ -29,7 +29,7 @@ LL | fn should_return_fruit_too() -> Fruit::Apple { | not a type | help: try using the variant's enum: `Fruit` -error[E0425]: cannot find function, tuple struct or tuple variant `Apple` in this scope +error[E0425]: cannot find function, tuple struct or tuple variant `Apple` --> $DIR/issue-35675.rs:15:5 | LL | Apple(5) @@ -49,7 +49,7 @@ LL | fn foo() -> Ok { | not a type | help: try using the variant's enum: `std::result::Result` -error[E0412]: cannot find type `Variant3` in this scope +error[E0412]: cannot find type `Variant3` --> $DIR/issue-35675.rs:24:13 | LL | fn bar() -> Variant3 { diff --git a/tests/ui/resolve/issue-42944.rs b/tests/ui/resolve/issue-42944.rs index 7e439c10b7b84..75b69735e5b97 100644 --- a/tests/ui/resolve/issue-42944.rs +++ b/tests/ui/resolve/issue-42944.rs @@ -14,7 +14,7 @@ mod bar { mod baz { fn foo() { Bx(()); - //~^ ERROR cannot find function, tuple struct or tuple variant `Bx` in this scope [E0425] + //~^ ERROR cannot find function, tuple struct or tuple variant `Bx` [E0425] } } diff --git a/tests/ui/resolve/issue-42944.stderr b/tests/ui/resolve/issue-42944.stderr index 4ffa9402c667e..8ee3179d85d10 100644 --- a/tests/ui/resolve/issue-42944.stderr +++ b/tests/ui/resolve/issue-42944.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find function, tuple struct or tuple variant `Bx` in this scope +error[E0425]: cannot find function, tuple struct or tuple variant `Bx` --> $DIR/issue-42944.rs:16:9 | LL | Bx(()); diff --git a/tests/ui/resolve/issue-49074.rs b/tests/ui/resolve/issue-49074.rs index 752bb345b703e..7b3842ef5e92d 100644 --- a/tests/ui/resolve/issue-49074.rs +++ b/tests/ui/resolve/issue-49074.rs @@ -1,7 +1,7 @@ // Check that unknown attribute error is shown even if there are unresolved macros. #[marco_use] // typo -//~^ ERROR cannot find attribute `marco_use` in this scope +//~^ ERROR cannot find attribute `marco_use` mod foo { macro_rules! bar { () => (); @@ -9,5 +9,5 @@ mod foo { } fn main() { - bar!(); //~ ERROR cannot find macro `bar` in this scope + bar!(); //~ ERROR cannot find macro `bar` } diff --git a/tests/ui/resolve/issue-50599.stderr b/tests/ui/resolve/issue-50599.stderr index 24fb3d580b8fa..29265bca44724 100644 --- a/tests/ui/resolve/issue-50599.stderr +++ b/tests/ui/resolve/issue-50599.stderr @@ -1,8 +1,8 @@ -error[E0425]: cannot find value `LOG10_2` in module `std::f64` +error[E0425]: cannot find value `LOG10_2` --> $DIR/issue-50599.rs:3:48 | LL | const M: usize = (f64::from(N) * std::f64::LOG10_2) as usize; - | ^^^^^^^ not found in `std::f64` + | ^^^^^^^ not found in module `std::f64` | help: consider importing one of these constants | diff --git a/tests/ui/resolve/issue-5099.rs b/tests/ui/resolve/issue-5099.rs index b5abccb4b19f9..a8e7d05550bc9 100644 --- a/tests/ui/resolve/issue-5099.rs +++ b/tests/ui/resolve/issue-5099.rs @@ -1,12 +1,12 @@ trait B { fn a() -> A { - this.a //~ ERROR cannot find value `this` in this scope + this.a //~ ERROR cannot find value `this` } fn b(x: i32) { - this.b(x); //~ ERROR cannot find value `this` in this scope + this.b(x); //~ ERROR cannot find value `this` } fn c() { - let _ = || this.a; //~ ERROR cannot find value `this` in this scope + let _ = || this.a; //~ ERROR cannot find value `this` } } diff --git a/tests/ui/resolve/issue-5099.stderr b/tests/ui/resolve/issue-5099.stderr index e9b2a9c4d4844..62b02b3f6f152 100644 --- a/tests/ui/resolve/issue-5099.stderr +++ b/tests/ui/resolve/issue-5099.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `this` in this scope +error[E0425]: cannot find value `this` --> $DIR/issue-5099.rs:3:9 | LL | this.a @@ -13,7 +13,7 @@ help: if you meant to use `self`, you are also missing a `self` receiver argumen LL | fn a(&self) -> A { | +++++ -error[E0425]: cannot find value `this` in this scope +error[E0425]: cannot find value `this` --> $DIR/issue-5099.rs:6:9 | LL | this.b(x); @@ -28,7 +28,7 @@ help: if you meant to use `self`, you are also missing a `self` receiver argumen LL | fn b(&self, x: i32) { | ++++++ -error[E0425]: cannot find value `this` in this scope +error[E0425]: cannot find value `this` --> $DIR/issue-5099.rs:9:20 | LL | let _ = || this.a; diff --git a/tests/ui/resolve/issue-5927.rs b/tests/ui/resolve/issue-5927.rs index 14f95827be8ea..a483705fe72c8 100644 --- a/tests/ui/resolve/issue-5927.rs +++ b/tests/ui/resolve/issue-5927.rs @@ -1,7 +1,7 @@ fn main() { let z = match 3 { - x(1) => x(1) //~ ERROR cannot find tuple struct or tuple variant `x` in this scope - //~^ ERROR cannot find function `x` in this scope + x(1) => x(1) //~ ERROR cannot find tuple struct or tuple variant `x` + //~^ ERROR cannot find function `x` }; assert!(z == 3); } diff --git a/tests/ui/resolve/issue-5927.stderr b/tests/ui/resolve/issue-5927.stderr index d6cd6853dbdb5..131f94d6d6427 100644 --- a/tests/ui/resolve/issue-5927.stderr +++ b/tests/ui/resolve/issue-5927.stderr @@ -1,10 +1,10 @@ -error[E0531]: cannot find tuple struct or tuple variant `x` in this scope +error[E0531]: cannot find tuple struct or tuple variant `x` --> $DIR/issue-5927.rs:3:9 | LL | x(1) => x(1) | ^ not found in this scope -error[E0425]: cannot find function `x` in this scope +error[E0425]: cannot find function `x` --> $DIR/issue-5927.rs:3:17 | LL | x(1) => x(1) diff --git a/tests/ui/resolve/issue-60057.rs b/tests/ui/resolve/issue-60057.rs index b52343adaee71..be01c2c91d629 100644 --- a/tests/ui/resolve/issue-60057.rs +++ b/tests/ui/resolve/issue-60057.rs @@ -5,13 +5,13 @@ struct A { impl A { fn new(peach: u8) -> A { A { - banana: banana //~ ERROR cannot find value `banana` in this scope + banana: banana //~ ERROR cannot find value `banana` } } fn foo(&self, peach: u8) -> A { A { - banana: banana //~ ERROR cannot find value `banana` in this scope + banana: banana //~ ERROR cannot find value `banana` } } } diff --git a/tests/ui/resolve/issue-60057.stderr b/tests/ui/resolve/issue-60057.stderr index 8737cf770015f..dd90d34054bdb 100644 --- a/tests/ui/resolve/issue-60057.stderr +++ b/tests/ui/resolve/issue-60057.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `banana` in this scope +error[E0425]: cannot find value `banana` --> $DIR/issue-60057.rs:8:21 | LL | banana: u8, @@ -7,7 +7,7 @@ LL | banana: u8, LL | banana: banana | ^^^^^^ -error[E0425]: cannot find value `banana` in this scope +error[E0425]: cannot find value `banana` --> $DIR/issue-60057.rs:14:21 | LL | banana: banana diff --git a/tests/ui/resolve/issue-69401-trait-fn-no-body-ty-local.rs b/tests/ui/resolve/issue-69401-trait-fn-no-body-ty-local.rs index c377ecea94d0c..bbc96c875c66e 100644 --- a/tests/ui/resolve/issue-69401-trait-fn-no-body-ty-local.rs +++ b/tests/ui/resolve/issue-69401-trait-fn-no-body-ty-local.rs @@ -2,5 +2,5 @@ fn main() {} trait Foo { fn fn_with_type_named_same_as_local_in_param(b: b); - //~^ ERROR cannot find type `b` in this scope [E0412] + //~^ ERROR cannot find type `b` [E0412] } diff --git a/tests/ui/resolve/issue-69401-trait-fn-no-body-ty-local.stderr b/tests/ui/resolve/issue-69401-trait-fn-no-body-ty-local.stderr index 60ef13551a17c..78e47163ebfd2 100644 --- a/tests/ui/resolve/issue-69401-trait-fn-no-body-ty-local.stderr +++ b/tests/ui/resolve/issue-69401-trait-fn-no-body-ty-local.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `b` in this scope +error[E0412]: cannot find type `b` --> $DIR/issue-69401-trait-fn-no-body-ty-local.rs:4:53 | LL | fn fn_with_type_named_same_as_local_in_param(b: b); diff --git a/tests/ui/resolve/issue-80079.rs b/tests/ui/resolve/issue-80079.rs index 4dc61c320adce..2c6e431769a5a 100644 --- a/tests/ui/resolve/issue-80079.rs +++ b/tests/ui/resolve/issue-80079.rs @@ -8,5 +8,5 @@ extern crate issue_80079; use issue_80079::public; fn main() { - let _ = Foo; //~ ERROR cannot find value `Foo` in this scope + let _ = Foo; //~ ERROR cannot find value `Foo` } diff --git a/tests/ui/resolve/issue-80079.stderr b/tests/ui/resolve/issue-80079.stderr index e300ee964bee7..4f344d7f5ec98 100644 --- a/tests/ui/resolve/issue-80079.stderr +++ b/tests/ui/resolve/issue-80079.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `Foo` in this scope +error[E0425]: cannot find value `Foo` --> $DIR/issue-80079.rs:11:13 | LL | let _ = Foo; diff --git a/tests/ui/resolve/issue-85348.rs b/tests/ui/resolve/issue-85348.rs index 3a33c19340841..a23793a4fdb90 100644 --- a/tests/ui/resolve/issue-85348.rs +++ b/tests/ui/resolve/issue-85348.rs @@ -1,7 +1,7 @@ // Checks whether shadowing a const parameter leads to an ICE (#85348). impl ArrayWindowsExample { -//~^ ERROR: cannot find type `ArrayWindowsExample` in this scope [E0412] +//~^ ERROR: cannot find type `ArrayWindowsExample` [E0412] fn next() { let mut N; //~^ ERROR: let bindings cannot shadow const parameters [E0530] diff --git a/tests/ui/resolve/issue-85348.stderr b/tests/ui/resolve/issue-85348.stderr index 42b43f825d10c..ce2fc48922d68 100644 --- a/tests/ui/resolve/issue-85348.stderr +++ b/tests/ui/resolve/issue-85348.stderr @@ -7,7 +7,7 @@ LL | impl ArrayWindowsExample { LL | let mut N; | ^ cannot be named the same as a const parameter -error[E0412]: cannot find type `ArrayWindowsExample` in this scope +error[E0412]: cannot find type `ArrayWindowsExample` --> $DIR/issue-85348.rs:3:22 | LL | impl ArrayWindowsExample { diff --git a/tests/ui/resolve/issue-88472.rs b/tests/ui/resolve/issue-88472.rs index 6bf7caeddbfcd..4eff15d941c27 100644 --- a/tests/ui/resolve/issue-88472.rs +++ b/tests/ui/resolve/issue-88472.rs @@ -14,8 +14,8 @@ mod b { use crate::a::*; //~^ WARNING: unused import type Bar = Foo; - //~^ ERROR: cannot find type `Foo` in this scope [E0412] - //~| NOTE: not found in this scope + //~^ ERROR: cannot find type `Foo` [E0412] + //~| NOTE: not found } mod c { @@ -31,8 +31,8 @@ mod c { mod e { type Baz = Eee; - //~^ ERROR: cannot find type `Eee` in this scope [E0412] - //~| NOTE: not found in this scope + //~^ ERROR: cannot find type `Eee` [E0412] + //~| NOTE: not found } fn main() {} diff --git a/tests/ui/resolve/issue-88472.stderr b/tests/ui/resolve/issue-88472.stderr index 8431fc97766f7..dbb0daa06363b 100644 --- a/tests/ui/resolve/issue-88472.stderr +++ b/tests/ui/resolve/issue-88472.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `Foo` in this scope +error[E0412]: cannot find type `Foo` --> $DIR/issue-88472.rs:16:16 | LL | type Bar = Foo; @@ -10,7 +10,7 @@ note: struct `a::Foo` exists but is inaccessible LL | struct Foo; | ^^^^^^^^^^^ not accessible -error[E0412]: cannot find type `Eee` in this scope +error[E0412]: cannot find type `Eee` --> $DIR/issue-88472.rs:33:16 | LL | type Baz = Eee; diff --git a/tests/ui/resolve/issue-90113.rs b/tests/ui/resolve/issue-90113.rs index f6658b45ed1a6..1418a831880f4 100644 --- a/tests/ui/resolve/issue-90113.rs +++ b/tests/ui/resolve/issue-90113.rs @@ -14,7 +14,7 @@ mod alias { fn foo(l: crate::alias::Foo) { match l { - Cons(..) => {} //~ ERROR: cannot find tuple struct or tuple variant `Cons` in this scope + Cons(..) => {} //~ ERROR: cannot find tuple struct or tuple variant `Cons` } } diff --git a/tests/ui/resolve/issue-90113.stderr b/tests/ui/resolve/issue-90113.stderr index d25c67825e3a1..6f36be4a18670 100644 --- a/tests/ui/resolve/issue-90113.stderr +++ b/tests/ui/resolve/issue-90113.stderr @@ -1,4 +1,4 @@ -error[E0531]: cannot find tuple struct or tuple variant `Cons` in this scope +error[E0531]: cannot find tuple struct or tuple variant `Cons` --> $DIR/issue-90113.rs:17:9 | LL | Cons(..) => {} diff --git a/tests/ui/resolve/levenshtein.stderr b/tests/ui/resolve/levenshtein.stderr index cf478210132ed..140d269ab84bc 100644 --- a/tests/ui/resolve/levenshtein.stderr +++ b/tests/ui/resolve/levenshtein.stderr @@ -1,10 +1,10 @@ -error[E0412]: cannot find type `esize` in this scope +error[E0412]: cannot find type `esize` --> $DIR/levenshtein.rs:5:11 | LL | fn foo(c: esize) {} // Misspelled primitive type name. | ^^^^^ help: a builtin type with a similar name exists: `isize` -error[E0412]: cannot find type `Baz` in this scope +error[E0412]: cannot find type `Baz` --> $DIR/levenshtein.rs:10:10 | LL | enum Bar { } @@ -13,7 +13,7 @@ LL | LL | type A = Baz; // Misspelled type name. | ^^^ help: an enum with a similar name exists: `Bar` -error[E0412]: cannot find type `Opiton` in this scope +error[E0412]: cannot find type `Opiton` --> $DIR/levenshtein.rs:12:10 | LL | type B = Opiton; // Misspelled type name from the prelude. @@ -22,13 +22,13 @@ LL | type B = Opiton; // Misspelled type name from the prelude. | = note: similarly named enum `Option` defined here -error[E0412]: cannot find type `Baz` in this scope +error[E0412]: cannot find type `Baz` --> $DIR/levenshtein.rs:16:14 | LL | type A = Baz; // No suggestion here, Bar is not visible | ^^^ not found in this scope -error[E0425]: cannot find value `MAXITEM` in this scope +error[E0425]: cannot find value `MAXITEM` --> $DIR/levenshtein.rs:24:20 | LL | const MAX_ITEM: usize = 10; @@ -37,7 +37,7 @@ LL | const MAX_ITEM: usize = 10; LL | let v = [0u32; MAXITEM]; // Misspelled constant name. | ^^^^^^^ help: a constant with a similar name exists: `MAX_ITEM` -error[E0412]: cannot find type `first` in module `m` +error[E0412]: cannot find type `first` --> $DIR/levenshtein.rs:28:15 | LL | pub struct First; @@ -46,7 +46,7 @@ LL | pub struct First; LL | let b: m::first = m::second; // Misspelled item in module. | ^^^^^ help: a struct with a similar name exists (notice the capitalization): `First` -error[E0425]: cannot find value `second` in module `m` +error[E0425]: cannot find value `second` --> $DIR/levenshtein.rs:28:26 | LL | pub struct Second; @@ -55,7 +55,7 @@ LL | pub struct Second; LL | let b: m::first = m::second; // Misspelled item in module. | ^^^^^^ help: a unit struct with a similar name exists (notice the capitalization): `Second` -error[E0425]: cannot find function `foobar` in this scope +error[E0425]: cannot find function `foobar` --> $DIR/levenshtein.rs:26:5 | LL | fn foo_bar() {} diff --git a/tests/ui/resolve/no-implicit-prelude-nested.rs b/tests/ui/resolve/no-implicit-prelude-nested.rs index c314967da4fb7..06497d4be963e 100644 --- a/tests/ui/resolve/no-implicit-prelude-nested.rs +++ b/tests/ui/resolve/no-implicit-prelude-nested.rs @@ -8,26 +8,26 @@ mod foo { mod baz { struct Test; - impl Add for Test {} //~ ERROR cannot find trait `Add` in this scope + impl Add for Test {} //~ ERROR cannot find trait `Add` impl Clone for Test {} //~ ERROR expected trait, found derive macro `Clone` - impl Iterator for Test {} //~ ERROR cannot find trait `Iterator` in this scope - impl ToString for Test {} //~ ERROR cannot find trait `ToString` in this scope - impl Writer for Test {} //~ ERROR cannot find trait `Writer` in this scope + impl Iterator for Test {} //~ ERROR cannot find trait `Iterator` + impl ToString for Test {} //~ ERROR cannot find trait `ToString` + impl Writer for Test {} //~ ERROR cannot find trait `Writer` fn foo() { - drop(2) //~ ERROR cannot find function `drop` in this scope + drop(2) //~ ERROR cannot find function `drop` } } struct Test; - impl Add for Test {} //~ ERROR cannot find trait `Add` in this scope + impl Add for Test {} //~ ERROR cannot find trait `Add` impl Clone for Test {} //~ ERROR expected trait, found derive macro `Clone` - impl Iterator for Test {} //~ ERROR cannot find trait `Iterator` in this scope - impl ToString for Test {} //~ ERROR cannot find trait `ToString` in this scope - impl Writer for Test {} //~ ERROR cannot find trait `Writer` in this scope + impl Iterator for Test {} //~ ERROR cannot find trait `Iterator` + impl ToString for Test {} //~ ERROR cannot find trait `ToString` + impl Writer for Test {} //~ ERROR cannot find trait `Writer` fn foo() { - drop(2) //~ ERROR cannot find function `drop` in this scope + drop(2) //~ ERROR cannot find function `drop` } } @@ -35,14 +35,14 @@ fn qux() { #[no_implicit_prelude] mod qux_inner { struct Test; - impl Add for Test {} //~ ERROR cannot find trait `Add` in this scope + impl Add for Test {} //~ ERROR cannot find trait `Add` impl Clone for Test {} //~ ERROR expected trait, found derive macro `Clone` - impl Iterator for Test {} //~ ERROR cannot find trait `Iterator` in this scope - impl ToString for Test {} //~ ERROR cannot find trait `ToString` in this scope - impl Writer for Test {} //~ ERROR cannot find trait `Writer` in this scope + impl Iterator for Test {} //~ ERROR cannot find trait `Iterator` + impl ToString for Test {} //~ ERROR cannot find trait `ToString` + impl Writer for Test {} //~ ERROR cannot find trait `Writer` fn foo() { - drop(2) //~ ERROR cannot find function `drop` in this scope + drop(2) //~ ERROR cannot find function `drop` } } } diff --git a/tests/ui/resolve/no-implicit-prelude-nested.stderr b/tests/ui/resolve/no-implicit-prelude-nested.stderr index 49cf72bfee2d6..e3e338cae9e73 100644 --- a/tests/ui/resolve/no-implicit-prelude-nested.stderr +++ b/tests/ui/resolve/no-implicit-prelude-nested.stderr @@ -1,4 +1,4 @@ -error[E0405]: cannot find trait `Add` in this scope +error[E0405]: cannot find trait `Add` --> $DIR/no-implicit-prelude-nested.rs:11:14 | LL | impl Add for Test {} @@ -20,7 +20,7 @@ help: consider importing this trait instead LL + use std::clone::Clone; | -error[E0405]: cannot find trait `Iterator` in this scope +error[E0405]: cannot find trait `Iterator` --> $DIR/no-implicit-prelude-nested.rs:13:14 | LL | impl Iterator for Test {} @@ -31,7 +31,7 @@ help: consider importing this trait LL + use std::iter::Iterator; | -error[E0405]: cannot find trait `ToString` in this scope +error[E0405]: cannot find trait `ToString` --> $DIR/no-implicit-prelude-nested.rs:14:14 | LL | impl ToString for Test {} @@ -42,13 +42,13 @@ help: consider importing this trait LL + use std::string::ToString; | -error[E0405]: cannot find trait `Writer` in this scope +error[E0405]: cannot find trait `Writer` --> $DIR/no-implicit-prelude-nested.rs:15:14 | LL | impl Writer for Test {} | ^^^^^^ not found in this scope -error[E0425]: cannot find function `drop` in this scope +error[E0425]: cannot find function `drop` --> $DIR/no-implicit-prelude-nested.rs:18:13 | LL | drop(2) @@ -59,7 +59,7 @@ help: consider importing this function LL + use std::mem::drop; | -error[E0405]: cannot find trait `Add` in this scope +error[E0405]: cannot find trait `Add` --> $DIR/no-implicit-prelude-nested.rs:23:10 | LL | impl Add for Test {} @@ -81,7 +81,7 @@ help: consider importing this trait instead LL + use std::clone::Clone; | -error[E0405]: cannot find trait `Iterator` in this scope +error[E0405]: cannot find trait `Iterator` --> $DIR/no-implicit-prelude-nested.rs:25:10 | LL | impl Iterator for Test {} @@ -92,7 +92,7 @@ help: consider importing this trait LL + use std::iter::Iterator; | -error[E0405]: cannot find trait `ToString` in this scope +error[E0405]: cannot find trait `ToString` --> $DIR/no-implicit-prelude-nested.rs:26:10 | LL | impl ToString for Test {} @@ -103,13 +103,13 @@ help: consider importing this trait LL + use std::string::ToString; | -error[E0405]: cannot find trait `Writer` in this scope +error[E0405]: cannot find trait `Writer` --> $DIR/no-implicit-prelude-nested.rs:27:10 | LL | impl Writer for Test {} | ^^^^^^ not found in this scope -error[E0425]: cannot find function `drop` in this scope +error[E0425]: cannot find function `drop` --> $DIR/no-implicit-prelude-nested.rs:30:9 | LL | drop(2) @@ -120,7 +120,7 @@ help: consider importing this function LL + use std::mem::drop; | -error[E0405]: cannot find trait `Add` in this scope +error[E0405]: cannot find trait `Add` --> $DIR/no-implicit-prelude-nested.rs:38:14 | LL | impl Add for Test {} @@ -142,7 +142,7 @@ help: consider importing this trait instead LL + use std::clone::Clone; | -error[E0405]: cannot find trait `Iterator` in this scope +error[E0405]: cannot find trait `Iterator` --> $DIR/no-implicit-prelude-nested.rs:40:14 | LL | impl Iterator for Test {} @@ -153,7 +153,7 @@ help: consider importing this trait LL + use std::iter::Iterator; | -error[E0405]: cannot find trait `ToString` in this scope +error[E0405]: cannot find trait `ToString` --> $DIR/no-implicit-prelude-nested.rs:41:14 | LL | impl ToString for Test {} @@ -164,13 +164,13 @@ help: consider importing this trait LL + use std::string::ToString; | -error[E0405]: cannot find trait `Writer` in this scope +error[E0405]: cannot find trait `Writer` --> $DIR/no-implicit-prelude-nested.rs:42:14 | LL | impl Writer for Test {} | ^^^^^^ not found in this scope -error[E0425]: cannot find function `drop` in this scope +error[E0425]: cannot find function `drop` --> $DIR/no-implicit-prelude-nested.rs:45:13 | LL | drop(2) diff --git a/tests/ui/resolve/no-implicit-prelude.rs b/tests/ui/resolve/no-implicit-prelude.rs index 4b0ca4d524e62..3bf8d92142956 100644 --- a/tests/ui/resolve/no-implicit-prelude.rs +++ b/tests/ui/resolve/no-implicit-prelude.rs @@ -7,12 +7,12 @@ // fail with the same error message). struct Test; -impl Add for Test {} //~ ERROR cannot find trait `Add` in this scope +impl Add for Test {} //~ ERROR cannot find trait `Add` impl Clone for Test {} //~ ERROR expected trait, found derive macro `Clone` -impl Iterator for Test {} //~ ERROR cannot find trait `Iterator` in this scope -impl ToString for Test {} //~ ERROR cannot find trait `ToString` in this scope -impl Writer for Test {} //~ ERROR cannot find trait `Writer` in this scope +impl Iterator for Test {} //~ ERROR cannot find trait `Iterator` +impl ToString for Test {} //~ ERROR cannot find trait `ToString` +impl Writer for Test {} //~ ERROR cannot find trait `Writer` fn main() { - drop(2) //~ ERROR cannot find function `drop` in this scope + drop(2) //~ ERROR cannot find function `drop` } diff --git a/tests/ui/resolve/no-implicit-prelude.stderr b/tests/ui/resolve/no-implicit-prelude.stderr index 5a759743f7258..ee933ae2dd60a 100644 --- a/tests/ui/resolve/no-implicit-prelude.stderr +++ b/tests/ui/resolve/no-implicit-prelude.stderr @@ -1,4 +1,4 @@ -error[E0405]: cannot find trait `Add` in this scope +error[E0405]: cannot find trait `Add` --> $DIR/no-implicit-prelude.rs:10:6 | LL | impl Add for Test {} @@ -20,7 +20,7 @@ help: consider importing this trait instead LL + use std::clone::Clone; | -error[E0405]: cannot find trait `Iterator` in this scope +error[E0405]: cannot find trait `Iterator` --> $DIR/no-implicit-prelude.rs:12:6 | LL | impl Iterator for Test {} @@ -31,7 +31,7 @@ help: consider importing this trait LL + use std::iter::Iterator; | -error[E0405]: cannot find trait `ToString` in this scope +error[E0405]: cannot find trait `ToString` --> $DIR/no-implicit-prelude.rs:13:6 | LL | impl ToString for Test {} @@ -42,13 +42,13 @@ help: consider importing this trait LL + use std::string::ToString; | -error[E0405]: cannot find trait `Writer` in this scope +error[E0405]: cannot find trait `Writer` --> $DIR/no-implicit-prelude.rs:14:6 | LL | impl Writer for Test {} | ^^^^^^ not found in this scope -error[E0425]: cannot find function `drop` in this scope +error[E0425]: cannot find function `drop` --> $DIR/no-implicit-prelude.rs:17:5 | LL | drop(2) diff --git a/tests/ui/resolve/privacy-enum-ctor.rs b/tests/ui/resolve/privacy-enum-ctor.rs index f0d2cf8c04e90..8b160257680ca 100644 --- a/tests/ui/resolve/privacy-enum-ctor.rs +++ b/tests/ui/resolve/privacy-enum-ctor.rs @@ -55,17 +55,17 @@ fn main() { let _: E = E::Unit(); //~^ ERROR expected function, found enum variant `E::Unit` let _: Z = m::n::Z; - //~^ ERROR cannot find type `Z` in this scope + //~^ ERROR cannot find type `Z` //~| ERROR expected value, found enum `m::n::Z` //~| ERROR enum `Z` is private let _: Z = m::n::Z::Fn; - //~^ ERROR cannot find type `Z` in this scope + //~^ ERROR cannot find type `Z` //~| ERROR enum `Z` is private let _: Z = m::n::Z::Struct; - //~^ ERROR cannot find type `Z` in this scope + //~^ ERROR cannot find type `Z` //~| ERROR expected value, found struct variant `m::n::Z::Struct` //~| ERROR enum `Z` is private let _: Z = m::n::Z::Unit {}; - //~^ ERROR cannot find type `Z` in this scope + //~^ ERROR cannot find type `Z` //~| ERROR enum `Z` is private } diff --git a/tests/ui/resolve/privacy-enum-ctor.stderr b/tests/ui/resolve/privacy-enum-ctor.stderr index ee3aecddcc342..ea0e99b90e4cc 100644 --- a/tests/ui/resolve/privacy-enum-ctor.stderr +++ b/tests/ui/resolve/privacy-enum-ctor.stderr @@ -134,7 +134,7 @@ LL + use std::f32::consts::E; LL + use std::f64::consts::E; | -error[E0412]: cannot find type `Z` in this scope +error[E0412]: cannot find type `Z` --> $DIR/privacy-enum-ctor.rs:57:12 | LL | pub enum E { @@ -175,7 +175,7 @@ help: alternatively, the following enum variant is available LL | let _: Z = (m::Z::Fn(/* fields */)); | ~~~~~~~~~~~~~~~~~~~~~~~~ -error[E0412]: cannot find type `Z` in this scope +error[E0412]: cannot find type `Z` --> $DIR/privacy-enum-ctor.rs:61:12 | LL | pub enum E { @@ -190,7 +190,7 @@ note: enum `m::Z` exists but is inaccessible LL | pub(in m) enum Z { | ^^^^^^^^^^^^^^^^ not accessible -error[E0412]: cannot find type `Z` in this scope +error[E0412]: cannot find type `Z` --> $DIR/privacy-enum-ctor.rs:64:12 | LL | pub enum E { @@ -205,7 +205,7 @@ note: enum `m::Z` exists but is inaccessible LL | pub(in m) enum Z { | ^^^^^^^^^^^^^^^^ not accessible -error[E0412]: cannot find type `Z` in this scope +error[E0412]: cannot find type `Z` --> $DIR/privacy-enum-ctor.rs:68:12 | LL | pub enum E { diff --git a/tests/ui/resolve/raw-ident-in-path.rs b/tests/ui/resolve/raw-ident-in-path.rs index 7f1163bebde67..05d18a9f1c679 100644 --- a/tests/ui/resolve/raw-ident-in-path.rs +++ b/tests/ui/resolve/raw-ident-in-path.rs @@ -1,5 +1,5 @@ // Regression test for issue #63882. -type A = crate::r#break; //~ ERROR cannot find type `r#break` in the crate root +type A = crate::r#break; //~ ERROR cannot find type `r#break` fn main() {} diff --git a/tests/ui/resolve/raw-ident-in-path.stderr b/tests/ui/resolve/raw-ident-in-path.stderr index 7d2aa69113638..d1bad7ea1844f 100644 --- a/tests/ui/resolve/raw-ident-in-path.stderr +++ b/tests/ui/resolve/raw-ident-in-path.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `r#break` in the crate root +error[E0412]: cannot find type `r#break` --> $DIR/raw-ident-in-path.rs:3:17 | LL | type A = crate::r#break; diff --git a/tests/ui/resolve/resolve-assoc-suggestions.stderr b/tests/ui/resolve/resolve-assoc-suggestions.stderr index 3d9d4ffaa10c8..401d7dc5beb54 100644 --- a/tests/ui/resolve/resolve-assoc-suggestions.stderr +++ b/tests/ui/resolve/resolve-assoc-suggestions.stderr @@ -1,16 +1,16 @@ -error[E0412]: cannot find type `field` in this scope +error[E0412]: cannot find type `field` --> $DIR/resolve-assoc-suggestions.rs:16:16 | LL | let _: field; | ^^^^^ not found in this scope -error[E0531]: cannot find tuple struct or tuple variant `field` in this scope +error[E0531]: cannot find tuple struct or tuple variant `field` --> $DIR/resolve-assoc-suggestions.rs:18:13 | LL | let field(..); | ^^^^^ not found in this scope -error[E0425]: cannot find value `field` in this scope +error[E0425]: cannot find value `field` --> $DIR/resolve-assoc-suggestions.rs:20:9 | LL | field; @@ -21,7 +21,7 @@ help: you might have meant to use the available field LL | self.field; | +++++ -error[E0412]: cannot find type `Type` in this scope +error[E0412]: cannot find type `Type` --> $DIR/resolve-assoc-suggestions.rs:23:16 | LL | let _: Type; @@ -32,31 +32,31 @@ help: you might have meant to use the associated type LL | let _: Self::Type; | ++++++ -error[E0531]: cannot find tuple struct or tuple variant `Type` in this scope +error[E0531]: cannot find tuple struct or tuple variant `Type` --> $DIR/resolve-assoc-suggestions.rs:25:13 | LL | let Type(..); | ^^^^ not found in this scope -error[E0425]: cannot find value `Type` in this scope +error[E0425]: cannot find value `Type` --> $DIR/resolve-assoc-suggestions.rs:27:9 | LL | Type; | ^^^^ not found in this scope -error[E0412]: cannot find type `method` in this scope +error[E0412]: cannot find type `method` --> $DIR/resolve-assoc-suggestions.rs:30:16 | LL | let _: method; | ^^^^^^ not found in this scope -error[E0531]: cannot find tuple struct or tuple variant `method` in this scope +error[E0531]: cannot find tuple struct or tuple variant `method` --> $DIR/resolve-assoc-suggestions.rs:32:13 | LL | let method(..); | ^^^^^^ not found in this scope -error[E0425]: cannot find value `method` in this scope +error[E0425]: cannot find value `method` --> $DIR/resolve-assoc-suggestions.rs:34:9 | LL | method; diff --git a/tests/ui/resolve/resolve-primitive-fallback.rs b/tests/ui/resolve/resolve-primitive-fallback.rs index 05cabd9e3cd01..f4d06ec208688 100644 --- a/tests/ui/resolve/resolve-primitive-fallback.rs +++ b/tests/ui/resolve/resolve-primitive-fallback.rs @@ -6,5 +6,5 @@ fn main() { // Make sure primitive type fallback doesn't work with global paths let _: ::u8; - //~^ ERROR cannot find type `u8` in the crate root + //~^ ERROR cannot find type `u8` } diff --git a/tests/ui/resolve/resolve-primitive-fallback.stderr b/tests/ui/resolve/resolve-primitive-fallback.stderr index d0583966459be..e2a982880e7bb 100644 --- a/tests/ui/resolve/resolve-primitive-fallback.stderr +++ b/tests/ui/resolve/resolve-primitive-fallback.stderr @@ -4,7 +4,7 @@ error[E0423]: expected value, found builtin type `u16` LL | std::mem::size_of(u16); | ^^^ not a value -error[E0412]: cannot find type `u8` in the crate root +error[E0412]: cannot find type `u8` --> $DIR/resolve-primitive-fallback.rs:8:14 | LL | let _: ::u8; diff --git a/tests/ui/resolve/resolve-self-in-impl-2.rs b/tests/ui/resolve/resolve-self-in-impl-2.rs index f586760c8b096..7ce4c5ededad3 100644 --- a/tests/ui/resolve/resolve-self-in-impl-2.rs +++ b/tests/ui/resolve/resolve-self-in-impl-2.rs @@ -2,6 +2,6 @@ struct S(T); trait Tr {} impl Self for S {} //~ ERROR expected trait, found self type `Self` -impl Self::N for S {} //~ ERROR cannot find trait `N` in `Self` +impl Self::N for S {} //~ ERROR cannot find trait `N` fn main() {} diff --git a/tests/ui/resolve/resolve-self-in-impl-2.stderr b/tests/ui/resolve/resolve-self-in-impl-2.stderr index 3791fe90a6bae..3627bf1d45227 100644 --- a/tests/ui/resolve/resolve-self-in-impl-2.stderr +++ b/tests/ui/resolve/resolve-self-in-impl-2.stderr @@ -4,7 +4,7 @@ error[E0411]: expected trait, found self type `Self` LL | impl Self for S {} | ^^^^ `Self` is only available in impls, traits, and type definitions -error[E0405]: cannot find trait `N` in `Self` +error[E0405]: cannot find trait `N` --> $DIR/resolve-self-in-impl-2.rs:5:12 | LL | impl Self::N for S {} diff --git a/tests/ui/resolve/resolve-speculative-adjustment.stderr b/tests/ui/resolve/resolve-speculative-adjustment.stderr index fb15472bdae8d..bea202013863b 100644 --- a/tests/ui/resolve/resolve-speculative-adjustment.stderr +++ b/tests/ui/resolve/resolve-speculative-adjustment.stderr @@ -1,10 +1,10 @@ -error[E0425]: cannot find value `field` in this scope +error[E0425]: cannot find value `field` --> $DIR/resolve-speculative-adjustment.rs:17:13 | LL | field; | ^^^^^ not found in this scope -error[E0425]: cannot find value `field` in this scope +error[E0425]: cannot find value `field` --> $DIR/resolve-speculative-adjustment.rs:23:9 | LL | field; @@ -15,7 +15,7 @@ help: you might have meant to use the available field LL | self.field; | +++++ -error[E0425]: cannot find function `method` in this scope +error[E0425]: cannot find function `method` --> $DIR/resolve-speculative-adjustment.rs:25:9 | LL | method(); @@ -26,7 +26,7 @@ help: you might have meant to call the method LL | self.method(); | +++++ -error[E0425]: cannot find function `method` in this scope +error[E0425]: cannot find function `method` --> $DIR/resolve-speculative-adjustment.rs:19:13 | LL | method(); diff --git a/tests/ui/resolve/resolve-unknown-trait.rs b/tests/ui/resolve/resolve-unknown-trait.rs index 290893bbbec40..b8b41279bef00 100644 --- a/tests/ui/resolve/resolve-unknown-trait.rs +++ b/tests/ui/resolve/resolve-unknown-trait.rs @@ -1,10 +1,10 @@ trait NewTrait : SomeNonExistentTrait {} -//~^ ERROR cannot find trait `SomeNonExistentTrait` in this scope +//~^ ERROR cannot find trait `SomeNonExistentTrait` impl SomeNonExistentTrait for isize {} -//~^ ERROR cannot find trait `SomeNonExistentTrait` in this scope +//~^ ERROR cannot find trait `SomeNonExistentTrait` fn f() {} -//~^ ERROR cannot find trait `SomeNonExistentTrait` in this scope +//~^ ERROR cannot find trait `SomeNonExistentTrait` fn main() {} diff --git a/tests/ui/resolve/resolve-unknown-trait.stderr b/tests/ui/resolve/resolve-unknown-trait.stderr index e19cfe617d4f2..e27b954efbcd6 100644 --- a/tests/ui/resolve/resolve-unknown-trait.stderr +++ b/tests/ui/resolve/resolve-unknown-trait.stderr @@ -1,16 +1,16 @@ -error[E0405]: cannot find trait `SomeNonExistentTrait` in this scope +error[E0405]: cannot find trait `SomeNonExistentTrait` --> $DIR/resolve-unknown-trait.rs:1:18 | LL | trait NewTrait : SomeNonExistentTrait {} | ^^^^^^^^^^^^^^^^^^^^ not found in this scope -error[E0405]: cannot find trait `SomeNonExistentTrait` in this scope +error[E0405]: cannot find trait `SomeNonExistentTrait` --> $DIR/resolve-unknown-trait.rs:4:6 | LL | impl SomeNonExistentTrait for isize {} | ^^^^^^^^^^^^^^^^^^^^ not found in this scope -error[E0405]: cannot find trait `SomeNonExistentTrait` in this scope +error[E0405]: cannot find trait `SomeNonExistentTrait` --> $DIR/resolve-unknown-trait.rs:7:8 | LL | fn f() {} diff --git a/tests/ui/resolve/suggest-import-without-clobbering-attrs.fixed b/tests/ui/resolve/suggest-import-without-clobbering-attrs.fixed index 607c9af492713..ac8a4d283c827 100644 --- a/tests/ui/resolve/suggest-import-without-clobbering-attrs.fixed +++ b/tests/ui/resolve/suggest-import-without-clobbering-attrs.fixed @@ -12,5 +12,5 @@ mod y { fn main() { z(); - //~^ ERROR cannot find function `z` in this scope + //~^ ERROR cannot find function `z` } diff --git a/tests/ui/resolve/suggest-import-without-clobbering-attrs.rs b/tests/ui/resolve/suggest-import-without-clobbering-attrs.rs index 6cc53fb108658..b879183c6549a 100644 --- a/tests/ui/resolve/suggest-import-without-clobbering-attrs.rs +++ b/tests/ui/resolve/suggest-import-without-clobbering-attrs.rs @@ -11,5 +11,5 @@ mod y { fn main() { z(); - //~^ ERROR cannot find function `z` in this scope + //~^ ERROR cannot find function `z` } diff --git a/tests/ui/resolve/suggest-import-without-clobbering-attrs.stderr b/tests/ui/resolve/suggest-import-without-clobbering-attrs.stderr index de65d695dd23d..ce457c6c7247d 100644 --- a/tests/ui/resolve/suggest-import-without-clobbering-attrs.stderr +++ b/tests/ui/resolve/suggest-import-without-clobbering-attrs.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find function `z` in this scope +error[E0425]: cannot find function `z` --> $DIR/suggest-import-without-clobbering-attrs.rs:13:5 | LL | z(); diff --git a/tests/ui/resolve/typo-suggestion-for-variable-with-name-similar-to-struct-field.rs b/tests/ui/resolve/typo-suggestion-for-variable-with-name-similar-to-struct-field.rs index ecd3f58811904..acc4b08a1fa62 100644 --- a/tests/ui/resolve/typo-suggestion-for-variable-with-name-similar-to-struct-field.rs +++ b/tests/ui/resolve/typo-suggestion-for-variable-with-name-similar-to-struct-field.rs @@ -4,15 +4,15 @@ struct A { impl A { fn new(cofig: String) -> Self { - Self { config } //~ Error cannot find value `config` in this scope + Self { config } //~ Error cannot find value `config` } fn do_something(cofig: String) { - println!("{config}"); //~ Error cannot find value `config` in this scope + println!("{config}"); //~ Error cannot find value `config` } fn self_is_available(self, cofig: String) { - println!("{config}"); //~ Error cannot find value `config` in this scope + println!("{config}"); //~ Error cannot find value `config` } } @@ -33,9 +33,9 @@ impl B for Box { bah; //~^ ERROR cannot find value `bah` BAR; - //~^ ERROR cannot find value `BAR` in this scope + //~^ ERROR cannot find value `BAR` let foo: Baz = "".to_string(); - //~^ ERROR cannot find type `Baz` in this scope + //~^ ERROR cannot find type `Baz` } } diff --git a/tests/ui/resolve/typo-suggestion-for-variable-with-name-similar-to-struct-field.stderr b/tests/ui/resolve/typo-suggestion-for-variable-with-name-similar-to-struct-field.stderr index 5662021a2d523..8b4881c1618cc 100644 --- a/tests/ui/resolve/typo-suggestion-for-variable-with-name-similar-to-struct-field.stderr +++ b/tests/ui/resolve/typo-suggestion-for-variable-with-name-similar-to-struct-field.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `config` in this scope +error[E0425]: cannot find value `config` --> $DIR/typo-suggestion-for-variable-with-name-similar-to-struct-field.rs:7:16 | LL | config: String, @@ -7,7 +7,7 @@ LL | config: String, LL | Self { config } | ^^^^^^ help: a local variable with a similar name exists: `cofig` -error[E0425]: cannot find value `config` in this scope +error[E0425]: cannot find value `config` --> $DIR/typo-suggestion-for-variable-with-name-similar-to-struct-field.rs:11:20 | LL | config: String, @@ -16,7 +16,7 @@ LL | config: String, LL | println!("{config}"); | ^^^^^^ help: a local variable with a similar name exists: `cofig` -error[E0425]: cannot find value `config` in this scope +error[E0425]: cannot find value `config` --> $DIR/typo-suggestion-for-variable-with-name-similar-to-struct-field.rs:15:20 | LL | println!("{config}"); @@ -31,7 +31,7 @@ help: a local variable with a similar name exists LL | println!("{cofig}"); | ~~~~~ -error[E0425]: cannot find value `bah` in this scope +error[E0425]: cannot find value `bah` --> $DIR/typo-suggestion-for-variable-with-name-similar-to-struct-field.rs:33:9 | LL | bah; @@ -49,7 +49,7 @@ help: a function with a similar name exists LL | ba; | ~~ -error[E0425]: cannot find value `BAR` in this scope +error[E0425]: cannot find value `BAR` --> $DIR/typo-suggestion-for-variable-with-name-similar-to-struct-field.rs:35:9 | LL | BAR; @@ -67,7 +67,7 @@ help: a constant with a similar name exists LL | BARR; | ~~~~ -error[E0412]: cannot find type `Baz` in this scope +error[E0412]: cannot find type `Baz` --> $DIR/typo-suggestion-for-variable-with-name-similar-to-struct-field.rs:37:18 | LL | let foo: Baz = "".to_string(); @@ -85,7 +85,7 @@ help: a type alias with a similar name exists LL | let foo: Bar = "".to_string(); | ~~~ -error[E0425]: cannot find function `baz` in this scope +error[E0425]: cannot find function `baz` --> $DIR/typo-suggestion-for-variable-with-name-similar-to-struct-field.rs:31:9 | LL | baz(); diff --git a/tests/ui/resolve/typo-suggestion-named-underscore.rs b/tests/ui/resolve/typo-suggestion-named-underscore.rs index a2b05db035150..e39369ffcccae 100644 --- a/tests/ui/resolve/typo-suggestion-named-underscore.rs +++ b/tests/ui/resolve/typo-suggestion-named-underscore.rs @@ -2,7 +2,7 @@ const _: () = (); fn main() { a // Shouldn't suggest underscore - //~^ ERROR: cannot find value `a` in this scope + //~^ ERROR: cannot find value `a` } trait Unknown {} @@ -11,4 +11,4 @@ trait Unknown {} use Unknown as _; fn foo(x: T) {} // Shouldn't suggest underscore -//~^ ERROR: cannot find trait `A` in this scope +//~^ ERROR: cannot find trait `A` diff --git a/tests/ui/resolve/typo-suggestion-named-underscore.stderr b/tests/ui/resolve/typo-suggestion-named-underscore.stderr index 65d1b084a3a7b..ed7fb40d1196d 100644 --- a/tests/ui/resolve/typo-suggestion-named-underscore.stderr +++ b/tests/ui/resolve/typo-suggestion-named-underscore.stderr @@ -1,10 +1,10 @@ -error[E0425]: cannot find value `a` in this scope +error[E0425]: cannot find value `a` --> $DIR/typo-suggestion-named-underscore.rs:4:5 | LL | a // Shouldn't suggest underscore | ^ not found in this scope -error[E0405]: cannot find trait `A` in this scope +error[E0405]: cannot find trait `A` --> $DIR/typo-suggestion-named-underscore.rs:13:11 | LL | fn foo(x: T) {} // Shouldn't suggest underscore diff --git a/tests/ui/resolve/unboxed-closure-sugar-nonexistent-trait.stderr b/tests/ui/resolve/unboxed-closure-sugar-nonexistent-trait.stderr index 8addc0303fb91..2d2d0fd4b8e0b 100644 --- a/tests/ui/resolve/unboxed-closure-sugar-nonexistent-trait.stderr +++ b/tests/ui/resolve/unboxed-closure-sugar-nonexistent-trait.stderr @@ -1,4 +1,4 @@ -error[E0405]: cannot find trait `Nonexist` in this scope +error[E0405]: cannot find trait `Nonexist` --> $DIR/unboxed-closure-sugar-nonexistent-trait.rs:1:8 | LL | fn f isize>(x: F) {} diff --git a/tests/ui/resolve/unresolved_static_type_field.rs b/tests/ui/resolve/unresolved_static_type_field.rs index 494ad083f1a87..784926e267795 100644 --- a/tests/ui/resolve/unresolved_static_type_field.rs +++ b/tests/ui/resolve/unresolved_static_type_field.rs @@ -7,7 +7,7 @@ struct Foo { impl Foo { fn bar() { f(cx); - //~^ ERROR cannot find value `cx` in this scope + //~^ ERROR cannot find value `cx` } } diff --git a/tests/ui/resolve/unresolved_static_type_field.stderr b/tests/ui/resolve/unresolved_static_type_field.stderr index f039eef2e06b9..9bcf3af02c0e4 100644 --- a/tests/ui/resolve/unresolved_static_type_field.stderr +++ b/tests/ui/resolve/unresolved_static_type_field.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `cx` in this scope +error[E0425]: cannot find value `cx` --> $DIR/unresolved_static_type_field.rs:9:11 | LL | cx: bool, diff --git a/tests/ui/resolve/use_suggestion.stderr b/tests/ui/resolve/use_suggestion.stderr index 1155f5caa1739..1d8acaf67fac9 100644 --- a/tests/ui/resolve/use_suggestion.stderr +++ b/tests/ui/resolve/use_suggestion.stderr @@ -9,7 +9,7 @@ help: consider importing this struct LL + use std::collections::HashMap; | -error[E0412]: cannot find type `HashMap` in this scope +error[E0412]: cannot find type `HashMap` --> $DIR/use_suggestion.rs:5:13 | LL | let y1: HashMap; @@ -20,7 +20,7 @@ help: consider importing this struct LL + use std::collections::HashMap; | -error[E0412]: cannot find type `GooMap` in this scope +error[E0412]: cannot find type `GooMap` --> $DIR/use_suggestion.rs:6:13 | LL | let y2: GooMap; diff --git a/tests/ui/resolve/use_suggestion_placement.stderr b/tests/ui/resolve/use_suggestion_placement.stderr index 3611f9ae6b4ed..08bd4269649ed 100644 --- a/tests/ui/resolve/use_suggestion_placement.stderr +++ b/tests/ui/resolve/use_suggestion_placement.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `Path` in this scope +error[E0412]: cannot find type `Path` --> $DIR/use_suggestion_placement.rs:18:16 | LL | type Bar = Path; @@ -9,7 +9,7 @@ help: consider importing this struct LL + use std::path::Path; | -error[E0425]: cannot find value `A` in this scope +error[E0425]: cannot find value `A` --> $DIR/use_suggestion_placement.rs:23:13 | LL | let _ = A; @@ -20,7 +20,7 @@ help: consider importing this constant LL + use m::A; | -error[E0412]: cannot find type `HashMap` in this scope +error[E0412]: cannot find type `HashMap` --> $DIR/use_suggestion_placement.rs:28:23 | LL | type Dict = HashMap; diff --git a/tests/ui/resolve/visibility-indeterminate.rs b/tests/ui/resolve/visibility-indeterminate.rs index 17e5fec4701b9..9bb9af404e0cc 100644 --- a/tests/ui/resolve/visibility-indeterminate.rs +++ b/tests/ui/resolve/visibility-indeterminate.rs @@ -1,6 +1,6 @@ //@ edition:2018 -foo!(); //~ ERROR cannot find macro `foo` in this scope +foo!(); //~ ERROR cannot find macro `foo` pub(in ::bar) struct Baz {} //~ ERROR cannot determine resolution for the visibility diff --git a/tests/ui/rfcs/rfc-2294-if-let-guard/bindings.stderr b/tests/ui/rfcs/rfc-2294-if-let-guard/bindings.stderr index 2463b7f3eacc7..5aa1888f8cc5d 100644 --- a/tests/ui/rfcs/rfc-2294-if-let-guard/bindings.stderr +++ b/tests/ui/rfcs/rfc-2294-if-let-guard/bindings.stderr @@ -1,10 +1,10 @@ -error[E0425]: cannot find value `y` in this scope +error[E0425]: cannot find value `y` --> $DIR/bindings.rs:6:14 | LL | _ => y, | ^ not found in this scope -error[E0425]: cannot find value `y` in this scope +error[E0425]: cannot find value `y` --> $DIR/bindings.rs:8:5 | LL | y diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-120503-async-const-method.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-120503-async-const-method.stderr index 1f309e1e85446..460797c6fd020 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-120503-async-const-method.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/ice-120503-async-const-method.stderr @@ -60,7 +60,7 @@ error: using `#![feature(effects)]` without enabling next trait solver globally = note: the next trait solver must be enabled globally for the effects feature to work correctly = help: use `-Znext-solver` to enable -error[E0425]: cannot find function `main8` in this scope +error[E0425]: cannot find function `main8` --> $DIR/ice-120503-async-const-method.rs:13:9 | LL | main8().await; diff --git a/tests/ui/rmeta/rmeta.rs b/tests/ui/rmeta/rmeta.rs index 4d8cff8e60e8c..089bcfb5f6424 100644 --- a/tests/ui/rmeta/rmeta.rs +++ b/tests/ui/rmeta/rmeta.rs @@ -4,5 +4,5 @@ // Check that building a metadata crate finds an error. fn main() { - let _ = Foo; //~ ERROR cannot find value `Foo` in this scope + let _ = Foo; //~ ERROR cannot find value `Foo` } diff --git a/tests/ui/rmeta/rmeta.stderr b/tests/ui/rmeta/rmeta.stderr index 85452ea41d313..14048dc899826 100644 --- a/tests/ui/rmeta/rmeta.stderr +++ b/tests/ui/rmeta/rmeta.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `Foo` in this scope +error[E0425]: cannot find value `Foo` --> $DIR/rmeta.rs:7:13 | LL | let _ = Foo; diff --git a/tests/ui/rust-2018/issue-52202-use-suggestions.rs b/tests/ui/rust-2018/issue-52202-use-suggestions.rs index ce9a5edf007f9..0392df4678a44 100644 --- a/tests/ui/rust-2018/issue-52202-use-suggestions.rs +++ b/tests/ui/rust-2018/issue-52202-use-suggestions.rs @@ -9,5 +9,5 @@ mod plumbing { fn main() { let _d = Drain {}; - //~^ ERROR cannot find struct, variant or union type `Drain` in this scope + //~^ ERROR cannot find struct, variant or union type `Drain` } diff --git a/tests/ui/rust-2018/issue-52202-use-suggestions.stderr b/tests/ui/rust-2018/issue-52202-use-suggestions.stderr index ee1a336ea98f6..c6a600de55233 100644 --- a/tests/ui/rust-2018/issue-52202-use-suggestions.stderr +++ b/tests/ui/rust-2018/issue-52202-use-suggestions.stderr @@ -1,4 +1,4 @@ -error[E0422]: cannot find struct, variant or union type `Drain` in this scope +error[E0422]: cannot find struct, variant or union type `Drain` --> $DIR/issue-52202-use-suggestions.rs:11:14 | LL | let _d = Drain {}; diff --git a/tests/ui/rustdoc/cfg-rustdoc.stderr b/tests/ui/rustdoc/cfg-rustdoc.stderr index 340a8e22482ce..42c388dcb6d64 100644 --- a/tests/ui/rustdoc/cfg-rustdoc.stderr +++ b/tests/ui/rustdoc/cfg-rustdoc.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `Foo` in this scope +error[E0425]: cannot find value `Foo` --> $DIR/cfg-rustdoc.rs:5:13 | LL | let f = Foo; diff --git a/tests/ui/self/class-missing-self.rs b/tests/ui/self/class-missing-self.rs index 8ad347d20e6e4..4d973d3a2aeed 100644 --- a/tests/ui/self/class-missing-self.rs +++ b/tests/ui/self/class-missing-self.rs @@ -6,8 +6,8 @@ impl Cat { fn sleep(&self) { loop{} } fn meow(&self) { println!("Meow"); - meows += 1; //~ ERROR cannot find value `meows` in this scope - sleep(); //~ ERROR cannot find function `sleep` in this + meows += 1; //~ ERROR cannot find value `meows` + sleep(); //~ ERROR cannot find function `sleep` } } diff --git a/tests/ui/self/class-missing-self.stderr b/tests/ui/self/class-missing-self.stderr index ca7a896200fc3..0caf630bfc021 100644 --- a/tests/ui/self/class-missing-self.stderr +++ b/tests/ui/self/class-missing-self.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `meows` in this scope +error[E0425]: cannot find value `meows` --> $DIR/class-missing-self.rs:9:7 | LL | meows += 1; @@ -9,7 +9,7 @@ help: you might have meant to use the available field LL | self.meows += 1; | +++++ -error[E0425]: cannot find function `sleep` in this scope +error[E0425]: cannot find function `sleep` --> $DIR/class-missing-self.rs:10:7 | LL | sleep(); diff --git a/tests/ui/self/elision/nested-item.rs b/tests/ui/self/elision/nested-item.rs index 4bcb645c60eef..6cc379747ab8e 100644 --- a/tests/ui/self/elision/nested-item.rs +++ b/tests/ui/self/elision/nested-item.rs @@ -6,7 +6,7 @@ fn wrap(self: Wrap<{ fn bar(&self) {} }>) -> &() { //~^ ERROR `self` parameter is only allowed in associated functions //~| ERROR `self` parameter is only allowed in associated functions //~| ERROR missing lifetime specifier - //~| ERROR cannot find type `Wrap` in this scope + //~| ERROR cannot find type `Wrap` &() } diff --git a/tests/ui/self/elision/nested-item.stderr b/tests/ui/self/elision/nested-item.stderr index 7bad26fa13303..feeb560d995cc 100644 --- a/tests/ui/self/elision/nested-item.stderr +++ b/tests/ui/self/elision/nested-item.stderr @@ -35,7 +35,7 @@ LL - fn wrap(self: Wrap<{ fn bar(&self) {} }>) -> &() { LL + fn wrap(self: Wrap<{ fn bar(&self) {} }>) -> () { | -error[E0412]: cannot find type `Wrap` in this scope +error[E0412]: cannot find type `Wrap` --> $DIR/nested-item.rs:5:15 | LL | fn wrap(self: Wrap<{ fn bar(&self) {} }>) -> &() { diff --git a/tests/ui/self/self_type_keyword-2.rs b/tests/ui/self/self_type_keyword-2.rs index cfb87f5186d32..0af2c42b0bf23 100644 --- a/tests/ui/self/self_type_keyword-2.rs +++ b/tests/ui/self/self_type_keyword-2.rs @@ -2,12 +2,12 @@ use self::Self as Foo; //~ ERROR unresolved import `self::Self` pub fn main() { let Self = 5; - //~^ ERROR cannot find unit struct, unit variant or constant `Self` in this scope + //~^ ERROR cannot find unit struct, unit variant or constant `Self` match 15 { Self => (), - //~^ ERROR cannot find unit struct, unit variant or constant `Self` in this scope + //~^ ERROR cannot find unit struct, unit variant or constant `Self` Foo { x: Self } => (), - //~^ ERROR cannot find unit struct, unit variant or constant `Self` in this scope + //~^ ERROR cannot find unit struct, unit variant or constant `Self` } } diff --git a/tests/ui/self/self_type_keyword-2.stderr b/tests/ui/self/self_type_keyword-2.stderr index 4e931f91f70c4..7e96bcc89eebf 100644 --- a/tests/ui/self/self_type_keyword-2.stderr +++ b/tests/ui/self/self_type_keyword-2.stderr @@ -4,19 +4,19 @@ error[E0432]: unresolved import `self::Self` LL | use self::Self as Foo; | ^^^^^^^^^^^^^^^^^ no `Self` in the root -error[E0531]: cannot find unit struct, unit variant or constant `Self` in this scope +error[E0531]: cannot find unit struct, unit variant or constant `Self` --> $DIR/self_type_keyword-2.rs:4:9 | LL | let Self = 5; | ^^^^ not found in this scope -error[E0531]: cannot find unit struct, unit variant or constant `Self` in this scope +error[E0531]: cannot find unit struct, unit variant or constant `Self` --> $DIR/self_type_keyword-2.rs:8:9 | LL | Self => (), | ^^^^ not found in this scope -error[E0531]: cannot find unit struct, unit variant or constant `Self` in this scope +error[E0531]: cannot find unit struct, unit variant or constant `Self` --> $DIR/self_type_keyword-2.rs:10:18 | LL | Foo { x: Self } => (), diff --git a/tests/ui/self/self_type_keyword.rs b/tests/ui/self/self_type_keyword.rs index 96d24715edb10..a0cda4ee49002 100644 --- a/tests/ui/self/self_type_keyword.rs +++ b/tests/ui/self/self_type_keyword.rs @@ -19,7 +19,7 @@ pub fn main() { ref mut Self => (), //~^ ERROR expected identifier, found keyword `Self` Self!() => (), - //~^ ERROR cannot find macro `Self` in this scope + //~^ ERROR cannot find macro `Self` Foo { Self } => (), //~^ ERROR expected identifier, found keyword `Self` //~| ERROR mismatched types diff --git a/tests/ui/self/self_type_keyword.stderr b/tests/ui/self/self_type_keyword.stderr index 4909a9cdc7f5c..8886fcfdc60cc 100644 --- a/tests/ui/self/self_type_keyword.stderr +++ b/tests/ui/self/self_type_keyword.stderr @@ -60,7 +60,7 @@ error: cannot find macro `Self` in this scope LL | Self!() => (), | ^^^^ -error[E0531]: cannot find unit struct, unit variant or constant `Self` in this scope +error[E0531]: cannot find unit struct, unit variant or constant `Self` --> $DIR/self_type_keyword.rs:16:13 | LL | mut Self => (), diff --git a/tests/ui/self/suggest-self-2.rs b/tests/ui/self/suggest-self-2.rs index 1e001827e475f..74573e111f2b5 100644 --- a/tests/ui/self/suggest-self-2.rs +++ b/tests/ui/self/suggest-self-2.rs @@ -3,19 +3,19 @@ struct Foo {} impl Foo { fn foo(&self) { bar(self); - //~^ ERROR cannot find function `bar` in this scope + //~^ ERROR cannot find function `bar` //~| HELP try calling `bar` as a method bar(&&self, 102); - //~^ ERROR cannot find function `bar` in this scope + //~^ ERROR cannot find function `bar` //~| HELP try calling `bar` as a method bar(&mut self, 102, &"str"); - //~^ ERROR cannot find function `bar` in this scope + //~^ ERROR cannot find function `bar` //~| HELP try calling `bar` as a method bar(); - //~^ ERROR cannot find function `bar` in this scope + //~^ ERROR cannot find function `bar` self.bar(); //~^ ERROR no method named `bar` found for reference diff --git a/tests/ui/self/suggest-self-2.stderr b/tests/ui/self/suggest-self-2.stderr index 4bd025ea07630..dbb3c2ab9235d 100644 --- a/tests/ui/self/suggest-self-2.stderr +++ b/tests/ui/self/suggest-self-2.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find function `bar` in this scope +error[E0425]: cannot find function `bar` --> $DIR/suggest-self-2.rs:5:9 | LL | bar(self); @@ -6,7 +6,7 @@ LL | bar(self); | | | help: try calling `bar` as a method: `self.bar()` -error[E0425]: cannot find function `bar` in this scope +error[E0425]: cannot find function `bar` --> $DIR/suggest-self-2.rs:9:9 | LL | bar(&&self, 102); @@ -14,7 +14,7 @@ LL | bar(&&self, 102); | | | help: try calling `bar` as a method: `self.bar(102)` -error[E0425]: cannot find function `bar` in this scope +error[E0425]: cannot find function `bar` --> $DIR/suggest-self-2.rs:13:9 | LL | bar(&mut self, 102, &"str"); @@ -22,7 +22,7 @@ LL | bar(&mut self, 102, &"str"); | | | help: try calling `bar` as a method: `self.bar(102, &"str")` -error[E0425]: cannot find function `bar` in this scope +error[E0425]: cannot find function `bar` --> $DIR/suggest-self-2.rs:17:9 | LL | bar(); diff --git a/tests/ui/self/suggest-self.rs b/tests/ui/self/suggest-self.rs index 1cc17116ea7f7..3d292a02e5310 100644 --- a/tests/ui/self/suggest-self.rs +++ b/tests/ui/self/suggest-self.rs @@ -19,17 +19,17 @@ impl Foo { fn foo(&self) -> i32 { this.x - //~^ ERROR cannot find value `this` in this scope + //~^ ERROR cannot find value `this` } fn bar(&self) -> i32 { this.foo() - //~^ ERROR cannot find value `this` in this scope + //~^ ERROR cannot find value `this` } fn baz(&self) -> i32 { my.bar() - //~^ ERROR cannot find value `my` in this scope + //~^ ERROR cannot find value `my` } } diff --git a/tests/ui/self/suggest-self.stderr b/tests/ui/self/suggest-self.stderr index 0d38b9d87c5e8..8625a83694698 100644 --- a/tests/ui/self/suggest-self.stderr +++ b/tests/ui/self/suggest-self.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `this` in this scope +error[E0425]: cannot find value `this` --> $DIR/suggest-self.rs:21:9 | LL | this.x @@ -7,7 +7,7 @@ LL | this.x | not found in this scope | help: you might have meant to use `self` here instead -error[E0425]: cannot find value `this` in this scope +error[E0425]: cannot find value `this` --> $DIR/suggest-self.rs:26:9 | LL | this.foo() @@ -16,7 +16,7 @@ LL | this.foo() | not found in this scope | help: you might have meant to use `self` here instead -error[E0425]: cannot find value `my` in this scope +error[E0425]: cannot find value `my` --> $DIR/suggest-self.rs:31:9 | LL | my.bar() diff --git a/tests/ui/sized/ensure-overriding-bindings-in-pattern-with-ty-err-doesnt-ice.rs b/tests/ui/sized/ensure-overriding-bindings-in-pattern-with-ty-err-doesnt-ice.rs index d0bf5078165b7..7d5cfbc9c6bd2 100644 --- a/tests/ui/sized/ensure-overriding-bindings-in-pattern-with-ty-err-doesnt-ice.rs +++ b/tests/ui/sized/ensure-overriding-bindings-in-pattern-with-ty-err-doesnt-ice.rs @@ -1,7 +1,7 @@ fn main() { let str::<{fn str() { let str::T>>::as_bytes; }}, T>::as_bytes; //~^ ERROR expected a pattern, found an expression -//~| ERROR cannot find type `T` in this scope +//~| ERROR cannot find type `T` //~| ERROR const and type arguments are not allowed on builtin type `str` //~| ERROR expected unit struct, unit variant or constant, found associated function `str< //~| ERROR type annotations needed diff --git a/tests/ui/sized/ensure-overriding-bindings-in-pattern-with-ty-err-doesnt-ice.stderr b/tests/ui/sized/ensure-overriding-bindings-in-pattern-with-ty-err-doesnt-ice.stderr index fc431eb14127f..1b3c6641e194d 100644 --- a/tests/ui/sized/ensure-overriding-bindings-in-pattern-with-ty-err-doesnt-ice.stderr +++ b/tests/ui/sized/ensure-overriding-bindings-in-pattern-with-ty-err-doesnt-ice.stderr @@ -4,7 +4,7 @@ error: expected a pattern, found an expression LL | let str::<{fn str() { let str::T>>::as_bytes; }}, T>::as_bytes; | ^^^^^^^^^^^^^^^^^^ arbitrary expressions are not allowed in patterns -error[E0412]: cannot find type `T` in this scope +error[E0412]: cannot find type `T` --> $DIR/ensure-overriding-bindings-in-pattern-with-ty-err-doesnt-ice.rs:2:55 | LL | let str::<{fn str() { let str::T>>::as_bytes; }}, T>::as_bytes; diff --git a/tests/ui/span/drop-location-span-error-rust-2021-incompatible-closure-captures-96258.rs b/tests/ui/span/drop-location-span-error-rust-2021-incompatible-closure-captures-96258.rs index 66a432be35737..dc5c4f7627522 100644 --- a/tests/ui/span/drop-location-span-error-rust-2021-incompatible-closure-captures-96258.rs +++ b/tests/ui/span/drop-location-span-error-rust-2021-incompatible-closure-captures-96258.rs @@ -8,7 +8,7 @@ impl Numberer { pub(crate) async fn new( //~^ ERROR `async fn` is not permitted in Rust 2015 interval: Duration, - //~^ ERROR cannot find type `Duration` in this scope + //~^ ERROR cannot find type `Duration` ) -> Numberer { Numberer {} } diff --git a/tests/ui/span/drop-location-span-error-rust-2021-incompatible-closure-captures-96258.stderr b/tests/ui/span/drop-location-span-error-rust-2021-incompatible-closure-captures-96258.stderr index 60433e1c28467..bf8191e5fb425 100644 --- a/tests/ui/span/drop-location-span-error-rust-2021-incompatible-closure-captures-96258.stderr +++ b/tests/ui/span/drop-location-span-error-rust-2021-incompatible-closure-captures-96258.stderr @@ -7,7 +7,7 @@ LL | pub(crate) async fn new( = help: pass `--edition 2021` to `rustc` = note: for more on editions, read https://doc.rust-lang.org/edition-guide -error[E0412]: cannot find type `Duration` in this scope +error[E0412]: cannot find type `Duration` --> $DIR/drop-location-span-error-rust-2021-incompatible-closure-captures-96258.rs:10:19 | LL | interval: Duration, diff --git a/tests/ui/span/suggestion-raw-68962.stderr b/tests/ui/span/suggestion-raw-68962.stderr index 2e25f5cbdf58d..2a76514405770 100644 --- a/tests/ui/span/suggestion-raw-68962.stderr +++ b/tests/ui/span/suggestion-raw-68962.stderr @@ -1,10 +1,10 @@ -error[E0425]: cannot find value `fina` in this scope +error[E0425]: cannot find value `fina` --> $DIR/suggestion-raw-68962.rs:7:5 | LL | fina; | ^^^^ help: a local variable with a similar name exists: `r#final` -error[E0425]: cannot find function `f` in this scope +error[E0425]: cannot find function `f` --> $DIR/suggestion-raw-68962.rs:10:5 | LL | fn r#fn() {} diff --git a/tests/ui/span/typo-suggestion.stderr b/tests/ui/span/typo-suggestion.stderr index 61d4e06119c4f..5d7c41319a7e4 100644 --- a/tests/ui/span/typo-suggestion.stderr +++ b/tests/ui/span/typo-suggestion.stderr @@ -1,10 +1,10 @@ -error[E0425]: cannot find value `bar` in this scope +error[E0425]: cannot find value `bar` --> $DIR/typo-suggestion.rs:5:26 | LL | println!("Hello {}", bar); | ^^^ not found in this scope -error[E0425]: cannot find value `fob` in this scope +error[E0425]: cannot find value `fob` --> $DIR/typo-suggestion.rs:8:26 | LL | println!("Hello {}", fob); diff --git a/tests/ui/specialization/issue-68830-spurious-diagnostics.rs b/tests/ui/specialization/issue-68830-spurious-diagnostics.rs index a7487b8aecb9c..7ff92bff26a25 100644 --- a/tests/ui/specialization/issue-68830-spurious-diagnostics.rs +++ b/tests/ui/specialization/issue-68830-spurious-diagnostics.rs @@ -5,7 +5,7 @@ #![allow(incomplete_features)] struct BadStruct { - err: MissingType //~ ERROR: cannot find type `MissingType` in this scope + err: MissingType //~ ERROR: cannot find type `MissingType` } trait MyTrait { diff --git a/tests/ui/specialization/issue-68830-spurious-diagnostics.stderr b/tests/ui/specialization/issue-68830-spurious-diagnostics.stderr index 13f6ae0805dad..dff73f6f09d1c 100644 --- a/tests/ui/specialization/issue-68830-spurious-diagnostics.stderr +++ b/tests/ui/specialization/issue-68830-spurious-diagnostics.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `MissingType` in this scope +error[E0412]: cannot find type `MissingType` --> $DIR/issue-68830-spurious-diagnostics.rs:8:10 | LL | err: MissingType diff --git a/tests/ui/specialization/min_specialization/impl-on-nonexisting.rs b/tests/ui/specialization/min_specialization/impl-on-nonexisting.rs index 77a64320d6f37..b3e08f5a86770 100644 --- a/tests/ui/specialization/min_specialization/impl-on-nonexisting.rs +++ b/tests/ui/specialization/min_specialization/impl-on-nonexisting.rs @@ -2,6 +2,6 @@ trait Trait {} impl Trait for NonExistent {} -//~^ ERROR cannot find type `NonExistent` in this scope +//~^ ERROR cannot find type `NonExistent` fn main() {} diff --git a/tests/ui/specialization/min_specialization/impl-on-nonexisting.stderr b/tests/ui/specialization/min_specialization/impl-on-nonexisting.stderr index 85b492c0503b2..934a502091972 100644 --- a/tests/ui/specialization/min_specialization/impl-on-nonexisting.stderr +++ b/tests/ui/specialization/min_specialization/impl-on-nonexisting.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `NonExistent` in this scope +error[E0412]: cannot find type `NonExistent` --> $DIR/impl-on-nonexisting.rs:4:16 | LL | impl Trait for NonExistent {} diff --git a/tests/ui/stability-attribute/issue-109177.rs b/tests/ui/stability-attribute/issue-109177.rs index 52880a43bcc3d..f7d4afd256ee6 100644 --- a/tests/ui/stability-attribute/issue-109177.rs +++ b/tests/ui/stability-attribute/issue-109177.rs @@ -5,7 +5,7 @@ extern crate similar_unstable_method; fn main() { // FIXME: this function should not suggest the `foo` function. similar_unstable_method::foo1(); - //~^ ERROR cannot find function `foo1` in crate `similar_unstable_method` [E0425] + //~^ ERROR cannot find function `foo1` [E0425] let foo = similar_unstable_method::Foo; foo.foo1(); diff --git a/tests/ui/stability-attribute/issue-109177.stderr b/tests/ui/stability-attribute/issue-109177.stderr index 9c2ac591ace05..d0ed578887197 100644 --- a/tests/ui/stability-attribute/issue-109177.stderr +++ b/tests/ui/stability-attribute/issue-109177.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find function `foo1` in crate `similar_unstable_method` +error[E0425]: cannot find function `foo1` --> $DIR/issue-109177.rs:7:30 | LL | similar_unstable_method::foo1(); diff --git a/tests/ui/stability-attribute/unresolved_stability_lint.rs b/tests/ui/stability-attribute/unresolved_stability_lint.rs index 818d228bc91c5..2af8ce01e34e2 100644 --- a/tests/ui/stability-attribute/unresolved_stability_lint.rs +++ b/tests/ui/stability-attribute/unresolved_stability_lint.rs @@ -3,6 +3,6 @@ #[unstable(feature = "foo", issue = "none")] impl Foo for () {} -//~^ ERROR cannot find trait `Foo` in this scope +//~^ ERROR cannot find trait `Foo` fn main() {} diff --git a/tests/ui/stability-attribute/unresolved_stability_lint.stderr b/tests/ui/stability-attribute/unresolved_stability_lint.stderr index 51780d2088099..f7c29495f7f44 100644 --- a/tests/ui/stability-attribute/unresolved_stability_lint.stderr +++ b/tests/ui/stability-attribute/unresolved_stability_lint.stderr @@ -1,4 +1,4 @@ -error[E0405]: cannot find trait `Foo` in this scope +error[E0405]: cannot find trait `Foo` --> $DIR/unresolved_stability_lint.rs:5:6 | LL | impl Foo for () {} diff --git a/tests/ui/structs/ice-struct-tail-normalization-113272.rs b/tests/ui/structs/ice-struct-tail-normalization-113272.rs index 85d3d1b4886f7..eab99be4b13ee 100644 --- a/tests/ui/structs/ice-struct-tail-normalization-113272.rs +++ b/tests/ui/structs/ice-struct-tail-normalization-113272.rs @@ -3,7 +3,7 @@ trait Trait { } impl Trait for () where Missing: Trait {} -//~^ ERROR cannot find type `Missing` in this scope +//~^ ERROR cannot find type `Missing` //~| ERROR not all trait items implemented, missing: `RefTarget` struct Other { diff --git a/tests/ui/structs/ice-struct-tail-normalization-113272.stderr b/tests/ui/structs/ice-struct-tail-normalization-113272.stderr index a205eb80f5c0a..be8be757ef753 100644 --- a/tests/ui/structs/ice-struct-tail-normalization-113272.stderr +++ b/tests/ui/structs/ice-struct-tail-normalization-113272.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `Missing` in this scope +error[E0412]: cannot find type `Missing` --> $DIR/ice-struct-tail-normalization-113272.rs:5:25 | LL | impl Trait for () where Missing: Trait {} diff --git a/tests/ui/structs/struct-fields-shorthand-unresolved.rs b/tests/ui/structs/struct-fields-shorthand-unresolved.rs index caad149160c89..14700e827a074 100644 --- a/tests/ui/structs/struct-fields-shorthand-unresolved.rs +++ b/tests/ui/structs/struct-fields-shorthand-unresolved.rs @@ -7,6 +7,6 @@ fn main() { let x = 0; let foo = Foo { x, - y //~ ERROR cannot find value `y` in this scope + y //~ ERROR cannot find value `y` }; } diff --git a/tests/ui/structs/struct-fields-shorthand-unresolved.stderr b/tests/ui/structs/struct-fields-shorthand-unresolved.stderr index b485c17c1b270..e99312f77ec40 100644 --- a/tests/ui/structs/struct-fields-shorthand-unresolved.stderr +++ b/tests/ui/structs/struct-fields-shorthand-unresolved.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `y` in this scope +error[E0425]: cannot find value `y` --> $DIR/struct-fields-shorthand-unresolved.rs:10:9 | LL | y diff --git a/tests/ui/structs/unresolved-struct-with-fru.rs b/tests/ui/structs/unresolved-struct-with-fru.rs index c9fdca4577279..3b84b807c51cc 100644 --- a/tests/ui/structs/unresolved-struct-with-fru.rs +++ b/tests/ui/structs/unresolved-struct-with-fru.rs @@ -7,6 +7,6 @@ fn main() { let _ = || { let s2 = Oops { a: 2, ..s1 }; - //~^ ERROR cannot find struct, variant or union type `Oops` in this scope + //~^ ERROR cannot find struct, variant or union type `Oops` }; } diff --git a/tests/ui/structs/unresolved-struct-with-fru.stderr b/tests/ui/structs/unresolved-struct-with-fru.stderr index 9902c3ed35711..df44538bbddda 100644 --- a/tests/ui/structs/unresolved-struct-with-fru.stderr +++ b/tests/ui/structs/unresolved-struct-with-fru.stderr @@ -1,4 +1,4 @@ -error[E0422]: cannot find struct, variant or union type `Oops` in this scope +error[E0422]: cannot find struct, variant or union type `Oops` --> $DIR/unresolved-struct-with-fru.rs:9:18 | LL | let s2 = Oops { a: 2, ..s1 }; diff --git a/tests/ui/suggestions/assoc-const-without-self.rs b/tests/ui/suggestions/assoc-const-without-self.rs index 95070ec601cd4..020b1c2f9a8e3 100644 --- a/tests/ui/suggestions/assoc-const-without-self.rs +++ b/tests/ui/suggestions/assoc-const-without-self.rs @@ -4,7 +4,7 @@ impl Foo { const A_CONST: usize = 1; fn foo() -> usize { - A_CONST //~ ERROR cannot find value `A_CONST` in this scope + A_CONST //~ ERROR cannot find value `A_CONST` } } diff --git a/tests/ui/suggestions/assoc-const-without-self.stderr b/tests/ui/suggestions/assoc-const-without-self.stderr index 5a9fba8a0e47b..b31ea8c6b1ef1 100644 --- a/tests/ui/suggestions/assoc-const-without-self.stderr +++ b/tests/ui/suggestions/assoc-const-without-self.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `A_CONST` in this scope +error[E0425]: cannot find value `A_CONST` --> $DIR/assoc-const-without-self.rs:7:9 | LL | A_CONST diff --git a/tests/ui/suggestions/assoc-type-in-method-return.rs b/tests/ui/suggestions/assoc-type-in-method-return.rs index 9bde65998d744..e9341304d7990 100644 --- a/tests/ui/suggestions/assoc-type-in-method-return.rs +++ b/tests/ui/suggestions/assoc-type-in-method-return.rs @@ -1,7 +1,7 @@ trait A { type Bla; fn to_bla(&self) -> Bla; - //~^ ERROR cannot find type `Bla` in this scope + //~^ ERROR cannot find type `Bla` } fn main() {} diff --git a/tests/ui/suggestions/assoc-type-in-method-return.stderr b/tests/ui/suggestions/assoc-type-in-method-return.stderr index f83da79097009..5a53eeb8d6134 100644 --- a/tests/ui/suggestions/assoc-type-in-method-return.stderr +++ b/tests/ui/suggestions/assoc-type-in-method-return.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `Bla` in this scope +error[E0412]: cannot find type `Bla` --> $DIR/assoc-type-in-method-return.rs:3:25 | LL | fn to_bla(&self) -> Bla; diff --git a/tests/ui/suggestions/assoc_fn_without_self.rs b/tests/ui/suggestions/assoc_fn_without_self.rs index 35c16ef3e9f7c..c9c62b8bba313 100644 --- a/tests/ui/suggestions/assoc_fn_without_self.rs +++ b/tests/ui/suggestions/assoc_fn_without_self.rs @@ -11,18 +11,18 @@ impl S { fn b() { fn c() { - foo(); //~ ERROR cannot find function `foo` in this scope + foo(); //~ ERROR cannot find function `foo` } - foo(); //~ ERROR cannot find function `foo` in this scope - bar(); //~ ERROR cannot find function `bar` in this scope - baz(2, 3); //~ ERROR cannot find function `baz` in this scope + foo(); //~ ERROR cannot find function `foo` + bar(); //~ ERROR cannot find function `bar` + baz(2, 3); //~ ERROR cannot find function `baz` } fn d(&self) { fn c() { - foo(); //~ ERROR cannot find function `foo` in this scope + foo(); //~ ERROR cannot find function `foo` } - foo(); //~ ERROR cannot find function `foo` in this scope - bar(); //~ ERROR cannot find function `bar` in this scope - baz(2, 3); //~ ERROR cannot find function `baz` in this scope + foo(); //~ ERROR cannot find function `foo` + bar(); //~ ERROR cannot find function `bar` + baz(2, 3); //~ ERROR cannot find function `baz` } } diff --git a/tests/ui/suggestions/assoc_fn_without_self.stderr b/tests/ui/suggestions/assoc_fn_without_self.stderr index 9cee7c7ee5ee8..ba6dea8f7deb5 100644 --- a/tests/ui/suggestions/assoc_fn_without_self.stderr +++ b/tests/ui/suggestions/assoc_fn_without_self.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find function `foo` in this scope +error[E0425]: cannot find function `foo` --> $DIR/assoc_fn_without_self.rs:16:9 | LL | foo(); @@ -9,7 +9,7 @@ help: consider using the associated function on `Self` LL | Self::foo(); | ++++++ -error[E0425]: cannot find function `bar` in this scope +error[E0425]: cannot find function `bar` --> $DIR/assoc_fn_without_self.rs:17:9 | LL | fn bar(&self) {} @@ -18,7 +18,7 @@ LL | fn bar(&self) {} LL | bar(); | ^^^ not found in this scope -error[E0425]: cannot find function `baz` in this scope +error[E0425]: cannot find function `baz` --> $DIR/assoc_fn_without_self.rs:18:9 | LL | baz(2, 3); @@ -29,13 +29,13 @@ help: consider using the associated function on `Self` LL | Self::baz(2, 3); | ++++++ -error[E0425]: cannot find function `foo` in this scope +error[E0425]: cannot find function `foo` --> $DIR/assoc_fn_without_self.rs:14:13 | LL | foo(); | ^^^ not found in this scope -error[E0425]: cannot find function `foo` in this scope +error[E0425]: cannot find function `foo` --> $DIR/assoc_fn_without_self.rs:24:9 | LL | foo(); @@ -46,7 +46,7 @@ help: consider using the associated function on `Self` LL | Self::foo(); | ++++++ -error[E0425]: cannot find function `bar` in this scope +error[E0425]: cannot find function `bar` --> $DIR/assoc_fn_without_self.rs:25:9 | LL | bar(); @@ -57,7 +57,7 @@ help: consider using the method on `Self` LL | self.bar(); | +++++ -error[E0425]: cannot find function `baz` in this scope +error[E0425]: cannot find function `baz` --> $DIR/assoc_fn_without_self.rs:26:9 | LL | baz(2, 3); @@ -68,7 +68,7 @@ help: consider using the associated function on `Self` LL | Self::baz(2, 3); | ++++++ -error[E0425]: cannot find function `foo` in this scope +error[E0425]: cannot find function `foo` --> $DIR/assoc_fn_without_self.rs:22:13 | LL | foo(); diff --git a/tests/ui/suggestions/attribute-typos.rs b/tests/ui/suggestions/attribute-typos.rs index 7c8231bbb24f8..b8bc785a93833 100644 --- a/tests/ui/suggestions/attribute-typos.rs +++ b/tests/ui/suggestions/attribute-typos.rs @@ -1,11 +1,11 @@ -#[deprcated] //~ ERROR cannot find attribute `deprcated` in this scope +#[deprcated] //~ ERROR cannot find attribute `deprcated` fn foo() {} -#[tests] //~ ERROR cannot find attribute `tests` in this scope +#[tests] //~ ERROR cannot find attribute `tests` fn bar() {} #[rustc_err] -//~^ ERROR cannot find attribute `rustc_err` in this scope +//~^ ERROR cannot find attribute `rustc_err` //~| ERROR attributes starting with `rustc` are reserved for use by the `rustc` compiler fn main() {} diff --git a/tests/ui/suggestions/bool_typo_err_suggest.rs b/tests/ui/suggestions/bool_typo_err_suggest.rs index deab0fb05b76b..7a32c55dc862c 100644 --- a/tests/ui/suggestions/bool_typo_err_suggest.rs +++ b/tests/ui/suggestions/bool_typo_err_suggest.rs @@ -3,10 +3,10 @@ fn main() { let x = True; - //~^ ERROR cannot find value `True` in this scope + //~^ ERROR cannot find value `True` //~| HELP you may want to use a bool value instead let y = False; - //~^ ERROR cannot find value `False` in this scope + //~^ ERROR cannot find value `False` //~| HELP you may want to use a bool value instead } diff --git a/tests/ui/suggestions/bool_typo_err_suggest.stderr b/tests/ui/suggestions/bool_typo_err_suggest.stderr index 8d59ed63e5432..0c41080e7c07b 100644 --- a/tests/ui/suggestions/bool_typo_err_suggest.stderr +++ b/tests/ui/suggestions/bool_typo_err_suggest.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `True` in this scope +error[E0425]: cannot find value `True` --> $DIR/bool_typo_err_suggest.rs:5:13 | LL | let x = True; @@ -9,7 +9,7 @@ help: you may want to use a bool value instead LL | let x = true; | ~~~~ -error[E0425]: cannot find value `False` in this scope +error[E0425]: cannot find value `False` --> $DIR/bool_typo_err_suggest.rs:9:13 | LL | let y = False; diff --git a/tests/ui/suggestions/dont-suggest-foreign-doc-hidden.rs b/tests/ui/suggestions/dont-suggest-foreign-doc-hidden.rs index 281975dcc2f3b..43badc7a8f881 100644 --- a/tests/ui/suggestions/dont-suggest-foreign-doc-hidden.rs +++ b/tests/ui/suggestions/dont-suggest-foreign-doc-hidden.rs @@ -9,7 +9,7 @@ mod local { } pub fn test(_: Foo) {} -//~^ ERROR cannot find type `Foo` in this scope +//~^ ERROR cannot find type `Foo` pub fn test2(_: Bar) {} -//~^ ERROR cannot find type `Bar` in this scope +//~^ ERROR cannot find type `Bar` diff --git a/tests/ui/suggestions/dont-suggest-foreign-doc-hidden.stderr b/tests/ui/suggestions/dont-suggest-foreign-doc-hidden.stderr index 7fb4d95ff9bf5..071d17c614763 100644 --- a/tests/ui/suggestions/dont-suggest-foreign-doc-hidden.stderr +++ b/tests/ui/suggestions/dont-suggest-foreign-doc-hidden.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `Foo` in this scope +error[E0412]: cannot find type `Foo` --> $DIR/dont-suggest-foreign-doc-hidden.rs:11:16 | LL | pub fn test(_: Foo) {} @@ -9,7 +9,7 @@ help: consider importing this struct LL + use local::Foo; | -error[E0412]: cannot find type `Bar` in this scope +error[E0412]: cannot find type `Bar` --> $DIR/dont-suggest-foreign-doc-hidden.rs:14:17 | LL | pub fn test2(_: Bar) {} diff --git a/tests/ui/suggestions/fn-to-method-deeply-nested.rs b/tests/ui/suggestions/fn-to-method-deeply-nested.rs index 58ee3d6409a7e..b271aa9ab02bb 100644 --- a/tests/ui/suggestions/fn-to-method-deeply-nested.rs +++ b/tests/ui/suggestions/fn-to-method-deeply-nested.rs @@ -1,13 +1,13 @@ fn main() -> Result<(), ()> { a(b(c(d(e( - //~^ ERROR cannot find function `a` in this scope - //~| ERROR cannot find function `b` in this scope - //~| ERROR cannot find function `c` in this scope - //~| ERROR cannot find function `d` in this scope - //~| ERROR cannot find function `e` in this scope + //~^ ERROR cannot find function `a` + //~| ERROR cannot find function `b` + //~| ERROR cannot find function `c` + //~| ERROR cannot find function `d` + //~| ERROR cannot find function `e` z???????????????????????????????????????????????????????????????????????????????????????? ????????????????????????????????????????????????????????????????????????????????????????? ?????????????????????????????????????????????????????????????????? - //~^^^ ERROR cannot find value `z` in this scope + //~^^^ ERROR cannot find value `z` ))))) } diff --git a/tests/ui/suggestions/fn-to-method-deeply-nested.stderr b/tests/ui/suggestions/fn-to-method-deeply-nested.stderr index ce813ea7abae8..9c7850a7e497c 100644 --- a/tests/ui/suggestions/fn-to-method-deeply-nested.stderr +++ b/tests/ui/suggestions/fn-to-method-deeply-nested.stderr @@ -1,34 +1,34 @@ -error[E0425]: cannot find value `z` in this scope +error[E0425]: cannot find value `z` --> $DIR/fn-to-method-deeply-nested.rs:8:9 | LL | z???????????????????????????????????????????????????????????????????????????????????????? | ^ not found in this scope -error[E0425]: cannot find function `e` in this scope +error[E0425]: cannot find function `e` --> $DIR/fn-to-method-deeply-nested.rs:2:13 | LL | a(b(c(d(e( | ^ not found in this scope -error[E0425]: cannot find function `d` in this scope +error[E0425]: cannot find function `d` --> $DIR/fn-to-method-deeply-nested.rs:2:11 | LL | a(b(c(d(e( | ^ not found in this scope -error[E0425]: cannot find function `c` in this scope +error[E0425]: cannot find function `c` --> $DIR/fn-to-method-deeply-nested.rs:2:9 | LL | a(b(c(d(e( | ^ not found in this scope -error[E0425]: cannot find function `b` in this scope +error[E0425]: cannot find function `b` --> $DIR/fn-to-method-deeply-nested.rs:2:7 | LL | a(b(c(d(e( | ^ not found in this scope -error[E0425]: cannot find function `a` in this scope +error[E0425]: cannot find function `a` --> $DIR/fn-to-method-deeply-nested.rs:2:5 | LL | a(b(c(d(e( diff --git a/tests/ui/suggestions/fn-to-method.rs b/tests/ui/suggestions/fn-to-method.rs index 9a35c3efc41b7..5594b80a188e2 100644 --- a/tests/ui/suggestions/fn-to-method.rs +++ b/tests/ui/suggestions/fn-to-method.rs @@ -6,14 +6,14 @@ impl Foo { fn main() { let x = cmp(&1, &2); - //~^ ERROR cannot find function `cmp` in this scope + //~^ ERROR cannot find function `cmp` //~| HELP use the `.` operator to call the method `Ord::cmp` on `&{integer}` let y = len([1, 2, 3]); - //~^ ERROR cannot find function `len` in this scope + //~^ ERROR cannot find function `len` //~| HELP use the `.` operator to call the method `len` on `&[{integer}]` let z = bar(Foo); - //~^ ERROR cannot find function `bar` in this scope + //~^ ERROR cannot find function `bar` //~| HELP use the `.` operator to call the method `bar` on `Foo` } diff --git a/tests/ui/suggestions/fn-to-method.stderr b/tests/ui/suggestions/fn-to-method.stderr index 36c17e60d3572..1a29cf163ae00 100644 --- a/tests/ui/suggestions/fn-to-method.stderr +++ b/tests/ui/suggestions/fn-to-method.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find function `cmp` in this scope +error[E0425]: cannot find function `cmp` --> $DIR/fn-to-method.rs:8:13 | LL | let x = cmp(&1, &2); @@ -9,7 +9,7 @@ help: use the `.` operator to call the method `Ord::cmp` on `&{integer}` LL | let x = (&1).cmp(&2); | ~ ~~~~~~~~~ -error[E0425]: cannot find function `len` in this scope +error[E0425]: cannot find function `len` --> $DIR/fn-to-method.rs:12:13 | LL | let y = len([1, 2, 3]); @@ -21,7 +21,7 @@ LL - let y = len([1, 2, 3]); LL + let y = [1, 2, 3].len(); | -error[E0425]: cannot find function `bar` in this scope +error[E0425]: cannot find function `bar` --> $DIR/fn-to-method.rs:16:13 | LL | let z = bar(Foo); diff --git a/tests/ui/suggestions/ice-unwrap-probe-many-result-125876.rs b/tests/ui/suggestions/ice-unwrap-probe-many-result-125876.rs index efa296db47cf9..5292ba3b9dae3 100644 --- a/tests/ui/suggestions/ice-unwrap-probe-many-result-125876.rs +++ b/tests/ui/suggestions/ice-unwrap-probe-many-result-125876.rs @@ -2,7 +2,7 @@ fn main() { std::ptr::from_ref(num).cast_mut().as_deref(); - //~^ ERROR cannot find value `num` in this scope + //~^ ERROR cannot find value `num` //~| ERROR no method named `as_deref` found for raw pointer `*mut _` in the current scope //~| WARN type annotations needed //~| WARN this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! diff --git a/tests/ui/suggestions/ice-unwrap-probe-many-result-125876.stderr b/tests/ui/suggestions/ice-unwrap-probe-many-result-125876.stderr index d610a3b7cadd2..ea0f50d4df22f 100644 --- a/tests/ui/suggestions/ice-unwrap-probe-many-result-125876.stderr +++ b/tests/ui/suggestions/ice-unwrap-probe-many-result-125876.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `num` in this scope +error[E0425]: cannot find value `num` --> $DIR/ice-unwrap-probe-many-result-125876.rs:4:24 | LL | std::ptr::from_ref(num).cast_mut().as_deref(); diff --git a/tests/ui/suggestions/if-let-typo.rs b/tests/ui/suggestions/if-let-typo.rs index 375bd3f03c920..ed889ad007853 100644 --- a/tests/ui/suggestions/if-let-typo.rs +++ b/tests/ui/suggestions/if-let-typo.rs @@ -1,11 +1,11 @@ fn main() { let foo = Some(0); let bar = None; - if Some(x) = foo {} //~ ERROR cannot find value `x` in this scope + if Some(x) = foo {} //~ ERROR cannot find value `x` //~^ ERROR mismatched types if Some(foo) = bar {} //~ ERROR mismatched types if 3 = foo {} //~ ERROR mismatched types if Some(3) = foo {} //~ ERROR mismatched types //~^ ERROR invalid left-hand side of assignment - if x = 5 {} //~ ERROR cannot find value `x` in this scope + if x = 5 {} //~ ERROR cannot find value `x` } diff --git a/tests/ui/suggestions/if-let-typo.stderr b/tests/ui/suggestions/if-let-typo.stderr index 02148b7f7adfd..cc73bfd187735 100644 --- a/tests/ui/suggestions/if-let-typo.stderr +++ b/tests/ui/suggestions/if-let-typo.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `x` in this scope +error[E0425]: cannot find value `x` --> $DIR/if-let-typo.rs:4:13 | LL | if Some(x) = foo {} @@ -9,7 +9,7 @@ help: you might have meant to use pattern matching LL | if let Some(x) = foo {} | +++ -error[E0425]: cannot find value `x` in this scope +error[E0425]: cannot find value `x` --> $DIR/if-let-typo.rs:10:8 | LL | if x = 5 {} diff --git a/tests/ui/suggestions/issue-104086-suggest-let.rs b/tests/ui/suggestions/issue-104086-suggest-let.rs index d22ad27d0e031..5c415afee6d37 100644 --- a/tests/ui/suggestions/issue-104086-suggest-let.rs +++ b/tests/ui/suggestions/issue-104086-suggest-let.rs @@ -1,30 +1,30 @@ fn main() { x = x = x; - //~^ ERROR cannot find value `x` in this scope - //~| ERROR cannot find value `x` in this scope - //~| ERROR cannot find value `x` in this scope + //~^ ERROR cannot find value `x` + //~| ERROR cannot find value `x` + //~| ERROR cannot find value `x` x = y = y = y; - //~^ ERROR cannot find value `y` in this scope - //~| ERROR cannot find value `y` in this scope - //~| ERROR cannot find value `y` in this scope - //~| ERROR cannot find value `x` in this scope + //~^ ERROR cannot find value `y` + //~| ERROR cannot find value `y` + //~| ERROR cannot find value `y` + //~| ERROR cannot find value `x` x = y = y; - //~^ ERROR cannot find value `x` in this scope - //~| ERROR cannot find value `y` in this scope - //~| ERROR cannot find value `y` in this scope + //~^ ERROR cannot find value `x` + //~| ERROR cannot find value `y` + //~| ERROR cannot find value `y` x = x = y; - //~^ ERROR cannot find value `x` in this scope - //~| ERROR cannot find value `x` in this scope - //~| ERROR cannot find value `y` in this scope + //~^ ERROR cannot find value `x` + //~| ERROR cannot find value `x` + //~| ERROR cannot find value `y` x = x; // will suggest add `let` - //~^ ERROR cannot find value `x` in this scope - //~| ERROR cannot find value `x` in this scope + //~^ ERROR cannot find value `x` + //~| ERROR cannot find value `x` x = y // will suggest add `let` - //~^ ERROR cannot find value `x` in this scope - //~| ERROR cannot find value `y` in this scope + //~^ ERROR cannot find value `x` + //~| ERROR cannot find value `y` } diff --git a/tests/ui/suggestions/issue-104086-suggest-let.stderr b/tests/ui/suggestions/issue-104086-suggest-let.stderr index fb4ea3121ac67..ca54d93b1b424 100644 --- a/tests/ui/suggestions/issue-104086-suggest-let.stderr +++ b/tests/ui/suggestions/issue-104086-suggest-let.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `x` in this scope +error[E0425]: cannot find value `x` --> $DIR/issue-104086-suggest-let.rs:2:5 | LL | x = x = x; @@ -9,19 +9,19 @@ help: you might have meant to introduce a new binding LL | let x = x = x; | +++ -error[E0425]: cannot find value `x` in this scope +error[E0425]: cannot find value `x` --> $DIR/issue-104086-suggest-let.rs:2:9 | LL | x = x = x; | ^ not found in this scope -error[E0425]: cannot find value `x` in this scope +error[E0425]: cannot find value `x` --> $DIR/issue-104086-suggest-let.rs:2:13 | LL | x = x = x; | ^ not found in this scope -error[E0425]: cannot find value `x` in this scope +error[E0425]: cannot find value `x` --> $DIR/issue-104086-suggest-let.rs:7:5 | LL | x = y = y = y; @@ -32,25 +32,25 @@ help: you might have meant to introduce a new binding LL | let x = y = y = y; | +++ -error[E0425]: cannot find value `y` in this scope +error[E0425]: cannot find value `y` --> $DIR/issue-104086-suggest-let.rs:7:9 | LL | x = y = y = y; | ^ not found in this scope -error[E0425]: cannot find value `y` in this scope +error[E0425]: cannot find value `y` --> $DIR/issue-104086-suggest-let.rs:7:13 | LL | x = y = y = y; | ^ not found in this scope -error[E0425]: cannot find value `y` in this scope +error[E0425]: cannot find value `y` --> $DIR/issue-104086-suggest-let.rs:7:17 | LL | x = y = y = y; | ^ not found in this scope -error[E0425]: cannot find value `x` in this scope +error[E0425]: cannot find value `x` --> $DIR/issue-104086-suggest-let.rs:13:5 | LL | x = y = y; @@ -61,19 +61,19 @@ help: you might have meant to introduce a new binding LL | let x = y = y; | +++ -error[E0425]: cannot find value `y` in this scope +error[E0425]: cannot find value `y` --> $DIR/issue-104086-suggest-let.rs:13:9 | LL | x = y = y; | ^ not found in this scope -error[E0425]: cannot find value `y` in this scope +error[E0425]: cannot find value `y` --> $DIR/issue-104086-suggest-let.rs:13:13 | LL | x = y = y; | ^ not found in this scope -error[E0425]: cannot find value `x` in this scope +error[E0425]: cannot find value `x` --> $DIR/issue-104086-suggest-let.rs:18:5 | LL | x = x = y; @@ -84,19 +84,19 @@ help: you might have meant to introduce a new binding LL | let x = x = y; | +++ -error[E0425]: cannot find value `x` in this scope +error[E0425]: cannot find value `x` --> $DIR/issue-104086-suggest-let.rs:18:9 | LL | x = x = y; | ^ not found in this scope -error[E0425]: cannot find value `y` in this scope +error[E0425]: cannot find value `y` --> $DIR/issue-104086-suggest-let.rs:18:13 | LL | x = x = y; | ^ not found in this scope -error[E0425]: cannot find value `x` in this scope +error[E0425]: cannot find value `x` --> $DIR/issue-104086-suggest-let.rs:23:5 | LL | x = x; // will suggest add `let` @@ -107,13 +107,13 @@ help: you might have meant to introduce a new binding LL | let x = x; // will suggest add `let` | +++ -error[E0425]: cannot find value `x` in this scope +error[E0425]: cannot find value `x` --> $DIR/issue-104086-suggest-let.rs:23:9 | LL | x = x; // will suggest add `let` | ^ not found in this scope -error[E0425]: cannot find value `x` in this scope +error[E0425]: cannot find value `x` --> $DIR/issue-104086-suggest-let.rs:27:5 | LL | x = y // will suggest add `let` @@ -124,7 +124,7 @@ help: you might have meant to introduce a new binding LL | let x = y // will suggest add `let` | +++ -error[E0425]: cannot find value `y` in this scope +error[E0425]: cannot find value `y` --> $DIR/issue-104086-suggest-let.rs:27:9 | LL | x = y // will suggest add `let` diff --git a/tests/ui/suggestions/issue-104287.rs b/tests/ui/suggestions/issue-104287.rs index 37b3339fa923e..3d4c8c5d4d357 100644 --- a/tests/ui/suggestions/issue-104287.rs +++ b/tests/ui/suggestions/issue-104287.rs @@ -9,5 +9,5 @@ fn main() { let x = S; foo::<()>(x); //~^ ERROR method takes 0 generic arguments but 1 generic argument was supplied - //~| ERROR cannot find function `foo` in this scope + //~| ERROR cannot find function `foo` } diff --git a/tests/ui/suggestions/issue-104287.stderr b/tests/ui/suggestions/issue-104287.stderr index ed59b2e7a2d3b..7696b0dd7f569 100644 --- a/tests/ui/suggestions/issue-104287.stderr +++ b/tests/ui/suggestions/issue-104287.stderr @@ -12,7 +12,7 @@ note: method defined here, with 0 generic parameters LL | fn foo(&self) {} | ^^^ -error[E0425]: cannot find function `foo` in this scope +error[E0425]: cannot find function `foo` --> $DIR/issue-104287.rs:10:5 | LL | foo::<()>(x); diff --git a/tests/ui/suggestions/issue-66968-suggest-sorted-words.stderr b/tests/ui/suggestions/issue-66968-suggest-sorted-words.stderr index ce0087fbfcbab..fd88444e8f9f9 100644 --- a/tests/ui/suggestions/issue-66968-suggest-sorted-words.stderr +++ b/tests/ui/suggestions/issue-66968-suggest-sorted-words.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `a_variable_longer_name` in this scope +error[E0425]: cannot find value `a_variable_longer_name` --> $DIR/issue-66968-suggest-sorted-words.rs:3:20 | LL | println!("{}", a_variable_longer_name); diff --git a/tests/ui/suggestions/method-access-to-range-literal-typo.stderr b/tests/ui/suggestions/method-access-to-range-literal-typo.stderr index b1fb0254cd9cf..28ae1a6b57f16 100644 --- a/tests/ui/suggestions/method-access-to-range-literal-typo.stderr +++ b/tests/ui/suggestions/method-access-to-range-literal-typo.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find function `foo` in this scope +error[E0425]: cannot find function `foo` --> $DIR/method-access-to-range-literal-typo.rs:26:22 | LL | self.option..foo().get(0) diff --git a/tests/ui/suggestions/no-extern-crate-in-type.stderr b/tests/ui/suggestions/no-extern-crate-in-type.stderr index 384b17d1e2b48..8dce68802f55d 100644 --- a/tests/ui/suggestions/no-extern-crate-in-type.stderr +++ b/tests/ui/suggestions/no-extern-crate-in-type.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `Foo` in this scope +error[E0412]: cannot find type `Foo` --> $DIR/no-extern-crate-in-type.rs:5:22 | LL | type Output = Option; diff --git a/tests/ui/suggestions/non_ascii_ident.rs b/tests/ui/suggestions/non_ascii_ident.rs index 9c89714751826..45d9b1bdf0b12 100644 --- a/tests/ui/suggestions/non_ascii_ident.rs +++ b/tests/ui/suggestions/non_ascii_ident.rs @@ -1,7 +1,7 @@ fn main() { // There shall be no suggestions here. In particular not `Ok`. - let _ = 读文; //~ ERROR cannot find value `读文` in this scope + let _ = 读文; //~ ERROR cannot find value `读文` let f = 0f32; // Important line to make this an ICE regression test - 读文(f); //~ ERROR cannot find function `读文` in this scope + 读文(f); //~ ERROR cannot find function `读文` } diff --git a/tests/ui/suggestions/non_ascii_ident.stderr b/tests/ui/suggestions/non_ascii_ident.stderr index fdcc64aef3681..f084eba3afc84 100644 --- a/tests/ui/suggestions/non_ascii_ident.stderr +++ b/tests/ui/suggestions/non_ascii_ident.stderr @@ -1,10 +1,10 @@ -error[E0425]: cannot find value `读文` in this scope +error[E0425]: cannot find value `读文` --> $DIR/non_ascii_ident.rs:3:13 | LL | let _ = 读文; | ^^^^ not found in this scope -error[E0425]: cannot find function `读文` in this scope +error[E0425]: cannot find function `读文` --> $DIR/non_ascii_ident.rs:6:5 | LL | 读文(f); diff --git a/tests/ui/suggestions/raw-name-use-suggestion.rs b/tests/ui/suggestions/raw-name-use-suggestion.rs index 0a8073c0be2ea..c5ccc7566111d 100644 --- a/tests/ui/suggestions/raw-name-use-suggestion.rs +++ b/tests/ui/suggestions/raw-name-use-suggestion.rs @@ -5,5 +5,5 @@ mod foo { fn main() { foo::let(); //~ ERROR expected identifier, found keyword `let` - r#break(); //~ ERROR cannot find function `r#break` in this scope + r#break(); //~ ERROR cannot find function `r#break` } diff --git a/tests/ui/suggestions/raw-name-use-suggestion.stderr b/tests/ui/suggestions/raw-name-use-suggestion.stderr index fb070ffc33230..2ebfc27a9e3ba 100644 --- a/tests/ui/suggestions/raw-name-use-suggestion.stderr +++ b/tests/ui/suggestions/raw-name-use-suggestion.stderr @@ -20,7 +20,7 @@ help: escape `let` to use it as an identifier LL | foo::r#let(); | ++ -error[E0425]: cannot find function `r#break` in this scope +error[E0425]: cannot find function `r#break` --> $DIR/raw-name-use-suggestion.rs:8:5 | LL | r#break(); diff --git a/tests/ui/suggestions/silenced-binding-typo.stderr b/tests/ui/suggestions/silenced-binding-typo.stderr index a1e8b9e30d4b7..d57909036d70d 100644 --- a/tests/ui/suggestions/silenced-binding-typo.stderr +++ b/tests/ui/suggestions/silenced-binding-typo.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `x` in this scope +error[E0425]: cannot find value `x` --> $DIR/silenced-binding-typo.rs:4:14 | LL | let _x = 42; diff --git a/tests/ui/suggestions/suggest-let-for-assignment.fixed b/tests/ui/suggestions/suggest-let-for-assignment.fixed index 80b9333827ec9..5010e290c8342 100644 --- a/tests/ui/suggestions/suggest-let-for-assignment.fixed +++ b/tests/ui/suggestions/suggest-let-for-assignment.fixed @@ -1,23 +1,23 @@ //@ run-rustfix fn main() { - let demo = 1; //~ ERROR cannot find value `demo` in this scope - dbg!(demo); //~ ERROR cannot find value `demo` in this scope + let demo = 1; //~ ERROR cannot find value `demo` + dbg!(demo); //~ ERROR cannot find value `demo` - let x = "x"; //~ ERROR cannot find value `x` in this scope - println!("x: {}", x); //~ ERROR cannot find value `x` in this scope + let x = "x"; //~ ERROR cannot find value `x` + println!("x: {}", x); //~ ERROR cannot find value `x` - let some_variable = 6; //~ cannot find value `let_some_variable` in this scope - println!("some_variable: {}", some_variable); //~ ERROR cannot find value `some_variable` in this scope + let some_variable = 6; //~ cannot find value `let_some_variable` + println!("some_variable: {}", some_variable); //~ ERROR cannot find value `some_variable` - let other_variable = 6; //~ cannot find value `letother_variable` in this scope - println!("other_variable: {}", other_variable); //~ ERROR cannot find value `other_variable` in this scope + let other_variable = 6; //~ cannot find value `letother_variable` + println!("other_variable: {}", other_variable); //~ ERROR cannot find value `other_variable` if x == "x" { - //~^ ERROR cannot find value `x` in this scope + //~^ ERROR cannot find value `x` println!("x is 1"); } - let y = 1 + 2; //~ ERROR cannot find value `y` in this scope - println!("y: {}", y); //~ ERROR cannot find value `y` in this scope + let y = 1 + 2; //~ ERROR cannot find value `y` + println!("y: {}", y); //~ ERROR cannot find value `y` } diff --git a/tests/ui/suggestions/suggest-let-for-assignment.rs b/tests/ui/suggestions/suggest-let-for-assignment.rs index 22560083d34c9..59005a29d5e88 100644 --- a/tests/ui/suggestions/suggest-let-for-assignment.rs +++ b/tests/ui/suggestions/suggest-let-for-assignment.rs @@ -1,23 +1,23 @@ //@ run-rustfix fn main() { - demo = 1; //~ ERROR cannot find value `demo` in this scope - dbg!(demo); //~ ERROR cannot find value `demo` in this scope + demo = 1; //~ ERROR cannot find value `demo` + dbg!(demo); //~ ERROR cannot find value `demo` - x = "x"; //~ ERROR cannot find value `x` in this scope - println!("x: {}", x); //~ ERROR cannot find value `x` in this scope + x = "x"; //~ ERROR cannot find value `x` + println!("x: {}", x); //~ ERROR cannot find value `x` - let_some_variable = 6; //~ cannot find value `let_some_variable` in this scope - println!("some_variable: {}", some_variable); //~ ERROR cannot find value `some_variable` in this scope + let_some_variable = 6; //~ cannot find value `let_some_variable` + println!("some_variable: {}", some_variable); //~ ERROR cannot find value `some_variable` - letother_variable = 6; //~ cannot find value `letother_variable` in this scope - println!("other_variable: {}", other_variable); //~ ERROR cannot find value `other_variable` in this scope + letother_variable = 6; //~ cannot find value `letother_variable` + println!("other_variable: {}", other_variable); //~ ERROR cannot find value `other_variable` if x == "x" { - //~^ ERROR cannot find value `x` in this scope + //~^ ERROR cannot find value `x` println!("x is 1"); } - y = 1 + 2; //~ ERROR cannot find value `y` in this scope - println!("y: {}", y); //~ ERROR cannot find value `y` in this scope + y = 1 + 2; //~ ERROR cannot find value `y` + println!("y: {}", y); //~ ERROR cannot find value `y` } diff --git a/tests/ui/suggestions/suggest-let-for-assignment.stderr b/tests/ui/suggestions/suggest-let-for-assignment.stderr index 8d97dbeb14a7a..9dbb02b8afda5 100644 --- a/tests/ui/suggestions/suggest-let-for-assignment.stderr +++ b/tests/ui/suggestions/suggest-let-for-assignment.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `demo` in this scope +error[E0425]: cannot find value `demo` --> $DIR/suggest-let-for-assignment.rs:4:5 | LL | demo = 1; @@ -9,13 +9,13 @@ help: you might have meant to introduce a new binding LL | let demo = 1; | +++ -error[E0425]: cannot find value `demo` in this scope +error[E0425]: cannot find value `demo` --> $DIR/suggest-let-for-assignment.rs:5:10 | LL | dbg!(demo); | ^^^^ not found in this scope -error[E0425]: cannot find value `x` in this scope +error[E0425]: cannot find value `x` --> $DIR/suggest-let-for-assignment.rs:7:5 | LL | x = "x"; @@ -26,13 +26,13 @@ help: you might have meant to introduce a new binding LL | let x = "x"; | +++ -error[E0425]: cannot find value `x` in this scope +error[E0425]: cannot find value `x` --> $DIR/suggest-let-for-assignment.rs:8:23 | LL | println!("x: {}", x); | ^ not found in this scope -error[E0425]: cannot find value `let_some_variable` in this scope +error[E0425]: cannot find value `let_some_variable` --> $DIR/suggest-let-for-assignment.rs:10:5 | LL | let_some_variable = 6; @@ -43,13 +43,13 @@ help: you might have meant to introduce a new binding LL | let some_variable = 6; | ~~~~~~~~~~~~~~~~~ -error[E0425]: cannot find value `some_variable` in this scope +error[E0425]: cannot find value `some_variable` --> $DIR/suggest-let-for-assignment.rs:11:35 | LL | println!("some_variable: {}", some_variable); | ^^^^^^^^^^^^^ not found in this scope -error[E0425]: cannot find value `letother_variable` in this scope +error[E0425]: cannot find value `letother_variable` --> $DIR/suggest-let-for-assignment.rs:13:5 | LL | letother_variable = 6; @@ -60,19 +60,19 @@ help: you might have meant to introduce a new binding LL | let other_variable = 6; | ~~~~~~~~~~~~~~~~~~ -error[E0425]: cannot find value `other_variable` in this scope +error[E0425]: cannot find value `other_variable` --> $DIR/suggest-let-for-assignment.rs:14:36 | LL | println!("other_variable: {}", other_variable); | ^^^^^^^^^^^^^^ not found in this scope -error[E0425]: cannot find value `x` in this scope +error[E0425]: cannot find value `x` --> $DIR/suggest-let-for-assignment.rs:16:8 | LL | if x == "x" { | ^ not found in this scope -error[E0425]: cannot find value `y` in this scope +error[E0425]: cannot find value `y` --> $DIR/suggest-let-for-assignment.rs:21:5 | LL | y = 1 + 2; @@ -83,7 +83,7 @@ help: you might have meant to introduce a new binding LL | let y = 1 + 2; | +++ -error[E0425]: cannot find value `y` in this scope +error[E0425]: cannot find value `y` --> $DIR/suggest-let-for-assignment.rs:22:23 | LL | println!("y: {}", y); diff --git a/tests/ui/suggestions/suggest_print_over_printf.rs b/tests/ui/suggestions/suggest_print_over_printf.rs index 124ddec50cbbe..8272172abaa5a 100644 --- a/tests/ui/suggestions/suggest_print_over_printf.rs +++ b/tests/ui/suggestions/suggest_print_over_printf.rs @@ -3,6 +3,6 @@ fn main() { let x = 4; printf("%d", x); - //~^ ERROR cannot find function `printf` in this scope + //~^ ERROR cannot find function `printf` //~| HELP you may have meant to use the `print` macro } diff --git a/tests/ui/suggestions/suggest_print_over_printf.stderr b/tests/ui/suggestions/suggest_print_over_printf.stderr index 8a79745133c93..b81fc80599ec4 100644 --- a/tests/ui/suggestions/suggest_print_over_printf.stderr +++ b/tests/ui/suggestions/suggest_print_over_printf.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find function `printf` in this scope +error[E0425]: cannot find function `printf` --> $DIR/suggest_print_over_printf.rs:5:5 | LL | printf("%d", x); diff --git a/tests/ui/suggestions/type-ascription-instead-of-path-in-type.rs b/tests/ui/suggestions/type-ascription-instead-of-path-in-type.rs index 99f943d71e9e5..353961ab00ea1 100644 --- a/tests/ui/suggestions/type-ascription-instead-of-path-in-type.rs +++ b/tests/ui/suggestions/type-ascription-instead-of-path-in-type.rs @@ -4,7 +4,7 @@ enum A { fn main() { let _: Vec = A::B; - //~^ ERROR cannot find trait `B` in this scope + //~^ ERROR cannot find trait `B` //~| HELP you might have meant to write a path instead of an associated type bound //~| ERROR struct takes at least 1 generic argument but 0 generic arguments were supplied //~| HELP add missing generic argument diff --git a/tests/ui/suggestions/type-ascription-instead-of-path-in-type.stderr b/tests/ui/suggestions/type-ascription-instead-of-path-in-type.stderr index 56b6a69a283f4..c675f98c51033 100644 --- a/tests/ui/suggestions/type-ascription-instead-of-path-in-type.stderr +++ b/tests/ui/suggestions/type-ascription-instead-of-path-in-type.stderr @@ -1,4 +1,4 @@ -error[E0405]: cannot find trait `B` in this scope +error[E0405]: cannot find trait `B` --> $DIR/type-ascription-instead-of-path-in-type.rs:6:18 | LL | let _: Vec = A::B; diff --git a/tests/ui/suggestions/type-not-found-in-adt-field.rs b/tests/ui/suggestions/type-not-found-in-adt-field.rs index 4cbfe58d35703..3fe05ac1bd09b 100644 --- a/tests/ui/suggestions/type-not-found-in-adt-field.rs +++ b/tests/ui/suggestions/type-not-found-in-adt-field.rs @@ -1,9 +1,9 @@ struct Struct { - m: Vec>, //~ ERROR cannot find type `Someunknownname` in this scope - //~^ NOTE not found in this scope + m: Vec>, //~ ERROR cannot find type `Someunknownname` + //~^ NOTE not found } struct OtherStruct { //~ HELP you might be missing a type parameter - m: K, //~ ERROR cannot find type `K` in this scope - //~^ NOTE not found in this scope + m: K, //~ ERROR cannot find type `K` + //~^ NOTE not found } fn main() {} diff --git a/tests/ui/suggestions/type-not-found-in-adt-field.stderr b/tests/ui/suggestions/type-not-found-in-adt-field.stderr index 934ba87bbaa88..77c4c5b73d757 100644 --- a/tests/ui/suggestions/type-not-found-in-adt-field.stderr +++ b/tests/ui/suggestions/type-not-found-in-adt-field.stderr @@ -1,10 +1,10 @@ -error[E0412]: cannot find type `Someunknownname` in this scope +error[E0412]: cannot find type `Someunknownname` --> $DIR/type-not-found-in-adt-field.rs:2:12 | LL | m: Vec>, | ^^^^^^^^^^^^^^^ not found in this scope -error[E0412]: cannot find type `K` in this scope +error[E0412]: cannot find type `K` --> $DIR/type-not-found-in-adt-field.rs:6:8 | LL | m: K, diff --git a/tests/ui/suggestions/while-let-typo.rs b/tests/ui/suggestions/while-let-typo.rs index 21b254054bbc0..06a277b0b9ec0 100644 --- a/tests/ui/suggestions/while-let-typo.rs +++ b/tests/ui/suggestions/while-let-typo.rs @@ -1,9 +1,9 @@ fn main() { let foo = Some(0); let bar = None; - while Some(x) = foo {} //~ ERROR cannot find value `x` in this scope + while Some(x) = foo {} //~ ERROR cannot find value `x` while Some(foo) = bar {} //~ ERROR mismatched types while 3 = foo {} //~ ERROR mismatched types while Some(3) = foo {} //~ ERROR invalid left-hand side of assignment - while x = 5 {} //~ ERROR cannot find value `x` in this scope + while x = 5 {} //~ ERROR cannot find value `x` } diff --git a/tests/ui/suggestions/while-let-typo.stderr b/tests/ui/suggestions/while-let-typo.stderr index 69a7e5761d421..abc9fe2c5045c 100644 --- a/tests/ui/suggestions/while-let-typo.stderr +++ b/tests/ui/suggestions/while-let-typo.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `x` in this scope +error[E0425]: cannot find value `x` --> $DIR/while-let-typo.rs:4:16 | LL | while Some(x) = foo {} @@ -9,7 +9,7 @@ help: you might have meant to use pattern matching LL | while let Some(x) = foo {} | +++ -error[E0425]: cannot find value `x` in this scope +error[E0425]: cannot find value `x` --> $DIR/while-let-typo.rs:8:11 | LL | while x = 5 {} diff --git a/tests/ui/tool-attributes/tool-attributes-misplaced-1.rs b/tests/ui/tool-attributes/tool-attributes-misplaced-1.rs index bf45ba2ed8227..03f5482f000f4 100644 --- a/tests/ui/tool-attributes/tool-attributes-misplaced-1.rs +++ b/tests/ui/tool-attributes/tool-attributes-misplaced-1.rs @@ -1,18 +1,18 @@ type A = rustfmt; //~ ERROR expected type, found tool module `rustfmt` type B = rustfmt::skip; //~ ERROR expected type, found tool attribute `rustfmt::skip` -#[derive(rustfmt)] //~ ERROR cannot find derive macro `rustfmt` in this scope - //~| ERROR cannot find derive macro `rustfmt` in this scope +#[derive(rustfmt)] //~ ERROR cannot find derive macro `rustfmt` + //~| ERROR cannot find derive macro `rustfmt` struct S; // Interpreted as an unstable custom attribute -#[rustfmt] //~ ERROR cannot find attribute `rustfmt` in this scope +#[rustfmt] //~ ERROR cannot find attribute `rustfmt` fn check() {} #[rustfmt::skip] // OK fn main() { rustfmt; //~ ERROR expected value, found tool module `rustfmt` - rustfmt!(); //~ ERROR cannot find macro `rustfmt` in this scope + rustfmt!(); //~ ERROR cannot find macro `rustfmt` rustfmt::skip; //~ ERROR expected value, found tool attribute `rustfmt::skip` } diff --git a/tests/ui/track-diagnostics/track.stderr b/tests/ui/track-diagnostics/track.stderr index 436f9ecf93dec..462c741d41897 100644 --- a/tests/ui/track-diagnostics/track.stderr +++ b/tests/ui/track-diagnostics/track.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `rust` in this scope +error[E0425]: cannot find value `rust` --> $DIR/track.rs:LL:CC | LL | break rust diff --git a/tests/ui/track-diagnostics/track3.stderr b/tests/ui/track-diagnostics/track3.stderr index dc468d7e8eeb1..f7c451365279d 100644 --- a/tests/ui/track-diagnostics/track3.stderr +++ b/tests/ui/track-diagnostics/track3.stderr @@ -1,4 +1,4 @@ -error[E0422]: cannot find struct, variant or union type `Blah` in this scope +error[E0422]: cannot find struct, variant or union type `Blah` --> $DIR/track3.rs:LL:CC | LL | let _unimported = Blah { field: u8 }; diff --git a/tests/ui/trait-bounds/ice-unsized-struct-arg-issue-121612.rs b/tests/ui/trait-bounds/ice-unsized-struct-arg-issue-121612.rs index 5ca4f49c3bac5..765740c089181 100644 --- a/tests/ui/trait-bounds/ice-unsized-struct-arg-issue-121612.rs +++ b/tests/ui/trait-bounds/ice-unsized-struct-arg-issue-121612.rs @@ -3,8 +3,8 @@ trait Trait {} impl Trait for bool {} struct MySlice Idx>(bool, T); -//~^ ERROR cannot find type `Idx` in this scope -//~| ERROR cannot find type `Idx` in this scope +//~^ ERROR cannot find type `Idx` +//~| ERROR cannot find type `Idx` type MySliceBool = MySlice<[bool]>; const MYSLICE_GOOD: &MySliceBool = &MySlice(true, [false]); //~^ ERROR the size for values of type `[bool]` cannot be known at compilation time diff --git a/tests/ui/trait-bounds/ice-unsized-struct-arg-issue-121612.stderr b/tests/ui/trait-bounds/ice-unsized-struct-arg-issue-121612.stderr index 0be80e9479f0b..29e77d55b5869 100644 --- a/tests/ui/trait-bounds/ice-unsized-struct-arg-issue-121612.stderr +++ b/tests/ui/trait-bounds/ice-unsized-struct-arg-issue-121612.stderr @@ -1,10 +1,10 @@ -error[E0412]: cannot find type `Idx` in this scope +error[E0412]: cannot find type `Idx` --> $DIR/ice-unsized-struct-arg-issue-121612.rs:5:30 | LL | struct MySlice Idx>(bool, T); | ^^^ not found in this scope -error[E0412]: cannot find type `Idx` in this scope +error[E0412]: cannot find type `Idx` --> $DIR/ice-unsized-struct-arg-issue-121612.rs:5:38 | LL | struct MySlice Idx>(bool, T); diff --git a/tests/ui/trait-bounds/ice-unsized-tuple-const-issue-121443.rs b/tests/ui/trait-bounds/ice-unsized-tuple-const-issue-121443.rs index c3a2ab82adc6a..636fb68c4c369 100644 --- a/tests/ui/trait-bounds/ice-unsized-tuple-const-issue-121443.rs +++ b/tests/ui/trait-bounds/ice-unsized-tuple-const-issue-121443.rs @@ -6,7 +6,7 @@ type Fn = dyn FnOnce() -> u8; const TEST: Fn = some_fn; -//~^ ERROR cannot find value `some_fn` in this scope +//~^ ERROR cannot find value `some_fn` //~| ERROR the size for values of type `(dyn FnOnce() -> u8 + 'static)` cannot be known at compilation time //~| ERROR the size for values of type `(dyn FnOnce() -> u8 + 'static)` cannot be known at compilation time const TEST2: (Fn, u8) = (TEST, 0); diff --git a/tests/ui/trait-bounds/ice-unsized-tuple-const-issue-121443.stderr b/tests/ui/trait-bounds/ice-unsized-tuple-const-issue-121443.stderr index 0e92979ccd507..a6db24897dc50 100644 --- a/tests/ui/trait-bounds/ice-unsized-tuple-const-issue-121443.stderr +++ b/tests/ui/trait-bounds/ice-unsized-tuple-const-issue-121443.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `some_fn` in this scope +error[E0425]: cannot find value `some_fn` --> $DIR/ice-unsized-tuple-const-issue-121443.rs:8:18 | LL | const TEST: Fn = some_fn; diff --git a/tests/ui/trait-bounds/impl-bound-with-references-error.rs b/tests/ui/trait-bounds/impl-bound-with-references-error.rs index 5ba35da83839e..1eb4360cbb5a6 100644 --- a/tests/ui/trait-bounds/impl-bound-with-references-error.rs +++ b/tests/ui/trait-bounds/impl-bound-with-references-error.rs @@ -10,7 +10,7 @@ impl From for LabelText //~^ ERROR conflicting implementations of trait `From` for type `LabelText` [E0119] where T: Into>, - //~^ ERROR cannot find type `Cow` in this scope [E0412] + //~^ ERROR cannot find type `Cow` [E0412] { fn from(text: T) -> Self { LabelText::Plain(text.into()) //~ ERROR expected function, found `LabelText` diff --git a/tests/ui/trait-bounds/impl-bound-with-references-error.stderr b/tests/ui/trait-bounds/impl-bound-with-references-error.stderr index b3ac5544e38f5..ed2da8268a04a 100644 --- a/tests/ui/trait-bounds/impl-bound-with-references-error.stderr +++ b/tests/ui/trait-bounds/impl-bound-with-references-error.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `Cow` in this scope +error[E0412]: cannot find type `Cow` --> $DIR/impl-bound-with-references-error.rs:12:13 | LL | T: Into>, diff --git a/tests/ui/trait-bounds/shadowed-path-in-trait-bound-suggestion.stderr b/tests/ui/trait-bounds/shadowed-path-in-trait-bound-suggestion.stderr index e2a72697501f2..c076219d9631d 100644 --- a/tests/ui/trait-bounds/shadowed-path-in-trait-bound-suggestion.stderr +++ b/tests/ui/trait-bounds/shadowed-path-in-trait-bound-suggestion.stderr @@ -1,4 +1,4 @@ -error[E0405]: cannot find trait `Trait` in `A` +error[E0405]: cannot find trait `Trait` --> $DIR/shadowed-path-in-trait-bound-suggestion.rs:9:24 | LL | pub struct A(pub H); diff --git a/tests/ui/traits/associated_type_bound/assoc_type_bound_with_struct.rs b/tests/ui/traits/associated_type_bound/assoc_type_bound_with_struct.rs index 8e43b7249f7c0..4d5e96cae02ec 100644 --- a/tests/ui/traits/associated_type_bound/assoc_type_bound_with_struct.rs +++ b/tests/ui/traits/associated_type_bound/assoc_type_bound_with_struct.rs @@ -18,6 +18,6 @@ fn qux<'a, T: Bar>(_: &'a T) where <&'a T as Bar>::Baz: String { //~ ERROR expec fn issue_95327() where ::Assoc: String {} //~^ ERROR expected trait, found struct -//~| ERROR cannot find trait `Unresolved` in this scope +//~| ERROR cannot find trait `Unresolved` fn main() {} diff --git a/tests/ui/traits/associated_type_bound/assoc_type_bound_with_struct.stderr b/tests/ui/traits/associated_type_bound/assoc_type_bound_with_struct.stderr index 0020f9e416df2..f5503f5c09044 100644 --- a/tests/ui/traits/associated_type_bound/assoc_type_bound_with_struct.stderr +++ b/tests/ui/traits/associated_type_bound/assoc_type_bound_with_struct.stderr @@ -70,7 +70,7 @@ help: a trait with a similar name exists LL | fn qux<'a, T: Bar>(_: &'a T) where <&'a T as Bar>::Baz: ToString { | ~~~~~~~~ -error[E0405]: cannot find trait `Unresolved` in this scope +error[E0405]: cannot find trait `Unresolved` --> $DIR/assoc_type_bound_with_struct.rs:19:31 | LL | fn issue_95327() where ::Assoc: String {} diff --git a/tests/ui/traits/dont-autoderef-ty-with-escaping-var.rs b/tests/ui/traits/dont-autoderef-ty-with-escaping-var.rs index d5ba3847ac38c..cccb0c8099927 100644 --- a/tests/ui/traits/dont-autoderef-ty-with-escaping-var.rs +++ b/tests/ui/traits/dont-autoderef-ty-with-escaping-var.rs @@ -15,7 +15,7 @@ where fn coerce_lifetime2() { >::ref_foo(unknown); - //~^ ERROR cannot find value `unknown` in this scope + //~^ ERROR cannot find value `unknown` //~| ERROR the trait bound `for<'a> &'a mut Vec<&'a u32>: Foo<'static, i32>` is not satisfied } diff --git a/tests/ui/traits/dont-autoderef-ty-with-escaping-var.stderr b/tests/ui/traits/dont-autoderef-ty-with-escaping-var.stderr index fecb05cade758..5d1d3671e194f 100644 --- a/tests/ui/traits/dont-autoderef-ty-with-escaping-var.stderr +++ b/tests/ui/traits/dont-autoderef-ty-with-escaping-var.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `unknown` in this scope +error[E0425]: cannot find value `unknown` --> $DIR/dont-autoderef-ty-with-escaping-var.rs:17:35 | LL | >::ref_foo(unknown); diff --git a/tests/ui/traits/dont-match-error-ty-with-calller-supplied-obligation-issue-121941.rs b/tests/ui/traits/dont-match-error-ty-with-calller-supplied-obligation-issue-121941.rs index a08407683d8fe..f5d76683e6ab5 100644 --- a/tests/ui/traits/dont-match-error-ty-with-calller-supplied-obligation-issue-121941.rs +++ b/tests/ui/traits/dont-match-error-ty-with-calller-supplied-obligation-issue-121941.rs @@ -1,5 +1,5 @@ fn function() { - foo == 2; //~ ERROR cannot find value `foo` in this scope [E0425] + foo == 2; //~ ERROR cannot find value `foo` [E0425] } fn main() {} diff --git a/tests/ui/traits/dont-match-error-ty-with-calller-supplied-obligation-issue-121941.stderr b/tests/ui/traits/dont-match-error-ty-with-calller-supplied-obligation-issue-121941.stderr index 2da731dcc4b14..09d593b03916e 100644 --- a/tests/ui/traits/dont-match-error-ty-with-calller-supplied-obligation-issue-121941.stderr +++ b/tests/ui/traits/dont-match-error-ty-with-calller-supplied-obligation-issue-121941.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `foo` in this scope +error[E0425]: cannot find value `foo` --> $DIR/dont-match-error-ty-with-calller-supplied-obligation-issue-121941.rs:2:5 | LL | foo == 2; diff --git a/tests/ui/traits/ignore-err-impls.rs b/tests/ui/traits/ignore-err-impls.rs index 67e880b006a7f..ccfa1fc535c0d 100644 --- a/tests/ui/traits/ignore-err-impls.rs +++ b/tests/ui/traits/ignore-err-impls.rs @@ -4,6 +4,6 @@ trait Generic {} impl<'a, T> Generic<&'a T> for S {} impl Generic for S {} -//~^ ERROR cannot find type `Type` in this scope +//~^ ERROR cannot find type `Type` fn main() {} diff --git a/tests/ui/traits/ignore-err-impls.stderr b/tests/ui/traits/ignore-err-impls.stderr index 955e2d7804981..fa8899d4d6731 100644 --- a/tests/ui/traits/ignore-err-impls.stderr +++ b/tests/ui/traits/ignore-err-impls.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `Type` in this scope +error[E0412]: cannot find type `Type` --> $DIR/ignore-err-impls.rs:6:14 | LL | impl Generic for S {} diff --git a/tests/ui/traits/issue-22384.rs b/tests/ui/traits/issue-22384.rs index 98988f27ecce5..04d90acfba8bc 100644 --- a/tests/ui/traits/issue-22384.rs +++ b/tests/ui/traits/issue-22384.rs @@ -4,5 +4,5 @@ trait Trait { fn main() { <::foobar as Trait>::foo(); - //~^ ERROR cannot find associated type `foobar` in trait `Copy` + //~^ ERROR cannot find associated type `foobar` } diff --git a/tests/ui/traits/issue-22384.stderr b/tests/ui/traits/issue-22384.stderr index f53c95c2b677e..4cc4dc71e6e04 100644 --- a/tests/ui/traits/issue-22384.stderr +++ b/tests/ui/traits/issue-22384.stderr @@ -1,8 +1,8 @@ -error[E0576]: cannot find associated type `foobar` in trait `Copy` +error[E0576]: cannot find associated type `foobar` --> $DIR/issue-22384.rs:6:21 | LL | <::foobar as Trait>::foo(); - | ^^^^^^ not found in `Copy` + | ^^^^^^ not found in trait `Copy` error: aborting due to 1 previous error diff --git a/tests/ui/traits/issue-50480.rs b/tests/ui/traits/issue-50480.rs index ccd35a850f2d7..a5c2f144e086e 100644 --- a/tests/ui/traits/issue-50480.rs +++ b/tests/ui/traits/issue-50480.rs @@ -1,10 +1,10 @@ #[derive(Clone, Copy)] //~^ ERROR the trait `Copy` cannot be implemented for this type struct Foo(N, NotDefined, ::Item, Vec, String); -//~^ ERROR cannot find type `NotDefined` in this scope -//~| ERROR cannot find type `NotDefined` in this scope -//~| ERROR cannot find type `N` in this scope -//~| ERROR cannot find type `N` in this scope +//~^ ERROR cannot find type `NotDefined` +//~| ERROR cannot find type `NotDefined` +//~| ERROR cannot find type `N` +//~| ERROR cannot find type `N` //~| ERROR `i32` is not an iterator //~| ERROR `i32` is not an iterator @@ -12,8 +12,8 @@ struct Foo(N, NotDefined, ::Item, Vec, String); //~^ ERROR the trait `Copy` cannot be implemented for this type //~| ERROR `i32` is not an iterator struct Bar(T, N, NotDefined, ::Item, Vec, String); -//~^ ERROR cannot find type `NotDefined` in this scope -//~| ERROR cannot find type `N` in this scope +//~^ ERROR cannot find type `NotDefined` +//~| ERROR cannot find type `N` //~| ERROR `i32` is not an iterator //~| ERROR `i32` is not an iterator diff --git a/tests/ui/traits/issue-50480.stderr b/tests/ui/traits/issue-50480.stderr index 330b23b5755d7..b9fd86dd2f574 100644 --- a/tests/ui/traits/issue-50480.stderr +++ b/tests/ui/traits/issue-50480.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `N` in this scope +error[E0412]: cannot find type `N` --> $DIR/issue-50480.rs:3:12 | LL | struct Foo(N, NotDefined, ::Item, Vec, String); @@ -9,13 +9,13 @@ help: you might be missing a type parameter LL | struct Foo(N, NotDefined, ::Item, Vec, String); | +++ -error[E0412]: cannot find type `NotDefined` in this scope +error[E0412]: cannot find type `NotDefined` --> $DIR/issue-50480.rs:3:15 | LL | struct Foo(N, NotDefined, ::Item, Vec, String); | ^^^^^^^^^^ not found in this scope -error[E0412]: cannot find type `N` in this scope +error[E0412]: cannot find type `N` --> $DIR/issue-50480.rs:3:12 | LL | struct Foo(N, NotDefined, ::Item, Vec, String); @@ -26,7 +26,7 @@ help: you might be missing a type parameter LL | struct Foo(N, NotDefined, ::Item, Vec, String); | +++ -error[E0412]: cannot find type `NotDefined` in this scope +error[E0412]: cannot find type `NotDefined` --> $DIR/issue-50480.rs:3:15 | LL | struct Foo(N, NotDefined, ::Item, Vec, String); @@ -37,7 +37,7 @@ help: you might be missing a type parameter LL | struct Foo(N, NotDefined, ::Item, Vec, String); | ++++++++++++ -error[E0412]: cannot find type `N` in this scope +error[E0412]: cannot find type `N` --> $DIR/issue-50480.rs:14:18 | LL | struct Bar(T, N, NotDefined, ::Item, Vec, String); @@ -54,7 +54,7 @@ help: you might be missing a type parameter LL | struct Bar(T, N, NotDefined, ::Item, Vec, String); | +++ -error[E0412]: cannot find type `NotDefined` in this scope +error[E0412]: cannot find type `NotDefined` --> $DIR/issue-50480.rs:14:21 | LL | struct Bar(T, N, NotDefined, ::Item, Vec, String); diff --git a/tests/ui/traits/issue-75627.stderr b/tests/ui/traits/issue-75627.stderr index 137985ee04641..82ad7b4e1b3da 100644 --- a/tests/ui/traits/issue-75627.stderr +++ b/tests/ui/traits/issue-75627.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `T` in this scope +error[E0412]: cannot find type `T` --> $DIR/issue-75627.rs:3:26 | LL | unsafe impl Send for Foo {} diff --git a/tests/ui/traits/issue-78372.rs b/tests/ui/traits/issue-78372.rs index b97835bbc57fd..d123e4515dbee 100644 --- a/tests/ui/traits/issue-78372.rs +++ b/tests/ui/traits/issue-78372.rs @@ -1,7 +1,7 @@ use std::ops::DispatchFromDyn; //~ ERROR use of unstable library feature 'dispatch_from_dyn' -struct Smaht(PhantomData); //~ ERROR cannot find type `PhantomData` in this scope -impl DispatchFromDyn> for T {} //~ ERROR cannot find type `U` in this scope -//~^ ERROR cannot find type `MISC` in this scope +struct Smaht(PhantomData); //~ ERROR cannot find type `PhantomData` +impl DispatchFromDyn> for T {} //~ ERROR cannot find type `U` +//~^ ERROR cannot find type `MISC` //~| ERROR use of unstable library feature 'dispatch_from_dyn' //~| ERROR the trait `DispatchFromDyn` may only be implemented for a coercion between structures trait Foo: X {} diff --git a/tests/ui/traits/issue-78372.stderr b/tests/ui/traits/issue-78372.stderr index cdcb0cdf2593d..5daf86367ba7d 100644 --- a/tests/ui/traits/issue-78372.stderr +++ b/tests/ui/traits/issue-78372.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `PhantomData` in this scope +error[E0412]: cannot find type `PhantomData` --> $DIR/issue-78372.rs:2:23 | LL | struct Smaht(PhantomData); @@ -9,7 +9,7 @@ help: consider importing this struct LL + use std::marker::PhantomData; | -error[E0412]: cannot find type `U` in this scope +error[E0412]: cannot find type `U` --> $DIR/issue-78372.rs:3:31 | LL | impl DispatchFromDyn> for T {} @@ -26,7 +26,7 @@ help: you might be missing a type parameter LL | impl DispatchFromDyn> for T {} | +++ -error[E0412]: cannot find type `MISC` in this scope +error[E0412]: cannot find type `MISC` --> $DIR/issue-78372.rs:3:34 | LL | impl DispatchFromDyn> for T {} diff --git a/tests/ui/traits/next-solver/dont-normalize-proj-with-error.rs b/tests/ui/traits/next-solver/dont-normalize-proj-with-error.rs index 2f7ea3bb09548..692e93053cc27 100644 --- a/tests/ui/traits/next-solver/dont-normalize-proj-with-error.rs +++ b/tests/ui/traits/next-solver/dont-normalize-proj-with-error.rs @@ -15,7 +15,7 @@ impl Mirror for Wrapper { fn mirror(_: W) -> Box { todo!() } fn type_error() -> TypeError { todo!() } -//~^ ERROR cannot find type `TypeError` in this scope +//~^ ERROR cannot find type `TypeError` fn main() { let x = mirror(type_error()); diff --git a/tests/ui/traits/next-solver/dont-normalize-proj-with-error.stderr b/tests/ui/traits/next-solver/dont-normalize-proj-with-error.stderr index 576ede52aff2d..dc5628392ce7a 100644 --- a/tests/ui/traits/next-solver/dont-normalize-proj-with-error.stderr +++ b/tests/ui/traits/next-solver/dont-normalize-proj-with-error.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `TypeError` in this scope +error[E0412]: cannot find type `TypeError` --> $DIR/dont-normalize-proj-with-error.rs:17:20 | LL | fn type_error() -> TypeError { todo!() } diff --git a/tests/ui/traits/next-solver/issue-118950-root-region.rs b/tests/ui/traits/next-solver/issue-118950-root-region.rs index 9f6dea5d5bf86..501b906f3f491 100644 --- a/tests/ui/traits/next-solver/issue-118950-root-region.rs +++ b/tests/ui/traits/next-solver/issue-118950-root-region.rs @@ -18,6 +18,6 @@ impl Overlap for T {} impl Overlap fn(Assoc<'a, T>)> for T where Missing: Overlap {} //~^ ERROR conflicting implementations of trait `Overlap` for type `fn(_)` -//~| ERROR cannot find type `Missing` in this scope +//~| ERROR cannot find type `Missing` fn main() {} diff --git a/tests/ui/traits/next-solver/issue-118950-root-region.stderr b/tests/ui/traits/next-solver/issue-118950-root-region.stderr index 17da1f5247963..2af6db20ddcf3 100644 --- a/tests/ui/traits/next-solver/issue-118950-root-region.stderr +++ b/tests/ui/traits/next-solver/issue-118950-root-region.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `Missing` in this scope +error[E0412]: cannot find type `Missing` --> $DIR/issue-118950-root-region.rs:19:55 | LL | impl Overlap fn(Assoc<'a, T>)> for T where Missing: Overlap {} diff --git a/tests/ui/traits/no-fallback-multiple-impls.rs b/tests/ui/traits/no-fallback-multiple-impls.rs index 7ed3796f08b76..aea6d86bfb4dd 100644 --- a/tests/ui/traits/no-fallback-multiple-impls.rs +++ b/tests/ui/traits/no-fallback-multiple-impls.rs @@ -10,7 +10,7 @@ impl Fallback for usize {} fn main() { missing(); - //~^ ERROR cannot find function `missing` in this scope + //~^ ERROR cannot find function `missing` 0.foo(); // But then we shouldn't report an inference ambiguity here... } diff --git a/tests/ui/traits/no-fallback-multiple-impls.stderr b/tests/ui/traits/no-fallback-multiple-impls.stderr index e38c432ca98c8..c2eae3e91a043 100644 --- a/tests/ui/traits/no-fallback-multiple-impls.stderr +++ b/tests/ui/traits/no-fallback-multiple-impls.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find function `missing` in this scope +error[E0425]: cannot find function `missing` --> $DIR/no-fallback-multiple-impls.rs:12:5 | LL | missing(); diff --git a/tests/ui/traits/non_lifetime_binders/binder-defaults-112547.rs b/tests/ui/traits/non_lifetime_binders/binder-defaults-112547.rs index c6bf0dc1f720f..b7b91a5325731 100644 --- a/tests/ui/traits/non_lifetime_binders/binder-defaults-112547.rs +++ b/tests/ui/traits/non_lifetime_binders/binder-defaults-112547.rs @@ -7,7 +7,7 @@ where (||1usize)() }> V: IntoIterator //~^^^ ERROR defaults for generic parameters are not allowed in `for<...>` binders -//~^^ ERROR cannot find type `V` in this scope +//~^^ ERROR cannot find type `V` { } diff --git a/tests/ui/traits/non_lifetime_binders/binder-defaults-112547.stderr b/tests/ui/traits/non_lifetime_binders/binder-defaults-112547.stderr index edc55a3c8e68f..48a5126eedd39 100644 --- a/tests/ui/traits/non_lifetime_binders/binder-defaults-112547.stderr +++ b/tests/ui/traits/non_lifetime_binders/binder-defaults-112547.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `V` in this scope +error[E0412]: cannot find type `V` --> $DIR/binder-defaults-112547.rs:8:4 | LL | }> V: IntoIterator diff --git a/tests/ui/traits/non_lifetime_binders/binder-defaults-118697.rs b/tests/ui/traits/non_lifetime_binders/binder-defaults-118697.rs index 2dc9fb98b153d..fbb1bcbb9d92d 100644 --- a/tests/ui/traits/non_lifetime_binders/binder-defaults-118697.rs +++ b/tests/ui/traits/non_lifetime_binders/binder-defaults-118697.rs @@ -3,7 +3,7 @@ type T = dyn for Fn(()); //~^ ERROR defaults for generic parameters are not allowed in `for<...>` binders -//~| ERROR cannot find type `A` in this scope +//~| ERROR cannot find type `A` //~| ERROR late-bound type parameter not allowed on trait object types fn main() {} diff --git a/tests/ui/traits/non_lifetime_binders/binder-defaults-118697.stderr b/tests/ui/traits/non_lifetime_binders/binder-defaults-118697.stderr index 6b93f52dbfcaa..d0369eda5935e 100644 --- a/tests/ui/traits/non_lifetime_binders/binder-defaults-118697.stderr +++ b/tests/ui/traits/non_lifetime_binders/binder-defaults-118697.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `A` in this scope +error[E0412]: cannot find type `A` --> $DIR/binder-defaults-118697.rs:4:22 | LL | type T = dyn for Fn(()); diff --git a/tests/ui/traits/trait-selection-ice-84727.rs b/tests/ui/traits/trait-selection-ice-84727.rs index 08a282892a59c..c899a6928de2a 100644 --- a/tests/ui/traits/trait-selection-ice-84727.rs +++ b/tests/ui/traits/trait-selection-ice-84727.rs @@ -3,9 +3,9 @@ struct Cell { foreground: Color, - //~^ ERROR cannot find type `Color` in this scope + //~^ ERROR cannot find type `Color` background: Color, - //~^ ERROR cannot find type `Color` in this scope + //~^ ERROR cannot find type `Color` } trait Over { @@ -16,7 +16,7 @@ impl Over, Cell> for Cell where Self: Over, Cell>, - //~^ ERROR cannot find type `Color` in this scope + //~^ ERROR cannot find type `Color` { fn over(self) -> Cell { //~^ ERROR mismatched types @@ -30,7 +30,7 @@ where Cell: Over, Cell>, { fn over(self) -> Cell { - //~^ ERROR cannot find type `NewBg` in this scope + //~^ ERROR cannot find type `NewBg` self.over(); } } diff --git a/tests/ui/traits/trait-selection-ice-84727.stderr b/tests/ui/traits/trait-selection-ice-84727.stderr index d4bc4163897c4..bfd4c1689d5d6 100644 --- a/tests/ui/traits/trait-selection-ice-84727.stderr +++ b/tests/ui/traits/trait-selection-ice-84727.stderr @@ -1,22 +1,22 @@ -error[E0412]: cannot find type `Color` in this scope +error[E0412]: cannot find type `Color` --> $DIR/trait-selection-ice-84727.rs:5:17 | LL | foreground: Color, | ^^^^^ not found in this scope -error[E0412]: cannot find type `Color` in this scope +error[E0412]: cannot find type `Color` --> $DIR/trait-selection-ice-84727.rs:7:17 | LL | background: Color, | ^^^^^ not found in this scope -error[E0412]: cannot find type `Color` in this scope +error[E0412]: cannot find type `Color` --> $DIR/trait-selection-ice-84727.rs:18:16 | LL | Self: Over, Cell>, | ^^^^^ not found in this scope -error[E0412]: cannot find type `NewBg` in this scope +error[E0412]: cannot find type `NewBg` --> $DIR/trait-selection-ice-84727.rs:32:27 | LL | fn over(self) -> Cell { diff --git a/tests/ui/transmutability/issue-101739-1.rs b/tests/ui/transmutability/issue-101739-1.rs index 0695d7d409fe0..81e848ce262d9 100644 --- a/tests/ui/transmutability/issue-101739-1.rs +++ b/tests/ui/transmutability/issue-101739-1.rs @@ -5,7 +5,7 @@ mod assert { pub fn is_transmutable() where - Dst: BikeshedIntrinsicFrom, //~ ERROR cannot find type `Dst` in this scope + Dst: BikeshedIntrinsicFrom, //~ ERROR cannot find type `Dst` //~^ the constant `ASSUME_ALIGNMENT` is not of type `Assume` //~| ERROR: mismatched types { diff --git a/tests/ui/transmutability/issue-101739-1.stderr b/tests/ui/transmutability/issue-101739-1.stderr index 6f79bf7b42468..e587848c2a5c8 100644 --- a/tests/ui/transmutability/issue-101739-1.stderr +++ b/tests/ui/transmutability/issue-101739-1.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `Dst` in this scope +error[E0412]: cannot find type `Dst` --> $DIR/issue-101739-1.rs:8:9 | LL | Dst: BikeshedIntrinsicFrom, diff --git a/tests/ui/transmutability/malformed-program-gracefulness/unknown_dst.stderr b/tests/ui/transmutability/malformed-program-gracefulness/unknown_dst.stderr index 9fa376bf4332b..d58974efb143d 100644 --- a/tests/ui/transmutability/malformed-program-gracefulness/unknown_dst.stderr +++ b/tests/ui/transmutability/malformed-program-gracefulness/unknown_dst.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `Dst` in this scope +error[E0412]: cannot find type `Dst` --> $DIR/unknown_dst.rs:18:36 | LL | assert::is_transmutable::(); diff --git a/tests/ui/transmutability/malformed-program-gracefulness/unknown_src.stderr b/tests/ui/transmutability/malformed-program-gracefulness/unknown_src.stderr index f2c7d9e1bcc15..685220e5ce80b 100644 --- a/tests/ui/transmutability/malformed-program-gracefulness/unknown_src.stderr +++ b/tests/ui/transmutability/malformed-program-gracefulness/unknown_src.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `Src` in this scope +error[E0412]: cannot find type `Src` --> $DIR/unknown_src.rs:18:31 | LL | assert::is_transmutable::(); diff --git a/tests/ui/transmutability/malformed-program-gracefulness/unknown_src_field.stderr b/tests/ui/transmutability/malformed-program-gracefulness/unknown_src_field.stderr index cabc7bcfef762..c1995bfb02a1b 100644 --- a/tests/ui/transmutability/malformed-program-gracefulness/unknown_src_field.stderr +++ b/tests/ui/transmutability/malformed-program-gracefulness/unknown_src_field.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `Missing` in this scope +error[E0412]: cannot find type `Missing` --> $DIR/unknown_src_field.rs:18:27 | LL | #[repr(C)] struct Dst(Missing); diff --git a/tests/ui/tuple/tuple-struct-fields/test.rs b/tests/ui/tuple/tuple-struct-fields/test.rs index 00677090d78c5..e2c0f438ef6c1 100644 --- a/tests/ui/tuple/tuple-struct-fields/test.rs +++ b/tests/ui/tuple/tuple-struct-fields/test.rs @@ -3,7 +3,7 @@ mod foo { struct S1(pub(in foo) (), pub(T), pub(crate) (), pub(((), T))); struct S2(pub((foo)) ()); //~^ ERROR expected one of `)` or `,`, found `(` - //~| ERROR cannot find type `foo` in this scope + //~| ERROR cannot find type `foo` } fn main() {} diff --git a/tests/ui/tuple/tuple-struct-fields/test.stderr b/tests/ui/tuple/tuple-struct-fields/test.stderr index bfa0b32fd458a..b5cce9a480924 100644 --- a/tests/ui/tuple/tuple-struct-fields/test.stderr +++ b/tests/ui/tuple/tuple-struct-fields/test.stderr @@ -6,7 +6,7 @@ LL | struct S2(pub((foo)) ()); | | | help: missing `,` -error[E0412]: cannot find type `foo` in this scope +error[E0412]: cannot find type `foo` --> $DIR/test.rs:4:20 | LL | struct S2(pub((foo)) ()); diff --git a/tests/ui/tuple/tuple-struct-fields/test2.rs b/tests/ui/tuple/tuple-struct-fields/test2.rs index 2b2a2c127e985..8b7a4713fc9f3 100644 --- a/tests/ui/tuple/tuple-struct-fields/test2.rs +++ b/tests/ui/tuple/tuple-struct-fields/test2.rs @@ -8,8 +8,8 @@ macro_rules! define_struct { } mod foo { - define_struct! { (foo) } //~ ERROR cannot find type `foo` in this scope - //~| ERROR cannot find type `foo` in this scope + define_struct! { (foo) } //~ ERROR cannot find type `foo` + //~| ERROR cannot find type `foo` } fn main() {} diff --git a/tests/ui/tuple/tuple-struct-fields/test2.stderr b/tests/ui/tuple/tuple-struct-fields/test2.stderr index 784411aba8f8a..97e67307d849b 100644 --- a/tests/ui/tuple/tuple-struct-fields/test2.stderr +++ b/tests/ui/tuple/tuple-struct-fields/test2.stderr @@ -11,13 +11,13 @@ LL | define_struct! { (foo) } | = note: this error originates in the macro `define_struct` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0412]: cannot find type `foo` in this scope +error[E0412]: cannot find type `foo` --> $DIR/test2.rs:11:23 | LL | define_struct! { (foo) } | ^^^ not found in this scope -error[E0412]: cannot find type `foo` in this scope +error[E0412]: cannot find type `foo` --> $DIR/test2.rs:11:23 | LL | define_struct! { (foo) } diff --git a/tests/ui/tuple/tuple-struct-fields/test3.rs b/tests/ui/tuple/tuple-struct-fields/test3.rs index 98d19426e7733..9ebbb266b6b04 100644 --- a/tests/ui/tuple/tuple-struct-fields/test3.rs +++ b/tests/ui/tuple/tuple-struct-fields/test3.rs @@ -8,8 +8,8 @@ macro_rules! define_struct { } mod foo { - define_struct! { foo } //~ ERROR cannot find type `foo` in this scope - //~| ERROR cannot find type `foo` in this scope + define_struct! { foo } //~ ERROR cannot find type `foo` + //~| ERROR cannot find type `foo` } fn main() {} diff --git a/tests/ui/tuple/tuple-struct-fields/test3.stderr b/tests/ui/tuple/tuple-struct-fields/test3.stderr index 00b07c0315292..6c0a05be33a5e 100644 --- a/tests/ui/tuple/tuple-struct-fields/test3.stderr +++ b/tests/ui/tuple/tuple-struct-fields/test3.stderr @@ -11,13 +11,13 @@ LL | define_struct! { foo } | = note: this error originates in the macro `define_struct` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0412]: cannot find type `foo` in this scope +error[E0412]: cannot find type `foo` --> $DIR/test3.rs:11:22 | LL | define_struct! { foo } | ^^^ not found in this scope -error[E0412]: cannot find type `foo` in this scope +error[E0412]: cannot find type `foo` --> $DIR/test3.rs:11:22 | LL | define_struct! { foo } diff --git a/tests/ui/type-alias-impl-trait/nested-impl-trait-in-tait.rs b/tests/ui/type-alias-impl-trait/nested-impl-trait-in-tait.rs index 6a74d1dc4ef38..f7f808d22003d 100644 --- a/tests/ui/type-alias-impl-trait/nested-impl-trait-in-tait.rs +++ b/tests/ui/type-alias-impl-trait/nested-impl-trait-in-tait.rs @@ -2,7 +2,7 @@ pub type Tait = impl Iterator; //~^ ERROR use of undeclared lifetime name `'db` -//~| ERROR cannot find type `LocalKey` in this scope +//~| ERROR cannot find type `LocalKey` //~| ERROR unconstrained opaque type //~| ERROR unconstrained opaque type diff --git a/tests/ui/type-alias-impl-trait/nested-impl-trait-in-tait.stderr b/tests/ui/type-alias-impl-trait/nested-impl-trait-in-tait.stderr index ca15b134a9947..eca7205add50d 100644 --- a/tests/ui/type-alias-impl-trait/nested-impl-trait-in-tait.stderr +++ b/tests/ui/type-alias-impl-trait/nested-impl-trait-in-tait.stderr @@ -14,7 +14,7 @@ help: consider introducing lifetime `'db` here LL | pub type Tait<'db> = impl Iterator; | +++++ -error[E0412]: cannot find type `LocalKey` in this scope +error[E0412]: cannot find type `LocalKey` --> $DIR/nested-impl-trait-in-tait.rs:3:44 | LL | pub type Tait = impl Iterator; diff --git a/tests/ui/type-alias/issue-62364-self-ty-arg.rs b/tests/ui/type-alias/issue-62364-self-ty-arg.rs index bebb4a9021aab..ec7b6baff49b3 100644 --- a/tests/ui/type-alias/issue-62364-self-ty-arg.rs +++ b/tests/ui/type-alias/issue-62364-self-ty-arg.rs @@ -3,6 +3,6 @@ struct Struct { } type Alias<'a> = Struct<&'a Self>; -//~^ ERROR cannot find type `Self` in this scope [E0411] +//~^ ERROR cannot find type `Self` [E0411] fn main() {} diff --git a/tests/ui/type-alias/issue-62364-self-ty-arg.stderr b/tests/ui/type-alias/issue-62364-self-ty-arg.stderr index 26d93dcc27276..3389dfe27c414 100644 --- a/tests/ui/type-alias/issue-62364-self-ty-arg.stderr +++ b/tests/ui/type-alias/issue-62364-self-ty-arg.stderr @@ -1,4 +1,4 @@ -error[E0411]: cannot find type `Self` in this scope +error[E0411]: cannot find type `Self` --> $DIR/issue-62364-self-ty-arg.rs:5:29 | LL | type Alias<'a> = Struct<&'a Self>; diff --git a/tests/ui/type/issue-7607-1.rs b/tests/ui/type/issue-7607-1.rs index 5221f2c529bc6..984617c0e653f 100644 --- a/tests/ui/type/issue-7607-1.rs +++ b/tests/ui/type/issue-7607-1.rs @@ -2,7 +2,7 @@ struct Foo { x: isize } -impl Fo { //~ ERROR cannot find type `Fo` in this scope +impl Fo { //~ ERROR cannot find type `Fo` fn foo() {} } diff --git a/tests/ui/type/issue-7607-1.stderr b/tests/ui/type/issue-7607-1.stderr index db4c8f25dbc43..1b4fb5077b534 100644 --- a/tests/ui/type/issue-7607-1.stderr +++ b/tests/ui/type/issue-7607-1.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `Fo` in this scope +error[E0412]: cannot find type `Fo` --> $DIR/issue-7607-1.rs:5:6 | LL | impl Fo { diff --git a/tests/ui/type/type-path-err-node-types.rs b/tests/ui/type/type-path-err-node-types.rs index b3795772e6fe2..c3a61b1ceda56 100644 --- a/tests/ui/type/type-path-err-node-types.rs +++ b/tests/ui/type/type-path-err-node-types.rs @@ -4,7 +4,7 @@ trait Tr {} fn local_type() { - let _: Nonexistent; //~ ERROR cannot find type `Nonexistent` in this scope + let _: Nonexistent; //~ ERROR cannot find type `Nonexistent` } fn ufcs_trait() { diff --git a/tests/ui/type/type-path-err-node-types.stderr b/tests/ui/type/type-path-err-node-types.stderr index 8b12aa1a393b2..9a56eda807706 100644 --- a/tests/ui/type/type-path-err-node-types.stderr +++ b/tests/ui/type/type-path-err-node-types.stderr @@ -1,16 +1,16 @@ -error[E0412]: cannot find type `Nonexistent` in this scope +error[E0412]: cannot find type `Nonexistent` --> $DIR/type-path-err-node-types.rs:7:12 | LL | let _: Nonexistent; | ^^^^^^^^^^^ not found in this scope -error[E0576]: cannot find method or associated constant `nonexistent` in trait `Tr` +error[E0576]: cannot find method or associated constant `nonexistent` --> $DIR/type-path-err-node-types.rs:11:21 | LL | >::nonexistent(); - | ^^^^^^^^^^^ not found in `Tr` + | ^^^^^^^^^^^ not found in trait `Tr` -error[E0425]: cannot find value `nonexistent` in this scope +error[E0425]: cannot find value `nonexistent` --> $DIR/type-path-err-node-types.rs:19:5 | LL | nonexistent.nonexistent::(); diff --git a/tests/ui/typeck/apit-with-error-type-in-sig.rs b/tests/ui/typeck/apit-with-error-type-in-sig.rs index 35990fc16c89a..7a24948bdd314 100644 --- a/tests/ui/typeck/apit-with-error-type-in-sig.rs +++ b/tests/ui/typeck/apit-with-error-type-in-sig.rs @@ -1,5 +1,5 @@ type Foo = Bar; -//~^ ERROR cannot find type `Bar` in this scope +//~^ ERROR cannot find type `Bar` fn check(f: impl FnOnce(Foo), val: Foo) { f(val); diff --git a/tests/ui/typeck/apit-with-error-type-in-sig.stderr b/tests/ui/typeck/apit-with-error-type-in-sig.stderr index 6ed9b1f9b8cba..d470891413eb8 100644 --- a/tests/ui/typeck/apit-with-error-type-in-sig.stderr +++ b/tests/ui/typeck/apit-with-error-type-in-sig.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `Bar` in this scope +error[E0412]: cannot find type `Bar` --> $DIR/apit-with-error-type-in-sig.rs:1:12 | LL | type Foo = Bar; diff --git a/tests/ui/typeck/autoderef-with-param-env-error.rs b/tests/ui/typeck/autoderef-with-param-env-error.rs index ec96c61c63e3a..5c76bb4480514 100644 --- a/tests/ui/typeck/autoderef-with-param-env-error.rs +++ b/tests/ui/typeck/autoderef-with-param-env-error.rs @@ -1,7 +1,7 @@ fn foo() where T: Send, - //~^ cannot find type `T` in this scope + //~^ cannot find type `T` { let s = "abc".to_string(); } diff --git a/tests/ui/typeck/autoderef-with-param-env-error.stderr b/tests/ui/typeck/autoderef-with-param-env-error.stderr index e06be398aa07a..bf07ba74c6a39 100644 --- a/tests/ui/typeck/autoderef-with-param-env-error.stderr +++ b/tests/ui/typeck/autoderef-with-param-env-error.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `T` in this scope +error[E0412]: cannot find type `T` --> $DIR/autoderef-with-param-env-error.rs:3:5 | LL | T: Send, diff --git a/tests/ui/typeck/check-args-on-fn-err-2.rs b/tests/ui/typeck/check-args-on-fn-err-2.rs index af57dbe33177d..31d38975b4a60 100644 --- a/tests/ui/typeck/check-args-on-fn-err-2.rs +++ b/tests/ui/typeck/check-args-on-fn-err-2.rs @@ -1,5 +1,5 @@ fn main() { a((), 1i32 == 2u32); - //~^ ERROR cannot find function `a` in this scope + //~^ ERROR cannot find function `a` //~| ERROR mismatched types } diff --git a/tests/ui/typeck/check-args-on-fn-err-2.stderr b/tests/ui/typeck/check-args-on-fn-err-2.stderr index 301bb88dbacf6..6f85cc7ef3365 100644 --- a/tests/ui/typeck/check-args-on-fn-err-2.stderr +++ b/tests/ui/typeck/check-args-on-fn-err-2.stderr @@ -11,7 +11,7 @@ help: change the type of the numeric literal from `u32` to `i32` LL | a((), 1i32 == 2i32); | ~~~ -error[E0425]: cannot find function `a` in this scope +error[E0425]: cannot find function `a` --> $DIR/check-args-on-fn-err-2.rs:2:5 | LL | a((), 1i32 == 2u32); diff --git a/tests/ui/typeck/check-args-on-fn-err.rs b/tests/ui/typeck/check-args-on-fn-err.rs index 04b98ddd95295..87ec4c314876a 100644 --- a/tests/ui/typeck/check-args-on-fn-err.rs +++ b/tests/ui/typeck/check-args-on-fn-err.rs @@ -1,6 +1,6 @@ fn main() { unknown(1, |glyf| { - //~^ ERROR: cannot find function `unknown` in this scope + //~^ ERROR: cannot find function `unknown` let actual = glyf; }); } diff --git a/tests/ui/typeck/check-args-on-fn-err.stderr b/tests/ui/typeck/check-args-on-fn-err.stderr index be0798ab107c0..3c4689877b6af 100644 --- a/tests/ui/typeck/check-args-on-fn-err.stderr +++ b/tests/ui/typeck/check-args-on-fn-err.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find function `unknown` in this scope +error[E0425]: cannot find function `unknown` --> $DIR/check-args-on-fn-err.rs:2:5 | LL | unknown(1, |glyf| { diff --git a/tests/ui/typeck/issue-104510-ice.rs b/tests/ui/typeck/issue-104510-ice.rs index 627af1fe95230..a105675075fd4 100644 --- a/tests/ui/typeck/issue-104510-ice.rs +++ b/tests/ui/typeck/issue-104510-ice.rs @@ -2,7 +2,7 @@ //@ only-x86_64 struct W(Oops); -//~^ ERROR cannot find type `Oops` in this scope +//~^ ERROR cannot find type `Oops` unsafe fn test() { let j = W(()); diff --git a/tests/ui/typeck/issue-104510-ice.stderr b/tests/ui/typeck/issue-104510-ice.stderr index 143139b2c089c..bfbc8dd5ff227 100644 --- a/tests/ui/typeck/issue-104510-ice.stderr +++ b/tests/ui/typeck/issue-104510-ice.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `Oops` in this scope +error[E0412]: cannot find type `Oops` --> $DIR/issue-104510-ice.rs:4:21 | LL | struct W(Oops); diff --git a/tests/ui/typeck/issue-104513-ice.rs b/tests/ui/typeck/issue-104513-ice.rs index aaeee9cef48ac..5659cd49ed904 100644 --- a/tests/ui/typeck/issue-104513-ice.rs +++ b/tests/ui/typeck/issue-104513-ice.rs @@ -1,6 +1,6 @@ struct S; fn f() { - let _: S = S; //~ ERROR cannot find trait `Oops` in this scope + let _: S = S; //~ ERROR cannot find trait `Oops` //~^ ERROR `impl Trait` is not allowed in the type of variable bindings } fn main() {} diff --git a/tests/ui/typeck/issue-104513-ice.stderr b/tests/ui/typeck/issue-104513-ice.stderr index 37d38a76a4034..80a0168e08f27 100644 --- a/tests/ui/typeck/issue-104513-ice.stderr +++ b/tests/ui/typeck/issue-104513-ice.stderr @@ -1,4 +1,4 @@ -error[E0405]: cannot find trait `Oops` in this scope +error[E0405]: cannot find trait `Oops` --> $DIR/issue-104513-ice.rs:3:19 | LL | let _: S = S; diff --git a/tests/ui/typeck/issue-105946.rs b/tests/ui/typeck/issue-105946.rs index f53f31138f811..305f524e18521 100644 --- a/tests/ui/typeck/issue-105946.rs +++ b/tests/ui/typeck/issue-105946.rs @@ -4,7 +4,7 @@ fn digit() -> str { } fn main() { let [_y..] = [Box::new(1), Box::new(2)]; - //~^ ERROR: cannot find value `_y` in this scope [E0425] + //~^ ERROR: cannot find value `_y` [E0425] //~| ERROR: `X..` patterns in slices are experimental [E0658] //~| ERROR: pattern requires 1 element but array has 2 [E0527] } diff --git a/tests/ui/typeck/issue-105946.stderr b/tests/ui/typeck/issue-105946.stderr index 33d4e0b141ab3..6c6d4c456bb66 100644 --- a/tests/ui/typeck/issue-105946.stderr +++ b/tests/ui/typeck/issue-105946.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `_y` in this scope +error[E0425]: cannot find value `_y` --> $DIR/issue-105946.rs:6:10 | LL | let [_y..] = [Box::new(1), Box::new(2)]; diff --git a/tests/ui/typeck/issue-106929.rs b/tests/ui/typeck/issue-106929.rs index 91342229ae1a5..beaa6aae52a63 100644 --- a/tests/ui/typeck/issue-106929.rs +++ b/tests/ui/typeck/issue-106929.rs @@ -7,7 +7,7 @@ impl Client { fn f() { let c = Client; post(c, ()); - //~^ ERROR cannot find function `post` in this scope + //~^ ERROR cannot find function `post` } fn main() {} diff --git a/tests/ui/typeck/issue-106929.stderr b/tests/ui/typeck/issue-106929.stderr index 375c9372ec288..34ce63bb604ef 100644 --- a/tests/ui/typeck/issue-106929.stderr +++ b/tests/ui/typeck/issue-106929.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find function `post` in this scope +error[E0425]: cannot find function `post` --> $DIR/issue-106929.rs:9:5 | LL | post(c, ()); diff --git a/tests/ui/typeck/issue-114423-ice-regression-in-suggestion.rs b/tests/ui/typeck/issue-114423-ice-regression-in-suggestion.rs index da2dae1c46b06..642b821234e60 100644 --- a/tests/ui/typeck/issue-114423-ice-regression-in-suggestion.rs +++ b/tests/ui/typeck/issue-114423-ice-regression-in-suggestion.rs @@ -5,11 +5,11 @@ struct RGB { fn main() { let (r, alone_in_path, b): (f32, f32, f32) = (e.clone(), e.clone()); - //~^ ERROR cannot find value `e` in this scope - //~| ERROR cannot find value `e` in this scope + //~^ ERROR cannot find value `e` + //~| ERROR cannot find value `e` //~| ERROR mismatched types let _ = RGB { r, g, b }; - //~^ ERROR cannot find value `g` in this scope + //~^ ERROR cannot find value `g` //~| ERROR struct `RGB` has no field named `r` //~| ERROR mismatched types } diff --git a/tests/ui/typeck/issue-114423-ice-regression-in-suggestion.stderr b/tests/ui/typeck/issue-114423-ice-regression-in-suggestion.stderr index 4ccfacfb00521..0e4d79fe958c8 100644 --- a/tests/ui/typeck/issue-114423-ice-regression-in-suggestion.stderr +++ b/tests/ui/typeck/issue-114423-ice-regression-in-suggestion.stderr @@ -1,16 +1,16 @@ -error[E0425]: cannot find value `e` in this scope +error[E0425]: cannot find value `e` --> $DIR/issue-114423-ice-regression-in-suggestion.rs:7:51 | LL | let (r, alone_in_path, b): (f32, f32, f32) = (e.clone(), e.clone()); | ^ not found in this scope -error[E0425]: cannot find value `e` in this scope +error[E0425]: cannot find value `e` --> $DIR/issue-114423-ice-regression-in-suggestion.rs:7:62 | LL | let (r, alone_in_path, b): (f32, f32, f32) = (e.clone(), e.clone()); | ^ not found in this scope -error[E0425]: cannot find value `g` in this scope +error[E0425]: cannot find value `g` --> $DIR/issue-114423-ice-regression-in-suggestion.rs:11:22 | LL | let _ = RGB { r, g, b }; diff --git a/tests/ui/typeck/issue-83693.rs b/tests/ui/typeck/issue-83693.rs index 02a0bb30d7ce1..ec23cc58cd7e7 100644 --- a/tests/ui/typeck/issue-83693.rs +++ b/tests/ui/typeck/issue-83693.rs @@ -4,16 +4,16 @@ #![crate_type="lib"] impl F { -//~^ ERROR: cannot find type `F` in this scope [E0412] +//~^ ERROR: cannot find type `F` [E0412] fn call() { ::call - //~^ ERROR: cannot find type `TestResult` in this scope [E0412] + //~^ ERROR: cannot find type `TestResult` [E0412] //~| associated item constraints are not allowed here [E0229] } } fn call() { ::call - //~^ ERROR: cannot find type `x` in this scope [E0412] + //~^ ERROR: cannot find type `x` [E0412] //~| ERROR: associated item constraints are not allowed here [E0229] } diff --git a/tests/ui/typeck/issue-83693.stderr b/tests/ui/typeck/issue-83693.stderr index 34bca426116e5..ff0f90929d55d 100644 --- a/tests/ui/typeck/issue-83693.stderr +++ b/tests/ui/typeck/issue-83693.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `F` in this scope +error[E0412]: cannot find type `F` --> $DIR/issue-83693.rs:6:6 | LL | impl F { @@ -7,13 +7,13 @@ LL | impl F { | = note: similarly named trait `Fn` defined here -error[E0412]: cannot find type `TestResult` in this scope +error[E0412]: cannot find type `TestResult` --> $DIR/issue-83693.rs:9:22 | LL | ::call | ^^^^^^^^^^ not found in this scope -error[E0412]: cannot find type `x` in this scope +error[E0412]: cannot find type `x` --> $DIR/issue-83693.rs:16:6 | LL | ::call diff --git a/tests/ui/typeck/issue-88844.rs b/tests/ui/typeck/issue-88844.rs index 116c75aabdbdf..34e6d254091de 100644 --- a/tests/ui/typeck/issue-88844.rs +++ b/tests/ui/typeck/issue-88844.rs @@ -4,7 +4,7 @@ struct Struct { value: i32 } //~^ NOTE: similarly named struct `Struct` defined here impl Stuct { -//~^ ERROR: cannot find type `Stuct` in this scope [E0412] +//~^ ERROR: cannot find type `Stuct` [E0412] //~| HELP: a struct with a similar name exists fn new() -> Self { Self { value: 42 } diff --git a/tests/ui/typeck/issue-88844.stderr b/tests/ui/typeck/issue-88844.stderr index 68473f65dcf53..5c62e428fe7ac 100644 --- a/tests/ui/typeck/issue-88844.stderr +++ b/tests/ui/typeck/issue-88844.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `Stuct` in this scope +error[E0412]: cannot find type `Stuct` --> $DIR/issue-88844.rs:6:6 | LL | struct Struct { value: i32 } diff --git a/tests/ui/typeck/issue-90319.rs b/tests/ui/typeck/issue-90319.rs index 57e6ac7cf34f5..3140bb519a6ed 100644 --- a/tests/ui/typeck/issue-90319.rs +++ b/tests/ui/typeck/issue-90319.rs @@ -11,7 +11,7 @@ fn get() -> T { } fn main() { - let thing = get::();//~ERROR cannot find type `Thing` in this scope [E0412] + let thing = get::();//~ERROR cannot find type `Thing` [E0412] let wrapper = Wrapper(thing); Trait::method(&wrapper); } diff --git a/tests/ui/typeck/issue-90319.stderr b/tests/ui/typeck/issue-90319.stderr index fa18056e802d4..20ef8811b8921 100644 --- a/tests/ui/typeck/issue-90319.stderr +++ b/tests/ui/typeck/issue-90319.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `Thing` in this scope +error[E0412]: cannot find type `Thing` --> $DIR/issue-90319.rs:14:23 | LL | let thing = get::(); diff --git a/tests/ui/typeck/issue-91267.rs b/tests/ui/typeck/issue-91267.rs index 1bffa09e64360..c4f3f7b30dabd 100644 --- a/tests/ui/typeck/issue-91267.rs +++ b/tests/ui/typeck/issue-91267.rs @@ -2,7 +2,7 @@ fn main() { type_ascribe!(0, u8=e>) - //~^ ERROR: cannot find type `e` in this scope [E0412] + //~^ ERROR: cannot find type `e` [E0412] //~| ERROR: associated item constraints are not allowed here [E0229] //~| ERROR: mismatched types [E0308] } diff --git a/tests/ui/typeck/issue-91267.stderr b/tests/ui/typeck/issue-91267.stderr index d16b1997e9f7d..5363e47c9e03a 100644 --- a/tests/ui/typeck/issue-91267.stderr +++ b/tests/ui/typeck/issue-91267.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `e` in this scope +error[E0412]: cannot find type `e` --> $DIR/issue-91267.rs:4:30 | LL | type_ascribe!(0, u8=e>) diff --git a/tests/ui/typeck/nonexistent-field-not-ambiguous.rs b/tests/ui/typeck/nonexistent-field-not-ambiguous.rs index 1cd192b783cdb..78a53923a389b 100644 --- a/tests/ui/typeck/nonexistent-field-not-ambiguous.rs +++ b/tests/ui/typeck/nonexistent-field-not-ambiguous.rs @@ -1,6 +1,6 @@ struct Foo { val: MissingType, - //~^ ERROR cannot find type `MissingType` in this scope + //~^ ERROR cannot find type `MissingType` } fn main() { diff --git a/tests/ui/typeck/nonexistent-field-not-ambiguous.stderr b/tests/ui/typeck/nonexistent-field-not-ambiguous.stderr index 82207a731b962..36c33db44faea 100644 --- a/tests/ui/typeck/nonexistent-field-not-ambiguous.stderr +++ b/tests/ui/typeck/nonexistent-field-not-ambiguous.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `MissingType` in this scope +error[E0412]: cannot find type `MissingType` --> $DIR/nonexistent-field-not-ambiguous.rs:2:10 | LL | val: MissingType, diff --git a/tests/ui/typeck/quiet-type-err-let-binding.rs b/tests/ui/typeck/quiet-type-err-let-binding.rs index a6eab536a6b09..9435c7308ea27 100644 --- a/tests/ui/typeck/quiet-type-err-let-binding.rs +++ b/tests/ui/typeck/quiet-type-err-let-binding.rs @@ -11,7 +11,7 @@ fn test2(s: String) { } fn main() { - let x = foo(); //~ERROR cannot find function `foo` in this scope + let x = foo(); //~ERROR cannot find function `foo` test(&x); test2(x); // Does not complain about `x` being a `&str`. } diff --git a/tests/ui/typeck/quiet-type-err-let-binding.stderr b/tests/ui/typeck/quiet-type-err-let-binding.stderr index f27ca1dd58206..0eba3448cabcf 100644 --- a/tests/ui/typeck/quiet-type-err-let-binding.stderr +++ b/tests/ui/typeck/quiet-type-err-let-binding.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find function `foo` in this scope +error[E0425]: cannot find function `foo` --> $DIR/quiet-type-err-let-binding.rs:14:13 | LL | let x = foo(); diff --git a/tests/ui/ufcs/ufcs-partially-resolved.rs b/tests/ui/ufcs/ufcs-partially-resolved.rs index 712668728c9e7..dd19943d255b8 100644 --- a/tests/ui/ufcs/ufcs-partially-resolved.rs +++ b/tests/ui/ufcs/ufcs-partially-resolved.rs @@ -16,10 +16,10 @@ enum E { Y } type A = u32; fn main() { - let _: ::N; //~ ERROR cannot find associated type `N` in trait `Tr` + let _: ::N; //~ ERROR cannot find associated type `N` let _: ::N; //~ ERROR expected trait, found enum `E` let _: ::N; //~ ERROR expected trait, found type alias `A` - ::N; //~ ERROR cannot find method or associated constant `N` in trait `Tr` + ::N; //~ ERROR cannot find method or associated constant `N` ::N; //~ ERROR expected trait, found enum `E` ::N; //~ ERROR expected trait, found type alias `A` let _: ::Y; // OK @@ -27,10 +27,10 @@ fn main() { ::Y; // OK ::Y; //~ ERROR expected trait, found enum `E` - let _: ::N::NN; //~ ERROR cannot find associated type `N` in trait `Tr` + let _: ::N::NN; //~ ERROR cannot find associated type `N` let _: ::N::NN; //~ ERROR expected trait, found enum `E` let _: ::N::NN; //~ ERROR expected trait, found type alias `A` - ::N::NN; //~ ERROR cannot find associated type `N` in trait `Tr` + ::N::NN; //~ ERROR cannot find associated type `N` ::N::NN; //~ ERROR expected trait, found enum `E` ::N::NN; //~ ERROR expected trait, found type alias `A` let _: ::Y::NN; //~ ERROR ambiguous associated type @@ -38,12 +38,12 @@ fn main() { ::Y::NN; //~ ERROR no associated item named `NN` found for type `u16` ::Y::NN; //~ ERROR expected trait, found enum `E` - let _: ::NN; //~ ERROR cannot find trait `N` in trait `Tr` - let _: ::NN; //~ ERROR cannot find trait `N` in enum `E` - let _: ::NN; //~ ERROR cannot find trait `N` in `A` - ::NN; //~ ERROR cannot find trait `N` in trait `Tr` - ::NN; //~ ERROR cannot find trait `N` in enum `E` - ::NN; //~ ERROR cannot find trait `N` in `A` + let _: ::NN; //~ ERROR cannot find trait `N` + let _: ::NN; //~ ERROR cannot find trait `N` + let _: ::NN; //~ ERROR cannot find trait `N` + ::NN; //~ ERROR cannot find trait `N` + ::NN; //~ ERROR cannot find trait `N` + ::NN; //~ ERROR cannot find trait `N` let _: ::NN; //~ ERROR expected trait, found associated type `Tr::Y let _: ::NN; //~ ERROR expected trait, found variant `E::Y` ::NN; //~ ERROR expected trait, found associated type `Tr::Y` diff --git a/tests/ui/ufcs/ufcs-partially-resolved.stderr b/tests/ui/ufcs/ufcs-partially-resolved.stderr index eef55c8dc686f..82d472ead7b73 100644 --- a/tests/ui/ufcs/ufcs-partially-resolved.stderr +++ b/tests/ui/ufcs/ufcs-partially-resolved.stderr @@ -1,4 +1,4 @@ -error[E0576]: cannot find associated type `N` in trait `Tr` +error[E0576]: cannot find associated type `N` --> $DIR/ufcs-partially-resolved.rs:19:24 | LL | type Y = u16; @@ -27,7 +27,7 @@ help: you might have meant to use `#![feature(trait_alias)]` instead of a `type` LL | trait A = u32; | -error[E0576]: cannot find method or associated constant `N` in trait `Tr` +error[E0576]: cannot find method or associated constant `N` --> $DIR/ufcs-partially-resolved.rs:22:17 | LL | fn Y() {} @@ -74,7 +74,7 @@ LL | ::Y; | = note: similarly named trait `Eq` defined here -error[E0576]: cannot find associated type `N` in trait `Tr` +error[E0576]: cannot find associated type `N` --> $DIR/ufcs-partially-resolved.rs:30:24 | LL | type Y = u16; @@ -103,7 +103,7 @@ help: you might have meant to use `#![feature(trait_alias)]` instead of a `type` LL | trait A = u32; | -error[E0576]: cannot find associated type `N` in trait `Tr` +error[E0576]: cannot find associated type `N` --> $DIR/ufcs-partially-resolved.rs:33:17 | LL | type Y = u16; @@ -150,37 +150,37 @@ LL | ::Y::NN; | = note: similarly named trait `Eq` defined here -error[E0405]: cannot find trait `N` in trait `Tr` +error[E0405]: cannot find trait `N` --> $DIR/ufcs-partially-resolved.rs:41:23 | LL | let _: ::NN; - | ^ not found in `Tr` + | ^ not found in trait `Tr` -error[E0405]: cannot find trait `N` in enum `E` +error[E0405]: cannot find trait `N` --> $DIR/ufcs-partially-resolved.rs:42:22 | LL | let _: ::NN; - | ^ not found in `E` + | ^ not found in enum `E` -error[E0405]: cannot find trait `N` in `A` +error[E0405]: cannot find trait `N` --> $DIR/ufcs-partially-resolved.rs:43:22 | LL | let _: ::NN; | ^ not found in `A` -error[E0405]: cannot find trait `N` in trait `Tr` +error[E0405]: cannot find trait `N` --> $DIR/ufcs-partially-resolved.rs:44:16 | LL | ::NN; - | ^ not found in `Tr` + | ^ not found in trait `Tr` -error[E0405]: cannot find trait `N` in enum `E` +error[E0405]: cannot find trait `N` --> $DIR/ufcs-partially-resolved.rs:45:15 | LL | ::NN; - | ^ not found in `E` + | ^ not found in enum `E` -error[E0405]: cannot find trait `N` in `A` +error[E0405]: cannot find trait `N` --> $DIR/ufcs-partially-resolved.rs:46:15 | LL | ::NN; diff --git a/tests/ui/unboxed-closures/unboxed-closures-type-mismatch-closure-from-another-scope.stderr b/tests/ui/unboxed-closures/unboxed-closures-type-mismatch-closure-from-another-scope.stderr index 5f22c781345ff..7ed432240bc8a 100644 --- a/tests/ui/unboxed-closures/unboxed-closures-type-mismatch-closure-from-another-scope.stderr +++ b/tests/ui/unboxed-closures/unboxed-closures-type-mismatch-closure-from-another-scope.stderr @@ -1,10 +1,10 @@ -error[E0425]: cannot find value `x` in this scope +error[E0425]: cannot find value `x` --> $DIR/unboxed-closures-type-mismatch-closure-from-another-scope.rs:2:21 | LL | let x = match **x { | ^ not found in this scope -error[E0425]: cannot find value `y` in this scope +error[E0425]: cannot find value `y` --> $DIR/unboxed-closures-type-mismatch-closure-from-another-scope.rs:9:26 | LL | closure(&mut p, &y); diff --git a/tests/ui/union/unresolved-field-isnt-copy.rs b/tests/ui/union/unresolved-field-isnt-copy.rs index 7a6d79b2faa88..957b4fe4ec799 100644 --- a/tests/ui/union/unresolved-field-isnt-copy.rs +++ b/tests/ui/union/unresolved-field-isnt-copy.rs @@ -2,7 +2,7 @@ pub union Foo { x: *const Missing, - //~^ ERROR cannot find type `Missing` in this scope + //~^ ERROR cannot find type `Missing` } fn main() {} diff --git a/tests/ui/union/unresolved-field-isnt-copy.stderr b/tests/ui/union/unresolved-field-isnt-copy.stderr index ee5d1e37b141c..26d207104be9f 100644 --- a/tests/ui/union/unresolved-field-isnt-copy.stderr +++ b/tests/ui/union/unresolved-field-isnt-copy.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `Missing` in this scope +error[E0412]: cannot find type `Missing` --> $DIR/unresolved-field-isnt-copy.rs:4:15 | LL | x: *const Missing, diff --git a/tests/ui/unresolved/unresolved-candidates.rs b/tests/ui/unresolved/unresolved-candidates.rs index 38b227f609b26..7e614a9bc430e 100644 --- a/tests/ui/unresolved/unresolved-candidates.rs +++ b/tests/ui/unresolved/unresolved-candidates.rs @@ -7,7 +7,7 @@ mod b { } mod c { - impl Trait for () {} //~ ERROR cannot find trait `Trait` in this scope + impl Trait for () {} //~ ERROR cannot find trait `Trait` } fn main() {} diff --git a/tests/ui/unresolved/unresolved-candidates.stderr b/tests/ui/unresolved/unresolved-candidates.stderr index 7ef2f6b1a2922..03b13e7b92ade 100644 --- a/tests/ui/unresolved/unresolved-candidates.stderr +++ b/tests/ui/unresolved/unresolved-candidates.stderr @@ -9,7 +9,7 @@ help: consider importing this trait instead LL | use a::Trait; | ~~~~~~~~ -error[E0405]: cannot find trait `Trait` in this scope +error[E0405]: cannot find trait `Trait` --> $DIR/unresolved-candidates.rs:10:10 | LL | impl Trait for () {} diff --git a/tests/ui/wf/ice-hir-wf-check-anon-const-issue-122199.rs b/tests/ui/wf/ice-hir-wf-check-anon-const-issue-122199.rs index 3f43fbfc0cf41..bd6422cb37a8d 100644 --- a/tests/ui/wf/ice-hir-wf-check-anon-const-issue-122199.rs +++ b/tests/ui/wf/ice-hir-wf-check-anon-const-issue-122199.rs @@ -1,5 +1,5 @@ trait Trait { - //~^ ERROR cannot find value `bar` in this scope + //~^ ERROR cannot find value `bar` //~| ERROR cycle detected when computing type of `Trait::N` //~| ERROR the trait `Trait` cannot be made into an object //~| ERROR the trait `Trait` cannot be made into an object @@ -23,7 +23,7 @@ trait Trait { //~| WARN trait objects without an explicit `dyn` are deprecated [bare_trait_objects] //~| WARN this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! bar - //~^ ERROR cannot find value `bar` in this scope + //~^ ERROR cannot find value `bar` } } diff --git a/tests/ui/wf/ice-hir-wf-check-anon-const-issue-122199.stderr b/tests/ui/wf/ice-hir-wf-check-anon-const-issue-122199.stderr index f2456f99e6233..9f9984ad1c075 100644 --- a/tests/ui/wf/ice-hir-wf-check-anon-const-issue-122199.stderr +++ b/tests/ui/wf/ice-hir-wf-check-anon-const-issue-122199.stderr @@ -7,7 +7,7 @@ LL | trait Trait { LL | fn fnc(&self) -> Trait { | ^ already used -error[E0425]: cannot find value `bar` in this scope +error[E0425]: cannot find value `bar` --> $DIR/ice-hir-wf-check-anon-const-issue-122199.rs:1:30 | LL | trait Trait { @@ -19,7 +19,7 @@ error[E0423]: expected value, found builtin type `u32` LL | fn fnc(&self) -> Trait { | ^^^ not a value -error[E0425]: cannot find value `bar` in this scope +error[E0425]: cannot find value `bar` --> $DIR/ice-hir-wf-check-anon-const-issue-122199.rs:25:9 | LL | bar diff --git a/tests/ui/wf/issue-110157.rs b/tests/ui/wf/issue-110157.rs index 1a3d13e93b0de..65136b79df7c7 100644 --- a/tests/ui/wf/issue-110157.rs +++ b/tests/ui/wf/issue-110157.rs @@ -4,9 +4,9 @@ impl<'tcx, F, I> Iterator for NeedsDropTypes<'tcx, F> //~^ ERROR not all trait items implemented where F: Fn(&Missing) -> Result, - //~^ ERROR cannot find type `Missing` in this scope + //~^ ERROR cannot find type `Missing` I: Iterator, - //~^ ERROR cannot find type `Missing` in this scope + //~^ ERROR cannot find type `Missing` {} fn main() {} diff --git a/tests/ui/wf/issue-110157.stderr b/tests/ui/wf/issue-110157.stderr index e750ea47d515c..0785a10306cc4 100644 --- a/tests/ui/wf/issue-110157.stderr +++ b/tests/ui/wf/issue-110157.stderr @@ -1,10 +1,10 @@ -error[E0412]: cannot find type `Missing` in this scope +error[E0412]: cannot find type `Missing` --> $DIR/issue-110157.rs:6:12 | LL | F: Fn(&Missing) -> Result, | ^^^^^^^ not found in this scope -error[E0412]: cannot find type `Missing` in this scope +error[E0412]: cannot find type `Missing` --> $DIR/issue-110157.rs:8:24 | LL | I: Iterator, diff --git a/tests/ui/where-clauses/ignore-err-clauses.rs b/tests/ui/where-clauses/ignore-err-clauses.rs index c76f0e1a8b2b5..83c4bc7fa7178 100644 --- a/tests/ui/where-clauses/ignore-err-clauses.rs +++ b/tests/ui/where-clauses/ignore-err-clauses.rs @@ -4,7 +4,7 @@ fn dbl(x: T) -> ::Output where T: Copy + Add, UUU: Copy, - //~^ ERROR cannot find type `UUU` in this scope + //~^ ERROR cannot find type `UUU` { x + x } diff --git a/tests/ui/where-clauses/ignore-err-clauses.stderr b/tests/ui/where-clauses/ignore-err-clauses.stderr index 4cf553da4c5fc..146915f991580 100644 --- a/tests/ui/where-clauses/ignore-err-clauses.stderr +++ b/tests/ui/where-clauses/ignore-err-clauses.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `UUU` in this scope +error[E0412]: cannot find type `UUU` --> $DIR/ignore-err-clauses.rs:6:5 | LL | UUU: Copy, diff --git a/tests/ui/where-clauses/normalization-of-unknown-type.stderr b/tests/ui/where-clauses/normalization-of-unknown-type.stderr index 11b83224352b8..69690e16f31b1 100644 --- a/tests/ui/where-clauses/normalization-of-unknown-type.stderr +++ b/tests/ui/where-clauses/normalization-of-unknown-type.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `Foo` in this scope +error[E0412]: cannot find type `Foo` --> $DIR/normalization-of-unknown-type.rs:24:5 | LL | Foo: Filter, From 3abad1401a37a2a2a613224b0aa4cc71f5fe9f1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 26 Jun 2024 20:25:34 +0000 Subject: [PATCH 885/892] Unify output of the different "cannot find X" errors Do not mention the scope where an ident couldn't be resolved (particularly for macros), and add a primary span label mentioning "this scope" (ideally we would replace the text with the actual scope name in the future): ``` error: cannot find derive macro `rustfmt` --> $DIR/tool-attributes-misplaced-1.rs:4:10 | LL | #[derive(rustfmt)] | ^^^^^^^ not found in this scope ``` --- compiler/rustc_lint/messages.ftl | 5 +- .../rustc_lint/src/context/diagnostics.rs | 4 +- compiler/rustc_lint/src/lints.rs | 2 + compiler/rustc_lint_defs/src/lib.rs | 1 + compiler/rustc_resolve/messages.ftl | 4 +- compiler/rustc_resolve/src/errors.rs | 1 + compiler/rustc_resolve/src/late.rs | 2 +- .../rustc_resolve/src/late/diagnostics.rs | 2 +- compiler/rustc_resolve/src/macros.rs | 5 +- tests/rustdoc-ui/impl-fn-nesting.stderr | 4 +- .../session-diagnostic/diagnostic-derive.rs | 20 ++--- .../subdiagnostic-derive.rs | 16 ++-- tests/ui/attributes/issue-90873.stderr | 8 +- .../attributes/key-value-expansion-scope.rs | 10 +-- .../key-value-expansion-scope.stderr | 88 +++++++++---------- tests/ui/attributes/main-removed-1.stderr | 4 +- tests/ui/attributes/obsolete-attr.stderr | 8 +- tests/ui/attributes/unknown-attr.stderr | 12 +-- .../unsafe/double-unsafe-attributes.stderr | 4 +- .../ui/attributes/unused-item-in-attr.stderr | 4 +- ...r-unknown-attribute-macro-expansion.stderr | 4 +- .../cfg-generic-params.stderr | 20 ++--- tests/ui/consts/issue-90878-2.stderr | 4 +- tests/ui/custom_attribute.stderr | 12 +-- ...deduplicate-diagnostics.deduplicate.stderr | 4 +- .../deduplicate-diagnostics.duplicate.stderr | 8 +- tests/ui/derives/deriving-bounds.stderr | 16 ++-- .../deriving-meta-unknown-trait.stderr | 14 ++- tests/ui/derives/deriving-primitive.stderr | 8 +- .../diagnostic_namespace/requires_path.stderr | 4 +- tests/ui/did_you_mean/println-typo.stderr | 7 +- tests/ui/empty/empty-macro-use.stderr | 4 +- .../ui/enum/suggest-default-attribute.stderr | 4 +- tests/ui/ext-nonexistent.stderr | 4 +- tests/ui/extern/issue-80074.stderr | 8 +- .../feature-gate-custom_attribute.rs | 6 +- .../feature-gate-custom_attribute.stderr | 52 +++++------ .../feature-gate-custom_attribute2.stderr | 68 +++++++------- .../feature-gate-rustc-attrs.stderr | 4 +- .../issue-43106-gating-of-derive-2.stderr | 24 ++--- .../hygiene/no_implicit_prelude-2018.stderr | 4 +- tests/ui/issues/issue-19734.stderr | 4 +- tests/ui/issues/issue-32655.stderr | 14 ++- tests/ui/issues/issue-33571.stderr | 8 +- tests/ui/issues/issue-40845.stderr | 8 +- .../defined-later-issue-121061-2.stderr | 7 +- .../macros/defined-later-issue-121061.stderr | 7 +- .../macros/expand-full-no-resolution.stderr | 8 +- tests/ui/macros/issue-11692-1.stderr | 4 +- tests/ui/macros/issue-11692-2.stderr | 4 +- tests/ui/macros/issue-118786.stderr | 4 +- tests/ui/macros/issue-88206.rs | 11 +++ tests/ui/macros/issue-88206.stderr | 64 +++++++------- tests/ui/macros/issue-88228.stderr | 12 +-- ...acro-expand-within-generics-in-path.stderr | 4 +- tests/ui/macros/macro-expansion-tests.stderr | 8 +- tests/ui/macros/macro-name-typo.stderr | 7 +- .../macros/macro-path-prelude-fail-3.stderr | 7 +- tests/ui/macros/macro-reexport-removed.stderr | 7 +- tests/ui/macros/macro-use-wrong-name.stderr | 4 +- tests/ui/macros/macro_undefined.stderr | 7 +- tests/ui/macros/macros-nonfatal-errors.stderr | 4 +- tests/ui/missing/missing-macro-use.stderr | 4 +- .../multiple-tail-expr-behind-cfg.stderr | 4 +- .../ui/parser/default-unmatched-assoc.stderr | 8 +- .../ui/parser/default-unmatched-extern.stderr | 4 +- .../ui/parser/issues/issue-118531-ice.stderr | 4 +- ...sue-65122-mac-invoc-in-mut-patterns.stderr | 8 +- .../derive-helper-legacy-limits.stderr | 4 +- .../derive-helper-legacy-spurious.stderr | 8 +- .../proc-macro/derive-helper-shadowing.stderr | 8 +- tests/ui/proc-macro/derive-still-gated.stderr | 4 +- .../proc-macro/disappearing-resolution.stderr | 4 +- tests/ui/proc-macro/generate-mod.stderr | 20 ++--- .../issue-118455-skip-err-builtin.stderr | 4 +- .../macro-namespace-reserved-2.stderr | 20 ++--- .../proc-macro/proc-macro-attributes.stderr | 7 +- tests/ui/proc-macro/resolve-error.stderr | 86 ++++++++++++------ .../ui/reserved/reserved-attr-on-macro.stderr | 4 +- tests/ui/resolve/issue-118295.rs | 1 + tests/ui/resolve/issue-118295.stderr | 4 +- tests/ui/resolve/issue-49074.stderr | 11 ++- tests/ui/resolve/path-attr-in-const-block.rs | 2 +- .../resolve/path-attr-in-const-block.stderr | 4 +- .../resolve/visibility-indeterminate.stderr | 4 +- tests/ui/self/self_type_keyword.stderr | 4 +- tests/ui/suggestions/attribute-typos.stderr | 21 +++-- .../tool-attributes-misplaced-1.stderr | 16 ++-- 88 files changed, 526 insertions(+), 428 deletions(-) diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl index 4f2d59b4c6632..dbd703cf9889e 100644 --- a/compiler/rustc_lint/messages.ftl +++ b/compiler/rustc_lint/messages.ftl @@ -609,7 +609,8 @@ lint_opaque_hidden_inferred_bound_sugg = add this bound lint_or_patterns_back_compat = the meaning of the `pat` fragment specifier is changing in Rust 2021, which may affect this macro .suggestion = use pat_param to preserve semantics -lint_out_of_scope_macro_calls = cannot find macro `{$path}` in this scope +lint_out_of_scope_macro_calls = cannot find macro `{$path}` + .label = not found in this scope .help = import `macro_rules` with `use` to make it callable above its definition lint_overflowing_bin_hex = literal out of range for `{$ty}` @@ -650,7 +651,7 @@ lint_pattern_in_foreign = patterns aren't allowed in foreign function declaratio lint_private_extern_crate_reexport = extern crate `{$ident}` is private and cannot be re-exported .suggestion = consider making the `extern crate` item publicly accessible -lint_proc_macro_derive_resolution_fallback = cannot find {$ns} `{$ident}` in this scope +lint_proc_macro_derive_resolution_fallback = cannot find {$ns} `{$ident}` .label = names from parent modules are not accessible without an explicit import lint_ptr_null_checks_fn_ptr = function pointers are not nullable, so checking them for null will always return false diff --git a/compiler/rustc_lint/src/context/diagnostics.rs b/compiler/rustc_lint/src/context/diagnostics.rs index 05e075205c4b7..99e1c7f29289a 100644 --- a/compiler/rustc_lint/src/context/diagnostics.rs +++ b/compiler/rustc_lint/src/context/diagnostics.rs @@ -434,8 +434,8 @@ pub(super) fn decorate_lint(sess: &Session, diagnostic: BuiltinLintDiag, diag: & lints::InnerAttributeUnstable::CustomInnerAttribute } .decorate_lint(diag), - BuiltinLintDiag::OutOfScopeMacroCalls { path } => { - lints::OutOfScopeMacroCalls { path }.decorate_lint(diag) + BuiltinLintDiag::OutOfScopeMacroCalls { span, path } => { + lints::OutOfScopeMacroCalls { span, path }.decorate_lint(diag) } } } diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs index 54c73710eca6f..1dcc561a32ed2 100644 --- a/compiler/rustc_lint/src/lints.rs +++ b/compiler/rustc_lint/src/lints.rs @@ -2917,5 +2917,7 @@ pub struct UnsafeAttrOutsideUnsafeSuggestion { #[diag(lint_out_of_scope_macro_calls)] #[help] pub struct OutOfScopeMacroCalls { + #[label] + pub span: Span, pub path: String, } diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs index f87f19e170005..1e67b0bf68a73 100644 --- a/compiler/rustc_lint_defs/src/lib.rs +++ b/compiler/rustc_lint_defs/src/lib.rs @@ -745,6 +745,7 @@ pub enum BuiltinLintDiag { is_macro: bool, }, OutOfScopeMacroCalls { + span: Span, path: String, }, } diff --git a/compiler/rustc_resolve/messages.ftl b/compiler/rustc_resolve/messages.ftl index 4b9c36ad39fb5..479c7588c3ca9 100644 --- a/compiler/rustc_resolve/messages.ftl +++ b/compiler/rustc_resolve/messages.ftl @@ -80,8 +80,8 @@ resolve_cannot_determine_macro_resolution = resolve_cannot_find_builtin_macro_with_name = cannot find a built-in macro with name `{$ident}` -resolve_cannot_find_ident_in_this_scope = - cannot find {$expected} `{$ident}` in this scope +resolve_cannot_find_ident_in_this_scope = cannot find {$expected} `{$ident}` + .label = not found in this scope resolve_cannot_glob_import_possible_crates = cannot glob-import all possible crates diff --git a/compiler/rustc_resolve/src/errors.rs b/compiler/rustc_resolve/src/errors.rs index 0620f3d709eb2..03ad245d128f0 100644 --- a/compiler/rustc_resolve/src/errors.rs +++ b/compiler/rustc_resolve/src/errors.rs @@ -635,6 +635,7 @@ pub(crate) struct ImportsCannotReferTo<'a> { #[diag(resolve_cannot_find_ident_in_this_scope)] pub(crate) struct CannotFindIdentInThisScope<'a> { #[primary_span] + #[label] pub(crate) span: Span, pub(crate) expected: &'a str, pub(crate) ident: Ident, diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 1d37264f96a3c..3363fb0298dc5 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -3918,7 +3918,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { // There are two different error messages user might receive at // this point: - // - E0412 cannot find type `{}` in this scope + // - E0412 cannot find type `{}` // - E0433 failed to resolve: use of undeclared type or module `{}` // // The first one is emitted for paths in type-position, and the diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 6cbf5fce1786f..74921a535b428 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -2522,7 +2522,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { if let Some(generics) = kind.generics() { if span.overlaps(generics.span) { // Avoid the following: - // error[E0405]: cannot find trait `A` in this scope + // error[E0405]: cannot find trait `A` // --> $DIR/typo-suggestion-named-underscore.rs:CC:LL // | // L | fn foo(x: T) {} // Shouldn't suggest underscore diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs index cb9bebd33d306..a6c56743bfe77 100644 --- a/compiler/rustc_resolve/src/macros.rs +++ b/compiler/rustc_resolve/src/macros.rs @@ -1071,7 +1071,10 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { OUT_OF_SCOPE_MACRO_CALLS, path.span, node_id, - BuiltinLintDiag::OutOfScopeMacroCalls { path: pprust::path_to_string(path) }, + BuiltinLintDiag::OutOfScopeMacroCalls { + span: path.span, + path: pprust::path_to_string(path), + }, ); } } diff --git a/tests/rustdoc-ui/impl-fn-nesting.stderr b/tests/rustdoc-ui/impl-fn-nesting.stderr index 8723380894f29..3e629d5c6f94f 100644 --- a/tests/rustdoc-ui/impl-fn-nesting.stderr +++ b/tests/rustdoc-ui/impl-fn-nesting.stderr @@ -1,8 +1,8 @@ -error: cannot find macro `unknown_macro` in this scope +error: cannot find macro `unknown_macro` --> $DIR/impl-fn-nesting.rs:32:13 | LL | unknown_macro!(); - | ^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^ not found in this scope error[E0405]: cannot find trait `UnknownBound` --> $DIR/impl-fn-nesting.rs:11:13 diff --git a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.rs b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.rs index 803cd10155e65..af3f7e5a6f11c 100644 --- a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.rs +++ b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.rs @@ -62,8 +62,8 @@ struct WrongStructAttrStyle {} #[derive(Diagnostic)] #[nonsense(no_crate_example, code = E0123)] //~^ ERROR `#[nonsense(...)]` is not a valid attribute -//~^^ ERROR diagnostic slug not specified -//~^^^ ERROR cannot find attribute `nonsense` in this scope +//~| ERROR diagnostic slug not specified +//~| ERROR cannot find attribute `nonsense` struct InvalidStructAttr {} #[derive(Diagnostic)] @@ -149,7 +149,7 @@ struct MessageWrongType { struct InvalidPathFieldAttr { #[nonsense] //~^ ERROR `#[nonsense]` is not a valid attribute - //~^^ ERROR cannot find attribute `nonsense` in this scope + //~^^ ERROR cannot find attribute `nonsense` foo: String, } @@ -583,28 +583,28 @@ struct ErrorWithWarn { #[error(no_crate_example, code = E0123)] //~^ ERROR `#[error(...)]` is not a valid attribute //~| ERROR diagnostic slug not specified -//~| ERROR cannot find attribute `error` in this scope +//~| ERROR cannot find attribute `error` struct ErrorAttribute {} #[derive(Diagnostic)] #[warn_(no_crate_example, code = E0123)] //~^ ERROR `#[warn_(...)]` is not a valid attribute //~| ERROR diagnostic slug not specified -//~| ERROR cannot find attribute `warn_` in this scope +//~| ERROR cannot find attribute `warn_` struct WarnAttribute {} #[derive(Diagnostic)] #[lint(no_crate_example, code = E0123)] //~^ ERROR `#[lint(...)]` is not a valid attribute //~| ERROR diagnostic slug not specified -//~| ERROR cannot find attribute `lint` in this scope +//~| ERROR cannot find attribute `lint` struct LintAttributeOnSessionDiag {} #[derive(LintDiagnostic)] #[lint(no_crate_example, code = E0123)] //~^ ERROR `#[lint(...)]` is not a valid attribute //~| ERROR diagnostic slug not specified -//~| ERROR cannot find attribute `lint` in this scope +//~| ERROR cannot find attribute `lint` struct LintAttributeOnLintDiag {} #[derive(Diagnostic)] @@ -643,14 +643,14 @@ struct MissingCodeInSuggestion { #[diag(no_crate_example, code = E0123)] #[multipart_suggestion(no_crate_suggestion)] //~^ ERROR `#[multipart_suggestion(...)]` is not a valid attribute -//~| ERROR cannot find attribute `multipart_suggestion` in this scope +//~| ERROR cannot find attribute `multipart_suggestion` #[multipart_suggestion()] -//~^ ERROR cannot find attribute `multipart_suggestion` in this scope +//~^ ERROR cannot find attribute `multipart_suggestion` //~| ERROR `#[multipart_suggestion(...)]` is not a valid attribute struct MultipartSuggestion { #[multipart_suggestion(no_crate_suggestion)] //~^ ERROR `#[multipart_suggestion(...)]` is not a valid attribute - //~| ERROR cannot find attribute `multipart_suggestion` in this scope + //~| ERROR cannot find attribute `multipart_suggestion` suggestion: Span, } diff --git a/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive.rs b/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive.rs index 43deef7d8caf6..c02434e3a8a39 100644 --- a/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive.rs +++ b/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive.rs @@ -161,7 +161,7 @@ struct O { #[derive(Subdiagnostic)] #[foo] -//~^ ERROR cannot find attribute `foo` in this scope +//~^ ERROR cannot find attribute `foo` //~^^ ERROR unsupported type attribute for subdiagnostic enum enum P { #[label(no_crate_example)] @@ -176,7 +176,7 @@ enum P { enum Q { #[bar] //~^ ERROR `#[bar]` is not a valid attribute - //~^^ ERROR cannot find attribute `bar` in this scope + //~^^ ERROR cannot find attribute `bar` A { #[primary_span] span: Span, @@ -188,7 +188,7 @@ enum Q { enum R { #[bar = "..."] //~^ ERROR `#[bar = ...]` is not a valid attribute - //~^^ ERROR cannot find attribute `bar` in this scope + //~^^ ERROR cannot find attribute `bar` A { #[primary_span] span: Span, @@ -200,7 +200,7 @@ enum R { enum S { #[bar = 4] //~^ ERROR `#[bar = ...]` is not a valid attribute - //~^^ ERROR cannot find attribute `bar` in this scope + //~^^ ERROR cannot find attribute `bar` A { #[primary_span] span: Span, @@ -212,7 +212,7 @@ enum S { enum T { #[bar("...")] //~^ ERROR `#[bar(...)]` is not a valid attribute - //~^^ ERROR cannot find attribute `bar` in this scope + //~^^ ERROR cannot find attribute `bar` A { #[primary_span] span: Span, @@ -273,7 +273,7 @@ struct Y { span: Span, #[bar] //~^ ERROR `#[bar]` is not a valid attribute - //~^^ ERROR cannot find attribute `bar` in this scope + //~^^ ERROR cannot find attribute `bar` bar: String, } @@ -284,7 +284,7 @@ struct Z { span: Span, #[bar = "..."] //~^ ERROR `#[bar = ...]` is not a valid attribute - //~^^ ERROR cannot find attribute `bar` in this scope + //~^^ ERROR cannot find attribute `bar` bar: String, } @@ -295,7 +295,7 @@ struct AA { span: Span, #[bar("...")] //~^ ERROR `#[bar(...)]` is not a valid attribute - //~^^ ERROR cannot find attribute `bar` in this scope + //~^^ ERROR cannot find attribute `bar` bar: String, } diff --git a/tests/ui/attributes/issue-90873.stderr b/tests/ui/attributes/issue-90873.stderr index 5a8bbaf8ec191..8035ae3f068de 100644 --- a/tests/ui/attributes/issue-90873.stderr +++ b/tests/ui/attributes/issue-90873.stderr @@ -10,17 +10,17 @@ error: attribute value must be a literal LL | #![a={impl std::ops::Neg for i8 {}}] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: cannot find attribute `u` in this scope +error: cannot find attribute `u` --> $DIR/issue-90873.rs:1:4 | LL | #![u=||{static d=||1;}] - | ^ + | ^ not found in this scope -error: cannot find attribute `a` in this scope +error: cannot find attribute `a` --> $DIR/issue-90873.rs:6:4 | LL | #![a={impl std::ops::Neg for i8 {}}] - | ^ + | ^ not found in this scope error[E0601]: `main` function not found in crate `issue_90873` --> $DIR/issue-90873.rs:6:37 diff --git a/tests/ui/attributes/key-value-expansion-scope.rs b/tests/ui/attributes/key-value-expansion-scope.rs index 15da8228cc02c..6860b55a0ac0d 100644 --- a/tests/ui/attributes/key-value-expansion-scope.rs +++ b/tests/ui/attributes/key-value-expansion-scope.rs @@ -18,10 +18,10 @@ fn before() { macro_rules! in_root { () => { "" } } -#[doc = in_mod!()] //~ WARN cannot find macro `in_mod` in this scope +#[doc = in_mod!()] //~ WARN cannot find macro `in_mod` //~| WARN this was previously accepted by the compiler mod macros_stay { - #![doc = in_mod!()] //~ WARN cannot find macro `in_mod` in this scope + #![doc = in_mod!()] //~ WARN cannot find macro `in_mod` //~| WARN this was previously accepted by the compiler macro_rules! in_mod { () => { "" } } @@ -33,10 +33,10 @@ mod macros_stay { } #[macro_use] -#[doc = in_mod_escape!()] //~ WARN cannot find macro `in_mod_escape` in this scope +#[doc = in_mod_escape!()] //~ WARN cannot find macro `in_mod_escape` //~| WARN this was previously accepted by the compiler mod macros_escape { - #![doc = in_mod_escape!()] //~ WARN cannot find macro `in_mod_escape` in this scope + #![doc = in_mod_escape!()] //~ WARN cannot find macro `in_mod_escape` //~| WARN this was previously accepted by the compiler macro_rules! in_mod_escape { () => { "" } } @@ -47,7 +47,7 @@ mod macros_escape { } } -#[doc = in_block!()] //~ ERROR cannot find macro `in_block` in this scope +#[doc = in_block!()] //~ ERROR cannot find macro `in_block` fn block() { #![doc = in_block!()] //~ ERROR cannot find macro `in_block` diff --git a/tests/ui/attributes/key-value-expansion-scope.stderr b/tests/ui/attributes/key-value-expansion-scope.stderr index d22fef7dd251e..72865116f721f 100644 --- a/tests/ui/attributes/key-value-expansion-scope.stderr +++ b/tests/ui/attributes/key-value-expansion-scope.stderr @@ -1,187 +1,187 @@ -error: cannot find macro `in_mod` in this scope +error: cannot find macro `in_mod` --> $DIR/key-value-expansion-scope.rs:3:10 | LL | #![doc = in_mod!()] - | ^^^^^^ + | ^^^^^^ not found in this scope | = help: have you added the `#[macro_use]` on the module/import? -error: cannot find macro `in_block` in this scope +error: cannot find macro `in_block` --> $DIR/key-value-expansion-scope.rs:6:10 | LL | #![doc = in_block!()] - | ^^^^^^^^ + | ^^^^^^^^ not found in this scope | = help: have you added the `#[macro_use]` on the module/import? -error: cannot find macro `in_root` in this scope +error: cannot find macro `in_root` --> $DIR/key-value-expansion-scope.rs:8:9 | LL | #[doc = in_root!()] - | ^^^^^^^ + | ^^^^^^^ not found in this scope | = help: have you added the `#[macro_use]` on the module/import? -error: cannot find macro `in_mod` in this scope +error: cannot find macro `in_mod` --> $DIR/key-value-expansion-scope.rs:9:9 | LL | #[doc = in_mod!()] - | ^^^^^^ + | ^^^^^^ not found in this scope | = help: have you added the `#[macro_use]` on the module/import? -error: cannot find macro `in_mod_escape` in this scope +error: cannot find macro `in_mod_escape` --> $DIR/key-value-expansion-scope.rs:10:9 | LL | #[doc = in_mod_escape!()] - | ^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^ not found in this scope | = help: have you added the `#[macro_use]` on the module/import? -error: cannot find macro `in_block` in this scope +error: cannot find macro `in_block` --> $DIR/key-value-expansion-scope.rs:11:9 | LL | #[doc = in_block!()] - | ^^^^^^^^ + | ^^^^^^^^ not found in this scope | = help: have you added the `#[macro_use]` on the module/import? -error: cannot find macro `in_root` in this scope +error: cannot find macro `in_root` --> $DIR/key-value-expansion-scope.rs:13:14 | LL | #![doc = in_root!()] - | ^^^^^^^ + | ^^^^^^^ not found in this scope | = help: have you added the `#[macro_use]` on the module/import? -error: cannot find macro `in_mod` in this scope +error: cannot find macro `in_mod` --> $DIR/key-value-expansion-scope.rs:14:14 | LL | #![doc = in_mod!()] - | ^^^^^^ + | ^^^^^^ not found in this scope | = help: have you added the `#[macro_use]` on the module/import? -error: cannot find macro `in_mod_escape` in this scope +error: cannot find macro `in_mod_escape` --> $DIR/key-value-expansion-scope.rs:15:14 | LL | #![doc = in_mod_escape!()] - | ^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^ not found in this scope | = help: have you added the `#[macro_use]` on the module/import? -error: cannot find macro `in_block` in this scope +error: cannot find macro `in_block` --> $DIR/key-value-expansion-scope.rs:16:14 | LL | #![doc = in_block!()] - | ^^^^^^^^ + | ^^^^^^^^ not found in this scope | = help: have you added the `#[macro_use]` on the module/import? -error: cannot find macro `in_block` in this scope +error: cannot find macro `in_block` --> $DIR/key-value-expansion-scope.rs:50:9 | LL | #[doc = in_block!()] - | ^^^^^^^^ + | ^^^^^^^^ not found in this scope | = help: have you added the `#[macro_use]` on the module/import? -error: cannot find macro `in_block` in this scope +error: cannot find macro `in_block` --> $DIR/key-value-expansion-scope.rs:52:14 | LL | #![doc = in_block!()] - | ^^^^^^^^ + | ^^^^^^^^ not found in this scope | = help: have you added the `#[macro_use]` on the module/import? -error: cannot find macro `in_mod` in this scope +error: cannot find macro `in_mod` --> $DIR/key-value-expansion-scope.rs:63:9 | LL | #[doc = in_mod!()] - | ^^^^^^ + | ^^^^^^ not found in this scope | = help: have you added the `#[macro_use]` on the module/import? -error: cannot find macro `in_block` in this scope +error: cannot find macro `in_block` --> $DIR/key-value-expansion-scope.rs:65:9 | LL | #[doc = in_block!()] - | ^^^^^^^^ + | ^^^^^^^^ not found in this scope | = help: have you added the `#[macro_use]` on the module/import? -error: cannot find macro `in_mod` in this scope +error: cannot find macro `in_mod` --> $DIR/key-value-expansion-scope.rs:68:14 | LL | #![doc = in_mod!()] - | ^^^^^^ + | ^^^^^^ not found in this scope | = help: have you added the `#[macro_use]` on the module/import? -error: cannot find macro `in_block` in this scope +error: cannot find macro `in_block` --> $DIR/key-value-expansion-scope.rs:70:14 | LL | #![doc = in_block!()] - | ^^^^^^^^ + | ^^^^^^^^ not found in this scope | = help: have you added the `#[macro_use]` on the module/import? -warning: cannot find macro `in_root` in this scope +warning: cannot find macro `in_root` --> $DIR/key-value-expansion-scope.rs:1:10 | LL | #![doc = in_root!()] - | ^^^^^^^ + | ^^^^^^^ not found in this scope | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #124535 = help: import `macro_rules` with `use` to make it callable above its definition = note: `#[warn(out_of_scope_macro_calls)]` on by default -warning: cannot find macro `in_mod_escape` in this scope +warning: cannot find macro `in_mod_escape` --> $DIR/key-value-expansion-scope.rs:4:10 | LL | #![doc = in_mod_escape!()] - | ^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^ not found in this scope | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #124535 = help: import `macro_rules` with `use` to make it callable above its definition -warning: cannot find macro `in_mod` in this scope +warning: cannot find macro `in_mod` --> $DIR/key-value-expansion-scope.rs:21:9 | LL | #[doc = in_mod!()] - | ^^^^^^ + | ^^^^^^ not found in this scope | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #124535 = help: import `macro_rules` with `use` to make it callable above its definition -warning: cannot find macro `in_mod` in this scope +warning: cannot find macro `in_mod` --> $DIR/key-value-expansion-scope.rs:24:14 | LL | #![doc = in_mod!()] - | ^^^^^^ + | ^^^^^^ not found in this scope | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #124535 = help: import `macro_rules` with `use` to make it callable above its definition -warning: cannot find macro `in_mod_escape` in this scope +warning: cannot find macro `in_mod_escape` --> $DIR/key-value-expansion-scope.rs:36:9 | LL | #[doc = in_mod_escape!()] - | ^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^ not found in this scope | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #124535 = help: import `macro_rules` with `use` to make it callable above its definition -warning: cannot find macro `in_mod_escape` in this scope +warning: cannot find macro `in_mod_escape` --> $DIR/key-value-expansion-scope.rs:39:14 | LL | #![doc = in_mod_escape!()] - | ^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^ not found in this scope | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #124535 diff --git a/tests/ui/attributes/main-removed-1.stderr b/tests/ui/attributes/main-removed-1.stderr index fda28772e429b..e996ac0b7710c 100644 --- a/tests/ui/attributes/main-removed-1.stderr +++ b/tests/ui/attributes/main-removed-1.stderr @@ -1,8 +1,8 @@ -error: cannot find attribute `main` in this scope +error: cannot find attribute `main` --> $DIR/main-removed-1.rs:1:3 | LL | #[main] - | ^^^^ + | ^^^^ not found in this scope | = note: `main` is in scope, but it is a function, not an attribute diff --git a/tests/ui/attributes/obsolete-attr.stderr b/tests/ui/attributes/obsolete-attr.stderr index 37c1cd0c94df2..d5f0f25b1dc9e 100644 --- a/tests/ui/attributes/obsolete-attr.stderr +++ b/tests/ui/attributes/obsolete-attr.stderr @@ -1,14 +1,14 @@ -error: cannot find attribute `fixed_stack_segment` in this scope +error: cannot find attribute `fixed_stack_segment` --> $DIR/obsolete-attr.rs:6:3 | LL | #[fixed_stack_segment] fn f() {} - | ^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^ not found in this scope -error: cannot find attribute `ab_isize` in this scope +error: cannot find attribute `ab_isize` --> $DIR/obsolete-attr.rs:3:3 | LL | #[ab_isize = "stdcall"] extern "C" {} - | ^^^^^^^^ + | ^^^^^^^^ not found in this scope error: aborting due to 2 previous errors diff --git a/tests/ui/attributes/unknown-attr.stderr b/tests/ui/attributes/unknown-attr.stderr index 85c227dc83aa6..06e60d8299703 100644 --- a/tests/ui/attributes/unknown-attr.stderr +++ b/tests/ui/attributes/unknown-attr.stderr @@ -1,20 +1,20 @@ -error: cannot find attribute `mutable_doc` in this scope +error: cannot find attribute `mutable_doc` --> $DIR/unknown-attr.rs:5:4 | LL | #![mutable_doc] - | ^^^^^^^^^^^ + | ^^^^^^^^^^^ not found in this scope -error: cannot find attribute `dance` in this scope +error: cannot find attribute `dance` --> $DIR/unknown-attr.rs:8:3 | LL | #[dance] mod a {} - | ^^^^^ + | ^^^^^ not found in this scope -error: cannot find attribute `dance` in this scope +error: cannot find attribute `dance` --> $DIR/unknown-attr.rs:11:3 | LL | #[dance] fn main() {} - | ^^^^^ + | ^^^^^ not found in this scope error: aborting due to 3 previous errors diff --git a/tests/ui/attributes/unsafe/double-unsafe-attributes.stderr b/tests/ui/attributes/unsafe/double-unsafe-attributes.stderr index ea82bac6df07b..c776c4a52193b 100644 --- a/tests/ui/attributes/unsafe/double-unsafe-attributes.stderr +++ b/tests/ui/attributes/unsafe/double-unsafe-attributes.stderr @@ -17,11 +17,11 @@ LL | #[unsafe(unsafe(no_mangle))] | = note: extraneous unsafe is not allowed in attributes -error: cannot find attribute `r#unsafe` in this scope +error: cannot find attribute `r#unsafe` --> $DIR/double-unsafe-attributes.rs:3:10 | LL | #[unsafe(unsafe(no_mangle))] - | ^^^^^^ + | ^^^^^^ not found in this scope error: aborting due to 3 previous errors diff --git a/tests/ui/attributes/unused-item-in-attr.stderr b/tests/ui/attributes/unused-item-in-attr.stderr index 84130965d31cf..9df0416e76655 100644 --- a/tests/ui/attributes/unused-item-in-attr.stderr +++ b/tests/ui/attributes/unused-item-in-attr.stderr @@ -4,11 +4,11 @@ error: attribute value must be a literal LL | #[w = { extern crate alloc; }] | ^^^^^^^^^^^^^^^^^^^^^^^ -error: cannot find attribute `w` in this scope +error: cannot find attribute `w` --> $DIR/unused-item-in-attr.rs:1:3 | LL | #[w = { extern crate alloc; }] - | ^ + | ^ not found in this scope error: aborting due to 2 previous errors diff --git a/tests/ui/conditional-compilation/cfg-attr-unknown-attribute-macro-expansion.stderr b/tests/ui/conditional-compilation/cfg-attr-unknown-attribute-macro-expansion.stderr index c91ad128d6e57..13909c9e2faf9 100644 --- a/tests/ui/conditional-compilation/cfg-attr-unknown-attribute-macro-expansion.stderr +++ b/tests/ui/conditional-compilation/cfg-attr-unknown-attribute-macro-expansion.stderr @@ -1,8 +1,8 @@ -error: cannot find attribute `unknown` in this scope +error: cannot find attribute `unknown` --> $DIR/cfg-attr-unknown-attribute-macro-expansion.rs:3:27 | LL | #[cfg_attr(all(), unknown)] - | ^^^^^^^ + | ^^^^^^^ not found in this scope ... LL | foo!(); | ------ in this macro invocation diff --git a/tests/ui/conditional-compilation/cfg-generic-params.stderr b/tests/ui/conditional-compilation/cfg-generic-params.stderr index 563616be36bc1..8d8c9548c009e 100644 --- a/tests/ui/conditional-compilation/cfg-generic-params.stderr +++ b/tests/ui/conditional-compilation/cfg-generic-params.stderr @@ -1,32 +1,32 @@ -error: cannot find attribute `unknown` in this scope +error: cannot find attribute `unknown` --> $DIR/cfg-generic-params.rs:19:29 | LL | fn f_lt_yes<#[cfg_attr(yes, unknown)] 'a>() {} - | ^^^^^^^ + | ^^^^^^^ not found in this scope -error: cannot find attribute `unknown` in this scope +error: cannot find attribute `unknown` --> $DIR/cfg-generic-params.rs:22:29 | LL | fn f_ty_yes<#[cfg_attr(yes, unknown)] T>() {} - | ^^^^^^^ + | ^^^^^^^ not found in this scope -error: cannot find attribute `unknown` in this scope +error: cannot find attribute `unknown` --> $DIR/cfg-generic-params.rs:26:34 | LL | type FnYes = for<#[cfg_attr(yes, unknown)] 'a> fn(); - | ^^^^^^^ + | ^^^^^^^ not found in this scope -error: cannot find attribute `unknown` in this scope +error: cannot find attribute `unknown` --> $DIR/cfg-generic-params.rs:30:40 | LL | type PolyYes = dyn for<#[cfg_attr(yes, unknown)] 'a> Copy; - | ^^^^^^^ + | ^^^^^^^ not found in this scope -error: cannot find attribute `unknown` in this scope +error: cannot find attribute `unknown` --> $DIR/cfg-generic-params.rs:34:43 | LL | struct WhereYes where for<#[cfg_attr(yes, unknown)] 'a> u8: Copy; - | ^^^^^^^ + | ^^^^^^^ not found in this scope error[E0658]: only lifetime parameters can be used in this context --> $DIR/cfg-generic-params.rs:7:48 diff --git a/tests/ui/consts/issue-90878-2.stderr b/tests/ui/consts/issue-90878-2.stderr index 0b332840042ef..af6d48d215f3b 100644 --- a/tests/ui/consts/issue-90878-2.stderr +++ b/tests/ui/consts/issue-90878-2.stderr @@ -4,11 +4,11 @@ error: attribute value must be a literal LL | #![l=|x|[b;x ]] | ^^^^^^^^^ -error: cannot find attribute `l` in this scope +error: cannot find attribute `l` --> $DIR/issue-90878-2.rs:1:5 | LL | #![l=|x|[b;x ]] - | ^ + | ^ not found in this scope error: aborting due to 2 previous errors diff --git a/tests/ui/custom_attribute.stderr b/tests/ui/custom_attribute.stderr index 4023892d29466..9e6a5dde6c7fd 100644 --- a/tests/ui/custom_attribute.stderr +++ b/tests/ui/custom_attribute.stderr @@ -1,20 +1,20 @@ -error: cannot find attribute `foo` in this scope +error: cannot find attribute `foo` --> $DIR/custom_attribute.rs:3:3 | LL | #[foo] - | ^^^ + | ^^^ not found in this scope -error: cannot find attribute `foo` in this scope +error: cannot find attribute `foo` --> $DIR/custom_attribute.rs:5:7 | LL | #[foo] - | ^^^ + | ^^^ not found in this scope -error: cannot find attribute `foo` in this scope +error: cannot find attribute `foo` --> $DIR/custom_attribute.rs:7:7 | LL | #[foo] - | ^^^ + | ^^^ not found in this scope error: aborting due to 3 previous errors diff --git a/tests/ui/deduplicate-diagnostics.deduplicate.stderr b/tests/ui/deduplicate-diagnostics.deduplicate.stderr index 5df2c687bddc2..ed897b2023e1c 100644 --- a/tests/ui/deduplicate-diagnostics.deduplicate.stderr +++ b/tests/ui/deduplicate-diagnostics.deduplicate.stderr @@ -4,11 +4,11 @@ error[E0452]: malformed lint attribute input LL | #[deny("literal")] | ^^^^^^^^^ bad attribute argument -error: cannot find derive macro `Unresolved` in this scope +error: cannot find derive macro `Unresolved` --> $DIR/deduplicate-diagnostics.rs:4:10 | LL | #[derive(Unresolved)] - | ^^^^^^^^^^ + | ^^^^^^^^^^ not found in this scope error: aborting due to 2 previous errors diff --git a/tests/ui/deduplicate-diagnostics.duplicate.stderr b/tests/ui/deduplicate-diagnostics.duplicate.stderr index 0544b993278d7..69e9f606b4967 100644 --- a/tests/ui/deduplicate-diagnostics.duplicate.stderr +++ b/tests/ui/deduplicate-diagnostics.duplicate.stderr @@ -4,17 +4,17 @@ error[E0452]: malformed lint attribute input LL | #[deny("literal")] | ^^^^^^^^^ bad attribute argument -error: cannot find derive macro `Unresolved` in this scope +error: cannot find derive macro `Unresolved` --> $DIR/deduplicate-diagnostics.rs:4:10 | LL | #[derive(Unresolved)] - | ^^^^^^^^^^ + | ^^^^^^^^^^ not found in this scope -error: cannot find derive macro `Unresolved` in this scope +error: cannot find derive macro `Unresolved` --> $DIR/deduplicate-diagnostics.rs:4:10 | LL | #[derive(Unresolved)] - | ^^^^^^^^^^ + | ^^^^^^^^^^ not found in this scope | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` diff --git a/tests/ui/derives/deriving-bounds.stderr b/tests/ui/derives/deriving-bounds.stderr index 4461652eb02e3..09b8cb4339356 100644 --- a/tests/ui/derives/deriving-bounds.stderr +++ b/tests/ui/derives/deriving-bounds.stderr @@ -1,8 +1,8 @@ -error: cannot find derive macro `Sync` in this scope +error: cannot find derive macro `Sync` --> $DIR/deriving-bounds.rs:6:10 | LL | #[derive(Sync)] - | ^^^^ + | ^^^^ not found in this scope | note: unsafe traits like `Sync` should be implemented explicitly --> $DIR/deriving-bounds.rs:6:10 @@ -10,11 +10,11 @@ note: unsafe traits like `Sync` should be implemented explicitly LL | #[derive(Sync)] | ^^^^ -error: cannot find derive macro `Sync` in this scope +error: cannot find derive macro `Sync` --> $DIR/deriving-bounds.rs:6:10 | LL | #[derive(Sync)] - | ^^^^ + | ^^^^ not found in this scope | note: unsafe traits like `Sync` should be implemented explicitly --> $DIR/deriving-bounds.rs:6:10 @@ -23,11 +23,11 @@ LL | #[derive(Sync)] | ^^^^ = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error: cannot find derive macro `Send` in this scope +error: cannot find derive macro `Send` --> $DIR/deriving-bounds.rs:1:10 | LL | #[derive(Send)] - | ^^^^ + | ^^^^ not found in this scope | note: unsafe traits like `Send` should be implemented explicitly --> $DIR/deriving-bounds.rs:1:10 @@ -35,11 +35,11 @@ note: unsafe traits like `Send` should be implemented explicitly LL | #[derive(Send)] | ^^^^ -error: cannot find derive macro `Send` in this scope +error: cannot find derive macro `Send` --> $DIR/deriving-bounds.rs:1:10 | LL | #[derive(Send)] - | ^^^^ + | ^^^^ not found in this scope | note: unsafe traits like `Send` should be implemented explicitly --> $DIR/deriving-bounds.rs:1:10 diff --git a/tests/ui/derives/deriving-meta-unknown-trait.stderr b/tests/ui/derives/deriving-meta-unknown-trait.stderr index 28753b8f9f288..bd00c3b01cf15 100644 --- a/tests/ui/derives/deriving-meta-unknown-trait.stderr +++ b/tests/ui/derives/deriving-meta-unknown-trait.stderr @@ -1,17 +1,23 @@ -error: cannot find derive macro `Eqr` in this scope +error: cannot find derive macro `Eqr` --> $DIR/deriving-meta-unknown-trait.rs:1:10 | LL | #[derive(Eqr)] - | ^^^ help: a derive macro with a similar name exists: `Eq` + | ^^^ + | | + | not found in this scope + | help: a derive macro with a similar name exists: `Eq` --> $SRC_DIR/core/src/cmp.rs:LL:COL | = note: similarly named derive macro `Eq` defined here -error: cannot find derive macro `Eqr` in this scope +error: cannot find derive macro `Eqr` --> $DIR/deriving-meta-unknown-trait.rs:1:10 | LL | #[derive(Eqr)] - | ^^^ help: a derive macro with a similar name exists: `Eq` + | ^^^ + | | + | not found in this scope + | help: a derive macro with a similar name exists: `Eq` --> $SRC_DIR/core/src/cmp.rs:LL:COL | = note: similarly named derive macro `Eq` defined here diff --git a/tests/ui/derives/deriving-primitive.stderr b/tests/ui/derives/deriving-primitive.stderr index b39637825e56c..1c5e75199c1d5 100644 --- a/tests/ui/derives/deriving-primitive.stderr +++ b/tests/ui/derives/deriving-primitive.stderr @@ -1,14 +1,14 @@ -error: cannot find derive macro `FromPrimitive` in this scope +error: cannot find derive macro `FromPrimitive` --> $DIR/deriving-primitive.rs:1:10 | LL | #[derive(FromPrimitive)] - | ^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^ not found in this scope -error: cannot find derive macro `FromPrimitive` in this scope +error: cannot find derive macro `FromPrimitive` --> $DIR/deriving-primitive.rs:1:10 | LL | #[derive(FromPrimitive)] - | ^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^ not found in this scope | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` diff --git a/tests/ui/diagnostic_namespace/requires_path.stderr b/tests/ui/diagnostic_namespace/requires_path.stderr index e02aacac8c1a7..abcf637a72027 100644 --- a/tests/ui/diagnostic_namespace/requires_path.stderr +++ b/tests/ui/diagnostic_namespace/requires_path.stderr @@ -1,8 +1,8 @@ -error: cannot find attribute `diagnostic` in this scope +error: cannot find attribute `diagnostic` --> $DIR/requires_path.rs:1:3 | LL | #[diagnostic] - | ^^^^^^^^^^ + | ^^^^^^^^^^ not found in this scope error: aborting due to 1 previous error diff --git a/tests/ui/did_you_mean/println-typo.stderr b/tests/ui/did_you_mean/println-typo.stderr index a1e0b1f1ba4f1..54bc308bcae76 100644 --- a/tests/ui/did_you_mean/println-typo.stderr +++ b/tests/ui/did_you_mean/println-typo.stderr @@ -1,8 +1,11 @@ -error: cannot find macro `prinltn` in this scope +error: cannot find macro `prinltn` --> $DIR/println-typo.rs:4:5 | LL | prinltn!(); - | ^^^^^^^ help: a macro with a similar name exists: `println` + | ^^^^^^^ + | | + | not found in this scope + | help: a macro with a similar name exists: `println` --> $SRC_DIR/std/src/macros.rs:LL:COL | = note: similarly named macro `println` defined here diff --git a/tests/ui/empty/empty-macro-use.stderr b/tests/ui/empty/empty-macro-use.stderr index cdf3ff83cc38c..36cf6eb1ee926 100644 --- a/tests/ui/empty/empty-macro-use.stderr +++ b/tests/ui/empty/empty-macro-use.stderr @@ -1,8 +1,8 @@ -error: cannot find macro `macro_two` in this scope +error: cannot find macro `macro_two` --> $DIR/empty-macro-use.rs:7:5 | LL | macro_two!(); - | ^^^^^^^^^ + | ^^^^^^^^^ not found in this scope | help: consider importing this macro | diff --git a/tests/ui/enum/suggest-default-attribute.stderr b/tests/ui/enum/suggest-default-attribute.stderr index fa72db6aaef9d..d18f912354950 100644 --- a/tests/ui/enum/suggest-default-attribute.stderr +++ b/tests/ui/enum/suggest-default-attribute.stderr @@ -1,8 +1,8 @@ -error: cannot find attribute `default` in this scope +error: cannot find attribute `default` --> $DIR/suggest-default-attribute.rs:2:7 | LL | #[default] - | ^^^^^^^ + | ^^^^^^^ not found in this scope | help: consider adding a derive | diff --git a/tests/ui/ext-nonexistent.stderr b/tests/ui/ext-nonexistent.stderr index 8891e823e4af7..fa2ebb1679893 100644 --- a/tests/ui/ext-nonexistent.stderr +++ b/tests/ui/ext-nonexistent.stderr @@ -1,8 +1,8 @@ -error: cannot find macro `iamnotanextensionthatexists` in this scope +error: cannot find macro `iamnotanextensionthatexists` --> $DIR/ext-nonexistent.rs:2:13 | LL | fn main() { iamnotanextensionthatexists!(""); } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ not found in this scope error: aborting due to 1 previous error diff --git a/tests/ui/extern/issue-80074.stderr b/tests/ui/extern/issue-80074.stderr index b30b761593e88..cf0c8e057d70d 100644 --- a/tests/ui/extern/issue-80074.stderr +++ b/tests/ui/extern/issue-80074.stderr @@ -4,17 +4,17 @@ error[E0469]: imported macro not found LL | #[macro_use(m)] | ^ -error: cannot find macro `bar` in this scope +error: cannot find macro `bar` --> $DIR/issue-80074.rs:16:5 | LL | bar!(); - | ^^^ + | ^^^ not found in this scope -error: cannot find macro `m` in this scope +error: cannot find macro `m` --> $DIR/issue-80074.rs:18:5 | LL | m!(); - | ^ + | ^ not found in this scope warning: macro `foo` is private --> $DIR/issue-80074.rs:13:5 diff --git a/tests/ui/feature-gates/feature-gate-custom_attribute.rs b/tests/ui/feature-gates/feature-gate-custom_attribute.rs index 08acffe414614..775e13114e51c 100644 --- a/tests/ui/feature-gates/feature-gate-custom_attribute.rs +++ b/tests/ui/feature-gates/feature-gate-custom_attribute.rs @@ -5,10 +5,10 @@ #[fake_attr(1, 2, 3)] //~ ERROR cannot find attribute `fake_attr` #[fake_attr("hello")] //~ ERROR cannot find attribute `fake_attr` #[fake_attr(name = "hello")] //~ ERROR cannot find attribute `fake_attr` -#[fake_attr(1, "hi", key = 12, true, false)] //~ ERROR cannot find attribute `fake_attr` in th -#[fake_attr(key = "hello", val = 10)] //~ ERROR cannot find attribute `fake_attr` in this scop +#[fake_attr(1, "hi", key = 12, true, false)] //~ ERROR cannot find attribute `fake_attr` +#[fake_attr(key = "hello", val = 10)] //~ ERROR cannot find attribute `fake_attr` #[fake_attr(key("hello"), val(10))] //~ ERROR cannot find attribute `fake_attr` -#[fake_attr(enabled = true, disabled = false)] //~ ERROR cannot find attribute `fake_attr` in +#[fake_attr(enabled = true, disabled = false)] //~ ERROR cannot find attribute `fake_attr` #[fake_attr(true)] //~ ERROR cannot find attribute `fake_attr` #[fake_attr(pi = 3.14159)] //~ ERROR cannot find attribute `fake_attr` #[fake_attr(b"hi")] //~ ERROR cannot find attribute `fake_attr` diff --git a/tests/ui/feature-gates/feature-gate-custom_attribute.stderr b/tests/ui/feature-gates/feature-gate-custom_attribute.stderr index b7c45ec1fb7ea..dbedb8fed2600 100644 --- a/tests/ui/feature-gates/feature-gate-custom_attribute.stderr +++ b/tests/ui/feature-gates/feature-gate-custom_attribute.stderr @@ -1,80 +1,80 @@ -error: cannot find attribute `fake_attr` in this scope +error: cannot find attribute `fake_attr` --> $DIR/feature-gate-custom_attribute.rs:3:3 | LL | #[fake_attr] - | ^^^^^^^^^ + | ^^^^^^^^^ not found in this scope -error: cannot find attribute `fake_attr` in this scope +error: cannot find attribute `fake_attr` --> $DIR/feature-gate-custom_attribute.rs:4:3 | LL | #[fake_attr(100)] - | ^^^^^^^^^ + | ^^^^^^^^^ not found in this scope -error: cannot find attribute `fake_attr` in this scope +error: cannot find attribute `fake_attr` --> $DIR/feature-gate-custom_attribute.rs:5:3 | LL | #[fake_attr(1, 2, 3)] - | ^^^^^^^^^ + | ^^^^^^^^^ not found in this scope -error: cannot find attribute `fake_attr` in this scope +error: cannot find attribute `fake_attr` --> $DIR/feature-gate-custom_attribute.rs:6:3 | LL | #[fake_attr("hello")] - | ^^^^^^^^^ + | ^^^^^^^^^ not found in this scope -error: cannot find attribute `fake_attr` in this scope +error: cannot find attribute `fake_attr` --> $DIR/feature-gate-custom_attribute.rs:7:3 | LL | #[fake_attr(name = "hello")] - | ^^^^^^^^^ + | ^^^^^^^^^ not found in this scope -error: cannot find attribute `fake_attr` in this scope +error: cannot find attribute `fake_attr` --> $DIR/feature-gate-custom_attribute.rs:8:3 | LL | #[fake_attr(1, "hi", key = 12, true, false)] - | ^^^^^^^^^ + | ^^^^^^^^^ not found in this scope -error: cannot find attribute `fake_attr` in this scope +error: cannot find attribute `fake_attr` --> $DIR/feature-gate-custom_attribute.rs:9:3 | LL | #[fake_attr(key = "hello", val = 10)] - | ^^^^^^^^^ + | ^^^^^^^^^ not found in this scope -error: cannot find attribute `fake_attr` in this scope +error: cannot find attribute `fake_attr` --> $DIR/feature-gate-custom_attribute.rs:10:3 | LL | #[fake_attr(key("hello"), val(10))] - | ^^^^^^^^^ + | ^^^^^^^^^ not found in this scope -error: cannot find attribute `fake_attr` in this scope +error: cannot find attribute `fake_attr` --> $DIR/feature-gate-custom_attribute.rs:11:3 | LL | #[fake_attr(enabled = true, disabled = false)] - | ^^^^^^^^^ + | ^^^^^^^^^ not found in this scope -error: cannot find attribute `fake_attr` in this scope +error: cannot find attribute `fake_attr` --> $DIR/feature-gate-custom_attribute.rs:12:3 | LL | #[fake_attr(true)] - | ^^^^^^^^^ + | ^^^^^^^^^ not found in this scope -error: cannot find attribute `fake_attr` in this scope +error: cannot find attribute `fake_attr` --> $DIR/feature-gate-custom_attribute.rs:13:3 | LL | #[fake_attr(pi = 3.14159)] - | ^^^^^^^^^ + | ^^^^^^^^^ not found in this scope -error: cannot find attribute `fake_attr` in this scope +error: cannot find attribute `fake_attr` --> $DIR/feature-gate-custom_attribute.rs:14:3 | LL | #[fake_attr(b"hi")] - | ^^^^^^^^^ + | ^^^^^^^^^ not found in this scope -error: cannot find attribute `fake_doc` in this scope +error: cannot find attribute `fake_doc` --> $DIR/feature-gate-custom_attribute.rs:15:3 | LL | #[fake_doc(r"doc")] - | ^^^^^^^^ + | ^^^^^^^^ not found in this scope error: aborting due to 13 previous errors diff --git a/tests/ui/feature-gates/feature-gate-custom_attribute2.stderr b/tests/ui/feature-gates/feature-gate-custom_attribute2.stderr index f2287111719bc..703a5a43f39f2 100644 --- a/tests/ui/feature-gates/feature-gate-custom_attribute2.stderr +++ b/tests/ui/feature-gates/feature-gate-custom_attribute2.stderr @@ -1,104 +1,104 @@ -error: cannot find attribute `lt_struct` in this scope +error: cannot find attribute `lt_struct` --> $DIR/feature-gate-custom_attribute2.rs:4:15 | LL | struct StLt<#[lt_struct] 'a>(&'a u32); - | ^^^^^^^^^ + | ^^^^^^^^^ not found in this scope -error: cannot find attribute `ty_struct` in this scope +error: cannot find attribute `ty_struct` --> $DIR/feature-gate-custom_attribute2.rs:6:15 | LL | struct StTy<#[ty_struct] I>(I); - | ^^^^^^^^^ + | ^^^^^^^^^ not found in this scope -error: cannot find attribute `lt_enum` in this scope +error: cannot find attribute `lt_enum` --> $DIR/feature-gate-custom_attribute2.rs:9:13 | LL | enum EnLt<#[lt_enum] 'b> { A(&'b u32), B } - | ^^^^^^^ + | ^^^^^^^ not found in this scope -error: cannot find attribute `ty_enum` in this scope +error: cannot find attribute `ty_enum` --> $DIR/feature-gate-custom_attribute2.rs:11:13 | LL | enum EnTy<#[ty_enum] J> { A(J), B } - | ^^^^^^^ + | ^^^^^^^ not found in this scope -error: cannot find attribute `lt_trait` in this scope +error: cannot find attribute `lt_trait` --> $DIR/feature-gate-custom_attribute2.rs:14:14 | LL | trait TrLt<#[lt_trait] 'c> { fn foo(&self, _: &'c [u32]) -> &'c u32; } - | ^^^^^^^^ + | ^^^^^^^^ not found in this scope -error: cannot find attribute `ty_trait` in this scope +error: cannot find attribute `ty_trait` --> $DIR/feature-gate-custom_attribute2.rs:16:14 | LL | trait TrTy<#[ty_trait] K> { fn foo(&self, _: K); } - | ^^^^^^^^ + | ^^^^^^^^ not found in this scope -error: cannot find attribute `lt_type` in this scope +error: cannot find attribute `lt_type` --> $DIR/feature-gate-custom_attribute2.rs:19:13 | LL | type TyLt<#[lt_type] 'd> = &'d u32; - | ^^^^^^^ + | ^^^^^^^ not found in this scope -error: cannot find attribute `ty_type` in this scope +error: cannot find attribute `ty_type` --> $DIR/feature-gate-custom_attribute2.rs:21:13 | LL | type TyTy<#[ty_type] L> = (L, ); - | ^^^^^^^ + | ^^^^^^^ not found in this scope -error: cannot find attribute `lt_inherent` in this scope +error: cannot find attribute `lt_inherent` --> $DIR/feature-gate-custom_attribute2.rs:24:8 | LL | impl<#[lt_inherent] 'e> StLt<'e> { } - | ^^^^^^^^^^^ + | ^^^^^^^^^^^ not found in this scope -error: cannot find attribute `ty_inherent` in this scope +error: cannot find attribute `ty_inherent` --> $DIR/feature-gate-custom_attribute2.rs:26:8 | LL | impl<#[ty_inherent] M> StTy { } - | ^^^^^^^^^^^ + | ^^^^^^^^^^^ not found in this scope -error: cannot find attribute `lt_impl_for` in this scope +error: cannot find attribute `lt_impl_for` --> $DIR/feature-gate-custom_attribute2.rs:29:8 | LL | impl<#[lt_impl_for] 'f> TrLt<'f> for StLt<'f> { - | ^^^^^^^^^^^ + | ^^^^^^^^^^^ not found in this scope -error: cannot find attribute `ty_impl_for` in this scope +error: cannot find attribute `ty_impl_for` --> $DIR/feature-gate-custom_attribute2.rs:33:8 | LL | impl<#[ty_impl_for] N> TrTy for StTy { - | ^^^^^^^^^^^ + | ^^^^^^^^^^^ not found in this scope -error: cannot find attribute `lt_fn` in this scope +error: cannot find attribute `lt_fn` --> $DIR/feature-gate-custom_attribute2.rs:38:11 | LL | fn f_lt<#[lt_fn] 'g>(_: &'g [u32]) -> &'g u32 { loop { } } - | ^^^^^ + | ^^^^^ not found in this scope -error: cannot find attribute `ty_fn` in this scope +error: cannot find attribute `ty_fn` --> $DIR/feature-gate-custom_attribute2.rs:40:11 | LL | fn f_ty<#[ty_fn] O>(_: O) { } - | ^^^^^ + | ^^^^^ not found in this scope -error: cannot find attribute `lt_meth` in this scope +error: cannot find attribute `lt_meth` --> $DIR/feature-gate-custom_attribute2.rs:44:15 | LL | fn m_lt<#[lt_meth] 'h>(_: &'h [u32]) -> &'h u32 { loop { } } - | ^^^^^^^ + | ^^^^^^^ not found in this scope -error: cannot find attribute `ty_meth` in this scope +error: cannot find attribute `ty_meth` --> $DIR/feature-gate-custom_attribute2.rs:46:15 | LL | fn m_ty<#[ty_meth] P>(_: P) { } - | ^^^^^^^ + | ^^^^^^^ not found in this scope -error: cannot find attribute `lt_hof` in this scope +error: cannot find attribute `lt_hof` --> $DIR/feature-gate-custom_attribute2.rs:51:21 | LL | where Q: for <#[lt_hof] 'i> Fn(&'i [u32]) -> &'i u32 - | ^^^^^^ + | ^^^^^^ not found in this scope error: aborting due to 17 previous errors diff --git a/tests/ui/feature-gates/feature-gate-rustc-attrs.stderr b/tests/ui/feature-gates/feature-gate-rustc-attrs.stderr index c7a5ef3e44be7..cb8b9a027c3c4 100644 --- a/tests/ui/feature-gates/feature-gate-rustc-attrs.stderr +++ b/tests/ui/feature-gates/feature-gate-rustc-attrs.stderr @@ -28,11 +28,11 @@ error: attributes starting with `rustc` are reserved for use by the `rustc` comp LL | #[rustc_unknown] | ^^^^^^^^^^^^^ -error: cannot find attribute `rustc_unknown` in this scope +error: cannot find attribute `rustc_unknown` --> $DIR/feature-gate-rustc-attrs.rs:20:3 | LL | #[rustc_unknown] - | ^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^ not found in this scope error[E0658]: the `#[rustc_dummy]` attribute is just used for rustc unit tests and will never be stable --> $DIR/feature-gate-rustc-attrs.rs:18:1 diff --git a/tests/ui/feature-gates/issue-43106-gating-of-derive-2.stderr b/tests/ui/feature-gates/issue-43106-gating-of-derive-2.stderr index 1e47259cb7ed5..28c20ddca7db5 100644 --- a/tests/ui/feature-gates/issue-43106-gating-of-derive-2.stderr +++ b/tests/ui/feature-gates/issue-43106-gating-of-derive-2.stderr @@ -1,42 +1,42 @@ -error: cannot find derive macro `x3300` in this scope +error: cannot find derive macro `x3300` --> $DIR/issue-43106-gating-of-derive-2.rs:14:14 | LL | #[derive(x3300)] - | ^^^^^ + | ^^^^^ not found in this scope -error: cannot find derive macro `x3300` in this scope +error: cannot find derive macro `x3300` --> $DIR/issue-43106-gating-of-derive-2.rs:14:14 | LL | #[derive(x3300)] - | ^^^^^ + | ^^^^^ not found in this scope | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error: cannot find derive macro `x3300` in this scope +error: cannot find derive macro `x3300` --> $DIR/issue-43106-gating-of-derive-2.rs:9:14 | LL | #[derive(x3300)] - | ^^^^^ + | ^^^^^ not found in this scope -error: cannot find derive macro `x3300` in this scope +error: cannot find derive macro `x3300` --> $DIR/issue-43106-gating-of-derive-2.rs:9:14 | LL | #[derive(x3300)] - | ^^^^^ + | ^^^^^ not found in this scope | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error: cannot find derive macro `x3300` in this scope +error: cannot find derive macro `x3300` --> $DIR/issue-43106-gating-of-derive-2.rs:4:14 | LL | #[derive(x3300)] - | ^^^^^ + | ^^^^^ not found in this scope -error: cannot find derive macro `x3300` in this scope +error: cannot find derive macro `x3300` --> $DIR/issue-43106-gating-of-derive-2.rs:4:14 | LL | #[derive(x3300)] - | ^^^^^ + | ^^^^^ not found in this scope | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` diff --git a/tests/ui/hygiene/no_implicit_prelude-2018.stderr b/tests/ui/hygiene/no_implicit_prelude-2018.stderr index 7b124edf6f6db..f367e8a062fc6 100644 --- a/tests/ui/hygiene/no_implicit_prelude-2018.stderr +++ b/tests/ui/hygiene/no_implicit_prelude-2018.stderr @@ -1,8 +1,8 @@ -error: cannot find macro `print` in this scope +error: cannot find macro `print` --> $DIR/no_implicit_prelude-2018.rs:7:9 | LL | print!(); - | ^^^^^ + | ^^^^^ not found in this scope | help: consider importing this macro | diff --git a/tests/ui/issues/issue-19734.stderr b/tests/ui/issues/issue-19734.stderr index ed48714fe5078..9c5dba3fc67a4 100644 --- a/tests/ui/issues/issue-19734.stderr +++ b/tests/ui/issues/issue-19734.stderr @@ -1,8 +1,8 @@ -error: cannot find macro `undef` in this scope +error: cannot find macro `undef` --> $DIR/issue-19734.rs:6:5 | LL | undef!(); - | ^^^^^ + | ^^^^^ not found in this scope error: aborting due to 1 previous error diff --git a/tests/ui/issues/issue-32655.stderr b/tests/ui/issues/issue-32655.stderr index b8362499b2d0a..215e2f7c69bcc 100644 --- a/tests/ui/issues/issue-32655.stderr +++ b/tests/ui/issues/issue-32655.stderr @@ -1,8 +1,11 @@ -error: cannot find attribute `derive_Clone` in this scope +error: cannot find attribute `derive_Clone` --> $DIR/issue-32655.rs:3:11 | LL | #[derive_Clone] - | ^^^^^^^^^^^^ help: an attribute macro with a similar name exists: `derive_const` + | ^^^^^^^^^^^^ + | | + | not found in this scope + | help: an attribute macro with a similar name exists: `derive_const` ... LL | foo!(); | ------ in this macro invocation @@ -12,11 +15,14 @@ LL | foo!(); | = note: this error originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info) -error: cannot find attribute `derive_Clone` in this scope +error: cannot find attribute `derive_Clone` --> $DIR/issue-32655.rs:15:7 | LL | #[derive_Clone] - | ^^^^^^^^^^^^ help: an attribute macro with a similar name exists: `derive_const` + | ^^^^^^^^^^^^ + | | + | not found in this scope + | help: an attribute macro with a similar name exists: `derive_const` --> $SRC_DIR/core/src/macros/mod.rs:LL:COL | = note: similarly named attribute macro `derive_const` defined here diff --git a/tests/ui/issues/issue-33571.stderr b/tests/ui/issues/issue-33571.stderr index 819a533ddbe2f..3f9bf3acb09ee 100644 --- a/tests/ui/issues/issue-33571.stderr +++ b/tests/ui/issues/issue-33571.stderr @@ -1,8 +1,8 @@ -error: cannot find derive macro `Sync` in this scope +error: cannot find derive macro `Sync` --> $DIR/issue-33571.rs:2:10 | LL | Sync, - | ^^^^ + | ^^^^ not found in this scope | note: unsafe traits like `Sync` should be implemented explicitly --> $DIR/issue-33571.rs:2:10 @@ -10,11 +10,11 @@ note: unsafe traits like `Sync` should be implemented explicitly LL | Sync, | ^^^^ -error: cannot find derive macro `Sync` in this scope +error: cannot find derive macro `Sync` --> $DIR/issue-33571.rs:2:10 | LL | Sync, - | ^^^^ + | ^^^^ not found in this scope | note: unsafe traits like `Sync` should be implemented explicitly --> $DIR/issue-33571.rs:2:10 diff --git a/tests/ui/issues/issue-40845.stderr b/tests/ui/issues/issue-40845.stderr index 66bf053204c08..d0811cbe846ea 100644 --- a/tests/ui/issues/issue-40845.stderr +++ b/tests/ui/issues/issue-40845.stderr @@ -1,14 +1,14 @@ -error: cannot find macro `m` in this scope +error: cannot find macro `m` --> $DIR/issue-40845.rs:1:11 | LL | trait T { m!(); } - | ^ + | ^ not found in this scope -error: cannot find macro `m` in this scope +error: cannot find macro `m` --> $DIR/issue-40845.rs:4:10 | LL | impl S { m!(); } - | ^ + | ^ not found in this scope error: aborting due to 2 previous errors diff --git a/tests/ui/macros/defined-later-issue-121061-2.stderr b/tests/ui/macros/defined-later-issue-121061-2.stderr index aa6ef33853193..78c6d5f90f5a2 100644 --- a/tests/ui/macros/defined-later-issue-121061-2.stderr +++ b/tests/ui/macros/defined-later-issue-121061-2.stderr @@ -1,8 +1,11 @@ -error: cannot find macro `something_later` in this scope +error: cannot find macro `something_later` --> $DIR/defined-later-issue-121061-2.rs:3:9 | LL | something_later!(); - | ^^^^^^^^^^^^^^^ consider moving the definition of `something_later` before this call + | ^^^^^^^^^^^^^^^ + | | + | not found in this scope + | consider moving the definition of `something_later` before this call | note: a macro with the same name exists, but it appears later at here --> $DIR/defined-later-issue-121061-2.rs:6:18 diff --git a/tests/ui/macros/defined-later-issue-121061.stderr b/tests/ui/macros/defined-later-issue-121061.stderr index 65cb53432a932..bbaf3055b366b 100644 --- a/tests/ui/macros/defined-later-issue-121061.stderr +++ b/tests/ui/macros/defined-later-issue-121061.stderr @@ -1,8 +1,11 @@ -error: cannot find macro `something_later` in this scope +error: cannot find macro `something_later` --> $DIR/defined-later-issue-121061.rs:2:5 | LL | something_later!(); - | ^^^^^^^^^^^^^^^ consider moving the definition of `something_later` before this call + | ^^^^^^^^^^^^^^^ + | | + | not found in this scope + | consider moving the definition of `something_later` before this call | note: a macro with the same name exists, but it appears later at here --> $DIR/defined-later-issue-121061.rs:5:14 diff --git a/tests/ui/macros/expand-full-no-resolution.stderr b/tests/ui/macros/expand-full-no-resolution.stderr index df6f20332bfd8..8680eccd8669e 100644 --- a/tests/ui/macros/expand-full-no-resolution.stderr +++ b/tests/ui/macros/expand-full-no-resolution.stderr @@ -1,25 +1,25 @@ -error: cannot find macro `a` in this scope +error: cannot find macro `a` --> $DIR/expand-full-no-resolution.rs:18:18 | LL | macro_rules! _a { | --------------- similarly named macro `_a` defined here ... LL | format_args!(a!()); - | ^ + | ^ not found in this scope | help: the leading underscore in `_a` marks it as unused, consider renaming it to `a` | LL | macro_rules! a { | ~ -error: cannot find macro `a` in this scope +error: cannot find macro `a` --> $DIR/expand-full-no-resolution.rs:19:10 | LL | macro_rules! _a { | --------------- similarly named macro `_a` defined here ... LL | env!(a!()); - | ^ + | ^ not found in this scope | help: the leading underscore in `_a` marks it as unused, consider renaming it to `a` | diff --git a/tests/ui/macros/issue-11692-1.stderr b/tests/ui/macros/issue-11692-1.stderr index 46382f6521841..8fb713beaa349 100644 --- a/tests/ui/macros/issue-11692-1.stderr +++ b/tests/ui/macros/issue-11692-1.stderr @@ -1,8 +1,8 @@ -error: cannot find macro `testo` in this scope +error: cannot find macro `testo` --> $DIR/issue-11692-1.rs:2:12 | LL | print!(testo!()); - | ^^^^^ + | ^^^^^ not found in this scope error: aborting due to 1 previous error diff --git a/tests/ui/macros/issue-11692-2.stderr b/tests/ui/macros/issue-11692-2.stderr index 53add509ca56d..0d17f857f962e 100644 --- a/tests/ui/macros/issue-11692-2.stderr +++ b/tests/ui/macros/issue-11692-2.stderr @@ -1,8 +1,8 @@ -error: cannot find macro `test` in this scope +error: cannot find macro `test` --> $DIR/issue-11692-2.rs:2:13 | LL | concat!(test!()); - | ^^^^ + | ^^^^ not found in this scope | = note: `test` is in scope, but it is an attribute: `#[test]` diff --git a/tests/ui/macros/issue-118786.stderr b/tests/ui/macros/issue-118786.stderr index 03e65c94ba739..cb5ef0d1febd0 100644 --- a/tests/ui/macros/issue-118786.stderr +++ b/tests/ui/macros/issue-118786.stderr @@ -24,11 +24,11 @@ LL | make_macro!((meow)); | = note: the usage of `make_macro!` is likely invalid in item context -error: cannot find macro `macro_rules` in this scope +error: cannot find macro `macro_rules` --> $DIR/issue-118786.rs:7:9 | LL | macro_rules! $macro_name { - | ^^^^^^^^^^^ + | ^^^^^^^^^^^ not found in this scope ... LL | make_macro!((meow)); | ------------------- in this macro invocation diff --git a/tests/ui/macros/issue-88206.rs b/tests/ui/macros/issue-88206.rs index abf58fdcbc815..89995296a388f 100644 --- a/tests/ui/macros/issue-88206.rs +++ b/tests/ui/macros/issue-88206.rs @@ -21,46 +21,57 @@ use hey::{Serialize, Deserialize, X}; #[derive(Serialize)] //~^ ERROR cannot find derive macro `Serialize` +//~| NOTE not found in this scope struct A; #[derive(from_utf8_mut)] //~^ ERROR cannot find derive macro `from_utf8_mut` +//~| NOTE not found in this scope struct B; #[derive(println)] //~^ ERROR cannot find derive macro `println` //~| NOTE `println` is in scope, but it is a function-like macro +//~| NOTE not found in this scope struct C; #[Deserialize] //~^ ERROR cannot find attribute `Deserialize` +//~| NOTE not found in this scope struct D; #[from_utf8_unchecked] //~^ ERROR cannot find attribute `from_utf8_unchecked` +//~| NOTE not found in this scope struct E; #[println] //~^ ERROR cannot find attribute `println` //~| NOTE `println` is in scope, but it is a function-like macro +//~| NOTE not found in this scope struct F; fn main() { from_utf8!(); //~^ ERROR cannot find macro `from_utf8` + //~| NOTE not found in this scope Box!(); //~^ ERROR cannot find macro `Box` //~| NOTE `Box` is in scope, but it is a struct + //~| NOTE not found in this scope Copy!(); //~^ ERROR cannot find macro `Copy` //~| NOTE `Copy` is in scope, but it is a derive macro + //~| NOTE not found in this scope test!(); //~^ ERROR cannot find macro `test` //~| NOTE `test` is in scope, but it is an attribute + //~| NOTE not found in this scope X!(); //~^ ERROR cannot find macro `X` + //~| NOTE not found in this scope } diff --git a/tests/ui/macros/issue-88206.stderr b/tests/ui/macros/issue-88206.stderr index f7f5b56488007..aefa7793d6965 100644 --- a/tests/ui/macros/issue-88206.stderr +++ b/tests/ui/macros/issue-88206.stderr @@ -1,8 +1,8 @@ -error: cannot find macro `X` in this scope - --> $DIR/issue-88206.rs:64:5 +error: cannot find macro `X` + --> $DIR/issue-88206.rs:74:5 | LL | X!(); - | ^ + | ^ not found in this scope | note: `X` is imported here, but it is a struct, not a macro --> $DIR/issue-88206.rs:17:35 @@ -10,35 +10,35 @@ note: `X` is imported here, but it is a struct, not a macro LL | use hey::{Serialize, Deserialize, X}; | ^ -error: cannot find macro `test` in this scope - --> $DIR/issue-88206.rs:60:5 +error: cannot find macro `test` + --> $DIR/issue-88206.rs:69:5 | LL | test!(); - | ^^^^ + | ^^^^ not found in this scope | = note: `test` is in scope, but it is an attribute: `#[test]` -error: cannot find macro `Copy` in this scope - --> $DIR/issue-88206.rs:56:5 +error: cannot find macro `Copy` + --> $DIR/issue-88206.rs:64:5 | LL | Copy!(); - | ^^^^ + | ^^^^ not found in this scope | = note: `Copy` is in scope, but it is a derive macro: `#[derive(Copy)]` -error: cannot find macro `Box` in this scope - --> $DIR/issue-88206.rs:52:5 +error: cannot find macro `Box` + --> $DIR/issue-88206.rs:59:5 | LL | Box!(); - | ^^^ + | ^^^ not found in this scope | = note: `Box` is in scope, but it is a struct, not a macro -error: cannot find macro `from_utf8` in this scope - --> $DIR/issue-88206.rs:49:5 +error: cannot find macro `from_utf8` + --> $DIR/issue-88206.rs:55:5 | LL | from_utf8!(); - | ^^^^^^^^^ + | ^^^^^^^^^ not found in this scope | note: `from_utf8` is imported here, but it is a function, not a macro --> $DIR/issue-88206.rs:5:5 @@ -46,19 +46,19 @@ note: `from_utf8` is imported here, but it is a function, not a macro LL | use std::str::*; | ^^^^^^^^^^^ -error: cannot find attribute `println` in this scope - --> $DIR/issue-88206.rs:43:3 +error: cannot find attribute `println` + --> $DIR/issue-88206.rs:48:3 | LL | #[println] - | ^^^^^^^ + | ^^^^^^^ not found in this scope | = note: `println` is in scope, but it is a function-like macro -error: cannot find attribute `from_utf8_unchecked` in this scope - --> $DIR/issue-88206.rs:39:3 +error: cannot find attribute `from_utf8_unchecked` + --> $DIR/issue-88206.rs:43:3 | LL | #[from_utf8_unchecked] - | ^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^ not found in this scope | note: `from_utf8_unchecked` is imported here, but it is a function, not an attribute --> $DIR/issue-88206.rs:5:5 @@ -66,11 +66,11 @@ note: `from_utf8_unchecked` is imported here, but it is a function, not an attri LL | use std::str::*; | ^^^^^^^^^^^ -error: cannot find attribute `Deserialize` in this scope - --> $DIR/issue-88206.rs:35:3 +error: cannot find attribute `Deserialize` + --> $DIR/issue-88206.rs:38:3 | LL | #[Deserialize] - | ^^^^^^^^^^^ + | ^^^^^^^^^^^ not found in this scope | note: `Deserialize` is imported here, but it is a trait, not an attribute --> $DIR/issue-88206.rs:17:22 @@ -78,19 +78,19 @@ note: `Deserialize` is imported here, but it is a trait, not an attribute LL | use hey::{Serialize, Deserialize, X}; | ^^^^^^^^^^^ -error: cannot find derive macro `println` in this scope - --> $DIR/issue-88206.rs:30:10 +error: cannot find derive macro `println` + --> $DIR/issue-88206.rs:32:10 | LL | #[derive(println)] - | ^^^^^^^ + | ^^^^^^^ not found in this scope | = note: `println` is in scope, but it is a function-like macro -error: cannot find derive macro `from_utf8_mut` in this scope - --> $DIR/issue-88206.rs:26:10 +error: cannot find derive macro `from_utf8_mut` + --> $DIR/issue-88206.rs:27:10 | LL | #[derive(from_utf8_mut)] - | ^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^ not found in this scope | note: `from_utf8_mut` is imported here, but it is a function, not a derive macro --> $DIR/issue-88206.rs:5:5 @@ -98,11 +98,11 @@ note: `from_utf8_mut` is imported here, but it is a function, not a derive macro LL | use std::str::*; | ^^^^^^^^^^^ -error: cannot find derive macro `Serialize` in this scope +error: cannot find derive macro `Serialize` --> $DIR/issue-88206.rs:22:10 | LL | #[derive(Serialize)] - | ^^^^^^^^^ + | ^^^^^^^^^ not found in this scope | note: `Serialize` is imported here, but it is only a trait, without a derive macro --> $DIR/issue-88206.rs:17:11 diff --git a/tests/ui/macros/issue-88228.stderr b/tests/ui/macros/issue-88228.stderr index f9d0ac95da756..328799dd5b121 100644 --- a/tests/ui/macros/issue-88228.stderr +++ b/tests/ui/macros/issue-88228.stderr @@ -1,27 +1,27 @@ -error: cannot find macro `bla` in this scope +error: cannot find macro `bla` --> $DIR/issue-88228.rs:20:5 | LL | bla!(); - | ^^^ + | ^^^ not found in this scope | help: consider importing this macro through its public re-export | LL + use crate::hey::bla; | -error: cannot find derive macro `println` in this scope +error: cannot find derive macro `println` --> $DIR/issue-88228.rs:14:10 | LL | #[derive(println)] - | ^^^^^^^ + | ^^^^^^^ not found in this scope | = note: `println` is in scope, but it is a function-like macro -error: cannot find derive macro `Bla` in this scope +error: cannot find derive macro `Bla` --> $DIR/issue-88228.rs:10:10 | LL | #[derive(Bla)] - | ^^^ + | ^^^ not found in this scope | help: consider importing this derive macro through its public re-export | diff --git a/tests/ui/macros/macro-expand-within-generics-in-path.stderr b/tests/ui/macros/macro-expand-within-generics-in-path.stderr index 72026c41050a2..fd4fbcdc60a46 100644 --- a/tests/ui/macros/macro-expand-within-generics-in-path.stderr +++ b/tests/ui/macros/macro-expand-within-generics-in-path.stderr @@ -4,11 +4,11 @@ error: unexpected generic arguments in path LL | m!(generic); | ^^^^^^ -error: cannot find attribute `generic` in this scope +error: cannot find attribute `generic` --> $DIR/macro-expand-within-generics-in-path.rs:15:4 | LL | m!(generic); - | ^^^^^^^ + | ^^^^^^^ not found in this scope error: aborting due to 2 previous errors diff --git a/tests/ui/macros/macro-expansion-tests.stderr b/tests/ui/macros/macro-expansion-tests.stderr index 8b3f7ca88171c..39cee66c3df55 100644 --- a/tests/ui/macros/macro-expansion-tests.stderr +++ b/tests/ui/macros/macro-expansion-tests.stderr @@ -1,16 +1,16 @@ -error: cannot find macro `m` in this scope +error: cannot find macro `m` --> $DIR/macro-expansion-tests.rs:7:21 | LL | fn g() -> i32 { m!() } - | ^ + | ^ not found in this scope | = help: have you added the `#[macro_use]` on the module/import? -error: cannot find macro `m` in this scope +error: cannot find macro `m` --> $DIR/macro-expansion-tests.rs:15:21 | LL | fn g() -> i32 { m!() } - | ^ + | ^ not found in this scope | = help: have you added the `#[macro_use]` on the module/import? diff --git a/tests/ui/macros/macro-name-typo.stderr b/tests/ui/macros/macro-name-typo.stderr index 9059b10faaacd..283c1b6d252bd 100644 --- a/tests/ui/macros/macro-name-typo.stderr +++ b/tests/ui/macros/macro-name-typo.stderr @@ -1,8 +1,11 @@ -error: cannot find macro `printlx` in this scope +error: cannot find macro `printlx` --> $DIR/macro-name-typo.rs:2:5 | LL | printlx!("oh noes!"); - | ^^^^^^^ help: a macro with a similar name exists: `println` + | ^^^^^^^ + | | + | not found in this scope + | help: a macro with a similar name exists: `println` --> $SRC_DIR/std/src/macros.rs:LL:COL | = note: similarly named macro `println` defined here diff --git a/tests/ui/macros/macro-path-prelude-fail-3.stderr b/tests/ui/macros/macro-path-prelude-fail-3.stderr index 485d7b7869a9a..ac888a3957411 100644 --- a/tests/ui/macros/macro-path-prelude-fail-3.stderr +++ b/tests/ui/macros/macro-path-prelude-fail-3.stderr @@ -1,8 +1,11 @@ -error: cannot find macro `inline` in this scope +error: cannot find macro `inline` --> $DIR/macro-path-prelude-fail-3.rs:2:5 | LL | inline!(); - | ^^^^^^ help: a macro with a similar name exists: `line` + | ^^^^^^ + | | + | not found in this scope + | help: a macro with a similar name exists: `line` --> $SRC_DIR/core/src/macros/mod.rs:LL:COL | = note: similarly named macro `line` defined here diff --git a/tests/ui/macros/macro-reexport-removed.stderr b/tests/ui/macros/macro-reexport-removed.stderr index 475a586ddc083..f6ebad65a8099 100644 --- a/tests/ui/macros/macro-reexport-removed.stderr +++ b/tests/ui/macros/macro-reexport-removed.stderr @@ -6,11 +6,14 @@ LL | #![feature(macro_reexport)] | = note: subsumed by `pub use` -error: cannot find attribute `macro_reexport` in this scope +error: cannot find attribute `macro_reexport` --> $DIR/macro-reexport-removed.rs:5:3 | LL | #[macro_reexport(macro_one)] - | ^^^^^^^^^^^^^^ help: a built-in attribute with a similar name exists: `macro_export` + | ^^^^^^^^^^^^^^ + | | + | not found in this scope + | help: a built-in attribute with a similar name exists: `macro_export` error: aborting due to 2 previous errors diff --git a/tests/ui/macros/macro-use-wrong-name.stderr b/tests/ui/macros/macro-use-wrong-name.stderr index 89345866be804..62948823cf85c 100644 --- a/tests/ui/macros/macro-use-wrong-name.stderr +++ b/tests/ui/macros/macro-use-wrong-name.stderr @@ -1,8 +1,8 @@ -error: cannot find macro `macro_two` in this scope +error: cannot find macro `macro_two` --> $DIR/macro-use-wrong-name.rs:7:5 | LL | macro_two!(); - | ^^^^^^^^^ + | ^^^^^^^^^ not found in this scope | ::: $DIR/auxiliary/two_macros.rs:2:1 | diff --git a/tests/ui/macros/macro_undefined.stderr b/tests/ui/macros/macro_undefined.stderr index cc3efacbc5415..44155da0e933d 100644 --- a/tests/ui/macros/macro_undefined.stderr +++ b/tests/ui/macros/macro_undefined.stderr @@ -1,11 +1,14 @@ -error: cannot find macro `k` in this scope +error: cannot find macro `k` --> $DIR/macro_undefined.rs:11:5 | LL | macro_rules! kl { | --------------- similarly named macro `kl` defined here ... LL | k!(); - | ^ help: a macro with a similar name exists: `kl` + | ^ + | | + | not found in this scope + | help: a macro with a similar name exists: `kl` error: aborting due to 1 previous error diff --git a/tests/ui/macros/macros-nonfatal-errors.stderr b/tests/ui/macros/macros-nonfatal-errors.stderr index abf43e2a009d7..cbec314323aa4 100644 --- a/tests/ui/macros/macros-nonfatal-errors.stderr +++ b/tests/ui/macros/macros-nonfatal-errors.stderr @@ -238,11 +238,11 @@ LL | Foo, | = help: consider a manual implementation of `Default` -error: cannot find macro `llvm_asm` in this scope +error: cannot find macro `llvm_asm` --> $DIR/macros-nonfatal-errors.rs:99:5 | LL | llvm_asm!(invalid); - | ^^^^^^^^ + | ^^^^^^^^ not found in this scope error: aborting due to 28 previous errors diff --git a/tests/ui/missing/missing-macro-use.stderr b/tests/ui/missing/missing-macro-use.stderr index 5d8ff486e06a3..f4a3f2c231f29 100644 --- a/tests/ui/missing/missing-macro-use.stderr +++ b/tests/ui/missing/missing-macro-use.stderr @@ -1,8 +1,8 @@ -error: cannot find macro `macro_two` in this scope +error: cannot find macro `macro_two` --> $DIR/missing-macro-use.rs:6:5 | LL | macro_two!(); - | ^^^^^^^^^ + | ^^^^^^^^^ not found in this scope | help: consider importing this macro | diff --git a/tests/ui/parser/attribute/multiple-tail-expr-behind-cfg.stderr b/tests/ui/parser/attribute/multiple-tail-expr-behind-cfg.stderr index 6266718162f8e..982fa63de391a 100644 --- a/tests/ui/parser/attribute/multiple-tail-expr-behind-cfg.stderr +++ b/tests/ui/parser/attribute/multiple-tail-expr-behind-cfg.stderr @@ -44,11 +44,11 @@ help: alternatively, consider surrounding the expression with a block LL | { [1, 2, 3].iter().map(|c| c.to_string()).collect::() } | + + -error: cannot find attribute `attr` in this scope +error: cannot find attribute `attr` --> $DIR/multiple-tail-expr-behind-cfg.rs:13:7 | LL | #[attr] - | ^^^^ + | ^^^^ not found in this scope error: aborting due to 3 previous errors diff --git a/tests/ui/parser/default-unmatched-assoc.stderr b/tests/ui/parser/default-unmatched-assoc.stderr index ee35fded99ec9..88b6d14681016 100644 --- a/tests/ui/parser/default-unmatched-assoc.stderr +++ b/tests/ui/parser/default-unmatched-assoc.stderr @@ -38,17 +38,17 @@ LL | default do LL | } | - item list ends here -error: cannot find macro `default` in this scope +error: cannot find macro `default` --> $DIR/default-unmatched-assoc.rs:4:5 | LL | default!(); - | ^^^^^^^ + | ^^^^^^^ not found in this scope -error: cannot find macro `default` in this scope +error: cannot find macro `default` --> $DIR/default-unmatched-assoc.rs:12:5 | LL | default!(); - | ^^^^^^^ + | ^^^^^^^ not found in this scope error: aborting due to 6 previous errors diff --git a/tests/ui/parser/default-unmatched-extern.stderr b/tests/ui/parser/default-unmatched-extern.stderr index bb4efd51631e4..1e6b7ac269faf 100644 --- a/tests/ui/parser/default-unmatched-extern.stderr +++ b/tests/ui/parser/default-unmatched-extern.stderr @@ -18,11 +18,11 @@ LL | default do LL | } | - item list ends here -error: cannot find macro `default` in this scope +error: cannot find macro `default` --> $DIR/default-unmatched-extern.rs:4:5 | LL | default!(); - | ^^^^^^^ + | ^^^^^^^ not found in this scope error: aborting due to 3 previous errors diff --git a/tests/ui/parser/issues/issue-118531-ice.stderr b/tests/ui/parser/issues/issue-118531-ice.stderr index 68c7ad47b9dec..ca5638a2c99b4 100644 --- a/tests/ui/parser/issues/issue-118531-ice.stderr +++ b/tests/ui/parser/issues/issue-118531-ice.stderr @@ -28,11 +28,11 @@ LL | #[attr] = help: add `#![feature(stmt_expr_attributes)]` 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: cannot find attribute `attr` in this scope +error: cannot find attribute `attr` --> $DIR/issue-118531-ice.rs:5:7 | LL | #[attr] - | ^^^^ + | ^^^^ not found in this scope error: aborting due to 3 previous errors diff --git a/tests/ui/parser/issues/issue-65122-mac-invoc-in-mut-patterns.stderr b/tests/ui/parser/issues/issue-65122-mac-invoc-in-mut-patterns.stderr index 2bd87ee0c38fa..3c2a57c3c57f6 100644 --- a/tests/ui/parser/issues/issue-65122-mac-invoc-in-mut-patterns.stderr +++ b/tests/ui/parser/issues/issue-65122-mac-invoc-in-mut-patterns.stderr @@ -33,17 +33,17 @@ LL | mac2! { does_not_exist!() } = note: `mut` may be followed by `variable` and `variable @ pattern` = note: this error originates in the macro `mac2` (in Nightly builds, run with -Z macro-backtrace for more info) -error: cannot find macro `does_not_exist` in this scope +error: cannot find macro `does_not_exist` --> $DIR/issue-65122-mac-invoc-in-mut-patterns.rs:22:13 | LL | mac2! { does_not_exist!() } - | ^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^ not found in this scope -error: cannot find macro `does_not_exist` in this scope +error: cannot find macro `does_not_exist` --> $DIR/issue-65122-mac-invoc-in-mut-patterns.rs:20:13 | LL | mac1! { does_not_exist!() } - | ^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^ not found in this scope error: aborting due to 5 previous errors diff --git a/tests/ui/proc-macro/derive-helper-legacy-limits.stderr b/tests/ui/proc-macro/derive-helper-legacy-limits.stderr index f5cd455435d4a..c209e1cc0d8c2 100644 --- a/tests/ui/proc-macro/derive-helper-legacy-limits.stderr +++ b/tests/ui/proc-macro/derive-helper-legacy-limits.stderr @@ -1,8 +1,8 @@ -error: cannot find attribute `empty_helper` in this scope +error: cannot find attribute `empty_helper` --> $DIR/derive-helper-legacy-limits.rs:17:3 | LL | #[empty_helper] - | ^^^^^^^^^^^^ + | ^^^^^^^^^^^^ not found in this scope error: aborting due to 1 previous error diff --git a/tests/ui/proc-macro/derive-helper-legacy-spurious.stderr b/tests/ui/proc-macro/derive-helper-legacy-spurious.stderr index b34713b8ca68e..f23eb9aa6256e 100644 --- a/tests/ui/proc-macro/derive-helper-legacy-spurious.stderr +++ b/tests/ui/proc-macro/derive-helper-legacy-spurious.stderr @@ -1,14 +1,14 @@ -error: cannot find attribute `dummy` in this scope +error: cannot find attribute `dummy` --> $DIR/derive-helper-legacy-spurious.rs:3:4 | LL | #![dummy] - | ^^^^^ + | ^^^^^ not found in this scope -error: cannot find attribute `empty_helper` in this scope +error: cannot find attribute `empty_helper` --> $DIR/derive-helper-legacy-spurious.rs:9:3 | LL | #[empty_helper] - | ^^^^^^^^^^^^ + | ^^^^^^^^^^^^ not found in this scope error: aborting due to 2 previous errors diff --git a/tests/ui/proc-macro/derive-helper-shadowing.stderr b/tests/ui/proc-macro/derive-helper-shadowing.stderr index f284b1c54dd61..bf929eef2cb0b 100644 --- a/tests/ui/proc-macro/derive-helper-shadowing.stderr +++ b/tests/ui/proc-macro/derive-helper-shadowing.stderr @@ -10,11 +10,11 @@ note: the derive helper attribute imported here LL | use empty_helper as renamed; | ^^^^^^^^^^^^^^^^^^^^^^^ -error: cannot find attribute `empty_helper` in this scope +error: cannot find attribute `empty_helper` --> $DIR/derive-helper-shadowing.rs:38:22 | LL | #[derive(GenHelperUse)] - | ^^^^^^^^^^^^ + | ^^^^^^^^^^^^ not found in this scope | = note: this error originates in the derive macro `GenHelperUse` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider importing this attribute macro through its public re-export @@ -22,11 +22,11 @@ help: consider importing this attribute macro through its public re-export LL + use empty_helper; | -error: cannot find attribute `empty_helper` in this scope +error: cannot find attribute `empty_helper` --> $DIR/derive-helper-shadowing.rs:14:11 | LL | #[empty_helper] - | ^^^^^^^^^^^^ + | ^^^^^^^^^^^^ not found in this scope ... LL | gen_helper_use!(); | ----------------- in this macro invocation diff --git a/tests/ui/proc-macro/derive-still-gated.stderr b/tests/ui/proc-macro/derive-still-gated.stderr index 25777f72b8d11..f51cb5073aeba 100644 --- a/tests/ui/proc-macro/derive-still-gated.stderr +++ b/tests/ui/proc-macro/derive-still-gated.stderr @@ -1,8 +1,8 @@ -error: cannot find attribute `derive_Empty` in this scope +error: cannot find attribute `derive_Empty` --> $DIR/derive-still-gated.rs:6:3 | LL | #[derive_Empty] - | ^^^^^^^^^^^^ + | ^^^^^^^^^^^^ not found in this scope error: aborting due to 1 previous error diff --git a/tests/ui/proc-macro/disappearing-resolution.stderr b/tests/ui/proc-macro/disappearing-resolution.stderr index e6d0868687e27..25c5ccdd57b8d 100644 --- a/tests/ui/proc-macro/disappearing-resolution.stderr +++ b/tests/ui/proc-macro/disappearing-resolution.stderr @@ -1,8 +1,8 @@ -error: cannot find attribute `empty_helper` in this scope +error: cannot find attribute `empty_helper` --> $DIR/disappearing-resolution.rs:18:3 | LL | #[empty_helper] - | ^^^^^^^^^^^^ + | ^^^^^^^^^^^^ not found in this scope error[E0603]: derive macro import `Empty` is private --> $DIR/disappearing-resolution.rs:11:8 diff --git a/tests/ui/proc-macro/generate-mod.stderr b/tests/ui/proc-macro/generate-mod.stderr index 528ec6558e43e..fac7d422f7305 100644 --- a/tests/ui/proc-macro/generate-mod.stderr +++ b/tests/ui/proc-macro/generate-mod.stderr @@ -38,7 +38,7 @@ LL | #[generate_mod::check_attr] OuterAttr = note: this error originates in the attribute macro `generate_mod::check_attr` (in Nightly builds, run with -Z macro-backtrace for more info) -error: cannot find type `FromOutside` in this scope +error: cannot find type `FromOutside` --> $DIR/generate-mod.rs:16:10 | LL | #[derive(generate_mod::CheckDerive)] @@ -49,7 +49,7 @@ LL | #[derive(generate_mod::CheckDerive)] = note: `#[deny(proc_macro_derive_resolution_fallback)]` on by default = note: this error originates in the derive macro `generate_mod::CheckDerive` (in Nightly builds, run with -Z macro-backtrace for more info) -error: cannot find type `OuterDerive` in this scope +error: cannot find type `OuterDerive` --> $DIR/generate-mod.rs:16:10 | LL | #[derive(generate_mod::CheckDerive)] @@ -59,7 +59,7 @@ LL | #[derive(generate_mod::CheckDerive)] = note: for more information, see issue #83583 = note: this error originates in the derive macro `generate_mod::CheckDerive` (in Nightly builds, run with -Z macro-backtrace for more info) -error: cannot find type `FromOutside` in this scope +error: cannot find type `FromOutside` --> $DIR/generate-mod.rs:23:14 | LL | #[derive(generate_mod::CheckDerive)] @@ -69,7 +69,7 @@ LL | #[derive(generate_mod::CheckDerive)] = note: for more information, see issue #83583 = note: this error originates in the derive macro `generate_mod::CheckDerive` (in Nightly builds, run with -Z macro-backtrace for more info) -error: cannot find type `OuterDerive` in this scope +error: cannot find type `OuterDerive` --> $DIR/generate-mod.rs:23:14 | LL | #[derive(generate_mod::CheckDerive)] @@ -83,7 +83,7 @@ error: aborting due to 8 previous errors For more information about this error, try `rustc --explain E0412`. Future incompatibility report: Future breakage diagnostic: -error: cannot find type `FromOutside` in this scope +error: cannot find type `FromOutside` --> $DIR/generate-mod.rs:16:10 | LL | #[derive(generate_mod::CheckDerive)] @@ -95,7 +95,7 @@ LL | #[derive(generate_mod::CheckDerive)] = note: this error originates in the derive macro `generate_mod::CheckDerive` (in Nightly builds, run with -Z macro-backtrace for more info) Future breakage diagnostic: -error: cannot find type `OuterDerive` in this scope +error: cannot find type `OuterDerive` --> $DIR/generate-mod.rs:16:10 | LL | #[derive(generate_mod::CheckDerive)] @@ -107,7 +107,7 @@ LL | #[derive(generate_mod::CheckDerive)] = note: this error originates in the derive macro `generate_mod::CheckDerive` (in Nightly builds, run with -Z macro-backtrace for more info) Future breakage diagnostic: -error: cannot find type `FromOutside` in this scope +error: cannot find type `FromOutside` --> $DIR/generate-mod.rs:23:14 | LL | #[derive(generate_mod::CheckDerive)] @@ -119,7 +119,7 @@ LL | #[derive(generate_mod::CheckDerive)] = note: this error originates in the derive macro `generate_mod::CheckDerive` (in Nightly builds, run with -Z macro-backtrace for more info) Future breakage diagnostic: -error: cannot find type `OuterDerive` in this scope +error: cannot find type `OuterDerive` --> $DIR/generate-mod.rs:23:14 | LL | #[derive(generate_mod::CheckDerive)] @@ -131,7 +131,7 @@ LL | #[derive(generate_mod::CheckDerive)] = note: this error originates in the derive macro `generate_mod::CheckDerive` (in Nightly builds, run with -Z macro-backtrace for more info) Future breakage diagnostic: -warning: cannot find type `FromOutside` in this scope +warning: cannot find type `FromOutside` --> $DIR/generate-mod.rs:30:10 | LL | #[derive(generate_mod::CheckDeriveLint)] // OK, lint is suppressed @@ -142,7 +142,7 @@ LL | #[derive(generate_mod::CheckDeriveLint)] // OK, lint is suppressed = note: this warning originates in the derive macro `generate_mod::CheckDeriveLint` (in Nightly builds, run with -Z macro-backtrace for more info) Future breakage diagnostic: -warning: cannot find type `OuterDeriveLint` in this scope +warning: cannot find type `OuterDeriveLint` --> $DIR/generate-mod.rs:30:10 | LL | #[derive(generate_mod::CheckDeriveLint)] // OK, lint is suppressed diff --git a/tests/ui/proc-macro/issue-118455-skip-err-builtin.stderr b/tests/ui/proc-macro/issue-118455-skip-err-builtin.stderr index fa8af87a3d019..ebaa407daaf2f 100644 --- a/tests/ui/proc-macro/issue-118455-skip-err-builtin.stderr +++ b/tests/ui/proc-macro/issue-118455-skip-err-builtin.stderr @@ -1,8 +1,8 @@ -error: cannot find attribute `some_nonexistent_attribute` in this scope +error: cannot find attribute `some_nonexistent_attribute` --> $DIR/issue-118455-skip-err-builtin.rs:1:4 | LL | #![some_nonexistent_attribute] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ not found in this scope error: aborting due to 1 previous error diff --git a/tests/ui/proc-macro/macro-namespace-reserved-2.stderr b/tests/ui/proc-macro/macro-namespace-reserved-2.stderr index 0471124061ef4..5a05d44e3b97b 100644 --- a/tests/ui/proc-macro/macro-namespace-reserved-2.stderr +++ b/tests/ui/proc-macro/macro-namespace-reserved-2.stderr @@ -104,43 +104,43 @@ LL | #[derive(crate::my_macro)] = help: add as non-Derive macro `#[crate::my_macro]` -error: cannot find macro `my_macro_attr` in this scope +error: cannot find macro `my_macro_attr` --> $DIR/macro-namespace-reserved-2.rs:28:5 | LL | my_macro_attr!(); - | ^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^ not found in this scope | = note: `my_macro_attr` is in scope, but it is an attribute: `#[my_macro_attr]` -error: cannot find macro `MyTrait` in this scope +error: cannot find macro `MyTrait` --> $DIR/macro-namespace-reserved-2.rs:33:5 | LL | MyTrait!(); - | ^^^^^^^ + | ^^^^^^^ not found in this scope | = note: `MyTrait` is in scope, but it is a derive macro: `#[derive(MyTrait)]` -error: cannot find attribute `my_macro` in this scope +error: cannot find attribute `my_macro` --> $DIR/macro-namespace-reserved-2.rs:38:3 | LL | #[my_macro] - | ^^^^^^^^ + | ^^^^^^^^ not found in this scope | = note: `my_macro` is in scope, but it is a function-like macro -error: cannot find derive macro `my_macro` in this scope +error: cannot find derive macro `my_macro` --> $DIR/macro-namespace-reserved-2.rs:48:10 | LL | #[derive(my_macro)] - | ^^^^^^^^ + | ^^^^^^^^ not found in this scope | = note: `my_macro` is in scope, but it is a function-like macro -error: cannot find derive macro `my_macro` in this scope +error: cannot find derive macro `my_macro` --> $DIR/macro-namespace-reserved-2.rs:48:10 | LL | #[derive(my_macro)] - | ^^^^^^^^ + | ^^^^^^^^ not found in this scope | = note: `my_macro` is in scope, but it is a function-like macro = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` diff --git a/tests/ui/proc-macro/proc-macro-attributes.stderr b/tests/ui/proc-macro/proc-macro-attributes.stderr index 140d879069040..1721f038fadd3 100644 --- a/tests/ui/proc-macro/proc-macro-attributes.stderr +++ b/tests/ui/proc-macro/proc-macro-attributes.stderr @@ -1,8 +1,11 @@ -error: cannot find attribute `C` in this scope +error: cannot find attribute `C` --> $DIR/proc-macro-attributes.rs:9:3 | LL | #[C] - | ^ help: a derive helper attribute with a similar name exists: `B` + | ^ + | | + | not found in this scope + | help: a derive helper attribute with a similar name exists: `B` error[E0659]: `B` is ambiguous --> $DIR/proc-macro-attributes.rs:6:3 diff --git a/tests/ui/proc-macro/resolve-error.stderr b/tests/ui/proc-macro/resolve-error.stderr index e7639f474c75e..cf8253664ac8e 100644 --- a/tests/ui/proc-macro/resolve-error.stderr +++ b/tests/ui/proc-macro/resolve-error.stderr @@ -1,68 +1,83 @@ -error: cannot find macro `bang_proc_macrp` in this scope +error: cannot find macro `bang_proc_macrp` --> $DIR/resolve-error.rs:60:5 | LL | bang_proc_macrp!(); - | ^^^^^^^^^^^^^^^ help: a macro with a similar name exists: `bang_proc_macro` + | ^^^^^^^^^^^^^^^ + | | + | not found in this scope + | help: a macro with a similar name exists: `bang_proc_macro` | ::: $DIR/auxiliary/test-macros.rs:15:1 | LL | pub fn empty(_: TokenStream) -> TokenStream { | ------------------------------------------- similarly named macro `bang_proc_macro` defined here -error: cannot find macro `Dlona` in this scope +error: cannot find macro `Dlona` --> $DIR/resolve-error.rs:57:5 | LL | Dlona!(); - | ^^^^^ + | ^^^^^ not found in this scope -error: cannot find macro `attr_proc_macra` in this scope +error: cannot find macro `attr_proc_macra` --> $DIR/resolve-error.rs:54:5 | LL | macro_rules! attr_proc_mac { | -------------------------- similarly named macro `attr_proc_mac` defined here ... LL | attr_proc_macra!(); - | ^^^^^^^^^^^^^^^ help: a macro with a similar name exists: `attr_proc_mac` + | ^^^^^^^^^^^^^^^ + | | + | not found in this scope + | help: a macro with a similar name exists: `attr_proc_mac` -error: cannot find macro `FooWithLongNama` in this scope +error: cannot find macro `FooWithLongNama` --> $DIR/resolve-error.rs:51:5 | LL | macro_rules! FooWithLongNam { | --------------------------- similarly named macro `FooWithLongNam` defined here ... LL | FooWithLongNama!(); - | ^^^^^^^^^^^^^^^ help: a macro with a similar name exists: `FooWithLongNam` + | ^^^^^^^^^^^^^^^ + | | + | not found in this scope + | help: a macro with a similar name exists: `FooWithLongNam` -error: cannot find derive macro `attr_proc_macra` in this scope +error: cannot find derive macro `attr_proc_macra` --> $DIR/resolve-error.rs:45:10 | LL | #[derive(attr_proc_macra)] - | ^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^ not found in this scope -error: cannot find derive macro `attr_proc_macra` in this scope +error: cannot find derive macro `attr_proc_macra` --> $DIR/resolve-error.rs:45:10 | LL | #[derive(attr_proc_macra)] - | ^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^ not found in this scope | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error: cannot find derive macro `Dlona` in this scope +error: cannot find derive macro `Dlona` --> $DIR/resolve-error.rs:40:10 | LL | #[derive(Dlona)] - | ^^^^^ help: a derive macro with a similar name exists: `Clona` + | ^^^^^ + | | + | not found in this scope + | help: a derive macro with a similar name exists: `Clona` | ::: $DIR/auxiliary/derive-clona.rs:11:1 | LL | pub fn derive_clonea(input: TokenStream) -> TokenStream { | ------------------------------------------------------- similarly named derive macro `Clona` defined here -error: cannot find derive macro `Dlona` in this scope +error: cannot find derive macro `Dlona` --> $DIR/resolve-error.rs:40:10 | LL | #[derive(Dlona)] - | ^^^^^ help: a derive macro with a similar name exists: `Clona` + | ^^^^^ + | | + | not found in this scope + | help: a derive macro with a similar name exists: `Clona` | ::: $DIR/auxiliary/derive-clona.rs:11:1 | @@ -71,59 +86,74 @@ LL | pub fn derive_clonea(input: TokenStream) -> TokenStream { | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error: cannot find derive macro `Dlone` in this scope +error: cannot find derive macro `Dlone` --> $DIR/resolve-error.rs:35:10 | LL | #[derive(Dlone)] - | ^^^^^ help: a derive macro with a similar name exists: `Clone` + | ^^^^^ + | | + | not found in this scope + | help: a derive macro with a similar name exists: `Clone` --> $SRC_DIR/core/src/clone.rs:LL:COL | = note: similarly named derive macro `Clone` defined here -error: cannot find derive macro `Dlone` in this scope +error: cannot find derive macro `Dlone` --> $DIR/resolve-error.rs:35:10 | LL | #[derive(Dlone)] - | ^^^^^ help: a derive macro with a similar name exists: `Clone` + | ^^^^^ + | | + | not found in this scope + | help: a derive macro with a similar name exists: `Clone` --> $SRC_DIR/core/src/clone.rs:LL:COL | = note: similarly named derive macro `Clone` defined here | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error: cannot find attribute `FooWithLongNan` in this scope +error: cannot find attribute `FooWithLongNan` --> $DIR/resolve-error.rs:32:3 | LL | #[FooWithLongNan] - | ^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^ not found in this scope -error: cannot find attribute `attr_proc_macra` in this scope +error: cannot find attribute `attr_proc_macra` --> $DIR/resolve-error.rs:28:3 | LL | #[attr_proc_macra] - | ^^^^^^^^^^^^^^^ help: an attribute macro with a similar name exists: `attr_proc_macro` + | ^^^^^^^^^^^^^^^ + | | + | not found in this scope + | help: an attribute macro with a similar name exists: `attr_proc_macro` | ::: $DIR/auxiliary/test-macros.rs:20:1 | LL | pub fn empty_attr(_: TokenStream, _: TokenStream) -> TokenStream { | ---------------------------------------------------------------- similarly named attribute macro `attr_proc_macro` defined here -error: cannot find derive macro `FooWithLongNan` in this scope +error: cannot find derive macro `FooWithLongNan` --> $DIR/resolve-error.rs:22:10 | LL | #[derive(FooWithLongNan)] - | ^^^^^^^^^^^^^^ help: a derive macro with a similar name exists: `FooWithLongName` + | ^^^^^^^^^^^^^^ + | | + | not found in this scope + | help: a derive macro with a similar name exists: `FooWithLongName` | ::: $DIR/auxiliary/derive-foo.rs:11:1 | LL | pub fn derive_foo(input: TokenStream) -> TokenStream { | ---------------------------------------------------- similarly named derive macro `FooWithLongName` defined here -error: cannot find derive macro `FooWithLongNan` in this scope +error: cannot find derive macro `FooWithLongNan` --> $DIR/resolve-error.rs:22:10 | LL | #[derive(FooWithLongNan)] - | ^^^^^^^^^^^^^^ help: a derive macro with a similar name exists: `FooWithLongName` + | ^^^^^^^^^^^^^^ + | | + | not found in this scope + | help: a derive macro with a similar name exists: `FooWithLongName` | ::: $DIR/auxiliary/derive-foo.rs:11:1 | diff --git a/tests/ui/reserved/reserved-attr-on-macro.stderr b/tests/ui/reserved/reserved-attr-on-macro.stderr index 066f72367b1a5..591f9b3f47ef0 100644 --- a/tests/ui/reserved/reserved-attr-on-macro.stderr +++ b/tests/ui/reserved/reserved-attr-on-macro.stderr @@ -4,11 +4,11 @@ error: attributes starting with `rustc` are reserved for use by the `rustc` comp LL | #[rustc_attribute_should_be_reserved] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: cannot find attribute `rustc_attribute_should_be_reserved` in this scope +error: cannot find attribute `rustc_attribute_should_be_reserved` --> $DIR/reserved-attr-on-macro.rs:1:3 | LL | #[rustc_attribute_should_be_reserved] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not found in this scope error: aborting due to 2 previous errors diff --git a/tests/ui/resolve/issue-118295.rs b/tests/ui/resolve/issue-118295.rs index 314d7d9aa4fe0..31dba3381e49d 100644 --- a/tests/ui/resolve/issue-118295.rs +++ b/tests/ui/resolve/issue-118295.rs @@ -1,5 +1,6 @@ macro_rules! {} //~^ ERROR cannot find macro `macro_rules` +//~| NOTE not found in this scope //~| NOTE maybe you have forgotten to define a name for this `macro_rules!` fn main() {} diff --git a/tests/ui/resolve/issue-118295.stderr b/tests/ui/resolve/issue-118295.stderr index d60d7d9185db4..43a56d6e25a32 100644 --- a/tests/ui/resolve/issue-118295.stderr +++ b/tests/ui/resolve/issue-118295.stderr @@ -1,8 +1,8 @@ -error: cannot find macro `macro_rules` in this scope +error: cannot find macro `macro_rules` --> $DIR/issue-118295.rs:1:1 | LL | macro_rules! {} - | ^^^^^^^^^^^ + | ^^^^^^^^^^^ not found in this scope | note: maybe you have forgotten to define a name for this `macro_rules!` --> $DIR/issue-118295.rs:1:1 diff --git a/tests/ui/resolve/issue-49074.stderr b/tests/ui/resolve/issue-49074.stderr index bbfeb4ea9483a..0ded4d9eab2cc 100644 --- a/tests/ui/resolve/issue-49074.stderr +++ b/tests/ui/resolve/issue-49074.stderr @@ -1,16 +1,19 @@ -error: cannot find macro `bar` in this scope +error: cannot find macro `bar` --> $DIR/issue-49074.rs:12:4 | LL | bar!(); - | ^^^ + | ^^^ not found in this scope | = help: have you added the `#[macro_use]` on the module/import? -error: cannot find attribute `marco_use` in this scope +error: cannot find attribute `marco_use` --> $DIR/issue-49074.rs:3:3 | LL | #[marco_use] // typo - | ^^^^^^^^^ help: a built-in attribute with a similar name exists: `macro_use` + | ^^^^^^^^^ + | | + | not found in this scope + | help: a built-in attribute with a similar name exists: `macro_use` error: aborting due to 2 previous errors diff --git a/tests/ui/resolve/path-attr-in-const-block.rs b/tests/ui/resolve/path-attr-in-const-block.rs index 076511d26d6d3..d73acab44ebcd 100644 --- a/tests/ui/resolve/path-attr-in-const-block.rs +++ b/tests/ui/resolve/path-attr-in-const-block.rs @@ -4,6 +4,6 @@ fn main() { const { #![path = foo!()] - //~^ ERROR: cannot find macro `foo` in this scope + //~^ ERROR: cannot find macro `foo` } } diff --git a/tests/ui/resolve/path-attr-in-const-block.stderr b/tests/ui/resolve/path-attr-in-const-block.stderr index 8f9e58157c809..a3ad87f0ddcfb 100644 --- a/tests/ui/resolve/path-attr-in-const-block.stderr +++ b/tests/ui/resolve/path-attr-in-const-block.stderr @@ -1,8 +1,8 @@ -error: cannot find macro `foo` in this scope +error: cannot find macro `foo` --> $DIR/path-attr-in-const-block.rs:6:19 | LL | #![path = foo!()] - | ^^^ + | ^^^ not found in this scope error: aborting due to 1 previous error diff --git a/tests/ui/resolve/visibility-indeterminate.stderr b/tests/ui/resolve/visibility-indeterminate.stderr index 84d82ce852240..c74c4f67d61e1 100644 --- a/tests/ui/resolve/visibility-indeterminate.stderr +++ b/tests/ui/resolve/visibility-indeterminate.stderr @@ -4,11 +4,11 @@ error[E0578]: cannot determine resolution for the visibility LL | pub(in ::bar) struct Baz {} | ^^^^^ -error: cannot find macro `foo` in this scope +error: cannot find macro `foo` --> $DIR/visibility-indeterminate.rs:3:1 | LL | foo!(); - | ^^^ + | ^^^ not found in this scope error: aborting due to 2 previous errors diff --git a/tests/ui/self/self_type_keyword.stderr b/tests/ui/self/self_type_keyword.stderr index 8886fcfdc60cc..b69a40b335e9d 100644 --- a/tests/ui/self/self_type_keyword.stderr +++ b/tests/ui/self/self_type_keyword.stderr @@ -54,11 +54,11 @@ error: lifetimes cannot use keyword names LL | struct Bar<'Self>; | ^^^^^ -error: cannot find macro `Self` in this scope +error: cannot find macro `Self` --> $DIR/self_type_keyword.rs:21:9 | LL | Self!() => (), - | ^^^^ + | ^^^^ not found in this scope error[E0531]: cannot find unit struct, unit variant or constant `Self` --> $DIR/self_type_keyword.rs:16:13 diff --git a/tests/ui/suggestions/attribute-typos.stderr b/tests/ui/suggestions/attribute-typos.stderr index b871c9b45a56c..23566efcf84ac 100644 --- a/tests/ui/suggestions/attribute-typos.stderr +++ b/tests/ui/suggestions/attribute-typos.stderr @@ -4,26 +4,35 @@ error: attributes starting with `rustc` are reserved for use by the `rustc` comp LL | #[rustc_err] | ^^^^^^^^^ -error: cannot find attribute `rustc_err` in this scope +error: cannot find attribute `rustc_err` --> $DIR/attribute-typos.rs:7:3 | LL | #[rustc_err] - | ^^^^^^^^^ help: a built-in attribute with a similar name exists: `rustc_error` + | ^^^^^^^^^ + | | + | not found in this scope + | help: a built-in attribute with a similar name exists: `rustc_error` -error: cannot find attribute `tests` in this scope +error: cannot find attribute `tests` --> $DIR/attribute-typos.rs:4:3 | LL | #[tests] - | ^^^^^ help: an attribute macro with a similar name exists: `test` + | ^^^^^ + | | + | not found in this scope + | help: an attribute macro with a similar name exists: `test` --> $SRC_DIR/core/src/macros/mod.rs:LL:COL | = note: similarly named attribute macro `test` defined here -error: cannot find attribute `deprcated` in this scope +error: cannot find attribute `deprcated` --> $DIR/attribute-typos.rs:1:3 | LL | #[deprcated] - | ^^^^^^^^^ help: a built-in attribute with a similar name exists: `deprecated` + | ^^^^^^^^^ + | | + | not found in this scope + | help: a built-in attribute with a similar name exists: `deprecated` error: aborting due to 4 previous errors diff --git a/tests/ui/tool-attributes/tool-attributes-misplaced-1.stderr b/tests/ui/tool-attributes/tool-attributes-misplaced-1.stderr index 2045dc6a36e1a..39c7d04ced3e6 100644 --- a/tests/ui/tool-attributes/tool-attributes-misplaced-1.stderr +++ b/tests/ui/tool-attributes/tool-attributes-misplaced-1.stderr @@ -1,28 +1,28 @@ -error: cannot find derive macro `rustfmt` in this scope +error: cannot find derive macro `rustfmt` --> $DIR/tool-attributes-misplaced-1.rs:4:10 | LL | #[derive(rustfmt)] - | ^^^^^^^ + | ^^^^^^^ not found in this scope -error: cannot find derive macro `rustfmt` in this scope +error: cannot find derive macro `rustfmt` --> $DIR/tool-attributes-misplaced-1.rs:4:10 | LL | #[derive(rustfmt)] - | ^^^^^^^ + | ^^^^^^^ not found in this scope | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error: cannot find attribute `rustfmt` in this scope +error: cannot find attribute `rustfmt` --> $DIR/tool-attributes-misplaced-1.rs:9:3 | LL | #[rustfmt] - | ^^^^^^^ + | ^^^^^^^ not found in this scope -error: cannot find macro `rustfmt` in this scope +error: cannot find macro `rustfmt` --> $DIR/tool-attributes-misplaced-1.rs:15:5 | LL | rustfmt!(); - | ^^^^^^^ + | ^^^^^^^ not found in this scope error[E0573]: expected type, found tool module `rustfmt` --> $DIR/tool-attributes-misplaced-1.rs:1:10 From 5f47d1faeb203eedcbbc9df1c4cfe4e18d01e0dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Fri, 28 Jun 2024 22:08:59 +0000 Subject: [PATCH 886/892] revert wording changes to main message --- compiler/rustc_lint/messages.ftl | 4 +- compiler/rustc_resolve/messages.ftl | 2 +- compiler/rustc_resolve/src/late.rs | 2 +- .../rustc_resolve/src/late/diagnostics.rs | 4 +- .../clippy/tests/ui/crashes/ice-6252.stderr | 4 +- .../ui/option_map_unit_fn_unfixable.stderr | 8 ++-- .../doctest/failed-doctest-output.stdout | 2 +- tests/rustdoc-ui/impl-fn-nesting.stderr | 20 ++++---- .../issues/issue-81662-shortness.stdout | 2 +- tests/ui/annotate-snippet/missing-type.stderr | 2 +- .../extern-fn-arg-names.stderr | 2 +- .../argument-suggestions/issue-109831.stderr | 4 +- ...uggest-better-removing-issue-126246.stderr | 10 ++-- .../slice-pat-type-mismatches.stderr | 2 +- tests/ui/asm/issue-113788.rs | 2 +- tests/ui/asm/issue-113788.stderr | 2 +- tests/ui/associated-consts/issue-93835.stderr | 6 +-- tests/ui/associated-item/issue-87638.stderr | 4 +- tests/ui/associated-path-shl.stderr | 10 ++-- .../missing-trait-bound-for-assoc-fails.rs | 2 +- ...missing-trait-bound-for-assoc-fails.stderr | 2 +- .../associated-types-eq-1.stderr | 2 +- tests/ui/associated-types/issue-19883.stderr | 2 +- tests/ui/associated-types/issue-22037.stderr | 2 +- .../async-closures/tainted-body.stderr | 2 +- .../async-await/async-fn/not-a-trait.stderr | 2 +- .../drop-order-locals-are-hidden.rs | 8 ++-- .../drop-order-locals-are-hidden.stderr | 8 ++-- .../in-trait/return-not-existing-pair.rs | 2 +- .../in-trait/return-not-existing-pair.stderr | 2 +- ...eturn-not-existing-type-wrapping-rpitit.rs | 2 +- ...n-not-existing-type-wrapping-rpitit.stderr | 2 +- .../issue-72590-type-error-sized.stderr | 4 +- tests/ui/attributes/issue-90873.stderr | 4 +- .../key-value-expansion-scope.stderr | 44 ++++++++--------- tests/ui/attributes/main-removed-1.stderr | 2 +- tests/ui/attributes/obsolete-attr.stderr | 4 +- tests/ui/attributes/unknown-attr.stderr | 6 +-- .../unsafe/double-unsafe-attributes.stderr | 2 +- .../ui/attributes/unused-item-in-attr.stderr | 2 +- tests/ui/c-variadic/issue-86053-1.stderr | 2 +- tests/ui/cast/cast-errors-issue-43825.stderr | 2 +- tests/ui/cast/casts-issue-46365.stderr | 2 +- .../ice-cast-type-with-error-124848.stderr | 2 +- tests/ui/cfg/diagnostics-cross-crate.stderr | 8 ++-- tests/ui/cfg/diagnostics-not-a-def.stderr | 2 +- tests/ui/cfg/diagnostics-reexport.stderr | 2 +- tests/ui/cfg/diagnostics-same-crate.stderr | 8 ++-- tests/ui/closures/issue-78720.stderr | 2 +- tests/ui/closures/issue-90871.stderr | 2 +- tests/ui/codemap_tests/tab.stderr | 2 +- tests/ui/codemap_tests/unicode_2.stderr | 2 +- tests/ui/coercion/type-errors.stderr | 6 +-- .../coherence-error-suppression.stderr | 2 +- .../illegal-copy-bad-projection.stderr | 2 +- .../ui-testing-optout.stderr | 6 +-- ...r-unknown-attribute-macro-expansion.stderr | 2 +- .../cfg-generic-params.stderr | 10 ++-- .../cfg_accessible.stderr | 6 +-- .../conditional-compilation/test-cfg.stderr | 2 +- .../early/invalid-const-arguments.stderr | 4 +- .../generic_const_exprs/error_in_ty.stderr | 2 +- ...e-a-closure-or-coroutine-ice-113776.stderr | 2 +- ...es-of-no-entry-found-for-key-119275.stderr | 2 +- .../generic_const_exprs/issue-109141.stderr | 2 +- .../unevaluated-const-ice-119731.stderr | 10 ++-- .../not_wf_param_in_rpitit.stderr | 2 +- .../const-generics/type_not_in_scope.stderr | 2 +- tests/ui/const-generics/unknown_adt.stderr | 2 +- ...e-type-mismatch-when-copying-112824.stderr | 2 +- .../ice-unhandled-type-122191.stderr | 2 +- ...rroneous_type_in_const_return_value.stderr | 2 +- .../consts/erroneous_type_in_promoted.stderr | 2 +- .../ice-bad-input-type-for-cast-83056.stderr | 2 +- tests/ui/consts/issue-104609.stderr | 2 +- tests/ui/consts/issue-116186.stderr | 2 +- tests/ui/consts/issue-90878-2.stderr | 2 +- tests/ui/consts/issue-91434.rs | 2 +- tests/ui/consts/issue-91434.stderr | 2 +- tests/ui/coroutine/gen_block.none.stderr | 6 +-- tests/ui/coroutine/layout-error.stderr | 2 +- tests/ui/custom_attribute.stderr | 6 +-- ...deduplicate-diagnostics.deduplicate.stderr | 2 +- .../deduplicate-diagnostics.duplicate.stderr | 4 +- tests/ui/delegation/bad-resolve.stderr | 4 +- tests/ui/delegation/explicit-paths.stderr | 8 ++-- tests/ui/delegation/ice-issue-124342.stderr | 4 +- tests/ui/delegation/target-expr.stderr | 2 +- tests/ui/derived-errors/issue-31997.stderr | 2 +- tests/ui/derives/deriving-bounds.stderr | 8 ++-- .../deriving-meta-unknown-trait.stderr | 4 +- tests/ui/derives/deriving-primitive.stderr | 4 +- .../diagnostic_namespace/requires_path.stderr | 2 +- tests/ui/did_you_mean/issue-103909.stderr | 2 +- ...ssue-56028-there-is-an-enum-variant.stderr | 4 +- tests/ui/did_you_mean/println-typo.stderr | 2 +- tests/ui/dropck/drop-on-non-struct.stderr | 2 +- tests/ui/editions/async-block-2015.stderr | 2 +- tests/ui/empty/empty-macro-use.stderr | 2 +- .../ui/enum/suggest-default-attribute.stderr | 2 +- tests/ui/error-codes/E0405.stderr | 2 +- tests/ui/error-codes/E0411.stderr | 2 +- tests/ui/error-codes/E0412.stderr | 2 +- tests/ui/error-codes/E0425.stderr | 2 +- tests/ui/error-festival.stderr | 2 +- .../ui/errors/remap-path-prefix.normal.stderr | 2 +- ...p-path-prefix.with-diagnostic-scope.stderr | 2 +- ...ath-prefix.without-diagnostic-scope.stderr | 2 +- tests/ui/expr/if/bad-if-let-suggestion.stderr | 10 ++-- .../ruby_style_closure.stderr | 2 +- tests/ui/ext-nonexistent.stderr | 2 +- .../ui/extern/extern-with-type-bounds.stderr | 2 +- ...extern-item-where-clauses-debug-ice.stderr | 4 +- tests/ui/extern/issue-80074.stderr | 4 +- .../feature-gate-concat_idents2.stderr | 2 +- .../feature-gate-custom_attribute.stderr | 26 +++++----- .../feature-gate-custom_attribute2.stderr | 34 ++++++------- .../feature-gate-gen_blocks.none.stderr | 2 +- .../feature-gate-rustc-attrs.stderr | 2 +- .../issue-43106-gating-of-derive-2.stderr | 12 ++--- .../format-args-capture-issue-102057.stderr | 14 +++--- .../format-args-capture-issue-94010.stderr | 4 +- ...rmat-args-capture-missing-variables.stderr | 12 ++--- tests/ui/fmt/ifmt-bad-arg.stderr | 10 ++-- tests/ui/fmt/unicode-escape-spans.stderr | 20 ++++---- tests/ui/for/for-expn.stderr | 2 +- ...lp-with-err-generic-is-not-function.stderr | 4 +- .../fn-help-with-err.stderr | 2 +- .../equality-bound.stderr | 12 ++--- tests/ui/generics/issue-106694.stderr | 6 +-- tests/ui/hygiene/arguments.stderr | 2 +- .../hygiene/cross-crate-glob-hygiene.stderr | 2 +- .../hygiene/cross-crate-name-hiding-2.stderr | 2 +- .../ui/hygiene/cross-crate-name-hiding.stderr | 2 +- tests/ui/hygiene/for-loop.stderr | 2 +- tests/ui/hygiene/generate-mod.stderr | 12 ++--- tests/ui/hygiene/globs.stderr | 8 ++-- .../hygiene/no_implicit_prelude-2018.stderr | 2 +- tests/ui/hygiene/pattern-macro.stderr | 2 +- .../hygiene/rustc-macro-transparency.stderr | 2 +- ...rpitits-are-created-before-freezing.stderr | 2 +- .../rpitit-shadowed-by-missing-adt.stderr | 2 +- tests/ui/impl-trait/issue-103181-2.stderr | 2 +- tests/ui/impl-trait/issue-54966.stderr | 2 +- tests/ui/impl-trait/issues/issue-82139.stderr | 2 +- .../opaque-used-in-extraneous-argument.stderr | 4 +- .../precise-capturing/bad-params.stderr | 4 +- .../precise-capturing/bound-modifiers.stderr | 8 ++-- tests/ui/implied-bounds/references-err.stderr | 2 +- .../glob-conflict-cross-crate-1.stderr | 4 +- .../glob-conflict-cross-crate-2.stderr | 2 +- tests/ui/imports/glob-resolve1.stderr | 14 +++--- ...port-alias-issue-121168.edition2015.stderr | 2 +- ...port-alias-issue-121168.edition2018.stderr | 2 +- ...port-alias-issue-121168.edition2021.stderr | 2 +- tests/ui/imports/import-glob-0.stderr | 2 +- tests/ui/imports/import-glob-circular.stderr | 2 +- .../imports/inaccessible_type_aliases.stderr | 4 +- tests/ui/imports/issue-4366-2.stderr | 2 +- tests/ui/imports/issue-4366.stderr | 2 +- tests/ui/imports/issue-59764.rs | 2 +- tests/ui/imports/issue-59764.stderr | 2 +- tests/ui/issues-71798.stderr | 2 +- tests/ui/issues/issue-15167.stderr | 8 ++-- tests/ui/issues/issue-18058.stderr | 2 +- tests/ui/issues/issue-19734.stderr | 2 +- tests/ui/issues/issue-2281-part1.stderr | 2 +- tests/ui/issues/issue-30589.stderr | 2 +- tests/ui/issues/issue-32655.stderr | 4 +- tests/ui/issues/issue-32950.stderr | 2 +- tests/ui/issues/issue-33525.stderr | 2 +- tests/ui/issues/issue-33571.stderr | 4 +- tests/ui/issues/issue-36836.stderr | 2 +- tests/ui/issues/issue-40845.stderr | 4 +- tests/ui/issues/issue-46332.stderr | 2 +- tests/ui/issues/issue-53300.rs | 2 +- tests/ui/issues/issue-53300.stderr | 2 +- tests/ui/issues/issue-58712.stderr | 4 +- .../issues/issue-72839-error-overflow.stderr | 2 +- tests/ui/issues/issue-77919.stderr | 4 +- tests/ui/issues/issue-86756.stderr | 2 +- tests/ui/issues/issue-8767.stderr | 2 +- .../keyword/keyword-self-as-identifier.stderr | 2 +- tests/ui/label/label_misspelled.stderr | 16 +++---- tests/ui/label/label_misspelled_2.stderr | 4 +- tests/ui/lang-items/issue-83471.stderr | 2 +- ...annot-transmute-unnormalizable-type.stderr | 2 +- tests/ui/layout/issue-84108.stderr | 4 +- .../malformed-unsized-type-in-union.stderr | 2 +- .../layout/transmute-to-tail-with-err.stderr | 2 +- tests/ui/let-else/let-else-scope.stderr | 2 +- .../issue-83907-invalid-fn-like-path.stderr | 2 +- .../lint/internal/trivial-diagnostics.stderr | 4 +- tests/ui/lint/issue-35075.stderr | 4 +- tests/ui/lint/recommend-literal.rs | 4 +- tests/ui/lint/recommend-literal.stderr | 18 +++---- tests/ui/lint/use_suggestion_json.stderr | 4 +- tests/ui/loops/loop-break-value.stderr | 2 +- .../ui/lowering/span-bug-issue-121431.stderr | 2 +- .../defined-later-issue-121061-2.stderr | 2 +- .../macros/defined-later-issue-121061.stderr | 2 +- .../macros/expand-full-no-resolution.stderr | 4 +- tests/ui/macros/issue-100199.stderr | 2 +- tests/ui/macros/issue-11692-1.stderr | 2 +- tests/ui/macros/issue-11692-2.stderr | 2 +- tests/ui/macros/issue-118786.stderr | 2 +- tests/ui/macros/issue-88206.stderr | 22 ++++----- tests/ui/macros/issue-88228.stderr | 6 +-- tests/ui/macros/macro-backtrace-nested.stderr | 4 +- tests/ui/macros/macro-context.stderr | 4 +- ...acro-expand-within-generics-in-path.stderr | 2 +- tests/ui/macros/macro-expansion-tests.stderr | 4 +- .../macro-metavar-expr-concat/hygiene.stderr | 2 +- tests/ui/macros/macro-name-typo.stderr | 2 +- tests/ui/macros/macro-outer-attributes.stderr | 2 +- tests/ui/macros/macro-parameter-span.stderr | 2 +- .../macros/macro-path-prelude-fail-3.stderr | 2 +- tests/ui/macros/macro-reexport-removed.stderr | 2 +- tests/ui/macros/macro-use-wrong-name.stderr | 2 +- tests/ui/macros/macro_undefined.stderr | 2 +- tests/ui/macros/macros-nonfatal-errors.stderr | 2 +- .../syntax-errors.stderr | 12 ++--- tests/ui/match/expr_before_ident_pat.stderr | 2 +- tests/ui/match/issue-82866.stderr | 4 +- tests/ui/match/issue-92100.stderr | 2 +- tests/ui/match/match-join.stderr | 2 +- ...t-method-on-call-for-ambig-receiver.stderr | 2 +- ...gest-method-on-call-with-macro-rcvr.stderr | 2 +- ...ue-83499-input-output-iteration-ice.stderr | 2 +- ...d-2021-closure-capture-ice-110453-1.stderr | 2 +- ...d-2021-closure-capture-ice-110453-2.stderr | 2 +- tests/ui/mir/validate/error-body.stderr | 2 +- .../missing-const-parameter.stderr | 10 ++-- .../missing-type-parameter2.stderr | 10 ++-- tests/ui/missing/missing-macro-use.stderr | 2 +- .../mod_file_correct_spans.stderr | 2 +- ...ed-enum-glob-import-no-impls-xcrate.stderr | 8 ++-- ...amespaced-enum-glob-import-no-impls.stderr | 8 ++-- tests/ui/nested-cfg-attrs.stderr | 2 +- .../avoid-ice-on-warning.new.stderr | 2 +- .../avoid-ice-on-warning.old.stderr | 2 +- .../object-safety/erroneous_signature.stderr | 4 +- tests/ui/offset-of/offset-of-enum.stderr | 2 +- tests/ui/offset-of/offset-of-self.stderr | 4 +- tests/ui/panics/default-backtrace-ice.stderr | 2 +- .../multiple-tail-expr-behind-cfg.stderr | 2 +- tests/ui/parser/circular_modules_main.stderr | 2 +- ...-param-decl-on-type-instead-of-impl.stderr | 2 +- .../ui/parser/default-unmatched-assoc.stderr | 4 +- .../ui/parser/default-unmatched-extern.stderr | 2 +- .../ui/parser/dyn-trait-compatibility.stderr | 14 +++--- tests/ui/parser/emoji-identifiers.stderr | 2 +- .../ui/parser/fn-field-parse-error-ice.stderr | 2 +- tests/ui/parser/issues/issue-103143.stderr | 2 +- .../issues/issue-103748-ICE-wrong-braces.rs | 2 +- .../issue-103748-ICE-wrong-braces.stderr | 2 +- tests/ui/parser/issues/issue-112458.stderr | 2 +- .../ui/parser/issues/issue-118531-ice.stderr | 2 +- tests/ui/parser/issues/issue-32505.stderr | 2 +- ...sue-65122-mac-invoc-in-mut-patterns.stderr | 4 +- tests/ui/parser/kw-in-trait-bounds.stderr | 8 ++-- ...byte-char-use-seperator-issue-80134.stderr | 4 +- tests/ui/parser/not-a-pred.rs | 2 +- tests/ui/parser/not-a-pred.stderr | 2 +- tests/ui/parser/pat-lt-bracket-5.stderr | 2 +- .../ui/parser/raw/raw-literal-keywords.stderr | 6 +-- .../recover-fn-ptr-with-generics.stderr | 4 +- .../ui/parser/recover/recover-ref-dyn-mut.rs | 2 +- .../parser/recover/recover-ref-dyn-mut.stderr | 2 +- .../recover/recover-unticked-labels.stderr | 2 +- .../trailing-question-in-macro-type.stderr | 2 +- tests/ui/parser/unmatched-langle-1.rs | 4 +- tests/ui/parser/unmatched-langle-1.stderr | 4 +- tests/ui/parser/where_with_bound.stderr | 2 +- ...tern-meant-to-be-slice-rest-pattern.stderr | 12 ++--- .../issue-119493-type-error-ice.stderr | 4 +- .../issue-119778-type-error-ice.stderr | 4 +- tests/ui/privacy/privacy-ns1.stderr | 4 +- .../ambiguous-builtin-attrs-test.stderr | 2 +- .../proc-macro/ambiguous-builtin-attrs.stderr | 2 +- .../attributes-on-modules-fail.stderr | 4 +- tests/ui/proc-macro/break-token-spans.stderr | 2 +- .../derive-helper-legacy-limits.stderr | 2 +- .../derive-helper-legacy-spurious.stderr | 4 +- .../proc-macro/derive-helper-shadowing.stderr | 4 +- tests/ui/proc-macro/derive-still-gated.stderr | 2 +- .../proc-macro/disappearing-resolution.stderr | 2 +- tests/ui/proc-macro/empty-where-clause.stderr | 6 +-- .../proc-macro/gen-macro-rules-hygiene.stderr | 4 +- tests/ui/proc-macro/generate-mod.stderr | 28 +++++------ .../issue-118455-skip-err-builtin.stderr | 2 +- tests/ui/proc-macro/issue-38586.stderr | 2 +- tests/ui/proc-macro/issue-83510.stderr | 4 +- tests/ui/proc-macro/keep-expr-tokens.stderr | 4 +- .../ui/proc-macro/lints_in_proc_macros.stderr | 2 +- .../macro-namespace-reserved-2.stderr | 10 ++-- tests/ui/proc-macro/macro-rules-derive.stderr | 2 +- tests/ui/proc-macro/mixed-site-span.stderr | 6 +-- .../ui/proc-macro/parent-source-spans.stderr | 6 +-- .../proc-macro/proc-macro-attributes.stderr | 2 +- tests/ui/proc-macro/resolve-error.stderr | 28 +++++------ .../ui/proc-macro/span-from-proc-macro.stderr | 6 +-- tests/ui/proc-macro/weird-hygiene.stderr | 4 +- tests/ui/query-system/issue-83479.stderr | 4 +- tests/ui/recursion/recursive-reexports.stderr | 2 +- tests/ui/regions/outlives-with-missing.stderr | 2 +- .../ui/reserved/reserved-attr-on-macro.stderr | 2 +- .../resolve/associated-fn-called-as-fn.stderr | 4 +- tests/ui/resolve/bad-env-capture.stderr | 4 +- tests/ui/resolve/bad-env-capture2.stderr | 4 +- tests/ui/resolve/bad-env-capture3.stderr | 4 +- tests/ui/resolve/bad-expr-path.stderr | 6 +-- tests/ui/resolve/bad-expr-path2.stderr | 4 +- .../resolve/crate-called-as-function.stderr | 2 +- tests/ui/resolve/crate-in-paths.rs | 2 +- tests/ui/resolve/crate-in-paths.stderr | 2 +- .../resolve/editions-crate-root-2015.stderr | 4 +- .../resolve/editions-crate-root-2018.stderr | 4 +- .../ui/resolve/enums-are-namespaced-xc.stderr | 6 +-- tests/ui/resolve/enums-pats-not-idents.stderr | 2 +- ...d-in-self-not-available-in-assoc-fn.stderr | 6 +-- tests/ui/resolve/filter-intrinsics.stderr | 4 +- tests/ui/resolve/issue-102946.stderr | 2 +- tests/ui/resolve/issue-103474.stderr | 6 +-- .../resolve/issue-104700-inner_scope.stderr | 4 +- tests/ui/resolve/issue-116164.stderr | 2 +- tests/ui/resolve/issue-118295.stderr | 2 +- tests/ui/resolve/issue-14254.stderr | 48 +++++++++---------- tests/ui/resolve/issue-17518.stderr | 2 +- tests/ui/resolve/issue-21221-1.stderr | 8 ++-- tests/ui/resolve/issue-21221-2.stderr | 2 +- tests/ui/resolve/issue-21221-3.stderr | 2 +- tests/ui/resolve/issue-21221-4.stderr | 2 +- tests/ui/resolve/issue-2356.rs | 2 +- tests/ui/resolve/issue-2356.stderr | 30 ++++++------ tests/ui/resolve/issue-24968.stderr | 10 ++-- tests/ui/resolve/issue-26545.rs | 2 +- tests/ui/resolve/issue-26545.stderr | 2 +- tests/ui/resolve/issue-31845.stderr | 2 +- tests/ui/resolve/issue-35675.stderr | 8 ++-- tests/ui/resolve/issue-42944.rs | 2 +- tests/ui/resolve/issue-42944.stderr | 2 +- tests/ui/resolve/issue-49074.stderr | 4 +- tests/ui/resolve/issue-50599.stderr | 2 +- tests/ui/resolve/issue-5099.stderr | 6 +-- tests/ui/resolve/issue-5927.stderr | 4 +- tests/ui/resolve/issue-60057.stderr | 4 +- .../issue-69401-trait-fn-no-body-ty-local.rs | 2 +- ...sue-69401-trait-fn-no-body-ty-local.stderr | 2 +- tests/ui/resolve/issue-80079.stderr | 2 +- tests/ui/resolve/issue-85348.rs | 2 +- tests/ui/resolve/issue-85348.stderr | 2 +- tests/ui/resolve/issue-88472.rs | 4 +- tests/ui/resolve/issue-88472.stderr | 4 +- tests/ui/resolve/issue-90113.stderr | 2 +- tests/ui/resolve/levenshtein.stderr | 16 +++---- .../resolve/no-implicit-prelude-nested.stderr | 30 ++++++------ tests/ui/resolve/no-implicit-prelude.stderr | 10 ++-- .../resolve/path-attr-in-const-block.stderr | 2 +- tests/ui/resolve/privacy-enum-ctor.stderr | 8 ++-- tests/ui/resolve/raw-ident-in-path.stderr | 2 +- .../resolve/resolve-assoc-suggestions.stderr | 18 +++---- .../resolve/resolve-primitive-fallback.stderr | 2 +- .../ui/resolve/resolve-self-in-impl-2.stderr | 2 +- .../resolve-speculative-adjustment.stderr | 8 ++-- tests/ui/resolve/resolve-unknown-trait.stderr | 6 +-- ...est-import-without-clobbering-attrs.stderr | 2 +- ...e-with-name-similar-to-struct-field.stderr | 14 +++--- .../typo-suggestion-named-underscore.stderr | 4 +- ...xed-closure-sugar-nonexistent-trait.stderr | 2 +- .../unresolved_static_type_field.stderr | 2 +- tests/ui/resolve/use_suggestion.stderr | 4 +- .../resolve/use_suggestion_placement.stderr | 6 +-- .../resolve/visibility-indeterminate.stderr | 2 +- .../rfc-2294-if-let-guard/bindings.stderr | 4 +- .../ice-120503-async-const-method.stderr | 2 +- tests/ui/rmeta/rmeta.stderr | 2 +- .../issue-52202-use-suggestions.stderr | 2 +- tests/ui/rustdoc/cfg-rustdoc.stderr | 2 +- tests/ui/self/class-missing-self.stderr | 4 +- tests/ui/self/elision/nested-item.stderr | 2 +- tests/ui/self/self_type_keyword-2.stderr | 6 +-- tests/ui/self/self_type_keyword.stderr | 4 +- tests/ui/self/suggest-self-2.stderr | 8 ++-- tests/ui/self/suggest-self.stderr | 6 +-- ...s-in-pattern-with-ty-err-doesnt-ice.stderr | 2 +- ...incompatible-closure-captures-96258.stderr | 2 +- tests/ui/span/suggestion-raw-68962.stderr | 4 +- tests/ui/span/typo-suggestion.stderr | 4 +- .../issue-68830-spurious-diagnostics.stderr | 2 +- .../impl-on-nonexisting.stderr | 2 +- tests/ui/stability-attribute/issue-109177.rs | 2 +- .../stability-attribute/issue-109177.stderr | 2 +- .../unresolved_stability_lint.stderr | 2 +- ...ce-struct-tail-normalization-113272.stderr | 2 +- .../struct-fields-shorthand-unresolved.stderr | 2 +- .../structs/unresolved-struct-with-fru.stderr | 2 +- .../assoc-const-without-self.stderr | 2 +- .../assoc-type-in-method-return.stderr | 2 +- .../suggestions/assoc_fn_without_self.stderr | 16 +++---- tests/ui/suggestions/attribute-typos.stderr | 6 +-- .../suggestions/bool_typo_err_suggest.stderr | 4 +- .../dont-suggest-foreign-doc-hidden.stderr | 4 +- .../fn-to-method-deeply-nested.stderr | 12 ++--- tests/ui/suggestions/fn-to-method.stderr | 6 +-- ...ice-unwrap-probe-many-result-125876.stderr | 2 +- tests/ui/suggestions/if-let-typo.stderr | 4 +- .../issue-104086-suggest-let.stderr | 34 ++++++------- tests/ui/suggestions/issue-104287.stderr | 2 +- .../issue-66968-suggest-sorted-words.stderr | 2 +- ...method-access-to-range-literal-typo.stderr | 2 +- .../no-extern-crate-in-type.stderr | 2 +- tests/ui/suggestions/non_ascii_ident.stderr | 4 +- .../raw-name-use-suggestion.stderr | 2 +- .../suggestions/silenced-binding-typo.stderr | 2 +- .../suggest-let-for-assignment.stderr | 22 ++++----- .../suggest_print_over_printf.stderr | 2 +- ...-ascription-instead-of-path-in-type.stderr | 2 +- .../type-not-found-in-adt-field.stderr | 4 +- tests/ui/suggestions/while-let-typo.stderr | 4 +- .../tool-attributes-misplaced-1.stderr | 8 ++-- tests/ui/track-diagnostics/track.stderr | 2 +- tests/ui/track-diagnostics/track3.stderr | 2 +- ...ice-unsized-struct-arg-issue-121612.stderr | 4 +- ...ce-unsized-tuple-const-issue-121443.stderr | 2 +- .../impl-bound-with-references-error.rs | 2 +- .../impl-bound-with-references-error.stderr | 2 +- ...owed-path-in-trait-bound-suggestion.stderr | 2 +- .../assoc_type_bound_with_struct.stderr | 2 +- ...dont-autoderef-ty-with-escaping-var.stderr | 2 +- ...alller-supplied-obligation-issue-121941.rs | 2 +- ...er-supplied-obligation-issue-121941.stderr | 2 +- tests/ui/traits/ignore-err-impls.stderr | 2 +- tests/ui/traits/issue-22384.stderr | 2 +- tests/ui/traits/issue-50480.stderr | 12 ++--- tests/ui/traits/issue-75627.stderr | 2 +- tests/ui/traits/issue-78372.stderr | 6 +-- .../dont-normalize-proj-with-error.stderr | 2 +- .../issue-118950-root-region.stderr | 2 +- .../traits/no-fallback-multiple-impls.stderr | 2 +- .../binder-defaults-112547.stderr | 2 +- .../binder-defaults-118697.stderr | 2 +- .../traits/trait-selection-ice-84727.stderr | 8 ++-- .../ui/transmutability/issue-101739-1.stderr | 2 +- .../unknown_dst.stderr | 2 +- .../unknown_src.stderr | 2 +- .../unknown_src_field.stderr | 2 +- .../ui/tuple/tuple-struct-fields/test.stderr | 2 +- .../ui/tuple/tuple-struct-fields/test2.stderr | 4 +- .../ui/tuple/tuple-struct-fields/test3.stderr | 4 +- .../nested-impl-trait-in-tait.stderr | 2 +- .../ui/type-alias/issue-62364-self-ty-arg.rs | 2 +- .../type-alias/issue-62364-self-ty-arg.stderr | 2 +- tests/ui/type/issue-7607-1.stderr | 2 +- tests/ui/type/type-path-err-node-types.stderr | 6 +-- .../typeck/apit-with-error-type-in-sig.stderr | 2 +- .../autoderef-with-param-env-error.stderr | 2 +- tests/ui/typeck/check-args-on-fn-err-2.stderr | 2 +- tests/ui/typeck/check-args-on-fn-err.stderr | 2 +- tests/ui/typeck/issue-104510-ice.stderr | 2 +- tests/ui/typeck/issue-104513-ice.stderr | 2 +- tests/ui/typeck/issue-105946.rs | 2 +- tests/ui/typeck/issue-105946.stderr | 2 +- tests/ui/typeck/issue-106929.stderr | 2 +- ...114423-ice-regression-in-suggestion.stderr | 6 +-- tests/ui/typeck/issue-83693.rs | 6 +-- tests/ui/typeck/issue-83693.stderr | 6 +-- tests/ui/typeck/issue-88844.rs | 2 +- tests/ui/typeck/issue-88844.stderr | 2 +- tests/ui/typeck/issue-90319.rs | 2 +- tests/ui/typeck/issue-90319.stderr | 2 +- tests/ui/typeck/issue-91267.rs | 2 +- tests/ui/typeck/issue-91267.stderr | 2 +- .../nonexistent-field-not-ambiguous.stderr | 2 +- .../typeck/quiet-type-err-let-binding.stderr | 2 +- tests/ui/ufcs/ufcs-partially-resolved.stderr | 20 ++++---- ...mismatch-closure-from-another-scope.stderr | 4 +- .../union/unresolved-field-isnt-copy.stderr | 2 +- .../unresolved/unresolved-candidates.stderr | 2 +- ...ir-wf-check-anon-const-issue-122199.stderr | 4 +- tests/ui/wf/issue-110157.stderr | 4 +- .../where-clauses/ignore-err-clauses.stderr | 2 +- .../normalization-of-unknown-type.stderr | 2 +- 483 files changed, 1028 insertions(+), 1028 deletions(-) diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl index dbd703cf9889e..5921492160e24 100644 --- a/compiler/rustc_lint/messages.ftl +++ b/compiler/rustc_lint/messages.ftl @@ -609,7 +609,7 @@ lint_opaque_hidden_inferred_bound_sugg = add this bound lint_or_patterns_back_compat = the meaning of the `pat` fragment specifier is changing in Rust 2021, which may affect this macro .suggestion = use pat_param to preserve semantics -lint_out_of_scope_macro_calls = cannot find macro `{$path}` +lint_out_of_scope_macro_calls = cannot find macro `{$path}` in this scope .label = not found in this scope .help = import `macro_rules` with `use` to make it callable above its definition @@ -651,7 +651,7 @@ lint_pattern_in_foreign = patterns aren't allowed in foreign function declaratio lint_private_extern_crate_reexport = extern crate `{$ident}` is private and cannot be re-exported .suggestion = consider making the `extern crate` item publicly accessible -lint_proc_macro_derive_resolution_fallback = cannot find {$ns} `{$ident}` +lint_proc_macro_derive_resolution_fallback = cannot find {$ns} `{$ident}` in this scope .label = names from parent modules are not accessible without an explicit import lint_ptr_null_checks_fn_ptr = function pointers are not nullable, so checking them for null will always return false diff --git a/compiler/rustc_resolve/messages.ftl b/compiler/rustc_resolve/messages.ftl index 479c7588c3ca9..2e9d36b80133d 100644 --- a/compiler/rustc_resolve/messages.ftl +++ b/compiler/rustc_resolve/messages.ftl @@ -80,7 +80,7 @@ resolve_cannot_determine_macro_resolution = resolve_cannot_find_builtin_macro_with_name = cannot find a built-in macro with name `{$ident}` -resolve_cannot_find_ident_in_this_scope = cannot find {$expected} `{$ident}` +resolve_cannot_find_ident_in_this_scope = cannot find {$expected} `{$ident}` in this scope .label = not found in this scope resolve_cannot_glob_import_possible_crates = diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 3363fb0298dc5..1d37264f96a3c 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -3918,7 +3918,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { // There are two different error messages user might receive at // this point: - // - E0412 cannot find type `{}` + // - E0412 cannot find type `{}` in this scope // - E0433 failed to resolve: use of undeclared type or module `{}` // // The first one is emitted for paths in type-position, and the diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 74921a535b428..3bf881b0e42b1 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -351,7 +351,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { }; BaseError { - msg: format!("cannot find {expected} `{item_str}`"), + msg: format!("cannot find {expected} `{item_str}` in {mod_prefix}{mod_str}"), fallback_label, span: item_span, span_label, @@ -2522,7 +2522,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { if let Some(generics) = kind.generics() { if span.overlaps(generics.span) { // Avoid the following: - // error[E0405]: cannot find trait `A` + // error[E0405]: cannot find trait `A` in this scope // --> $DIR/typo-suggestion-named-underscore.rs:CC:LL // | // L | fn foo(x: T) {} // Shouldn't suggest underscore diff --git a/src/tools/clippy/tests/ui/crashes/ice-6252.stderr b/src/tools/clippy/tests/ui/crashes/ice-6252.stderr index 067809c7cd6f6..cd2031af1c6da 100644 --- a/src/tools/clippy/tests/ui/crashes/ice-6252.stderr +++ b/src/tools/clippy/tests/ui/crashes/ice-6252.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `PhantomData` +error[E0412]: cannot find type `PhantomData` in this scope --> tests/ui/crashes/ice-6252.rs:9:9 | LL | _n: PhantomData, @@ -9,7 +9,7 @@ help: consider importing this struct LL + use std::marker::PhantomData; | -error[E0412]: cannot find type `VAL` +error[E0412]: cannot find type `VAL` in this scope --> tests/ui/crashes/ice-6252.rs:11:63 | LL | impl TypeVal for Multiply where N: TypeVal {} diff --git a/src/tools/clippy/tests/ui/option_map_unit_fn_unfixable.stderr b/src/tools/clippy/tests/ui/option_map_unit_fn_unfixable.stderr index b49d182b64567..66271036113ca 100644 --- a/src/tools/clippy/tests/ui/option_map_unit_fn_unfixable.stderr +++ b/src/tools/clippy/tests/ui/option_map_unit_fn_unfixable.stderr @@ -1,22 +1,22 @@ -error[E0425]: cannot find value `x` +error[E0425]: cannot find value `x` in this scope --> tests/ui/option_map_unit_fn_unfixable.rs:17:5 | LL | x.field.map(|value| { do_nothing(value); do_nothing(value) }); | ^ not found in this scope -error[E0425]: cannot find value `x` +error[E0425]: cannot find value `x` in this scope --> tests/ui/option_map_unit_fn_unfixable.rs:19:5 | LL | x.field.map(|value| if value > 0 { do_nothing(value); do_nothing(value) }); | ^ not found in this scope -error[E0425]: cannot find value `x` +error[E0425]: cannot find value `x` in this scope --> tests/ui/option_map_unit_fn_unfixable.rs:23:5 | LL | x.field.map(|value| { | ^ not found in this scope -error[E0425]: cannot find value `x` +error[E0425]: cannot find value `x` in this scope --> tests/ui/option_map_unit_fn_unfixable.rs:27:5 | LL | x.field.map(|value| { do_nothing(value); do_nothing(value); }); diff --git a/tests/rustdoc-ui/doctest/failed-doctest-output.stdout b/tests/rustdoc-ui/doctest/failed-doctest-output.stdout index 4c7233a296060..7b0cf9a432d4c 100644 --- a/tests/rustdoc-ui/doctest/failed-doctest-output.stdout +++ b/tests/rustdoc-ui/doctest/failed-doctest-output.stdout @@ -6,7 +6,7 @@ test $DIR/failed-doctest-output.rs - SomeStruct (line 15) ... FAILED failures: ---- $DIR/failed-doctest-output.rs - OtherStruct (line 25) stdout ---- -error[E0425]: cannot find value `no` +error[E0425]: cannot find value `no` in this scope --> $DIR/failed-doctest-output.rs:26:1 | LL | no diff --git a/tests/rustdoc-ui/impl-fn-nesting.stderr b/tests/rustdoc-ui/impl-fn-nesting.stderr index 3e629d5c6f94f..4710e9893acb8 100644 --- a/tests/rustdoc-ui/impl-fn-nesting.stderr +++ b/tests/rustdoc-ui/impl-fn-nesting.stderr @@ -1,58 +1,58 @@ -error: cannot find macro `unknown_macro` +error: cannot find macro `unknown_macro` in this scope --> $DIR/impl-fn-nesting.rs:32:13 | LL | unknown_macro!(); | ^^^^^^^^^^^^^ not found in this scope -error[E0405]: cannot find trait `UnknownBound` +error[E0405]: cannot find trait `UnknownBound` in this scope --> $DIR/impl-fn-nesting.rs:11:13 | LL | pub fn f(a: UnknownType, b: B) { | ^^^^^^^^^^^^ not found in this scope -error[E0412]: cannot find type `UnknownType` +error[E0412]: cannot find type `UnknownType` in this scope --> $DIR/impl-fn-nesting.rs:11:30 | LL | pub fn f(a: UnknownType, b: B) { | ^^^^^^^^^^^ not found in this scope -error[E0405]: cannot find trait `UnknownTrait` +error[E0405]: cannot find trait `UnknownTrait` in this scope --> $DIR/impl-fn-nesting.rs:14:10 | LL | impl UnknownTrait for ValidType {} | ^^^^^^^^^^^^ not found in this scope -error[E0405]: cannot find trait `UnknownTrait` +error[E0405]: cannot find trait `UnknownTrait` in this scope --> $DIR/impl-fn-nesting.rs:15:27 | LL | impl UnknownTrait for T {} | ^^^^^^^^^^^^ not found in this scope -error[E0405]: cannot find trait `UnknownBound` +error[E0405]: cannot find trait `UnknownBound` in this scope --> $DIR/impl-fn-nesting.rs:15:13 | LL | impl UnknownTrait for T {} | ^^^^^^^^^^^^ not found in this scope -error[E0412]: cannot find type `UnknownType` +error[E0412]: cannot find type `UnknownType` in this scope --> $DIR/impl-fn-nesting.rs:18:25 | LL | impl ValidTrait for UnknownType {} | ^^^^^^^^^^^ not found in this scope -error[E0405]: cannot find trait `UnknownBound` +error[E0405]: cannot find trait `UnknownBound` in this scope --> $DIR/impl-fn-nesting.rs:20:53 | LL | impl ValidTrait for ValidType where ValidTrait: UnknownBound {} | ^^^^^^^^^^^^ not found in this scope -error[E0412]: cannot find type `UnknownType` +error[E0412]: cannot find type `UnknownType` in this scope --> $DIR/impl-fn-nesting.rs:25:21 | LL | type Item = UnknownType; | ^^^^^^^^^^^ not found in this scope -error[E0412]: cannot find type `UnknownType` +error[E0412]: cannot find type `UnknownType` in this scope --> $DIR/impl-fn-nesting.rs:44:37 | LL | pub fn doubly_nested(c: UnknownType) { diff --git a/tests/rustdoc-ui/issues/issue-81662-shortness.stdout b/tests/rustdoc-ui/issues/issue-81662-shortness.stdout index 754396380116d..f32f51e12f2c3 100644 --- a/tests/rustdoc-ui/issues/issue-81662-shortness.stdout +++ b/tests/rustdoc-ui/issues/issue-81662-shortness.stdout @@ -5,7 +5,7 @@ test $DIR/issue-81662-shortness.rs - foo (line 8) ... FAILED failures: ---- $DIR/issue-81662-shortness.rs - foo (line 8) stdout ---- -$DIR/issue-81662-shortness.rs:9:1: error[E0425]: cannot find function `foo` +$DIR/issue-81662-shortness.rs:9:1: error[E0425]: cannot find function `foo` in this scope error: aborting due to 1 previous error Couldn't compile the test. diff --git a/tests/ui/annotate-snippet/missing-type.stderr b/tests/ui/annotate-snippet/missing-type.stderr index c6c5c1d258ed2..89ce19c182f52 100644 --- a/tests/ui/annotate-snippet/missing-type.stderr +++ b/tests/ui/annotate-snippet/missing-type.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `Iter` +error[E0412]: cannot find type `Iter` in this scope --> $DIR/missing-type.rs:5:12 | LL | let x: Iter; diff --git a/tests/ui/argument-suggestions/extern-fn-arg-names.stderr b/tests/ui/argument-suggestions/extern-fn-arg-names.stderr index 265c0ad477b39..f6bc84c1203ad 100644 --- a/tests/ui/argument-suggestions/extern-fn-arg-names.stderr +++ b/tests/ui/argument-suggestions/extern-fn-arg-names.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `err` +error[E0412]: cannot find type `err` in this scope --> $DIR/extern-fn-arg-names.rs:2:29 | LL | fn dstfn(src: i32, dst: err); diff --git a/tests/ui/argument-suggestions/issue-109831.stderr b/tests/ui/argument-suggestions/issue-109831.stderr index 2962e10aebbe6..7b9a3c9ef2c6c 100644 --- a/tests/ui/argument-suggestions/issue-109831.stderr +++ b/tests/ui/argument-suggestions/issue-109831.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `C` +error[E0412]: cannot find type `C` in this scope --> $DIR/issue-109831.rs:4:24 | LL | struct A; @@ -16,7 +16,7 @@ help: you might be missing a type parameter LL | fn f(b1: B, b2: B, a2: C) {} | +++ -error[E0425]: cannot find value `C` +error[E0425]: cannot find value `C` in this scope --> $DIR/issue-109831.rs:7:16 | LL | struct A; diff --git a/tests/ui/argument-suggestions/suggest-better-removing-issue-126246.stderr b/tests/ui/argument-suggestions/suggest-better-removing-issue-126246.stderr index 23e074d79ffb2..dc293945eb600 100644 --- a/tests/ui/argument-suggestions/suggest-better-removing-issue-126246.stderr +++ b/tests/ui/argument-suggestions/suggest-better-removing-issue-126246.stderr @@ -1,28 +1,28 @@ -error[E0425]: cannot find value `no_such_local` +error[E0425]: cannot find value `no_such_local` in this scope --> $DIR/suggest-better-removing-issue-126246.rs:11:13 | LL | add_one(no_such_local, 10); | ^^^^^^^^^^^^^ not found in this scope -error[E0425]: cannot find value `no_such_local` +error[E0425]: cannot find value `no_such_local` in this scope --> $DIR/suggest-better-removing-issue-126246.rs:13:17 | LL | add_one(10, no_such_local); | ^^^^^^^^^^^^^ not found in this scope -error[E0425]: cannot find value `no_such_local` +error[E0425]: cannot find value `no_such_local` in this scope --> $DIR/suggest-better-removing-issue-126246.rs:15:17 | LL | add_two(10, no_such_local, 10); | ^^^^^^^^^^^^^ not found in this scope -error[E0425]: cannot find value `no_such_local` +error[E0425]: cannot find value `no_such_local` in this scope --> $DIR/suggest-better-removing-issue-126246.rs:17:13 | LL | add_two(no_such_local, 10, 10); | ^^^^^^^^^^^^^ not found in this scope -error[E0425]: cannot find value `no_such_local` +error[E0425]: cannot find value `no_such_local` in this scope --> $DIR/suggest-better-removing-issue-126246.rs:19:21 | LL | add_two(10, 10, no_such_local); diff --git a/tests/ui/array-slice-vec/slice-pat-type-mismatches.stderr b/tests/ui/array-slice-vec/slice-pat-type-mismatches.stderr index f48c1564babd4..d1d042c477681 100644 --- a/tests/ui/array-slice-vec/slice-pat-type-mismatches.stderr +++ b/tests/ui/array-slice-vec/slice-pat-type-mismatches.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `does_not_exist` +error[E0425]: cannot find value `does_not_exist` in this scope --> $DIR/slice-pat-type-mismatches.rs:26:11 | LL | match does_not_exist { diff --git a/tests/ui/asm/issue-113788.rs b/tests/ui/asm/issue-113788.rs index 1d63cb309ef73..04a88999e5aff 100644 --- a/tests/ui/asm/issue-113788.rs +++ b/tests/ui/asm/issue-113788.rs @@ -2,6 +2,6 @@ //@ needs-asm-support //@ only-x86_64 fn main() { - let peb: *const PEB; //~ ERROR cannot find type `PEB` [E0412] + let peb: *const PEB; //~ ERROR cannot find type `PEB` unsafe { std::arch::asm!("mov {0}, fs:[0x30]", out(reg) peb); } } diff --git a/tests/ui/asm/issue-113788.stderr b/tests/ui/asm/issue-113788.stderr index ba27c8b101fb1..c44ba3c91d91a 100644 --- a/tests/ui/asm/issue-113788.stderr +++ b/tests/ui/asm/issue-113788.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `PEB` +error[E0412]: cannot find type `PEB` in this scope --> $DIR/issue-113788.rs:5:21 | LL | let peb: *const PEB; diff --git a/tests/ui/associated-consts/issue-93835.stderr b/tests/ui/associated-consts/issue-93835.stderr index 8de7c04530f54..dfe78b3d1f380 100644 --- a/tests/ui/associated-consts/issue-93835.stderr +++ b/tests/ui/associated-consts/issue-93835.stderr @@ -1,16 +1,16 @@ -error[E0425]: cannot find value `p` +error[E0425]: cannot find value `p` in this scope --> $DIR/issue-93835.rs:4:19 | LL | type_ascribe!(p, a>); | ^ not found in this scope -error[E0412]: cannot find type `a` +error[E0412]: cannot find type `a` in this scope --> $DIR/issue-93835.rs:4:22 | LL | type_ascribe!(p, a>); | ^ not found in this scope -error[E0405]: cannot find trait `p` +error[E0405]: cannot find trait `p` in this scope --> $DIR/issue-93835.rs:4:26 | LL | type_ascribe!(p, a>); diff --git a/tests/ui/associated-item/issue-87638.stderr b/tests/ui/associated-item/issue-87638.stderr index ce13a4eac4b3b..7f8e58f457889 100644 --- a/tests/ui/associated-item/issue-87638.stderr +++ b/tests/ui/associated-item/issue-87638.stderr @@ -1,4 +1,4 @@ -error[E0576]: cannot find associated type `Output` +error[E0576]: cannot find associated type `Output` in trait `Trait` --> $DIR/issue-87638.rs:17:26 | LL | type Target; @@ -10,7 +10,7 @@ LL | let _: ::Output; | not found in trait `Trait` | help: maybe you meant this associated type: `Target` -error[E0576]: cannot find method or associated constant `BAR` +error[E0576]: cannot find method or associated constant `BAR` in trait `Trait` --> $DIR/issue-87638.rs:20:27 | LL | const FOO: usize; diff --git a/tests/ui/associated-path-shl.stderr b/tests/ui/associated-path-shl.stderr index 330a304919c2b..71ee93f4835fb 100644 --- a/tests/ui/associated-path-shl.stderr +++ b/tests/ui/associated-path-shl.stderr @@ -1,28 +1,28 @@ -error[E0412]: cannot find type `A` +error[E0412]: cannot find type `A` in this scope --> $DIR/associated-path-shl.rs:4:14 | LL | let _: <::B>::C; | ^ not found in this scope -error[E0412]: cannot find type `A` +error[E0412]: cannot find type `A` in this scope --> $DIR/associated-path-shl.rs:5:15 | LL | let _ = <::B>::C; | ^ not found in this scope -error[E0412]: cannot find type `A` +error[E0412]: cannot find type `A` in this scope --> $DIR/associated-path-shl.rs:6:11 | LL | let <::B>::C; | ^ not found in this scope -error[E0412]: cannot find type `A` +error[E0412]: cannot find type `A` in this scope --> $DIR/associated-path-shl.rs:7:17 | LL | let 0 ..= <::B>::C; | ^ not found in this scope -error[E0412]: cannot find type `A` +error[E0412]: cannot find type `A` in this scope --> $DIR/associated-path-shl.rs:8:7 | LL | <::B>::C; diff --git a/tests/ui/associated-type-bounds/missing-trait-bound-for-assoc-fails.rs b/tests/ui/associated-type-bounds/missing-trait-bound-for-assoc-fails.rs index 93c7203f14710..05343e853a9fc 100644 --- a/tests/ui/associated-type-bounds/missing-trait-bound-for-assoc-fails.rs +++ b/tests/ui/associated-type-bounds/missing-trait-bound-for-assoc-fails.rs @@ -2,7 +2,7 @@ fn foo(_m: M) where M::Item: Temp, - //~^ ERROR cannot find trait `Temp` [E0405] + //~^ ERROR cannot find trait `Temp` //~| ERROR associated type `Item` not found for `M` [E0220] { } diff --git a/tests/ui/associated-type-bounds/missing-trait-bound-for-assoc-fails.stderr b/tests/ui/associated-type-bounds/missing-trait-bound-for-assoc-fails.stderr index 65c37ecf5bbc0..bc2807b03961c 100644 --- a/tests/ui/associated-type-bounds/missing-trait-bound-for-assoc-fails.stderr +++ b/tests/ui/associated-type-bounds/missing-trait-bound-for-assoc-fails.stderr @@ -1,4 +1,4 @@ -error[E0405]: cannot find trait `Temp` +error[E0405]: cannot find trait `Temp` in this scope --> $DIR/missing-trait-bound-for-assoc-fails.rs:4:14 | LL | M::Item: Temp, diff --git a/tests/ui/associated-types/associated-types-eq-1.stderr b/tests/ui/associated-types/associated-types-eq-1.stderr index a9267d07265dd..14ef36876740b 100644 --- a/tests/ui/associated-types/associated-types-eq-1.stderr +++ b/tests/ui/associated-types/associated-types-eq-1.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `A` +error[E0412]: cannot find type `A` in this scope --> $DIR/associated-types-eq-1.rs:10:12 | LL | fn foo2(x: I) { diff --git a/tests/ui/associated-types/issue-19883.stderr b/tests/ui/associated-types/issue-19883.stderr index 03a4bdf38c388..66615fba8362f 100644 --- a/tests/ui/associated-types/issue-19883.stderr +++ b/tests/ui/associated-types/issue-19883.stderr @@ -1,4 +1,4 @@ -error[E0576]: cannot find associated type `Dst` +error[E0576]: cannot find associated type `Dst` in trait `From` --> $DIR/issue-19883.rs:9:30 | LL | type Output; diff --git a/tests/ui/associated-types/issue-22037.stderr b/tests/ui/associated-types/issue-22037.stderr index 135f228bfad48..568b49d3ad220 100644 --- a/tests/ui/associated-types/issue-22037.stderr +++ b/tests/ui/associated-types/issue-22037.stderr @@ -1,4 +1,4 @@ -error[E0576]: cannot find associated type `X` +error[E0576]: cannot find associated type `X` in trait `A` --> $DIR/issue-22037.rs:3:33 | LL | type Output; diff --git a/tests/ui/async-await/async-closures/tainted-body.stderr b/tests/ui/async-await/async-closures/tainted-body.stderr index f8ae0d1558809..b06a896b81f52 100644 --- a/tests/ui/async-await/async-closures/tainted-body.stderr +++ b/tests/ui/async-await/async-closures/tainted-body.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find function `used_fn` +error[E0425]: cannot find function `used_fn` in this scope --> $DIR/tainted-body.rs:9:9 | LL | used_fn(); diff --git a/tests/ui/async-await/async-fn/not-a-trait.stderr b/tests/ui/async-await/async-fn/not-a-trait.stderr index b9a07a0b04cc1..d49f7d7d2fc16 100644 --- a/tests/ui/async-await/async-fn/not-a-trait.stderr +++ b/tests/ui/async-await/async-fn/not-a-trait.stderr @@ -4,7 +4,7 @@ error[E0404]: expected trait, found struct `S` LL | fn test(x: impl async S) {} | ^ not a trait -error[E0405]: cannot find trait `Missing` +error[E0405]: cannot find trait `Missing` in this scope --> $DIR/not-a-trait.rs:10:26 | LL | fn missing(x: impl async Missing) {} diff --git a/tests/ui/async-await/drop-order/drop-order-locals-are-hidden.rs b/tests/ui/async-await/drop-order/drop-order-locals-are-hidden.rs index cb9c70ff665ed..a218877047866 100644 --- a/tests/ui/async-await/drop-order/drop-order-locals-are-hidden.rs +++ b/tests/ui/async-await/drop-order/drop-order-locals-are-hidden.rs @@ -1,13 +1,13 @@ //@ edition:2018 async fn foobar_async(x: u32, (a, _, _c): (u32, u32, u32), _: u32, _y: u32) { - assert_eq!(__arg1, (1, 2, 3)); //~ ERROR cannot find value `__arg1` [E0425] - assert_eq!(__arg2, 4); //~ ERROR cannot find value `__arg2` [E0425] + assert_eq!(__arg1, (1, 2, 3)); //~ ERROR cannot find value `__arg1` + assert_eq!(__arg2, 4); //~ ERROR cannot find value `__arg2` } async fn baz_async(ref mut x: u32, ref y: u32) { - assert_eq!(__arg0, 1); //~ ERROR cannot find value `__arg0` [E0425] - assert_eq!(__arg1, 2); //~ ERROR cannot find value `__arg1` [E0425] + assert_eq!(__arg0, 1); //~ ERROR cannot find value `__arg0` + assert_eq!(__arg1, 2); //~ ERROR cannot find value `__arg1` } fn main() {} diff --git a/tests/ui/async-await/drop-order/drop-order-locals-are-hidden.stderr b/tests/ui/async-await/drop-order/drop-order-locals-are-hidden.stderr index 01460b1a9751e..aa04a613f47c1 100644 --- a/tests/ui/async-await/drop-order/drop-order-locals-are-hidden.stderr +++ b/tests/ui/async-await/drop-order/drop-order-locals-are-hidden.stderr @@ -1,22 +1,22 @@ -error[E0425]: cannot find value `__arg1` +error[E0425]: cannot find value `__arg1` in this scope --> $DIR/drop-order-locals-are-hidden.rs:4:16 | LL | assert_eq!(__arg1, (1, 2, 3)); | ^^^^^^ not found in this scope -error[E0425]: cannot find value `__arg2` +error[E0425]: cannot find value `__arg2` in this scope --> $DIR/drop-order-locals-are-hidden.rs:5:16 | LL | assert_eq!(__arg2, 4); | ^^^^^^ not found in this scope -error[E0425]: cannot find value `__arg0` +error[E0425]: cannot find value `__arg0` in this scope --> $DIR/drop-order-locals-are-hidden.rs:9:16 | LL | assert_eq!(__arg0, 1); | ^^^^^^ not found in this scope -error[E0425]: cannot find value `__arg1` +error[E0425]: cannot find value `__arg1` in this scope --> $DIR/drop-order-locals-are-hidden.rs:10:16 | LL | assert_eq!(__arg1, 2); diff --git a/tests/ui/async-await/in-trait/return-not-existing-pair.rs b/tests/ui/async-await/in-trait/return-not-existing-pair.rs index e72c8d8e93783..f3105e7c451bb 100644 --- a/tests/ui/async-await/in-trait/return-not-existing-pair.rs +++ b/tests/ui/async-await/in-trait/return-not-existing-pair.rs @@ -3,7 +3,7 @@ trait MyTrait<'a, 'b, T> { async fn foo(&'a self, key: &'b T) -> (&'a ConnImpl, &'b T); - //~^ ERROR: cannot find type `ConnImpl` [E0412] + //~^ ERROR: cannot find type `ConnImpl` } impl<'a, 'b, T, U> MyTrait for U { diff --git a/tests/ui/async-await/in-trait/return-not-existing-pair.stderr b/tests/ui/async-await/in-trait/return-not-existing-pair.stderr index bfa1cf1ddecf0..13d3606abba78 100644 --- a/tests/ui/async-await/in-trait/return-not-existing-pair.stderr +++ b/tests/ui/async-await/in-trait/return-not-existing-pair.stderr @@ -9,7 +9,7 @@ help: indicate the anonymous lifetimes LL | impl<'a, 'b, T, U> MyTrait<'_, '_, T> for U { | +++++++ -error[E0412]: cannot find type `ConnImpl` +error[E0412]: cannot find type `ConnImpl` in this scope --> $DIR/return-not-existing-pair.rs:5:48 | LL | async fn foo(&'a self, key: &'b T) -> (&'a ConnImpl, &'b T); diff --git a/tests/ui/async-await/in-trait/return-not-existing-type-wrapping-rpitit.rs b/tests/ui/async-await/in-trait/return-not-existing-type-wrapping-rpitit.rs index e485a19a41523..fbbba38c57405 100644 --- a/tests/ui/async-await/in-trait/return-not-existing-type-wrapping-rpitit.rs +++ b/tests/ui/async-await/in-trait/return-not-existing-type-wrapping-rpitit.rs @@ -5,7 +5,7 @@ struct Wrapper(T); trait Foo { fn bar() -> Wrapper>; - //~^ ERROR: cannot find type `Missing` [E0412] + //~^ ERROR: cannot find type `Missing` } impl Foo for () { diff --git a/tests/ui/async-await/in-trait/return-not-existing-type-wrapping-rpitit.stderr b/tests/ui/async-await/in-trait/return-not-existing-type-wrapping-rpitit.stderr index 58773c066b884..84e0a643485f7 100644 --- a/tests/ui/async-await/in-trait/return-not-existing-type-wrapping-rpitit.stderr +++ b/tests/ui/async-await/in-trait/return-not-existing-type-wrapping-rpitit.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `Missing` +error[E0412]: cannot find type `Missing` in this scope --> $DIR/return-not-existing-type-wrapping-rpitit.rs:7:25 | LL | fn bar() -> Wrapper>; diff --git a/tests/ui/async-await/issue-72590-type-error-sized.stderr b/tests/ui/async-await/issue-72590-type-error-sized.stderr index 557b29472bfe5..1b822234d80cc 100644 --- a/tests/ui/async-await/issue-72590-type-error-sized.stderr +++ b/tests/ui/async-await/issue-72590-type-error-sized.stderr @@ -1,10 +1,10 @@ -error[E0412]: cannot find type `Nonexistent` +error[E0412]: cannot find type `Nonexistent` in this scope --> $DIR/issue-72590-type-error-sized.rs:6:10 | LL | foo: Nonexistent, | ^^^^^^^^^^^ not found in this scope -error[E0412]: cannot find type `Missing` +error[E0412]: cannot find type `Missing` in this scope --> $DIR/issue-72590-type-error-sized.rs:11:11 | LL | test: Missing diff --git a/tests/ui/attributes/issue-90873.stderr b/tests/ui/attributes/issue-90873.stderr index 8035ae3f068de..313ecb8cf25e8 100644 --- a/tests/ui/attributes/issue-90873.stderr +++ b/tests/ui/attributes/issue-90873.stderr @@ -10,13 +10,13 @@ error: attribute value must be a literal LL | #![a={impl std::ops::Neg for i8 {}}] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: cannot find attribute `u` +error: cannot find attribute `u` in this scope --> $DIR/issue-90873.rs:1:4 | LL | #![u=||{static d=||1;}] | ^ not found in this scope -error: cannot find attribute `a` +error: cannot find attribute `a` in this scope --> $DIR/issue-90873.rs:6:4 | LL | #![a={impl std::ops::Neg for i8 {}}] diff --git a/tests/ui/attributes/key-value-expansion-scope.stderr b/tests/ui/attributes/key-value-expansion-scope.stderr index 72865116f721f..19948c4c283ac 100644 --- a/tests/ui/attributes/key-value-expansion-scope.stderr +++ b/tests/ui/attributes/key-value-expansion-scope.stderr @@ -1,4 +1,4 @@ -error: cannot find macro `in_mod` +error: cannot find macro `in_mod` in this scope --> $DIR/key-value-expansion-scope.rs:3:10 | LL | #![doc = in_mod!()] @@ -6,7 +6,7 @@ LL | #![doc = in_mod!()] | = help: have you added the `#[macro_use]` on the module/import? -error: cannot find macro `in_block` +error: cannot find macro `in_block` in this scope --> $DIR/key-value-expansion-scope.rs:6:10 | LL | #![doc = in_block!()] @@ -14,7 +14,7 @@ LL | #![doc = in_block!()] | = help: have you added the `#[macro_use]` on the module/import? -error: cannot find macro `in_root` +error: cannot find macro `in_root` in this scope --> $DIR/key-value-expansion-scope.rs:8:9 | LL | #[doc = in_root!()] @@ -22,7 +22,7 @@ LL | #[doc = in_root!()] | = help: have you added the `#[macro_use]` on the module/import? -error: cannot find macro `in_mod` +error: cannot find macro `in_mod` in this scope --> $DIR/key-value-expansion-scope.rs:9:9 | LL | #[doc = in_mod!()] @@ -30,7 +30,7 @@ LL | #[doc = in_mod!()] | = help: have you added the `#[macro_use]` on the module/import? -error: cannot find macro `in_mod_escape` +error: cannot find macro `in_mod_escape` in this scope --> $DIR/key-value-expansion-scope.rs:10:9 | LL | #[doc = in_mod_escape!()] @@ -38,7 +38,7 @@ LL | #[doc = in_mod_escape!()] | = help: have you added the `#[macro_use]` on the module/import? -error: cannot find macro `in_block` +error: cannot find macro `in_block` in this scope --> $DIR/key-value-expansion-scope.rs:11:9 | LL | #[doc = in_block!()] @@ -46,7 +46,7 @@ LL | #[doc = in_block!()] | = help: have you added the `#[macro_use]` on the module/import? -error: cannot find macro `in_root` +error: cannot find macro `in_root` in this scope --> $DIR/key-value-expansion-scope.rs:13:14 | LL | #![doc = in_root!()] @@ -54,7 +54,7 @@ LL | #![doc = in_root!()] | = help: have you added the `#[macro_use]` on the module/import? -error: cannot find macro `in_mod` +error: cannot find macro `in_mod` in this scope --> $DIR/key-value-expansion-scope.rs:14:14 | LL | #![doc = in_mod!()] @@ -62,7 +62,7 @@ LL | #![doc = in_mod!()] | = help: have you added the `#[macro_use]` on the module/import? -error: cannot find macro `in_mod_escape` +error: cannot find macro `in_mod_escape` in this scope --> $DIR/key-value-expansion-scope.rs:15:14 | LL | #![doc = in_mod_escape!()] @@ -70,7 +70,7 @@ LL | #![doc = in_mod_escape!()] | = help: have you added the `#[macro_use]` on the module/import? -error: cannot find macro `in_block` +error: cannot find macro `in_block` in this scope --> $DIR/key-value-expansion-scope.rs:16:14 | LL | #![doc = in_block!()] @@ -78,7 +78,7 @@ LL | #![doc = in_block!()] | = help: have you added the `#[macro_use]` on the module/import? -error: cannot find macro `in_block` +error: cannot find macro `in_block` in this scope --> $DIR/key-value-expansion-scope.rs:50:9 | LL | #[doc = in_block!()] @@ -86,7 +86,7 @@ LL | #[doc = in_block!()] | = help: have you added the `#[macro_use]` on the module/import? -error: cannot find macro `in_block` +error: cannot find macro `in_block` in this scope --> $DIR/key-value-expansion-scope.rs:52:14 | LL | #![doc = in_block!()] @@ -94,7 +94,7 @@ LL | #![doc = in_block!()] | = help: have you added the `#[macro_use]` on the module/import? -error: cannot find macro `in_mod` +error: cannot find macro `in_mod` in this scope --> $DIR/key-value-expansion-scope.rs:63:9 | LL | #[doc = in_mod!()] @@ -102,7 +102,7 @@ LL | #[doc = in_mod!()] | = help: have you added the `#[macro_use]` on the module/import? -error: cannot find macro `in_block` +error: cannot find macro `in_block` in this scope --> $DIR/key-value-expansion-scope.rs:65:9 | LL | #[doc = in_block!()] @@ -110,7 +110,7 @@ LL | #[doc = in_block!()] | = help: have you added the `#[macro_use]` on the module/import? -error: cannot find macro `in_mod` +error: cannot find macro `in_mod` in this scope --> $DIR/key-value-expansion-scope.rs:68:14 | LL | #![doc = in_mod!()] @@ -118,7 +118,7 @@ LL | #![doc = in_mod!()] | = help: have you added the `#[macro_use]` on the module/import? -error: cannot find macro `in_block` +error: cannot find macro `in_block` in this scope --> $DIR/key-value-expansion-scope.rs:70:14 | LL | #![doc = in_block!()] @@ -126,7 +126,7 @@ LL | #![doc = in_block!()] | = help: have you added the `#[macro_use]` on the module/import? -warning: cannot find macro `in_root` +warning: cannot find macro `in_root` in this scope --> $DIR/key-value-expansion-scope.rs:1:10 | LL | #![doc = in_root!()] @@ -137,7 +137,7 @@ LL | #![doc = in_root!()] = help: import `macro_rules` with `use` to make it callable above its definition = note: `#[warn(out_of_scope_macro_calls)]` on by default -warning: cannot find macro `in_mod_escape` +warning: cannot find macro `in_mod_escape` in this scope --> $DIR/key-value-expansion-scope.rs:4:10 | LL | #![doc = in_mod_escape!()] @@ -147,7 +147,7 @@ LL | #![doc = in_mod_escape!()] = note: for more information, see issue #124535 = help: import `macro_rules` with `use` to make it callable above its definition -warning: cannot find macro `in_mod` +warning: cannot find macro `in_mod` in this scope --> $DIR/key-value-expansion-scope.rs:21:9 | LL | #[doc = in_mod!()] @@ -157,7 +157,7 @@ LL | #[doc = in_mod!()] = note: for more information, see issue #124535 = help: import `macro_rules` with `use` to make it callable above its definition -warning: cannot find macro `in_mod` +warning: cannot find macro `in_mod` in this scope --> $DIR/key-value-expansion-scope.rs:24:14 | LL | #![doc = in_mod!()] @@ -167,7 +167,7 @@ LL | #![doc = in_mod!()] = note: for more information, see issue #124535 = help: import `macro_rules` with `use` to make it callable above its definition -warning: cannot find macro `in_mod_escape` +warning: cannot find macro `in_mod_escape` in this scope --> $DIR/key-value-expansion-scope.rs:36:9 | LL | #[doc = in_mod_escape!()] @@ -177,7 +177,7 @@ LL | #[doc = in_mod_escape!()] = note: for more information, see issue #124535 = help: import `macro_rules` with `use` to make it callable above its definition -warning: cannot find macro `in_mod_escape` +warning: cannot find macro `in_mod_escape` in this scope --> $DIR/key-value-expansion-scope.rs:39:14 | LL | #![doc = in_mod_escape!()] diff --git a/tests/ui/attributes/main-removed-1.stderr b/tests/ui/attributes/main-removed-1.stderr index e996ac0b7710c..ad6b60a212cc8 100644 --- a/tests/ui/attributes/main-removed-1.stderr +++ b/tests/ui/attributes/main-removed-1.stderr @@ -1,4 +1,4 @@ -error: cannot find attribute `main` +error: cannot find attribute `main` in this scope --> $DIR/main-removed-1.rs:1:3 | LL | #[main] diff --git a/tests/ui/attributes/obsolete-attr.stderr b/tests/ui/attributes/obsolete-attr.stderr index d5f0f25b1dc9e..e3ab0ecfbd2bf 100644 --- a/tests/ui/attributes/obsolete-attr.stderr +++ b/tests/ui/attributes/obsolete-attr.stderr @@ -1,10 +1,10 @@ -error: cannot find attribute `fixed_stack_segment` +error: cannot find attribute `fixed_stack_segment` in this scope --> $DIR/obsolete-attr.rs:6:3 | LL | #[fixed_stack_segment] fn f() {} | ^^^^^^^^^^^^^^^^^^^ not found in this scope -error: cannot find attribute `ab_isize` +error: cannot find attribute `ab_isize` in this scope --> $DIR/obsolete-attr.rs:3:3 | LL | #[ab_isize = "stdcall"] extern "C" {} diff --git a/tests/ui/attributes/unknown-attr.stderr b/tests/ui/attributes/unknown-attr.stderr index 06e60d8299703..acd8b93a78e99 100644 --- a/tests/ui/attributes/unknown-attr.stderr +++ b/tests/ui/attributes/unknown-attr.stderr @@ -1,16 +1,16 @@ -error: cannot find attribute `mutable_doc` +error: cannot find attribute `mutable_doc` in this scope --> $DIR/unknown-attr.rs:5:4 | LL | #![mutable_doc] | ^^^^^^^^^^^ not found in this scope -error: cannot find attribute `dance` +error: cannot find attribute `dance` in this scope --> $DIR/unknown-attr.rs:8:3 | LL | #[dance] mod a {} | ^^^^^ not found in this scope -error: cannot find attribute `dance` +error: cannot find attribute `dance` in this scope --> $DIR/unknown-attr.rs:11:3 | LL | #[dance] fn main() {} diff --git a/tests/ui/attributes/unsafe/double-unsafe-attributes.stderr b/tests/ui/attributes/unsafe/double-unsafe-attributes.stderr index c776c4a52193b..9f9a4e2f214c1 100644 --- a/tests/ui/attributes/unsafe/double-unsafe-attributes.stderr +++ b/tests/ui/attributes/unsafe/double-unsafe-attributes.stderr @@ -17,7 +17,7 @@ LL | #[unsafe(unsafe(no_mangle))] | = note: extraneous unsafe is not allowed in attributes -error: cannot find attribute `r#unsafe` +error: cannot find attribute `r#unsafe` in this scope --> $DIR/double-unsafe-attributes.rs:3:10 | LL | #[unsafe(unsafe(no_mangle))] diff --git a/tests/ui/attributes/unused-item-in-attr.stderr b/tests/ui/attributes/unused-item-in-attr.stderr index 9df0416e76655..3b2f196b468c3 100644 --- a/tests/ui/attributes/unused-item-in-attr.stderr +++ b/tests/ui/attributes/unused-item-in-attr.stderr @@ -4,7 +4,7 @@ error: attribute value must be a literal LL | #[w = { extern crate alloc; }] | ^^^^^^^^^^^^^^^^^^^^^^^ -error: cannot find attribute `w` +error: cannot find attribute `w` in this scope --> $DIR/unused-item-in-attr.rs:1:3 | LL | #[w = { extern crate alloc; }] diff --git a/tests/ui/c-variadic/issue-86053-1.stderr b/tests/ui/c-variadic/issue-86053-1.stderr index 9c34766d87ce7..67a619e46d57d 100644 --- a/tests/ui/c-variadic/issue-86053-1.stderr +++ b/tests/ui/c-variadic/issue-86053-1.stderr @@ -52,7 +52,7 @@ error: only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` function LL | self , ... , self , self , ... ) where F : FnOnce ( & 'a & 'b usize ) { | ^^^ ^^^ -error[E0412]: cannot find type `F` +error[E0412]: cannot find type `F` in this scope --> $DIR/issue-86053-1.rs:11:48 | LL | self , ... , self , self , ... ) where F : FnOnce ( & 'a & 'b usize ) { diff --git a/tests/ui/cast/cast-errors-issue-43825.stderr b/tests/ui/cast/cast-errors-issue-43825.stderr index 5ed78fd04cf74..658d5ddbb611c 100644 --- a/tests/ui/cast/cast-errors-issue-43825.stderr +++ b/tests/ui/cast/cast-errors-issue-43825.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `error` +error[E0425]: cannot find value `error` in this scope --> $DIR/cast-errors-issue-43825.rs:2:17 | LL | let error = error; diff --git a/tests/ui/cast/casts-issue-46365.stderr b/tests/ui/cast/casts-issue-46365.stderr index 68e46618a621e..84bc73a9b7862 100644 --- a/tests/ui/cast/casts-issue-46365.stderr +++ b/tests/ui/cast/casts-issue-46365.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `Ipsum` +error[E0412]: cannot find type `Ipsum` in this scope --> $DIR/casts-issue-46365.rs:2:12 | LL | ipsum: Ipsum diff --git a/tests/ui/cast/ice-cast-type-with-error-124848.stderr b/tests/ui/cast/ice-cast-type-with-error-124848.stderr index 60a4eb21bfd16..2d86bf76d1102 100644 --- a/tests/ui/cast/ice-cast-type-with-error-124848.stderr +++ b/tests/ui/cast/ice-cast-type-with-error-124848.stderr @@ -24,7 +24,7 @@ LL | fn main() { LL | let bad_addr = &unpinned as *const Cell>> as usize; | ^^ undeclared lifetime -error[E0412]: cannot find type `Pin` +error[E0412]: cannot find type `Pin` in this scope --> $DIR/ice-cast-type-with-error-124848.rs:7:60 | LL | struct MyType<'a>(Cell>>, Pin); diff --git a/tests/ui/cfg/diagnostics-cross-crate.stderr b/tests/ui/cfg/diagnostics-cross-crate.stderr index a01b1a47ef8d1..73598df060b67 100644 --- a/tests/ui/cfg/diagnostics-cross-crate.stderr +++ b/tests/ui/cfg/diagnostics-cross-crate.stderr @@ -10,13 +10,13 @@ note: found an item that was configured out LL | pub mod doesnt_exist { | ^^^^^^^^^^^^ -error[E0425]: cannot find function `uwu` +error[E0425]: cannot find function `uwu` in crate `cfged_out` --> $DIR/diagnostics-cross-crate.rs:7:16 | LL | cfged_out::uwu(); | ^^^ not found in crate `cfged_out` -error[E0425]: cannot find function `uwu` +error[E0425]: cannot find function `uwu` in module `cfged_out::inner` --> $DIR/diagnostics-cross-crate.rs:11:23 | LL | cfged_out::inner::uwu(); @@ -28,7 +28,7 @@ note: found an item that was configured out LL | pub fn uwu() {} | ^^^ -error[E0425]: cannot find function `meow` +error[E0425]: cannot find function `meow` in module `cfged_out::inner::right` --> $DIR/diagnostics-cross-crate.rs:22:30 | LL | cfged_out::inner::right::meow(); @@ -41,7 +41,7 @@ LL | pub fn meow() {} | ^^^^ = note: the item is gated behind the `what-a-cool-feature` feature -error[E0425]: cannot find function `vanished` +error[E0425]: cannot find function `vanished` in crate `cfged_out` --> $DIR/diagnostics-cross-crate.rs:28:16 | LL | cfged_out::vanished(); diff --git a/tests/ui/cfg/diagnostics-not-a-def.stderr b/tests/ui/cfg/diagnostics-not-a-def.stderr index e987bc7060596..7018064b178ae 100644 --- a/tests/ui/cfg/diagnostics-not-a-def.stderr +++ b/tests/ui/cfg/diagnostics-not-a-def.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find function `i_am_not` +error[E0425]: cannot find function `i_am_not` in module `inner` --> $DIR/diagnostics-not-a-def.rs:12:12 | LL | inner::i_am_not(); diff --git a/tests/ui/cfg/diagnostics-reexport.stderr b/tests/ui/cfg/diagnostics-reexport.stderr index c64179a741bb7..4d9b50e6c3416 100644 --- a/tests/ui/cfg/diagnostics-reexport.stderr +++ b/tests/ui/cfg/diagnostics-reexport.stderr @@ -29,7 +29,7 @@ note: found an item that was configured out LL | pub fn y() {} | ^ -error[E0425]: cannot find function `uwu` +error[E0425]: cannot find function `uwu` in module `inner` --> $DIR/diagnostics-reexport.rs:38:12 | LL | inner::uwu(); diff --git a/tests/ui/cfg/diagnostics-same-crate.stderr b/tests/ui/cfg/diagnostics-same-crate.stderr index f215738469249..f98fdcf4b61c3 100644 --- a/tests/ui/cfg/diagnostics-same-crate.stderr +++ b/tests/ui/cfg/diagnostics-same-crate.stderr @@ -34,7 +34,7 @@ note: found an item that was configured out LL | pub mod doesnt_exist { | ^^^^^^^^^^^^ -error[E0425]: cannot find function `uwu` +error[E0425]: cannot find function `uwu` in module `inner` --> $DIR/diagnostics-same-crate.rs:47:12 | LL | inner::uwu(); @@ -46,7 +46,7 @@ note: found an item that was configured out LL | pub fn uwu() {} | ^^^ -error[E0425]: cannot find function `meow` +error[E0425]: cannot find function `meow` in module `inner::right` --> $DIR/diagnostics-same-crate.rs:56:19 | LL | inner::right::meow(); @@ -59,13 +59,13 @@ LL | pub fn meow() {} | ^^^^ = note: the item is gated behind the `what-a-cool-feature` feature -error[E0425]: cannot find function `uwu` +error[E0425]: cannot find function `uwu` in this scope --> $DIR/diagnostics-same-crate.rs:43:5 | LL | uwu(); | ^^^ not found in this scope -error[E0425]: cannot find function `vanished` +error[E0425]: cannot find function `vanished` in this scope --> $DIR/diagnostics-same-crate.rs:63:5 | LL | vanished(); diff --git a/tests/ui/closures/issue-78720.stderr b/tests/ui/closures/issue-78720.stderr index 09b115b07e153..5d65c87b0fd61 100644 --- a/tests/ui/closures/issue-78720.stderr +++ b/tests/ui/closures/issue-78720.stderr @@ -4,7 +4,7 @@ error: at least one trait must be specified LL | fn server() -> impl { | ^^^^ -error[E0412]: cannot find type `F` +error[E0412]: cannot find type `F` in this scope --> $DIR/issue-78720.rs:13:12 | LL | _func: F, diff --git a/tests/ui/closures/issue-90871.stderr b/tests/ui/closures/issue-90871.stderr index 4a607b5b66a84..ef1cb213f73be 100644 --- a/tests/ui/closures/issue-90871.stderr +++ b/tests/ui/closures/issue-90871.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `n` +error[E0412]: cannot find type `n` in this scope --> $DIR/issue-90871.rs:4:22 | LL | type_ascribe!(2, n([u8; || 1])) diff --git a/tests/ui/codemap_tests/tab.stderr b/tests/ui/codemap_tests/tab.stderr index 51f68358873d5..d2de7486557f7 100644 --- a/tests/ui/codemap_tests/tab.stderr +++ b/tests/ui/codemap_tests/tab.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `bar` +error[E0425]: cannot find value `bar` in this scope --> $DIR/tab.rs:4:2 | LL | bar; diff --git a/tests/ui/codemap_tests/unicode_2.stderr b/tests/ui/codemap_tests/unicode_2.stderr index c0acaa95d2127..19aae1d3c9511 100644 --- a/tests/ui/codemap_tests/unicode_2.stderr +++ b/tests/ui/codemap_tests/unicode_2.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `a̐é` +error[E0425]: cannot find value `a̐é` in this scope --> $DIR/unicode_2.rs:4:13 | LL | let _ = a̐é; diff --git a/tests/ui/coercion/type-errors.stderr b/tests/ui/coercion/type-errors.stderr index dd0fe6a5660af..14deb785f75aa 100644 --- a/tests/ui/coercion/type-errors.stderr +++ b/tests/ui/coercion/type-errors.stderr @@ -1,16 +1,16 @@ -error[E0412]: cannot find type `TypeError` +error[E0412]: cannot find type `TypeError` in this scope --> $DIR/type-errors.rs:5:23 | LL | pub fn has_error() -> TypeError {} | ^^^^^^^^^ not found in this scope -error[E0412]: cannot find type `TypeError` +error[E0412]: cannot find type `TypeError` in this scope --> $DIR/type-errors.rs:18:29 | LL | pub fn autoderef_source(e: &TypeError) { | ^^^^^^^^^ not found in this scope -error[E0412]: cannot find type `TypeError` +error[E0412]: cannot find type `TypeError` in this scope --> $DIR/type-errors.rs:23:29 | LL | pub fn autoderef_target(_: &TypeError) {} diff --git a/tests/ui/coherence/coherence-error-suppression.stderr b/tests/ui/coherence/coherence-error-suppression.stderr index 0e96bee2e9ba5..fcaa510c632a8 100644 --- a/tests/ui/coherence/coherence-error-suppression.stderr +++ b/tests/ui/coherence/coherence-error-suppression.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `DoesNotExist` +error[E0412]: cannot find type `DoesNotExist` in this scope --> $DIR/coherence-error-suppression.rs:9:14 | LL | impl Foo for DoesNotExist {} diff --git a/tests/ui/coherence/illegal-copy-bad-projection.stderr b/tests/ui/coherence/illegal-copy-bad-projection.stderr index be778e6f488bd..2a74cb5a9b8b1 100644 --- a/tests/ui/coherence/illegal-copy-bad-projection.stderr +++ b/tests/ui/coherence/illegal-copy-bad-projection.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `void` +error[E0412]: cannot find type `void` in this scope --> $DIR/illegal-copy-bad-projection.rs:6:23 | LL | type Ptr = *const void; diff --git a/tests/ui/compiletest-self-test/ui-testing-optout.stderr b/tests/ui/compiletest-self-test/ui-testing-optout.stderr index e789b56f5f7ae..652c472c0bcfe 100644 --- a/tests/ui/compiletest-self-test/ui-testing-optout.stderr +++ b/tests/ui/compiletest-self-test/ui-testing-optout.stderr @@ -1,10 +1,10 @@ -error[E0412]: cannot find type `B` +error[E0412]: cannot find type `B` in this scope --> $DIR/ui-testing-optout.rs:4:10 | 4 | type A = B; | ^ not found in this scope -error[E0412]: cannot find type `D` +error[E0412]: cannot find type `D` in this scope --> $DIR/ui-testing-optout.rs:7:10 | 4 | type A = B; @@ -13,7 +13,7 @@ error[E0412]: cannot find type `D` 7 | type C = D; | ^ help: a type alias with a similar name exists: `A` -error[E0412]: cannot find type `F` +error[E0412]: cannot find type `F` in this scope --> $DIR/ui-testing-optout.rs:92:10 | 4 | type A = B; diff --git a/tests/ui/conditional-compilation/cfg-attr-unknown-attribute-macro-expansion.stderr b/tests/ui/conditional-compilation/cfg-attr-unknown-attribute-macro-expansion.stderr index 13909c9e2faf9..775349f8fb11c 100644 --- a/tests/ui/conditional-compilation/cfg-attr-unknown-attribute-macro-expansion.stderr +++ b/tests/ui/conditional-compilation/cfg-attr-unknown-attribute-macro-expansion.stderr @@ -1,4 +1,4 @@ -error: cannot find attribute `unknown` +error: cannot find attribute `unknown` in this scope --> $DIR/cfg-attr-unknown-attribute-macro-expansion.rs:3:27 | LL | #[cfg_attr(all(), unknown)] diff --git a/tests/ui/conditional-compilation/cfg-generic-params.stderr b/tests/ui/conditional-compilation/cfg-generic-params.stderr index 8d8c9548c009e..7ddfb445f7324 100644 --- a/tests/ui/conditional-compilation/cfg-generic-params.stderr +++ b/tests/ui/conditional-compilation/cfg-generic-params.stderr @@ -1,28 +1,28 @@ -error: cannot find attribute `unknown` +error: cannot find attribute `unknown` in this scope --> $DIR/cfg-generic-params.rs:19:29 | LL | fn f_lt_yes<#[cfg_attr(yes, unknown)] 'a>() {} | ^^^^^^^ not found in this scope -error: cannot find attribute `unknown` +error: cannot find attribute `unknown` in this scope --> $DIR/cfg-generic-params.rs:22:29 | LL | fn f_ty_yes<#[cfg_attr(yes, unknown)] T>() {} | ^^^^^^^ not found in this scope -error: cannot find attribute `unknown` +error: cannot find attribute `unknown` in this scope --> $DIR/cfg-generic-params.rs:26:34 | LL | type FnYes = for<#[cfg_attr(yes, unknown)] 'a> fn(); | ^^^^^^^ not found in this scope -error: cannot find attribute `unknown` +error: cannot find attribute `unknown` in this scope --> $DIR/cfg-generic-params.rs:30:40 | LL | type PolyYes = dyn for<#[cfg_attr(yes, unknown)] 'a> Copy; | ^^^^^^^ not found in this scope -error: cannot find attribute `unknown` +error: cannot find attribute `unknown` in this scope --> $DIR/cfg-generic-params.rs:34:43 | LL | struct WhereYes where for<#[cfg_attr(yes, unknown)] 'a> u8: Copy; diff --git a/tests/ui/conditional-compilation/cfg_accessible.stderr b/tests/ui/conditional-compilation/cfg_accessible.stderr index a2a7b1a9f66e9..e3731a1ad7128 100644 --- a/tests/ui/conditional-compilation/cfg_accessible.stderr +++ b/tests/ui/conditional-compilation/cfg_accessible.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `ExistingPrivate` +error[E0425]: cannot find value `ExistingPrivate` in this scope --> $DIR/cfg_accessible.rs:52:5 | LL | ExistingPrivate; @@ -10,13 +10,13 @@ note: unit struct `m::ExistingPrivate` exists but is inaccessible LL | struct ExistingPrivate; | ^^^^^^^^^^^^^^^^^^^^^^^ not accessible -error[E0425]: cannot find value `NonExistingPrivate` +error[E0425]: cannot find value `NonExistingPrivate` in this scope --> $DIR/cfg_accessible.rs:53:5 | LL | NonExistingPrivate; | ^^^^^^^^^^^^^^^^^^ not found in this scope -error[E0425]: cannot find value `NonExistingTraitAlias` +error[E0425]: cannot find value `NonExistingTraitAlias` in this scope --> $DIR/cfg_accessible.rs:54:5 | LL | NonExistingTraitAlias; diff --git a/tests/ui/conditional-compilation/test-cfg.stderr b/tests/ui/conditional-compilation/test-cfg.stderr index 62bca67db729f..9715f16acc20c 100644 --- a/tests/ui/conditional-compilation/test-cfg.stderr +++ b/tests/ui/conditional-compilation/test-cfg.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find function `foo` +error[E0425]: cannot find function `foo` in this scope --> $DIR/test-cfg.rs:7:5 | LL | foo(); diff --git a/tests/ui/const-generics/early/invalid-const-arguments.stderr b/tests/ui/const-generics/early/invalid-const-arguments.stderr index 3472a4c40ca48..cee34e3b71593 100644 --- a/tests/ui/const-generics/early/invalid-const-arguments.stderr +++ b/tests/ui/const-generics/early/invalid-const-arguments.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `N` +error[E0412]: cannot find type `N` in this scope --> $DIR/invalid-const-arguments.rs:5:16 | LL | struct A; @@ -16,7 +16,7 @@ help: you might be missing a type parameter LL | impl Foo for A {} | +++ -error[E0412]: cannot find type `T` +error[E0412]: cannot find type `T` in this scope --> $DIR/invalid-const-arguments.rs:14:32 | LL | struct A; diff --git a/tests/ui/const-generics/generic_const_exprs/error_in_ty.stderr b/tests/ui/const-generics/generic_const_exprs/error_in_ty.stderr index 45fd2e1121db8..0e40255bcf59b 100644 --- a/tests/ui/const-generics/generic_const_exprs/error_in_ty.stderr +++ b/tests/ui/const-generics/generic_const_exprs/error_in_ty.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `x` +error[E0425]: cannot find value `x` in this scope --> $DIR/error_in_ty.rs:6:31 | LL | pub struct A {} diff --git a/tests/ui/const-generics/generic_const_exprs/expected-type-of-closure-body-to-be-a-closure-or-coroutine-ice-113776.stderr b/tests/ui/const-generics/generic_const_exprs/expected-type-of-closure-body-to-be-a-closure-or-coroutine-ice-113776.stderr index a7633068d2973..416a938112424 100644 --- a/tests/ui/const-generics/generic_const_exprs/expected-type-of-closure-body-to-be-a-closure-or-coroutine-ice-113776.stderr +++ b/tests/ui/const-generics/generic_const_exprs/expected-type-of-closure-body-to-be-a-closure-or-coroutine-ice-113776.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `F` +error[E0412]: cannot find type `F` in this scope --> $DIR/expected-type-of-closure-body-to-be-a-closure-or-coroutine-ice-113776.rs:11:17 | LL | let f: F = async { 1 }; diff --git a/tests/ui/const-generics/generic_const_exprs/ice-predicates-of-no-entry-found-for-key-119275.stderr b/tests/ui/const-generics/generic_const_exprs/ice-predicates-of-no-entry-found-for-key-119275.stderr index 7a2a5ade7fea1..ee0ec38ab0631 100644 --- a/tests/ui/const-generics/generic_const_exprs/ice-predicates-of-no-entry-found-for-key-119275.stderr +++ b/tests/ui/const-generics/generic_const_exprs/ice-predicates-of-no-entry-found-for-key-119275.stderr @@ -6,7 +6,7 @@ LL | fn bug(&self) | = note: associated functions are those in `impl` or `trait` definitions -error[E0412]: cannot find type `Nat` +error[E0412]: cannot find type `Nat` in this scope --> $DIR/ice-predicates-of-no-entry-found-for-key-119275.rs:6:17 | LL | fn bug(&self) diff --git a/tests/ui/const-generics/generic_const_exprs/issue-109141.stderr b/tests/ui/const-generics/generic_const_exprs/issue-109141.stderr index 0068873f08721..7a9572d000d5a 100644 --- a/tests/ui/const-generics/generic_const_exprs/issue-109141.stderr +++ b/tests/ui/const-generics/generic_const_exprs/issue-109141.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `HashesEntryLEN` +error[E0425]: cannot find value `HashesEntryLEN` in this scope --> $DIR/issue-109141.rs:11:32 | LL | struct EntriesBuffer(Box<[[u8; HashesEntryLEN]; 5]>); diff --git a/tests/ui/const-generics/generic_const_exprs/unevaluated-const-ice-119731.stderr b/tests/ui/const-generics/generic_const_exprs/unevaluated-const-ice-119731.stderr index dfba4fab25874..39f022fbee9db 100644 --- a/tests/ui/const-generics/generic_const_exprs/unevaluated-const-ice-119731.stderr +++ b/tests/ui/const-generics/generic_const_exprs/unevaluated-const-ice-119731.stderr @@ -7,13 +7,13 @@ LL | pub use v20::{v13, v17}; | no `v13` in `v20` | help: a similar name exists in the module: `v11` -error[E0425]: cannot find value `v8` +error[E0425]: cannot find value `v8` in this scope --> $DIR/unevaluated-const-ice-119731.rs:13:38 | LL | const v0: [[usize; v4]; v4] = v6(v8); | ^^ not found in this scope -error[E0412]: cannot find type `v18` +error[E0412]: cannot find type `v18` in this scope --> $DIR/unevaluated-const-ice-119731.rs:23:31 | LL | pub type v11 = [[usize; v4]; v4]; @@ -22,7 +22,7 @@ LL | pub type v11 = [[usize; v4]; v4]; LL | pub const fn v21() -> v18 {} | ^^^ help: a type alias with a similar name exists: `v11` -error[E0412]: cannot find type `v18` +error[E0412]: cannot find type `v18` in this scope --> $DIR/unevaluated-const-ice-119731.rs:30:31 | LL | pub type v11 = [[usize; v4]; v4]; @@ -31,7 +31,7 @@ LL | pub type v11 = [[usize; v4]; v4]; LL | pub const fn v21() -> v18 { | ^^^ help: a type alias with a similar name exists: `v11` -error[E0422]: cannot find struct, variant or union type `v18` +error[E0422]: cannot find struct, variant or union type `v18` in this scope --> $DIR/unevaluated-const-ice-119731.rs:32:13 | LL | pub type v11 = [[usize; v4]; v4]; @@ -54,7 +54,7 @@ warning: type `v17` should have an upper camel case name LL | pub struct v17 { | ^^^ help: convert the identifier to upper camel case (notice the capitalization): `V17` -error[E0425]: cannot find function `v6` +error[E0425]: cannot find function `v6` in this scope --> $DIR/unevaluated-const-ice-119731.rs:13:35 | LL | const v0: [[usize; v4]; v4] = v6(v8); diff --git a/tests/ui/const-generics/not_wf_param_in_rpitit.stderr b/tests/ui/const-generics/not_wf_param_in_rpitit.stderr index d15c244ae5120..9095948d22b8a 100644 --- a/tests/ui/const-generics/not_wf_param_in_rpitit.stderr +++ b/tests/ui/const-generics/not_wf_param_in_rpitit.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `bar` +error[E0425]: cannot find value `bar` in this scope --> $DIR/not_wf_param_in_rpitit.rs:3:30 | LL | trait Trait { diff --git a/tests/ui/const-generics/type_not_in_scope.stderr b/tests/ui/const-generics/type_not_in_scope.stderr index 55fa5b9cfc365..5f45550a62796 100644 --- a/tests/ui/const-generics/type_not_in_scope.stderr +++ b/tests/ui/const-generics/type_not_in_scope.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `X` +error[E0412]: cannot find type `X` in this scope --> $DIR/type_not_in_scope.rs:1:6 | LL | impl X { diff --git a/tests/ui/const-generics/unknown_adt.stderr b/tests/ui/const-generics/unknown_adt.stderr index d27314275c591..2e8210772e94a 100644 --- a/tests/ui/const-generics/unknown_adt.stderr +++ b/tests/ui/const-generics/unknown_adt.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `UnknownStruct` +error[E0412]: cannot find type `UnknownStruct` in this scope --> $DIR/unknown_adt.rs:2:12 | LL | let _: UnknownStruct<7>; diff --git a/tests/ui/const_prop/ice-type-mismatch-when-copying-112824.stderr b/tests/ui/const_prop/ice-type-mismatch-when-copying-112824.stderr index 9d2cd64fb5a66..9442eac0cf54a 100644 --- a/tests/ui/const_prop/ice-type-mismatch-when-copying-112824.stderr +++ b/tests/ui/const_prop/ice-type-mismatch-when-copying-112824.stderr @@ -6,7 +6,7 @@ LL | pub struct Opcode2(&'a S); | | | help: consider introducing lifetime `'a` here: `<'a>` -error[E0412]: cannot find type `S` +error[E0412]: cannot find type `S` in this scope --> $DIR/ice-type-mismatch-when-copying-112824.rs:5:24 | LL | pub struct Opcode2(&'a S); diff --git a/tests/ui/consts/const-eval/ice-unhandled-type-122191.stderr b/tests/ui/consts/const-eval/ice-unhandled-type-122191.stderr index fcba6c45a35e4..daf0ccaa776ca 100644 --- a/tests/ui/consts/const-eval/ice-unhandled-type-122191.stderr +++ b/tests/ui/consts/const-eval/ice-unhandled-type-122191.stderr @@ -8,7 +8,7 @@ LL | type Foo = impl Send; = help: add `#![feature(type_alias_impl_trait)]` 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[E0425]: cannot find function `value` +error[E0425]: cannot find function `value` in this scope --> $DIR/ice-unhandled-type-122191.rs:6:20 | LL | const VALUE: Foo = value(); diff --git a/tests/ui/consts/erroneous_type_in_const_return_value.stderr b/tests/ui/consts/erroneous_type_in_const_return_value.stderr index 390c8e5151ad9..453f5b640973f 100644 --- a/tests/ui/consts/erroneous_type_in_const_return_value.stderr +++ b/tests/ui/consts/erroneous_type_in_const_return_value.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `Sum` +error[E0412]: cannot find type `Sum` in this scope --> $DIR/erroneous_type_in_const_return_value.rs:6:22 | LL | UnusedByTheConst(Sum), diff --git a/tests/ui/consts/erroneous_type_in_promoted.stderr b/tests/ui/consts/erroneous_type_in_promoted.stderr index f70404b2f5797..0601fc9ebe7fb 100644 --- a/tests/ui/consts/erroneous_type_in_promoted.stderr +++ b/tests/ui/consts/erroneous_type_in_promoted.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `Sum` +error[E0412]: cannot find type `Sum` in this scope --> $DIR/erroneous_type_in_promoted.rs:6:22 | LL | UnusedByTheConst(Sum), diff --git a/tests/ui/consts/ice-bad-input-type-for-cast-83056.stderr b/tests/ui/consts/ice-bad-input-type-for-cast-83056.stderr index 374bf6cc8d8a5..115f168852058 100644 --- a/tests/ui/consts/ice-bad-input-type-for-cast-83056.stderr +++ b/tests/ui/consts/ice-bad-input-type-for-cast-83056.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `T` +error[E0412]: cannot find type `T` in this scope --> $DIR/ice-bad-input-type-for-cast-83056.rs:5:11 | LL | struct S([bool; f as usize]); diff --git a/tests/ui/consts/issue-104609.stderr b/tests/ui/consts/issue-104609.stderr index 408c0c242a7fd..fe84d83725fd2 100644 --- a/tests/ui/consts/issue-104609.stderr +++ b/tests/ui/consts/issue-104609.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `oops` +error[E0425]: cannot find value `oops` in this scope --> $DIR/issue-104609.rs:2:5 | LL | oops; diff --git a/tests/ui/consts/issue-116186.stderr b/tests/ui/consts/issue-116186.stderr index 2e8c2dc4d3d78..e6eae2d9f55ef 100644 --- a/tests/ui/consts/issue-116186.stderr +++ b/tests/ui/consts/issue-116186.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `N` +error[E0425]: cannot find value `N` in this scope --> $DIR/issue-116186.rs:4:28 | LL | fn something(path: [usize; N]) -> impl Clone { diff --git a/tests/ui/consts/issue-90878-2.stderr b/tests/ui/consts/issue-90878-2.stderr index af6d48d215f3b..20e3b50baae8d 100644 --- a/tests/ui/consts/issue-90878-2.stderr +++ b/tests/ui/consts/issue-90878-2.stderr @@ -4,7 +4,7 @@ error: attribute value must be a literal LL | #![l=|x|[b;x ]] | ^^^^^^^^^ -error: cannot find attribute `l` +error: cannot find attribute `l` in this scope --> $DIR/issue-90878-2.rs:1:5 | LL | #![l=|x|[b;x ]] diff --git a/tests/ui/consts/issue-91434.rs b/tests/ui/consts/issue-91434.rs index 9131b16ec4df5..da515adea6a09 100644 --- a/tests/ui/consts/issue-91434.rs +++ b/tests/ui/consts/issue-91434.rs @@ -1,5 +1,5 @@ fn main() { [9; [[9E; h]]]; //~^ ERROR: expected at least one digit in exponent - //~| ERROR: cannot find value `h` [E0425] + //~| ERROR: cannot find value `h` } diff --git a/tests/ui/consts/issue-91434.stderr b/tests/ui/consts/issue-91434.stderr index 3123a12e77cb6..08d3ad77053d5 100644 --- a/tests/ui/consts/issue-91434.stderr +++ b/tests/ui/consts/issue-91434.stderr @@ -4,7 +4,7 @@ error: expected at least one digit in exponent LL | [9; [[9E; h]]]; | ^^ -error[E0425]: cannot find value `h` +error[E0425]: cannot find value `h` in this scope --> $DIR/issue-91434.rs:2:15 | LL | [9; [[9E; h]]]; diff --git a/tests/ui/coroutine/gen_block.none.stderr b/tests/ui/coroutine/gen_block.none.stderr index 781434ad05ab9..64fa2be003de5 100644 --- a/tests/ui/coroutine/gen_block.none.stderr +++ b/tests/ui/coroutine/gen_block.none.stderr @@ -6,19 +6,19 @@ LL | let y = gen { yield 42 }; | | | while parsing this struct -error[E0422]: cannot find struct, variant or union type `gen` +error[E0422]: cannot find struct, variant or union type `gen` in this scope --> $DIR/gen_block.rs:7:13 | LL | let x = gen {}; | ^^^ not found in this scope -error[E0422]: cannot find struct, variant or union type `gen` +error[E0422]: cannot find struct, variant or union type `gen` in this scope --> $DIR/gen_block.rs:10:13 | LL | let y = gen { yield 42 }; | ^^^ not found in this scope -error[E0422]: cannot find struct, variant or union type `gen` +error[E0422]: cannot find struct, variant or union type `gen` in this scope --> $DIR/gen_block.rs:13:5 | LL | gen {}; diff --git a/tests/ui/coroutine/layout-error.stderr b/tests/ui/coroutine/layout-error.stderr index bb7d32d3ea025..ceadb62c99988 100644 --- a/tests/ui/coroutine/layout-error.stderr +++ b/tests/ui/coroutine/layout-error.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `Foo` +error[E0425]: cannot find value `Foo` in this scope --> $DIR/layout-error.rs:27:21 | LL | let a = Foo; diff --git a/tests/ui/custom_attribute.stderr b/tests/ui/custom_attribute.stderr index 9e6a5dde6c7fd..ba29951323862 100644 --- a/tests/ui/custom_attribute.stderr +++ b/tests/ui/custom_attribute.stderr @@ -1,16 +1,16 @@ -error: cannot find attribute `foo` +error: cannot find attribute `foo` in this scope --> $DIR/custom_attribute.rs:3:3 | LL | #[foo] | ^^^ not found in this scope -error: cannot find attribute `foo` +error: cannot find attribute `foo` in this scope --> $DIR/custom_attribute.rs:5:7 | LL | #[foo] | ^^^ not found in this scope -error: cannot find attribute `foo` +error: cannot find attribute `foo` in this scope --> $DIR/custom_attribute.rs:7:7 | LL | #[foo] diff --git a/tests/ui/deduplicate-diagnostics.deduplicate.stderr b/tests/ui/deduplicate-diagnostics.deduplicate.stderr index ed897b2023e1c..f441c71771507 100644 --- a/tests/ui/deduplicate-diagnostics.deduplicate.stderr +++ b/tests/ui/deduplicate-diagnostics.deduplicate.stderr @@ -4,7 +4,7 @@ error[E0452]: malformed lint attribute input LL | #[deny("literal")] | ^^^^^^^^^ bad attribute argument -error: cannot find derive macro `Unresolved` +error: cannot find derive macro `Unresolved` in this scope --> $DIR/deduplicate-diagnostics.rs:4:10 | LL | #[derive(Unresolved)] diff --git a/tests/ui/deduplicate-diagnostics.duplicate.stderr b/tests/ui/deduplicate-diagnostics.duplicate.stderr index 69e9f606b4967..69217fa810bd6 100644 --- a/tests/ui/deduplicate-diagnostics.duplicate.stderr +++ b/tests/ui/deduplicate-diagnostics.duplicate.stderr @@ -4,13 +4,13 @@ error[E0452]: malformed lint attribute input LL | #[deny("literal")] | ^^^^^^^^^ bad attribute argument -error: cannot find derive macro `Unresolved` +error: cannot find derive macro `Unresolved` in this scope --> $DIR/deduplicate-diagnostics.rs:4:10 | LL | #[derive(Unresolved)] | ^^^^^^^^^^ not found in this scope -error: cannot find derive macro `Unresolved` +error: cannot find derive macro `Unresolved` in this scope --> $DIR/deduplicate-diagnostics.rs:4:10 | LL | #[derive(Unresolved)] diff --git a/tests/ui/delegation/bad-resolve.stderr b/tests/ui/delegation/bad-resolve.stderr index 8dd883e68be2c..883ff523bcfea 100644 --- a/tests/ui/delegation/bad-resolve.stderr +++ b/tests/ui/delegation/bad-resolve.stderr @@ -39,7 +39,7 @@ LL | reuse ::Type; | = note: can't use a type alias as a constructor -error[E0576]: cannot find method or associated constant `baz` +error[E0576]: cannot find method or associated constant `baz` in trait `Trait` --> $DIR/bad-resolve.rs:30:25 | LL | fn bar() {} @@ -48,7 +48,7 @@ LL | fn bar() {} LL | reuse ::baz; | ^^^ help: an associated function with a similar name exists: `bar` -error[E0425]: cannot find function `foo` +error[E0425]: cannot find function `foo` in this scope --> $DIR/bad-resolve.rs:35:11 | LL | reuse foo { &self.0 } diff --git a/tests/ui/delegation/explicit-paths.stderr b/tests/ui/delegation/explicit-paths.stderr index 833c6d5974175..d33c5da4377b1 100644 --- a/tests/ui/delegation/explicit-paths.stderr +++ b/tests/ui/delegation/explicit-paths.stderr @@ -16,13 +16,13 @@ LL | reuse F::foo4 { &self.0 } | | help: there is an associated function with a similar name: `foo1` | not a member of trait `Trait` -error[E0425]: cannot find function `foo4` +error[E0425]: cannot find function `foo4` in `S` --> $DIR/explicit-paths.rs:29:14 | LL | reuse S::foo4; | ^^^^ not found in `S` -error[E0425]: cannot find function `foo4` +error[E0425]: cannot find function `foo4` in `F` --> $DIR/explicit-paths.rs:40:18 | LL | reuse F::foo4 { &self.0 } @@ -34,7 +34,7 @@ note: function `fn_to_other::foo4` exists but is inaccessible LL | reuse S::foo4; | ^^^^^^^^^^^^^^ not accessible -error[E0425]: cannot find function `foo4` +error[E0425]: cannot find function `foo4` in `F` --> $DIR/explicit-paths.rs:53:18 | LL | reuse F::foo4 { &self.0 } @@ -46,7 +46,7 @@ note: function `fn_to_other::foo4` exists but is inaccessible LL | reuse S::foo4; | ^^^^^^^^^^^^^^ not accessible -error[E0425]: cannot find function `foo4` +error[E0425]: cannot find function `foo4` in `F` --> $DIR/explicit-paths.rs:67:18 | LL | reuse F::foo4 { &F } diff --git a/tests/ui/delegation/ice-issue-124342.stderr b/tests/ui/delegation/ice-issue-124342.stderr index d6cd20827be64..a53739676cfc3 100644 --- a/tests/ui/delegation/ice-issue-124342.stderr +++ b/tests/ui/delegation/ice-issue-124342.stderr @@ -1,10 +1,10 @@ -error[E0425]: cannot find function `foo` +error[E0425]: cannot find function `foo` in module `to_reuse` --> $DIR/ice-issue-124342.rs:7:21 | LL | reuse to_reuse::foo { foo } | ^^^ not found in module `to_reuse` -error[E0425]: cannot find value `foo` +error[E0425]: cannot find value `foo` in this scope --> $DIR/ice-issue-124342.rs:7:27 | LL | reuse to_reuse::foo { foo } diff --git a/tests/ui/delegation/target-expr.stderr b/tests/ui/delegation/target-expr.stderr index f5858d99620a7..b30f0c474c68b 100644 --- a/tests/ui/delegation/target-expr.stderr +++ b/tests/ui/delegation/target-expr.stderr @@ -26,7 +26,7 @@ LL | fn main() { LL | self.0; | ^^^^ `self` value is a keyword only available in methods with a `self` parameter -error[E0425]: cannot find value `x` +error[E0425]: cannot find value `x` in this scope --> $DIR/target-expr.rs:38:13 | LL | let z = x; diff --git a/tests/ui/derived-errors/issue-31997.stderr b/tests/ui/derived-errors/issue-31997.stderr index 0c765fad72b40..7d6415fef83c1 100644 --- a/tests/ui/derived-errors/issue-31997.stderr +++ b/tests/ui/derived-errors/issue-31997.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find function `bar` +error[E0425]: cannot find function `bar` in this scope --> $DIR/issue-31997.rs:14:21 | LL | try!(closure(|| bar(core::ptr::null_mut()))); diff --git a/tests/ui/derives/deriving-bounds.stderr b/tests/ui/derives/deriving-bounds.stderr index 09b8cb4339356..f3ddbffe4f55e 100644 --- a/tests/ui/derives/deriving-bounds.stderr +++ b/tests/ui/derives/deriving-bounds.stderr @@ -1,4 +1,4 @@ -error: cannot find derive macro `Sync` +error: cannot find derive macro `Sync` in this scope --> $DIR/deriving-bounds.rs:6:10 | LL | #[derive(Sync)] @@ -10,7 +10,7 @@ note: unsafe traits like `Sync` should be implemented explicitly LL | #[derive(Sync)] | ^^^^ -error: cannot find derive macro `Sync` +error: cannot find derive macro `Sync` in this scope --> $DIR/deriving-bounds.rs:6:10 | LL | #[derive(Sync)] @@ -23,7 +23,7 @@ LL | #[derive(Sync)] | ^^^^ = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error: cannot find derive macro `Send` +error: cannot find derive macro `Send` in this scope --> $DIR/deriving-bounds.rs:1:10 | LL | #[derive(Send)] @@ -35,7 +35,7 @@ note: unsafe traits like `Send` should be implemented explicitly LL | #[derive(Send)] | ^^^^ -error: cannot find derive macro `Send` +error: cannot find derive macro `Send` in this scope --> $DIR/deriving-bounds.rs:1:10 | LL | #[derive(Send)] diff --git a/tests/ui/derives/deriving-meta-unknown-trait.stderr b/tests/ui/derives/deriving-meta-unknown-trait.stderr index bd00c3b01cf15..77fcacaa7a206 100644 --- a/tests/ui/derives/deriving-meta-unknown-trait.stderr +++ b/tests/ui/derives/deriving-meta-unknown-trait.stderr @@ -1,4 +1,4 @@ -error: cannot find derive macro `Eqr` +error: cannot find derive macro `Eqr` in this scope --> $DIR/deriving-meta-unknown-trait.rs:1:10 | LL | #[derive(Eqr)] @@ -10,7 +10,7 @@ LL | #[derive(Eqr)] | = note: similarly named derive macro `Eq` defined here -error: cannot find derive macro `Eqr` +error: cannot find derive macro `Eqr` in this scope --> $DIR/deriving-meta-unknown-trait.rs:1:10 | LL | #[derive(Eqr)] diff --git a/tests/ui/derives/deriving-primitive.stderr b/tests/ui/derives/deriving-primitive.stderr index 1c5e75199c1d5..27a13f517daf9 100644 --- a/tests/ui/derives/deriving-primitive.stderr +++ b/tests/ui/derives/deriving-primitive.stderr @@ -1,10 +1,10 @@ -error: cannot find derive macro `FromPrimitive` +error: cannot find derive macro `FromPrimitive` in this scope --> $DIR/deriving-primitive.rs:1:10 | LL | #[derive(FromPrimitive)] | ^^^^^^^^^^^^^ not found in this scope -error: cannot find derive macro `FromPrimitive` +error: cannot find derive macro `FromPrimitive` in this scope --> $DIR/deriving-primitive.rs:1:10 | LL | #[derive(FromPrimitive)] diff --git a/tests/ui/diagnostic_namespace/requires_path.stderr b/tests/ui/diagnostic_namespace/requires_path.stderr index abcf637a72027..7f7162a861135 100644 --- a/tests/ui/diagnostic_namespace/requires_path.stderr +++ b/tests/ui/diagnostic_namespace/requires_path.stderr @@ -1,4 +1,4 @@ -error: cannot find attribute `diagnostic` +error: cannot find attribute `diagnostic` in this scope --> $DIR/requires_path.rs:1:3 | LL | #[diagnostic] diff --git a/tests/ui/did_you_mean/issue-103909.stderr b/tests/ui/did_you_mean/issue-103909.stderr index a684a29ad62d9..8641017470ba0 100644 --- a/tests/ui/did_you_mean/issue-103909.stderr +++ b/tests/ui/did_you_mean/issue-103909.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `err` +error[E0425]: cannot find value `err` in this scope --> $DIR/issue-103909.rs:5:12 | LL | if Err(err) = File::open("hello.txt") { diff --git a/tests/ui/did_you_mean/issue-56028-there-is-an-enum-variant.stderr b/tests/ui/did_you_mean/issue-56028-there-is-an-enum-variant.stderr index 65990ec80c35b..b1a15b8594a0a 100644 --- a/tests/ui/did_you_mean/issue-56028-there-is-an-enum-variant.stderr +++ b/tests/ui/did_you_mean/issue-56028-there-is-an-enum-variant.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `Set` +error[E0412]: cannot find type `Set` in this scope --> $DIR/issue-56028-there-is-an-enum-variant.rs:9:15 | LL | fn setup() -> Set { Set } @@ -16,7 +16,7 @@ LL | fn setup() -> PutDown { Set } | ~~~~~~~ and 3 other candidates -error[E0425]: cannot find value `Set` +error[E0425]: cannot find value `Set` in this scope --> $DIR/issue-56028-there-is-an-enum-variant.rs:9:21 | LL | fn setup() -> Set { Set } diff --git a/tests/ui/did_you_mean/println-typo.stderr b/tests/ui/did_you_mean/println-typo.stderr index 54bc308bcae76..07fb577b3a4f8 100644 --- a/tests/ui/did_you_mean/println-typo.stderr +++ b/tests/ui/did_you_mean/println-typo.stderr @@ -1,4 +1,4 @@ -error: cannot find macro `prinltn` +error: cannot find macro `prinltn` in this scope --> $DIR/println-typo.rs:4:5 | LL | prinltn!(); diff --git a/tests/ui/dropck/drop-on-non-struct.stderr b/tests/ui/dropck/drop-on-non-struct.stderr index 06c7c6c0d75e4..e8fbe5e972642 100644 --- a/tests/ui/dropck/drop-on-non-struct.stderr +++ b/tests/ui/dropck/drop-on-non-struct.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `Nonexistent` +error[E0412]: cannot find type `Nonexistent` in this scope --> $DIR/drop-on-non-struct.rs:9:15 | LL | impl Drop for Nonexistent { diff --git a/tests/ui/editions/async-block-2015.stderr b/tests/ui/editions/async-block-2015.stderr index 93962ceff3e2b..b792b8c1e0dd8 100644 --- a/tests/ui/editions/async-block-2015.stderr +++ b/tests/ui/editions/async-block-2015.stderr @@ -29,7 +29,7 @@ LL | 42 = help: pass `--edition 2021` to `rustc` = note: for more on editions, read https://doc.rust-lang.org/edition-guide -error[E0422]: cannot find struct, variant or union type `async` +error[E0422]: cannot find struct, variant or union type `async` in this scope --> $DIR/async-block-2015.rs:7:13 | LL | let x = async {}; diff --git a/tests/ui/empty/empty-macro-use.stderr b/tests/ui/empty/empty-macro-use.stderr index 36cf6eb1ee926..b64236023cb63 100644 --- a/tests/ui/empty/empty-macro-use.stderr +++ b/tests/ui/empty/empty-macro-use.stderr @@ -1,4 +1,4 @@ -error: cannot find macro `macro_two` +error: cannot find macro `macro_two` in this scope --> $DIR/empty-macro-use.rs:7:5 | LL | macro_two!(); diff --git a/tests/ui/enum/suggest-default-attribute.stderr b/tests/ui/enum/suggest-default-attribute.stderr index d18f912354950..217d971a0cc9d 100644 --- a/tests/ui/enum/suggest-default-attribute.stderr +++ b/tests/ui/enum/suggest-default-attribute.stderr @@ -1,4 +1,4 @@ -error: cannot find attribute `default` +error: cannot find attribute `default` in this scope --> $DIR/suggest-default-attribute.rs:2:7 | LL | #[default] diff --git a/tests/ui/error-codes/E0405.stderr b/tests/ui/error-codes/E0405.stderr index f264ad58ec07a..1fb115c9e999b 100644 --- a/tests/ui/error-codes/E0405.stderr +++ b/tests/ui/error-codes/E0405.stderr @@ -1,4 +1,4 @@ -error[E0405]: cannot find trait `SomeTrait` +error[E0405]: cannot find trait `SomeTrait` in this scope --> $DIR/E0405.rs:3:6 | LL | impl SomeTrait for Foo {} diff --git a/tests/ui/error-codes/E0411.stderr b/tests/ui/error-codes/E0411.stderr index 3a2977d011d56..16da10348a28f 100644 --- a/tests/ui/error-codes/E0411.stderr +++ b/tests/ui/error-codes/E0411.stderr @@ -1,4 +1,4 @@ -error[E0411]: cannot find type `Self` +error[E0411]: cannot find type `Self` in this scope --> $DIR/E0411.rs:2:6 | LL | fn main() { diff --git a/tests/ui/error-codes/E0412.stderr b/tests/ui/error-codes/E0412.stderr index 105a36b30d316..7c1172642faff 100644 --- a/tests/ui/error-codes/E0412.stderr +++ b/tests/ui/error-codes/E0412.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `Something` +error[E0412]: cannot find type `Something` in this scope --> $DIR/E0412.rs:1:6 | LL | impl Something {} diff --git a/tests/ui/error-codes/E0425.stderr b/tests/ui/error-codes/E0425.stderr index fb21ca3302474..db78dc3f7abe3 100644 --- a/tests/ui/error-codes/E0425.stderr +++ b/tests/ui/error-codes/E0425.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `elf` +error[E0425]: cannot find value `elf` in this scope --> $DIR/E0425.rs:3:9 | LL | elf; diff --git a/tests/ui/error-festival.stderr b/tests/ui/error-festival.stderr index b0983fbb6bf88..9d75671c4e6b4 100644 --- a/tests/ui/error-festival.stderr +++ b/tests/ui/error-festival.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `y` +error[E0425]: cannot find value `y` in this scope --> $DIR/error-festival.rs:14:5 | LL | y = 2; diff --git a/tests/ui/errors/remap-path-prefix.normal.stderr b/tests/ui/errors/remap-path-prefix.normal.stderr index 32029becfa86e..46d33d26052cb 100644 --- a/tests/ui/errors/remap-path-prefix.normal.stderr +++ b/tests/ui/errors/remap-path-prefix.normal.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `ferris` +error[E0425]: cannot find value `ferris` in this scope --> remapped/errors/remap-path-prefix.rs:19:5 | LL | ferris diff --git a/tests/ui/errors/remap-path-prefix.with-diagnostic-scope.stderr b/tests/ui/errors/remap-path-prefix.with-diagnostic-scope.stderr index 32029becfa86e..46d33d26052cb 100644 --- a/tests/ui/errors/remap-path-prefix.with-diagnostic-scope.stderr +++ b/tests/ui/errors/remap-path-prefix.with-diagnostic-scope.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `ferris` +error[E0425]: cannot find value `ferris` in this scope --> remapped/errors/remap-path-prefix.rs:19:5 | LL | ferris diff --git a/tests/ui/errors/remap-path-prefix.without-diagnostic-scope.stderr b/tests/ui/errors/remap-path-prefix.without-diagnostic-scope.stderr index 02131f934d312..0badea6e27bf3 100644 --- a/tests/ui/errors/remap-path-prefix.without-diagnostic-scope.stderr +++ b/tests/ui/errors/remap-path-prefix.without-diagnostic-scope.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `ferris` +error[E0425]: cannot find value `ferris` in this scope --> $DIR/remap-path-prefix.rs:19:5 | LL | ferris diff --git a/tests/ui/expr/if/bad-if-let-suggestion.stderr b/tests/ui/expr/if/bad-if-let-suggestion.stderr index 0c9b53c2ce48d..0d1f895bd82bf 100644 --- a/tests/ui/expr/if/bad-if-let-suggestion.stderr +++ b/tests/ui/expr/if/bad-if-let-suggestion.stderr @@ -14,13 +14,13 @@ help: you might have meant to compare for equality LL | if let x = 1 && i == 2 {} | + -error[E0425]: cannot find value `i` +error[E0425]: cannot find value `i` in this scope --> $DIR/bad-if-let-suggestion.rs:2:21 | LL | if let x = 1 && i = 2 {} | ^ not found in this scope -error[E0425]: cannot find value `i` +error[E0425]: cannot find value `i` in this scope --> $DIR/bad-if-let-suggestion.rs:9:9 | LL | fn a() { @@ -29,7 +29,7 @@ LL | fn a() { LL | if (i + j) = i {} | ^ help: a function with a similar name exists: `a` -error[E0425]: cannot find value `j` +error[E0425]: cannot find value `j` in this scope --> $DIR/bad-if-let-suggestion.rs:9:13 | LL | fn a() { @@ -38,7 +38,7 @@ LL | fn a() { LL | if (i + j) = i {} | ^ help: a function with a similar name exists: `a` -error[E0425]: cannot find value `i` +error[E0425]: cannot find value `i` in this scope --> $DIR/bad-if-let-suggestion.rs:9:18 | LL | fn a() { @@ -47,7 +47,7 @@ LL | fn a() { LL | if (i + j) = i {} | ^ help: a function with a similar name exists: `a` -error[E0425]: cannot find value `x` +error[E0425]: cannot find value `x` in this scope --> $DIR/bad-if-let-suggestion.rs:16:8 | LL | fn a() { diff --git a/tests/ui/expr/malformed_closure/ruby_style_closure.stderr b/tests/ui/expr/malformed_closure/ruby_style_closure.stderr index deff78a926edc..b1607bbacc926 100644 --- a/tests/ui/expr/malformed_closure/ruby_style_closure.stderr +++ b/tests/ui/expr/malformed_closure/ruby_style_closure.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `x` +error[E0425]: cannot find value `x` in this scope --> $DIR/ruby_style_closure.rs:12:14 | LL | Some(x * 2) diff --git a/tests/ui/ext-nonexistent.stderr b/tests/ui/ext-nonexistent.stderr index fa2ebb1679893..3be17859b5e39 100644 --- a/tests/ui/ext-nonexistent.stderr +++ b/tests/ui/ext-nonexistent.stderr @@ -1,4 +1,4 @@ -error: cannot find macro `iamnotanextensionthatexists` +error: cannot find macro `iamnotanextensionthatexists` in this scope --> $DIR/ext-nonexistent.rs:2:13 | LL | fn main() { iamnotanextensionthatexists!(""); } diff --git a/tests/ui/extern/extern-with-type-bounds.stderr b/tests/ui/extern/extern-with-type-bounds.stderr index 266b67cabeb91..42448d9e9246d 100644 --- a/tests/ui/extern/extern-with-type-bounds.stderr +++ b/tests/ui/extern/extern-with-type-bounds.stderr @@ -1,4 +1,4 @@ -error[E0405]: cannot find trait `NoSuchTrait` +error[E0405]: cannot find trait `NoSuchTrait` in this scope --> $DIR/extern-with-type-bounds.rs:18:20 | LL | fn align_of() -> usize; diff --git a/tests/ui/extern/issue-112363-extern-item-where-clauses-debug-ice.stderr b/tests/ui/extern/issue-112363-extern-item-where-clauses-debug-ice.stderr index 3064d24c4462c..039e50b5e12da 100644 --- a/tests/ui/extern/issue-112363-extern-item-where-clauses-debug-ice.stderr +++ b/tests/ui/extern/issue-112363-extern-item-where-clauses-debug-ice.stderr @@ -20,13 +20,13 @@ LL | type Item = [T] where [T]: Sized; | = note: for more information, visit https://doc.rust-lang.org/std/keyword.extern.html -error[E0412]: cannot find type `T` +error[E0412]: cannot find type `T` in this scope --> $DIR/issue-112363-extern-item-where-clauses-debug-ice.rs:2:28 | LL | type Item = [T] where [T]: Sized; | ^ not found in this scope -error[E0412]: cannot find type `T` +error[E0412]: cannot find type `T` in this scope --> $DIR/issue-112363-extern-item-where-clauses-debug-ice.rs:2:18 | LL | type Item = [T] where [T]: Sized; diff --git a/tests/ui/extern/issue-80074.stderr b/tests/ui/extern/issue-80074.stderr index cf0c8e057d70d..8bdcb220e5b6f 100644 --- a/tests/ui/extern/issue-80074.stderr +++ b/tests/ui/extern/issue-80074.stderr @@ -4,13 +4,13 @@ error[E0469]: imported macro not found LL | #[macro_use(m)] | ^ -error: cannot find macro `bar` +error: cannot find macro `bar` in this scope --> $DIR/issue-80074.rs:16:5 | LL | bar!(); | ^^^ not found in this scope -error: cannot find macro `m` +error: cannot find macro `m` in this scope --> $DIR/issue-80074.rs:18:5 | LL | m!(); diff --git a/tests/ui/feature-gates/feature-gate-concat_idents2.stderr b/tests/ui/feature-gates/feature-gate-concat_idents2.stderr index 261b3661ac7a5..2fe786ff4063d 100644 --- a/tests/ui/feature-gates/feature-gate-concat_idents2.stderr +++ b/tests/ui/feature-gates/feature-gate-concat_idents2.stderr @@ -8,7 +8,7 @@ LL | concat_idents!(a, b); = help: add `#![feature(concat_idents)]` 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[E0425]: cannot find value `ab` +error[E0425]: cannot find value `ab` in this scope --> $DIR/feature-gate-concat_idents2.rs:2:5 | LL | concat_idents!(a, b); diff --git a/tests/ui/feature-gates/feature-gate-custom_attribute.stderr b/tests/ui/feature-gates/feature-gate-custom_attribute.stderr index dbedb8fed2600..9901dff87ec16 100644 --- a/tests/ui/feature-gates/feature-gate-custom_attribute.stderr +++ b/tests/ui/feature-gates/feature-gate-custom_attribute.stderr @@ -1,76 +1,76 @@ -error: cannot find attribute `fake_attr` +error: cannot find attribute `fake_attr` in this scope --> $DIR/feature-gate-custom_attribute.rs:3:3 | LL | #[fake_attr] | ^^^^^^^^^ not found in this scope -error: cannot find attribute `fake_attr` +error: cannot find attribute `fake_attr` in this scope --> $DIR/feature-gate-custom_attribute.rs:4:3 | LL | #[fake_attr(100)] | ^^^^^^^^^ not found in this scope -error: cannot find attribute `fake_attr` +error: cannot find attribute `fake_attr` in this scope --> $DIR/feature-gate-custom_attribute.rs:5:3 | LL | #[fake_attr(1, 2, 3)] | ^^^^^^^^^ not found in this scope -error: cannot find attribute `fake_attr` +error: cannot find attribute `fake_attr` in this scope --> $DIR/feature-gate-custom_attribute.rs:6:3 | LL | #[fake_attr("hello")] | ^^^^^^^^^ not found in this scope -error: cannot find attribute `fake_attr` +error: cannot find attribute `fake_attr` in this scope --> $DIR/feature-gate-custom_attribute.rs:7:3 | LL | #[fake_attr(name = "hello")] | ^^^^^^^^^ not found in this scope -error: cannot find attribute `fake_attr` +error: cannot find attribute `fake_attr` in this scope --> $DIR/feature-gate-custom_attribute.rs:8:3 | LL | #[fake_attr(1, "hi", key = 12, true, false)] | ^^^^^^^^^ not found in this scope -error: cannot find attribute `fake_attr` +error: cannot find attribute `fake_attr` in this scope --> $DIR/feature-gate-custom_attribute.rs:9:3 | LL | #[fake_attr(key = "hello", val = 10)] | ^^^^^^^^^ not found in this scope -error: cannot find attribute `fake_attr` +error: cannot find attribute `fake_attr` in this scope --> $DIR/feature-gate-custom_attribute.rs:10:3 | LL | #[fake_attr(key("hello"), val(10))] | ^^^^^^^^^ not found in this scope -error: cannot find attribute `fake_attr` +error: cannot find attribute `fake_attr` in this scope --> $DIR/feature-gate-custom_attribute.rs:11:3 | LL | #[fake_attr(enabled = true, disabled = false)] | ^^^^^^^^^ not found in this scope -error: cannot find attribute `fake_attr` +error: cannot find attribute `fake_attr` in this scope --> $DIR/feature-gate-custom_attribute.rs:12:3 | LL | #[fake_attr(true)] | ^^^^^^^^^ not found in this scope -error: cannot find attribute `fake_attr` +error: cannot find attribute `fake_attr` in this scope --> $DIR/feature-gate-custom_attribute.rs:13:3 | LL | #[fake_attr(pi = 3.14159)] | ^^^^^^^^^ not found in this scope -error: cannot find attribute `fake_attr` +error: cannot find attribute `fake_attr` in this scope --> $DIR/feature-gate-custom_attribute.rs:14:3 | LL | #[fake_attr(b"hi")] | ^^^^^^^^^ not found in this scope -error: cannot find attribute `fake_doc` +error: cannot find attribute `fake_doc` in this scope --> $DIR/feature-gate-custom_attribute.rs:15:3 | LL | #[fake_doc(r"doc")] diff --git a/tests/ui/feature-gates/feature-gate-custom_attribute2.stderr b/tests/ui/feature-gates/feature-gate-custom_attribute2.stderr index 703a5a43f39f2..64c2f5dcbd1e7 100644 --- a/tests/ui/feature-gates/feature-gate-custom_attribute2.stderr +++ b/tests/ui/feature-gates/feature-gate-custom_attribute2.stderr @@ -1,100 +1,100 @@ -error: cannot find attribute `lt_struct` +error: cannot find attribute `lt_struct` in this scope --> $DIR/feature-gate-custom_attribute2.rs:4:15 | LL | struct StLt<#[lt_struct] 'a>(&'a u32); | ^^^^^^^^^ not found in this scope -error: cannot find attribute `ty_struct` +error: cannot find attribute `ty_struct` in this scope --> $DIR/feature-gate-custom_attribute2.rs:6:15 | LL | struct StTy<#[ty_struct] I>(I); | ^^^^^^^^^ not found in this scope -error: cannot find attribute `lt_enum` +error: cannot find attribute `lt_enum` in this scope --> $DIR/feature-gate-custom_attribute2.rs:9:13 | LL | enum EnLt<#[lt_enum] 'b> { A(&'b u32), B } | ^^^^^^^ not found in this scope -error: cannot find attribute `ty_enum` +error: cannot find attribute `ty_enum` in this scope --> $DIR/feature-gate-custom_attribute2.rs:11:13 | LL | enum EnTy<#[ty_enum] J> { A(J), B } | ^^^^^^^ not found in this scope -error: cannot find attribute `lt_trait` +error: cannot find attribute `lt_trait` in this scope --> $DIR/feature-gate-custom_attribute2.rs:14:14 | LL | trait TrLt<#[lt_trait] 'c> { fn foo(&self, _: &'c [u32]) -> &'c u32; } | ^^^^^^^^ not found in this scope -error: cannot find attribute `ty_trait` +error: cannot find attribute `ty_trait` in this scope --> $DIR/feature-gate-custom_attribute2.rs:16:14 | LL | trait TrTy<#[ty_trait] K> { fn foo(&self, _: K); } | ^^^^^^^^ not found in this scope -error: cannot find attribute `lt_type` +error: cannot find attribute `lt_type` in this scope --> $DIR/feature-gate-custom_attribute2.rs:19:13 | LL | type TyLt<#[lt_type] 'd> = &'d u32; | ^^^^^^^ not found in this scope -error: cannot find attribute `ty_type` +error: cannot find attribute `ty_type` in this scope --> $DIR/feature-gate-custom_attribute2.rs:21:13 | LL | type TyTy<#[ty_type] L> = (L, ); | ^^^^^^^ not found in this scope -error: cannot find attribute `lt_inherent` +error: cannot find attribute `lt_inherent` in this scope --> $DIR/feature-gate-custom_attribute2.rs:24:8 | LL | impl<#[lt_inherent] 'e> StLt<'e> { } | ^^^^^^^^^^^ not found in this scope -error: cannot find attribute `ty_inherent` +error: cannot find attribute `ty_inherent` in this scope --> $DIR/feature-gate-custom_attribute2.rs:26:8 | LL | impl<#[ty_inherent] M> StTy { } | ^^^^^^^^^^^ not found in this scope -error: cannot find attribute `lt_impl_for` +error: cannot find attribute `lt_impl_for` in this scope --> $DIR/feature-gate-custom_attribute2.rs:29:8 | LL | impl<#[lt_impl_for] 'f> TrLt<'f> for StLt<'f> { | ^^^^^^^^^^^ not found in this scope -error: cannot find attribute `ty_impl_for` +error: cannot find attribute `ty_impl_for` in this scope --> $DIR/feature-gate-custom_attribute2.rs:33:8 | LL | impl<#[ty_impl_for] N> TrTy for StTy { | ^^^^^^^^^^^ not found in this scope -error: cannot find attribute `lt_fn` +error: cannot find attribute `lt_fn` in this scope --> $DIR/feature-gate-custom_attribute2.rs:38:11 | LL | fn f_lt<#[lt_fn] 'g>(_: &'g [u32]) -> &'g u32 { loop { } } | ^^^^^ not found in this scope -error: cannot find attribute `ty_fn` +error: cannot find attribute `ty_fn` in this scope --> $DIR/feature-gate-custom_attribute2.rs:40:11 | LL | fn f_ty<#[ty_fn] O>(_: O) { } | ^^^^^ not found in this scope -error: cannot find attribute `lt_meth` +error: cannot find attribute `lt_meth` in this scope --> $DIR/feature-gate-custom_attribute2.rs:44:15 | LL | fn m_lt<#[lt_meth] 'h>(_: &'h [u32]) -> &'h u32 { loop { } } | ^^^^^^^ not found in this scope -error: cannot find attribute `ty_meth` +error: cannot find attribute `ty_meth` in this scope --> $DIR/feature-gate-custom_attribute2.rs:46:15 | LL | fn m_ty<#[ty_meth] P>(_: P) { } | ^^^^^^^ not found in this scope -error: cannot find attribute `lt_hof` +error: cannot find attribute `lt_hof` in this scope --> $DIR/feature-gate-custom_attribute2.rs:51:21 | LL | where Q: for <#[lt_hof] 'i> Fn(&'i [u32]) -> &'i u32 diff --git a/tests/ui/feature-gates/feature-gate-gen_blocks.none.stderr b/tests/ui/feature-gates/feature-gate-gen_blocks.none.stderr index bc4c6f5e1235e..b4b37f0e63847 100644 --- a/tests/ui/feature-gates/feature-gate-gen_blocks.none.stderr +++ b/tests/ui/feature-gates/feature-gate-gen_blocks.none.stderr @@ -10,7 +10,7 @@ error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found LL | async gen {}; | ^^^ expected one of 8 possible tokens -error[E0422]: cannot find struct, variant or union type `gen` +error[E0422]: cannot find struct, variant or union type `gen` in this scope --> $DIR/feature-gate-gen_blocks.rs:5:5 | LL | gen {}; diff --git a/tests/ui/feature-gates/feature-gate-rustc-attrs.stderr b/tests/ui/feature-gates/feature-gate-rustc-attrs.stderr index cb8b9a027c3c4..b49d299d522de 100644 --- a/tests/ui/feature-gates/feature-gate-rustc-attrs.stderr +++ b/tests/ui/feature-gates/feature-gate-rustc-attrs.stderr @@ -28,7 +28,7 @@ error: attributes starting with `rustc` are reserved for use by the `rustc` comp LL | #[rustc_unknown] | ^^^^^^^^^^^^^ -error: cannot find attribute `rustc_unknown` +error: cannot find attribute `rustc_unknown` in this scope --> $DIR/feature-gate-rustc-attrs.rs:20:3 | LL | #[rustc_unknown] diff --git a/tests/ui/feature-gates/issue-43106-gating-of-derive-2.stderr b/tests/ui/feature-gates/issue-43106-gating-of-derive-2.stderr index 28c20ddca7db5..97f7fbaeaee26 100644 --- a/tests/ui/feature-gates/issue-43106-gating-of-derive-2.stderr +++ b/tests/ui/feature-gates/issue-43106-gating-of-derive-2.stderr @@ -1,10 +1,10 @@ -error: cannot find derive macro `x3300` +error: cannot find derive macro `x3300` in this scope --> $DIR/issue-43106-gating-of-derive-2.rs:14:14 | LL | #[derive(x3300)] | ^^^^^ not found in this scope -error: cannot find derive macro `x3300` +error: cannot find derive macro `x3300` in this scope --> $DIR/issue-43106-gating-of-derive-2.rs:14:14 | LL | #[derive(x3300)] @@ -12,13 +12,13 @@ LL | #[derive(x3300)] | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error: cannot find derive macro `x3300` +error: cannot find derive macro `x3300` in this scope --> $DIR/issue-43106-gating-of-derive-2.rs:9:14 | LL | #[derive(x3300)] | ^^^^^ not found in this scope -error: cannot find derive macro `x3300` +error: cannot find derive macro `x3300` in this scope --> $DIR/issue-43106-gating-of-derive-2.rs:9:14 | LL | #[derive(x3300)] @@ -26,13 +26,13 @@ LL | #[derive(x3300)] | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error: cannot find derive macro `x3300` +error: cannot find derive macro `x3300` in this scope --> $DIR/issue-43106-gating-of-derive-2.rs:4:14 | LL | #[derive(x3300)] | ^^^^^ not found in this scope -error: cannot find derive macro `x3300` +error: cannot find derive macro `x3300` in this scope --> $DIR/issue-43106-gating-of-derive-2.rs:4:14 | LL | #[derive(x3300)] diff --git a/tests/ui/fmt/format-args-capture-issue-102057.stderr b/tests/ui/fmt/format-args-capture-issue-102057.stderr index 339c66c4990c5..f2d625e7f8dc8 100644 --- a/tests/ui/fmt/format-args-capture-issue-102057.stderr +++ b/tests/ui/fmt/format-args-capture-issue-102057.stderr @@ -1,40 +1,40 @@ -error[E0425]: cannot find value `a` +error[E0425]: cannot find value `a` in this scope --> $DIR/format-args-capture-issue-102057.rs:2:18 | LL | format!("\x7Ba}"); | ^ not found in this scope -error[E0425]: cannot find value `a` +error[E0425]: cannot find value `a` in this scope --> $DIR/format-args-capture-issue-102057.rs:4:18 | LL | format!("\x7Ba\x7D"); | ^ not found in this scope -error[E0425]: cannot find value `b` +error[E0425]: cannot find value `b` in this scope --> $DIR/format-args-capture-issue-102057.rs:9:22 | LL | format!("\x7Ba} {b}"); | ^ help: a local variable with a similar name exists: `a` -error[E0425]: cannot find value `b` +error[E0425]: cannot find value `b` in this scope --> $DIR/format-args-capture-issue-102057.rs:11:25 | LL | format!("\x7Ba\x7D {b}"); | ^ help: a local variable with a similar name exists: `a` -error[E0425]: cannot find value `b` +error[E0425]: cannot find value `b` in this scope --> $DIR/format-args-capture-issue-102057.rs:13:25 | LL | format!("\x7Ba} \x7Bb}"); | ^ help: a local variable with a similar name exists: `a` -error[E0425]: cannot find value `b` +error[E0425]: cannot find value `b` in this scope --> $DIR/format-args-capture-issue-102057.rs:15:28 | LL | format!("\x7Ba\x7D \x7Bb}"); | ^ help: a local variable with a similar name exists: `a` -error[E0425]: cannot find value `b` +error[E0425]: cannot find value `b` in this scope --> $DIR/format-args-capture-issue-102057.rs:17:28 | LL | format!("\x7Ba\x7D \x7Bb\x7D"); diff --git a/tests/ui/fmt/format-args-capture-issue-94010.stderr b/tests/ui/fmt/format-args-capture-issue-94010.stderr index 852957edd57b2..ed90dc855360a 100644 --- a/tests/ui/fmt/format-args-capture-issue-94010.stderr +++ b/tests/ui/fmt/format-args-capture-issue-94010.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `foo` +error[E0425]: cannot find value `foo` in this scope --> $DIR/format-args-capture-issue-94010.rs:3:16 | LL | const FOO: i32 = 123; @@ -6,7 +6,7 @@ LL | const FOO: i32 = 123; LL | println!("{foo:X}"); | ^^^ help: a constant with a similar name exists (notice the capitalization): `FOO` -error[E0425]: cannot find value `foo` +error[E0425]: cannot find value `foo` in this scope --> $DIR/format-args-capture-issue-94010.rs:5:18 | LL | const FOO: i32 = 123; diff --git a/tests/ui/fmt/format-args-capture-missing-variables.stderr b/tests/ui/fmt/format-args-capture-missing-variables.stderr index ed75fd54f20e7..d980e7be273e8 100644 --- a/tests/ui/fmt/format-args-capture-missing-variables.stderr +++ b/tests/ui/fmt/format-args-capture-missing-variables.stderr @@ -6,37 +6,37 @@ LL | format!("{valuea} {valueb}", valuea=5, valuec=7); | | | formatting specifier missing -error[E0425]: cannot find value `foo` +error[E0425]: cannot find value `foo` in this scope --> $DIR/format-args-capture-missing-variables.rs:2:18 | LL | format!("{} {foo} {} {bar} {}", 1, 2, 3); | ^^^ not found in this scope -error[E0425]: cannot find value `bar` +error[E0425]: cannot find value `bar` in this scope --> $DIR/format-args-capture-missing-variables.rs:2:27 | LL | format!("{} {foo} {} {bar} {}", 1, 2, 3); | ^^^ not found in this scope -error[E0425]: cannot find value `foo` +error[E0425]: cannot find value `foo` in this scope --> $DIR/format-args-capture-missing-variables.rs:6:15 | LL | format!("{foo}"); | ^^^ not found in this scope -error[E0425]: cannot find value `valueb` +error[E0425]: cannot find value `valueb` in this scope --> $DIR/format-args-capture-missing-variables.rs:8:24 | LL | format!("{valuea} {valueb}", valuea=5, valuec=7); | ^^^^^^ not found in this scope -error[E0425]: cannot find value `foo` +error[E0425]: cannot find value `foo` in this scope --> $DIR/format-args-capture-missing-variables.rs:14:10 | LL | {foo} | ^^^ not found in this scope -error[E0425]: cannot find value `foo` +error[E0425]: cannot find value `foo` in this scope --> $DIR/format-args-capture-missing-variables.rs:19:14 | LL | panic!("{foo} {bar}", bar=1); diff --git a/tests/ui/fmt/ifmt-bad-arg.stderr b/tests/ui/fmt/ifmt-bad-arg.stderr index c51b7efc89337..09ce3dca4117e 100644 --- a/tests/ui/fmt/ifmt-bad-arg.stderr +++ b/tests/ui/fmt/ifmt-bad-arg.stderr @@ -266,31 +266,31 @@ LL | println!("{:.0$}"); = note: positional arguments are zero-based = note: for information about formatting flags, visit https://doc.rust-lang.org/std/fmt/index.html -error[E0425]: cannot find value `foo` +error[E0425]: cannot find value `foo` in this scope --> $DIR/ifmt-bad-arg.rs:27:18 | LL | format!("{} {foo} {} {bar} {}", 1, 2, 3); | ^^^ not found in this scope -error[E0425]: cannot find value `bar` +error[E0425]: cannot find value `bar` in this scope --> $DIR/ifmt-bad-arg.rs:27:27 | LL | format!("{} {foo} {} {bar} {}", 1, 2, 3); | ^^^ not found in this scope -error[E0425]: cannot find value `foo` +error[E0425]: cannot find value `foo` in this scope --> $DIR/ifmt-bad-arg.rs:31:15 | LL | format!("{foo}"); | ^^^ not found in this scope -error[E0425]: cannot find value `valueb` +error[E0425]: cannot find value `valueb` in this scope --> $DIR/ifmt-bad-arg.rs:45:24 | LL | format!("{valuea} {valueb}", valuea=5, valuec=7); | ^^^^^^ not found in this scope -error[E0425]: cannot find value `foo` +error[E0425]: cannot find value `foo` in this scope --> $DIR/ifmt-bad-arg.rs:60:10 | LL | {foo} diff --git a/tests/ui/fmt/unicode-escape-spans.stderr b/tests/ui/fmt/unicode-escape-spans.stderr index 11e4979a49825..1d8473f01b822 100644 --- a/tests/ui/fmt/unicode-escape-spans.stderr +++ b/tests/ui/fmt/unicode-escape-spans.stderr @@ -1,58 +1,58 @@ -error[E0425]: cannot find value `a` +error[E0425]: cannot find value `a` in this scope --> $DIR/unicode-escape-spans.rs:3:25 | LL | format!("\u{000041}{a}"); | ^ not found in this scope -error[E0425]: cannot find value `a` +error[E0425]: cannot find value `a` in this scope --> $DIR/unicode-escape-spans.rs:4:23 | LL | format!("\u{0041}{a}"); | ^ not found in this scope -error[E0425]: cannot find value `a` +error[E0425]: cannot find value `a` in this scope --> $DIR/unicode-escape-spans.rs:5:21 | LL | format!("\u{41}{a}"); | ^ not found in this scope -error[E0425]: cannot find value `a` +error[E0425]: cannot find value `a` in this scope --> $DIR/unicode-escape-spans.rs:6:20 | LL | format!("\u{0}{a}"); | ^ not found in this scope -error[E0425]: cannot find value `a` +error[E0425]: cannot find value `a` in this scope --> $DIR/unicode-escape-spans.rs:9:22 | LL | format!("\u{0df}{a}"); | ^ not found in this scope -error[E0425]: cannot find value `a` +error[E0425]: cannot find value `a` in this scope --> $DIR/unicode-escape-spans.rs:10:21 | LL | format!("\u{df}{a}"); | ^ not found in this scope -error[E0425]: cannot find value `a` +error[E0425]: cannot find value `a` in this scope --> $DIR/unicode-escape-spans.rs:13:25 | LL | format!("\u{00211d}{a}"); | ^ not found in this scope -error[E0425]: cannot find value `a` +error[E0425]: cannot find value `a` in this scope --> $DIR/unicode-escape-spans.rs:14:23 | LL | format!("\u{211d}{a}"); | ^ not found in this scope -error[E0425]: cannot find value `a` +error[E0425]: cannot find value `a` in this scope --> $DIR/unicode-escape-spans.rs:17:24 | LL | format!("\u{1f4a3}{a}"); | ^ not found in this scope -error[E0425]: cannot find value `a` +error[E0425]: cannot find value `a` in this scope --> $DIR/unicode-escape-spans.rs:18:25 | LL | format!("\u{10ffff}{a}"); diff --git a/tests/ui/for/for-expn.stderr b/tests/ui/for/for-expn.stderr index f4d5e7e3eb7ea..00822324039f0 100644 --- a/tests/ui/for/for-expn.stderr +++ b/tests/ui/for/for-expn.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `foo` +error[E0425]: cannot find value `foo` in this scope --> $DIR/for-expn.rs:6:7 | LL | foo diff --git a/tests/ui/functions-closures/fn-help-with-err-generic-is-not-function.stderr b/tests/ui/functions-closures/fn-help-with-err-generic-is-not-function.stderr index eef18f68084ed..9d4ea01152cc9 100644 --- a/tests/ui/functions-closures/fn-help-with-err-generic-is-not-function.stderr +++ b/tests/ui/functions-closures/fn-help-with-err-generic-is-not-function.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `T` +error[E0412]: cannot find type `T` in this scope --> $DIR/fn-help-with-err-generic-is-not-function.rs:2:13 | LL | impl Struct @@ -9,7 +9,7 @@ help: you might be missing a type parameter LL | impl Struct | +++ -error[E0412]: cannot find type `T` +error[E0412]: cannot find type `T` in this scope --> $DIR/fn-help-with-err-generic-is-not-function.rs:7:5 | LL | T: Copy, diff --git a/tests/ui/functions-closures/fn-help-with-err.stderr b/tests/ui/functions-closures/fn-help-with-err.stderr index 91de164b013dd..e5fe4611434ea 100644 --- a/tests/ui/functions-closures/fn-help-with-err.stderr +++ b/tests/ui/functions-closures/fn-help-with-err.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `oops` +error[E0425]: cannot find value `oops` in this scope --> $DIR/fn-help-with-err.rs:13:35 | LL | let arc = std::sync::Arc::new(oops); diff --git a/tests/ui/generic-associated-types/equality-bound.stderr b/tests/ui/generic-associated-types/equality-bound.stderr index 72200c462ac8f..a054c06caebde 100644 --- a/tests/ui/generic-associated-types/equality-bound.stderr +++ b/tests/ui/generic-associated-types/equality-bound.stderr @@ -110,7 +110,7 @@ LL - fn from_iter(_: T) -> Self where T::Item = A, T: IntoIterator, LL + fn from_iter(_: T) -> Self where T: IntoIterator, | -error[E0412]: cannot find type `A` +error[E0412]: cannot find type `A` in this scope --> $DIR/equality-bound.rs:20:79 | LL | fn from_iter(_: T) -> Self where T: IntoIterator, IntoIterator::Item = A, @@ -119,7 +119,7 @@ LL | fn from_iter(_: T) -> Self where T: IntoIterator, IntoIterator::Item LL | struct K {} | -------- similarly named struct `K` defined here -error[E0412]: cannot find type `A` +error[E0412]: cannot find type `A` in this scope --> $DIR/equality-bound.rs:31:68 | LL | fn from_iter(_: T) -> Self where T: IntoIterator, T::Item = A, @@ -128,7 +128,7 @@ LL | fn from_iter(_: T) -> Self where T: IntoIterator, T::Item = A, LL | struct K {} | -------- similarly named struct `K` defined here -error[E0412]: cannot find type `A` +error[E0412]: cannot find type `A` in this scope --> $DIR/equality-bound.rs:42:76 | LL | fn from_iter(_: T) -> Self where IntoIterator::Item = A, @@ -137,7 +137,7 @@ LL | fn from_iter(_: T) -> Self where IntoIterator::Item = LL | struct K {} | -------- similarly named struct `K` defined here -error[E0412]: cannot find type `A` +error[E0412]: cannot find type `A` in this scope --> $DIR/equality-bound.rs:53:65 | LL | struct K {} @@ -146,7 +146,7 @@ LL | struct K {} LL | fn from_iter(_: T) -> Self where T::Item = A, | ^ help: a struct with a similar name exists: `K` -error[E0412]: cannot find type `A` +error[E0412]: cannot find type `A` in this scope --> $DIR/equality-bound.rs:64:62 | LL | struct K {} @@ -155,7 +155,7 @@ LL | struct K {} LL | fn from_iter(_: T) -> Self where IntoIterator::Item = A, T: IntoIterator, | ^ help: a struct with a similar name exists: `K` -error[E0412]: cannot find type `A` +error[E0412]: cannot find type `A` in this scope --> $DIR/equality-bound.rs:75:51 | LL | struct K {} diff --git a/tests/ui/generics/issue-106694.stderr b/tests/ui/generics/issue-106694.stderr index 435b05938c822..235b8982a99c6 100644 --- a/tests/ui/generics/issue-106694.stderr +++ b/tests/ui/generics/issue-106694.stderr @@ -70,19 +70,19 @@ LL - fn partially_correct_impl_bad(_: impl &*const &BadTrait + Copy) {} LL + fn partially_correct_impl_bad(_: impl BadTrait + Copy) {} | -error[E0405]: cannot find trait `BadTrait` +error[E0405]: cannot find trait `BadTrait` in this scope --> $DIR/issue-106694.rs:12:21 | LL | fn foo_bad(_: impl &BadTrait) {} | ^^^^^^^^ not found in this scope -error[E0405]: cannot find trait `BadTrait` +error[E0405]: cannot find trait `BadTrait` in this scope --> $DIR/issue-106694.rs:16:16 | LL | fn bar_bad(_: T) {} | ^^^^^^^^ not found in this scope -error[E0405]: cannot find trait `BadTrait` +error[E0405]: cannot find trait `BadTrait` in this scope --> $DIR/issue-106694.rs:20:48 | LL | fn partially_correct_impl_bad(_: impl &*const &BadTrait + Copy) {} diff --git a/tests/ui/hygiene/arguments.stderr b/tests/ui/hygiene/arguments.stderr index e13adaabfe809..0d8d652b6f33d 100644 --- a/tests/ui/hygiene/arguments.stderr +++ b/tests/ui/hygiene/arguments.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `S` +error[E0412]: cannot find type `S` in this scope --> $DIR/arguments.rs:14:8 | LL | m!(S, S); diff --git a/tests/ui/hygiene/cross-crate-glob-hygiene.stderr b/tests/ui/hygiene/cross-crate-glob-hygiene.stderr index e0612da5bd710..1abc739fc362d 100644 --- a/tests/ui/hygiene/cross-crate-glob-hygiene.stderr +++ b/tests/ui/hygiene/cross-crate-glob-hygiene.stderr @@ -1,4 +1,4 @@ -error[E0422]: cannot find struct, variant or union type `MyStruct` +error[E0422]: cannot find struct, variant or union type `MyStruct` in this scope --> $DIR/cross-crate-glob-hygiene.rs:21:13 | LL | let x = my_struct!(create); diff --git a/tests/ui/hygiene/cross-crate-name-hiding-2.stderr b/tests/ui/hygiene/cross-crate-name-hiding-2.stderr index bede1625a0857..a5d509fab996f 100644 --- a/tests/ui/hygiene/cross-crate-name-hiding-2.stderr +++ b/tests/ui/hygiene/cross-crate-name-hiding-2.stderr @@ -1,4 +1,4 @@ -error[E0422]: cannot find struct, variant or union type `MyStruct` +error[E0422]: cannot find struct, variant or union type `MyStruct` in this scope --> $DIR/cross-crate-name-hiding-2.rs:13:13 | LL | let x = MyStruct {}; diff --git a/tests/ui/hygiene/cross-crate-name-hiding.stderr b/tests/ui/hygiene/cross-crate-name-hiding.stderr index f1947a2c1803b..4abd14f935581 100644 --- a/tests/ui/hygiene/cross-crate-name-hiding.stderr +++ b/tests/ui/hygiene/cross-crate-name-hiding.stderr @@ -1,4 +1,4 @@ -error[E0422]: cannot find struct, variant or union type `MyStruct` +error[E0422]: cannot find struct, variant or union type `MyStruct` in this scope --> $DIR/cross-crate-name-hiding.rs:11:13 | LL | let x = MyStruct {}; diff --git a/tests/ui/hygiene/for-loop.stderr b/tests/ui/hygiene/for-loop.stderr index 62195b7ce8e1f..5f334fd89603c 100644 --- a/tests/ui/hygiene/for-loop.stderr +++ b/tests/ui/hygiene/for-loop.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `iter` +error[E0425]: cannot find value `iter` in this scope --> $DIR/for-loop.rs:6:9 | LL | iter.next(); diff --git a/tests/ui/hygiene/generate-mod.stderr b/tests/ui/hygiene/generate-mod.stderr index d090cc12dc93f..32a2e145ca942 100644 --- a/tests/ui/hygiene/generate-mod.stderr +++ b/tests/ui/hygiene/generate-mod.stderr @@ -1,16 +1,16 @@ -error[E0412]: cannot find type `FromOutside` +error[E0412]: cannot find type `FromOutside` in this scope --> $DIR/generate-mod.rs:35:13 | LL | genmod!(FromOutside, Outer); | ^^^^^^^^^^^ not found in this scope -error[E0412]: cannot find type `Outer` +error[E0412]: cannot find type `Outer` in this scope --> $DIR/generate-mod.rs:35:26 | LL | genmod!(FromOutside, Outer); | ^^^^^ not found in this scope -error[E0412]: cannot find type `FromOutside` +error[E0412]: cannot find type `FromOutside` in this scope --> $DIR/generate-mod.rs:19:18 | LL | type A = FromOutside; @@ -21,7 +21,7 @@ LL | genmod_transparent!(); | = note: this error originates in the macro `genmod_transparent` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0412]: cannot find type `Outer` +error[E0412]: cannot find type `Outer` in this scope --> $DIR/generate-mod.rs:20:22 | LL | type Inner = Outer; @@ -32,7 +32,7 @@ LL | genmod_transparent!(); | = note: this error originates in the macro `genmod_transparent` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0412]: cannot find type `FromOutside` +error[E0412]: cannot find type `FromOutside` in this scope --> $DIR/generate-mod.rs:28:18 | LL | type A = FromOutside; @@ -43,7 +43,7 @@ LL | genmod_legacy!(); | = note: this error originates in the macro `genmod_legacy` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0412]: cannot find type `Outer` +error[E0412]: cannot find type `Outer` in this scope --> $DIR/generate-mod.rs:29:22 | LL | type Inner = Outer; diff --git a/tests/ui/hygiene/globs.stderr b/tests/ui/hygiene/globs.stderr index 3b6e74009e087..180172644402b 100644 --- a/tests/ui/hygiene/globs.stderr +++ b/tests/ui/hygiene/globs.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find function `f` +error[E0425]: cannot find function `f` in this scope --> $DIR/globs.rs:22:9 | LL | pub fn g() {} @@ -16,7 +16,7 @@ help: consider importing this function LL + use foo::f; | -error[E0425]: cannot find function `g` +error[E0425]: cannot find function `g` in this scope --> $DIR/globs.rs:15:5 | LL | pub fn f() {} @@ -42,7 +42,7 @@ help: consider importing this function LL + use bar::g; | -error[E0425]: cannot find function `f` +error[E0425]: cannot find function `f` in this scope --> $DIR/globs.rs:61:12 | LL | n!(f); @@ -55,7 +55,7 @@ LL | n!(f); foo::f = note: this error originates in the macro `n` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0425]: cannot find function `f` +error[E0425]: cannot find function `f` in this scope --> $DIR/globs.rs:65:17 | LL | n!(f); diff --git a/tests/ui/hygiene/no_implicit_prelude-2018.stderr b/tests/ui/hygiene/no_implicit_prelude-2018.stderr index f367e8a062fc6..40ca300a52939 100644 --- a/tests/ui/hygiene/no_implicit_prelude-2018.stderr +++ b/tests/ui/hygiene/no_implicit_prelude-2018.stderr @@ -1,4 +1,4 @@ -error: cannot find macro `print` +error: cannot find macro `print` in this scope --> $DIR/no_implicit_prelude-2018.rs:7:9 | LL | print!(); diff --git a/tests/ui/hygiene/pattern-macro.stderr b/tests/ui/hygiene/pattern-macro.stderr index cb9b743432b5c..a9764cea49e59 100644 --- a/tests/ui/hygiene/pattern-macro.stderr +++ b/tests/ui/hygiene/pattern-macro.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `x` +error[E0425]: cannot find value `x` in this scope --> $DIR/pattern-macro.rs:5:5 | LL | x + 1; diff --git a/tests/ui/hygiene/rustc-macro-transparency.stderr b/tests/ui/hygiene/rustc-macro-transparency.stderr index 9b23bbb360a0d..1d2a1e1249864 100644 --- a/tests/ui/hygiene/rustc-macro-transparency.stderr +++ b/tests/ui/hygiene/rustc-macro-transparency.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `Opaque` +error[E0425]: cannot find value `Opaque` in this scope --> $DIR/rustc-macro-transparency.rs:26:5 | LL | Opaque; diff --git a/tests/ui/impl-trait/in-trait/ensure-rpitits-are-created-before-freezing.stderr b/tests/ui/impl-trait/in-trait/ensure-rpitits-are-created-before-freezing.stderr index 86ec30da61830..c172787e6ef21 100644 --- a/tests/ui/impl-trait/in-trait/ensure-rpitits-are-created-before-freezing.stderr +++ b/tests/ui/impl-trait/in-trait/ensure-rpitits-are-created-before-freezing.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `Missing` +error[E0412]: cannot find type `Missing` in this scope --> $DIR/ensure-rpitits-are-created-before-freezing.rs:8:19 | LL | impl Iterable for Missing { diff --git a/tests/ui/impl-trait/in-trait/rpitit-shadowed-by-missing-adt.stderr b/tests/ui/impl-trait/in-trait/rpitit-shadowed-by-missing-adt.stderr index 66353b8601f6d..e7d38f2240642 100644 --- a/tests/ui/impl-trait/in-trait/rpitit-shadowed-by-missing-adt.stderr +++ b/tests/ui/impl-trait/in-trait/rpitit-shadowed-by-missing-adt.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `Missing` +error[E0412]: cannot find type `Missing` in this scope --> $DIR/rpitit-shadowed-by-missing-adt.rs:6:35 | LL | fn w() -> impl Deref>; diff --git a/tests/ui/impl-trait/issue-103181-2.stderr b/tests/ui/impl-trait/issue-103181-2.stderr index eef4df16b59ef..cef4449dbb986 100644 --- a/tests/ui/impl-trait/issue-103181-2.stderr +++ b/tests/ui/impl-trait/issue-103181-2.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `ident_error` +error[E0425]: cannot find value `ident_error` in this scope --> $DIR/issue-103181-2.rs:12:5 | LL | ident_error; diff --git a/tests/ui/impl-trait/issue-54966.stderr b/tests/ui/impl-trait/issue-54966.stderr index 9b936c25d78a4..4024c5afa80b6 100644 --- a/tests/ui/impl-trait/issue-54966.stderr +++ b/tests/ui/impl-trait/issue-54966.stderr @@ -1,4 +1,4 @@ -error[E0412]: cannot find type `Oper` +error[E0412]: cannot find type `Oper` in this scope --> $DIR/issue-54966.rs:3:27 | LL | fn generate_duration() -> Oper {} diff --git a/tests/ui/impl-trait/issues/issue-82139.stderr b/tests/ui/impl-trait/issues/issue-82139.stderr index 4c0c997bef1e0..b87084433120b 100644 --- a/tests/ui/impl-trait/issues/issue-82139.stderr +++ b/tests/ui/impl-trait/issues/issue-82139.stderr @@ -1,4 +1,4 @@ -error[E0425]: cannot find value `j` +error[E0425]: cannot find value `j` in this scope --> $DIR/issue-82139.rs:15:26 | LL | Some(42).map(|_| j) diff --git a/tests/ui/impl-trait/opaque-used-in-extraneous-argument.stderr b/tests/ui/impl-trait/opaque-used-in-extraneous-argument.stderr index f03665d192a54..caaac5434c56a 100644 --- a/tests/ui/impl-trait/opaque-used-in-extraneous-argument.stderr +++ b/tests/ui/impl-trait/opaque-used-in-extraneous-argument.stderr @@ -10,7 +10,7 @@ help: consider using the `'static` lifetime, but this is uncommon unless you're LL | fn frob() -> impl Fn + 'static {} | ~~~~~~~ -error[E0412]: cannot find type `P` +error[E0412]: cannot find type `P` in this scope --> $DIR/opaque-used-in-extraneous-argument.rs:5:22 | LL | fn frob() -> impl Fn + '_ {} @@ -21,7 +21,7 @@ help: you might be missing a type parameter LL | fn frob