From 59a3a5dba314d4b693d141a56fde2e6a879d0af0 Mon Sep 17 00:00:00 2001 From: Joshua Liebow-Feeser Date: Sun, 3 Mar 2024 07:55:23 -0800 Subject: [PATCH 001/165] Clarify atomic bit validity The previous definition used the phrase "representation", which is ambiguous given the current state of memory model nomenclature in Rust. The new wording clarifies that size and bit validity are guaranteed to match the corresponding native integer type. --- library/core/src/sync/atomic.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/core/src/sync/atomic.rs b/library/core/src/sync/atomic.rs index 45193c11e1d6..303f1bf8f65e 100644 --- a/library/core/src/sync/atomic.rs +++ b/library/core/src/sync/atomic.rs @@ -2121,7 +2121,7 @@ macro_rules! atomic_int { $int_type:ident $atomic_type:ident) => { /// An integer type which can be safely shared between threads. /// - /// This type has the same in-memory representation as the underlying + /// This type has the same in-memory size and bit validity as the underlying /// integer type, [` #[doc = $s_int_type] /// `]. From db34b082c0895e80bc9eda17a4c859c51e6509bd Mon Sep 17 00:00:00 2001 From: Joshua Liebow-Feeser Date: Sun, 3 Mar 2024 07:57:35 -0800 Subject: [PATCH 002/165] Clarify bit validity for AtomicBool --- library/core/src/sync/atomic.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/core/src/sync/atomic.rs b/library/core/src/sync/atomic.rs index 303f1bf8f65e..5947f6569a7f 100644 --- a/library/core/src/sync/atomic.rs +++ b/library/core/src/sync/atomic.rs @@ -243,7 +243,7 @@ const EMULATE_ATOMIC_BOOL: bool = /// A boolean type which can be safely shared between threads. /// -/// This type has the same in-memory representation as a [`bool`]. +/// This type has the same memory layout and bit validity as a [`bool`]. /// /// **Note**: This type is only available on platforms that support atomic /// loads and stores of `u8`. From 00d21c91f0cafc97dabe261f934af7ea0df089b4 Mon Sep 17 00:00:00 2001 From: Joshua Liebow-Feeser Date: Sun, 3 Mar 2024 08:04:41 -0800 Subject: [PATCH 003/165] Document AtomicPtr bit validity --- library/core/src/sync/atomic.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/core/src/sync/atomic.rs b/library/core/src/sync/atomic.rs index 5947f6569a7f..4eaacdfe7945 100644 --- a/library/core/src/sync/atomic.rs +++ b/library/core/src/sync/atomic.rs @@ -272,7 +272,7 @@ unsafe impl Sync for AtomicBool {} /// A raw pointer type which can be safely shared between threads. /// -/// This type has the same in-memory representation as a `*mut T`. +/// This type has the same memory layout and bit validity as a `*mut T`. /// /// **Note**: This type is only available on platforms that support atomic /// loads and stores of pointers. Its size depends on the target pointer's size. From fba87f6892a052fdaed45993a1ec03d6c51ab87d Mon Sep 17 00:00:00 2001 From: Joshua Liebow-Feeser Date: Sun, 3 Mar 2024 08:06:41 -0800 Subject: [PATCH 004/165] Use "size and alignment" rather than layout --- library/core/src/sync/atomic.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/core/src/sync/atomic.rs b/library/core/src/sync/atomic.rs index 4eaacdfe7945..0a0daa49926a 100644 --- a/library/core/src/sync/atomic.rs +++ b/library/core/src/sync/atomic.rs @@ -243,7 +243,7 @@ const EMULATE_ATOMIC_BOOL: bool = /// A boolean type which can be safely shared between threads. /// -/// This type has the same memory layout and bit validity as a [`bool`]. +/// This type has the same size, alignment, and bit validity as a [`bool`]. /// /// **Note**: This type is only available on platforms that support atomic /// loads and stores of `u8`. @@ -272,7 +272,7 @@ unsafe impl Sync for AtomicBool {} /// A raw pointer type which can be safely shared between threads. /// -/// This type has the same memory layout and bit validity as a `*mut T`. +/// This type has the same size, alignment, and bit validity as a `*mut T`. /// /// **Note**: This type is only available on platforms that support atomic /// loads and stores of pointers. Its size depends on the target pointer's size. From c50804cfdd5deac77a8eff6e1b2303b6453e786f Mon Sep 17 00:00:00 2001 From: Joshua Liebow-Feeser Date: Sun, 3 Mar 2024 08:08:52 -0800 Subject: [PATCH 005/165] Update library/core/src/sync/atomic.rs Co-authored-by: Taiki Endo --- library/core/src/sync/atomic.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/core/src/sync/atomic.rs b/library/core/src/sync/atomic.rs index 0a0daa49926a..aac0acbadbfc 100644 --- a/library/core/src/sync/atomic.rs +++ b/library/core/src/sync/atomic.rs @@ -2121,7 +2121,7 @@ macro_rules! atomic_int { $int_type:ident $atomic_type:ident) => { /// An integer type which can be safely shared between threads. /// - /// This type has the same in-memory size and bit validity as the underlying + /// This type has the same size and bit validity as the underlying /// integer type, [` #[doc = $s_int_type] /// `]. From a6e3e02d70708c6777e2b4090e12d7ee528fd1ac Mon Sep 17 00:00:00 2001 From: Joshua Liebow-Feeser Date: Sun, 3 Mar 2024 08:12:56 -0800 Subject: [PATCH 006/165] Update library/core/src/sync/atomic.rs Co-authored-by: Taiki Endo --- library/core/src/sync/atomic.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/core/src/sync/atomic.rs b/library/core/src/sync/atomic.rs index aac0acbadbfc..632f5f4be685 100644 --- a/library/core/src/sync/atomic.rs +++ b/library/core/src/sync/atomic.rs @@ -272,7 +272,7 @@ unsafe impl Sync for AtomicBool {} /// A raw pointer type which can be safely shared between threads. /// -/// This type has the same size, alignment, and bit validity as a `*mut T`. +/// This type has the same size and bit validity as a `*mut T`. /// /// **Note**: This type is only available on platforms that support atomic /// loads and stores of pointers. Its size depends on the target pointer's size. From a47d3909a7ae65ee398d4ce0822a92a59943caaf Mon Sep 17 00:00:00 2001 From: Mads Marquart Date: Wed, 13 Mar 2024 10:59:07 +0100 Subject: [PATCH 007/165] Add compare-output-lines-by-subset to compiletest KNOWN_DIRECTIVE_NAMES --- src/tools/compiletest/src/header.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs index 69658222ff3e..3ee315edc51b 100644 --- a/src/tools/compiletest/src/header.rs +++ b/src/tools/compiletest/src/header.rs @@ -693,6 +693,7 @@ const KNOWN_DIRECTIVE_NAMES: &[&str] = &[ "check-run-results", "check-stdout", "check-test-line-numbers-match", + "compare-output-lines-by-subset", "compile-flags", "dont-check-compiler-stderr", "dont-check-compiler-stdout", From 5aece7fad06baaa745784d118db862b3e3ccf7f8 Mon Sep 17 00:00:00 2001 From: onur-ozkan Date: Fri, 8 Mar 2024 22:20:51 +0300 Subject: [PATCH 008/165] ensure std for cross-targets Previously, doing `x test compiler/*` would fail the build due to missing std. This change ensures that it is prepared. Signed-off-by: onur-ozkan --- src/bootstrap/src/core/build_steps/test.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index 4a4497e57db1..14a6ee22de6c 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -2564,8 +2564,12 @@ impl Step for Crate { let mode = self.mode; // See [field@compile::Std::force_recompile]. - builder.ensure(compile::Std::force_recompile(compiler, target)); - builder.ensure(RemoteCopyLibs { compiler, target }); + builder.ensure(compile::Std::force_recompile(compiler, compiler.host)); + + if builder.config.build != target { + builder.ensure(compile::Std::force_recompile(compiler, target)); + builder.ensure(RemoteCopyLibs { compiler, target }); + } // If we're not doing a full bootstrap but we're testing a stage2 // version of libstd, then what we're actually testing is the libstd From 17ba73cfa03099e9c89d42964328148d27c0599f Mon Sep 17 00:00:00 2001 From: Aurora Date: Thu, 2 Mar 2023 21:55:56 +0100 Subject: [PATCH 009/165] Document `adt_const_params` feature in Unstable Book --- .../src/language-features/adt-const-params.md | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 src/doc/unstable-book/src/language-features/adt-const-params.md diff --git a/src/doc/unstable-book/src/language-features/adt-const-params.md b/src/doc/unstable-book/src/language-features/adt-const-params.md new file mode 100644 index 000000000000..208bf5e4c153 --- /dev/null +++ b/src/doc/unstable-book/src/language-features/adt-const-params.md @@ -0,0 +1,35 @@ +# `adt_const_params` + +The tracking issue for this feature is: [#95174] + +[#95174]: https://github.com/rust-lang/rust/issues/95174 + +------------------------ + +Allows for using more complex types for const parameters, such as structs or enums. + +```rust +#![feature(adt_const_params)] +#![allow(incomplete_features)] + +use std::marker::ConstParamTy; + +#[derive(ConstParamTy, PartialEq, Eq)] +enum Foo { + A, + B, + C, +} + +#[derive(ConstParamTy, PartialEq, Eq)] +struct Bar { + flag: bool, +} + +fn is_foo_a_and_bar_true() -> bool { + match (F, B.flag) { + (Foo::A, true) => true, + _ => false, + } +} +``` From 4b616299511c3de88f1052594e19940733567afe Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sat, 16 Mar 2024 17:23:11 +0000 Subject: [PATCH 010/165] Merge commit '4cf4ffc6ba514f171b3f52d1c731063e4fc45be3' into sync_cg_clif-2024-03-16 --- .github/workflows/main.yml | 30 ++++++++++++++++---------- example/std_example.rs | 8 +++++++ patches/bcryptprimitives.rs | 22 +++++++++++++++++++ patches/stdlib-lock.toml | 7 ++----- rust-toolchain | 2 +- scripts/test_rustc_tests.sh | 2 ++ src/constant.rs | 42 +++++++++++++++++++++++++------------ 7 files changed, 83 insertions(+), 30 deletions(-) create mode 100644 patches/bcryptprimitives.rs diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 5f0f3e6549c9..526871d0c05f 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -44,10 +44,9 @@ jobs: env: TARGET_TRIPLE: x86_64-apple-darwin # cross-compile from Linux to Windows using mingw - # FIXME The wine version in Ubuntu 22.04 is missing ProcessPrng - #- os: ubuntu-latest - # env: - # TARGET_TRIPLE: x86_64-pc-windows-gnu + - os: ubuntu-latest + env: + TARGET_TRIPLE: x86_64-pc-windows-gnu - os: ubuntu-latest env: TARGET_TRIPLE: aarch64-unknown-linux-gnu @@ -81,11 +80,11 @@ 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: Install MinGW toolchain and wine - # 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 wine-stable + - name: Install MinGW toolchain and wine + 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 wine-stable - name: Install AArch64 toolchain and qemu if: matrix.os == 'ubuntu-latest' && matrix.env.TARGET_TRIPLE == 'aarch64-unknown-linux-gnu' @@ -108,6 +107,15 @@ jobs: - name: Prepare dependencies run: ./y.sh prepare + # The Wine version shipped with Ubuntu 22.04 doesn't implement bcryptprimitives.dll + - name: Build bcryptprimitives.dll shim for Wine + if: matrix.os == 'ubuntu-latest' && matrix.env.TARGET_TRIPLE == 'x86_64-pc-windows-gnu' + run: | + rustup target add x86_64-pc-windows-gnu + mkdir wine_shims + rustc patches/bcryptprimitives.rs -Copt-level=3 -Clto=fat --out-dir wine_shims --target x86_64-pc-windows-gnu + echo "WINEPATH=$(pwd)/wine_shims" >> $GITHUB_ENV + - name: Build run: ./y.sh build --sysroot none @@ -234,11 +242,11 @@ 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: Install MinGW toolchain and wine + - 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 wine-stable + sudo apt-get install -y gcc-mingw-w64-x86-64 - name: Prepare dependencies run: ./y.sh prepare diff --git a/example/std_example.rs b/example/std_example.rs index 9bd2ab5c638c..2fee912e52cc 100644 --- a/example/std_example.rs +++ b/example/std_example.rs @@ -167,6 +167,14 @@ fn main() { transmute_fat_pointer(); rust_call_abi(); + + const fn no_str() -> Option> { + None + } + + static STATIC_WITH_MAYBE_NESTED_BOX: &Option> = &no_str(); + + println!("{:?}", STATIC_WITH_MAYBE_NESTED_BOX); } fn panic(_: u128) { diff --git a/patches/bcryptprimitives.rs b/patches/bcryptprimitives.rs new file mode 100644 index 000000000000..4d186485aac1 --- /dev/null +++ b/patches/bcryptprimitives.rs @@ -0,0 +1,22 @@ +// Shim for bcryptprimitives.dll. The Wine version shipped with Ubuntu 22.04 +// doesn't support it yet. Authored by @ChrisDenton + +#![crate_type = "cdylib"] +#![allow(nonstandard_style)] + +#[no_mangle] +pub unsafe extern "system" fn ProcessPrng(mut pbData: *mut u8, mut cbData: usize) -> i32 { + while cbData > 0 { + let size = core::cmp::min(cbData, u32::MAX as usize); + RtlGenRandom(pbData, size as u32); + cbData -= size; + pbData = pbData.add(size); + } + 1 +} + +#[link(name = "advapi32")] +extern "system" { + #[link_name = "SystemFunction036"] + pub fn RtlGenRandom(RandomBuffer: *mut u8, RandomBufferLength: u32) -> u8; +} diff --git a/patches/stdlib-lock.toml b/patches/stdlib-lock.toml index 369f9c88be11..a72fa2c62a96 100644 --- a/patches/stdlib-lock.toml +++ b/patches/stdlib-lock.toml @@ -42,12 +42,9 @@ checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" [[package]] name = "cc" -version = "1.0.83" +version = "1.0.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" -dependencies = [ - "libc", -] +checksum = "8cd6604a82acf3039f1144f54b8eb34e91ffba622051189e71b781822d5ee1f5" [[package]] name = "cfg-if" diff --git a/rust-toolchain b/rust-toolchain index e9f225b4e9e1..f3cd4cbe4935 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2024-03-08" +channel = "nightly-2024-03-16" components = ["rust-src", "rustc-dev", "llvm-tools"] diff --git a/scripts/test_rustc_tests.sh b/scripts/test_rustc_tests.sh index e884577d519d..9b360fb30362 100755 --- a/scripts/test_rustc_tests.sh +++ b/scripts/test_rustc_tests.sh @@ -83,6 +83,7 @@ rm -r tests/run-make/symbols-include-type-name # --emit=asm not supported rm -r tests/run-make/target-specs # i686 not supported by Cranelift rm -r tests/run-make/mismatching-target-triples # same rm tests/ui/asm/x86_64/issue-96797.rs # const and sym inline asm operands don't work entirely correctly +rm tests/ui/asm/x86_64/goto.rs # inline asm labels not supported # requires LTO rm -r tests/run-make/cdylib @@ -121,6 +122,7 @@ rm -r tests/run-make/optimization-remarks-dir # remarks are LLVM specific rm tests/ui/mir/mir_misc_casts.rs # depends on deduplication of constants rm tests/ui/mir/mir_raw_fat_ptr.rs # same rm tests/ui/consts/issue-33537.rs # same +rm tests/ui/consts/const-mut-refs-crate.rs # same # rustdoc-clif passes extra args, suppressing the help message when no args are passed rm -r tests/run-make/issue-88756-default-output diff --git a/src/constant.rs b/src/constant.rs index cec479218b71..39fa277fedc5 100644 --- a/src/constant.rs +++ b/src/constant.rs @@ -53,7 +53,11 @@ pub(crate) fn codegen_tls_ref<'tcx>( let call = fx.bcx.ins().call(func_ref, &[]); fx.bcx.func.dfg.first_result(call) } else { - let data_id = data_id_for_static(fx.tcx, fx.module, def_id, false); + let data_id = data_id_for_static( + fx.tcx, fx.module, def_id, false, + // For a declaration the stated mutability doesn't matter. + false, + ); let local_data_id = fx.module.declare_data_in_func(data_id, &mut fx.bcx.func); if fx.clif_comments.enabled() { fx.add_comment(local_data_id, format!("tls {:?}", def_id)); @@ -164,7 +168,11 @@ pub(crate) fn codegen_const_value<'tcx>( } GlobalAlloc::Static(def_id) => { assert!(fx.tcx.is_static(def_id)); - let data_id = data_id_for_static(fx.tcx, fx.module, def_id, false); + let data_id = data_id_for_static( + fx.tcx, fx.module, def_id, false, + // For a declaration the stated mutability doesn't matter. + false, + ); let local_data_id = fx.module.declare_data_in_func(data_id, &mut fx.bcx.func); if fx.clif_comments.enabled() { @@ -232,21 +240,19 @@ fn data_id_for_static( module: &mut dyn Module, def_id: DefId, definition: bool, + definition_writable: bool, ) -> DataId { let attrs = tcx.codegen_fn_attrs(def_id); let instance = Instance::mono(tcx, def_id).polymorphize(tcx); let symbol_name = tcx.symbol_name(instance).name; - let ty = instance.ty(tcx, ParamEnv::reveal_all()); - let is_mutable = if tcx.is_mutable_static(def_id) { - true - } else { - !ty.is_freeze(tcx, ParamEnv::reveal_all()) - }; - let align = tcx.layout_of(ParamEnv::reveal_all().and(ty)).unwrap().align.pref.bytes(); if let Some(import_linkage) = attrs.import_linkage { assert!(!definition); + assert!(!tcx.is_mutable_static(def_id)); + + let ty = instance.ty(tcx, ParamEnv::reveal_all()); + let align = tcx.layout_of(ParamEnv::reveal_all().and(ty)).unwrap().align.pref.bytes(); let linkage = if import_linkage == rustc_middle::mir::mono::Linkage::ExternalWeak || import_linkage == rustc_middle::mir::mono::Linkage::WeakAny @@ -259,7 +265,7 @@ fn data_id_for_static( let data_id = match module.declare_data( symbol_name, linkage, - is_mutable, + false, attrs.flags.contains(CodegenFnAttrFlags::THREAD_LOCAL), ) { Ok(data_id) => data_id, @@ -307,7 +313,7 @@ fn data_id_for_static( let data_id = match module.declare_data( symbol_name, linkage, - is_mutable, + definition_writable, attrs.flags.contains(CodegenFnAttrFlags::THREAD_LOCAL), ) { Ok(data_id) => data_id, @@ -341,7 +347,13 @@ fn define_all_allocs(tcx: TyCtxt<'_>, module: &mut dyn Module, cx: &mut Constant let alloc = tcx.eval_static_initializer(def_id).unwrap(); - let data_id = data_id_for_static(tcx, module, def_id, true); + let data_id = data_id_for_static( + tcx, + module, + def_id, + true, + alloc.inner().mutability == Mutability::Mut, + ); (data_id, alloc, section_name) } }; @@ -421,7 +433,11 @@ fn define_all_allocs(tcx: TyCtxt<'_>, module: &mut dyn Module, cx: &mut Constant // Don't push a `TodoItem::Static` here, as it will cause statics used by // multiple crates to be duplicated between them. It isn't necessary anyway, // as it will get pushed by `codegen_static` when necessary. - data_id_for_static(tcx, module, def_id, false) + data_id_for_static( + tcx, module, def_id, false, + // For a declaration the stated mutability doesn't matter. + false, + ) } }; From e46114fdc880cded537697a25ba0cf04f242ca82 Mon Sep 17 00:00:00 2001 From: Ben Kimock Date: Fri, 15 Mar 2024 14:13:11 -0400 Subject: [PATCH 011/165] Handle calls to upstream monomorphizations in compiler_builtins --- src/abi/mod.rs | 14 ++++++++++++++ src/base.rs | 7 +++++++ src/lib.rs | 1 + 3 files changed, 22 insertions(+) diff --git a/src/abi/mod.rs b/src/abi/mod.rs index 6e846d721f2e..b33587f8948b 100644 --- a/src/abi/mod.rs +++ b/src/abi/mod.rs @@ -8,8 +8,11 @@ use std::borrow::Cow; use cranelift_codegen::ir::SigRef; use cranelift_module::ModuleError; +use rustc_codegen_ssa::errors::CompilerBuiltinsCannotCall; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; use rustc_middle::ty::layout::FnAbiOf; +use rustc_middle::ty::print::with_no_trimmed_paths; +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}; @@ -372,6 +375,17 @@ pub(crate) fn codegen_terminator_call<'tcx>( ty::Instance::expect_resolve(fx.tcx, ty::ParamEnv::reveal_all(), def_id, fn_args) .polymorphize(fx.tcx); + if is_call_from_compiler_builtins_to_upstream_monomorphization(fx.tcx, instance) { + if target.is_some() { + let caller = with_no_trimmed_paths!(fx.tcx.def_path_str(fx.instance.def_id())); + let callee = with_no_trimmed_paths!(fx.tcx.def_path_str(def_id)); + fx.tcx.dcx().emit_err(CompilerBuiltinsCannotCall { caller, callee }); + } else { + fx.bcx.ins().trap(TrapCode::User(0)); + return; + } + } + if fx.tcx.symbol_name(instance).name.starts_with("llvm.") { crate::intrinsics::codegen_llvm_intrinsic_call( fx, diff --git a/src/base.rs b/src/base.rs index 2415c2c90b22..047dc56a32ea 100644 --- a/src/base.rs +++ b/src/base.rs @@ -8,6 +8,7 @@ use rustc_index::IndexVec; use rustc_middle::ty::adjustment::PointerCoercion; use rustc_middle::ty::layout::FnAbiOf; use rustc_middle::ty::print::with_no_trimmed_paths; +use rustc_monomorphize::is_call_from_compiler_builtins_to_upstream_monomorphization; use crate::constant::ConstantCx; use crate::debuginfo::FunctionDebugContext; @@ -999,6 +1000,12 @@ fn codegen_panic_inner<'tcx>( let def_id = fx.tcx.require_lang_item(lang_item, span); let instance = Instance::mono(fx.tcx, def_id).polymorphize(fx.tcx); + + if is_call_from_compiler_builtins_to_upstream_monomorphization(fx.tcx, instance) { + fx.bcx.ins().trap(TrapCode::User(0)); + return; + } + let symbol_name = fx.tcx.symbol_name(instance).name; fx.lib_call( diff --git a/src/lib.rs b/src/lib.rs index 7e2e1f7c6ac0..a59a39074f8c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -21,6 +21,7 @@ extern crate rustc_hir; extern crate rustc_incremental; extern crate rustc_index; extern crate rustc_metadata; +extern crate rustc_monomorphize; extern crate rustc_session; extern crate rustc_span; extern crate rustc_target; From eeca87b8c7316c017f50b4e22b47164926ef24fe Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Thu, 14 Mar 2024 09:10:28 +0000 Subject: [PATCH 012/165] Avoid various uses of `Option` in favor of using `DUMMY_SP` in the few cases that used `None` --- src/constant.rs | 2 +- src/intrinsics/mod.rs | 6 ++++-- src/intrinsics/simd.rs | 2 +- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/constant.rs b/src/constant.rs index 39fa277fedc5..fc9b0f6ef024 100644 --- a/src/constant.rs +++ b/src/constant.rs @@ -74,7 +74,7 @@ pub(crate) fn eval_mir_constant<'tcx>( let cv = fx.monomorphize(constant.const_); // This cannot fail because we checked all required_consts in advance. let val = cv - .eval(fx.tcx, ty::ParamEnv::reveal_all(), Some(constant.span)) + .eval(fx.tcx, ty::ParamEnv::reveal_all(), constant.span) .expect("erroneous constant missed by mono item collection"); (val, cv.ty()) } diff --git a/src/intrinsics/mod.rs b/src/intrinsics/mod.rs index 8b86a116df1f..c802d9bbefbe 100644 --- a/src/intrinsics/mod.rs +++ b/src/intrinsics/mod.rs @@ -728,8 +728,10 @@ fn codegen_regular_intrinsic_call<'tcx>( | sym::variant_count => { intrinsic_args!(fx, args => (); intrinsic); - let const_val = - fx.tcx.const_eval_instance(ParamEnv::reveal_all(), instance, None).unwrap(); + let const_val = fx + .tcx + .const_eval_instance(ParamEnv::reveal_all(), instance, source_info.span) + .unwrap(); let val = crate::constant::codegen_const_value(fx, const_val, ret.layout().ty); ret.write_cvalue(fx, val); } diff --git a/src/intrinsics/simd.rs b/src/intrinsics/simd.rs index 79da970a58ef..4d55a95aa9db 100644 --- a/src/intrinsics/simd.rs +++ b/src/intrinsics/simd.rs @@ -131,7 +131,7 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>( let idx = generic_args[2] .expect_const() - .eval(fx.tcx, ty::ParamEnv::reveal_all(), Some(span)) + .eval(fx.tcx, ty::ParamEnv::reveal_all(), span) .unwrap() .unwrap_branch(); From 1aac27e6b6f0a3cb86434803cd7a2535c7587f82 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Mon, 18 Mar 2024 13:59:53 +0000 Subject: [PATCH 013/165] Rustup to rustc 1.79.0-nightly (eb45c8444 2024-03-17) --- patches/0022-coretests-Disable-not-compiling-tests.patch | 2 +- rust-toolchain | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/patches/0022-coretests-Disable-not-compiling-tests.patch b/patches/0022-coretests-Disable-not-compiling-tests.patch index 5442c3cef9ec..7cf7f86700ea 100644 --- a/patches/0022-coretests-Disable-not-compiling-tests.patch +++ b/patches/0022-coretests-Disable-not-compiling-tests.patch @@ -39,6 +39,6 @@ index 42a26ae..5ac1042 100644 +#![cfg(test)] #![feature(alloc_layout_extra)] #![feature(array_chunks)] - #![feature(array_windows)] + #![feature(array_ptr_get)] -- 2.21.0 (Apple Git-122) diff --git a/rust-toolchain b/rust-toolchain index f3cd4cbe4935..31aec1131e52 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2024-03-16" +channel = "nightly-2024-03-18" components = ["rust-src", "rustc-dev", "llvm-tools"] From b64079d6313446bbb40cf6c467c1e2d068f8f682 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Mon, 18 Mar 2024 14:08:59 +0000 Subject: [PATCH 014/165] Re-enable rmake.rs tests as a compiletest bug has been fixed --- scripts/test_rustc_tests.sh | 8 -------- 1 file changed, 8 deletions(-) diff --git a/scripts/test_rustc_tests.sh b/scripts/test_rustc_tests.sh index 9b360fb30362..b7808b6f4c3d 100755 --- a/scripts/test_rustc_tests.sh +++ b/scripts/test_rustc_tests.sh @@ -10,14 +10,6 @@ pushd rust command -v rg >/dev/null 2>&1 || cargo install ripgrep -# FIXME(rust-lang/rust#122196) fix stage0 rmake.rs run-make tests and remove -# this workaround -for test in $(ls tests/run-make); do - if [[ -e "tests/run-make/$test/rmake.rs" ]]; then - rm -r "tests/run-make/$test" - fi -done - # FIXME remove this workaround once ICE tests no longer emit an outdated nightly message for test in $(rg -i --files-with-matches "//@(\[.*\])? failure-status: 101" tests/ui); do echo "rm $test" From c49f6080629e4e0b788a8b58225e1ba35a3dbf1e Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Mon, 18 Mar 2024 15:10:23 +0000 Subject: [PATCH 015/165] Several refactorings to constant.rs * Move the done hash set from ConstantCx to define_all_allocs. * Move check if alloc has already been defined to the start of the loop. * Extract helper function for vtables. --- src/constant.rs | 50 +++++++++++++++++++++++++------------------------ src/vtable.rs | 8 +++----- 2 files changed, 29 insertions(+), 29 deletions(-) diff --git a/src/constant.rs b/src/constant.rs index 39fa277fedc5..737406a0d4ab 100644 --- a/src/constant.rs +++ b/src/constant.rs @@ -6,17 +6,16 @@ use cranelift_module::*; use rustc_data_structures::fx::FxHashSet; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; use rustc_middle::mir::interpret::{read_target_uint, AllocId, GlobalAlloc, Scalar}; -use rustc_middle::ty::ScalarInt; +use rustc_middle::ty::{Binder, ExistentialTraitRef, ScalarInt}; use crate::prelude::*; pub(crate) struct ConstantCx { todo: Vec, - done: FxHashSet, anon_allocs: FxHashMap, } -#[derive(Copy, Clone, Debug)] +#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] enum TodoItem { Alloc(AllocId), Static(DefId), @@ -24,12 +23,11 @@ enum TodoItem { impl ConstantCx { pub(crate) fn new() -> Self { - ConstantCx { todo: vec![], done: FxHashSet::default(), anon_allocs: FxHashMap::default() } + ConstantCx { todo: vec![], anon_allocs: FxHashMap::default() } } pub(crate) fn finalize(mut self, tcx: TyCtxt<'_>, module: &mut dyn Module) { define_all_allocs(tcx, module, &mut self); - self.done.clear(); } } @@ -153,14 +151,12 @@ pub(crate) fn codegen_const_value<'tcx>( fx.bcx.ins().func_addr(fx.pointer_type, local_func_id) } GlobalAlloc::VTable(ty, trait_ref) => { - let alloc_id = fx.tcx.vtable_allocation((ty, trait_ref)); - let alloc = fx.tcx.global_alloc(alloc_id).unwrap_memory(); - // FIXME: factor this common code with the `Memory` arm into a function? - let data_id = data_id_for_alloc_id( + let data_id = data_id_for_vtable( + fx.tcx, &mut fx.constants_cx, fx.module, - alloc_id, - alloc.inner().mutability, + ty, + trait_ref, ); let local_data_id = fx.module.declare_data_in_func(data_id, &mut fx.bcx.func); @@ -208,12 +204,8 @@ fn pointer_for_allocation<'tcx>( alloc_id: AllocId, ) -> crate::pointer::Pointer { let alloc = fx.tcx.global_alloc(alloc_id).unwrap_memory(); - let data_id = data_id_for_alloc_id( - &mut fx.constants_cx, - &mut *fx.module, - alloc_id, - alloc.inner().mutability, - ); + let data_id = + data_id_for_alloc_id(&mut fx.constants_cx, fx.module, alloc_id, alloc.inner().mutability); let local_data_id = fx.module.declare_data_in_func(data_id, &mut fx.bcx.func); if fx.clif_comments.enabled() { @@ -235,6 +227,17 @@ pub(crate) fn data_id_for_alloc_id( .or_insert_with(|| module.declare_anonymous_data(mutability.is_mut(), false).unwrap()) } +pub(crate) fn data_id_for_vtable<'tcx>( + tcx: TyCtxt<'tcx>, + cx: &mut ConstantCx, + module: &mut dyn Module, + ty: Ty<'tcx>, + trait_ref: Option>>, +) -> DataId { + let alloc_id = tcx.vtable_allocation((ty, trait_ref)); + data_id_for_alloc_id(cx, module, alloc_id, Mutability::Not) +} + fn data_id_for_static( tcx: TyCtxt<'_>, module: &mut dyn Module, @@ -327,7 +330,12 @@ fn data_id_for_static( } fn define_all_allocs(tcx: TyCtxt<'_>, module: &mut dyn Module, cx: &mut ConstantCx) { + let mut done = FxHashSet::default(); while let Some(todo_item) = cx.todo.pop() { + if !done.insert(todo_item) { + continue; + } + let (data_id, alloc, section_name) = match todo_item { TodoItem::Alloc(alloc_id) => { let alloc = match tcx.global_alloc(alloc_id) { @@ -358,10 +366,6 @@ fn define_all_allocs(tcx: TyCtxt<'_>, module: &mut dyn Module, cx: &mut Constant } }; - if cx.done.contains(&data_id) { - continue; - } - let mut data = DataDescription::new(); let alloc = alloc.inner(); data.set_align(alloc.align.bytes()); @@ -418,8 +422,7 @@ fn define_all_allocs(tcx: TyCtxt<'_>, module: &mut dyn Module, cx: &mut Constant data_id_for_alloc_id(cx, module, alloc_id, target_alloc.inner().mutability) } GlobalAlloc::VTable(ty, trait_ref) => { - let alloc_id = tcx.vtable_allocation((ty, trait_ref)); - data_id_for_alloc_id(cx, module, alloc_id, Mutability::Not) + data_id_for_vtable(tcx, cx, module, ty, trait_ref) } GlobalAlloc::Static(def_id) => { if tcx.codegen_fn_attrs(def_id).flags.contains(CodegenFnAttrFlags::THREAD_LOCAL) @@ -446,7 +449,6 @@ fn define_all_allocs(tcx: TyCtxt<'_>, module: &mut dyn Module, cx: &mut Constant } module.define_data(data_id, &data).unwrap(); - cx.done.insert(data_id); } assert!(cx.todo.is_empty(), "{:?}", cx.todo); diff --git a/src/vtable.rs b/src/vtable.rs index d2254d4c15e6..86ebf37d105f 100644 --- a/src/vtable.rs +++ b/src/vtable.rs @@ -2,7 +2,7 @@ //! //! See `rustc_codegen_ssa/src/meth.rs` for reference. -use crate::constant::data_id_for_alloc_id; +use crate::constant::data_id_for_vtable; use crate::prelude::*; pub(crate) fn vtable_memflags() -> MemFlags { @@ -92,12 +92,10 @@ pub(crate) fn get_vtable<'tcx>( ty: Ty<'tcx>, trait_ref: Option>, ) -> Value { - let alloc_id = fx.tcx.vtable_allocation((ty, trait_ref)); - let data_id = - data_id_for_alloc_id(&mut fx.constants_cx, &mut *fx.module, alloc_id, Mutability::Not); + let data_id = data_id_for_vtable(fx.tcx, &mut fx.constants_cx, fx.module, ty, trait_ref); let local_data_id = fx.module.declare_data_in_func(data_id, fx.bcx.func); if fx.clif_comments.enabled() { - fx.add_comment(local_data_id, format!("vtable: {:?}", alloc_id)); + fx.add_comment(local_data_id, "vtable"); } fx.bcx.ins().global_value(fx.pointer_type, local_data_id) } From ec5c8fec6c748b6eea3334637d4b6ce99e736e13 Mon Sep 17 00:00:00 2001 From: Mads Marquart Date: Mon, 18 Mar 2024 23:27:34 +0100 Subject: [PATCH 016/165] Add test for Apple's -weak_framework linker argument --- tests/run-pass-valgrind/osx-frameworks.rs | 21 --------------- tests/ui/linkage-attr/framework.omit.stderr | 8 ++++++ tests/ui/linkage-attr/framework.rs | 30 +++++++++++++++++++++ 3 files changed, 38 insertions(+), 21 deletions(-) delete mode 100644 tests/run-pass-valgrind/osx-frameworks.rs create mode 100644 tests/ui/linkage-attr/framework.omit.stderr create mode 100644 tests/ui/linkage-attr/framework.rs diff --git a/tests/run-pass-valgrind/osx-frameworks.rs b/tests/run-pass-valgrind/osx-frameworks.rs deleted file mode 100644 index 71465c0d1997..000000000000 --- a/tests/run-pass-valgrind/osx-frameworks.rs +++ /dev/null @@ -1,21 +0,0 @@ -//@ pretty-expanded FIXME #23616 - -#![feature(rustc_private)] - -extern crate libc; - -#[cfg(target_os = "macos")] -#[link(name = "CoreFoundation", kind = "framework")] -extern "C" { - fn CFRunLoopGetTypeID() -> libc::c_ulong; -} - -#[cfg(target_os = "macos")] -pub fn main() { - unsafe { - CFRunLoopGetTypeID(); - } -} - -#[cfg(not(target_os = "macos"))] -pub fn main() {} diff --git a/tests/ui/linkage-attr/framework.omit.stderr b/tests/ui/linkage-attr/framework.omit.stderr new file mode 100644 index 000000000000..5cb4d3914371 --- /dev/null +++ b/tests/ui/linkage-attr/framework.omit.stderr @@ -0,0 +1,8 @@ +error: linking with `cc` failed: exit status: 1 + | + ld: Undefined symbols: + _CFRunLoopGetTypeID, referenced from: + clang: error: linker command failed with exit code 1 (use -v to see invocation) + + +error: aborting due to 1 previous error diff --git a/tests/ui/linkage-attr/framework.rs b/tests/ui/linkage-attr/framework.rs new file mode 100644 index 000000000000..662ef4c429dd --- /dev/null +++ b/tests/ui/linkage-attr/framework.rs @@ -0,0 +1,30 @@ +// Check that linking frameworks on Apple platforms works. +//@ only-macos +//@ revisions: omit link weak both +//@ [omit]build-fail +//@ [link]run-pass +//@ [weak]run-pass +//@ [both]run-pass + +// The linker's exact error output changes between Xcode versions. +//@ compare-output-lines-by-subset +//@ normalize-stderr-test: "Undefined symbols for architecture .*" -> "ld: Undefined symbols:" +//@ normalize-stderr-test: "._CFRunLoopGetTypeID.," -> "_CFRunLoopGetTypeID," + +#![cfg_attr(any(weak, both), feature(link_arg_attribute))] + +#[cfg_attr(any(link, both), link(name = "CoreFoundation", kind = "framework"))] +#[cfg_attr( + any(weak, both), + link(name = "-weak_framework", kind = "link-arg", modifiers = "+verbatim"), + link(name = "CoreFoundation", kind = "link-arg", modifiers = "+verbatim") +)] +extern "C" { + fn CFRunLoopGetTypeID() -> core::ffi::c_ulong; +} + +pub fn main() { + unsafe { + CFRunLoopGetTypeID(); + } +} From 440fce19a1d412d560a13cfe1d98351e16703468 Mon Sep 17 00:00:00 2001 From: Mads Marquart Date: Tue, 12 Dec 2023 05:56:07 +0100 Subject: [PATCH 017/165] Ensure using `otool` that framework linking actually happened --- tests/run-make/link-framework/Makefile | 23 +++++++++++++++++++ .../link-framework/dep-link-framework.rs | 4 ++++ .../link-framework/dep-link-weak-framework.rs | 6 +++++ tests/run-make/link-framework/empty.rs | 1 + tests/run-make/link-framework/link-both.rs | 4 ++++ .../run-make/link-framework/link-framework.rs | 3 +++ .../link-framework/link-weak-framework.rs | 3 +++ 7 files changed, 44 insertions(+) create mode 100644 tests/run-make/link-framework/Makefile create mode 100644 tests/run-make/link-framework/dep-link-framework.rs create mode 100644 tests/run-make/link-framework/dep-link-weak-framework.rs create mode 100644 tests/run-make/link-framework/empty.rs create mode 100644 tests/run-make/link-framework/link-both.rs create mode 100644 tests/run-make/link-framework/link-framework.rs create mode 100644 tests/run-make/link-framework/link-weak-framework.rs diff --git a/tests/run-make/link-framework/Makefile b/tests/run-make/link-framework/Makefile new file mode 100644 index 000000000000..f33347ac7f8f --- /dev/null +++ b/tests/run-make/link-framework/Makefile @@ -0,0 +1,23 @@ +# only-macos +# +# Check that linking to a framework actually makes it to the linker. + +include ../tools.mk + +all: + $(RUSTC) dep-link-framework.rs + $(RUSTC) dep-link-weak-framework.rs + + $(RUSTC) empty.rs + otool -L $(TMPDIR)/no-link | $(CGREP) -v CoreFoundation + + $(RUSTC) link-framework.rs + otool -L $(TMPDIR)/link-framework | $(CGREP) CoreFoundation | $(CGREP) -v weak + + $(RUSTC) link-weak-framework.rs + otool -L $(TMPDIR)/link-weak-framework | $(CGREP) CoreFoundation | $(CGREP) weak + +# When linking the framework both normally, and weakly, the weak linking takes preference + + $(RUSTC) link-both.rs + otool -L $(TMPDIR)/link-both | $(CGREP) CoreFoundation | $(CGREP) weak diff --git a/tests/run-make/link-framework/dep-link-framework.rs b/tests/run-make/link-framework/dep-link-framework.rs new file mode 100644 index 000000000000..9bdeb2052d25 --- /dev/null +++ b/tests/run-make/link-framework/dep-link-framework.rs @@ -0,0 +1,4 @@ +#![crate_type = "rlib"] + +#[link(name = "CoreFoundation", kind = "framework")] +extern "C" {} diff --git a/tests/run-make/link-framework/dep-link-weak-framework.rs b/tests/run-make/link-framework/dep-link-weak-framework.rs new file mode 100644 index 000000000000..d3e1cf9c98f5 --- /dev/null +++ b/tests/run-make/link-framework/dep-link-weak-framework.rs @@ -0,0 +1,6 @@ +#![crate_type = "rlib"] +#![feature(link_arg_attribute)] + +#[link(name = "-weak_framework", kind = "link-arg", modifiers = "+verbatim")] +#[link(name = "CoreFoundation", kind = "link-arg", modifiers = "+verbatim")] +extern "C" {} diff --git a/tests/run-make/link-framework/empty.rs b/tests/run-make/link-framework/empty.rs new file mode 100644 index 000000000000..f328e4d9d04c --- /dev/null +++ b/tests/run-make/link-framework/empty.rs @@ -0,0 +1 @@ +fn main() {} diff --git a/tests/run-make/link-framework/link-both.rs b/tests/run-make/link-framework/link-both.rs new file mode 100644 index 000000000000..31fc79e1929a --- /dev/null +++ b/tests/run-make/link-framework/link-both.rs @@ -0,0 +1,4 @@ +extern crate dep_link_framework; +extern crate dep_link_weak_framework; + +fn main() {} diff --git a/tests/run-make/link-framework/link-framework.rs b/tests/run-make/link-framework/link-framework.rs new file mode 100644 index 000000000000..e33e830248eb --- /dev/null +++ b/tests/run-make/link-framework/link-framework.rs @@ -0,0 +1,3 @@ +extern crate dep_link_framework; + +fn main() {} diff --git a/tests/run-make/link-framework/link-weak-framework.rs b/tests/run-make/link-framework/link-weak-framework.rs new file mode 100644 index 000000000000..f0557f8013a4 --- /dev/null +++ b/tests/run-make/link-framework/link-weak-framework.rs @@ -0,0 +1,3 @@ +extern crate dep_link_weak_framework; + +fn main() {} From 06ef32c86251ba3a54ced4d8bf074f95ee30bc62 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 5 Mar 2024 17:50:07 +0000 Subject: [PATCH 018/165] Make ptr_guaranteed_cmp a rustc_intrinsic and favor its body over backends implementing it --- src/intrinsics/mod.rs | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/intrinsics/mod.rs b/src/intrinsics/mod.rs index c802d9bbefbe..25694af78f17 100644 --- a/src/intrinsics/mod.rs +++ b/src/intrinsics/mod.rs @@ -757,13 +757,6 @@ fn codegen_regular_intrinsic_call<'tcx>( ret.write_cvalue(fx, val); } - sym::ptr_guaranteed_cmp => { - intrinsic_args!(fx, args => (a, b); intrinsic); - - let val = crate::num::codegen_ptr_binop(fx, BinOp::Eq, a, b).load_scalar(fx); - ret.write_cvalue(fx, CValue::by_val(val, fx.layout_of(fx.tcx.types.u8))); - } - sym::caller_location => { intrinsic_args!(fx, args => (); intrinsic); From 3ec5042cf944cfb242408e45166e7da79eaf0692 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Thu, 22 Feb 2024 09:35:33 +0000 Subject: [PATCH 019/165] Avoid computing generic params or a param env for free const items --- compiler/rustc_hir_analysis/src/lib.rs | 10 ++++++++-- tests/ui/generic-const-items/hkl_where_bounds.rs | 14 ++++++++++++++ 2 files changed, 22 insertions(+), 2 deletions(-) create mode 100644 tests/ui/generic-const-items/hkl_where_bounds.rs diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs index 19ab2045cc55..ffebaaa24b68 100644 --- a/compiler/rustc_hir_analysis/src/lib.rs +++ b/compiler/rustc_hir_analysis/src/lib.rs @@ -102,8 +102,9 @@ use rustc_errors::ErrorGuaranteed; use rustc_hir as hir; use rustc_hir::def::DefKind; use rustc_middle::middle; +use rustc_middle::mir::interpret::GlobalId; use rustc_middle::query::Providers; -use rustc_middle::ty::{Ty, TyCtxt}; +use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_middle::util; use rustc_session::parse::feature_err; use rustc_span::{symbol::sym, Span}; @@ -187,7 +188,12 @@ pub fn check_crate(tcx: TyCtxt<'_>) -> Result<(), ErrorGuaranteed> { let def_kind = tcx.def_kind(item_def_id); match def_kind { DefKind::Static { .. } => tcx.ensure().eval_static_initializer(item_def_id), - DefKind::Const => tcx.ensure().const_eval_poly(item_def_id.into()), + DefKind::Const if tcx.generics_of(item_def_id).params.is_empty() => { + let instance = ty::Instance::new(item_def_id.into(), ty::GenericArgs::empty()); + let cid = GlobalId { instance, promoted: None }; + let param_env = ty::ParamEnv::reveal_all(); + tcx.ensure().eval_to_const_value_raw(param_env.and(cid)); + } _ => (), } }); diff --git a/tests/ui/generic-const-items/hkl_where_bounds.rs b/tests/ui/generic-const-items/hkl_where_bounds.rs new file mode 100644 index 000000000000..cded518312a0 --- /dev/null +++ b/tests/ui/generic-const-items/hkl_where_bounds.rs @@ -0,0 +1,14 @@ +//! Test that nonsense bounds prevent consts from being evaluated at all. +//@ check-pass + +#![feature(generic_const_items)] +#![allow(incomplete_features)] +trait Trait { + const ASSOC: u32; +} + +// rustfmt eats the where bound +#[rustfmt::skip] +const ASSOC: u32 = <&'static ()>::ASSOC where for<'a> &'a (): Trait; + +fn main() {} From 7f45f53204d9f3ec030b4a20afb479170f9a37d0 Mon Sep 17 00:00:00 2001 From: bohan Date: Wed, 20 Mar 2024 17:06:58 +0800 Subject: [PATCH 020/165] store segment and module in `UnresolvedImportError` --- compiler/rustc_resolve/src/imports.rs | 55 +++++++++++++++------- compiler/rustc_resolve/src/lib.rs | 13 +++++ tests/ui/cfg/diagnostics-same-crate.rs | 15 +++++- tests/ui/cfg/diagnostics-same-crate.stderr | 40 ++++++++++++---- 4 files changed, 98 insertions(+), 25 deletions(-) diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs index 9bf3e9ccabdf..48711f435186 100644 --- a/compiler/rustc_resolve/src/imports.rs +++ b/compiler/rustc_resolve/src/imports.rs @@ -19,6 +19,7 @@ use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::intern::Interned; use rustc_errors::{codes::*, pluralize, struct_span_code_err, Applicability, MultiSpan}; use rustc_hir::def::{self, DefKind, PartialRes}; +use rustc_hir::def_id::DefId; use rustc_middle::metadata::ModChild; use rustc_middle::metadata::Reexport; use rustc_middle::span_bug; @@ -250,6 +251,9 @@ struct UnresolvedImportError { note: Option, suggestion: Option, candidates: Option>, + segment: Option, + /// comes from `PathRes::Failed { module }` + module: Option, } // Reexports of the form `pub use foo as bar;` where `foo` is `extern crate foo;` @@ -579,16 +583,18 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { &import.kind, import.span, ); - let err = UnresolvedImportError { - span: import.span, - label: None, - note: None, - suggestion: None, - candidates: None, - }; // FIXME: there should be a better way of doing this than // formatting this as a string then checking for `::` if path.contains("::") { + let err = UnresolvedImportError { + span: import.span, + label: None, + note: None, + suggestion: None, + candidates: None, + segment: None, + module: None, + }; errors.push((*import, err)) } } @@ -738,15 +744,11 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { } } - match &import.kind { - ImportKind::Single { source, .. } => { - if let Some(ModuleOrUniformRoot::Module(module)) = import.imported_module.get() - && let Some(module) = module.opt_def_id() - { - self.find_cfg_stripped(&mut diag, &source.name, module) - } - } - _ => {} + if matches!(import.kind, ImportKind::Single { .. }) + && let Some(segment) = err.segment + && let Some(module) = err.module + { + self.find_cfg_stripped(&mut diag, &segment, module) } } @@ -916,10 +918,17 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { span, label, suggestion, + module, + segment_name, .. } => { if no_ambiguity { assert!(import.imported_module.get().is_none()); + let module = if let Some(ModuleOrUniformRoot::Module(m)) = module { + m.opt_def_id() + } else { + None + }; let err = match self.make_path_suggestion( span, import.module_path.clone(), @@ -935,6 +944,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { Applicability::MaybeIncorrect, )), candidates: None, + segment: Some(segment_name), + module, }, None => UnresolvedImportError { span, @@ -942,6 +953,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { note: None, suggestion, candidates: None, + segment: Some(segment_name), + module, }, }; return Some(err); @@ -990,6 +1003,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { note: None, suggestion: None, candidates: None, + segment: None, + module: None, }); } } @@ -1199,6 +1214,14 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { } else { None }, + module: import.imported_module.get().and_then(|module| { + if let ModuleOrUniformRoot::Module(m) = module { + m.opt_def_id() + } else { + None + } + }), + segment: Some(ident.name), }) } else { // `resolve_ident_in_module` reported a privacy error. diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index dfc2d029d4cf..aa03adb7097e 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -415,6 +415,19 @@ enum PathResult<'a> { label: String, suggestion: Option, is_error_from_last_segment: bool, + /// The final module being resolved, for instance: + /// + /// ```compile_fail + /// mod a { + /// mod b { + /// mod c {} + /// } + /// } + /// + /// use a::not_exist::c; + /// ``` + /// + /// In this case, `module` will point to `a`. module: Option>, /// The segment name of target segment_name: Symbol, diff --git a/tests/ui/cfg/diagnostics-same-crate.rs b/tests/ui/cfg/diagnostics-same-crate.rs index 2d0907c6dfb8..d9ff8d61e924 100644 --- a/tests/ui/cfg/diagnostics-same-crate.rs +++ b/tests/ui/cfg/diagnostics-same-crate.rs @@ -4,8 +4,12 @@ pub mod inner { //~^ NOTE found an item that was configured out #[cfg(FALSE)] - pub mod doesnt_exist { //~ NOTE found an item that was configured out + pub mod doesnt_exist { + //~^ NOTE found an item that was configured out + //~| NOTE found an item that was configured out + //~| NOTE found an item that was configured out pub fn hello() {} + pub mod hi {} } pub mod wrong { @@ -20,6 +24,15 @@ pub mod inner { } } +mod placeholder { + use super::inner::doesnt_exist; + //~^ ERROR unresolved import `super::inner::doesnt_exist` + //~| 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` +} + #[cfg(i_dont_exist_and_you_can_do_nothing_about_it)] pub fn vanished() {} diff --git a/tests/ui/cfg/diagnostics-same-crate.stderr b/tests/ui/cfg/diagnostics-same-crate.stderr index 62a9d132de09..83a44587238a 100644 --- a/tests/ui/cfg/diagnostics-same-crate.stderr +++ b/tests/ui/cfg/diagnostics-same-crate.stderr @@ -1,5 +1,29 @@ +error[E0432]: unresolved import `super::inner::doesnt_exist` + --> $DIR/diagnostics-same-crate.rs:28:9 + | +LL | use super::inner::doesnt_exist; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ no `doesnt_exist` in `inner` + | +note: found an item that was configured out + --> $DIR/diagnostics-same-crate.rs:7:13 + | +LL | pub mod doesnt_exist { + | ^^^^^^^^^^^^ + +error[E0432]: unresolved import `super::inner::doesnt_exist` + --> $DIR/diagnostics-same-crate.rs:31:23 + | +LL | use super::inner::doesnt_exist::hi; + | ^^^^^^^^^^^^ could not find `doesnt_exist` in `inner` + | +note: found an item that was configured out + --> $DIR/diagnostics-same-crate.rs:7:13 + | +LL | pub mod doesnt_exist { + | ^^^^^^^^^^^^ + error[E0433]: failed to resolve: could not find `doesnt_exist` in `inner` - --> $DIR/diagnostics-same-crate.rs:37:12 + --> $DIR/diagnostics-same-crate.rs:50:12 | LL | inner::doesnt_exist::hello(); | ^^^^^^^^^^^^ could not find `doesnt_exist` in `inner` @@ -11,7 +35,7 @@ LL | pub mod doesnt_exist { | ^^^^^^^^^^^^ error[E0425]: cannot find function `uwu` in module `inner` - --> $DIR/diagnostics-same-crate.rs:32:12 + --> $DIR/diagnostics-same-crate.rs:45:12 | LL | inner::uwu(); | ^^^ not found in `inner` @@ -23,31 +47,31 @@ LL | pub fn uwu() {} | ^^^ error[E0425]: cannot find function `meow` in module `inner::right` - --> $DIR/diagnostics-same-crate.rs:41:19 + --> $DIR/diagnostics-same-crate.rs:54:19 | LL | inner::right::meow(); | ^^^^ not found in `inner::right` | note: found an item that was configured out - --> $DIR/diagnostics-same-crate.rs:18:16 + --> $DIR/diagnostics-same-crate.rs:22:16 | 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 - --> $DIR/diagnostics-same-crate.rs:28:5 + --> $DIR/diagnostics-same-crate.rs:41:5 | LL | uwu(); | ^^^ not found in this scope error[E0425]: cannot find function `vanished` in this scope - --> $DIR/diagnostics-same-crate.rs:48:5 + --> $DIR/diagnostics-same-crate.rs:61:5 | LL | vanished(); | ^^^^^^^^ not found in this scope -error: aborting due to 5 previous errors +error: aborting due to 7 previous errors -Some errors have detailed explanations: E0425, E0433. +Some errors have detailed explanations: E0425, E0432, E0433. For more information about an error, try `rustc --explain E0425`. From eb752bc6a79e13eb779eeeba7f589aef58f80e9f Mon Sep 17 00:00:00 2001 From: BeetleFunk <124721033+BeetleFunk@users.noreply.github.com> Date: Thu, 21 Mar 2024 11:59:03 -0400 Subject: [PATCH 021/165] Avoid ICE when global_asm const operand fails to evaluate --- src/global_asm.rs | 34 ++++++++++++++++++++++------------ 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/src/global_asm.rs b/src/global_asm.rs index 44650898de89..5a0cd3990f2a 100644 --- a/src/global_asm.rs +++ b/src/global_asm.rs @@ -8,6 +8,7 @@ use std::sync::Arc; use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece}; use rustc_hir::{InlineAsmOperand, ItemId}; +use rustc_middle::mir::interpret::ErrorHandled; use rustc_session::config::{OutputFilenames, OutputType}; use rustc_target::asm::InlineAsmArch; @@ -32,18 +33,27 @@ pub(crate) fn codegen_global_asm_item(tcx: TyCtxt<'_>, global_asm: &mut String, InlineAsmTemplatePiece::Placeholder { operand_idx, modifier: _, span: op_sp } => { match asm.operands[operand_idx].0 { InlineAsmOperand::Const { ref anon_const } => { - let const_value = - tcx.const_eval_poly(anon_const.def_id.to_def_id()).unwrap_or_else( - |_| span_bug!(op_sp, "asm const cannot be resolved"), - ); - let ty = tcx.typeck_body(anon_const.body).node_type(anon_const.hir_id); - let string = rustc_codegen_ssa::common::asm_const_to_str( - tcx, - op_sp, - const_value, - RevealAllLayoutCx(tcx).layout_of(ty), - ); - global_asm.push_str(&string); + match tcx.const_eval_poly(anon_const.def_id.to_def_id()) { + Ok(const_value) => { + let ty = tcx + .typeck_body(anon_const.body) + .node_type(anon_const.hir_id); + let string = rustc_codegen_ssa::common::asm_const_to_str( + tcx, + op_sp, + const_value, + RevealAllLayoutCx(tcx).layout_of(ty), + ); + global_asm.push_str(&string); + } + Err(ErrorHandled::Reported { .. }) => { + // An error has already been reported and compilation is + // guaranteed to fail if execution hits this path. + } + Err(ErrorHandled::TooGeneric(_)) => { + span_bug!(op_sp, "asm const cannot be resolved; too generic"); + } + } } InlineAsmOperand::SymFn { anon_const } => { if cfg!(not(feature = "inline_asm_sym")) { From 00f4daa27673a07bf9ad20f4707d97bc1079450f Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Sun, 17 Mar 2024 22:26:39 -0400 Subject: [PATCH 022/165] 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 ++++++++ compiler/rustc_codegen_cranelift/src/base.rs | 24 ++---- .../rustc_codegen_gcc/example/mini_core.rs | 30 ++++++++ compiler/rustc_codegen_ssa/src/mir/block.rs | 6 +- compiler/rustc_hir/src/lang_items.rs | 19 +++++ compiler/rustc_middle/src/mir/terminator.rs | 73 +++++++++++++------ compiler/rustc_monomorphize/src/collector.rs | 21 +++--- compiler/rustc_span/src/symbol.rs | 18 +++++ library/core/src/panicking.rs | 69 +++++++++++++++++- src/tools/miri/src/shims/panic.rs | 12 ++- .../item-collection/implicit-panic-call.rs | 14 +++- tests/codegen/inherit_overflow.rs | 2 +- 12 files changed, 255 insertions(+), 63 deletions(-) diff --git a/compiler/rustc_codegen_cranelift/example/mini_core.rs b/compiler/rustc_codegen_cranelift/example/mini_core.rs index 39988cf64e54..1cee51319078 100644 --- a/compiler/rustc_codegen_cranelift/example/mini_core.rs +++ b/compiler/rustc_codegen_cranelift/example/mini_core.rs @@ -465,6 +465,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_bounds_check"] #[track_caller] fn panic_bounds_check(index: usize, len: usize) -> ! { diff --git a/compiler/rustc_codegen_cranelift/src/base.rs b/compiler/rustc_codegen_cranelift/src/base.rs index 2415c2c90b22..f597f084e70c 100644 --- a/compiler/rustc_codegen_cranelift/src/base.rs +++ b/compiler/rustc_codegen_cranelift/src/base.rs @@ -369,8 +369,14 @@ fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) { ); } _ => { - let msg_str = msg.description(); - codegen_panic(fx, msg_str, source_info); + let location = fx.get_caller_location(source_info).load_scalar(fx); + + codegen_panic_inner( + fx, + msg.panic_function(), + &[location], + Some(source_info.span), + ); } } } @@ -954,20 +960,6 @@ pub(crate) fn codegen_operand<'tcx>( } } -pub(crate) fn codegen_panic<'tcx>( - fx: &mut FunctionCx<'_, '_, 'tcx>, - msg_str: &str, - source_info: mir::SourceInfo, -) { - let location = fx.get_caller_location(source_info).load_scalar(fx); - - let msg_ptr = fx.anonymous_str(msg_str); - let msg_len = fx.bcx.ins().iconst(fx.pointer_type, i64::try_from(msg_str.len()).unwrap()); - let args = [msg_ptr, msg_len, location]; - - codegen_panic_inner(fx, rustc_hir::LangItem::Panic, &args, Some(source_info.span)); -} - pub(crate) fn codegen_panic_nounwind<'tcx>( fx: &mut FunctionCx<'_, '_, 'tcx>, msg_str: &str, diff --git a/compiler/rustc_codegen_gcc/example/mini_core.rs b/compiler/rustc_codegen_gcc/example/mini_core.rs index a868471ed1d4..4665009e191e 100644 --- a/compiler/rustc_codegen_gcc/example/mini_core.rs +++ b/compiler/rustc_codegen_gcc/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 { diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index 02e7bb05b770..3749133b7435 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -651,10 +651,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { (LangItem::PanicMisalignedPointerDereference, vec![required, found, location]) } _ => { - let msg = bx.const_str(msg.description()); - // It's `pub fn panic(expr: &str)`, with the wide reference being passed - // as two arguments, and `#[track_caller]` adds an implicit third argument. - (LangItem::Panic, vec![msg.0, msg.1, location]) + // It's `pub fn panic_...()` and `#[track_caller]` adds an implicit argument. + (msg.panic_function(), vec![location]) } }; diff --git a/compiler/rustc_hir/src/lang_items.rs b/compiler/rustc_hir/src/lang_items.rs index 5118bf5c3b7a..f1a2b4d91640 100644 --- a/compiler/rustc_hir/src/lang_items.rs +++ b/compiler/rustc_hir/src/lang_items.rs @@ -246,6 +246,25 @@ language_item_table! { PanicImpl, sym::panic_impl, panic_impl, Target::Fn, GenericRequirement::None; PanicCannotUnwind, sym::panic_cannot_unwind, panic_cannot_unwind, Target::Fn, GenericRequirement::Exact(0); PanicInCleanup, sym::panic_in_cleanup, panic_in_cleanup, Target::Fn, GenericRequirement::Exact(0); + /// Constant panic messages, used for codegen of MIR asserts. + PanicAddOverflow, sym::panic_const_add_overflow, panic_const_add_overflow, Target::Fn, GenericRequirement::None; + PanicSubOverflow, sym::panic_const_sub_overflow, panic_const_sub_overflow, Target::Fn, GenericRequirement::None; + PanicMulOverflow, sym::panic_const_mul_overflow, panic_const_mul_overflow, Target::Fn, GenericRequirement::None; + PanicDivOverflow, sym::panic_const_div_overflow, panic_const_div_overflow, Target::Fn, GenericRequirement::None; + PanicRemOverflow, sym::panic_const_rem_overflow, panic_const_rem_overflow, Target::Fn, GenericRequirement::None; + PanicNegOverflow, sym::panic_const_neg_overflow, panic_const_neg_overflow, Target::Fn, GenericRequirement::None; + PanicShrOverflow, sym::panic_const_shr_overflow, panic_const_shr_overflow, Target::Fn, GenericRequirement::None; + PanicShlOverflow, sym::panic_const_shl_overflow, panic_const_shl_overflow, Target::Fn, GenericRequirement::None; + PanicDivZero, sym::panic_const_div_by_zero, panic_const_div_by_zero, Target::Fn, GenericRequirement::None; + PanicRemZero, sym::panic_const_rem_by_zero, panic_const_rem_by_zero, Target::Fn, GenericRequirement::None; + PanicCoroutineResumed, sym::panic_const_coroutine_resumed, panic_const_coroutine_resumed, Target::Fn, GenericRequirement::None; + PanicAsyncFnResumed, sym::panic_const_async_fn_resumed, panic_const_async_fn_resumed, Target::Fn, GenericRequirement::None; + PanicAsyncGenFnResumed, sym::panic_const_async_gen_fn_resumed, panic_const_async_gen_fn_resumed, Target::Fn, GenericRequirement::None; + PanicGenFnNone, sym::panic_const_gen_fn_none, panic_const_gen_fn_none, Target::Fn, GenericRequirement::None; + PanicCoroutineResumedPanic, sym::panic_const_coroutine_resumed_panic, panic_const_coroutine_resumed_panic, Target::Fn, GenericRequirement::None; + PanicAsyncFnResumedPanic, sym::panic_const_async_fn_resumed_panic, panic_const_async_fn_resumed_panic, Target::Fn, GenericRequirement::None; + PanicAsyncGenFnResumedPanic, sym::panic_const_async_gen_fn_resumed_panic, panic_const_async_gen_fn_resumed_panic, Target::Fn, GenericRequirement::None; + PanicGenFnNonePanic, sym::panic_const_gen_fn_none_panic, panic_const_gen_fn_none_panic, Target::Fn, GenericRequirement::None; /// libstd panic entry point. Necessary for const eval to be able to catch it BeginPanic, sym::begin_panic, begin_panic_fn, Target::Fn, GenericRequirement::None; diff --git a/compiler/rustc_middle/src/mir/terminator.rs b/compiler/rustc_middle/src/mir/terminator.rs index 94f8cba6fb57..f116347cc2ba 100644 --- a/compiler/rustc_middle/src/mir/terminator.rs +++ b/compiler/rustc_middle/src/mir/terminator.rs @@ -149,44 +149,45 @@ impl AssertKind { matches!(self, OverflowNeg(..) | Overflow(Add | Sub | Mul | Shl | Shr, ..)) } - /// Get the message that is printed at runtime when this assertion fails. + /// Get the lang item that is invoked to print a static message when this assert fires. /// /// The caller is expected to handle `BoundsCheck` and `MisalignedPointerDereference` by /// invoking the appropriate lang item (panic_bounds_check/panic_misaligned_pointer_dereference) - /// instead of printing a static message. - pub fn description(&self) -> &'static str { + /// instead of printing a static message. Those have dynamic arguments that aren't present for + /// the rest of the messages here. + pub fn panic_function(&self) -> LangItem { use AssertKind::*; match self { - Overflow(BinOp::Add, _, _) => "attempt to add with overflow", - Overflow(BinOp::Sub, _, _) => "attempt to subtract with overflow", - Overflow(BinOp::Mul, _, _) => "attempt to multiply with overflow", - Overflow(BinOp::Div, _, _) => "attempt to divide with overflow", - Overflow(BinOp::Rem, _, _) => "attempt to calculate the remainder with overflow", - OverflowNeg(_) => "attempt to negate with overflow", - Overflow(BinOp::Shr, _, _) => "attempt to shift right with overflow", - Overflow(BinOp::Shl, _, _) => "attempt to shift left with overflow", + Overflow(BinOp::Add, _, _) => LangItem::PanicAddOverflow, + Overflow(BinOp::Sub, _, _) => LangItem::PanicSubOverflow, + Overflow(BinOp::Mul, _, _) => LangItem::PanicMulOverflow, + Overflow(BinOp::Div, _, _) => LangItem::PanicDivOverflow, + Overflow(BinOp::Rem, _, _) => LangItem::PanicRemOverflow, + OverflowNeg(_) => LangItem::PanicNegOverflow, + Overflow(BinOp::Shr, _, _) => LangItem::PanicShrOverflow, + Overflow(BinOp::Shl, _, _) => LangItem::PanicShlOverflow, Overflow(op, _, _) => bug!("{:?} cannot overflow", op), - DivisionByZero(_) => "attempt to divide by zero", - RemainderByZero(_) => "attempt to calculate the remainder with a divisor of zero", - ResumedAfterReturn(CoroutineKind::Coroutine(_)) => "coroutine resumed after completion", + DivisionByZero(_) => LangItem::PanicDivZero, + RemainderByZero(_) => LangItem::PanicRemZero, + ResumedAfterReturn(CoroutineKind::Coroutine(_)) => LangItem::PanicCoroutineResumed, ResumedAfterReturn(CoroutineKind::Desugared(CoroutineDesugaring::Async, _)) => { - "`async fn` resumed after completion" + LangItem::PanicAsyncFnResumed } ResumedAfterReturn(CoroutineKind::Desugared(CoroutineDesugaring::AsyncGen, _)) => { - "`async gen fn` resumed after completion" + LangItem::PanicAsyncGenFnResumed } ResumedAfterReturn(CoroutineKind::Desugared(CoroutineDesugaring::Gen, _)) => { - "`gen fn` should just keep returning `None` after completion" + LangItem::PanicGenFnNone } - ResumedAfterPanic(CoroutineKind::Coroutine(_)) => "coroutine resumed after panicking", + ResumedAfterPanic(CoroutineKind::Coroutine(_)) => LangItem::PanicCoroutineResumedPanic, ResumedAfterPanic(CoroutineKind::Desugared(CoroutineDesugaring::Async, _)) => { - "`async fn` resumed after panicking" + LangItem::PanicAsyncFnResumedPanic } ResumedAfterPanic(CoroutineKind::Desugared(CoroutineDesugaring::AsyncGen, _)) => { - "`async gen fn` resumed after panicking" + LangItem::PanicAsyncGenFnResumedPanic } ResumedAfterPanic(CoroutineKind::Desugared(CoroutineDesugaring::Gen, _)) => { - "`gen fn` should just keep returning `None` after panicking" + LangItem::PanicGenFnNonePanic } BoundsCheck { .. } | MisalignedPointerDereference { .. } => { @@ -198,7 +199,7 @@ impl AssertKind { /// Format the message arguments for the `assert(cond, msg..)` terminator in MIR printing. /// /// Needs to be kept in sync with the run-time behavior (which is defined by - /// `AssertKind::description` and the lang items mentioned in its docs). + /// `AssertKind::panic_function` and the lang items mentioned in its docs). /// Note that we deliberately show more details here than we do at runtime, such as the actual /// numbers that overflowed -- it is much easier to do so here than at runtime. pub fn fmt_assert_args(&self, f: &mut W) -> fmt::Result @@ -246,20 +247,44 @@ impl AssertKind { Overflow(BinOp::Shl, _, r) => { write!(f, "\"attempt to shift left by `{{}}`, which would overflow\", {r:?}") } + Overflow(op, _, _) => bug!("{:?} cannot overflow", op), MisalignedPointerDereference { required, found } => { write!( f, "\"misaligned pointer dereference: address must be a multiple of {{}} but is {{}}\", {required:?}, {found:?}" ) } - _ => write!(f, "\"{}\"", self.description()), + ResumedAfterReturn(CoroutineKind::Coroutine(_)) => { + write!(f, "\"coroutine resumed after completion\"") + } + ResumedAfterReturn(CoroutineKind::Desugared(CoroutineDesugaring::Async, _)) => { + write!(f, "\"`async fn` resumed after completion\"") + } + ResumedAfterReturn(CoroutineKind::Desugared(CoroutineDesugaring::AsyncGen, _)) => { + write!(f, "\"`async gen fn` resumed after completion\"") + } + ResumedAfterReturn(CoroutineKind::Desugared(CoroutineDesugaring::Gen, _)) => { + write!(f, "\"`gen fn` should just keep returning `None` after completion\"") + } + ResumedAfterPanic(CoroutineKind::Coroutine(_)) => { + write!(f, "\"coroutine resumed after panicking\"") + } + ResumedAfterPanic(CoroutineKind::Desugared(CoroutineDesugaring::Async, _)) => { + write!(f, "\"`async fn` resumed after panicking\"") + } + ResumedAfterPanic(CoroutineKind::Desugared(CoroutineDesugaring::AsyncGen, _)) => { + write!(f, "\"`async gen fn` resumed after panicking\"") + } + ResumedAfterPanic(CoroutineKind::Desugared(CoroutineDesugaring::Gen, _)) => { + write!(f, "\"`gen fn` should just keep returning `None` after panicking\"") + } } } /// Format the diagnostic message for use in a lint (e.g. when the assertion fails during const-eval). /// /// Needs to be kept in sync with the run-time behavior (which is defined by - /// `AssertKind::description` and the lang items mentioned in its docs). + /// `AssertKind::panic_function` and the lang items mentioned in its docs). /// Note that we deliberately show more details here than we do at runtime, such as the actual /// numbers that overflowed -- it is much easier to do so here than at runtime. pub fn diagnostic_message(&self) -> DiagMessage { diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index 1a18a84b3585..94057c25aebf 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -971,16 +971,17 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirUsedCollector<'a, 'tcx> { } } } - mir::TerminatorKind::Assert { ref msg, .. } => { - let lang_item = match &**msg { - mir::AssertKind::BoundsCheck { .. } => LangItem::PanicBoundsCheck, - mir::AssertKind::MisalignedPointerDereference { .. } => { - LangItem::PanicMisalignedPointerDereference - } - _ => LangItem::Panic, - }; - push_mono_lang_item(self, lang_item); - } + mir::TerminatorKind::Assert { ref msg, .. } => match &**msg { + mir::AssertKind::BoundsCheck { .. } => { + push_mono_lang_item(self, LangItem::PanicBoundsCheck); + } + mir::AssertKind::MisalignedPointerDereference { .. } => { + push_mono_lang_item(self, LangItem::PanicMisalignedPointerDereference); + } + _ => { + push_mono_lang_item(self, msg.panic_function()); + } + }, mir::TerminatorKind::UnwindTerminate(reason) => { push_mono_lang_item(self, reason.lang_item()); } diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 8b35087a0056..0bac4d2e2fe2 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1297,6 +1297,24 @@ symbols! { panic_abort, panic_bounds_check, panic_cannot_unwind, + panic_const_add_overflow, + panic_const_async_fn_resumed, + panic_const_async_fn_resumed_panic, + panic_const_async_gen_fn_resumed, + panic_const_async_gen_fn_resumed_panic, + panic_const_coroutine_resumed, + panic_const_coroutine_resumed_panic, + panic_const_div_by_zero, + panic_const_div_overflow, + panic_const_gen_fn_none, + panic_const_gen_fn_none_panic, + panic_const_mul_overflow, + panic_const_neg_overflow, + panic_const_rem_by_zero, + panic_const_rem_overflow, + panic_const_shl_overflow, + panic_const_shr_overflow, + panic_const_sub_overflow, panic_fmt, panic_handler, panic_impl, diff --git a/library/core/src/panicking.rs b/library/core/src/panicking.rs index 9e8dac888166..cbb0a7d61db0 100644 --- a/library/core/src/panicking.rs +++ b/library/core/src/panicking.rs @@ -130,17 +130,80 @@ pub const fn panic_nounwind_fmt(fmt: fmt::Arguments<'_>, force_no_backtrace: boo #[cfg_attr(feature = "panic_immediate_abort", inline)] #[track_caller] #[rustc_const_unstable(feature = "panic_internals", issue = "none")] -#[lang = "panic"] // needed by codegen for panic on overflow and other `Assert` MIR terminators +#[lang = "panic"] // used by lints and miri for panics pub const fn panic(expr: &'static str) -> ! { - // Use Arguments::new_v1 instead of format_args!("{expr}") to potentially + // Use Arguments::new_const instead of format_args!("{expr}") to potentially // reduce size overhead. The format_args! macro uses str's Display trait to // write expr, which calls Formatter::pad, which must accommodate string // truncation and padding (even though none is used here). Using - // Arguments::new_v1 may allow the compiler to omit Formatter::pad from the + // Arguments::new_const may allow the compiler to omit Formatter::pad from the // output binary, saving up to a few kilobytes. panic_fmt(fmt::Arguments::new_const(&[expr])); } +// We generate functions for usage by compiler-generated assertions. +// +// Placing these functions in libcore means that all Rust programs can generate a jump into this +// code rather than expanding to panic("...") above, which adds extra bloat to call sites (for the +// constant string argument's pointer and length). +// +// This is especially important when this code is called often (e.g., with -Coverflow-checks) for +// reducing binary size impact. +macro_rules! panic_const { + ($($lang:ident = $message:expr,)+) => { + #[cfg(not(bootstrap))] + pub mod panic_const { + use super::*; + + $( + /// This is a panic called with a message that's a result of a MIR-produced Assert. + // + // never inline unless panic_immediate_abort to avoid code + // bloat at the call sites as much as possible + #[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold)] + #[cfg_attr(feature = "panic_immediate_abort", inline)] + #[track_caller] + #[rustc_const_unstable(feature = "panic_internals", issue = "none")] + #[lang = stringify!($lang)] + pub const fn $lang() -> ! { + // Use Arguments::new_const instead of format_args!("{expr}") to potentially + // reduce size overhead. The format_args! macro uses str's Display trait to + // write expr, which calls Formatter::pad, which must accommodate string + // truncation and padding (even though none is used here). Using + // Arguments::new_const may allow the compiler to omit Formatter::pad from the + // output binary, saving up to a few kilobytes. + panic_fmt(fmt::Arguments::new_const(&[$message])); + } + )+ + } + } +} + +// Unfortunately this set of strings is replicated here and in a few places in the compiler in +// slightly different forms. It's not clear if there's a good way to deduplicate without adding +// special cases to the compiler (e.g., a const generic function wouldn't have a single definition +// shared across crates, which is exactly what we want here). +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", + panic_const_coroutine_resumed = "coroutine resumed after completion", + panic_const_async_fn_resumed = "`async fn` resumed after completion", + panic_const_async_gen_fn_resumed = "`async gen fn` resumed after completion", + panic_const_gen_fn_none = "`gen fn` should just keep returning `None` after completion", + panic_const_coroutine_resumed_panic = "coroutine resumed after panicking", + panic_const_async_fn_resumed_panic = "`async fn` resumed after panicking", + panic_const_async_gen_fn_resumed_panic = "`async gen fn` resumed after panicking", + panic_const_gen_fn_none_panic = "`gen fn` should just keep returning `None` after panicking", +} + /// Like `panic`, but without unwinding and track_caller to reduce the impact on codesize on the caller. /// If you want `#[track_caller]` for nicer errors, call `panic_nounwind_fmt` directly. #[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold)] diff --git a/src/tools/miri/src/shims/panic.rs b/src/tools/miri/src/shims/panic.rs index 34b6481dd387..bb31ef733cf9 100644 --- a/src/tools/miri/src/shims/panic.rs +++ b/src/tools/miri/src/shims/panic.rs @@ -256,8 +256,16 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { } _ => { - // Forward everything else to `panic` lang item. - this.start_panic(msg.description(), unwind)?; + // Call the lang item associated with this message. + let fn_item = this.tcx.require_lang_item(msg.panic_function(), None); + let instance = ty::Instance::mono(this.tcx.tcx, fn_item); + this.call_function( + instance, + Abi::Rust, + &[], + None, + StackPopCleanup::Goto { ret: None, unwind }, + )?; } } Ok(()) diff --git a/tests/codegen-units/item-collection/implicit-panic-call.rs b/tests/codegen-units/item-collection/implicit-panic-call.rs index 2e0d742307a8..b348b4acc248 100644 --- a/tests/codegen-units/item-collection/implicit-panic-call.rs +++ b/tests/codegen-units/item-collection/implicit-panic-call.rs @@ -16,10 +16,17 @@ struct Location<'a> { _col: u32, } -#[lang = "panic"] +#[lang = "panic_const_div_by_zero"] #[inline] #[track_caller] -fn panic(_: &'static str) -> ! { +fn panic_div_zero() -> ! { + loop {} +} + +#[lang = "panic_const_div_overflow"] +#[inline] +#[track_caller] +fn panic_div_overflow() -> ! { loop {} } @@ -55,4 +62,5 @@ pub fn foo() { //~ MONO_ITEM fn foo //~ MONO_ITEM fn ::div -//~ MONO_ITEM fn panic +//~ MONO_ITEM fn panic_div_zero +//~ MONO_ITEM fn panic_div_overflow diff --git a/tests/codegen/inherit_overflow.rs b/tests/codegen/inherit_overflow.rs index f08071aaa618..e4a5ef39fc54 100644 --- a/tests/codegen/inherit_overflow.rs +++ b/tests/codegen/inherit_overflow.rs @@ -4,7 +4,7 @@ //@[NOASSERT] compile-flags: -Coverflow-checks=off // CHECK-LABEL: define{{.*}} @assertion -// ASSERT: call void @{{.*4core9panicking5panic}} +// ASSERT: call void @{{.*4core9panicking11panic_const24panic_const_add_overflow}} // NOASSERT: ret i8 0 #[no_mangle] pub fn assertion() -> u8 { From dfc1bd751674a3715221a8bb6791043d1a2e0664 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 21 Mar 2024 16:50:21 -0400 Subject: [PATCH 023/165] Eagerly convert some ctors to use their specialized ctors --- src/abi/mod.rs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/abi/mod.rs b/src/abi/mod.rs index 6e846d721f2e..cdfbbe7b6744 100644 --- a/src/abi/mod.rs +++ b/src/abi/mod.rs @@ -663,11 +663,7 @@ pub(crate) fn codegen_drop<'tcx>( let arg_value = drop_place.place_ref( fx, - fx.layout_of(Ty::new_ref( - fx.tcx, - fx.tcx.lifetimes.re_erased, - TypeAndMut { ty, mutbl: crate::rustc_hir::Mutability::Mut }, - )), + fx.layout_of(Ty::new_mut_ref(fx.tcx, fx.tcx.lifetimes.re_erased, ty)), ); let arg_value = adjust_arg_for_abi(fx, arg_value, &fn_abi.args[0], true); From 155b46aeb2076c622965204a5aa84a32e2c32a55 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 21 Mar 2024 17:11:06 -0400 Subject: [PATCH 024/165] Programmatically convert some of the pat ctors --- src/common.rs | 4 ++-- src/unsize.rs | 6 ++---- src/value_and_place.rs | 9 ++------- 3 files changed, 6 insertions(+), 13 deletions(-) diff --git a/src/common.rs b/src/common.rs index 7e29d407a1fa..a7c3d68ff8cf 100644 --- a/src/common.rs +++ b/src/common.rs @@ -69,7 +69,7 @@ fn clif_type_from_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Option unimplemented!("f16_f128"), }, ty::FnPtr(_) => pointer_ty(tcx), - ty::RawPtr(TypeAndMut { ty: pointee_ty, mutbl: _ }) | ty::Ref(_, pointee_ty, _) => { + ty::RawPtr(pointee_ty, _) | ty::Ref(_, pointee_ty, _) => { if has_ptr_meta(tcx, *pointee_ty) { return None; } else { @@ -89,7 +89,7 @@ fn clif_pair_type_from_ty<'tcx>( ty::Tuple(types) if types.len() == 2 => { (clif_type_from_ty(tcx, types[0])?, clif_type_from_ty(tcx, types[1])?) } - ty::RawPtr(TypeAndMut { ty: pointee_ty, mutbl: _ }) | ty::Ref(_, pointee_ty, _) => { + ty::RawPtr(pointee_ty, _) | ty::Ref(_, pointee_ty, _) => { if has_ptr_meta(tcx, *pointee_ty) { (pointer_ty(tcx), pointer_ty(tcx)) } else { diff --git a/src/unsize.rs b/src/unsize.rs index 7b61dc64cb1a..f33bacb99a3f 100644 --- a/src/unsize.rs +++ b/src/unsize.rs @@ -70,10 +70,8 @@ fn unsize_ptr<'tcx>( ) -> (Value, Value) { match (&src_layout.ty.kind(), &dst_layout.ty.kind()) { (&ty::Ref(_, a, _), &ty::Ref(_, b, _)) - | (&ty::Ref(_, a, _), &ty::RawPtr(ty::TypeAndMut { ty: b, .. })) - | (&ty::RawPtr(ty::TypeAndMut { ty: a, .. }), &ty::RawPtr(ty::TypeAndMut { ty: b, .. })) => { - (src, unsized_info(fx, *a, *b, old_info)) - } + | (&ty::Ref(_, a, _), &ty::RawPtr(b, _)) + | (&ty::RawPtr(a, _), &ty::RawPtr(b, _)) => (src, unsized_info(fx, *a, *b, old_info)), (&ty::Adt(def_a, _), &ty::Adt(def_b, _)) => { assert_eq!(def_a, def_b); diff --git a/src/value_and_place.rs b/src/value_and_place.rs index f016e6950d48..fc5b88a54fe5 100644 --- a/src/value_and_place.rs +++ b/src/value_and_place.rs @@ -865,15 +865,10 @@ pub(crate) fn assert_assignable<'tcx>( return; } match (from_ty.kind(), to_ty.kind()) { - (ty::Ref(_, a, _), ty::Ref(_, b, _)) - | ( - ty::RawPtr(TypeAndMut { ty: a, mutbl: _ }), - ty::RawPtr(TypeAndMut { ty: b, mutbl: _ }), - ) => { + (ty::Ref(_, a, _), ty::Ref(_, b, _)) | (ty::RawPtr(a, _), ty::RawPtr(b, _)) => { assert_assignable(fx, *a, *b, limit - 1); } - (ty::Ref(_, a, _), ty::RawPtr(TypeAndMut { ty: b, mutbl: _ })) - | (ty::RawPtr(TypeAndMut { ty: a, mutbl: _ }), ty::Ref(_, b, _)) => { + (ty::Ref(_, a, _), ty::RawPtr(b, _)) | (ty::RawPtr(a, _), ty::Ref(_, b, _)) => { assert_assignable(fx, *a, *b, limit - 1); } (ty::FnPtr(_), ty::FnPtr(_)) => { From ae0e6e22f09fbfbcf7b1252d80c90ad8a423e10d Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 22 Mar 2024 18:34:00 +0000 Subject: [PATCH 025/165] Update to Cranelift 0.106 --- Cargo.lock | 56 +++++++++++++++++++++++++++--------------------------- Cargo.toml | 12 ++++++------ 2 files changed, 34 insertions(+), 34 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e308cf80284a..8fdc1941de88 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -46,18 +46,18 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "cranelift-bforest" -version = "0.105.2" +version = "0.106.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9515fcc42b6cb5137f76b84c1a6f819782d0cf12473d145d3bc5cd67eedc8bc2" +checksum = "6a535eb1cf5a6003197dc569320c40c1cb2d2f97ef5d5348eebf067f20957381" dependencies = [ "cranelift-entity", ] [[package]] name = "cranelift-codegen" -version = "0.105.2" +version = "0.106.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ad827c6071bfe6d22de1bc331296a29f9ddc506ff926d8415b435ec6a6efce0" +checksum = "11b5066db32cec1492573827183af2142d2d88fe85a83cfc9e73f0f63d3788d4" dependencies = [ "bumpalo", "cranelift-bforest", @@ -76,39 +76,39 @@ dependencies = [ [[package]] name = "cranelift-codegen-meta" -version = "0.105.2" +version = "0.106.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10e6b36237a9ca2ce2fb4cc7741d418a080afa1327402138412ef85d5367bef1" +checksum = "64942e5774308e835fbad4dd25f253105412c90324631910e1ec27963147bddb" dependencies = [ "cranelift-codegen-shared", ] [[package]] name = "cranelift-codegen-shared" -version = "0.105.2" +version = "0.106.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c36bf4bfb86898a94ccfa773a1f86e8a5346b1983ff72059bdd2db4600325251" +checksum = "c39c33db9a86dd6d8d04166a10c53deb477aeea3500eaaefca682e4eda9bb986" [[package]] name = "cranelift-control" -version = "0.105.2" +version = "0.106.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cbf36560e7a6bd1409ca91e7b43b2cc7ed8429f343d7605eadf9046e8fac0d0" +checksum = "4b7fc4937613aea3156a0538800a17bf56f345a5da2e79ae3df58488c93d867f" dependencies = [ "arbitrary", ] [[package]] name = "cranelift-entity" -version = "0.105.2" +version = "0.106.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a71e11061a75b1184c09bea97c026a88f08b59ade96a7bb1f259d4ea0df2e942" +checksum = "f85575e79a153ce1ddbfb7fe1813519b4bfe1eb200cc9c8353b45ad123ae4d36" [[package]] name = "cranelift-frontend" -version = "0.105.2" +version = "0.106.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af5d4da63143ee3485c7bcedde0a818727d737d1083484a0ceedb8950c89e495" +checksum = "bbc31d6c0ab2249fe0c21e988256b42f5f401ab2673b4fc40076c82a698bdfb9" dependencies = [ "cranelift-codegen", "log", @@ -118,15 +118,15 @@ dependencies = [ [[package]] name = "cranelift-isle" -version = "0.105.2" +version = "0.106.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "457a9832b089e26f5eea70dcf49bed8ec6edafed630ce7c83161f24d46ab8085" +checksum = "dc14f37e3314c0e4c53779c2f46753bf242efff76ee9473757a1fff3b495ad37" [[package]] name = "cranelift-jit" -version = "0.105.2" +version = "0.106.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0af95fe68d5a10919012c8db82b1d59820405b8001c8c6d05f94b08031334fa9" +checksum = "cfdd1942f3233176a68c285380dbc84ff0440246a1bce308611c0a385b56ab18" dependencies = [ "anyhow", "cranelift-codegen", @@ -144,9 +144,9 @@ dependencies = [ [[package]] name = "cranelift-module" -version = "0.105.2" +version = "0.106.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11b0b201fa10a4014062d4c56c307c8d18fdf9a84cb5279efe6080241f42c7a7" +checksum = "121b2b5a16912554a1b9aace75b9b21eca49f28e33cbfbad4786dd9bc5361a5c" dependencies = [ "anyhow", "cranelift-codegen", @@ -155,9 +155,9 @@ dependencies = [ [[package]] name = "cranelift-native" -version = "0.105.2" +version = "0.106.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b490d579df1ce365e1ea359e24ed86d82289fa785153327c2f6a69a59a731e4" +checksum = "2ea5375f76ab31f9800a23fb2b440810286a6f669a3eb467cdd7ff255ea64268" dependencies = [ "cranelift-codegen", "libc", @@ -166,9 +166,9 @@ dependencies = [ [[package]] name = "cranelift-object" -version = "0.105.2" +version = "0.106.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb7e821ac6db471bcdbd004e5a4fa0d374f1046bd3a2ce278c332e0b0c01ca63" +checksum = "f34e04419ab41661e973d90a73aa7b12771455394dae7a69b101a9b7e7589db7" dependencies = [ "anyhow", "cranelift-codegen", @@ -392,9 +392,9 @@ dependencies = [ [[package]] name = "target-lexicon" -version = "0.12.12" +version = "0.12.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14c39fd04924ca3a864207c66fc2cd7d22d7c016007f9ce846cbb9326331930a" +checksum = "e1fc403891a21bcfb7c37834ba66a547a8f402146eba7265b5a6d88059c9ff2f" [[package]] name = "unicode-ident" @@ -410,9 +410,9 @@ checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" [[package]] name = "wasmtime-jit-icache-coherence" -version = "18.0.2" +version = "19.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33f4121cb29dda08139b2824a734dd095d83ce843f2d613a84eb580b9cfc17ac" +checksum = "2796e4b4989db62899d2117e1e0258b839d088c044591b14e3a0396e7b3ae53a" dependencies = [ "cfg-if", "libc", diff --git a/Cargo.toml b/Cargo.toml index c0b9e27b179d..d8a855b03830 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.105.2", default-features = false, features = ["std", "unwind", "all-arch"] } -cranelift-frontend = { version = "0.105.2" } -cranelift-module = { version = "0.105.2" } -cranelift-native = { version = "0.105.2" } -cranelift-jit = { version = "0.105.2", optional = true } -cranelift-object = { version = "0.105.2" } +cranelift-codegen = { version = "0.106.0", default-features = false, features = ["std", "unwind", "all-arch"] } +cranelift-frontend = { version = "0.106.0" } +cranelift-module = { version = "0.106.0" } +cranelift-native = { version = "0.106.0" } +cranelift-jit = { version = "0.106.0", optional = true } +cranelift-object = { version = "0.106.0" } target-lexicon = "0.12.0" gimli = { version = "0.28", default-features = false, features = ["write"]} object = { version = "0.32", default-features = false, features = ["std", "read_core", "write", "archive", "coff", "elf", "macho", "pe"] } From e2cc8ebd87da39cef9dde3ab209826a1f5880b5a Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 22 Mar 2024 18:51:59 +0000 Subject: [PATCH 026/165] Rustup to rustc 1.79.0-nightly (0ad927c0c 2024-03-21) --- rust-toolchain | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-toolchain b/rust-toolchain index 31aec1131e52..1901f699b9dc 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2024-03-18" +channel = "nightly-2024-03-22" components = ["rust-src", "rustc-dev", "llvm-tools"] From 593228373d175650bb1033814f515df2e15a489d Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 22 Mar 2024 18:58:36 +0000 Subject: [PATCH 027/165] Remove workaround for UB in cranelift-jit that has been fixed --- src/constant.rs | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/constant.rs b/src/constant.rs index c40005993941..690e8fe0e20a 100644 --- a/src/constant.rs +++ b/src/constant.rs @@ -388,13 +388,7 @@ fn define_all_allocs(tcx: TyCtxt<'_>, module: &mut dyn Module, cx: &mut Constant } let bytes = alloc.inspect_with_uninit_and_ptr_outside_interpreter(0..alloc.len()).to_vec(); - if bytes.is_empty() { - // FIXME(bytecodealliance/wasmtime#7918) cranelift-jit has a bug where it causes UB on - // empty data objects - data.define(Box::new([0])); - } else { - data.define(bytes.into_boxed_slice()); - } + data.define(bytes.into_boxed_slice()); for &(offset, prov) in alloc.provenance().ptrs().iter() { let alloc_id = prov.alloc_id(); From 2624e9183d8f3587bac325d6f7a9777c36f2f45b Mon Sep 17 00:00:00 2001 From: Jacob Pratt Date: Thu, 21 Sep 2023 00:06:22 +0000 Subject: [PATCH 028/165] Soft-destabilize `RustcEncodable`/`RustcDecodable` --- library/core/src/macros/mod.rs | 20 +++++++++++++------ library/core/src/prelude/v1.rs | 7 ++++++- library/std/src/prelude/v1.rs | 7 ++++++- .../pretty-expanded/input.rs | 16 ++++++--------- 4 files changed, 32 insertions(+), 18 deletions(-) diff --git a/library/core/src/macros/mod.rs b/library/core/src/macros/mod.rs index a78842c8f8d6..574a357b44ab 100644 --- a/library/core/src/macros/mod.rs +++ b/library/core/src/macros/mod.rs @@ -1726,20 +1726,28 @@ pub(crate) mod builtin { builtin # deref($pat) } - /// Unstable implementation detail of the `rustc` compiler, do not use. + /// Derive macro for `rustc-serialize`. Should not be used in new code. #[rustc_builtin_macro] - #[stable(feature = "rust1", since = "1.0.0")] - #[allow_internal_unstable(core_intrinsics, libstd_sys_internals, rt)] + #[unstable( + feature = "rustc_encodable_decodable", + issue = "none", + soft, + reason = "derive macro for `rustc-serialize`; should not be used in new code" + )] #[deprecated(since = "1.52.0", note = "rustc-serialize is deprecated and no longer supported")] #[doc(hidden)] // While technically stable, using it is unstable, and deprecated. Hide it. pub macro RustcDecodable($item:item) { /* compiler built-in */ } - /// Unstable implementation detail of the `rustc` compiler, do not use. + /// Derive macro for `rustc-serialize`. Should not be used in new code. #[rustc_builtin_macro] - #[stable(feature = "rust1", since = "1.0.0")] - #[allow_internal_unstable(core_intrinsics, rt)] + #[unstable( + feature = "rustc_encodable_decodable", + issue = "none", + soft, + reason = "derive macro for `rustc-serialize`; should not be used in new code" + )] #[deprecated(since = "1.52.0", note = "rustc-serialize is deprecated and no longer supported")] #[doc(hidden)] // While technically stable, using it is unstable, and deprecated. Hide it. pub macro RustcEncodable($item:item) { diff --git a/library/core/src/prelude/v1.rs b/library/core/src/prelude/v1.rs index 29f73bb4942a..698aaa6bbcfd 100644 --- a/library/core/src/prelude/v1.rs +++ b/library/core/src/prelude/v1.rs @@ -69,7 +69,12 @@ pub use crate::{ pub use crate::concat_bytes; // Do not `doc(inline)` these `doc(hidden)` items. -#[stable(feature = "builtin_macro_prelude", since = "1.38.0")] +#[unstable( + feature = "rustc_encodable_decodable", + issue = "none", + soft, + reason = "unstable implementation detail of the `rustc` compiler, do not use" +)] #[allow(deprecated)] pub use crate::macros::builtin::{RustcDecodable, RustcEncodable}; diff --git a/library/std/src/prelude/v1.rs b/library/std/src/prelude/v1.rs index 36fa4e88b5bd..0559f34c1b4c 100644 --- a/library/std/src/prelude/v1.rs +++ b/library/std/src/prelude/v1.rs @@ -53,7 +53,12 @@ pub use core::prelude::v1::{ pub use core::prelude::v1::concat_bytes; // Do not `doc(inline)` these `doc(hidden)` items. -#[stable(feature = "builtin_macro_prelude", since = "1.38.0")] +#[unstable( + feature = "rustc_encodable_decodable", + issue = "none", + soft, + reason = "unstable implementation detail of the `rustc` compiler, do not use" +)] #[allow(deprecated)] pub use core::prelude::v1::{RustcDecodable, RustcEncodable}; diff --git a/tests/run-make-fulldeps/pretty-expanded/input.rs b/tests/run-make-fulldeps/pretty-expanded/input.rs index af3d75b3bf21..02b235068a1d 100644 --- a/tests/run-make-fulldeps/pretty-expanded/input.rs +++ b/tests/run-make-fulldeps/pretty-expanded/input.rs @@ -1,12 +1,8 @@ -#[crate_type="lib"] - // #13544 -extern crate rustc_serialize; - -#[derive(RustcEncodable)] pub struct A; -#[derive(RustcEncodable)] pub struct B(isize); -#[derive(RustcEncodable)] pub struct C { x: isize } -#[derive(RustcEncodable)] pub enum D {} -#[derive(RustcEncodable)] pub enum E { y } -#[derive(RustcEncodable)] pub enum F { z(isize) } +#[derive(Debug)] pub struct A; +#[derive(Debug)] pub struct B(isize); +#[derive(Debug)] pub struct C { x: isize } +#[derive(Debug)] pub enum D {} +#[derive(Debug)] pub enum E { y } +#[derive(Debug)] pub enum F { z(isize) } From fbf21c5763430d7acdfe9843d8bc7fc2253be334 Mon Sep 17 00:00:00 2001 From: Jacob Pratt Date: Thu, 21 Sep 2023 00:56:59 +0000 Subject: [PATCH 029/165] Remove RustcEncodable/Decodable from 2024 prelude --- library/core/src/prelude/{v1.rs => common.rs} | 14 +--- library/core/src/prelude/mod.rs | 34 ++++++++-- library/std/src/prelude/{v1.rs => common.rs} | 14 +--- library/std/src/prelude/mod.rs | 26 ++++++-- .../feature-gate-rustc_encodable_decodable.rs | 16 +++++ ...ture-gate-rustc_encodable_decodable.stderr | 66 +++++++++++++++++++ 6 files changed, 136 insertions(+), 34 deletions(-) rename library/core/src/prelude/{v1.rs => common.rs} (89%) rename library/std/src/prelude/{v1.rs => common.rs} (89%) create mode 100644 tests/ui/feature-gates/feature-gate-rustc_encodable_decodable.rs create mode 100644 tests/ui/feature-gates/feature-gate-rustc_encodable_decodable.stderr diff --git a/library/core/src/prelude/v1.rs b/library/core/src/prelude/common.rs similarity index 89% rename from library/core/src/prelude/v1.rs rename to library/core/src/prelude/common.rs index 698aaa6bbcfd..b98f3a4659b1 100644 --- a/library/core/src/prelude/v1.rs +++ b/library/core/src/prelude/common.rs @@ -1,9 +1,7 @@ -//! The first version of the core prelude. +//! Items common to the prelude of all editions. //! //! See the [module-level documentation](super) for more. -#![stable(feature = "core_prelude", since = "1.4.0")] - // Re-exported core operators #[stable(feature = "core_prelude", since = "1.4.0")] #[doc(no_inline)] @@ -68,16 +66,6 @@ pub use crate::{ #[doc(no_inline)] pub use crate::concat_bytes; -// Do not `doc(inline)` these `doc(hidden)` items. -#[unstable( - feature = "rustc_encodable_decodable", - issue = "none", - soft, - reason = "unstable implementation detail of the `rustc` compiler, do not use" -)] -#[allow(deprecated)] -pub use crate::macros::builtin::{RustcDecodable, RustcEncodable}; - // Do not `doc(no_inline)` so that they become doc items on their own // (no public module for them to be re-exported from). #[stable(feature = "builtin_macro_prelude", since = "1.38.0")] diff --git a/library/core/src/prelude/mod.rs b/library/core/src/prelude/mod.rs index b4791c2c022e..ca33ef160e88 100644 --- a/library/core/src/prelude/mod.rs +++ b/library/core/src/prelude/mod.rs @@ -6,7 +6,26 @@ #![stable(feature = "core_prelude", since = "1.4.0")] -pub mod v1; +mod common; + +/// The first version of the prelude of The Rust Standard Library. +/// +/// See the [module-level documentation](self) for more. +#[stable(feature = "rust1", since = "1.0.0")] +pub mod v1 { + #[stable(feature = "rust1", since = "1.0.0")] + pub use super::common::*; + + // Do not `doc(inline)` these `doc(hidden)` items. + #[unstable( + feature = "rustc_encodable_decodable", + issue = "none", + soft, + reason = "derive macro for `rustc-serialize`; should not be used in new code" + )] + #[allow(deprecated)] + pub use crate::macros::builtin::{RustcDecodable, RustcEncodable}; +} /// The 2015 version of the core prelude. /// @@ -46,14 +65,21 @@ pub mod rust_2021 { pub use crate::convert::{TryFrom, TryInto}; } -/// The 2024 edition of the core prelude. +/// The 2024 version of the core prelude. /// /// See the [module-level documentation](self) for more. #[unstable(feature = "prelude_2024", issue = "121042")] pub mod rust_2024 { - #[unstable(feature = "prelude_2024", issue = "121042")] + #[stable(feature = "rust1", since = "1.0.0")] + pub use super::common::*; + + #[stable(feature = "prelude_2021", since = "1.55.0")] #[doc(no_inline)] - pub use super::rust_2021::*; + pub use crate::iter::FromIterator; + + #[stable(feature = "prelude_2021", since = "1.55.0")] + #[doc(no_inline)] + pub use crate::convert::{TryFrom, TryInto}; #[unstable(feature = "prelude_2024", issue = "121042")] #[doc(no_inline)] diff --git a/library/std/src/prelude/v1.rs b/library/std/src/prelude/common.rs similarity index 89% rename from library/std/src/prelude/v1.rs rename to library/std/src/prelude/common.rs index 0559f34c1b4c..f61e04e02b66 100644 --- a/library/std/src/prelude/v1.rs +++ b/library/std/src/prelude/common.rs @@ -1,9 +1,7 @@ -//! The first version of the prelude of The Rust Standard Library. +//! Items common to the prelude of all editions. //! //! See the [module-level documentation](super) for more. -#![stable(feature = "rust1", since = "1.0.0")] - // Re-exported core operators #[stable(feature = "rust1", since = "1.0.0")] #[doc(no_inline)] @@ -52,16 +50,6 @@ pub use core::prelude::v1::{ #[doc(no_inline)] pub use core::prelude::v1::concat_bytes; -// Do not `doc(inline)` these `doc(hidden)` items. -#[unstable( - feature = "rustc_encodable_decodable", - issue = "none", - soft, - reason = "unstable implementation detail of the `rustc` compiler, do not use" -)] -#[allow(deprecated)] -pub use core::prelude::v1::{RustcDecodable, RustcEncodable}; - // Do not `doc(no_inline)` so that they become doc items on their own // (no public module for them to be re-exported from). #[stable(feature = "builtin_macro_prelude", since = "1.38.0")] diff --git a/library/std/src/prelude/mod.rs b/library/std/src/prelude/mod.rs index 7d44d2e4b5da..0bdbab716adb 100644 --- a/library/std/src/prelude/mod.rs +++ b/library/std/src/prelude/mod.rs @@ -93,7 +93,26 @@ #![stable(feature = "rust1", since = "1.0.0")] -pub mod v1; +mod common; + +/// The first version of the prelude of The Rust Standard Library. +/// +/// See the [module-level documentation](self) for more. +#[stable(feature = "rust1", since = "1.0.0")] +pub mod v1 { + #[stable(feature = "rust1", since = "1.0.0")] + pub use super::common::*; + + // Do not `doc(inline)` these `doc(hidden)` items. + #[unstable( + feature = "rustc_encodable_decodable", + issue = "none", + soft, + reason = "derive macro for `rustc-serialize`; should not be used in new code" + )] + #[allow(deprecated)] + pub use core::prelude::v1::{RustcDecodable, RustcEncodable}; +} /// The 2015 version of the prelude of The Rust Standard Library. /// @@ -134,9 +153,8 @@ pub mod rust_2021 { /// See the [module-level documentation](self) for more. #[unstable(feature = "prelude_2024", issue = "121042")] pub mod rust_2024 { - #[unstable(feature = "prelude_2024", issue = "121042")] - #[doc(no_inline)] - pub use super::v1::*; + #[stable(feature = "rust1", since = "1.0.0")] + pub use super::common::*; #[unstable(feature = "prelude_2024", issue = "121042")] #[doc(no_inline)] diff --git a/tests/ui/feature-gates/feature-gate-rustc_encodable_decodable.rs b/tests/ui/feature-gates/feature-gate-rustc_encodable_decodable.rs new file mode 100644 index 000000000000..13f8fd5fe22a --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-rustc_encodable_decodable.rs @@ -0,0 +1,16 @@ +#![crate_type = "lib"] + +// This isn't intended to compile, so it's easiest to just ignore this error. +extern crate rustc_serialize; //~ERROR can't find crate for `rustc_serialize` + +#[derive( + RustcEncodable, + //~^ ERROR use of unstable library feature 'rustc_encodable_decodable' + //~^^ WARNING this was previously accepted by the compiler + //~^^^ WARNING use of deprecated macro `RustcEncodable` + RustcDecodable, + //~^ ERROR use of unstable library feature 'rustc_encodable_decodable' + //~^^ WARNING this was previously accepted by the compiler + //~^^^ WARNING use of deprecated macro `RustcDecodable` +)] +struct S; diff --git a/tests/ui/feature-gates/feature-gate-rustc_encodable_decodable.stderr b/tests/ui/feature-gates/feature-gate-rustc_encodable_decodable.stderr new file mode 100644 index 000000000000..02b74dacf4da --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-rustc_encodable_decodable.stderr @@ -0,0 +1,66 @@ +error[E0463]: can't find crate for `rustc_serialize` + --> $DIR/feature-gate-rustc_encodable_decodable.rs:4:1 + | +LL | extern crate rustc_serialize; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't find crate + | + = help: maybe you need to install the missing components with: `rustup component add rust-src rustc-dev llvm-tools-preview` + +error: use of unstable library feature 'rustc_encodable_decodable': derive macro for `rustc-serialize`; should not be used in new code + --> $DIR/feature-gate-rustc_encodable_decodable.rs:7:5 + | +LL | RustcEncodable, + | ^^^^^^^^^^^^^^ + | + = 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 #64266 + = note: `#[deny(soft_unstable)]` on by default + +warning: use of deprecated macro `RustcEncodable`: rustc-serialize is deprecated and no longer supported + --> $DIR/feature-gate-rustc_encodable_decodable.rs:7:5 + | +LL | RustcEncodable, + | ^^^^^^^^^^^^^^ + | + = note: `#[warn(deprecated)]` on by default + +error: use of unstable library feature 'rustc_encodable_decodable': derive macro for `rustc-serialize`; should not be used in new code + --> $DIR/feature-gate-rustc_encodable_decodable.rs:11:5 + | +LL | RustcDecodable, + | ^^^^^^^^^^^^^^ + | + = 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 #64266 + +warning: use of deprecated macro `RustcDecodable`: rustc-serialize is deprecated and no longer supported + --> $DIR/feature-gate-rustc_encodable_decodable.rs:11:5 + | +LL | RustcDecodable, + | ^^^^^^^^^^^^^^ + +error: aborting due to 3 previous errors; 2 warnings emitted + +For more information about this error, try `rustc --explain E0463`. +Future incompatibility report: Future breakage diagnostic: +error: use of unstable library feature 'rustc_encodable_decodable': derive macro for `rustc-serialize`; should not be used in new code + --> $DIR/feature-gate-rustc_encodable_decodable.rs:7:5 + | +LL | RustcEncodable, + | ^^^^^^^^^^^^^^ + | + = 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 #64266 + = note: `#[deny(soft_unstable)]` on by default + +Future breakage diagnostic: +error: use of unstable library feature 'rustc_encodable_decodable': derive macro for `rustc-serialize`; should not be used in new code + --> $DIR/feature-gate-rustc_encodable_decodable.rs:11:5 + | +LL | RustcDecodable, + | ^^^^^^^^^^^^^^ + | + = 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 #64266 + = note: `#[deny(soft_unstable)]` on by default + From 6b85f075ccbf20ac10a8a2148e8b75ce14329c74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Le=C3=B3n=20Orell=20Valerian=20Liehr?= Date: Wed, 6 Mar 2024 19:18:30 +0100 Subject: [PATCH 030/165] Small tweaks to the linting code for bare trait object types --- .../src/hir_ty_lowering/lint.rs | 147 +++++++++--------- .../src/hir_ty_lowering/mod.rs | 4 +- 2 files changed, 79 insertions(+), 72 deletions(-) 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 80be563686a7..ba6adfffd2e6 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs @@ -9,8 +9,83 @@ use rustc_trait_selection::traits::error_reporting::suggestions::NextTypeParamNa use super::HirTyLowerer; impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { + /// Prohibit or lint against *bare* trait object types depending on the edition. + /// + /// *Bare* trait object types are ones that aren't preceeded by the keyword `dyn`. + /// In edition 2021 and onward we emit a hard error for them. + pub(super) fn prohibit_or_lint_bare_trait_object_ty( + &self, + self_ty: &hir::Ty<'_>, + in_path: bool, + ) { + let tcx = self.tcx(); + + let hir::TyKind::TraitObject([poly_trait_ref, ..], _, TraitObjectSyntax::None) = + self_ty.kind + else { + return; + }; + + let needs_bracket = in_path + && !tcx + .sess + .source_map() + .span_to_prev_source(self_ty.span) + .ok() + .is_some_and(|s| s.trim_end().ends_with('<')); + + let is_global = poly_trait_ref.trait_ref.path.is_global(); + + let mut sugg = vec![( + self_ty.span.shrink_to_lo(), + format!( + "{}dyn {}", + if needs_bracket { "<" } else { "" }, + if is_global { "(" } else { "" }, + ), + )]; + + if is_global || needs_bracket { + sugg.push(( + self_ty.span.shrink_to_hi(), + format!( + "{}{}", + if is_global { ")" } else { "" }, + if needs_bracket { ">" } else { "" }, + ), + )); + } + + if self_ty.span.edition().at_least_rust_2021() { + 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); + if self_ty.span.can_be_used_for_suggestions() + && !self.maybe_suggest_impl_trait(self_ty, &mut diag) + { + diag.multipart_suggestion_verbose(label, sugg, Applicability::MachineApplicable); + } + // Check if the impl trait that we are considering is an impl of a local trait. + self.maybe_suggest_blanket_trait_impl(self_ty, &mut diag); + diag.stash(self_ty.span, StashKey::TraitMissingMethod); + } else { + let msg = "trait objects without an explicit `dyn` are deprecated"; + tcx.node_span_lint(BARE_TRAIT_OBJECTS, self_ty.hir_id, self_ty.span, msg, |lint| { + if self_ty.span.can_be_used_for_suggestions() { + lint.multipart_suggestion_verbose( + "if this is an object-safe trait, use `dyn`", + sugg, + Applicability::MachineApplicable, + ); + } + self.maybe_suggest_blanket_trait_impl(self_ty, lint); + }); + } + } + /// Make sure that we are in the condition to suggest the blanket implementation. - pub(super) fn maybe_lint_blanket_trait_impl( + fn maybe_suggest_blanket_trait_impl( &self, self_ty: &hir::Ty<'_>, diag: &mut Diag<'_, G>, @@ -75,7 +150,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { } /// Make sure that we are in the condition to suggest `impl Trait`. - fn maybe_lint_impl_trait(&self, self_ty: &hir::Ty<'_>, diag: &mut Diag<'_>) -> bool { + fn maybe_suggest_impl_trait(&self, self_ty: &hir::Ty<'_>, diag: &mut Diag<'_>) -> bool { let tcx = self.tcx(); let parent_id = tcx.hir().get_parent_item(self_ty.hir_id).def_id; let (sig, generics, owner) = match tcx.hir_node_by_def_id(parent_id) { @@ -185,72 +260,4 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { } false } - - pub(super) fn maybe_lint_bare_trait(&self, self_ty: &hir::Ty<'_>, in_path: bool) { - let tcx = self.tcx(); - if let hir::TyKind::TraitObject([poly_trait_ref, ..], _, TraitObjectSyntax::None) = - self_ty.kind - { - let needs_bracket = in_path - && !tcx - .sess - .source_map() - .span_to_prev_source(self_ty.span) - .ok() - .is_some_and(|s| s.trim_end().ends_with('<')); - - let is_global = poly_trait_ref.trait_ref.path.is_global(); - - let mut sugg = Vec::from_iter([( - self_ty.span.shrink_to_lo(), - format!( - "{}dyn {}", - if needs_bracket { "<" } else { "" }, - if is_global { "(" } else { "" }, - ), - )]); - - if is_global || needs_bracket { - sugg.push(( - self_ty.span.shrink_to_hi(), - format!( - "{}{}", - if is_global { ")" } else { "" }, - if needs_bracket { ">" } else { "" }, - ), - )); - } - - if self_ty.span.edition().at_least_rust_2021() { - 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); - if self_ty.span.can_be_used_for_suggestions() - && !self.maybe_lint_impl_trait(self_ty, &mut diag) - { - diag.multipart_suggestion_verbose( - label, - sugg, - Applicability::MachineApplicable, - ); - } - // check if the impl trait that we are considering is a impl of a local trait - self.maybe_lint_blanket_trait_impl(self_ty, &mut diag); - diag.stash(self_ty.span, StashKey::TraitMissingMethod); - } else { - let msg = "trait objects without an explicit `dyn` are deprecated"; - tcx.node_span_lint(BARE_TRAIT_OBJECTS, self_ty.hir_id, self_ty.span, msg, |lint| { - if self_ty.span.can_be_used_for_suggestions() { - lint.multipart_suggestion_verbose( - "if this is an object-safe trait, use `dyn`", - sugg, - Applicability::MachineApplicable, - ); - } - self.maybe_lint_blanket_trait_impl(self_ty, lint); - }); - } - } - } } 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 109e00d4f24e..ae12229a52e8 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -2341,12 +2341,12 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { ) } hir::TyKind::TraitObject(bounds, lifetime, repr) => { - self.maybe_lint_bare_trait(hir_ty, in_path); + self.prohibit_or_lint_bare_trait_object_ty(hir_ty, in_path); + let repr = match repr { TraitObjectSyntax::Dyn | TraitObjectSyntax::None => ty::Dyn, TraitObjectSyntax::DynStar => ty::DynStar, }; - self.lower_trait_object_ty( hir_ty.span, hir_ty.hir_id, From d3d77a8733e9a37c1dba4810e86a3e1a50dc5d92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Le=C3=B3n=20Orell=20Valerian=20Liehr?= Date: Wed, 6 Mar 2024 23:45:36 +0100 Subject: [PATCH 031/165] Update docs of hir::TypeBinding --- compiler/rustc_hir/src/hir.rs | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 162ec16fabcd..820976489339 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -2289,21 +2289,15 @@ pub enum ImplItemKind<'hir> { Type(&'hir Ty<'hir>), } -/// Bind a type to an associated type (i.e., `A = Foo`). +/// An associated item binding. /// -/// Bindings like `A: Debug` are represented as a special type `A = -/// $::Debug` that is understood by the HIR ty lowering code. +/// ### Examples /// -/// FIXME(alexreg): why have a separate type for the binding case, -/// wouldn't it be better to make the `ty` field an enum like the -/// following? -/// -/// ```ignore (pseudo-rust) -/// enum TypeBindingKind { -/// Equals(...), -/// Binding(...), -/// } -/// ``` +/// * `Trait` +/// * `Trait = Ty>` +/// * `Trait` +/// * `Trait` (under feature `associated_const_equality`) +/// * `Trait` (under feature `return_type_notation`) #[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct TypeBinding<'hir> { pub hir_id: HirId, @@ -2336,7 +2330,7 @@ impl<'hir> From for Term<'hir> { pub enum TypeBindingKind<'hir> { /// E.g., `Foo`. Constraint { bounds: &'hir [GenericBound<'hir>] }, - /// E.g., `Foo`, `Foo` + /// E.g., `Foo`. Equality { term: Term<'hir> }, } From 22b9e960d9357f83110d42a31b7a2d47e6ae25e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Le=C3=B3n=20Orell=20Valerian=20Liehr?= Date: Wed, 6 Mar 2024 23:48:10 +0100 Subject: [PATCH 032/165] Suggest assoc ty bound on bare dyn trait in eq constraint --- .../src/hir_ty_lowering/lint.rs | 38 ++++++++ .../suggest-assoc-ty-bound-on-eq-bound.rs | 30 ++++++ .../suggest-assoc-ty-bound-on-eq-bound.stderr | 91 +++++++++++++++++++ 3 files changed, 159 insertions(+) create mode 100644 tests/ui/associated-type-bounds/suggest-assoc-ty-bound-on-eq-bound.rs create mode 100644 tests/ui/associated-type-bounds/suggest-assoc-ty-bound-on-eq-bound.stderr 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 ba6adfffd2e6..8c35da3ac7b7 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs @@ -64,10 +64,12 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { if self_ty.span.can_be_used_for_suggestions() && !self.maybe_suggest_impl_trait(self_ty, &mut diag) { + // FIXME: Only emit this suggestion if the trait is object safe. diag.multipart_suggestion_verbose(label, sugg, Applicability::MachineApplicable); } // Check if the impl trait that we are considering is an impl of a local trait. self.maybe_suggest_blanket_trait_impl(self_ty, &mut diag); + self.maybe_suggest_assoc_ty_bound(self_ty, &mut diag); diag.stash(self_ty.span, StashKey::TraitMissingMethod); } else { let msg = "trait objects without an explicit `dyn` are deprecated"; @@ -153,6 +155,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { fn maybe_suggest_impl_trait(&self, self_ty: &hir::Ty<'_>, diag: &mut Diag<'_>) -> bool { let tcx = self.tcx(); let parent_id = tcx.hir().get_parent_item(self_ty.hir_id).def_id; + // FIXME: If `type_alias_impl_trait` is enabled, also look for `Trait0` + // and suggest `Trait0`. let (sig, generics, owner) = match tcx.hir_node_by_def_id(parent_id) { hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn(sig, generics, _), .. }) => { (sig, generics, None) @@ -260,4 +264,38 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { } false } + + fn maybe_suggest_assoc_ty_bound(&self, self_ty: &hir::Ty<'_>, diag: &mut Diag<'_>) { + let mut parents = self.tcx().hir().parent_iter(self_ty.hir_id); + + if let Some((_, hir::Node::TypeBinding(binding))) = parents.next() + && let hir::TypeBindingKind::Equality { term: hir::Term::Ty(obj_ty) } = binding.kind + { + if let Some((_, hir::Node::TraitRef(..))) = parents.next() + && let Some((_, hir::Node::Ty(ty))) = parents.next() + && let hir::TyKind::TraitObject(..) = ty.kind + { + // Assoc ty bounds aren't permitted inside trait object types. + return; + } + + let lo = if binding.gen_args.span_ext.is_dummy() { + binding.ident.span + } else { + binding.gen_args.span_ext + }; + let hi = obj_ty.span; + + if !lo.eq_ctxt(hi) { + return; + } + + diag.span_suggestion_verbose( + lo.between(hi), + "you might have meant to write a bound here", + ": ", + Applicability::MaybeIncorrect, + ); + } + } } diff --git a/tests/ui/associated-type-bounds/suggest-assoc-ty-bound-on-eq-bound.rs b/tests/ui/associated-type-bounds/suggest-assoc-ty-bound-on-eq-bound.rs new file mode 100644 index 000000000000..7df042d5f88e --- /dev/null +++ b/tests/ui/associated-type-bounds/suggest-assoc-ty-bound-on-eq-bound.rs @@ -0,0 +1,30 @@ +// Regression test for issue #105056. +//@ edition: 2021 + +fn f(_: impl Trait) {} +//~^ ERROR trait objects must include the `dyn` keyword +//~| HELP add `dyn` keyword before this trait +//~| HELP you might have meant to write a bound here +//~| ERROR the trait `Copy` cannot be made into an object + +fn g(_: impl Trait) {} +//~^ ERROR trait objects must include the `dyn` keyword +//~| HELP add `dyn` keyword before this trait +//~| HELP you might have meant to write a bound here +//~| ERROR only auto traits can be used as additional traits in a trait object +//~| HELP consider creating a new trait +//~| ERROR the trait `Eq` cannot be made into an object + +fn h(_: impl Trait = 'static + for<'a> Fn(&'a ())>) {} +//~^ ERROR trait objects must include the `dyn` keyword +//~| HELP add `dyn` keyword before this trait +//~| HELP you might have meant to write a bound here + +// Don't suggest assoc ty bound in trait object types, that's not valid: +type Obj = dyn Trait; +//~^ ERROR trait objects must include the `dyn` keyword +//~| HELP add `dyn` keyword before this trait + +trait Trait { type T; } + +fn main() {} diff --git a/tests/ui/associated-type-bounds/suggest-assoc-ty-bound-on-eq-bound.stderr b/tests/ui/associated-type-bounds/suggest-assoc-ty-bound-on-eq-bound.stderr new file mode 100644 index 000000000000..13be2162c52b --- /dev/null +++ b/tests/ui/associated-type-bounds/suggest-assoc-ty-bound-on-eq-bound.stderr @@ -0,0 +1,91 @@ +error[E0038]: the trait `Copy` cannot be made into an object + --> $DIR/suggest-assoc-ty-bound-on-eq-bound.rs:4:20 + | +LL | fn f(_: impl Trait) {} + | ^^^^^^^^ `Copy` cannot be made into an object + | + = note: the trait cannot be made into an object because it requires `Self: Sized` + = note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit + +error[E0225]: only auto traits can be used as additional traits in a trait object + --> $DIR/suggest-assoc-ty-bound-on-eq-bound.rs:10:42 + | +LL | fn g(_: impl Trait) {} + | --------------- ^^ additional non-auto trait + | | + | first non-auto trait + | + = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: Debug + Eq {}` + = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit + +error[E0038]: the trait `Eq` cannot be made into an object + --> $DIR/suggest-assoc-ty-bound-on-eq-bound.rs:10:24 + | +LL | fn g(_: impl Trait) {} + | ^^^^^^^^^^^^^^^^^^^^ `Eq` cannot be made into an object + | +note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit + --> $SRC_DIR/core/src/cmp.rs:LL:COL + | + = note: the trait cannot be made into an object because it uses `Self` as a type parameter + +error[E0782]: trait objects must include the `dyn` keyword + --> $DIR/suggest-assoc-ty-bound-on-eq-bound.rs:4:24 + | +LL | fn f(_: impl Trait) {} + | ^^^^ + | +help: add `dyn` keyword before this trait + | +LL | fn f(_: impl Trait) {} + | +++ +help: you might have meant to write a bound here + | +LL | fn f(_: impl Trait) {} + | ~ + +error[E0782]: trait objects must include the `dyn` keyword + --> $DIR/suggest-assoc-ty-bound-on-eq-bound.rs:10:24 + | +LL | fn g(_: impl Trait) {} + | ^^^^^^^^^^^^^^^^^^^^ + | +help: add `dyn` keyword before this trait + | +LL | fn g(_: impl Trait) {} + | +++ +help: you might have meant to write a bound here + | +LL | fn g(_: impl Trait) {} + | ~ + +error[E0782]: trait objects must include the `dyn` keyword + --> $DIR/suggest-assoc-ty-bound-on-eq-bound.rs:18:26 + | +LL | fn h(_: impl Trait = 'static + for<'a> Fn(&'a ())>) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: add `dyn` keyword before this trait + | +LL | fn h(_: impl Trait = dyn 'static + for<'a> Fn(&'a ())>) {} + | +++ +help: you might have meant to write a bound here + | +LL | fn h(_: impl Trait: 'static + for<'a> Fn(&'a ())>) {} + | ~ + +error[E0782]: trait objects must include the `dyn` keyword + --> $DIR/suggest-assoc-ty-bound-on-eq-bound.rs:24:26 + | +LL | type Obj = dyn Trait; + | ^^^^^ + | +help: add `dyn` keyword before this trait + | +LL | type Obj = dyn Trait; + | +++ + +error: aborting due to 7 previous errors + +Some errors have detailed explanations: E0038, E0225, E0782. +For more information about an error, try `rustc --explain E0038`. From 3879acbec090b36454c0384cd8602047b806f47a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Le=C3=B3n=20Orell=20Valerian=20Liehr?= Date: Wed, 6 Mar 2024 23:49:05 +0100 Subject: [PATCH 033/165] Suggest assoc ty bound on lifetime in eq constraint --- compiler/rustc_parse/messages.ftl | 10 ++++---- compiler/rustc_parse/src/errors.rs | 17 +++++++++---- compiler/rustc_parse/src/parser/path.rs | 24 ++++++++++++++----- .../recover-assoc-lifetime-constraint.rs | 2 +- .../recover-assoc-lifetime-constraint.stderr | 17 ++++++++----- 5 files changed, 49 insertions(+), 21 deletions(-) diff --git a/compiler/rustc_parse/messages.ftl b/compiler/rustc_parse/messages.ftl index e1d26f090e0d..960558f1ff62 100644 --- a/compiler/rustc_parse/messages.ftl +++ b/compiler/rustc_parse/messages.ftl @@ -14,10 +14,6 @@ parse_array_index_offset_of = array indexing not supported in offset_of parse_assignment_else_not_allowed = ... else {"{"} ... {"}"} is not allowed -parse_assoc_lifetime = associated lifetimes are not supported - .label = the lifetime is given here - .help = if you meant to specify a trait object, write `dyn Trait + 'lifetime` - parse_associated_static_item_not_allowed = associated `static` items are not allowed parse_async_block_in_2015 = `async` blocks are only allowed in Rust 2018 or later @@ -445,6 +441,12 @@ parse_lifetime_in_borrow_expression = borrow expressions cannot be annotated wit .suggestion = remove the lifetime annotation .label = annotated with lifetime here +parse_lifetime_in_eq_constraint = lifetimes are not permitted in this context + .label = lifetime is not allowed here + .context_label = this introduces an associated item binding + .help = if you meant to specify a trait object, write `dyn /* Trait */ + {$lifetime}` + .colon_sugg = you might have meant to write a bound here + parse_lone_slash = invalid trailing slash in literal .label = {parse_lone_slash} diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs index 5cad3a568ee2..7c6bef0d7e4d 100644 --- a/compiler/rustc_parse/src/errors.rs +++ b/compiler/rustc_parse/src/errors.rs @@ -2611,13 +2611,22 @@ pub(crate) struct GenericsInPath { } #[derive(Diagnostic)] -#[diag(parse_assoc_lifetime)] +#[diag(parse_lifetime_in_eq_constraint)] #[help] -pub(crate) struct AssocLifetime { +pub(crate) struct LifetimeInEqConstraint { #[primary_span] - pub span: Span, #[label] - pub lifetime: Span, + pub span: Span, + pub lifetime: Ident, + #[label(parse_context_label)] + pub binding_label: Span, + #[suggestion( + parse_colon_sugg, + style = "verbose", + applicability = "maybe-incorrect", + code = ": " + )] + pub colon_sugg: Span, } #[derive(Diagnostic)] diff --git a/compiler/rustc_parse/src/parser/path.rs b/compiler/rustc_parse/src/parser/path.rs index 9153f2b9d06f..608cdd945ff9 100644 --- a/compiler/rustc_parse/src/parser/path.rs +++ b/compiler/rustc_parse/src/parser/path.rs @@ -718,7 +718,11 @@ impl<'a> Parser<'a> { let bounds = self.parse_generic_bounds()?; AssocConstraintKind::Bound { bounds } } else if self.eat(&token::Eq) { - self.parse_assoc_equality_term(ident, self.prev_token.span)? + self.parse_assoc_equality_term( + ident, + gen_args.as_ref(), + self.prev_token.span, + )? } else { unreachable!(); }; @@ -753,11 +757,13 @@ impl<'a> Parser<'a> { } /// Parse the term to the right of an associated item equality constraint. - /// That is, parse `` in `Item = `. - /// Right now, this only admits types in ``. + /// + /// That is, parse `$term` in `Item = $term` where `$term` is a type or + /// a const expression (wrapped in curly braces if complex). fn parse_assoc_equality_term( &mut self, ident: Ident, + gen_args: Option<&GenericArgs>, eq: Span, ) -> PResult<'a, AssocConstraintKind> { let arg = self.parse_generic_arg(None)?; @@ -769,9 +775,15 @@ impl<'a> Parser<'a> { c.into() } Some(GenericArg::Lifetime(lt)) => { - let guar = - self.dcx().emit_err(errors::AssocLifetime { span, lifetime: lt.ident.span }); - self.mk_ty(span, ast::TyKind::Err(guar)).into() + let guar = self.dcx().emit_err(errors::LifetimeInEqConstraint { + span: lt.ident.span, + lifetime: lt.ident, + binding_label: span, + colon_sugg: gen_args + .map_or(ident.span, |args| args.span()) + .between(lt.ident.span), + }); + self.mk_ty(lt.ident.span, ast::TyKind::Err(guar)).into() } None => { let after_eq = eq.shrink_to_hi(); diff --git a/tests/ui/parser/recover/recover-assoc-lifetime-constraint.rs b/tests/ui/parser/recover/recover-assoc-lifetime-constraint.rs index 558fcdfe1776..cb65f80b0890 100644 --- a/tests/ui/parser/recover/recover-assoc-lifetime-constraint.rs +++ b/tests/ui/parser/recover/recover-assoc-lifetime-constraint.rs @@ -1,6 +1,6 @@ #[cfg(FALSE)] fn syntax() { - bar::(); //~ ERROR associated lifetimes are not supported + bar::(); //~ ERROR lifetimes are not permitted in this context } fn main() {} diff --git a/tests/ui/parser/recover/recover-assoc-lifetime-constraint.stderr b/tests/ui/parser/recover/recover-assoc-lifetime-constraint.stderr index 39a6682fcaee..606b737e7231 100644 --- a/tests/ui/parser/recover/recover-assoc-lifetime-constraint.stderr +++ b/tests/ui/parser/recover/recover-assoc-lifetime-constraint.stderr @@ -1,12 +1,17 @@ -error: associated lifetimes are not supported - --> $DIR/recover-assoc-lifetime-constraint.rs:3:11 +error: lifetimes are not permitted in this context + --> $DIR/recover-assoc-lifetime-constraint.rs:3:18 | LL | bar::(); - | ^^^^^^^-- - | | - | the lifetime is given here + | -------^^ + | | | + | | lifetime is not allowed here + | this introduces an associated item binding | - = help: if you meant to specify a trait object, write `dyn Trait + 'lifetime` + = help: if you meant to specify a trait object, write `dyn /* Trait */ + 'a` +help: you might have meant to write a bound here + | +LL | bar::(); + | ~ error: aborting due to 1 previous error From ac770f7bd57614e728980073a2a89702e78da2d8 Mon Sep 17 00:00:00 2001 From: joboet Date: Sat, 23 Mar 2024 12:15:11 +0100 Subject: [PATCH 034/165] proc_macro: simplify bridge state --- library/proc_macro/src/bridge/client.rs | 122 +++++++++---------- library/proc_macro/src/bridge/mod.rs | 4 +- library/proc_macro/src/bridge/scoped_cell.rs | 64 ---------- 3 files changed, 58 insertions(+), 132 deletions(-) delete mode 100644 library/proc_macro/src/bridge/scoped_cell.rs diff --git a/library/proc_macro/src/bridge/client.rs b/library/proc_macro/src/bridge/client.rs index 8a1ba436f726..f3cfc41bac7c 100644 --- a/library/proc_macro/src/bridge/client.rs +++ b/library/proc_macro/src/bridge/client.rs @@ -2,6 +2,7 @@ use super::*; +use std::cell::RefCell; use std::marker::PhantomData; use std::sync::atomic::AtomicU32; @@ -189,61 +190,61 @@ struct Bridge<'a> { impl<'a> !Send for Bridge<'a> {} impl<'a> !Sync for Bridge<'a> {} -enum BridgeState<'a> { - /// No server is currently connected to this client. - NotConnected, +#[allow(unsafe_code)] +mod state { + use super::Bridge; + use std::cell::{Cell, RefCell}; + use std::ptr; - /// A server is connected and available for requests. - Connected(Bridge<'a>), + thread_local! { + static BRIDGE_STATE: Cell<*const ()> = const { Cell::new(ptr::null()) }; + } - /// Access to the bridge is being exclusively acquired - /// (e.g., during `BridgeState::with`). - InUse, -} + pub(super) fn set<'bridge, R>(state: &RefCell>, f: impl FnOnce() -> R) -> R { + struct RestoreOnDrop(*const ()); + impl Drop for RestoreOnDrop { + fn drop(&mut self) { + BRIDGE_STATE.set(self.0); + } + } -enum BridgeStateL {} + let inner = ptr::from_ref(state).cast(); + let outer = BRIDGE_STATE.replace(inner); + let _restore = RestoreOnDrop(outer); -impl<'a> scoped_cell::ApplyL<'a> for BridgeStateL { - type Out = BridgeState<'a>; -} + f() + } -thread_local! { - static BRIDGE_STATE: scoped_cell::ScopedCell = - const { scoped_cell::ScopedCell::new(BridgeState::NotConnected) }; -} - -impl BridgeState<'_> { - /// Take exclusive control of the thread-local - /// `BridgeState`, and pass it to `f`, mutably. - /// The state will be restored after `f` exits, even - /// by panic, including modifications made to it by `f`. - /// - /// N.B., while `f` is running, the thread-local state - /// is `BridgeState::InUse`. - fn with(f: impl FnOnce(&mut BridgeState<'_>) -> R) -> R { - BRIDGE_STATE.with(|state| state.replace(BridgeState::InUse, f)) + pub(super) fn with( + f: impl for<'bridge> FnOnce(Option<&RefCell>>) -> R, + ) -> R { + let state = BRIDGE_STATE.get(); + // SAFETY: the only place where the pointer is set is in `set`. It puts + // back the previous value after the inner call has returned, so we know + // that as long as the pointer is not null, it came from a reference to + // a `RefCell` that outlasts the call to this function. Since `f` + // works the same for any lifetime of the bridge, including the actual + // one, we can lie here and say that the lifetime is `'static` without + // anyone noticing. + let bridge = unsafe { state.cast::>>().as_ref() }; + f(bridge) } } impl Bridge<'_> { fn with(f: impl FnOnce(&mut Bridge<'_>) -> R) -> R { - BridgeState::with(|state| match state { - BridgeState::NotConnected => { - panic!("procedural macro API is used outside of a procedural macro"); - } - BridgeState::InUse => { - panic!("procedural macro API is used while it's already in use"); - } - BridgeState::Connected(bridge) => f(bridge), + state::with(|state| { + let bridge = state.expect("procedural macro API is used outside of a procedural macro"); + let mut bridge = bridge + .try_borrow_mut() + .expect("procedural macro API is used while it's already in use"); + f(&mut bridge) }) } } pub(crate) fn is_available() -> bool { - BridgeState::with(|state| match state { - BridgeState::Connected(_) | BridgeState::InUse => true, - BridgeState::NotConnected => false, - }) + state::with(|s| s.is_some()) } /// A client-side RPC entry-point, which may be using a different `proc_macro` @@ -282,11 +283,7 @@ fn maybe_install_panic_hook(force_show_panics: bool) { HIDE_PANICS_DURING_EXPANSION.call_once(|| { let prev = panic::take_hook(); panic::set_hook(Box::new(move |info| { - let show = BridgeState::with(|state| match state { - BridgeState::NotConnected => true, - BridgeState::Connected(_) | BridgeState::InUse => force_show_panics, - }); - if show { + if force_show_panics || !is_available() { prev(info) } })); @@ -312,29 +309,24 @@ fn run_client DecodeMut<'a, 's, ()>, R: Encode<()>>( let (globals, input) = <(ExpnGlobals, A)>::decode(reader, &mut ()); // Put the buffer we used for input back in the `Bridge` for requests. - let new_state = - BridgeState::Connected(Bridge { cached_buffer: buf.take(), dispatch, globals }); + let state = RefCell::new(Bridge { cached_buffer: buf.take(), dispatch, globals }); - BRIDGE_STATE.with(|state| { - state.set(new_state, || { - let output = f(input); + let output = state::set(&state, || f(input)); - // Take the `cached_buffer` back out, for the output value. - buf = Bridge::with(|bridge| bridge.cached_buffer.take()); + // Take the `cached_buffer` back out, for the output value. + buf = RefCell::into_inner(state).cached_buffer; - // HACK(eddyb) Separate encoding a success value (`Ok(output)`) - // from encoding a panic (`Err(e: PanicMessage)`) to avoid - // having handles outside the `bridge.enter(|| ...)` scope, and - // to catch panics that could happen while encoding the success. - // - // Note that panics should be impossible beyond this point, but - // this is defensively trying to avoid any accidental panicking - // reaching the `extern "C"` (which should `abort` but might not - // at the moment, so this is also potentially preventing UB). - buf.clear(); - Ok::<_, ()>(output).encode(&mut buf, &mut ()); - }) - }) + // HACK(eddyb) Separate encoding a success value (`Ok(output)`) + // from encoding a panic (`Err(e: PanicMessage)`) to avoid + // having handles outside the `bridge.enter(|| ...)` scope, and + // to catch panics that could happen while encoding the success. + // + // Note that panics should be impossible beyond this point, but + // this is defensively trying to avoid any accidental panicking + // reaching the `extern "C"` (which should `abort` but might not + // at the moment, so this is also potentially preventing UB). + buf.clear(); + Ok::<_, ()>(output).encode(&mut buf, &mut ()); })) .map_err(PanicMessage::from) .unwrap_or_else(|e| { diff --git a/library/proc_macro/src/bridge/mod.rs b/library/proc_macro/src/bridge/mod.rs index 67c72cf98d40..8553e8d5e4fd 100644 --- a/library/proc_macro/src/bridge/mod.rs +++ b/library/proc_macro/src/bridge/mod.rs @@ -154,7 +154,7 @@ macro_rules! reverse_decode { mod arena; #[allow(unsafe_code)] mod buffer; -#[forbid(unsafe_code)] +#[deny(unsafe_code)] pub mod client; #[allow(unsafe_code)] mod closure; @@ -166,8 +166,6 @@ mod handle; #[forbid(unsafe_code)] mod rpc; #[allow(unsafe_code)] -mod scoped_cell; -#[allow(unsafe_code)] mod selfless_reify; #[forbid(unsafe_code)] pub mod server; diff --git a/library/proc_macro/src/bridge/scoped_cell.rs b/library/proc_macro/src/bridge/scoped_cell.rs deleted file mode 100644 index a8b341439084..000000000000 --- a/library/proc_macro/src/bridge/scoped_cell.rs +++ /dev/null @@ -1,64 +0,0 @@ -//! `Cell` variant for (scoped) existential lifetimes. - -use std::cell::Cell; -use std::mem; - -/// Type lambda application, with a lifetime. -#[allow(unused_lifetimes)] -pub trait ApplyL<'a> { - type Out; -} - -/// Type lambda taking a lifetime, i.e., `Lifetime -> Type`. -pub trait LambdaL: for<'a> ApplyL<'a> {} - -impl ApplyL<'a>> LambdaL for T {} - -pub struct ScopedCell(Cell<>::Out>); - -impl ScopedCell { - pub const fn new(value: >::Out) -> Self { - ScopedCell(Cell::new(value)) - } - - /// Sets the value in `self` to `replacement` while - /// running `f`, which gets the old value, mutably. - /// The old value will be restored after `f` exits, even - /// by panic, including modifications made to it by `f`. - #[rustc_confusables("swap")] - pub fn replace<'a, R>( - &self, - replacement: >::Out, - f: impl for<'b, 'c> FnOnce(&'b mut >::Out) -> R, - ) -> R { - /// Wrapper that ensures that the cell always gets filled - /// (with the original state, optionally changed by `f`), - /// even if `f` had panicked. - struct PutBackOnDrop<'a, T: LambdaL> { - cell: &'a ScopedCell, - value: Option<>::Out>, - } - - impl<'a, T: LambdaL> Drop for PutBackOnDrop<'a, T> { - fn drop(&mut self) { - self.cell.0.set(self.value.take().unwrap()); - } - } - - let mut put_back_on_drop = PutBackOnDrop { - cell: self, - value: Some(self.0.replace(unsafe { - let erased = mem::transmute_copy(&replacement); - mem::forget(replacement); - erased - })), - }; - - f(put_back_on_drop.value.as_mut().unwrap()) - } - - /// Sets the value in `self` to `value` while running `f`. - pub fn set(&self, value: >::Out, f: impl FnOnce() -> R) -> R { - self.replace(value, |_| f()) - } -} From a517adc66e30b695dc96778d1699dd17751e6cec Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 17 Mar 2024 10:12:25 +0100 Subject: [PATCH 035/165] move assert_unsafe_preconditions to its own file These macros and functions are not intrinsics, after all. --- src/base.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/base.rs b/src/base.rs index 047dc56a32ea..dbce6d165d2d 100644 --- a/src/base.rs +++ b/src/base.rs @@ -780,7 +780,7 @@ fn codegen_stmt<'tcx>( NullOp::OffsetOf(fields) => { layout.offset_of_subfield(fx, fields.iter()).bytes() } - NullOp::UbCheck(_) => { + NullOp::UbChecks => { let val = fx.tcx.sess.opts.debug_assertions; let val = CValue::by_val( fx.bcx.ins().iconst(types::I8, i64::try_from(val).unwrap()), From 0c7f8b0f89e3b4a8ed46074e39a4de160d098489 Mon Sep 17 00:00:00 2001 From: Daniel Sedlak Date: Sat, 16 Mar 2024 11:50:02 +0100 Subject: [PATCH 036/165] Fix diagnostics for async block cloning --- .../src/diagnostics/conflict_errors.rs | 10 +++++++++ .../borrowck/cloning-in-async-block-121547.rs | 11 ++++++++++ .../cloning-in-async-block-121547.stderr | 22 +++++++++++++++++++ 3 files changed, 43 insertions(+) create mode 100644 tests/ui/borrowck/cloning-in-async-block-121547.rs create mode 100644 tests/ui/borrowck/cloning-in-async-block-121547.stderr diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index 35bd7d379921..106e68a779cd 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -4,6 +4,7 @@ #![allow(rustc::untranslatable_diagnostic)] use either::Either; +use hir::ClosureKind; use rustc_data_structures::captures::Captures; use rustc_data_structures::fx::FxIndexSet; use rustc_errors::{codes::*, struct_span_code_err, Applicability, Diag, MultiSpan}; @@ -463,6 +464,15 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { } else if let UseSpans::FnSelfUse { kind: CallKind::Normal { .. }, .. } = move_spans { // We already suggest cloning for these cases in `explain_captures`. + } else if let UseSpans::ClosureUse { + closure_kind: + ClosureKind::Coroutine(CoroutineKind::Desugared(_, CoroutineSource::Block)), + args_span: _, + capture_kind_span: _, + path_span, + } = move_spans + { + self.suggest_cloning(err, ty, expr, path_span); } else if self.suggest_hoisting_call_outside_loop(err, expr) { // The place where the the type moves would be misleading to suggest clone. // #121466 diff --git a/tests/ui/borrowck/cloning-in-async-block-121547.rs b/tests/ui/borrowck/cloning-in-async-block-121547.rs new file mode 100644 index 000000000000..b2d8dbae977e --- /dev/null +++ b/tests/ui/borrowck/cloning-in-async-block-121547.rs @@ -0,0 +1,11 @@ +//@ edition:2021 + +async fn clone_async_block(value: String) { + for _ in 0..10 { + async { //~ ERROR: use of moved value: `value` [E0382] + drop(value); + //~^ HELP: consider cloning the value if the performance cost is acceptable + }.await + } +} +fn main() {} diff --git a/tests/ui/borrowck/cloning-in-async-block-121547.stderr b/tests/ui/borrowck/cloning-in-async-block-121547.stderr new file mode 100644 index 000000000000..ae57e0018f8a --- /dev/null +++ b/tests/ui/borrowck/cloning-in-async-block-121547.stderr @@ -0,0 +1,22 @@ +error[E0382]: use of moved value: `value` + --> $DIR/cloning-in-async-block-121547.rs:5:9 + | +LL | async fn clone_async_block(value: String) { + | ----- move occurs because `value` has type `String`, which does not implement the `Copy` trait +LL | for _ in 0..10 { + | -------------- inside of this loop +LL | / async { +LL | | drop(value); + | | ----- use occurs due to use in coroutine +LL | | +LL | | }.await + | |_________^ value moved here, in previous iteration of loop + | +help: consider cloning the value if the performance cost is acceptable + | +LL | drop(value.clone()); + | ++++++++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0382`. From 2c433d0e9c17b004ff2303f7ae8a901f55da5dbc Mon Sep 17 00:00:00 2001 From: Daniel Sedlak Date: Sat, 16 Mar 2024 11:57:05 +0100 Subject: [PATCH 037/165] Fix typos --- compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index 106e68a779cd..578369de4d6e 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -631,7 +631,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { } // FIXME: We make sure that this is a normal top-level binding, - // but we could suggest `todo!()` for all uninitalized bindings in the pattern pattern + // but we could suggest `todo!()` for all uninitialized bindings in the pattern pattern if let hir::StmtKind::Let(hir::LetStmt { span, ty, init: None, pat, .. }) = &ex.kind && let hir::PatKind::Binding(..) = pat.kind @@ -759,7 +759,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { true } - /// In a move error that occurs on a call wihtin a loop, we try to identify cases where cloning + /// In a move error that occurs on a call within a loop, we try to identify cases where cloning /// the value would lead to a logic error. We infer these cases by seeing if the moved value is /// part of the logic to break the loop, either through an explicit `break` or if the expression /// is part of a `while let`. @@ -960,7 +960,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { { // FIXME: We could check that the call's *parent* takes `&mut val` to make the // suggestion more targeted to the `mk_iter(val).next()` case. Maybe do that only to - // check for wheter to suggest `let value` or `let mut value`. + // check for whether to suggest `let value` or `let mut value`. let span = in_loop.span; if !finder.found_breaks.is_empty() From 42526e142aa697db9391c7df0810ca4a4f73a164 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 24 Mar 2024 12:53:03 +0100 Subject: [PATCH 038/165] simplify_branches: add comment --- compiler/rustc_mir_transform/src/simplify_branches.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/compiler/rustc_mir_transform/src/simplify_branches.rs b/compiler/rustc_mir_transform/src/simplify_branches.rs index 35a052166bd9..c746041ebd8a 100644 --- a/compiler/rustc_mir_transform/src/simplify_branches.rs +++ b/compiler/rustc_mir_transform/src/simplify_branches.rs @@ -19,6 +19,7 @@ impl<'tcx> MirPass<'tcx> for SimplifyConstCondition { let param_env = tcx.param_env_reveal_all_normalized(body.source.def_id()); 'blocks: for block in body.basic_blocks_mut() { for stmt in block.statements.iter_mut() { + // Simplify `assume` of a known value: either a NOP or unreachable. if let StatementKind::Intrinsic(box ref intrinsic) = stmt.kind && let NonDivergingIntrinsic::Assume(discr) = intrinsic && let Operand::Constant(ref c) = discr From 1f2178b9e7b43f4efe549e19889eafeec9061e8c 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, 13 Mar 2024 21:52:23 +0000 Subject: [PATCH 039/165] Rework rmake support library to have a weakly-typed API with helper methods --- src/tools/run-make-support/src/lib.rs | 189 ++---------------- src/tools/run-make-support/src/run.rs | 67 +++++++ src/tools/run-make-support/src/rustc.rs | 147 ++++++++++++++ src/tools/run-make-support/src/rustdoc.rs | 80 ++++++++ tests/run-make/CURRENT_RUSTC_VERSION/rmake.rs | 21 +- tests/run-make/a-b-a-linker-guard/rmake.rs | 44 ++-- tests/run-make/compiler-builtins/rmake.rs | 8 +- tests/run-make/rustdoc-test-args/rmake.rs | 9 +- tests/run-make/wasm-abi/rmake.rs | 7 +- tests/run-make/wasm-custom-section/rmake.rs | 8 +- .../wasm-custom-sections-opt/rmake.rs | 7 +- .../run-make/wasm-export-all-symbols/rmake.rs | 13 +- tests/run-make/wasm-import-module/rmake.rs | 13 +- tests/run-make/wasm-panic-small/rmake.rs | 14 +- tests/run-make/wasm-spurious-import/rmake.rs | 11 +- .../wasm-stringify-ints-small/rmake.rs | 6 +- .../wasm-symbols-different-module/rmake.rs | 6 +- .../wasm-symbols-not-exported/rmake.rs | 18 +- .../wasm-symbols-not-imported/rmake.rs | 18 +- 19 files changed, 404 insertions(+), 282 deletions(-) create mode 100644 src/tools/run-make-support/src/run.rs create mode 100644 src/tools/run-make-support/src/rustc.rs create mode 100644 src/tools/run-make-support/src/rustdoc.rs diff --git a/src/tools/run-make-support/src/lib.rs b/src/tools/run-make-support/src/lib.rs index 419b04231b57..7975677286d3 100644 --- a/src/tools/run-make-support/src/lib.rs +++ b/src/tools/run-make-support/src/lib.rs @@ -1,19 +1,21 @@ +pub mod run; +pub mod rustc; +pub mod rustdoc; + use std::env; -use std::path::{Path, PathBuf}; -use std::process::{Command, Output}; +use std::path::PathBuf; +use std::process::Output; pub use object; pub use wasmparser; -pub fn out_dir() -> PathBuf { - env::var_os("TMPDIR").unwrap().into() -} +pub use run::{run, run_fail}; +pub use rustc::{aux_build, rustc, Rustc}; +pub use rustdoc::{bare_rustdoc, rustdoc, Rustdoc}; -fn setup_common_build_cmd(command: &str) -> Command { - let rustc = env::var(command).unwrap(); - let mut cmd = Command::new(rustc); - cmd.arg("--out-dir").arg(out_dir()).arg("-L").arg(out_dir()); - cmd +/// Path of `TMPDIR` (a temporary build directory, not under `/tmp`). +pub fn tmp_dir() -> PathBuf { + env::var_os("TMPDIR").unwrap().into() } fn handle_failed_output(cmd: &str, output: Output, caller_line_number: u32) -> ! { @@ -24,170 +26,3 @@ fn handle_failed_output(cmd: &str, output: Output, caller_line_number: u32) -> ! eprintln!("=== STDERR ===\n{}\n\n", String::from_utf8(output.stderr).unwrap()); std::process::exit(1) } - -pub fn rustc() -> RustcInvocationBuilder { - RustcInvocationBuilder::new() -} - -pub fn aux_build() -> AuxBuildInvocationBuilder { - AuxBuildInvocationBuilder::new() -} - -pub fn rustdoc() -> Rustdoc { - Rustdoc::new() -} - -#[derive(Debug)] -pub struct RustcInvocationBuilder { - cmd: Command, -} - -impl RustcInvocationBuilder { - fn new() -> Self { - let cmd = setup_common_build_cmd("RUSTC"); - Self { cmd } - } - - pub fn arg(&mut self, arg: &str) -> &mut RustcInvocationBuilder { - self.cmd.arg(arg); - self - } - - pub fn args(&mut self, args: &[&str]) -> &mut RustcInvocationBuilder { - self.cmd.args(args); - self - } - - #[track_caller] - pub fn run(&mut self) -> Output { - let caller_location = std::panic::Location::caller(); - let caller_line_number = caller_location.line(); - - let output = self.cmd.output().unwrap(); - if !output.status.success() { - handle_failed_output(&format!("{:#?}", self.cmd), output, caller_line_number); - } - output - } -} - -#[derive(Debug)] -pub struct AuxBuildInvocationBuilder { - cmd: Command, -} - -impl AuxBuildInvocationBuilder { - fn new() -> Self { - let mut cmd = setup_common_build_cmd("RUSTC"); - cmd.arg("--crate-type=lib"); - Self { cmd } - } - - pub fn arg(&mut self, arg: &str) -> &mut AuxBuildInvocationBuilder { - self.cmd.arg(arg); - self - } - - #[track_caller] - pub fn run(&mut self) -> Output { - let caller_location = std::panic::Location::caller(); - let caller_line_number = caller_location.line(); - - let output = self.cmd.output().unwrap(); - if !output.status.success() { - handle_failed_output(&format!("{:#?}", self.cmd), output, caller_line_number); - } - output - } -} - -#[derive(Debug)] -pub struct Rustdoc { - cmd: Command, -} - -impl Rustdoc { - fn new() -> Self { - let cmd = setup_common_build_cmd("RUSTDOC"); - Self { cmd } - } - - pub fn arg(&mut self, arg: &str) -> &mut Self { - self.cmd.arg(arg); - self - } - - #[track_caller] - pub fn run(&mut self) -> Output { - let caller_location = std::panic::Location::caller(); - let caller_line_number = caller_location.line(); - - let output = self.cmd.output().unwrap(); - if !output.status.success() { - handle_failed_output(&format!("{:#?}", self.cmd), output, caller_line_number); - } - output - } -} - -fn run_common(bin_name: &str) -> (Command, Output) { - let target = env::var("TARGET").unwrap(); - - let bin_name = - if target.contains("windows") { format!("{}.exe", bin_name) } else { bin_name.to_owned() }; - - let mut bin_path = PathBuf::new(); - bin_path.push(env::var("TMPDIR").unwrap()); - bin_path.push(&bin_name); - let ld_lib_path_envvar = env::var("LD_LIB_PATH_ENVVAR").unwrap(); - let mut cmd = Command::new(bin_path); - cmd.env(&ld_lib_path_envvar, { - let mut paths = vec![]; - paths.push(PathBuf::from(env::var("TMPDIR").unwrap())); - for p in env::split_paths(&env::var("TARGET_RPATH_ENV").unwrap()) { - paths.push(p.to_path_buf()); - } - for p in env::split_paths(&env::var(&ld_lib_path_envvar).unwrap()) { - paths.push(p.to_path_buf()); - } - env::join_paths(paths.iter()).unwrap() - }); - - if target.contains("windows") { - let mut paths = vec![]; - for p in env::split_paths(&std::env::var("PATH").unwrap_or(String::new())) { - paths.push(p.to_path_buf()); - } - paths.push(Path::new(&std::env::var("TARGET_RPATH_DIR").unwrap()).to_path_buf()); - cmd.env("PATH", env::join_paths(paths.iter()).unwrap()); - } - - let output = cmd.output().unwrap(); - (cmd, output) -} - -/// Run a built binary and make sure it succeeds. -#[track_caller] -pub fn run(bin_name: &str) -> Output { - let caller_location = std::panic::Location::caller(); - let caller_line_number = caller_location.line(); - - let (cmd, output) = run_common(bin_name); - if !output.status.success() { - handle_failed_output(&format!("{:#?}", cmd), output, caller_line_number); - } - output -} - -/// Run a built binary and make sure it fails. -#[track_caller] -pub fn run_fail(bin_name: &str) -> Output { - let caller_location = std::panic::Location::caller(); - let caller_line_number = caller_location.line(); - - let (cmd, output) = run_common(bin_name); - if output.status.success() { - handle_failed_output(&format!("{:#?}", cmd), output, caller_line_number); - } - output -} diff --git a/src/tools/run-make-support/src/run.rs b/src/tools/run-make-support/src/run.rs new file mode 100644 index 000000000000..42dcf54da22e --- /dev/null +++ b/src/tools/run-make-support/src/run.rs @@ -0,0 +1,67 @@ +use std::env; +use std::path::{Path, PathBuf}; +use std::process::{Command, Output}; + +use super::handle_failed_output; + +fn run_common(bin_name: &str) -> (Command, Output) { + let target = env::var("TARGET").unwrap(); + + let bin_name = + if target.contains("windows") { format!("{}.exe", bin_name) } else { bin_name.to_owned() }; + + let mut bin_path = PathBuf::new(); + bin_path.push(env::var("TMPDIR").unwrap()); + bin_path.push(&bin_name); + let ld_lib_path_envvar = env::var("LD_LIB_PATH_ENVVAR").unwrap(); + let mut cmd = Command::new(bin_path); + cmd.env(&ld_lib_path_envvar, { + let mut paths = vec![]; + paths.push(PathBuf::from(env::var("TMPDIR").unwrap())); + for p in env::split_paths(&env::var("TARGET_RPATH_ENV").unwrap()) { + paths.push(p.to_path_buf()); + } + for p in env::split_paths(&env::var(&ld_lib_path_envvar).unwrap()) { + paths.push(p.to_path_buf()); + } + env::join_paths(paths.iter()).unwrap() + }); + + if target.contains("windows") { + let mut paths = vec![]; + for p in env::split_paths(&std::env::var("PATH").unwrap_or(String::new())) { + paths.push(p.to_path_buf()); + } + paths.push(Path::new(&std::env::var("TARGET_RPATH_DIR").unwrap()).to_path_buf()); + cmd.env("PATH", env::join_paths(paths.iter()).unwrap()); + } + + let output = cmd.output().unwrap(); + (cmd, output) +} + +/// Run a built binary and make sure it succeeds. +#[track_caller] +pub fn run(bin_name: &str) -> Output { + let caller_location = std::panic::Location::caller(); + let caller_line_number = caller_location.line(); + + let (cmd, output) = run_common(bin_name); + if !output.status.success() { + handle_failed_output(&format!("{:#?}", cmd), output, caller_line_number); + } + output +} + +/// Run a built binary and make sure it fails. +#[track_caller] +pub fn run_fail(bin_name: &str) -> Output { + let caller_location = std::panic::Location::caller(); + let caller_line_number = caller_location.line(); + + let (cmd, output) = run_common(bin_name); + if output.status.success() { + handle_failed_output(&format!("{:#?}", cmd), output, caller_line_number); + } + output +} diff --git a/src/tools/run-make-support/src/rustc.rs b/src/tools/run-make-support/src/rustc.rs new file mode 100644 index 000000000000..d0ab8df42d28 --- /dev/null +++ b/src/tools/run-make-support/src/rustc.rs @@ -0,0 +1,147 @@ +use std::env; +use std::path::Path; +use std::process::{Command, Output}; + +use crate::{handle_failed_output, tmp_dir}; + +/// Construct a new `rustc` invocation. +pub fn rustc() -> Rustc { + Rustc::new() +} + +/// Construct a new `rustc` aux-build invocation. +pub fn aux_build() -> Rustc { + Rustc::new_aux_build() +} + +/// A `rustc` invocation builder. +#[derive(Debug)] +pub struct Rustc { + cmd: Command, +} + +fn setup_common() -> Command { + let rustc = env::var("RUSTC").unwrap(); + let mut cmd = Command::new(rustc); + cmd.arg("--out-dir").arg(tmp_dir()).arg("-L").arg(tmp_dir()); + cmd +} + +impl Rustc { + // `rustc` invocation constructor methods + + /// Construct a new `rustc` invocation. + pub fn new() -> Self { + let cmd = setup_common(); + Self { cmd } + } + + /// Construct a new `rustc` invocation with `aux_build` preset (setting `--crate-type=lib`). + pub fn new_aux_build() -> Self { + let mut cmd = setup_common(); + cmd.arg("--crate-type=lib"); + Self { cmd } + } + + // Argument provider methods + + /// Configure the compilation environment. + pub fn cfg(&mut self, s: &str) -> &mut Self { + self.cmd.arg("--cfg"); + self.cmd.arg(s); + self + } + + /// Specify default optimization level `-O` (alias for `-C opt-level=2`). + pub fn opt(&mut self) -> &mut Self { + self.cmd.arg("-O"); + self + } + + /// Specify type(s) of output files to generate. + pub fn emit(&mut self, kinds: &str) -> &mut Self { + self.cmd.arg(format!("--emit={kinds}")); + self + } + + /// Specify where an external library is located. + pub fn extern_>(&mut self, crate_name: &str, path: P) -> &mut Self { + assert!( + !crate_name.contains(|c: char| c.is_whitespace() || c == '\\' || c == '/'), + "crate name cannot contain whitespace or path separators" + ); + + let path = path.as_ref().to_string_lossy(); + + self.cmd.arg("--extern"); + self.cmd.arg(format!("{crate_name}={path}")); + + self + } + + /// Specify path to the input file. + pub fn input>(&mut self, path: P) -> &mut Self { + self.cmd.arg(path.as_ref()); + self + } + + /// Specify target triple. + pub fn target(&mut self, target: &str) -> &mut Self { + assert!(!target.contains(char::is_whitespace), "target triple cannot contain spaces"); + self.cmd.arg(format!("--target={target}")); + self + } + + /// Generic command argument provider. Use `.arg("-Zname")` over `.arg("-Z").arg("arg")`. + /// This method will panic if a plain `-Z` or `-C` is passed, or if `-Z ` or `-C ` + /// is passed (note the space). + pub fn arg(&mut self, arg: &str) -> &mut Self { + assert!( + !(["-Z", "-C"].contains(&arg) || arg.starts_with("-Z ") || arg.starts_with("-C ")), + "use `-Zarg` or `-Carg` over split `-Z` `arg` or `-C` `arg`" + ); + self.cmd.arg(arg); + self + } + + /// Generic command arguments provider. Use `.arg("-Zname")` over `.arg("-Z").arg("arg")`. + /// This method will panic if a plain `-Z` or `-C` is passed, or if `-Z ` or `-C ` + /// is passed (note the space). + pub fn args(&mut self, args: &[&str]) -> &mut Self { + for arg in args { + assert!( + !(["-Z", "-C"].contains(&arg) || arg.starts_with("-Z ") || arg.starts_with("-C ")), + "use `-Zarg` or `-Carg` over split `-Z` `arg` or `-C` `arg`" + ); + } + + self.cmd.args(args); + self + } + + // Command inspection, output and running helper methods + + /// Get the [`Output`][std::process::Output] of the finished `rustc` process. + pub fn output(&mut self) -> Output { + self.cmd.output().unwrap() + } + + /// Run the constructed `rustc` command and assert that it is successfully run. + #[track_caller] + pub fn run(&mut self) -> Output { + let caller_location = std::panic::Location::caller(); + let caller_line_number = caller_location.line(); + + let output = self.cmd.output().unwrap(); + if !output.status.success() { + handle_failed_output(&format!("{:#?}", self.cmd), output, caller_line_number); + } + output + } + + /// Inspect what the underlying [`Command`] is up to the current construction. + pub fn inspect(&mut self, f: impl FnOnce(&Command)) -> &mut Self { + f(&self.cmd); + self + } +} diff --git a/src/tools/run-make-support/src/rustdoc.rs b/src/tools/run-make-support/src/rustdoc.rs new file mode 100644 index 000000000000..9607ff02f968 --- /dev/null +++ b/src/tools/run-make-support/src/rustdoc.rs @@ -0,0 +1,80 @@ +use std::env; +use std::path::Path; +use std::process::{Command, Output}; + +use crate::handle_failed_output; + +/// Construct a plain `rustdoc` invocation with no flags set. +pub fn bare_rustdoc() -> Rustdoc { + Rustdoc::bare() +} + +/// Construct a new `rustdoc` invocation with `-L $(TARGET_RPATH_DIR)` set. +pub fn rustdoc() -> Rustdoc { + Rustdoc::new() +} + +#[derive(Debug)] +pub struct Rustdoc { + cmd: Command, +} + +fn setup_common() -> Command { + let rustdoc = env::var("RUSTDOC").unwrap(); + Command::new(rustdoc) +} + +impl Rustdoc { + /// Construct a bare `rustdoc` invocation. + pub fn bare() -> Self { + let cmd = setup_common(); + Self { cmd } + } + + /// 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(); + cmd.arg(format!("-L{}", target_rpath_dir.to_string_lossy())); + Self { cmd } + } + + /// Specify path to the input file. + pub fn input>(&mut self, path: P) -> &mut Self { + self.cmd.arg(path.as_ref()); + self + } + + /// Specify output directory. + pub fn out_dir>(&mut self, path: P) -> &mut Self { + self.cmd.arg("--out-dir").arg(path.as_ref()); + self + } + + /// Given a `path`, pass `@{path}` to `rustdoc` as an + /// [arg file](https://doc.rust-lang.org/rustdoc/command-line-arguments.html#path-load-command-line-flags-from-a-path). + pub fn arg_file>(&mut self, path: P) -> &mut Self { + self.cmd.arg(format!("@{}", path.as_ref().display())); + self + } + + /// Fallback argument provider. Consider adding meaningfully named methods instead of using + /// this method. + pub fn arg(&mut self, arg: &str) -> &mut Self { + self.cmd.arg(arg); + self + } + + /// Run the build `rustdoc` command and assert that the run is successful. + #[track_caller] + pub fn run(&mut self) -> Output { + let caller_location = std::panic::Location::caller(); + let caller_line_number = caller_location.line(); + + let output = self.cmd.output().unwrap(); + if !output.status.success() { + handle_failed_output(&format!("{:#?}", self.cmd), output, caller_line_number); + } + output + } +} diff --git a/tests/run-make/CURRENT_RUSTC_VERSION/rmake.rs b/tests/run-make/CURRENT_RUSTC_VERSION/rmake.rs index 586f4e4095fc..1204260a2f46 100644 --- a/tests/run-make/CURRENT_RUSTC_VERSION/rmake.rs +++ b/tests/run-make/CURRENT_RUSTC_VERSION/rmake.rs @@ -1,24 +1,25 @@ // ignore-tidy-linelength +// Check that the `CURRENT_RUSTC_VERSION` placeholder is correctly replaced by the current +// `rustc` version and the `since` property in feature stability gating is properly respected. + extern crate run_make_support; use std::path::PathBuf; -use run_make_support::{aux_build, rustc}; +use run_make_support::{rustc, aux_build}; fn main() { - aux_build() - .arg("--emit=metadata") - .arg("stable.rs") - .run(); + aux_build().input("stable.rs").emit("metadata").run(); + let mut stable_path = PathBuf::from(env!("TMPDIR")); stable_path.push("libstable.rmeta"); + let output = rustc() - .arg("--emit=metadata") - .arg("--extern") - .arg(&format!("stable={}", &stable_path.to_string_lossy())) - .arg("main.rs") - .run(); + .input("main.rs") + .emit("metadata") + .extern_("stable", &stable_path) + .output(); let stderr = String::from_utf8_lossy(&output.stderr); let version = include_str!(concat!(env!("S"), "/src/version")); diff --git a/tests/run-make/a-b-a-linker-guard/rmake.rs b/tests/run-make/a-b-a-linker-guard/rmake.rs index ef4813e12140..ffc1b2000b90 100644 --- a/tests/run-make/a-b-a-linker-guard/rmake.rs +++ b/tests/run-make/a-b-a-linker-guard/rmake.rs @@ -1,44 +1,36 @@ // ignore-tidy-linelength +// Test that if we build `b` against a version of `a` that has one set of types, it will not run +// with a dylib that has a different set of types. + extern crate run_make_support; use run_make_support::{run, run_fail, rustc}; fn main() { rustc() - .arg("a.rs") - .arg("--cfg") - .arg("x") - .arg("-C") - .arg("prefer-dynamic") - .arg("-Z") - .arg("unstable-options") - .arg("-C") - .arg("symbol-mangling-version=legacy") + .input("a.rs") + .cfg("x") + .arg("-Zunstable-options") + .arg("-Cprefer-dynamic") + .arg("-Csymbol-mangling-version=legacy") .run(); rustc() - .arg("b.rs") - .arg("-C") - .arg("prefer-dynamic") - .arg("-Z") - .arg("unstable-options") - .arg("-C") - .arg("symbol-mangling-version=legacy") - .run(); + .input("b.rs") + .arg("-Zunstable-options") + .arg("-Cprefer-dynamic") + .arg("-Csymbol-mangling-version=legacy") + .run(); run("b"); rustc() - .arg("a.rs") - .arg("--cfg") - .arg("y") - .arg("-C") - .arg("prefer-dynamic") - .arg("-Z") - .arg("unstable-options") - .arg("-C") - .arg("symbol-mangling-version=legacy") + .input("a.rs") + .cfg("y") + .arg("-Zunstable-options") + .arg("-Cprefer-dynamic") + .arg("-Csymbol-mangling-version=legacy") .run(); run_fail("b"); diff --git a/tests/run-make/compiler-builtins/rmake.rs b/tests/run-make/compiler-builtins/rmake.rs index e7a5e8addbe9..b546a095c512 100644 --- a/tests/run-make/compiler-builtins/rmake.rs +++ b/tests/run-make/compiler-builtins/rmake.rs @@ -18,7 +18,7 @@ use run_make_support::object::read::Object; use run_make_support::object::ObjectSection; use run_make_support::object::ObjectSymbol; use run_make_support::object::RelocationTarget; -use run_make_support::out_dir; +use run_make_support::tmp_dir; use std::collections::HashSet; const MANIFEST: &str = r#" @@ -31,7 +31,7 @@ edition = "2021" path = "lib.rs""#; fn main() { - let target_dir = out_dir().join("target"); + let target_dir = tmp_dir().join("target"); let target = std::env::var("TARGET").unwrap(); if target.starts_with("wasm") || target.starts_with("nvptx") { // wasm and nvptx targets don't produce rlib files that object can parse. @@ -41,9 +41,9 @@ fn main() { println!("Testing compiler_builtins for {}", target); // Set up the tiniest Cargo project: An empty no_std library. Just enough to run -Zbuild-std. - let manifest_path = out_dir().join("Cargo.toml"); + let manifest_path = tmp_dir().join("Cargo.toml"); std::fs::write(&manifest_path, MANIFEST.as_bytes()).unwrap(); - std::fs::write(out_dir().join("lib.rs"), b"#![no_std]").unwrap(); + std::fs::write(tmp_dir().join("lib.rs"), b"#![no_std]").unwrap(); let path = std::env::var("PATH").unwrap(); let rustc = std::env::var("RUSTC").unwrap(); diff --git a/tests/run-make/rustdoc-test-args/rmake.rs b/tests/run-make/rustdoc-test-args/rmake.rs index 808d13928ebd..c8edfb6370e5 100644 --- a/tests/run-make/rustdoc-test-args/rmake.rs +++ b/tests/run-make/rustdoc-test-args/rmake.rs @@ -1,8 +1,8 @@ extern crate run_make_support; -use run_make_support::{out_dir, rustdoc}; -use std::{fs, iter}; +use run_make_support::{rustdoc, tmp_dir}; use std::path::Path; +use std::{fs, iter}; fn generate_a_lot_of_cfgs(path: &Path) { let content = iter::repeat("--cfg=a\n").take(100_000).collect::(); @@ -10,9 +10,8 @@ fn generate_a_lot_of_cfgs(path: &Path) { } fn main() { - let arg_file = out_dir().join("args"); + let arg_file = tmp_dir().join("args"); generate_a_lot_of_cfgs(&arg_file); - let arg_file = format!("@{}", arg_file.display()); - rustdoc().arg("--test").arg(&arg_file).arg("foo.rs").run(); + rustdoc().out_dir(tmp_dir()).input("foo.rs").arg_file(&arg_file).arg("--test").run(); } diff --git a/tests/run-make/wasm-abi/rmake.rs b/tests/run-make/wasm-abi/rmake.rs index 07b826ae6fe1..f4d0027798ae 100644 --- a/tests/run-make/wasm-abi/rmake.rs +++ b/tests/run-make/wasm-abi/rmake.rs @@ -1,6 +1,6 @@ extern crate run_make_support; -use run_make_support::{out_dir, rustc}; +use run_make_support::{rustc, tmp_dir}; use std::path::Path; use std::process::Command; @@ -9,8 +9,9 @@ fn main() { return; } - rustc().arg("foo.rs").arg("--target=wasm32-wasip1").run(); - let file = out_dir().join("foo.wasm"); + rustc().input("foo.rs").target("wasm32-wasip1").run(); + + let file = tmp_dir().join("foo.wasm"); let has_wasmtime = match Command::new("wasmtime").arg("--version").output() { Ok(s) => s.status.success(), diff --git a/tests/run-make/wasm-custom-section/rmake.rs b/tests/run-make/wasm-custom-section/rmake.rs index 9ad152695eca..31fb5fb32303 100644 --- a/tests/run-make/wasm-custom-section/rmake.rs +++ b/tests/run-make/wasm-custom-section/rmake.rs @@ -1,6 +1,6 @@ extern crate run_make_support; -use run_make_support::{out_dir, rustc, wasmparser}; +use run_make_support::{rustc, tmp_dir, wasmparser}; use std::collections::HashMap; fn main() { @@ -8,10 +8,10 @@ fn main() { return; } - rustc().arg("foo.rs").arg("--target=wasm32-wasip1").run(); - rustc().arg("bar.rs").arg("--target=wasm32-wasip1").arg("-Clto").arg("-O").run(); + rustc().input("foo.rs").target("wasm32-wasip1").run(); + rustc().input("bar.rs").target("wasm32-wasip1").arg("-Clto").opt().run(); - let file = std::fs::read(&out_dir().join("bar.wasm")).unwrap(); + let file = std::fs::read(&tmp_dir().join("bar.wasm")).unwrap(); let mut custom = HashMap::new(); for payload in wasmparser::Parser::new(0).parse_all(&file) { diff --git a/tests/run-make/wasm-custom-sections-opt/rmake.rs b/tests/run-make/wasm-custom-sections-opt/rmake.rs index db31d6b71639..3164de1b4c9a 100644 --- a/tests/run-make/wasm-custom-sections-opt/rmake.rs +++ b/tests/run-make/wasm-custom-sections-opt/rmake.rs @@ -1,6 +1,6 @@ extern crate run_make_support; -use run_make_support::{out_dir, rustc, wasmparser}; +use run_make_support::{tmp_dir, wasmparser, rustc}; use std::collections::HashMap; use std::path::Path; @@ -9,8 +9,9 @@ fn main() { return; } - rustc().arg("foo.rs").arg("--target=wasm32-wasip1").arg("-O").run(); - verify(&out_dir().join("foo.wasm")); + rustc().input("foo.rs").target("wasm32-wasip1").opt().run(); + + verify(&tmp_dir().join("foo.wasm")); } fn verify(path: &Path) { diff --git a/tests/run-make/wasm-export-all-symbols/rmake.rs b/tests/run-make/wasm-export-all-symbols/rmake.rs index e3b118279b75..13101a97444e 100644 --- a/tests/run-make/wasm-export-all-symbols/rmake.rs +++ b/tests/run-make/wasm-export-all-symbols/rmake.rs @@ -1,6 +1,6 @@ extern crate run_make_support; -use run_make_support::{out_dir, rustc, wasmparser}; +use run_make_support::{tmp_dir, wasmparser, rustc}; use std::collections::HashMap; use std::path::Path; use wasmparser::ExternalKind::*; @@ -17,16 +17,17 @@ fn main() { fn test(args: &[&str]) { eprintln!("running with {args:?}"); - rustc().arg("bar.rs").arg("--target=wasm32-wasip1").args(args).run(); - rustc().arg("foo.rs").arg("--target=wasm32-wasip1").args(args).run(); - rustc().arg("main.rs").arg("--target=wasm32-wasip1").args(args).run(); + + rustc().input("bar.rs").target("wasm32-wasip1").args(args).run(); + rustc().input("foo.rs").target("wasm32-wasip1").args(args).run(); + rustc().input("main.rs").target("wasm32-wasip1").args(args).run(); verify_exports( - &out_dir().join("foo.wasm"), + &tmp_dir().join("foo.wasm"), &[("foo", Func), ("FOO", Global), ("memory", Memory)], ); verify_exports( - &out_dir().join("main.wasm"), + &tmp_dir().join("main.wasm"), &[ ("foo", Func), ("FOO", Global), diff --git a/tests/run-make/wasm-import-module/rmake.rs b/tests/run-make/wasm-import-module/rmake.rs index e521b5b0983a..3962bd80a898 100644 --- a/tests/run-make/wasm-import-module/rmake.rs +++ b/tests/run-make/wasm-import-module/rmake.rs @@ -1,6 +1,6 @@ extern crate run_make_support; -use run_make_support::{out_dir, rustc, wasmparser}; +use run_make_support::{tmp_dir, wasmparser, rustc}; use std::collections::HashMap; use wasmparser::TypeRef::Func; @@ -9,10 +9,15 @@ fn main() { return; } - rustc().arg("foo.rs").arg("--target=wasm32-wasip1").run(); - rustc().arg("bar.rs").arg("--target=wasm32-wasip1").arg("-Clto").arg("-O").run(); + rustc().input("foo.rs").target("wasm32-wasip1").run(); + rustc() + .input("bar.rs") + .target("wasm32-wasip1") + .arg("-Clto") + .opt() + .run(); - let file = std::fs::read(&out_dir().join("bar.wasm")).unwrap(); + let file = std::fs::read(&tmp_dir().join("bar.wasm")).unwrap(); let mut imports = HashMap::new(); for payload in wasmparser::Parser::new(0).parse_all(&file) { diff --git a/tests/run-make/wasm-panic-small/rmake.rs b/tests/run-make/wasm-panic-small/rmake.rs index 0260485f7447..7941b503994d 100644 --- a/tests/run-make/wasm-panic-small/rmake.rs +++ b/tests/run-make/wasm-panic-small/rmake.rs @@ -2,7 +2,7 @@ extern crate run_make_support; -use run_make_support::{out_dir, rustc}; +use run_make_support::{rustc, tmp_dir}; fn main() { if std::env::var("TARGET").unwrap() != "wasm32-wasip1" { @@ -17,16 +17,10 @@ fn main() { fn test(cfg: &str) { eprintln!("running cfg {cfg:?}"); - rustc() - .arg("foo.rs") - .arg("--target=wasm32-wasip1") - .arg("-Clto") - .arg("-O") - .arg("--cfg") - .arg(cfg) - .run(); - let bytes = std::fs::read(&out_dir().join("foo.wasm")).unwrap(); + rustc().input("foo.rs").target("wasm32-wasip1").arg("-Clto").opt().cfg(cfg).run(); + + let bytes = std::fs::read(&tmp_dir().join("foo.wasm")).unwrap(); println!("{}", bytes.len()); assert!(bytes.len() < 40_000); } diff --git a/tests/run-make/wasm-spurious-import/rmake.rs b/tests/run-make/wasm-spurious-import/rmake.rs index 0ac9104bfb4e..9dafa6f594a9 100644 --- a/tests/run-make/wasm-spurious-import/rmake.rs +++ b/tests/run-make/wasm-spurious-import/rmake.rs @@ -1,8 +1,7 @@ extern crate run_make_support; -use run_make_support::{out_dir, rustc, wasmparser}; +use run_make_support::{rustc, tmp_dir, wasmparser}; use std::collections::HashMap; -use wasmparser::TypeRef::Func; fn main() { if std::env::var("TARGET").unwrap() != "wasm32-wasip1" { @@ -10,15 +9,15 @@ fn main() { } rustc() - .arg("main.rs") - .arg("--target=wasm32-wasip1") - .arg("-Coverflow-checks=yes") + .input("main.rs") + .target("wasm32-wasip1") + .arg("-Coverflow-checks") .arg("-Cpanic=abort") .arg("-Clto") .arg("-Copt-level=z") .run(); - let file = std::fs::read(&out_dir().join("main.wasm")).unwrap(); + let file = std::fs::read(&tmp_dir().join("main.wasm")).unwrap(); let mut imports = HashMap::new(); for payload in wasmparser::Parser::new(0).parse_all(&file) { diff --git a/tests/run-make/wasm-stringify-ints-small/rmake.rs b/tests/run-make/wasm-stringify-ints-small/rmake.rs index 80cff7acdf41..6b3ad871a707 100644 --- a/tests/run-make/wasm-stringify-ints-small/rmake.rs +++ b/tests/run-make/wasm-stringify-ints-small/rmake.rs @@ -2,16 +2,16 @@ extern crate run_make_support; -use run_make_support::{out_dir, rustc}; +use run_make_support::{rustc, tmp_dir}; fn main() { if std::env::var("TARGET").unwrap() != "wasm32-wasip1" { return; } - rustc().arg("foo.rs").arg("--target=wasm32-wasip1").arg("-Clto").arg("-O").run(); + rustc().input("foo.rs").target("wasm32-wasip1").arg("-Clto").opt().run(); - let bytes = std::fs::read(&out_dir().join("foo.wasm")).unwrap(); + let bytes = std::fs::read(&tmp_dir().join("foo.wasm")).unwrap(); println!("{}", bytes.len()); assert!(bytes.len() < 50_000); } diff --git a/tests/run-make/wasm-symbols-different-module/rmake.rs b/tests/run-make/wasm-symbols-different-module/rmake.rs index c3cc1e0c32b7..a27da446baae 100644 --- a/tests/run-make/wasm-symbols-different-module/rmake.rs +++ b/tests/run-make/wasm-symbols-different-module/rmake.rs @@ -1,6 +1,6 @@ extern crate run_make_support; -use run_make_support::{out_dir, rustc, wasmparser}; +use run_make_support::{rustc, tmp_dir, wasmparser}; use std::collections::{HashMap, HashSet}; fn main() { @@ -24,9 +24,9 @@ fn test_file(file: &str, expected_imports: &[(&str, &[&str])]) { fn test(file: &str, args: &[&str], expected_imports: &[(&str, &[&str])]) { println!("test {file:?} {args:?} for {expected_imports:?}"); - rustc().arg(file).arg("--target=wasm32-wasip1").args(args).run(); + rustc().input(file).target("wasm32-wasip1").args(args).run(); - let file = std::fs::read(&out_dir().join(file).with_extension("wasm")).unwrap(); + let file = std::fs::read(&tmp_dir().join(file).with_extension("wasm")).unwrap(); let mut imports = HashMap::new(); for payload in wasmparser::Parser::new(0).parse_all(&file) { diff --git a/tests/run-make/wasm-symbols-not-exported/rmake.rs b/tests/run-make/wasm-symbols-not-exported/rmake.rs index 5ff0dc578b34..da536f2af71a 100644 --- a/tests/run-make/wasm-symbols-not-exported/rmake.rs +++ b/tests/run-make/wasm-symbols-not-exported/rmake.rs @@ -1,6 +1,6 @@ extern crate run_make_support; -use run_make_support::{out_dir, rustc, wasmparser}; +use run_make_support::{rustc, tmp_dir, wasmparser}; use std::path::Path; fn main() { @@ -8,15 +8,15 @@ fn main() { return; } - rustc().arg("foo.rs").arg("--target=wasm32-wasip1").run(); - verify_symbols(&out_dir().join("foo.wasm")); - rustc().arg("foo.rs").arg("--target=wasm32-wasip1").arg("-O").run(); - verify_symbols(&out_dir().join("foo.wasm")); + rustc().input("foo.rs").target("wasm32-wasip1").run(); + verify_symbols(&tmp_dir().join("foo.wasm")); + rustc().input("foo.rs").target("wasm32-wasip1").opt().run(); + verify_symbols(&tmp_dir().join("foo.wasm")); - rustc().arg("bar.rs").arg("--target=wasm32-wasip1").run(); - verify_symbols(&out_dir().join("bar.wasm")); - rustc().arg("bar.rs").arg("--target=wasm32-wasip1").arg("-O").run(); - verify_symbols(&out_dir().join("bar.wasm")); + rustc().input("bar.rs").target("wasm32-wasip1").run(); + verify_symbols(&tmp_dir().join("bar.wasm")); + rustc().input("bar.rs").target("wasm32-wasip1").opt().run(); + verify_symbols(&tmp_dir().join("bar.wasm")); } fn verify_symbols(path: &Path) { diff --git a/tests/run-make/wasm-symbols-not-imported/rmake.rs b/tests/run-make/wasm-symbols-not-imported/rmake.rs index 974f415166b9..b784b6aff6a2 100644 --- a/tests/run-make/wasm-symbols-not-imported/rmake.rs +++ b/tests/run-make/wasm-symbols-not-imported/rmake.rs @@ -1,6 +1,6 @@ extern crate run_make_support; -use run_make_support::{out_dir, rustc, wasmparser}; +use run_make_support::{rustc, tmp_dir, wasmparser}; use std::path::Path; fn main() { @@ -8,14 +8,14 @@ fn main() { return; } - rustc().arg("foo.rs").arg("--target=wasm32-wasip1").run(); - verify_symbols(&out_dir().join("foo.wasm")); - rustc().arg("foo.rs").arg("--target=wasm32-wasip1").arg("-Clto").run(); - verify_symbols(&out_dir().join("foo.wasm")); - rustc().arg("foo.rs").arg("--target=wasm32-wasip1").arg("-O").run(); - verify_symbols(&out_dir().join("foo.wasm")); - rustc().arg("foo.rs").arg("--target=wasm32-wasip1").arg("-Clto").arg("-O").run(); - verify_symbols(&out_dir().join("foo.wasm")); + rustc().input("foo.rs").target("wasm32-wasip1").run(); + verify_symbols(&tmp_dir().join("foo.wasm")); + rustc().input("foo.rs").target("wasm32-wasip1").arg("-Clto").run(); + verify_symbols(&tmp_dir().join("foo.wasm")); + rustc().input("foo.rs").target("wasm32-wasip1").opt().run(); + verify_symbols(&tmp_dir().join("foo.wasm")); + rustc().input("foo.rs").target("wasm32-wasip1").arg("-Clto").opt().run(); + verify_symbols(&tmp_dir().join("foo.wasm")); } fn verify_symbols(path: &Path) { From 955f762fc170814cb3b81f3f4831250b90155bfc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= Date: Mon, 25 Mar 2024 00:00:00 +0000 Subject: [PATCH 040/165] Function ABI is irrelevant for reachability --- compiler/rustc_passes/src/reachable.rs | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/compiler/rustc_passes/src/reachable.rs b/compiler/rustc_passes/src/reachable.rs index c2e604b02b3d..b8db7fda4d84 100644 --- a/compiler/rustc_passes/src/reachable.rs +++ b/compiler/rustc_passes/src/reachable.rs @@ -19,7 +19,6 @@ use rustc_middle::query::Providers; use rustc_middle::ty::{self, ExistentialTraitRef, TyCtxt}; use rustc_privacy::DefIdVisitor; use rustc_session::config::CrateType; -use rustc_target::spec::abi::Abi; fn item_might_be_inlined(tcx: TyCtxt<'_>, def_id: DefId) -> bool { tcx.generics_of(def_id).requires_monomorphization(tcx) @@ -141,16 +140,6 @@ impl<'tcx> ReachableContext<'tcx> { if !self.any_library { // If we are building an executable, only explicitly extern // types need to be exported. - let reachable = - if let Node::Item(hir::Item { kind: hir::ItemKind::Fn(sig, ..), .. }) - | Node::ImplItem(hir::ImplItem { - kind: hir::ImplItemKind::Fn(sig, ..), .. - }) = *node - { - sig.header.abi != Abi::Rust - } else { - false - }; let codegen_attrs = if self.tcx.def_kind(search_item).has_codegen_attrs() { self.tcx.codegen_fn_attrs(search_item) } else { @@ -159,7 +148,7 @@ impl<'tcx> ReachableContext<'tcx> { let is_extern = codegen_attrs.contains_extern_indicator(); let std_internal = codegen_attrs.flags.contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL); - if reachable || is_extern || std_internal { + if is_extern || std_internal { self.reachable_symbols.insert(search_item); } } else { From 847fd88df724280880c705848ba1a120ce15e020 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sun, 24 Mar 2024 20:06:05 -0400 Subject: [PATCH 041/165] Always use tcx.coroutine_layout over calling optimized_mir directly --- .../src/debuginfo/metadata/enums/cpp_like.rs | 2 +- .../rustc_codegen_llvm/src/debuginfo/metadata/enums/native.rs | 3 +-- compiler/rustc_ty_utils/src/layout.rs | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs index 4792b0798dfb..9a10e1bc1299 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs @@ -683,7 +683,7 @@ fn build_union_fields_for_direct_tag_coroutine<'ll, 'tcx>( _ => unreachable!(), }; - let coroutine_layout = cx.tcx.optimized_mir(coroutine_def_id).coroutine_layout().unwrap(); + let coroutine_layout = cx.tcx.coroutine_layout(coroutine_def_id).unwrap(); let common_upvar_names = cx.tcx.closure_saved_names_of_captured_variables(coroutine_def_id); let variant_range = coroutine_args.variant_range(coroutine_def_id, cx.tcx); diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/native.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/native.rs index 3dbe820b8ff9..f0f55981760c 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/native.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/native.rs @@ -158,8 +158,7 @@ pub(super) fn build_coroutine_di_node<'ll, 'tcx>( DIFlags::FlagZero, ), |cx, coroutine_type_di_node| { - let coroutine_layout = - cx.tcx.optimized_mir(coroutine_def_id).coroutine_layout().unwrap(); + let coroutine_layout = cx.tcx.coroutine_layout(coroutine_def_id).unwrap(); let Variants::Multiple { tag_encoding: TagEncoding::Direct, ref variants, .. } = coroutine_type_and_layout.variants diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs index 9c3d39307b26..85ac6071a08c 100644 --- a/compiler/rustc_ty_utils/src/layout.rs +++ b/compiler/rustc_ty_utils/src/layout.rs @@ -1072,7 +1072,7 @@ fn variant_info_for_coroutine<'tcx>( return (vec![], None); }; - let coroutine = cx.tcx.optimized_mir(def_id).coroutine_layout().unwrap(); + let coroutine = cx.tcx.coroutine_layout(def_id).unwrap(); let upvar_names = cx.tcx.closure_saved_names_of_captured_variables(def_id); let mut upvars_size = Size::ZERO; From b7d67eace78d5e660df93b513326650fe8226a96 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sun, 24 Mar 2024 21:12:49 -0400 Subject: [PATCH 042/165] Require coroutine kind type to be passed to TyCtxt::coroutine_layout --- .../src/debuginfo/metadata/enums/cpp_like.rs | 3 +- .../src/debuginfo/metadata/enums/native.rs | 7 +++- .../src/transform/validate.rs | 13 ++++--- compiler/rustc_middle/src/mir/mod.rs | 3 +- compiler/rustc_middle/src/mir/pretty.rs | 2 +- compiler/rustc_middle/src/ty/mod.rs | 37 ++++++++++++++++++- compiler/rustc_middle/src/ty/sty.rs | 7 +++- compiler/rustc_ty_utils/src/layout.rs | 4 +- 8 files changed, 59 insertions(+), 17 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs index 9a10e1bc1299..4edef14422e5 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs @@ -683,7 +683,8 @@ fn build_union_fields_for_direct_tag_coroutine<'ll, 'tcx>( _ => unreachable!(), }; - let coroutine_layout = cx.tcx.coroutine_layout(coroutine_def_id).unwrap(); + let coroutine_layout = + cx.tcx.coroutine_layout(coroutine_def_id, coroutine_args.kind_ty()).unwrap(); let common_upvar_names = cx.tcx.closure_saved_names_of_captured_variables(coroutine_def_id); let variant_range = coroutine_args.variant_range(coroutine_def_id, cx.tcx); diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/native.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/native.rs index f0f55981760c..115d5187eafa 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/native.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/native.rs @@ -135,7 +135,7 @@ pub(super) fn build_coroutine_di_node<'ll, 'tcx>( unique_type_id: UniqueTypeId<'tcx>, ) -> DINodeCreationResult<'ll> { let coroutine_type = unique_type_id.expect_ty(); - let &ty::Coroutine(coroutine_def_id, _) = coroutine_type.kind() else { + let &ty::Coroutine(coroutine_def_id, coroutine_args) = coroutine_type.kind() else { bug!("build_coroutine_di_node() called with non-coroutine type: `{:?}`", coroutine_type) }; @@ -158,7 +158,10 @@ pub(super) fn build_coroutine_di_node<'ll, 'tcx>( DIFlags::FlagZero, ), |cx, coroutine_type_di_node| { - let coroutine_layout = cx.tcx.coroutine_layout(coroutine_def_id).unwrap(); + let coroutine_layout = cx + .tcx + .coroutine_layout(coroutine_def_id, coroutine_args.as_coroutine().kind_ty()) + .unwrap(); let Variants::Multiple { tag_encoding: TagEncoding::Direct, ref variants, .. } = coroutine_type_and_layout.variants diff --git a/compiler/rustc_const_eval/src/transform/validate.rs b/compiler/rustc_const_eval/src/transform/validate.rs index 08e3e42a82e2..b085e4e76a11 100644 --- a/compiler/rustc_const_eval/src/transform/validate.rs +++ b/compiler/rustc_const_eval/src/transform/validate.rs @@ -101,9 +101,9 @@ impl<'tcx> MirPass<'tcx> for Validator { } // Enforce that coroutine-closure layouts are identical. - if let Some(layout) = body.coroutine_layout() + if let Some(layout) = body.coroutine_layout_raw() && let Some(by_move_body) = body.coroutine_by_move_body() - && let Some(by_move_layout) = by_move_body.coroutine_layout() + && let Some(by_move_layout) = by_move_body.coroutine_layout_raw() { if layout != by_move_layout { // If this turns out not to be true, please let compiler-errors know. @@ -715,13 +715,14 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { // args of the coroutine. Otherwise, we prefer to use this body // since we may be in the process of computing this MIR in the // first place. - let gen_body = if def_id == self.caller_body.source.def_id() { - self.caller_body + let layout = if def_id == self.caller_body.source.def_id() { + // FIXME: This is not right for async closures. + self.caller_body.coroutine_layout_raw() } else { - self.tcx.optimized_mir(def_id) + self.tcx.coroutine_layout(def_id, args.as_coroutine().kind_ty()) }; - let Some(layout) = gen_body.coroutine_layout() else { + let Some(layout) = layout else { self.fail( location, format!("No coroutine layout for {parent_ty:?}"), diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index e4dce2bdc9e8..02af55fbf0e4 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -652,8 +652,9 @@ impl<'tcx> Body<'tcx> { self.coroutine.as_ref().and_then(|coroutine| coroutine.resume_ty) } + /// Prefer going through [`TyCtxt::coroutine_layout`] rather than using this directly. #[inline] - pub fn coroutine_layout(&self) -> Option<&CoroutineLayout<'tcx>> { + pub fn coroutine_layout_raw(&self) -> Option<&CoroutineLayout<'tcx>> { self.coroutine.as_ref().and_then(|coroutine| coroutine.coroutine_layout.as_ref()) } diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs index f0499cf344fc..41df2e3b5875 100644 --- a/compiler/rustc_middle/src/mir/pretty.rs +++ b/compiler/rustc_middle/src/mir/pretty.rs @@ -126,7 +126,7 @@ fn dump_matched_mir_node<'tcx, F>( Some(promoted) => write!(file, "::{promoted:?}`")?, } writeln!(file, " {disambiguator} {pass_name}")?; - if let Some(ref layout) = body.coroutine_layout() { + if let Some(ref layout) = body.coroutine_layout_raw() { writeln!(file, "/* coroutine_layout = {layout:#?} */")?; } writeln!(file)?; diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 6ce53ccc8cd7..aad2f6a4cf8a 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -60,6 +60,7 @@ pub use rustc_target::abi::{ReprFlags, ReprOptions}; pub use rustc_type_ir::{DebugWithInfcx, InferCtxtLike, WithInfcx}; pub use vtable::*; +use std::assert_matches::assert_matches; use std::fmt::Debug; use std::hash::{Hash, Hasher}; use std::marker::PhantomData; @@ -1826,8 +1827,40 @@ impl<'tcx> TyCtxt<'tcx> { /// Returns layout of a coroutine. Layout might be unavailable if the /// coroutine is tainted by errors. - pub fn coroutine_layout(self, def_id: DefId) -> Option<&'tcx CoroutineLayout<'tcx>> { - self.optimized_mir(def_id).coroutine_layout() + /// + /// Takes `coroutine_kind` which can be acquired from the `CoroutineArgs::kind_ty`, + /// e.g. `args.as_coroutine().kind_ty()`. + pub fn coroutine_layout( + self, + def_id: DefId, + coroutine_kind_ty: Ty<'tcx>, + ) -> Option<&'tcx CoroutineLayout<'tcx>> { + let mir = self.optimized_mir(def_id); + // Regular coroutine + if coroutine_kind_ty.is_unit() { + mir.coroutine_layout_raw() + } else { + // If we have a `Coroutine` that comes from an coroutine-closure, + // then it may be a by-move or by-ref body. + let ty::Coroutine(_, identity_args) = + *self.type_of(def_id).instantiate_identity().kind() + else { + unreachable!(); + }; + let identity_kind_ty = identity_args.as_coroutine().kind_ty(); + // If the types differ, then we must be getting the by-move body of + // a by-ref coroutine. + if identity_kind_ty == coroutine_kind_ty { + mir.coroutine_layout_raw() + } else { + assert_matches!(coroutine_kind_ty.to_opt_closure_kind(), Some(ClosureKind::FnOnce)); + assert_matches!( + identity_kind_ty.to_opt_closure_kind(), + Some(ClosureKind::Fn | ClosureKind::FnMut) + ); + mir.coroutine_by_move_body().unwrap().coroutine_layout_raw() + } + } } /// Given the `DefId` of an impl, returns the `DefId` of the trait it implements. diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index c85ee140fa4e..82a2423cbc6b 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -694,7 +694,10 @@ impl<'tcx> CoroutineArgs<'tcx> { #[inline] pub fn variant_range(&self, def_id: DefId, tcx: TyCtxt<'tcx>) -> Range { // FIXME requires optimized MIR - FIRST_VARIANT..tcx.coroutine_layout(def_id).unwrap().variant_fields.next_index() + // FIXME(async_closures): We should assert all coroutine layouts have + // the same number of variants. + FIRST_VARIANT + ..tcx.coroutine_layout(def_id, tcx.types.unit).unwrap().variant_fields.next_index() } /// The discriminant for the given variant. Panics if the `variant_index` is @@ -754,7 +757,7 @@ impl<'tcx> CoroutineArgs<'tcx> { def_id: DefId, tcx: TyCtxt<'tcx>, ) -> impl Iterator> + Captures<'tcx>> { - let layout = tcx.coroutine_layout(def_id).unwrap(); + let layout = tcx.coroutine_layout(def_id, self.kind_ty()).unwrap(); layout.variant_fields.iter().map(move |variant| { variant.iter().map(move |field| { ty::EarlyBinder::bind(layout.field_tys[*field].ty).instantiate(tcx, self.args) diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs index 85ac6071a08c..331970ac3623 100644 --- a/compiler/rustc_ty_utils/src/layout.rs +++ b/compiler/rustc_ty_utils/src/layout.rs @@ -745,7 +745,7 @@ fn coroutine_layout<'tcx>( let tcx = cx.tcx; let instantiate_field = |ty: Ty<'tcx>| EarlyBinder::bind(ty).instantiate(tcx, args); - let Some(info) = tcx.coroutine_layout(def_id) else { + let Some(info) = tcx.coroutine_layout(def_id, args.as_coroutine().kind_ty()) else { return Err(error(cx, LayoutError::Unknown(ty))); }; let (ineligible_locals, assignments) = coroutine_saved_local_eligibility(info); @@ -1072,7 +1072,7 @@ fn variant_info_for_coroutine<'tcx>( return (vec![], None); }; - let coroutine = cx.tcx.coroutine_layout(def_id).unwrap(); + let coroutine = cx.tcx.coroutine_layout(def_id, args.as_coroutine().kind_ty()).unwrap(); let upvar_names = cx.tcx.closure_saved_names_of_captured_variables(def_id); let mut upvars_size = Size::ZERO; From 9bda9ac76e8d232c6cf0efde55dace718c1d428c Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sun, 24 Mar 2024 21:14:49 -0400 Subject: [PATCH 043/165] Relax validation now --- compiler/rustc_const_eval/src/transform/validate.rs | 9 ++++----- compiler/rustc_middle/src/ty/sty.rs | 2 -- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_const_eval/src/transform/validate.rs b/compiler/rustc_const_eval/src/transform/validate.rs index b085e4e76a11..378b168a50c3 100644 --- a/compiler/rustc_const_eval/src/transform/validate.rs +++ b/compiler/rustc_const_eval/src/transform/validate.rs @@ -105,14 +105,13 @@ impl<'tcx> MirPass<'tcx> for Validator { && let Some(by_move_body) = body.coroutine_by_move_body() && let Some(by_move_layout) = by_move_body.coroutine_layout_raw() { - if layout != by_move_layout { - // If this turns out not to be true, please let compiler-errors know. - // It is possible to support, but requires some changes to the layout - // computation code. + // FIXME(async_closures): We could do other validation here? + if layout.variant_fields.len() != by_move_layout.variant_fields.len() { cfg_checker.fail( Location::START, format!( - "Coroutine layout differs from by-move coroutine layout:\n\ + "Coroutine layout has different number of variant fields from \ + by-move coroutine layout:\n\ layout: {layout:#?}\n\ by_move_layout: {by_move_layout:#?}", ), diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 82a2423cbc6b..510a4b59520c 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -694,8 +694,6 @@ impl<'tcx> CoroutineArgs<'tcx> { #[inline] pub fn variant_range(&self, def_id: DefId, tcx: TyCtxt<'tcx>) -> Range { // FIXME requires optimized MIR - // FIXME(async_closures): We should assert all coroutine layouts have - // the same number of variants. FIRST_VARIANT ..tcx.coroutine_layout(def_id, tcx.types.unit).unwrap().variant_fields.next_index() } From 4609a48d6a0f9bfcedcf622e19646cc2400fa98f Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sun, 24 Mar 2024 21:42:32 -0400 Subject: [PATCH 044/165] Add async-closures/once.rs back to cranelift tests --- 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 9b360fb30362..fcf3ba035748 100755 --- a/scripts/test_rustc_tests.sh +++ b/scripts/test_rustc_tests.sh @@ -154,7 +154,6 @@ rm tests/ui/codegen/subtyping-enforces-type-equality.rs # assert_assignable bug # ====================== rm tests/ui/backtrace.rs # TODO warning rm tests/ui/process/nofile-limit.rs # TODO some AArch64 linking issue -rm tests/ui/async-await/async-closures/once.rs # FIXME bug in the rustc FnAbi calculation code rm tests/ui/stdio-is-blocking.rs # really slow with unoptimized libstd From 0231d65cec8e6e48a0e46f1e285901f743d05896 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Mon, 25 Mar 2024 14:05:11 +0000 Subject: [PATCH 045/165] Rustup to rustc 1.79.0-nightly (0824b300e 2024-03-24) --- rust-toolchain | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-toolchain b/rust-toolchain index 1901f699b9dc..3845b57b91d0 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2024-03-22" +channel = "nightly-2024-03-25" components = ["rust-src", "rustc-dev", "llvm-tools"] From c53025b45d741955fee5c1bb25fdee25676abe96 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Mon, 25 Mar 2024 14:19:07 +0000 Subject: [PATCH 046/165] Add needs-unwind annotations to a couple of tests --- scripts/test_rustc_tests.sh | 6 ------ 1 file changed, 6 deletions(-) diff --git a/scripts/test_rustc_tests.sh b/scripts/test_rustc_tests.sh index 9b360fb30362..7f47fd972c44 100755 --- a/scripts/test_rustc_tests.sh +++ b/scripts/test_rustc_tests.sh @@ -41,12 +41,6 @@ rm tests/ui/parser/unclosed-delimiter-in-dep.rs # submodule contains //~ERROR # missing features # ================ -# requires stack unwinding -# FIXME add needs-unwind to these tests -rm -r tests/run-make/libtest-junit -rm tests/ui/asm/may_unwind.rs -rm tests/ui/stable-mir-print/basic_function.rs - # extra warning about -Cpanic=abort for proc macros rm tests/ui/proc-macro/crt-static.rs rm tests/ui/proc-macro/proc-macro-deprecated-attr.rs From 187decaf18a2ceb9d1e8e04bd273de807318526b Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Mon, 25 Mar 2024 14:29:11 +0000 Subject: [PATCH 047/165] Fix rustc test suite --- 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 b7808b6f4c3d..d3d1477bdecc 100755 --- a/scripts/test_rustc_tests.sh +++ b/scripts/test_rustc_tests.sh @@ -123,6 +123,7 @@ rm -r tests/run-make/issue-88756-default-output # should work when using ./x.py test the way it is intended # ============================================================ rm -r tests/run-make/remap-path-prefix-dwarf # requires llvm-dwarfdump +rm -r tests/run-make/compiler-builtins # Expects lib/rustlib/src/rust to contains the standard library source # genuine bugs # ============ From 654ce59f701b05fb15ef6c009988a4d0fc4b34c4 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Mon, 25 Mar 2024 14:41:19 +0000 Subject: [PATCH 048/165] Remove ignore for fixed rustc test --- 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 d3d1477bdecc..7e4a1a5c787b 100755 --- a/scripts/test_rustc_tests.sh +++ b/scripts/test_rustc_tests.sh @@ -49,7 +49,6 @@ rm tests/ui/proc-macro/allowed-signatures.rs rm tests/ui/proc-macro/no-mangle-in-proc-macro-issue-111888.rs # vendor intrinsics -rm tests/ui/simd/array-type.rs # "Index argument for `simd_insert` is not a constant" rm tests/ui/asm/x86_64/evex512-implicit-feature.rs # unimplemented AVX512 x86 vendor intrinsic # exotic linkages From 49777c3bfacc927b8c0771217b027d9ee287b6dc Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Mon, 25 Mar 2024 14:24:08 +0000 Subject: [PATCH 049/165] Add needs-unwind for proc macro tests Rustc gives a warning when compiling proc macros with panic=abort. --- scripts/test_rustc_tests.sh | 9 --------- 1 file changed, 9 deletions(-) diff --git a/scripts/test_rustc_tests.sh b/scripts/test_rustc_tests.sh index 7f47fd972c44..b6651fa28919 100755 --- a/scripts/test_rustc_tests.sh +++ b/scripts/test_rustc_tests.sh @@ -41,15 +41,6 @@ rm tests/ui/parser/unclosed-delimiter-in-dep.rs # submodule contains //~ERROR # missing features # ================ -# extra warning about -Cpanic=abort for proc macros -rm tests/ui/proc-macro/crt-static.rs -rm tests/ui/proc-macro/proc-macro-deprecated-attr.rs -rm tests/ui/proc-macro/quote-debug.rs -rm tests/ui/proc-macro/no-missing-docs.rs -rm tests/ui/rust-2018/proc-macro-crate-in-paths.rs -rm tests/ui/proc-macro/allowed-signatures.rs -rm tests/ui/proc-macro/no-mangle-in-proc-macro-issue-111888.rs - # vendor intrinsics rm tests/ui/simd/array-type.rs # "Index argument for `simd_insert` is not a constant" rm tests/ui/asm/x86_64/evex512-implicit-feature.rs # unimplemented AVX512 x86 vendor intrinsic From 8560d01a96f38790299c20b9c34dcc6853a08a00 Mon Sep 17 00:00:00 2001 From: klensy Date: Mon, 25 Mar 2024 23:19:40 +0300 Subject: [PATCH 050/165] lib: fix some unnecessary_cast clippy lint warning: casting raw pointers to the same type and constness is unnecessary (`*mut V` -> `*mut V`) --> library\alloc\src\collections\btree\map\entry.rs:357:31 | 357 | let val_ptr = root.borrow_mut().push(self.key, value) as *mut V; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `root.borrow_mut().push (self.key, value)` | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_cast warning: casting to the same type is unnecessary (`usize` -> `usize`) --> library\alloc\src\ffi\c_str.rs:411:56 | 411 | let slice = slice::from_raw_parts_mut(ptr, len as usize); | ^^^^^^^^^^^^ help: try: `len` | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_cast warning: casting raw pointers to the same type and constness is unnecessary (`*mut T` -> `*mut T`) --> library\alloc\src\slice.rs:516:25 | 516 | (buf.as_mut_ptr() as *mut T).add(buf.len()), | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `buf.as_mut_ptr()` | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_cast warning: casting raw pointers to the same type and constness is unnecessary (`*mut T` -> `*mut T`) --> library\alloc\src\slice.rs:537:21 | 537 | (buf.as_mut_ptr() as *mut T).add(buf.len()), | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `buf.as_mut_ptr()` | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_cast warning: casting raw pointers to the same type and constness is unnecessary (`*const ()` -> `*const ()`) --> library\alloc\src\task.rs:151:13 | 151 | waker as *const (), | ^^^^^^^^^^^^^^^^^^ help: try: `waker` | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_cast warning: casting raw pointers to the same type and constness is unnecessary (`*const ()` -> `*const ()`) --> library\alloc\src\task.rs:323:13 | 323 | waker as *const (), | ^^^^^^^^^^^^^^^^^^ help: try: `waker` | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_cast warning: casting to the same type is unnecessary (`usize` -> `usize`) --> library\std\src\sys_common\net.rs:110:21 | 110 | assert!(len as usize >= mem::size_of::()); | ^^^^^^^^^^^^ help: try: `len` | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_cast warning: casting to the same type is unnecessary (`usize` -> `usize`) --> library\std\src\sys_common\net.rs:116:21 | 116 | assert!(len as usize >= mem::size_of::()); | ^^^^^^^^^^^^ help: try: `len` | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_cast --- library/alloc/src/collections/btree/map/entry.rs | 2 +- library/alloc/src/ffi/c_str.rs | 2 +- library/alloc/src/slice.rs | 8 ++++---- library/alloc/src/task.rs | 4 ++-- library/std/src/sys_common/net.rs | 4 ++-- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/library/alloc/src/collections/btree/map/entry.rs b/library/alloc/src/collections/btree/map/entry.rs index 0a894258f469..66eb991c6d4b 100644 --- a/library/alloc/src/collections/btree/map/entry.rs +++ b/library/alloc/src/collections/btree/map/entry.rs @@ -354,7 +354,7 @@ impl<'a, K: Ord, V, A: Allocator + Clone> VacantEntry<'a, K, V, A> { // SAFETY: There is no tree yet so no reference to it exists. let map = unsafe { self.dormant_map.awaken() }; let mut root = NodeRef::new_leaf(self.alloc.clone()); - let val_ptr = root.borrow_mut().push(self.key, value) as *mut V; + let val_ptr = root.borrow_mut().push(self.key, value); map.root = Some(root.forget_type()); map.length = 1; val_ptr diff --git a/library/alloc/src/ffi/c_str.rs b/library/alloc/src/ffi/c_str.rs index 0c7f94ccceb0..6a64eaf576bb 100644 --- a/library/alloc/src/ffi/c_str.rs +++ b/library/alloc/src/ffi/c_str.rs @@ -408,7 +408,7 @@ impl CString { fn strlen(s: *const c_char) -> usize; } let len = strlen(ptr) + 1; // Including the NUL byte - let slice = slice::from_raw_parts_mut(ptr, len as usize); + let slice = slice::from_raw_parts_mut(ptr, len); CString { inner: Box::from_raw(slice as *mut [c_char] as *mut [u8]) } } } diff --git a/library/alloc/src/slice.rs b/library/alloc/src/slice.rs index 21d5dce04a0f..ebe6f7e7caa9 100644 --- a/library/alloc/src/slice.rs +++ b/library/alloc/src/slice.rs @@ -511,9 +511,9 @@ impl [T] { while m > 0 { // `buf.extend(buf)`: unsafe { - ptr::copy_nonoverlapping( + ptr::copy_nonoverlapping::( buf.as_ptr(), - (buf.as_mut_ptr() as *mut T).add(buf.len()), + (buf.as_mut_ptr()).add(buf.len()), buf.len(), ); // `buf` has capacity of `self.len() * n`. @@ -532,9 +532,9 @@ impl [T] { // `buf.extend(buf[0 .. rem_len])`: unsafe { // This is non-overlapping since `2^expn > rem`. - ptr::copy_nonoverlapping( + ptr::copy_nonoverlapping::( buf.as_ptr(), - (buf.as_mut_ptr() as *mut T).add(buf.len()), + (buf.as_mut_ptr()).add(buf.len()), rem_len, ); // `buf.len() + rem_len` equals to `buf.capacity()` (`= self.len() * n`). diff --git a/library/alloc/src/task.rs b/library/alloc/src/task.rs index b40768a52b6b..a3fa6585a37f 100644 --- a/library/alloc/src/task.rs +++ b/library/alloc/src/task.rs @@ -148,7 +148,7 @@ fn raw_waker(waker: Arc) -> RawWaker { unsafe fn clone_waker(waker: *const ()) -> RawWaker { unsafe { Arc::increment_strong_count(waker as *const W) }; RawWaker::new( - waker as *const (), + waker, &RawWakerVTable::new(clone_waker::, wake::, wake_by_ref::, drop_waker::), ) } @@ -320,7 +320,7 @@ fn local_raw_waker(waker: Rc) -> RawWaker { unsafe fn clone_waker(waker: *const ()) -> RawWaker { unsafe { Rc::increment_strong_count(waker as *const W) }; RawWaker::new( - waker as *const (), + waker, &RawWakerVTable::new(clone_waker::, wake::, wake_by_ref::, drop_waker::), ) } diff --git a/library/std/src/sys_common/net.rs b/library/std/src/sys_common/net.rs index 581c46af0eac..2d785064245d 100644 --- a/library/std/src/sys_common/net.rs +++ b/library/std/src/sys_common/net.rs @@ -107,13 +107,13 @@ where pub fn sockaddr_to_addr(storage: &c::sockaddr_storage, len: usize) -> io::Result { match storage.ss_family as c_int { c::AF_INET => { - assert!(len as usize >= mem::size_of::()); + assert!(len >= mem::size_of::()); Ok(SocketAddr::V4(FromInner::from_inner(unsafe { *(storage as *const _ as *const c::sockaddr_in) }))) } c::AF_INET6 => { - assert!(len as usize >= mem::size_of::()); + assert!(len >= mem::size_of::()); Ok(SocketAddr::V6(FromInner::from_inner(unsafe { *(storage as *const _ as *const c::sockaddr_in6) }))) From 91547573af82ddac521a5287e2d03a28454a10ce Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Thu, 29 Feb 2024 14:16:32 +0100 Subject: [PATCH 051/165] Implement `-L builtin:$path` --- compiler/rustc_interface/src/tests.rs | 49 +++++++++++++--------- compiler/rustc_session/src/config.rs | 10 ++--- compiler/rustc_session/src/search_paths.rs | 29 ++++++++++++- src/librustdoc/config.rs | 8 +++- 4 files changed, 68 insertions(+), 28 deletions(-) diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index 8a27e9a6453b..8e43d6974fe7 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -315,30 +315,39 @@ fn test_search_paths_tracking_hash_different_order() { json_rendered: HumanReadableErrorType::Default(ColorConfig::Never), }; + let push = |opts: &mut Options, search_path| { + opts.search_paths.push(SearchPath::from_cli_opt( + None, + &opts.target_triple, + &early_dcx, + search_path, + )); + }; + // Reference - v1.search_paths.push(SearchPath::from_cli_opt(&early_dcx, "native=abc")); - v1.search_paths.push(SearchPath::from_cli_opt(&early_dcx, "crate=def")); - v1.search_paths.push(SearchPath::from_cli_opt(&early_dcx, "dependency=ghi")); - v1.search_paths.push(SearchPath::from_cli_opt(&early_dcx, "framework=jkl")); - v1.search_paths.push(SearchPath::from_cli_opt(&early_dcx, "all=mno")); + push(&mut v1, "native=abc"); + push(&mut v1, "crate=def"); + push(&mut v1, "dependency=ghi"); + push(&mut v1, "framework=jkl"); + push(&mut v1, "all=mno"); - v2.search_paths.push(SearchPath::from_cli_opt(&early_dcx, "native=abc")); - v2.search_paths.push(SearchPath::from_cli_opt(&early_dcx, "dependency=ghi")); - v2.search_paths.push(SearchPath::from_cli_opt(&early_dcx, "crate=def")); - v2.search_paths.push(SearchPath::from_cli_opt(&early_dcx, "framework=jkl")); - v2.search_paths.push(SearchPath::from_cli_opt(&early_dcx, "all=mno")); + push(&mut v2, "native=abc"); + push(&mut v2, "dependency=ghi"); + push(&mut v2, "crate=def"); + push(&mut v2, "framework=jkl"); + push(&mut v2, "all=mno"); - v3.search_paths.push(SearchPath::from_cli_opt(&early_dcx, "crate=def")); - v3.search_paths.push(SearchPath::from_cli_opt(&early_dcx, "framework=jkl")); - v3.search_paths.push(SearchPath::from_cli_opt(&early_dcx, "native=abc")); - v3.search_paths.push(SearchPath::from_cli_opt(&early_dcx, "dependency=ghi")); - v3.search_paths.push(SearchPath::from_cli_opt(&early_dcx, "all=mno")); + push(&mut v3, "crate=def"); + push(&mut v3, "framework=jkl"); + push(&mut v3, "native=abc"); + push(&mut v3, "dependency=ghi"); + push(&mut v3, "all=mno"); - v4.search_paths.push(SearchPath::from_cli_opt(&early_dcx, "all=mno")); - v4.search_paths.push(SearchPath::from_cli_opt(&early_dcx, "native=abc")); - v4.search_paths.push(SearchPath::from_cli_opt(&early_dcx, "crate=def")); - v4.search_paths.push(SearchPath::from_cli_opt(&early_dcx, "dependency=ghi")); - v4.search_paths.push(SearchPath::from_cli_opt(&early_dcx, "framework=jkl")); + push(&mut v4, "all=mno"); + push(&mut v4, "native=abc"); + push(&mut v4, "crate=def"); + push(&mut v4, "dependency=ghi"); + push(&mut v4, "framework=jkl"); assert_same_hash(&v1, &v2); assert_same_hash(&v1, &v3); diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index c06fe29c5673..793286592277 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -2795,11 +2795,6 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M let debuginfo = select_debuginfo(matches, &cg); let debuginfo_compression = unstable_opts.debuginfo_compression; - let mut search_paths = vec![]; - for s in &matches.opt_strs("L") { - search_paths.push(SearchPath::from_cli_opt(early_dcx, s)); - } - let libs = parse_libs(early_dcx, matches); let test = matches.opt_present("test"); @@ -2848,6 +2843,11 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M candidate.join("library/std/src/lib.rs").is_file().then_some(candidate) }; + let mut search_paths = vec![]; + for s in &matches.opt_strs("L") { + search_paths.push(SearchPath::from_cli_opt(Some(&sysroot), &target_triple, early_dcx, s)); + } + let working_dir = std::env::current_dir().unwrap_or_else(|e| { early_dcx.early_fatal(format!("Current directory is invalid: {e}")); }); diff --git a/compiler/rustc_session/src/search_paths.rs b/compiler/rustc_session/src/search_paths.rs index 32d5e430717b..58b4a08b5b02 100644 --- a/compiler/rustc_session/src/search_paths.rs +++ b/compiler/rustc_session/src/search_paths.rs @@ -1,5 +1,6 @@ use crate::filesearch::make_target_lib_path; use crate::EarlyDiagCtxt; +use rustc_target::spec::TargetTriple; use std::path::{Path, PathBuf}; #[derive(Clone, Debug)] @@ -46,7 +47,12 @@ impl PathKind { } impl SearchPath { - pub fn from_cli_opt(early_dcx: &EarlyDiagCtxt, path: &str) -> Self { + pub fn from_cli_opt( + sysroot: Option<&Path>, + triple: &TargetTriple, + early_dcx: &EarlyDiagCtxt, + path: &str, + ) -> Self { let (kind, path) = if let Some(stripped) = path.strip_prefix("native=") { (PathKind::Native, stripped) } else if let Some(stripped) = path.strip_prefix("crate=") { @@ -57,6 +63,27 @@ impl SearchPath { (PathKind::Framework, stripped) } else if let Some(stripped) = path.strip_prefix("all=") { (PathKind::All, stripped) + } else if let Some(stripped) = path.strip_prefix("builtin:") { + let Some(sysroot) = sysroot else { + early_dcx.early_fatal("`-L builtin:` is not supported without a sysroot present"); + }; + let triple = match triple { + TargetTriple::TargetTriple(triple) => triple, + TargetTriple::TargetJson { .. } => { + early_dcx.early_fatal("`-L builtin:` is not supported with custom targets"); + } + }; + + if stripped.contains(std::path::is_separator) { + early_dcx.early_fatal("`-L builtin:` does not accept paths"); + } + + let path = make_target_lib_path(sysroot, triple).join("builtin").join(stripped); + if !path.is_dir() { + early_dcx.early_fatal(format!("builtin:{stripped} does not exist")); + } + + return Self::new(PathKind::All, path); } else { (PathKind::All, path) }; diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs index be7e319bc79f..ab793bb30621 100644 --- a/src/librustdoc/config.rs +++ b/src/librustdoc/config.rs @@ -460,8 +460,6 @@ impl Options { &matches.free[0] }); - let libs = - matches.opt_strs("L").iter().map(|s| SearchPath::from_cli_opt(early_dcx, s)).collect(); let externs = parse_externs(early_dcx, matches, &unstable_opts); let extern_html_root_urls = match parse_extern_html_roots(matches) { Ok(ex) => ex, @@ -626,6 +624,12 @@ impl Options { let target = parse_target_triple(early_dcx, matches); + let libs = matches + .opt_strs("L") + .iter() + .map(|s| SearchPath::from_cli_opt(None, &target, early_dcx, s)) + .collect(); + let show_coverage = matches.opt_present("show-coverage"); let crate_types = match parse_crate_types_from_list(matches.opt_strs("crate-type")) { From 9ae4e3eb7ca9f9e6c61cedcd8c32f790867a4b37 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Mon, 4 Mar 2024 09:07:02 +0100 Subject: [PATCH 052/165] Make use of sysroot in librustdoc/config.rs for builtin:$path --- src/librustdoc/config.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs index ab793bb30621..fdbbe62c1588 100644 --- a/src/librustdoc/config.rs +++ b/src/librustdoc/config.rs @@ -623,11 +623,12 @@ impl Options { } let target = parse_target_triple(early_dcx, matches); + let maybe_sysroot = matches.opt_str("sysroot").map(PathBuf::from); let libs = matches .opt_strs("L") .iter() - .map(|s| SearchPath::from_cli_opt(None, &target, early_dcx, s)) + .map(|s| SearchPath::from_cli_opt(maybe_sysroot.as_deref(), &target, early_dcx, s)) .collect(); let show_coverage = matches.opt_present("show-coverage"); @@ -657,7 +658,6 @@ impl Options { let bin_crate = crate_types.contains(&CrateType::Executable); let proc_macro_crate = crate_types.contains(&CrateType::ProcMacro); let playground_url = matches.opt_str("playground-url"); - let maybe_sysroot = matches.opt_str("sysroot").map(PathBuf::from); let module_sorting = if matches.opt_present("sort-modules-by-appearance") { ModuleSorting::DeclarationOrder } else { From 2fae4ee92ea9a28722673df442112446f7521079 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Wed, 6 Mar 2024 10:19:34 +0100 Subject: [PATCH 053/165] Make sysroot mandatory for rustdoc --- compiler/rustc_interface/src/tests.rs | 2 +- compiler/rustc_session/src/config.rs | 3 +-- compiler/rustc_session/src/search_paths.rs | 15 +++------------ src/librustdoc/config.rs | 9 ++++++++- 4 files changed, 13 insertions(+), 16 deletions(-) diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index 8e43d6974fe7..3b78e6a43ab3 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -317,7 +317,7 @@ fn test_search_paths_tracking_hash_different_order() { let push = |opts: &mut Options, search_path| { opts.search_paths.push(SearchPath::from_cli_opt( - None, + "not-a-sysroot".as_ref(), &opts.target_triple, &early_dcx, search_path, diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 793286592277..8d186f7c749e 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -2824,7 +2824,6 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M let logical_env = parse_logical_env(early_dcx, matches); let sysroot = filesearch::materialize_sysroot(sysroot_opt); - let real_rust_source_base_dir = { // This is the location used by the `rust-src` `rustup` component. let mut candidate = sysroot.join("lib/rustlib/src/rust"); @@ -2845,7 +2844,7 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M let mut search_paths = vec![]; for s in &matches.opt_strs("L") { - search_paths.push(SearchPath::from_cli_opt(Some(&sysroot), &target_triple, early_dcx, s)); + search_paths.push(SearchPath::from_cli_opt(&sysroot, &target_triple, early_dcx, s)); } let working_dir = std::env::current_dir().unwrap_or_else(|e| { diff --git a/compiler/rustc_session/src/search_paths.rs b/compiler/rustc_session/src/search_paths.rs index 58b4a08b5b02..9cabdec34ae5 100644 --- a/compiler/rustc_session/src/search_paths.rs +++ b/compiler/rustc_session/src/search_paths.rs @@ -48,7 +48,7 @@ impl PathKind { impl SearchPath { pub fn from_cli_opt( - sysroot: Option<&Path>, + sysroot: &Path, triple: &TargetTriple, early_dcx: &EarlyDiagCtxt, path: &str, @@ -64,21 +64,12 @@ impl SearchPath { } else if let Some(stripped) = path.strip_prefix("all=") { (PathKind::All, stripped) } else if let Some(stripped) = path.strip_prefix("builtin:") { - let Some(sysroot) = sysroot else { - early_dcx.early_fatal("`-L builtin:` is not supported without a sysroot present"); - }; - let triple = match triple { - TargetTriple::TargetTriple(triple) => triple, - TargetTriple::TargetJson { .. } => { - early_dcx.early_fatal("`-L builtin:` is not supported with custom targets"); - } - }; - if stripped.contains(std::path::is_separator) { early_dcx.early_fatal("`-L builtin:` does not accept paths"); } - let path = make_target_lib_path(sysroot, triple).join("builtin").join(stripped); + let path = + make_target_lib_path(sysroot, triple.triple()).join("builtin").join(stripped); if !path.is_dir() { early_dcx.early_fatal(format!("builtin:{stripped} does not exist")); } diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs index fdbbe62c1588..f078ad2fb537 100644 --- a/src/librustdoc/config.rs +++ b/src/librustdoc/config.rs @@ -625,10 +625,17 @@ impl Options { let target = parse_target_triple(early_dcx, matches); let maybe_sysroot = matches.opt_str("sysroot").map(PathBuf::from); + let sysroot = match &maybe_sysroot { + Some(s) => s.clone(), + None => { + rustc_session::filesearch::get_or_default_sysroot().expect("Failed finding sysroot") + } + }; + let libs = matches .opt_strs("L") .iter() - .map(|s| SearchPath::from_cli_opt(maybe_sysroot.as_deref(), &target, early_dcx, s)) + .map(|s| SearchPath::from_cli_opt(&sysroot, &target, early_dcx, s)) .collect(); let show_coverage = matches.opt_present("show-coverage"); From 3d65c920404959cc8ef3ba9e963a31fc91983caf Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Wed, 6 Mar 2024 13:28:12 +0100 Subject: [PATCH 054/165] Replace implementation with @RUSTC_BUILTIN prefix substitution var --- compiler/rustc_session/src/config.rs | 1 + compiler/rustc_session/src/search_paths.rs | 21 +++++++-------------- 2 files changed, 8 insertions(+), 14 deletions(-) diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 8d186f7c749e..f612e8b5b1a5 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -2824,6 +2824,7 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M let logical_env = parse_logical_env(early_dcx, matches); let sysroot = filesearch::materialize_sysroot(sysroot_opt); + let real_rust_source_base_dir = { // This is the location used by the `rust-src` `rustup` component. let mut candidate = sysroot.join("lib/rustlib/src/rust"); diff --git a/compiler/rustc_session/src/search_paths.rs b/compiler/rustc_session/src/search_paths.rs index 9cabdec34ae5..16dd40acef04 100644 --- a/compiler/rustc_session/src/search_paths.rs +++ b/compiler/rustc_session/src/search_paths.rs @@ -63,27 +63,20 @@ impl SearchPath { (PathKind::Framework, stripped) } else if let Some(stripped) = path.strip_prefix("all=") { (PathKind::All, stripped) - } else if let Some(stripped) = path.strip_prefix("builtin:") { - if stripped.contains(std::path::is_separator) { - early_dcx.early_fatal("`-L builtin:` does not accept paths"); - } - - let path = - make_target_lib_path(sysroot, triple.triple()).join("builtin").join(stripped); - if !path.is_dir() { - early_dcx.early_fatal(format!("builtin:{stripped} does not exist")); - } - - return Self::new(PathKind::All, path); } else { (PathKind::All, path) }; - if path.is_empty() { + let dir = match path.strip_prefix("@RUSTC_BUILTIN") { + Some(stripped) => { + make_target_lib_path(sysroot, triple.triple()).join("builtin").join(stripped) + } + None => PathBuf::from(path), + }; + if dir.as_os_str().is_empty() { #[allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable early_dcx.early_fatal("empty search path given via `-L`"); } - let dir = PathBuf::from(path); Self::new(kind, dir) } From 08d73799611e06064001bc2839d134b98c07bdad Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Tue, 5 Mar 2024 21:51:22 +0100 Subject: [PATCH 055/165] Use the correct span for simplifying or-patterns We have to make sure we set it everywhere that we set `subcandidates`. --- .../rustc_mir_build/src/build/matches/mod.rs | 21 ++++++++++++------- .../src/build/matches/simplify.rs | 3 ++- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs index f4f452d474f1..0b25213ca7b8 100644 --- a/compiler/rustc_mir_build/src/build/matches/mod.rs +++ b/compiler/rustc_mir_build/src/build/matches/mod.rs @@ -1006,6 +1006,10 @@ struct Candidate<'pat, 'tcx> { /// If the candidate matches, bindings and ascriptions must be established. extra_data: PatternExtraData<'tcx>, + /// If we filled `self.subcandidate`, we store here the span of the or-pattern they came from. + // Invariant: it is `None` iff `subcandidates.is_empty()`. + or_span: Option, + /// The block before the `bindings` have been established. pre_binding_block: Option, /// The pre-binding block of the next candidate. @@ -1028,6 +1032,7 @@ impl<'tcx, 'pat> Candidate<'pat, 'tcx> { extra_data: flat_pat.extra_data, has_guard, subcandidates: Vec::new(), + or_span: None, otherwise_block: None, pre_binding_block: None, next_candidate_pre_binding_block: None, @@ -1277,7 +1282,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // // only generates a single switch. candidate.subcandidates = self.create_or_subcandidates(pats, candidate.has_guard); - candidate.match_pairs.pop(); + let first_match_pair = candidate.match_pairs.pop().unwrap(); + candidate.or_span = Some(first_match_pair.pattern.span); split_or_candidate = true; } } @@ -1531,16 +1537,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { &mut or_candidate_refs, ); candidate.subcandidates = or_candidates; - self.merge_trivial_subcandidates(candidate, self.source_info(or_span)); + candidate.or_span = Some(or_span); + self.merge_trivial_subcandidates(candidate); } /// Try to merge all of the subcandidates of the given candidate into one. /// This avoids exponentially large CFGs in cases like `(1 | 2, 3 | 4, ...)`. - fn merge_trivial_subcandidates( - &mut self, - candidate: &mut Candidate<'_, 'tcx>, - source_info: SourceInfo, - ) { + fn merge_trivial_subcandidates(&mut self, candidate: &mut Candidate<'_, 'tcx>) { if candidate.subcandidates.is_empty() || candidate.has_guard { // FIXME(or_patterns; matthewjasper) Don't give up if we have a guard. return; @@ -1550,7 +1553,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // Not `Iterator::all` because we don't want to short-circuit. for subcandidate in &mut candidate.subcandidates { - self.merge_trivial_subcandidates(subcandidate, source_info); + self.merge_trivial_subcandidates(subcandidate); // FIXME(or_patterns; matthewjasper) Try to be more aggressive here. can_merge &= @@ -1559,6 +1562,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { if can_merge { let any_matches = self.cfg.start_new_block(); + let or_span = candidate.or_span.take().unwrap(); + let source_info = self.source_info(or_span); for subcandidate in mem::take(&mut candidate.subcandidates) { let or_block = subcandidate.pre_binding_block.unwrap(); self.cfg.goto(or_block, source_info, any_matches); diff --git a/compiler/rustc_mir_build/src/build/matches/simplify.rs b/compiler/rustc_mir_build/src/build/matches/simplify.rs index 97b94a0b362a..bf1906f370b6 100644 --- a/compiler/rustc_mir_build/src/build/matches/simplify.rs +++ b/compiler/rustc_mir_build/src/build/matches/simplify.rs @@ -82,7 +82,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { &*candidate.match_pairs { candidate.subcandidates = self.create_or_subcandidates(pats, has_guard); - candidate.match_pairs.pop(); + let first_match_pair = candidate.match_pairs.pop().unwrap(); + candidate.or_span = Some(first_match_pair.pattern.span); } candidate }) From 70e1d23895f861ef6c3d936a91dd5f31e4ca0a40 Mon Sep 17 00:00:00 2001 From: Matthew Maurer Date: Mon, 25 Mar 2024 21:38:05 +0000 Subject: [PATCH 056/165] CFI: Pad out associated type resolution with erased lifetimes `trait_object_ty` assumed that associated types would be fully determined by the trait. This is *almost* true - const parameters and type parameters are no longer allowed, but lifetime parameters are. Since we erase all lifetime parameters anyways, instantiate it with as many erased regions as it needs. Fixes: #123053 --- .../src/typeid/typeid_itanium_cxx_abi.rs | 11 ++++-- .../cfi-assoc-ty-lifetime-issue-123053.rs | 38 +++++++++++++++++++ 2 files changed, 46 insertions(+), 3 deletions(-) create mode 100644 tests/ui/sanitizer/cfi-assoc-ty-lifetime-issue-123053.rs diff --git a/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs b/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs index 3101015281b8..1c6a0f9cf4d4 100644 --- a/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs +++ b/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs @@ -1124,7 +1124,10 @@ pub fn typeid_for_instance<'tcx>( .trait_item_def_id .expect("Part of a trait implementation, but not linked to the def_id?"); let trait_method = tcx.associated_item(method_id); - if traits::is_vtable_safe_method(tcx, trait_ref.skip_binder().def_id, trait_method) { + let trait_id = trait_ref.skip_binder().def_id; + if traits::is_vtable_safe_method(tcx, trait_id, trait_method) + && tcx.object_safety_violations(trait_id).is_empty() + { // Trait methods will have a Self polymorphic parameter, where the concreteized // implementatation will not. We need to walk back to the more general trait method let trait_ref = tcx.instantiate_and_normalize_erasing_regions( @@ -1152,8 +1155,8 @@ pub fn typeid_for_instance<'tcx>( let fn_abi = tcx .fn_abi_of_instance(tcx.param_env(instance.def_id()).and((instance, ty::List::empty()))) - .unwrap_or_else(|instance| { - bug!("typeid_for_instance: couldn't get fn_abi of instance {:?}", instance) + .unwrap_or_else(|error| { + bug!("typeid_for_instance: couldn't get fn_abi of instance {instance:?}: {error:?}") }); typeid_for_fnabi(tcx, fn_abi, options) @@ -1182,6 +1185,7 @@ fn strip_receiver_auto<'tcx>( tcx.mk_args_trait(new_rcvr, args.into_iter().skip(1)) } +#[instrument(skip(tcx), ret)] fn trait_object_ty<'tcx>(tcx: TyCtxt<'tcx>, poly_trait_ref: ty::PolyTraitRef<'tcx>) -> Ty<'tcx> { assert!(!poly_trait_ref.has_non_region_param()); let principal_pred = poly_trait_ref.map_bound(|trait_ref| { @@ -1199,6 +1203,7 @@ fn trait_object_ty<'tcx>(tcx: TyCtxt<'tcx>, poly_trait_ref: ty::PolyTraitRef<'tc ty::ParamEnv::reveal_all(), alias_ty.to_ty(tcx), ); + debug!("Resolved {:?} -> {resolved}", alias_ty.to_ty(tcx)); ty::ExistentialPredicate::Projection(ty::ExistentialProjection { def_id: assoc_ty.def_id, args: ty::ExistentialTraitRef::erase_self_ty(tcx, super_trait_ref).args, diff --git a/tests/ui/sanitizer/cfi-assoc-ty-lifetime-issue-123053.rs b/tests/ui/sanitizer/cfi-assoc-ty-lifetime-issue-123053.rs new file mode 100644 index 000000000000..dd604b6bf7dc --- /dev/null +++ b/tests/ui/sanitizer/cfi-assoc-ty-lifetime-issue-123053.rs @@ -0,0 +1,38 @@ +// Regression test for issue 123053, where associated types with lifetimes caused generation of the +// trait object type to fail, causing an ICE. +// +//@ needs-sanitizer-cfi +//@ compile-flags: -Ccodegen-units=1 -Clto -Ctarget-feature=-crt-static -Zsanitizer=cfi --edition=2021 +//@ no-prefer-dynamic +//@ only-x86_64-unknown-linux-gnu +//@ build-pass + +trait Iterable { + type Item<'a> + where + Self: 'a; + type Iter<'a>: Iterator> + where + Self: 'a; + + fn iter<'a>(&'a self) -> Self::Iter<'a>; +} + +impl Iterable for [T] { + type Item<'a> = as Iterator>::Item where T: 'a; + type Iter<'a> = std::slice::Iter<'a, T> where T: 'a; + + fn iter<'a>(&'a self) -> Self::Iter<'a> { + self.iter() + } +} + +fn get_first<'a, I: Iterable + ?Sized>(it: &'a I) -> Option> { + it.iter().next() +} + +fn main() { + let v = vec![1, 2, 3]; + + assert_eq!(Some(&1), get_first(&*v)); +} From d1d9aa3108aaff42a1b71040d02012001cf53ae0 Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Tue, 5 Mar 2024 21:52:40 +0100 Subject: [PATCH 057/165] Consistently merge simplifiable or-patterns --- .../rustc_mir_build/src/build/matches/mod.rs | 7 +++-- ...e_75439.foo.MatchBranchSimplification.diff | 26 ++++++------------- 2 files changed, 13 insertions(+), 20 deletions(-) diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs index 0b25213ca7b8..fcfd05ccbacf 100644 --- a/compiler/rustc_mir_build/src/build/matches/mod.rs +++ b/compiler/rustc_mir_build/src/build/matches/mod.rs @@ -1293,8 +1293,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // At least one of the candidates has been split into subcandidates. // We need to change the candidate list to include those. let mut new_candidates = Vec::new(); - - for candidate in candidates { + for candidate in candidates.iter_mut() { candidate.visit_leaves(|leaf_candidate| new_candidates.push(leaf_candidate)); } self.match_simplified_candidates( @@ -1304,6 +1303,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { otherwise_block, &mut *new_candidates, ); + + for candidate in candidates { + self.merge_trivial_subcandidates(candidate); + } } else { self.match_simplified_candidates( span, diff --git a/tests/mir-opt/issues/issue_75439.foo.MatchBranchSimplification.diff b/tests/mir-opt/issues/issue_75439.foo.MatchBranchSimplification.diff index f1d18b0f7ff9..f11c993340fd 100644 --- a/tests/mir-opt/issues/issue_75439.foo.MatchBranchSimplification.diff +++ b/tests/mir-opt/issues/issue_75439.foo.MatchBranchSimplification.diff @@ -26,18 +26,20 @@ _3 = _1; _2 = move _3 as [u32; 4] (Transmute); StorageDead(_3); - switchInt(_2[0 of 4]) -> [0: bb1, otherwise: bb6]; + switchInt(_2[0 of 4]) -> [0: bb1, otherwise: bb4]; } bb1: { - switchInt(_2[1 of 4]) -> [0: bb2, otherwise: bb6]; + switchInt(_2[1 of 4]) -> [0: bb2, otherwise: bb4]; } bb2: { - switchInt(_2[2 of 4]) -> [0: bb4, 4294901760: bb5, otherwise: bb6]; + switchInt(_2[2 of 4]) -> [0: bb3, 4294901760: bb3, otherwise: bb4]; } bb3: { + StorageLive(_4); + _4 = _2[3 of 4]; StorageLive(_5); StorageLive(_6); _6 = _4; @@ -46,27 +48,15 @@ _0 = Option::<[u8; 4]>::Some(move _5); StorageDead(_5); StorageDead(_4); - goto -> bb7; + goto -> bb5; } bb4: { - StorageLive(_4); - _4 = _2[3 of 4]; - goto -> bb3; + _0 = Option::<[u8; 4]>::None; + goto -> bb5; } bb5: { - StorageLive(_4); - _4 = _2[3 of 4]; - goto -> bb3; - } - - bb6: { - _0 = Option::<[u8; 4]>::None; - goto -> bb7; - } - - bb7: { StorageDead(_2); return; } From b56279569be90758f1b53bb658ceace1527f5837 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 21 Mar 2024 14:37:43 -0400 Subject: [PATCH 058/165] Require DerefPure for patterns --- compiler/rustc_hir/src/lang_items.rs | 1 + compiler/rustc_hir_typeck/src/pat.rs | 8 ++++++-- compiler/rustc_span/src/symbol.rs | 1 + library/alloc/src/boxed.rs | 5 ++++- library/alloc/src/lib.rs | 1 + library/alloc/src/rc.rs | 5 ++++- library/alloc/src/string.rs | 3 +++ library/alloc/src/sync.rs | 5 ++++- library/alloc/src/vec/mod.rs | 3 +++ library/core/src/ops/deref.rs | 11 +++++++++++ library/core/src/ops/mod.rs | 3 +++ 11 files changed, 41 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_hir/src/lang_items.rs b/compiler/rustc_hir/src/lang_items.rs index dbf86f5cf747..5d97019416f8 100644 --- a/compiler/rustc_hir/src/lang_items.rs +++ b/compiler/rustc_hir/src/lang_items.rs @@ -199,6 +199,7 @@ language_item_table! { Deref, sym::deref, deref_trait, Target::Trait, GenericRequirement::Exact(0); DerefMut, sym::deref_mut, deref_mut_trait, Target::Trait, GenericRequirement::Exact(0); + DerefPure, sym::deref_pure, deref_pure_trait, Target::Trait, GenericRequirement::Exact(0); DerefTarget, sym::deref_target, deref_target, Target::AssocTy, GenericRequirement::None; Receiver, sym::receiver, receiver_trait, Target::Trait, GenericRequirement::None; diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index 4dc60f7c6da1..242523fb3179 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -2002,8 +2002,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { pat_info: PatInfo<'tcx, '_>, ) -> Ty<'tcx> { let tcx = self.tcx; - // FIXME(deref_patterns): use `DerefPure` for soundness - // FIXME(deref_patterns): use `DerefMut` when required + // Register a `DerefPure` bound, which is required by all `deref!()` pats. + self.register_bound( + expected, + tcx.require_lang_item(hir::LangItem::DerefPure, Some(span)), + self.misc(span), + ); // ::Target let ty = Ty::new_projection( tcx, diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 73fcd2a76dfc..891ddb7af5b0 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -674,6 +674,7 @@ symbols! { deref_mut, deref_mut_method, deref_patterns, + deref_pure, deref_target, derive, derive_const, diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs index cfaf533088a2..7c3fa2312e5f 100644 --- a/library/alloc/src/boxed.rs +++ b/library/alloc/src/boxed.rs @@ -161,7 +161,7 @@ use core::marker::Unsize; use core::mem::{self, SizedTypeProperties}; use core::ops::{AsyncFn, AsyncFnMut, AsyncFnOnce}; use core::ops::{ - CoerceUnsized, Coroutine, CoroutineState, Deref, DerefMut, DispatchFromDyn, Receiver, + CoerceUnsized, Coroutine, CoroutineState, Deref, DerefMut, DerefPure, DispatchFromDyn, Receiver, }; use core::pin::Pin; use core::ptr::{self, addr_of_mut, NonNull, Unique}; @@ -1939,6 +1939,9 @@ impl DerefMut for Box { } } +#[unstable(feature = "deref_pure_trait", issue = "87121")] +unsafe impl DerefPure for Box {} + #[unstable(feature = "receiver_trait", issue = "none")] impl Receiver for Box {} diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs index 02d155aaf12f..ebc30c089103 100644 --- a/library/alloc/src/lib.rs +++ b/library/alloc/src/lib.rs @@ -122,6 +122,7 @@ #![feature(const_waker)] #![feature(core_intrinsics)] #![feature(deprecated_suggestion)] +#![feature(deref_pure_trait)] #![feature(dispatch_from_dyn)] #![feature(error_generic_member_access)] #![feature(error_in_core)] diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs index facfc9d208e4..569db54b137f 100644 --- a/library/alloc/src/rc.rs +++ b/library/alloc/src/rc.rs @@ -260,7 +260,7 @@ use core::marker::{PhantomData, Unsize}; #[cfg(not(no_global_oom_handling))] use core::mem::size_of_val; use core::mem::{self, align_of_val_raw, forget, ManuallyDrop}; -use core::ops::{CoerceUnsized, Deref, DerefMut, DispatchFromDyn, Receiver}; +use core::ops::{CoerceUnsized, Deref, DerefMut, DerefPure, DispatchFromDyn, Receiver}; use core::panic::{RefUnwindSafe, UnwindSafe}; #[cfg(not(no_global_oom_handling))] use core::pin::Pin; @@ -2126,6 +2126,9 @@ impl Deref for Rc { } } +#[unstable(feature = "deref_pure_trait", issue = "87121")] +unsafe impl DerefPure for Rc {} + #[unstable(feature = "receiver_trait", issue = "none")] impl Receiver for Rc {} diff --git a/library/alloc/src/string.rs b/library/alloc/src/string.rs index c4dcff1b1c49..3b29b3a8b39a 100644 --- a/library/alloc/src/string.rs +++ b/library/alloc/src/string.rs @@ -2479,6 +2479,9 @@ impl ops::Deref for String { } } +#[unstable(feature = "deref_pure_trait", issue = "87121")] +unsafe impl ops::DerefPure for String {} + #[stable(feature = "derefmut_for_string", since = "1.3.0")] impl ops::DerefMut for String { #[inline] diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs index 7e3e2fb38b13..4dea27221b73 100644 --- a/library/alloc/src/sync.rs +++ b/library/alloc/src/sync.rs @@ -21,7 +21,7 @@ use core::marker::{PhantomData, Unsize}; #[cfg(not(no_global_oom_handling))] use core::mem::size_of_val; use core::mem::{self, align_of_val_raw}; -use core::ops::{CoerceUnsized, Deref, DispatchFromDyn, Receiver}; +use core::ops::{CoerceUnsized, Deref, DerefPure, DispatchFromDyn, Receiver}; use core::panic::{RefUnwindSafe, UnwindSafe}; use core::pin::Pin; use core::ptr::{self, NonNull}; @@ -2107,6 +2107,9 @@ impl Deref for Arc { } } +#[unstable(feature = "deref_pure_trait", issue = "87121")] +unsafe impl DerefPure for Arc {} + #[unstable(feature = "receiver_trait", issue = "none")] impl Receiver for Arc {} diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index 94bed825bb2f..3062f8664b72 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -2772,6 +2772,9 @@ impl ops::DerefMut for Vec { } } +#[unstable(feature = "deref_pure_trait", issue = "87121")] +unsafe impl ops::DerefPure for Vec {} + #[cfg(not(no_global_oom_handling))] #[stable(feature = "rust1", since = "1.0.0")] impl Clone for Vec { diff --git a/library/core/src/ops/deref.rs b/library/core/src/ops/deref.rs index 2c7845d4304f..fe7b6f0d262f 100644 --- a/library/core/src/ops/deref.rs +++ b/library/core/src/ops/deref.rs @@ -275,6 +275,17 @@ impl DerefMut for &mut T { } } +/// UwU +#[unstable(feature = "deref_pure_trait", issue = "87121")] +#[cfg_attr(not(bootstrap), lang = "deref_pure")] +pub unsafe trait DerefPure {} + +#[unstable(feature = "deref_pure_trait", issue = "87121")] +unsafe impl DerefPure for &T {} + +#[unstable(feature = "deref_pure_trait", issue = "87121")] +unsafe impl DerefPure for &mut T {} + /// Indicates that a struct can be used as a method receiver, without the /// `arbitrary_self_types` feature. This is implemented by stdlib pointer types like `Box`, /// `Rc`, `&T`, and `Pin

`. diff --git a/library/core/src/ops/mod.rs b/library/core/src/ops/mod.rs index 4289a86f89b0..ac808bec50ec 100644 --- a/library/core/src/ops/mod.rs +++ b/library/core/src/ops/mod.rs @@ -165,6 +165,9 @@ pub use self::bit::{BitAndAssign, BitOrAssign, BitXorAssign, ShlAssign, ShrAssig #[stable(feature = "rust1", since = "1.0.0")] pub use self::deref::{Deref, DerefMut}; +#[unstable(feature = "deref_pure_trait", issue = "87121")] +pub use self::deref::DerefPure; + #[unstable(feature = "receiver_trait", issue = "none")] pub use self::deref::Receiver; From 5fdc7555c1d6c80a51a3a88c494f255f719bdd35 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 21 Mar 2024 14:38:01 -0400 Subject: [PATCH 059/165] Require DerefMut if deref pattern has nested ref mut binding --- compiler/rustc_hir_typeck/src/pat.rs | 24 +++++++++++++++++++ tests/ui/pattern/deref-patterns/ref-mut.rs | 17 +++++++++++++ .../ui/pattern/deref-patterns/ref-mut.stderr | 20 ++++++++++++++++ 3 files changed, 61 insertions(+) create mode 100644 tests/ui/pattern/deref-patterns/ref-mut.rs create mode 100644 tests/ui/pattern/deref-patterns/ref-mut.stderr diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index 242523fb3179..5f8b833b3064 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -2017,6 +2017,30 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let ty = self.normalize(span, ty); let ty = self.try_structurally_resolve_type(span, ty); self.check_pat(inner, ty, pat_info); + + // Check if the pattern has any `ref mut` bindings, which would require + // `DerefMut` to be emitted in MIR building instead of just `Deref`. + let mut needs_mut = false; + inner.walk(|pat| { + if let hir::PatKind::Binding(_, id, _, _) = pat.kind + && let Some(ty::BindByReference(ty::Mutability::Mut)) = + self.typeck_results.borrow().pat_binding_modes().get(id) + { + needs_mut = true; + // No need to continue recursing + false + } else { + true + } + }); + if needs_mut { + self.register_bound( + expected, + tcx.require_lang_item(hir::LangItem::DerefMut, Some(span)), + self.misc(span), + ); + } + expected } diff --git a/tests/ui/pattern/deref-patterns/ref-mut.rs b/tests/ui/pattern/deref-patterns/ref-mut.rs new file mode 100644 index 000000000000..1918008a761a --- /dev/null +++ b/tests/ui/pattern/deref-patterns/ref-mut.rs @@ -0,0 +1,17 @@ +#![feature(deref_patterns)] +//~^ WARN the feature `deref_patterns` is incomplete + +use std::rc::Rc; + +fn main() { + match &mut vec![1] { + deref!(x) => {} + _ => {} + } + + match &mut Rc::new(1) { + deref!(x) => {} + //~^ ERROR the trait bound `Rc<{integer}>: DerefMut` is not satisfied + _ => {} + } +} diff --git a/tests/ui/pattern/deref-patterns/ref-mut.stderr b/tests/ui/pattern/deref-patterns/ref-mut.stderr new file mode 100644 index 000000000000..41f1c3061ce6 --- /dev/null +++ b/tests/ui/pattern/deref-patterns/ref-mut.stderr @@ -0,0 +1,20 @@ +warning: the feature `deref_patterns` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/ref-mut.rs:1:12 + | +LL | #![feature(deref_patterns)] + | ^^^^^^^^^^^^^^ + | + = note: see issue #87121 for more information + = note: `#[warn(incomplete_features)]` on by default + +error[E0277]: the trait bound `Rc<{integer}>: DerefMut` is not satisfied + --> $DIR/ref-mut.rs:13:9 + | +LL | deref!(x) => {} + | ^^^^^^^^^ the trait `DerefMut` is not implemented for `Rc<{integer}>` + | + = note: this error originates in the macro `deref` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 1 previous error; 1 warning emitted + +For more information about this error, try `rustc --explain E0277`. From fc1d7d275ba11e37cf9962f0126ca9ed54b137b4 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sun, 24 Mar 2024 19:41:48 -0400 Subject: [PATCH 060/165] Extract helper, fix comment on DerefPure --- compiler/rustc_hir_typeck/src/pat.rs | 17 +++---------- .../rustc_middle/src/ty/typeck_results.rs | 25 +++++++++++++++++++ library/core/src/ops/deref.rs | 10 +++++++- 3 files changed, 37 insertions(+), 15 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index 5f8b833b3064..30ce52ef325f 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -2020,20 +2020,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Check if the pattern has any `ref mut` bindings, which would require // `DerefMut` to be emitted in MIR building instead of just `Deref`. - let mut needs_mut = false; - inner.walk(|pat| { - if let hir::PatKind::Binding(_, id, _, _) = pat.kind - && let Some(ty::BindByReference(ty::Mutability::Mut)) = - self.typeck_results.borrow().pat_binding_modes().get(id) - { - needs_mut = true; - // No need to continue recursing - false - } else { - true - } - }); - if needs_mut { + // We do this *after* checking the inner pattern, since we want to make + // sure to apply any match-ergonomics adjustments. + if self.typeck_results.borrow().pat_has_ref_mut_binding(inner) { self.register_bound( expected, tcx.require_lang_item(hir::LangItem::DerefMut, Some(span)), diff --git a/compiler/rustc_middle/src/ty/typeck_results.rs b/compiler/rustc_middle/src/ty/typeck_results.rs index d8541f4b25a5..827b7e088ce0 100644 --- a/compiler/rustc_middle/src/ty/typeck_results.rs +++ b/compiler/rustc_middle/src/ty/typeck_results.rs @@ -430,6 +430,31 @@ impl<'tcx> TypeckResults<'tcx> { LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.pat_adjustments } } + /// Does the pattern recursively contain a `ref mut` binding in it? + /// + /// This is used to determined whether a `deref` pattern should emit a `Deref` + /// or `DerefMut` call for its pattern scrutinee. + /// + /// This is computed from the typeck results since we want to make + /// sure to apply any match-ergonomics adjustments, which we cannot + /// determine from the HIR alone. + pub fn pat_has_ref_mut_binding(&self, pat: &'tcx hir::Pat<'tcx>) -> bool { + let mut has_ref_mut = false; + pat.walk(|pat| { + if let hir::PatKind::Binding(_, id, _, _) = pat.kind + && let Some(ty::BindByReference(ty::Mutability::Mut)) = + self.pat_binding_modes().get(id) + { + has_ref_mut = true; + // No need to continue recursing + false + } else { + true + } + }); + has_ref_mut + } + /// For a given closure, returns the iterator of `ty::CapturedPlace`s that are captured /// by the closure. pub fn closure_min_captures_flattened( diff --git a/library/core/src/ops/deref.rs b/library/core/src/ops/deref.rs index fe7b6f0d262f..3795a81c2c15 100644 --- a/library/core/src/ops/deref.rs +++ b/library/core/src/ops/deref.rs @@ -275,7 +275,15 @@ impl DerefMut for &mut T { } } -/// UwU +/// Perma-unstable marker trait. Indicates that the type has a well-behaved [`Deref`] +/// (and, if applicable, [`DerefMut`]) implementation. This is relied on for soundness +/// of deref patterns. +/// +/// FIXME(deref_patterns): The precise semantics are undecided; the rough idea is that +/// successive calls to `deref`/`deref_mut` without intermediate mutation should be +/// idempotent, in the sense that they return the same value as far as pattern-matching +/// is concerned. Calls to `deref`/`deref_mut`` must leave the pointer itself likewise +/// unchanged. #[unstable(feature = "deref_pure_trait", issue = "87121")] #[cfg_attr(not(bootstrap), lang = "deref_pure")] pub unsafe trait DerefPure {} From d0bf6e694821586b499da1749df3f94b8ce27e5b Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Mon, 25 Mar 2024 12:00:47 -0700 Subject: [PATCH 061/165] triagebot: Add notification of 2024 issues --- triagebot.toml | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/triagebot.toml b/triagebot.toml index a42bafe148c5..62a706fafe12 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -424,7 +424,15 @@ message_on_reopen = "Issue #{number} has been reopened. Pinging @*T-types*." [notify-zulip."A-edition-2021"] required_labels = ["C-bug"] -zulip_stream = 268952 # #edition 2021 +zulip_stream = 268952 # #edition +topic = "Edition Bugs" +message_on_add = """\ +Issue #{number} "{title}" has been added (previous edition 2021). +""" + +[notify-zulip."A-edition-2024"] +required_labels = ["C-bug"] +zulip_stream = 268952 # #edition topic = "Edition Bugs" message_on_add = """\ Issue #{number} "{title}" has been added. From 5ddc4f24cc66d02431fcfc6a4cb32c040c0b511c Mon Sep 17 00:00:00 2001 From: Zalathar Date: Fri, 22 Mar 2024 14:33:58 +1100 Subject: [PATCH 062/165] coverage: Inline creating a dummy instance for unused functions --- .../src/coverageinfo/mapgen.rs | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs index ee7ea3423016..28ff3eccedac 100644 --- a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs +++ b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs @@ -385,8 +385,7 @@ fn add_unused_functions(cx: &CodegenCx<'_, '_>) { }; debug!("generating unused fn: {def_id:?}"); - let instance = declare_unused_fn(tcx, def_id); - add_unused_function_coverage(cx, instance, function_coverage_info); + add_unused_function_coverage(cx, def_id, function_coverage_info); } } @@ -421,8 +420,15 @@ fn codegenned_and_inlined_items(tcx: TyCtxt<'_>) -> DefIdSet { result } -fn declare_unused_fn<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> ty::Instance<'tcx> { - ty::Instance::new( +fn add_unused_function_coverage<'tcx>( + cx: &CodegenCx<'_, 'tcx>, + def_id: DefId, + function_coverage_info: &'tcx mir::coverage::FunctionCoverageInfo, +) { + let tcx = cx.tcx; + + // Make a dummy instance that fills in all generics with placeholders. + let instance = ty::Instance::new( def_id, ty::GenericArgs::for_item(tcx, def_id, |param, _| { if let ty::GenericParamDefKind::Lifetime = param.kind { @@ -431,14 +437,8 @@ fn declare_unused_fn<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> ty::Instance<'tc tcx.mk_param_from_def(param) } }), - ) -} + ); -fn add_unused_function_coverage<'tcx>( - cx: &CodegenCx<'_, 'tcx>, - instance: ty::Instance<'tcx>, - function_coverage_info: &'tcx mir::coverage::FunctionCoverageInfo, -) { // An unused function's mappings will automatically be rewritten to map to // zero, because none of its counters/expressions are marked as seen. let function_coverage = FunctionCoverageCollector::unused(instance, function_coverage_info); From e3f66b24933356e5bda6a7161ab92706cd015dea Mon Sep 17 00:00:00 2001 From: Zalathar Date: Fri, 22 Mar 2024 12:59:49 +1100 Subject: [PATCH 063/165] coverage: Overhaul the search for unused functions --- .../src/coverageinfo/mapgen.rs | 128 +++++++++--------- 1 file changed, 67 insertions(+), 61 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs index 28ff3eccedac..95cd4cca4d2c 100644 --- a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs +++ b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs @@ -6,9 +6,8 @@ use crate::llvm; use itertools::Itertools as _; use rustc_codegen_ssa::traits::{BaseTypeMethods, ConstMethods}; -use rustc_data_structures::fx::{FxIndexMap, FxIndexSet}; -use rustc_hir::def::DefKind; -use rustc_hir::def_id::DefId; +use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet}; +use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_index::IndexVec; use rustc_middle::bug; use rustc_middle::mir; @@ -335,16 +334,9 @@ fn save_function_record( ); } -/// When finalizing the coverage map, `FunctionCoverage` only has the `CodeRegion`s and counters for -/// the functions that went through codegen; such as public functions and "used" functions -/// (functions referenced by other "used" or public items). Any other functions considered unused, -/// or "Unreachable", were still parsed and processed through the MIR stage, but were not -/// codegenned. (Note that `-Clink-dead-code` can force some unused code to be codegenned, but -/// that flag is known to cause other errors, when combined with `-C instrument-coverage`; and -/// `-Clink-dead-code` will not generate code for unused generic functions.) -/// -/// We can find the unused functions (including generic functions) by the set difference of all MIR -/// `DefId`s (`tcx` query `mir_keys`) minus the codegenned `DefId`s (`codegenned_and_inlined_items`). +/// Each CGU will normally only emit coverage metadata for the functions that it actually generates. +/// But since we don't want unused functions to disappear from coverage reports, we also scan for +/// functions that were instrumented but are not participating in codegen. /// /// These unused functions don't need to be codegenned, but we do need to add them to the function /// coverage map (in a single designated CGU) so that we still emit coverage mappings for them. @@ -354,78 +346,92 @@ fn add_unused_functions(cx: &CodegenCx<'_, '_>) { assert!(cx.codegen_unit.is_code_coverage_dead_code_cgu()); let tcx = cx.tcx; + let usage = prepare_usage_sets(tcx); - let eligible_def_ids = tcx.mir_keys(()).iter().filter_map(|local_def_id| { - let def_id = local_def_id.to_def_id(); - let kind = tcx.def_kind(def_id); - // `mir_keys` will give us `DefId`s for all kinds of things, not - // just "functions", like consts, statics, etc. Filter those out. - if !matches!(kind, DefKind::Fn | DefKind::AssocFn | DefKind::Closure) { - return None; - } + let is_unused_fn = |def_id: LocalDefId| -> bool { + let def_id = def_id.to_def_id(); + + // To be eligible for "unused function" mappings, a definition must: + // - Be function-like + // - Not participate directly in codegen + // - Not have any coverage statements inlined into codegenned functions + tcx.def_kind(def_id).is_fn_like() + && !usage.all_mono_items.contains(&def_id) + && !usage.used_via_inlining.contains(&def_id) + }; + + // Scan for unused functions that were instrumented for coverage. + for def_id in tcx.mir_keys(()).iter().copied().filter(|&def_id| is_unused_fn(def_id)) { + // Get the coverage info from MIR, skipping functions that were never instrumented. + let body = tcx.optimized_mir(def_id); + let Some(function_coverage_info) = body.function_coverage_info.as_deref() else { continue }; // FIXME(79651): Consider trying to filter out dummy instantiations of // unused generic functions from library crates, because they can produce // "unused instantiation" in coverage reports even when they are actually // used by some downstream crate in the same binary. - Some(local_def_id.to_def_id()) - }); - - let codegenned_def_ids = codegenned_and_inlined_items(tcx); - - // For each `DefId` that should have coverage instrumentation but wasn't - // codegenned, add it to the function coverage map as an unused function. - for def_id in eligible_def_ids.filter(|id| !codegenned_def_ids.contains(id)) { - // Skip any function that didn't have coverage data added to it by the - // coverage instrumentor. - let body = tcx.instance_mir(ty::InstanceDef::Item(def_id)); - let Some(function_coverage_info) = body.function_coverage_info.as_deref() else { - continue; - }; - debug!("generating unused fn: {def_id:?}"); add_unused_function_coverage(cx, def_id, function_coverage_info); } } -/// All items participating in code generation together with (instrumented) -/// items inlined into them. -fn codegenned_and_inlined_items(tcx: TyCtxt<'_>) -> DefIdSet { - let (items, cgus) = tcx.collect_and_partition_mono_items(()); - let mut visited = DefIdSet::default(); - let mut result = items.clone(); +struct UsageSets<'tcx> { + all_mono_items: &'tcx DefIdSet, + used_via_inlining: FxHashSet, +} - for cgu in cgus { - for item in cgu.items().keys() { - if let mir::mono::MonoItem::Fn(ref instance) = item { - let did = instance.def_id(); - if !visited.insert(did) { - continue; - } - let body = tcx.instance_mir(instance.def); - for block in body.basic_blocks.iter() { - for statement in &block.statements { - let mir::StatementKind::Coverage(_) = statement.kind else { continue }; - let scope = statement.source_info.scope; - if let Some(inlined) = scope.inlined_instance(&body.source_scopes) { - result.insert(inlined.def_id()); - } - } - } +/// Prepare sets of definitions that are relevant to deciding whether something +/// is an "unused function" for coverage purposes. +fn prepare_usage_sets<'tcx>(tcx: TyCtxt<'tcx>) -> UsageSets<'tcx> { + let (all_mono_items, cgus) = tcx.collect_and_partition_mono_items(()); + + // Obtain a MIR body for each function participating in codegen, via an + // arbitrary instance. + let mut def_ids_seen = FxHashSet::default(); + let def_and_mir_for_all_mono_fns = cgus + .iter() + .flat_map(|cgu| cgu.items().keys()) + .filter_map(|item| match item { + mir::mono::MonoItem::Fn(instance) => Some(instance), + mir::mono::MonoItem::Static(_) | mir::mono::MonoItem::GlobalAsm(_) => None, + }) + // We only need one arbitrary instance per definition. + .filter(move |instance| def_ids_seen.insert(instance.def_id())) + .map(|instance| { + // We don't care about the instance, just its underlying MIR. + let body = tcx.instance_mir(instance.def); + (instance.def_id(), body) + }); + + // Functions whose coverage statments were found inlined into other functions. + let mut used_via_inlining = FxHashSet::default(); + + for (_def_id, body) in def_and_mir_for_all_mono_fns { + // Inspect every coverage statement in the function's MIR. + for stmt in body + .basic_blocks + .iter() + .flat_map(|block| &block.statements) + .filter(|stmt| matches!(stmt.kind, mir::StatementKind::Coverage(_))) + { + if let Some(inlined) = stmt.source_info.scope.inlined_instance(&body.source_scopes) { + // This coverage statement was inlined from another function. + used_via_inlining.insert(inlined.def_id()); } } } - result + UsageSets { all_mono_items, used_via_inlining } } fn add_unused_function_coverage<'tcx>( cx: &CodegenCx<'_, 'tcx>, - def_id: DefId, + def_id: LocalDefId, function_coverage_info: &'tcx mir::coverage::FunctionCoverageInfo, ) { let tcx = cx.tcx; + let def_id = def_id.to_def_id(); // Make a dummy instance that fills in all generics with placeholders. let instance = ty::Instance::new( From 54116c8cae58f1d46f231fbeac5630a81b994a4c Mon Sep 17 00:00:00 2001 From: Zalathar Date: Fri, 22 Mar 2024 13:23:04 +1100 Subject: [PATCH 064/165] coverage: Detect functions that have lost all their coverage statements If a function was instrumented for coverage, but all of its coverage statements have been removed by later MIR transforms, it should be treated as "unused" even if the compiler generates an unreachable stub for it. --- .../src/coverageinfo/mapgen.rs | 22 +++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs index 95cd4cca4d2c..0fbc624389bc 100644 --- a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs +++ b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs @@ -353,10 +353,11 @@ fn add_unused_functions(cx: &CodegenCx<'_, '_>) { // To be eligible for "unused function" mappings, a definition must: // - Be function-like - // - Not participate directly in codegen + // - Not participate directly in codegen (or have lost all its coverage statements) // - Not have any coverage statements inlined into codegenned functions tcx.def_kind(def_id).is_fn_like() - && !usage.all_mono_items.contains(&def_id) + && (!usage.all_mono_items.contains(&def_id) + || usage.missing_own_coverage.contains(&def_id)) && !usage.used_via_inlining.contains(&def_id) }; @@ -379,6 +380,7 @@ fn add_unused_functions(cx: &CodegenCx<'_, '_>) { struct UsageSets<'tcx> { all_mono_items: &'tcx DefIdSet, used_via_inlining: FxHashSet, + missing_own_coverage: FxHashSet, } /// Prepare sets of definitions that are relevant to deciding whether something @@ -406,8 +408,13 @@ fn prepare_usage_sets<'tcx>(tcx: TyCtxt<'tcx>) -> UsageSets<'tcx> { // Functions whose coverage statments were found inlined into other functions. let mut used_via_inlining = FxHashSet::default(); + // Functions that were instrumented, but had all of their coverage statements + // removed by later MIR transforms (e.g. UnreachablePropagation). + let mut missing_own_coverage = FxHashSet::default(); + + for (def_id, body) in def_and_mir_for_all_mono_fns { + let mut saw_own_coverage = false; - for (_def_id, body) in def_and_mir_for_all_mono_fns { // Inspect every coverage statement in the function's MIR. for stmt in body .basic_blocks @@ -418,11 +425,18 @@ fn prepare_usage_sets<'tcx>(tcx: TyCtxt<'tcx>) -> UsageSets<'tcx> { if let Some(inlined) = stmt.source_info.scope.inlined_instance(&body.source_scopes) { // This coverage statement was inlined from another function. used_via_inlining.insert(inlined.def_id()); + } else { + // Non-inlined coverage statements belong to the enclosing function. + saw_own_coverage = true; } } + + if !saw_own_coverage && body.function_coverage_info.is_some() { + missing_own_coverage.insert(def_id); + } } - UsageSets { all_mono_items, used_via_inlining } + UsageSets { all_mono_items, used_via_inlining, missing_own_coverage } } fn add_unused_function_coverage<'tcx>( From 1cca2529d1c90458080be6cf271a92eedc49d399 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Fri, 22 Mar 2024 13:34:26 +1100 Subject: [PATCH 065/165] coverage: Re-enable `UnreachablePropagation` for coverage builds --- compiler/rustc_mir_transform/src/unreachable_prop.rs | 6 +----- tests/coverage/unreachable.cov-map | 6 +++--- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_mir_transform/src/unreachable_prop.rs b/compiler/rustc_mir_transform/src/unreachable_prop.rs index bff59aa60237..8ad7bc394c5a 100644 --- a/compiler/rustc_mir_transform/src/unreachable_prop.rs +++ b/compiler/rustc_mir_transform/src/unreachable_prop.rs @@ -14,11 +14,7 @@ pub struct UnreachablePropagation; impl MirPass<'_> for UnreachablePropagation { fn is_enabled(&self, sess: &rustc_session::Session) -> bool { // Enable only under -Zmir-opt-level=2 as this can make programs less debuggable. - - // FIXME(#116171) Coverage gets confused by MIR passes that can remove all - // coverage statements from an instrumented function. This pass can be - // re-enabled when coverage codegen is robust against that happening. - sess.mir_opt_level() >= 2 && !sess.instrument_coverage() + sess.mir_opt_level() >= 2 } fn run_pass<'tcx>(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { diff --git a/tests/coverage/unreachable.cov-map b/tests/coverage/unreachable.cov-map index 55d124a16f59..9d4698527d09 100644 --- a/tests/coverage/unreachable.cov-map +++ b/tests/coverage/unreachable.cov-map @@ -14,11 +14,11 @@ Number of expressions: 0 Number of file 0 mappings: 1 - Code(Counter(0)) at (prev + 17, 1) to (start + 1, 37) -Function name: unreachable::unreachable_intrinsic -Raw bytes (9): 0x[01, 01, 00, 01, 01, 16, 01, 01, 2c] +Function name: unreachable::unreachable_intrinsic (unused) +Raw bytes (9): 0x[01, 01, 00, 01, 00, 16, 01, 01, 2c] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 22, 1) to (start + 1, 44) +- Code(Zero) at (prev + 22, 1) to (start + 1, 44) From 22da5e008289f8084171031786952da20ec707b9 Mon Sep 17 00:00:00 2001 From: Kevin Reid Date: Mon, 25 Mar 2024 18:48:54 -0700 Subject: [PATCH 066/165] Add my former address to .mailmap --- .mailmap | 1 + 1 file changed, 1 insertion(+) diff --git a/.mailmap b/.mailmap index 0d96f5f3d4f6..93f5ca8157cf 100644 --- a/.mailmap +++ b/.mailmap @@ -324,6 +324,7 @@ Katze Keegan McAllister Kerem Kat Kevin Butler +Kevin Reid Kevin Jiang Kornel Lesiński Krishna Sai Veera Reddy From 2c0a8de0b91d0ea9dcab390cbff430329b1342b7 Mon Sep 17 00:00:00 2001 From: Matthew Maurer Date: Mon, 25 Mar 2024 02:42:04 +0000 Subject: [PATCH 067/165] CFI: Enable KCFI testing of run-pass tests This enables KCFI-based testing for all the CFI run-pass tests in the suite today. We can add the test header on top of in-flight CFI tests once they land. It also enables KCFI as a sanitizer for x86_64 and aarch64 Linux to make this possible. The sanitizer should likely be available for all aarch64, x86_64, and riscv targets, but that isn't critical for initial testing. --- .../src/spec/targets/aarch64_unknown_linux_gnu.rs | 1 + .../src/spec/targets/x86_64_unknown_linux_gnu.rs | 1 + src/tools/compiletest/src/header.rs | 1 + tests/ui/sanitizer/cfi-closure-fn-ptr-cast.rs | 10 +++++++--- tests/ui/sanitizer/cfi-complex-receiver.rs | 10 +++++++--- tests/ui/sanitizer/cfi-self-ref.rs | 10 +++++++--- tests/ui/sanitizer/cfi-virtual-auto.rs | 10 +++++++--- 7 files changed, 31 insertions(+), 12 deletions(-) diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_linux_gnu.rs index 2169e2971d88..703a3206af21 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_linux_gnu.rs @@ -19,6 +19,7 @@ pub fn target() -> Target { stack_probes: StackProbeType::Inline, supported_sanitizers: SanitizerSet::ADDRESS | SanitizerSet::CFI + | SanitizerSet::KCFI | SanitizerSet::LEAK | SanitizerSet::MEMORY | SanitizerSet::MEMTAG diff --git a/compiler/rustc_target/src/spec/targets/x86_64_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/targets/x86_64_unknown_linux_gnu.rs index 98374023dc57..11fb28a9aed7 100644 --- a/compiler/rustc_target/src/spec/targets/x86_64_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/targets/x86_64_unknown_linux_gnu.rs @@ -10,6 +10,7 @@ pub fn target() -> Target { base.static_position_independent_executables = true; base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::CFI + | SanitizerSet::KCFI | SanitizerSet::DATAFLOW | SanitizerSet::LEAK | SanitizerSet::MEMORY diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs index 6ff47dbffbcb..45c330b34e2c 100644 --- a/src/tools/compiletest/src/header.rs +++ b/src/tools/compiletest/src/header.rs @@ -826,6 +826,7 @@ const KNOWN_DIRECTIVE_NAMES: &[&str] = &[ "needs-sanitizer-cfi", "needs-sanitizer-dataflow", "needs-sanitizer-hwaddress", + "needs-sanitizer-kcfi", "needs-sanitizer-leak", "needs-sanitizer-memory", "needs-sanitizer-memtag", diff --git a/tests/ui/sanitizer/cfi-closure-fn-ptr-cast.rs b/tests/ui/sanitizer/cfi-closure-fn-ptr-cast.rs index a46a3afd7343..1ae494d87d42 100644 --- a/tests/ui/sanitizer/cfi-closure-fn-ptr-cast.rs +++ b/tests/ui/sanitizer/cfi-closure-fn-ptr-cast.rs @@ -5,11 +5,15 @@ // // This checks that the reified function pointer will have the expected alias set at its call-site. -//@ needs-sanitizer-cfi +//@ revisions: cfi kcfi // FIXME(#122848) Remove only-linux once OSX CFI binaries work //@ only-linux -//@ compile-flags: --crate-type=bin -Cprefer-dynamic=off -Clto -Zsanitizer=cfi -//@ compile-flags: -C target-feature=-crt-static -C codegen-units=1 -C opt-level=0 +//@ [cfi] needs-sanitizer-cfi +//@ [kcfi] needs-sanitizer-kcfi +//@ compile-flags: -C target-feature=-crt-static +//@ [cfi] compile-flags: -C codegen-units=1 -C lto -C prefer-dynamic=off -C opt-level=0 +//@ [cfi] compile-flags: -Z sanitizer=cfi +//@ [kcfi] compile-flags: -Z sanitizer=kcfi //@ run-pass pub fn main() { diff --git a/tests/ui/sanitizer/cfi-complex-receiver.rs b/tests/ui/sanitizer/cfi-complex-receiver.rs index c3e59258db20..52095a384b25 100644 --- a/tests/ui/sanitizer/cfi-complex-receiver.rs +++ b/tests/ui/sanitizer/cfi-complex-receiver.rs @@ -2,11 +2,15 @@ // * Arc as for custom receivers // * &dyn Bar for type constraints -//@ needs-sanitizer-cfi +//@ revisions: cfi kcfi // FIXME(#122848) Remove only-linux once OSX CFI binaries work //@ only-linux -//@ compile-flags: --crate-type=bin -Cprefer-dynamic=off -Clto -Zsanitizer=cfi -//@ compile-flags: -C target-feature=-crt-static -C codegen-units=1 -C opt-level=0 +//@ [cfi] needs-sanitizer-cfi +//@ [kcfi] needs-sanitizer-kcfi +//@ compile-flags: -C target-feature=-crt-static +//@ [cfi] compile-flags: -C codegen-units=1 -C lto -C prefer-dynamic=off -C opt-level=0 +//@ [cfi] compile-flags: -Z sanitizer=cfi +//@ [kcfi] compile-flags: -Z sanitizer=kcfi //@ run-pass use std::sync::Arc; diff --git a/tests/ui/sanitizer/cfi-self-ref.rs b/tests/ui/sanitizer/cfi-self-ref.rs index 32d0b1007026..f8793aec6e21 100644 --- a/tests/ui/sanitizer/cfi-self-ref.rs +++ b/tests/ui/sanitizer/cfi-self-ref.rs @@ -1,10 +1,14 @@ // Check that encoding self-referential types works with #[repr(transparent)] -//@ needs-sanitizer-cfi +//@ revisions: cfi kcfi // FIXME(#122848) Remove only-linux once OSX CFI binaries work //@ only-linux -//@ compile-flags: --crate-type=bin -Cprefer-dynamic=off -Clto -Zsanitizer=cfi -//@ compile-flags: -C target-feature=-crt-static -C codegen-units=1 -C opt-level=0 +//@ [cfi] needs-sanitizer-cfi +//@ [kcfi] needs-sanitizer-kcfi +//@ compile-flags: -C target-feature=-crt-static +//@ [cfi] compile-flags: -C codegen-units=1 -C lto -C prefer-dynamic=off -C opt-level=0 +//@ [cfi] compile-flags: -Z sanitizer=cfi +//@ [kcfi] compile-flags: -Z sanitizer=kcfi //@ run-pass use std::marker::PhantomData; diff --git a/tests/ui/sanitizer/cfi-virtual-auto.rs b/tests/ui/sanitizer/cfi-virtual-auto.rs index 7a0c246a4122..517c3d49f765 100644 --- a/tests/ui/sanitizer/cfi-virtual-auto.rs +++ b/tests/ui/sanitizer/cfi-virtual-auto.rs @@ -1,10 +1,14 @@ // Tests that calling a trait object method on a trait object with additional auto traits works. -//@ needs-sanitizer-cfi +//@ revisions: cfi kcfi // FIXME(#122848) Remove only-linux once OSX CFI binaries work //@ only-linux -//@ compile-flags: --crate-type=bin -Cprefer-dynamic=off -Clto -Zsanitizer=cfi -//@ compile-flags: -C target-feature=-crt-static -C codegen-units=1 -C opt-level=0 +//@ [cfi] needs-sanitizer-cfi +//@ [kcfi] needs-sanitizer-kcfi +//@ compile-flags: -C target-feature=-crt-static +//@ [cfi] compile-flags: -C codegen-units=1 -C lto -C prefer-dynamic=off -C opt-level=0 +//@ [cfi] compile-flags: -Z sanitizer=cfi +//@ [kcfi] compile-flags: -Z sanitizer=kcfi //@ run-pass trait Foo { From 3d58ef9e3c5b703a34606e0a9e1ea764710d384d Mon Sep 17 00:00:00 2001 From: Scott Schafer Date: Tue, 26 Mar 2024 00:06:06 -0600 Subject: [PATCH 068/165] Update cargo --- src/tools/cargo | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/cargo b/src/tools/cargo index a510712d05c6..499a61ce7a0f 160000 --- a/src/tools/cargo +++ b/src/tools/cargo @@ -1 +1 @@ -Subproject commit a510712d05c6c98f987af24dd73cdfafee8922e6 +Subproject commit 499a61ce7a0fc6a72040084862a68b2603e770e8 From 69af113f44a219f12add9b5458b9a5075b23ae3c Mon Sep 17 00:00:00 2001 From: onur-ozkan Date: Mon, 25 Mar 2024 23:34:01 +0300 Subject: [PATCH 069/165] enable cargo miri test doctests Signed-off-by: onur-ozkan --- src/bootstrap/src/core/build_steps/test.rs | 6 +++++- src/tools/miri/README.md | 2 ++ src/tools/miri/cargo-miri/src/phases.rs | 10 +++++++--- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index 6d3163b90b10..d689f9942469 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -680,9 +680,13 @@ impl Step for Miri { .arg("--manifest-path") .arg(builder.src.join("src/tools/miri/test-cargo-miri/Cargo.toml")); cargo.arg("--target").arg(target.rustc_target_arg()); - cargo.arg("--tests"); // don't run doctests, they are too confused by the staging cargo.arg("--").args(builder.config.test_args()); + // `prepare_tool_cargo` sets RUSTDOC to the bootstrap wrapper and RUSTDOC_REAL to a dummy path as this is a "run", not a "test". + // Also, we want the rustdoc from the "next" stage for the same reason that we build a std from the next stage. + // So let's just set that here, and bypass bootstrap's RUSTDOC (just like cargo-miri already ignores bootstrap's RUSTC_WRAPPER). + cargo.env("RUSTDOC", builder.rustdoc(compiler_std)); + // Tell `cargo miri` where to find things. cargo.env("MIRI_SYSROOT", &miri_sysroot); cargo.env("MIRI_HOST_SYSROOT", sysroot); diff --git a/src/tools/miri/README.md b/src/tools/miri/README.md index b043805291ea..26e55b897080 100644 --- a/src/tools/miri/README.md +++ b/src/tools/miri/README.md @@ -505,6 +505,8 @@ binaries, and as such worth documenting: * `MIRI_LOCAL_CRATES` is set by `cargo-miri` to tell the Miri driver which crates should be given special treatment in diagnostics, in addition to the crate currently being compiled. +* `MIRI_ORIG_RUSTDOC` is set and read by different phases of `cargo-miri` to remember the + value of `RUSTDOC` from before it was overwritten. * `MIRI_VERBOSE` when set to any value tells the various `cargo-miri` phases to perform verbose logging. * `MIRI_HOST_SYSROOT` is set by bootstrap to tell `cargo-miri` which sysroot to use for *host* diff --git a/src/tools/miri/cargo-miri/src/phases.rs b/src/tools/miri/cargo-miri/src/phases.rs index 81ff68545ccd..799731320a68 100644 --- a/src/tools/miri/cargo-miri/src/phases.rs +++ b/src/tools/miri/cargo-miri/src/phases.rs @@ -202,6 +202,9 @@ pub fn phase_cargo_miri(mut args: impl Iterator) { cmd.env("MIRI_BE_RUSTC", "target"); // we better remember to *unset* this in the other phases! // Set rustdoc to us as well, so we can run doctests. + if let Some(orig_rustdoc) = env::var_os("RUSTDOC") { + cmd.env("MIRI_ORIG_RUSTDOC", orig_rustdoc); + } cmd.env("RUSTDOC", &cargo_miri_path); cmd.env("MIRI_LOCAL_CRATES", local_crates(&metadata)); @@ -581,9 +584,10 @@ pub fn phase_rustdoc(mut args: impl Iterator) { let verbose = std::env::var("MIRI_VERBOSE") .map_or(0, |verbose| verbose.parse().expect("verbosity flag must be an integer")); - // phase_cargo_miri sets the RUSTDOC env var to ourselves, so we can't use that here; - // just default to a straight-forward invocation for now: - let mut cmd = Command::new("rustdoc"); + // phase_cargo_miri sets the RUSTDOC env var to ourselves, and puts a backup + // of the old value into MIRI_ORIG_RUSTDOC. So that's what we have to invoke now. + let rustdoc = env::var("MIRI_ORIG_RUSTDOC").unwrap_or("rustdoc".to_string()); + let mut cmd = Command::new(rustdoc); let extern_flag = "--extern"; let runtool_flag = "--runtool"; From 1ad3954668ccad3d00b9d98d9d24fb76fae1c0f9 Mon Sep 17 00:00:00 2001 From: Havard Eidnes Date: Mon, 25 Mar 2024 15:35:22 +0000 Subject: [PATCH 070/165] std library unix/thread.rs: fix NetBSD code for ILP32 CPUs. --- library/std/src/sys/pal/unix/thread.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/std/src/sys/pal/unix/thread.rs b/library/std/src/sys/pal/unix/thread.rs index a3e1b6782e8a..4cd7c0e3059b 100644 --- a/library/std/src/sys/pal/unix/thread.rs +++ b/library/std/src/sys/pal/unix/thread.rs @@ -424,7 +424,7 @@ pub fn available_parallelism() -> io::Result> { if !set.is_null() { let mut count: usize = 0; if libc::pthread_getaffinity_np(libc::pthread_self(), libc::_cpuset_size(set), set) == 0 { - for i in 0..u64::MAX { + for i in 0..libc::cpuid_t::MAX { match libc::_cpuset_isset(i, set) { -1 => break, 0 => continue, From a241ffc6b6f89ca9691b39662624dd3b7c08a703 Mon Sep 17 00:00:00 2001 From: ding-young Date: Tue, 26 Mar 2024 18:04:19 +0900 Subject: [PATCH 071/165] Fix link to BufWriter --- library/std/src/fs.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/std/src/fs.rs b/library/std/src/fs.rs index 5d0de2d06a0a..8b3a9e82aad1 100644 --- a/library/std/src/fs.rs +++ b/library/std/src/fs.rs @@ -97,7 +97,7 @@ use crate::time::SystemTime; /// have been opened for asynchronous I/O (e.g. by using `FILE_FLAG_OVERLAPPED`). /// /// [`BufReader`]: io::BufReader -/// [`BufWriter`]: io::BufReader +/// [`BufWriter`]: io::BufWriter /// [`sync_all`]: File::sync_all /// [`write`]: File::write /// [`read`]: File::read From bff13e98ad61b060ddb7c6c9afc9d1738af95804 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20du=20Garreau?= Date: Tue, 26 Mar 2024 10:11:29 +0100 Subject: [PATCH 072/165] `UnixStream`: override `read_buf` --- library/std/src/os/unix/net/stream.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/library/std/src/os/unix/net/stream.rs b/library/std/src/os/unix/net/stream.rs index d67493aaf4d6..9b01d2326112 100644 --- a/library/std/src/os/unix/net/stream.rs +++ b/library/std/src/os/unix/net/stream.rs @@ -580,6 +580,10 @@ impl io::Read for UnixStream { io::Read::read(&mut &*self, buf) } + fn read_buf(&mut self, buf: io::BorrowedCursor<'_>) -> io::Result<()> { + io::Read::read_buf(&mut &*self, buf) + } + fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result { io::Read::read_vectored(&mut &*self, bufs) } @@ -596,6 +600,10 @@ impl<'a> io::Read for &'a UnixStream { self.0.read(buf) } + fn read_buf(&mut self, buf: io::BorrowedCursor<'_>) -> io::Result<()> { + self.0.read_buf(buf) + } + fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result { self.0.read_vectored(bufs) } From ff6d9f79ae630cfea44b461cf04d5cdcca02657d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20du=20Garreau?= Date: Fri, 22 Mar 2024 15:47:12 +0100 Subject: [PATCH 073/165] Unix: Support more platforms with `preadv` and `pwritev` --- library/std/src/sys/pal/unix/fd.rs | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/library/std/src/sys/pal/unix/fd.rs b/library/std/src/sys/pal/unix/fd.rs index a1c0321876fa..9d8cc18b8389 100644 --- a/library/std/src/sys/pal/unix/fd.rs +++ b/library/std/src/sys/pal/unix/fd.rs @@ -167,6 +167,8 @@ impl FileDesc { } #[cfg(any( + target_os = "aix", + target_os = "dragonfly", // DragonFly 1.5 target_os = "emscripten", target_os = "freebsd", target_os = "fuchsia", @@ -174,6 +176,7 @@ impl FileDesc { target_os = "illumos", target_os = "linux", target_os = "netbsd", + target_os = "openbsd", // OpenBSD 2.7 ))] pub fn read_vectored_at(&self, bufs: &mut [IoSliceMut<'_>], offset: u64) -> io::Result { let ret = cvt(unsafe { @@ -188,7 +191,9 @@ impl FileDesc { } #[cfg(not(any( + target_os = "aix", target_os = "android", + target_os = "dragonfly", target_os = "emscripten", target_os = "freebsd", target_os = "fuchsia", @@ -199,6 +204,8 @@ impl FileDesc { target_os = "linux", target_os = "macos", target_os = "netbsd", + target_os = "openbsd", + target_os = "watchos", )))] pub fn read_vectored_at(&self, bufs: &mut [IoSliceMut<'_>], offset: u64) -> io::Result { io::default_read_vectored(|b| self.read_at(b, offset), bufs) @@ -236,9 +243,10 @@ impl FileDesc { // no `syscall` possible in these platform. #[cfg(any( all(target_os = "android", target_pointer_width = "32"), - target_os = "ios", - target_os = "tvos", - target_os = "macos", + target_os = "ios", // ios 14.0 + target_os = "tvos", // tvos 14.0 + target_os = "macos", // macos 11.0 + target_os = "watchos", // watchos 7.0 ))] pub fn read_vectored_at(&self, bufs: &mut [IoSliceMut<'_>], offset: u64) -> io::Result { super::weak::weak!(fn preadv64(libc::c_int, *const libc::iovec, libc::c_int, off64_t) -> isize); @@ -318,6 +326,8 @@ impl FileDesc { } #[cfg(any( + target_os = "aix", + target_os = "dragonfly", // DragonFly 1.5 target_os = "emscripten", target_os = "freebsd", target_os = "fuchsia", @@ -325,6 +335,7 @@ impl FileDesc { target_os = "illumos", target_os = "linux", target_os = "netbsd", + target_os = "openbsd", // OpenBSD 2.7 ))] pub fn write_vectored_at(&self, bufs: &[IoSlice<'_>], offset: u64) -> io::Result { let ret = cvt(unsafe { @@ -339,7 +350,9 @@ impl FileDesc { } #[cfg(not(any( + target_os = "aix", target_os = "android", + target_os = "dragonfly", target_os = "emscripten", target_os = "freebsd", target_os = "fuchsia", @@ -350,6 +363,8 @@ impl FileDesc { target_os = "linux", target_os = "macos", target_os = "netbsd", + target_os = "openbsd", + target_os = "watchos", )))] pub fn write_vectored_at(&self, bufs: &[IoSlice<'_>], offset: u64) -> io::Result { io::default_write_vectored(|b| self.write_at(b, offset), bufs) @@ -387,9 +402,10 @@ impl FileDesc { // no `syscall` possible in these platform. #[cfg(any( all(target_os = "android", target_pointer_width = "32"), - target_os = "ios", - target_os = "tvos", - target_os = "macos", + target_os = "ios", // ios 14.0 + target_os = "tvos", // tvos 14.0 + target_os = "macos", // macos 11.0 + target_os = "watchos", // watchos 7.0 ))] pub fn write_vectored_at(&self, bufs: &[IoSlice<'_>], offset: u64) -> io::Result { super::weak::weak!(fn pwritev64(libc::c_int, *const libc::iovec, libc::c_int, off64_t) -> isize); From 60921608f794a217be1bc923b525e4d4c5b8109b Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Tue, 26 Mar 2024 09:56:55 +0000 Subject: [PATCH 074/165] Rustup to rustc 1.79.0-nightly (5f2c7d2bf 2024-03-25) --- rust-toolchain | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-toolchain b/rust-toolchain index 3845b57b91d0..e9e7f90bbb48 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2024-03-25" +channel = "nightly-2024-03-26" components = ["rust-src", "rustc-dev", "llvm-tools"] From dc6595ddbc94173289092d653215e4add8c666e2 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Tue, 26 Mar 2024 10:18:44 +0000 Subject: [PATCH 075/165] Implement nearbyintf32 and nearbyintf64 and remove two test ignores --- scripts/test_rustc_tests.sh | 3 --- src/intrinsics/mod.rs | 5 +++++ 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/scripts/test_rustc_tests.sh b/scripts/test_rustc_tests.sh index 3a28e1d53b75..63f4ef9464a1 100755 --- a/scripts/test_rustc_tests.sh +++ b/scripts/test_rustc_tests.sh @@ -50,7 +50,6 @@ rm -r tests/run-make/c-link-to-rust-va-list-fn # requires callee side vararg sup rm -r tests/run-pass-valgrind/unsized-locals # misc unimplemented things -rm tests/ui/intrinsics/intrinsic-nearby.rs # unimplemented nearbyintf32 and nearbyintf64 intrinsics rm tests/ui/target-feature/missing-plusminus.rs # error not implemented rm -r tests/run-make/emit-named-files # requires full --emit support rm -r tests/run-make/repr128-dwarf # debuginfo test @@ -125,8 +124,6 @@ rm -r tests/run-make/compressed-debuginfo rm -r tests/run-make/extern-fn-explicit-align # argument alignment not yet supported -rm tests/ui/codegen/subtyping-enforces-type-equality.rs # assert_assignable bug with Coroutine's - # bugs in the test suite # ====================== rm tests/ui/backtrace.rs # TODO warning diff --git a/src/intrinsics/mod.rs b/src/intrinsics/mod.rs index 25694af78f17..0b213ff82696 100644 --- a/src/intrinsics/mod.rs +++ b/src/intrinsics/mod.rs @@ -341,6 +341,8 @@ fn codegen_float_intrinsic_call<'tcx>( sym::roundf64 => ("round", 1, fx.tcx.types.f64, types::F64), sym::roundevenf32 => ("roundevenf", 1, fx.tcx.types.f32, types::F32), sym::roundevenf64 => ("roundeven", 1, fx.tcx.types.f64, types::F64), + sym::nearbyintf32 => ("nearbyintf", 1, fx.tcx.types.f32, types::F32), + sym::nearbyintf64 => ("nearbyint", 1, fx.tcx.types.f64, types::F64), sym::sinf32 => ("sinf", 1, fx.tcx.types.f32, types::F32), sym::sinf64 => ("sin", 1, fx.tcx.types.f64, types::F64), sym::cosf32 => ("cosf", 1, fx.tcx.types.f32, types::F32), @@ -392,6 +394,8 @@ fn codegen_float_intrinsic_call<'tcx>( | sym::ceilf64 | sym::truncf32 | sym::truncf64 + | sym::nearbyintf32 + | sym::nearbyintf64 | sym::sqrtf32 | sym::sqrtf64 => { let val = match intrinsic { @@ -399,6 +403,7 @@ fn codegen_float_intrinsic_call<'tcx>( sym::floorf32 | sym::floorf64 => fx.bcx.ins().floor(args[0]), sym::ceilf32 | sym::ceilf64 => fx.bcx.ins().ceil(args[0]), sym::truncf32 | sym::truncf64 => fx.bcx.ins().trunc(args[0]), + sym::nearbyintf32 | sym::nearbyintf64 => fx.bcx.ins().nearest(args[0]), sym::sqrtf32 | sym::sqrtf64 => fx.bcx.ins().sqrt(args[0]), _ => unreachable!(), }; From ad1886a5f0a6a56e9ee9c22ca80e1bcd27d4edd8 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Tue, 26 Mar 2024 10:27:19 +0000 Subject: [PATCH 076/165] Fix rustdoc help message when no args are passed --- scripts/rustc-clif.rs | 7 ++++--- scripts/rustdoc-clif.rs | 12 +++++++++--- scripts/test_rustc_tests.sh | 3 --- 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/scripts/rustc-clif.rs b/scripts/rustc-clif.rs index 550f20515536..92defd21cd9b 100644 --- a/scripts/rustc-clif.rs +++ b/scripts/rustc-clif.rs @@ -26,9 +26,10 @@ fn main() { codegen_backend_arg.push(cg_clif_dylib_path); args.push(codegen_backend_arg); } - if !passed_args.iter().any(|arg| { - arg == "--sysroot" || arg.to_str().is_some_and(|s| s.starts_with("--sysroot=")) - }) { + if !passed_args + .iter() + .any(|arg| arg == "--sysroot" || arg.to_str().is_some_and(|s| s.starts_with("--sysroot="))) + { args.push(OsString::from("--sysroot")); args.push(OsString::from(sysroot.to_str().unwrap())); } diff --git a/scripts/rustdoc-clif.rs b/scripts/rustdoc-clif.rs index f7d1bdbc4c6f..1cad312bb791 100644 --- a/scripts/rustdoc-clif.rs +++ b/scripts/rustdoc-clif.rs @@ -26,12 +26,18 @@ fn main() { codegen_backend_arg.push(cg_clif_dylib_path); args.push(codegen_backend_arg); } - if !passed_args.iter().any(|arg| { - arg == "--sysroot" || arg.to_str().is_some_and(|s| s.starts_with("--sysroot=")) - }) { + if !passed_args + .iter() + .any(|arg| arg == "--sysroot" || arg.to_str().is_some_and(|s| s.starts_with("--sysroot="))) + { args.push(OsString::from("--sysroot")); args.push(OsString::from(sysroot.to_str().unwrap())); } + if passed_args.is_empty() { + // Don't pass any arguments when the user didn't pass any arguments + // either to ensure the help message is shown. + args.clear(); + } args.extend(passed_args); let rustdoc = if let Some(rustdoc) = option_env!("RUSTDOC") { diff --git a/scripts/test_rustc_tests.sh b/scripts/test_rustc_tests.sh index 63f4ef9464a1..a6f25c3f8194 100755 --- a/scripts/test_rustc_tests.sh +++ b/scripts/test_rustc_tests.sh @@ -99,9 +99,6 @@ rm tests/ui/mir/mir_raw_fat_ptr.rs # same rm tests/ui/consts/issue-33537.rs # same rm tests/ui/consts/const-mut-refs-crate.rs # same -# rustdoc-clif passes extra args, suppressing the help message when no args are passed -rm -r tests/run-make/issue-88756-default-output - # doesn't work due to the way the rustc test suite is invoked. # should work when using ./x.py test the way it is intended # ============================================================ From 23868af850dab115306f7dd7e2dcb334dd97afd4 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Tue, 26 Mar 2024 10:55:46 +0000 Subject: [PATCH 077/165] Correctly implement --emit --- scripts/test_rustc_tests.sh | 24 ++--- src/driver/aot.rs | 196 +++++++++++++++++++++++++++++++++--- src/lib.rs | 11 +- 3 files changed, 201 insertions(+), 30 deletions(-) diff --git a/scripts/test_rustc_tests.sh b/scripts/test_rustc_tests.sh index a6f25c3f8194..2c1cff51014f 100755 --- a/scripts/test_rustc_tests.sh +++ b/scripts/test_rustc_tests.sh @@ -51,10 +51,8 @@ rm -r tests/run-pass-valgrind/unsized-locals # misc unimplemented things rm tests/ui/target-feature/missing-plusminus.rs # error not implemented -rm -r tests/run-make/emit-named-files # requires full --emit support rm -r tests/run-make/repr128-dwarf # debuginfo test rm -r tests/run-make/split-debuginfo # same -rm -r tests/run-make/symbols-include-type-name # --emit=asm not supported rm -r tests/run-make/target-specs # i686 not supported by Cranelift rm -r tests/run-make/mismatching-target-triples # same rm tests/ui/asm/x86_64/issue-96797.rs # const and sym inline asm operands don't work entirely correctly @@ -92,6 +90,17 @@ 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 +# 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 +rm -r tests/run-make/compressed-debuginfo +rm -r tests/run-make/symbols-include-type-name + + # giving different but possibly correct results # ============================================= rm tests/ui/mir/mir_misc_casts.rs # depends on deduplication of constants @@ -109,17 +118,8 @@ rm -r tests/run-make/compiler-builtins # Expects lib/rustlib/src/rust to contain # ============ rm tests/incremental/spike-neg1.rs # errors out for some reason rm tests/incremental/spike-neg2.rs # same - -rm -r tests/run-make/issue-51671 # wrong filename given in case of --emit=obj -rm -r tests/run-make/issue-30063 # same -rm -r tests/run-make/multiple-emits # same -rm -r tests/run-make/output-type-permutations # same -rm -r tests/run-make/used # same -rm -r tests/run-make/no-alloc-shim -rm -r tests/run-make/emit-to-stdout -rm -r tests/run-make/compressed-debuginfo - 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 # bugs in the test suite # ====================== diff --git a/src/driver/aot.rs b/src/driver/aot.rs index 757082a5fed1..4a28b2d93fab 100644 --- a/src/driver/aot.rs +++ b/src/driver/aot.rs @@ -1,22 +1,25 @@ //! The AOT driver uses [`cranelift_object`] to write object files suitable for linking into a //! standalone executable. -use std::fs::File; -use std::path::PathBuf; +use std::fs::{self, File}; +use std::path::{Path, PathBuf}; use std::sync::Arc; use std::thread::JoinHandle; use cranelift_object::{ObjectBuilder, ObjectModule}; use rustc_codegen_ssa::assert_module_sources::CguReuse; +use rustc_codegen_ssa::back::link::ensure_removed; use rustc_codegen_ssa::back::metadata::create_compressed_metadata_file; use rustc_codegen_ssa::base::determine_cgu_reuse; +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_metadata::fs::copy_to_stdout; use rustc_metadata::EncodedMetadata; use rustc_middle::dep_graph::{WorkProduct, WorkProductId}; use rustc_middle::mir::mono::{CodegenUnit, MonoItem}; -use rustc_session::config::{DebugInfo, OutputFilenames, OutputType}; +use rustc_session::config::{DebugInfo, OutFileName, OutputFilenames, OutputType}; use rustc_session::Session; use crate::concurrency_limiter::{ConcurrencyLimiter, ConcurrencyLimiterToken}; @@ -53,6 +56,7 @@ impl OngoingCodegen { pub(crate) fn join( self, sess: &Session, + outputs: &OutputFilenames, backend_config: &BackendConfig, ) -> (CodegenResults, FxIndexMap) { let mut work_products = FxIndexMap::default(); @@ -110,19 +114,185 @@ impl OngoingCodegen { sess.dcx().abort_if_errors(); - ( - CodegenResults { - modules, - allocator_module: self.allocator_module, - metadata_module: self.metadata_module, - metadata: self.metadata, - crate_info: self.crate_info, - }, - work_products, - ) + let codegen_results = CodegenResults { + modules, + allocator_module: self.allocator_module, + metadata_module: self.metadata_module, + metadata: self.metadata, + crate_info: self.crate_info, + }; + + produce_final_output_artifacts(sess, &codegen_results, outputs); + + (codegen_results, work_products) } } +// Adapted from https://github.com/rust-lang/rust/blob/73476d49904751f8d90ce904e16dfbc278083d2c/compiler/rustc_codegen_ssa/src/back/write.rs#L547C1-L706C2 +fn produce_final_output_artifacts( + sess: &Session, + codegen_results: &CodegenResults, + crate_output: &OutputFilenames, +) { + let user_wants_bitcode = false; + let mut user_wants_objects = false; + + // Produce final compile outputs. + let copy_gracefully = |from: &Path, to: &OutFileName| match to { + OutFileName::Stdout => { + if let Err(e) = copy_to_stdout(from) { + sess.dcx().emit_err(ssa_errors::CopyPath::new(from, to.as_path(), e)); + } + } + OutFileName::Real(path) => { + if let Err(e) = fs::copy(from, path) { + sess.dcx().emit_err(ssa_errors::CopyPath::new(from, path, e)); + } + } + }; + + let copy_if_one_unit = |output_type: OutputType, keep_numbered: bool| { + if codegen_results.modules.len() == 1 { + // 1) Only one codegen unit. In this case it's no difficulty + // to copy `foo.0.x` to `foo.x`. + let module_name = Some(&codegen_results.modules[0].name[..]); + let path = crate_output.temp_path(output_type, module_name); + let output = crate_output.path(output_type); + if !output_type.is_text_output() && output.is_tty() { + sess.dcx() + .emit_err(ssa_errors::BinaryOutputToTty { shorthand: output_type.shorthand() }); + } else { + copy_gracefully(&path, &output); + } + if !sess.opts.cg.save_temps && !keep_numbered { + // The user just wants `foo.x`, not `foo.#module-name#.x`. + ensure_removed(sess.dcx(), &path); + } + } else { + let extension = crate_output + .temp_path(output_type, None) + .extension() + .unwrap() + .to_str() + .unwrap() + .to_owned(); + + if crate_output.outputs.contains_explicit_name(&output_type) { + // 2) Multiple codegen units, with `--emit foo=some_name`. We have + // no good solution for this case, so warn the user. + sess.dcx().emit_warn(ssa_errors::IgnoringEmitPath { extension }); + } else if crate_output.single_output_file.is_some() { + // 3) Multiple codegen units, with `-o some_name`. We have + // no good solution for this case, so warn the user. + sess.dcx().emit_warn(ssa_errors::IgnoringOutput { extension }); + } else { + // 4) Multiple codegen units, but no explicit name. We + // just leave the `foo.0.x` files in place. + // (We don't have to do any work in this case.) + } + } + }; + + // Flag to indicate whether the user explicitly requested bitcode. + // Otherwise, we produced it only as a temporary output, and will need + // to get rid of it. + for output_type in crate_output.outputs.keys() { + match *output_type { + OutputType::Bitcode => { + // Cranelift doesn't have bitcode + // user_wants_bitcode = true; + // // Copy to .bc, but always keep the .0.bc. There is a later + // // check to figure out if we should delete .0.bc files, or keep + // // them for making an rlib. + // copy_if_one_unit(OutputType::Bitcode, true); + } + OutputType::LlvmAssembly => { + // Cranelift IR text already emitted during codegen + // copy_if_one_unit(OutputType::LlvmAssembly, false); + } + OutputType::Assembly => { + // Currently no support for emitting raw assembly files + // copy_if_one_unit(OutputType::Assembly, false); + } + OutputType::Object => { + user_wants_objects = true; + copy_if_one_unit(OutputType::Object, true); + } + OutputType::Mir | OutputType::Metadata | OutputType::Exe | OutputType::DepInfo => {} + } + } + + // Clean up unwanted temporary files. + + // We create the following files by default: + // - #crate#.#module-name#.bc + // - #crate#.#module-name#.o + // - #crate#.crate.metadata.bc + // - #crate#.crate.metadata.o + // - #crate#.o (linked from crate.##.o) + // - #crate#.bc (copied from crate.##.bc) + // We may create additional files if requested by the user (through + // `-C save-temps` or `--emit=` flags). + + if !sess.opts.cg.save_temps { + // Remove the temporary .#module-name#.o objects. If the user didn't + // explicitly request bitcode (with --emit=bc), and the bitcode is not + // needed for building an rlib, then we must remove .#module-name#.bc as + // well. + + // Specific rules for keeping .#module-name#.bc: + // - If the user requested bitcode (`user_wants_bitcode`), and + // codegen_units > 1, then keep it. + // - If the user requested bitcode but codegen_units == 1, then we + // can toss .#module-name#.bc because we copied it to .bc earlier. + // - If we're not building an rlib and the user didn't request + // bitcode, then delete .#module-name#.bc. + // If you change how this works, also update back::link::link_rlib, + // where .#module-name#.bc files are (maybe) deleted after making an + // rlib. + let needs_crate_object = crate_output.outputs.contains_key(&OutputType::Exe); + + let keep_numbered_bitcode = user_wants_bitcode && sess.codegen_units().as_usize() > 1; + + let keep_numbered_objects = + needs_crate_object || (user_wants_objects && sess.codegen_units().as_usize() > 1); + + for module in codegen_results.modules.iter() { + if let Some(ref path) = module.object { + if !keep_numbered_objects { + ensure_removed(sess.dcx(), path); + } + } + + if let Some(ref path) = module.dwarf_object { + if !keep_numbered_objects { + ensure_removed(sess.dcx(), path); + } + } + + if let Some(ref path) = module.bytecode { + if !keep_numbered_bitcode { + ensure_removed(sess.dcx(), path); + } + } + } + + if !user_wants_bitcode { + if let Some(ref allocator_module) = codegen_results.allocator_module { + if let Some(ref path) = allocator_module.bytecode { + ensure_removed(sess.dcx(), path); + } + } + } + } + + // We leave the following files around by default: + // - #crate#.o + // - #crate#.crate.metadata.o + // - #crate#.bc + // These are used in linking steps and will be cleaned up afterward. +} + fn make_module(sess: &Session, backend_config: &BackendConfig, name: String) -> ObjectModule { let isa = crate::build_isa(sess, backend_config); diff --git a/src/lib.rs b/src/lib.rs index a59a39074f8c..a121ac75a287 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -233,12 +233,13 @@ impl CodegenBackend for CraneliftCodegenBackend { &self, ongoing_codegen: Box, sess: &Session, - _outputs: &OutputFilenames, + outputs: &OutputFilenames, ) -> (CodegenResults, FxIndexMap) { - ongoing_codegen - .downcast::() - .unwrap() - .join(sess, self.config.borrow().as_ref().unwrap()) + ongoing_codegen.downcast::().unwrap().join( + sess, + outputs, + self.config.borrow().as_ref().unwrap(), + ) } fn link( From 17c6101864a3d7f5d655d69f18c7bd1cf8bfa92c Mon Sep 17 00:00:00 2001 From: Bryanskiy Date: Fri, 22 Mar 2024 21:54:17 +0300 Subject: [PATCH 078/165] Delegation: fix ICE on wrong `self` resolution --- compiler/rustc_resolve/src/late.rs | 53 ++++++++++++++++----- tests/ui/delegation/target-expr.rs | 38 +++++++++++++++ tests/ui/delegation/target-expr.stderr | 65 ++++++++++++++++++++++++++ 3 files changed, 145 insertions(+), 11 deletions(-) create mode 100644 tests/ui/delegation/target-expr.rs create mode 100644 tests/ui/delegation/target-expr.stderr diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index b2b339d25217..49b4a6efd3c3 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -2531,7 +2531,17 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { } ItemKind::Delegation(ref delegation) => { - self.resolve_delegation(delegation); + let span = delegation.path.segments.last().unwrap().ident.span; + self.with_generic_param_rib( + &[], + RibKind::Item(HasGenericParams::Yes(span), def_kind), + LifetimeRibKind::Generics { + binder: item.id, + kind: LifetimeBinderKind::Function, + span, + }, + |this| this.resolve_delegation(delegation), + ); } ItemKind::ExternCrate(..) => {} @@ -2819,7 +2829,16 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { walk_assoc_item(self, generics, LifetimeBinderKind::Function, item); } AssocItemKind::Delegation(delegation) => { - self.resolve_delegation(delegation); + self.with_generic_param_rib( + &[], + RibKind::AssocItem, + LifetimeRibKind::Generics { + binder: item.id, + kind: LifetimeBinderKind::Function, + span: delegation.path.segments.last().unwrap().ident.span, + }, + |this| this.resolve_delegation(delegation), + ); } AssocItemKind::Type(box TyAlias { generics, .. }) => self .with_lifetime_rib(LifetimeRibKind::AnonymousReportError, |this| { @@ -3069,16 +3088,28 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { } AssocItemKind::Delegation(box delegation) => { debug!("resolve_implementation AssocItemKind::Delegation"); - self.check_trait_item( - item.id, - item.ident, - &item.kind, - ValueNS, - item.span, - seen_trait_items, - |i, s, c| MethodNotMemberOfTrait(i, s, c), + self.with_generic_param_rib( + &[], + RibKind::AssocItem, + LifetimeRibKind::Generics { + binder: item.id, + kind: LifetimeBinderKind::Function, + span: delegation.path.segments.last().unwrap().ident.span, + }, + |this| { + this.check_trait_item( + item.id, + item.ident, + &item.kind, + ValueNS, + item.span, + seen_trait_items, + |i, s, c| MethodNotMemberOfTrait(i, s, c), + ); + + this.resolve_delegation(delegation) + }, ); - self.resolve_delegation(delegation); } AssocItemKind::MacCall(_) => { panic!("unexpanded macro in resolve!") diff --git a/tests/ui/delegation/target-expr.rs b/tests/ui/delegation/target-expr.rs new file mode 100644 index 000000000000..b9c6fe92810b --- /dev/null +++ b/tests/ui/delegation/target-expr.rs @@ -0,0 +1,38 @@ +#![feature(fn_delegation)] +#![allow(incomplete_features)] + +trait Trait { + fn static_method(x: i32) -> i32 { x } +} + +struct F; + +struct S(F); +impl Trait for S {} + +fn foo(x: i32) -> i32 { x } + +fn bar(_: T) { + reuse Trait::static_method { + //~^ ERROR delegation with early bound generics is not supported yet + //~| ERROR mismatched types + let _ = T::Default(); + //~^ ERROR can't use generic parameters from outer item + } +} + +fn main() { + let y = 0; + reuse ::static_method { + let x = y; + //~^ ERROR can't capture dynamic environment in a fn item + foo(self); + + let reuse_ptr: fn(i32) -> i32 = static_method; + reuse_ptr(0) + } + self.0; + //~^ ERROR expected value, found module `self` + let z = x; + //~^ ERROR cannot find value `x` in this scope +} diff --git a/tests/ui/delegation/target-expr.stderr b/tests/ui/delegation/target-expr.stderr new file mode 100644 index 000000000000..da0fac2f5e46 --- /dev/null +++ b/tests/ui/delegation/target-expr.stderr @@ -0,0 +1,65 @@ +error[E0401]: can't use generic parameters from outer item + --> $DIR/target-expr.rs:19:17 + | +LL | fn bar(_: T) { + | - type parameter from outer item +LL | reuse Trait::static_method { + | - help: try introducing a local generic parameter here: `T,` +... +LL | let _ = T::Default(); + | ^^^^^^^^^^ use of generic parameter from outer item + +error[E0434]: can't capture dynamic environment in a fn item + --> $DIR/target-expr.rs:27:17 + | +LL | let x = y; + | ^ + | + = help: use the `|| { ... }` closure form instead + +error[E0424]: expected value, found module `self` + --> $DIR/target-expr.rs:34:5 + | +LL | fn main() { + | ---- this function can't have a `self` parameter +... +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 + --> $DIR/target-expr.rs:36:13 + | +LL | let z = x; + | ^ + | +help: the binding `x` is available in a different scope in the same function + --> $DIR/target-expr.rs:27:13 + | +LL | let x = y; + | ^ + +error: delegation with early bound generics is not supported yet + --> $DIR/target-expr.rs:16:18 + | +LL | fn static_method(x: i32) -> i32 { x } + | ------------------------------- callee defined here +... +LL | reuse Trait::static_method { + | ^^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/target-expr.rs:16:32 + | +LL | reuse Trait::static_method { + | ________________________________^ +LL | | +LL | | +LL | | let _ = T::Default(); +LL | | +LL | | } + | |_____^ expected `i32`, found `()` + +error: aborting due to 6 previous errors + +Some errors have detailed explanations: E0308, E0401, E0424, E0425, E0434. +For more information about an error, try `rustc --explain E0308`. From 3b94f33c232d40ab8cf6487261178292981bc6d5 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 26 Mar 2024 11:03:23 +0000 Subject: [PATCH 079/165] Remove `CacheSelector` trait now that we can use GATs --- compiler/rustc_middle/src/query/keys.rs | 109 +++++++++--------- compiler/rustc_middle/src/query/mod.rs | 2 +- compiler/rustc_middle/src/query/plumbing.rs | 4 +- .../rustc_query_system/src/query/caches.rs | 39 ------- compiler/rustc_query_system/src/query/mod.rs | 5 +- 5 files changed, 57 insertions(+), 102 deletions(-) diff --git a/compiler/rustc_middle/src/query/keys.rs b/compiler/rustc_middle/src/query/keys.rs index 3b1d1a04d6f7..9cbc4d10146d 100644 --- a/compiler/rustc_middle/src/query/keys.rs +++ b/compiler/rustc_middle/src/query/keys.rs @@ -9,8 +9,7 @@ use crate::ty::{self, Ty, TyCtxt}; use crate::ty::{GenericArg, GenericArgsRef}; use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, LocalModDefId, ModDefId, LOCAL_CRATE}; use rustc_hir::hir_id::{HirId, OwnerId}; -use rustc_query_system::query::DefIdCacheSelector; -use rustc_query_system::query::{DefaultCacheSelector, SingleCacheSelector, VecCacheSelector}; +use rustc_query_system::query::{DefIdCache, DefaultCache, SingleCache, VecCache}; use rustc_span::symbol::{Ident, Symbol}; use rustc_span::{Span, DUMMY_SP}; use rustc_target::abi; @@ -22,7 +21,7 @@ pub struct LocalCrate; /// The `Key` trait controls what types can legally be used as the key /// for a query. pub trait Key: Sized { - // N.B. Most of the keys down below have `type CacheSelector = DefaultCacheSelector;`, + // N.B. Most of the keys down below have `type Cache = DefaultCache;`, // it would be reasonable to use associated type defaults, to remove the duplication... // // ...But r-a doesn't support them yet and using a default here causes r-a to not infer @@ -30,7 +29,7 @@ pub trait Key: Sized { // type defaults, please restrain from using them here <3 // // r-a issue: - type CacheSelector; + type Cache; /// In the event that a cycle occurs, if no explicit span has been /// given for a query with key `self`, what span should we use? @@ -56,7 +55,7 @@ pub trait AsLocalKey: Key { } impl Key for () { - type CacheSelector = SingleCacheSelector; + type Cache = SingleCache; fn default_span(&self, _: TyCtxt<'_>) -> Span { DUMMY_SP @@ -64,7 +63,7 @@ impl Key for () { } impl<'tcx> Key for ty::InstanceDef<'tcx> { - type CacheSelector = DefaultCacheSelector; + type Cache = DefaultCache; fn default_span(&self, tcx: TyCtxt<'_>) -> Span { tcx.def_span(self.def_id()) @@ -81,7 +80,7 @@ impl<'tcx> AsLocalKey for ty::InstanceDef<'tcx> { } impl<'tcx> Key for ty::Instance<'tcx> { - type CacheSelector = DefaultCacheSelector; + type Cache = DefaultCache; fn default_span(&self, tcx: TyCtxt<'_>) -> Span { tcx.def_span(self.def_id()) @@ -89,7 +88,7 @@ impl<'tcx> Key for ty::Instance<'tcx> { } impl<'tcx> Key for mir::interpret::GlobalId<'tcx> { - type CacheSelector = DefaultCacheSelector; + type Cache = DefaultCache; fn default_span(&self, tcx: TyCtxt<'_>) -> Span { self.instance.default_span(tcx) @@ -97,7 +96,7 @@ impl<'tcx> Key for mir::interpret::GlobalId<'tcx> { } impl<'tcx> Key for (Ty<'tcx>, Option>) { - type CacheSelector = DefaultCacheSelector; + type Cache = DefaultCache; fn default_span(&self, _: TyCtxt<'_>) -> Span { DUMMY_SP @@ -105,7 +104,7 @@ impl<'tcx> Key for (Ty<'tcx>, Option>) { } impl<'tcx> Key for mir::interpret::LitToConstInput<'tcx> { - type CacheSelector = DefaultCacheSelector; + type Cache = DefaultCache; fn default_span(&self, _tcx: TyCtxt<'_>) -> Span { DUMMY_SP @@ -113,7 +112,7 @@ impl<'tcx> Key for mir::interpret::LitToConstInput<'tcx> { } impl Key for CrateNum { - type CacheSelector = VecCacheSelector; + type Cache = VecCache; fn default_span(&self, _: TyCtxt<'_>) -> Span { DUMMY_SP @@ -130,7 +129,7 @@ impl AsLocalKey for CrateNum { } impl Key for OwnerId { - type CacheSelector = VecCacheSelector; + type Cache = VecCache; fn default_span(&self, tcx: TyCtxt<'_>) -> Span { self.to_def_id().default_span(tcx) @@ -142,7 +141,7 @@ impl Key for OwnerId { } impl Key for LocalDefId { - type CacheSelector = VecCacheSelector; + type Cache = VecCache; fn default_span(&self, tcx: TyCtxt<'_>) -> Span { self.to_def_id().default_span(tcx) @@ -154,7 +153,7 @@ impl Key for LocalDefId { } impl Key for DefId { - type CacheSelector = DefIdCacheSelector; + type Cache = DefIdCache; fn default_span(&self, tcx: TyCtxt<'_>) -> Span { tcx.def_span(*self) @@ -176,7 +175,7 @@ impl AsLocalKey for DefId { } impl Key for LocalModDefId { - type CacheSelector = DefaultCacheSelector; + type Cache = DefaultCache; fn default_span(&self, tcx: TyCtxt<'_>) -> Span { tcx.def_span(*self) @@ -189,7 +188,7 @@ impl Key for LocalModDefId { } impl Key for ModDefId { - type CacheSelector = DefaultCacheSelector; + type Cache = DefaultCache; fn default_span(&self, tcx: TyCtxt<'_>) -> Span { tcx.def_span(*self) @@ -211,7 +210,7 @@ impl AsLocalKey for ModDefId { } impl Key for SimplifiedType { - type CacheSelector = DefaultCacheSelector; + type Cache = DefaultCache; fn default_span(&self, _: TyCtxt<'_>) -> Span { DUMMY_SP @@ -219,7 +218,7 @@ impl Key for SimplifiedType { } impl Key for (DefId, DefId) { - type CacheSelector = DefaultCacheSelector; + type Cache = DefaultCache; fn default_span(&self, tcx: TyCtxt<'_>) -> Span { self.1.default_span(tcx) @@ -227,7 +226,7 @@ impl Key for (DefId, DefId) { } impl<'tcx> Key for (ty::Instance<'tcx>, LocalDefId) { - type CacheSelector = DefaultCacheSelector; + type Cache = DefaultCache; fn default_span(&self, tcx: TyCtxt<'_>) -> Span { self.0.default_span(tcx) @@ -235,7 +234,7 @@ impl<'tcx> Key for (ty::Instance<'tcx>, LocalDefId) { } impl Key for (DefId, LocalDefId) { - type CacheSelector = DefaultCacheSelector; + type Cache = DefaultCache; fn default_span(&self, tcx: TyCtxt<'_>) -> Span { self.1.default_span(tcx) @@ -243,7 +242,7 @@ impl Key for (DefId, LocalDefId) { } impl Key for (LocalDefId, DefId) { - type CacheSelector = DefaultCacheSelector; + type Cache = DefaultCache; fn default_span(&self, tcx: TyCtxt<'_>) -> Span { self.0.default_span(tcx) @@ -251,7 +250,7 @@ impl Key for (LocalDefId, DefId) { } impl Key for (LocalDefId, LocalDefId) { - type CacheSelector = DefaultCacheSelector; + type Cache = DefaultCache; fn default_span(&self, tcx: TyCtxt<'_>) -> Span { self.0.default_span(tcx) @@ -259,7 +258,7 @@ impl Key for (LocalDefId, LocalDefId) { } impl Key for (DefId, Ident) { - type CacheSelector = DefaultCacheSelector; + type Cache = DefaultCache; fn default_span(&self, tcx: TyCtxt<'_>) -> Span { tcx.def_span(self.0) @@ -272,7 +271,7 @@ impl Key for (DefId, Ident) { } impl Key for (LocalDefId, LocalDefId, Ident) { - type CacheSelector = DefaultCacheSelector; + type Cache = DefaultCache; fn default_span(&self, tcx: TyCtxt<'_>) -> Span { self.1.default_span(tcx) @@ -280,7 +279,7 @@ impl Key for (LocalDefId, LocalDefId, Ident) { } impl Key for (CrateNum, DefId) { - type CacheSelector = DefaultCacheSelector; + type Cache = DefaultCache; fn default_span(&self, tcx: TyCtxt<'_>) -> Span { self.1.default_span(tcx) @@ -297,7 +296,7 @@ impl AsLocalKey for (CrateNum, DefId) { } impl Key for (CrateNum, SimplifiedType) { - type CacheSelector = DefaultCacheSelector; + type Cache = DefaultCache; fn default_span(&self, _: TyCtxt<'_>) -> Span { DUMMY_SP @@ -314,7 +313,7 @@ impl AsLocalKey for (CrateNum, SimplifiedType) { } impl Key for (DefId, SimplifiedType) { - type CacheSelector = DefaultCacheSelector; + type Cache = DefaultCache; fn default_span(&self, tcx: TyCtxt<'_>) -> Span { self.0.default_span(tcx) @@ -322,7 +321,7 @@ impl Key for (DefId, SimplifiedType) { } impl<'tcx> Key for GenericArgsRef<'tcx> { - type CacheSelector = DefaultCacheSelector; + type Cache = DefaultCache; fn default_span(&self, _: TyCtxt<'_>) -> Span { DUMMY_SP @@ -330,7 +329,7 @@ impl<'tcx> Key for GenericArgsRef<'tcx> { } impl<'tcx> Key for (DefId, GenericArgsRef<'tcx>) { - type CacheSelector = DefaultCacheSelector; + type Cache = DefaultCache; fn default_span(&self, tcx: TyCtxt<'_>) -> Span { self.0.default_span(tcx) @@ -338,7 +337,7 @@ impl<'tcx> Key for (DefId, GenericArgsRef<'tcx>) { } impl<'tcx> Key for (ty::UnevaluatedConst<'tcx>, ty::UnevaluatedConst<'tcx>) { - type CacheSelector = DefaultCacheSelector; + type Cache = DefaultCache; fn default_span(&self, tcx: TyCtxt<'_>) -> Span { (self.0).def.default_span(tcx) @@ -346,7 +345,7 @@ impl<'tcx> Key for (ty::UnevaluatedConst<'tcx>, ty::UnevaluatedConst<'tcx>) { } impl<'tcx> Key for (LocalDefId, DefId, GenericArgsRef<'tcx>) { - type CacheSelector = DefaultCacheSelector; + type Cache = DefaultCache; fn default_span(&self, tcx: TyCtxt<'_>) -> Span { self.0.default_span(tcx) @@ -354,7 +353,7 @@ impl<'tcx> Key for (LocalDefId, DefId, GenericArgsRef<'tcx>) { } impl<'tcx> Key for (ty::ParamEnv<'tcx>, ty::TraitRef<'tcx>) { - type CacheSelector = DefaultCacheSelector; + type Cache = DefaultCache; fn default_span(&self, tcx: TyCtxt<'_>) -> Span { tcx.def_span(self.1.def_id) @@ -362,7 +361,7 @@ impl<'tcx> Key for (ty::ParamEnv<'tcx>, ty::TraitRef<'tcx>) { } impl<'tcx> Key for ty::PolyTraitRef<'tcx> { - type CacheSelector = DefaultCacheSelector; + type Cache = DefaultCache; fn default_span(&self, tcx: TyCtxt<'_>) -> Span { tcx.def_span(self.def_id()) @@ -370,7 +369,7 @@ impl<'tcx> Key for ty::PolyTraitRef<'tcx> { } impl<'tcx> Key for ty::PolyExistentialTraitRef<'tcx> { - type CacheSelector = DefaultCacheSelector; + type Cache = DefaultCache; fn default_span(&self, tcx: TyCtxt<'_>) -> Span { tcx.def_span(self.def_id()) @@ -378,7 +377,7 @@ impl<'tcx> Key for ty::PolyExistentialTraitRef<'tcx> { } impl<'tcx> Key for (ty::PolyTraitRef<'tcx>, ty::PolyTraitRef<'tcx>) { - type CacheSelector = DefaultCacheSelector; + type Cache = DefaultCache; fn default_span(&self, tcx: TyCtxt<'_>) -> Span { tcx.def_span(self.0.def_id()) @@ -386,7 +385,7 @@ impl<'tcx> Key for (ty::PolyTraitRef<'tcx>, ty::PolyTraitRef<'tcx>) { } impl<'tcx> Key for GenericArg<'tcx> { - type CacheSelector = DefaultCacheSelector; + type Cache = DefaultCache; fn default_span(&self, _: TyCtxt<'_>) -> Span { DUMMY_SP @@ -394,7 +393,7 @@ impl<'tcx> Key for GenericArg<'tcx> { } impl<'tcx> Key for ty::Const<'tcx> { - type CacheSelector = DefaultCacheSelector; + type Cache = DefaultCache; fn default_span(&self, _: TyCtxt<'_>) -> Span { DUMMY_SP @@ -402,7 +401,7 @@ impl<'tcx> Key for ty::Const<'tcx> { } impl<'tcx> Key for Ty<'tcx> { - type CacheSelector = DefaultCacheSelector; + type Cache = DefaultCache; fn default_span(&self, _: TyCtxt<'_>) -> Span { DUMMY_SP @@ -418,7 +417,7 @@ impl<'tcx> Key for Ty<'tcx> { } impl<'tcx> Key for TyAndLayout<'tcx> { - type CacheSelector = DefaultCacheSelector; + type Cache = DefaultCache; fn default_span(&self, _: TyCtxt<'_>) -> Span { DUMMY_SP @@ -426,7 +425,7 @@ impl<'tcx> Key for TyAndLayout<'tcx> { } impl<'tcx> Key for (Ty<'tcx>, Ty<'tcx>) { - type CacheSelector = DefaultCacheSelector; + type Cache = DefaultCache; fn default_span(&self, _: TyCtxt<'_>) -> Span { DUMMY_SP @@ -434,7 +433,7 @@ impl<'tcx> Key for (Ty<'tcx>, Ty<'tcx>) { } impl<'tcx> Key for &'tcx ty::List> { - type CacheSelector = DefaultCacheSelector; + type Cache = DefaultCache; fn default_span(&self, _: TyCtxt<'_>) -> Span { DUMMY_SP @@ -442,7 +441,7 @@ impl<'tcx> Key for &'tcx ty::List> { } impl<'tcx> Key for ty::ParamEnv<'tcx> { - type CacheSelector = DefaultCacheSelector; + type Cache = DefaultCache; fn default_span(&self, _: TyCtxt<'_>) -> Span { DUMMY_SP @@ -450,7 +449,7 @@ impl<'tcx> Key for ty::ParamEnv<'tcx> { } impl<'tcx, T: Key> Key for ty::ParamEnvAnd<'tcx, T> { - type CacheSelector = DefaultCacheSelector; + type Cache = DefaultCache; fn default_span(&self, tcx: TyCtxt<'_>) -> Span { self.value.default_span(tcx) @@ -462,7 +461,7 @@ impl<'tcx, T: Key> Key for ty::ParamEnvAnd<'tcx, T> { } impl Key for Symbol { - type CacheSelector = DefaultCacheSelector; + type Cache = DefaultCache; fn default_span(&self, _tcx: TyCtxt<'_>) -> Span { DUMMY_SP @@ -470,7 +469,7 @@ impl Key for Symbol { } impl Key for Option { - type CacheSelector = DefaultCacheSelector; + type Cache = DefaultCache; fn default_span(&self, _tcx: TyCtxt<'_>) -> Span { DUMMY_SP @@ -480,7 +479,7 @@ impl Key for Option { /// Canonical query goals correspond to abstract trait operations that /// are not tied to any crate in particular. impl<'tcx, T: Clone> Key for Canonical<'tcx, T> { - type CacheSelector = DefaultCacheSelector; + type Cache = DefaultCache; fn default_span(&self, _tcx: TyCtxt<'_>) -> Span { DUMMY_SP @@ -488,7 +487,7 @@ impl<'tcx, T: Clone> Key for Canonical<'tcx, T> { } impl Key for (Symbol, u32, u32) { - type CacheSelector = DefaultCacheSelector; + type Cache = DefaultCache; fn default_span(&self, _tcx: TyCtxt<'_>) -> Span { DUMMY_SP @@ -496,7 +495,7 @@ impl Key for (Symbol, u32, u32) { } impl<'tcx> Key for (DefId, Ty<'tcx>, GenericArgsRef<'tcx>, ty::ParamEnv<'tcx>) { - type CacheSelector = DefaultCacheSelector; + type Cache = DefaultCache; fn default_span(&self, _tcx: TyCtxt<'_>) -> Span { DUMMY_SP @@ -504,7 +503,7 @@ impl<'tcx> Key for (DefId, Ty<'tcx>, GenericArgsRef<'tcx>, ty::ParamEnv<'tcx>) { } impl<'tcx> Key for (Ty<'tcx>, abi::VariantIdx) { - type CacheSelector = DefaultCacheSelector; + type Cache = DefaultCache; fn default_span(&self, _tcx: TyCtxt<'_>) -> Span { DUMMY_SP @@ -512,7 +511,7 @@ impl<'tcx> Key for (Ty<'tcx>, abi::VariantIdx) { } impl<'tcx> Key for (ty::Predicate<'tcx>, traits::WellFormedLoc) { - type CacheSelector = DefaultCacheSelector; + type Cache = DefaultCache; fn default_span(&self, _tcx: TyCtxt<'_>) -> Span { DUMMY_SP @@ -520,7 +519,7 @@ impl<'tcx> Key for (ty::Predicate<'tcx>, traits::WellFormedLoc) { } impl<'tcx> Key for (ty::PolyFnSig<'tcx>, &'tcx ty::List>) { - type CacheSelector = DefaultCacheSelector; + type Cache = DefaultCache; fn default_span(&self, _: TyCtxt<'_>) -> Span { DUMMY_SP @@ -528,7 +527,7 @@ impl<'tcx> Key for (ty::PolyFnSig<'tcx>, &'tcx ty::List>) { } impl<'tcx> Key for (ty::Instance<'tcx>, &'tcx ty::List>) { - type CacheSelector = DefaultCacheSelector; + type Cache = DefaultCache; fn default_span(&self, tcx: TyCtxt<'_>) -> Span { self.0.default_span(tcx) @@ -536,7 +535,7 @@ impl<'tcx> Key for (ty::Instance<'tcx>, &'tcx ty::List>) { } impl<'tcx> Key for (Ty<'tcx>, ty::ValTree<'tcx>) { - type CacheSelector = DefaultCacheSelector; + type Cache = DefaultCache; fn default_span(&self, _: TyCtxt<'_>) -> Span { DUMMY_SP @@ -544,7 +543,7 @@ impl<'tcx> Key for (Ty<'tcx>, ty::ValTree<'tcx>) { } impl Key for HirId { - type CacheSelector = DefaultCacheSelector; + type Cache = DefaultCache; fn default_span(&self, tcx: TyCtxt<'_>) -> Span { tcx.hir().span(*self) @@ -557,7 +556,7 @@ impl Key for HirId { } impl<'tcx> Key for (ValidityRequirement, ty::ParamEnvAnd<'tcx, Ty<'tcx>>) { - type CacheSelector = DefaultCacheSelector; + type Cache = DefaultCache; // Just forward to `Ty<'tcx>` diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 38cfd11a016f..5e4454db3e28 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -73,7 +73,7 @@ use rustc_hir::lang_items::{LangItem, LanguageItems}; use rustc_hir::{Crate, ItemLocalId, ItemLocalMap, TraitCandidate}; use rustc_index::IndexVec; use rustc_query_system::ich::StableHashingContext; -use rustc_query_system::query::{try_get_cached, CacheSelector, QueryCache, QueryMode, QueryState}; +use rustc_query_system::query::{try_get_cached, QueryCache, QueryMode, QueryState}; use rustc_session::config::{EntryFnType, OptLevel, OutputFilenames, SymbolManglingVersion}; use rustc_session::cstore::{CrateDepKind, CrateSource}; use rustc_session::cstore::{ExternCrate, ForeignModule, LinkagePreference, NativeLib}; diff --git a/compiler/rustc_middle/src/query/plumbing.rs b/compiler/rustc_middle/src/query/plumbing.rs index 8d88488e1675..e3588a7afdc1 100644 --- a/compiler/rustc_middle/src/query/plumbing.rs +++ b/compiler/rustc_middle/src/query/plumbing.rs @@ -336,9 +336,7 @@ macro_rules! define_callbacks { )) } - pub type Storage<'tcx> = < - <$($K)* as keys::Key>::CacheSelector as CacheSelector<'tcx, Erase<$V>> - >::Cache; + pub type Storage<'tcx> = <$($K)* as keys::Key>::Cache>; // Ensure that keys grow no larger than 64 bytes #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))] diff --git a/compiler/rustc_query_system/src/query/caches.rs b/compiler/rustc_query_system/src/query/caches.rs index 674a0984ae98..c3fc036aed31 100644 --- a/compiler/rustc_query_system/src/query/caches.rs +++ b/compiler/rustc_query_system/src/query/caches.rs @@ -9,13 +9,6 @@ use rustc_span::def_id::DefId; use rustc_span::def_id::DefIndex; use std::fmt::Debug; use std::hash::Hash; -use std::marker::PhantomData; - -pub trait CacheSelector<'tcx, V> { - type Cache - where - V: Copy; -} pub trait QueryCache: Sized { type Key: Hash + Eq + Copy + Debug; @@ -29,14 +22,6 @@ pub trait QueryCache: Sized { fn iter(&self, f: &mut dyn FnMut(&Self::Key, &Self::Value, DepNodeIndex)); } -pub struct DefaultCacheSelector(PhantomData); - -impl<'tcx, K: Eq + Hash, V: 'tcx> CacheSelector<'tcx, V> for DefaultCacheSelector { - type Cache = DefaultCache - where - V: Copy; -} - pub struct DefaultCache { cache: Sharded>, } @@ -81,14 +66,6 @@ where } } -pub struct SingleCacheSelector; - -impl<'tcx, V: 'tcx> CacheSelector<'tcx, V> for SingleCacheSelector { - type Cache = SingleCache - where - V: Copy; -} - pub struct SingleCache { cache: OnceLock<(V, DepNodeIndex)>, } @@ -123,14 +100,6 @@ where } } -pub struct VecCacheSelector(PhantomData); - -impl<'tcx, K: Idx, V: 'tcx> CacheSelector<'tcx, V> for VecCacheSelector { - type Cache = VecCache - where - V: Copy; -} - pub struct VecCache { cache: Sharded>>, } @@ -174,14 +143,6 @@ where } } -pub struct DefIdCacheSelector; - -impl<'tcx, V: 'tcx> CacheSelector<'tcx, V> for DefIdCacheSelector { - type Cache = DefIdCache - where - V: Copy; -} - pub struct DefIdCache { /// Stores the local DefIds in a dense map. Local queries are much more often dense, so this is /// a win over hashing query keys at marginal memory cost (~5% at most) compared to FxHashMap. diff --git a/compiler/rustc_query_system/src/query/mod.rs b/compiler/rustc_query_system/src/query/mod.rs index 01b9d458f1e4..91a0026f281e 100644 --- a/compiler/rustc_query_system/src/query/mod.rs +++ b/compiler/rustc_query_system/src/query/mod.rs @@ -9,10 +9,7 @@ pub use self::job::{ }; mod caches; -pub use self::caches::{ - CacheSelector, DefIdCacheSelector, DefaultCacheSelector, QueryCache, SingleCacheSelector, - VecCacheSelector, -}; +pub use self::caches::{DefIdCache, DefaultCache, QueryCache, SingleCache, VecCache}; mod config; pub use self::config::{HashResult, QueryConfig}; From 34d0f6a1d41de0e9111646b55e959022dff21eb1 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Tue, 26 Mar 2024 11:03:50 +0000 Subject: [PATCH 080/165] Re-enable fixed rustc test --- 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 2c1cff51014f..96f71bcf7670 100755 --- a/scripts/test_rustc_tests.sh +++ b/scripts/test_rustc_tests.sh @@ -123,7 +123,6 @@ rm -r tests/run-make/panic-abort-eh_frame # .eh_frame emitted with panic=abort # bugs in the test suite # ====================== -rm tests/ui/backtrace.rs # TODO warning rm tests/ui/process/nofile-limit.rs # TODO some AArch64 linking issue rm tests/ui/stdio-is-blocking.rs # really slow with unoptimized libstd From 7b4e5079619f99a1bff8a2f388b498be5687d280 Mon Sep 17 00:00:00 2001 From: Samuel Thibault Date: Mon, 25 Mar 2024 21:29:42 +0100 Subject: [PATCH 081/165] unix fs: Make hurd and horizon using explicit new rather than From 408c0ea2162b ("unix time module now return result") dropped the From impl for SystemTime, breaking the hurd and horizon builds. Fixes #123032 --- library/std/src/sys/pal/unix/fs.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/std/src/sys/pal/unix/fs.rs b/library/std/src/sys/pal/unix/fs.rs index b968f8df34c2..99b6da60c146 100644 --- a/library/std/src/sys/pal/unix/fs.rs +++ b/library/std/src/sys/pal/unix/fs.rs @@ -517,7 +517,7 @@ impl FileAttr { #[cfg(any(target_os = "horizon", target_os = "hurd"))] pub fn modified(&self) -> io::Result { - Ok(SystemTime::from(self.stat.st_mtim)) + SystemTime::new(self.stat.st_mtim.tv_sec as i64, self.stat.st_mtim.tv_nsec as i64) } #[cfg(not(any( @@ -545,7 +545,7 @@ impl FileAttr { #[cfg(any(target_os = "horizon", target_os = "hurd"))] pub fn accessed(&self) -> io::Result { - Ok(SystemTime::from(self.stat.st_atim)) + SystemTime::new(self.stat.st_atim.tv_sec as i64, self.stat.st_atim.tv_nsec as i64) } #[cfg(any( From 950b40f1119ebe5ae51555ca7d236a899b604a4c Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 26 Mar 2024 11:16:09 -0400 Subject: [PATCH 082/165] Don't check match scrutinee of postfix match for unused parens --- compiler/rustc_lint/src/unused.rs | 4 +++- tests/ui/match/postfix-match/no-unused-parens.rs | 8 ++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) create mode 100644 tests/ui/match/postfix-match/no-unused-parens.rs diff --git a/compiler/rustc_lint/src/unused.rs b/compiler/rustc_lint/src/unused.rs index 0b757f95a99b..111a4fdcea17 100644 --- a/compiler/rustc_lint/src/unused.rs +++ b/compiler/rustc_lint/src/unused.rs @@ -865,7 +865,9 @@ trait UnusedDelimLint { (iter, UnusedDelimsCtx::ForIterExpr, true, None, Some(body.span.lo()), true) } - Match(ref head, ..) if Self::LINT_EXPR_IN_PATTERN_MATCHING_CTX => { + Match(ref head, _, ast::MatchKind::Prefix) + if Self::LINT_EXPR_IN_PATTERN_MATCHING_CTX => + { let left = e.span.lo() + rustc_span::BytePos(5); (head, UnusedDelimsCtx::MatchScrutineeExpr, true, Some(left), None, true) } diff --git a/tests/ui/match/postfix-match/no-unused-parens.rs b/tests/ui/match/postfix-match/no-unused-parens.rs new file mode 100644 index 000000000000..46cac7a6107e --- /dev/null +++ b/tests/ui/match/postfix-match/no-unused-parens.rs @@ -0,0 +1,8 @@ +//@ check-pass + +#![feature(postfix_match)] + +fn main() { + (&1).match { a => a }; + (1 + 2).match { b => b }; +} From c2de5aff71b53858d18d30695ee180327c78d44c Mon Sep 17 00:00:00 2001 From: clubby789 Date: Tue, 26 Mar 2024 00:50:20 +0000 Subject: [PATCH 083/165] Revert `cargo update` changes --- .github/workflows/dependencies.yml | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/.github/workflows/dependencies.yml b/.github/workflows/dependencies.yml index 1dc5b0e9d08d..f4e409e0d491 100644 --- a/.github/workflows/dependencies.yml +++ b/.github/workflows/dependencies.yml @@ -6,8 +6,6 @@ on: schedule: # Run weekly - cron: '0 0 * * Sun' - # Re-bump deps every 4 hours - - cron: '0 */4 * * *' workflow_dispatch: # Needed so we can run it manually permissions: @@ -42,7 +40,7 @@ jobs: # Exit with error if open and S-waiting-on-bors if [[ "$STATE" == "OPEN" && "$WAITING_ON_BORS" == "true" ]]; then - gh run cancel ${{ github.run_id }} + exit 1 fi update: @@ -65,10 +63,7 @@ jobs: - name: cargo update # Remove first line that always just says "Updating crates.io index" - # If there are no changes, cancel the job here - run: | - cargo update 2>&1 | sed '/crates.io index/d' | tee -a cargo_update.log - git status --porcelain | grep -q Cargo.lock || gh run cancel ${{ github.run_id }} + run: cargo update 2>&1 | sed '/crates.io index/d' | tee -a cargo_update.log - name: upload Cargo.lock artifact for use in PR uses: actions/upload-artifact@v4 with: @@ -95,11 +90,11 @@ jobs: uses: actions/checkout@v4 - name: download Cargo.lock from update job - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: name: Cargo-lock - name: download cargo-update log from update job - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: name: cargo-updates @@ -134,14 +129,14 @@ jobs: # Exit with error if PR is closed STATE=$(gh pr view cargo_update --repo $GITHUB_REPOSITORY --json state --jq '.state') if [[ "$STATE" != "OPEN" ]]; then - gh run cancel ${{ github.run_id }} + exit 1 fi gh pr edit cargo_update --title "${PR_TITLE}" --body-file body.md --repo $GITHUB_REPOSITORY - name: open new pull request - # Only run if there wasn't an existing PR and if this is the weekly run - if: steps.edit.outcome != 'success' && github.event.schedule == '0 0 * * Sun' + # Only run if there wasn't an existing PR + if: steps.edit.outcome != 'success' env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: gh pr create --title "${PR_TITLE}" --body-file body.md --repo $GITHUB_REPOSITORY From 22bc5c538d2c20efb886c4923d7c0658e1f3a2ac Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 25 Mar 2024 15:29:00 -0400 Subject: [PATCH 084/165] In ConstructCoroutineInClosureShim, pass receiver by ref, not pointer --- compiler/rustc_mir_transform/src/shim.rs | 6 +-- compiler/rustc_ty_utils/src/abi.rs | 8 +++- .../miri/tests/pass/async-closure-drop.rs | 40 +++++++++++++++++++ .../miri/tests/pass/async-closure-drop.stdout | 3 ++ src/tools/miri/tests/pass/async-closure.rs | 34 +++++++++++----- .../miri/tests/pass/async-closure.stdout | 7 ++-- ...coroutine_closure_by_ref.0.panic-abort.mir | 2 +- ...oroutine_closure_by_ref.0.panic-unwind.mir | 2 +- 8 files changed, 81 insertions(+), 21 deletions(-) create mode 100644 src/tools/miri/tests/pass/async-closure-drop.rs create mode 100644 src/tools/miri/tests/pass/async-closure-drop.stdout diff --git a/compiler/rustc_mir_transform/src/shim.rs b/compiler/rustc_mir_transform/src/shim.rs index 94a95428ab03..b60ee7649b24 100644 --- a/compiler/rustc_mir_transform/src/shim.rs +++ b/compiler/rustc_mir_transform/src/shim.rs @@ -1015,8 +1015,8 @@ fn build_construct_coroutine_by_move_shim<'tcx>( bug!(); }; - // We use `*mut Self` here because we only need to emit an ABI-compatible shim body, - // rather than match the signature exactly. + // 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). // // 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 @@ -1025,7 +1025,7 @@ fn build_construct_coroutine_by_move_shim<'tcx>( 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_ptr(tcx, self_ty); + self_ty = Ty::new_mut_ref(tcx, tcx.lifetimes.re_erased, self_ty); } let poly_sig = args.as_coroutine_closure().coroutine_closure_sig().map_bound(|sig| { diff --git a/compiler/rustc_ty_utils/src/abi.rs b/compiler/rustc_ty_utils/src/abi.rs index af1dfb6f7e92..65c3cf1a6074 100644 --- a/compiler/rustc_ty_utils/src/abi.rs +++ b/compiler/rustc_ty_utils/src/abi.rs @@ -125,8 +125,12 @@ 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 ref. - if receiver_by_ref { Ty::new_mut_ptr(tcx, coroutine_ty) } else { coroutine_ty } + // still take their receiver by (mut) ref. + if receiver_by_ref { + Ty::new_mut_ref(tcx, tcx.lifetimes.re_erased, coroutine_ty) + } else { + coroutine_ty + } } else { tcx.closure_env_ty(coroutine_ty, coroutine_kind, env_region) }; diff --git a/src/tools/miri/tests/pass/async-closure-drop.rs b/src/tools/miri/tests/pass/async-closure-drop.rs new file mode 100644 index 000000000000..9b2fc2948bf4 --- /dev/null +++ b/src/tools/miri/tests/pass/async-closure-drop.rs @@ -0,0 +1,40 @@ +#![feature(async_closure, noop_waker, async_fn_traits)] + +use std::future::Future; +use std::pin::pin; +use std::task::*; + +pub fn block_on(fut: impl Future) -> T { + let mut fut = pin!(fut); + let ctx = &mut Context::from_waker(Waker::noop()); + + loop { + match fut.as_mut().poll(ctx) { + Poll::Pending => {} + Poll::Ready(t) => break t, + } + } +} + +async fn call_once(f: impl async FnOnce(DropMe)) { + f(DropMe("world")).await; +} + +#[derive(Debug)] +struct DropMe(&'static str); + +impl Drop for DropMe { + fn drop(&mut self) { + println!("{}", self.0); + } +} + +pub fn main() { + block_on(async { + let b = DropMe("hello"); + let async_closure = async move |a: DropMe| { + println!("{a:?} {b:?}"); + }; + call_once(async_closure).await; + }); +} diff --git a/src/tools/miri/tests/pass/async-closure-drop.stdout b/src/tools/miri/tests/pass/async-closure-drop.stdout new file mode 100644 index 000000000000..34cfdedc44ac --- /dev/null +++ b/src/tools/miri/tests/pass/async-closure-drop.stdout @@ -0,0 +1,3 @@ +DropMe("world") DropMe("hello") +world +hello diff --git a/src/tools/miri/tests/pass/async-closure.rs b/src/tools/miri/tests/pass/async-closure.rs index 9b2fc2948bf4..2f7ec2b9e6f8 100644 --- a/src/tools/miri/tests/pass/async-closure.rs +++ b/src/tools/miri/tests/pass/async-closure.rs @@ -1,6 +1,7 @@ #![feature(async_closure, noop_waker, async_fn_traits)] use std::future::Future; +use std::ops::{AsyncFnMut, AsyncFnOnce}; use std::pin::pin; use std::task::*; @@ -16,25 +17,36 @@ pub fn block_on(fut: impl Future) -> T { } } -async fn call_once(f: impl async FnOnce(DropMe)) { - f(DropMe("world")).await; +async fn call_mut(f: &mut impl AsyncFnMut(i32)) { + f(0).await; } -#[derive(Debug)] -struct DropMe(&'static str); +async fn call_once(f: impl AsyncFnOnce(i32)) { + f(1).await; +} -impl Drop for DropMe { - fn drop(&mut self) { - println!("{}", self.0); - } +async fn call_normal>(f: &impl Fn(i32) -> F) { + f(0).await; +} + +async fn call_normal_once>(f: impl FnOnce(i32) -> F) { + f(1).await; } pub fn main() { block_on(async { - let b = DropMe("hello"); - let async_closure = async move |a: DropMe| { - println!("{a:?} {b:?}"); + let b = 2i32; + let mut async_closure = async move |a: i32| { + println!("{a} {b}"); }; + 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}"); + }; + call_normal(&async_closure).await; + call_normal_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 34cfdedc44ac..7baae1aa94f8 100644 --- a/src/tools/miri/tests/pass/async-closure.stdout +++ b/src/tools/miri/tests/pass/async-closure.stdout @@ -1,3 +1,4 @@ -DropMe("world") DropMe("hello") -world -hello +0 2 +1 2 +0 +1 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 f51540bcfff7..cab7bdb7e3cb 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,6 +1,6 @@ // 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} { +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}; bb0: { 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 f51540bcfff7..cab7bdb7e3cb 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,6 +1,6 @@ // 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} { +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}; bb0: { From 2cfd5326a58bb782dd725a481c82dbb05817d654 Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Tue, 26 Mar 2024 05:48:13 -0400 Subject: [PATCH 085/165] Change `f16` and `f128` clippy stubs to be nonpanicking It turns out there is a bit of a circular dependency - I cannot add anything to `core` because Clippy fails, and I can't actually add correct Clippy implementations without new implementations from `core`. Change some of the Clippy stubs from `unimplemented!` to success values and leave a FIXME in their place to mitigate this. Fixes --- .../clippy/clippy_lints/src/float_literal.rs | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/tools/clippy/clippy_lints/src/float_literal.rs b/src/tools/clippy/clippy_lints/src/float_literal.rs index 07fbb1cb5c9f..981a76d683d2 100644 --- a/src/tools/clippy/clippy_lints/src/float_literal.rs +++ b/src/tools/clippy/clippy_lints/src/float_literal.rs @@ -83,7 +83,10 @@ impl<'tcx> LateLintPass<'tcx> for FloatLiteral { LitFloatType::Unsuffixed => None, }; let (is_whole, is_inf, mut float_str) = match fty { - FloatTy::F16 => unimplemented!("f16_f128"), + FloatTy::F16 => { + // FIXME(f16_f128): do a check like the others when parsing is available + return; + }, FloatTy::F32 => { let value = sym_str.parse::().unwrap(); @@ -94,7 +97,10 @@ impl<'tcx> LateLintPass<'tcx> for FloatLiteral { (value.fract() == 0.0, value.is_infinite(), formatter.format(value)) }, - FloatTy::F128 => unimplemented!("f16_f128"), + FloatTy::F128 => { + // FIXME(f16_f128): do a check like the others when parsing is available + return; + }, }; if is_inf { @@ -139,10 +145,11 @@ impl<'tcx> LateLintPass<'tcx> for FloatLiteral { #[must_use] fn max_digits(fty: FloatTy) -> u32 { match fty { - FloatTy::F16 => unimplemented!("f16_f128"), + // FIXME(f16_f128): replace the magic numbers once `{f16,f128}::DIGITS` are available + FloatTy::F16 => 3, FloatTy::F32 => f32::DIGITS, FloatTy::F64 => f64::DIGITS, - FloatTy::F128 => unimplemented!("f16_f128"), + FloatTy::F128 => 33, } } From 2a0107496ec22c63f313e39482377a4189cce904 Mon Sep 17 00:00:00 2001 From: Augie Fackler Date: Tue, 26 Mar 2024 14:10:25 -0400 Subject: [PATCH 086/165] RustWrapper: update call for llvm/llvm-project@44d037cc258dcf179d2c48c93996bb406ecd0fae Easy change. @rustbot label: +llvm-main --- compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp index f6ec410bfac2..8ec1f5a99e7c 100644 --- a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp @@ -1992,7 +1992,11 @@ extern "C" void LLVMRustContextConfigureDiagnosticHandler( } } if (DiagnosticHandlerCallback) { +#if LLVM_VERSION_GE(19, 0) + DiagnosticHandlerCallback(&DI, DiagnosticHandlerContext); +#else DiagnosticHandlerCallback(DI, DiagnosticHandlerContext); +#endif return true; } return false; From 3878b3716d352990cd5f9e8359daeefc11cc76ce Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Sat, 2 Mar 2024 20:53:12 +0100 Subject: [PATCH 087/165] Rename --- .../rustc_mir_build/src/build/matches/util.rs | 39 ++++++++++--------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/compiler/rustc_mir_build/src/build/matches/util.rs b/compiler/rustc_mir_build/src/build/matches/util.rs index 1148cd19a01c..8e0624a174e8 100644 --- a/compiler/rustc_mir_build/src/build/matches/util.rs +++ b/compiler/rustc_mir_build/src/build/matches/util.rs @@ -95,27 +95,28 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { impl<'pat, 'tcx> MatchPair<'pat, 'tcx> { pub(in crate::build) fn new( - mut place: PlaceBuilder<'tcx>, + mut place_builder: PlaceBuilder<'tcx>, pattern: &'pat Pat<'tcx>, cx: &mut Builder<'_, 'tcx>, ) -> MatchPair<'pat, 'tcx> { // Force the place type to the pattern's type. // FIXME(oli-obk): can we use this to simplify slice/array pattern hacks? - if let Some(resolved) = place.resolve_upvar(cx) { - place = resolved; + if let Some(resolved) = place_builder.resolve_upvar(cx) { + place_builder = resolved; } // Only add the OpaqueCast projection if the given place is an opaque type and the // expected type from the pattern is not. - let may_need_cast = match place.base() { + let may_need_cast = match place_builder.base() { PlaceBase::Local(local) => { - let ty = Place::ty_from(local, place.projection(), &cx.local_decls, cx.tcx).ty; + let ty = + Place::ty_from(local, place_builder.projection(), &cx.local_decls, cx.tcx).ty; ty != pattern.ty && ty.has_opaque_types() } _ => true, }; if may_need_cast { - place = place.project(ProjectionElem::OpaqueCast(pattern.ty)); + place_builder = place_builder.project(ProjectionElem::OpaqueCast(pattern.ty)); } let default_irrefutable = || TestCase::Irrefutable { binding: None, ascription: None }; @@ -123,7 +124,7 @@ impl<'pat, 'tcx> MatchPair<'pat, 'tcx> { let test_case = match pattern.kind { PatKind::Never | PatKind::Wild | PatKind::Error(_) => default_irrefutable(), PatKind::Or { ref pats } => TestCase::Or { - pats: pats.iter().map(|pat| FlatPat::new(place.clone(), pat, cx)).collect(), + pats: pats.iter().map(|pat| FlatPat::new(place_builder.clone(), pat, cx)).collect(), }, PatKind::Range(ref range) => { @@ -142,13 +143,13 @@ impl<'pat, 'tcx> MatchPair<'pat, 'tcx> { .. } => { // Apply the type ascription to the value at `match_pair.place` - let ascription = place.try_to_place(cx).map(|source| super::Ascription { + let ascription = place_builder.try_to_place(cx).map(|source| super::Ascription { annotation: annotation.clone(), source, variance, }); - subpairs.push(MatchPair::new(place.clone(), subpattern, cx)); + subpairs.push(MatchPair::new(place_builder.clone(), subpattern, cx)); TestCase::Irrefutable { ascription, binding: None } } @@ -161,7 +162,7 @@ impl<'pat, 'tcx> MatchPair<'pat, 'tcx> { ref subpattern, is_primary: _, } => { - let binding = place.try_to_place(cx).map(|source| super::Binding { + let binding = place_builder.try_to_place(cx).map(|source| super::Binding { span: pattern.span, source, var_id: var, @@ -170,14 +171,14 @@ impl<'pat, 'tcx> MatchPair<'pat, 'tcx> { if let Some(subpattern) = subpattern.as_ref() { // this is the `x @ P` case; have to keep matching against `P` now - subpairs.push(MatchPair::new(place.clone(), subpattern, cx)); + subpairs.push(MatchPair::new(place_builder.clone(), subpattern, cx)); } TestCase::Irrefutable { ascription: None, binding } } PatKind::InlineConstant { subpattern: ref pattern, def, .. } => { // Apply a type ascription for the inline constant to the value at `match_pair.place` - let ascription = place.try_to_place(cx).map(|source| { + let ascription = place_builder.try_to_place(cx).map(|source| { let span = pattern.span; let parent_id = cx.tcx.typeck_root_def_id(cx.def_id.to_def_id()); let args = ty::InlineConstArgs::new( @@ -203,16 +204,16 @@ impl<'pat, 'tcx> MatchPair<'pat, 'tcx> { super::Ascription { annotation, source, variance: ty::Contravariant } }); - subpairs.push(MatchPair::new(place.clone(), pattern, cx)); + subpairs.push(MatchPair::new(place_builder.clone(), pattern, cx)); TestCase::Irrefutable { ascription, binding: None } } PatKind::Array { ref prefix, ref slice, ref suffix } => { - cx.prefix_slice_suffix(&mut subpairs, &place, prefix, slice, suffix); + cx.prefix_slice_suffix(&mut subpairs, &place_builder, prefix, slice, suffix); default_irrefutable() } PatKind::Slice { ref prefix, ref slice, ref suffix } => { - cx.prefix_slice_suffix(&mut subpairs, &place, prefix, slice, suffix); + cx.prefix_slice_suffix(&mut subpairs, &place_builder, prefix, slice, suffix); if prefix.is_empty() && slice.is_some() && suffix.is_empty() { default_irrefutable() @@ -225,7 +226,7 @@ impl<'pat, 'tcx> MatchPair<'pat, 'tcx> { } PatKind::Variant { adt_def, variant_index, args, ref subpatterns } => { - let downcast_place = place.clone().downcast(adt_def, variant_index); // `(x as Variant)` + let downcast_place = place_builder.clone().downcast(adt_def, variant_index); // `(x as Variant)` subpairs = cx.field_match_pairs(downcast_place, subpatterns); let irrefutable = adt_def.variants().iter_enumerated().all(|(i, v)| { @@ -247,12 +248,12 @@ impl<'pat, 'tcx> MatchPair<'pat, 'tcx> { } PatKind::Leaf { ref subpatterns } => { - subpairs = cx.field_match_pairs(place.clone(), subpatterns); + subpairs = cx.field_match_pairs(place_builder.clone(), subpatterns); default_irrefutable() } PatKind::Deref { ref subpattern } => { - let place_builder = place.clone().deref(); + let place_builder = place_builder.clone().deref(); subpairs.push(MatchPair::new(place_builder, subpattern, cx)); default_irrefutable() } @@ -264,7 +265,7 @@ impl<'pat, 'tcx> MatchPair<'pat, 'tcx> { } }; - MatchPair { place, test_case, subpairs, pattern } + MatchPair { place: place_builder, test_case, subpairs, pattern } } } From 14f186c75690755cfe132df044b2b66f646d0d6c Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Sat, 2 Mar 2024 21:26:01 +0100 Subject: [PATCH 088/165] Store `Place` instead of `PlaceBuilder` in `MatchPair` --- .../rustc_mir_build/src/build/matches/mod.rs | 18 ++++++++----- .../rustc_mir_build/src/build/matches/test.rs | 17 ++++++------ .../rustc_mir_build/src/build/matches/util.rs | 26 +++++++++---------- 3 files changed, 33 insertions(+), 28 deletions(-) diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs index f4f452d474f1..6b7ab892a962 100644 --- a/compiler/rustc_mir_build/src/build/matches/mod.rs +++ b/compiler/rustc_mir_build/src/build/matches/mod.rs @@ -1106,7 +1106,10 @@ impl<'pat, 'tcx> TestCase<'pat, 'tcx> { #[derive(Debug, Clone)] pub(crate) struct MatchPair<'pat, 'tcx> { /// This place... - place: PlaceBuilder<'tcx>, + // This can be `None` if it referred to a non-captured place in a closure. + // Invariant: place.is_none() => test_case is Irrefutable + // In other words this must be `Some(_)` after simplification. + place: Option>, /// ... must pass this test... // Invariant: after creation and simplification in `Candidate::new()`, this must not be @@ -1587,11 +1590,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { fn pick_test( &mut self, candidates: &mut [&mut Candidate<'_, 'tcx>], - ) -> (PlaceBuilder<'tcx>, Test<'tcx>) { + ) -> (Place<'tcx>, Test<'tcx>) { // Extract the match-pair from the highest priority candidate let match_pair = &candidates.first().unwrap().match_pairs[0]; let test = self.test(match_pair); - let match_place = match_pair.place.clone(); + // Unwrap is ok after simplification. + let match_place = match_pair.place.unwrap(); debug!(?test, ?match_pair); (match_place, test) @@ -1632,7 +1636,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { /// - candidate 1 becomes `[y @ false]` since we know that `x` was `false`. fn sort_candidates<'b, 'c, 'pat>( &mut self, - match_place: &PlaceBuilder<'tcx>, + match_place: Place<'tcx>, test: &Test<'tcx>, mut candidates: &'b mut [&'c mut Candidate<'pat, 'tcx>], ) -> ( @@ -1650,7 +1654,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // sorting. while let Some(candidate) = candidates.first_mut() { let Some(branch) = - self.sort_candidate(&match_place, test, candidate, &target_candidates) + self.sort_candidate(match_place, test, candidate, &target_candidates) else { break; }; @@ -1778,7 +1782,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // For each of the N possible test outcomes, build the vector of candidates that applies if // the test has that particular outcome. let (remaining_candidates, target_candidates) = - self.sort_candidates(&match_place, &test, candidates); + self.sort_candidates(match_place, &test, candidates); // The block that we should branch to if none of the // `target_candidates` match. @@ -1818,7 +1822,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { scrutinee_span, start_block, remainder_start, - &match_place, + match_place, &test, target_blocks, ); diff --git a/compiler/rustc_mir_build/src/build/matches/test.rs b/compiler/rustc_mir_build/src/build/matches/test.rs index 9d77bd063e11..b66dd83b7ecb 100644 --- a/compiler/rustc_mir_build/src/build/matches/test.rs +++ b/compiler/rustc_mir_build/src/build/matches/test.rs @@ -5,7 +5,6 @@ // identify what tests are needed, perform the tests, and then filter // the candidates based on the result. -use crate::build::expr::as_place::PlaceBuilder; use crate::build::matches::{Candidate, MatchPair, Test, TestBranch, TestCase, TestKind}; use crate::build::Builder; use rustc_data_structures::fx::FxIndexMap; @@ -55,18 +54,17 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { Test { span: match_pair.pattern.span, kind } } - #[instrument(skip(self, target_blocks, place_builder), level = "debug")] + #[instrument(skip(self, target_blocks, place), level = "debug")] pub(super) fn perform_test( &mut self, match_start_span: Span, scrutinee_span: Span, block: BasicBlock, otherwise_block: BasicBlock, - place_builder: &PlaceBuilder<'tcx>, + place: Place<'tcx>, test: &Test<'tcx>, target_blocks: FxIndexMap, BasicBlock>, ) { - let place = place_builder.to_place(self); let place_ty = place.ty(&self.local_decls, self.tcx); debug!(?place, ?place_ty); let target_block = |branch| target_blocks.get(&branch).copied().unwrap_or(otherwise_block); @@ -475,7 +473,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { /// tighter match code if we do something a bit different. pub(super) fn sort_candidate( &mut self, - test_place: &PlaceBuilder<'tcx>, + test_place: Place<'tcx>, test: &Test<'tcx>, candidate: &mut Candidate<'_, 'tcx>, sorted_candidates: &FxIndexMap, Vec<&mut Candidate<'_, 'tcx>>>, @@ -486,8 +484,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // than one, but it'd be very unusual to have two sides that // both require tests; you'd expect one side to be simplified // away.) - let (match_pair_index, match_pair) = - candidate.match_pairs.iter().enumerate().find(|&(_, mp)| mp.place == *test_place)?; + let (match_pair_index, match_pair) = candidate + .match_pairs + .iter() + .enumerate() + .find(|&(_, mp)| mp.place == Some(test_place))?; let fully_matched; let ret = match (&test.kind, &match_pair.test_case) { @@ -521,7 +522,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { candidate .match_pairs .iter() - .any(|mp| mp.place == *test_place && is_covering_range(&mp.test_case)) + .any(|mp| mp.place == Some(test_place) && is_covering_range(&mp.test_case)) }; if sorted_candidates .get(&TestBranch::Failure) diff --git a/compiler/rustc_mir_build/src/build/matches/util.rs b/compiler/rustc_mir_build/src/build/matches/util.rs index 8e0624a174e8..bc6f0a26582c 100644 --- a/compiler/rustc_mir_build/src/build/matches/util.rs +++ b/compiler/rustc_mir_build/src/build/matches/util.rs @@ -119,6 +119,7 @@ impl<'pat, 'tcx> MatchPair<'pat, 'tcx> { place_builder = place_builder.project(ProjectionElem::OpaqueCast(pattern.ty)); } + let place = place_builder.try_to_place(cx); let default_irrefutable = || TestCase::Irrefutable { binding: None, ascription: None }; let mut subpairs = Vec::new(); let test_case = match pattern.kind { @@ -143,13 +144,13 @@ impl<'pat, 'tcx> MatchPair<'pat, 'tcx> { .. } => { // Apply the type ascription to the value at `match_pair.place` - let ascription = place_builder.try_to_place(cx).map(|source| super::Ascription { + let ascription = place.map(|source| super::Ascription { annotation: annotation.clone(), source, variance, }); - subpairs.push(MatchPair::new(place_builder.clone(), subpattern, cx)); + subpairs.push(MatchPair::new(place_builder, subpattern, cx)); TestCase::Irrefutable { ascription, binding: None } } @@ -162,7 +163,7 @@ impl<'pat, 'tcx> MatchPair<'pat, 'tcx> { ref subpattern, is_primary: _, } => { - let binding = place_builder.try_to_place(cx).map(|source| super::Binding { + let binding = place.map(|source| super::Binding { span: pattern.span, source, var_id: var, @@ -171,14 +172,14 @@ impl<'pat, 'tcx> MatchPair<'pat, 'tcx> { if let Some(subpattern) = subpattern.as_ref() { // this is the `x @ P` case; have to keep matching against `P` now - subpairs.push(MatchPair::new(place_builder.clone(), subpattern, cx)); + subpairs.push(MatchPair::new(place_builder, subpattern, cx)); } TestCase::Irrefutable { ascription: None, binding } } PatKind::InlineConstant { subpattern: ref pattern, def, .. } => { // Apply a type ascription for the inline constant to the value at `match_pair.place` - let ascription = place_builder.try_to_place(cx).map(|source| { + let ascription = place.map(|source| { let span = pattern.span; let parent_id = cx.tcx.typeck_root_def_id(cx.def_id.to_def_id()); let args = ty::InlineConstArgs::new( @@ -204,7 +205,7 @@ impl<'pat, 'tcx> MatchPair<'pat, 'tcx> { super::Ascription { annotation, source, variance: ty::Contravariant } }); - subpairs.push(MatchPair::new(place_builder.clone(), pattern, cx)); + subpairs.push(MatchPair::new(place_builder, pattern, cx)); TestCase::Irrefutable { ascription, binding: None } } @@ -226,7 +227,7 @@ impl<'pat, 'tcx> MatchPair<'pat, 'tcx> { } PatKind::Variant { adt_def, variant_index, args, ref subpatterns } => { - let downcast_place = place_builder.clone().downcast(adt_def, variant_index); // `(x as Variant)` + let downcast_place = place_builder.downcast(adt_def, variant_index); // `(x as Variant)` subpairs = cx.field_match_pairs(downcast_place, subpatterns); let irrefutable = adt_def.variants().iter_enumerated().all(|(i, v)| { @@ -248,13 +249,12 @@ impl<'pat, 'tcx> MatchPair<'pat, 'tcx> { } PatKind::Leaf { ref subpatterns } => { - subpairs = cx.field_match_pairs(place_builder.clone(), subpatterns); + subpairs = cx.field_match_pairs(place_builder, subpatterns); default_irrefutable() } PatKind::Deref { ref subpattern } => { - let place_builder = place_builder.clone().deref(); - subpairs.push(MatchPair::new(place_builder, subpattern, cx)); + subpairs.push(MatchPair::new(place_builder.deref(), subpattern, cx)); default_irrefutable() } @@ -265,7 +265,7 @@ impl<'pat, 'tcx> MatchPair<'pat, 'tcx> { } }; - MatchPair { place: place_builder, test_case, subpairs, pattern } + MatchPair { place, test_case, subpairs, pattern } } } @@ -311,8 +311,8 @@ impl<'a, 'b, 'tcx> FakeBorrowCollector<'a, 'b, 'tcx> { } } else { // Insert a Shallow borrow of any place that is switched on. - if let Some(resolved_place) = match_pair.place.try_to_place(self.cx) { - self.fake_borrows.insert(resolved_place); + if let Some(place) = match_pair.place { + self.fake_borrows.insert(place); } for subpair in &match_pair.subpairs { From 7764e8ace3b22dff544fe2722d238d060f13e55b 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: Sat, 23 Mar 2024 18:10:14 +0000 Subject: [PATCH 089/165] Port backtrace dylib-dep test to a ui test --- .../auxiliary/dylib-dep-helper-aux.rs | 17 +++ .../debuginfo/auxiliary/dylib-dep-helper.rs | 19 +++ tests/ui/debuginfo/backtrace-dylib-dep.rs | 114 ++++++++++++++++++ 3 files changed, 150 insertions(+) create mode 100644 tests/ui/debuginfo/auxiliary/dylib-dep-helper-aux.rs create mode 100644 tests/ui/debuginfo/auxiliary/dylib-dep-helper.rs create mode 100644 tests/ui/debuginfo/backtrace-dylib-dep.rs diff --git a/tests/ui/debuginfo/auxiliary/dylib-dep-helper-aux.rs b/tests/ui/debuginfo/auxiliary/dylib-dep-helper-aux.rs new file mode 100644 index 000000000000..d45e0bcd3b45 --- /dev/null +++ b/tests/ui/debuginfo/auxiliary/dylib-dep-helper-aux.rs @@ -0,0 +1,17 @@ +//@ compile-flags: -g -Cstrip=none -Cforce-frame-pointers=yes + +#[inline(never)] +pub fn callback(f: F) +where + F: FnOnce((&'static str, u32)), +{ + f((file!(), line!())) +} + +#[inline(always)] +pub fn callback_inlined(f: F) +where + F: FnOnce((&'static str, u32)), +{ + f((file!(), line!())) +} diff --git a/tests/ui/debuginfo/auxiliary/dylib-dep-helper.rs b/tests/ui/debuginfo/auxiliary/dylib-dep-helper.rs new file mode 100644 index 000000000000..565d8b65de05 --- /dev/null +++ b/tests/ui/debuginfo/auxiliary/dylib-dep-helper.rs @@ -0,0 +1,19 @@ +//@ compile-flags: -g -Cstrip=none -Cforce-frame-pointers=yes + +#![crate_type = "cdylib"] +#![crate_type = "rlib"] + +#![allow(improper_ctypes_definitions)] + +type Pos = (&'static str, u32); + +macro_rules! pos { + () => { + (file!(), line!()) + }; +} + +#[no_mangle] +pub extern "C" fn foo(outer: Pos, inner: fn(Pos, Pos)) { + inner(outer, pos!()); +} diff --git a/tests/ui/debuginfo/backtrace-dylib-dep.rs b/tests/ui/debuginfo/backtrace-dylib-dep.rs new file mode 100644 index 000000000000..e2414073edef --- /dev/null +++ b/tests/ui/debuginfo/backtrace-dylib-dep.rs @@ -0,0 +1,114 @@ +// Check that backtrace info is correctly generated for dynamic libraries and is usable by a +// rust binary. +// Part of porting some backtrace tests to rustc: . +// Original test: +// +// ignore-tidy-linelength +//@ ignore-android FIXME #17520 +//@ ignore-fuchsia Backtraces not symbolized +//@ ignore-musl musl doesn't support dynamic libraries (at least when the original test was written). +//@ needs-unwind +//@ compile-flags: -g -Copt-level=0 -Cstrip=none -Cforce-frame-pointers=yes +//@ aux-crate: dylib_dep_helper=dylib-dep-helper.rs +//@ aux-crate: auxiliary=dylib-dep-helper-aux.rs +//@ run-pass + +#![allow(improper_ctypes)] +#![allow(improper_ctypes_definitions)] + +extern crate dylib_dep_helper; +extern crate auxiliary; + +use std::backtrace::Backtrace; + +macro_rules! pos { + () => { + (file!(), line!()) + }; +} + +macro_rules! check { + ($($pos:expr),*) => ({ + verify(&[$($pos,)* pos!()]); + }) +} + +fn verify(filelines: &[Pos]) { + let trace = Backtrace::capture(); + eprintln!("-----------------------------------"); + eprintln!("looking for:"); + for (file, line) in filelines.iter().rev() { + eprintln!("\t{file}:{line}"); + } + eprintln!("found:\n{trace:#?}"); + let mut iter = filelines.iter().rev(); + // FIXME(jieyouxu): use proper `BacktraceFrame` accessors when it becomes available. Right now, + // this depends on the debug format of `Backtrace` which is of course fragile. + let backtrace = format!("{:#?}", trace); + while let Some((file, line)) = iter.next() { + // FIXME(jieyouxu): make this test use proper accessors on `BacktraceFrames` once it has + // them. + assert!(backtrace.contains(file), "expected backtrace to contain {}", file); + assert!(backtrace.contains(&line.to_string()), "expected backtrace to contain {}", line); + } +} + +type Pos = (&'static str, u32); + +extern "C" { + #[link_name = "foo"] + fn foo(p: Pos, cb: fn(Pos, Pos)); +} + +fn main() { + std::env::set_var("RUST_BACKTRACE", "1"); + + unsafe { + foo(pos!(), |a, b| { + check!(a, b) + }) + } + + outer(pos!()); +} + +#[inline(never)] +fn outer(main_pos: Pos) { + inner(main_pos, pos!()); + inner_inlined(main_pos, pos!()); +} + +#[inline(never)] +fn inner(main_pos: Pos, outer_pos: Pos) { + check!(main_pos, outer_pos); + check!(main_pos, outer_pos); + let inner_pos = pos!(); auxiliary::callback(|aux_pos| { + check!(main_pos, outer_pos, inner_pos, aux_pos); + }); + let inner_pos = pos!(); auxiliary::callback_inlined(|aux_pos| { + check!(main_pos, outer_pos, inner_pos, aux_pos); + }); +} + +#[inline(always)] +fn inner_inlined(main_pos: Pos, outer_pos: Pos) { + check!(main_pos, outer_pos); + check!(main_pos, outer_pos); + + #[inline(always)] + fn inner_further_inlined(main_pos: Pos, outer_pos: Pos, inner_pos: Pos) { + check!(main_pos, outer_pos, inner_pos); + } + inner_further_inlined(main_pos, outer_pos, pos!()); + + let inner_pos = pos!(); auxiliary::callback(|aux_pos| { + check!(main_pos, outer_pos, inner_pos, aux_pos); + }); + let inner_pos = pos!(); auxiliary::callback_inlined(|aux_pos| { + check!(main_pos, outer_pos, inner_pos, aux_pos); + }); + + // this tests a distinction between two independent calls to the inlined function. + // (un)fortunately, LLVM somehow merges two consecutive such calls into one node. + inner_further_inlined(main_pos, outer_pos, pos!()); +} From bf7a74507777ad81ae83e76da19952185aee35e8 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 26 Mar 2024 14:11:51 -0400 Subject: [PATCH 090/165] Inherited -> TypeckRootCtxt --- compiler/rustc_hir_typeck/src/_match.rs | 2 +- compiler/rustc_hir_typeck/src/closure.rs | 2 +- compiler/rustc_hir_typeck/src/fallback.rs | 1 - compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs | 2 +- compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs | 14 +++++++------- compiler/rustc_hir_typeck/src/gather_locals.rs | 3 +-- compiler/rustc_hir_typeck/src/lib.rs | 10 +++++----- compiler/rustc_hir_typeck/src/pat.rs | 5 ++--- .../src/{inherited.rs => typeck_root_ctxt.rs} | 14 ++++++++------ .../src/methods/unnecessary_to_owned.rs | 6 +++--- .../clippy/clippy_lints/src/transmute/utils.rs | 6 +++--- 11 files changed, 32 insertions(+), 33 deletions(-) rename compiler/rustc_hir_typeck/src/{inherited.rs => typeck_root_ctxt.rs} (94%) diff --git a/compiler/rustc_hir_typeck/src/_match.rs b/compiler/rustc_hir_typeck/src/_match.rs index 9b7db9e4c8e6..e42db342f14e 100644 --- a/compiler/rustc_hir_typeck/src/_match.rs +++ b/compiler/rustc_hir_typeck/src/_match.rs @@ -243,7 +243,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let can_coerce_to_return_ty = match self.ret_coercion.as_ref() { Some(ret_coercion) => { let ret_ty = ret_coercion.borrow().expected_ty(); - let ret_ty = self.inh.infcx.shallow_resolve(ret_ty); + let ret_ty = self.infcx.shallow_resolve(ret_ty); self.can_coerce(arm_ty, ret_ty) && prior_arm.map_or(true, |(_, ty, _)| self.can_coerce(ty, ret_ty)) // The match arms need to unify for the case of `impl Trait`. diff --git a/compiler/rustc_hir_typeck/src/closure.rs b/compiler/rustc_hir_typeck/src/closure.rs index 40555bf14eb2..36af53940156 100644 --- a/compiler/rustc_hir_typeck/src/closure.rs +++ b/compiler/rustc_hir_typeck/src/closure.rs @@ -848,7 +848,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { bound_vars, ); - let c_result = self.inh.infcx.canonicalize_response(result); + let c_result = self.infcx.canonicalize_response(result); self.typeck_results.borrow_mut().user_provided_sigs.insert(expr_def_id, c_result); // Normalize only after registering in `user_provided_sigs`. diff --git a/compiler/rustc_hir_typeck/src/fallback.rs b/compiler/rustc_hir_typeck/src/fallback.rs index 140618e97cca..fe1e4e74973f 100644 --- a/compiler/rustc_hir_typeck/src/fallback.rs +++ b/compiler/rustc_hir_typeck/src/fallback.rs @@ -347,7 +347,6 @@ impl<'tcx> FnCtxt<'_, 'tcx> { .any(|n| roots_reachable_from_non_diverging.visited(n)); let infer_var_infos: UnordBag<_> = self - .inh .infer_var_info .borrow() .items() diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index 8e0be7c7163d..011607bacc6c 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -526,7 +526,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { pub(in super::super) fn resolve_rvalue_scopes(&self, def_id: DefId) { let scope_tree = self.tcx.region_scope_tree(def_id); let rvalue_scopes = { rvalue_scopes::resolve_rvalue_scopes(self, scope_tree, def_id) }; - let mut typeck_results = self.inh.typeck_results.borrow_mut(); + let mut typeck_results = self.typeck_results.borrow_mut(); typeck_results.rvalue_scopes = rvalue_scopes; } diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs index efa2862177e1..74f27cfebbd2 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs @@ -7,7 +7,7 @@ mod suggestions; use crate::coercion::DynamicCoerceMany; use crate::fallback::DivergingFallbackBehavior; use crate::fn_ctxt::checks::DivergingBlockBehavior; -use crate::{CoroutineTypes, Diverges, EnclosingBreakables, Inherited}; +use crate::{CoroutineTypes, Diverges, EnclosingBreakables, TypeckRootCtxt}; use hir::def_id::CRATE_DEF_ID; use rustc_errors::{DiagCtxt, ErrorGuaranteed}; use rustc_hir as hir; @@ -108,7 +108,7 @@ pub struct FnCtxt<'a, 'tcx> { pub(super) enclosing_breakables: RefCell>, - pub(super) inh: &'a Inherited<'tcx>, + pub(super) root_ctxt: &'a TypeckRootCtxt<'tcx>, pub(super) fallback_has_occurred: Cell, @@ -118,12 +118,12 @@ pub struct FnCtxt<'a, 'tcx> { impl<'a, 'tcx> FnCtxt<'a, 'tcx> { pub fn new( - inh: &'a Inherited<'tcx>, + root_ctxt: &'a TypeckRootCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>, body_id: LocalDefId, ) -> FnCtxt<'a, 'tcx> { let (diverging_fallback_behavior, diverging_block_behavior) = - parse_never_type_options_attr(inh.tcx); + parse_never_type_options_attr(root_ctxt.tcx); FnCtxt { body_id, param_env, @@ -137,7 +137,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { stack: Vec::new(), by_id: Default::default(), }), - inh, + root_ctxt, fallback_has_occurred: Cell::new(false), diverging_fallback_behavior, diverging_block_behavior, @@ -206,9 +206,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } impl<'a, 'tcx> Deref for FnCtxt<'a, 'tcx> { - type Target = Inherited<'tcx>; + type Target = TypeckRootCtxt<'tcx>; fn deref(&self) -> &Self::Target { - self.inh + self.root_ctxt } } diff --git a/compiler/rustc_hir_typeck/src/gather_locals.rs b/compiler/rustc_hir_typeck/src/gather_locals.rs index 1fa799dcec7f..be5cd6e9d487 100644 --- a/compiler/rustc_hir_typeck/src/gather_locals.rs +++ b/compiler/rustc_hir_typeck/src/gather_locals.rs @@ -95,8 +95,7 @@ impl<'a, 'tcx> GatherLocalsVisitor<'a, 'tcx> { Some(ref ty) => { let o_ty = self.fcx.lower_ty(ty); - let c_ty = - self.fcx.inh.infcx.canonicalize_user_type_annotation(UserType::Ty(o_ty.raw)); + let c_ty = self.fcx.infcx.canonicalize_user_type_annotation(UserType::Ty(o_ty.raw)); debug!("visit_local: ty.hir_id={:?} o_ty={:?} c_ty={:?}", ty.hir_id, o_ty, c_ty); self.fcx .typeck_results diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs index 0b67b37df29d..3a16884d5c76 100644 --- a/compiler/rustc_hir_typeck/src/lib.rs +++ b/compiler/rustc_hir_typeck/src/lib.rs @@ -31,7 +31,6 @@ pub mod expr_use_visitor; mod fallback; mod fn_ctxt; mod gather_locals; -mod inherited; mod intrinsicck; mod mem_categorization; mod method; @@ -39,11 +38,12 @@ mod op; mod pat; mod place_op; mod rvalue_scopes; +mod typeck_root_ctxt; mod upvar; mod writeback; pub use fn_ctxt::FnCtxt; -pub use inherited::Inherited; +pub use typeck_root_ctxt::TypeckRootCtxt; use crate::check::check_fn; use crate::coercion::DynamicCoerceMany; @@ -170,11 +170,11 @@ fn typeck_with_fallback<'tcx>( let param_env = tcx.param_env(def_id); - let inh = Inherited::new(tcx, def_id); + let root_ctxt = TypeckRootCtxt::new(tcx, def_id); if let Some(inspector) = inspector { - inh.infcx.attach_obligation_inspector(inspector); + root_ctxt.infcx.attach_obligation_inspector(inspector); } - let mut fcx = FnCtxt::new(&inh, param_env, def_id); + let mut fcx = FnCtxt::new(&root_ctxt, param_env, def_id); if let Some(hir::FnSig { header, decl, .. }) = fn_sig { let fn_sig = if decl.output.get_infer_ret_ty().is_some() { diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index 4dc60f7c6da1..66290b52bf52 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -388,8 +388,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if !pat_adjustments.is_empty() { debug!("default binding mode is now {:?}", def_bm); - self.inh - .typeck_results + self.typeck_results .borrow_mut() .pat_adjustments_mut() .insert(pat.hir_id, pat_adjustments); @@ -614,7 +613,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { _ => BindingMode::convert(ba), }; // ...and store it in a side table: - self.inh.typeck_results.borrow_mut().pat_binding_modes_mut().insert(pat.hir_id, bm); + self.typeck_results.borrow_mut().pat_binding_modes_mut().insert(pat.hir_id, bm); debug!("check_pat_ident: pat.hir_id={:?} bm={:?}", pat.hir_id, bm); diff --git a/compiler/rustc_hir_typeck/src/inherited.rs b/compiler/rustc_hir_typeck/src/typeck_root_ctxt.rs similarity index 94% rename from compiler/rustc_hir_typeck/src/inherited.rs rename to compiler/rustc_hir_typeck/src/typeck_root_ctxt.rs index b0950ed28008..e493e6a0a7ed 100644 --- a/compiler/rustc_hir_typeck/src/inherited.rs +++ b/compiler/rustc_hir_typeck/src/typeck_root_ctxt.rs @@ -16,7 +16,8 @@ use rustc_trait_selection::traits::{self, PredicateObligation, TraitEngine, Trai use std::cell::RefCell; use std::ops::Deref; -/// Closures defined within the function. For example: +// Data shared between a "typeck root" and its nested bodies, +/// e.g. closures defined within the function. For example: /// ```ignore (illustrative) /// fn foo() { /// bar(move|| { ... }) @@ -24,8 +25,9 @@ use std::ops::Deref; /// ``` /// Here, the function `foo()` and the closure passed to /// `bar()` will each have their own `FnCtxt`, but they will -/// share the inherited fields. -pub struct Inherited<'tcx> { +/// share the inference context, will process obligations together, +/// can access each other's local types (scoping permitted), etc. +pub struct TypeckRootCtxt<'tcx> { pub(super) infcx: InferCtxt<'tcx>, pub(super) typeck_results: RefCell>, @@ -65,14 +67,14 @@ pub struct Inherited<'tcx> { pub(super) infer_var_info: RefCell>, } -impl<'tcx> Deref for Inherited<'tcx> { +impl<'tcx> Deref for TypeckRootCtxt<'tcx> { type Target = InferCtxt<'tcx>; fn deref(&self) -> &Self::Target { &self.infcx } } -impl<'tcx> Inherited<'tcx> { +impl<'tcx> TypeckRootCtxt<'tcx> { pub fn new(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Self { let hir_owner = tcx.local_def_id_to_hir_id(def_id).owner; @@ -83,7 +85,7 @@ impl<'tcx> Inherited<'tcx> { .build(); let typeck_results = RefCell::new(ty::TypeckResults::new(hir_owner)); - Inherited { + TypeckRootCtxt { typeck_results, fulfillment_cx: RefCell::new(>::new(&infcx)), infcx, diff --git a/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs b/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs index bc5dd10cad0a..e58d47764279 100644 --- a/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs +++ b/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs @@ -12,7 +12,7 @@ use rustc_errors::Applicability; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::DefId; use rustc_hir::{BorrowKind, Expr, ExprKind, ItemKind, LangItem, Node}; -use rustc_hir_typeck::{FnCtxt, Inherited}; +use rustc_hir_typeck::{FnCtxt, TypeckRootCtxt}; use rustc_infer::infer::TyCtxtInferExt; use rustc_lint::LateContext; use rustc_middle::mir::Mutability; @@ -438,8 +438,8 @@ fn can_change_type<'a>(cx: &LateContext<'a>, mut expr: &'a Expr<'a>, mut ty: Ty< Node::Item(item) => { if let ItemKind::Fn(_, _, body_id) = &item.kind && let output_ty = return_ty(cx, item.owner_id) - && let inherited = Inherited::new(cx.tcx, item.owner_id.def_id) - && let fn_ctxt = FnCtxt::new(&inherited, cx.param_env, item.owner_id.def_id) + && let root_ctxt = TypeckRootCtxt::new(cx.tcx, item.owner_id.def_id) + && let fn_ctxt = FnCtxt::new(&root_ctxt, cx.param_env, item.owner_id.def_id) && fn_ctxt.can_coerce(ty, output_ty) { if has_lifetime(output_ty) && has_lifetime(ty) { diff --git a/src/tools/clippy/clippy_lints/src/transmute/utils.rs b/src/tools/clippy/clippy_lints/src/transmute/utils.rs index 7a7bb9f9c94c..15f1890aa39e 100644 --- a/src/tools/clippy/clippy_lints/src/transmute/utils.rs +++ b/src/tools/clippy/clippy_lints/src/transmute/utils.rs @@ -1,6 +1,6 @@ use rustc_hir as hir; use rustc_hir::Expr; -use rustc_hir_typeck::{cast, FnCtxt, Inherited}; +use rustc_hir_typeck::{cast, FnCtxt, TypeckRootCtxt}; use rustc_lint::LateContext; use rustc_middle::ty::cast::CastKind; use rustc_middle::ty::Ty; @@ -34,8 +34,8 @@ pub(super) fn check_cast<'tcx>( let hir_id = e.hir_id; let local_def_id = hir_id.owner.def_id; - let inherited = Inherited::new(cx.tcx, local_def_id); - let fn_ctxt = FnCtxt::new(&inherited, cx.param_env, local_def_id); + let root_ctxt = TypeckRootCtxt::new(cx.tcx, local_def_id); + let fn_ctxt = FnCtxt::new(&root_ctxt, cx.param_env, local_def_id); if let Ok(check) = cast::CastCheck::new( &fn_ctxt, From 07d3806eb1a9dcfc6acdc54476c9cc2b7bbbad7b Mon Sep 17 00:00:00 2001 From: Alex van de Sandt Date: Tue, 26 Mar 2024 15:54:22 -0400 Subject: [PATCH 091/165] Implement `Vec::pop_if` --- library/alloc/src/lib.rs | 1 + library/alloc/src/vec/mod.rs | 25 +++++++++++++++++++++++++ library/alloc/tests/lib.rs | 1 + library/alloc/tests/vec.rs | 30 ++++++++++++++++++++++++++++++ 4 files changed, 57 insertions(+) diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs index 02d155aaf12f..97ad0dbd5ad5 100644 --- a/library/alloc/src/lib.rs +++ b/library/alloc/src/lib.rs @@ -169,6 +169,7 @@ #![feature(unicode_internals)] #![feature(unsize)] #![feature(utf8_chunks)] +#![feature(vec_pop_if)] // tidy-alphabetical-end // // Language features: diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index 94bed825bb2f..35789f526dbc 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -2058,6 +2058,31 @@ impl Vec { } } + /// Removes and returns the last element in a vector if the predicate + /// returns `true`, or [`None`] if the predicate returns false or the vector + /// is empty. + /// + /// # Examples + /// + /// ``` + /// #![feature(vec_pop_if)] + /// + /// let mut vec = vec![1, 2, 3, 4]; + /// let pred = |x: &mut i32| *x % 2 == 0; + /// + /// assert_eq!(vec.pop_if(pred), Some(4)); + /// assert_eq!(vec, [1, 2, 3]); + /// assert_eq!(vec.pop_if(pred), None); + /// ``` + #[unstable(feature = "vec_pop_if", issue = "122741")] + pub fn pop_if(&mut self, f: F) -> Option + where + F: FnOnce(&mut T) -> bool, + { + let last = self.last_mut()?; + if f(last) { self.pop() } else { None } + } + /// Moves all the elements of `other` into `self`, leaving `other` empty. /// /// # Panics diff --git a/library/alloc/tests/lib.rs b/library/alloc/tests/lib.rs index f58998fbd796..04709af5c0a0 100644 --- a/library/alloc/tests/lib.rs +++ b/library/alloc/tests/lib.rs @@ -43,6 +43,7 @@ #![feature(strict_provenance)] #![feature(drain_keep_rest)] #![feature(local_waker)] +#![feature(vec_pop_if)] #![allow(internal_features)] #![deny(fuzzy_provenance_casts)] #![deny(unsafe_op_in_unsafe_fn)] diff --git a/library/alloc/tests/vec.rs b/library/alloc/tests/vec.rs index f1f841fe190f..71d79893e01d 100644 --- a/library/alloc/tests/vec.rs +++ b/library/alloc/tests/vec.rs @@ -2644,6 +2644,36 @@ fn test_vec_from_array_mut_ref() { assert_eq!(Vec::from(&mut [1, 2, 3]), vec![1, 2, 3]); } +#[test] +fn test_pop_if() { + let mut v = vec![1, 2, 3, 4]; + let pred = |x: &mut i32| *x % 2 == 0; + + assert_eq!(v.pop_if(pred), Some(4)); + assert_eq!(v, [1, 2, 3]); + + assert_eq!(v.pop_if(pred), None); + assert_eq!(v, [1, 2, 3]); +} + +#[test] +fn test_pop_if_empty() { + let mut v = Vec::::new(); + assert_eq!(v.pop_if(|_| true), None); + assert!(v.is_empty()); +} + +#[test] +fn test_pop_if_mutates() { + let mut v = vec![1]; + let pred = |x: &mut i32| { + *x += 1; + false + }; + assert_eq!(v.pop_if(pred), None); + assert_eq!(v, [2]); +} + /// This assortment of tests, in combination with miri, verifies we handle UB on fishy arguments /// in the stdlib. Draining and extending the allocation are fairly well-tested earlier, but /// `vec.insert(usize::MAX, val)` once slipped by! From 1942f956a3d8c92fb33d6841b7410e65c33b60dd Mon Sep 17 00:00:00 2001 From: chloekek Date: Wed, 27 Mar 2024 01:17:33 +0100 Subject: [PATCH 092/165] rustdoc: Swap fields and variant documentations Previously, the documentation for a variant appeared after the documentation for each of its fields. This was inconsistent with structs and unions, and made little sense on its own; fields are subordinate to variants and should therefore appear later in the documentation. --- src/librustdoc/html/render/print_item.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index 5d4f1acc4b18..fbb521a6188a 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -1728,6 +1728,8 @@ fn item_variants( } w.write_str(""); + write!(w, "{}", document(cx, variant, Some(it), HeadingOffset::H4)); + let heading_and_fields = match &variant_data.kind { clean::VariantKind::Struct(s) => { // If there is no field to display, no need to add the heading. @@ -1789,8 +1791,6 @@ fn item_variants( } w.write_str(""); } - - write!(w, "{}", document(cx, variant, Some(it), HeadingOffset::H4)); } write!(w, ""); } From 0cd57725f9d624aed3cdaa3852a1f80f550ae275 Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Tue, 26 Mar 2024 21:38:28 -0400 Subject: [PATCH 093/165] Update `RwLock` deadlock example to not use shadowing Tweak variable names in the deadlock example to remove any potential confusion that the behavior is somehow shadowing-related. --- library/std/src/sync/rwlock.rs | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/library/std/src/sync/rwlock.rs b/library/std/src/sync/rwlock.rs index d648cd089943..e0a8a7603d71 100644 --- a/library/std/src/sync/rwlock.rs +++ b/library/std/src/sync/rwlock.rs @@ -31,13 +31,14 @@ use crate::sys::sync as sys; ///

Potential deadlock example /// /// ```text -/// // Thread 1 | // Thread 2 -/// let _rg = lock.read(); | -/// | // will block -/// | let _wg = lock.write(); -/// // may deadlock | -/// let _rg = lock.read(); | +/// // Thread 1 | // Thread 2 +/// let _rg1 = lock.read(); | +/// | // will block +/// | let _wg = lock.write(); +/// // may deadlock | +/// let _rg2 = lock.read(); | /// ``` +/// ///
/// /// The type parameter `T` represents the data that this lock protects. It is From 9936a399dfd85b7ed07f948d602f332e5258f2c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Fri, 25 Aug 2023 17:26:24 +0200 Subject: [PATCH 094/165] Add a `CurrentGcx` type to let the deadlock handler access `TyCtxt` --- compiler/rustc_interface/src/interface.rs | 13 ++++-- compiler/rustc_interface/src/passes.rs | 1 + compiler/rustc_interface/src/util.rs | 33 +++++++++----- compiler/rustc_middle/src/ty/context.rs | 53 ++++++++++++++++++++++- compiler/rustc_middle/src/ty/mod.rs | 4 +- 5 files changed, 88 insertions(+), 16 deletions(-) diff --git a/compiler/rustc_interface/src/interface.rs b/compiler/rustc_interface/src/interface.rs index 656c7ffae193..da2fb490a36f 100644 --- a/compiler/rustc_interface/src/interface.rs +++ b/compiler/rustc_interface/src/interface.rs @@ -10,7 +10,9 @@ use rustc_data_structures::sync::Lrc; use rustc_errors::registry::Registry; use rustc_errors::{DiagCtxt, ErrorGuaranteed}; use rustc_lint::LintStore; + use rustc_middle::ty; +use rustc_middle::ty::CurrentGcx; use rustc_middle::util::Providers; use rustc_parse::maybe_new_parser_from_source_str; use rustc_query_impl::QueryCtxt; @@ -39,6 +41,7 @@ pub struct Compiler { pub sess: Session, pub codegen_backend: Box, pub(crate) override_queries: Option, + pub(crate) current_gcx: CurrentGcx, } /// Converts strings provided as `--cfg [cfgspec]` into a `Cfg`. @@ -336,7 +339,7 @@ pub fn run_compiler(config: Config, f: impl FnOnce(&Compiler) -> R + Se util::run_in_thread_pool_with_globals( config.opts.edition, config.opts.unstable_opts.threads, - || { + |current_gcx| { crate::callbacks::setup_callbacks(); let early_dcx = EarlyDiagCtxt::new(config.opts.error_format); @@ -430,8 +433,12 @@ pub fn run_compiler(config: Config, f: impl FnOnce(&Compiler) -> R + Se } sess.lint_store = Some(Lrc::new(lint_store)); - let compiler = - Compiler { sess, codegen_backend, override_queries: config.override_queries }; + let compiler = Compiler { + sess, + codegen_backend, + override_queries: config.override_queries, + current_gcx, + }; rustc_span::set_source_map(compiler.sess.psess.clone_source_map(), move || { // There are two paths out of `f`. diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index 4b4c1d6cf672..d763a12f816b 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -680,6 +680,7 @@ pub fn create_global_ctxt<'tcx>( incremental, ), providers.hooks, + compiler.current_gcx.clone(), ) }) }) diff --git a/compiler/rustc_interface/src/util.rs b/compiler/rustc_interface/src/util.rs index d09f8d7d7cf7..d0f04fccc481 100644 --- a/compiler/rustc_interface/src/util.rs +++ b/compiler/rustc_interface/src/util.rs @@ -5,6 +5,7 @@ use rustc_codegen_ssa::traits::CodegenBackend; #[cfg(parallel_compiler)] use rustc_data_structures::sync; use rustc_metadata::{load_symbol_from_dylib, DylibError}; +use rustc_middle::ty::CurrentGcx; use rustc_parse::validate_attr; use rustc_session as session; use rustc_session::config::{Cfg, OutFileName, OutputFilenames, OutputTypes}; @@ -64,7 +65,7 @@ fn init_stack_size() -> usize { }) } -pub(crate) fn run_in_thread_with_globals R + Send, R: Send>( +pub(crate) fn run_in_thread_with_globals R + Send, R: Send>( edition: Edition, f: F, ) -> R { @@ -82,7 +83,9 @@ pub(crate) fn run_in_thread_with_globals R + Send, R: Send>( // `unwrap` is ok here because `spawn_scoped` only panics if the thread // name contains null bytes. let r = builder - .spawn_scoped(s, move || rustc_span::create_session_globals_then(edition, f)) + .spawn_scoped(s, move || { + rustc_span::create_session_globals_then(edition, || f(CurrentGcx::new())) + }) .unwrap() .join(); @@ -94,7 +97,7 @@ pub(crate) fn run_in_thread_with_globals R + Send, R: Send>( } #[cfg(not(parallel_compiler))] -pub(crate) fn run_in_thread_pool_with_globals R + Send, R: Send>( +pub(crate) fn run_in_thread_pool_with_globals R + Send, R: Send>( edition: Edition, _threads: usize, f: F, @@ -103,7 +106,7 @@ pub(crate) fn run_in_thread_pool_with_globals R + Send, R: Send>( } #[cfg(parallel_compiler)] -pub(crate) fn run_in_thread_pool_with_globals R + Send, R: Send>( +pub(crate) fn run_in_thread_pool_with_globals R + Send, R: Send>( edition: Edition, threads: usize, f: F, @@ -117,24 +120,34 @@ pub(crate) fn run_in_thread_pool_with_globals R + Send, R: Send>( let registry = sync::Registry::new(std::num::NonZero::new(threads).unwrap()); if !sync::is_dyn_thread_safe() { - return run_in_thread_with_globals(edition, || { + return run_in_thread_with_globals(edition, |current_gcx| { // Register the thread for use with the `WorkerLocal` type. registry.register(); - f() + f(current_gcx) }); } + let current_gcx = FromDyn::from(CurrentGcx::new()); + let current_gcx2 = current_gcx.clone(); + let builder = rayon::ThreadPoolBuilder::new() .thread_name(|_| "rustc".to_string()) .acquire_thread_handler(jobserver::acquire_thread) .release_thread_handler(jobserver::release_thread) .num_threads(threads) - .deadlock_handler(|| { + .deadlock_handler(move || { // On deadlock, creates a new thread and forwards information in thread // locals to it. The new thread runs the deadlock handler. - let query_map = - FromDyn::from(tls::with(|tcx| QueryCtxt::new(tcx).collect_active_jobs())); + + // Get a `GlobalCtxt` reference from `CurrentGcx` as we cannot rely on having a + // `TyCtxt` TLS reference here. + let query_map = current_gcx2.access(|gcx| { + tls::enter_context(&tls::ImplicitCtxt::new(gcx), || { + tls::with(|tcx| QueryCtxt::new(tcx).collect_active_jobs()) + }) + }); + let query_map = FromDyn::from(query_map); let registry = rayon_core::Registry::current(); thread::Builder::new() .name("rustc query cycle handler".to_string()) @@ -171,7 +184,7 @@ pub(crate) fn run_in_thread_pool_with_globals R + Send, R: Send>( }) }, // Run `f` on the first thread in the thread pool. - move |pool: &rayon::ThreadPool| pool.install(f), + move |pool: &rayon::ThreadPool| pool.install(|| f(current_gcx.into_inner())), ) .unwrap() }) diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 3393f4448438..188cb50849dc 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -32,6 +32,7 @@ use crate::ty::{ }; 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::intern::Interned; @@ -39,7 +40,7 @@ use rustc_data_structures::profiling::SelfProfilerRef; use rustc_data_structures::sharded::{IntoPointer, ShardedHashMap}; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::steal::Steal; -use rustc_data_structures::sync::{self, FreezeReadGuard, Lock, Lrc, WorkerLocal}; +use rustc_data_structures::sync::{self, FreezeReadGuard, Lock, Lrc, RwLock, WorkerLocal}; #[cfg(parallel_compiler)] use rustc_data_structures::sync::{DynSend, DynSync}; use rustc_data_structures::unord::UnordSet; @@ -723,6 +724,8 @@ pub struct GlobalCtxt<'tcx> { /// Stores memory for globals (statics/consts). pub(crate) alloc_map: Lock>, + + current_gcx: CurrentGcx, } impl<'tcx> GlobalCtxt<'tcx> { @@ -733,6 +736,19 @@ impl<'tcx> GlobalCtxt<'tcx> { F: FnOnce(TyCtxt<'tcx>) -> R, { let icx = tls::ImplicitCtxt::new(self); + + // Reset `current_gcx` to `None` when we exit. + let _on_drop = defer(move || { + *self.current_gcx.value.write() = None; + }); + + // Set this `GlobalCtxt` as the current one. + { + let mut guard = self.current_gcx.value.write(); + assert!(guard.is_none(), "no `GlobalCtxt` is currently set"); + *guard = Some(self as *const _ as *const ()); + } + tls::enter_context(&icx, || f(icx.tcx)) } @@ -741,6 +757,39 @@ impl<'tcx> GlobalCtxt<'tcx> { } } +/// This is used to get a reference to a `GlobalCtxt` if one is available. +/// +/// This is needed to allow the deadlock handler access to `GlobalCtxt` to look for query cycles. +/// It cannot use the `TLV` global because that's only guaranteed to be defined on the thread +/// creating the `GlobalCtxt`. Other threads have access to the `TLV` only inside Rayon jobs, but +/// the deadlock handler is not called inside such a job. +#[derive(Clone)] +pub struct CurrentGcx { + /// This stores a pointer to a `GlobalCtxt`. This is set to `Some` inside `GlobalCtxt::enter` + /// and reset to `None` when that function returns or unwinds. + value: Lrc>>, +} + +#[cfg(parallel_compiler)] +unsafe impl DynSend for CurrentGcx {} +#[cfg(parallel_compiler)] +unsafe impl DynSync for CurrentGcx {} + +impl CurrentGcx { + pub fn new() -> Self { + Self { value: Lrc::new(RwLock::new(None)) } + } + + pub fn access(&self, f: impl for<'tcx> FnOnce(&'tcx GlobalCtxt<'tcx>) -> R) -> R { + let read_guard = self.value.read(); + let gcx: *const GlobalCtxt<'_> = read_guard.unwrap() as *const _; + // SAFETY: We hold the read lock for the `GlobalCtxt` pointer. That prevents + // `GlobalCtxt::enter` from returning as it would first acquire the write lock. + // This ensures the `GlobalCtxt` is live during `f`. + f(unsafe { &*gcx }) + } +} + impl<'tcx> TyCtxt<'tcx> { /// Expects a body and returns its codegen attributes. /// @@ -859,6 +908,7 @@ impl<'tcx> TyCtxt<'tcx> { query_kinds: &'tcx [DepKindStruct<'tcx>], query_system: QuerySystem<'tcx>, hooks: crate::hooks::Providers, + current_gcx: CurrentGcx, ) -> GlobalCtxt<'tcx> { let data_layout = s.target.parse_data_layout().unwrap_or_else(|err| { s.dcx().emit_fatal(err); @@ -893,6 +943,7 @@ impl<'tcx> TyCtxt<'tcx> { canonical_param_env_cache: Default::default(), data_layout, alloc_map: Lock::new(interpret::AllocMap::new()), + current_gcx, } } diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 6ce53ccc8cd7..616887419204 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -86,8 +86,8 @@ pub use self::consts::{ Const, ConstData, ConstInt, ConstKind, Expr, ScalarInt, UnevaluatedConst, ValTree, }; pub use self::context::{ - tls, CtxtInterners, DeducedParamAttrs, Feed, FreeRegionInfo, GlobalCtxt, Lift, TyCtxt, - TyCtxtFeed, + tls, CtxtInterners, CurrentGcx, DeducedParamAttrs, Feed, FreeRegionInfo, GlobalCtxt, Lift, + TyCtxt, TyCtxtFeed, }; pub use self::instance::{Instance, InstanceDef, ShortInstance, UnusedGenericParams}; pub use self::list::List; From 09ec683ae72086278db2ba8fa0d6168814b51b93 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Wed, 27 Mar 2024 10:57:13 +0000 Subject: [PATCH 095/165] Emit DW_AT_frame_base debuginfo attribute --- src/debuginfo/mod.rs | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/src/debuginfo/mod.rs b/src/debuginfo/mod.rs index 2d9c2ecdbc2b..56307aa3bb93 100644 --- a/src/debuginfo/mod.rs +++ b/src/debuginfo/mod.rs @@ -8,10 +8,10 @@ mod unwind; use cranelift_codegen::ir::Endianness; use cranelift_codegen::isa::TargetIsa; use gimli::write::{ - Address, AttributeValue, DwarfUnit, FileId, LineProgram, LineString, Range, RangeList, - UnitEntryId, + Address, AttributeValue, DwarfUnit, Expression, FileId, LineProgram, LineString, Range, + RangeList, UnitEntryId, }; -use gimli::{Encoding, Format, LineEncoding, RunTimeEndian}; +use gimli::{AArch64, Encoding, Format, LineEncoding, Register, RiscV, RunTimeEndian, X86_64}; use indexmap::IndexSet; use rustc_session::Session; @@ -28,6 +28,7 @@ pub(crate) struct DebugContext { dwarf: DwarfUnit, unit_range_list: RangeList, + stack_pointer_register: Register, should_remap_filepaths: bool, } @@ -60,6 +61,15 @@ impl DebugContext { Endianness::Big => RunTimeEndian::Big, }; + let stack_pointer_register = match isa.triple().architecture { + target_lexicon::Architecture::Aarch64(_) => AArch64::SP, + target_lexicon::Architecture::Riscv64(_) => RiscV::SP, + target_lexicon::Architecture::X86_64 | target_lexicon::Architecture::X86_64h => { + X86_64::RSP + } + _ => Register(u16::MAX), + }; + let mut dwarf = DwarfUnit::new(encoding); let should_remap_filepaths = tcx.sess.should_prefer_remapped_for_codegen(); @@ -111,6 +121,7 @@ impl DebugContext { endian, dwarf, unit_range_list: RangeList(Vec::new()), + stack_pointer_register, should_remap_filepaths, } } @@ -135,6 +146,10 @@ impl DebugContext { entry.set(gimli::DW_AT_name, AttributeValue::StringRef(name_id)); entry.set(gimli::DW_AT_linkage_name, AttributeValue::StringRef(name_id)); + let mut frame_base_expr = Expression::new(); + frame_base_expr.op_reg(self.stack_pointer_register); + entry.set(gimli::DW_AT_frame_base, AttributeValue::Exprloc(frame_base_expr)); + entry.set(gimli::DW_AT_decl_file, AttributeValue::FileIndex(Some(file_id))); entry.set(gimli::DW_AT_decl_line, AttributeValue::Udata(line)); entry.set(gimli::DW_AT_decl_column, AttributeValue::Udata(column)); From 804c0476575e891aa47131d67cbb3b6c21682abf Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Wed, 27 Mar 2024 10:56:11 +0000 Subject: [PATCH 096/165] Load missing type of impl associated constant from trait definition --- compiler/rustc_hir_typeck/src/lib.rs | 18 +++++++++--- tests/ui/consts/missing_assoc_const_type.rs | 28 +++++++++++++++++++ .../ui/consts/missing_assoc_const_type.stderr | 8 ++++++ tests/ui/consts/missing_assoc_const_type2.rs | 21 ++++++++++++++ .../consts/missing_assoc_const_type2.stderr | 8 ++++++ .../typeck_type_placeholder_item.stderr | 23 +++++++-------- 6 files changed, 89 insertions(+), 17 deletions(-) create mode 100644 tests/ui/consts/missing_assoc_const_type.rs create mode 100644 tests/ui/consts/missing_assoc_const_type.stderr create mode 100644 tests/ui/consts/missing_assoc_const_type2.rs create mode 100644 tests/ui/consts/missing_assoc_const_type2.stderr diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs index 0b67b37df29d..f201bfddf4bb 100644 --- a/compiler/rustc_hir_typeck/src/lib.rs +++ b/compiler/rustc_hir_typeck/src/lib.rs @@ -192,10 +192,20 @@ fn typeck_with_fallback<'tcx>( check_fn(&mut fcx, fn_sig, None, decl, def_id, body, tcx.features().unsized_fn_params); } else { let expected_type = if let Some(&hir::Ty { kind: hir::TyKind::Infer, span, .. }) = body_ty { - Some(fcx.next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::TypeInference, - span, - })) + if let Some(item) = tcx.opt_associated_item(def_id.into()) + && let ty::AssocKind::Const = item.kind + && let ty::ImplContainer = item.container + && let Some(trait_item) = item.trait_item_def_id + { + let args = + tcx.impl_trait_ref(item.container_id(tcx)).unwrap().instantiate_identity().args; + Some(tcx.type_of(trait_item).instantiate(tcx, args)) + } else { + Some(fcx.next_ty_var(TypeVariableOrigin { + kind: TypeVariableOriginKind::TypeInference, + span, + })) + } } else if let Node::AnonConst(_) = node { match tcx.parent_hir_node(id) { Node::Ty(&hir::Ty { kind: hir::TyKind::Typeof(ref anon_const), .. }) diff --git a/tests/ui/consts/missing_assoc_const_type.rs b/tests/ui/consts/missing_assoc_const_type.rs new file mode 100644 index 000000000000..8d95e3dca633 --- /dev/null +++ b/tests/ui/consts/missing_assoc_const_type.rs @@ -0,0 +1,28 @@ +//! Test that we compute the right type for associated constants +//! of impls, even if the type is missing. We know it from the trait +//! declaration after all. + +trait Range { + const FIRST: u8; + const LAST: u8; +} + +struct TwoDigits; +impl Range for TwoDigits { + const FIRST: = 10; + //~^ ERROR: missing type for `const` item + const LAST: u8 = 99; +} + +const fn digits(x: u8) -> usize { + match x { + TwoDigits::FIRST..=TwoDigits::LAST => 0, + 0..=9 | 100..=255 => panic!(), + } +} + +const FOOMP: [(); { + digits(42) +}] = []; + +fn main() {} diff --git a/tests/ui/consts/missing_assoc_const_type.stderr b/tests/ui/consts/missing_assoc_const_type.stderr new file mode 100644 index 000000000000..28af1f0f321e --- /dev/null +++ b/tests/ui/consts/missing_assoc_const_type.stderr @@ -0,0 +1,8 @@ +error: missing type for `const` item + --> $DIR/missing_assoc_const_type.rs:12:17 + | +LL | const FIRST: = 10; + | ^ help: provide a type for the associated constant: `u8` + +error: aborting due to 1 previous error + diff --git a/tests/ui/consts/missing_assoc_const_type2.rs b/tests/ui/consts/missing_assoc_const_type2.rs new file mode 100644 index 000000000000..baf236700a39 --- /dev/null +++ b/tests/ui/consts/missing_assoc_const_type2.rs @@ -0,0 +1,21 @@ +//! Test that we compute the right type for associated constants +//! of impls, even if the type is missing. We know it from the trait +//! declaration after all. + +trait Range { + const FIRST: u8; + const LAST: u8; +} + +struct TwoDigits; +impl Range for TwoDigits { + const FIRST: = 10; + //~^ ERROR: missing type + const LAST: u8 = 99; +} + +const FOOMP: [(); { + TwoDigits::FIRST as usize +}] = [(); 10]; + +fn main() {} diff --git a/tests/ui/consts/missing_assoc_const_type2.stderr b/tests/ui/consts/missing_assoc_const_type2.stderr new file mode 100644 index 000000000000..1255ca2d102b --- /dev/null +++ b/tests/ui/consts/missing_assoc_const_type2.stderr @@ -0,0 +1,8 @@ +error: missing type for `const` item + --> $DIR/missing_assoc_const_type2.rs:12:17 + | +LL | const FIRST: = 10; + | ^ help: provide a type for the associated constant: `u8` + +error: aborting due to 1 previous error + diff --git a/tests/ui/typeck/typeck_type_placeholder_item.stderr b/tests/ui/typeck/typeck_type_placeholder_item.stderr index 8bcad56916aa..7977504dae1d 100644 --- a/tests/ui/typeck/typeck_type_placeholder_item.stderr +++ b/tests/ui/typeck/typeck_type_placeholder_item.stderr @@ -546,6 +546,15 @@ help: use type parameters instead LL | fn fn_test10(&self, _x : T) { } | +++ ~ +error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated constants + --> $DIR/typeck_type_placeholder_item.rs:194:14 + | +LL | const D: _ = 42; + | ^ + | | + | not allowed in type signatures + | help: replace with the correct type: `i32` + error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types --> $DIR/typeck_type_placeholder_item.rs:217:31 | @@ -574,19 +583,7 @@ error[E0121]: the placeholder `_` is not allowed within types on item signatures --> $DIR/typeck_type_placeholder_item.rs:209:14 | LL | const D: _ = 42; - | ^ - | | - | not allowed in type signatures - | help: replace with the correct type: `i32` - -error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated constants - --> $DIR/typeck_type_placeholder_item.rs:194:14 - | -LL | const D: _ = 42; - | ^ - | | - | not allowed in type signatures - | help: replace with the correct type: `i32` + | ^ not allowed in type signatures error[E0046]: not all trait items implemented, missing: `F` --> $DIR/typeck_type_placeholder_item.rs:200:1 From c76c269aa466b786d4ca3a78dae9cb84912406ed Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Wed, 27 Mar 2024 11:04:35 +0000 Subject: [PATCH 097/165] Reduce debuginfo divergence between cg_llvm and cg_clif --- src/debuginfo/mod.rs | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/debuginfo/mod.rs b/src/debuginfo/mod.rs index 56307aa3bb93..44ee2b822a9d 100644 --- a/src/debuginfo/mod.rs +++ b/src/debuginfo/mod.rs @@ -142,17 +142,25 @@ impl DebugContext { let entry_id = self.dwarf.unit.add(scope, gimli::DW_TAG_subprogram); let entry = self.dwarf.unit.get_mut(entry_id); let name_id = self.dwarf.strings.add(name); - // Gdb requires DW_AT_name. Otherwise the DW_TAG_subprogram is skipped. - entry.set(gimli::DW_AT_name, AttributeValue::StringRef(name_id)); - entry.set(gimli::DW_AT_linkage_name, AttributeValue::StringRef(name_id)); + + // These will be replaced in FunctionDebugContext::finalize. They are + // only defined here to ensure that the order of the attributes matches + // rustc. + entry.set(gimli::DW_AT_low_pc, AttributeValue::Udata(0)); + entry.set(gimli::DW_AT_high_pc, AttributeValue::Udata(0)); let mut frame_base_expr = Expression::new(); frame_base_expr.op_reg(self.stack_pointer_register); entry.set(gimli::DW_AT_frame_base, AttributeValue::Exprloc(frame_base_expr)); + // Gdb requires DW_AT_name. Otherwise the DW_TAG_subprogram is skipped. + // FIXME only include the function name and not the full mangled symbol + entry.set(gimli::DW_AT_name, AttributeValue::StringRef(name_id)); + entry.set(gimli::DW_AT_decl_file, AttributeValue::FileIndex(Some(file_id))); entry.set(gimli::DW_AT_decl_line, AttributeValue::Udata(line)); - entry.set(gimli::DW_AT_decl_column, AttributeValue::Udata(column)); + + // FIXME set DW_AT_external as appropriate FunctionDebugContext { entry_id, From d0eb9c86f1ec1d2f6c2c5c09abb31d2b3d3e7069 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Wed, 27 Mar 2024 11:12:21 +0000 Subject: [PATCH 098/165] move type inference for missing types on constants into its own method --- compiler/rustc_hir_typeck/src/lib.rs | 104 +++++++++++++++------------ 1 file changed, 58 insertions(+), 46 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs index f201bfddf4bb..55e86bbec1c4 100644 --- a/compiler/rustc_hir_typeck/src/lib.rs +++ b/compiler/rustc_hir_typeck/src/lib.rs @@ -191,52 +191,7 @@ fn typeck_with_fallback<'tcx>( check_fn(&mut fcx, fn_sig, None, decl, def_id, body, tcx.features().unsized_fn_params); } else { - let expected_type = if let Some(&hir::Ty { kind: hir::TyKind::Infer, span, .. }) = body_ty { - if let Some(item) = tcx.opt_associated_item(def_id.into()) - && let ty::AssocKind::Const = item.kind - && let ty::ImplContainer = item.container - && let Some(trait_item) = item.trait_item_def_id - { - let args = - tcx.impl_trait_ref(item.container_id(tcx)).unwrap().instantiate_identity().args; - Some(tcx.type_of(trait_item).instantiate(tcx, args)) - } else { - Some(fcx.next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::TypeInference, - span, - })) - } - } else if let Node::AnonConst(_) = node { - match tcx.parent_hir_node(id) { - Node::Ty(&hir::Ty { kind: hir::TyKind::Typeof(ref anon_const), .. }) - if anon_const.hir_id == id => - { - Some(fcx.next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::TypeInference, - span, - })) - } - Node::Expr(&hir::Expr { kind: hir::ExprKind::InlineAsm(asm), .. }) - | Node::Item(&hir::Item { kind: hir::ItemKind::GlobalAsm(asm), .. }) => { - asm.operands.iter().find_map(|(op, _op_sp)| match op { - hir::InlineAsmOperand::Const { anon_const } if anon_const.hir_id == id => { - // Inline assembly constants must be integers. - Some(fcx.next_int_var()) - } - hir::InlineAsmOperand::SymFn { anon_const } if anon_const.hir_id == id => { - Some(fcx.next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::MiscVariable, - span, - })) - } - _ => None, - }) - } - _ => None, - } - } else { - None - }; + let expected_type = infer_type_if_missing(body_ty, &fcx, node); let expected_type = expected_type.unwrap_or_else(fallback); let expected_type = fcx.normalize(body.value.span, expected_type); @@ -306,6 +261,63 @@ fn typeck_with_fallback<'tcx>( typeck_results } +fn infer_type_if_missing<'tcx>( + body_ty: Option<&hir::Ty<'tcx>>, + fcx: &FnCtxt<'_, 'tcx>, + node: Node<'tcx>, +) -> Option> { + let tcx = fcx.tcx; + let def_id = fcx.body_id; + let expected_type = if let Some(&hir::Ty { kind: hir::TyKind::Infer, span, .. }) = body_ty { + if let Some(item) = tcx.opt_associated_item(def_id.into()) + && let ty::AssocKind::Const = item.kind + && let ty::ImplContainer = item.container + && let Some(trait_item) = item.trait_item_def_id + { + let args = + tcx.impl_trait_ref(item.container_id(tcx)).unwrap().instantiate_identity().args; + Some(tcx.type_of(trait_item).instantiate(tcx, args)) + } else { + Some(fcx.next_ty_var(TypeVariableOrigin { + kind: TypeVariableOriginKind::TypeInference, + span, + })) + } + } else if let Node::AnonConst(_) = node { + let id = tcx.local_def_id_to_hir_id(def_id); + match tcx.parent_hir_node(id) { + Node::Ty(&hir::Ty { kind: hir::TyKind::Typeof(ref anon_const), span, .. }) + if anon_const.hir_id == id => + { + Some(fcx.next_ty_var(TypeVariableOrigin { + kind: TypeVariableOriginKind::TypeInference, + span, + })) + } + Node::Expr(&hir::Expr { kind: hir::ExprKind::InlineAsm(asm), span, .. }) + | Node::Item(&hir::Item { kind: hir::ItemKind::GlobalAsm(asm), span, .. }) => { + asm.operands.iter().find_map(|(op, _op_sp)| match op { + hir::InlineAsmOperand::Const { anon_const } if anon_const.hir_id == id => { + // Inline assembly constants must be integers. + Some(fcx.next_int_var()) + } + hir::InlineAsmOperand::SymFn { anon_const } if anon_const.hir_id == id => { + Some(fcx.next_ty_var(TypeVariableOrigin { + kind: TypeVariableOriginKind::MiscVariable, + span, + })) + } + _ => None, + }) + } + _ => None, + } + } else { + None + }; + expected_type +} + /// When `check_fn` is invoked on a coroutine (i.e., a body that /// includes yield), it returns back some information about the yield /// points. From 7786ee3c9240084ddb2b62d3f78cffce61462199 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Wed, 27 Mar 2024 11:13:34 +0000 Subject: [PATCH 099/165] Remove a call-site to `primary_body_of` as it is only interested in the body id --- compiler/rustc_hir_typeck/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs index 55e86bbec1c4..c135389ec986 100644 --- a/compiler/rustc_hir_typeck/src/lib.rs +++ b/compiler/rustc_hir_typeck/src/lib.rs @@ -106,7 +106,7 @@ fn has_typeck_results(tcx: TyCtxt<'_>, def_id: DefId) -> bool { } if let Some(def_id) = def_id.as_local() { - primary_body_of(tcx.hir_node_by_def_id(def_id)).is_some() + tcx.hir_node_by_def_id(def_id).body_id().is_some() } else { false } From 86e750f0f777d78a108fa224731ef163b35f2309 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Wed, 27 Mar 2024 11:16:41 +0000 Subject: [PATCH 100/165] Inline `primary_body_of` into its sole call site --- compiler/rustc_hir_typeck/src/lib.rs | 28 +++++----------------------- 1 file changed, 5 insertions(+), 23 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs index c135389ec986..00d3e262cc89 100644 --- a/compiler/rustc_hir_typeck/src/lib.rs +++ b/compiler/rustc_hir_typeck/src/lib.rs @@ -83,20 +83,6 @@ macro_rules! type_error_struct { }) } -/// If this `DefId` is a "primary tables entry", returns -/// `Some((body_id, body_ty, fn_sig))`. Otherwise, returns `None`. -/// -/// If this function returns `Some`, then `typeck_results(def_id)` will -/// succeed; if it returns `None`, then `typeck_results(def_id)` may or -/// may not succeed. In some cases where this function returns `None` -/// (notably closures), `typeck_results(def_id)` would wind up -/// redirecting to the owning function. -fn primary_body_of( - node: Node<'_>, -) -> Option<(hir::BodyId, Option<&hir::Ty<'_>>, Option<&hir::FnSig<'_>>)> { - Some((node.body_id()?, node.ty(), node.fn_sig())) -} - fn has_typeck_results(tcx: TyCtxt<'_>, def_id: DefId) -> bool { // Closures' typeck results come from their outermost function, // as they are part of the same "inference environment". @@ -163,7 +149,7 @@ fn typeck_with_fallback<'tcx>( let span = tcx.hir().span(id); // Figure out what primary body this item has. - let (body_id, body_ty, fn_sig) = primary_body_of(node).unwrap_or_else(|| { + let body_id = node.body_id().unwrap_or_else(|| { span_bug!(span, "can't type-check body of {:?}", def_id); }); let body = tcx.hir().body(body_id); @@ -176,7 +162,7 @@ fn typeck_with_fallback<'tcx>( } let mut fcx = FnCtxt::new(&inh, param_env, def_id); - if let Some(hir::FnSig { header, decl, .. }) = fn_sig { + if let Some(hir::FnSig { header, decl, .. }) = node.fn_sig() { let fn_sig = if decl.output.get_infer_ret_ty().is_some() { fcx.lowerer().lower_fn_ty(id, header.unsafety, header.abi, decl, None, None) } else { @@ -191,7 +177,7 @@ fn typeck_with_fallback<'tcx>( check_fn(&mut fcx, fn_sig, None, decl, def_id, body, tcx.features().unsized_fn_params); } else { - let expected_type = infer_type_if_missing(body_ty, &fcx, node); + let expected_type = infer_type_if_missing(&fcx, node); let expected_type = expected_type.unwrap_or_else(fallback); let expected_type = fcx.normalize(body.value.span, expected_type); @@ -261,14 +247,10 @@ fn typeck_with_fallback<'tcx>( typeck_results } -fn infer_type_if_missing<'tcx>( - body_ty: Option<&hir::Ty<'tcx>>, - fcx: &FnCtxt<'_, 'tcx>, - node: Node<'tcx>, -) -> Option> { +fn infer_type_if_missing<'tcx>(fcx: &FnCtxt<'_, 'tcx>, node: Node<'tcx>) -> Option> { let tcx = fcx.tcx; let def_id = fcx.body_id; - let expected_type = if let Some(&hir::Ty { kind: hir::TyKind::Infer, span, .. }) = body_ty { + let expected_type = if let Some(&hir::Ty { kind: hir::TyKind::Infer, span, .. }) = node.ty() { if let Some(item) = tcx.opt_associated_item(def_id.into()) && let ty::AssocKind::Const = item.kind && let ty::ImplContainer = item.container From e48d7d242fcf378d66d27dddea546029239bd5c6 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Wed, 27 Mar 2024 12:43:47 +0000 Subject: [PATCH 101/165] Emit namespace debuginfo --- src/base.rs | 2 +- src/debuginfo/mod.rs | 63 +++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 60 insertions(+), 5 deletions(-) diff --git a/src/base.rs b/src/base.rs index dbce6d165d2d..4e60f820594b 100644 --- a/src/base.rs +++ b/src/base.rs @@ -70,7 +70,7 @@ pub(crate) fn codegen_fn<'tcx>( let clif_comments = crate::pretty_clif::CommentWriter::new(tcx, instance); let func_debug_cx = if let Some(debug_context) = &mut cx.debug_context { - Some(debug_context.define_function(tcx, &symbol_name, mir.span)) + Some(debug_context.define_function(tcx, instance, &symbol_name, mir.span)) } else { None }; diff --git a/src/debuginfo/mod.rs b/src/debuginfo/mod.rs index 44ee2b822a9d..2b5f472c5fc7 100644 --- a/src/debuginfo/mod.rs +++ b/src/debuginfo/mod.rs @@ -13,6 +13,8 @@ use gimli::write::{ }; use gimli::{AArch64, Encoding, Format, LineEncoding, Register, RiscV, RunTimeEndian, X86_64}; use indexmap::IndexSet; +use rustc_codegen_ssa::debuginfo::type_names; +use rustc_hir::def_id::DefIdMap; use rustc_session::Session; pub(crate) use self::emit::{DebugReloc, DebugRelocName}; @@ -29,6 +31,7 @@ pub(crate) struct DebugContext { dwarf: DwarfUnit, unit_range_list: RangeList, stack_pointer_register: Register, + namespace_map: DefIdMap, should_remap_filepaths: bool, } @@ -122,14 +125,42 @@ impl DebugContext { dwarf, unit_range_list: RangeList(Vec::new()), stack_pointer_register, + namespace_map: DefIdMap::default(), should_remap_filepaths, } } - pub(crate) fn define_function( + fn item_namespace(&mut self, tcx: TyCtxt<'_>, def_id: DefId) -> UnitEntryId { + if let Some(&scope) = self.namespace_map.get(&def_id) { + return scope; + } + + let def_key = tcx.def_key(def_id); + let parent_scope = def_key + .parent + .map(|parent| self.item_namespace(tcx, DefId { krate: def_id.krate, index: parent })) + .unwrap_or(self.dwarf.unit.root()); + + let namespace_name = { + let mut output = String::new(); + type_names::push_item_name(tcx, def_id, false, &mut output); + output + }; + let namespace_name_id = self.dwarf.strings.add(namespace_name); + + let scope = self.dwarf.unit.add(parent_scope, gimli::DW_TAG_namespace); + let scope_entry = self.dwarf.unit.get_mut(scope); + scope_entry.set(gimli::DW_AT_name, AttributeValue::StringRef(namespace_name_id)); + + self.namespace_map.insert(def_id, scope); + scope + } + + pub(crate) fn define_function<'tcx>( &mut self, - tcx: TyCtxt<'_>, - name: &str, + tcx: TyCtxt<'tcx>, + instance: Instance<'tcx>, + linkage_name: &str, function_span: Span, ) -> FunctionDebugContext { let (file, line, column) = DebugContext::get_span_loc(tcx, function_span, function_span); @@ -137,10 +168,31 @@ impl DebugContext { let file_id = self.add_source_file(&file); // FIXME: add to appropriate scope instead of root - let scope = self.dwarf.unit.root(); + let scope = self.item_namespace(tcx, tcx.parent(instance.def_id())); + + let mut name = String::new(); + type_names::push_item_name(tcx, instance.def_id(), false, &mut name); + + // Find the enclosing function, in case this is a closure. + let enclosing_fn_def_id = tcx.typeck_root_def_id(instance.def_id()); + + // We look up the generics of the enclosing function and truncate the args + // to their length in order to cut off extra stuff that might be in there for + // closures or coroutines. + let generics = tcx.generics_of(enclosing_fn_def_id); + let args = instance.args.truncate_to(tcx, generics); + + type_names::push_generic_params( + tcx, + tcx.normalize_erasing_regions(ty::ParamEnv::reveal_all(), args), + enclosing_fn_def_id, + &mut name, + ); let entry_id = self.dwarf.unit.add(scope, gimli::DW_TAG_subprogram); let entry = self.dwarf.unit.get_mut(entry_id); + let linkage_name_id = + if name != linkage_name { Some(self.dwarf.strings.add(linkage_name)) } else { None }; let name_id = self.dwarf.strings.add(name); // These will be replaced in FunctionDebugContext::finalize. They are @@ -153,6 +205,9 @@ impl DebugContext { frame_base_expr.op_reg(self.stack_pointer_register); entry.set(gimli::DW_AT_frame_base, AttributeValue::Exprloc(frame_base_expr)); + if let Some(linkage_name_id) = linkage_name_id { + entry.set(gimli::DW_AT_linkage_name, AttributeValue::StringRef(linkage_name_id)); + } // Gdb requires DW_AT_name. Otherwise the DW_TAG_subprogram is skipped. // FIXME only include the function name and not the full mangled symbol entry.set(gimli::DW_AT_name, AttributeValue::StringRef(name_id)); From 0cd9708de60fb0f92561e0a6ed0a8c5991fd871d Mon Sep 17 00:00:00 2001 From: Bryanskiy Date: Tue, 26 Mar 2024 18:59:03 +0300 Subject: [PATCH 102/165] Delegation: fix ICE on wrong instantiation --- .../src/hir_ty_lowering/mod.rs | 11 ++ tests/ui/delegation/bad-resolve.rs | 10 +- tests/ui/delegation/bad-resolve.stderr | 37 +---- .../duplicate-definition-inside-trait-impl.rs | 2 +- ...licate-definition-inside-trait-impl.stderr | 11 +- .../explicit-paths-in-traits-pass.rs | 2 +- .../explicit-paths-in-traits-pass.stderr | 11 -- tests/ui/delegation/explicit-paths-pass.rs | 13 +- .../ui/delegation/explicit-paths-pass.stderr | 11 -- .../explicit-paths-signature-pass.rs | 2 +- .../explicit-paths-signature-pass.stderr | 11 -- tests/ui/delegation/explicit-paths.rs | 79 ++++++++-- tests/ui/delegation/explicit-paths.stderr | 141 ++++++++++++++---- tests/ui/delegation/not-supported.rs | 2 +- tests/ui/delegation/not-supported.stderr | 11 +- tests/ui/delegation/parse.rs | 2 +- tests/ui/delegation/parse.stderr | 11 -- tests/ui/delegation/target-expr-pass.rs | 2 +- tests/ui/delegation/target-expr-pass.stderr | 11 +- tests/ui/delegation/target-expr.rs | 6 +- tests/ui/delegation/target-expr.stderr | 31 +++- 21 files changed, 238 insertions(+), 179 deletions(-) delete mode 100644 tests/ui/delegation/explicit-paths-in-traits-pass.stderr delete mode 100644 tests/ui/delegation/explicit-paths-pass.stderr delete mode 100644 tests/ui/delegation/explicit-paths-signature-pass.stderr delete mode 100644 tests/ui/delegation/parse.stderr 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 a83b5b78f9cc..8886a78c6ecd 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -2212,6 +2212,17 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { try_emit("delegation with early bound generics"); } + // There is no way to instantiate `Self` param for caller if + // 1. callee is a trait method + // 2. delegation item isn't an associative item + if let DefKind::AssocFn = self.tcx().def_kind(sig_id) + && let DefKind::Fn = self.tcx().def_kind(self.item_def_id()) + && self.tcx().associated_item(sig_id).container + == ty::AssocItemContainer::TraitContainer + { + try_emit("delegation to a trait method from a free function"); + } + if self.tcx().asyncness(sig_id) == ty::Asyncness::Yes { try_emit("delegation to async functions"); } diff --git a/tests/ui/delegation/bad-resolve.rs b/tests/ui/delegation/bad-resolve.rs index df456f94507b..d2723dc32e04 100644 --- a/tests/ui/delegation/bad-resolve.rs +++ b/tests/ui/delegation/bad-resolve.rs @@ -1,5 +1,5 @@ #![feature(fn_delegation)] -//~^ WARN the feature `fn_delegation` is incomplete +#![allow(incomplete_features)] trait Trait { const C: u32 = 0; @@ -34,14 +34,6 @@ impl Trait for S { reuse foo { &self.0 } //~^ ERROR cannot find function `foo` in this scope - reuse F::foo { &self.0 } - //~^ ERROR cannot find function `foo` in `F` - //~| ERROR duplicate definitions with name `foo` -} - -impl S { - reuse F::foo { &self.0 } - //~^ ERROR cannot find function `foo` in `F` } fn main() {} diff --git a/tests/ui/delegation/bad-resolve.stderr b/tests/ui/delegation/bad-resolve.stderr index d52066373100..f669ac3730e2 100644 --- a/tests/ui/delegation/bad-resolve.stderr +++ b/tests/ui/delegation/bad-resolve.stderr @@ -25,18 +25,6 @@ LL | reuse ::baz; | | help: there is an associated function with a similar name: `bar` | not a member of trait `Trait` -error[E0201]: duplicate definitions with name `foo`: - --> $DIR/bad-resolve.rs:37:5 - | -LL | fn foo(&self, x: i32) -> i32 { x } - | ---------------------------------- item in trait -... -LL | reuse foo { &self.0 } - | --------------------- previous definition here -LL | -LL | reuse F::foo { &self.0 } - | ^^^^^^^^^^^^^^^^^^^^^^^^ duplicate definition - error[E0423]: expected function, found associated constant `Trait::C` --> $DIR/bad-resolve.rs:24:11 | @@ -66,27 +54,6 @@ error[E0425]: cannot find function `foo` in this scope LL | reuse foo { &self.0 } | ^^^ not found in this scope -error[E0425]: cannot find function `foo` in `F` - --> $DIR/bad-resolve.rs:37:14 - | -LL | reuse F::foo { &self.0 } - | ^^^ not found in `F` - -error[E0425]: cannot find function `foo` in `F` - --> $DIR/bad-resolve.rs:43:14 - | -LL | reuse F::foo { &self.0 } - | ^^^ not found in `F` - -warning: the feature `fn_delegation` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/bad-resolve.rs:1:12 - | -LL | #![feature(fn_delegation)] - | ^^^^^^^^^^^^^ - | - = note: see issue #118212 for more information - = note: `#[warn(incomplete_features)]` on by default - error[E0046]: not all trait items implemented, missing: `Type` --> $DIR/bad-resolve.rs:22:1 | @@ -96,7 +63,7 @@ LL | type Type; LL | impl Trait for S { | ^^^^^^^^^^^^^^^^ missing `Type` in implementation -error: aborting due to 11 previous errors; 1 warning emitted +error: aborting due to 8 previous errors -Some errors have detailed explanations: E0046, E0201, E0324, E0407, E0423, E0425, E0575, E0576. +Some errors have detailed explanations: E0046, E0324, E0407, E0423, E0425, E0575, E0576. For more information about an error, try `rustc --explain E0046`. diff --git a/tests/ui/delegation/duplicate-definition-inside-trait-impl.rs b/tests/ui/delegation/duplicate-definition-inside-trait-impl.rs index bd685b40b2ff..9c7afcef3ec1 100644 --- a/tests/ui/delegation/duplicate-definition-inside-trait-impl.rs +++ b/tests/ui/delegation/duplicate-definition-inside-trait-impl.rs @@ -1,5 +1,5 @@ #![feature(fn_delegation)] -//~^ WARN the feature `fn_delegation` is incomplete +#![allow(incomplete_features)] trait Trait { fn foo(&self) -> u32 { 0 } diff --git a/tests/ui/delegation/duplicate-definition-inside-trait-impl.stderr b/tests/ui/delegation/duplicate-definition-inside-trait-impl.stderr index a5f9e6ad0bf4..a0f157800cb5 100644 --- a/tests/ui/delegation/duplicate-definition-inside-trait-impl.stderr +++ b/tests/ui/delegation/duplicate-definition-inside-trait-impl.stderr @@ -9,15 +9,6 @@ LL | reuse to_reuse::foo { self } LL | reuse Trait::foo; | ^^^^^^^^^^^^^^^^^ duplicate definition -warning: the feature `fn_delegation` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/duplicate-definition-inside-trait-impl.rs:1:12 - | -LL | #![feature(fn_delegation)] - | ^^^^^^^^^^^^^ - | - = note: see issue #118212 for more information - = note: `#[warn(incomplete_features)]` on by default - -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 E0201`. diff --git a/tests/ui/delegation/explicit-paths-in-traits-pass.rs b/tests/ui/delegation/explicit-paths-in-traits-pass.rs index 4abcc18b9b2c..7d281ad150a0 100644 --- a/tests/ui/delegation/explicit-paths-in-traits-pass.rs +++ b/tests/ui/delegation/explicit-paths-in-traits-pass.rs @@ -1,7 +1,7 @@ //@ run-pass #![feature(fn_delegation)] -//~^ WARN the feature `fn_delegation` is incomplete +#![allow(incomplete_features)] trait ToReuse { fn foo(&self, x: i32) -> i32 { x } diff --git a/tests/ui/delegation/explicit-paths-in-traits-pass.stderr b/tests/ui/delegation/explicit-paths-in-traits-pass.stderr deleted file mode 100644 index 8a320b44e63d..000000000000 --- a/tests/ui/delegation/explicit-paths-in-traits-pass.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `fn_delegation` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/explicit-paths-in-traits-pass.rs:3:12 - | -LL | #![feature(fn_delegation)] - | ^^^^^^^^^^^^^ - | - = note: see issue #118212 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/delegation/explicit-paths-pass.rs b/tests/ui/delegation/explicit-paths-pass.rs index 140605a2bc5b..fada793bd118 100644 --- a/tests/ui/delegation/explicit-paths-pass.rs +++ b/tests/ui/delegation/explicit-paths-pass.rs @@ -1,7 +1,7 @@ //@ run-pass #![feature(fn_delegation)] -//~^ WARN the feature `fn_delegation` is incomplete +#![allow(incomplete_features)] trait Trait { fn bar(&self, x: i32) -> i32 { x } @@ -10,7 +10,6 @@ trait Trait { } fn static_method(x: i32) -> i32 { x } fn static_method2(x: i32, y: i32) -> i32 { x + y } - fn baz<'a>(&self, x: &'a i32) -> &'a i32 { x } } struct F; @@ -29,11 +28,9 @@ impl Trait for S { reuse Trait::description { &self.0 } reuse ::static_method; reuse ::static_method2 { S::static_method(self) } - reuse Trait::baz { &self.0 } } impl S { - reuse Trait::baz { &self.0 } reuse ::static_method { to_reuse::foo(self) } } @@ -49,16 +46,8 @@ fn main() { assert_eq!(42, ::static_method(42)); assert_eq!(21, S::static_method2(10, 10)); - reuse ::static_method; - reuse ::static_method2 { static_method(self) } #[inline] reuse to_reuse::foo; - assert_eq!(42, static_method(42)); - assert_eq!(21, static_method2(10, 10)); assert_eq!(43, foo(42)); assert_eq!(15, zero_args()); - - let x: i32 = 15; - assert_eq!(&x, ::baz(&s, &x)); - assert_eq!(&x, S::baz(&s, &x)); } diff --git a/tests/ui/delegation/explicit-paths-pass.stderr b/tests/ui/delegation/explicit-paths-pass.stderr deleted file mode 100644 index 6d25fb4a5a57..000000000000 --- a/tests/ui/delegation/explicit-paths-pass.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `fn_delegation` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/explicit-paths-pass.rs:3:12 - | -LL | #![feature(fn_delegation)] - | ^^^^^^^^^^^^^ - | - = note: see issue #118212 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/delegation/explicit-paths-signature-pass.rs b/tests/ui/delegation/explicit-paths-signature-pass.rs index b53e57799246..8c16ad92393c 100644 --- a/tests/ui/delegation/explicit-paths-signature-pass.rs +++ b/tests/ui/delegation/explicit-paths-signature-pass.rs @@ -1,7 +1,7 @@ //@ run-pass #![feature(fn_delegation)] -//~^ WARN the feature `fn_delegation` is incomplete +#![allow(incomplete_features)] mod to_reuse { use crate::S; diff --git a/tests/ui/delegation/explicit-paths-signature-pass.stderr b/tests/ui/delegation/explicit-paths-signature-pass.stderr deleted file mode 100644 index 6c81a2ea0af7..000000000000 --- a/tests/ui/delegation/explicit-paths-signature-pass.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `fn_delegation` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/explicit-paths-signature-pass.rs:3:12 - | -LL | #![feature(fn_delegation)] - | ^^^^^^^^^^^^^ - | - = note: see issue #118212 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/delegation/explicit-paths.rs b/tests/ui/delegation/explicit-paths.rs index 1feaaa73f79e..a91ca4cb931e 100644 --- a/tests/ui/delegation/explicit-paths.rs +++ b/tests/ui/delegation/explicit-paths.rs @@ -1,25 +1,84 @@ #![feature(fn_delegation)] -//~^ WARN the feature `fn_delegation` is incomplete +#![allow(incomplete_features)] trait Trait { - fn bar(&self) -> i32 { 42 } + fn foo1(&self, x: i32) -> i32 { x } + fn foo2(x: i32) -> i32 { x } } struct F; impl Trait for F {} - struct S(F); -impl Trait for S { - reuse ::bar; - //~^ ERROR mismatched types +pub mod to_reuse { + pub fn foo3() {} } -struct S2(F); +impl F { + fn foo4(&self) {} +} -impl Trait for S2 { - reuse ::bar { &self.0 } - //~^ ERROR mismatched types +mod fn_to_other { + use super::*; + + reuse Trait::foo1; + //~^ ERROR delegation to a trait method from a free function is not supported yet + reuse ::foo2; + //~^ 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` +} + +mod inherent_impl_assoc_fn_to_other { + use crate::*; + + impl S { + reuse Trait::foo1 { &self.0 } + reuse ::foo2; + reuse to_reuse::foo3; + reuse F::foo4 { &self.0 } + //~^ ERROR cannot find function `foo4` in `F` + } +} + +mod trait_impl_assoc_fn_to_other { + use crate::*; + + impl Trait for S { + reuse Trait::foo1 { &self.0 } + reuse ::foo2; + reuse to_reuse::foo3; + //~^ 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` + } +} + +mod trait_assoc_fn_to_other { + use crate::*; + + trait Trait2 : Trait { + reuse ::foo1 { self } + //~^ ERROR mismatched types + reuse ::foo2; + reuse to_reuse::foo3; + reuse F::foo4 { &F } + //~^ ERROR cannot find function `foo4` in `F` + } +} + +mod type_mismatch { + use crate::*; + + struct S2; + impl Trait for S { + //~^ ERROR conflicting implementations of trait `Trait` for type `S` + reuse ::foo1; + //~^ ERROR mismatched types + //~| ERROR the trait bound `S2: Trait` is not satisfied + } } fn main() {} diff --git a/tests/ui/delegation/explicit-paths.stderr b/tests/ui/delegation/explicit-paths.stderr index 2994b2390ded..30891c94c0e9 100644 --- a/tests/ui/delegation/explicit-paths.stderr +++ b/tests/ui/delegation/explicit-paths.stderr @@ -1,38 +1,129 @@ -warning: the feature `fn_delegation` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/explicit-paths.rs:1:12 +error[E0407]: method `foo3` is not a member of trait `Trait` + --> $DIR/explicit-paths.rs:51:9 | -LL | #![feature(fn_delegation)] - | ^^^^^^^^^^^^^ +LL | reuse to_reuse::foo3; + | ^^^^^^^^^^^^^^^^----^ + | | | + | | help: there is an associated function with a similar name: `foo1` + | not a member of trait `Trait` + +error[E0407]: method `foo4` is not a member of trait `Trait` + --> $DIR/explicit-paths.rs:53:9 | - = note: see issue #118212 for more information - = note: `#[warn(incomplete_features)]` on by default +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` + --> $DIR/explicit-paths.rs:29:14 + | +LL | reuse S::foo4; + | ^^^^ not found in `S` + +error[E0425]: cannot find function `foo4` in `F` + --> $DIR/explicit-paths.rs:40:18 + | +LL | reuse F::foo4 { &self.0 } + | ^^^^ not found in `F` + | +note: function `fn_to_other::foo4` exists but is inaccessible + --> $DIR/explicit-paths.rs:29:5 + | +LL | reuse S::foo4; + | ^^^^^^^^^^^^^^ not accessible + +error[E0425]: cannot find function `foo4` in `F` + --> $DIR/explicit-paths.rs:53:18 + | +LL | reuse F::foo4 { &self.0 } + | ^^^^ not found in `F` + | +note: function `fn_to_other::foo4` exists but is inaccessible + --> $DIR/explicit-paths.rs:29:5 + | +LL | reuse S::foo4; + | ^^^^^^^^^^^^^^ not accessible + +error[E0425]: cannot find function `foo4` in `F` + --> $DIR/explicit-paths.rs:67:18 + | +LL | reuse F::foo4 { &F } + | ^^^^ not found in `F` + | +note: function `fn_to_other::foo4` exists but is inaccessible + --> $DIR/explicit-paths.rs:29:5 + | +LL | reuse S::foo4; + | ^^^^^^^^^^^^^^ not accessible + +error[E0119]: conflicting implementations of trait `Trait` for type `S` + --> $DIR/explicit-paths.rs:76:5 + | +LL | impl Trait for S { + | ---------------- first implementation here +... +LL | impl Trait for S { + | ^^^^^^^^^^^^^^^^ conflicting implementation for `S` + +error: delegation to a trait method from a free function is not supported yet + --> $DIR/explicit-paths.rs:24:18 + | +LL | fn foo1(&self, x: i32) -> i32 { x } + | ----------------------------- callee defined here +... +LL | reuse Trait::foo1; + | ^^^^ + +error: delegation to a trait method from a free function is not supported yet + --> $DIR/explicit-paths.rs:26:25 + | +LL | fn foo2(x: i32) -> i32 { x } + | ---------------------- callee defined here +... +LL | reuse ::foo2; + | ^^^^ error[E0308]: mismatched types - --> $DIR/explicit-paths.rs:14:25 + --> $DIR/explicit-paths.rs:63:36 | -LL | reuse ::bar; - | --------------^^^ - | | | - | | expected `&F`, found `&S` - | arguments to this function are incorrect +LL | trait Trait2 : Trait { + | -------------------- found this type parameter +LL | reuse ::foo1 { self } + | ^^^^ expected `&F`, found `&Self` | = note: expected reference `&F` + found reference `&Self` + +error[E0277]: the trait bound `S2: Trait` is not satisfied + --> $DIR/explicit-paths.rs:78:16 + | +LL | reuse ::foo1; + | ^^ the trait `Trait` is not implemented for `S2` + | + = help: the following other types implement trait `Trait`: + F + S + +error[E0308]: mismatched types + --> $DIR/explicit-paths.rs:78:30 + | +LL | reuse ::foo1; + | ---------------^^^^ + | | | + | | expected `&S2`, found `&S` + | arguments to this function are incorrect + | + = note: expected reference `&S2` found reference `&S` note: method defined here --> $DIR/explicit-paths.rs:5:8 | -LL | fn bar(&self) -> i32 { 42 } - | ^^^ ----- +LL | fn foo1(&self, x: i32) -> i32 { x } + | ^^^^ ----- -error[E0308]: mismatched types - --> $DIR/explicit-paths.rs:21:32 - | -LL | reuse ::bar { &self.0 } - | ^^^^^^^ expected `&S2`, found `&F` - | - = note: expected reference `&S2` - found reference `&F` +error: aborting due to 12 previous errors -error: aborting due to 2 previous errors; 1 warning emitted - -For more information about this error, try `rustc --explain E0308`. +Some errors have detailed explanations: E0119, E0277, E0308, E0407, E0425. +For more information about an error, try `rustc --explain E0119`. diff --git a/tests/ui/delegation/not-supported.rs b/tests/ui/delegation/not-supported.rs index 23081b1e1fc8..9dccb12b57ad 100644 --- a/tests/ui/delegation/not-supported.rs +++ b/tests/ui/delegation/not-supported.rs @@ -1,6 +1,6 @@ #![feature(c_variadic)] #![feature(fn_delegation)] -//~^ WARN the feature `fn_delegation` is incomplete +#![allow(incomplete_features)] mod generics { trait GenericTrait { diff --git a/tests/ui/delegation/not-supported.stderr b/tests/ui/delegation/not-supported.stderr index 324b79f3c535..f6c49366899c 100644 --- a/tests/ui/delegation/not-supported.stderr +++ b/tests/ui/delegation/not-supported.stderr @@ -1,12 +1,3 @@ -warning: the feature `fn_delegation` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/not-supported.rs:2:12 - | -LL | #![feature(fn_delegation)] - | ^^^^^^^^^^^^^ - | - = note: see issue #118212 for more information - = note: `#[warn(incomplete_features)]` on by default - error: delegation with early bound generics is not supported yet --> $DIR/not-supported.rs:16:29 | @@ -178,7 +169,7 @@ LL | pub reuse to_reuse2::foo; LL | reuse to_reuse1::foo; | ^^^ -error: aborting due to 19 previous errors; 1 warning emitted +error: aborting due to 19 previous errors Some errors have detailed explanations: E0049, E0195. For more information about an error, try `rustc --explain E0049`. diff --git a/tests/ui/delegation/parse.rs b/tests/ui/delegation/parse.rs index 5e8026c55321..72b00bf6e0d5 100644 --- a/tests/ui/delegation/parse.rs +++ b/tests/ui/delegation/parse.rs @@ -2,7 +2,7 @@ #![feature(decl_macro)] #![feature(fn_delegation)] -//~^ WARN the feature `fn_delegation` is incomplete +#![allow(incomplete_features)] macro_rules! reuse { {} => {} } diff --git a/tests/ui/delegation/parse.stderr b/tests/ui/delegation/parse.stderr deleted file mode 100644 index 1e420ceeec7f..000000000000 --- a/tests/ui/delegation/parse.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `fn_delegation` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/parse.rs:4:12 - | -LL | #![feature(fn_delegation)] - | ^^^^^^^^^^^^^ - | - = note: see issue #118212 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/delegation/target-expr-pass.rs b/tests/ui/delegation/target-expr-pass.rs index 1f2edf0dc13f..9e326a19b8f1 100644 --- a/tests/ui/delegation/target-expr-pass.rs +++ b/tests/ui/delegation/target-expr-pass.rs @@ -1,7 +1,7 @@ //@ run-pass #![feature(fn_delegation)] -//~^ WARN the feature `fn_delegation` is incomplete +#![allow(incomplete_features)] mod to_reuse { pub fn foo(x: i32) -> i32 { x } diff --git a/tests/ui/delegation/target-expr-pass.stderr b/tests/ui/delegation/target-expr-pass.stderr index dd1f3a14e0bd..c8d73ec6e5aa 100644 --- a/tests/ui/delegation/target-expr-pass.stderr +++ b/tests/ui/delegation/target-expr-pass.stderr @@ -1,12 +1,3 @@ -warning: the feature `fn_delegation` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/target-expr-pass.rs:3:12 - | -LL | #![feature(fn_delegation)] - | ^^^^^^^^^^^^^ - | - = note: see issue #118212 for more information - = note: `#[warn(incomplete_features)]` on by default - warning: trait `Trait` is never used --> $DIR/target-expr-pass.rs:17:7 | @@ -27,5 +18,5 @@ warning: struct `S` is never constructed LL | struct S(F); | ^ -warning: 4 warnings emitted +warning: 3 warnings emitted diff --git a/tests/ui/delegation/target-expr.rs b/tests/ui/delegation/target-expr.rs index b9c6fe92810b..fd7ea943b9d5 100644 --- a/tests/ui/delegation/target-expr.rs +++ b/tests/ui/delegation/target-expr.rs @@ -14,8 +14,9 @@ fn foo(x: i32) -> i32 { x } fn bar(_: T) { reuse Trait::static_method { - //~^ ERROR delegation with early bound generics is not supported yet - //~| ERROR mismatched types + //~^ ERROR delegation to a trait method from a free function is not supported yet + //~| ERROR delegation with early bound generics is not supported yet + //~| ERROR mismatched types let _ = T::Default(); //~^ ERROR can't use generic parameters from outer item } @@ -24,6 +25,7 @@ fn bar(_: T) { fn main() { let y = 0; reuse ::static_method { + //~^ ERROR delegation to a trait method from a free function is not supported yet let x = y; //~^ ERROR can't capture dynamic environment in a fn item foo(self); diff --git a/tests/ui/delegation/target-expr.stderr b/tests/ui/delegation/target-expr.stderr index da0fac2f5e46..b30f0c474c68 100644 --- a/tests/ui/delegation/target-expr.stderr +++ b/tests/ui/delegation/target-expr.stderr @@ -1,5 +1,5 @@ error[E0401]: can't use generic parameters from outer item - --> $DIR/target-expr.rs:19:17 + --> $DIR/target-expr.rs:20:17 | LL | fn bar(_: T) { | - type parameter from outer item @@ -10,7 +10,7 @@ LL | let _ = T::Default(); | ^^^^^^^^^^ use of generic parameter from outer item error[E0434]: can't capture dynamic environment in a fn item - --> $DIR/target-expr.rs:27:17 + --> $DIR/target-expr.rs:29:17 | LL | let x = y; | ^ @@ -18,7 +18,7 @@ LL | let x = y; = help: use the `|| { ... }` closure form instead error[E0424]: expected value, found module `self` - --> $DIR/target-expr.rs:34:5 + --> $DIR/target-expr.rs:36:5 | LL | fn main() { | ---- this function can't have a `self` parameter @@ -27,13 +27,13 @@ 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 - --> $DIR/target-expr.rs:36:13 + --> $DIR/target-expr.rs:38:13 | LL | let z = x; | ^ | help: the binding `x` is available in a different scope in the same function - --> $DIR/target-expr.rs:27:13 + --> $DIR/target-expr.rs:29:13 | LL | let x = y; | ^ @@ -47,6 +47,24 @@ LL | fn static_method(x: i32) -> i32 { x } LL | reuse Trait::static_method { | ^^^^^^^^^^^^^ +error: delegation to a trait method from a free function is not supported yet + --> $DIR/target-expr.rs:16:18 + | +LL | fn static_method(x: i32) -> i32 { x } + | ------------------------------- callee defined here +... +LL | reuse Trait::static_method { + | ^^^^^^^^^^^^^ + +error: delegation to a trait method from a free function is not supported yet + --> $DIR/target-expr.rs:27:25 + | +LL | fn static_method(x: i32) -> i32 { x } + | ------------------------------- callee defined here +... +LL | reuse ::static_method { + | ^^^^^^^^^^^^^ + error[E0308]: mismatched types --> $DIR/target-expr.rs:16:32 | @@ -54,12 +72,13 @@ LL | reuse Trait::static_method { | ________________________________^ LL | | LL | | +LL | | LL | | let _ = T::Default(); LL | | LL | | } | |_____^ expected `i32`, found `()` -error: aborting due to 6 previous errors +error: aborting due to 8 previous errors Some errors have detailed explanations: E0308, E0401, E0424, E0425, E0434. For more information about an error, try `rustc --explain E0308`. From 98eaaeda111673c617134fe2dcd3f10bb6dfc2f0 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Wed, 27 Mar 2024 12:57:24 +0000 Subject: [PATCH 103/165] Match unit names with cg_llvm --- src/debuginfo/mod.rs | 10 ++++++++-- src/lib.rs | 2 +- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/debuginfo/mod.rs b/src/debuginfo/mod.rs index 2b5f472c5fc7..4232018916fc 100644 --- a/src/debuginfo/mod.rs +++ b/src/debuginfo/mod.rs @@ -43,7 +43,7 @@ pub(crate) struct FunctionDebugContext { } impl DebugContext { - pub(crate) fn new(tcx: TyCtxt<'_>, isa: &dyn TargetIsa) -> Self { + pub(crate) fn new(tcx: TyCtxt<'_>, isa: &dyn TargetIsa, cgu_name: &str) -> Self { let encoding = Encoding { format: Format::Dwarf32, // FIXME this should be configurable @@ -108,7 +108,7 @@ impl DebugContext { dwarf.unit.line_program = line_program; { - let name = dwarf.strings.add(name); + let name = dwarf.strings.add(format!("{name}/@/{cgu_name}")); let comp_dir = dwarf.strings.add(comp_dir); let root = dwarf.unit.root(); @@ -116,6 +116,12 @@ impl DebugContext { root.set(gimli::DW_AT_producer, AttributeValue::StringRef(dwarf.strings.add(producer))); root.set(gimli::DW_AT_language, AttributeValue::Language(gimli::DW_LANG_Rust)); root.set(gimli::DW_AT_name, AttributeValue::StringRef(name)); + + // This will be replaced when emitting the debuginfo. It is only + // defined here to ensure that the order of the attributes matches + // rustc. + root.set(gimli::DW_AT_stmt_list, AttributeValue::Udata(0)); + root.set(gimli::DW_AT_comp_dir, AttributeValue::StringRef(comp_dir)); root.set(gimli::DW_AT_low_pc, AttributeValue::Address(Address::Constant(0))); } diff --git a/src/lib.rs b/src/lib.rs index a121ac75a287..d0ab64a55849 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -148,7 +148,7 @@ impl CodegenCx { 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)) + Some(DebugContext::new(tcx, isa, cgu_name.as_str())) } else { None }; From 47ed73a7b510b416a191f343c2f07826e8072396 Mon Sep 17 00:00:00 2001 From: DianQK Date: Sun, 10 Mar 2024 16:29:39 +0800 Subject: [PATCH 104/165] Eliminate `UbCheck` for non-standard libraries --- compiler/rustc_feature/src/builtin_attrs.rs | 4 ++ compiler/rustc_middle/src/mir/syntax.rs | 4 +- .../rustc_mir_transform/src/instsimplify.rs | 15 +++++ compiler/rustc_span/src/symbol.rs | 1 + library/alloc/src/lib.rs | 1 + library/core/src/intrinsics.rs | 12 ++-- library/core/src/lib.rs | 1 + library/std/src/lib.rs | 1 + tests/coverage/unreachable.cov-map | 12 ++-- ...unchecked.PreCodegen.after.panic-abort.mir | 13 +--- ...nchecked.PreCodegen.after.panic-unwind.mir | 13 +--- tests/mir-opt/instsimplify/ub_check.rs | 16 +++++ ...b_check.unwrap_unchecked.InstSimplify.diff | 59 +++++++++++++++++++ ...witch_targets.ub_if_b.PreCodegen.after.mir | 11 +--- 14 files changed, 118 insertions(+), 45 deletions(-) create mode 100644 tests/mir-opt/instsimplify/ub_check.rs create mode 100644 tests/mir-opt/instsimplify/ub_check.unwrap_unchecked.InstSimplify.diff diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index 22cf50fce7f4..6a8a1722bcb2 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -821,6 +821,10 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ rustc_allow_incoherent_impl, AttributeType::Normal, template!(Word), ErrorFollowing, EncodeCrossCrate::No, "#[rustc_allow_incoherent_impl] has to be added to all impl items of an incoherent inherent impl." ), + rustc_attr!( + rustc_preserve_ub_checks, AttributeType::CrateLevel, template!(Word), ErrorFollowing, EncodeCrossCrate::No, + "`#![rustc_preserve_ub_checks]` prevents the designated crate from evaluating whether UB checks are enabled when optimizing MIR", + ), rustc_attr!( rustc_deny_explicit_impl, AttributeType::Normal, diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs index 12bf8efd73ad..2fe63fe4cb86 100644 --- a/compiler/rustc_middle/src/mir/syntax.rs +++ b/compiler/rustc_middle/src/mir/syntax.rs @@ -1361,8 +1361,8 @@ pub enum NullOp<'tcx> { AlignOf, /// Returns the offset of a field OffsetOf(&'tcx List<(VariantIdx, FieldIdx)>), - /// Returns whether we want to check for UB. - /// This returns the value of `cfg!(debug_assertions)` at monomorphization time. + /// Returns whether we should perform some UB-checking at runtime. + /// See the `ub_checks` intrinsic docs for details. UbChecks, } diff --git a/compiler/rustc_mir_transform/src/instsimplify.rs b/compiler/rustc_mir_transform/src/instsimplify.rs index 6b33d81c1c41..1b38eeccfad0 100644 --- a/compiler/rustc_mir_transform/src/instsimplify.rs +++ b/compiler/rustc_mir_transform/src/instsimplify.rs @@ -1,10 +1,12 @@ //! Performs various peephole optimizations. use crate::simplify::simplify_duplicate_switch_targets; +use rustc_ast::attr; use rustc_middle::mir::*; use rustc_middle::ty::layout; use rustc_middle::ty::layout::ValidityRequirement; use rustc_middle::ty::{self, GenericArgsRef, ParamEnv, Ty, TyCtxt}; +use rustc_span::sym; use rustc_span::symbol::Symbol; use rustc_target::abi::FieldIdx; use rustc_target::spec::abi::Abi; @@ -22,10 +24,15 @@ impl<'tcx> MirPass<'tcx> for InstSimplify { local_decls: &body.local_decls, param_env: tcx.param_env_reveal_all_normalized(body.source.def_id()), }; + let preserve_ub_checks = + attr::contains_name(tcx.hir().krate_attrs(), sym::rustc_preserve_ub_checks); for block in body.basic_blocks.as_mut() { for statement in block.statements.iter_mut() { match statement.kind { StatementKind::Assign(box (_place, ref mut rvalue)) => { + if !preserve_ub_checks { + ctx.simplify_ub_check(&statement.source_info, rvalue); + } ctx.simplify_bool_cmp(&statement.source_info, rvalue); ctx.simplify_ref_deref(&statement.source_info, rvalue); ctx.simplify_len(&statement.source_info, rvalue); @@ -140,6 +147,14 @@ impl<'tcx> InstSimplifyContext<'tcx, '_> { } } + fn simplify_ub_check(&self, source_info: &SourceInfo, rvalue: &mut Rvalue<'tcx>) { + if let Rvalue::NullaryOp(NullOp::UbChecks, _) = *rvalue { + let const_ = Const::from_bool(self.tcx, self.tcx.sess.opts.debug_assertions); + let constant = ConstOperand { span: source_info.span, const_, user_ty: None }; + *rvalue = Rvalue::Use(Operand::Constant(Box::new(constant))); + } + } + fn simplify_cast(&self, rvalue: &mut Rvalue<'tcx>) { if let Rvalue::Cast(kind, operand, cast_ty) = rvalue { let operand_ty = operand.ty(self.local_decls, self.tcx); diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 891ddb7af5b0..b92d9c06dc44 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1572,6 +1572,7 @@ symbols! { rustc_peek_maybe_init, rustc_peek_maybe_uninit, rustc_polymorphize_error, + rustc_preserve_ub_checks, rustc_private, rustc_proc_macro_decls, rustc_promotable, diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs index 20b7d0afa87e..26d238154a3b 100644 --- a/library/alloc/src/lib.rs +++ b/library/alloc/src/lib.rs @@ -176,6 +176,7 @@ // Language features: // tidy-alphabetical-start #![cfg_attr(bootstrap, feature(associated_type_bounds))] +#![cfg_attr(not(bootstrap), rustc_preserve_ub_checks)] #![cfg_attr(not(test), feature(coroutine_trait))] #![cfg_attr(test, feature(panic_update_hook))] #![cfg_attr(test, feature(test))] diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs index bb1debfc77de..ae6e39d19e14 100644 --- a/library/core/src/intrinsics.rs +++ b/library/core/src/intrinsics.rs @@ -2686,12 +2686,14 @@ pub const unsafe fn typed_swap(x: *mut T, y: *mut T) { unsafe { ptr::swap_nonoverlapping(x, y, 1) }; } -/// Returns whether we should perform some UB-checking at runtime. This evaluate to the value of -/// `cfg!(debug_assertions)` during monomorphization. +/// Returns whether we should perform some UB-checking at runtime. This eventually evaluates to +/// `cfg!(debug_assertions)`, but behaves different from `cfg!` when mixing crates built with different +/// flags: if the crate has debug assertions enabled or carries the `#[rustc_preserve_ub_checks]` +/// attribute, evaluation is delayed until monomorphization (or until the call gets inlined into +/// a crate that does not delay evaluation further); otherwise it can happen any time. /// -/// This intrinsic is evaluated after monomorphization, which is relevant when mixing crates -/// compiled with and without debug_assertions. The common case here is a user program built with -/// debug_assertions linked against the distributed sysroot which is built without debug_assertions. +/// The common case here is a user program built with debug_assertions linked against the distributed +/// sysroot which is built without debug_assertions but with `#[rustc_preserve_ub_checks]`. /// For code that gets monomorphized in the user crate (i.e., generic functions and functions with /// `#[inline]`), gating assertions on `ub_checks()` rather than `cfg!(debug_assertions)` means that /// assertions are enabled whenever the *user crate* has debug assertions enabled. However if the diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index 3bc1a87f848f..cf13496b367d 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -94,6 +94,7 @@ ))] #![no_core] #![rustc_coherence_is_core] +#![cfg_attr(not(bootstrap), rustc_preserve_ub_checks)] // // Lints: #![deny(rust_2021_incompatible_or_patterns)] diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index dc5a8704498d..3781ae15c3ab 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -221,6 +221,7 @@ // #![cfg_attr(not(feature = "restricted-std"), stable(feature = "rust1", since = "1.0.0"))] #![cfg_attr(feature = "restricted-std", unstable(feature = "restricted_std", issue = "none"))] +#![cfg_attr(not(bootstrap), rustc_preserve_ub_checks)] #![doc( html_playground_url = "https://play.rust-lang.org/", issue_tracker_base_url = "https://github.com/rust-lang/rust/issues/", diff --git a/tests/coverage/unreachable.cov-map b/tests/coverage/unreachable.cov-map index 9d4698527d09..09d3b2345431 100644 --- a/tests/coverage/unreachable.cov-map +++ b/tests/coverage/unreachable.cov-map @@ -1,18 +1,18 @@ -Function name: unreachable::UNREACHABLE_CLOSURE::{closure#0} -Raw bytes (9): 0x[01, 01, 00, 01, 01, 0f, 27, 00, 47] +Function name: unreachable::UNREACHABLE_CLOSURE::{closure#0} (unused) +Raw bytes (9): 0x[01, 01, 00, 01, 00, 0f, 27, 00, 47] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 15, 39) to (start + 0, 71) +- Code(Zero) at (prev + 15, 39) to (start + 0, 71) -Function name: unreachable::unreachable_function -Raw bytes (9): 0x[01, 01, 00, 01, 01, 11, 01, 01, 25] +Function name: unreachable::unreachable_function (unused) +Raw bytes (9): 0x[01, 01, 00, 01, 00, 11, 01, 01, 25] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 17, 1) to (start + 1, 37) +- Code(Zero) at (prev + 17, 1) to (start + 1, 37) Function name: unreachable::unreachable_intrinsic (unused) Raw bytes (9): 0x[01, 01, 00, 01, 00, 16, 01, 01, 2c] diff --git a/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.PreCodegen.after.panic-abort.mir b/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.PreCodegen.after.panic-abort.mir index 9cd7053871e5..d629336d3859 100644 --- a/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.PreCodegen.after.panic-abort.mir +++ b/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.PreCodegen.after.panic-abort.mir @@ -11,8 +11,6 @@ fn unwrap_unchecked(_1: Option) -> T { } scope 3 { scope 4 (inlined unreachable_unchecked) { - let mut _3: bool; - let _4: (); scope 5 { } scope 6 (inlined core::ub_checks::check_language_ub) { @@ -26,23 +24,16 @@ fn unwrap_unchecked(_1: Option) -> T { bb0: { StorageLive(_2); _2 = discriminant(_1); - switchInt(move _2) -> [0: bb1, 1: bb2, otherwise: bb3]; + switchInt(move _2) -> [0: bb2, 1: bb1, otherwise: bb2]; } bb1: { - StorageLive(_3); - _3 = UbChecks(); - assume(_3); - _4 = unreachable_unchecked::precondition_check() -> [return: bb3, unwind unreachable]; - } - - bb2: { _0 = ((_1 as Some).0: T); StorageDead(_2); return; } - bb3: { + bb2: { unreachable; } } diff --git a/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.PreCodegen.after.panic-unwind.mir index 9cd7053871e5..d629336d3859 100644 --- a/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.PreCodegen.after.panic-unwind.mir +++ b/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.PreCodegen.after.panic-unwind.mir @@ -11,8 +11,6 @@ fn unwrap_unchecked(_1: Option) -> T { } scope 3 { scope 4 (inlined unreachable_unchecked) { - let mut _3: bool; - let _4: (); scope 5 { } scope 6 (inlined core::ub_checks::check_language_ub) { @@ -26,23 +24,16 @@ fn unwrap_unchecked(_1: Option) -> T { bb0: { StorageLive(_2); _2 = discriminant(_1); - switchInt(move _2) -> [0: bb1, 1: bb2, otherwise: bb3]; + switchInt(move _2) -> [0: bb2, 1: bb1, otherwise: bb2]; } bb1: { - StorageLive(_3); - _3 = UbChecks(); - assume(_3); - _4 = unreachable_unchecked::precondition_check() -> [return: bb3, unwind unreachable]; - } - - bb2: { _0 = ((_1 as Some).0: T); StorageDead(_2); return; } - bb3: { + bb2: { unreachable; } } diff --git a/tests/mir-opt/instsimplify/ub_check.rs b/tests/mir-opt/instsimplify/ub_check.rs new file mode 100644 index 000000000000..fc568abcd601 --- /dev/null +++ b/tests/mir-opt/instsimplify/ub_check.rs @@ -0,0 +1,16 @@ +//@ unit-test: InstSimplify +//@ compile-flags: -Cdebug-assertions=no -Zinline-mir + +// EMIT_MIR ub_check.unwrap_unchecked.InstSimplify.diff +pub fn unwrap_unchecked(x: Option) -> i32 { + // CHECK-LABEL: fn unwrap_unchecked( + // CHECK-NOT: UbChecks() + // CHECK: [[assume:_.*]] = const false; + // CHECK-NEXT: assume([[assume]]); + // CHECK-NEXT: unreachable_unchecked::precondition_check + unsafe { x.unwrap_unchecked() } +} + +fn main() { + unwrap_unchecked(None); +} diff --git a/tests/mir-opt/instsimplify/ub_check.unwrap_unchecked.InstSimplify.diff b/tests/mir-opt/instsimplify/ub_check.unwrap_unchecked.InstSimplify.diff new file mode 100644 index 000000000000..f3402fde05b9 --- /dev/null +++ b/tests/mir-opt/instsimplify/ub_check.unwrap_unchecked.InstSimplify.diff @@ -0,0 +1,59 @@ +- // MIR for `unwrap_unchecked` before InstSimplify ++ // MIR for `unwrap_unchecked` after InstSimplify + + fn unwrap_unchecked(_1: Option) -> i32 { + debug x => _1; + let mut _0: i32; + let mut _2: std::option::Option; + scope 1 { + scope 2 (inlined #[track_caller] Option::::unwrap_unchecked) { + debug self => _2; + let mut _3: isize; + scope 3 { + debug val => _0; + } + scope 4 { + scope 5 (inlined unreachable_unchecked) { + let mut _4: bool; + let _5: (); + scope 6 { + } + scope 7 (inlined core::ub_checks::check_language_ub) { + scope 8 (inlined core::ub_checks::check_language_ub::runtime) { + } + } + } + } + } + } + + bb0: { + StorageLive(_2); + _2 = _1; + StorageLive(_3); + StorageLive(_5); + _3 = discriminant(_2); + switchInt(move _3) -> [0: bb2, 1: bb3, otherwise: bb1]; + } + + bb1: { + unreachable; + } + + bb2: { + StorageLive(_4); +- _4 = UbChecks(); ++ _4 = const false; + assume(_4); + _5 = unreachable_unchecked::precondition_check() -> [return: bb1, unwind unreachable]; + } + + bb3: { + _0 = move ((_2 as Some).0: i32); + StorageDead(_5); + StorageDead(_3); + StorageDead(_2); + return; + } + } + diff --git a/tests/mir-opt/pre-codegen/duplicate_switch_targets.ub_if_b.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/duplicate_switch_targets.ub_if_b.PreCodegen.after.mir index 455e4ba72441..ebe846e8a510 100644 --- a/tests/mir-opt/pre-codegen/duplicate_switch_targets.ub_if_b.PreCodegen.after.mir +++ b/tests/mir-opt/pre-codegen/duplicate_switch_targets.ub_if_b.PreCodegen.after.mir @@ -5,8 +5,6 @@ fn ub_if_b(_1: Thing) -> Thing { let mut _0: Thing; let mut _2: isize; scope 1 (inlined unreachable_unchecked) { - let mut _3: bool; - let _4: (); scope 2 { } scope 3 (inlined core::ub_checks::check_language_ub) { @@ -17,7 +15,7 @@ fn ub_if_b(_1: Thing) -> Thing { bb0: { _2 = discriminant(_1); - switchInt(move _2) -> [0: bb1, 1: bb2, otherwise: bb3]; + switchInt(move _2) -> [0: bb1, 1: bb2, otherwise: bb2]; } bb1: { @@ -26,13 +24,6 @@ fn ub_if_b(_1: Thing) -> Thing { } bb2: { - StorageLive(_3); - _3 = UbChecks(); - assume(_3); - _4 = unreachable_unchecked::precondition_check() -> [return: bb3, unwind unreachable]; - } - - bb3: { unreachable; } } From a64387bb6be6360df09e4844c35d63b50b20262e Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Wed, 27 Mar 2024 13:28:40 +0000 Subject: [PATCH 105/165] Emit DW_AT_external if applicable --- src/debuginfo/mod.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/debuginfo/mod.rs b/src/debuginfo/mod.rs index 4232018916fc..ef6841997569 100644 --- a/src/debuginfo/mod.rs +++ b/src/debuginfo/mod.rs @@ -221,6 +221,10 @@ impl DebugContext { entry.set(gimli::DW_AT_decl_file, AttributeValue::FileIndex(Some(file_id))); entry.set(gimli::DW_AT_decl_line, AttributeValue::Udata(line)); + if tcx.is_reachable_non_generic(instance.def_id()) { + entry.set(gimli::DW_AT_external, AttributeValue::FlagPresent); + } + // FIXME set DW_AT_external as appropriate FunctionDebugContext { From 41246b2cf629a0b2699360f35952cff8a7d3d784 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Wed, 27 Mar 2024 13:35:11 +0000 Subject: [PATCH 106/165] Remove fixed todos --- src/debuginfo/mod.rs | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/debuginfo/mod.rs b/src/debuginfo/mod.rs index ef6841997569..b541cf0512e1 100644 --- a/src/debuginfo/mod.rs +++ b/src/debuginfo/mod.rs @@ -215,7 +215,6 @@ impl DebugContext { entry.set(gimli::DW_AT_linkage_name, AttributeValue::StringRef(linkage_name_id)); } // Gdb requires DW_AT_name. Otherwise the DW_TAG_subprogram is skipped. - // FIXME only include the function name and not the full mangled symbol entry.set(gimli::DW_AT_name, AttributeValue::StringRef(name_id)); entry.set(gimli::DW_AT_decl_file, AttributeValue::FileIndex(Some(file_id))); @@ -225,8 +224,6 @@ impl DebugContext { entry.set(gimli::DW_AT_external, AttributeValue::FlagPresent); } - // FIXME set DW_AT_external as appropriate - FunctionDebugContext { entry_id, function_source_loc: (file_id, line, column), From 2707ac96067bf9d9e7ad1a7887be4ef90c939220 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Thu, 21 Mar 2024 12:33:11 +0000 Subject: [PATCH 107/165] Remove unnecessary `Partial/Ord` derive --- compiler/rustc_transmute/src/layout/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_transmute/src/layout/mod.rs b/compiler/rustc_transmute/src/layout/mod.rs index a7c60c3b4904..0377ed5d4c57 100644 --- a/compiler/rustc_transmute/src/layout/mod.rs +++ b/compiler/rustc_transmute/src/layout/mod.rs @@ -65,7 +65,7 @@ pub mod rustc { use std::fmt::{self, Write}; /// A reference in the layout. - #[derive(Debug, Hash, Eq, PartialEq, PartialOrd, Ord, Clone, Copy)] + #[derive(Debug, Hash, Eq, PartialEq, Clone, Copy)] pub struct Ref<'tcx> { pub lifetime: ty::Region<'tcx>, pub ty: Ty<'tcx>, From ae24fef028ca9b27c3209fca1229a99d45873774 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Thu, 21 Mar 2024 12:55:28 +0000 Subject: [PATCH 108/165] Use `TraitRef::to_string` sorting in favor of `TraitRef::ord`, as the latter compares `DefId`s which we need to avoid --- .../error_reporting/type_err_ctxt_ext.rs | 4 +- tests/ui/binop/binary-op-suggest-deref.stderr | 14 ++-- tests/ui/binop/binop-mul-i32-f32.stderr | 4 +- tests/ui/binop/shift-various-bad-types.stderr | 48 ++++++------- .../ui/const-generics/exhaustive-value.stderr | 14 ++-- .../generic_arg_infer/issue-91614.stderr | 4 +- .../issues/issue-67185-2.stderr | 12 ++-- .../const-eval/const-eval-overflow-3b.stderr | 4 +- .../const-eval/const-eval-overflow-4b.stderr | 4 +- .../consts/missing-larger-array-impl.stderr | 14 ++-- tests/ui/consts/too_generic_eval_ice.stderr | 12 ++-- tests/ui/deriving/issue-103157.stderr | 10 +-- ...e-21659-show-relevant-trait-impls-2.stderr | 4 +- .../issue-39802-show-5-trait-impls.stderr | 4 +- tests/ui/fmt/ifmt-unimpl.stderr | 12 ++-- tests/ui/impl-trait/equality.stderr | 4 +- .../impl-trait/impl_trait_projections.stderr | 16 ++--- tests/ui/issues/issue-11771.stderr | 32 ++++----- tests/ui/issues/issue-24352.stderr | 4 +- tests/ui/issues/issue-50582.stderr | 16 ++--- .../invalid-iterator-chain-fixable.stderr | 6 +- ...valid-iterator-chain-with-int-infer.stderr | 2 +- .../iterators/invalid-iterator-chain.stderr | 10 +-- .../trailing-where-clause.stderr | 8 +-- tests/ui/mismatched_types/binops.stderr | 72 +++++++++---------- ...diverging-fallback-no-leak.fallback.stderr | 2 +- tests/ui/never_type/issue-13352.stderr | 4 +- .../not-suggest-float-literal.stderr | 50 ++++++------- .../suggest-float-literal.stderr | 32 ++++----- .../ui/on-unimplemented/multiple-impls.stderr | 12 ++-- tests/ui/on-unimplemented/slice-index.stderr | 2 +- tests/ui/on-unimplemented/sum.stderr | 4 +- tests/ui/range/range-1.stderr | 8 +-- tests/ui/span/multiline-span-simple.stderr | 4 +- ...mpl-trait-return-trailing-semicolon.stderr | 2 +- tests/ui/suggestions/into-str.stderr | 8 +-- .../issue-71394-no-from-impl.stderr | 6 +- .../assoc-fn-bound-root-obligation.stderr | 6 +- .../question-mark-result-err-mismatch.stderr | 8 +-- tests/ui/try-trait/bad-interconversion.stderr | 6 +- tests/ui/try-trait/issue-32709.stderr | 2 +- tests/ui/try-trait/option-to-result.stderr | 2 +- tests/ui/try-trait/try-on-option.stderr | 2 +- .../nested-tait-inference2.stderr | 2 +- tests/ui/type/type-check-defaults.stderr | 4 +- tests/ui/typeck/issue-81293.stderr | 4 +- tests/ui/typeck/issue-90101.stderr | 2 +- tests/ui/ufcs/ufcs-qpath-self-mismatch.stderr | 8 +-- 48 files changed, 257 insertions(+), 257 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 3cc46b5c6382..9186241d6074 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 @@ -2117,7 +2117,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { }) .collect(); - impl_candidates.sort(); + impl_candidates.sort_by_key(|tr| tr.to_string()); impl_candidates.dedup(); return report(impl_candidates, err); } @@ -2143,7 +2143,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { cand }) .collect(); - impl_candidates.sort_by_key(|cand| (cand.similarity, cand.trait_ref)); + impl_candidates.sort_by_key(|cand| (cand.similarity, cand.trait_ref.to_string())); let mut impl_candidates: Vec<_> = impl_candidates.into_iter().map(|cand| cand.trait_ref).collect(); impl_candidates.dedup(); diff --git a/tests/ui/binop/binary-op-suggest-deref.stderr b/tests/ui/binop/binary-op-suggest-deref.stderr index 8a226d712ff5..32bd2554abb6 100644 --- a/tests/ui/binop/binary-op-suggest-deref.stderr +++ b/tests/ui/binop/binary-op-suggest-deref.stderr @@ -247,14 +247,14 @@ LL | _ = &&0 == Foo; | = help: the trait `PartialEq` is not implemented for `&&{integer}` = help: the following other types implement trait `PartialEq`: - isize - i8 + f32 + f64 + i128 i16 i32 i64 - i128 - usize - u8 + i8 + isize and 6 others error[E0369]: binary operation `==` cannot be applied to type `Foo` @@ -303,10 +303,10 @@ LL | let _ = FOO & (*"Sized".to_string().into_boxed_str()); | = help: the trait `BitAnd` is not implemented for `i32` = help: the following other types implement trait `BitAnd`: - - > <&'a i32 as BitAnd> <&i32 as BitAnd<&i32>> + > + error[E0277]: the size for values of type `str` cannot be known at compilation time --> $DIR/binary-op-suggest-deref.rs:78:17 diff --git a/tests/ui/binop/binop-mul-i32-f32.stderr b/tests/ui/binop/binop-mul-i32-f32.stderr index 6ed3e7b44476..29e1ff918340 100644 --- a/tests/ui/binop/binop-mul-i32-f32.stderr +++ b/tests/ui/binop/binop-mul-i32-f32.stderr @@ -6,10 +6,10 @@ LL | x * y | = help: the trait `Mul` is not implemented for `i32` = help: the following other types implement trait `Mul`: - - > <&'a i32 as Mul> <&i32 as Mul<&i32>> + > + error: aborting due to 1 previous error diff --git a/tests/ui/binop/shift-various-bad-types.stderr b/tests/ui/binop/shift-various-bad-types.stderr index b43672ef3b56..38db66f86b46 100644 --- a/tests/ui/binop/shift-various-bad-types.stderr +++ b/tests/ui/binop/shift-various-bad-types.stderr @@ -6,14 +6,14 @@ LL | 22 >> p.char; | = help: the trait `Shr` is not implemented for `{integer}` = help: the following other types implement trait `Shr`: - - > - > - > - > - > - > - > + <&'a i128 as Shr> + <&'a i128 as Shr> + <&'a i128 as Shr> + <&'a i128 as Shr> + <&'a i128 as Shr> + <&'a i128 as Shr> + <&'a i128 as Shr> + <&'a i128 as Shr> and 568 others error[E0277]: no implementation for `{integer} >> &str` @@ -24,14 +24,14 @@ LL | 22 >> p.str; | = help: the trait `Shr<&str>` is not implemented for `{integer}` = help: the following other types implement trait `Shr`: - - > - > - > - > - > - > - > + <&'a i128 as Shr> + <&'a i128 as Shr> + <&'a i128 as Shr> + <&'a i128 as Shr> + <&'a i128 as Shr> + <&'a i128 as Shr> + <&'a i128 as Shr> + <&'a i128 as Shr> and 568 others error[E0277]: no implementation for `{integer} >> &Panolpy` @@ -42,14 +42,14 @@ LL | 22 >> p; | = help: the trait `Shr<&Panolpy>` is not implemented for `{integer}` = help: the following other types implement trait `Shr`: - - > - > - > - > - > - > - > + <&'a i128 as Shr> + <&'a i128 as Shr> + <&'a i128 as Shr> + <&'a i128 as Shr> + <&'a i128 as Shr> + <&'a i128 as Shr> + <&'a i128 as Shr> + <&'a i128 as Shr> and 568 others error[E0308]: mismatched types diff --git a/tests/ui/const-generics/exhaustive-value.stderr b/tests/ui/const-generics/exhaustive-value.stderr index 42814c1fb705..acaa0cf1a508 100644 --- a/tests/ui/const-generics/exhaustive-value.stderr +++ b/tests/ui/const-generics/exhaustive-value.stderr @@ -6,13 +6,13 @@ LL | <() as Foo>::test() | = help: the following other types implement trait `Foo`: <() as Foo<0>> - <() as Foo<1>> - <() as Foo<2>> - <() as Foo<3>> - <() as Foo<4>> - <() as Foo<5>> - <() as Foo<6>> - <() as Foo<7>> + <() as Foo<100>> + <() as Foo<101>> + <() as Foo<102>> + <() as Foo<103>> + <() as Foo<104>> + <() as Foo<105>> + <() as Foo<106>> and 248 others error: aborting due to 1 previous error diff --git a/tests/ui/const-generics/generic_arg_infer/issue-91614.stderr b/tests/ui/const-generics/generic_arg_infer/issue-91614.stderr index 6d3b0b8508c0..5b296a14869f 100644 --- a/tests/ui/const-generics/generic_arg_infer/issue-91614.stderr +++ b/tests/ui/const-generics/generic_arg_infer/issue-91614.stderr @@ -6,11 +6,11 @@ LL | let y = Mask::<_, _>::splat(false); | = note: cannot satisfy `_: MaskElement` = help: the following types implement trait `MaskElement`: - isize - i8 i16 i32 i64 + i8 + isize note: required by a bound in `Mask::::splat` --> $SRC_DIR/core/src/../../portable-simd/crates/core_simd/src/masks.rs:LL:COL help: consider giving `y` an explicit type, where the type for type parameter `T` is specified diff --git a/tests/ui/const-generics/issues/issue-67185-2.stderr b/tests/ui/const-generics/issues/issue-67185-2.stderr index e39d43205c1d..5cc3bb673bc4 100644 --- a/tests/ui/const-generics/issues/issue-67185-2.stderr +++ b/tests/ui/const-generics/issues/issue-67185-2.stderr @@ -5,8 +5,8 @@ LL | ::Quaks: Bar, | ^^^^^^^^^^^^^^^^^^^^^^^ the trait `Bar` is not implemented for `[u16; 3]` | = help: the following other types implement trait `Bar`: - [u16; 4] [[u16; 3]; 3] + [u16; 4] = help: see issue #48214 help: add `#![feature(trivial_bounds)]` to the crate attributes to enable | @@ -20,8 +20,8 @@ LL | [::Quaks; 2]: Bar, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Bar` is not implemented for `[[u16; 3]; 2]` | = help: the following other types implement trait `Bar`: - [u16; 4] [[u16; 3]; 3] + [u16; 4] = help: see issue #48214 help: add `#![feature(trivial_bounds)]` to the crate attributes to enable | @@ -35,8 +35,8 @@ LL | impl Foo for FooImpl {} | ^^^ the trait `Bar` is not implemented for `[u16; 3]`, which is required by `::Quaks: Bar` | = help: the following other types implement trait `Bar`: - [u16; 4] [[u16; 3]; 3] + [u16; 4] note: required by a bound in `Foo` --> $DIR/issue-67185-2.rs:15:25 | @@ -53,8 +53,8 @@ LL | impl Foo for FooImpl {} | ^^^ the trait `Bar` is not implemented for `[[u16; 3]; 2]`, which is required by `[::Quaks; 2]: Bar` | = help: the following other types implement trait `Bar`: - [u16; 4] [[u16; 3]; 3] + [u16; 4] note: required by a bound in `Foo` --> $DIR/issue-67185-2.rs:14:30 | @@ -71,8 +71,8 @@ LL | fn f(_: impl Foo) {} | ^^^ the trait `Bar` is not implemented for `[[u16; 3]; 2]` | = help: the following other types implement trait `Bar`: - [u16; 4] [[u16; 3]; 3] + [u16; 4] note: required by a bound in `Foo` --> $DIR/issue-67185-2.rs:14:30 | @@ -89,8 +89,8 @@ LL | fn f(_: impl Foo) {} | ^^^ the trait `Bar` is not implemented for `[u16; 3]` | = help: the following other types implement trait `Bar`: - [u16; 4] [[u16; 3]; 3] + [u16; 4] note: required by a bound in `Foo` --> $DIR/issue-67185-2.rs:15:25 | diff --git a/tests/ui/consts/const-eval/const-eval-overflow-3b.stderr b/tests/ui/consts/const-eval/const-eval-overflow-3b.stderr index 06e398edca9a..05f33c33946a 100644 --- a/tests/ui/consts/const-eval/const-eval-overflow-3b.stderr +++ b/tests/ui/consts/const-eval/const-eval-overflow-3b.stderr @@ -12,10 +12,10 @@ LL | = [0; (i8::MAX + 1u8) as usize]; | = help: the trait `Add` is not implemented for `i8` = help: the following other types implement trait `Add`: - - > <&'a i8 as Add> <&i8 as Add<&i8>> + > + error: aborting due to 2 previous errors diff --git a/tests/ui/consts/const-eval/const-eval-overflow-4b.stderr b/tests/ui/consts/const-eval/const-eval-overflow-4b.stderr index 07ef2ac090f7..d019f5920b51 100644 --- a/tests/ui/consts/const-eval/const-eval-overflow-4b.stderr +++ b/tests/ui/consts/const-eval/const-eval-overflow-4b.stderr @@ -12,10 +12,10 @@ LL | : [u32; (i8::MAX as i8 + 1u8) as usize] | = help: the trait `Add` is not implemented for `i8` = help: the following other types implement trait `Add`: - - > <&'a i8 as Add> <&i8 as Add<&i8>> + > + error[E0604]: only `u8` can be cast as `char`, not `i8` --> $DIR/const-eval-overflow-4b.rs:22:13 diff --git a/tests/ui/consts/missing-larger-array-impl.stderr b/tests/ui/consts/missing-larger-array-impl.stderr index acf38d00ec64..ff4fa36d684c 100644 --- a/tests/ui/consts/missing-larger-array-impl.stderr +++ b/tests/ui/consts/missing-larger-array-impl.stderr @@ -5,14 +5,14 @@ LL | <[X; 35] as Default>::default(); | ^^^^^^^ the trait `Default` is not implemented for `[X; 35]` | = help: the following other types implement trait `Default`: + &[T] + &mut [T] [T; 0] - [T; 1] - [T; 2] - [T; 3] - [T; 4] - [T; 5] - [T; 6] - [T; 7] + [T; 10] + [T; 11] + [T; 12] + [T; 13] + [T; 14] and 27 others error: aborting due to 1 previous error diff --git a/tests/ui/consts/too_generic_eval_ice.stderr b/tests/ui/consts/too_generic_eval_ice.stderr index 4089c850c802..54dffa3befcf 100644 --- a/tests/ui/consts/too_generic_eval_ice.stderr +++ b/tests/ui/consts/too_generic_eval_ice.stderr @@ -22,14 +22,14 @@ LL | [5; Self::HOST_SIZE] == [6; 0] | = help: the trait `PartialEq<[{integer}; 0]>` is not implemented for `[{integer}; Self::HOST_SIZE]` = help: the following other types implement trait `PartialEq`: - <[T; N] as PartialEq<[U; N]>> - <[T; N] as PartialEq<[U]>> + <&[T] as PartialEq>> + <&[T] as PartialEq<[U; N]>> + <&mut [T] as PartialEq>> + <&mut [T] as PartialEq<[U; N]>> <[T; N] as PartialEq<&[U]>> <[T; N] as PartialEq<&mut [U]>> - <[T] as PartialEq>> - <[T] as PartialEq<[U; N]>> - <[T] as PartialEq<[U]>> - <&[T] as PartialEq>> + <[T; N] as PartialEq<[U; N]>> + <[T; N] as PartialEq<[U]>> and 3 others error: aborting due to 3 previous errors diff --git a/tests/ui/deriving/issue-103157.stderr b/tests/ui/deriving/issue-103157.stderr index f76701860efb..612a7aff2254 100644 --- a/tests/ui/deriving/issue-103157.stderr +++ b/tests/ui/deriving/issue-103157.stderr @@ -8,14 +8,14 @@ LL | Float(Option), | ^^^^^^^^^^^ the trait `Eq` is not implemented for `f64`, which is required by `Option: Eq` | = help: the following other types implement trait `Eq`: - isize - i8 + i128 i16 i32 i64 - i128 - usize - u8 + i8 + isize + u128 + u16 and 4 others = note: required for `Option` to implement `Eq` note: required by a bound in `AssertParamIsEq` diff --git a/tests/ui/did_you_mean/issue-21659-show-relevant-trait-impls-2.stderr b/tests/ui/did_you_mean/issue-21659-show-relevant-trait-impls-2.stderr index 6ac0bf21e4ac..a2b7d804cb8c 100644 --- a/tests/ui/did_you_mean/issue-21659-show-relevant-trait-impls-2.stderr +++ b/tests/ui/did_you_mean/issue-21659-show-relevant-trait-impls-2.stderr @@ -7,12 +7,12 @@ LL | f1.foo(1usize); | required by a bound introduced by this call | = help: the following other types implement trait `Foo
`: - > > > - > + > > > + > error: aborting due to 1 previous error diff --git a/tests/ui/did_you_mean/issue-39802-show-5-trait-impls.stderr b/tests/ui/did_you_mean/issue-39802-show-5-trait-impls.stderr index ae15e054f628..7229b9ac986a 100644 --- a/tests/ui/did_you_mean/issue-39802-show-5-trait-impls.stderr +++ b/tests/ui/did_you_mean/issue-39802-show-5-trait-impls.stderr @@ -8,10 +8,10 @@ LL | Foo::::bar(&1i8); | = help: the following other types implement trait `Foo`: > - > > > > + > error[E0277]: the trait bound `u8: Foo` is not satisfied --> $DIR/issue-39802-show-5-trait-impls.rs:25:21 @@ -38,10 +38,10 @@ LL | Foo::::bar(&true); = help: the following other types implement trait `Foo`: > > - > > > > + > error: aborting due to 3 previous errors diff --git a/tests/ui/fmt/ifmt-unimpl.stderr b/tests/ui/fmt/ifmt-unimpl.stderr index 3c5428e59fb5..a22bba07c027 100644 --- a/tests/ui/fmt/ifmt-unimpl.stderr +++ b/tests/ui/fmt/ifmt-unimpl.stderr @@ -7,14 +7,14 @@ LL | format!("{:X}", "3"); | required by a bound introduced by this call | = help: the following other types implement trait `UpperHex`: - isize - i8 + &T + &mut T + NonZero + Saturating + Wrapping + i128 i16 i32 - i64 - i128 - usize - u8 and 9 others = note: required for `&str` to implement `UpperHex` note: required by a bound in `core::fmt::rt::Argument::<'a>::new_upper_hex` diff --git a/tests/ui/impl-trait/equality.stderr b/tests/ui/impl-trait/equality.stderr index 9b8bff215e02..69f4cbbbf429 100644 --- a/tests/ui/impl-trait/equality.stderr +++ b/tests/ui/impl-trait/equality.stderr @@ -30,10 +30,10 @@ LL | n + sum_to(n - 1) | = help: the trait `Add` is not implemented for `u32` = help: the following other types implement trait `Add`: - - > <&'a u32 as Add> <&u32 as Add<&u32>> + > + error: aborting due to 2 previous errors; 1 warning emitted diff --git a/tests/ui/impl-trait/impl_trait_projections.stderr b/tests/ui/impl-trait/impl_trait_projections.stderr index 421afc96eed0..d62e3ac4183f 100644 --- a/tests/ui/impl-trait/impl_trait_projections.stderr +++ b/tests/ui/impl-trait/impl_trait_projections.stderr @@ -35,14 +35,14 @@ LL | -> <::std::ops::Range as Iterator>::Item | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Step` is not implemented for `impl Debug`, which is required by `std::ops::Range: Iterator` | = help: the following other types implement trait `Step`: + Char + Ipv4Addr + Ipv6Addr char - isize - i8 + i128 i16 i32 i64 - i128 - usize and 8 others = note: required for `std::ops::Range` to implement `Iterator` @@ -56,14 +56,14 @@ LL | | } | |_^ the trait `Step` is not implemented for `impl Debug`, which is required by `std::ops::Range: Iterator` | = help: the following other types implement trait `Step`: + Char + Ipv4Addr + Ipv6Addr char - isize - i8 + i128 i16 i32 i64 - i128 - usize and 8 others = note: required for `std::ops::Range` to implement `Iterator` diff --git a/tests/ui/issues/issue-11771.stderr b/tests/ui/issues/issue-11771.stderr index b37140f60f9c..161fce4b0315 100644 --- a/tests/ui/issues/issue-11771.stderr +++ b/tests/ui/issues/issue-11771.stderr @@ -6,14 +6,14 @@ LL | 1 + | = help: the trait `Add<()>` is not implemented for `{integer}` = help: the following other types implement trait `Add`: - - > - - > - - > - - > + <&'a f32 as Add> + <&'a f64 as Add> + <&'a i128 as Add> + <&'a i16 as Add> + <&'a i32 as Add> + <&'a i64 as Add> + <&'a i8 as Add> + <&'a isize as Add> and 48 others error[E0277]: cannot add `()` to `{integer}` @@ -24,14 +24,14 @@ LL | 1 + | = help: the trait `Add<()>` is not implemented for `{integer}` = help: the following other types implement trait `Add`: - - > - - > - - > - - > + <&'a f32 as Add> + <&'a f64 as Add> + <&'a i128 as Add> + <&'a i16 as Add> + <&'a i32 as Add> + <&'a i64 as Add> + <&'a i8 as Add> + <&'a isize as Add> and 48 others error: aborting due to 2 previous errors diff --git a/tests/ui/issues/issue-24352.stderr b/tests/ui/issues/issue-24352.stderr index 015569cce06b..a9f886158e1d 100644 --- a/tests/ui/issues/issue-24352.stderr +++ b/tests/ui/issues/issue-24352.stderr @@ -6,10 +6,10 @@ LL | 1.0f64 - 1 | = help: the trait `Sub<{integer}>` is not implemented for `f64` = help: the following other types implement trait `Sub`: - - > <&'a f64 as Sub> <&f64 as Sub<&f64>> + > + help: consider using a floating-point literal by writing it with `.0` | LL | 1.0f64 - 1.0 diff --git a/tests/ui/issues/issue-50582.stderr b/tests/ui/issues/issue-50582.stderr index 7b65fa25ae37..1967b51128f6 100644 --- a/tests/ui/issues/issue-50582.stderr +++ b/tests/ui/issues/issue-50582.stderr @@ -16,14 +16,14 @@ LL | Vec::<[(); 1 + for x in 0..1 {}]>::new(); | = help: the trait `Add<()>` is not implemented for `{integer}` = help: the following other types implement trait `Add`: - - > - - > - - > - - > + <&'a f32 as Add> + <&'a f64 as Add> + <&'a i128 as Add> + <&'a i16 as Add> + <&'a i32 as Add> + <&'a i64 as Add> + <&'a i8 as Add> + <&'a isize as Add> and 48 others error: aborting due to 2 previous errors diff --git a/tests/ui/iterators/invalid-iterator-chain-fixable.stderr b/tests/ui/iterators/invalid-iterator-chain-fixable.stderr index 1bfe765e78af..4d1e4207fdcb 100644 --- a/tests/ui/iterators/invalid-iterator-chain-fixable.stderr +++ b/tests/ui/iterators/invalid-iterator-chain-fixable.stderr @@ -33,8 +33,8 @@ LL | println!("{}", scores.sum::()); | = help: the trait `Sum<()>` is not implemented for `i32` = help: the following other types implement trait `Sum`: - > + note: the method call chain might not have had the expected associated types --> $DIR/invalid-iterator-chain-fixable.rs:14:10 | @@ -66,8 +66,8 @@ LL | .sum::(), | = help: the trait `Sum<()>` is not implemented for `i32` = help: the following other types implement trait `Sum`: - > + note: the method call chain might not have had the expected associated types --> $DIR/invalid-iterator-chain-fixable.rs:23:14 | @@ -99,8 +99,8 @@ LL | println!("{}", vec![0, 1].iter().map(|x| { x; }).sum::()); | = help: the trait `Sum<()>` is not implemented for `i32` = help: the following other types implement trait `Sum`: - > + note: the method call chain might not have had the expected associated types --> $DIR/invalid-iterator-chain-fixable.rs:27:38 | diff --git a/tests/ui/iterators/invalid-iterator-chain-with-int-infer.stderr b/tests/ui/iterators/invalid-iterator-chain-with-int-infer.stderr index f68c596367e5..9381a98e0778 100644 --- a/tests/ui/iterators/invalid-iterator-chain-with-int-infer.stderr +++ b/tests/ui/iterators/invalid-iterator-chain-with-int-infer.stderr @@ -8,8 +8,8 @@ LL | let x = Some(()).iter().map(|()| 1).sum::(); | = help: the trait `Sum<{integer}>` is not implemented for `f32` = help: the following other types implement trait `Sum`: - > + note: the method call chain might not have had the expected associated types --> $DIR/invalid-iterator-chain-with-int-infer.rs:2:29 | diff --git a/tests/ui/iterators/invalid-iterator-chain.stderr b/tests/ui/iterators/invalid-iterator-chain.stderr index 4dc130869123..6129a724f447 100644 --- a/tests/ui/iterators/invalid-iterator-chain.stderr +++ b/tests/ui/iterators/invalid-iterator-chain.stderr @@ -33,8 +33,8 @@ LL | println!("{}", scores.sum::()); | = help: the trait `Sum<()>` is not implemented for `i32` = help: the following other types implement trait `Sum`: - > + note: the method call chain might not have had the expected associated types --> $DIR/invalid-iterator-chain.rs:12:10 | @@ -65,8 +65,8 @@ LL | .sum::(), | = help: the trait `Sum<()>` is not implemented for `i32` = help: the following other types implement trait `Sum`: - > + note: the method call chain might not have had the expected associated types --> $DIR/invalid-iterator-chain.rs:25:14 | @@ -104,8 +104,8 @@ LL | .sum::(), | = help: the trait `Sum` is not implemented for `i32` = help: the following other types implement trait `Sum`: - > + note: the method call chain might not have had the expected associated types --> $DIR/invalid-iterator-chain.rs:33:14 | @@ -134,8 +134,8 @@ LL | println!("{}", vec![0, 1].iter().map(|x| { x; }).sum::()); | = help: the trait `Sum<()>` is not implemented for `i32` = help: the following other types implement trait `Sum`: - > + note: the method call chain might not have had the expected associated types --> $DIR/invalid-iterator-chain.rs:38:38 | @@ -162,8 +162,8 @@ LL | println!("{}", vec![(), ()].iter().sum::()); | = help: the trait `Sum<&()>` is not implemented for `i32` = help: the following other types implement trait `Sum`: - > + note: the method call chain might not have had the expected associated types --> $DIR/invalid-iterator-chain.rs:39:33 | diff --git a/tests/ui/lazy-type-alias/trailing-where-clause.stderr b/tests/ui/lazy-type-alias/trailing-where-clause.stderr index baf4215bbf78..534df382eb6e 100644 --- a/tests/ui/lazy-type-alias/trailing-where-clause.stderr +++ b/tests/ui/lazy-type-alias/trailing-where-clause.stderr @@ -5,12 +5,12 @@ LL | let _: Alias<()>; | ^^ the trait `From<()>` is not implemented for `String` | = help: the following other types implement trait `From`: - > + > + > + > >> >> - > - > - > + > note: required by a bound in `Alias` --> $DIR/trailing-where-clause.rs:8:13 | diff --git a/tests/ui/mismatched_types/binops.stderr b/tests/ui/mismatched_types/binops.stderr index b18ab7f7608d..3585587ed4c0 100644 --- a/tests/ui/mismatched_types/binops.stderr +++ b/tests/ui/mismatched_types/binops.stderr @@ -6,14 +6,14 @@ LL | 1 + Some(1); | = help: the trait `Add>` is not implemented for `{integer}` = help: the following other types implement trait `Add`: - - > - - > - - > - - > + <&'a f32 as Add> + <&'a f64 as Add> + <&'a i128 as Add> + <&'a i16 as Add> + <&'a i32 as Add> + <&'a i64 as Add> + <&'a i8 as Add> + <&'a isize as Add> and 48 others error[E0277]: cannot subtract `Option<{integer}>` from `usize` @@ -24,10 +24,10 @@ LL | 2 as usize - Some(1); | = help: the trait `Sub>` is not implemented for `usize` = help: the following other types implement trait `Sub`: - - > <&'a usize as Sub> <&usize as Sub<&usize>> + > + error[E0277]: cannot multiply `{integer}` by `()` --> $DIR/binops.rs:4:7 @@ -37,14 +37,14 @@ LL | 3 * (); | = help: the trait `Mul<()>` is not implemented for `{integer}` = help: the following other types implement trait `Mul`: - - > - - > - - > - - > + <&'a f32 as Mul> + <&'a f64 as Mul> + <&'a i128 as Mul> + <&'a i16 as Mul> + <&'a i32 as Mul> + <&'a i64 as Mul> + <&'a i8 as Mul> + <&'a isize as Mul> and 49 others error[E0277]: cannot divide `{integer}` by `&str` @@ -55,14 +55,14 @@ LL | 4 / ""; | = help: the trait `Div<&str>` is not implemented for `{integer}` = help: the following other types implement trait `Div`: - - > - - > - - > - - > + <&'a f32 as Div> + <&'a f64 as Div> + <&'a i128 as Div> + <&'a i16 as Div> + <&'a i32 as Div> + <&'a i64 as Div> + <&'a i8 as Div> + <&'a isize as Div> and 54 others error[E0277]: can't compare `{integer}` with `String` @@ -73,14 +73,14 @@ LL | 5 < String::new(); | = help: the trait `PartialOrd` is not implemented for `{integer}` = help: the following other types implement trait `PartialOrd`: - isize - i8 + f32 + f64 + i128 i16 i32 i64 - i128 - usize - u8 + i8 + isize and 6 others error[E0277]: can't compare `{integer}` with `Result<{integer}, _>` @@ -91,14 +91,14 @@ LL | 6 == Ok(1); | = help: the trait `PartialEq>` is not implemented for `{integer}` = help: the following other types implement trait `PartialEq`: - isize - i8 + f32 + f64 + i128 i16 i32 i64 - i128 - usize - u8 + i8 + isize and 6 others error: aborting due to 6 previous errors diff --git a/tests/ui/never_type/diverging-fallback-no-leak.fallback.stderr b/tests/ui/never_type/diverging-fallback-no-leak.fallback.stderr index ff28480bd995..01abf2e17f1e 100644 --- a/tests/ui/never_type/diverging-fallback-no-leak.fallback.stderr +++ b/tests/ui/never_type/diverging-fallback-no-leak.fallback.stderr @@ -7,8 +7,8 @@ LL | unconstrained_arg(return); | required by a bound introduced by this call | = help: the following other types implement trait `Test`: - i32 () + i32 = note: this error might have been caused by changes to Rust's type-inference algorithm (see issue #48950 for more information) = help: did you intend to use the type `()` here instead? note: required by a bound in `unconstrained_arg` diff --git a/tests/ui/never_type/issue-13352.stderr b/tests/ui/never_type/issue-13352.stderr index 91885380b1ff..1b979d934462 100644 --- a/tests/ui/never_type/issue-13352.stderr +++ b/tests/ui/never_type/issue-13352.stderr @@ -6,10 +6,10 @@ LL | 2_usize + (loop {}); | = help: the trait `Add<()>` is not implemented for `usize` = help: the following other types implement trait `Add`: - - > <&'a usize as Add> <&usize as Add<&usize>> + > + error: aborting due to 1 previous error diff --git a/tests/ui/numbers-arithmetic/not-suggest-float-literal.stderr b/tests/ui/numbers-arithmetic/not-suggest-float-literal.stderr index be0fc0f98e24..14685a3f9371 100644 --- a/tests/ui/numbers-arithmetic/not-suggest-float-literal.stderr +++ b/tests/ui/numbers-arithmetic/not-suggest-float-literal.stderr @@ -6,10 +6,10 @@ LL | x + 100.0 | = help: the trait `Add<{float}>` is not implemented for `u8` = help: the following other types implement trait `Add`: - - > <&'a u8 as Add> <&u8 as Add<&u8>> + > + error[E0277]: cannot add `&str` to `f64` --> $DIR/not-suggest-float-literal.rs:6:7 @@ -19,10 +19,10 @@ LL | x + "foo" | = help: the trait `Add<&str>` is not implemented for `f64` = help: the following other types implement trait `Add`: - - > <&'a f64 as Add> <&f64 as Add<&f64>> + > + error[E0277]: cannot add `{integer}` to `f64` --> $DIR/not-suggest-float-literal.rs:11:7 @@ -32,10 +32,10 @@ LL | x + y | = help: the trait `Add<{integer}>` is not implemented for `f64` = help: the following other types implement trait `Add`: - - > <&'a f64 as Add> <&f64 as Add<&f64>> + > + error[E0277]: cannot subtract `{float}` from `u8` --> $DIR/not-suggest-float-literal.rs:15:7 @@ -45,10 +45,10 @@ LL | x - 100.0 | = help: the trait `Sub<{float}>` is not implemented for `u8` = help: the following other types implement trait `Sub`: - - > <&'a u8 as Sub> <&u8 as Sub<&u8>> + > + error[E0277]: cannot subtract `&str` from `f64` --> $DIR/not-suggest-float-literal.rs:19:7 @@ -58,10 +58,10 @@ LL | x - "foo" | = help: the trait `Sub<&str>` is not implemented for `f64` = help: the following other types implement trait `Sub`: - - > <&'a f64 as Sub> <&f64 as Sub<&f64>> + > + error[E0277]: cannot subtract `{integer}` from `f64` --> $DIR/not-suggest-float-literal.rs:24:7 @@ -71,10 +71,10 @@ LL | x - y | = help: the trait `Sub<{integer}>` is not implemented for `f64` = help: the following other types implement trait `Sub`: - - > <&'a f64 as Sub> <&f64 as Sub<&f64>> + > + error[E0277]: cannot multiply `u8` by `{float}` --> $DIR/not-suggest-float-literal.rs:28:7 @@ -84,10 +84,10 @@ LL | x * 100.0 | = help: the trait `Mul<{float}>` is not implemented for `u8` = help: the following other types implement trait `Mul`: - - > <&'a u8 as Mul> <&u8 as Mul<&u8>> + > + error[E0277]: cannot multiply `f64` by `&str` --> $DIR/not-suggest-float-literal.rs:32:7 @@ -97,10 +97,10 @@ LL | x * "foo" | = help: the trait `Mul<&str>` is not implemented for `f64` = help: the following other types implement trait `Mul`: - - > <&'a f64 as Mul> <&f64 as Mul<&f64>> + > + error[E0277]: cannot multiply `f64` by `{integer}` --> $DIR/not-suggest-float-literal.rs:37:7 @@ -110,10 +110,10 @@ LL | x * y | = help: the trait `Mul<{integer}>` is not implemented for `f64` = help: the following other types implement trait `Mul`: - - > <&'a f64 as Mul> <&f64 as Mul<&f64>> + > + error[E0277]: cannot divide `u8` by `{float}` --> $DIR/not-suggest-float-literal.rs:41:7 @@ -123,11 +123,11 @@ LL | x / 100.0 | = help: the trait `Div<{float}>` is not implemented for `u8` = help: the following other types implement trait `Div`: - - >> - > <&'a u8 as Div> <&u8 as Div<&u8>> + > + >> + error[E0277]: cannot divide `f64` by `&str` --> $DIR/not-suggest-float-literal.rs:45:7 @@ -137,10 +137,10 @@ LL | x / "foo" | = help: the trait `Div<&str>` is not implemented for `f64` = help: the following other types implement trait `Div`: - - > <&'a f64 as Div> <&f64 as Div<&f64>> + > + error[E0277]: cannot divide `f64` by `{integer}` --> $DIR/not-suggest-float-literal.rs:50:7 @@ -150,10 +150,10 @@ LL | x / y | = help: the trait `Div<{integer}>` is not implemented for `f64` = help: the following other types implement trait `Div`: - - > <&'a f64 as Div> <&f64 as Div<&f64>> + > + error: aborting due to 12 previous errors diff --git a/tests/ui/numbers-arithmetic/suggest-float-literal.stderr b/tests/ui/numbers-arithmetic/suggest-float-literal.stderr index 929a9e3b5954..03779d356371 100644 --- a/tests/ui/numbers-arithmetic/suggest-float-literal.stderr +++ b/tests/ui/numbers-arithmetic/suggest-float-literal.stderr @@ -6,10 +6,10 @@ LL | x + 100 | = help: the trait `Add<{integer}>` is not implemented for `f32` = help: the following other types implement trait `Add`: - - > <&'a f32 as Add> <&f32 as Add<&f32>> + > + help: consider using a floating-point literal by writing it with `.0` | LL | x + 100.0 @@ -23,10 +23,10 @@ LL | x + 100 | = help: the trait `Add<{integer}>` is not implemented for `f64` = help: the following other types implement trait `Add`: - - > <&'a f64 as Add> <&f64 as Add<&f64>> + > + help: consider using a floating-point literal by writing it with `.0` | LL | x + 100.0 @@ -40,10 +40,10 @@ LL | x - 100 | = help: the trait `Sub<{integer}>` is not implemented for `f32` = help: the following other types implement trait `Sub`: - - > <&'a f32 as Sub> <&f32 as Sub<&f32>> + > + help: consider using a floating-point literal by writing it with `.0` | LL | x - 100.0 @@ -57,10 +57,10 @@ LL | x - 100 | = help: the trait `Sub<{integer}>` is not implemented for `f64` = help: the following other types implement trait `Sub`: - - > <&'a f64 as Sub> <&f64 as Sub<&f64>> + > + help: consider using a floating-point literal by writing it with `.0` | LL | x - 100.0 @@ -74,10 +74,10 @@ LL | x * 100 | = help: the trait `Mul<{integer}>` is not implemented for `f32` = help: the following other types implement trait `Mul`: - - > <&'a f32 as Mul> <&f32 as Mul<&f32>> + > + help: consider using a floating-point literal by writing it with `.0` | LL | x * 100.0 @@ -91,10 +91,10 @@ LL | x * 100 | = help: the trait `Mul<{integer}>` is not implemented for `f64` = help: the following other types implement trait `Mul`: - - > <&'a f64 as Mul> <&f64 as Mul<&f64>> + > + help: consider using a floating-point literal by writing it with `.0` | LL | x * 100.0 @@ -108,10 +108,10 @@ LL | x / 100 | = help: the trait `Div<{integer}>` is not implemented for `f32` = help: the following other types implement trait `Div`: - - > <&'a f32 as Div> <&f32 as Div<&f32>> + > + help: consider using a floating-point literal by writing it with `.0` | LL | x / 100.0 @@ -125,10 +125,10 @@ LL | x / 100 | = help: the trait `Div<{integer}>` is not implemented for `f64` = help: the following other types implement trait `Div`: - - > <&'a f64 as Div> <&f64 as Div<&f64>> + > + help: consider using a floating-point literal by writing it with `.0` | LL | x / 100.0 diff --git a/tests/ui/on-unimplemented/multiple-impls.stderr b/tests/ui/on-unimplemented/multiple-impls.stderr index f59c93a7c375..b50dc251baac 100644 --- a/tests/ui/on-unimplemented/multiple-impls.stderr +++ b/tests/ui/on-unimplemented/multiple-impls.stderr @@ -8,8 +8,8 @@ LL | Index::index(&[] as &[i32], 2u32); | = help: the trait `Index` is not implemented for `[i32]` = help: the following other types implement trait `Index`: - <[i32] as Index>> <[i32] as Index>> + <[i32] as Index>> error[E0277]: the trait bound `[i32]: Index>` is not satisfied --> $DIR/multiple-impls.rs:36:33 @@ -21,8 +21,8 @@ LL | Index::index(&[] as &[i32], Foo(2u32)); | = help: the trait `Index>` is not implemented for `[i32]` = help: the following other types implement trait `Index`: - <[i32] as Index>> <[i32] as Index>> + <[i32] as Index>> error[E0277]: the trait bound `[i32]: Index>` is not satisfied --> $DIR/multiple-impls.rs:39:33 @@ -34,8 +34,8 @@ LL | Index::index(&[] as &[i32], Bar(2u32)); | = help: the trait `Index>` is not implemented for `[i32]` = help: the following other types implement trait `Index`: - <[i32] as Index>> <[i32] as Index>> + <[i32] as Index>> error[E0277]: the trait bound `[i32]: Index` is not satisfied --> $DIR/multiple-impls.rs:33:5 @@ -45,8 +45,8 @@ LL | Index::index(&[] as &[i32], 2u32); | = help: the trait `Index` is not implemented for `[i32]` = help: the following other types implement trait `Index`: - <[i32] as Index>> <[i32] as Index>> + <[i32] as Index>> error[E0277]: the trait bound `[i32]: Index>` is not satisfied --> $DIR/multiple-impls.rs:36:5 @@ -56,8 +56,8 @@ LL | Index::index(&[] as &[i32], Foo(2u32)); | = help: the trait `Index>` is not implemented for `[i32]` = help: the following other types implement trait `Index`: - <[i32] as Index>> <[i32] as Index>> + <[i32] as Index>> error[E0277]: the trait bound `[i32]: Index>` is not satisfied --> $DIR/multiple-impls.rs:39:5 @@ -67,8 +67,8 @@ LL | Index::index(&[] as &[i32], Bar(2u32)); | = help: the trait `Index>` is not implemented for `[i32]` = help: the following other types implement trait `Index`: - <[i32] as Index>> <[i32] as Index>> + <[i32] as Index>> error: aborting due to 6 previous errors diff --git a/tests/ui/on-unimplemented/slice-index.stderr b/tests/ui/on-unimplemented/slice-index.stderr index c0314fa42d72..f17f3cfce8de 100644 --- a/tests/ui/on-unimplemented/slice-index.stderr +++ b/tests/ui/on-unimplemented/slice-index.stderr @@ -17,8 +17,8 @@ LL | x[..1i32]; | = help: the trait `SliceIndex<[i32]>` is not implemented for `RangeTo`, which is required by `[i32]: Index<_>` = help: the following other types implement trait `SliceIndex`: - as SliceIndex> as SliceIndex<[T]>> + as SliceIndex> = note: required for `[i32]` to implement `Index>` error: aborting due to 2 previous errors diff --git a/tests/ui/on-unimplemented/sum.stderr b/tests/ui/on-unimplemented/sum.stderr index 257dec200743..65bab458cf18 100644 --- a/tests/ui/on-unimplemented/sum.stderr +++ b/tests/ui/on-unimplemented/sum.stderr @@ -8,8 +8,8 @@ LL | vec![(), ()].iter().sum::(); | = help: the trait `Sum<&()>` is not implemented for `i32` = help: the following other types implement trait `Sum`: - > + note: the method call chain might not have had the expected associated types --> $DIR/sum.rs:4:18 | @@ -30,8 +30,8 @@ LL | vec![(), ()].iter().product::(); | = help: the trait `Product<&()>` is not implemented for `i32` = help: the following other types implement trait `Product`: - > + note: the method call chain might not have had the expected associated types --> $DIR/sum.rs:7:18 | diff --git a/tests/ui/range/range-1.stderr b/tests/ui/range/range-1.stderr index 3d9b7a940b7c..f98420557c62 100644 --- a/tests/ui/range/range-1.stderr +++ b/tests/ui/range/range-1.stderr @@ -11,14 +11,14 @@ LL | for i in false..true {} | ^^^^^^^^^^^ the trait `Step` is not implemented for `bool`, which is required by `std::ops::Range: IntoIterator` | = help: the following other types implement trait `Step`: + Char + Ipv4Addr + Ipv6Addr char - isize - i8 + i128 i16 i32 i64 - i128 - usize and 8 others = note: required for `std::ops::Range` to implement `Iterator` = note: required for `std::ops::Range` to implement `IntoIterator` diff --git a/tests/ui/span/multiline-span-simple.stderr b/tests/ui/span/multiline-span-simple.stderr index f0eec632aa1c..2de792b03d72 100644 --- a/tests/ui/span/multiline-span-simple.stderr +++ b/tests/ui/span/multiline-span-simple.stderr @@ -6,10 +6,10 @@ LL | foo(1 as u32 + | = help: the trait `Add<()>` is not implemented for `u32` = help: the following other types implement trait `Add`: - - > <&'a u32 as Add> <&u32 as Add<&u32>> + > + error: aborting due to 1 previous error diff --git a/tests/ui/suggestions/impl-trait-return-trailing-semicolon.stderr b/tests/ui/suggestions/impl-trait-return-trailing-semicolon.stderr index 6465eeb8bc62..e74c2c4214fe 100644 --- a/tests/ui/suggestions/impl-trait-return-trailing-semicolon.stderr +++ b/tests/ui/suggestions/impl-trait-return-trailing-semicolon.stderr @@ -16,8 +16,8 @@ LL | fn bar() -> impl Bar { | ^^^^^^^^ the trait `Bar` is not implemented for `()` | = help: the following other types implement trait `Bar`: - i32 Qux + i32 error: aborting due to 2 previous errors diff --git a/tests/ui/suggestions/into-str.stderr b/tests/ui/suggestions/into-str.stderr index d10a294c7d2d..2fdfab8bdc54 100644 --- a/tests/ui/suggestions/into-str.stderr +++ b/tests/ui/suggestions/into-str.stderr @@ -8,12 +8,12 @@ LL | foo(String::new()); | = note: to coerce a `String` into a `&str`, use `&*` as a prefix = help: the following other types implement trait `From`: - > + > + > + > >> >> - > - > - > + > = note: required for `String` to implement `Into<&str>` note: required by a bound in `foo` --> $DIR/into-str.rs:1:31 diff --git a/tests/ui/suggestions/issue-71394-no-from-impl.stderr b/tests/ui/suggestions/issue-71394-no-from-impl.stderr index 0f6bfbeec45f..e626b5b0eb7c 100644 --- a/tests/ui/suggestions/issue-71394-no-from-impl.stderr +++ b/tests/ui/suggestions/issue-71394-no-from-impl.stderr @@ -5,14 +5,14 @@ LL | let _: &[i8] = data.into(); | ^^^^ the trait `From<&[u8]>` is not implemented for `&[i8]`, which is required by `&[u8]: Into<_>` | = help: the following other types implement trait `From`: - <[bool; N] as From>> - <[T; N] as From>> + <[T; 10] as From<(T, T, T, T, T, T, T, T, T, T)>> + <[T; 11] as From<(T, T, T, T, T, T, T, T, T, T, T)>> + <[T; 12] as From<(T, T, T, T, T, T, T, T, T, T, T, T)>> <[T; 1] as From<(T,)>> <[T; 2] as From<(T, T)>> <[T; 3] as From<(T, T, T)>> <[T; 4] as From<(T, T, T, T)>> <[T; 5] as From<(T, T, T, T, T)>> - <[T; 6] as From<(T, T, T, T, T, T)>> and 6 others = note: required for `&[u8]` to implement `Into<&[i8]>` diff --git a/tests/ui/traits/bound/assoc-fn-bound-root-obligation.stderr b/tests/ui/traits/bound/assoc-fn-bound-root-obligation.stderr index bd9838bc6235..27006f59b902 100644 --- a/tests/ui/traits/bound/assoc-fn-bound-root-obligation.stderr +++ b/tests/ui/traits/bound/assoc-fn-bound-root-obligation.stderr @@ -6,13 +6,13 @@ LL | s.strip_suffix(b'\n').unwrap_or(s) | = help: the trait `FnMut<(char,)>` is not implemented for `u8`, which is required by `u8: Pattern<'_>` = help: the following other types implement trait `Pattern<'a>`: - char - [char; N] &'b String &'b [char; N] &'b [char] - &'c &'b str &'b str + &'c &'b str + [char; N] + char = note: required for `u8` to implement `Pattern<'_>` error: aborting due to 1 previous error diff --git a/tests/ui/traits/question-mark-result-err-mismatch.stderr b/tests/ui/traits/question-mark-result-err-mismatch.stderr index 79f270fd1bbd..8a6c5fc10c5f 100644 --- a/tests/ui/traits/question-mark-result-err-mismatch.stderr +++ b/tests/ui/traits/question-mark-result-err-mismatch.stderr @@ -31,12 +31,12 @@ LL | .map_err(|_| ())?; | = note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait = help: the following other types implement trait `From`: - > + > + > + > >> >> - > - > - > + > = note: required for `Result<(), String>` to implement `FromResidual>` error[E0277]: `?` couldn't convert the error to `String` diff --git a/tests/ui/try-trait/bad-interconversion.stderr b/tests/ui/try-trait/bad-interconversion.stderr index 817acc8fc990..e3edec6a4c76 100644 --- a/tests/ui/try-trait/bad-interconversion.stderr +++ b/tests/ui/try-trait/bad-interconversion.stderr @@ -10,8 +10,8 @@ LL | Ok(Err(123_i32)?) | = note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait = help: the following other types implement trait `From`: - > > + > = note: required for `Result` to implement `FromResidual>` error[E0277]: the `?` operator can only be used on `Result`s, not `Option`s, in a function that returns `Result` @@ -24,8 +24,8 @@ LL | Some(3)?; | = help: the trait `FromResidual>` is not implemented for `Result` = help: the following other types implement trait `FromResidual`: - as FromResidual>> as FromResidual>> + as FromResidual>> error[E0277]: the `?` operator can only be used on `Result`s in a function that returns `Result` --> $DIR/bad-interconversion.rs:17:31 @@ -37,8 +37,8 @@ LL | Ok(ControlFlow::Break(123)?) | = help: the trait `FromResidual>` is not implemented for `Result` = help: the following other types implement trait `FromResidual`: - as FromResidual>> as FromResidual>> + as FromResidual>> error[E0277]: the `?` operator can only be used on `Option`s, not `Result`s, in a function that returns `Option` --> $DIR/bad-interconversion.rs:22:22 diff --git a/tests/ui/try-trait/issue-32709.stderr b/tests/ui/try-trait/issue-32709.stderr index 34618de78cd0..a0dd18fa039c 100644 --- a/tests/ui/try-trait/issue-32709.stderr +++ b/tests/ui/try-trait/issue-32709.stderr @@ -10,7 +10,6 @@ LL | Err(5)?; | = note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait = help: the following other types implement trait `From`: - <(T,) as From<[T; 1]>> <(T, T) as From<[T; 2]>> <(T, T, T) as From<[T; 3]>> <(T, T, T, T) as From<[T; 4]>> @@ -18,6 +17,7 @@ LL | Err(5)?; <(T, T, T, T, T, T) as From<[T; 6]>> <(T, T, T, T, T, T, T) as From<[T; 7]>> <(T, T, T, T, T, T, T, T) as From<[T; 8]>> + <(T, T, T, T, T, T, T, T, T) as From<[T; 9]>> and 4 others = note: required for `Result` to implement `FromResidual>` diff --git a/tests/ui/try-trait/option-to-result.stderr b/tests/ui/try-trait/option-to-result.stderr index 1c4d718f1eeb..fabc1ff2c762 100644 --- a/tests/ui/try-trait/option-to-result.stderr +++ b/tests/ui/try-trait/option-to-result.stderr @@ -9,8 +9,8 @@ LL | a?; | = help: the trait `FromResidual>` is not implemented for `Result<(), ()>` = help: the following other types implement trait `FromResidual`: - as FromResidual>> as FromResidual>> + as FromResidual>> error[E0277]: the `?` operator can only be used on `Option`s, not `Result`s, in a function that returns `Option` --> $DIR/option-to-result.rs:11:6 diff --git a/tests/ui/try-trait/try-on-option.stderr b/tests/ui/try-trait/try-on-option.stderr index eeb0439df298..fad6a1fe8237 100644 --- a/tests/ui/try-trait/try-on-option.stderr +++ b/tests/ui/try-trait/try-on-option.stderr @@ -9,8 +9,8 @@ LL | x?; | = help: the trait `FromResidual>` is not implemented for `Result` = help: the following other types implement trait `FromResidual`: - as FromResidual>> as FromResidual>> + as FromResidual>> error[E0277]: the `?` operator can only be used in a function that returns `Result` or `Option` (or another type that implements `FromResidual`) --> $DIR/try-on-option.rs:11:6 diff --git a/tests/ui/type-alias-impl-trait/nested-tait-inference2.stderr b/tests/ui/type-alias-impl-trait/nested-tait-inference2.stderr index c549ca5b2ce1..241342b05096 100644 --- a/tests/ui/type-alias-impl-trait/nested-tait-inference2.stderr +++ b/tests/ui/type-alias-impl-trait/nested-tait-inference2.stderr @@ -8,8 +8,8 @@ LL | () | -- return type was inferred to be `()` here | = help: the following other types implement trait `Foo`: - <() as Foo> <() as Foo<()>> + <() as Foo> error: aborting due to 1 previous error diff --git a/tests/ui/type/type-check-defaults.stderr b/tests/ui/type/type-check-defaults.stderr index 10d600cbfccc..9ba63ffe9c93 100644 --- a/tests/ui/type/type-check-defaults.stderr +++ b/tests/ui/type/type-check-defaults.stderr @@ -66,10 +66,10 @@ LL | trait ProjectionPred> where T::Item : Add {} | = help: the trait `Add` is not implemented for `i32` = help: the following other types implement trait `Add`: - - > <&'a i32 as Add> <&i32 as Add<&i32>> + > + error: aborting due to 7 previous errors diff --git a/tests/ui/typeck/issue-81293.stderr b/tests/ui/typeck/issue-81293.stderr index 292c63070ae4..6976be71135c 100644 --- a/tests/ui/typeck/issue-81293.stderr +++ b/tests/ui/typeck/issue-81293.stderr @@ -21,10 +21,10 @@ LL | a = c + b * 5; | = help: the trait `Add` is not implemented for `usize` = help: the following other types implement trait `Add`: - - > <&'a usize as Add> <&usize as Add<&usize>> + > + error: aborting due to 3 previous errors diff --git a/tests/ui/typeck/issue-90101.stderr b/tests/ui/typeck/issue-90101.stderr index d5ba157974d9..800d7e9594a2 100644 --- a/tests/ui/typeck/issue-90101.stderr +++ b/tests/ui/typeck/issue-90101.stderr @@ -7,11 +7,11 @@ LL | func(Path::new("hello").to_path_buf().to_string_lossy(), "world") | required by a bound introduced by this call | = help: the following other types implement trait `From`: + > >> >> > > - > = note: required for `Cow<'_, str>` to implement `Into` note: required by a bound in `func` --> $DIR/issue-90101.rs:3:20 diff --git a/tests/ui/ufcs/ufcs-qpath-self-mismatch.stderr b/tests/ui/ufcs/ufcs-qpath-self-mismatch.stderr index c1281ce6a422..964fd4af0092 100644 --- a/tests/ui/ufcs/ufcs-qpath-self-mismatch.stderr +++ b/tests/ui/ufcs/ufcs-qpath-self-mismatch.stderr @@ -6,10 +6,10 @@ LL | >::add(1, 2); | = help: the trait `Add` is not implemented for `i32` = help: the following other types implement trait `Add`: - - > <&'a i32 as Add> <&i32 as Add<&i32>> + > + error[E0277]: cannot add `u32` to `i32` --> $DIR/ufcs-qpath-self-mismatch.rs:4:5 @@ -19,10 +19,10 @@ LL | >::add(1, 2); | = help: the trait `Add` is not implemented for `i32` = help: the following other types implement trait `Add`: - - > <&'a i32 as Add> <&i32 as Add<&i32>> + > + error[E0308]: mismatched types --> $DIR/ufcs-qpath-self-mismatch.rs:7:28 From 5ae546e108957acc08bc3559106090f6cf6aee37 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Thu, 21 Mar 2024 13:01:15 +0000 Subject: [PATCH 109/165] Use FxIndexMap instead of BTreeMap to avoid sorting `DefId`s --- compiler/rustc_hir_analysis/src/outlives/utils.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/outlives/utils.rs b/compiler/rustc_hir_analysis/src/outlives/utils.rs index 8077acea52e4..d3bb22d715d7 100644 --- a/compiler/rustc_hir_analysis/src/outlives/utils.rs +++ b/compiler/rustc_hir_analysis/src/outlives/utils.rs @@ -1,14 +1,14 @@ +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_span::Span; use smallvec::smallvec; -use std::collections::BTreeMap; /// Tracks the `T: 'a` or `'a: 'a` predicates that we have inferred /// must be added to the struct header. pub(crate) type RequiredPredicates<'tcx> = - BTreeMap, ty::Region<'tcx>>, Span>; + FxIndexMap, ty::Region<'tcx>>, Span>; /// Given a requirement `T: 'a` or `'b: 'a`, deduce the /// outlives_component and add it to `required_predicates` From 939df293d8cd9053a83d750b17437bf5c7b1f007 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Thu, 21 Mar 2024 13:08:49 +0000 Subject: [PATCH 110/165] Sort diagnostics by rendered trait ref instead of its def ids --- compiler/rustc_hir_typeck/src/method/suggest.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 0dcde0cdecbb..952d53682986 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -2549,7 +2549,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { _ => None, }) .collect(); - preds.sort_by_key(|pred| (pred.def_id(), pred.self_ty())); + preds.sort_by_key(|pred| pred.trait_ref.to_string()); let def_ids = preds .iter() .filter_map(|pred| match pred.self_ty().kind() { From dc95bd69f24474032123e371a4059f5502de3309 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Thu, 21 Mar 2024 13:10:28 +0000 Subject: [PATCH 111/165] Remove `Ord` from `Ty`, `Const`, and `Region` --- compiler/rustc_middle/src/thir.rs | 6 ++- compiler/rustc_middle/src/ty/consts.rs | 4 +- compiler/rustc_middle/src/ty/consts/kind.rs | 4 +- compiler/rustc_middle/src/ty/generic_args.rs | 15 +----- compiler/rustc_middle/src/ty/mod.rs | 6 +-- compiler/rustc_middle/src/ty/predicate.rs | 8 +-- compiler/rustc_middle/src/ty/region.rs | 2 +- compiler/rustc_middle/src/ty/sty.rs | 6 +-- compiler/rustc_type_ir/src/const_kind.rs | 10 +--- compiler/rustc_type_ir/src/interner.rs | 54 ++++++++++---------- compiler/rustc_type_ir/src/region_kind.rs | 10 +--- compiler/rustc_type_ir/src/ty_kind.rs | 12 +---- 12 files changed, 51 insertions(+), 86 deletions(-) diff --git a/compiler/rustc_middle/src/thir.rs b/compiler/rustc_middle/src/thir.rs index f684f83a2612..966d4ff43680 100644 --- a/compiler/rustc_middle/src/thir.rs +++ b/compiler/rustc_middle/src/thir.rs @@ -1018,7 +1018,11 @@ impl<'tcx> PatRangeBoundary<'tcx> { (Finite(mir::Const::Ty(a)), Finite(mir::Const::Ty(b))) if matches!(ty.kind(), ty::Uint(_) | ty::Char) => { - return Some(a.kind().cmp(&b.kind())); + if let Some(a) = a.try_to_valtree() { + if let Some(b) = b.try_to_valtree() { + return Some(a.cmp(&b)); + } + } } ( Finite(mir::Const::Val(mir::ConstValue::Scalar(Scalar::Int(a)), _)), diff --git a/compiler/rustc_middle/src/ty/consts.rs b/compiler/rustc_middle/src/ty/consts.rs index 0d621cd1cfd9..3713883eb00d 100644 --- a/compiler/rustc_middle/src/ty/consts.rs +++ b/compiler/rustc_middle/src/ty/consts.rs @@ -23,7 +23,7 @@ pub use valtree::*; pub type ConstKind<'tcx> = IrConstKind>; /// Use this rather than `ConstData`, whenever possible. -#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, HashStable)] +#[derive(Copy, Clone, PartialEq, Eq, Hash, HashStable)] #[rustc_pass_by_value] pub struct Const<'tcx>(pub(super) Interned<'tcx, WithCachedTypeInfo>>); @@ -52,7 +52,7 @@ impl<'tcx> ConstTy> for Const<'tcx> { } /// Typed constant value. -#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] +#[derive(Copy, Clone, PartialEq, Eq, Hash)] #[derive(HashStable, TyEncodable, TyDecodable)] pub struct ConstData<'tcx> { pub ty: Ty<'tcx>, diff --git a/compiler/rustc_middle/src/ty/consts/kind.rs b/compiler/rustc_middle/src/ty/consts/kind.rs index 705987d92fed..ea02faca5f39 100644 --- a/compiler/rustc_middle/src/ty/consts/kind.rs +++ b/compiler/rustc_middle/src/ty/consts/kind.rs @@ -7,7 +7,7 @@ use rustc_hir::def_id::DefId; use rustc_macros::HashStable; /// An unevaluated (potentially generic) constant used in the type-system. -#[derive(Copy, Clone, Eq, PartialEq, PartialOrd, Ord, TyEncodable, TyDecodable)] +#[derive(Copy, Clone, Eq, PartialEq, TyEncodable, TyDecodable)] #[derive(Hash, HashStable, TypeFoldable, TypeVisitable)] pub struct UnevaluatedConst<'tcx> { pub def: DefId, @@ -62,7 +62,7 @@ impl<'tcx> UnevaluatedConst<'tcx> { } } -#[derive(Copy, Clone, Eq, PartialEq, PartialOrd, Ord, Hash)] +#[derive(Copy, Clone, Eq, PartialEq, Hash)] #[derive(HashStable, TyEncodable, TyDecodable, TypeVisitable, TypeFoldable)] pub enum Expr<'tcx> { Binop(mir::BinOp, Const<'tcx>, Const<'tcx>), diff --git a/compiler/rustc_middle/src/ty/generic_args.rs b/compiler/rustc_middle/src/ty/generic_args.rs index 02b58c035d4e..19cef927faf5 100644 --- a/compiler/rustc_middle/src/ty/generic_args.rs +++ b/compiler/rustc_middle/src/ty/generic_args.rs @@ -17,7 +17,6 @@ use rustc_type_ir::WithCachedTypeInfo; use smallvec::SmallVec; use core::intrinsics; -use std::cmp::Ordering; use std::marker::PhantomData; use std::mem; use std::num::NonZero; @@ -68,7 +67,7 @@ const TYPE_TAG: usize = 0b00; const REGION_TAG: usize = 0b01; const CONST_TAG: usize = 0b10; -#[derive(Debug, TyEncodable, TyDecodable, PartialEq, Eq, PartialOrd, Ord, HashStable)] +#[derive(Debug, TyEncodable, TyDecodable, PartialEq, Eq, HashStable)] pub enum GenericArgKind<'tcx> { Lifetime(ty::Region<'tcx>), Type(Ty<'tcx>), @@ -100,18 +99,6 @@ impl<'tcx> GenericArgKind<'tcx> { } } -impl<'tcx> Ord for GenericArg<'tcx> { - fn cmp(&self, other: &GenericArg<'tcx>) -> Ordering { - self.unpack().cmp(&other.unpack()) - } -} - -impl<'tcx> PartialOrd for GenericArg<'tcx> { - fn partial_cmp(&self, other: &GenericArg<'tcx>) -> Option { - Some(self.cmp(other)) - } -} - impl<'tcx> From> for GenericArg<'tcx> { #[inline] fn from(r: ty::Region<'tcx>) -> GenericArg<'tcx> { diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index aad2f6a4cf8a..d1d8a3ea0725 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -517,7 +517,7 @@ pub struct CReaderCacheKey { } /// Use this rather than `TyKind`, whenever possible. -#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, HashStable)] +#[derive(Copy, Clone, PartialEq, Eq, Hash, HashStable)] #[rustc_diagnostic_item = "Ty"] #[rustc_pass_by_value] pub struct Ty<'tcx>(Interned<'tcx, WithCachedTypeInfo>>); @@ -702,7 +702,7 @@ const TAG_MASK: usize = 0b11; const TYPE_TAG: usize = 0b00; const CONST_TAG: usize = 0b01; -#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, TyEncodable, TyDecodable)] +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable)] #[derive(HashStable, TypeFoldable, TypeVisitable)] pub enum TermKind<'tcx> { Ty(Ty<'tcx>), @@ -980,7 +980,7 @@ impl PlaceholderLike for PlaceholderType { } #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, HashStable)] -#[derive(TyEncodable, TyDecodable, PartialOrd, Ord)] +#[derive(TyEncodable, TyDecodable)] pub struct BoundConst<'tcx> { pub var: BoundVar, pub ty: Ty<'tcx>, diff --git a/compiler/rustc_middle/src/ty/predicate.rs b/compiler/rustc_middle/src/ty/predicate.rs index d3bc7dd22e7b..05156dd5205e 100644 --- a/compiler/rustc_middle/src/ty/predicate.rs +++ b/compiler/rustc_middle/src/ty/predicate.rs @@ -192,7 +192,7 @@ impl<'tcx> Clause<'tcx> { } } -#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Ord, Eq, Hash, TyEncodable, TyDecodable)] +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable)] #[derive(HashStable, TypeFoldable, TypeVisitable, Lift)] pub enum ExistentialPredicate<'tcx> { /// E.g., `Iterator`. @@ -336,7 +336,7 @@ impl<'tcx> ty::List> { /// /// Trait references also appear in object types like `Foo`, but in /// that case the `Self` parameter is absent from the generic parameters. -#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, TyEncodable, TyDecodable)] +#[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable)] #[derive(HashStable, TypeFoldable, TypeVisitable, Lift)] pub struct TraitRef<'tcx> { pub def_id: DefId, @@ -420,7 +420,7 @@ impl<'tcx> IntoDiagArg for TraitRef<'tcx> { /// ``` /// The generic parameters don't include the erased `Self`, only trait /// type and lifetime parameters (`[X, Y]` and `['a, 'b]` above). -#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, TyEncodable, TyDecodable)] +#[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable)] #[derive(HashStable, TypeFoldable, TypeVisitable, Lift)] pub struct ExistentialTraitRef<'tcx> { pub def_id: DefId, @@ -476,7 +476,7 @@ impl<'tcx> PolyExistentialTraitRef<'tcx> { } /// A `ProjectionPredicate` for an `ExistentialTraitRef`. -#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, TyEncodable, TyDecodable)] +#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, TyEncodable, TyDecodable)] #[derive(HashStable, TypeFoldable, TypeVisitable, Lift)] pub struct ExistentialProjection<'tcx> { pub def_id: DefId, diff --git a/compiler/rustc_middle/src/ty/region.rs b/compiler/rustc_middle/src/ty/region.rs index c66b9864e462..821642b8ab61 100644 --- a/compiler/rustc_middle/src/ty/region.rs +++ b/compiler/rustc_middle/src/ty/region.rs @@ -14,7 +14,7 @@ use crate::ty::{self, BoundVar, TyCtxt, TypeFlags}; pub type RegionKind<'tcx> = IrRegionKind>; /// Use this rather than `RegionKind`, whenever possible. -#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, HashStable)] +#[derive(Copy, Clone, PartialEq, Eq, Hash, HashStable)] #[rustc_pass_by_value] pub struct Region<'tcx>(pub Interned<'tcx, RegionKind<'tcx>>); diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 510a4b59520c..a000c84696bc 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -1109,7 +1109,7 @@ where /// * For a projection, this would be `>::N<...>`. /// * For an inherent projection, this would be `Ty::N<...>`. /// * For an opaque type, there is no explicit syntax. -#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, TyEncodable, TyDecodable)] +#[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable)] #[derive(HashStable, TypeFoldable, TypeVisitable, Lift)] pub struct AliasTy<'tcx> { /// The parameters of the associated or opaque item. @@ -1278,7 +1278,7 @@ pub struct GenSig<'tcx> { /// - `inputs`: is the list of arguments and their modes. /// - `output`: is the return type. /// - `c_variadic`: indicates whether this is a C-variadic function. -#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, TyEncodable, TyDecodable)] +#[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable)] #[derive(HashStable, TypeFoldable, TypeVisitable, Lift)] pub struct FnSig<'tcx> { pub inputs_and_output: &'tcx List>, @@ -2661,7 +2661,7 @@ impl<'tcx> Ty<'tcx> { /// a miscompilation or unsoundness. /// /// When in doubt, use `VarianceDiagInfo::default()` -#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord)] +#[derive(Copy, Clone, Debug, Default, PartialEq, Eq)] pub enum VarianceDiagInfo<'tcx> { /// No additional information - this is the default. /// We will not add any additional information to error messages. diff --git a/compiler/rustc_type_ir/src/const_kind.rs b/compiler/rustc_type_ir/src/const_kind.rs index 0aaaad5af05d..5b08140db3a3 100644 --- a/compiler/rustc_type_ir/src/const_kind.rs +++ b/compiler/rustc_type_ir/src/const_kind.rs @@ -8,15 +8,7 @@ use self::ConstKind::*; /// Represents a constant in Rust. #[derive(derivative::Derivative)] -#[derivative( - Clone(bound = ""), - Copy(bound = ""), - PartialOrd(bound = ""), - PartialOrd = "feature_allow_slow_enum", - Ord(bound = ""), - Ord = "feature_allow_slow_enum", - Hash(bound = "") -)] +#[derivative(Clone(bound = ""), Copy(bound = ""), Hash(bound = ""))] #[cfg_attr(feature = "nightly", derive(TyEncodable, TyDecodable, HashStable_NoContext))] pub enum ConstKind { /// A const generic parameter. diff --git a/compiler/rustc_type_ir/src/interner.rs b/compiler/rustc_type_ir/src/interner.rs index 373540de05e0..bd67fdbfb2b7 100644 --- a/compiler/rustc_type_ir/src/interner.rs +++ b/compiler/rustc_type_ir/src/interner.rs @@ -10,15 +10,15 @@ use crate::{ pub trait Interner: Sized { type DefId: Copy + Debug + Hash + Ord; - type AdtDef: Copy + Debug + Hash + Ord; + type AdtDef: Copy + Debug + Hash + Eq; type GenericArgs: Copy + DebugWithInfcx + Hash - + Ord + + Eq + IntoIterator; - type GenericArg: Copy + DebugWithInfcx + Hash + Ord; - type Term: Copy + Debug + Hash + Ord; + type GenericArg: Copy + DebugWithInfcx + Hash + Eq; + type Term: Copy + Debug + Hash + Eq; type Binder>: BoundVars + TypeSuperVisitable; type BoundVars: IntoIterator; @@ -30,56 +30,56 @@ pub trait Interner: Sized { type Ty: Copy + DebugWithInfcx + Hash - + Ord + + Eq + Into + IntoKind> + TypeSuperVisitable + Flags + new::Ty; - type Tys: Copy + Debug + Hash + Ord + IntoIterator; - type AliasTy: Copy + DebugWithInfcx + Hash + Ord; - type ParamTy: Copy + Debug + Hash + Ord; - type BoundTy: Copy + Debug + Hash + Ord; - type PlaceholderTy: Copy + Debug + Hash + Ord + PlaceholderLike; + type Tys: Copy + Debug + Hash + Eq + IntoIterator; + type AliasTy: Copy + DebugWithInfcx + Hash + Eq; + type ParamTy: Copy + Debug + Hash + Eq; + type BoundTy: Copy + Debug + Hash + Eq; + type PlaceholderTy: Copy + Debug + Hash + Eq + PlaceholderLike; // Things stored inside of tys - type ErrorGuaranteed: Copy + Debug + Hash + Ord; - type BoundExistentialPredicates: Copy + DebugWithInfcx + Hash + Ord; - type PolyFnSig: Copy + DebugWithInfcx + Hash + Ord; - type AllocId: Copy + Debug + Hash + Ord; + type ErrorGuaranteed: Copy + Debug + Hash + Eq; + type BoundExistentialPredicates: Copy + DebugWithInfcx + Hash + Eq; + type PolyFnSig: Copy + DebugWithInfcx + Hash + Eq; + type AllocId: Copy + Debug + Hash + Eq; // Kinds of consts type Const: Copy + DebugWithInfcx + Hash - + Ord + + Eq + Into + IntoKind> + ConstTy + TypeSuperVisitable + Flags + new::Const; - type AliasConst: Copy + DebugWithInfcx + Hash + Ord; - type PlaceholderConst: Copy + Debug + Hash + Ord + PlaceholderLike; - type ParamConst: Copy + Debug + Hash + Ord; - type BoundConst: Copy + Debug + Hash + Ord; - type ValueConst: Copy + Debug + Hash + Ord; - type ExprConst: Copy + DebugWithInfcx + Hash + Ord; + type AliasConst: Copy + DebugWithInfcx + Hash + Eq; + type PlaceholderConst: Copy + Debug + Hash + Eq + PlaceholderLike; + type ParamConst: Copy + Debug + Hash + Eq; + type BoundConst: Copy + Debug + Hash + Eq; + type ValueConst: Copy + Debug + Hash + Eq; + type ExprConst: Copy + DebugWithInfcx + Hash + Eq; // Kinds of regions type Region: Copy + DebugWithInfcx + Hash - + Ord + + Eq + Into + IntoKind> + Flags + new::Region; - type EarlyParamRegion: Copy + Debug + Hash + Ord; - type LateParamRegion: Copy + Debug + Hash + Ord; - type BoundRegion: Copy + Debug + Hash + Ord; - type InferRegion: Copy + DebugWithInfcx + Hash + Ord; - type PlaceholderRegion: Copy + Debug + Hash + Ord + PlaceholderLike; + type EarlyParamRegion: Copy + Debug + Hash + Eq; + type LateParamRegion: Copy + Debug + Hash + Eq; + type BoundRegion: Copy + Debug + Hash + Eq; + type InferRegion: Copy + DebugWithInfcx + Hash + Eq; + type PlaceholderRegion: Copy + Debug + Hash + Eq + PlaceholderLike; // Predicates type Predicate: Copy + Debug + Hash + Eq + TypeSuperVisitable + Flags; diff --git a/compiler/rustc_type_ir/src/region_kind.rs b/compiler/rustc_type_ir/src/region_kind.rs index 2e8481df56d3..e1247e2661a2 100644 --- a/compiler/rustc_type_ir/src/region_kind.rs +++ b/compiler/rustc_type_ir/src/region_kind.rs @@ -113,15 +113,7 @@ use self::RegionKind::*; /// [2]: https://smallcultfollowing.com/babysteps/blog/2013/11/04/intermingled-parameter-lists/ /// [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/traits/hrtb.html #[derive(derivative::Derivative)] -#[derivative( - Clone(bound = ""), - Copy(bound = ""), - PartialOrd(bound = ""), - PartialOrd = "feature_allow_slow_enum", - Ord(bound = ""), - Ord = "feature_allow_slow_enum", - Hash(bound = "") -)] +#[derivative(Clone(bound = ""), Copy(bound = ""), Hash(bound = ""))] #[cfg_attr(feature = "nightly", derive(TyEncodable, TyDecodable))] pub enum RegionKind { /// A region parameter; for example `'a` in `impl<'a> Trait for &'a ()`. diff --git a/compiler/rustc_type_ir/src/ty_kind.rs b/compiler/rustc_type_ir/src/ty_kind.rs index 5ed73cd94f4e..fad67fe3cbbc 100644 --- a/compiler/rustc_type_ir/src/ty_kind.rs +++ b/compiler/rustc_type_ir/src/ty_kind.rs @@ -63,15 +63,7 @@ impl AliasKind { /// converted to this representation using `::lower_ty`. #[cfg_attr(feature = "nightly", rustc_diagnostic_item = "IrTyKind")] #[derive(derivative::Derivative)] -#[derivative( - Clone(bound = ""), - Copy(bound = ""), - PartialOrd(bound = ""), - PartialOrd = "feature_allow_slow_enum", - Ord(bound = ""), - Ord = "feature_allow_slow_enum", - Hash(bound = "") -)] +#[derivative(Clone(bound = ""), Copy(bound = ""), Hash(bound = ""))] #[cfg_attr(feature = "nightly", derive(TyEncodable, TyDecodable, HashStable_NoContext))] pub enum TyKind { /// The primitive boolean type. Written as `bool`. @@ -803,8 +795,6 @@ impl DebugWithInfcx for InferTy { #[derivative( Clone(bound = ""), Copy(bound = ""), - PartialOrd(bound = ""), - Ord(bound = ""), PartialEq(bound = ""), Eq(bound = ""), Hash(bound = ""), From dd9fe01d0612d7dd06c53c9ad60d1fd224cb0c49 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Thu, 21 Mar 2024 13:15:46 +0000 Subject: [PATCH 112/165] Remove `Ord` from `Binder` --- compiler/rustc_middle/src/ty/sty.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index a000c84696bc..da74a3e12165 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -908,7 +908,7 @@ impl BoundVariableKind { /// e.g., `liberate_late_bound_regions`). /// /// `Decodable` and `Encodable` are implemented for `Binder` using the `impl_binder_encode_decode!` macro. -#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] +#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] #[derive(HashStable, Lift)] pub struct Binder<'tcx, T> { value: T, From e87d10846ee914128860bff08c7f71553355c5f4 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Thu, 21 Mar 2024 13:20:16 +0000 Subject: [PATCH 113/165] Remove `Ord` from `BoundTy` --- compiler/rustc_middle/src/ty/sty.rs | 6 +++--- compiler/rustc_trait_selection/src/traits/util.rs | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index da74a3e12165..57a675e4453b 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -868,7 +868,7 @@ impl<'tcx> InlineConstArgs<'tcx> { } } -#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, TyEncodable, TyDecodable)] +#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, TyEncodable, TyDecodable)] #[derive(HashStable)] pub enum BoundVariableKind { Ty(BoundTyKind), @@ -1403,14 +1403,14 @@ impl ParamConst { } } -#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, TyEncodable, TyDecodable)] +#[derive(Clone, Copy, PartialEq, Eq, Hash, TyEncodable, TyDecodable)] #[derive(HashStable)] pub struct BoundTy { pub var: BoundVar, pub kind: BoundTyKind, } -#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, TyEncodable, TyDecodable)] +#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, TyEncodable, TyDecodable)] #[derive(HashStable)] pub enum BoundTyKind { Anon, diff --git a/compiler/rustc_trait_selection/src/traits/util.rs b/compiler/rustc_trait_selection/src/traits/util.rs index 3f433a9e919a..c9d76aa6ee90 100644 --- a/compiler/rustc_trait_selection/src/traits/util.rs +++ b/compiler/rustc_trait_selection/src/traits/util.rs @@ -2,7 +2,7 @@ use std::collections::BTreeMap; use super::NormalizeExt; use super::{ObligationCause, PredicateObligation, SelectionContext}; -use rustc_data_structures::fx::FxHashSet; +use rustc_data_structures::fx::{FxHashSet, FxIndexMap}; use rustc_errors::Diag; use rustc_hir::def_id::DefId; use rustc_infer::infer::{InferCtxt, InferOk}; @@ -432,7 +432,7 @@ pub struct BoundVarReplacer<'me, 'tcx> { // nice to remove these since we already have the `kind` in the placeholder; we really just need // the `var` (but we *could* bring that into scope if we were to track them as we pass them). mapped_regions: BTreeMap, - mapped_types: BTreeMap, + mapped_types: FxIndexMap, mapped_consts: BTreeMap, // The current depth relative to *this* folding, *not* the entire normalization. In other words, // the depth of binders we've passed here. @@ -452,11 +452,11 @@ impl<'me, 'tcx> BoundVarReplacer<'me, 'tcx> { ) -> ( T, BTreeMap, - BTreeMap, + FxIndexMap, BTreeMap, ) { let mapped_regions: BTreeMap = BTreeMap::new(); - let mapped_types: BTreeMap = BTreeMap::new(); + let mapped_types: FxIndexMap = FxIndexMap::default(); let mapped_consts: BTreeMap = BTreeMap::new(); let mut replacer = BoundVarReplacer { @@ -575,7 +575,7 @@ impl<'tcx> TypeFolder> for BoundVarReplacer<'_, 'tcx> { pub struct PlaceholderReplacer<'me, 'tcx> { infcx: &'me InferCtxt<'tcx>, mapped_regions: BTreeMap, - mapped_types: BTreeMap, + mapped_types: FxIndexMap, mapped_consts: BTreeMap, universe_indices: &'me [Option], current_index: ty::DebruijnIndex, @@ -585,7 +585,7 @@ impl<'me, 'tcx> PlaceholderReplacer<'me, 'tcx> { pub fn replace_placeholders>>( infcx: &'me InferCtxt<'tcx>, mapped_regions: BTreeMap, - mapped_types: BTreeMap, + mapped_types: FxIndexMap, mapped_consts: BTreeMap, universe_indices: &'me [Option], value: T, From 459ea32a278b64c7a0dbf63ca258786d6fb89a1a Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Thu, 21 Mar 2024 14:02:13 +0000 Subject: [PATCH 114/165] Remove `Partial/Ord` from `BoundRegion` --- compiler/rustc_infer/src/infer/error_reporting/mod.rs | 3 ++- compiler/rustc_middle/src/ty/fold.rs | 6 ++---- compiler/rustc_middle/src/ty/print/pretty.rs | 10 +++++----- compiler/rustc_middle/src/ty/region.rs | 6 +++--- compiler/rustc_trait_selection/src/traits/util.rs | 11 ++++++----- tests/ui/anonymous-higher-ranked-lifetime.stderr | 4 ++-- 6 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 82634f7308d5..d6a3f756eeb8 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -1074,7 +1074,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { let (sig, reg) = ty::print::FmtPrinter::new(self.tcx, Namespace::TypeNS) .name_all_regions(sig) .unwrap(); - let lts: Vec = reg.into_values().map(|kind| kind.to_string()).collect(); + let lts: Vec = + reg.into_items().map(|(_, kind)| kind.to_string()).into_sorted_stable_ord(); (if lts.is_empty() { String::new() } else { format!("for<{}> ", lts.join(", ")) }, sig) }; diff --git a/compiler/rustc_middle/src/ty/fold.rs b/compiler/rustc_middle/src/ty/fold.rs index b57d4f372a7f..fd3bee16e268 100644 --- a/compiler/rustc_middle/src/ty/fold.rs +++ b/compiler/rustc_middle/src/ty/fold.rs @@ -2,8 +2,6 @@ use crate::ty::{self, Binder, BoundTy, Ty, TyCtxt, TypeVisitableExt}; use rustc_data_structures::fx::FxIndexMap; use rustc_hir::def_id::DefId; -use std::collections::BTreeMap; - pub use rustc_type_ir::fold::{FallibleTypeFolder, TypeFoldable, TypeFolder, TypeSuperFoldable}; /////////////////////////////////////////////////////////////////////////// @@ -254,12 +252,12 @@ impl<'tcx> TyCtxt<'tcx> { self, value: Binder<'tcx, T>, mut fld_r: F, - ) -> (T, BTreeMap>) + ) -> (T, FxIndexMap>) where F: FnMut(ty::BoundRegion) -> ty::Region<'tcx>, T: TypeFoldable>, { - let mut region_map = BTreeMap::new(); + let mut region_map = FxIndexMap::default(); let real_fld_r = |br: ty::BoundRegion| *region_map.entry(br).or_insert_with(|| fld_r(br)); let value = self.instantiate_bound_regions_uncached(value, real_fld_r); (value, region_map) diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 914b19efc7e8..5ff98dc8c873 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -10,6 +10,7 @@ use crate::ty::{ use rustc_apfloat::ieee::{Double, Single}; use rustc_apfloat::Float; use rustc_data_structures::fx::{FxHashMap, FxIndexMap}; +use rustc_data_structures::unord::UnordMap; use rustc_hir as hir; use rustc_hir::def::{self, CtorKind, DefKind, Namespace}; use rustc_hir::def_id::{DefIdMap, DefIdSet, ModDefId, CRATE_DEF_ID, LOCAL_CRATE}; @@ -24,7 +25,6 @@ use rustc_target::spec::abi::Abi; use smallvec::SmallVec; use std::cell::Cell; -use std::collections::BTreeMap; use std::fmt::{self, Write as _}; use std::iter; use std::ops::{Deref, DerefMut}; @@ -2537,7 +2537,7 @@ impl<'tcx> FmtPrinter<'_, 'tcx> { struct RegionFolder<'a, 'tcx> { tcx: TyCtxt<'tcx>, current_index: ty::DebruijnIndex, - region_map: BTreeMap>, + region_map: UnordMap>, name: &'a mut ( dyn FnMut( Option, // Debruijn index of the folded late-bound region @@ -2614,7 +2614,7 @@ impl<'tcx> FmtPrinter<'_, 'tcx> { pub fn name_all_regions( &mut self, value: &ty::Binder<'tcx, T>, - ) -> Result<(T, BTreeMap>), fmt::Error> + ) -> Result<(T, UnordMap>), fmt::Error> where T: Print<'tcx, Self> + TypeFoldable>, { @@ -2691,7 +2691,7 @@ impl<'tcx> FmtPrinter<'_, 'tcx> { write!(self, "{var:?}")?; } start_or_continue(self, "", "> "); - (value.clone().skip_binder(), BTreeMap::default()) + (value.clone().skip_binder(), UnordMap::default()) } else { let tcx = self.tcx; @@ -2763,7 +2763,7 @@ impl<'tcx> FmtPrinter<'_, 'tcx> { tcx, current_index: ty::INNERMOST, name: &mut name, - region_map: BTreeMap::new(), + region_map: UnordMap::default(), }; let new_value = value.clone().skip_binder().fold_with(&mut folder); let region_map = folder.region_map; diff --git a/compiler/rustc_middle/src/ty/region.rs b/compiler/rustc_middle/src/ty/region.rs index 821642b8ab61..983340bd6254 100644 --- a/compiler/rustc_middle/src/ty/region.rs +++ b/compiler/rustc_middle/src/ty/region.rs @@ -358,7 +358,7 @@ impl Atom for RegionVid { } } -#[derive(Clone, PartialEq, PartialOrd, Eq, Ord, Hash, TyEncodable, TyDecodable, Copy)] +#[derive(Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable, Copy)] #[derive(HashStable)] /// The parameter representation of late-bound function parameters, "some region /// at least as big as the scope `fr.scope`". @@ -367,7 +367,7 @@ pub struct LateParamRegion { pub bound_region: BoundRegionKind, } -#[derive(Clone, PartialEq, PartialOrd, Eq, Ord, Hash, TyEncodable, TyDecodable, Copy)] +#[derive(Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable, Copy)] #[derive(HashStable)] pub enum BoundRegionKind { /// An anonymous region parameter for a given fn (&T) @@ -384,7 +384,7 @@ pub enum BoundRegionKind { BrEnv, } -#[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable, PartialOrd, Ord)] +#[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable)] #[derive(HashStable)] pub struct BoundRegion { pub var: BoundVar, diff --git a/compiler/rustc_trait_selection/src/traits/util.rs b/compiler/rustc_trait_selection/src/traits/util.rs index c9d76aa6ee90..29d063321a79 100644 --- a/compiler/rustc_trait_selection/src/traits/util.rs +++ b/compiler/rustc_trait_selection/src/traits/util.rs @@ -431,7 +431,7 @@ pub struct BoundVarReplacer<'me, 'tcx> { // These three maps track the bound variable that were replaced by placeholders. It might be // nice to remove these since we already have the `kind` in the placeholder; we really just need // the `var` (but we *could* bring that into scope if we were to track them as we pass them). - mapped_regions: BTreeMap, + mapped_regions: FxIndexMap, mapped_types: FxIndexMap, mapped_consts: BTreeMap, // The current depth relative to *this* folding, *not* the entire normalization. In other words, @@ -451,11 +451,12 @@ impl<'me, 'tcx> BoundVarReplacer<'me, 'tcx> { value: T, ) -> ( T, - BTreeMap, + FxIndexMap, FxIndexMap, BTreeMap, ) { - let mapped_regions: BTreeMap = BTreeMap::new(); + let mapped_regions: FxIndexMap = + FxIndexMap::default(); let mapped_types: FxIndexMap = FxIndexMap::default(); let mapped_consts: BTreeMap = BTreeMap::new(); @@ -574,7 +575,7 @@ impl<'tcx> TypeFolder> for BoundVarReplacer<'_, 'tcx> { /// The inverse of [`BoundVarReplacer`]: replaces placeholders with the bound vars from which they came. pub struct PlaceholderReplacer<'me, 'tcx> { infcx: &'me InferCtxt<'tcx>, - mapped_regions: BTreeMap, + mapped_regions: FxIndexMap, mapped_types: FxIndexMap, mapped_consts: BTreeMap, universe_indices: &'me [Option], @@ -584,7 +585,7 @@ pub struct PlaceholderReplacer<'me, 'tcx> { impl<'me, 'tcx> PlaceholderReplacer<'me, 'tcx> { pub fn replace_placeholders>>( infcx: &'me InferCtxt<'tcx>, - mapped_regions: BTreeMap, + mapped_regions: FxIndexMap, mapped_types: FxIndexMap, mapped_consts: BTreeMap, universe_indices: &'me [Option], diff --git a/tests/ui/anonymous-higher-ranked-lifetime.stderr b/tests/ui/anonymous-higher-ranked-lifetime.stderr index cc27a0fcf95f..c28d856ad55f 100644 --- a/tests/ui/anonymous-higher-ranked-lifetime.stderr +++ b/tests/ui/anonymous-higher-ranked-lifetime.stderr @@ -70,7 +70,7 @@ LL | f4(|_: (), _: ()| {}); | | found signature defined here | expected due to this | - = note: expected closure signature `for<'r, 'a> fn(&'a (), &'r ()) -> _` + = note: expected closure signature `for<'a, 'r> fn(&'a (), &'r ()) -> _` found closure signature `fn((), ()) -> _` note: required by a bound in `f4` --> $DIR/anonymous-higher-ranked-lifetime.rs:19:25 @@ -217,7 +217,7 @@ LL | h2(|_: (), _: (), _: (), _: ()| {}); | | found signature defined here | expected due to this | - = note: expected closure signature `for<'t0, 'a> fn(&'a (), Box<(dyn for<'a> Fn(&'a ()) + 'static)>, &'t0 (), for<'a, 'b> fn(&'a (), &'b ())) -> _` + = note: expected closure signature `for<'a, 't0> fn(&'a (), Box<(dyn for<'a> Fn(&'a ()) + 'static)>, &'t0 (), for<'a, 'b> fn(&'a (), &'b ())) -> _` found closure signature `fn((), (), (), ()) -> _` note: required by a bound in `h2` --> $DIR/anonymous-higher-ranked-lifetime.rs:30:25 From 1d662c9eee794d990f1faa106e96d5bf6b42e0c7 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Thu, 21 Mar 2024 14:06:51 +0000 Subject: [PATCH 115/165] Remove `Partial/Ord` from `AdtDef` --- compiler/rustc_middle/src/ty/adt.rs | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) diff --git a/compiler/rustc_middle/src/ty/adt.rs b/compiler/rustc_middle/src/ty/adt.rs index a71443167699..a7f1ba46b617 100644 --- a/compiler/rustc_middle/src/ty/adt.rs +++ b/compiler/rustc_middle/src/ty/adt.rs @@ -18,7 +18,6 @@ use rustc_span::symbol::sym; use rustc_target::abi::{ReprOptions, VariantIdx, FIRST_VARIANT}; use std::cell::RefCell; -use std::cmp::Ordering; use std::hash::{Hash, Hasher}; use std::ops::Range; use std::str; @@ -102,20 +101,6 @@ pub struct AdtDefData { repr: ReprOptions, } -impl PartialOrd for AdtDefData { - fn partial_cmp(&self, other: &AdtDefData) -> Option { - Some(self.cmp(other)) - } -} - -/// There should be only one AdtDef for each `did`, therefore -/// it is fine to implement `Ord` only based on `did`. -impl Ord for AdtDefData { - fn cmp(&self, other: &AdtDefData) -> Ordering { - self.did.cmp(&other.did) - } -} - impl PartialEq for AdtDefData { #[inline] fn eq(&self, other: &Self) -> bool { @@ -180,7 +165,7 @@ impl<'a> HashStable> for AdtDefData { } } -#[derive(Copy, Clone, PartialEq, Eq, Hash, Ord, PartialOrd, HashStable)] +#[derive(Copy, Clone, PartialEq, Eq, Hash, HashStable)] #[rustc_pass_by_value] pub struct AdtDef<'tcx>(pub Interned<'tcx, AdtDefData>); From 28363ea4eb41b073f8a10e4a0fef2ff3b9b6abe6 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Thu, 21 Mar 2024 14:08:49 +0000 Subject: [PATCH 116/165] Remove `Partial/Ord` from `EarlyParamRegion` --- compiler/rustc_middle/src/ty/region.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_middle/src/ty/region.rs b/compiler/rustc_middle/src/ty/region.rs index 983340bd6254..867faf632619 100644 --- a/compiler/rustc_middle/src/ty/region.rs +++ b/compiler/rustc_middle/src/ty/region.rs @@ -327,7 +327,7 @@ impl<'tcx> Deref for Region<'tcx> { } } -#[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable, PartialOrd, Ord)] +#[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable)] #[derive(HashStable)] pub struct EarlyParamRegion { pub def_id: DefId, From 150a5e5f92a5f62adbb0d35323c267f227cab0a1 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Thu, 21 Mar 2024 14:17:50 +0000 Subject: [PATCH 117/165] Do not sort `DefId`s in diagnostics --- compiler/rustc_resolve/src/diagnostics.rs | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index 476b31f44ae6..4057bc9ffbd0 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -2730,7 +2730,7 @@ pub(crate) fn import_candidates( ); } -type PathString<'a> = (String, &'a str, Option, &'a Option, bool); +type PathString<'a> = (String, &'a str, Option, &'a Option, bool); /// When an entity with a given name is not available in scope, we search for /// entities with that name in all crates. This method allows outputting the @@ -2762,7 +2762,7 @@ fn show_candidates( accessible_path_strings.push(( pprust::path_to_string(&c.path), c.descr, - c.did, + c.did.and_then(|did| Some(tcx.source_span(did.as_local()?))), &c.note, c.via_import, )) @@ -2771,7 +2771,7 @@ fn show_candidates( inaccessible_path_strings.push(( pprust::path_to_string(&c.path), c.descr, - c.did, + c.did.and_then(|did| Some(tcx.source_span(did.as_local()?))), &c.note, c.via_import, )) @@ -2889,15 +2889,14 @@ fn show_candidates( } else if !(inaccessible_path_strings.is_empty() || matches!(mode, DiagMode::Import { .. })) { let prefix = if let DiagMode::Pattern = mode { "you might have meant to match on " } else { "" }; - if let [(name, descr, def_id, note, _)] = &inaccessible_path_strings[..] { + if let [(name, descr, source_span, note, _)] = &inaccessible_path_strings[..] { let msg = format!( "{prefix}{descr} `{name}`{} exists but is inaccessible", if let DiagMode::Pattern = mode { ", which" } else { "" } ); - if let Some(local_def_id) = def_id.and_then(|did| did.as_local()) { - let span = tcx.source_span(local_def_id); - let span = tcx.sess.source_map().guess_head_span(span); + if let Some(source_span) = source_span { + let span = tcx.sess.source_map().guess_head_span(*source_span); let mut multi_span = MultiSpan::from_span(span); multi_span.push_span_label(span, "not accessible"); err.span_note(multi_span, msg); @@ -2925,10 +2924,9 @@ fn show_candidates( let mut has_colon = false; let mut spans = Vec::new(); - for (name, _, def_id, _, _) in &inaccessible_path_strings { - if let Some(local_def_id) = def_id.and_then(|did| did.as_local()) { - let span = tcx.source_span(local_def_id); - let span = tcx.sess.source_map().guess_head_span(span); + for (name, _, source_span, _, _) in &inaccessible_path_strings { + if let Some(source_span) = source_span { + let span = tcx.sess.source_map().guess_head_span(*source_span); spans.push((name, span)); } else { if !has_colon { From 727807293bc21c072162e9420096cb5a10cc63da Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Thu, 21 Mar 2024 16:35:45 +0000 Subject: [PATCH 118/165] Don't sort `DefId`s in suggestions --- .../src/traits/error_reporting/type_err_ctxt_ext.rs | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 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 9186241d6074..7a62030353d9 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 @@ -21,6 +21,7 @@ use crate::traits::{ }; 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::{Diag, EmissionGuarantee, ErrorGuaranteed, FatalError, StashKey}; @@ -2243,14 +2244,18 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { }; let required_trait_path = self.tcx.def_path_str(trait_ref.def_id()); - let traits_with_same_path: std::collections::BTreeSet<_> = self + let traits_with_same_path: UnordSet<_> = self .tcx .all_traits() .filter(|trait_def_id| *trait_def_id != trait_ref.def_id()) - .filter(|trait_def_id| self.tcx.def_path_str(*trait_def_id) == required_trait_path) + .map(|trait_def_id| (self.tcx.def_path_str(trait_def_id), trait_def_id)) + .filter(|(p, _)| *p == required_trait_path) .collect(); + + let traits_with_same_path = + traits_with_same_path.into_items().into_sorted_stable_ord_by_key(|(p, _)| p); let mut suggested = false; - for trait_with_same_path in traits_with_same_path { + for (_, trait_with_same_path) in traits_with_same_path { let trait_impls = get_trait_impls(trait_with_same_path); if trait_impls.is_empty() { continue; From 57f68c3555202c77bdf3b1aaf25449aba2946c0c Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Thu, 21 Mar 2024 16:47:04 +0000 Subject: [PATCH 119/165] Sort method suggestions by `DefPath` instead of `DefId` --- compiler/rustc_hir_typeck/src/method/mod.rs | 2 +- .../rustc_hir_typeck/src/method/suggest.rs | 5 +++- .../associated-const-ambiguity-report.stderr | 12 +++++----- tests/ui/issues/issue-18446.stderr | 14 +++++------ tests/ui/issues/issue-3702-2.stderr | 20 ++++++++-------- ...method-ambig-two-traits-cross-crate.stderr | 12 +++++----- ...mbig-two-traits-with-default-method.stderr | 16 ++++++------- ...e-trait-object-with-separate-params.stderr | 24 +++++++++---------- 8 files changed, 54 insertions(+), 51 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/method/mod.rs b/compiler/rustc_hir_typeck/src/method/mod.rs index e9752d7a4a8a..39d54f1a25e0 100644 --- a/compiler/rustc_hir_typeck/src/method/mod.rs +++ b/compiler/rustc_hir_typeck/src/method/mod.rs @@ -81,7 +81,7 @@ pub struct NoMatchData<'tcx> { // A pared down enum describing just the places from which a method // candidate can arise. Used for error reporting only. -#[derive(Copy, Clone, Debug, Eq, Ord, PartialEq, PartialOrd)] +#[derive(Copy, Clone, Debug, Eq, PartialEq)] pub enum CandidateSource { Impl(DefId), Trait(DefId /* trait id */), diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 952d53682986..3a4ff8fbb3ba 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -1567,7 +1567,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { sources: &mut Vec, sugg_span: Option, ) { - sources.sort(); + sources.sort_by_key(|source| match source { + CandidateSource::Trait(id) => (0, self.tcx.def_path_str(id)), + CandidateSource::Impl(id) => (1, self.tcx.def_path_str(id)), + }); sources.dedup(); // Dynamic limit to avoid hiding just one candidate, which is silly. let limit = if sources.len() == 5 { 5 } else { 4 }; diff --git a/tests/ui/associated-consts/associated-const-ambiguity-report.stderr b/tests/ui/associated-consts/associated-const-ambiguity-report.stderr index 42d722291c38..35ee95d1215b 100644 --- a/tests/ui/associated-consts/associated-const-ambiguity-report.stderr +++ b/tests/ui/associated-consts/associated-const-ambiguity-report.stderr @@ -4,16 +4,16 @@ error[E0034]: multiple applicable items in scope LL | const X: i32 = ::ID; | ^^ multiple `ID` found | -note: candidate #1 is defined in an impl of the trait `Foo` for the type `i32` - --> $DIR/associated-const-ambiguity-report.rs:10:5 - | -LL | const ID: i32 = 1; - | ^^^^^^^^^^^^^ -note: candidate #2 is defined in an impl of the trait `Bar` for the type `i32` +note: candidate #1 is defined in an impl of the trait `Bar` for the type `i32` --> $DIR/associated-const-ambiguity-report.rs:14:5 | LL | const ID: i32 = 3; | ^^^^^^^^^^^^^ +note: candidate #2 is defined in an impl of the trait `Foo` for the type `i32` + --> $DIR/associated-const-ambiguity-report.rs:10:5 + | +LL | const ID: i32 = 1; + | ^^^^^^^^^^^^^ help: use fully-qualified syntax to disambiguate | LL | const X: i32 = ::ID; diff --git a/tests/ui/issues/issue-18446.stderr b/tests/ui/issues/issue-18446.stderr index d84c490df4dc..08a9cfc644f4 100644 --- a/tests/ui/issues/issue-18446.stderr +++ b/tests/ui/issues/issue-18446.stderr @@ -4,17 +4,17 @@ error[E0034]: multiple applicable items in scope LL | x.foo(); | ^^^ multiple `foo` found | -note: candidate #1 is defined in an impl for the type `(dyn T + 'a)` - --> $DIR/issue-18446.rs:9:5 - | -LL | fn foo(&self) {} - | ^^^^^^^^^^^^^ -note: candidate #2 is defined in the trait `T` +note: candidate #1 is defined in the trait `T` --> $DIR/issue-18446.rs:5:5 | LL | fn foo(&self); | ^^^^^^^^^^^^^^ -help: disambiguate the method for candidate #2 +note: candidate #2 is defined in an impl for the type `(dyn T + 'a)` + --> $DIR/issue-18446.rs:9:5 + | +LL | fn foo(&self) {} + | ^^^^^^^^^^^^^ +help: disambiguate the method for candidate #1 | LL | T::foo(&x); | ~~~~~~~~~~ diff --git a/tests/ui/issues/issue-3702-2.stderr b/tests/ui/issues/issue-3702-2.stderr index 4edca796f43e..7ab6520a0cad 100644 --- a/tests/ui/issues/issue-3702-2.stderr +++ b/tests/ui/issues/issue-3702-2.stderr @@ -4,24 +4,24 @@ error[E0034]: multiple applicable items in scope LL | self.to_int() + other.to_int() | ^^^^^^ multiple `to_int` found | -note: candidate #1 is defined in an impl of the trait `ToPrimitive` for the type `isize` - --> $DIR/issue-3702-2.rs:2:5 - | -LL | fn to_int(&self) -> isize { 0 } - | ^^^^^^^^^^^^^^^^^^^^^^^^^ -note: candidate #2 is defined in an impl of the trait `Add` for the type `isize` +note: candidate #1 is defined in an impl of the trait `Add` for the type `isize` --> $DIR/issue-3702-2.rs:14:5 | LL | fn to_int(&self) -> isize { *self } | ^^^^^^^^^^^^^^^^^^^^^^^^^ -help: disambiguate the method for candidate #1 +note: candidate #2 is defined in an impl of the trait `ToPrimitive` for the type `isize` + --> $DIR/issue-3702-2.rs:2:5 | -LL | ToPrimitive::to_int(&self) + other.to_int() - | ~~~~~~~~~~~~~~~~~~~~~~~~~~ -help: disambiguate the method for candidate #2 +LL | fn to_int(&self) -> isize { 0 } + | ^^^^^^^^^^^^^^^^^^^^^^^^^ +help: disambiguate the method for candidate #1 | LL | Add::to_int(&self) + other.to_int() | ~~~~~~~~~~~~~~~~~~ +help: disambiguate the method for candidate #2 + | +LL | ToPrimitive::to_int(&self) + other.to_int() + | ~~~~~~~~~~~~~~~~~~~~~~~~~~ error: aborting due to 1 previous error diff --git a/tests/ui/methods/method-ambig-two-traits-cross-crate.stderr b/tests/ui/methods/method-ambig-two-traits-cross-crate.stderr index 0c775612bfbf..0fc0c909ea8f 100644 --- a/tests/ui/methods/method-ambig-two-traits-cross-crate.stderr +++ b/tests/ui/methods/method-ambig-two-traits-cross-crate.stderr @@ -4,20 +4,20 @@ error[E0034]: multiple applicable items in scope LL | fn main() { 1_usize.me(); } | ^^ multiple `me` found | - = note: candidate #1 is defined in an impl of the trait `Me` for the type `usize` -note: candidate #2 is defined in an impl of the trait `Me2` for the type `usize` +note: candidate #1 is defined in an impl of the trait `Me2` for the type `usize` --> $DIR/method-ambig-two-traits-cross-crate.rs:10:22 | LL | impl Me2 for usize { fn me(&self) -> usize { *self } } | ^^^^^^^^^^^^^^^^^^^^^ + = note: candidate #2 is defined in an impl of the trait `Me` for the type `usize` help: disambiguate the method for candidate #1 | -LL | fn main() { Me::me(&1_usize); } - | ~~~~~~~~~~~~~~~~ -help: disambiguate the method for candidate #2 - | LL | fn main() { Me2::me(&1_usize); } | ~~~~~~~~~~~~~~~~~ +help: disambiguate the method for candidate #2 + | +LL | fn main() { Me::me(&1_usize); } + | ~~~~~~~~~~~~~~~~ error: aborting due to 1 previous error diff --git a/tests/ui/methods/method-ambig-two-traits-with-default-method.stderr b/tests/ui/methods/method-ambig-two-traits-with-default-method.stderr index 9da307436e9b..b36ef77fb7ea 100644 --- a/tests/ui/methods/method-ambig-two-traits-with-default-method.stderr +++ b/tests/ui/methods/method-ambig-two-traits-with-default-method.stderr @@ -4,23 +4,23 @@ error[E0034]: multiple applicable items in scope LL | 1_usize.method(); | ^^^^^^ multiple `method` found | -note: candidate #1 is defined in an impl of the trait `Foo` for the type `usize` - --> $DIR/method-ambig-two-traits-with-default-method.rs:5:13 - | -LL | trait Foo { fn method(&self) {} } - | ^^^^^^^^^^^^^^^^ -note: candidate #2 is defined in an impl of the trait `Bar` for the type `usize` +note: candidate #1 is defined in an impl of the trait `Bar` for the type `usize` --> $DIR/method-ambig-two-traits-with-default-method.rs:6:13 | LL | trait Bar { fn method(&self) {} } | ^^^^^^^^^^^^^^^^ +note: candidate #2 is defined in an impl of the trait `Foo` for the type `usize` + --> $DIR/method-ambig-two-traits-with-default-method.rs:5:13 + | +LL | trait Foo { fn method(&self) {} } + | ^^^^^^^^^^^^^^^^ help: disambiguate the method for candidate #1 | -LL | Foo::method(&1_usize); +LL | Bar::method(&1_usize); | ~~~~~~~~~~~~~~~~~~~~~ help: disambiguate the method for candidate #2 | -LL | Bar::method(&1_usize); +LL | Foo::method(&1_usize); | ~~~~~~~~~~~~~~~~~~~~~ error: aborting due to 1 previous error diff --git a/tests/ui/methods/method-deref-to-same-trait-object-with-separate-params.stderr b/tests/ui/methods/method-deref-to-same-trait-object-with-separate-params.stderr index 755179650bba..6159d87c73e7 100644 --- a/tests/ui/methods/method-deref-to-same-trait-object-with-separate-params.stderr +++ b/tests/ui/methods/method-deref-to-same-trait-object-with-separate-params.stderr @@ -29,33 +29,33 @@ error[E0034]: multiple applicable items in scope LL | let z = x.foo(); | ^^^ multiple `foo` found | -note: candidate #1 is defined in an impl of the trait `X` for the type `T` - --> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:45:9 +note: candidate #1 is defined in the trait `FinalFoo` + --> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:59:5 | -LL | fn foo(self: Smaht) -> u64 { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | fn foo(&self) -> u8; + | ^^^^^^^^^^^^^^^^^^^^ note: candidate #2 is defined in an impl of the trait `NuisanceFoo` for the type `T` --> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:72:9 | LL | fn foo(self) {} | ^^^^^^^^^^^^ -note: candidate #3 is defined in the trait `FinalFoo` - --> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:59:5 +note: candidate #3 is defined in an impl of the trait `X` for the type `T` + --> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:45:9 | -LL | fn foo(&self) -> u8; - | ^^^^^^^^^^^^^^^^^^^^ +LL | fn foo(self: Smaht) -> u64 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: disambiguate the method for candidate #1 | -LL | let z = X::foo(x); - | ~~~~~~~~~ +LL | let z = FinalFoo::foo(&x); + | ~~~~~~~~~~~~~~~~~ help: disambiguate the method for candidate #2 | LL | let z = NuisanceFoo::foo(x); | ~~~~~~~~~~~~~~~~~~~ help: disambiguate the method for candidate #3 | -LL | let z = FinalFoo::foo(&x); - | ~~~~~~~~~~~~~~~~~ +LL | let z = X::foo(x); + | ~~~~~~~~~ error[E0308]: mismatched types --> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:139:24 From 6be79cb103ff92bfd6db55f9f7602049e557a3ce Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Thu, 21 Mar 2024 17:00:11 +0000 Subject: [PATCH 120/165] Sort a diagnostic by `DefPathStr` instead of `DefId` --- .../rustc_hir_typeck/src/method/suggest.rs | 30 +++---------------- .../no-method-suggested-traits.stderr | 8 ++--- tests/ui/methods/method-call-err-msg.stderr | 4 +-- .../method-on-unbounded-type-param.stderr | 16 +++++----- 4 files changed, 18 insertions(+), 40 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 3a4ff8fbb3ba..33eb9b839bd5 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -49,7 +49,6 @@ use std::borrow::Cow; use super::probe::{AutorefOrPtrAdjustment, IsSuggestion, Mode, ProbeScope}; use super::{CandidateSource, MethodError, NoMatchData}; use rustc_hir::intravisit::Visitor; -use std::cmp::{self, Ordering}; use std::iter; impl<'a, 'tcx> FnCtxt<'a, 'tcx> { @@ -3215,8 +3214,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } if !candidates.is_empty() { - // Sort from most relevant to least relevant. - candidates.sort_by_key(|&info| cmp::Reverse(info)); + // Sort local crate results before others + candidates + .sort_by_key(|&info| (!info.def_id.is_local(), self.tcx.def_path_str(info.def_id))); candidates.dedup(); let param_type = match rcvr_ty.kind() { @@ -3564,33 +3564,11 @@ pub enum SelfSource<'a> { MethodCall(&'a hir::Expr<'a> /* rcvr */), } -#[derive(Copy, Clone)] +#[derive(Copy, Clone, PartialEq, Eq)] pub struct TraitInfo { pub def_id: DefId, } -impl PartialEq for TraitInfo { - fn eq(&self, other: &TraitInfo) -> bool { - self.cmp(other) == Ordering::Equal - } -} -impl Eq for TraitInfo {} -impl PartialOrd for TraitInfo { - fn partial_cmp(&self, other: &TraitInfo) -> Option { - Some(self.cmp(other)) - } -} -impl Ord for TraitInfo { - fn cmp(&self, other: &TraitInfo) -> Ordering { - // Local crates are more important than remote ones (local: - // `cnum == 0`), and otherwise we throw in the defid for totality. - - let lhs = (other.def_id.krate, other.def_id); - let rhs = (self.def_id.krate, self.def_id); - lhs.cmp(&rhs) - } -} - /// Retrieves all traits in this crate and any dependent crates, /// and wraps them into `TraitInfo` for custom sorting. pub fn all_traits(tcx: TyCtxt<'_>) -> Vec { diff --git a/tests/ui/impl-trait/no-method-suggested-traits.stderr b/tests/ui/impl-trait/no-method-suggested-traits.stderr index 7a4dc366618e..676247d1a423 100644 --- a/tests/ui/impl-trait/no-method-suggested-traits.stderr +++ b/tests/ui/impl-trait/no-method-suggested-traits.stderr @@ -127,8 +127,8 @@ LL | Foo.method(); = note: the following traits define an item `method`, perhaps you need to implement one of them: candidate #1: `foo::Bar` candidate #2: `PubPub` - candidate #3: `no_method_suggested_traits::qux::PrivPub` - candidate #4: `Reexported` + candidate #3: `Reexported` + candidate #4: `no_method_suggested_traits::qux::PrivPub` error[E0599]: no method named `method` found for struct `Rc<&mut Box<&Foo>>` in the current scope --> $DIR/no-method-suggested-traits.rs:42:43 @@ -140,8 +140,8 @@ LL | std::rc::Rc::new(&mut Box::new(&Foo)).method(); = note: the following traits define an item `method`, perhaps you need to implement one of them: candidate #1: `foo::Bar` candidate #2: `PubPub` - candidate #3: `no_method_suggested_traits::qux::PrivPub` - candidate #4: `Reexported` + candidate #3: `Reexported` + candidate #4: `no_method_suggested_traits::qux::PrivPub` error[E0599]: no method named `method2` found for type `u64` in the current scope --> $DIR/no-method-suggested-traits.rs:45:10 diff --git a/tests/ui/methods/method-call-err-msg.stderr b/tests/ui/methods/method-call-err-msg.stderr index 6df49e432a13..7d9b38fb29b5 100644 --- a/tests/ui/methods/method-call-err-msg.stderr +++ b/tests/ui/methods/method-call-err-msg.stderr @@ -64,8 +64,8 @@ note: the trait `Iterator` must be implemented --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL = help: items from traits can only be used if the trait is implemented and in scope = note: the following traits define an item `take`, perhaps you need to implement one of them: - candidate #1: `std::io::Read` - candidate #2: `Iterator` + candidate #1: `Iterator` + candidate #2: `std::io::Read` error[E0061]: this method takes 3 arguments but 0 arguments were supplied --> $DIR/method-call-err-msg.rs:21:7 diff --git a/tests/ui/traits/method-on-unbounded-type-param.stderr b/tests/ui/traits/method-on-unbounded-type-param.stderr index 0d8bd8ee964e..4d968e7bee10 100644 --- a/tests/ui/traits/method-on-unbounded-type-param.stderr +++ b/tests/ui/traits/method-on-unbounded-type-param.stderr @@ -9,10 +9,10 @@ LL | a.cmp(&b) = help: items from traits can only be used if the type parameter is bounded by the trait help: the following traits define an item `cmp`, perhaps you need to restrict type parameter `T` with one of them: | -LL | fn f(a: T, b: T) -> std::cmp::Ordering { - | +++++ LL | fn f(a: T, b: T) -> std::cmp::Ordering { | ++++++++++ +LL | fn f(a: T, b: T) -> std::cmp::Ordering { + | +++++ error[E0599]: the method `cmp` exists for reference `&T`, but its trait bounds were not satisfied --> $DIR/method-on-unbounded-type-param.rs:5:10 @@ -30,10 +30,10 @@ LL | (&a).cmp(&b) = help: items from traits can only be used if the type parameter is bounded by the trait help: the following traits define an item `cmp`, perhaps you need to restrict type parameter `T` with one of them: | -LL | fn g(a: T, b: T) -> std::cmp::Ordering { - | +++++ LL | fn g(a: T, b: T) -> std::cmp::Ordering { | ++++++++++ +LL | fn g(a: T, b: T) -> std::cmp::Ordering { + | +++++ error[E0599]: the method `cmp` exists for reference `&T`, but its trait bounds were not satisfied --> $DIR/method-on-unbounded-type-param.rs:8:7 @@ -51,10 +51,10 @@ LL | a.cmp(&b) = help: items from traits can only be used if the type parameter is bounded by the trait help: the following traits define an item `cmp`, perhaps you need to restrict type parameter `T` with one of them: | -LL | fn h(a: &T, b: T) -> std::cmp::Ordering { - | +++++ LL | fn h(a: &T, b: T) -> std::cmp::Ordering { | ++++++++++ +LL | fn h(a: &T, b: T) -> std::cmp::Ordering { + | +++++ error[E0599]: the method `cmp` exists for struct `Box`, but its trait bounds were not satisfied --> $DIR/method-on-unbounded-type-param.rs:14:7 @@ -76,8 +76,8 @@ LL | x.cmp(&x); which is required by `&mut dyn T: Iterator` = help: items from traits can only be used if the trait is implemented and in scope = note: the following traits define an item `cmp`, perhaps you need to implement one of them: - candidate #1: `Ord` - candidate #2: `Iterator` + candidate #1: `Iterator` + candidate #2: `Ord` error: aborting due to 4 previous errors From 5676326c7292e043278f2cfc2b35d93167817f30 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Thu, 21 Mar 2024 17:04:56 +0000 Subject: [PATCH 121/165] Sort somem diagnostics by `DefPathStr` instead of `DefId` --- compiler/rustc_hir_typeck/src/method/suggest.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 33eb9b839bd5..34b73947e3d9 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -2665,7 +2665,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { traits.push(trait_pred.def_id()); } } - traits.sort(); + traits.sort_by_key(|id| self.tcx.def_path_str(id)); traits.dedup(); let len = traits.len(); @@ -2888,7 +2888,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ) -> bool { if !valid_out_of_scope_traits.is_empty() { let mut candidates = valid_out_of_scope_traits; - candidates.sort(); + candidates.sort_by_key(|id| self.tcx.def_path_str(id)); candidates.dedup(); // `TryFrom` and `FromIterator` have no methods From e522d2906d712b27fa218ccabe3e962bfab9867b Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Thu, 21 Mar 2024 17:14:14 +0000 Subject: [PATCH 122/165] Stop sorting `DefId`s in the compiler --- compiler/rustc_hir_typeck/src/method/suggest.rs | 2 +- tests/ui/methods/method-not-found-generic-arg-elision.stderr | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 34b73947e3d9..12f522d1adcf 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -1185,7 +1185,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }) .collect::>(); if !inherent_impls_candidate.is_empty() { - inherent_impls_candidate.sort(); + inherent_impls_candidate.sort_by_key(|id| self.tcx.def_path_str(id)); inherent_impls_candidate.dedup(); // number of types to show at most diff --git a/tests/ui/methods/method-not-found-generic-arg-elision.stderr b/tests/ui/methods/method-not-found-generic-arg-elision.stderr index b97688d3868b..a665500fd9e1 100644 --- a/tests/ui/methods/method-not-found-generic-arg-elision.stderr +++ b/tests/ui/methods/method-not-found-generic-arg-elision.stderr @@ -35,10 +35,10 @@ LL | wrapper.method(); | ^^^^^^ method not found in `Wrapper` | = note: the method was found for - - `Wrapper` - `Wrapper` - `Wrapper` - `Wrapper` + - `Wrapper` and 2 more types error[E0599]: no method named `other` found for struct `Wrapper` in the current scope @@ -60,9 +60,9 @@ LL | wrapper.method(); | ^^^^^^ method not found in `Wrapper2<'_, bool, 3>` | = note: the method was found for - - `Wrapper2<'a, i8, C>` - `Wrapper2<'a, i16, C>` - `Wrapper2<'a, i32, C>` + - `Wrapper2<'a, i8, C>` error[E0599]: no method named `other` found for struct `Wrapper2` in the current scope --> $DIR/method-not-found-generic-arg-elision.rs:98:13 From 5f4ac61ebdeb5024744e0a828d2ff79b2b71740d Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Thu, 21 Mar 2024 17:23:00 +0000 Subject: [PATCH 123/165] Remove `DefId`'s `Partial/Ord` impls --- compiler/rustc_span/src/def_id.rs | 18 ------------------ compiler/rustc_type_ir/src/interner.rs | 2 +- src/librustdoc/clean/mod.rs | 13 ++++++------- src/librustdoc/core.rs | 2 +- src/librustdoc/html/render/search_index.rs | 4 ++-- 5 files changed, 10 insertions(+), 29 deletions(-) diff --git a/compiler/rustc_span/src/def_id.rs b/compiler/rustc_span/src/def_id.rs index 0c811d7dff1d..5454f6661a98 100644 --- a/compiler/rustc_span/src/def_id.rs +++ b/compiler/rustc_span/src/def_id.rs @@ -218,8 +218,6 @@ rustc_index::newtype_index! { /// /// You can create a `DefId` from a `LocalDefId` using `local_def_id.to_def_id()`. #[derive(Clone, PartialEq, Eq, Copy)] -// Don't derive order on 64-bit big-endian, so we can be consistent regardless of field order. -#[cfg_attr(not(all(target_pointer_width = "64", target_endian = "big")), derive(PartialOrd, Ord))] // On below-64 bit systems we can simply use the derived `Hash` impl #[cfg_attr(not(target_pointer_width = "64"), derive(Hash))] #[repr(C)] @@ -261,22 +259,6 @@ impl Hash for DefId { } } -// Implement the same comparison as derived with the other field order. -#[cfg(all(target_pointer_width = "64", target_endian = "big"))] -impl Ord for DefId { - #[inline] - fn cmp(&self, other: &DefId) -> std::cmp::Ordering { - Ord::cmp(&(self.index, self.krate), &(other.index, other.krate)) - } -} -#[cfg(all(target_pointer_width = "64", target_endian = "big"))] -impl PartialOrd for DefId { - #[inline] - fn partial_cmp(&self, other: &DefId) -> Option { - Some(self.cmp(other)) - } -} - impl DefId { /// Makes a local `DefId` from the given `DefIndex`. #[inline] diff --git a/compiler/rustc_type_ir/src/interner.rs b/compiler/rustc_type_ir/src/interner.rs index bd67fdbfb2b7..ae1e1902f14c 100644 --- a/compiler/rustc_type_ir/src/interner.rs +++ b/compiler/rustc_type_ir/src/interner.rs @@ -9,7 +9,7 @@ use crate::{ }; pub trait Interner: Sized { - type DefId: Copy + Debug + Hash + Ord; + type DefId: Copy + Debug + Hash + Eq; type AdtDef: Copy + Debug + Hash + Eq; type GenericArgs: Copy diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index ef707d179ea3..0cdf52bfb004 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -41,7 +41,7 @@ use std::hash::Hash; use std::mem; use thin_vec::ThinVec; -use crate::core::{self, DocContext, ImplTraitParam}; +use crate::core::{self, DocContext}; use crate::formats::item_type::ItemType; use crate::visit_ast::Module as DocModule; @@ -761,7 +761,7 @@ fn clean_ty_generics<'tcx>( ) -> Generics { // Don't populate `cx.impl_trait_bounds` before `clean`ning `where` clauses, // since `Clean for ty::Predicate` would consume them. - let mut impl_trait = BTreeMap::>::default(); + let mut impl_trait = BTreeMap::>::default(); // Bounds in the type_params and lifetimes fields are repeated in the // predicates field (see rustc_hir_analysis::collect::ty_generics), so remove @@ -778,7 +778,7 @@ fn clean_ty_generics<'tcx>( return None; } if synthetic { - impl_trait.insert(param.index.into(), vec![]); + impl_trait.insert(param.index, vec![]); return None; } Some(clean_generic_param_def(param, cx)) @@ -823,7 +823,7 @@ fn clean_ty_generics<'tcx>( })(); if let Some(param_idx) = param_idx - && let Some(bounds) = impl_trait.get_mut(¶m_idx.into()) + && let Some(bounds) = impl_trait.get_mut(¶m_idx) { let pred = clean_predicate(*pred, cx)?; @@ -847,7 +847,7 @@ fn clean_ty_generics<'tcx>( }) .collect::>(); - for (param, mut bounds) in impl_trait { + for (idx, mut bounds) in impl_trait { let mut has_sized = false; bounds.retain(|b| { if b.is_sized_bound(cx) { @@ -870,7 +870,6 @@ fn clean_ty_generics<'tcx>( bounds.insert(0, GenericBound::sized(cx)); } - let crate::core::ImplTraitParam::ParamIndex(idx) = param else { unreachable!() }; if let Some(proj) = impl_trait_proj.remove(&idx) { for (trait_did, name, rhs) in proj { let rhs = clean_middle_term(rhs, cx); @@ -878,7 +877,7 @@ fn clean_ty_generics<'tcx>( } } - cx.impl_trait_bounds.insert(param, bounds); + cx.impl_trait_bounds.insert(idx.into(), bounds); } // Now that `cx.impl_trait_bounds` is populated, we can process diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 80a30ac27277..25b78d9598d8 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -509,7 +509,7 @@ impl<'tcx> Visitor<'tcx> for EmitIgnoredResolutionErrors<'tcx> { /// `DefId` or parameter index (`ty::ParamTy.index`) of a synthetic type parameter /// for `impl Trait` in argument position. -#[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[derive(Clone, Copy, PartialEq, Eq, Hash)] pub(crate) enum ImplTraitParam { DefId(DefId), ParamIndex(u32), diff --git a/src/librustdoc/html/render/search_index.rs b/src/librustdoc/html/render/search_index.rs index f153a9083291..b244309da692 100644 --- a/src/librustdoc/html/render/search_index.rs +++ b/src/librustdoc/html/render/search_index.rs @@ -65,8 +65,8 @@ pub(crate) fn build_index<'tcx>( // Sort search index items. This improves the compressibility of the search index. cache.search_index.sort_unstable_by(|k1, k2| { // `sort_unstable_by_key` produces lifetime errors - let k1 = (&k1.path, k1.name.as_str(), &k1.ty, &k1.parent); - let k2 = (&k2.path, k2.name.as_str(), &k2.ty, &k2.parent); + let k1 = (&k1.path, k1.name.as_str(), &k1.ty, &k1.parent.map(|id| tcx.def_path_str(id))); + let k2 = (&k2.path, k2.name.as_str(), &k2.ty, &k2.parent.map(|id| tcx.def_path_str(id))); Ord::cmp(&k1, &k2) }); From cf3ab41c8331bac9aa8efc1a3d75b8bdeb8f26cc Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Thu, 21 Mar 2024 17:24:49 +0000 Subject: [PATCH 124/165] Ensure no one re-adds `Partial/Ord` impls for `DefId` --- compiler/rustc_span/src/def_id.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/compiler/rustc_span/src/def_id.rs b/compiler/rustc_span/src/def_id.rs index 5454f6661a98..8f721bac9514 100644 --- a/compiler/rustc_span/src/def_id.rs +++ b/compiler/rustc_span/src/def_id.rs @@ -234,6 +234,12 @@ pub struct DefId { pub index: DefIndex, } +// To ensure correctness of incremental compilation, +// `DefId` must not implement `Ord` or `PartialOrd`. +// See https://github.com/rust-lang/rust/issues/90317. +impl !Ord for DefId {} +impl !PartialOrd for DefId {} + // On 64-bit systems, we can hash the whole `DefId` as one `u64` instead of two `u32`s. This // improves performance without impairing `FxHash` quality. So the below code gets compiled to a // noop on little endian systems because the memory layout of `DefId` is as follows: From d03df0a6b349289690ac2c11d71c5ed8e859f2be Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Fri, 22 Mar 2024 11:52:33 +0000 Subject: [PATCH 125/165] Add rustdoc hack --- src/librustdoc/html/render/search_index.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/librustdoc/html/render/search_index.rs b/src/librustdoc/html/render/search_index.rs index b244309da692..be2786c99eca 100644 --- a/src/librustdoc/html/render/search_index.rs +++ b/src/librustdoc/html/render/search_index.rs @@ -65,8 +65,9 @@ pub(crate) fn build_index<'tcx>( // Sort search index items. This improves the compressibility of the search index. cache.search_index.sort_unstable_by(|k1, k2| { // `sort_unstable_by_key` produces lifetime errors - let k1 = (&k1.path, k1.name.as_str(), &k1.ty, &k1.parent.map(|id| tcx.def_path_str(id))); - let k2 = (&k2.path, k2.name.as_str(), &k2.ty, &k2.parent.map(|id| tcx.def_path_str(id))); + // HACK(rustdoc): should not be sorting `CrateNum` or `DefIndex`, this will soon go away, too + let k1 = (&k1.path, k1.name.as_str(), &k1.ty, k1.parent.map(|id| (id.index, id.krate))); + let k2 = (&k2.path, k2.name.as_str(), &k2.ty, k2.parent.map(|id| (id.index, id.krate))); Ord::cmp(&k1, &k2) }); From 2fe936f17d86fa1c8bcf96844888ccf740cf3d89 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sun, 24 Mar 2024 12:23:36 -0400 Subject: [PATCH 126/165] Stop doing expensive work in opt_suggest_box_span eagerly --- compiler/rustc_hir_typeck/messages.ftl | 4 + compiler/rustc_hir_typeck/src/_match.rs | 139 +++++------------ compiler/rustc_hir_typeck/src/coercion.rs | 141 +++++++++++++++++- compiler/rustc_hir_typeck/src/errors.rs | 18 +++ compiler/rustc_hir_typeck/src/expr.rs | 5 +- compiler/rustc_infer/messages.ftl | 3 - compiler/rustc_infer/src/errors/mod.rs | 18 --- .../src/infer/error_reporting/mod.rs | 38 +---- .../src/infer/error_reporting/suggest.rs | 27 +--- compiler/rustc_infer/src/infer/mod.rs | 9 ++ compiler/rustc_middle/src/traits/mod.rs | 6 +- 11 files changed, 217 insertions(+), 191 deletions(-) diff --git a/compiler/rustc_hir_typeck/messages.ftl b/compiler/rustc_hir_typeck/messages.ftl index 0ca958302f79..f7af438ad16c 100644 --- a/compiler/rustc_hir_typeck/messages.ftl +++ b/compiler/rustc_hir_typeck/messages.ftl @@ -122,6 +122,10 @@ hir_typeck_return_stmt_outside_of_fn_body = .encl_body_label = the {$statement_kind} is part of this body... .encl_fn_label = ...not the enclosing function body +hir_typeck_rpit_box_return_expr = if you change the return type to expect trait objects, box the returned expressions + +hir_typeck_rpit_change_return_type = you could change the return type to be a boxed trait object + hir_typeck_rustcall_incorrect_args = functions with the "rust-call" ABI must take a single non-self tuple argument diff --git a/compiler/rustc_hir_typeck/src/_match.rs b/compiler/rustc_hir_typeck/src/_match.rs index e42db342f14e..2a2fd0a41a62 100644 --- a/compiler/rustc_hir_typeck/src/_match.rs +++ b/compiler/rustc_hir_typeck/src/_match.rs @@ -1,17 +1,13 @@ use crate::coercion::{AsCoercionSite, CoerceMany}; use crate::{Diverges, Expectation, FnCtxt, Needs}; use rustc_errors::{Applicability, Diag}; -use rustc_hir::{ - self as hir, - def::{CtorOf, DefKind, Res}, - ExprKind, PatKind, -}; +use rustc_hir::def::{CtorOf, DefKind, Res}; +use rustc_hir::def_id::LocalDefId; +use rustc_hir::{self as hir, ExprKind, PatKind}; use rustc_hir_pretty::ty_to_string; use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; -use rustc_infer::traits::Obligation; use rustc_middle::ty::{self, Ty}; use rustc_span::Span; -use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt; use rustc_trait_selection::traits::{ IfExpressionCause, MatchExpressionArmCause, ObligationCause, ObligationCauseCode, }; @@ -91,10 +87,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let arm_ty = self.check_expr_with_expectation(arm.body, expected); all_arms_diverge &= self.diverges.get(); - - let opt_suggest_box_span = prior_arm.and_then(|(_, prior_arm_ty, _)| { - self.opt_suggest_box_span(prior_arm_ty, arm_ty, orig_expected) - }); + let tail_defines_return_position_impl_trait = + self.return_position_impl_trait_from_match_expectation(orig_expected); let (arm_block_id, arm_span) = if let hir::ExprKind::Block(blk, _) = arm.body.kind { (Some(blk.hir_id), self.find_block_span(blk)) @@ -120,7 +114,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { scrut_span: scrut.span, source: match_src, prior_non_diverging_arms: prior_non_diverging_arms.clone(), - opt_suggest_box_span, + tail_defines_return_position_impl_trait, })), ), }; @@ -422,7 +416,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { else_expr: &'tcx hir::Expr<'tcx>, then_ty: Ty<'tcx>, else_ty: Ty<'tcx>, - opt_suggest_box_span: Option, + tail_defines_return_position_impl_trait: Option, ) -> ObligationCause<'tcx> { let mut outer_span = if self.tcx.sess.source_map().is_multiline(span) { // The `if`/`else` isn't in one line in the output, include some context to make it @@ -513,7 +507,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { then_ty, else_ty, outer_span, - opt_suggest_box_span, + tail_defines_return_position_impl_trait, })), ) } @@ -593,96 +587,37 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } - /// When we have a `match` as a tail expression in a `fn` with a returned `impl Trait` - /// we check if the different arms would work with boxed trait objects instead and - /// provide a structured suggestion in that case. - pub(crate) fn opt_suggest_box_span( + // Does the expectation of the match define an RPIT? + // (e.g. we're in the tail of a function body) + // + // Returns the `LocalDefId` of the RPIT, which is always identity-substituted. + pub fn return_position_impl_trait_from_match_expectation( &self, - first_ty: Ty<'tcx>, - second_ty: Ty<'tcx>, - orig_expected: Expectation<'tcx>, - ) -> Option { - // FIXME(compiler-errors): This really shouldn't need to be done during the - // "good" path of typeck, but here we are. - match orig_expected { - Expectation::ExpectHasType(expected) => { - let TypeVariableOrigin { - span, - kind: TypeVariableOriginKind::OpaqueTypeInference(rpit_def_id), - .. - } = self.type_var_origin(expected)? - else { - return None; - }; - - let Some(rpit_local_def_id) = rpit_def_id.as_local() else { - return None; - }; - if !matches!( - self.tcx.hir().expect_item(rpit_local_def_id).expect_opaque_ty().origin, - hir::OpaqueTyOrigin::FnReturn(..) - ) { - return None; - } - - let sig = self.body_fn_sig()?; - - let args = sig.output().walk().find_map(|arg| { - if let ty::GenericArgKind::Type(ty) = arg.unpack() - && let ty::Alias(ty::Opaque, ty::AliasTy { def_id, args, .. }) = *ty.kind() - && def_id == rpit_def_id - { - Some(args) - } else { - None - } - })?; - - if !self.can_coerce(first_ty, expected) || !self.can_coerce(second_ty, expected) { - return None; - } - - for ty in [first_ty, second_ty] { - for (clause, _) in self - .tcx - .explicit_item_super_predicates(rpit_def_id) - .iter_instantiated_copied(self.tcx, args) - { - let pred = clause.kind().rebind(match clause.kind().skip_binder() { - ty::ClauseKind::Trait(trait_pred) => { - assert!(matches!( - *trait_pred.trait_ref.self_ty().kind(), - ty::Alias(ty::Opaque, ty::AliasTy { def_id, args: alias_args, .. }) - if def_id == rpit_def_id && args == alias_args - )); - ty::ClauseKind::Trait(trait_pred.with_self_ty(self.tcx, ty)) - } - ty::ClauseKind::Projection(mut proj_pred) => { - assert!(matches!( - *proj_pred.projection_ty.self_ty().kind(), - ty::Alias(ty::Opaque, ty::AliasTy { def_id, args: alias_args, .. }) - if def_id == rpit_def_id && args == alias_args - )); - proj_pred = proj_pred.with_self_ty(self.tcx, ty); - ty::ClauseKind::Projection(proj_pred) - } - _ => continue, - }); - if !self.predicate_must_hold_modulo_regions(&Obligation::new( - self.tcx, - ObligationCause::misc(span, self.body_id), - self.param_env, - pred, - )) { - return None; - } - } - } - - Some(span) - } - _ => None, + expectation: Expectation<'tcx>, + ) -> Option { + let expected_ty = expectation.to_option(self)?; + let (def_id, args) = match *expected_ty.kind() { + // FIXME: Could also check that the RPIT is not defined + ty::Alias(ty::Opaque, alias_ty) => (alias_ty.def_id.as_local()?, alias_ty.args), + // FIXME(-Znext-solver): Remove this branch once `replace_opaque_types_with_infer` is gone. + ty::Infer(ty::TyVar(_)) => self + .inner + .borrow() + .iter_opaque_types() + .find(|(_, v)| v.ty == expected_ty) + .map(|(k, _)| (k.def_id, k.args))?, + _ => return None, + }; + let hir::OpaqueTyOrigin::FnReturn(parent_def_id) = self.tcx.opaque_type_origin(def_id) + else { + return None; + }; + if &args[0..self.tcx.generics_of(parent_def_id).count()] + != ty::GenericArgs::identity_for_item(self.tcx, parent_def_id).as_slice() + { + return None; } + Some(def_id) } } diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs index 3328177634b0..44b19318d5d1 100644 --- a/compiler/rustc_hir_typeck/src/coercion.rs +++ b/compiler/rustc_hir_typeck/src/coercion.rs @@ -35,17 +35,18 @@ //! // and are then unable to coerce `&7i32` to `&mut i32`. //! ``` +use crate::errors::SuggestBoxingForReturnImplTrait; use crate::FnCtxt; use rustc_errors::{codes::*, struct_span_code_err, Applicability, Diag, MultiSpan}; use rustc_hir as hir; -use rustc_hir::def_id::DefId; +use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::Expr; use rustc_hir_analysis::hir_ty_lowering::HirTyLowerer; use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; use rustc_infer::infer::{Coercion, DefineOpaqueTypes, InferOk, InferResult}; -use rustc_infer::traits::TraitEngine; use rustc_infer::traits::TraitEngineExt as _; +use rustc_infer::traits::{IfExpressionCause, MatchExpressionArmCause, TraitEngine}; use rustc_infer::traits::{Obligation, PredicateObligation}; use rustc_middle::lint::in_external_macro; use rustc_middle::traits::BuiltinImplSource; @@ -59,6 +60,7 @@ use rustc_middle::ty::{self, GenericArgsRef, Ty, TyCtxt}; use rustc_session::parse::feature_err; use rustc_span::symbol::sym; use rustc_span::DesugaringKind; +use rustc_span::{BytePos, Span}; use rustc_target::spec::abi::Abi; use rustc_trait_selection::infer::InferCtxtExt as _; use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt as _; @@ -1638,6 +1640,77 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { unsized_return = self.is_return_ty_definitely_unsized(fcx); } } + ObligationCauseCode::MatchExpressionArm(box MatchExpressionArmCause { + arm_span, + arm_ty, + prior_arm_ty, + ref prior_non_diverging_arms, + tail_defines_return_position_impl_trait: Some(rpit_def_id), + .. + }) => { + err = fcx.err_ctxt().report_mismatched_types( + cause, + expected, + found, + coercion_error, + ); + // Check that we're actually in the second or later arm + if prior_non_diverging_arms.len() > 0 { + self.suggest_boxing_tail_for_return_position_impl_trait( + fcx, + &mut err, + rpit_def_id, + arm_ty, + prior_arm_ty, + prior_non_diverging_arms + .iter() + .chain(std::iter::once(&arm_span)) + .copied(), + ); + } + } + ObligationCauseCode::IfExpression(box IfExpressionCause { + then_id, + else_id, + then_ty, + else_ty, + tail_defines_return_position_impl_trait: Some(rpit_def_id), + .. + }) => { + err = fcx.err_ctxt().report_mismatched_types( + cause, + expected, + found, + coercion_error, + ); + let then_span = fcx.find_block_span_from_hir_id(then_id); + let else_span = fcx.find_block_span_from_hir_id(else_id); + // don't suggest wrapping either blocks in `if .. {} else {}` + let is_empty_arm = |id| { + let hir::Node::Block(blk) = fcx.tcx.hir_node(id) else { + return false; + }; + if blk.expr.is_some() || !blk.stmts.is_empty() { + return false; + } + let Some((_, hir::Node::Expr(expr))) = + fcx.tcx.hir().parent_iter(id).nth(1) + else { + return false; + }; + matches!(expr.kind, hir::ExprKind::If(..)) + }; + if !is_empty_arm(then_id) && !is_empty_arm(else_id) { + self.suggest_boxing_tail_for_return_position_impl_trait( + fcx, + &mut err, + rpit_def_id, + then_ty, + else_ty, + [then_span, else_span].into_iter(), + ); + } + } _ => { err = fcx.err_ctxt().report_mismatched_types( cause, @@ -1677,6 +1750,70 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { } } + fn suggest_boxing_tail_for_return_position_impl_trait( + &self, + fcx: &FnCtxt<'_, 'tcx>, + err: &mut Diag<'_>, + rpit_def_id: LocalDefId, + a_ty: Ty<'tcx>, + b_ty: Ty<'tcx>, + arm_spans: impl Iterator, + ) { + let compatible = |ty: Ty<'tcx>| { + fcx.probe(|_| { + let ocx = ObligationCtxt::new(fcx); + ocx.register_obligations( + fcx.tcx + .item_super_predicates(rpit_def_id) + .instantiate_identity_iter() + .filter_map(|clause| { + let predicate = clause + .kind() + .map_bound(|clause| match clause { + ty::ClauseKind::Trait(trait_pred) => Some( + ty::ClauseKind::Trait(trait_pred.with_self_ty(fcx.tcx, ty)), + ), + ty::ClauseKind::Projection(proj_pred) => { + Some(ty::ClauseKind::Projection( + proj_pred.with_self_ty(fcx.tcx, ty), + )) + } + _ => None, + }) + .transpose()?; + Some(Obligation::new( + fcx.tcx, + ObligationCause::dummy(), + fcx.param_env, + predicate, + )) + }), + ); + ocx.select_where_possible().is_empty() + }) + }; + + if !compatible(a_ty) || !compatible(b_ty) { + return; + } + + let rpid_def_span = fcx.tcx.def_span(rpit_def_id); + err.subdiagnostic( + fcx.tcx.dcx(), + SuggestBoxingForReturnImplTrait::ChangeReturnType { + start_sp: rpid_def_span.with_hi(rpid_def_span.lo() + BytePos(4)), + end_sp: rpid_def_span.shrink_to_hi(), + }, + ); + + let (starts, ends) = + arm_spans.map(|span| (span.shrink_to_lo(), span.shrink_to_hi())).unzip(); + err.subdiagnostic( + fcx.tcx.dcx(), + SuggestBoxingForReturnImplTrait::BoxReturnExpr { starts, ends }, + ); + } + fn note_unreachable_loop_return( &self, err: &mut Diag<'_>, diff --git a/compiler/rustc_hir_typeck/src/errors.rs b/compiler/rustc_hir_typeck/src/errors.rs index eee4ac5ad23b..f9b2ec697300 100644 --- a/compiler/rustc_hir_typeck/src/errors.rs +++ b/compiler/rustc_hir_typeck/src/errors.rs @@ -621,3 +621,21 @@ pub struct NoteCallerChoosesTyForTyParam<'tcx> { pub ty_param_name: Symbol, pub found_ty: Ty<'tcx>, } + +#[derive(Subdiagnostic)] +pub enum SuggestBoxingForReturnImplTrait { + #[multipart_suggestion(hir_typeck_rpit_change_return_type, applicability = "maybe-incorrect")] + ChangeReturnType { + #[suggestion_part(code = "Box, + #[suggestion_part(code = ")")] + ends: Vec, + }, +} diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index f38f04fce43f..d3e6eb124f72 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -1088,7 +1088,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let else_ty = self.check_expr_with_expectation(else_expr, expected); let else_diverges = self.diverges.get(); - let opt_suggest_box_span = self.opt_suggest_box_span(then_ty, else_ty, orig_expected); + let tail_defines_return_position_impl_trait = + self.return_position_impl_trait_from_match_expectation(orig_expected); let if_cause = self.if_cause( sp, cond_expr.span, @@ -1096,7 +1097,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { else_expr, then_ty, else_ty, - opt_suggest_box_span, + tail_defines_return_position_impl_trait, ); coerce.coerce(self, &if_cause, else_expr, else_ty); diff --git a/compiler/rustc_infer/messages.ftl b/compiler/rustc_infer/messages.ftl index 521c65c60091..fdb6ab8f59b9 100644 --- a/compiler/rustc_infer/messages.ftl +++ b/compiler/rustc_infer/messages.ftl @@ -270,9 +270,6 @@ infer_ril_introduced_by = requirement introduced by this return type infer_ril_introduced_here = `'static` requirement introduced here infer_ril_static_introduced_by = "`'static` lifetime requirement introduced by the return type -infer_sbfrit_box_return_expr = if you change the return type to expect trait objects, box the returned expressions - -infer_sbfrit_change_return_type = you could change the return type to be a boxed trait object infer_source_kind_closure_return = try giving this closure an explicit return type diff --git a/compiler/rustc_infer/src/errors/mod.rs b/compiler/rustc_infer/src/errors/mod.rs index d0b1f2848ff3..6192eaf3c3a4 100644 --- a/compiler/rustc_infer/src/errors/mod.rs +++ b/compiler/rustc_infer/src/errors/mod.rs @@ -1262,24 +1262,6 @@ pub enum SuggestAccessingField<'a> { }, } -#[derive(Subdiagnostic)] -pub enum SuggestBoxingForReturnImplTrait { - #[multipart_suggestion(infer_sbfrit_change_return_type, applicability = "maybe-incorrect")] - ChangeReturnType { - #[suggestion_part(code = "Box, - #[suggestion_part(code = ")")] - ends: Vec, - }, -} - #[derive(Subdiagnostic)] #[multipart_suggestion(infer_stp_wrap_one, applicability = "maybe-incorrect")] pub struct SuggestTuplePatternOne { diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index 82634f7308d5..dd438736baa6 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -784,7 +784,6 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { prior_arm_ty, source, ref prior_non_diverging_arms, - opt_suggest_box_span, scrut_span, .. }) => match source { @@ -853,17 +852,6 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { ) { err.subdiagnostic(self.dcx(), subdiag); } - if let Some(ret_sp) = opt_suggest_box_span { - // Get return type span and point to it. - self.suggest_boxing_for_return_impl_trait( - err, - ret_sp, - prior_non_diverging_arms - .iter() - .chain(std::iter::once(&arm_span)) - .copied(), - ); - } } }, ObligationCauseCode::IfExpression(box IfExpressionCause { @@ -872,7 +860,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { then_ty, else_ty, outer_span, - opt_suggest_box_span, + .. }) => { let then_span = self.find_block_span_from_hir_id(then_id); let else_span = self.find_block_span_from_hir_id(else_id); @@ -890,30 +878,6 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { ) { err.subdiagnostic(self.dcx(), subdiag); } - // don't suggest wrapping either blocks in `if .. {} else {}` - let is_empty_arm = |id| { - let hir::Node::Block(blk) = self.tcx.hir_node(id) else { - return false; - }; - if blk.expr.is_some() || !blk.stmts.is_empty() { - return false; - } - let Some((_, hir::Node::Expr(expr))) = self.tcx.hir().parent_iter(id).nth(1) - else { - return false; - }; - matches!(expr.kind, hir::ExprKind::If(..)) - }; - if let Some(ret_sp) = opt_suggest_box_span - && !is_empty_arm(then_id) - && !is_empty_arm(else_id) - { - self.suggest_boxing_for_return_impl_trait( - err, - ret_sp, - [then_span, else_span].into_iter(), - ); - } } ObligationCauseCode::LetElse => { err.help("try adding a diverging expression, such as `return` or `panic!(..)`"); diff --git a/compiler/rustc_infer/src/infer/error_reporting/suggest.rs b/compiler/rustc_infer/src/infer/error_reporting/suggest.rs index e220c4d02a2e..9a05fb1c30f8 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/suggest.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/suggest.rs @@ -19,9 +19,8 @@ use rustc_span::{sym, BytePos, Span}; use crate::errors::{ ConsiderAddingAwait, FnConsiderCasting, FnItemsAreDistinct, FnUniqTypes, - FunctionPointerSuggestion, SuggestAccessingField, SuggestBoxingForReturnImplTrait, - SuggestRemoveSemiOrReturnBinding, SuggestTuplePatternMany, SuggestTuplePatternOne, - TypeErrorAdditionalDiags, + FunctionPointerSuggestion, SuggestAccessingField, SuggestRemoveSemiOrReturnBinding, + SuggestTuplePatternMany, SuggestTuplePatternOne, TypeErrorAdditionalDiags, }; use super::TypeErrCtxt; @@ -80,28 +79,6 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { } } - pub(super) fn suggest_boxing_for_return_impl_trait( - &self, - err: &mut Diag<'_>, - return_sp: Span, - arm_spans: impl Iterator, - ) { - let sugg = SuggestBoxingForReturnImplTrait::ChangeReturnType { - start_sp: return_sp.with_hi(return_sp.lo() + BytePos(4)), - end_sp: return_sp.shrink_to_hi(), - }; - err.subdiagnostic(self.dcx(), sugg); - - let mut starts = Vec::new(); - let mut ends = Vec::new(); - for span in arm_spans { - starts.push(span.shrink_to_lo()); - ends.push(span.shrink_to_hi()); - } - let sugg = SuggestBoxingForReturnImplTrait::BoxReturnExpr { starts, ends }; - err.subdiagnostic(self.dcx(), sugg); - } - pub(super) fn suggest_tuple_pattern( &self, cause: &ObligationCause<'tcx>, diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index a3ff655b6096..339c8ac10b33 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -229,6 +229,15 @@ impl<'tcx> InferCtxtInner<'tcx> { .expect("region constraints already solved") .with_log(&mut self.undo_log) } + + // Iterates through the opaque type definitions without taking them; this holds the + // `InferCtxtInner` lock, so make sure to not do anything with `InferCtxt` side-effects + // while looping through this. + pub fn iter_opaque_types( + &self, + ) -> impl Iterator, ty::OpaqueHiddenType<'tcx>)> + '_ { + self.opaque_type_storage.opaque_types.iter().map(|(&k, v)| (k, v.hidden_type)) + } } pub struct InferCtxt<'tcx> { diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs index a04bd636622e..efea2a66bb21 100644 --- a/compiler/rustc_middle/src/traits/mod.rs +++ b/compiler/rustc_middle/src/traits/mod.rs @@ -571,7 +571,8 @@ pub struct MatchExpressionArmCause<'tcx> { pub scrut_span: Span, pub source: hir::MatchSource, pub prior_non_diverging_arms: Vec, - pub opt_suggest_box_span: Option, + // Is the expectation of this match expression an RPIT? + pub tail_defines_return_position_impl_trait: Option, } #[derive(Copy, Clone, Debug, PartialEq, Eq)] @@ -582,7 +583,8 @@ pub struct IfExpressionCause<'tcx> { pub then_ty: Ty<'tcx>, pub else_ty: Ty<'tcx>, pub outer_span: Option, - pub opt_suggest_box_span: Option, + // Is the expectation of this match expression an RPIT? + pub tail_defines_return_position_impl_trait: Option, } #[derive(Clone, Debug, PartialEq, Eq, HashStable, TyEncodable, TyDecodable)] From 864e1fbc81cdae128cd936cbeed179c99ab71025 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sun, 24 Mar 2024 12:26:20 -0400 Subject: [PATCH 127/165] Remove TypeVariableOriginKind::OpaqueInference --- compiler/rustc_infer/src/infer/opaque_types/mod.rs | 2 +- compiler/rustc_infer/src/infer/type_variable.rs | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/compiler/rustc_infer/src/infer/opaque_types/mod.rs b/compiler/rustc_infer/src/infer/opaque_types/mod.rs index 02b8ded285f6..01430e830e55 100644 --- a/compiler/rustc_infer/src/infer/opaque_types/mod.rs +++ b/compiler/rustc_infer/src/infer/opaque_types/mod.rs @@ -73,7 +73,7 @@ impl<'tcx> InferCtxt<'tcx> { // for opaque types, and then use that kind to fix the spans for type errors // that we see later on. let ty_var = self.next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::OpaqueTypeInference(def_id), + kind: TypeVariableOriginKind::MiscVariable, span, }); obligations.extend( diff --git a/compiler/rustc_infer/src/infer/type_variable.rs b/compiler/rustc_infer/src/infer/type_variable.rs index 3630b0f439ff..55c6c92a5848 100644 --- a/compiler/rustc_infer/src/infer/type_variable.rs +++ b/compiler/rustc_infer/src/infer/type_variable.rs @@ -47,7 +47,6 @@ pub enum TypeVariableOriginKind { MiscVariable, NormalizeProjectionType, TypeInference, - OpaqueTypeInference(DefId), TypeParameterDefinition(Symbol, DefId), /// One of the upvars or closure kind parameters in a `ClosureArgs` From 1f75f0fcad63b577ed38d5cf10b62c5af47a3269 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Wed, 27 Mar 2024 14:14:30 +0000 Subject: [PATCH 128/165] Move FileId caching to DebugContext::add_source_file --- src/base.rs | 1 - src/common.rs | 29 +----------- src/debuginfo/line_info.rs | 97 ++++++++++++++++++++------------------ src/debuginfo/mod.rs | 7 +-- 4 files changed, 57 insertions(+), 77 deletions(-) diff --git a/src/base.rs b/src/base.rs index 4e60f820594b..9c66fa6d9cca 100644 --- a/src/base.rs +++ b/src/base.rs @@ -95,7 +95,6 @@ pub(crate) fn codegen_fn<'tcx>( caller_location: None, // set by `codegen_fn_prelude` clif_comments, - last_source_file: None, next_ssa_var: 0, }; diff --git a/src/common.rs b/src/common.rs index a7c3d68ff8cf..b038c7194cd5 100644 --- a/src/common.rs +++ b/src/common.rs @@ -1,12 +1,9 @@ use cranelift_codegen::isa::TargetFrontendConfig; -use gimli::write::FileId; -use rustc_data_structures::sync::Lrc; use rustc_index::IndexVec; use rustc_middle::ty::layout::{ FnAbiError, FnAbiOfHelpers, FnAbiRequest, LayoutError, LayoutOfHelpers, }; use rustc_span::source_map::Spanned; -use rustc_span::SourceFile; use rustc_target::abi::call::FnAbi; use rustc_target::abi::{Integer, Primitive}; use rustc_target::spec::{HasTargetSpec, Target}; @@ -305,11 +302,6 @@ pub(crate) struct FunctionCx<'m, 'clif, 'tcx: 'm> { pub(crate) clif_comments: crate::pretty_clif::CommentWriter, - /// Last accessed source file and it's debuginfo file id. - /// - /// For optimization purposes only - pub(crate) last_source_file: Option<(Lrc, FileId)>, - /// This should only be accessed by `CPlace::new_var`. pub(crate) next_ssa_var: u32, } @@ -419,25 +411,8 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> { pub(crate) fn set_debug_loc(&mut self, source_info: mir::SourceInfo) { if let Some(debug_context) = &mut self.cx.debug_context { - let (file, line, column) = - DebugContext::get_span_loc(self.tcx, self.mir.span, source_info.span); - - // add_source_file is very slow. - // Optimize for the common case of the current file not being changed. - let mut cached_file_id = None; - if let Some((ref last_source_file, last_file_id)) = self.last_source_file { - // If the allocations are not equal, the files may still be equal, but that - // doesn't matter, as this is just an optimization. - if rustc_data_structures::sync::Lrc::ptr_eq(last_source_file, &file) { - cached_file_id = Some(last_file_id); - } - } - - let file_id = if let Some(file_id) = cached_file_id { - file_id - } else { - debug_context.add_source_file(&file) - }; + let (file_id, line, column) = + debug_context.get_span_loc(self.tcx, self.mir.span, source_info.span); let source_loc = self.func_debug_cx.as_mut().unwrap().add_dbg_loc(file_id, line, column); diff --git a/src/debuginfo/line_info.rs b/src/debuginfo/line_info.rs index d1b21d0a0b6c..916abf318699 100644 --- a/src/debuginfo/line_info.rs +++ b/src/debuginfo/line_info.rs @@ -8,7 +8,6 @@ use cranelift_codegen::MachSrcLoc; use gimli::write::{ Address, AttributeValue, FileId, FileInfo, LineProgram, LineString, LineStringTable, }; -use rustc_data_structures::sync::Lrc; use rustc_span::{ FileName, Pos, SourceFile, SourceFileAndLine, SourceFileHash, SourceFileHashAlgorithm, }; @@ -60,10 +59,11 @@ fn make_file_info(hash: SourceFileHash) -> Option { impl DebugContext { pub(crate) fn get_span_loc( + &mut self, tcx: TyCtxt<'_>, function_span: Span, span: Span, - ) -> (Lrc, u64, u64) { + ) -> (FileId, u64, u64) { // Based on https://github.com/rust-lang/rust/blob/e369d87b015a84653343032833d65d0545fd3f26/src/librustc_codegen_ssa/mir/mod.rs#L116-L131 // In order to have a good line stepping behavior in debugger, we overwrite debug // locations of macro expansions with that of the outermost expansion site (when the macro is @@ -71,61 +71,66 @@ impl DebugContext { let span = tcx.collapsed_debuginfo(span, function_span); match tcx.sess.source_map().lookup_line(span.lo()) { Ok(SourceFileAndLine { sf: file, line }) => { + let file_id = self.add_source_file(&file); let line_pos = file.lines()[line]; let col = file.relative_position(span.lo()) - line_pos; - (file, u64::try_from(line).unwrap() + 1, u64::from(col.to_u32()) + 1) + (file_id, u64::try_from(line).unwrap() + 1, u64::from(col.to_u32()) + 1) } - Err(file) => (file, 0, 0), + Err(file) => (self.add_source_file(&file), 0, 0), } } pub(crate) fn add_source_file(&mut self, source_file: &SourceFile) -> FileId { - let line_program: &mut LineProgram = &mut self.dwarf.unit.line_program; - let line_strings: &mut LineStringTable = &mut self.dwarf.line_strings; + let cache_key = (source_file.stable_id, source_file.src_hash); + *self.created_files.entry(cache_key).or_insert_with(|| { + let line_program: &mut LineProgram = &mut self.dwarf.unit.line_program; + let line_strings: &mut LineStringTable = &mut self.dwarf.line_strings; - match &source_file.name { - FileName::Real(path) => { - let (dir_path, file_name) = - split_path_dir_and_file(if self.should_remap_filepaths { - path.remapped_path_if_available() - } else { - path.local_path_if_available() - }); - let dir_name = osstr_as_utf8_bytes(dir_path.as_os_str()); - let file_name = osstr_as_utf8_bytes(file_name); - - let dir_id = if !dir_name.is_empty() { - let dir_name = LineString::new(dir_name, line_program.encoding(), line_strings); - line_program.add_directory(dir_name) - } else { - line_program.default_directory() - }; - let file_name = LineString::new(file_name, line_program.encoding(), line_strings); - - let info = make_file_info(source_file.src_hash); - - line_program.file_has_md5 &= info.is_some(); - line_program.add_file(file_name, dir_id, info) - } - // FIXME give more appropriate file names - filename => { - let dir_id = line_program.default_directory(); - let dummy_file_name = LineString::new( - filename - .display(if self.should_remap_filepaths { - FileNameDisplayPreference::Remapped + match &source_file.name { + FileName::Real(path) => { + let (dir_path, file_name) = + split_path_dir_and_file(if self.should_remap_filepaths { + path.remapped_path_if_available() } else { - FileNameDisplayPreference::Local - }) - .to_string() - .into_bytes(), - line_program.encoding(), - line_strings, - ); - line_program.add_file(dummy_file_name, dir_id, None) + path.local_path_if_available() + }); + let dir_name = osstr_as_utf8_bytes(dir_path.as_os_str()); + let file_name = osstr_as_utf8_bytes(file_name); + + let dir_id = if !dir_name.is_empty() { + let dir_name = + LineString::new(dir_name, line_program.encoding(), line_strings); + line_program.add_directory(dir_name) + } else { + line_program.default_directory() + }; + let file_name = + LineString::new(file_name, line_program.encoding(), line_strings); + + let info = make_file_info(source_file.src_hash); + + line_program.file_has_md5 &= info.is_some(); + line_program.add_file(file_name, dir_id, info) + } + filename => { + let dir_id = line_program.default_directory(); + let dummy_file_name = LineString::new( + filename + .display(if self.should_remap_filepaths { + FileNameDisplayPreference::Remapped + } else { + FileNameDisplayPreference::Local + }) + .to_string() + .into_bytes(), + line_program.encoding(), + line_strings, + ); + line_program.add_file(dummy_file_name, dir_id, None) + } } - } + }) } } diff --git a/src/debuginfo/mod.rs b/src/debuginfo/mod.rs index b541cf0512e1..172e72c0e263 100644 --- a/src/debuginfo/mod.rs +++ b/src/debuginfo/mod.rs @@ -16,6 +16,7 @@ use indexmap::IndexSet; use rustc_codegen_ssa::debuginfo::type_names; use rustc_hir::def_id::DefIdMap; use rustc_session::Session; +use rustc_span::{SourceFileHash, StableSourceFileId}; pub(crate) use self::emit::{DebugReloc, DebugRelocName}; pub(crate) use self::unwind::UnwindContext; @@ -30,6 +31,7 @@ pub(crate) struct DebugContext { dwarf: DwarfUnit, unit_range_list: RangeList, + created_files: FxHashMap<(StableSourceFileId, SourceFileHash), FileId>, stack_pointer_register: Register, namespace_map: DefIdMap, @@ -130,6 +132,7 @@ impl DebugContext { endian, dwarf, unit_range_list: RangeList(Vec::new()), + created_files: FxHashMap::default(), stack_pointer_register, namespace_map: DefIdMap::default(), should_remap_filepaths, @@ -169,9 +172,7 @@ impl DebugContext { linkage_name: &str, function_span: Span, ) -> FunctionDebugContext { - let (file, line, column) = DebugContext::get_span_loc(tcx, function_span, function_span); - - let file_id = self.add_source_file(&file); + let (file_id, line, column) = self.get_span_loc(tcx, function_span, function_span); // FIXME: add to appropriate scope instead of root let scope = self.item_namespace(tcx, tcx.parent(instance.def_id())); From bd6a96f04ec6d119c2d0a4b8f445886bdd6e76d9 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Wed, 27 Mar 2024 14:28:50 +0000 Subject: [PATCH 129/165] Int constants must be valtrees in pattern lowering --- compiler/rustc_middle/src/thir.rs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/compiler/rustc_middle/src/thir.rs b/compiler/rustc_middle/src/thir.rs index 966d4ff43680..b1162a34cdaf 100644 --- a/compiler/rustc_middle/src/thir.rs +++ b/compiler/rustc_middle/src/thir.rs @@ -1018,11 +1018,7 @@ impl<'tcx> PatRangeBoundary<'tcx> { (Finite(mir::Const::Ty(a)), Finite(mir::Const::Ty(b))) if matches!(ty.kind(), ty::Uint(_) | ty::Char) => { - if let Some(a) = a.try_to_valtree() { - if let Some(b) = b.try_to_valtree() { - return Some(a.cmp(&b)); - } - } + return Some(a.to_valtree().cmp(&b.to_valtree())); } ( Finite(mir::Const::Val(mir::ConstValue::Scalar(Scalar::Int(a)), _)), From 3157114f0b4b28caad0d593a0cc5d8b04d02a29c Mon Sep 17 00:00:00 2001 From: xiaoxiangxianzi Date: Wed, 27 Mar 2024 21:19:17 +0800 Subject: [PATCH 130/165] chore: fix some comments Signed-off-by: xiaoxiangxianzi --- INSTALL.md | 4 ++-- compiler/rustc_ast_pretty/src/pprust/state/expr.rs | 2 +- compiler/rustc_borrowck/src/type_check/mod.rs | 2 +- compiler/rustc_const_eval/src/const_eval/eval_queries.rs | 2 +- compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs | 2 +- compiler/rustc_parse/src/parser/expr.rs | 2 +- library/core/src/pin.rs | 2 +- tests/rustdoc-gui/target.goml | 2 +- 8 files changed, 9 insertions(+), 9 deletions(-) diff --git a/INSTALL.md b/INSTALL.md index a23ea4f1eeeb..9619ec2ce5cf 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -151,8 +151,8 @@ toolchain. directory and uncomment the line `MSYS2_PATH_TYPE=inherit`. You could install and use MSYS2's version of git instead with `pacman`, - however this is not recommended as it's excrutiatingly slow, and not frequently - tested for compatability. + however this is not recommended as it's excruciatingly slow, and not frequently + tested for compatibility. 3. Start a MINGW64 or MINGW32 shell (depending on whether you want 32-bit or 64-bit Rust) either from your start menu, or by running `mingw64.exe` diff --git a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs index 8bd8b6ac1447..6eff70410cbb 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs @@ -75,7 +75,7 @@ pub(crate) struct FixupContext { } /// The default amount of fixing is minimal fixing. Fixups should be turned on -/// in a targetted fashion where needed. +/// in a targeted fashion where needed. impl Default for FixupContext { fn default() -> Self { FixupContext { diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index a206aac0467f..dcf84a2e036b 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -592,7 +592,7 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> { } self.cx.borrowck_context.constraints.outlives_constraints.push(constraint) } - // If the region is live at at least one location in the promoted MIR, + // If the region is live at least one location in the promoted MIR, // then add a liveness constraint to the main MIR for this region // at the location provided as an argument to this method // diff --git a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs index 098a6201c4ea..4283ebc99d26 100644 --- a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs +++ b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs @@ -409,7 +409,7 @@ fn const_validate_mplace<'mir, 'tcx>( } }; ecx.const_validate_operand(&mplace.into(), path, &mut ref_tracking, mode) - // Instead of just reporting the `InterpError` via the usual machinery, we give a more targetted + // Instead of just reporting the `InterpError` via the usual machinery, we give a more targeted // error about the validation failure. .map_err(|error| report_validation_error(&ecx, error, alloc_id))?; inner = true; 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 8c35da3ac7b7..d9d36f5299b5 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs @@ -11,7 +11,7 @@ use super::HirTyLowerer; impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { /// Prohibit or lint against *bare* trait object types depending on the edition. /// - /// *Bare* trait object types are ones that aren't preceeded by the keyword `dyn`. + /// *Bare* trait object types are ones that aren't preceded by the keyword `dyn`. /// In edition 2021 and onward we emit a hard error for them. pub(super) fn prohibit_or_lint_bare_trait_object_ty( &self, diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index 7e317c3df146..18fb858c84cf 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -2768,7 +2768,7 @@ impl<'a> Parser<'a> { }; return if self.token.kind == token::CloseDelim(Delimiter::Parenthesis) { // We know for sure we have seen `for ($SOMETHING in $EXPR)`, so we recover the - // parser state and emit a targetted suggestion. + // parser state and emit a targeted suggestion. let span = vec![start_span, self.token.span]; let right = self.prev_token.span.between(self.look_ahead(1, |t| t.span)); self.bump(); // ) diff --git a/library/core/src/pin.rs b/library/core/src/pin.rs index d14cac9afb56..e843a5d5790d 100644 --- a/library/core/src/pin.rs +++ b/library/core/src/pin.rs @@ -806,7 +806,7 @@ //! //! As a consequence, the struct *must not* be [`#[repr(packed)]`][packed]. //! -//! 3. *Structural Notice of Destruction.* You must uphold the the +//! 3. *Structural Notice of Destruction.* You must uphold the //! [`Drop` guarantee][drop-guarantee]: once your struct is pinned, the struct's storage cannot //! be re-used without calling the structurally-pinned fields' destructors, as well. //! diff --git a/tests/rustdoc-gui/target.goml b/tests/rustdoc-gui/target.goml index c5e7f813dd19..26071df8d044 100644 --- a/tests/rustdoc-gui/target.goml +++ b/tests/rustdoc-gui/target.goml @@ -1,4 +1,4 @@ -// Check that the targetted element has the expected styles. +// Check that the targeted element has the expected styles. go-to: "file://" + |DOC_PATH| + "/lib2/struct.Foo.html#method.a_method" show-text: true From 89ceced6f6cb60143db400cb9c668fe2d36c0e4e Mon Sep 17 00:00:00 2001 From: Kornel Date: Fri, 1 Mar 2024 13:37:08 +0000 Subject: [PATCH 131/165] Helper function for resolve_path --- compiler/rustc_expand/src/base.rs | 25 +++++++++++-------------- compiler/rustc_span/src/lib.rs | 11 +++++++++++ 2 files changed, 22 insertions(+), 14 deletions(-) diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs index 30ee02ea3c0a..8ccb1c246b60 100644 --- a/compiler/rustc_expand/src/base.rs +++ b/compiler/rustc_expand/src/base.rs @@ -1252,21 +1252,18 @@ pub fn resolve_path(sess: &Session, path: impl Into, span: Span) -> PRe // after macro expansion (that is, they are unhygienic). if !path.is_absolute() { let callsite = span.source_callsite(); - let mut result = match sess.source_map().span_to_filename(callsite) { - FileName::Real(name) => name - .into_local_path() - .expect("attempting to resolve a file path in an external file"), - FileName::DocTest(path, _) => path, - other => { - return Err(sess.dcx().create_err(errors::ResolveRelativePath { - span, - path: sess.source_map().filename_for_diagnostics(&other).to_string(), - })); - } + let source_map = sess.source_map(); + let Some(mut base_path) = source_map.span_to_filename(callsite).into_local_path() else { + return Err(sess.dcx().create_err(errors::ResolveRelativePath { + span, + path: source_map + .filename_for_diagnostics(&source_map.span_to_filename(callsite)) + .to_string(), + })); }; - result.pop(); - result.push(path); - Ok(result) + base_path.pop(); + base_path.push(path); + Ok(base_path) } else { Ok(path) } diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs index 616a7ccc7c64..0c974ef4ca3e 100644 --- a/compiler/rustc_span/src/lib.rs +++ b/compiler/rustc_span/src/lib.rs @@ -427,6 +427,17 @@ impl FileName { src.hash(&mut hasher); FileName::InlineAsm(hasher.finish()) } + + /// Returns the path suitable for reading from the file system on the local host, + /// if this information exists. + /// Avoid embedding this in build artifacts; see `remapped_path_if_available()` for that. + pub fn into_local_path(self) -> Option { + match self { + FileName::Real(path) => path.into_local_path(), + FileName::DocTest(path, _) => Some(path), + _ => None, + } + } } /// Represents a span. From f086e7abaf2fc954a2801231bfe3aa4508b8f424 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Wed, 27 Mar 2024 15:00:41 +0000 Subject: [PATCH 132/165] Allow debuginfo to reference global variables --- src/debuginfo/emit.rs | 15 +++++++++++++++ src/debuginfo/line_info.rs | 18 +++++------------- src/debuginfo/mod.rs | 19 +++++++------------ src/debuginfo/object.rs | 13 ++++++++----- src/debuginfo/unwind.rs | 10 ++++------ 5 files changed, 39 insertions(+), 36 deletions(-) diff --git a/src/debuginfo/emit.rs b/src/debuginfo/emit.rs index 81b819a55464..d376766966d6 100644 --- a/src/debuginfo/emit.rs +++ b/src/debuginfo/emit.rs @@ -1,5 +1,6 @@ //! Write the debuginfo into an object file. +use cranelift_module::{DataId, FuncId}; use cranelift_object::ObjectProduct; use gimli::write::{Address, AttributeValue, EndianVec, Result, Sections, Writer}; use gimli::{RunTimeEndian, SectionId}; @@ -8,6 +9,19 @@ use rustc_data_structures::fx::FxHashMap; use super::object::WriteDebugInfo; use super::DebugContext; +pub(super) fn address_for_func(func_id: FuncId) -> Address { + let symbol = func_id.as_u32(); + assert!(symbol & 1 << 31 == 0); + Address::Symbol { symbol: symbol as usize, addend: 0 } +} + +#[allow(dead_code)] +pub(super) fn address_for_data(data_id: DataId) -> Address { + let symbol = data_id.as_u32(); + assert!(symbol & 1 << 31 == 0); + Address::Symbol { symbol: (symbol | 1 << 31) as usize, addend: 0 } +} + impl DebugContext { pub(crate) fn emit(&mut self, product: &mut ObjectProduct) { let unit_range_list_id = self.dwarf.unit.ranges.add(self.unit_range_list.clone()); @@ -171,6 +185,7 @@ impl Writer for WriterRelocate { gimli::DW_EH_PE_pcrel => { let size = match eh_pe.format() { gimli::DW_EH_PE_sdata4 => 4, + gimli::DW_EH_PE_sdata8 => 8, _ => return Err(gimli::write::Error::UnsupportedPointerEncoding(eh_pe)), }; self.relocs.push(DebugReloc { diff --git a/src/debuginfo/line_info.rs b/src/debuginfo/line_info.rs index 916abf318699..380eba437c27 100644 --- a/src/debuginfo/line_info.rs +++ b/src/debuginfo/line_info.rs @@ -5,13 +5,12 @@ use std::path::{Component, Path}; use cranelift_codegen::binemit::CodeOffset; use cranelift_codegen::MachSrcLoc; -use gimli::write::{ - Address, AttributeValue, FileId, FileInfo, LineProgram, LineString, LineStringTable, -}; +use gimli::write::{AttributeValue, FileId, FileInfo, LineProgram, LineString, LineStringTable}; use rustc_span::{ FileName, Pos, SourceFile, SourceFileAndLine, SourceFileHash, SourceFileHashAlgorithm, }; +use crate::debuginfo::emit::address_for_func; use crate::debuginfo::FunctionDebugContext; use crate::prelude::*; @@ -143,7 +142,7 @@ impl FunctionDebugContext { pub(super) fn create_debug_lines( &mut self, debug_context: &mut DebugContext, - symbol: usize, + func_id: FuncId, context: &Context, ) -> CodeOffset { let create_row_for_span = @@ -156,11 +155,7 @@ impl FunctionDebugContext { debug_context.dwarf.unit.line_program.generate_row(); }; - debug_context - .dwarf - .unit - .line_program - .begin_sequence(Some(Address::Symbol { symbol, addend: 0 })); + debug_context.dwarf.unit.line_program.begin_sequence(Some(address_for_func(func_id))); let mut func_end = 0; @@ -183,10 +178,7 @@ impl FunctionDebugContext { assert_ne!(func_end, 0); let entry = debug_context.dwarf.unit.get_mut(self.entry_id); - entry.set( - gimli::DW_AT_low_pc, - AttributeValue::Address(Address::Symbol { symbol, addend: 0 }), - ); + entry.set(gimli::DW_AT_low_pc, AttributeValue::Address(address_for_func(func_id))); entry.set(gimli::DW_AT_high_pc, AttributeValue::Udata(u64::from(func_end))); func_end diff --git a/src/debuginfo/mod.rs b/src/debuginfo/mod.rs index 172e72c0e263..3bf75e989c56 100644 --- a/src/debuginfo/mod.rs +++ b/src/debuginfo/mod.rs @@ -20,6 +20,7 @@ use rustc_span::{SourceFileHash, StableSourceFileId}; pub(crate) use self::emit::{DebugReloc, DebugRelocName}; pub(crate) use self::unwind::UnwindContext; +use crate::debuginfo::emit::address_for_func; use crate::prelude::*; pub(crate) fn producer(sess: &Session) -> String { @@ -174,7 +175,6 @@ impl DebugContext { ) -> FunctionDebugContext { let (file_id, line, column) = self.get_span_loc(tcx, function_span, function_span); - // FIXME: add to appropriate scope instead of root let scope = self.item_namespace(tcx, tcx.parent(instance.def_id())); let mut name = String::new(); @@ -240,21 +240,16 @@ impl FunctionDebugContext { func_id: FuncId, context: &Context, ) { - let symbol = func_id.as_u32() as usize; + let end = self.create_debug_lines(debug_context, func_id, context); - let end = self.create_debug_lines(debug_context, symbol, context); - - debug_context.unit_range_list.0.push(Range::StartLength { - begin: Address::Symbol { symbol, addend: 0 }, - length: u64::from(end), - }); + debug_context + .unit_range_list + .0 + .push(Range::StartLength { begin: address_for_func(func_id), length: u64::from(end) }); let func_entry = debug_context.dwarf.unit.get_mut(self.entry_id); // Gdb requires both DW_AT_low_pc and DW_AT_high_pc. Otherwise the DW_TAG_subprogram is skipped. - func_entry.set( - gimli::DW_AT_low_pc, - AttributeValue::Address(Address::Symbol { symbol, addend: 0 }), - ); + func_entry.set(gimli::DW_AT_low_pc, AttributeValue::Address(address_for_func(func_id))); // Using Udata for DW_AT_high_pc requires at least DWARF4 func_entry.set(gimli::DW_AT_high_pc, AttributeValue::Udata(u64::from(end))); } diff --git a/src/debuginfo/object.rs b/src/debuginfo/object.rs index f1840a7bf730..27eabd8a0a61 100644 --- a/src/debuginfo/object.rs +++ b/src/debuginfo/object.rs @@ -1,4 +1,4 @@ -use cranelift_module::FuncId; +use cranelift_module::{DataId, FuncId}; use cranelift_object::ObjectProduct; use gimli::SectionId; use object::write::{Relocation, StandardSegment}; @@ -57,10 +57,13 @@ impl WriteDebugInfo for ObjectProduct { let (symbol, symbol_offset) = match reloc.name { DebugRelocName::Section(id) => (section_map.get(&id).unwrap().1, 0), DebugRelocName::Symbol(id) => { - let symbol_id = self.function_symbol(FuncId::from_u32(id.try_into().unwrap())); - self.object - .symbol_section_and_offset(symbol_id) - .expect("Debug reloc for undef sym???") + let id = id.try_into().unwrap(); + let symbol_id = if id & 1 << 31 == 0 { + self.function_symbol(FuncId::from_u32(id)) + } else { + self.data_symbol(DataId::from_u32(id & !(1 << 31))) + }; + self.object.symbol_section_and_offset(symbol_id).unwrap_or((symbol_id, 0)) } }; self.object diff --git a/src/debuginfo/unwind.rs b/src/debuginfo/unwind.rs index 35278e6fb29d..96ab7a29205b 100644 --- a/src/debuginfo/unwind.rs +++ b/src/debuginfo/unwind.rs @@ -3,9 +3,10 @@ use cranelift_codegen::ir::Endianness; use cranelift_codegen::isa::{unwind::UnwindInfo, TargetIsa}; use cranelift_object::ObjectProduct; -use gimli::write::{Address, CieId, EhFrame, FrameTable, Section}; +use gimli::write::{CieId, EhFrame, FrameTable, Section}; use gimli::RunTimeEndian; +use super::emit::address_for_func; use super::object::WriteDebugInfo; use crate::prelude::*; @@ -47,11 +48,8 @@ impl UnwindContext { match unwind_info { UnwindInfo::SystemV(unwind_info) => { - self.frame_table.add_fde( - self.cie_id.unwrap(), - unwind_info - .to_fde(Address::Symbol { symbol: func_id.as_u32() as usize, addend: 0 }), - ); + self.frame_table + .add_fde(self.cie_id.unwrap(), unwind_info.to_fde(address_for_func(func_id))); } UnwindInfo::WindowsX64(_) => { // FIXME implement this From 826ddb30180373a1972cdf5787044d12f8ad868e Mon Sep 17 00:00:00 2001 From: Kornel Date: Fri, 1 Mar 2024 02:49:02 +0000 Subject: [PATCH 133/165] Suggest correct path in include_bytes! --- .../rustc_builtin_macros/src/source_util.rs | 161 ++++++++++++++---- compiler/rustc_expand/src/base.rs | 17 +- tests/ui/include-macros/parent_dir.rs | 12 ++ tests/ui/include-macros/parent_dir.stderr | 50 ++++++ tests/ui/macros/macros-nonfatal-errors.rs | 2 +- tests/ui/macros/macros-nonfatal-errors.stderr | 4 +- 6 files changed, 209 insertions(+), 37 deletions(-) create mode 100644 tests/ui/include-macros/parent_dir.rs create mode 100644 tests/ui/include-macros/parent_dir.stderr diff --git a/compiler/rustc_builtin_macros/src/source_util.rs b/compiler/rustc_builtin_macros/src/source_util.rs index dbb86df6811d..abcdfabcaeda 100644 --- a/compiler/rustc_builtin_macros/src/source_util.rs +++ b/compiler/rustc_builtin_macros/src/source_util.rs @@ -3,17 +3,22 @@ use rustc_ast::ptr::P; use rustc_ast::token; use rustc_ast::tokenstream::TokenStream; use rustc_ast_pretty::pprust; -use rustc_expand::base::{check_zero_tts, get_single_str_from_tts, parse_expr, resolve_path}; +use rustc_data_structures::sync::Lrc; +use rustc_expand::base::{ + check_zero_tts, get_single_str_from_tts, get_single_str_spanned_from_tts, parse_expr, + resolve_path, +}; use rustc_expand::base::{DummyResult, ExpandResult, ExtCtxt}; use rustc_expand::base::{MacEager, MacResult, MacroExpanderResult}; use rustc_expand::module::DirOwnership; use rustc_parse::new_parser_from_file; use rustc_parse::parser::{ForceCollect, Parser}; use rustc_session::lint::builtin::INCOMPLETE_INCLUDE; +use rustc_span::source_map::SourceMap; use rustc_span::symbol::Symbol; use rustc_span::{Pos, Span}; - use smallvec::SmallVec; +use std::path::{Path, PathBuf}; use std::rc::Rc; // These macros all relate to the file system; they either return @@ -182,35 +187,26 @@ pub fn expand_include_str( tts: TokenStream, ) -> MacroExpanderResult<'static> { let sp = cx.with_def_site_ctxt(sp); - let ExpandResult::Ready(mac) = get_single_str_from_tts(cx, sp, tts, "include_str!") else { + let ExpandResult::Ready(mac) = get_single_str_spanned_from_tts(cx, sp, tts, "include_str!") + else { return ExpandResult::Retry(()); }; - let file = match mac { - Ok(file) => file, + let (path, path_span) = match mac { + Ok(res) => res, Err(guar) => return ExpandResult::Ready(DummyResult::any(sp, guar)), }; - let file = match resolve_path(&cx.sess, file.as_str(), sp) { - Ok(f) => f, - Err(err) => { - let guar = err.emit(); - return ExpandResult::Ready(DummyResult::any(sp, guar)); - } - }; - ExpandResult::Ready(match cx.source_map().load_binary_file(&file) { + ExpandResult::Ready(match load_binary_file(cx, path.as_str().as_ref(), sp, path_span) { Ok(bytes) => match std::str::from_utf8(&bytes) { Ok(src) => { let interned_src = Symbol::intern(src); MacEager::expr(cx.expr_str(sp, interned_src)) } Err(_) => { - let guar = cx.dcx().span_err(sp, format!("{} wasn't a utf-8 file", file.display())); + let guar = cx.dcx().span_err(sp, format!("`{path}` wasn't a utf-8 file")); DummyResult::any(sp, guar) } }, - Err(e) => { - let guar = cx.dcx().span_err(sp, format!("couldn't read {}: {}", file.display(), e)); - DummyResult::any(sp, guar) - } + Err(dummy) => dummy, }) } @@ -220,28 +216,127 @@ pub fn expand_include_bytes( tts: TokenStream, ) -> MacroExpanderResult<'static> { let sp = cx.with_def_site_ctxt(sp); - let ExpandResult::Ready(mac) = get_single_str_from_tts(cx, sp, tts, "include_bytes!") else { + let ExpandResult::Ready(mac) = get_single_str_spanned_from_tts(cx, sp, tts, "include_bytes!") + else { return ExpandResult::Retry(()); }; - let file = match mac { - Ok(file) => file, + let (path, path_span) = match mac { + Ok(res) => res, Err(guar) => return ExpandResult::Ready(DummyResult::any(sp, guar)), }; - let file = match resolve_path(&cx.sess, file.as_str(), sp) { - Ok(f) => f, - Err(err) => { - let guar = err.emit(); - return ExpandResult::Ready(DummyResult::any(sp, guar)); - } - }; - ExpandResult::Ready(match cx.source_map().load_binary_file(&file) { + ExpandResult::Ready(match load_binary_file(cx, path.as_str().as_ref(), sp, path_span) { Ok(bytes) => { let expr = cx.expr(sp, ast::ExprKind::IncludedBytes(bytes)); MacEager::expr(expr) } - Err(e) => { - let guar = cx.dcx().span_err(sp, format!("couldn't read {}: {}", file.display(), e)); - DummyResult::any(sp, guar) - } + Err(dummy) => dummy, }) } + +fn load_binary_file( + cx: &mut ExtCtxt<'_>, + original_path: &Path, + macro_span: Span, + path_span: Span, +) -> Result, Box> { + let resolved_path = match resolve_path(&cx.sess, original_path, macro_span) { + Ok(path) => path, + Err(err) => { + let guar = err.emit(); + return Err(DummyResult::any(macro_span, guar)); + } + }; + match cx.source_map().load_binary_file(&resolved_path) { + Ok(data) => Ok(data), + Err(io_err) => { + let mut err = cx.dcx().struct_span_err( + macro_span, + format!("couldn't read `{}`: {io_err}", resolved_path.display()), + ); + + if original_path.is_relative() { + let source_map = cx.sess.source_map(); + let new_path = source_map + .span_to_filename(macro_span.source_callsite()) + .into_local_path() + .and_then(|src| find_path_suggestion(source_map, src.parent()?, original_path)) + .and_then(|path| path.into_os_string().into_string().ok()); + + if let Some(new_path) = new_path { + err.span_suggestion( + path_span, + "there is a file with the same name in a different directory", + format!("\"{}\"", new_path.replace('\\', "/").escape_debug()), + rustc_lint_defs::Applicability::MachineApplicable, + ); + } + } + let guar = err.emit(); + Err(DummyResult::any(macro_span, guar)) + } + } +} + +fn find_path_suggestion( + source_map: &SourceMap, + base_dir: &Path, + wanted_path: &Path, +) -> Option { + // Fix paths that assume they're relative to cargo manifest dir + let mut base_c = base_dir.components(); + let mut wanted_c = wanted_path.components(); + let mut without_base = None; + while let Some(wanted_next) = wanted_c.next() { + if wanted_c.as_path().file_name().is_none() { + break; + } + // base_dir may be absolute + while let Some(base_next) = base_c.next() { + if base_next == wanted_next { + without_base = Some(wanted_c.as_path()); + break; + } + } + } + let root_absolute = without_base.into_iter().map(PathBuf::from); + + let base_dir_components = base_dir.components().count(); + // Avoid going all the way to the root dir + let max_parent_components = if base_dir.is_relative() { + base_dir_components + 1 + } else { + base_dir_components.saturating_sub(1) + }; + + // Try with additional leading ../ + let mut prefix = PathBuf::new(); + let add = std::iter::from_fn(|| { + prefix.push(".."); + Some(prefix.join(wanted_path)) + }) + .take(max_parent_components.min(3)); + + // Try without leading directories + let mut trimmed_path = wanted_path; + let remove = std::iter::from_fn(|| { + let mut components = trimmed_path.components(); + let removed = components.next()?; + trimmed_path = components.as_path(); + let _ = trimmed_path.file_name()?; // ensure there is a file name left + Some([ + Some(trimmed_path.to_path_buf()), + (removed != std::path::Component::ParentDir) + .then(|| Path::new("..").join(trimmed_path)), + ]) + }) + .flatten() + .flatten() + .take(4); + + for new_path in root_absolute.chain(add).chain(remove) { + if source_map.file_exists(&base_dir.join(&new_path)) { + return Some(new_path); + } + } + None +} diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs index 8ccb1c246b60..b25dd8fe67b7 100644 --- a/compiler/rustc_expand/src/base.rs +++ b/compiler/rustc_expand/src/base.rs @@ -1376,6 +1376,15 @@ pub fn get_single_str_from_tts( tts: TokenStream, name: &str, ) -> ExpandResult, ()> { + get_single_str_spanned_from_tts(cx, span, tts, name).map(|res| res.map(|(s, _)| s)) +} + +pub fn get_single_str_spanned_from_tts( + cx: &mut ExtCtxt<'_>, + span: Span, + tts: TokenStream, + name: &str, +) -> ExpandResult, ()> { let mut p = cx.new_parser_from_tts(tts); if p.token == token::Eof { let guar = cx.dcx().emit_err(errors::OnlyOneArgument { span, name }); @@ -1390,7 +1399,13 @@ pub fn get_single_str_from_tts( if p.token != token::Eof { cx.dcx().emit_err(errors::OnlyOneArgument { span, name }); } - expr_to_string(cx, ret, "argument must be a string literal").map(|s| s.map(|(s, _)| s)) + expr_to_spanned_string(cx, ret, "argument must be a string literal").map(|res| { + res.map_err(|err| match err { + Ok((err, _)) => err.emit(), + Err(guar) => guar, + }) + .map(|(symbol, _style, span)| (symbol, span)) + }) } /// Extracts comma-separated expressions from `tts`. diff --git a/tests/ui/include-macros/parent_dir.rs b/tests/ui/include-macros/parent_dir.rs new file mode 100644 index 000000000000..5fadff77a37e --- /dev/null +++ b/tests/ui/include-macros/parent_dir.rs @@ -0,0 +1,12 @@ +//@ normalize-stderr-test: "`: .*" -> "`: $$FILE_NOT_FOUND_MSG" + +fn main() { + let _ = include_str!("include-macros/file.txt"); //~ ERROR couldn't read + //~^HELP different directory + let _ = include_str!("hello.rs"); //~ ERROR couldn't read + //~^HELP different directory + let _ = include_bytes!("../../data.bin"); //~ ERROR couldn't read + //~^HELP different directory + let _ = include_str!("tests/ui/include-macros/file.txt"); //~ ERROR couldn't read + //~^HELP different directory +} diff --git a/tests/ui/include-macros/parent_dir.stderr b/tests/ui/include-macros/parent_dir.stderr new file mode 100644 index 000000000000..0470d5b1f1e3 --- /dev/null +++ b/tests/ui/include-macros/parent_dir.stderr @@ -0,0 +1,50 @@ +error: couldn't read `$DIR/include-macros/file.txt`: $FILE_NOT_FOUND_MSG + --> $DIR/parent_dir.rs:4:13 + | +LL | let _ = include_str!("include-macros/file.txt"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: this error originates in the macro `include_str` (in Nightly builds, run with -Z macro-backtrace for more info) +help: there is a file with the same name in a different directory + | +LL | let _ = include_str!("file.txt"); + | ~~~~~~~~~~ + +error: couldn't read `$DIR/hello.rs`: $FILE_NOT_FOUND_MSG + --> $DIR/parent_dir.rs:6:13 + | +LL | let _ = include_str!("hello.rs"); + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: this error originates in the macro `include_str` (in Nightly builds, run with -Z macro-backtrace for more info) +help: there is a file with the same name in a different directory + | +LL | let _ = include_str!("../hello.rs"); + | ~~~~~~~~~~~~~ + +error: couldn't read `$DIR/../../data.bin`: $FILE_NOT_FOUND_MSG + --> $DIR/parent_dir.rs:8:13 + | +LL | let _ = include_bytes!("../../data.bin"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: this error originates in the macro `include_bytes` (in Nightly builds, run with -Z macro-backtrace for more info) +help: there is a file with the same name in a different directory + | +LL | let _ = include_bytes!("data.bin"); + | ~~~~~~~~~~ + +error: couldn't read `$DIR/tests/ui/include-macros/file.txt`: $FILE_NOT_FOUND_MSG + --> $DIR/parent_dir.rs:10:13 + | +LL | let _ = include_str!("tests/ui/include-macros/file.txt"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: this error originates in the macro `include_str` (in Nightly builds, run with -Z macro-backtrace for more info) +help: there is a file with the same name in a different directory + | +LL | let _ = include_str!("file.txt"); + | ~~~~~~~~~~ + +error: aborting due to 4 previous errors + diff --git a/tests/ui/macros/macros-nonfatal-errors.rs b/tests/ui/macros/macros-nonfatal-errors.rs index 20e6d7050035..46e865031ecd 100644 --- a/tests/ui/macros/macros-nonfatal-errors.rs +++ b/tests/ui/macros/macros-nonfatal-errors.rs @@ -1,4 +1,4 @@ -//@ normalize-stderr-test: "existed:.*\(" -> "existed: $$FILE_NOT_FOUND_MSG (" +//@ normalize-stderr-test: "`: .*" -> "`: $$FILE_NOT_FOUND_MSG" // test that errors in a (selection) of macros don't kill compilation // immediately, so that we get more errors listed at a time. diff --git a/tests/ui/macros/macros-nonfatal-errors.stderr b/tests/ui/macros/macros-nonfatal-errors.stderr index ca373ea6cd9e..abf43e2a009d 100644 --- a/tests/ui/macros/macros-nonfatal-errors.stderr +++ b/tests/ui/macros/macros-nonfatal-errors.stderr @@ -200,7 +200,7 @@ error: argument must be a string literal LL | include_str!(invalid); | ^^^^^^^ -error: couldn't read $DIR/i'd be quite surprised if a file with this name existed: $FILE_NOT_FOUND_MSG (os error 2) +error: couldn't read `$DIR/i'd be quite surprised if a file with this name existed`: $FILE_NOT_FOUND_MSG --> $DIR/macros-nonfatal-errors.rs:113:5 | LL | include_str!("i'd be quite surprised if a file with this name existed"); @@ -214,7 +214,7 @@ error: argument must be a string literal LL | include_bytes!(invalid); | ^^^^^^^ -error: couldn't read $DIR/i'd be quite surprised if a file with this name existed: $FILE_NOT_FOUND_MSG (os error 2) +error: couldn't read `$DIR/i'd be quite surprised if a file with this name existed`: $FILE_NOT_FOUND_MSG --> $DIR/macros-nonfatal-errors.rs:115:5 | LL | include_bytes!("i'd be quite surprised if a file with this name existed"); From cc4a1f42e64d1061bb59e349e999b925e1e85b99 Mon Sep 17 00:00:00 2001 From: Vagelis Prokopiou Date: Wed, 27 Mar 2024 17:26:18 +0200 Subject: [PATCH 134/165] Some wording improvement --- library/std/src/fs.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/std/src/fs.rs b/library/std/src/fs.rs index 8b3a9e82aad1..9017ba797146 100644 --- a/library/std/src/fs.rs +++ b/library/std/src/fs.rs @@ -385,7 +385,7 @@ impl File { /// See the [`OpenOptions::open`] function for more details. /// /// See also [`std::fs::write()`][self::write] for a simple function to - /// create a file with a given data. + /// create a file with some given data. /// /// # Examples /// @@ -1036,7 +1036,7 @@ impl OpenOptions { /// [`OpenOptions::append`] access must be used. /// /// See also [`std::fs::write()`][self::write] for a simple function to - /// create a file with a given data. + /// create a file with some given data. /// /// # Examples /// From 443e29cd97a68a5af171abf07fc1c4cf08577a73 Mon Sep 17 00:00:00 2001 From: Kornel Date: Tue, 12 Mar 2024 15:55:41 +0000 Subject: [PATCH 135/165] Less generic code for Vec allocations --- library/alloc/src/raw_vec.rs | 42 +++++++++++++++++++++++++----------- 1 file changed, 29 insertions(+), 13 deletions(-) diff --git a/library/alloc/src/raw_vec.rs b/library/alloc/src/raw_vec.rs index 0ee293db73a9..175e23b543cc 100644 --- a/library/alloc/src/raw_vec.rs +++ b/library/alloc/src/raw_vec.rs @@ -114,7 +114,10 @@ impl RawVec { #[must_use] #[inline] pub fn with_capacity(capacity: usize) -> Self { - handle_reserve(Self::try_allocate_in(capacity, AllocInit::Uninitialized, Global)) + match Self::try_allocate_in(capacity, AllocInit::Uninitialized, Global) { + Ok(res) => res, + Err(err) => handle_error(err), + } } /// Like `with_capacity`, but guarantees the buffer is zeroed. @@ -152,7 +155,10 @@ impl RawVec { #[cfg(not(no_global_oom_handling))] #[inline] pub fn with_capacity_in(capacity: usize, alloc: A) -> Self { - handle_reserve(Self::try_allocate_in(capacity, AllocInit::Uninitialized, alloc)) + match Self::try_allocate_in(capacity, AllocInit::Uninitialized, alloc) { + Ok(res) => res, + Err(err) => handle_error(err), + } } /// Like `try_with_capacity`, but parameterized over the choice of @@ -167,7 +173,10 @@ impl RawVec { #[cfg(not(no_global_oom_handling))] #[inline] pub fn with_capacity_zeroed_in(capacity: usize, alloc: A) -> Self { - handle_reserve(Self::try_allocate_in(capacity, AllocInit::Zeroed, alloc)) + match Self::try_allocate_in(capacity, AllocInit::Zeroed, alloc) { + Ok(res) => res, + Err(err) => handle_error(err), + } } /// Converts the entire buffer into `Box<[MaybeUninit]>` with the specified `len`. @@ -326,7 +335,9 @@ impl RawVec { len: usize, additional: usize, ) { - handle_reserve(slf.grow_amortized(len, additional)); + if let Err(err) = slf.grow_amortized(len, additional) { + handle_error(err); + } } if self.needs_to_grow(len, additional) { @@ -339,7 +350,9 @@ impl RawVec { #[cfg(not(no_global_oom_handling))] #[inline(never)] pub fn reserve_for_push(&mut self, len: usize) { - handle_reserve(self.grow_amortized(len, 1)); + if let Err(err) = self.grow_amortized(len, 1) { + handle_error(err); + } } /// The same as `reserve`, but returns on errors instead of panicking or aborting. @@ -373,7 +386,9 @@ impl RawVec { /// Aborts on OOM. #[cfg(not(no_global_oom_handling))] pub fn reserve_exact(&mut self, len: usize, additional: usize) { - handle_reserve(self.try_reserve_exact(len, additional)); + if let Err(err) = self.try_reserve_exact(len, additional) { + handle_error(err); + } } /// The same as `reserve_exact`, but returns on errors instead of panicking or aborting. @@ -404,7 +419,9 @@ impl RawVec { /// Aborts on OOM. #[cfg(not(no_global_oom_handling))] pub fn shrink_to_fit(&mut self, cap: usize) { - handle_reserve(self.shrink(cap)); + if let Err(err) = self.shrink(cap) { + handle_error(err); + } } } @@ -559,12 +576,11 @@ unsafe impl<#[may_dangle] T, A: Allocator> Drop for RawVec { // Central function for reserve error handling. #[cfg(not(no_global_oom_handling))] -#[inline] -fn handle_reserve(result: Result) -> T { - match result.map_err(|e| e.kind()) { - Ok(res) => res, - Err(CapacityOverflow) => capacity_overflow(), - Err(AllocError { layout, .. }) => handle_alloc_error(layout), +#[cold] +fn handle_error(e: TryReserveError) -> ! { + match e.kind() { + CapacityOverflow => capacity_overflow(), + AllocError { layout, .. } => handle_alloc_error(layout), } } From 4b80941ae36ce0e49ecbb772872108e4808b2c4a Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Wed, 27 Mar 2024 16:53:12 +0000 Subject: [PATCH 136/165] Add debuginfo for statics Most types are still unimplemented and get a placeholder byte array instead. --- src/constant.rs | 8 +- src/debuginfo/emit.rs | 1 - src/debuginfo/mod.rs | 77 +++++++++++++++++++- src/debuginfo/types.rs | 162 +++++++++++++++++++++++++++++++++++++++++ src/driver/aot.rs | 7 +- 5 files changed, 251 insertions(+), 4 deletions(-) create mode 100644 src/debuginfo/types.rs diff --git a/src/constant.rs b/src/constant.rs index 690e8fe0e20a..635ed6c8e88b 100644 --- a/src/constant.rs +++ b/src/constant.rs @@ -31,10 +31,16 @@ impl ConstantCx { } } -pub(crate) fn codegen_static(tcx: TyCtxt<'_>, module: &mut dyn Module, def_id: DefId) { +pub(crate) fn codegen_static(tcx: TyCtxt<'_>, module: &mut dyn Module, def_id: DefId) -> DataId { let mut constants_cx = ConstantCx::new(); constants_cx.todo.push(TodoItem::Static(def_id)); constants_cx.finalize(tcx, module); + + data_id_for_static( + tcx, module, def_id, false, + // For a declaration the stated mutability doesn't matter. + false, + ) } pub(crate) fn codegen_tls_ref<'tcx>( diff --git a/src/debuginfo/emit.rs b/src/debuginfo/emit.rs index d376766966d6..36af7d4450d0 100644 --- a/src/debuginfo/emit.rs +++ b/src/debuginfo/emit.rs @@ -15,7 +15,6 @@ pub(super) fn address_for_func(func_id: FuncId) -> Address { Address::Symbol { symbol: symbol as usize, addend: 0 } } -#[allow(dead_code)] pub(super) fn address_for_data(data_id: DataId) -> Address { let symbol = data_id.as_u32(); assert!(symbol & 1 << 31 == 0); diff --git a/src/debuginfo/mod.rs b/src/debuginfo/mod.rs index 3bf75e989c56..2bab897dbcd8 100644 --- a/src/debuginfo/mod.rs +++ b/src/debuginfo/mod.rs @@ -3,10 +3,12 @@ mod emit; mod line_info; mod object; +mod types; mod unwind; use cranelift_codegen::ir::Endianness; use cranelift_codegen::isa::TargetIsa; +use cranelift_module::DataId; use gimli::write::{ Address, AttributeValue, DwarfUnit, Expression, FileId, LineProgram, LineString, Range, RangeList, UnitEntryId, @@ -14,13 +16,15 @@ use gimli::write::{ use gimli::{AArch64, Encoding, Format, LineEncoding, Register, RiscV, RunTimeEndian, X86_64}; use indexmap::IndexSet; use rustc_codegen_ssa::debuginfo::type_names; +use rustc_hir::def::DefKind; use rustc_hir::def_id::DefIdMap; use rustc_session::Session; use rustc_span::{SourceFileHash, StableSourceFileId}; pub(crate) use self::emit::{DebugReloc, DebugRelocName}; +pub(crate) use self::types::TypeDebugContext; pub(crate) use self::unwind::UnwindContext; -use crate::debuginfo::emit::address_for_func; +use crate::debuginfo::emit::{address_for_data, address_for_func}; use crate::prelude::*; pub(crate) fn producer(sess: &Session) -> String { @@ -35,6 +39,7 @@ pub(crate) struct DebugContext { created_files: FxHashMap<(StableSourceFileId, SourceFileHash), FileId>, stack_pointer_register: Register, namespace_map: DefIdMap, + array_size_type: UnitEntryId, should_remap_filepaths: bool, } @@ -129,6 +134,19 @@ impl DebugContext { root.set(gimli::DW_AT_low_pc, AttributeValue::Address(Address::Constant(0))); } + let array_size_type = dwarf.unit.add(dwarf.unit.root(), gimli::DW_TAG_base_type); + let array_size_type_entry = dwarf.unit.get_mut(array_size_type); + array_size_type_entry.set( + gimli::DW_AT_name, + AttributeValue::StringRef(dwarf.strings.add("__ARRAY_SIZE_TYPE__")), + ); + array_size_type_entry + .set(gimli::DW_AT_encoding, AttributeValue::Encoding(gimli::DW_ATE_unsigned)); + array_size_type_entry.set( + gimli::DW_AT_byte_size, + AttributeValue::Udata(isa.frontend_config().pointer_bytes().into()), + ); + DebugContext { endian, dwarf, @@ -136,6 +154,7 @@ impl DebugContext { created_files: FxHashMap::default(), stack_pointer_register, namespace_map: DefIdMap::default(), + array_size_type, should_remap_filepaths, } } @@ -231,6 +250,62 @@ impl DebugContext { source_loc_set: IndexSet::new(), } } + + // Adapted from https://github.com/rust-lang/rust/blob/10a7aa14fed9b528b74b0f098c4899c37c09a9c7/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs#L1288-L1346 + pub(crate) fn define_static<'tcx>( + &mut self, + tcx: TyCtxt<'tcx>, + type_dbg: &mut TypeDebugContext<'tcx>, + def_id: DefId, + data_id: DataId, + ) { + let DefKind::Static { nested, .. } = tcx.def_kind(def_id) else { bug!() }; + if nested { + return; + } + + let scope = self.item_namespace(tcx, tcx.parent(def_id)); + + let span = tcx.def_span(def_id); + let (file_id, line, _column) = self.get_span_loc(tcx, span, span); + + let static_type = Instance::mono(tcx, def_id).ty(tcx, ty::ParamEnv::reveal_all()); + let static_layout = tcx.layout_of(ty::ParamEnv::reveal_all().and(static_type)).unwrap(); + // FIXME use the actual type layout + let type_id = self.debug_type(tcx, type_dbg, static_type); + + let name = tcx.item_name(def_id); + let linkage_name = tcx.symbol_name(Instance::mono(tcx, def_id)).name; + + let entry_id = self.dwarf.unit.add(scope, gimli::DW_TAG_variable); + let entry = self.dwarf.unit.get_mut(entry_id); + let linkage_name_id = if name.as_str() != linkage_name { + Some(self.dwarf.strings.add(linkage_name)) + } else { + None + }; + let name_id = self.dwarf.strings.add(name.as_str()); + + entry.set(gimli::DW_AT_name, AttributeValue::StringRef(name_id)); + entry.set(gimli::DW_AT_type, AttributeValue::UnitRef(type_id)); + + if tcx.is_reachable_non_generic(def_id) { + entry.set(gimli::DW_AT_external, AttributeValue::FlagPresent); + } + + entry.set(gimli::DW_AT_decl_file, AttributeValue::FileIndex(Some(file_id))); + entry.set(gimli::DW_AT_decl_line, AttributeValue::Udata(line)); + + entry.set(gimli::DW_AT_alignment, AttributeValue::Udata(static_layout.align.pref.bytes())); + + let mut expr = Expression::new(); + expr.op_addr(address_for_data(data_id)); + entry.set(gimli::DW_AT_location, AttributeValue::Exprloc(expr)); + + if let Some(linkage_name_id) = linkage_name_id { + entry.set(gimli::DW_AT_linkage_name, AttributeValue::StringRef(linkage_name_id)); + } + } } impl FunctionDebugContext { diff --git a/src/debuginfo/types.rs b/src/debuginfo/types.rs new file mode 100644 index 000000000000..650de945c7bb --- /dev/null +++ b/src/debuginfo/types.rs @@ -0,0 +1,162 @@ +// Adapted from https://github.com/rust-lang/rust/blob/10a7aa14fed9b528b74b0f098c4899c37c09a9c7/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs + +use gimli::write::{AttributeValue, UnitEntryId}; +use rustc_codegen_ssa::debuginfo::type_names; +use rustc_data_structures::fx::FxHashMap; +use rustc_middle::ty::{self, Ty, TyCtxt}; + +use crate::{has_ptr_meta, DebugContext}; + +#[derive(Default)] +pub(crate) struct TypeDebugContext<'tcx> { + type_map: FxHashMap, UnitEntryId>, +} + +/// Returns from the enclosing function if the type debuginfo node with the given +/// unique ID can be found in the type map. +macro_rules! return_if_type_created_in_meantime { + ($type_dbg:expr, $ty:expr) => { + if let Some(&type_id) = $type_dbg.type_map.get(&$ty) { + return type_id; + } + }; +} + +impl DebugContext { + pub(crate) fn debug_type<'tcx>( + &mut self, + tcx: TyCtxt<'tcx>, + type_dbg: &mut TypeDebugContext<'tcx>, + ty: Ty<'tcx>, + ) -> UnitEntryId { + if let Some(&type_id) = type_dbg.type_map.get(&ty) { + return type_id; + } + + let type_id = match ty.kind() { + ty::Never | ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) | ty::Float(_) => { + self.basic_type(tcx, ty) + } + ty::Tuple(elems) if elems.is_empty() => self.basic_type(tcx, ty), + ty::Array(elem_ty, len) => self.array_type( + tcx, + type_dbg, + *elem_ty, + len.eval_target_usize(tcx, ty::ParamEnv::reveal_all()), + ), + // ty::Slice(_) | ty::Str + // ty::Dynamic + // ty::Foreign + ty::RawPtr(pointee_type, _) | ty::Ref(_, pointee_type, _) => { + self.pointer_type(tcx, type_dbg, ty, *pointee_type) + } + // ty::Adt(def, args) if def.is_box() && args.get(1).map_or(true, |arg| cx.layout_of(arg.expect_ty()).is_1zst()) + // ty::FnDef(..) | ty::FnPtr(..) + // ty::Closure(..) + // ty::Adt(def, ..) + // ty::Tuple(_) + // ty::Param(_) + // FIXME implement remaining types and add unreachable!() to the fallback branch + _ => self.placeholder_for_type(tcx, type_dbg, ty), + }; + + type_dbg.type_map.insert(ty, type_id); + + type_id + } + + fn basic_type<'tcx>(&mut self, tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> UnitEntryId { + let (name, encoding) = match ty.kind() { + ty::Never => ("!", gimli::DW_ATE_unsigned), + ty::Tuple(elems) if elems.is_empty() => ("()", gimli::DW_ATE_unsigned), + ty::Bool => ("bool", gimli::DW_ATE_boolean), + ty::Char => ("char", gimli::DW_ATE_UTF), + ty::Int(int_ty) => (int_ty.name_str(), gimli::DW_ATE_signed), + ty::Uint(uint_ty) => (uint_ty.name_str(), gimli::DW_ATE_unsigned), + ty::Float(float_ty) => (float_ty.name_str(), gimli::DW_ATE_float), + _ => unreachable!(), + }; + + let type_id = self.dwarf.unit.add(self.dwarf.unit.root(), gimli::DW_TAG_base_type); + let type_entry = self.dwarf.unit.get_mut(type_id); + type_entry.set(gimli::DW_AT_name, AttributeValue::StringRef(self.dwarf.strings.add(name))); + type_entry.set(gimli::DW_AT_encoding, AttributeValue::Encoding(encoding)); + type_entry.set( + gimli::DW_AT_byte_size, + AttributeValue::Udata( + tcx.layout_of(ty::ParamEnv::reveal_all().and(ty)).expect("FIXME").size.bytes(), + ), + ); + + type_id + } + + fn array_type<'tcx>( + &mut self, + tcx: TyCtxt<'tcx>, + type_dbg: &mut TypeDebugContext<'tcx>, + elem_ty: Ty<'tcx>, + len: u64, + ) -> UnitEntryId { + let elem_dw_ty = self.debug_type(tcx, type_dbg, elem_ty); + + return_if_type_created_in_meantime!(type_dbg, elem_ty); + + let array_type_id = self.dwarf.unit.add(self.dwarf.unit.root(), gimli::DW_TAG_array_type); + let array_type_entry = self.dwarf.unit.get_mut(array_type_id); + array_type_entry.set(gimli::DW_AT_type, AttributeValue::UnitRef(elem_dw_ty)); + + let subrange_id = self.dwarf.unit.add(array_type_id, gimli::DW_TAG_subrange_type); + let subrange_entry = self.dwarf.unit.get_mut(subrange_id); + subrange_entry.set(gimli::DW_AT_type, AttributeValue::UnitRef(self.array_size_type)); + subrange_entry.set(gimli::DW_AT_lower_bound, AttributeValue::Udata(0)); + subrange_entry.set(gimli::DW_AT_count, AttributeValue::Udata(len)); + + array_type_id + } + + fn pointer_type<'tcx>( + &mut self, + tcx: TyCtxt<'tcx>, + type_dbg: &mut TypeDebugContext<'tcx>, + ptr_type: Ty<'tcx>, + pointee_type: Ty<'tcx>, + ) -> UnitEntryId { + let pointee_dw_ty = self.debug_type(tcx, type_dbg, pointee_type); + + return_if_type_created_in_meantime!(type_dbg, ptr_type); + + let name = type_names::compute_debuginfo_type_name(tcx, ptr_type, true); + + if !has_ptr_meta(tcx, ptr_type) { + let pointer_type_id = + self.dwarf.unit.add(self.dwarf.unit.root(), gimli::DW_TAG_pointer_type); + let pointer_entry = self.dwarf.unit.get_mut(pointer_type_id); + pointer_entry.set(gimli::DW_AT_type, AttributeValue::UnitRef(pointee_dw_ty)); + pointer_entry + .set(gimli::DW_AT_name, AttributeValue::StringRef(self.dwarf.strings.add(name))); + + pointer_type_id + } else { + // FIXME implement debuginfo for fat pointers + self.placeholder_for_type(tcx, type_dbg, ptr_type) + } + } + + fn placeholder_for_type<'tcx>( + &mut self, + tcx: TyCtxt<'tcx>, + type_dbg: &mut TypeDebugContext<'tcx>, + ty: Ty<'tcx>, + ) -> UnitEntryId { + self.debug_type( + tcx, + type_dbg, + Ty::new_array( + tcx, + tcx.types.u8, + tcx.layout_of(ty::ParamEnv::reveal_all().and(ty)).unwrap().size.bytes(), + ), + ) + } +} diff --git a/src/driver/aot.rs b/src/driver/aot.rs index 4a28b2d93fab..e5caceab3456 100644 --- a/src/driver/aot.rs +++ b/src/driver/aot.rs @@ -23,6 +23,7 @@ use rustc_session::config::{DebugInfo, OutFileName, OutputFilenames, OutputType} use rustc_session::Session; use crate::concurrency_limiter::{ConcurrencyLimiter, ConcurrencyLimiterToken}; +use crate::debuginfo::TypeDebugContext; use crate::global_asm::GlobalAsmConfig; use crate::{prelude::*, BackendConfig}; @@ -460,6 +461,7 @@ fn module_codegen( tcx.sess.opts.debuginfo != DebugInfo::None, cgu_name, ); + let mut type_dbg = TypeDebugContext::default(); super::predefine_mono_items(tcx, &mut module, &mono_items); let mut codegened_functions = vec![]; for (mono_item, _) in mono_items { @@ -475,7 +477,10 @@ fn module_codegen( codegened_functions.push(codegened_function); } MonoItem::Static(def_id) => { - crate::constant::codegen_static(tcx, &mut module, def_id) + let data_id = crate::constant::codegen_static(tcx, &mut module, def_id); + if let Some(debug_context) = &mut cx.debug_context { + debug_context.define_static(tcx, &mut type_dbg, def_id, data_id); + } } MonoItem::GlobalAsm(item_id) => { crate::global_asm::codegen_global_asm_item( From 336ff42367aa375bba85bf5dbbea535b3c04d929 Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Wed, 27 Mar 2024 10:25:56 -0700 Subject: [PATCH 137/165] `num::NonZero::get` can be 1 transmute instead of 3 --- library/core/src/num/nonzero.rs | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/library/core/src/num/nonzero.rs b/library/core/src/num/nonzero.rs index c65ffbb98f2f..1171407c07a3 100644 --- a/library/core/src/num/nonzero.rs +++ b/library/core/src/num/nonzero.rs @@ -20,7 +20,15 @@ use super::{IntErrorKind, ParseIntError}; /// /// # Safety /// -/// Types implementing this trait must be primitves that are valid when zeroed. +/// Types implementing this trait must be primitives that are valid when zeroed. +/// +/// The associated `Self::NonZeroInner` type must have the same size+align as `Self`, +/// but with a niche and bit validity making it so the following `transmutes` are sound: +/// +/// - `Self::NonZeroInner` to `Option` +/// - `Option` to `Self` +/// +/// (And, consequently, `Self::NonZeroInner` to `Self`.) #[unstable( feature = "nonzero_internals", reason = "implementation detail which may disappear or be replaced at any time", @@ -434,17 +442,11 @@ where // of some not-inlined function, LLVM don't have range metadata // to understand that the value cannot be zero. // - // SAFETY: `Self` is guaranteed to have the same layout as `Option`. - match unsafe { intrinsics::transmute_unchecked(self) } { - None => { - // SAFETY: `NonZero` is guaranteed to only contain non-zero values, so this is unreachable. - unsafe { intrinsics::unreachable() } - } - Some(Self(inner)) => { - // SAFETY: `T::NonZeroInner` is guaranteed to have the same layout as `T`. - unsafe { intrinsics::transmute_unchecked(inner) } - } - } + // For now, using the transmute `assume`s the range at runtime. + // + // SAFETY: `ZeroablePrimitive` guarantees that the size and bit validity + // of `.0` is such that this transmute is sound. + unsafe { intrinsics::transmute_unchecked(self) } } } From fee1204ffa7d5c989a2cb76d6b3bb8daa51af811 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Wed, 27 Mar 2024 19:49:20 +0000 Subject: [PATCH 138/165] Stop taking FunctionCx's fn_abi field --- src/abi/mod.rs | 7 ++----- src/abi/returning.rs | 26 +++++++------------------- src/base.rs | 2 +- src/common.rs | 2 +- 4 files changed, 11 insertions(+), 26 deletions(-) diff --git a/src/abi/mod.rs b/src/abi/mod.rs index b0af421008ac..6363a0d59a4f 100644 --- a/src/abi/mod.rs +++ b/src/abi/mod.rs @@ -222,17 +222,15 @@ pub(crate) fn codegen_fn_prelude<'tcx>(fx: &mut FunctionCx<'_, '_, 'tcx>, start_ Spread(Vec>>), } - let fn_abi = fx.fn_abi.take().unwrap(); - // FIXME implement variadics in cranelift - if fn_abi.c_variadic { + if fx.fn_abi.c_variadic { fx.tcx.dcx().span_fatal( fx.mir.span, "Defining variadic functions is not yet supported by Cranelift", ); } - let mut arg_abis_iter = fn_abi.args.iter(); + let mut arg_abis_iter = fx.fn_abi.args.iter(); let func_params = fx .mir @@ -279,7 +277,6 @@ pub(crate) fn codegen_fn_prelude<'tcx>(fx: &mut FunctionCx<'_, '_, 'tcx>, start_ } assert!(arg_abis_iter.next().is_none(), "ArgAbi left behind"); - fx.fn_abi = Some(fn_abi); assert!(block_params_iter.next().is_none(), "arg_value left behind"); self::comments::add_locals_header_comment(fx); diff --git a/src/abi/returning.rs b/src/abi/returning.rs index 0799a22c6e16..e0f399e616e5 100644 --- a/src/abi/returning.rs +++ b/src/abi/returning.rs @@ -12,27 +12,15 @@ pub(super) fn codegen_return_param<'tcx>( ssa_analyzed: &rustc_index::IndexSlice, block_params_iter: &mut impl Iterator, ) -> CPlace<'tcx> { - let (ret_place, ret_param): (_, SmallVec<[_; 2]>) = match fx.fn_abi.as_ref().unwrap().ret.mode { + let (ret_place, ret_param): (_, SmallVec<[_; 2]>) = match fx.fn_abi.ret.mode { PassMode::Ignore | PassMode::Direct(_) | PassMode::Pair(_, _) | PassMode::Cast { .. } => { - let is_ssa = - ssa_analyzed[RETURN_PLACE].is_ssa(fx, fx.fn_abi.as_ref().unwrap().ret.layout.ty); - ( - super::make_local_place( - fx, - RETURN_PLACE, - fx.fn_abi.as_ref().unwrap().ret.layout, - is_ssa, - ), - smallvec![], - ) + let is_ssa = ssa_analyzed[RETURN_PLACE].is_ssa(fx, fx.fn_abi.ret.layout.ty); + (super::make_local_place(fx, RETURN_PLACE, fx.fn_abi.ret.layout, is_ssa), smallvec![]) } PassMode::Indirect { attrs: _, meta_attrs: None, on_stack: _ } => { let ret_param = block_params_iter.next().unwrap(); assert_eq!(fx.bcx.func.dfg.value_type(ret_param), fx.pointer_type); - ( - CPlace::for_ptr(Pointer::new(ret_param), fx.fn_abi.as_ref().unwrap().ret.layout), - smallvec![ret_param], - ) + (CPlace::for_ptr(Pointer::new(ret_param), fx.fn_abi.ret.layout), smallvec![ret_param]) } PassMode::Indirect { attrs: _, meta_attrs: Some(_), on_stack: _ } => { unreachable!("unsized return value") @@ -45,8 +33,8 @@ pub(super) fn codegen_return_param<'tcx>( Some(RETURN_PLACE), None, &ret_param, - &fx.fn_abi.as_ref().unwrap().ret.mode, - fx.fn_abi.as_ref().unwrap().ret.layout, + &fx.fn_abi.ret.mode, + fx.fn_abi.ret.layout, ); ret_place @@ -115,7 +103,7 @@ pub(super) fn codegen_with_call_return_arg<'tcx>( /// Codegen a return instruction with the right return value(s) if any. pub(crate) fn codegen_return(fx: &mut FunctionCx<'_, '_, '_>) { - match fx.fn_abi.as_ref().unwrap().ret.mode { + match fx.fn_abi.ret.mode { PassMode::Ignore | PassMode::Indirect { attrs: _, meta_attrs: None, on_stack: _ } => { fx.bcx.ins().return_(&[]); } diff --git a/src/base.rs b/src/base.rs index 9c66fa6d9cca..049023f1560f 100644 --- a/src/base.rs +++ b/src/base.rs @@ -87,7 +87,7 @@ pub(crate) fn codegen_fn<'tcx>( instance, symbol_name, mir, - fn_abi: Some(RevealAllLayoutCx(tcx).fn_abi_of_instance(instance, ty::List::empty())), + fn_abi: RevealAllLayoutCx(tcx).fn_abi_of_instance(instance, ty::List::empty()), bcx, block_map, diff --git a/src/common.rs b/src/common.rs index b038c7194cd5..cf0b065414d8 100644 --- a/src/common.rs +++ b/src/common.rs @@ -291,7 +291,7 @@ pub(crate) struct FunctionCx<'m, 'clif, 'tcx: 'm> { pub(crate) instance: Instance<'tcx>, pub(crate) symbol_name: String, pub(crate) mir: &'tcx Body<'tcx>, - pub(crate) fn_abi: Option<&'tcx FnAbi<'tcx, Ty<'tcx>>>, + pub(crate) fn_abi: &'tcx FnAbi<'tcx, Ty<'tcx>>, pub(crate) bcx: FunctionBuilder<'clif>, pub(crate) block_map: IndexVec, From 0b860818e6fe937f09680a6434a9d6b0e1e44dcb Mon Sep 17 00:00:00 2001 From: Ramon de C Valle Date: Mon, 25 Mar 2024 21:39:26 -0700 Subject: [PATCH 139/165] CFI: Fix drop and drop_in_place Fix drop and drop_in_place by transforming self of drop and drop_in_place methods into Drop trait objects. --- .../src/typeid/typeid_itanium_cxx_abi.rs | 32 +++++++++++++++++-- ...tadata-id-itanium-cxx-abi-drop-in-place.rs | 27 ++++++++++++++++ .../kcfi/emit-type-metadata-trait-objects.rs | 2 ++ tests/ui/sanitizer/cfi-drop-in-place.rs | 20 ++++++++++++ 4 files changed, 79 insertions(+), 2 deletions(-) create mode 100644 tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-drop-in-place.rs create mode 100644 tests/ui/sanitizer/cfi-drop-in-place.rs diff --git a/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs b/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs index 3101015281b8..b41769b4b8f9 100644 --- a/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs +++ b/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs @@ -1112,8 +1112,36 @@ pub fn typeid_for_instance<'tcx>( mut instance: Instance<'tcx>, options: TypeIdOptions, ) -> String { - if matches!(instance.def, ty::InstanceDef::Virtual(..)) { - instance.args = strip_receiver_auto(tcx, instance.args) + if (matches!(instance.def, ty::InstanceDef::Virtual(..)) + && Some(instance.def_id()) == tcx.lang_items().drop_in_place_fn()) + || matches!(instance.def, ty::InstanceDef::DropGlue(..)) + { + // Adjust the type ids of DropGlues + // + // DropGlues may have indirect calls to one or more given types drop function. Rust allows + // for types to be erased to any trait object and retains the drop function for the original + // type, which means at the indirect call sites in DropGlues, when typeid_for_fnabi is + // called a second time, it only has information after type erasure and it could be a call + // on any arbitrary trait object. Normalize them to a synthesized Drop trait object, both on + // declaration/definition, and during code generation at call sites so they have the same + // type id and match. + // + // FIXME(rcvalle): This allows a drop call on any trait object to call the drop function of + // any other type. + // + let def_id = tcx + .lang_items() + .drop_trait() + .unwrap_or_else(|| bug!("typeid_for_instance: couldn't get drop_trait lang item")); + let predicate = ty::ExistentialPredicate::Trait(ty::ExistentialTraitRef { + def_id: def_id, + args: List::empty(), + }); + let predicates = tcx.mk_poly_existential_predicates(&[ty::Binder::dummy(predicate)]); + let self_ty = Ty::new_dynamic(tcx, predicates, tcx.lifetimes.re_erased, ty::Dyn); + instance.args = tcx.mk_args_trait(self_ty, List::empty()); + } else if matches!(instance.def, ty::InstanceDef::Virtual(..)) { + instance.args = strip_receiver_auto(tcx, instance.args); } if let Some(impl_id) = tcx.impl_of_method(instance.def_id()) diff --git a/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-drop-in-place.rs b/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-drop-in-place.rs new file mode 100644 index 000000000000..3ec1988edd6e --- /dev/null +++ b/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-drop-in-place.rs @@ -0,0 +1,27 @@ +// Verifies that type metadata identifiers for drop functions are emitted correctly. +// +//@ needs-sanitizer-cfi +//@ compile-flags: -Clto -Cno-prepopulate-passes -Copt-level=0 -Zsanitizer=cfi -Ctarget-feature=-crt-static + +#![crate_type="lib"] + +// CHECK-LABEL: define{{.*}}4core3ptr47drop_in_place$LT$dyn$u20$core..marker..Send$GT$ +// CHECK-SAME: {{.*}}!type ![[TYPE1:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +// CHECK: call i1 @llvm.type.test(ptr {{%.+}}, metadata !"_ZTSFvPu3dynIu{{[0-9]+}}NtNtNtC{{[[:print:]]+}}_4core3ops4drop4Dropu6regionEE") + +struct EmptyDrop; +// CHECK: define{{.*}}4core3ptr{{[0-9]+}}drop_in_place$LT${{.*}}EmptyDrop$GT${{.*}}!type ![[TYPE1]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} + +struct NonEmptyDrop; + +impl Drop for NonEmptyDrop { + fn drop(&mut self) {} + // CHECK: define{{.*}}4core3ptr{{[0-9]+}}drop_in_place$LT${{.*}}NonEmptyDrop$GT${{.*}}!type ![[TYPE1]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} +} + +pub fn foo() { + let _ = Box::new(EmptyDrop) as Box; + let _ = Box::new(NonEmptyDrop) as Box; +} + +// CHECK: ![[TYPE1]] = !{i64 0, !"_ZTSFvPu3dynIu{{[0-9]+}}NtNtNtC{{[[:print:]]+}}_4core3ops4drop4Dropu6regionEE"} diff --git a/tests/codegen/sanitizer/kcfi/emit-type-metadata-trait-objects.rs b/tests/codegen/sanitizer/kcfi/emit-type-metadata-trait-objects.rs index f08c9e6702ed..f9c7cca39898 100644 --- a/tests/codegen/sanitizer/kcfi/emit-type-metadata-trait-objects.rs +++ b/tests/codegen/sanitizer/kcfi/emit-type-metadata-trait-objects.rs @@ -29,6 +29,8 @@ impl<'a, 'b: 'a, T: ?Sized + Unsize, U: ?Sized> CoerceUnsized<&'a U> for &'b trait Freeze { } #[lang="drop_in_place"] fn drop_in_place_fn() { } +#[lang="drop"] +trait Drop { fn drop(&mut self); } pub trait Trait1 { fn foo(&self); diff --git a/tests/ui/sanitizer/cfi-drop-in-place.rs b/tests/ui/sanitizer/cfi-drop-in-place.rs new file mode 100644 index 000000000000..8ce2c4326026 --- /dev/null +++ b/tests/ui/sanitizer/cfi-drop-in-place.rs @@ -0,0 +1,20 @@ +// Verifies that drops can be called on arbitrary trait objects. +// +// FIXME(#122848): Remove only-linux when fixed. +//@ only-linux +//@ needs-sanitizer-cfi +//@ compile-flags: -Clto -Copt-level=0 -Cprefer-dynamic=off -Ctarget-feature=-crt-static -Zsanitizer=cfi +//@ run-pass + +struct EmptyDrop; + +struct NonEmptyDrop; + +impl Drop for NonEmptyDrop { + fn drop(&mut self) {} +} + +fn main() { + let _ = Box::new(EmptyDrop) as Box; + let _ = Box::new(NonEmptyDrop) as Box; +} From df4eec891d1cc25c4ae5f47d94e4b0634862aa4b Mon Sep 17 00:00:00 2001 From: Nilstrieb <48135649+Nilstrieb@users.noreply.github.com> Date: Wed, 27 Mar 2024 20:54:31 +0100 Subject: [PATCH 140/165] Let nils know about changes to target docs --- triagebot.toml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/triagebot.toml b/triagebot.toml index 2bcc77ae4332..1eec366eacb9 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -709,6 +709,9 @@ cc = ["@rust-lang/project-exploit-mitigations", "@rcvalle"] [mentions."src/doc/unstable-book/src/compiler-flags/check-cfg.md"] cc = ["@Urgau"] +[mentions."src/doc/rustc/src/platform-support"] +cc = ["@Nilstrieb"] + [mentions."tests/codegen/sanitizer"] cc = ["@rust-lang/project-exploit-mitigations", "@rcvalle"] From f85063c1a8f2433aec0ee7c95eacc22587ee8cda 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: Fri, 22 Mar 2024 18:45:15 +0000 Subject: [PATCH 141/165] Add tidy check to error on new `Makefile`s in `tests/run-make` --- .../tidy/src/expected_run_make_makefiles.txt | 343 ++++++++++++++++++ src/tools/tidy/src/lib.rs | 1 + src/tools/tidy/src/main.rs | 1 + src/tools/tidy/src/run_make_tests.rs | 98 +++++ 4 files changed, 443 insertions(+) create mode 100644 src/tools/tidy/src/expected_run_make_makefiles.txt create mode 100644 src/tools/tidy/src/run_make_tests.rs diff --git a/src/tools/tidy/src/expected_run_make_makefiles.txt b/src/tools/tidy/src/expected_run_make_makefiles.txt new file mode 100644 index 000000000000..0e8a4503aa5b --- /dev/null +++ b/src/tools/tidy/src/expected_run_make_makefiles.txt @@ -0,0 +1,343 @@ +/* +============================================================ + ⚠️⚠️⚠️NOTHING SHOULD EVER BE ADDED TO THIS LIST⚠️⚠️⚠️ +============================================================ +*/ +[ +"run-make/alloc-no-oom-handling/Makefile", +"run-make/alloc-no-rc/Makefile", +"run-make/alloc-no-sync/Makefile", +"run-make/allocator-shim-circular-deps/Makefile", +"run-make/allow-non-lint-warnings-cmdline/Makefile", +"run-make/allow-warnings-cmdline-stability/Makefile", +"run-make/archive-duplicate-names/Makefile", +"run-make/arguments-non-c-like-enum/Makefile", +"run-make/atomic-lock-free/Makefile", +"run-make/bare-outfile/Makefile", +"run-make/branch-protection-check-IBT/Makefile", +"run-make/c-dynamic-dylib/Makefile", +"run-make/c-dynamic-rlib/Makefile", +"run-make/c-link-to-rust-dylib/Makefile", +"run-make/c-link-to-rust-staticlib/Makefile", +"run-make/c-link-to-rust-va-list-fn/Makefile", +"run-make/c-static-dylib/Makefile", +"run-make/c-static-rlib/Makefile", +"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/cdylib/Makefile", +"run-make/codegen-options-parsing/Makefile", +"run-make/comment-section/Makefile", +"run-make/compile-stdin/Makefile", +"run-make/compiler-lookup-paths-2/Makefile", +"run-make/compiler-lookup-paths/Makefile", +"run-make/compiler-rt-works-on-mingw/Makefile", +"run-make/compressed-debuginfo/Makefile", +"run-make/const-prop-lint/Makefile", +"run-make/const_fn_mir/Makefile", +"run-make/core-no-fp-fmt-parse/Makefile", +"run-make/core-no-oom-handling/Makefile", +"run-make/crate-data-smoke/Makefile", +"run-make/crate-hash-rustc-version/Makefile", +"run-make/crate-name-priority/Makefile", +"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/debugger-visualizer-dep-info/Makefile", +"run-make/dep-graph/Makefile", +"run-make/dep-info-doesnt-run-much/Makefile", +"run-make/dep-info-spaces/Makefile", +"run-make/dep-info/Makefile", +"run-make/doctests-keep-binaries/Makefile", +"run-make/doctests-runtool/Makefile", +"run-make/dump-ice-to-disk/Makefile", +"run-make/dump-mono-stats/Makefile", +"run-make/duplicate-output-flavors/Makefile", +"run-make/dylib-chain/Makefile", +"run-make/emit-named-files/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/emit/Makefile", +"run-make/env-dep-info/Makefile", +"run-make/error-found-staticlib-instead-crate/Makefile", +"run-make/error-writing-dependencies/Makefile", +"run-make/exit-code/Makefile", +"run-make/export-executable-symbols/Makefile", +"run-make/extern-diff-internal-name/Makefile", +"run-make/extern-flag-disambiguates/Makefile", +"run-make/extern-flag-fun/Makefile", +"run-make/extern-flag-pathless/Makefile", +"run-make/extern-flag-rename-transitive/Makefile", +"run-make/extern-fn-explicit-align/Makefile", +"run-make/extern-fn-generic/Makefile", +"run-make/extern-fn-mangle/Makefile", +"run-make/extern-fn-reachable/Makefile", +"run-make/extern-fn-struct-passing-abi/Makefile", +"run-make/extern-fn-with-extern-types/Makefile", +"run-make/extern-fn-with-packed-struct/Makefile", +"run-make/extern-fn-with-union/Makefile", +"run-make/extern-multiple-copies/Makefile", +"run-make/extern-multiple-copies2/Makefile", +"run-make/extern-overrides-distribution/Makefile", +"run-make/extra-filename-with-temp-outputs/Makefile", +"run-make/fmt-write-bloat/Makefile", +"run-make/forced-unwind-terminate-pof/Makefile", +"run-make/foreign-double-unwind/Makefile", +"run-make/foreign-exceptions/Makefile", +"run-make/foreign-rust-exceptions/Makefile", +"run-make/fpic/Makefile", +"run-make/glibc-staticlib-args/Makefile", +"run-make/hir-tree/Makefile", +"run-make/inaccessible-temp-dir/Makefile", +"run-make/include_bytes_deps/Makefile", +"run-make/incr-add-rust-src-component/Makefile", +"run-make/incr-foreign-head-span/Makefile", +"run-make/incr-prev-body-beyond-eof/Makefile", +"run-make/incremental-debugger-visualizer/Makefile", +"run-make/incremental-session-fail/Makefile", +"run-make/inline-always-many-cgu/Makefile", +"run-make/interdependent-c-libraries/Makefile", +"run-make/intrinsic-unreachable/Makefile", +"run-make/invalid-library/Makefile", +"run-make/invalid-so/Makefile", +"run-make/invalid-staticlib/Makefile", +"run-make/issue-107094/Makefile", +"run-make/issue-10971-temps-dir/Makefile", +"run-make/issue-109934-lto-debuginfo/Makefile", +"run-make/issue-11908/Makefile", +"run-make/issue-14500/Makefile", +"run-make/issue-14698/Makefile", +"run-make/issue-15460/Makefile", +"run-make/issue-18943/Makefile", +"run-make/issue-20626/Makefile", +"run-make/issue-22131/Makefile", +"run-make/issue-24445/Makefile", +"run-make/issue-25581/Makefile", +"run-make/issue-26006/Makefile", +"run-make/issue-26092/Makefile", +"run-make/issue-28595/Makefile", +"run-make/issue-28766/Makefile", +"run-make/issue-30063/Makefile", +"run-make/issue-33329/Makefile", +"run-make/issue-35164/Makefile", +"run-make/issue-36710/Makefile", +"run-make/issue-37839/Makefile", +"run-make/issue-37893/Makefile", +"run-make/issue-38237/Makefile", +"run-make/issue-40535/Makefile", +"run-make/issue-46239/Makefile", +"run-make/issue-47384/Makefile", +"run-make/issue-47551/Makefile", +"run-make/issue-51671/Makefile", +"run-make/issue-53964/Makefile", +"run-make/issue-64153/Makefile", +"run-make/issue-68794-textrel-on-minimal-lib/Makefile", +"run-make/issue-69368/Makefile", +"run-make/issue-7349/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", +"run-make/issue-85441/Makefile", +"run-make/issue-88756-default-output/Makefile", +"run-make/issue-97463-abi-param-passing/Makefile", +"run-make/issue64319/Makefile", +"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-arg/Makefile", +"run-make/link-args-order/Makefile", +"run-make/link-cfg/Makefile", +"run-make/link-dedup/Makefile", +"run-make/link-path-order/Makefile", +"run-make/linkage-attr-on-static/Makefile", +"run-make/llvm-ident/Makefile", +"run-make/llvm-outputs/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/ls-metadata/Makefile", +"run-make/lto-dylib-dep/Makefile", +"run-make/lto-empty/Makefile", +"run-make/lto-linkage-used-attr/Makefile", +"run-make/lto-no-link-whole-rlib/Makefile", +"run-make/lto-readonly-lib/Makefile", +"run-make/lto-smoke-c/Makefile", +"run-make/lto-smoke/Makefile", +"run-make/macos-deployment-target/Makefile", +"run-make/macos-fat-archive/Makefile", +"run-make/manual-crate-name/Makefile", +"run-make/manual-link/Makefile", +"run-make/many-crates-but-no-match/Makefile", +"run-make/metadata-dep-info/Makefile", +"run-make/metadata-flag-frobs-symbols/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-deps/Makefile", +"run-make/mixing-formats/Makefile", +"run-make/mixing-libs/Makefile", +"run-make/msvc-opt-minsize/Makefile", +"run-make/multiple-emits/Makefile", +"run-make/native-link-modifier-bundle/Makefile", +"run-make/native-link-modifier-verbatim-linker/Makefile", +"run-make/native-link-modifier-verbatim-rustc/Makefile", +"run-make/native-link-modifier-whole-archive/Makefile", +"run-make/no-alloc-shim/Makefile", +"run-make/no-builtins-attribute/Makefile", +"run-make/no-builtins-lto/Makefile", +"run-make/no-cdylib-as-rdylib/Makefile", +"run-make/no-duplicate-libs/Makefile", +"run-make/no-input-file/Makefile", +"run-make/no-intermediate-extras/Makefile", +"run-make/obey-crate-type-flag/Makefile", +"run-make/optimization-remarks-dir-pgo/Makefile", +"run-make/optimization-remarks-dir/Makefile", +"run-make/output-filename-conflicts-with-directory/Makefile", +"run-make/output-filename-overwrites-input/Makefile", +"run-make/output-type-permutations/Makefile", +"run-make/output-with-hyphens/Makefile", +"run-make/override-aliased-flags/Makefile", +"run-make/overwrite-input/Makefile", +"run-make/panic-abort-eh_frame/Makefile", +"run-make/panic-impl-transitive/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-alt-path/Makefile", +"run-make/pdb-buildinfo-cl-cmd/Makefile", +"run-make/pgo-branch-weights/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", +"run-make/prefer-dylib/Makefile", +"run-make/prefer-rlib/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-cfg/Makefile", +"run-make/print-native-static-libs/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", +"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", +"run-make/raw-dylib-link-ordinal/Makefile", +"run-make/raw-dylib-stdcall-ordinal/Makefile", +"run-make/redundant-libs/Makefile", +"run-make/relocation-model/Makefile", +"run-make/relro-levels/Makefile", +"run-make/remap-path-prefix-dwarf/Makefile", +"run-make/remap-path-prefix/Makefile", +"run-make/repr128-dwarf/Makefile", +"run-make/reproducible-build-2/Makefile", +"run-make/reproducible-build/Makefile", +"run-make/resolve-rename/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", +"run-make/rlib-format-packed-bundled-libs/Makefile", +"run-make/rmeta-preferred/Makefile", +"run-make/rust-lld-custom-target/Makefile", +"run-make/rust-lld/Makefile", +"run-make/rustc-macro-dep-files/Makefile", +"run-make/rustdoc-determinism/Makefile", +"run-make/rustdoc-error-lines/Makefile", +"run-make/rustdoc-io-error/Makefile", +"run-make/rustdoc-map-file/Makefile", +"run-make/rustdoc-output-path/Makefile", +"run-make/rustdoc-scrape-examples-invalid-expr/Makefile", +"run-make/rustdoc-scrape-examples-macros/Makefile", +"run-make/rustdoc-scrape-examples-multiple/Makefile", +"run-make/rustdoc-scrape-examples-ordering/Makefile", +"run-make/rustdoc-scrape-examples-remap/Makefile", +"run-make/rustdoc-scrape-examples-test/Makefile", +"run-make/rustdoc-scrape-examples-whitespace/Makefile", +"run-make/rustdoc-shared-flags/Makefile", +"run-make/rustdoc-target-spec-json-path/Makefile", +"run-make/rustdoc-themes/Makefile", +"run-make/rustdoc-verify-output-files/Makefile", +"run-make/rustdoc-with-out-dir-option/Makefile", +"run-make/rustdoc-with-output-option/Makefile", +"run-make/rustdoc-with-short-out-dir-option/Makefile", +"run-make/sanitizer-cdylib-link/Makefile", +"run-make/sanitizer-dylib-link/Makefile", +"run-make/sanitizer-staticlib-link/Makefile", +"run-make/separate-link-fail/Makefile", +"run-make/separate-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/short-ice/Makefile", +"run-make/silly-file-names/Makefile", +"run-make/simd-ffi/Makefile", +"run-make/simple-dylib/Makefile", +"run-make/simple-rlib/Makefile", +"run-make/split-debuginfo/Makefile", +"run-make/stable-symbol-names/Makefile", +"run-make/static-dylib-by-default/Makefile", +"run-make/static-extern-type/Makefile", +"run-make/static-pie/Makefile", +"run-make/static-unwinding/Makefile", +"run-make/staticlib-blank-lib/Makefile", +"run-make/staticlib-dylib-linkage/Makefile", +"run-make/std-core-cycle/Makefile", +"run-make/stdin-non-utf8/Makefile", +"run-make/suspicious-library/Makefile", +"run-make/symbol-mangling-hashed/Makefile", +"run-make/symbol-visibility/Makefile", +"run-make/symbols-include-type-name/Makefile", +"run-make/symlinked-extern/Makefile", +"run-make/symlinked-libraries/Makefile", +"run-make/symlinked-rlib/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", +"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", +"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/used/Makefile", +"run-make/valid-print-requests/Makefile", +"run-make/version/Makefile", +"run-make/volatile-intrinsics/Makefile", +"run-make/wasm-exceptions-nostd/Makefile", +"run-make/wasm-override-linker/Makefile", +"run-make/weird-output-filenames/Makefile", +"run-make/windows-binary-no-external-deps/Makefile", +"run-make/windows-safeseh/Makefile", +"run-make/windows-spawn/Makefile", +"run-make/windows-subsystem/Makefile", +"run-make/x86_64-fortanix-unknown-sgx-lvi/Makefile", +] diff --git a/src/tools/tidy/src/lib.rs b/src/tools/tidy/src/lib.rs index 670b7eb2be99..57436e8d7fee 100644 --- a/src/tools/tidy/src/lib.rs +++ b/src/tools/tidy/src/lib.rs @@ -69,6 +69,7 @@ mod fluent_used; pub(crate) mod iter_header; pub mod mir_opt_tests; pub mod pal; +pub mod run_make_tests; pub mod rustdoc_css_themes; pub mod rustdoc_gui_tests; pub mod style; diff --git a/src/tools/tidy/src/main.rs b/src/tools/tidy/src/main.rs index 2bce246c3082..c823d46b2bd7 100644 --- a/src/tools/tidy/src/main.rs +++ b/src/tools/tidy/src/main.rs @@ -103,6 +103,7 @@ fn main() { check!(tests_revision_unpaired_stdout_stderr, &tests_path); check!(debug_artifacts, &tests_path); check!(ui_tests, &root_path, bless); + check!(run_make_tests, &root_path, bless); check!(mir_opt_tests, &tests_path, bless); check!(rustdoc_gui_tests, &tests_path); check!(rustdoc_css_themes, &librustdoc_path); diff --git a/src/tools/tidy/src/run_make_tests.rs b/src/tools/tidy/src/run_make_tests.rs new file mode 100644 index 000000000000..b591f3a7a222 --- /dev/null +++ b/src/tools/tidy/src/run_make_tests.rs @@ -0,0 +1,98 @@ +//! Tidy check to ensure that no new Makefiles are added under `tests/run-make/`. + +use std::collections::BTreeSet; +use std::fs::File; +use std::io::Write; +use std::path::{Path, PathBuf}; + +pub fn check(root_path: &Path, bless: bool, bad: &mut bool) { + let tests_path = &root_path.join("tests"); + + let allowed_makefiles = { + let allowed_makefiles = include!("expected_run_make_makefiles.txt"); + let is_sorted = allowed_makefiles.windows(2).all(|w| w[0] < w[1]); + if !is_sorted && !bless { + tidy_error!( + bad, + "`src/tools/tidy/src/expected_run_make_makefiles.txt` is not in order, likely \ + because you modified it manually, please only update it with command \ + `x test tidy --bless`" + ); + } + let allowed_makefiles_unique = + allowed_makefiles.into_iter().map(ToOwned::to_owned).collect::>(); + if allowed_makefiles_unique.len() != allowed_makefiles.len() { + tidy_error!( + bad, + "`src/tools/tidy/src/expected_run_make_makefiles.txt` contains duplicate entries, \ + likely because you modified it manually, please only update it with command \ + `x test tidy --bless`" + ); + } + allowed_makefiles_unique + }; + + let mut remaining_makefiles = allowed_makefiles.clone(); + + crate::walk::walk_no_read( + &[tests_path.join("run-make").as_ref()], + |_, _| false, + &mut |entry| { + if entry.file_type().map_or(true, |t| t.is_dir()) { + return; + } + + if entry.file_name().to_str().map_or(true, |f| f != "Makefile") { + return; + } + + let makefile_path = entry.path().strip_prefix(&tests_path).unwrap(); + let makefile_path = makefile_path.to_str().unwrap().replace('\\', "/"); + + if !remaining_makefiles.remove(&makefile_path) { + tidy_error!( + bad, + "found run-make Makefile not permitted in \ + `src/tools/tidy/src/expected_run_make_makefiles.txt`, please write new run-make \ + tests with `rmake.rs` instead: {}", + entry.path().display() + ); + } + }, + ); + + // If there are any expected Makefiles remaining, they were moved or deleted. + // Our data must remain up to date, so they must be removed from + // `src/tools/tidy/src/expected_run_make_makefiles.txt`. + // This can be done automatically on --bless, or else a tidy error will be issued. + if bless && !remaining_makefiles.is_empty() { + let header = r#"/* +============================================================ + ⚠️⚠️⚠️NOTHING SHOULD EVER BE ADDED TO THIS LIST⚠️⚠️⚠️ +============================================================ +*/ +[ +"#; + let tidy_src = root_path.join("src").join("tools").join("tidy").join("src"); + let org_file_path = tidy_src.join("expected_run_make_makefiles.txt"); + let temp_file_path = tidy_src.join("blessed_expected_run_make_makefiles.txt"); + let mut temp_file = t!(File::create_new(&temp_file_path)); + t!(write!(temp_file, "{}", header)); + for file in allowed_makefiles.difference(&remaining_makefiles) { + t!(write!(temp_file, "\"{file}\",\n")); + } + t!(write!(temp_file, "]\n")); + t!(std::fs::rename(&temp_file_path, &org_file_path)); + } else { + for file in remaining_makefiles { + let mut p = PathBuf::from(tests_path); + p.push(file); + tidy_error!( + bad, + "Makefile `{}` no longer exists and should be removed from the exclusions in \ + `src/tools/tidy/src/expected_run_make_makefiles.txt`", + p.display() + ); + } + } +} From ec25a425aa5f1e49213aafa7af9394fa96ef9207 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: Fri, 22 Mar 2024 19:03:29 +0000 Subject: [PATCH 142/165] Add comment for `include!()` usage --- src/tools/tidy/src/run_make_tests.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/tools/tidy/src/run_make_tests.rs b/src/tools/tidy/src/run_make_tests.rs index b591f3a7a222..0231ac0939e8 100644 --- a/src/tools/tidy/src/run_make_tests.rs +++ b/src/tools/tidy/src/run_make_tests.rs @@ -9,6 +9,9 @@ pub fn check(root_path: &Path, bless: bool, bad: &mut bool) { let tests_path = &root_path.join("tests"); let allowed_makefiles = { + // We use `include!` here which includes the file as Rust syntax because we want to have + // a comment that discourages people from adding entries to + // `expected_run_make_makefiles.txt` unless *absolutely* necessary. let allowed_makefiles = include!("expected_run_make_makefiles.txt"); let is_sorted = allowed_makefiles.windows(2).all(|w| w[0] < w[1]); if !is_sorted && !bless { From 7cf69a82304e1d01ea54b029a9e76af7f00e459b 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: Fri, 22 Mar 2024 19:07:25 +0000 Subject: [PATCH 143/165] Pass tests_path and src_path separately --- src/tools/tidy/src/main.rs | 2 +- src/tools/tidy/src/run_make_tests.rs | 6 ++---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/tools/tidy/src/main.rs b/src/tools/tidy/src/main.rs index c823d46b2bd7..bf5c0afdbb0a 100644 --- a/src/tools/tidy/src/main.rs +++ b/src/tools/tidy/src/main.rs @@ -103,7 +103,7 @@ fn main() { check!(tests_revision_unpaired_stdout_stderr, &tests_path); check!(debug_artifacts, &tests_path); check!(ui_tests, &root_path, bless); - check!(run_make_tests, &root_path, bless); + check!(run_make_tests, &tests_path, &src_path, bless); check!(mir_opt_tests, &tests_path, bless); check!(rustdoc_gui_tests, &tests_path); check!(rustdoc_css_themes, &librustdoc_path); diff --git a/src/tools/tidy/src/run_make_tests.rs b/src/tools/tidy/src/run_make_tests.rs index 0231ac0939e8..2d34bfc28f46 100644 --- a/src/tools/tidy/src/run_make_tests.rs +++ b/src/tools/tidy/src/run_make_tests.rs @@ -5,9 +5,7 @@ use std::fs::File; use std::io::Write; use std::path::{Path, PathBuf}; -pub fn check(root_path: &Path, bless: bool, bad: &mut bool) { - let tests_path = &root_path.join("tests"); - +pub fn check(tests_path: &Path, src_path: &Path, bless: bool, bad: &mut bool) { let allowed_makefiles = { // We use `include!` here which includes the file as Rust syntax because we want to have // a comment that discourages people from adding entries to @@ -76,7 +74,7 @@ pub fn check(root_path: &Path, bless: bool, bad: &mut bool) { */ [ "#; - let tidy_src = root_path.join("src").join("tools").join("tidy").join("src"); + let tidy_src = src_path.join("tools").join("tidy").join("src"); let org_file_path = tidy_src.join("expected_run_make_makefiles.txt"); let temp_file_path = tidy_src.join("blessed_expected_run_make_makefiles.txt"); let mut temp_file = t!(File::create_new(&temp_file_path)); From 81e3af7f4df5d42feb94c28d7f62eb53e6b6d5c6 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: Fri, 22 Mar 2024 19:13:11 +0000 Subject: [PATCH 144/165] Rename expected_run_make_makefiles -> allowed_run_make_makefiles --- ...iles.txt => allowed_run_make_makefiles.txt} | 0 src/tools/tidy/src/run_make_tests.rs | 18 +++++++++--------- 2 files changed, 9 insertions(+), 9 deletions(-) rename src/tools/tidy/src/{expected_run_make_makefiles.txt => allowed_run_make_makefiles.txt} (100%) diff --git a/src/tools/tidy/src/expected_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt similarity index 100% rename from src/tools/tidy/src/expected_run_make_makefiles.txt rename to src/tools/tidy/src/allowed_run_make_makefiles.txt diff --git a/src/tools/tidy/src/run_make_tests.rs b/src/tools/tidy/src/run_make_tests.rs index 2d34bfc28f46..47bafb4b39e4 100644 --- a/src/tools/tidy/src/run_make_tests.rs +++ b/src/tools/tidy/src/run_make_tests.rs @@ -9,13 +9,13 @@ pub fn check(tests_path: &Path, src_path: &Path, bless: bool, bad: &mut bool) { let allowed_makefiles = { // We use `include!` here which includes the file as Rust syntax because we want to have // a comment that discourages people from adding entries to - // `expected_run_make_makefiles.txt` unless *absolutely* necessary. - let allowed_makefiles = include!("expected_run_make_makefiles.txt"); + // `allowed_run_make_makefiles.txt` unless *absolutely* necessary. + let allowed_makefiles = include!("allowed_run_make_makefiles.txt"); let is_sorted = allowed_makefiles.windows(2).all(|w| w[0] < w[1]); if !is_sorted && !bless { tidy_error!( bad, - "`src/tools/tidy/src/expected_run_make_makefiles.txt` is not in order, likely \ + "`src/tools/tidy/src/allowed_run_make_makefiles.txt` is not in order, likely \ because you modified it manually, please only update it with command \ `x test tidy --bless`" ); @@ -25,7 +25,7 @@ pub fn check(tests_path: &Path, src_path: &Path, bless: bool, bad: &mut bool) { if allowed_makefiles_unique.len() != allowed_makefiles.len() { tidy_error!( bad, - "`src/tools/tidy/src/expected_run_make_makefiles.txt` contains duplicate entries, \ + "`src/tools/tidy/src/allowed_run_make_makefiles.txt` contains duplicate entries, \ likely because you modified it manually, please only update it with command \ `x test tidy --bless`" ); @@ -54,7 +54,7 @@ pub fn check(tests_path: &Path, src_path: &Path, bless: bool, bad: &mut bool) { tidy_error!( bad, "found run-make Makefile not permitted in \ - `src/tools/tidy/src/expected_run_make_makefiles.txt`, please write new run-make \ + `src/tools/tidy/src/allowed_run_make_makefiles.txt`, please write new run-make \ tests with `rmake.rs` instead: {}", entry.path().display() ); @@ -64,7 +64,7 @@ pub fn check(tests_path: &Path, src_path: &Path, bless: bool, bad: &mut bool) { // If there are any expected Makefiles remaining, they were moved or deleted. // Our data must remain up to date, so they must be removed from - // `src/tools/tidy/src/expected_run_make_makefiles.txt`. + // `src/tools/tidy/src/allowed_run_make_makefiles.txt`. // This can be done automatically on --bless, or else a tidy error will be issued. if bless && !remaining_makefiles.is_empty() { let header = r#"/* @@ -75,8 +75,8 @@ pub fn check(tests_path: &Path, src_path: &Path, bless: bool, bad: &mut bool) { [ "#; let tidy_src = src_path.join("tools").join("tidy").join("src"); - let org_file_path = tidy_src.join("expected_run_make_makefiles.txt"); - let temp_file_path = tidy_src.join("blessed_expected_run_make_makefiles.txt"); + let org_file_path = tidy_src.join("allowed_run_make_makefiles.txt"); + let temp_file_path = tidy_src.join("blessed_allowed_run_make_makefiles.txt"); let mut temp_file = t!(File::create_new(&temp_file_path)); t!(write!(temp_file, "{}", header)); for file in allowed_makefiles.difference(&remaining_makefiles) { @@ -91,7 +91,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/expected_run_make_makefiles.txt`", + `src/tools/tidy/src/allowed_run_make_makefiles.txt`", p.display() ); } From f10cf7bd856d71cf7f0ceedacdfc079adddb4076 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, 27 Mar 2024 20:02:43 +0000 Subject: [PATCH 145/165] Add run-make/link-framework/Makefile to allowlist --- src/tools/tidy/src/allowed_run_make_makefiles.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index 0e8a4503aa5b..817ac1f02c2e 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -159,6 +159,7 @@ "run-make/link-args-order/Makefile", "run-make/link-cfg/Makefile", "run-make/link-dedup/Makefile", +"run-make/link-framework/Makefile", "run-make/link-path-order/Makefile", "run-make/linkage-attr-on-static/Makefile", "run-make/llvm-ident/Makefile", From 55a2446a53272ca6a34ebbcd09166e02749ccd1b Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Wed, 27 Mar 2024 20:07:36 +0000 Subject: [PATCH 146/165] Don't panic when layout can't be computed and fix generation of array type debuginfo --- src/debuginfo/types.rs | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/src/debuginfo/types.rs b/src/debuginfo/types.rs index 650de945c7bb..7e5fafdd544a 100644 --- a/src/debuginfo/types.rs +++ b/src/debuginfo/types.rs @@ -3,9 +3,10 @@ use gimli::write::{AttributeValue, UnitEntryId}; use rustc_codegen_ssa::debuginfo::type_names; use rustc_data_structures::fx::FxHashMap; +use rustc_middle::ty::layout::LayoutOf; use rustc_middle::ty::{self, Ty, TyCtxt}; -use crate::{has_ptr_meta, DebugContext}; +use crate::{has_ptr_meta, DebugContext, RevealAllLayoutCx}; #[derive(Default)] pub(crate) struct TypeDebugContext<'tcx> { @@ -41,6 +42,7 @@ impl DebugContext { ty::Array(elem_ty, len) => self.array_type( tcx, type_dbg, + ty, *elem_ty, len.eval_target_usize(tcx, ty::ParamEnv::reveal_all()), ), @@ -83,9 +85,7 @@ impl DebugContext { type_entry.set(gimli::DW_AT_encoding, AttributeValue::Encoding(encoding)); type_entry.set( gimli::DW_AT_byte_size, - AttributeValue::Udata( - tcx.layout_of(ty::ParamEnv::reveal_all().and(ty)).expect("FIXME").size.bytes(), - ), + AttributeValue::Udata(RevealAllLayoutCx(tcx).layout_of(ty).size.bytes()), ); type_id @@ -95,12 +95,13 @@ impl DebugContext { &mut self, tcx: TyCtxt<'tcx>, type_dbg: &mut TypeDebugContext<'tcx>, + array_ty: Ty<'tcx>, elem_ty: Ty<'tcx>, len: u64, ) -> UnitEntryId { let elem_dw_ty = self.debug_type(tcx, type_dbg, elem_ty); - return_if_type_created_in_meantime!(type_dbg, elem_ty); + return_if_type_created_in_meantime!(type_dbg, array_ty); let array_type_id = self.dwarf.unit.add(self.dwarf.unit.root(), gimli::DW_TAG_array_type); let array_type_entry = self.dwarf.unit.get_mut(array_type_id); @@ -152,11 +153,7 @@ impl DebugContext { self.debug_type( tcx, type_dbg, - Ty::new_array( - tcx, - tcx.types.u8, - tcx.layout_of(ty::ParamEnv::reveal_all().and(ty)).unwrap().size.bytes(), - ), + Ty::new_array(tcx, tcx.types.u8, RevealAllLayoutCx(tcx).layout_of(ty).size.bytes()), ) } } From 0634aedbb7a1fba46a7991527b9d5c4517fb6924 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Wed, 27 Mar 2024 20:29:50 +0000 Subject: [PATCH 147/165] Implement debug_type for tuples --- src/debuginfo/types.rs | 47 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) diff --git a/src/debuginfo/types.rs b/src/debuginfo/types.rs index 7e5fafdd544a..7baf0a3868d2 100644 --- a/src/debuginfo/types.rs +++ b/src/debuginfo/types.rs @@ -56,7 +56,7 @@ impl DebugContext { // ty::FnDef(..) | ty::FnPtr(..) // ty::Closure(..) // ty::Adt(def, ..) - // ty::Tuple(_) + ty::Tuple(components) => self.tuple_type(tcx, type_dbg, ty, *components), // ty::Param(_) // FIXME implement remaining types and add unreachable!() to the fallback branch _ => self.placeholder_for_type(tcx, type_dbg, ty), @@ -144,6 +144,51 @@ impl DebugContext { } } + fn tuple_type<'tcx>( + &mut self, + tcx: TyCtxt<'tcx>, + type_dbg: &mut TypeDebugContext<'tcx>, + tuple_type: Ty<'tcx>, + components: &'tcx [Ty<'tcx>], + ) -> UnitEntryId { + let components = components + .into_iter() + .map(|&ty| (ty, self.debug_type(tcx, type_dbg, ty))) + .collect::>(); + + return_if_type_created_in_meantime!(type_dbg, tuple_type); + + let name = type_names::compute_debuginfo_type_name(tcx, tuple_type, false); + let layout = RevealAllLayoutCx(tcx).layout_of(tuple_type); + + let tuple_type_id = + self.dwarf.unit.add(self.dwarf.unit.root(), gimli::DW_TAG_structure_type); + let tuple_entry = self.dwarf.unit.get_mut(tuple_type_id); + tuple_entry.set(gimli::DW_AT_name, AttributeValue::StringRef(self.dwarf.strings.add(name))); + tuple_entry.set(gimli::DW_AT_byte_size, AttributeValue::Udata(layout.size.bytes())); + tuple_entry.set(gimli::DW_AT_alignment, AttributeValue::Udata(layout.align.pref.bytes())); + + for (i, (ty, dw_ty)) in components.into_iter().enumerate() { + let member_id = self.dwarf.unit.add(tuple_type_id, gimli::DW_TAG_member); + let member_entry = self.dwarf.unit.get_mut(member_id); + member_entry.set( + gimli::DW_AT_name, + AttributeValue::StringRef(self.dwarf.strings.add(format!("__{i}"))), + ); + member_entry.set(gimli::DW_AT_type, AttributeValue::UnitRef(dw_ty)); + member_entry.set( + gimli::DW_AT_alignment, + AttributeValue::Udata(RevealAllLayoutCx(tcx).layout_of(ty).align.pref.bytes()), + ); + member_entry.set( + gimli::DW_AT_data_member_location, + AttributeValue::Udata(layout.fields.offset(i).bytes()), + ); + } + + tuple_type_id + } + fn placeholder_for_type<'tcx>( &mut self, tcx: TyCtxt<'tcx>, From 50897170d5f605dbc12c679fd51d26604d5f022c 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, 27 Mar 2024 20:26:22 +0000 Subject: [PATCH 148/165] Use a line-separated plain-text allowlist instead --- .../tidy/src/allowed_run_make_makefiles.txt | 681 +++++++++--------- src/tools/tidy/src/run_make_tests.rs | 19 +- 2 files changed, 341 insertions(+), 359 deletions(-) diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index 817ac1f02c2e..bdee3afa6b71 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -1,344 +1,337 @@ -/* -============================================================ - ⚠️⚠️⚠️NOTHING SHOULD EVER BE ADDED TO THIS LIST⚠️⚠️⚠️ -============================================================ -*/ -[ -"run-make/alloc-no-oom-handling/Makefile", -"run-make/alloc-no-rc/Makefile", -"run-make/alloc-no-sync/Makefile", -"run-make/allocator-shim-circular-deps/Makefile", -"run-make/allow-non-lint-warnings-cmdline/Makefile", -"run-make/allow-warnings-cmdline-stability/Makefile", -"run-make/archive-duplicate-names/Makefile", -"run-make/arguments-non-c-like-enum/Makefile", -"run-make/atomic-lock-free/Makefile", -"run-make/bare-outfile/Makefile", -"run-make/branch-protection-check-IBT/Makefile", -"run-make/c-dynamic-dylib/Makefile", -"run-make/c-dynamic-rlib/Makefile", -"run-make/c-link-to-rust-dylib/Makefile", -"run-make/c-link-to-rust-staticlib/Makefile", -"run-make/c-link-to-rust-va-list-fn/Makefile", -"run-make/c-static-dylib/Makefile", -"run-make/c-static-rlib/Makefile", -"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/cdylib/Makefile", -"run-make/codegen-options-parsing/Makefile", -"run-make/comment-section/Makefile", -"run-make/compile-stdin/Makefile", -"run-make/compiler-lookup-paths-2/Makefile", -"run-make/compiler-lookup-paths/Makefile", -"run-make/compiler-rt-works-on-mingw/Makefile", -"run-make/compressed-debuginfo/Makefile", -"run-make/const-prop-lint/Makefile", -"run-make/const_fn_mir/Makefile", -"run-make/core-no-fp-fmt-parse/Makefile", -"run-make/core-no-oom-handling/Makefile", -"run-make/crate-data-smoke/Makefile", -"run-make/crate-hash-rustc-version/Makefile", -"run-make/crate-name-priority/Makefile", -"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/debugger-visualizer-dep-info/Makefile", -"run-make/dep-graph/Makefile", -"run-make/dep-info-doesnt-run-much/Makefile", -"run-make/dep-info-spaces/Makefile", -"run-make/dep-info/Makefile", -"run-make/doctests-keep-binaries/Makefile", -"run-make/doctests-runtool/Makefile", -"run-make/dump-ice-to-disk/Makefile", -"run-make/dump-mono-stats/Makefile", -"run-make/duplicate-output-flavors/Makefile", -"run-make/dylib-chain/Makefile", -"run-make/emit-named-files/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/emit/Makefile", -"run-make/env-dep-info/Makefile", -"run-make/error-found-staticlib-instead-crate/Makefile", -"run-make/error-writing-dependencies/Makefile", -"run-make/exit-code/Makefile", -"run-make/export-executable-symbols/Makefile", -"run-make/extern-diff-internal-name/Makefile", -"run-make/extern-flag-disambiguates/Makefile", -"run-make/extern-flag-fun/Makefile", -"run-make/extern-flag-pathless/Makefile", -"run-make/extern-flag-rename-transitive/Makefile", -"run-make/extern-fn-explicit-align/Makefile", -"run-make/extern-fn-generic/Makefile", -"run-make/extern-fn-mangle/Makefile", -"run-make/extern-fn-reachable/Makefile", -"run-make/extern-fn-struct-passing-abi/Makefile", -"run-make/extern-fn-with-extern-types/Makefile", -"run-make/extern-fn-with-packed-struct/Makefile", -"run-make/extern-fn-with-union/Makefile", -"run-make/extern-multiple-copies/Makefile", -"run-make/extern-multiple-copies2/Makefile", -"run-make/extern-overrides-distribution/Makefile", -"run-make/extra-filename-with-temp-outputs/Makefile", -"run-make/fmt-write-bloat/Makefile", -"run-make/forced-unwind-terminate-pof/Makefile", -"run-make/foreign-double-unwind/Makefile", -"run-make/foreign-exceptions/Makefile", -"run-make/foreign-rust-exceptions/Makefile", -"run-make/fpic/Makefile", -"run-make/glibc-staticlib-args/Makefile", -"run-make/hir-tree/Makefile", -"run-make/inaccessible-temp-dir/Makefile", -"run-make/include_bytes_deps/Makefile", -"run-make/incr-add-rust-src-component/Makefile", -"run-make/incr-foreign-head-span/Makefile", -"run-make/incr-prev-body-beyond-eof/Makefile", -"run-make/incremental-debugger-visualizer/Makefile", -"run-make/incremental-session-fail/Makefile", -"run-make/inline-always-many-cgu/Makefile", -"run-make/interdependent-c-libraries/Makefile", -"run-make/intrinsic-unreachable/Makefile", -"run-make/invalid-library/Makefile", -"run-make/invalid-so/Makefile", -"run-make/invalid-staticlib/Makefile", -"run-make/issue-107094/Makefile", -"run-make/issue-10971-temps-dir/Makefile", -"run-make/issue-109934-lto-debuginfo/Makefile", -"run-make/issue-11908/Makefile", -"run-make/issue-14500/Makefile", -"run-make/issue-14698/Makefile", -"run-make/issue-15460/Makefile", -"run-make/issue-18943/Makefile", -"run-make/issue-20626/Makefile", -"run-make/issue-22131/Makefile", -"run-make/issue-24445/Makefile", -"run-make/issue-25581/Makefile", -"run-make/issue-26006/Makefile", -"run-make/issue-26092/Makefile", -"run-make/issue-28595/Makefile", -"run-make/issue-28766/Makefile", -"run-make/issue-30063/Makefile", -"run-make/issue-33329/Makefile", -"run-make/issue-35164/Makefile", -"run-make/issue-36710/Makefile", -"run-make/issue-37839/Makefile", -"run-make/issue-37893/Makefile", -"run-make/issue-38237/Makefile", -"run-make/issue-40535/Makefile", -"run-make/issue-46239/Makefile", -"run-make/issue-47384/Makefile", -"run-make/issue-47551/Makefile", -"run-make/issue-51671/Makefile", -"run-make/issue-53964/Makefile", -"run-make/issue-64153/Makefile", -"run-make/issue-68794-textrel-on-minimal-lib/Makefile", -"run-make/issue-69368/Makefile", -"run-make/issue-7349/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", -"run-make/issue-85441/Makefile", -"run-make/issue-88756-default-output/Makefile", -"run-make/issue-97463-abi-param-passing/Makefile", -"run-make/issue64319/Makefile", -"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-arg/Makefile", -"run-make/link-args-order/Makefile", -"run-make/link-cfg/Makefile", -"run-make/link-dedup/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/llvm-outputs/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/ls-metadata/Makefile", -"run-make/lto-dylib-dep/Makefile", -"run-make/lto-empty/Makefile", -"run-make/lto-linkage-used-attr/Makefile", -"run-make/lto-no-link-whole-rlib/Makefile", -"run-make/lto-readonly-lib/Makefile", -"run-make/lto-smoke-c/Makefile", -"run-make/lto-smoke/Makefile", -"run-make/macos-deployment-target/Makefile", -"run-make/macos-fat-archive/Makefile", -"run-make/manual-crate-name/Makefile", -"run-make/manual-link/Makefile", -"run-make/many-crates-but-no-match/Makefile", -"run-make/metadata-dep-info/Makefile", -"run-make/metadata-flag-frobs-symbols/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-deps/Makefile", -"run-make/mixing-formats/Makefile", -"run-make/mixing-libs/Makefile", -"run-make/msvc-opt-minsize/Makefile", -"run-make/multiple-emits/Makefile", -"run-make/native-link-modifier-bundle/Makefile", -"run-make/native-link-modifier-verbatim-linker/Makefile", -"run-make/native-link-modifier-verbatim-rustc/Makefile", -"run-make/native-link-modifier-whole-archive/Makefile", -"run-make/no-alloc-shim/Makefile", -"run-make/no-builtins-attribute/Makefile", -"run-make/no-builtins-lto/Makefile", -"run-make/no-cdylib-as-rdylib/Makefile", -"run-make/no-duplicate-libs/Makefile", -"run-make/no-input-file/Makefile", -"run-make/no-intermediate-extras/Makefile", -"run-make/obey-crate-type-flag/Makefile", -"run-make/optimization-remarks-dir-pgo/Makefile", -"run-make/optimization-remarks-dir/Makefile", -"run-make/output-filename-conflicts-with-directory/Makefile", -"run-make/output-filename-overwrites-input/Makefile", -"run-make/output-type-permutations/Makefile", -"run-make/output-with-hyphens/Makefile", -"run-make/override-aliased-flags/Makefile", -"run-make/overwrite-input/Makefile", -"run-make/panic-abort-eh_frame/Makefile", -"run-make/panic-impl-transitive/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-alt-path/Makefile", -"run-make/pdb-buildinfo-cl-cmd/Makefile", -"run-make/pgo-branch-weights/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", -"run-make/prefer-dylib/Makefile", -"run-make/prefer-rlib/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-cfg/Makefile", -"run-make/print-native-static-libs/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", -"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", -"run-make/raw-dylib-link-ordinal/Makefile", -"run-make/raw-dylib-stdcall-ordinal/Makefile", -"run-make/redundant-libs/Makefile", -"run-make/relocation-model/Makefile", -"run-make/relro-levels/Makefile", -"run-make/remap-path-prefix-dwarf/Makefile", -"run-make/remap-path-prefix/Makefile", -"run-make/repr128-dwarf/Makefile", -"run-make/reproducible-build-2/Makefile", -"run-make/reproducible-build/Makefile", -"run-make/resolve-rename/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", -"run-make/rlib-format-packed-bundled-libs/Makefile", -"run-make/rmeta-preferred/Makefile", -"run-make/rust-lld-custom-target/Makefile", -"run-make/rust-lld/Makefile", -"run-make/rustc-macro-dep-files/Makefile", -"run-make/rustdoc-determinism/Makefile", -"run-make/rustdoc-error-lines/Makefile", -"run-make/rustdoc-io-error/Makefile", -"run-make/rustdoc-map-file/Makefile", -"run-make/rustdoc-output-path/Makefile", -"run-make/rustdoc-scrape-examples-invalid-expr/Makefile", -"run-make/rustdoc-scrape-examples-macros/Makefile", -"run-make/rustdoc-scrape-examples-multiple/Makefile", -"run-make/rustdoc-scrape-examples-ordering/Makefile", -"run-make/rustdoc-scrape-examples-remap/Makefile", -"run-make/rustdoc-scrape-examples-test/Makefile", -"run-make/rustdoc-scrape-examples-whitespace/Makefile", -"run-make/rustdoc-shared-flags/Makefile", -"run-make/rustdoc-target-spec-json-path/Makefile", -"run-make/rustdoc-themes/Makefile", -"run-make/rustdoc-verify-output-files/Makefile", -"run-make/rustdoc-with-out-dir-option/Makefile", -"run-make/rustdoc-with-output-option/Makefile", -"run-make/rustdoc-with-short-out-dir-option/Makefile", -"run-make/sanitizer-cdylib-link/Makefile", -"run-make/sanitizer-dylib-link/Makefile", -"run-make/sanitizer-staticlib-link/Makefile", -"run-make/separate-link-fail/Makefile", -"run-make/separate-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/short-ice/Makefile", -"run-make/silly-file-names/Makefile", -"run-make/simd-ffi/Makefile", -"run-make/simple-dylib/Makefile", -"run-make/simple-rlib/Makefile", -"run-make/split-debuginfo/Makefile", -"run-make/stable-symbol-names/Makefile", -"run-make/static-dylib-by-default/Makefile", -"run-make/static-extern-type/Makefile", -"run-make/static-pie/Makefile", -"run-make/static-unwinding/Makefile", -"run-make/staticlib-blank-lib/Makefile", -"run-make/staticlib-dylib-linkage/Makefile", -"run-make/std-core-cycle/Makefile", -"run-make/stdin-non-utf8/Makefile", -"run-make/suspicious-library/Makefile", -"run-make/symbol-mangling-hashed/Makefile", -"run-make/symbol-visibility/Makefile", -"run-make/symbols-include-type-name/Makefile", -"run-make/symlinked-extern/Makefile", -"run-make/symlinked-libraries/Makefile", -"run-make/symlinked-rlib/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", -"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", -"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/used/Makefile", -"run-make/valid-print-requests/Makefile", -"run-make/version/Makefile", -"run-make/volatile-intrinsics/Makefile", -"run-make/wasm-exceptions-nostd/Makefile", -"run-make/wasm-override-linker/Makefile", -"run-make/weird-output-filenames/Makefile", -"run-make/windows-binary-no-external-deps/Makefile", -"run-make/windows-safeseh/Makefile", -"run-make/windows-spawn/Makefile", -"run-make/windows-subsystem/Makefile", -"run-make/x86_64-fortanix-unknown-sgx-lvi/Makefile", -] +run-make/alloc-no-oom-handling/Makefile +run-make/alloc-no-rc/Makefile +run-make/alloc-no-sync/Makefile +run-make/allocator-shim-circular-deps/Makefile +run-make/allow-non-lint-warnings-cmdline/Makefile +run-make/allow-warnings-cmdline-stability/Makefile +run-make/archive-duplicate-names/Makefile +run-make/arguments-non-c-like-enum/Makefile +run-make/atomic-lock-free/Makefile +run-make/bare-outfile/Makefile +run-make/branch-protection-check-IBT/Makefile +run-make/c-dynamic-dylib/Makefile +run-make/c-dynamic-rlib/Makefile +run-make/c-link-to-rust-dylib/Makefile +run-make/c-link-to-rust-staticlib/Makefile +run-make/c-link-to-rust-va-list-fn/Makefile +run-make/c-static-dylib/Makefile +run-make/c-static-rlib/Makefile +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/cdylib/Makefile +run-make/codegen-options-parsing/Makefile +run-make/comment-section/Makefile +run-make/compile-stdin/Makefile +run-make/compiler-lookup-paths-2/Makefile +run-make/compiler-lookup-paths/Makefile +run-make/compiler-rt-works-on-mingw/Makefile +run-make/compressed-debuginfo/Makefile +run-make/const-prop-lint/Makefile +run-make/const_fn_mir/Makefile +run-make/core-no-fp-fmt-parse/Makefile +run-make/core-no-oom-handling/Makefile +run-make/crate-data-smoke/Makefile +run-make/crate-hash-rustc-version/Makefile +run-make/crate-name-priority/Makefile +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/debugger-visualizer-dep-info/Makefile +run-make/dep-graph/Makefile +run-make/dep-info-doesnt-run-much/Makefile +run-make/dep-info-spaces/Makefile +run-make/dep-info/Makefile +run-make/doctests-keep-binaries/Makefile +run-make/doctests-runtool/Makefile +run-make/dump-ice-to-disk/Makefile +run-make/dump-mono-stats/Makefile +run-make/duplicate-output-flavors/Makefile +run-make/dylib-chain/Makefile +run-make/emit-named-files/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/emit/Makefile +run-make/env-dep-info/Makefile +run-make/error-found-staticlib-instead-crate/Makefile +run-make/error-writing-dependencies/Makefile +run-make/exit-code/Makefile +run-make/export-executable-symbols/Makefile +run-make/extern-diff-internal-name/Makefile +run-make/extern-flag-disambiguates/Makefile +run-make/extern-flag-fun/Makefile +run-make/extern-flag-pathless/Makefile +run-make/extern-flag-rename-transitive/Makefile +run-make/extern-fn-explicit-align/Makefile +run-make/extern-fn-generic/Makefile +run-make/extern-fn-mangle/Makefile +run-make/extern-fn-reachable/Makefile +run-make/extern-fn-struct-passing-abi/Makefile +run-make/extern-fn-with-extern-types/Makefile +run-make/extern-fn-with-packed-struct/Makefile +run-make/extern-fn-with-union/Makefile +run-make/extern-multiple-copies/Makefile +run-make/extern-multiple-copies2/Makefile +run-make/extern-overrides-distribution/Makefile +run-make/extra-filename-with-temp-outputs/Makefile +run-make/fmt-write-bloat/Makefile +run-make/forced-unwind-terminate-pof/Makefile +run-make/foreign-double-unwind/Makefile +run-make/foreign-exceptions/Makefile +run-make/foreign-rust-exceptions/Makefile +run-make/fpic/Makefile +run-make/glibc-staticlib-args/Makefile +run-make/hir-tree/Makefile +run-make/inaccessible-temp-dir/Makefile +run-make/include_bytes_deps/Makefile +run-make/incr-add-rust-src-component/Makefile +run-make/incr-foreign-head-span/Makefile +run-make/incr-prev-body-beyond-eof/Makefile +run-make/incremental-debugger-visualizer/Makefile +run-make/incremental-session-fail/Makefile +run-make/inline-always-many-cgu/Makefile +run-make/interdependent-c-libraries/Makefile +run-make/intrinsic-unreachable/Makefile +run-make/invalid-library/Makefile +run-make/invalid-so/Makefile +run-make/invalid-staticlib/Makefile +run-make/issue-107094/Makefile +run-make/issue-10971-temps-dir/Makefile +run-make/issue-109934-lto-debuginfo/Makefile +run-make/issue-11908/Makefile +run-make/issue-14500/Makefile +run-make/issue-14698/Makefile +run-make/issue-15460/Makefile +run-make/issue-18943/Makefile +run-make/issue-20626/Makefile +run-make/issue-22131/Makefile +run-make/issue-24445/Makefile +run-make/issue-25581/Makefile +run-make/issue-26006/Makefile +run-make/issue-26092/Makefile +run-make/issue-28595/Makefile +run-make/issue-28766/Makefile +run-make/issue-30063/Makefile +run-make/issue-33329/Makefile +run-make/issue-35164/Makefile +run-make/issue-36710/Makefile +run-make/issue-37839/Makefile +run-make/issue-37893/Makefile +run-make/issue-38237/Makefile +run-make/issue-40535/Makefile +run-make/issue-46239/Makefile +run-make/issue-47384/Makefile +run-make/issue-47551/Makefile +run-make/issue-51671/Makefile +run-make/issue-53964/Makefile +run-make/issue-64153/Makefile +run-make/issue-68794-textrel-on-minimal-lib/Makefile +run-make/issue-69368/Makefile +run-make/issue-7349/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 +run-make/issue-85441/Makefile +run-make/issue-88756-default-output/Makefile +run-make/issue-97463-abi-param-passing/Makefile +run-make/issue64319/Makefile +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-arg/Makefile +run-make/link-args-order/Makefile +run-make/link-cfg/Makefile +run-make/link-dedup/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/llvm-outputs/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/ls-metadata/Makefile +run-make/lto-dylib-dep/Makefile +run-make/lto-empty/Makefile +run-make/lto-linkage-used-attr/Makefile +run-make/lto-no-link-whole-rlib/Makefile +run-make/lto-readonly-lib/Makefile +run-make/lto-smoke-c/Makefile +run-make/lto-smoke/Makefile +run-make/macos-deployment-target/Makefile +run-make/macos-fat-archive/Makefile +run-make/manual-crate-name/Makefile +run-make/manual-link/Makefile +run-make/many-crates-but-no-match/Makefile +run-make/metadata-dep-info/Makefile +run-make/metadata-flag-frobs-symbols/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-deps/Makefile +run-make/mixing-formats/Makefile +run-make/mixing-libs/Makefile +run-make/msvc-opt-minsize/Makefile +run-make/multiple-emits/Makefile +run-make/native-link-modifier-bundle/Makefile +run-make/native-link-modifier-verbatim-linker/Makefile +run-make/native-link-modifier-verbatim-rustc/Makefile +run-make/native-link-modifier-whole-archive/Makefile +run-make/no-alloc-shim/Makefile +run-make/no-builtins-attribute/Makefile +run-make/no-builtins-lto/Makefile +run-make/no-cdylib-as-rdylib/Makefile +run-make/no-duplicate-libs/Makefile +run-make/no-input-file/Makefile +run-make/no-intermediate-extras/Makefile +run-make/obey-crate-type-flag/Makefile +run-make/optimization-remarks-dir-pgo/Makefile +run-make/optimization-remarks-dir/Makefile +run-make/output-filename-conflicts-with-directory/Makefile +run-make/output-filename-overwrites-input/Makefile +run-make/output-type-permutations/Makefile +run-make/output-with-hyphens/Makefile +run-make/override-aliased-flags/Makefile +run-make/overwrite-input/Makefile +run-make/panic-abort-eh_frame/Makefile +run-make/panic-impl-transitive/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-alt-path/Makefile +run-make/pdb-buildinfo-cl-cmd/Makefile +run-make/pgo-branch-weights/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 +run-make/prefer-dylib/Makefile +run-make/prefer-rlib/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-cfg/Makefile +run-make/print-native-static-libs/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 +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 +run-make/raw-dylib-link-ordinal/Makefile +run-make/raw-dylib-stdcall-ordinal/Makefile +run-make/redundant-libs/Makefile +run-make/relocation-model/Makefile +run-make/relro-levels/Makefile +run-make/remap-path-prefix-dwarf/Makefile +run-make/remap-path-prefix/Makefile +run-make/repr128-dwarf/Makefile +run-make/reproducible-build-2/Makefile +run-make/reproducible-build/Makefile +run-make/resolve-rename/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 +run-make/rlib-format-packed-bundled-libs/Makefile +run-make/rmeta-preferred/Makefile +run-make/rust-lld-custom-target/Makefile +run-make/rust-lld/Makefile +run-make/rustc-macro-dep-files/Makefile +run-make/rustdoc-determinism/Makefile +run-make/rustdoc-error-lines/Makefile +run-make/rustdoc-io-error/Makefile +run-make/rustdoc-map-file/Makefile +run-make/rustdoc-output-path/Makefile +run-make/rustdoc-scrape-examples-invalid-expr/Makefile +run-make/rustdoc-scrape-examples-macros/Makefile +run-make/rustdoc-scrape-examples-multiple/Makefile +run-make/rustdoc-scrape-examples-ordering/Makefile +run-make/rustdoc-scrape-examples-remap/Makefile +run-make/rustdoc-scrape-examples-test/Makefile +run-make/rustdoc-scrape-examples-whitespace/Makefile +run-make/rustdoc-shared-flags/Makefile +run-make/rustdoc-target-spec-json-path/Makefile +run-make/rustdoc-themes/Makefile +run-make/rustdoc-verify-output-files/Makefile +run-make/rustdoc-with-out-dir-option/Makefile +run-make/rustdoc-with-output-option/Makefile +run-make/rustdoc-with-short-out-dir-option/Makefile +run-make/sanitizer-cdylib-link/Makefile +run-make/sanitizer-dylib-link/Makefile +run-make/sanitizer-staticlib-link/Makefile +run-make/separate-link-fail/Makefile +run-make/separate-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/short-ice/Makefile +run-make/silly-file-names/Makefile +run-make/simd-ffi/Makefile +run-make/simple-dylib/Makefile +run-make/simple-rlib/Makefile +run-make/split-debuginfo/Makefile +run-make/stable-symbol-names/Makefile +run-make/static-dylib-by-default/Makefile +run-make/static-extern-type/Makefile +run-make/static-pie/Makefile +run-make/static-unwinding/Makefile +run-make/staticlib-blank-lib/Makefile +run-make/staticlib-dylib-linkage/Makefile +run-make/std-core-cycle/Makefile +run-make/stdin-non-utf8/Makefile +run-make/suspicious-library/Makefile +run-make/symbol-mangling-hashed/Makefile +run-make/symbol-visibility/Makefile +run-make/symbols-include-type-name/Makefile +run-make/symlinked-extern/Makefile +run-make/symlinked-libraries/Makefile +run-make/symlinked-rlib/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 +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 +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/used/Makefile +run-make/valid-print-requests/Makefile +run-make/version/Makefile +run-make/volatile-intrinsics/Makefile +run-make/wasm-exceptions-nostd/Makefile +run-make/wasm-override-linker/Makefile +run-make/weird-output-filenames/Makefile +run-make/windows-binary-no-external-deps/Makefile +run-make/windows-safeseh/Makefile +run-make/windows-spawn/Makefile +run-make/windows-subsystem/Makefile +run-make/x86_64-fortanix-unknown-sgx-lvi/Makefile diff --git a/src/tools/tidy/src/run_make_tests.rs b/src/tools/tidy/src/run_make_tests.rs index 47bafb4b39e4..0486e2199180 100644 --- a/src/tools/tidy/src/run_make_tests.rs +++ b/src/tools/tidy/src/run_make_tests.rs @@ -7,10 +7,8 @@ use std::path::{Path, PathBuf}; pub fn check(tests_path: &Path, src_path: &Path, bless: bool, bad: &mut bool) { let allowed_makefiles = { - // We use `include!` here which includes the file as Rust syntax because we want to have - // a comment that discourages people from adding entries to - // `allowed_run_make_makefiles.txt` unless *absolutely* necessary. - let allowed_makefiles = include!("allowed_run_make_makefiles.txt"); + let allowed_makefiles = include_str!("allowed_run_make_makefiles.txt"); + let allowed_makefiles = allowed_makefiles.lines().collect::>(); let is_sorted = allowed_makefiles.windows(2).all(|w| w[0] < w[1]); if !is_sorted && !bless { tidy_error!( @@ -21,7 +19,7 @@ pub fn check(tests_path: &Path, src_path: &Path, bless: bool, bad: &mut bool) { ); } let allowed_makefiles_unique = - allowed_makefiles.into_iter().map(ToOwned::to_owned).collect::>(); + allowed_makefiles.iter().map(ToString::to_string).collect::>(); if allowed_makefiles_unique.len() != allowed_makefiles.len() { tidy_error!( bad, @@ -67,22 +65,13 @@ pub fn check(tests_path: &Path, src_path: &Path, bless: bool, bad: &mut bool) { // `src/tools/tidy/src/allowed_run_make_makefiles.txt`. // This can be done automatically on --bless, or else a tidy error will be issued. if bless && !remaining_makefiles.is_empty() { - let header = r#"/* -============================================================ - ⚠️⚠️⚠️NOTHING SHOULD EVER BE ADDED TO THIS LIST⚠️⚠️⚠️ -============================================================ -*/ -[ -"#; let tidy_src = src_path.join("tools").join("tidy").join("src"); let org_file_path = tidy_src.join("allowed_run_make_makefiles.txt"); let temp_file_path = tidy_src.join("blessed_allowed_run_make_makefiles.txt"); let mut temp_file = t!(File::create_new(&temp_file_path)); - t!(write!(temp_file, "{}", header)); for file in allowed_makefiles.difference(&remaining_makefiles) { - t!(write!(temp_file, "\"{file}\",\n")); + t!(writeln!(temp_file, "{file}")); } - t!(write!(temp_file, "]\n")); t!(std::fs::rename(&temp_file_path, &org_file_path)); } else { for file in remaining_makefiles { From 4f0cde1e51dbfb20a2260a0fc83a5c1359b4dc9d Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Wed, 27 Mar 2024 20:36:49 +0000 Subject: [PATCH 149/165] Define return type for functions in debuginfo --- src/base.rs | 9 ++++++--- src/debuginfo/mod.rs | 10 ++++++++++ src/driver/aot.rs | 1 + src/driver/jit.rs | 10 +++++++++- 4 files changed, 26 insertions(+), 4 deletions(-) diff --git a/src/base.rs b/src/base.rs index 049023f1560f..b4ea4e10a3d0 100644 --- a/src/base.rs +++ b/src/base.rs @@ -11,7 +11,7 @@ use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_monomorphize::is_call_from_compiler_builtins_to_upstream_monomorphization; use crate::constant::ConstantCx; -use crate::debuginfo::FunctionDebugContext; +use crate::debuginfo::{FunctionDebugContext, TypeDebugContext}; use crate::prelude::*; use crate::pretty_clif::CommentWriter; @@ -26,6 +26,7 @@ pub(crate) struct CodegenedFunction { pub(crate) fn codegen_fn<'tcx>( tcx: TyCtxt<'tcx>, cx: &mut crate::CodegenCx, + type_dbg: &mut TypeDebugContext<'tcx>, cached_func: Function, module: &mut dyn Module, instance: Instance<'tcx>, @@ -69,8 +70,10 @@ pub(crate) fn codegen_fn<'tcx>( let pointer_type = target_config.pointer_type(); let clif_comments = crate::pretty_clif::CommentWriter::new(tcx, instance); + let fn_abi = RevealAllLayoutCx(tcx).fn_abi_of_instance(instance, ty::List::empty()); + let func_debug_cx = if let Some(debug_context) = &mut cx.debug_context { - Some(debug_context.define_function(tcx, instance, &symbol_name, mir.span)) + Some(debug_context.define_function(tcx, type_dbg, instance, fn_abi, &symbol_name, mir.span)) } else { None }; @@ -87,7 +90,7 @@ pub(crate) fn codegen_fn<'tcx>( instance, symbol_name, mir, - fn_abi: RevealAllLayoutCx(tcx).fn_abi_of_instance(instance, ty::List::empty()), + fn_abi, bcx, block_map, diff --git a/src/debuginfo/mod.rs b/src/debuginfo/mod.rs index 2bab897dbcd8..1bb0e5905137 100644 --- a/src/debuginfo/mod.rs +++ b/src/debuginfo/mod.rs @@ -20,6 +20,7 @@ use rustc_hir::def::DefKind; use rustc_hir::def_id::DefIdMap; use rustc_session::Session; use rustc_span::{SourceFileHash, StableSourceFileId}; +use rustc_target::abi::call::FnAbi; pub(crate) use self::emit::{DebugReloc, DebugRelocName}; pub(crate) use self::types::TypeDebugContext; @@ -188,7 +189,9 @@ impl DebugContext { pub(crate) fn define_function<'tcx>( &mut self, tcx: TyCtxt<'tcx>, + type_dbg: &mut TypeDebugContext<'tcx>, instance: Instance<'tcx>, + fn_abi: &'tcx FnAbi<'tcx, Ty<'tcx>>, linkage_name: &str, function_span: Span, ) -> FunctionDebugContext { @@ -240,7 +243,14 @@ impl DebugContext { entry.set(gimli::DW_AT_decl_file, AttributeValue::FileIndex(Some(file_id))); entry.set(gimli::DW_AT_decl_line, AttributeValue::Udata(line)); + if !fn_abi.ret.is_ignore() { + let return_dw_ty = self.debug_type(tcx, type_dbg, fn_abi.ret.layout.ty); + let entry = self.dwarf.unit.get_mut(entry_id); + entry.set(gimli::DW_AT_type, AttributeValue::UnitRef(return_dw_ty)); + } + if tcx.is_reachable_non_generic(instance.def_id()) { + let entry = self.dwarf.unit.get_mut(entry_id); entry.set(gimli::DW_AT_external, AttributeValue::FlagPresent); } diff --git a/src/driver/aot.rs b/src/driver/aot.rs index e5caceab3456..75268341a4fe 100644 --- a/src/driver/aot.rs +++ b/src/driver/aot.rs @@ -470,6 +470,7 @@ fn module_codegen( let codegened_function = crate::base::codegen_fn( tcx, &mut cx, + &mut type_dbg, Function::new(), &mut module, inst, diff --git a/src/driver/jit.rs b/src/driver/jit.rs index 6b2b946db02b..6dbc3f191278 100644 --- a/src/driver/jit.rs +++ b/src/driver/jit.rs @@ -12,6 +12,7 @@ use rustc_middle::mir::mono::MonoItem; use rustc_session::Session; use rustc_span::Symbol; +use crate::debuginfo::TypeDebugContext; use crate::{prelude::*, BackendConfig}; use crate::{CodegenCx, CodegenMode}; @@ -229,7 +230,14 @@ 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(tcx, cx, cached_func, module, instance); + let 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); }); From 0f1bbe31418cdd5d4360d94d252f0d49046e0173 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, 27 Mar 2024 21:29:50 +0000 Subject: [PATCH 150/165] Point out you can use --bless to update allow list for removed entries --- src/tools/tidy/src/run_make_tests.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/tools/tidy/src/run_make_tests.rs b/src/tools/tidy/src/run_make_tests.rs index 0486e2199180..98021cec1301 100644 --- a/src/tools/tidy/src/run_make_tests.rs +++ b/src/tools/tidy/src/run_make_tests.rs @@ -80,7 +80,8 @@ 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`", + `src/tools/tidy/src/allowed_run_make_makefiles.txt`, you can run --bless to update \ + the allow list", p.display() ); } From 7a99be35f210b35d3ead95f7585b3242b0d096a3 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, 27 Mar 2024 21:31:56 +0000 Subject: [PATCH 151/165] Add FIXME to remind removing the check once all tests are ported over --- src/tools/tidy/src/main.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tools/tidy/src/main.rs b/src/tools/tidy/src/main.rs index bf5c0afdbb0a..93be4d61a9ab 100644 --- a/src/tools/tidy/src/main.rs +++ b/src/tools/tidy/src/main.rs @@ -103,6 +103,7 @@ fn main() { check!(tests_revision_unpaired_stdout_stderr, &tests_path); check!(debug_artifacts, &tests_path); check!(ui_tests, &root_path, bless); + // FIXME(jieyouxu): remove this check once all run-make tests are ported over to rmake.rs. check!(run_make_tests, &tests_path, &src_path, bless); check!(mir_opt_tests, &tests_path, bless); check!(rustdoc_gui_tests, &tests_path); From 1dcbc23c4bb1acb4dacf23f9e5e1b1f0c55829cf 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, 27 Mar 2024 21:43:40 +0000 Subject: [PATCH 152/165] Accept only-wasm32-wasip1 directives --- src/tools/compiletest/src/header.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs index 99f1e33299dc..351f97042d40 100644 --- a/src/tools/compiletest/src/header.rs +++ b/src/tools/compiletest/src/header.rs @@ -691,9 +691,9 @@ pub fn line_directive<'line>( } } -/// This is generated by collecting directives from ui tests and then extracting their directive -/// names. This is **not** an exhaustive list of all possible directives. Instead, this is a -/// best-effort approximation for diagnostics. +/// This was originally generated by collecting directives from ui tests and then extracting their +/// directive names. This is **not** an exhaustive list of all possible directives. Instead, this is +/// a best-effort approximation for diagnostics. Add new headers to this list when needed. const KNOWN_DIRECTIVE_NAMES: &[&str] = &[ // tidy-alphabetical-start "assembly-output", @@ -872,6 +872,7 @@ const KNOWN_DIRECTIVE_NAMES: &[&str] = &[ "only-unix", "only-wasm32", "only-wasm32-bare", + "only-wasm32-wasip1", "only-windows", "only-x86", "only-x86_64", From 08853804d059cb546137de6a89d8f05fc0193963 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, 27 Mar 2024 21:55:09 +0000 Subject: [PATCH 153/165] Use compiletest directives for properly only running wasm32-wasip1 tests on that target --- tests/run-make/wasm-abi/rmake.rs | 6 ++---- tests/run-make/wasm-custom-section/rmake.rs | 5 +---- tests/run-make/wasm-custom-sections-opt/rmake.rs | 5 +---- tests/run-make/wasm-export-all-symbols/rmake.rs | 6 ++---- tests/run-make/wasm-import-module/rmake.rs | 6 ++---- tests/run-make/wasm-panic-small/rmake.rs | 5 +---- tests/run-make/wasm-spurious-import/rmake.rs | 6 ++---- tests/run-make/wasm-stringify-ints-small/rmake.rs | 5 +---- tests/run-make/wasm-symbols-different-module/rmake.rs | 5 +---- tests/run-make/wasm-symbols-not-exported/rmake.rs | 5 +---- tests/run-make/wasm-symbols-not-imported/rmake.rs | 5 +---- 11 files changed, 15 insertions(+), 44 deletions(-) diff --git a/tests/run-make/wasm-abi/rmake.rs b/tests/run-make/wasm-abi/rmake.rs index f4d0027798ae..6d3d5b36c670 100644 --- a/tests/run-make/wasm-abi/rmake.rs +++ b/tests/run-make/wasm-abi/rmake.rs @@ -1,3 +1,5 @@ +//@ only-wasm32-wasip1 + extern crate run_make_support; use run_make_support::{rustc, tmp_dir}; @@ -5,10 +7,6 @@ use std::path::Path; use std::process::Command; fn main() { - if std::env::var("TARGET").unwrap() != "wasm32-wasip1" { - return; - } - rustc().input("foo.rs").target("wasm32-wasip1").run(); let file = tmp_dir().join("foo.wasm"); diff --git a/tests/run-make/wasm-custom-section/rmake.rs b/tests/run-make/wasm-custom-section/rmake.rs index 31fb5fb32303..825fcf71514c 100644 --- a/tests/run-make/wasm-custom-section/rmake.rs +++ b/tests/run-make/wasm-custom-section/rmake.rs @@ -1,13 +1,10 @@ +//@ only-wasm32-wasip1 extern crate run_make_support; use run_make_support::{rustc, tmp_dir, wasmparser}; use std::collections::HashMap; fn main() { - if std::env::var("TARGET").unwrap() != "wasm32-wasip1" { - return; - } - rustc().input("foo.rs").target("wasm32-wasip1").run(); rustc().input("bar.rs").target("wasm32-wasip1").arg("-Clto").opt().run(); diff --git a/tests/run-make/wasm-custom-sections-opt/rmake.rs b/tests/run-make/wasm-custom-sections-opt/rmake.rs index 3164de1b4c9a..634683adc220 100644 --- a/tests/run-make/wasm-custom-sections-opt/rmake.rs +++ b/tests/run-make/wasm-custom-sections-opt/rmake.rs @@ -1,3 +1,4 @@ +//@ only-wasm32-wasip1 extern crate run_make_support; use run_make_support::{tmp_dir, wasmparser, rustc}; @@ -5,10 +6,6 @@ use std::collections::HashMap; use std::path::Path; fn main() { - if std::env::var("TARGET").unwrap() != "wasm32-wasip1" { - return; - } - rustc().input("foo.rs").target("wasm32-wasip1").opt().run(); verify(&tmp_dir().join("foo.wasm")); diff --git a/tests/run-make/wasm-export-all-symbols/rmake.rs b/tests/run-make/wasm-export-all-symbols/rmake.rs index 13101a97444e..400d6db5651c 100644 --- a/tests/run-make/wasm-export-all-symbols/rmake.rs +++ b/tests/run-make/wasm-export-all-symbols/rmake.rs @@ -1,3 +1,5 @@ +//@ only-wasm32-wasip1 + extern crate run_make_support; use run_make_support::{tmp_dir, wasmparser, rustc}; @@ -6,10 +8,6 @@ use std::path::Path; use wasmparser::ExternalKind::*; fn main() { - if std::env::var("TARGET").unwrap() != "wasm32-wasip1" { - return; - } - test(&[]); test(&["-O"]); test(&["-Clto"]); diff --git a/tests/run-make/wasm-import-module/rmake.rs b/tests/run-make/wasm-import-module/rmake.rs index 3962bd80a898..1b814e9ccce3 100644 --- a/tests/run-make/wasm-import-module/rmake.rs +++ b/tests/run-make/wasm-import-module/rmake.rs @@ -1,3 +1,5 @@ +//@ only-wasm32-wasip1 + extern crate run_make_support; use run_make_support::{tmp_dir, wasmparser, rustc}; @@ -5,10 +7,6 @@ use std::collections::HashMap; use wasmparser::TypeRef::Func; fn main() { - if std::env::var("TARGET").unwrap() != "wasm32-wasip1" { - return; - } - rustc().input("foo.rs").target("wasm32-wasip1").run(); rustc() .input("bar.rs") diff --git a/tests/run-make/wasm-panic-small/rmake.rs b/tests/run-make/wasm-panic-small/rmake.rs index 7941b503994d..bffa311d93a1 100644 --- a/tests/run-make/wasm-panic-small/rmake.rs +++ b/tests/run-make/wasm-panic-small/rmake.rs @@ -1,3 +1,4 @@ +//@ only-wasm32-wasip1 #![deny(warnings)] extern crate run_make_support; @@ -5,10 +6,6 @@ extern crate run_make_support; use run_make_support::{rustc, tmp_dir}; fn main() { - if std::env::var("TARGET").unwrap() != "wasm32-wasip1" { - return; - } - test("a"); test("b"); test("c"); diff --git a/tests/run-make/wasm-spurious-import/rmake.rs b/tests/run-make/wasm-spurious-import/rmake.rs index 9dafa6f594a9..8f716061d28b 100644 --- a/tests/run-make/wasm-spurious-import/rmake.rs +++ b/tests/run-make/wasm-spurious-import/rmake.rs @@ -1,13 +1,11 @@ +//@ only-wasm32-wasip1 + extern crate run_make_support; use run_make_support::{rustc, tmp_dir, wasmparser}; use std::collections::HashMap; fn main() { - if std::env::var("TARGET").unwrap() != "wasm32-wasip1" { - return; - } - rustc() .input("main.rs") .target("wasm32-wasip1") diff --git a/tests/run-make/wasm-stringify-ints-small/rmake.rs b/tests/run-make/wasm-stringify-ints-small/rmake.rs index 6b3ad871a707..5efbfee8d383 100644 --- a/tests/run-make/wasm-stringify-ints-small/rmake.rs +++ b/tests/run-make/wasm-stringify-ints-small/rmake.rs @@ -1,3 +1,4 @@ +//@ only-wasm32-wasip1 #![deny(warnings)] extern crate run_make_support; @@ -5,10 +6,6 @@ extern crate run_make_support; use run_make_support::{rustc, tmp_dir}; fn main() { - if std::env::var("TARGET").unwrap() != "wasm32-wasip1" { - return; - } - rustc().input("foo.rs").target("wasm32-wasip1").arg("-Clto").opt().run(); let bytes = std::fs::read(&tmp_dir().join("foo.wasm")).unwrap(); diff --git a/tests/run-make/wasm-symbols-different-module/rmake.rs b/tests/run-make/wasm-symbols-different-module/rmake.rs index a27da446baae..88bd16a404c7 100644 --- a/tests/run-make/wasm-symbols-different-module/rmake.rs +++ b/tests/run-make/wasm-symbols-different-module/rmake.rs @@ -1,13 +1,10 @@ +//@ only-wasm32-wasip1 extern crate run_make_support; use run_make_support::{rustc, tmp_dir, wasmparser}; use std::collections::{HashMap, HashSet}; fn main() { - if std::env::var("TARGET").unwrap() != "wasm32-wasip1" { - return; - } - test_file("foo.rs", &[("a", &["foo"]), ("b", &["foo"])]); test_file("bar.rs", &[("m1", &["f", "g"]), ("m2", &["f"])]); test_file("baz.rs", &[("sqlite", &["allocate", "deallocate"])]); diff --git a/tests/run-make/wasm-symbols-not-exported/rmake.rs b/tests/run-make/wasm-symbols-not-exported/rmake.rs index da536f2af71a..c9207f70ae5f 100644 --- a/tests/run-make/wasm-symbols-not-exported/rmake.rs +++ b/tests/run-make/wasm-symbols-not-exported/rmake.rs @@ -1,13 +1,10 @@ +//@ only-wasm32-wasip1 extern crate run_make_support; use run_make_support::{rustc, tmp_dir, wasmparser}; use std::path::Path; fn main() { - if std::env::var("TARGET").unwrap() != "wasm32-wasip1" { - return; - } - rustc().input("foo.rs").target("wasm32-wasip1").run(); verify_symbols(&tmp_dir().join("foo.wasm")); rustc().input("foo.rs").target("wasm32-wasip1").opt().run(); diff --git a/tests/run-make/wasm-symbols-not-imported/rmake.rs b/tests/run-make/wasm-symbols-not-imported/rmake.rs index b784b6aff6a2..4d41dc7c0aa8 100644 --- a/tests/run-make/wasm-symbols-not-imported/rmake.rs +++ b/tests/run-make/wasm-symbols-not-imported/rmake.rs @@ -1,13 +1,10 @@ +//@ only-wasm32-wasip1 extern crate run_make_support; use run_make_support::{rustc, tmp_dir, wasmparser}; use std::path::Path; fn main() { - if std::env::var("TARGET").unwrap() != "wasm32-wasip1" { - return; - } - rustc().input("foo.rs").target("wasm32-wasip1").run(); verify_symbols(&tmp_dir().join("foo.wasm")); rustc().input("foo.rs").target("wasm32-wasip1").arg("-Clto").run(); From 12e999274deb278341206be162dc8515d6a77cf7 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, 27 Mar 2024 22:02:45 +0000 Subject: [PATCH 154/165] Convert wasmtime check into a compiletest needs directive --- src/tools/compiletest/src/header.rs | 1 + src/tools/compiletest/src/header/needs.rs | 5 +++++ tests/run-make/wasm-abi/rmake.rs | 10 +--------- 3 files changed, 7 insertions(+), 9 deletions(-) diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs index 351f97042d40..e414bc384f1f 100644 --- a/src/tools/compiletest/src/header.rs +++ b/src/tools/compiletest/src/header.rs @@ -837,6 +837,7 @@ const KNOWN_DIRECTIVE_NAMES: &[&str] = &[ "needs-sanitizer-thread", "needs-threads", "needs-unwind", + "needs-wasmtime", "needs-xray", "no-prefer-dynamic", "normalize-stderr-32bit", diff --git a/src/tools/compiletest/src/header/needs.rs b/src/tools/compiletest/src/header/needs.rs index d7c74038aea0..db154932d5b5 100644 --- a/src/tools/compiletest/src/header/needs.rs +++ b/src/tools/compiletest/src/header/needs.rs @@ -149,6 +149,11 @@ pub(super) fn handle_needs( condition: config.target_cfg().relocation_model == "pic", ignore_reason: "ignored on targets without PIC relocation model", }, + Need { + name: "needs-wasmtime", + condition: config.runner.as_ref().is_some_and(|r| r.contains("wasmtime")), + ignore_reason: "ignored when wasmtime runner is not available", + }, ]; let (name, comment) = match ln.split_once([':', ' ']) { diff --git a/tests/run-make/wasm-abi/rmake.rs b/tests/run-make/wasm-abi/rmake.rs index 6d3d5b36c670..d83332f6e034 100644 --- a/tests/run-make/wasm-abi/rmake.rs +++ b/tests/run-make/wasm-abi/rmake.rs @@ -1,4 +1,5 @@ //@ only-wasm32-wasip1 +//@ needs-wasmtime extern crate run_make_support; @@ -11,15 +12,6 @@ fn main() { let file = tmp_dir().join("foo.wasm"); - let has_wasmtime = match Command::new("wasmtime").arg("--version").output() { - Ok(s) => s.status.success(), - _ => false, - }; - if !has_wasmtime { - println!("skipping test, wasmtime isn't available"); - return; - } - run(&file, "return_two_i32", "1\n2\n"); run(&file, "return_two_i64", "3\n4\n"); run(&file, "return_two_f32", "5\n6\n"); From 9762d66f727bcc81c8b9fb8ec404a375ab639a52 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, 27 Mar 2024 22:07:49 +0000 Subject: [PATCH 155/165] Use compiletest directives for ignoring targets --- tests/run-make/compiler-builtins/rmake.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/run-make/compiler-builtins/rmake.rs b/tests/run-make/compiler-builtins/rmake.rs index b546a095c512..e5939470b46f 100644 --- a/tests/run-make/compiler-builtins/rmake.rs +++ b/tests/run-make/compiler-builtins/rmake.rs @@ -8,6 +8,10 @@ //! settings. Turning off optimizations and enabling debug assertions tends to produce the most //! dependence on core that is possible, so that is the configuration we test here. +// wasm and nvptx targets don't produce rlib files that object can parse. +//@ ignore-wasm +//@ ignore-nvptx64 + #![deny(warnings)] extern crate run_make_support; @@ -33,10 +37,6 @@ path = "lib.rs""#; fn main() { let target_dir = tmp_dir().join("target"); let target = std::env::var("TARGET").unwrap(); - if target.starts_with("wasm") || target.starts_with("nvptx") { - // wasm and nvptx targets don't produce rlib files that object can parse. - return; - } println!("Testing compiler_builtins for {}", target); From 90306cd84106741e884422745caf37e4f259e4af Mon Sep 17 00:00:00 2001 From: bohan Date: Thu, 28 Mar 2024 16:58:03 +0800 Subject: [PATCH 156/165] remove `def_id_to_node_id` in ast lowering --- compiler/rustc_middle/src/ty/mod.rs | 1 - compiler/rustc_resolve/src/lib.rs | 1 - 2 files changed, 2 deletions(-) diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index d1d8a3ea0725..f7dfb518903f 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -215,7 +215,6 @@ pub struct ResolverAstLowering { pub next_node_id: ast::NodeId, pub node_id_to_def_id: NodeMap, - pub def_id_to_node_id: IndexVec, pub trait_map: NodeMap>, /// List functions and methods for which lifetime elision was successful. diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index aa03adb7097e..39ccf6d37146 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -1618,7 +1618,6 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { .into_items() .map(|(k, f)| (k, f.key())) .collect(), - def_id_to_node_id: self.def_id_to_node_id, trait_map: self.trait_map, lifetime_elision_allowed: self.lifetime_elision_allowed, lint_buffer: Steal::new(self.lint_buffer), From 75fedfc4eaa9fd62160fadd21a98506520748f95 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 28 Mar 2024 11:08:50 +0100 Subject: [PATCH 157/165] Correctly get complete intra-doc link data --- .../passes/lint/redundant_explicit_links.rs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/librustdoc/passes/lint/redundant_explicit_links.rs b/src/librustdoc/passes/lint/redundant_explicit_links.rs index f7bc54647079..569c17ee36e5 100644 --- a/src/librustdoc/passes/lint/redundant_explicit_links.rs +++ b/src/librustdoc/passes/lint/redundant_explicit_links.rs @@ -90,7 +90,7 @@ fn check_redundant_explicit_link<'md>( ) -> Option<()> { let mut broken_line_callback = |link: BrokenLink<'md>| Some((link.reference, "".into())); let mut offset_iter = Parser::new_with_broken_link_callback( - &doc, + doc, main_body_opts(), Some(&mut broken_line_callback), ) @@ -264,6 +264,7 @@ fn collect_link_data(offset_iter: &mut OffsetIter<'_, '_>) -> LinkData { let mut resolvable_link = None; let mut resolvable_link_range = None; let mut display_link = String::new(); + let mut is_resolvable = true; while let Some((event, range)) = offset_iter.next() { match event { @@ -281,6 +282,11 @@ fn collect_link_data(offset_iter: &mut OffsetIter<'_, '_>) -> LinkData { resolvable_link = Some(code); resolvable_link_range = Some(range); } + Event::Start(_) => { + // If there is anything besides backticks, it's not considered as an intra-doc link + // so we ignore it. + is_resolvable = false; + } Event::End(_) => { break; } @@ -288,6 +294,11 @@ fn collect_link_data(offset_iter: &mut OffsetIter<'_, '_>) -> LinkData { } } + if !is_resolvable { + resolvable_link_range = None; + resolvable_link = None; + } + LinkData { resolvable_link, resolvable_link_range, display_link } } From f1cfbdbb9970890fc3b850037e84164a6b5c4ca0 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 28 Mar 2024 11:09:08 +0100 Subject: [PATCH 158/165] Add regression test for #123158 --- tests/rustdoc-ui/invalid-redundant-explicit-link.rs | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 tests/rustdoc-ui/invalid-redundant-explicit-link.rs diff --git a/tests/rustdoc-ui/invalid-redundant-explicit-link.rs b/tests/rustdoc-ui/invalid-redundant-explicit-link.rs new file mode 100644 index 000000000000..99ac1d82aafc --- /dev/null +++ b/tests/rustdoc-ui/invalid-redundant-explicit-link.rs @@ -0,0 +1,8 @@ +//@ check-pass + +// Regression test for . It +// should not emit any warning. + +//! [**`SomeTrait`**](SomeTrait): + +pub trait SomeTrait {} From e9870b5df305a90b285da012c7b617b702ff0c5c Mon Sep 17 00:00:00 2001 From: Marcondiro Date: Thu, 28 Mar 2024 11:21:52 +0100 Subject: [PATCH 159/165] Bump Unicode printables to version 15.1, align to unicode_data --- library/core/src/unicode/printable.rs | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/library/core/src/unicode/printable.rs b/library/core/src/unicode/printable.rs index ffb18a5ba8b3..33c3ef8083de 100644 --- a/library/core/src/unicode/printable.rs +++ b/library/core/src/unicode/printable.rs @@ -63,7 +63,10 @@ pub(crate) fn is_printable(x: char) -> bool { if 0x2cea2 <= x && x < 0x2ceb0 { return false; } - if 0x2ebe1 <= x && x < 0x2f800 { + if 0x2ebe1 <= x && x < 0x2ebf0 { + return false; + } + if 0x2ee5e <= x && x < 0x2f800 { return false; } if 0x2fa1e <= x && x < 0x30000 { @@ -112,7 +115,7 @@ const SINGLETONS0U: &[(u8, u8)] = &[ (0x2b, 3), (0x2d, 11), (0x2e, 1), - (0x30, 3), + (0x30, 4), (0x31, 2), (0x32, 1), (0xa7, 2), @@ -157,12 +160,12 @@ const SINGLETONS0L: &[u8] = &[ 0x7e, 0x7f, 0xb5, 0xc5, 0xd4, 0xd5, 0xdc, 0xf0, 0xf1, 0xf5, 0x72, 0x73, 0x8f, 0x74, 0x75, 0x96, 0x26, 0x2e, 0x2f, 0xa7, 0xaf, 0xb7, 0xbf, 0xc7, - 0xcf, 0xd7, 0xdf, 0x9a, 0x40, 0x97, 0x98, 0x30, - 0x8f, 0x1f, 0xd2, 0xd4, 0xce, 0xff, 0x4e, 0x4f, - 0x5a, 0x5b, 0x07, 0x08, 0x0f, 0x10, 0x27, 0x2f, - 0xee, 0xef, 0x6e, 0x6f, 0x37, 0x3d, 0x3f, 0x42, - 0x45, 0x90, 0x91, 0x53, 0x67, 0x75, 0xc8, 0xc9, - 0xd0, 0xd1, 0xd8, 0xd9, 0xe7, 0xfe, 0xff, + 0xcf, 0xd7, 0xdf, 0x9a, 0x00, 0x40, 0x97, 0x98, + 0x30, 0x8f, 0x1f, 0xd2, 0xd4, 0xce, 0xff, 0x4e, + 0x4f, 0x5a, 0x5b, 0x07, 0x08, 0x0f, 0x10, 0x27, + 0x2f, 0xee, 0xef, 0x6e, 0x6f, 0x37, 0x3d, 0x3f, + 0x42, 0x45, 0x90, 0x91, 0x53, 0x67, 0x75, 0xc8, + 0xc9, 0xd0, 0xd1, 0xd8, 0xd9, 0xe7, 0xfe, 0xff, ]; #[rustfmt::skip] const SINGLETONS1U: &[(u8, u8)] = &[ @@ -339,10 +342,9 @@ const NORMAL0: &[u8] = &[ 0x80, 0xbe, 0x22, 0x74, 0x0c, 0x80, 0xd6, 0x1a, - 0x0c, 0x05, - 0x80, 0xff, 0x05, - 0x80, 0xdf, 0x0c, - 0xf2, 0x9d, 0x03, + 0x81, 0x10, 0x05, + 0x80, 0xdf, 0x0b, + 0xf2, 0x9e, 0x03, 0x37, 0x09, 0x81, 0x5c, 0x14, 0x80, 0xb8, 0x08, From ef0b3d1def7cb38df376768810aae31de44b349e Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 28 Mar 2024 11:17:20 +0000 Subject: [PATCH 160/165] Rustup to rustc 1.79.0-nightly (c9f8f3438 2024-03-27) --- rust-toolchain | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-toolchain b/rust-toolchain index e9e7f90bbb48..612fc61ec27d 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2024-03-26" +channel = "nightly-2024-03-28" components = ["rust-src", "rustc-dev", "llvm-tools"] From 09fae60a86b848a2fc0ad219ecc4e438dc1eef86 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 28 Mar 2024 11:38:15 +0000 Subject: [PATCH 161/165] Fix rustc test suite --- scripts/test_rustc_tests.sh | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/scripts/test_rustc_tests.sh b/scripts/test_rustc_tests.sh index 96f71bcf7670..f42a008dc0c1 100755 --- a/scripts/test_rustc_tests.sh +++ b/scripts/test_rustc_tests.sh @@ -145,6 +145,19 @@ index ea06b620c4c..b969d0009c6 100644 ifdef RUSTC_LINKER RUSTC := \$(RUSTC) -Clinker='\$(RUSTC_LINKER)' RUSTDOC := \$(RUSTDOC) -Clinker='\$(RUSTC_LINKER)' +diff --git a/src/tools/run-make-support/src/rustdoc.rs b/src/tools/run-make-support/src/rustdoc.rs +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. + pub fn new() -> Self { + 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 } + } + EOF echo "[TEST] rustc test suite" From ec359f7d9f80a180e37f310fd417e9459e738466 Mon Sep 17 00:00:00 2001 From: DianQK Date: Thu, 28 Mar 2024 21:28:32 +0800 Subject: [PATCH 162/165] Restore the test checks for `wider_reduce_into_iter` The current minimum support is for LLVM 17. --- tests/codegen/simd/simd-wide-sum.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/codegen/simd/simd-wide-sum.rs b/tests/codegen/simd/simd-wide-sum.rs index 2edee552ca69..fb9b61884e7a 100644 --- a/tests/codegen/simd/simd-wide-sum.rs +++ b/tests/codegen/simd/simd-wide-sum.rs @@ -51,8 +51,8 @@ pub fn wider_reduce_iter(x: Simd) -> u16 { #[no_mangle] // CHECK-LABEL: @wider_reduce_into_iter pub fn wider_reduce_into_iter(x: Simd) -> u16 { - // FIXME: It would be nice if this was exactly the same as the above tests, - // but at the time of writing this comment, that didn't happen on LLVM main. - // CHECK: call i16 @llvm.vector.reduce.add + // CHECK: zext <16 x i8> + // CHECK-SAME: to <16 x i16> + // CHECK: call i16 @llvm.vector.reduce.add.v16i16(<16 x i16> x.to_array().into_iter().map(u16::from).sum() } From b546764cbef7ac449cbad86636b4ca8daa9f5ef6 Mon Sep 17 00:00:00 2001 From: Nilstrieb <48135649+Nilstrieb@users.noreply.github.com> Date: Thu, 28 Mar 2024 22:54:20 +0100 Subject: [PATCH 163/165] Update ninja on Windows Errors started showing up, and I read somewhere that this might be because of old ninja versions. This ninja version is indeed *ancient*. ``` multiple outputs aren't (yet?) supported by depslog; bring this up on the mailing list if it affects you ``` --- src/ci/scripts/install-ninja.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ci/scripts/install-ninja.sh b/src/ci/scripts/install-ninja.sh index 5145a03e353d..23cbc2eb6d10 100755 --- a/src/ci/scripts/install-ninja.sh +++ b/src/ci/scripts/install-ninja.sh @@ -8,7 +8,7 @@ source "$(cd "$(dirname "$0")" && pwd)/../shared.sh" if isWindows; then mkdir ninja - curl -o ninja.zip "${MIRRORS_BASE}/2017-03-15-ninja-win.zip" + curl -o ninja.zip "${MIRRORS_BASE}/2024-03-28-v1.11.1-ninja-win.zip" 7z x -oninja ninja.zip rm ninja.zip ciCommandSetEnv "RUST_CONFIGURE_ARGS" "${RUST_CONFIGURE_ARGS} --enable-ninja" From 29a59beaa6bc7841b12d6523bd638dbd6e7d0b01 Mon Sep 17 00:00:00 2001 From: The Miri Cronjob Bot Date: Fri, 29 Mar 2024 04:54:51 +0000 Subject: [PATCH 164/165] 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 acf96cfab7a0..6b432dde3b90 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version @@ -1 +1 @@ -b13a71a2e77f4625d1a2b8a5b9488414686ebca9 +760e567af5398a0d8c512f904e551e1f38e00d79 From 5eb78c515c777c232c35b2e606bcec7cefe875af Mon Sep 17 00:00:00 2001 From: Yedaya Katsman Date: Fri, 29 Mar 2024 10:44:19 +0300 Subject: [PATCH 165/165] Forward port 1.77.1 release notes --- RELEASES.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/RELEASES.md b/RELEASES.md index 922afdd3e185..f35dd27ec247 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -1,3 +1,13 @@ +Version 1.77.1 (2024-03-28) +=========================== + + + +- [Revert stripping debuginfo by default for Windows](https://github.com/rust-lang/cargo/pull/13654) + This fixes a regression in 1.77 by reverting to the previous default. + Platforms other than Windows are not affected. +- Internal: [Fix heading anchor rendering in doc pages](https://github.com/rust-lang/rust/pull/122693) + Version 1.77.0 (2024-03-21) ==========================